1 | import { __values } from 'tslib';
|
2 | import { Injectable, Component, Input, HostListener, Output, EventEmitter, NgModule } from '@angular/core';
|
3 | import { fabric } from 'fabric';
|
4 | import { CommonModule } from '@angular/common';
|
5 | import { MatToolbarModule } from '@angular/material/toolbar';
|
6 | import { ColorPickerModule } from 'ngx-color-picker';
|
7 | import { MatButtonModule } from '@angular/material';
|
8 |
|
9 | /**
|
10 | * @fileoverview added by tsickle
|
11 | * @suppress {checkTypes} checked by tsc
|
12 | */
|
13 | /** @enum {number} */
|
14 | var AvailableGeometricShape = {
|
15 | "Rectangle": 0,
|
16 | "Circle": 1,
|
17 | "Triangle": 2,
|
18 | "Line": 3,
|
19 | "Cross": 4,
|
20 | };
|
21 | AvailableGeometricShape[AvailableGeometricShape["Rectangle"]] = "Rectangle";
|
22 | AvailableGeometricShape[AvailableGeometricShape["Circle"]] = "Circle";
|
23 | AvailableGeometricShape[AvailableGeometricShape["Triangle"]] = "Triangle";
|
24 | AvailableGeometricShape[AvailableGeometricShape["Line"]] = "Line";
|
25 | AvailableGeometricShape[AvailableGeometricShape["Cross"]] = "Cross";
|
26 |
|
27 | /**
|
28 | * @fileoverview added by tsickle
|
29 | * @suppress {checkTypes} checked by tsc
|
30 | */
|
31 | var /** @type {?} */ SHAPE_DATA = {
|
32 | width: 200,
|
33 | height: 200,
|
34 | left: 50,
|
35 | top: 50,
|
36 | radius: 100,
|
37 | stroke: 10,
|
38 | freeDrawingBrushWidth: 10,
|
39 | cornerSize: 20
|
40 | };
|
41 |
|
42 | /**
|
43 | * @fileoverview added by tsickle
|
44 | * @suppress {checkTypes} checked by tsc
|
45 | */
|
46 | var CanvasManagerService = /** @class */ (function () {
|
47 | function CanvasManagerService() {
|
48 | this.emptyCanvas();
|
49 | this.mousePosition = { x: 0, y: 0 };
|
50 | this.cropStartingPosition = { x: 0, y: 0 };
|
51 | }
|
52 | Object.defineProperty(CanvasManagerService.prototype, "canvasObjects", {
|
53 | get: /**
|
54 | * @return {?}
|
55 | */
|
56 | function () {
|
57 | return this.canvas.getObjects();
|
58 | },
|
59 | enumerable: true,
|
60 | configurable: true
|
61 | });
|
62 | Object.defineProperty(CanvasManagerService.prototype, "canvasBackgroundImage", {
|
63 | get: /**
|
64 | * @return {?}
|
65 | */
|
66 | function () {
|
67 | return this.canvas.backgroundImage;
|
68 | },
|
69 | enumerable: true,
|
70 | configurable: true
|
71 | });
|
72 | Object.defineProperty(CanvasManagerService.prototype, "activeObject", {
|
73 | get: /**
|
74 | * @return {?}
|
75 | */
|
76 | function () {
|
77 | return this.canvas.getActiveObject();
|
78 | },
|
79 | enumerable: true,
|
80 | configurable: true
|
81 | });
|
82 | Object.defineProperty(CanvasManagerService.prototype, "activeGroup", {
|
83 | get: /**
|
84 | * @return {?}
|
85 | */
|
86 | function () {
|
87 | return this.canvas.getActiveObjects();
|
88 | },
|
89 | enumerable: true,
|
90 | configurable: true
|
91 | });
|
92 | Object.defineProperty(CanvasManagerService.prototype, "divCanvasContainer", {
|
93 | get: /**
|
94 | * @return {?}
|
95 | */
|
96 | function () {
|
97 | return document.getElementsByClassName('div-canvas-container')[0];
|
98 | },
|
99 | enumerable: true,
|
100 | configurable: true
|
101 | });
|
102 | /**
|
103 | * @return {?}
|
104 | */
|
105 | CanvasManagerService.prototype.emptyCanvas = /**
|
106 | * @return {?}
|
107 | */
|
108 | function () {
|
109 | if (this.canvas) {
|
110 | this.canvas.dispose();
|
111 | }
|
112 | this.canvas = new fabric.Canvas('canvas');
|
113 | this.canvas.clear();
|
114 | this.canvas.remove(this.canvas.getObjects());
|
115 | };
|
116 | /**
|
117 | * @param {?=} backgroundImageURL
|
118 | * @return {?}
|
119 | */
|
120 | CanvasManagerService.prototype.loadNewImage = /**
|
121 | * @param {?=} backgroundImageURL
|
122 | * @return {?}
|
123 | */
|
124 | function (backgroundImageURL) {
|
125 | this.emptyCanvas();
|
126 | if (backgroundImageURL) {
|
127 | this.setBackgroundFromURL(backgroundImageURL);
|
128 | }
|
129 | };
|
130 | /**
|
131 | * @return {?}
|
132 | */
|
133 | CanvasManagerService.prototype.renderCanvas = /**
|
134 | * @return {?}
|
135 | */
|
136 | function () {
|
137 | this.markSelectedObjectsDirty();
|
138 | this.canvas.renderAll();
|
139 | };
|
140 | /**
|
141 | * @param {?} strokeColor
|
142 | * @param {?} fillColor
|
143 | * @param {?} shape
|
144 | * @return {?}
|
145 | */
|
146 | CanvasManagerService.prototype.addGeometricShape = /**
|
147 | * @param {?} strokeColor
|
148 | * @param {?} fillColor
|
149 | * @param {?} shape
|
150 | * @return {?}
|
151 | */
|
152 | function (strokeColor, fillColor, shape) {
|
153 | switch (shape) {
|
154 | case AvailableGeometricShape.Rectangle:
|
155 | this.addRectangle(strokeColor, fillColor);
|
156 | break;
|
157 | case AvailableGeometricShape.Circle:
|
158 | this.addCircle(strokeColor, fillColor);
|
159 | break;
|
160 | case AvailableGeometricShape.Triangle:
|
161 | this.addTriangle(strokeColor, fillColor);
|
162 | break;
|
163 | case AvailableGeometricShape.Line:
|
164 | this.addHorizontalLine(strokeColor, fillColor);
|
165 | break;
|
166 | case AvailableGeometricShape.Cross:
|
167 | this.addCross(strokeColor, fillColor);
|
168 | break;
|
169 | }
|
170 | };
|
171 | /**
|
172 | * @param {?} strokeColor
|
173 | * @param {?} fillColor
|
174 | * @return {?}
|
175 | */
|
176 | CanvasManagerService.prototype.addRectangle = /**
|
177 | * @param {?} strokeColor
|
178 | * @param {?} fillColor
|
179 | * @return {?}
|
180 | */
|
181 | function (strokeColor, fillColor) {
|
182 | this.canvas.add(new fabric.Rect({
|
183 | width: SHAPE_DATA.width,
|
184 | height: SHAPE_DATA.height,
|
185 | left: SHAPE_DATA.left,
|
186 | top: SHAPE_DATA.top,
|
187 | fill: fillColor,
|
188 | stroke: strokeColor,
|
189 | strokeWidth: SHAPE_DATA.stroke,
|
190 | cornerSize: SHAPE_DATA.cornerSize
|
191 | }));
|
192 | };
|
193 | /**
|
194 | * @param {?} strokeColor
|
195 | * @param {?} fillColor
|
196 | * @return {?}
|
197 | */
|
198 | CanvasManagerService.prototype.addCircle = /**
|
199 | * @param {?} strokeColor
|
200 | * @param {?} fillColor
|
201 | * @return {?}
|
202 | */
|
203 | function (strokeColor, fillColor) {
|
204 | this.canvas.add(new fabric.Circle({
|
205 | left: SHAPE_DATA.left,
|
206 | top: SHAPE_DATA.top,
|
207 | radius: SHAPE_DATA.radius,
|
208 | stroke: strokeColor,
|
209 | strokeWidth: SHAPE_DATA.stroke,
|
210 | fill: fillColor,
|
211 | cornerSize: SHAPE_DATA.cornerSize
|
212 | }));
|
213 | };
|
214 | /**
|
215 | * @param {?} strokeColor
|
216 | * @param {?} fillColor
|
217 | * @return {?}
|
218 | */
|
219 | CanvasManagerService.prototype.addTriangle = /**
|
220 | * @param {?} strokeColor
|
221 | * @param {?} fillColor
|
222 | * @return {?}
|
223 | */
|
224 | function (strokeColor, fillColor) {
|
225 | this.canvas.add(new fabric.Triangle({
|
226 | width: SHAPE_DATA.width,
|
227 | height: SHAPE_DATA.height,
|
228 | left: SHAPE_DATA.left,
|
229 | top: SHAPE_DATA.top,
|
230 | fill: fillColor,
|
231 | stroke: strokeColor,
|
232 | strokeWidth: SHAPE_DATA.stroke,
|
233 | cornerSize: SHAPE_DATA.cornerSize
|
234 | }));
|
235 | };
|
236 | /**
|
237 | * @param {?} strokeColor
|
238 | * @param {?} fillColor
|
239 | * @return {?}
|
240 | */
|
241 | CanvasManagerService.prototype.addHorizontalLine = /**
|
242 | * @param {?} strokeColor
|
243 | * @param {?} fillColor
|
244 | * @return {?}
|
245 | */
|
246 | function (strokeColor, fillColor) {
|
247 | this.canvas.add(this.createHorizontalLine(strokeColor));
|
248 | };
|
249 | /**
|
250 | * @param {?} strokeColor
|
251 | * @return {?}
|
252 | */
|
253 | CanvasManagerService.prototype.createHorizontalLine = /**
|
254 | * @param {?} strokeColor
|
255 | * @return {?}
|
256 | */
|
257 | function (strokeColor) {
|
258 | var /** @type {?} */ line = new fabric.Line([100, 150, 200, 150], {
|
259 | left: 50,
|
260 | top: 100,
|
261 | stroke: strokeColor,
|
262 | strokeWidth: 5,
|
263 | cornerSize: SHAPE_DATA.cornerSize
|
264 | });
|
265 | line.setControlsVisibility({
|
266 | bl: false,
|
267 | br: false,
|
268 | tl: false,
|
269 | tr: false,
|
270 | mt: false,
|
271 | mb: false
|
272 | });
|
273 | return line;
|
274 | };
|
275 | /**
|
276 | * @param {?} strokeColor
|
277 | * @return {?}
|
278 | */
|
279 | CanvasManagerService.prototype.createVerticalLine = /**
|
280 | * @param {?} strokeColor
|
281 | * @return {?}
|
282 | */
|
283 | function (strokeColor) {
|
284 | var /** @type {?} */ line = new fabric.Line([150, 100, 150, 200], {
|
285 | left: 100,
|
286 | top: 50,
|
287 | stroke: strokeColor,
|
288 | strokeWidth: 5,
|
289 | cornerSize: SHAPE_DATA.cornerSize
|
290 | });
|
291 | line.setControlsVisibility({
|
292 | bl: false,
|
293 | br: false,
|
294 | tl: false,
|
295 | tr: false,
|
296 | ml: false,
|
297 | mr: false
|
298 | });
|
299 | return line;
|
300 | };
|
301 | /**
|
302 | * @param {?} strokeColor
|
303 | * @param {?} fillColor
|
304 | * @return {?}
|
305 | */
|
306 | CanvasManagerService.prototype.addCross = /**
|
307 | * @param {?} strokeColor
|
308 | * @param {?} fillColor
|
309 | * @return {?}
|
310 | */
|
311 | function (strokeColor, fillColor) {
|
312 | var /** @type {?} */ horizontalLine = this.createHorizontalLine(strokeColor);
|
313 | var /** @type {?} */ verticalLine = this.createVerticalLine(strokeColor);
|
314 | this.canvas.add(horizontalLine);
|
315 | this.canvas.add(verticalLine);
|
316 | };
|
317 | /**
|
318 | * @return {?}
|
319 | */
|
320 | CanvasManagerService.prototype.toggleFreeDrawing = /**
|
321 | * @return {?}
|
322 | */
|
323 | function () {
|
324 | this.canvas.isDrawingMode = !this.canvas.isDrawingMode;
|
325 | };
|
326 | /**
|
327 | * @param {?} color
|
328 | * @return {?}
|
329 | */
|
330 | CanvasManagerService.prototype.setFreeDrawingBrushColor = /**
|
331 | * @param {?} color
|
332 | * @return {?}
|
333 | */
|
334 | function (color) {
|
335 | this.canvas.freeDrawingBrush.color = color;
|
336 | this.setFreeDrawingBrushWidthFromZoom(this.canvas.getZoom());
|
337 | };
|
338 | /**
|
339 | * @param {?} zoom
|
340 | * @return {?}
|
341 | */
|
342 | CanvasManagerService.prototype.setFreeDrawingBrushWidthFromZoom = /**
|
343 | * @param {?} zoom
|
344 | * @return {?}
|
345 | */
|
346 | function (zoom) {
|
347 | this.canvas.freeDrawingBrush.width = SHAPE_DATA.freeDrawingBrushWidth * (1 / zoom);
|
348 | };
|
349 | /**
|
350 | * @param {?} color
|
351 | * @param {?} inputText
|
352 | * @return {?}
|
353 | */
|
354 | CanvasManagerService.prototype.addText = /**
|
355 | * @param {?} color
|
356 | * @param {?} inputText
|
357 | * @return {?}
|
358 | */
|
359 | function (color, inputText) {
|
360 | var /** @type {?} */ text = new fabric.IText('text', {
|
361 | fontFamily: 'arial black',
|
362 | fontStyle: 'bold',
|
363 | left: SHAPE_DATA.left,
|
364 | top: SHAPE_DATA.top,
|
365 | cornerSize: SHAPE_DATA.cornerSize
|
366 | });
|
367 | text.setColor(color);
|
368 | this.canvas.add(text);
|
369 | };
|
370 | /**
|
371 | * @param {?} imageURL
|
372 | * @return {?}
|
373 | */
|
374 | CanvasManagerService.prototype.addImage = /**
|
375 | * @param {?} imageURL
|
376 | * @return {?}
|
377 | */
|
378 | function (imageURL) {
|
379 | var _this = this;
|
380 | return new Promise(function (resolve, reject) {
|
381 | var /** @type {?} */ canvas = _this.canvas;
|
382 | var /** @type {?} */ image = new Image();
|
383 | image.onload = function (img) {
|
384 | var /** @type {?} */ fabricImage = new fabric.Image(image, {
|
385 | angle: 0,
|
386 | width: image.width,
|
387 | height: image.height,
|
388 | left: SHAPE_DATA.left,
|
389 | top: SHAPE_DATA.top,
|
390 | scaleX: 1,
|
391 | scaleY: 1,
|
392 | cornerSize: SHAPE_DATA.cornerSize
|
393 | });
|
394 | canvas.add(fabricImage);
|
395 | resolve();
|
396 | };
|
397 | image.src = imageURL;
|
398 | });
|
399 | };
|
400 | /**
|
401 | * @param {?} backgroundImageURL
|
402 | * @return {?}
|
403 | */
|
404 | CanvasManagerService.prototype.setBackgroundFromURL = /**
|
405 | * @param {?} backgroundImageURL
|
406 | * @return {?}
|
407 | */
|
408 | function (backgroundImageURL) {
|
409 | var /** @type {?} */ canvas = this.canvas;
|
410 | var /** @type {?} */ resize = this.resizeCanvasAndComputeScaleFactor;
|
411 | return new Promise(function (resolve, reject) {
|
412 | if (backgroundImageURL == null) {
|
413 | return reject();
|
414 | }
|
415 | var /** @type {?} */ image = new Image();
|
416 | image.onload = function () {
|
417 | var /** @type {?} */ f_img = new fabric.Image(image, {});
|
418 | var /** @type {?} */ scaleData = resize(f_img, canvas);
|
419 | canvas.setBackgroundImage(f_img, canvas.renderAll.bind(canvas), {
|
420 | scaleX: scaleData.scaleFactor,
|
421 | scaleY: scaleData.scaleFactor
|
422 | });
|
423 | canvas.setWidth(f_img.width * scaleData.scaleFactor);
|
424 | canvas.setHeight(f_img.height * scaleData.scaleFactor);
|
425 | canvas.renderAll();
|
426 | resolve();
|
427 | };
|
428 | image.src = backgroundImageURL;
|
429 | });
|
430 | };
|
431 | /**
|
432 | * @param {?} f_img
|
433 | * @param {?} canvas
|
434 | * @return {?}
|
435 | */
|
436 | CanvasManagerService.prototype.resizeCanvasAndComputeScaleFactor = /**
|
437 | * @param {?} f_img
|
438 | * @param {?} canvas
|
439 | * @return {?}
|
440 | */
|
441 | function (f_img, canvas) {
|
442 | var /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
|
443 | canvas.setWidth(container.clientWidth);
|
444 | canvas.setHeight(container.clientHeight);
|
445 | var /** @type {?} */ canvasAspect = container.clientWidth / container.clientHeight;
|
446 | var /** @type {?} */ imgAspect = f_img.width / f_img.height;
|
447 | var /** @type {?} */ left, /** @type {?} */ top, /** @type {?} */ scaleFactor;
|
448 | if (canvasAspect <= imgAspect) {
|
449 | scaleFactor = container.clientWidth / f_img.width;
|
450 | left = 0;
|
451 | top = -(f_img.height * scaleFactor - container.clientHeight) / 2;
|
452 | }
|
453 | else {
|
454 | scaleFactor = container.clientHeight / f_img.height;
|
455 | top = 0;
|
456 | left = -(f_img.width * scaleFactor - container.clientWidth) / 2;
|
457 | }
|
458 | return { scaleFactor: scaleFactor, left: left, top: top };
|
459 | };
|
460 | /**
|
461 | * @return {?}
|
462 | */
|
463 | CanvasManagerService.prototype.onOrientationChange = /**
|
464 | * @return {?}
|
465 | */
|
466 | function () {
|
467 | this.mousePosition = { x: this.canvas.getWidth, y: this.canvas.getHeight };
|
468 | this.cropImage();
|
469 | };
|
470 | /**
|
471 | * @param {?} color
|
472 | * @return {?}
|
473 | */
|
474 | CanvasManagerService.prototype.changeSelectedObjectsFillColor = /**
|
475 | * @param {?} color
|
476 | * @return {?}
|
477 | */
|
478 | function (color) {
|
479 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
480 | if (activeObjects) {
|
481 | try {
|
482 | for (var activeObjects_1 = __values(activeObjects), activeObjects_1_1 = activeObjects_1.next(); !activeObjects_1_1.done; activeObjects_1_1 = activeObjects_1.next()) {
|
483 | var object = activeObjects_1_1.value;
|
484 | object.setColor(color);
|
485 | this.canvas.renderAll();
|
486 | }
|
487 | }
|
488 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
489 | finally {
|
490 | try {
|
491 | if (activeObjects_1_1 && !activeObjects_1_1.done && (_a = activeObjects_1.return)) _a.call(activeObjects_1);
|
492 | }
|
493 | finally { if (e_1) throw e_1.error; }
|
494 | }
|
495 | }
|
496 | var e_1, _a;
|
497 | };
|
498 | /**
|
499 | * @param {?} color
|
500 | * @return {?}
|
501 | */
|
502 | CanvasManagerService.prototype.changeSelectedObjectsStrokeColor = /**
|
503 | * @param {?} color
|
504 | * @return {?}
|
505 | */
|
506 | function (color) {
|
507 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
508 | if (activeObjects) {
|
509 | try {
|
510 | for (var activeObjects_2 = __values(activeObjects), activeObjects_2_1 = activeObjects_2.next(); !activeObjects_2_1.done; activeObjects_2_1 = activeObjects_2.next()) {
|
511 | var object = activeObjects_2_1.value;
|
512 | if (object.type === 'i-text') {
|
513 | object.setColor(color);
|
514 | }
|
515 | else {
|
516 | object.stroke = color;
|
517 | object.set('dirty', true);
|
518 | }
|
519 | }
|
520 | }
|
521 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
522 | finally {
|
523 | try {
|
524 | if (activeObjects_2_1 && !activeObjects_2_1.done && (_a = activeObjects_2.return)) _a.call(activeObjects_2);
|
525 | }
|
526 | finally { if (e_2) throw e_2.error; }
|
527 | }
|
528 | this.canvas.renderAll();
|
529 | }
|
530 | var e_2, _a;
|
531 | };
|
532 | /**
|
533 | * @return {?}
|
534 | */
|
535 | CanvasManagerService.prototype.deleteSelectedObjects = /**
|
536 | * @return {?}
|
537 | */
|
538 | function () {
|
539 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
540 | if (activeObjects) {
|
541 | try {
|
542 | for (var activeObjects_3 = __values(activeObjects), activeObjects_3_1 = activeObjects_3.next(); !activeObjects_3_1.done; activeObjects_3_1 = activeObjects_3.next()) {
|
543 | var object = activeObjects_3_1.value;
|
544 | this.canvas.remove(object);
|
545 | }
|
546 | }
|
547 | catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
548 | finally {
|
549 | try {
|
550 | if (activeObjects_3_1 && !activeObjects_3_1.done && (_a = activeObjects_3.return)) _a.call(activeObjects_3);
|
551 | }
|
552 | finally { if (e_3) throw e_3.error; }
|
553 | }
|
554 | this.canvas.discardActiveObject();
|
555 | this.canvas.renderAll();
|
556 | }
|
557 | var e_3, _a;
|
558 | };
|
559 | /**
|
560 | * @return {?}
|
561 | */
|
562 | CanvasManagerService.prototype.bringSelectedObjectsToFront = /**
|
563 | * @return {?}
|
564 | */
|
565 | function () {
|
566 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
567 | if (activeObjects) {
|
568 | try {
|
569 | for (var activeObjects_4 = __values(activeObjects), activeObjects_4_1 = activeObjects_4.next(); !activeObjects_4_1.done; activeObjects_4_1 = activeObjects_4.next()) {
|
570 | var object = activeObjects_4_1.value;
|
571 | this.canvas.bringToFront(object);
|
572 | }
|
573 | }
|
574 | catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
575 | finally {
|
576 | try {
|
577 | if (activeObjects_4_1 && !activeObjects_4_1.done && (_a = activeObjects_4.return)) _a.call(activeObjects_4);
|
578 | }
|
579 | finally { if (e_4) throw e_4.error; }
|
580 | }
|
581 | }
|
582 | var e_4, _a;
|
583 | };
|
584 | /**
|
585 | * @return {?}
|
586 | */
|
587 | CanvasManagerService.prototype.sendSelectedObjectsToBack = /**
|
588 | * @return {?}
|
589 | */
|
590 | function () {
|
591 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
592 | if (activeObjects) {
|
593 | try {
|
594 | for (var activeObjects_5 = __values(activeObjects), activeObjects_5_1 = activeObjects_5.next(); !activeObjects_5_1.done; activeObjects_5_1 = activeObjects_5.next()) {
|
595 | var object = activeObjects_5_1.value;
|
596 | this.canvas.sendToBack(object);
|
597 | }
|
598 | }
|
599 | catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
600 | finally {
|
601 | try {
|
602 | if (activeObjects_5_1 && !activeObjects_5_1.done && (_a = activeObjects_5.return)) _a.call(activeObjects_5);
|
603 | }
|
604 | finally { if (e_5) throw e_5.error; }
|
605 | }
|
606 | }
|
607 | var e_5, _a;
|
608 | };
|
609 | /**
|
610 | * @return {?}
|
611 | */
|
612 | CanvasManagerService.prototype.jsonFromCanvas = /**
|
613 | * @return {?}
|
614 | */
|
615 | function () {
|
616 | return this.canvas.toJSON();
|
617 | };
|
618 | /**
|
619 | * @param {?} json
|
620 | * @return {?}
|
621 | */
|
622 | CanvasManagerService.prototype.loadfromJson = /**
|
623 | * @param {?} json
|
624 | * @return {?}
|
625 | */
|
626 | function (json) {
|
627 | var _this = this;
|
628 | var /** @type {?} */ container = this.divCanvasContainer;
|
629 | this.setCanvasSize(container.clientWidth, container.clientHeight);
|
630 | return new Promise(function (resolve, reject) {
|
631 | _this.adjustCanvas(json);
|
632 | _this.canvas.loadFromJSON(json, _this.canvas.renderAll.bind(_this.canvas));
|
633 | resolve();
|
634 | });
|
635 | };
|
636 | /**
|
637 | * @param {?} json
|
638 | * @return {?}
|
639 | */
|
640 | CanvasManagerService.prototype.adjustCanvas = /**
|
641 | * @param {?} json
|
642 | * @return {?}
|
643 | */
|
644 | function (json) {
|
645 | var /** @type {?} */ backgroundImage = json['backgroundImage'];
|
646 | var /** @type {?} */ container = this.divCanvasContainer;
|
647 | var /** @type {?} */ width = backgroundImage['width'];
|
648 | var /** @type {?} */ height = backgroundImage['height'];
|
649 | var /** @type {?} */ canvasWidth = container.clientWidth;
|
650 | var /** @type {?} */ canvasHeight = container.clientHeight;
|
651 | var /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
|
652 | var /** @type {?} */ imgAspect = width / height;
|
653 | var /** @type {?} */ scaleFactor;
|
654 | if (canvasAspect <= imgAspect) {
|
655 | scaleFactor = canvasWidth / width;
|
656 | }
|
657 | else {
|
658 | scaleFactor = canvasHeight / height;
|
659 | }
|
660 | var /** @type {?} */ objectScale = scaleFactor / backgroundImage['scaleX'];
|
661 | backgroundImage['scaleX'] = scaleFactor;
|
662 | backgroundImage['scaleY'] = scaleFactor;
|
663 | this.setCanvasSize(width * scaleFactor, height * scaleFactor);
|
664 | var /** @type {?} */ objects = json['objects'];
|
665 | for (var /** @type {?} */ i = 0; i < objects.length; i++) {
|
666 | objects[i]['left'] *= objectScale;
|
667 | objects[i]['top'] *= objectScale;
|
668 | objects[i]['scaleX'] *= objectScale;
|
669 | objects[i]['scaleY'] *= objectScale;
|
670 | }
|
671 | this.canvas.selectable = true;
|
672 | this.canvas.selection = true;
|
673 | this.canvas.renderAll();
|
674 | };
|
675 | /**
|
676 | * @return {?}
|
677 | */
|
678 | CanvasManagerService.prototype.exportImageAsDataURL = /**
|
679 | * @return {?}
|
680 | */
|
681 | function () {
|
682 | return this.canvas.toDataURL('image/png');
|
683 | };
|
684 | /**
|
685 | * @param {?} itemNumber
|
686 | * @return {?}
|
687 | */
|
688 | CanvasManagerService.prototype.selectItem = /**
|
689 | * @param {?} itemNumber
|
690 | * @return {?}
|
691 | */
|
692 | function (itemNumber) {
|
693 | this.canvas.setActiveObject(this.canvas.item(itemNumber));
|
694 | };
|
695 | /**
|
696 | * @param {?} activeObject
|
697 | * @return {?}
|
698 | */
|
699 | CanvasManagerService.prototype.getIndexOf = /**
|
700 | * @param {?} activeObject
|
701 | * @return {?}
|
702 | */
|
703 | function (activeObject) {
|
704 | return this.canvas.getObjects().indexOf(activeObject);
|
705 | };
|
706 | /**
|
707 | * @return {?}
|
708 | */
|
709 | CanvasManagerService.prototype.selectLastObject = /**
|
710 | * @return {?}
|
711 | */
|
712 | function () {
|
713 | var /** @type {?} */ itemNumber = this.canvas.getObjects().length - 1;
|
714 | var /** @type {?} */ object = this.canvas.item(itemNumber);
|
715 | this.canvas.setActiveObject(object);
|
716 | object.enterEditing();
|
717 | };
|
718 | /**
|
719 | * @return {?}
|
720 | */
|
721 | CanvasManagerService.prototype.markSelectedObjectsDirty = /**
|
722 | * @return {?}
|
723 | */
|
724 | function () {
|
725 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
726 | if (activeObjects) {
|
727 | try {
|
728 | for (var activeObjects_6 = __values(activeObjects), activeObjects_6_1 = activeObjects_6.next(); !activeObjects_6_1.done; activeObjects_6_1 = activeObjects_6.next()) {
|
729 | var object = activeObjects_6_1.value;
|
730 | object.set('dirty', true);
|
731 | }
|
732 | }
|
733 | catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
734 | finally {
|
735 | try {
|
736 | if (activeObjects_6_1 && !activeObjects_6_1.done && (_a = activeObjects_6.return)) _a.call(activeObjects_6);
|
737 | }
|
738 | finally { if (e_6) throw e_6.error; }
|
739 | }
|
740 | }
|
741 | var e_6, _a;
|
742 | };
|
743 | /**
|
744 | * @return {?}
|
745 | */
|
746 | CanvasManagerService.prototype.addSelectionRectangle = /**
|
747 | * @return {?}
|
748 | */
|
749 | function () {
|
750 | this.cropRectangle = new fabric.Rect({
|
751 | fill: 'transparent',
|
752 | originX: 'left',
|
753 | originY: 'top',
|
754 | stroke: '#ccc',
|
755 | strokeDashArray: [2, 2],
|
756 | opacity: 1,
|
757 | width: 1,
|
758 | height: 1
|
759 | });
|
760 | this.cropRectangle.visible = false;
|
761 | this.canvas.add(this.cropRectangle);
|
762 | };
|
763 | /**
|
764 | * @param {?} event
|
765 | * @return {?}
|
766 | */
|
767 | CanvasManagerService.prototype.ajustCropRectangleFromMouse = /**
|
768 | * @param {?} event
|
769 | * @return {?}
|
770 | */
|
771 | function (event) {
|
772 | var /** @type {?} */ x = Math.min(event.layerX, this.mousePosition.x), /** @type {?} */
|
773 | y = Math.min(event.layerY, this.mousePosition.y), /** @type {?} */
|
774 | w = Math.abs(event.layerX - this.mousePosition.x), /** @type {?} */
|
775 | h = Math.abs(event.layerY - this.mousePosition.y);
|
776 | if (!w || !h) {
|
777 | return false;
|
778 | }
|
779 | this.cropRectangle
|
780 | .set('top', y)
|
781 | .set('left', x)
|
782 | .set('width', w)
|
783 | .set('height', h);
|
784 | this.canvas.renderAll();
|
785 | return true;
|
786 | };
|
787 | /**
|
788 | * @param {?} event
|
789 | * @return {?}
|
790 | */
|
791 | CanvasManagerService.prototype.startSelectingCropRectangleFromMouse = /**
|
792 | * @param {?} event
|
793 | * @return {?}
|
794 | */
|
795 | function (event) {
|
796 | this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
|
797 | this.cropRectangle.left = event.layerX;
|
798 | this.cropRectangle.top = event.layerY;
|
799 | this.cropRectangle.setCoords();
|
800 | this.mousePosition = { x: event.layerX, y: event.layerY };
|
801 | this.canvas.renderAll();
|
802 | this.cropRectangle.visible = true;
|
803 | this.canvas.bringToFront(this.cropRectangle);
|
804 | };
|
805 | /**
|
806 | * @return {?}
|
807 | */
|
808 | CanvasManagerService.prototype.cropImage = /**
|
809 | * @return {?}
|
810 | */
|
811 | function () {
|
812 | var /** @type {?} */ left = this.cropRectangle.left;
|
813 | var /** @type {?} */ top = this.cropRectangle.top;
|
814 | var /** @type {?} */ width = this.cropRectangle.width;
|
815 | var /** @type {?} */ height = this.cropRectangle.height;
|
816 | var /** @type {?} */ container = this.divCanvasContainer;
|
817 | var /** @type {?} */ canvasWidth = container.clientWidth;
|
818 | var /** @type {?} */ canvasHeight = container.clientHeight;
|
819 | var /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
|
820 | var /** @type {?} */ imgAspect = width / height;
|
821 | var /** @type {?} */ scaleFactor;
|
822 | if (canvasAspect <= imgAspect) {
|
823 | scaleFactor = canvasWidth / width;
|
824 | }
|
825 | else {
|
826 | scaleFactor = canvasHeight / height;
|
827 | }
|
828 | this.setCanvasSize(width * scaleFactor, height * scaleFactor);
|
829 | this.canvas.backgroundImage.scaleX *= scaleFactor;
|
830 | this.canvas.backgroundImage.scaleY *= scaleFactor;
|
831 | this.canvas.backgroundImage.left -= left;
|
832 | this.canvas.backgroundImage.left *= scaleFactor;
|
833 | this.canvas.backgroundImage.top -= top - scaleFactor;
|
834 | this.canvas.backgroundImage.top *= scaleFactor;
|
835 | this.moveAllObjectsInCanvas(-1 * left, -1 * top, scaleFactor);
|
836 | this.enableSlection();
|
837 | this.cropRectangle.visible = false;
|
838 | this.canvas.remove(this.cropRectangle);
|
839 | this.canvas.renderAll();
|
840 | };
|
841 | /**
|
842 | * @return {?}
|
843 | */
|
844 | CanvasManagerService.prototype.enableSlection = /**
|
845 | * @return {?}
|
846 | */
|
847 | function () {
|
848 | this.canvas.selectable = true;
|
849 | this.canvas.selection = true;
|
850 | };
|
851 | /**
|
852 | * @param {?} event
|
853 | * @return {?}
|
854 | */
|
855 | CanvasManagerService.prototype.ajustCropRectangle = /**
|
856 | * @param {?} event
|
857 | * @return {?}
|
858 | */
|
859 | function (event) {
|
860 | var /** @type {?} */ touch = event.touches[0];
|
861 | var /** @type {?} */ rect = event.target.getBoundingClientRect();
|
862 | var /** @type {?} */ x = Math.min(touch.clientX - rect.left, this.mousePosition.x), /** @type {?} */
|
863 | y = Math.min(touch.clientY - rect.top, this.mousePosition.y), /** @type {?} */
|
864 | w = Math.abs(touch.clientX - rect.left - this.mousePosition.x), /** @type {?} */
|
865 | h = Math.abs(touch.clientY - rect.top - this.mousePosition.y);
|
866 | if (!w || !h) {
|
867 | return false;
|
868 | }
|
869 | this.cropRectangle
|
870 | .set('left', x)
|
871 | .set('top', y)
|
872 | .set('width', w)
|
873 | .set('height', h);
|
874 | this.canvas.renderAll();
|
875 | return true;
|
876 | };
|
877 | /**
|
878 | * @param {?} event
|
879 | * @return {?}
|
880 | */
|
881 | CanvasManagerService.prototype.startSelectingCropRectangle = /**
|
882 | * @param {?} event
|
883 | * @return {?}
|
884 | */
|
885 | function (event) {
|
886 | this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
|
887 | var /** @type {?} */ touch = event.touches[0];
|
888 | var /** @type {?} */ rect = event.target.getBoundingClientRect();
|
889 | this.cropRectangle.left = touch.clientX - rect.left;
|
890 | this.cropRectangle.top = touch.clientY - rect.top;
|
891 | this.cropRectangle.setCoords();
|
892 | this.mousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
|
893 | this.canvas.renderAll();
|
894 | this.cropRectangle.visible = true;
|
895 | this.canvas.bringToFront(this.cropRectangle);
|
896 | };
|
897 | /**
|
898 | * @return {?}
|
899 | */
|
900 | CanvasManagerService.prototype.disableSelection = /**
|
901 | * @return {?}
|
902 | */
|
903 | function () {
|
904 | this.canvas.selection = false;
|
905 | };
|
906 | /**
|
907 | * @param {?} x
|
908 | * @param {?} y
|
909 | * @param {?} scaleFactor
|
910 | * @return {?}
|
911 | */
|
912 | CanvasManagerService.prototype.moveAllObjectsInCanvas = /**
|
913 | * @param {?} x
|
914 | * @param {?} y
|
915 | * @param {?} scaleFactor
|
916 | * @return {?}
|
917 | */
|
918 | function (x, y, scaleFactor) {
|
919 | var /** @type {?} */ objects = this.canvas.getObjects();
|
920 | try {
|
921 | for (var objects_1 = __values(objects), objects_1_1 = objects_1.next(); !objects_1_1.done; objects_1_1 = objects_1.next()) {
|
922 | var obj = objects_1_1.value;
|
923 | obj.left += x;
|
924 | obj.left *= scaleFactor;
|
925 | obj.scaleX *= scaleFactor;
|
926 | obj.top += y;
|
927 | obj.scaleY *= scaleFactor;
|
928 | obj.top *= scaleFactor;
|
929 | obj.setCoords();
|
930 | }
|
931 | }
|
932 | catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
933 | finally {
|
934 | try {
|
935 | if (objects_1_1 && !objects_1_1.done && (_a = objects_1.return)) _a.call(objects_1);
|
936 | }
|
937 | finally { if (e_7) throw e_7.error; }
|
938 | }
|
939 | var e_7, _a;
|
940 | };
|
941 | /**
|
942 | * @return {?}
|
943 | */
|
944 | CanvasManagerService.prototype.groupSelectedObjects = /**
|
945 | * @return {?}
|
946 | */
|
947 | function () {
|
948 | var /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
|
949 | if (activeObjects) {
|
950 | var /** @type {?} */ objects = [];
|
951 | try {
|
952 | for (var activeObjects_7 = __values(activeObjects), activeObjects_7_1 = activeObjects_7.next(); !activeObjects_7_1.done; activeObjects_7_1 = activeObjects_7.next()) {
|
953 | var object = activeObjects_7_1.value;
|
954 | objects.push(object);
|
955 | }
|
956 | }
|
957 | catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
958 | finally {
|
959 | try {
|
960 | if (activeObjects_7_1 && !activeObjects_7_1.done && (_a = activeObjects_7.return)) _a.call(activeObjects_7);
|
961 | }
|
962 | finally { if (e_8) throw e_8.error; }
|
963 | }
|
964 | this.deleteSelectedObjects();
|
965 | var /** @type {?} */ group = new fabric.Group(objects);
|
966 | this.canvas.add(group);
|
967 | group.setCoords();
|
968 | this.canvas.setActiveObject(group);
|
969 | this.canvas.renderAll();
|
970 | }
|
971 | var e_8, _a;
|
972 | };
|
973 | /**
|
974 | * @param {?} event
|
975 | * @return {?}
|
976 | */
|
977 | CanvasManagerService.prototype.setLastPanPosition = /**
|
978 | * @param {?} event
|
979 | * @return {?}
|
980 | */
|
981 | function (event) {
|
982 | this.lastPanPosition = new fabric.Point(event.touches[0].clientX, event.touches[0].clientY);
|
983 | };
|
984 | /**
|
985 | * @param {?} event
|
986 | * @return {?}
|
987 | */
|
988 | CanvasManagerService.prototype.panCanvas = /**
|
989 | * @param {?} event
|
990 | * @return {?}
|
991 | */
|
992 | function (event) {
|
993 | var /** @type {?} */ delta = new fabric.Point(event.touches[0].clientX - this.lastPanPosition.x, event.touches[0].clientY - this.lastPanPosition.y);
|
994 | this.canvas.relativePan(delta);
|
995 | this.preventPanOutsideCanvas();
|
996 | this.canvas.renderAll();
|
997 | this.setLastPanPosition(event);
|
998 | };
|
999 | /**
|
1000 | * @return {?}
|
1001 | */
|
1002 | CanvasManagerService.prototype.preventPanOutsideCanvas = /**
|
1003 | * @return {?}
|
1004 | */
|
1005 | function () {
|
1006 | var /** @type {?} */ canvasViewPort = this.canvas.viewportTransform;
|
1007 | var /** @type {?} */ bottomEndPoint = this.canvas.height * (canvasViewPort[0] - 1);
|
1008 | if (canvasViewPort[5] >= 0 || -bottomEndPoint > canvasViewPort[5]) {
|
1009 | canvasViewPort[5] = (canvasViewPort[5] >= 0) ? 0 : -bottomEndPoint;
|
1010 | }
|
1011 | var /** @type {?} */ rightEndPoint = this.canvas.width * (canvasViewPort[0] - 1);
|
1012 | if (canvasViewPort[4] >= 0 || -rightEndPoint > canvasViewPort[4]) {
|
1013 | canvasViewPort[4] = (canvasViewPort[4] >= 0) ? 0 : -rightEndPoint;
|
1014 | }
|
1015 | };
|
1016 | /**
|
1017 | * @param {?} event
|
1018 | * @return {?}
|
1019 | */
|
1020 | CanvasManagerService.prototype.zoom = /**
|
1021 | * @param {?} event
|
1022 | * @return {?}
|
1023 | */
|
1024 | function (event) {
|
1025 | if (Math.abs(event.overallVelocity) > 0.005) {
|
1026 | var /** @type {?} */ point = new fabric.Point(event.center.x, event.center.y);
|
1027 | var /** @type {?} */ zoom = this.canvas.getZoom();
|
1028 | zoom = zoom + (event.scale - zoom) / 20;
|
1029 | if (zoom < 1) {
|
1030 | zoom = 1;
|
1031 | this.canvas.zoomToPoint(new fabric.Point(0, 0), zoom);
|
1032 | this.canvas.absolutePan(new fabric.Point(0, 0));
|
1033 | }
|
1034 | else {
|
1035 | if (zoom > 10) {
|
1036 | zoom = 10;
|
1037 | }
|
1038 | this.canvas.zoomToPoint(point, zoom);
|
1039 | }
|
1040 | this.setFreeDrawingBrushWidthFromZoom(zoom);
|
1041 | this.canvas.renderAll();
|
1042 | }
|
1043 | };
|
1044 | /**
|
1045 | * @param {?} width
|
1046 | * @param {?} height
|
1047 | * @return {?}
|
1048 | */
|
1049 | CanvasManagerService.prototype.setCanvasSize = /**
|
1050 | * @param {?} width
|
1051 | * @param {?} height
|
1052 | * @return {?}
|
1053 | */
|
1054 | function (width, height) {
|
1055 | this.canvas.setWidth(width);
|
1056 | this.canvas.setHeight(height);
|
1057 | };
|
1058 | /**
|
1059 | * @return {?}
|
1060 | */
|
1061 | CanvasManagerService.prototype.resetZoom = /**
|
1062 | * @return {?}
|
1063 | */
|
1064 | function () {
|
1065 | this.canvas.zoomToPoint(new fabric.Point(0, 0), 1);
|
1066 | this.canvas.absolutePan(new fabric.Point(0, 0));
|
1067 | };
|
1068 | CanvasManagerService.decorators = [
|
1069 | { type: Injectable },
|
1070 | ];
|
1071 | /** @nocollapse */
|
1072 | CanvasManagerService.ctorParameters = function () { return []; };
|
1073 | return CanvasManagerService;
|
1074 | }());
|
1075 |
|
1076 | /**
|
1077 | * @fileoverview added by tsickle
|
1078 | * @suppress {checkTypes} checked by tsc
|
1079 | */
|
1080 | /** @enum {number} */
|
1081 | var KEY_CODE = {
|
1082 | DELETE: 46,
|
1083 | BACKSPACE: 8,
|
1084 | };
|
1085 | KEY_CODE[KEY_CODE.DELETE] = "DELETE";
|
1086 | KEY_CODE[KEY_CODE.BACKSPACE] = "BACKSPACE";
|
1087 |
|
1088 | /**
|
1089 | * @fileoverview added by tsickle
|
1090 | * @suppress {checkTypes} checked by tsc
|
1091 | */
|
1092 | var /** @type {?} */ Black = '#000000';
|
1093 | var /** @type {?} */ Transparent = 'transparent';
|
1094 | var WebSketchToolComponent = /** @class */ (function () {
|
1095 | function WebSketchToolComponent(canvasManagerService) {
|
1096 | this.canvasManagerService = canvasManagerService;
|
1097 | this.availableGeometricShapes = AvailableGeometricShape;
|
1098 | this.canvas = new EventEmitter();
|
1099 | this.strokeColor = Black;
|
1100 | this.fillColor = Transparent;
|
1101 | this.isCropping = false;
|
1102 | this.isLoaded = false;
|
1103 | }
|
1104 | /**
|
1105 | * @return {?}
|
1106 | */
|
1107 | WebSketchToolComponent.prototype.ngOnInit = /**
|
1108 | * @return {?}
|
1109 | */
|
1110 | function () {
|
1111 | this.setCanvas();
|
1112 | };
|
1113 | /**
|
1114 | * @return {?}
|
1115 | */
|
1116 | WebSketchToolComponent.prototype.ngOnChanges = /**
|
1117 | * @return {?}
|
1118 | */
|
1119 | function () {
|
1120 | this.setCanvas();
|
1121 | };
|
1122 | /**
|
1123 | * @return {?}
|
1124 | */
|
1125 | WebSketchToolComponent.prototype.setCanvas = /**
|
1126 | * @return {?}
|
1127 | */
|
1128 | function () {
|
1129 | if (this.imageData) {
|
1130 | this.canvasManagerService.emptyCanvas();
|
1131 | this.canvasManagerService.resetZoom();
|
1132 | if (this.loadedJson == null || this.loadedJson.length < 10) {
|
1133 | this.canvasManagerService.setBackgroundFromURL(this.imageData);
|
1134 | }
|
1135 | else {
|
1136 | this.canvasManagerService.loadfromJson(JSON.parse(this.loadedJson));
|
1137 | }
|
1138 | this.isLoaded = true;
|
1139 | this.previousImageData = this.imageData;
|
1140 | this.emitCanvas();
|
1141 | }
|
1142 | };
|
1143 | /**
|
1144 | * @return {?}
|
1145 | */
|
1146 | WebSketchToolComponent.prototype.addText = /**
|
1147 | * @return {?}
|
1148 | */
|
1149 | function () {
|
1150 | this.canvasManagerService.addText(this.strokeColor, ' ');
|
1151 | this.emitCanvas();
|
1152 | };
|
1153 | /**
|
1154 | * @param {?} shape
|
1155 | * @return {?}
|
1156 | */
|
1157 | WebSketchToolComponent.prototype.addShape = /**
|
1158 | * @param {?} shape
|
1159 | * @return {?}
|
1160 | */
|
1161 | function (shape) {
|
1162 | this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape[shape]);
|
1163 | this.emitCanvas();
|
1164 | };
|
1165 | /**
|
1166 | * @return {?}
|
1167 | */
|
1168 | WebSketchToolComponent.prototype.changeStrokeColor = /**
|
1169 | * @return {?}
|
1170 | */
|
1171 | function () {
|
1172 | this.canvasManagerService.changeSelectedObjectsStrokeColor(this.strokeColor);
|
1173 | this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
|
1174 | this.emitCanvas();
|
1175 | };
|
1176 | /**
|
1177 | * @return {?}
|
1178 | */
|
1179 | WebSketchToolComponent.prototype.bringFoward = /**
|
1180 | * @return {?}
|
1181 | */
|
1182 | function () {
|
1183 | this.canvasManagerService.bringSelectedObjectsToFront();
|
1184 | this.emitCanvas();
|
1185 | };
|
1186 | /**
|
1187 | * @return {?}
|
1188 | */
|
1189 | WebSketchToolComponent.prototype.sendToBack = /**
|
1190 | * @return {?}
|
1191 | */
|
1192 | function () {
|
1193 | this.canvasManagerService.sendSelectedObjectsToBack();
|
1194 | this.emitCanvas();
|
1195 | };
|
1196 | /**
|
1197 | * @return {?}
|
1198 | */
|
1199 | WebSketchToolComponent.prototype.draw = /**
|
1200 | * @return {?}
|
1201 | */
|
1202 | function () {
|
1203 | this.isDrawing = !this.isDrawing;
|
1204 | this.canvasManagerService.toggleFreeDrawing();
|
1205 | this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
|
1206 | };
|
1207 | /**
|
1208 | * @return {?}
|
1209 | */
|
1210 | WebSketchToolComponent.prototype.saveImage = /**
|
1211 | * @return {?}
|
1212 | */
|
1213 | function () {
|
1214 | var /** @type {?} */ dataURL = this.canvasManagerService.exportImageAsDataURL();
|
1215 | var /** @type {?} */ link = document.createElement('a');
|
1216 | link.download = 'image';
|
1217 | link.href = dataURL;
|
1218 | document.body.appendChild(link);
|
1219 | link.click();
|
1220 | document.body.removeChild(link);
|
1221 | };
|
1222 | /**
|
1223 | * @return {?}
|
1224 | */
|
1225 | WebSketchToolComponent.prototype.crop = /**
|
1226 | * @return {?}
|
1227 | */
|
1228 | function () {
|
1229 | this.isCropping = true;
|
1230 | this.canvasManagerService.disableSelection();
|
1231 | this.canvasManagerService.addSelectionRectangle();
|
1232 | };
|
1233 | /**
|
1234 | * @param {?} event
|
1235 | * @return {?}
|
1236 | */
|
1237 | WebSketchToolComponent.prototype.keyEvent = /**
|
1238 | * @param {?} event
|
1239 | * @return {?}
|
1240 | */
|
1241 | function (event) {
|
1242 | if (event.keyCode === KEY_CODE.DELETE) {
|
1243 | this.deleteSelection();
|
1244 | }
|
1245 | this.emitCanvas();
|
1246 | };
|
1247 | /**
|
1248 | * @return {?}
|
1249 | */
|
1250 | WebSketchToolComponent.prototype.deleteSelection = /**
|
1251 | * @return {?}
|
1252 | */
|
1253 | function () {
|
1254 | this.canvasManagerService.deleteSelectedObjects();
|
1255 | this.emitCanvas();
|
1256 | };
|
1257 | /**
|
1258 | * @param {?} event
|
1259 | * @return {?}
|
1260 | */
|
1261 | WebSketchToolComponent.prototype.mouseUp = /**
|
1262 | * @param {?} event
|
1263 | * @return {?}
|
1264 | */
|
1265 | function (event) {
|
1266 | if (this.isCropping) {
|
1267 | this.canvasManagerService.cropImage();
|
1268 | this.isCropping = false;
|
1269 | }
|
1270 | this.emitCanvas();
|
1271 | };
|
1272 | /**
|
1273 | * @param {?} event
|
1274 | * @return {?}
|
1275 | */
|
1276 | WebSketchToolComponent.prototype.mouseMove = /**
|
1277 | * @param {?} event
|
1278 | * @return {?}
|
1279 | */
|
1280 | function (event) {
|
1281 | if (this.isCropping) {
|
1282 | this.canvasManagerService.ajustCropRectangleFromMouse(event);
|
1283 | }
|
1284 | };
|
1285 | /**
|
1286 | * @param {?} event
|
1287 | * @return {?}
|
1288 | */
|
1289 | WebSketchToolComponent.prototype.mouseDown = /**
|
1290 | * @param {?} event
|
1291 | * @return {?}
|
1292 | */
|
1293 | function (event) {
|
1294 | if (this.isCropping) {
|
1295 | this.canvasManagerService.startSelectingCropRectangleFromMouse(event);
|
1296 | }
|
1297 | };
|
1298 | /**
|
1299 | * @return {?}
|
1300 | */
|
1301 | WebSketchToolComponent.prototype.group = /**
|
1302 | * @return {?}
|
1303 | */
|
1304 | function () {
|
1305 | this.canvasManagerService.groupSelectedObjects();
|
1306 | this.emitCanvas();
|
1307 | };
|
1308 | /**
|
1309 | * @return {?}
|
1310 | */
|
1311 | WebSketchToolComponent.prototype.emitCanvas = /**
|
1312 | * @return {?}
|
1313 | */
|
1314 | function () {
|
1315 | this.canvas.emit(this.canvasManagerService.canvas);
|
1316 | };
|
1317 | WebSketchToolComponent.decorators = [
|
1318 | { type: Component, args: [{
|
1319 | selector: 'lib-web-sketch-tool',
|
1320 | template: "<div\n class=\"div-canvas-container\"\n (mousedown)=\"mouseDown($event)\"\n (mousemove)=\"mouseMove($event)\"\n (mouseup)=\"mouseUp($event)\"\n>\n <canvas id=\"canvas\"></canvas>\n</div>\n\n<mat-toolbar class=\"edit-toolbar\">\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"addShape('Rectangle')\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-square\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"addShape('Circle')\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-circle\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"addShape('Triangle')\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-caret-up\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"addShape('Line')\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-minus\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"addText()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-font\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n color=\"accent\"\n (click)=\"crop()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-crop\"></i>\n </button>\n\n <button\n mat-button\n (click)=\"draw()\"\n class=\"tool-button\"\n >\n <i class=\"fas fa-pencil-alt\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"group()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-object-group\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n color=\"accent\"\n (click)=\"bringFoward()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-angle-up\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n color=\"accent\"\n (click)=\"sendToBack()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-angle-down\"></i>\n </button>\n\n <button\n mat-button\n class=\"tool-button\"\n (click)=\"deleteSelection()\"\n [disabled]=\"isDrawing\"\n >\n <i class=\"fas fa-trash\"></i>\n </button>\n\n <button\n mat-button\n (click)=\"saveImage()\"\n class=\"tool-button\"\n >\n <i class=\"fas fa-download\"></i>\n </button>\n\n <input\n mat-button\n class=\"colorPicker\"\n [(colorPicker)]=\"strokeColor\"\n [style.background]=\"strokeColor\"\n (colorPickerChange)=\"changeStrokeColor()\"\n >\n</mat-toolbar>\n",
|
1321 | styles: [".div-canvas-container{text-align:center;margin:0 auto;padding:0;height:90%!important;width:100%!important;-o-object-fit:contain;object-fit:contain}.edit-toolbar{height:7%;justify-content:center}.toolbar-button{font-family:FontAwesome;display:inline-block;width:1.5em;min-width:0}.mat-button.tool-button{min-width:40px!important;width:50px;min-height:40px!important;height:40px;margin-right:10px}.colorPicker{width:40px;height:36px;margin-top:3px;color:transparent}i{font-size:1.5em;color:#000}"],
|
1322 | providers: [CanvasManagerService]
|
1323 | },] },
|
1324 | ];
|
1325 | /** @nocollapse */
|
1326 | WebSketchToolComponent.ctorParameters = function () { return [
|
1327 | { type: CanvasManagerService, },
|
1328 | ]; };
|
1329 | WebSketchToolComponent.propDecorators = {
|
1330 | "imageData": [{ type: Input },],
|
1331 | "loadedJson": [{ type: Input },],
|
1332 | "canvas": [{ type: Output },],
|
1333 | "keyEvent": [{ type: HostListener, args: ['window:keyup', ['$event'],] },],
|
1334 | };
|
1335 | return WebSketchToolComponent;
|
1336 | }());
|
1337 |
|
1338 | /**
|
1339 | * @fileoverview added by tsickle
|
1340 | * @suppress {checkTypes} checked by tsc
|
1341 | */
|
1342 | var WebSketchToolModule = /** @class */ (function () {
|
1343 | function WebSketchToolModule() {
|
1344 | }
|
1345 | WebSketchToolModule.decorators = [
|
1346 | { type: NgModule, args: [{
|
1347 | imports: [CommonModule, ColorPickerModule, MatButtonModule, MatToolbarModule],
|
1348 | declarations: [WebSketchToolComponent],
|
1349 | exports: [WebSketchToolComponent]
|
1350 | },] },
|
1351 | ];
|
1352 | return WebSketchToolModule;
|
1353 | }());
|
1354 |
|
1355 | /**
|
1356 | * @fileoverview added by tsickle
|
1357 | * @suppress {checkTypes} checked by tsc
|
1358 | */
|
1359 |
|
1360 | /**
|
1361 | * @fileoverview added by tsickle
|
1362 | * @suppress {checkTypes} checked by tsc
|
1363 | */
|
1364 |
|
1365 | export { WebSketchToolComponent, CanvasManagerService, WebSketchToolModule };
|
1366 |
|
1367 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliLXNrZXRjaC10b29sLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC9jb25zdGFudHMvc2hhcGUtZGF0YS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvd2ViLWNvbXBvbmVudC93ZWItc2tldGNoLXRvb2wuY29tcG9uZW50LnRzIiwibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC93ZWItc2tldGNoLXRvb2wubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBTSEFQRV9EQVRBID0ge1xuICB3aWR0aDogMjAwLFxuICBoZWlnaHQ6IDIwMCxcbiAgbGVmdDogNTAsXG4gIHRvcDogNTAsXG4gIHJhZGl1czogMTAwLFxuICBzdHJva2U6IDEwLFxuICBmcmVlRHJhd2luZ0JydXNoV2lkdGg6IDEwLFxuICBjb3JuZXJTaXplOiAyMFxufTtcbiIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZhYnJpYyB9IGZyb20gJ2ZhYnJpYyc7XG5cbmltcG9ydCB7IEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvYXZhaWxhYmxlLWdlb21ldHJpYy1zaGFwZXMnO1xuaW1wb3J0IHsgU0hBUEVfREFUQSB9IGZyb20gJy4vLi4vY29uc3RhbnRzL3NoYXBlLWRhdGEnO1xuXG5pbnRlcmZhY2UgU2NhbGVEYXRhIHtcbiAgc2NhbGVGYWN0b3I6IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFBvc2l0aW9uIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDYW52YXNNYW5hZ2VyU2VydmljZSB7XG4gIHB1YmxpYyBjYW52YXM7XG5cbiAgcHJpdmF0ZSBjcm9wUmVjdGFuZ2xlOiBmYWJyaWMuUmVjdDtcbiAgcHJpdmF0ZSBtb3VzZVBvc2l0aW9uOiBQb3NpdGlvbjtcbiAgcHJpdmF0ZSBjcm9wU3RhcnRpbmdQb3NpdGlvbjogUG9zaXRpb247XG4gIHByaXZhdGUgbGFzdFBhblBvc2l0aW9uOiBmYWJyaWMuUG9pbnQ7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5lbXB0eUNhbnZhcygpO1xuICAgIHRoaXMubW91c2VQb3NpdGlvbiA9IHt4OiAwLCB5OiAwfTtcbiAgICB0aGlzLmNyb3BTdGFydGluZ1Bvc2l0aW9uID0ge3g6IDAsIHk6IDB9O1xuICB9XG5cbiAgZ2V0IGNhbnZhc09iamVjdHMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLmdldE9iamVjdHMoKTtcbiAgfVxuXG4gIGdldCBjYW52YXNCYWNrZ3JvdW5kSW1hZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZTtcbiAgfVxuXG4gIGdldCBhY3RpdmVPYmplY3QoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdCgpO1xuICB9XG5cbiAgZ2V0IGFjdGl2ZUdyb3VwKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG4gIH1cblxuICBnZXQgZGl2Q2FudmFzQ29udGFpbmVyKCkge1xuICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdkaXYtY2FudmFzLWNvbnRhaW5lcicpWzBdO1xuICB9XG5cbiAgcHVibGljIGVtcHR5Q2FudmFzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgdGhpcy5jYW52YXMuZGlzcG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLmNhbnZhcyA9IG5ldyBmYWJyaWMuQ2FudmFzKCdjYW52YXMnKTtcbiAgICB0aGlzLmNhbnZhcy5jbGVhcigpO1xuICAgIHRoaXMuY2FudmFzLnJlbW92ZSh0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkpO1xuICB9XG5cbiAgcHVibGljIGxvYWROZXdJbWFnZShiYWNrZ3JvdW5kSW1hZ2VVUkw/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtcHR5Q2FudmFzKCk7XG4gICAgaWYgKGJhY2tncm91bmRJbWFnZVVSTCkge1xuICAgICAgdGhpcy5zZXRCYWNrZ3JvdW5kRnJvbVVSTChiYWNrZ3JvdW5kSW1hZ2VVUkwpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZW5kZXJDYW52YXMoKTogdm9pZCB7XG4gICAgdGhpcy5tYXJrU2VsZWN0ZWRPYmplY3RzRGlydHkoKTtcbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRHZW9tZXRyaWNTaGFwZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZywgc2hhcGU6IEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlKTogdm9pZCB7XG4gICAgc3dpdGNoIChzaGFwZSkge1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5SZWN0YW5nbGU6XG4gICAgICAgIHRoaXMuYWRkUmVjdGFuZ2xlKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuQ2lyY2xlOlxuICAgICAgICB0aGlzLmFkZENpcmNsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLlRyaWFuZ2xlOlxuICAgICAgICB0aGlzLmFkZFRyaWFuZ2xlKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuTGluZTpcbiAgICAgICAgdGhpcy5hZGRIb3Jpem9udGFsTGluZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkNyb3NzOlxuICAgICAgICB0aGlzLmFkZENyb3NzKHN0cm9rZUNvbG9yLCBmaWxsQ29sb3IpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZFJlY3RhbmdsZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZChcbiAgICAgIG5ldyBmYWJyaWMuUmVjdCh7XG4gICAgICAgIHdpZHRoOiBTSEFQRV9EQVRBLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IFNIQVBFX0RBVEEuaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IFNIQVBFX0RBVEEuc3Ryb2tlLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2lyY2xlKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXMuYWRkKFxuICAgICAgbmV3IGZhYnJpYy5DaXJjbGUoe1xuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIHJhZGl1czogU0hBUEVfREFUQS5yYWRpdXMsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBTSEFQRV9EQVRBLnN0cm9rZSxcbiAgICAgICAgZmlsbDogZmlsbENvbG9yLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkVHJpYW5nbGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQoXG4gICAgICBuZXcgZmFicmljLlRyaWFuZ2xlKHtcbiAgICAgICAgd2lkdGg6IFNIQVBFX0RBVEEud2lkdGgsXG4gICAgICAgIGhlaWdodDogU0hBUEVfREFUQS5oZWlnaHQsXG4gICAgICAgIGxlZnQ6IFNIQVBFX0RBVEEubGVmdCxcbiAgICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgICAgZmlsbDogZmlsbENvbG9yLFxuICAgICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogU0hBUEVfREFUQS5zdHJva2UsXG4gICAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZCh0aGlzLmNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yKSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yOiBzdHJpbmcpOiBmYWJyaWMuTGluZSB7XG4gICAgY29uc3QgbGluZSA9IG5ldyBmYWJyaWMuTGluZShbMTAwLCAxNTAsIDIwMCwgMTUwXSwge1xuICAgICAgbGVmdDogNTAsXG4gICAgICB0b3A6IDEwMCxcbiAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICBzdHJva2VXaWR0aDogNSxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgbGluZS5zZXRDb250cm9sc1Zpc2liaWxpdHkoe1xuICAgICAgYmw6IGZhbHNlLFxuICAgICAgYnI6IGZhbHNlLFxuICAgICAgdGw6IGZhbHNlLFxuICAgICAgdHI6IGZhbHNlLFxuICAgICAgbXQ6IGZhbHNlLFxuICAgICAgbWI6IGZhbHNlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmVydGljYWxMaW5lKHN0cm9rZUNvbG9yOiBzdHJpbmcpOiBmYWJyaWMuTGluZSB7XG4gICAgY29uc3QgbGluZSA9IG5ldyBmYWJyaWMuTGluZShbMTUwLCAxMDAsIDE1MCwgMjAwXSwge1xuICAgICAgbGVmdDogMTAwLFxuICAgICAgdG9wOiA1MCxcbiAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICBzdHJva2VXaWR0aDogNSxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgbGluZS5zZXRDb250cm9sc1Zpc2liaWxpdHkoe1xuICAgICAgYmw6IGZhbHNlLFxuICAgICAgYnI6IGZhbHNlLFxuICAgICAgdGw6IGZhbHNlLFxuICAgICAgdHI6IGZhbHNlLFxuICAgICAgbWw6IGZhbHNlLFxuICAgICAgbXI6IGZhbHNlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ3Jvc3Moc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBob3Jpem9udGFsTGluZSA9IHRoaXMuY3JlYXRlSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3IpO1xuICAgIGNvbnN0IHZlcnRpY2FsTGluZSA9IHRoaXMuY3JlYXRlVmVydGljYWxMaW5lKHN0cm9rZUNvbG9yKTtcbiAgICB0aGlzLmNhbnZhcy5hZGQoaG9yaXpvbnRhbExpbmUpO1xuICAgIHRoaXMuY2FudmFzLmFkZCh2ZXJ0aWNhbExpbmUpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZyZWVEcmF3aW5nKCk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmlzRHJhd2luZ01vZGUgPSAhdGhpcy5jYW52YXMuaXNEcmF3aW5nTW9kZTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGcmVlRHJhd2luZ0JydXNoQ29sb3IoY29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmZyZWVEcmF3aW5nQnJ1c2guY29sb3IgPSBjb2xvcjtcbiAgICB0aGlzLnNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHRoaXMuY2FudmFzLmdldFpvb20oKSk7XG4gIH1cblxuICBwcml2YXRlIHNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHpvb206IG51bWJlcikge1xuICAgIHRoaXMuY2FudmFzLmZyZWVEcmF3aW5nQnJ1c2gud2lkdGggPSBTSEFQRV9EQVRBLmZyZWVEcmF3aW5nQnJ1c2hXaWR0aCAqICgxIC8gem9vbSk7XG4gIH1cblxuICBwdWJsaWMgYWRkVGV4dChjb2xvcjogc3RyaW5nLCBpbnB1dFRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgZmFicmljLklUZXh0KCd0ZXh0Jywge1xuICAgICAgZm9udEZhbWlseTogJ2FyaWFsIGJsYWNrJyxcbiAgICAgIGZvbnRTdHlsZTogJ2JvbGQnLFxuICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgdGV4dC5zZXRDb2xvcihjb2xvcik7XG5cbiAgICB0aGlzLmNhbnZhcy5hZGQodGV4dCk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW1hZ2UoaW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShcbiAgICAgIChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXM7XG5cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oaW1nKSB7XG4gICAgICAgICAgY29uc3QgZmFicmljSW1hZ2UgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7XG4gICAgICAgICAgICBhbmdsZTogMCxcbiAgICAgICAgICAgIHdpZHRoOiBpbWFnZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaW1hZ2UuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgICAgICAgIHNjYWxlWDogMSxcbiAgICAgICAgICAgIHNjYWxlWTogMSxcbiAgICAgICAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNhbnZhcy5hZGQoZmFicmljSW1hZ2UpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gaW1hZ2VVUkw7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRCYWNrZ3JvdW5kRnJvbVVSTChiYWNrZ3JvdW5kSW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzO1xuICAgIGNvbnN0IHJlc2l6ZSA9IHRoaXMucmVzaXplQ2FudmFzQW5kQ29tcHV0ZVNjYWxlRmFjdG9yO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgICAgKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoYmFja2dyb3VuZEltYWdlVVJMID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgZl9pbWcgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7fSk7XG5cbiAgICAgICAgICBjb25zdCBzY2FsZURhdGEgPSByZXNpemUoZl9pbWcsIGNhbnZhcyk7XG5cbiAgICAgICAgICBjYW52YXMuc2V0QmFja2dyb3VuZEltYWdlKGZfaW1nLCBjYW52YXMucmVuZGVyQWxsLmJpbmQoY2FudmFzKSwge1xuICAgICAgICAgICAgc2NhbGVYOiBzY2FsZURhdGEuc2NhbGVGYWN0b3IsXG4gICAgICAgICAgICBzY2FsZVk6IHNjYWxlRGF0YS5zY2FsZUZhY3RvclxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2FudmFzLnNldFdpZHRoKGZfaW1nLndpZHRoICogc2NhbGVEYXRhLnNjYWxlRmFjdG9yKTtcbiAgICAgICAgICBjYW52YXMuc2V0SGVpZ2h0KGZfaW1nLmhlaWdodCAqIHNjYWxlRGF0YS5zY2FsZUZhY3Rvcik7XG5cbiAgICAgICAgICBjYW52YXMucmVuZGVyQWxsKCk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICBpbWFnZS5zcmMgPSBiYWNrZ3JvdW5kSW1hZ2VVUkw7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzaXplQ2FudmFzQW5kQ29tcHV0ZVNjYWxlRmFjdG9yKGZfaW1nOiBmYWJyaWMuSW1hZ2UsIGNhbnZhczogZmFicmljLkNhbnZhcyk6IFNjYWxlRGF0YSB7XG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcbiAgICAgICdkaXYtY2FudmFzLWNvbnRhaW5lcidcbiAgICApWzBdO1xuXG4gICAgY2FudmFzLnNldFdpZHRoKGNvbnRhaW5lci5jbGllbnRXaWR0aCk7XG4gICAgY2FudmFzLnNldEhlaWdodChjb250YWluZXIuY2xpZW50SGVpZ2h0KTtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aCAvIGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3QgaW1nQXNwZWN0ID0gZl9pbWcud2lkdGggLyBmX2ltZy5oZWlnaHQ7XG4gICAgbGV0IGxlZnQsIHRvcCwgc2NhbGVGYWN0b3I7XG5cbiAgICBpZiAoY2FudmFzQXNwZWN0IDw9IGltZ0FzcGVjdCkge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjb250YWluZXIuY2xpZW50V2lkdGggLyBmX2ltZy53aWR0aDtcbiAgICAgIGxlZnQgPSAwO1xuICAgICAgdG9wID0gLShmX2ltZy5oZWlnaHQgKiBzY2FsZUZhY3RvciAtIGNvbnRhaW5lci5jbGllbnRIZWlnaHQpIC8gMjtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjb250YWluZXIuY2xpZW50SGVpZ2h0IC8gZl9pbWcuaGVpZ2h0O1xuICAgICAgdG9wID0gMDtcbiAgICAgIGxlZnQgPSAtKGZfaW1nLndpZHRoICogc2NhbGVGYWN0b3IgLSBjb250YWluZXIuY2xpZW50V2lkdGgpIC8gMjtcbiAgICB9XG5cbiAgICByZXR1cm4geyBzY2FsZUZhY3Rvcjogc2NhbGVGYWN0b3IsIGxlZnQ6IGxlZnQsIHRvcDogdG9wIH07XG4gIH1cblxuICBwdWJsaWMgb25PcmllbnRhdGlvbkNoYW5nZSgpIHtcbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7eDogdGhpcy5jYW52YXMuZ2V0V2lkdGgsIHk6IHRoaXMuY2FudmFzLmdldEhlaWdodCB9O1xuICAgIHRoaXMuY3JvcEltYWdlKCk7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlU2VsZWN0ZWRPYmplY3RzRmlsbENvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgb2JqZWN0LnNldENvbG9yKGNvbG9yKTtcbiAgICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNoYW5nZVNlbGVjdGVkT2JqZWN0c1N0cm9rZUNvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgaWYgKG9iamVjdC50eXBlID09PSAnaS10ZXh0Jykge1xuICAgICAgICAgIG9iamVjdC5zZXRDb2xvcihjb2xvcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb2JqZWN0LnN0cm9rZSA9IGNvbG9yO1xuICAgICAgICAgIG9iamVjdC5zZXQoJ2RpcnR5JywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBkZWxldGVTZWxlY3RlZE9iamVjdHMoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLnJlbW92ZShvYmplY3QpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYW52YXMuZGlzY2FyZEFjdGl2ZU9iamVjdCgpO1xuICAgICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGJyaW5nU2VsZWN0ZWRPYmplY3RzVG9Gcm9udCgpOiB2b2lkIHtcbiAgICBjb25zdCBhY3RpdmVPYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0cygpO1xuXG4gICAgaWYgKGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgdGhpcy5jYW52YXMuYnJpbmdUb0Zyb250KG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHNlbmRTZWxlY3RlZE9iamVjdHNUb0JhY2soKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLnNlbmRUb0JhY2sob2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMganNvbkZyb21DYW52YXMoKTogSlNPTiB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvSlNPTigpO1xuICB9XG5cbiAgcHVibGljIGxvYWRmcm9tSnNvbihqc29uOiBKU09OKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5kaXZDYW52YXNDb250YWluZXI7XG5cbiAgICB0aGlzLnNldENhbnZhc1NpemUoY29udGFpbmVyLmNsaWVudFdpZHRoLCBjb250YWluZXIuY2xpZW50SGVpZ2h0KTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShcbiAgICAgIChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5hZGp1c3RDYW52YXMoanNvbik7XG4gICAgICAgIHRoaXMuY2FudmFzLmxvYWRGcm9tSlNPTihqc29uLCB0aGlzLmNhbnZhcy5yZW5kZXJBbGwuYmluZCh0aGlzLmNhbnZhcykpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGp1c3RDYW52YXMoanNvbjogSlNPTik6IHZvaWQge1xuICAgIGNvbnN0IGJhY2tncm91bmRJbWFnZSA9IGpzb25bJ2JhY2tncm91bmRJbWFnZSddO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5kaXZDYW52YXNDb250YWluZXI7XG5cbiAgICBjb25zdCB3aWR0aCA9IGJhY2tncm91bmRJbWFnZVsnd2lkdGgnXTtcbiAgICBjb25zdCBoZWlnaHQgPSBiYWNrZ3JvdW5kSW1hZ2VbJ2hlaWdodCddO1xuXG4gICAgY29uc3QgY2FudmFzV2lkdGggPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY29udGFpbmVyLmNsaWVudEhlaWdodDtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IHdpZHRoIC8gaGVpZ2h0O1xuICAgIGxldCBzY2FsZUZhY3RvcjtcblxuICAgIGlmIChjYW52YXNBc3BlY3QgPD0gaW1nQXNwZWN0KSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc1dpZHRoIC8gd2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzSGVpZ2h0IC8gaGVpZ2h0O1xuICAgIH1cblxuICAgIGNvbnN0IG9iamVjdFNjYWxlID0gc2NhbGVGYWN0b3IgLyBiYWNrZ3JvdW5kSW1hZ2VbJ3NjYWxlWCddO1xuXG4gICAgYmFja2dyb3VuZEltYWdlWydzY2FsZVgnXSA9IHNjYWxlRmFjdG9yO1xuICAgIGJhY2tncm91bmRJbWFnZVsnc2NhbGVZJ10gPSBzY2FsZUZhY3RvcjtcblxuICAgIHRoaXMuc2V0Q2FudmFzU2l6ZSh3aWR0aCAqIHNjYWxlRmFjdG9yLCBoZWlnaHQgKiBzY2FsZUZhY3Rvcik7XG5cbiAgICBjb25zdCBvYmplY3RzID0ganNvblsnb2JqZWN0cyddO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzW2ldWydsZWZ0J10gKj0gb2JqZWN0U2NhbGU7XG4gICAgICBvYmplY3RzW2ldWyd0b3AnXSAqPSBvYmplY3RTY2FsZTtcbiAgICAgIG9iamVjdHNbaV1bJ3NjYWxlWCddICo9IG9iamVjdFNjYWxlO1xuICAgICAgb2JqZWN0c1tpXVsnc2NhbGVZJ10gKj0gb2JqZWN0U2NhbGU7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuc2VsZWN0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICB9XG5cbiAgcHVibGljIGV4cG9ydEltYWdlQXNEYXRhVVJMKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0SXRlbShpdGVtTnVtYmVyOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5zZXRBY3RpdmVPYmplY3QodGhpcy5jYW52YXMuaXRlbShpdGVtTnVtYmVyKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0SW5kZXhPZihhY3RpdmVPYmplY3QpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkuaW5kZXhPZihhY3RpdmVPYmplY3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3RMYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW1OdW1iZXIgPSB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBvYmplY3QgPSB0aGlzLmNhbnZhcy5pdGVtKGl0ZW1OdW1iZXIpO1xuICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChvYmplY3QpO1xuICAgIG9iamVjdC5lbnRlckVkaXRpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRTZWxlY3Rpb25SZWN0YW5nbGUoKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlID0gbmV3IGZhYnJpYy5SZWN0KHtcbiAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICBvcmlnaW5YOiAnbGVmdCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIHN0cm9rZTogJyNjY2MnLFxuICAgICAgc3Ryb2tlRGFzaEFycmF5OiBbMiwgMl0sXG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgd2lkdGg6IDEsXG4gICAgICBoZWlnaHQ6IDFcbiAgICB9KTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5jYW52YXMuYWRkKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgYWp1c3RDcm9wUmVjdGFuZ2xlRnJvbU1vdXNlKGV2ZW50OiBNb3VzZUV2ZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3QgeCA9IE1hdGgubWluKGV2ZW50LmxheWVyWCwgdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgeSA9IE1hdGgubWluKGV2ZW50LmxheWVyWSwgdGhpcy5tb3VzZVBvc2l0aW9uLnkpLFxuICAgICAgdyA9IE1hdGguYWJzKGV2ZW50LmxheWVyWCAtIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIGggPSBNYXRoLmFicyhldmVudC5sYXllclkgLSB0aGlzLm1vdXNlUG9zaXRpb24ueSk7XG5cbiAgICBpZiAoIXcgfHwgIWgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGVcbiAgICAgIC5zZXQoJ3RvcCcsIHkpXG4gICAgICAuc2V0KCdsZWZ0JywgeClcbiAgICAgIC5zZXQoJ3dpZHRoJywgdylcbiAgICAgIC5zZXQoJ2hlaWdodCcsIGgpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGVGcm9tTW91c2UoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNyb3BTdGFydGluZ1Bvc2l0aW9uID0geyB4OiB0aGlzLmNhbnZhcy5sZWZ0LCB5OiB0aGlzLmNhbnZhcy50b3AgfTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS5sZWZ0ID0gZXZlbnQubGF5ZXJYO1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS50b3AgPSBldmVudC5sYXllclk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnNldENvb3JkcygpO1xuXG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IGV2ZW50LmxheWVyWCwgeTogZXZlbnQubGF5ZXJZIH07XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUudmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuYnJpbmdUb0Zyb250KHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgY3JvcEltYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdDtcbiAgICBjb25zdCB0b3AgPSB0aGlzLmNyb3BSZWN0YW5nbGUudG9wO1xuXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmNyb3BSZWN0YW5nbGUud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5jcm9wUmVjdGFuZ2xlLmhlaWdodDtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZGl2Q2FudmFzQ29udGFpbmVyO1xuXG4gICAgY29uc3QgY2FudmFzV2lkdGggPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY29udGFpbmVyLmNsaWVudEhlaWdodDtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IHdpZHRoIC8gaGVpZ2h0O1xuICAgIGxldCBzY2FsZUZhY3RvcjtcblxuICAgIGlmIChjYW52YXNBc3BlY3QgPD0gaW1nQXNwZWN0KSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc1dpZHRoIC8gd2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzSGVpZ2h0IC8gaGVpZ2h0O1xuICAgIH1cblxuICAgIHRoaXMuc2V0Q2FudmFzU2l6ZSh3aWR0aCAqIHNjYWxlRmFjdG9yLCBoZWlnaHQgKiBzY2FsZUZhY3Rvcik7XG5cbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2Uuc2NhbGVYICo9IHNjYWxlRmFjdG9yO1xuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS5zY2FsZVkgKj0gc2NhbGVGYWN0b3I7XG5cbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UubGVmdCAtPSBsZWZ0O1xuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS5sZWZ0ICo9IHNjYWxlRmFjdG9yO1xuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS50b3AgLT0gdG9wIC0gc2NhbGVGYWN0b3I7XG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLnRvcCAqPSBzY2FsZUZhY3RvcjtcblxuICAgIHRoaXMubW92ZUFsbE9iamVjdHNJbkNhbnZhcygtMSAqIGxlZnQsIC0xICogdG9wLCBzY2FsZUZhY3Rvcik7XG5cbiAgICB0aGlzLmVuYWJsZVNsZWN0aW9uKCk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnZpc2libGUgPSBmYWxzZTtcblxuICAgIHRoaXMuY2FudmFzLnJlbW92ZSh0aGlzLmNyb3BSZWN0YW5nbGUpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gIH1cblxuICBwdWJsaWMgZW5hYmxlU2xlY3Rpb24oKSB7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBhanVzdENyb3BSZWN0YW5nbGUoZXZlbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07XG5cbiAgICBjb25zdCByZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgY29uc3QgeCA9IE1hdGgubWluKHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQsIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIHkgPSBNYXRoLm1pbih0b3VjaC5jbGllbnRZIC0gcmVjdC50b3AsIHRoaXMubW91c2VQb3NpdGlvbi55KSxcbiAgICAgIHcgPSBNYXRoLmFicyh0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgaCA9IE1hdGguYWJzKHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCAtIHRoaXMubW91c2VQb3NpdGlvbi55KTtcblxuICAgIGlmICghdyB8fCAhaCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZVxuICAgICAgLnNldCgnbGVmdCcsIHgpXG4gICAgICAuc2V0KCd0b3AnLCB5KVxuICAgICAgLnNldCgnd2lkdGgnLCB3KVxuICAgICAgLnNldCgnaGVpZ2h0JywgaCk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0U2VsZWN0aW5nQ3JvcFJlY3RhbmdsZShldmVudCk6IHZvaWQge1xuICAgIHRoaXMuY3JvcFN0YXJ0aW5nUG9zaXRpb24gPSB7IHg6IHRoaXMuY2FudmFzLmxlZnQsIHk6IHRoaXMuY2FudmFzLnRvcCB9O1xuXG4gICAgY29uc3QgdG91Y2ggPSBldmVudC50b3VjaGVzWzBdO1xuICAgIGNvbnN0IHJlY3QgPSBldmVudC50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnRvcCA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUuc2V0Q29vcmRzKCk7XG5cbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7IHg6IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQsIHk6IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCB9O1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnZpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzLmJyaW5nVG9Gcm9udCh0aGlzLmNyb3BSZWN0YW5nbGUpO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGVTZWxlY3Rpb24oKSB7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG1vdmVBbGxPYmplY3RzSW5DYW52YXMoeDogbnVtYmVyLCB5OiBudW1iZXIsIHNjYWxlRmFjdG9yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBvYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpO1xuICAgIGZvciAoY29uc3Qgb2JqIG9mIG9iamVjdHMpIHtcbiAgICAgIG9iai5sZWZ0ICs9IHg7XG4gICAgICBvYmoubGVmdCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zY2FsZVggKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmoudG9wICs9IHk7XG4gICAgICBvYmouc2NhbGVZICo9IHNjYWxlRmFjdG9yO1xuICAgICAgb2JqLnRvcCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zZXRDb29yZHMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ3JvdXBTZWxlY3RlZE9iamVjdHMoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBjb25zdCBvYmplY3RzID0gW107XG5cbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgb2JqZWN0cy5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbGV0ZVNlbGVjdGVkT2JqZWN0cygpO1xuXG4gICAgICBjb25zdCBncm91cCA9IG5ldyBmYWJyaWMuR3JvdXAob2JqZWN0cyk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGQoZ3JvdXApO1xuICAgICAgZ3JvdXAuc2V0Q29vcmRzKCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChncm91cCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXN0UGFuUG9zaXRpb24oZXZlbnQpIHtcbiAgICB0aGlzLmxhc3RQYW5Qb3NpdGlvbiA9IG5ldyBmYWJyaWMuUG9pbnQoZXZlbnQudG91Y2hlc1swXS5jbGllbnRYLCBldmVudC50b3VjaGVzWzBdLmNsaWVudFkpO1xuICB9XG5cbiAgcHVibGljIHBhbkNhbnZhcyhldmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGRlbHRhID0gbmV3IGZhYnJpYy5Qb2ludChcbiAgICAgIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMubGFzdFBhblBvc2l0aW9uLngsXG4gICAgICBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmxhc3RQYW5Qb3NpdGlvbi55XG4gICAgKTtcblxuICAgIHRoaXMuY2FudmFzLnJlbGF0aXZlUGFuKGRlbHRhKTtcbiAgICB0aGlzLnByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLnNldExhc3RQYW5Qb3NpdGlvbihldmVudCk7XG4gIH1cblxuICBwcml2YXRlIHByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCkge1xuICAgIGNvbnN0IGNhbnZhc1ZpZXdQb3J0ID0gdGhpcy5jYW52YXMudmlld3BvcnRUcmFuc2Zvcm07XG5cbiAgICBjb25zdCBib3R0b21FbmRQb2ludCA9IHRoaXMuY2FudmFzLmhlaWdodCAqIChjYW52YXNWaWV3UG9ydFswXSAtIDEpO1xuICAgIGlmIChjYW52YXNWaWV3UG9ydFs1XSA+PSAwIHx8IC1ib3R0b21FbmRQb2ludCA+IGNhbnZhc1ZpZXdQb3J0WzVdKSB7XG4gICAgICAgIGNhbnZhc1ZpZXdQb3J0WzVdID0gKGNhbnZhc1ZpZXdQb3J0WzVdID49IDApID8gMCA6IC1ib3R0b21FbmRQb2ludDtcbiAgICB9XG5cbiAgICBjb25zdCByaWdodEVuZFBvaW50ID0gdGhpcy5jYW52YXMud2lkdGggKiAoY2FudmFzVmlld1BvcnRbMF0gLSAxKTtcbiAgICBpZiAoY2FudmFzVmlld1BvcnRbNF0gPj0gMCB8fCAtcmlnaHRFbmRQb2ludCA+IGNhbnZhc1ZpZXdQb3J0WzRdKSB7XG4gICAgICAgIGNhbnZhc1ZpZXdQb3J0WzRdID0gKGNhbnZhc1ZpZXdQb3J0WzRdID49IDApID8gMCA6IC1yaWdodEVuZFBvaW50O1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyB6b29tKGV2ZW50KTogdm9pZCB7XG4gICAgaWYgKE1hdGguYWJzKGV2ZW50Lm92ZXJhbGxWZWxvY2l0eSkgPiAwLjAwNSkge1xuICAgICAgY29uc3QgcG9pbnQgPSBuZXcgZmFicmljLlBvaW50KGV2ZW50LmNlbnRlci54LCBldmVudC5jZW50ZXIueSk7XG5cbiAgICAgIGxldCB6b29tID0gdGhpcy5jYW52YXMuZ2V0Wm9vbSgpO1xuICAgICAgem9vbSA9IHpvb20gKyAoZXZlbnQuc2NhbGUgLSB6b29tKSAvIDIwO1xuXG5cbiAgICAgIGlmICh6b29tIDwgMSkge1xuICAgICAgICB6b29tID0gMTtcbiAgICAgICAgdGhpcy5jYW52YXMuem9vbVRvUG9pbnQobmV3IGZhYnJpYy5Qb2ludCgwLCAwKSwgem9vbSk7XG4gICAgICAgIHRoaXMuY2FudmFzLmFic29sdXRlUGFuKG5ldyBmYWJyaWMuUG9pbnQoMCwgMCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHpvb20gPiAxMCkge1xuICAgICAgICAgIHpvb20gPSAxMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbnZhcy56b29tVG9Qb2ludChwb2ludCwgem9vbSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0RnJlZURyYXdpbmdCcnVzaFdpZHRoRnJvbVpvb20oem9vbSk7XG4gICAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldENhbnZhc1NpemUod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICB0aGlzLmNhbnZhcy5zZXRXaWR0aCh3aWR0aCk7XG4gICAgdGhpcy5jYW52YXMuc2V0SGVpZ2h0KGhlaWdodCk7XG4gIH1cblxuICBwdWJsaWMgcmVzZXRab29tKCkge1xuICAgIHRoaXMuY2FudmFzLnpvb21Ub1BvaW50KG5ldyBmYWJyaWMuUG9pbnQoMCwgMCksIDEpO1xuICAgIHRoaXMuY2FudmFzLmFic29sdXRlUGFuKG5ldyBmYWJyaWMuUG9pbnQoMCwgMCkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIEhvc3RMaXN0ZW5lciwgT3V0cHV0LCBPbkNoYW5nZXMsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZm9yRWFjaCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlci9zcmMvdXRpbHMvY29sbGVjdGlvbic7XG5pbXBvcnQgeyBDYW52YXNNYW5hZ2VyU2VydmljZSB9IGZyb20gJy4vLi4vc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZSB9IGZyb20gJy4vLi4vY29uc3RhbnRzL2F2YWlsYWJsZS1nZW9tZXRyaWMtc2hhcGVzJztcbmltcG9ydCB7IEtFWV9DT0RFIH0gZnJvbSAnLi8uLi9jb25zdGFudHMva2V5LWNvZGUnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcblxuY29uc3QgQmxhY2sgPSAnIzAwMDAwMCc7XG5jb25zdCBUcmFuc3BhcmVudCA9ICd0cmFuc3BhcmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi13ZWItc2tldGNoLXRvb2wnLFxuICB0ZW1wbGF0ZTogYDxkaXZcbiAgICBjbGFzcz1cImRpdi1jYW52YXMtY29udGFpbmVyXCJcbiAgICAobW91c2Vkb3duKT1cIm1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAobW91c2Vtb3ZlKT1cIm1vdXNlTW92ZSgkZXZlbnQpXCJcbiAgICAobW91c2V1cCk9XCJtb3VzZVVwKCRldmVudClcIlxuPlxuICAgIDxjYW52YXMgaWQ9XCJjYW52YXNcIj48L2NhbnZhcz5cbjwvZGl2PlxuXG48bWF0LXRvb2xiYXIgY2xhc3M9XCJlZGl0LXRvb2xiYXJcIj5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgY2xhc3M9XCJ0b29sLWJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJhZGRTaGFwZSgnUmVjdGFuZ2xlJylcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiaXNEcmF3aW5nXCJcbiAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXNxdWFyZVwiPjwvaT5cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICBjbGFzcz1cInRvb2wtYnV0dG9uXCJcbiAgICAgICAgKGNsaWNrKT1cImFkZFNoYXBlKCdDaXJjbGUnKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0RyYXdpbmdcIlxuICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY2lyY2xlXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiYWRkU2hhcGUoJ1RyaWFuZ2xlJylcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiaXNEcmF3aW5nXCJcbiAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNhcmV0LXVwXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiYWRkU2hhcGUoJ0xpbmUnKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0RyYXdpbmdcIlxuICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbWludXNcIj48L2k+XG4gICAgPC9idXR0b24+XG5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgY2xhc3M9XCJ0b29sLWJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJhZGRUZXh0KClcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiaXNEcmF3aW5nXCJcbiAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWZvbnRcIj48L2k+XG4gICAgPC9idXR0b24+XG5cbiAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgY2xhc3M9XCJ0b29sLWJ1dHRvblwiXG4gICAgICAgIGNvbG9yPVwiYWNjZW50XCJcbiAgICAgICAgKGNsaWNrKT1cImNyb3AoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0RyYXdpbmdcIlxuICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY3JvcFwiPjwvaT5cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAoY2xpY2spPVwiZHJhdygpXCJcbiAgICAgICAgY2xhc3M9XCJ0b29sLWJ1dHRvblwiXG4gICAgPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1wZW5jaWwtYWx0XCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiZ3JvdXAoKVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0RyYXdpbmdcIlxuICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtb2JqZWN0LWdyb3VwXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgICAgICBjb2xvcj1cImFjY2VudFwiXG4gICAgICAgIChjbGljayk9XCJicmluZ0Zvd2FyZCgpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImlzRHJhd2luZ1wiXG4gICAgPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS11cFwiPjwvaT5cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICBjbGFzcz1cInRvb2wtYnV0dG9uXCJcbiAgICAgICAgY29sb3I9XCJhY2NlbnRcIlxuICAgICAgICAoY2xpY2spPVwic2VuZFRvQmFjaygpXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImlzRHJhd2luZ1wiXG4gICAgPlxuICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1hbmdsZS1kb3duXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiZGVsZXRlU2VsZWN0aW9uKClcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiaXNEcmF3aW5nXCJcbiAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXRyYXNoXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgIChjbGljayk9XCJzYXZlSW1hZ2UoKVwiXG4gICAgICAgIGNsYXNzPVwidG9vbC1idXR0b25cIlxuICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtZG93bmxvYWRcIj48L2k+XG4gICAgPC9idXR0b24+XG5cbiAgICA8aW5wdXRcbiAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICBjbGFzcz1cImNvbG9yUGlja2VyXCJcbiAgICAgICAgWyhjb2xvclBpY2tlcildPVwic3Ryb2tlQ29sb3JcIlxuICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJzdHJva2VDb2xvclwiXG4gICAgICAgIChjb2xvclBpY2tlckNoYW5nZSk9XCJjaGFuZ2VTdHJva2VDb2xvcigpXCJcbiAgICA+XG48L21hdC10b29sYmFyPlxuYCxcbiAgc3R5bGVzOiBbYC5kaXYtY2FudmFzLWNvbnRhaW5lcnt0ZXh0LWFsaWduOmNlbnRlcjttYXJnaW46MCBhdXRvO3BhZGRpbmc6MDtoZWlnaHQ6OTAlIWltcG9ydGFudDt3aWR0aDoxMDAlIWltcG9ydGFudDstby1vYmplY3QtZml0OmNvbnRhaW47b2JqZWN0LWZpdDpjb250YWlufS5lZGl0LXRvb2xiYXJ7aGVpZ2h0OjclO2p1c3RpZnktY29udGVudDpjZW50ZXJ9LnRvb2xiYXItYnV0dG9ue2ZvbnQtZmFtaWx5OkZvbnRBd2Vzb21lO2Rpc3BsYXk6aW5saW5lLWJsb2NrO3dpZHRoOjEuNWVtO21pbi13aWR0aDowfS5tYXQtYnV0dG9uLnRvb2wtYnV0dG9ue21pbi13aWR0aDo0MHB4IWltcG9ydGFudDt3aWR0aDo1MHB4O21pbi1oZWlnaHQ6NDBweCFpbXBvcnRhbnQ7aGVpZ2h0OjQwcHg7bWFyZ2luLXJpZ2h0OjEwcHh9LmNvbG9yUGlja2Vye3dpZHRoOjQwcHg7aGVpZ2h0OjM2cHg7bWFyZ2luLXRvcDozcHg7Y29sb3I6dHJhbnNwYXJlbnR9aXtmb250LXNpemU6MS41ZW07Y29sb3I6IzAwMH1gXSxcbiAgcHJvdmlkZXJzOiBbQ2FudmFzTWFuYWdlclNlcnZpY2VdXG59KVxuXG5leHBvcnQgY2xhc3MgV2ViU2tldGNoVG9vbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzIHtcbiAgcHVibGljIGZpbGxDb2xvcjogc3RyaW5nO1xuICBwdWJsaWMgc3Ryb2tlQ29sb3I6IHN0cmluZztcblxuICBwdWJsaWMgYXZhaWxhYmxlR2VvbWV0cmljU2hhcGVzID0gQXZhaWxhYmxlR2VvbWV0cmljU2hhcGU7XG4gIHB1YmxpYyBpc0RyYXdpbmc6IGJvb2xlYW47XG4gIHB1YmxpYyBpc0Nyb3BwaW5nOiBib29sZWFuO1xuICBwdWJsaWMgaXNMYXN0SW1hZ2U6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBpc0xvYWRlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwcmV2aW91c0ltYWdlRGF0YTogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHB1YmxpYyBpbWFnZURhdGE6IHN0cmluZztcbiAgQElucHV0KCkgcHVibGljIGxvYWRlZEpzb246IHN0cmluZztcblxuICBAT3V0cHV0KCkgcHVibGljIGNhbnZhcyA9IG5ldyBFdmVudEVtaXR0ZXI8ZmFicmljLkNhbnZhcz4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNhbnZhc01hbmFnZXJTZXJ2aWNlOiBDYW52YXNNYW5hZ2VyU2VydmljZSkge1xuICAgIHRoaXMuc3Ryb2tlQ29sb3IgPSBCbGFjaztcbiAgICB0aGlzLmZpbGxDb2xvciA9IFRyYW5zcGFyZW50O1xuICAgIHRoaXMuaXNDcm9wcGluZyA9IGZhbHNlO1xuICAgIHRoaXMuaXNMb2FkZWQgPSBmYWxzZTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuc2V0Q2FudmFzKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICAgIHRoaXMuc2V0Q2FudmFzKCk7XG4gIH1cblxuICBwcml2YXRlIHNldENhbnZhcygpIHtcbiAgICBpZiAodGhpcy5pbWFnZURhdGEpIHtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW1wdHlDYW52YXMoKTtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UucmVzZXRab29tKCk7XG4gICAgICBpZiAodGhpcy5sb2FkZWRKc29uID09IG51bGwgfHwgdGhpcy5sb2FkZWRKc29uLmxlbmd0aCA8IDEwKSB7XG4gICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0QmFja2dyb3VuZEZyb21VUkwodGhpcy5pbWFnZURhdGEpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmxvYWRmcm9tSnNvbihKU09OLnBhcnNlKHRoaXMubG9hZGVkSnNvbikpO1xuICAgICAgfVxuICAgICAgdGhpcy5pc0xvYWRlZCA9IHRydWU7XG4gICAgICB0aGlzLnByZXZpb3VzSW1hZ2VEYXRhID0gdGhpcy5pbWFnZURhdGE7XG4gICAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYWRkVGV4dCgpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZFRleHQodGhpcy5zdHJva2VDb2xvciwgJyAnKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRTaGFwZShzaGFwZTogc3RyaW5nKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRHZW9tZXRyaWNTaGFwZShcbiAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlW3NoYXBlXVxuICAgICk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlU3Ryb2tlQ29sb3IoKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5jaGFuZ2VTZWxlY3RlZE9iamVjdHNTdHJva2VDb2xvcihcbiAgICAgIHRoaXMuc3Ryb2tlQ29sb3JcbiAgICApO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKHRoaXMuc3Ryb2tlQ29sb3IpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGJyaW5nRm93YXJkKCkge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYnJpbmdTZWxlY3RlZE9iamVjdHNUb0Zyb250KCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgc2VuZFRvQmFjaygpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNlbmRTZWxlY3RlZE9iamVjdHNUb0JhY2soKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBkcmF3KCkge1xuICAgIHRoaXMuaXNEcmF3aW5nID0gIXRoaXMuaXNEcmF3aW5nO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UudG9nZ2xlRnJlZURyYXdpbmcoKTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEZyZWVEcmF3aW5nQnJ1c2hDb2xvcih0aGlzLnN0cm9rZUNvbG9yKTtcbiAgfVxuXG4gIHB1YmxpYyBzYXZlSW1hZ2UoKSB7XG4gICAgY29uc3QgZGF0YVVSTCA9IHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZXhwb3J0SW1hZ2VBc0RhdGFVUkwoKTtcblxuICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgbGluay5kb3dubG9hZCA9ICdpbWFnZSc7XG5cbiAgICBsaW5rLmhyZWYgPSBkYXRhVVJMO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gIH1cblxuICBwdWJsaWMgY3JvcCgpIHtcbiAgICB0aGlzLmlzQ3JvcHBpbmcgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZGlzYWJsZVNlbGVjdGlvbigpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkU2VsZWN0aW9uUmVjdGFuZ2xlKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5dXAnLCBbJyRldmVudCddKVxuICBrZXlFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5rZXlDb2RlID09PSBLRVlfQ09ERS5ERUxFVEUpIHtcbiAgICAgIHRoaXMuZGVsZXRlU2VsZWN0aW9uKCk7XG4gICAgfVxuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGRlbGV0ZVNlbGVjdGlvbigpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmRlbGV0ZVNlbGVjdGVkT2JqZWN0cygpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIG1vdXNlVXAoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmNyb3BJbWFnZSgpO1xuICAgICAgdGhpcy5pc0Nyb3BwaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIG1vdXNlTW92ZShldmVudDogTW91c2VFdmVudCkge1xuICAgIGlmICh0aGlzLmlzQ3JvcHBpbmcpIHtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWp1c3RDcm9wUmVjdGFuZ2xlRnJvbU1vdXNlKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgbW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKHRoaXMuaXNDcm9wcGluZykge1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5zdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGVGcm9tTW91c2UoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBncm91cCgpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmdyb3VwU2VsZWN0ZWRPYmplY3RzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgZW1pdENhbnZhcygpIHtcbiAgICB0aGlzLmNhbnZhcy5lbWl0KHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuY2FudmFzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNYXRUb29sYmFyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbGJhcic7XG5pbXBvcnQgeyBDb2xvclBpY2tlck1vZHVsZSB9IGZyb20gJ25neC1jb2xvci1waWNrZXInO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwnO1xuXG5pbXBvcnQgeyBXZWJTa2V0Y2hUb29sQ29tcG9uZW50IH0gZnJvbSAnLi93ZWItY29tcG9uZW50L3dlYi1za2V0Y2gtdG9vbC5jb21wb25lbnQnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBDb2xvclBpY2tlck1vZHVsZSwgTWF0QnV0dG9uTW9kdWxlLCBNYXRUb29sYmFyTW9kdWxlXSxcbiAgZGVjbGFyYXRpb25zOiBbV2ViU2tldGNoVG9vbENvbXBvbmVudF0sXG4gIGV4cG9ydHM6IFtXZWJTa2V0Y2hUb29sQ29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBXZWJTa2V0Y2hUb29sTW9kdWxlIHt9XG4iXSwibmFtZXMiOlsidHNsaWJfMS5fX3ZhbHVlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsQUFBTyxxQkFBTSxVQUFVLEdBQUc7SUFDeEIsS0FBSyxFQUFFLEdBQUc7SUFDVixNQUFNLEVBQUUsR0FBRztJQUNYLElBQUksRUFBRSxFQUFFO0lBQ1IsR0FBRyxFQUFFLEVBQUU7SUFDUCxNQUFNLEVBQUUsR0FBRztJQUNYLE1BQU0sRUFBRSxFQUFFO0lBQ1YscUJBQXFCLEVBQUUsRUFBRTtJQUN6QixVQUFVLEVBQUUsRUFBRTtDQUNmLENBQUM7Ozs7Ozs7SUNpQkE7UUFDRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBQyxDQUFDO0tBQzFDO0lBRUQsc0JBQUksK0NBQWE7Ozs7UUFBakI7WUFDRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDakM7OztPQUFBO0lBRUQsc0JBQUksdURBQXFCOzs7O1FBQXpCO1lBQ0UsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQztTQUNwQzs7O09BQUE7SUFFRCxzQkFBSSw4Q0FBWTs7OztRQUFoQjtZQUNFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUN0Qzs7O09BQUE7SUFF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 |
\ | No newline at end of file |