UNPKG

147 kBJavaScriptView Raw
1import { Injectable, Component, Input, Output, EventEmitter, ViewChild, NgModule } from '@angular/core';
2import { fabric } from 'fabric';
3import { ActionSheetController, IonicModule } from 'ionic-angular';
4import { Gesture } from 'ionic-angular/gestures/gesture';
5import { TranslateService } from '@ngx-translate/core';
6import { CommonModule } from '@angular/common';
7
8/**
9 * @fileoverview added by tsickle
10 * @suppress {checkTypes} checked by tsc
11 */
12/** @enum {number} */
13const AvailableGeometricShape = {
14 "Rectangle": 0,
15 "Circle": 1,
16 "Triangle": 2,
17 "Line": 3,
18 "Cross": 4,
19};
20AvailableGeometricShape[AvailableGeometricShape["Rectangle"]] = "Rectangle";
21AvailableGeometricShape[AvailableGeometricShape["Circle"]] = "Circle";
22AvailableGeometricShape[AvailableGeometricShape["Triangle"]] = "Triangle";
23AvailableGeometricShape[AvailableGeometricShape["Line"]] = "Line";
24AvailableGeometricShape[AvailableGeometricShape["Cross"]] = "Cross";
25
26/**
27 * @fileoverview added by tsickle
28 * @suppress {checkTypes} checked by tsc
29 */
30const /** @type {?} */ SHAPE_DATA = {
31 width: 200,
32 height: 200,
33 left: 50,
34 top: 50,
35 radius: 100,
36 stroke: 10,
37 freeDrawingBrushWidth: 10,
38 cornerSize: 20
39};
40
41/**
42 * @fileoverview added by tsickle
43 * @suppress {checkTypes} checked by tsc
44 */
45class CanvasManagerService {
46 constructor() {
47 this.emptyCanvas();
48 this.mousePosition = { x: 0, y: 0 };
49 this.cropStartingPosition = { x: 0, y: 0 };
50 this.canvas.freeDrawingBrush.width = SHAPE_DATA.freeDrawingBrushWidth;
51 }
52 /**
53 * @return {?}
54 */
55 get backgroundImage() {
56 return this.canvas;
57 }
58 /**
59 * @return {?}
60 */
61 get canvasObjects() {
62 return this.canvas.getObjects();
63 }
64 /**
65 * @return {?}
66 */
67 get canvasBackgroundImage() {
68 return this.canvas.backgroundImage;
69 }
70 /**
71 * @return {?}
72 */
73 get activeObject() {
74 return this.canvas.getActiveObject();
75 }
76 /**
77 * @return {?}
78 */
79 get activeGroup() {
80 return this.canvas.getActiveObjects();
81 }
82 /**
83 * @return {?}
84 */
85 emptyCanvas() {
86 if (this.canvas) {
87 this.canvas.dispose();
88 }
89 this.canvas = new fabric.Canvas('canvas');
90 this.canvas.clear();
91 this.canvas.remove(this.canvas.getObjects());
92 }
93 /**
94 * @param {?=} backgroundImageURL
95 * @return {?}
96 */
97 loadNewImage(backgroundImageURL) {
98 this.emptyCanvas();
99 if (backgroundImageURL) {
100 this.setBackgroundFromURL(backgroundImageURL);
101 }
102 }
103 /**
104 * @return {?}
105 */
106 renderCanvas() {
107 this.markSelectedObjectsDirty();
108 this.canvas.renderAll();
109 }
110 /**
111 * @param {?} strokeColor
112 * @param {?} fillColor
113 * @param {?} shape
114 * @return {?}
115 */
116 addGeometricShape(strokeColor, fillColor, shape) {
117 switch (shape) {
118 case AvailableGeometricShape.Rectangle:
119 this.addRectangle(strokeColor, fillColor);
120 break;
121 case AvailableGeometricShape.Circle:
122 this.addCircle(strokeColor, fillColor);
123 break;
124 case AvailableGeometricShape.Triangle:
125 this.addTriangle(strokeColor, fillColor);
126 break;
127 case AvailableGeometricShape.Line:
128 this.addHorizontalLine(strokeColor, fillColor);
129 break;
130 case AvailableGeometricShape.Cross:
131 this.addCross(strokeColor, fillColor);
132 break;
133 }
134 }
135 /**
136 * @param {?} strokeColor
137 * @param {?} fillColor
138 * @return {?}
139 */
140 addRectangle(strokeColor, fillColor) {
141 this.canvas.add(new fabric.Rect({
142 width: SHAPE_DATA.width,
143 height: SHAPE_DATA.height,
144 left: SHAPE_DATA.left,
145 top: SHAPE_DATA.top,
146 fill: fillColor,
147 stroke: strokeColor,
148 strokeWidth: SHAPE_DATA.stroke,
149 cornerSize: SHAPE_DATA.cornerSize
150 }));
151 }
152 /**
153 * @param {?} strokeColor
154 * @param {?} fillColor
155 * @return {?}
156 */
157 addCircle(strokeColor, fillColor) {
158 this.canvas.add(new fabric.Circle({
159 left: SHAPE_DATA.left,
160 top: SHAPE_DATA.top,
161 radius: SHAPE_DATA.radius,
162 stroke: strokeColor,
163 strokeWidth: SHAPE_DATA.stroke,
164 fill: fillColor,
165 cornerSize: SHAPE_DATA.cornerSize
166 }));
167 }
168 /**
169 * @param {?} strokeColor
170 * @param {?} fillColor
171 * @return {?}
172 */
173 addTriangle(strokeColor, fillColor) {
174 this.canvas.add(new fabric.Triangle({
175 width: SHAPE_DATA.width,
176 height: SHAPE_DATA.height,
177 left: SHAPE_DATA.left,
178 top: SHAPE_DATA.top,
179 fill: fillColor,
180 stroke: strokeColor,
181 strokeWidth: SHAPE_DATA.stroke,
182 cornerSize: SHAPE_DATA.cornerSize
183 }));
184 }
185 /**
186 * @param {?} strokeColor
187 * @param {?} fillColor
188 * @return {?}
189 */
190 addHorizontalLine(strokeColor, fillColor) {
191 this.canvas.add(this.createHorizontalLine(strokeColor));
192 }
193 /**
194 * @param {?} strokeColor
195 * @return {?}
196 */
197 createHorizontalLine(strokeColor) {
198 const /** @type {?} */ line = new fabric.Line([100, 150, 200, 150], {
199 left: 50,
200 top: 100,
201 stroke: strokeColor,
202 strokeWidth: 5,
203 cornerSize: SHAPE_DATA.cornerSize
204 });
205 line.setControlsVisibility({
206 bl: false,
207 br: false,
208 tl: false,
209 tr: false,
210 mt: false,
211 mb: false
212 });
213 return line;
214 }
215 /**
216 * @param {?} strokeColor
217 * @return {?}
218 */
219 createVerticalLine(strokeColor) {
220 const /** @type {?} */ line = new fabric.Line([150, 100, 150, 200], {
221 left: 100,
222 top: 50,
223 stroke: strokeColor,
224 strokeWidth: 5,
225 cornerSize: SHAPE_DATA.cornerSize
226 });
227 line.setControlsVisibility({
228 bl: false,
229 br: false,
230 tl: false,
231 tr: false,
232 ml: false,
233 mr: false
234 });
235 return line;
236 }
237 /**
238 * @param {?} strokeColor
239 * @param {?} fillColor
240 * @return {?}
241 */
242 addCross(strokeColor, fillColor) {
243 const /** @type {?} */ horizontalLine = this.createHorizontalLine(strokeColor);
244 const /** @type {?} */ verticalLine = this.createVerticalLine(strokeColor);
245 this.canvas.add(horizontalLine);
246 this.canvas.add(verticalLine);
247 }
248 /**
249 * @return {?}
250 */
251 toggleFreeDrawing() {
252 this.canvas.isDrawingMode = !this.canvas.isDrawingMode;
253 }
254 /**
255 * @param {?} color
256 * @return {?}
257 */
258 setFreeDrawingBrushColor(color) {
259 this.canvas.freeDrawingBrush.color = color;
260 }
261 /**
262 * @param {?} zoom
263 * @return {?}
264 */
265 setFreeDrawingBrushWidthFromZoom(zoom) {
266 this.canvas.freeDrawingBrush.width = SHAPE_DATA.freeDrawingBrushWidth * (1 / zoom);
267 }
268 /**
269 * @param {?} color
270 * @param {?} inputText
271 * @return {?}
272 */
273 addText(color, inputText) {
274 const /** @type {?} */ text = new fabric.IText('text', {
275 fontFamily: 'arial black',
276 fontStyle: 'bold',
277 left: SHAPE_DATA.left,
278 top: SHAPE_DATA.top,
279 cornerSize: SHAPE_DATA.cornerSize
280 });
281 text.setColor(color);
282 this.canvas.add(text);
283 }
284 /**
285 * @param {?} imageURL
286 * @return {?}
287 */
288 addImage(imageURL) {
289 return new Promise((resolve, reject) => {
290 const /** @type {?} */ canvas = this.canvas;
291 const /** @type {?} */ image = new Image();
292 image.onload = function (img) {
293 const /** @type {?} */ fabricImage = new fabric.Image(image, {
294 angle: 0,
295 width: image.width,
296 height: image.height,
297 left: SHAPE_DATA.left,
298 top: SHAPE_DATA.top,
299 scaleX: 1,
300 scaleY: 1,
301 cornerSize: SHAPE_DATA.cornerSize
302 });
303 canvas.add(fabricImage);
304 resolve();
305 };
306 image.src = imageURL;
307 });
308 }
309 /**
310 * @param {?} backgroundImageURL
311 * @return {?}
312 */
313 setBackgroundFromURL(backgroundImageURL) {
314 const /** @type {?} */ canvas = this.canvas;
315 const /** @type {?} */ resize = this.resizeCanvasAndComputeScaleFactor;
316 return new Promise((resolve, reject) => {
317 if (backgroundImageURL == null) {
318 return reject();
319 }
320 const /** @type {?} */ image = new Image();
321 image.onload = function () {
322 const /** @type {?} */ f_img = new fabric.Image(image, {});
323 const /** @type {?} */ scaleData = resize(f_img, canvas);
324 canvas.setBackgroundImage(f_img, canvas.renderAll.bind(canvas), {
325 scaleX: scaleData.scaleFactor,
326 scaleY: scaleData.scaleFactor
327 });
328 canvas.renderAll();
329 resolve();
330 };
331 image.src = backgroundImageURL;
332 });
333 }
334 /**
335 * @param {?} f_img
336 * @param {?} canvas
337 * @return {?}
338 */
339 resizeCanvasAndComputeScaleFactor(f_img, canvas) {
340 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
341 canvas.setWidth(container.clientWidth);
342 canvas.setHeight(container.clientHeight);
343 const /** @type {?} */ canvasWidth = canvas.getWidth();
344 const /** @type {?} */ canvasHeight = canvas.getHeight();
345 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
346 const /** @type {?} */ imgAspect = f_img.width / f_img.height;
347 let /** @type {?} */ left, /** @type {?} */ top, /** @type {?} */ scaleFactor;
348 if (canvasAspect <= imgAspect) {
349 scaleFactor = canvasWidth / f_img.width;
350 left = 0;
351 top = -(f_img.height * scaleFactor - canvasHeight) / 2;
352 }
353 else {
354 scaleFactor = canvasHeight / f_img.height;
355 top = 0;
356 left = -(f_img.width * scaleFactor - canvasWidth) / 2;
357 }
358 return { scaleFactor: scaleFactor, left: left, top: top };
359 }
360 /**
361 * @return {?}
362 */
363 onOrientationChange() {
364 this.mousePosition = { x: this.canvas.getWidth, y: this.canvas.getHeight };
365 this.cropImage();
366 }
367 /**
368 * @param {?} color
369 * @return {?}
370 */
371 changeSelectedObjectsFillColor(color) {
372 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
373 if (activeObjects) {
374 for (const /** @type {?} */ object of activeObjects) {
375 object.setColor(color);
376 this.canvas.renderAll();
377 }
378 }
379 }
380 /**
381 * @param {?} color
382 * @return {?}
383 */
384 changeSelectedObjectsStrokeColor(color) {
385 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
386 if (activeObjects) {
387 for (const /** @type {?} */ object of activeObjects) {
388 if (object.type === 'i-text') {
389 object.setColor(color);
390 }
391 else {
392 object.stroke = color;
393 object.set('dirty', true);
394 }
395 }
396 this.canvas.renderAll();
397 }
398 }
399 /**
400 * @return {?}
401 */
402 deleteSelectedObjects() {
403 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
404 if (activeObjects) {
405 for (const /** @type {?} */ object of activeObjects) {
406 this.canvas.remove(object);
407 }
408 this.canvas.discardActiveObject();
409 this.canvas.renderAll();
410 }
411 }
412 /**
413 * @return {?}
414 */
415 bringSelectedObjectsToFront() {
416 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
417 if (activeObjects) {
418 for (const /** @type {?} */ object of activeObjects) {
419 this.canvas.bringToFront(object);
420 }
421 }
422 }
423 /**
424 * @return {?}
425 */
426 sendSelectedObjectsToBack() {
427 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
428 if (activeObjects) {
429 for (const /** @type {?} */ object of activeObjects) {
430 this.canvas.sendToBack(object);
431 }
432 }
433 }
434 /**
435 * @return {?}
436 */
437 jsonFromCanvas() {
438 return this.canvas.toJSON();
439 }
440 /**
441 * @param {?} json
442 * @return {?}
443 */
444 loadfromJson(json) {
445 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
446 this.canvas.setWidth(container.clientWidth);
447 this.canvas.setHeight(container.clientHeight);
448 return new Promise((resolve, reject) => {
449 this.adjustCanvas(json);
450 this.canvas.loadFromJSON(json, this.canvas.renderAll.bind(this.canvas));
451 resolve();
452 });
453 }
454 /**
455 * @param {?} json
456 * @return {?}
457 */
458 adjustCanvas(json) {
459 const /** @type {?} */ backgroundImage = json['backgroundImage'];
460 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
461 const /** @type {?} */ width = backgroundImage['width'];
462 const /** @type {?} */ height = backgroundImage['height'];
463 const /** @type {?} */ canvasWidth = container.clientWidth;
464 const /** @type {?} */ canvasHeight = container.clientHeight;
465 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
466 const /** @type {?} */ imgAspect = width / height;
467 let /** @type {?} */ scaleFactor;
468 if (canvasAspect <= imgAspect) {
469 scaleFactor = canvasWidth / width;
470 }
471 else {
472 scaleFactor = canvasHeight / height;
473 }
474 const /** @type {?} */ objectScale = scaleFactor / backgroundImage['scaleX'];
475 backgroundImage['scaleX'] = scaleFactor;
476 backgroundImage['scaleY'] = scaleFactor;
477 this.canvas.setWidth(width * scaleFactor);
478 this.canvas.setHeight(height * scaleFactor);
479 const /** @type {?} */ objects = json['objects'];
480 for (let /** @type {?} */ i = 0; i < objects.length; i++) {
481 objects[i]['left'] *= objectScale;
482 objects[i]['top'] *= objectScale;
483 objects[i]['scaleX'] *= objectScale;
484 objects[i]['scaleY'] *= objectScale;
485 }
486 this.canvas.selectable = true;
487 this.canvas.selection = true;
488 this.canvas.renderAll();
489 }
490 /**
491 * @return {?}
492 */
493 exportImageAsDataURL() {
494 return this.canvas.toDataURL('image/png');
495 }
496 /**
497 * @param {?} itemNumber
498 * @return {?}
499 */
500 selectItem(itemNumber) {
501 this.canvas.setActiveObject(this.canvas.item(itemNumber));
502 }
503 /**
504 * @param {?} activeObject
505 * @return {?}
506 */
507 getIndexOf(activeObject) {
508 return this.canvas.getObjects().indexOf(activeObject);
509 }
510 /**
511 * @return {?}
512 */
513 selectLastObject() {
514 const /** @type {?} */ itemNumber = this.canvas.getObjects().length - 1;
515 const /** @type {?} */ object = this.canvas.item(itemNumber);
516 this.canvas.setActiveObject(object);
517 object.enterEditing();
518 }
519 /**
520 * @return {?}
521 */
522 markSelectedObjectsDirty() {
523 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
524 if (activeObjects) {
525 for (const /** @type {?} */ object of activeObjects) {
526 object.set('dirty', true);
527 }
528 }
529 }
530 /**
531 * @return {?}
532 */
533 addSelectionRectangle() {
534 this.cropRectangle = new fabric.Rect({
535 fill: 'transparent',
536 originX: 'left',
537 originY: 'top',
538 stroke: '#ccc',
539 strokeDashArray: [2, 2],
540 opacity: 1,
541 width: 1,
542 height: 1
543 });
544 this.cropRectangle.visible = false;
545 this.canvas.add(this.cropRectangle);
546 }
547 /**
548 * @param {?} event
549 * @return {?}
550 */
551 ajustCropRectangleFromMouse(event) {
552 const /** @type {?} */ x = Math.min(event.layerX, this.mousePosition.x), /** @type {?} */
553 y = Math.min(event.layerY, this.mousePosition.y), /** @type {?} */
554 w = Math.abs(event.layerX - this.mousePosition.x), /** @type {?} */
555 h = Math.abs(event.layerY - this.mousePosition.y);
556 if (!w || !h) {
557 return false;
558 }
559 this.cropRectangle
560 .set('top', y)
561 .set('left', x)
562 .set('width', w)
563 .set('height', h);
564 this.canvas.renderAll();
565 return true;
566 }
567 /**
568 * @param {?} event
569 * @return {?}
570 */
571 startSelectingCropRectangleFromMouse(event) {
572 this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
573 this.cropRectangle.left = event.layerX;
574 this.cropRectangle.top = event.layerY;
575 this.cropRectangle.setCoords();
576 this.mousePosition = { x: event.layerX, y: event.layerY };
577 this.canvas.renderAll();
578 this.cropRectangle.visible = true;
579 this.canvas.bringToFront(this.cropRectangle);
580 }
581 /**
582 * @return {?}
583 */
584 cropImage() {
585 const /** @type {?} */ left = this.cropRectangle.left;
586 const /** @type {?} */ top = this.cropRectangle.top;
587 const /** @type {?} */ width = this.cropRectangle.width;
588 const /** @type {?} */ height = this.cropRectangle.height;
589 const /** @type {?} */ container = document.getElementsByClassName('div-canvas-container')[0];
590 const /** @type {?} */ canvasWidth = container.clientWidth;
591 const /** @type {?} */ canvasHeight = container.clientHeight;
592 const /** @type {?} */ canvasAspect = canvasWidth / canvasHeight;
593 const /** @type {?} */ imgAspect = width / height;
594 let /** @type {?} */ scaleFactor;
595 if (canvasAspect <= imgAspect) {
596 scaleFactor = canvasWidth / width;
597 }
598 else {
599 scaleFactor = canvasHeight / height;
600 }
601 this.canvas.setWidth(width * scaleFactor);
602 this.canvas.setHeight(height * scaleFactor);
603 this.canvas.backgroundImage.scaleX *= scaleFactor;
604 this.canvas.backgroundImage.scaleY *= scaleFactor;
605 this.canvas.backgroundImage.left -= left;
606 this.canvas.backgroundImage.left *= scaleFactor;
607 this.canvas.backgroundImage.top -= top - scaleFactor;
608 this.canvas.backgroundImage.top *= scaleFactor;
609 this.moveAllObjectsInCanvas(-1 * left, -1 * top, scaleFactor);
610 this.canvas.selectable = true;
611 this.canvas.selection = true;
612 this.cropRectangle.visible = false;
613 this.canvas.remove(this.cropRectangle);
614 this.canvas.renderAll();
615 }
616 /**
617 * @param {?} event
618 * @return {?}
619 */
620 ajustCropRectangle(event) {
621 const /** @type {?} */ touch = event.touches[0];
622 const /** @type {?} */ rect = event.target.getBoundingClientRect();
623 const /** @type {?} */ x = Math.min(touch.clientX - rect.left, this.mousePosition.x), /** @type {?} */
624 y = Math.min(touch.clientY - rect.top, this.mousePosition.y), /** @type {?} */
625 w = Math.abs(touch.clientX - rect.left - this.mousePosition.x), /** @type {?} */
626 h = Math.abs(touch.clientY - rect.top - this.mousePosition.y);
627 if (!w || !h) {
628 return false;
629 }
630 this.cropRectangle
631 .set('left', x)
632 .set('top', y)
633 .set('width', w)
634 .set('height', h);
635 this.canvas.renderAll();
636 return true;
637 }
638 /**
639 * @param {?} event
640 * @return {?}
641 */
642 startSelectingCropRectangle(event) {
643 this.cropStartingPosition = { x: this.canvas.left, y: this.canvas.top };
644 const /** @type {?} */ touch = event.touches[0];
645 const /** @type {?} */ rect = event.target.getBoundingClientRect();
646 this.cropRectangle.left = touch.clientX - rect.left;
647 this.cropRectangle.top = touch.clientY - rect.top;
648 this.cropRectangle.setCoords();
649 this.mousePosition = { x: touch.clientX - rect.left, y: touch.clientY - rect.top };
650 this.canvas.renderAll();
651 this.cropRectangle.visible = true;
652 this.canvas.bringToFront(this.cropRectangle);
653 }
654 /**
655 * @return {?}
656 */
657 disableSelection() {
658 this.canvas.selection = false;
659 }
660 /**
661 * @param {?} x
662 * @param {?} y
663 * @param {?} scaleFactor
664 * @return {?}
665 */
666 moveAllObjectsInCanvas(x, y, scaleFactor) {
667 const /** @type {?} */ objects = this.canvas.getObjects();
668 for (const /** @type {?} */ obj of objects) {
669 obj.left += x;
670 obj.left *= scaleFactor;
671 obj.scaleX *= scaleFactor;
672 obj.top += y;
673 obj.scaleY *= scaleFactor;
674 obj.top *= scaleFactor;
675 obj.setCoords();
676 }
677 }
678 /**
679 * @return {?}
680 */
681 groupSelectedObjects() {
682 const /** @type {?} */ activeObjects = this.canvas.getActiveObjects();
683 if (activeObjects) {
684 const /** @type {?} */ objects = [];
685 for (const /** @type {?} */ object of activeObjects) {
686 objects.push(object);
687 }
688 this.deleteSelectedObjects();
689 const /** @type {?} */ group = new fabric.Group(objects);
690 this.canvas.add(group);
691 group.setCoords();
692 this.canvas.setActiveObject(group);
693 this.canvas.renderAll();
694 }
695 }
696 /**
697 * @param {?} event
698 * @return {?}
699 */
700 setLastPanPosition(event) {
701 this.lastPanPosition = new fabric.Point(event.touches[0].clientX, event.touches[0].clientY);
702 }
703 /**
704 * @param {?} event
705 * @return {?}
706 */
707 panCanvas(event) {
708 const /** @type {?} */ delta = new fabric.Point(event.touches[0].clientX - this.lastPanPosition.x, event.touches[0].clientY - this.lastPanPosition.y);
709 this.canvas.relativePan(delta);
710 this.preventPanOutsideCanvas();
711 this.canvas.renderAll();
712 this.setLastPanPosition(event);
713 }
714 /**
715 * @return {?}
716 */
717 preventPanOutsideCanvas() {
718 const /** @type {?} */ canvasViewPort = this.canvas.viewportTransform;
719 const /** @type {?} */ imageHeight = this.canvas.height * canvasViewPort[0];
720 const /** @type {?} */ imageWidth = this.canvas.width * canvasViewPort[0];
721 const /** @type {?} */ bottomEndPoint = this.canvas.height * (canvasViewPort[0] - 1);
722 if (canvasViewPort[5] >= 0 || -bottomEndPoint > canvasViewPort[5]) {
723 canvasViewPort[5] = (canvasViewPort[5] >= 0) ? 0 : -bottomEndPoint;
724 }
725 const /** @type {?} */ rightEndPoint = this.canvas.width * (canvasViewPort[0] - 1);
726 if (canvasViewPort[4] >= 0 || -rightEndPoint > canvasViewPort[4]) {
727 canvasViewPort[4] = (canvasViewPort[4] >= 0) ? 0 : -rightEndPoint;
728 }
729 }
730 /**
731 * @param {?} event
732 * @return {?}
733 */
734 zoom(event) {
735 const /** @type {?} */ point = new fabric.Point(event.center.x, event.center.y);
736 let /** @type {?} */ zoom = this.canvas.getZoom();
737 if (event.additionalEvent === 'pinchout') {
738 zoom *= 1.05;
739 }
740 if (event.additionalEvent === 'pinchin') {
741 zoom /= 1.05;
742 }
743 if (zoom < 1) {
744 zoom = 1;
745 this.canvas.zoomToPoint(new fabric.Point(0, 0), zoom);
746 this.canvas.absolutePan(new fabric.Point(0, 0));
747 }
748 else {
749 if (zoom > 10) {
750 zoom = 10;
751 }
752 this.canvas.zoomToPoint(point, zoom);
753 }
754 this.setFreeDrawingBrushWidthFromZoom(zoom);
755 this.canvas.renderAll();
756 }
757}
758CanvasManagerService.decorators = [
759 { type: Injectable },
760];
761/** @nocollapse */
762CanvasManagerService.ctorParameters = () => [];
763
764/**
765 * @fileoverview added by tsickle
766 * @suppress {checkTypes} checked by tsc
767 */
768const /** @type {?} */ Black = '#000000';
769const /** @type {?} */ Transparent = 'transparent';
770class MobileSketchToolComponent {
771 /**
772 * @param {?} actionSheetCtrl
773 * @param {?} canvasManagerService
774 * @param {?} translate
775 */
776 constructor(actionSheetCtrl, canvasManagerService, translate) {
777 this.actionSheetCtrl = actionSheetCtrl;
778 this.canvasManagerService = canvasManagerService;
779 this.translate = translate;
780 this.canvas = new EventEmitter();
781 this.strokeColor = Black;
782 this.fillColor = Transparent;
783 this.isCropping = false;
784 this.isLoaded = false;
785 this.isUndoAvailable = false;
786 this.isSelectingColor = false;
787 }
788 /**
789 * @return {?}
790 */
791 ngOnInit() {
792 if (this.imageData) {
793 this.canvasManagerService.emptyCanvas();
794 if (this.loadedJson == null || this.loadedJson.length < 10) {
795 this.canvasManagerService.setBackgroundFromURL(this.imageData);
796 }
797 else {
798 this.previousJson = JSON.parse(this.loadedJson);
799 this.currentJson = this.previousJson;
800 this.canvasManagerService
801 .loadfromJson(JSON.parse(this.loadedJson));
802 }
803 this.isLoaded = true;
804 this.previousImageData = this.imageData;
805 }
806 this.emitCanvas();
807 }
808 /**
809 * @return {?}
810 */
811 ngOnChanges() {
812 if (this.isLoaded) {
813 if (this.loadedJson === null || this.loadedJson.length < 10 || this.imageData !== this.previousImageData) {
814 this.canvasManagerService.emptyCanvas();
815 this.canvasManagerService.setBackgroundFromURL(this.imageData);
816 this.previousImageData = this.imageData;
817 this.currentJson = null;
818 }
819 else if (this.loadedJson !== JSON.stringify(this.currentJson)) {
820 this.previousJson = JSON.parse(this.loadedJson);
821 this.currentJson = this.previousJson;
822 this.canvasManagerService
823 .loadfromJson(JSON.parse(this.loadedJson));
824 }
825 }
826 this.emitCanvas();
827 }
828 /**
829 * @return {?}
830 */
831 ngAfterViewInit() {
832 this.gesture = new Gesture(this.element.nativeElement);
833 this.gesture.listen();
834 this.gesture.on('pinch', $event => this.pinch($event));
835 }
836 /**
837 * @return {?}
838 */
839 ngOnDestroy() {
840 this.gesture.destroy();
841 }
842 /**
843 * @param {?} event
844 * @return {?}
845 */
846 pinchEvent(event) {
847 this.canvasManagerService.emptyCanvas();
848 }
849 /**
850 * @return {?}
851 */
852 get hasPictograms() {
853 return !(!this.icons);
854 }
855 /**
856 * @return {?}
857 */
858 addText() {
859 this.canvasManagerService.addText(this.strokeColor, 'text ');
860 this.emitCanvas();
861 }
862 /**
863 * @param {?} shape
864 * @return {?}
865 */
866 addShape(shape) {
867 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape[shape]);
868 this.emitCanvas();
869 }
870 /**
871 * @param {?} source
872 * @return {?}
873 */
874 addImage(source) {
875 this.canvasManagerService.addImage(this.iconsPath + source);
876 this.emitCanvas();
877 }
878 /**
879 * @return {?}
880 */
881 changeStrokeColor() {
882 this.canvasManagerService.changeSelectedObjectsStrokeColor(this.strokeColor);
883 this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
884 this.emitCanvas();
885 }
886 /**
887 * @return {?}
888 */
889 bringFoward() {
890 this.canvasManagerService.bringSelectedObjectsToFront();
891 this.emitCanvas();
892 }
893 /**
894 * @return {?}
895 */
896 sendToBack() {
897 this.canvasManagerService.sendSelectedObjectsToBack();
898 this.emitCanvas();
899 }
900 /**
901 * @return {?}
902 */
903 crop() {
904 this.isCropping = true;
905 this.canvasManagerService.disableSelection();
906 this.canvasManagerService.addSelectionRectangle();
907 this.isUndoAvailable = true;
908 this.previousJson = this.canvasManagerService.jsonFromCanvas();
909 this.emitCanvas();
910 }
911 /**
912 * @return {?}
913 */
914 deleteSelection() {
915 this.canvasManagerService.deleteSelectedObjects();
916 this.emitCanvas();
917 }
918 /**
919 * @param {?} event
920 * @return {?}
921 */
922 mouseUp(event) {
923 if (this.isCropping) {
924 this.isCropping = false;
925 this.canvasManagerService.cropImage();
926 this.isUndoAvailable = true;
927 this.emitCanvas();
928 }
929 }
930 /**
931 * @param {?} event
932 * @return {?}
933 */
934 mouseMove(event) {
935 if (this.isCropping) {
936 this.canvasManagerService.ajustCropRectangle(event);
937 }
938 else if (event.touches.length === 3) {
939 this.canvasManagerService.panCanvas(event);
940 }
941 }
942 /**
943 * @param {?} event
944 * @return {?}
945 */
946 mouseDown(event) {
947 if (this.isCropping) {
948 this.canvasManagerService.startSelectingCropRectangle(event);
949 }
950 else if (event.touches.length === 3) {
951 this.canvasManagerService.setLastPanPosition(event);
952 }
953 }
954 /**
955 * @param {?} event
956 * @return {?}
957 */
958 pinch(event) {
959 event.preventDefault();
960 this.canvasManagerService.zoom(event);
961 }
962 /**
963 * @return {?}
964 */
965 group() {
966 this.canvasManagerService.groupSelectedObjects();
967 this.emitCanvas();
968 }
969 /**
970 * @return {?}
971 */
972 undo() {
973 this.canvasManagerService.loadfromJson(this.previousJson);
974 this.isUndoAvailable = false;
975 this.emitCanvas();
976 }
977 /**
978 * @return {?}
979 */
980 onColorClicked() {
981 this.isSelectingColor = true;
982 }
983 /**
984 * @param {?} color
985 * @return {?}
986 */
987 setColor(color) {
988 this.strokeColor = color;
989 this.changeStrokeColor();
990 this.isSelectingColor = false;
991 this.emitCanvas();
992 }
993 /**
994 * @return {?}
995 */
996 draw() {
997 this.isDrawing = !this.isDrawing;
998 this.canvasManagerService.toggleFreeDrawing();
999 this.canvasManagerService.setFreeDrawingBrushColor(this.strokeColor);
1000 }
1001 /**
1002 * @return {?}
1003 */
1004 disableDrawing() {
1005 if (this.isDrawing) {
1006 this.isDrawing = false;
1007 this.canvasManagerService.toggleFreeDrawing();
1008 }
1009 }
1010 /**
1011 * @return {?}
1012 */
1013 translateShapeButtonsText() {
1014 const /** @type {?} */ translationArray = [];
1015 translationArray.push(this.translate.instant('rectangle'));
1016 translationArray.push(this.translate.instant('triangle'));
1017 translationArray.push(this.translate.instant('circle'));
1018 translationArray.push(this.translate.instant('line'));
1019 translationArray.push(this.translate.instant('cross'));
1020 translationArray.push(this.translate.instant('text'));
1021 return translationArray;
1022 }
1023 /**
1024 * @return {?}
1025 */
1026 presentShapeActionSheet() {
1027 this.disableDrawing();
1028 const /** @type {?} */ titleText = this.translate.instant('addGeometricShape');
1029 const /** @type {?} */ buttonsText = this.translateShapeButtonsText();
1030 let /** @type {?} */ i = 0;
1031 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1032 title: titleText,
1033 buttons: [
1034 {
1035 text: '\uf0c8 ' + buttonsText[i++],
1036 handler: () => {
1037 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Rectangle);
1038 }
1039 },
1040 {
1041 text: '\uf0d8 ' + buttonsText[i++],
1042 handler: () => {
1043 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Triangle);
1044 }
1045 },
1046 {
1047 text: '\uf111 ' + buttonsText[i++],
1048 handler: () => {
1049 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Circle);
1050 }
1051 },
1052 {
1053 text: '\uf068 ' + buttonsText[i++],
1054 handler: () => {
1055 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Line);
1056 }
1057 },
1058 {
1059 text: '\uf067 ' + buttonsText[i++],
1060 handler: () => {
1061 this.canvasManagerService.addGeometricShape(this.strokeColor, this.fillColor, AvailableGeometricShape.Cross);
1062 }
1063 },
1064 {
1065 text: '\uf031 ' + buttonsText[i++],
1066 handler: () => {
1067 this.canvasManagerService.addText(this.strokeColor, '');
1068 }
1069 }
1070 ]
1071 });
1072 actionSheet.present();
1073 }
1074 /**
1075 * @return {?}
1076 */
1077 translateEditButtonsText() {
1078 const /** @type {?} */ translationArray = [];
1079 translationArray.push(this.translate.instant('crop'));
1080 translationArray.push(this.translate.instant('group'));
1081 translationArray.push(this.translate.instant('bringToFront'));
1082 translationArray.push(this.translate.instant('sendToBack'));
1083 translationArray.push(this.translate.instant('delete'));
1084 return translationArray;
1085 }
1086 /**
1087 * @return {?}
1088 */
1089 presentEditActionSheet() {
1090 this.disableDrawing();
1091 const /** @type {?} */ titleText = this.translate.instant('edition');
1092 const /** @type {?} */ buttonsText = this.translateEditButtonsText();
1093 let /** @type {?} */ i = 0;
1094 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1095 title: titleText,
1096 buttons: [
1097 {
1098 text: '\uf125 ' + buttonsText[i++],
1099 handler: () => {
1100 this.crop();
1101 }
1102 },
1103 {
1104 text: '\uf247 ' + buttonsText[i++],
1105 handler: () => {
1106 this.group();
1107 }
1108 },
1109 {
1110 text: '\uf0de ' + buttonsText[i++],
1111 handler: () => {
1112 this.bringFoward();
1113 }
1114 },
1115 {
1116 text: '\uf0dd ' + buttonsText[i++],
1117 handler: () => {
1118 this.sendToBack();
1119 }
1120 },
1121 {
1122 text: '\uf1f8 ' + buttonsText[i++],
1123 handler: () => {
1124 this.deleteSelection();
1125 }
1126 }
1127 ]
1128 });
1129 actionSheet.present();
1130 }
1131 /**
1132 * @return {?}
1133 */
1134 presentPictogramsActionSheet() {
1135 this.disableDrawing();
1136 const /** @type {?} */ buttons = [];
1137 const /** @type {?} */ actionSheetStyles = [];
1138 const /** @type {?} */ images = this.icons;
1139 for (let /** @type {?} */ i = 0; i < images.length; i++) {
1140 const /** @type {?} */ style = document.createElement('style');
1141 style.type = 'text/css';
1142 style.innerHTML =
1143 '.customCSSClass' +
1144 i +
1145 '{background: url(' +
1146 "'" +
1147 this.iconsPath +
1148 images[i] +
1149 "'" +
1150 ') no-repeat !important;padding-left:50px !important;height:80px; background-position: left center !important;}';
1151 document.getElementsByTagName('head')[0].appendChild(style);
1152 actionSheetStyles.push(style);
1153 buttons.push({
1154 role: 'destructive',
1155 text: images[i],
1156 cssClass: 'customCSSClass' + i,
1157 handler: () => {
1158 this.addImage(images[i]);
1159 }
1160 });
1161 }
1162 const /** @type {?} */ titleText = this.translate.instant('addPictogram');
1163 const /** @type {?} */ actionSheet = this.actionSheetCtrl.create({
1164 title: titleText,
1165 buttons: buttons
1166 });
1167 actionSheet.onDidDismiss(() => {
1168 for (let /** @type {?} */ i = 0; i < actionSheetStyles.length; i++) {
1169 if (actionSheetStyles[i].parentNode != null) {
1170 actionSheetStyles[i].parentNode.removeChild(actionSheetStyles[i]);
1171 }
1172 }
1173 });
1174 actionSheet.present();
1175 }
1176 /**
1177 * @return {?}
1178 */
1179 emitCanvas() {
1180 this.canvas.emit(this.canvasManagerService.canvas);
1181 }
1182}
1183MobileSketchToolComponent.decorators = [
1184 { type: Component, args: [{
1185 selector: 'lib-mobile-sketch-tool',
1186 template: `<ion-content>
1187 <div
1188 class="div-canvas-container"
1189 (touchstart)="mouseDown($event)"
1190 (touchmove)="mouseMove($event)"
1191 (touchend)="mouseUp($event)"
1192 #pinchElement
1193 >
1194 <canvas id="canvas"></canvas>
1195
1196 <div
1197 class="color-picker"
1198 *ngIf="isSelectingColor"
1199 >
1200 <ion-grid fixed>
1201 <ion-row>
1202 <ion-col
1203 style="background:#660000"
1204 (tap)="setColor('#660000')"
1205
1206 </ion-col>
1207 <ion-col
1208 style="background:#663300"
1209 (tap)="setColor('#663300')"
1210
1211 </ion-col>
1212 <ion-col
1213 style="background:#666600"
1214 (tap)="setColor('#666600')"
1215
1216 </ion-col>
1217 <ion-col
1218 style="background:#006600"
1219 (tap)="setColor('#006600')"
1220
1221 </ion-col>
1222 <ion-col
1223 style="background:#000066"
1224 (tap)="setColor('#000066')"
1225
1226 </ion-col>
1227 <ion-col
1228 style="background:#660066"
1229 (tap)="setColor('#660066')"
1230
1231 </ion-col>
1232
1233 </ion-row>
1234 <ion-row>
1235 <ion-col
1236 style="background:#CC0000"
1237 (tap)="setColor('#CC0000')"
1238
1239 </ion-col>
1240 <ion-col
1241 style="background:#CC6600"
1242 (tap)="setColor('#CC6600')"
1243
1244 </ion-col>
1245 <ion-col
1246 style="background:#CCCC00"
1247 (tap)="setColor('#CCCC00')"
1248
1249 </ion-col>
1250 <ion-col
1251 style="background:#00CC00"
1252 (tap)="setColor('#00CC00')"
1253
1254 </ion-col>
1255 <ion-col
1256 style="background:#0000CC"
1257 (tap)="setColor('#0000CC')"
1258
1259 </ion-col>
1260 <ion-col
1261 style="background:#CC00CC"
1262 (tap)="setColor('#CC00CC')"
1263
1264 </ion-col>
1265
1266 </ion-row>
1267 <ion-row>
1268 <ion-col
1269 style="background:#FF0000"
1270 (tap)="setColor('#FF0000')"
1271
1272 </ion-col>
1273 <ion-col
1274 style="background:#FF8000"
1275 (tap)="setColor('#FF8000')"
1276
1277 </ion-col>
1278 <ion-col
1279 style="background:#FFFF00"
1280 (tap)="setColor('#FFFF00')"
1281
1282 </ion-col>
1283 <ion-col
1284 style="background:#00FF00"
1285 (tap)="setColor('#00FF00')"
1286
1287 </ion-col>
1288 <ion-col
1289 style="background:#0000FF"
1290 (tap)="setColor('#0000FF')"
1291
1292 </ion-col>
1293 <ion-col
1294 style="background:#FF00FF"
1295 (tap)="setColor('#FF00FF')"
1296
1297 </ion-col>
1298
1299 </ion-row>
1300 <ion-row>
1301 <ion-col
1302 style="background:#FF6666"
1303 (tap)="setColor('#FF6666')"
1304
1305 </ion-col>
1306 <ion-col
1307 style="background:#FFB266"
1308 (tap)="setColor('#FFB266')"
1309
1310 </ion-col>
1311 <ion-col
1312 style="background:#FFFF66"
1313 (tap)="setColor('#FFFF66')"
1314
1315 </ion-col>
1316 <ion-col
1317 style="background:#66FF66"
1318 (tap)="setColor('#66FF66')"
1319
1320 </ion-col>
1321 <ion-col
1322 style="background:#6666FF"
1323 (tap)="setColor('#6666FF')"
1324
1325 </ion-col>
1326 <ion-col
1327 style="background:#FF66FF"
1328 (tap)="setColor('#FF66FF')"
1329
1330 </ion-col>
1331
1332 </ion-row>
1333 <ion-row>
1334 <ion-col
1335 style="background:#FF9999"
1336 (tap)="setColor('#FF9999')"
1337
1338 </ion-col>
1339 <ion-col
1340 style="background:#FFCC99"
1341 (tap)="setColor('#FFCC99')"
1342
1343 </ion-col>
1344 <ion-col
1345 style="background:#FFFF99"
1346 (tap)="setColor('#FFFF99')"
1347
1348 </ion-col>
1349 <ion-col
1350 style="background:#99FF99"
1351 (tap)="setColor('#99FF99')"
1352
1353 </ion-col>
1354 <ion-col
1355 style="background:#9999FF"
1356 (tap)="setColor('#9999FF')"
1357
1358 </ion-col>
1359 <ion-col
1360 style="background:#FF99FF"
1361 (tap)="setColor('#FF99FF')"
1362
1363 </ion-col>
1364
1365 </ion-row>
1366 <ion-row>
1367 <ion-col
1368 style="background:#FFFFFF"
1369 (tap)="setColor('#FFFFFF')"
1370
1371 </ion-col>
1372 <ion-col
1373 style="background:#C0C0C0"
1374 (tap)="setColor('#C0C0C0')"
1375
1376 </ion-col>
1377 <ion-col
1378 style="background:#808080"
1379 (tap)="setColor('#808080')"
1380
1381 </ion-col>
1382 <ion-col
1383 style="background:#606060"
1384 (tap)="setColor('#606060')"
1385
1386 </ion-col>
1387 <ion-col
1388 style="background:#303030"
1389 (tap)="setColor('#606060')"
1390
1391 </ion-col>
1392 <ion-col
1393 style="background:#000000"
1394 (tap)="setColor('#000000')"
1395
1396 </ion-col>
1397 </ion-row>
1398 </ion-grid>
1399 </div>
1400 </div>
1401</ion-content>
1402
1403<ion-footer>
1404 <ion-toolbar>
1405 <div class="div-edit-toolbar">
1406 <button
1407 class="button-edit-toolbar"
1408 ion-button
1409 large
1410 [clear]="true"
1411 (click)="presentShapeActionSheet()"
1412 >
1413 <i
1414 class="fas fa-shapes"
1415 id="icon"
1416 ></i>
1417 </button>
1418
1419 <button
1420 class="button-edit-toolbar"
1421 ion-button
1422 large
1423 [clear]="true"
1424 (click)="presentPictogramsActionSheet()"
1425 *ngIf="hasPictograms"
1426 >
1427 <i
1428 class="fas fa-images"
1429 id="icon"
1430 ></i>
1431 </button>
1432
1433 <button
1434 class="button-edit-toolbar"
1435 ion-button
1436 large
1437 [clear]="true"
1438 (click)="presentEditActionSheet()"
1439 >
1440 <i
1441 class="fas fa-edit"
1442 id="icon"
1443 ></i>
1444 </button>
1445
1446 <button
1447 class="button-edit-toolbar"
1448 ion-button
1449 large
1450 [clear]="true"
1451 (click)="draw()"
1452 >
1453 <i
1454 class="fas fa-pencil-alt"
1455 id="icon"
1456 ></i>
1457 </button>
1458
1459 <button
1460 class="button-edit-toolbar"
1461 ion-button
1462 large
1463 [clear]="true"
1464 (click)="onColorClicked()"
1465 >
1466 <i
1467 class="fas fa-palette"
1468 id="icon"
1469 ></i>
1470 </button>
1471
1472 <button
1473 class="button-edit-toolbar"
1474 ion-button
1475 large
1476 [clear]="true"
1477 (click)="undo()"
1478 *ngIf="isUndoAvailable"
1479 >
1480 <i
1481 class="fas fa-undo"
1482 id="icon"
1483 ></i>
1484 </button>
1485
1486 </div>
1487 </ion-toolbar>
1488</ion-footer>
1489`,
1490 styles: [`.div-canvas-container{text-align:center;height:100%;width:100%;-o-object-fit:contain;object-fit:contain}.scroll-content{padding:0!important;overflow-y:hidden}.div-edit-toolbar{text-align:center}.button-edit-toolbar{padding:4%!important;margin:0!important}.action-sheet-button{font-family:FontAwesome,Arial}.color-picker{position:absolute;width:100%;height:auto;bottom:0;left:0}#icon{color:#b32017}`],
1491 providers: [CanvasManagerService]
1492 },] },
1493];
1494/** @nocollapse */
1495MobileSketchToolComponent.ctorParameters = () => [
1496 { type: ActionSheetController, },
1497 { type: CanvasManagerService, },
1498 { type: TranslateService, },
1499];
1500MobileSketchToolComponent.propDecorators = {
1501 "element": [{ type: ViewChild, args: ['pinchElement',] },],
1502 "imageData": [{ type: Input },],
1503 "loadedJson": [{ type: Input },],
1504 "iconsPath": [{ type: Input },],
1505 "icons": [{ type: Input },],
1506 "canvas": [{ type: Output },],
1507};
1508
1509/**
1510 * @fileoverview added by tsickle
1511 * @suppress {checkTypes} checked by tsc
1512 */
1513class SketchToolModule {
1514}
1515SketchToolModule.decorators = [
1516 { type: NgModule, args: [{
1517 imports: [CommonModule, IonicModule],
1518 declarations: [
1519 MobileSketchToolComponent,
1520 ],
1521 providers: [
1522 CanvasManagerService,
1523 ],
1524 exports: [MobileSketchToolComponent]
1525 },] },
1526];
1527
1528/**
1529 * @fileoverview added by tsickle
1530 * @suppress {checkTypes} checked by tsc
1531 */
1532
1533/**
1534 * @fileoverview added by tsickle
1535 * @suppress {checkTypes} checked by tsc
1536 */
1537
1538export { MobileSketchToolComponent, CanvasManagerService, SketchToolModule };
1539
1540//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliLXNrZXRjaC10b29sLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC9jb25zdGFudHMvc2hhcGUtZGF0YS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvc2VydmljZXMvY2FudmFzLW1hbmFnZXIuc2VydmljZS50cyIsIm5nOi8vbGliLXNrZXRjaC10b29sL2FwcC9saWItc2tldGNoLXRvb2wvbW9iaWxlLWNvbXBvbmVudC9tb2JpbGUtc2tldGNoLXRvb2wuY29tcG9uZW50LnRzIiwibmc6Ly9saWItc2tldGNoLXRvb2wvYXBwL2xpYi1za2V0Y2gtdG9vbC9za2V0Y2gtdG9vbC5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IFNIQVBFX0RBVEEgPSB7XG4gIHdpZHRoOiAyMDAsXG4gIGhlaWdodDogMjAwLFxuICBsZWZ0OiA1MCxcbiAgdG9wOiA1MCxcbiAgcmFkaXVzOiAxMDAsXG4gIHN0cm9rZTogMTAsXG4gIGZyZWVEcmF3aW5nQnJ1c2hXaWR0aDogMTAsXG4gIGNvcm5lclNpemU6IDIwXG59O1xuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcblxuaW1wb3J0IHsgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUgfSBmcm9tICcuLy4uL2NvbnN0YW50cy9hdmFpbGFibGUtZ2VvbWV0cmljLXNoYXBlcyc7XG5pbXBvcnQgeyBTSEFQRV9EQVRBIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvc2hhcGUtZGF0YSc7XG5cbmludGVyZmFjZSBTY2FsZURhdGEge1xuICBzY2FsZUZhY3RvcjogbnVtYmVyO1xuICBsZWZ0OiBudW1iZXI7XG4gIHRvcDogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUG9zaXRpb24ge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENhbnZhc01hbmFnZXJTZXJ2aWNlIHtcbiAgcHVibGljIGNhbnZhcztcblxuICBwcml2YXRlIGNyb3BSZWN0YW5nbGU6IGZhYnJpYy5SZWN0O1xuICBwcml2YXRlIG1vdXNlUG9zaXRpb246IFBvc2l0aW9uO1xuICBwcml2YXRlIGNyb3BTdGFydGluZ1Bvc2l0aW9uOiBQb3NpdGlvbjtcbiAgcHJpdmF0ZSBsYXN0UGFuUG9zaXRpb246IGZhYnJpYy5Qb2ludDtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmVtcHR5Q2FudmFzKCk7XG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IDAsIHk6IDB9O1xuICAgIHRoaXMuY3JvcFN0YXJ0aW5nUG9zaXRpb24gPSB7eDogMCwgeTogMH07XG4gICAgdGhpcy5jYW52YXMuZnJlZURyYXdpbmdCcnVzaC53aWR0aCA9IFNIQVBFX0RBVEEuZnJlZURyYXdpbmdCcnVzaFdpZHRoO1xuICB9XG5cbiAgZ2V0IGJhY2tncm91bmRJbWFnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXM7XG4gIH1cblxuICBnZXQgY2FudmFzT2JqZWN0cygpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpO1xuICB9XG5cbiAgZ2V0IGNhbnZhc0JhY2tncm91bmRJbWFnZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlO1xuICB9XG5cbiAgZ2V0IGFjdGl2ZU9iamVjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMuZ2V0QWN0aXZlT2JqZWN0KCk7XG4gIH1cblxuICBnZXQgYWN0aXZlR3JvdXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcbiAgfVxuXG4gIHB1YmxpYyBlbXB0eUNhbnZhcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jYW52YXMpIHtcbiAgICAgIHRoaXMuY2FudmFzLmRpc3Bvc2UoKTtcbiAgICB9XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgZmFicmljLkNhbnZhcygnY2FudmFzJyk7XG4gICAgdGhpcy5jYW52YXMuY2xlYXIoKTtcbiAgICB0aGlzLmNhbnZhcy5yZW1vdmUodGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkTmV3SW1hZ2UoYmFja2dyb3VuZEltYWdlVVJMPzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5lbXB0eUNhbnZhcygpO1xuICAgIGlmIChiYWNrZ3JvdW5kSW1hZ2VVUkwpIHtcbiAgICAgIHRoaXMuc2V0QmFja2dyb3VuZEZyb21VUkwoYmFja2dyb3VuZEltYWdlVVJMKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcmVuZGVyQ2FudmFzKCk6IHZvaWQge1xuICAgIHRoaXMubWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk7XG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gIH1cblxuICBwdWJsaWMgYWRkR2VvbWV0cmljU2hhcGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcsIHNoYXBlOiBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZSk6IHZvaWQge1xuICAgIHN3aXRjaCAoc2hhcGUpIHtcbiAgICAgIGNhc2UgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuUmVjdGFuZ2xlOlxuICAgICAgICB0aGlzLmFkZFJlY3RhbmdsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkNpcmNsZTpcbiAgICAgICAgdGhpcy5hZGRDaXJjbGUoc3Ryb2tlQ29sb3IsIGZpbGxDb2xvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5UcmlhbmdsZTpcbiAgICAgICAgdGhpcy5hZGRUcmlhbmdsZShzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkxpbmU6XG4gICAgICAgIHRoaXMuYWRkSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3IsIGZpbGxDb2xvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5Dcm9zczpcbiAgICAgICAgdGhpcy5hZGRDcm9zcyhzdHJva2VDb2xvciwgZmlsbENvbG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRSZWN0YW5nbGUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQoXG4gICAgICBuZXcgZmFicmljLlJlY3Qoe1xuICAgICAgICB3aWR0aDogU0hBUEVfREFUQS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBTSEFQRV9EQVRBLmhlaWdodCxcbiAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICB0b3A6IFNIQVBFX0RBVEEudG9wLFxuICAgICAgICBmaWxsOiBmaWxsQ29sb3IsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlQ29sb3IsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBTSEFQRV9EQVRBLnN0cm9rZSxcbiAgICAgICAgY29ybmVyU2l6ZTogU0hBUEVfREFUQS5jb3JuZXJTaXplXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZENpcmNsZShzdHJva2VDb2xvcjogc3RyaW5nLCBmaWxsQ29sb3I6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY2FudmFzLmFkZChcbiAgICAgIG5ldyBmYWJyaWMuQ2lyY2xlKHtcbiAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICB0b3A6IFNIQVBFX0RBVEEudG9wLFxuICAgICAgICByYWRpdXM6IFNIQVBFX0RBVEEucmFkaXVzLFxuICAgICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgICBzdHJva2VXaWR0aDogU0hBUEVfREFUQS5zdHJva2UsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgY29ybmVyU2l6ZTogU0hBUEVfREFUQS5jb3JuZXJTaXplXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFkZFRyaWFuZ2xlKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5jYW52YXMuYWRkKFxuICAgICAgbmV3IGZhYnJpYy5UcmlhbmdsZSh7XG4gICAgICAgIHdpZHRoOiBTSEFQRV9EQVRBLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IFNIQVBFX0RBVEEuaGVpZ2h0LFxuICAgICAgICBsZWZ0OiBTSEFQRV9EQVRBLmxlZnQsXG4gICAgICAgIHRvcDogU0hBUEVfREFUQS50b3AsXG4gICAgICAgIGZpbGw6IGZpbGxDb2xvcixcbiAgICAgICAgc3Ryb2tlOiBzdHJva2VDb2xvcixcbiAgICAgICAgc3Ryb2tlV2lkdGg6IFNIQVBFX0RBVEEuc3Ryb2tlLFxuICAgICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkSG9yaXpvbnRhbExpbmUoc3Ryb2tlQ29sb3I6IHN0cmluZywgZmlsbENvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5hZGQodGhpcy5jcmVhdGVIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcikpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVIb3Jpem9udGFsTGluZShzdHJva2VDb2xvcjogc3RyaW5nKTogZmFicmljLkxpbmUge1xuICAgIGNvbnN0IGxpbmUgPSBuZXcgZmFicmljLkxpbmUoWzEwMCwgMTUwLCAyMDAsIDE1MF0sIHtcbiAgICAgIGxlZnQ6IDUwLFxuICAgICAgdG9wOiAxMDAsXG4gICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgc3Ryb2tlV2lkdGg6IDUsXG4gICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICB9KTtcblxuICAgIGxpbmUuc2V0Q29udHJvbHNWaXNpYmlsaXR5KHtcbiAgICAgIGJsOiBmYWxzZSxcbiAgICAgIGJyOiBmYWxzZSxcbiAgICAgIHRsOiBmYWxzZSxcbiAgICAgIHRyOiBmYWxzZSxcbiAgICAgIG10OiBmYWxzZSxcbiAgICAgIG1iOiBmYWxzZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVZlcnRpY2FsTGluZShzdHJva2VDb2xvcjogc3RyaW5nKTogZmFicmljLkxpbmUge1xuICAgIGNvbnN0IGxpbmUgPSBuZXcgZmFicmljLkxpbmUoWzE1MCwgMTAwLCAxNTAsIDIwMF0sIHtcbiAgICAgIGxlZnQ6IDEwMCxcbiAgICAgIHRvcDogNTAsXG4gICAgICBzdHJva2U6IHN0cm9rZUNvbG9yLFxuICAgICAgc3Ryb2tlV2lkdGg6IDUsXG4gICAgICBjb3JuZXJTaXplOiBTSEFQRV9EQVRBLmNvcm5lclNpemVcbiAgICB9KTtcblxuICAgIGxpbmUuc2V0Q29udHJvbHNWaXNpYmlsaXR5KHtcbiAgICAgIGJsOiBmYWxzZSxcbiAgICAgIGJyOiBmYWxzZSxcbiAgICAgIHRsOiBmYWxzZSxcbiAgICAgIHRyOiBmYWxzZSxcbiAgICAgIG1sOiBmYWxzZSxcbiAgICAgIG1yOiBmYWxzZVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICBwcml2YXRlIGFkZENyb3NzKHN0cm9rZUNvbG9yOiBzdHJpbmcsIGZpbGxDb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaG9yaXpvbnRhbExpbmUgPSB0aGlzLmNyZWF0ZUhvcml6b250YWxMaW5lKHN0cm9rZUNvbG9yKTtcbiAgICBjb25zdCB2ZXJ0aWNhbExpbmUgPSB0aGlzLmNyZWF0ZVZlcnRpY2FsTGluZShzdHJva2VDb2xvcik7XG4gICAgdGhpcy5jYW52YXMuYWRkKGhvcml6b250YWxMaW5lKTtcbiAgICB0aGlzLmNhbnZhcy5hZGQodmVydGljYWxMaW5lKTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVGcmVlRHJhd2luZygpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5pc0RyYXdpbmdNb2RlID0gIXRoaXMuY2FudmFzLmlzRHJhd2luZ01vZGU7XG4gIH1cblxuICBwdWJsaWMgc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKGNvbG9yOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5mcmVlRHJhd2luZ0JydXNoLmNvbG9yID0gY29sb3I7XG4gIH1cblxuICBwcml2YXRlIHNldEZyZWVEcmF3aW5nQnJ1c2hXaWR0aEZyb21ab29tKHpvb206IG51bWJlcikge1xuICAgIHRoaXMuY2FudmFzLmZyZWVEcmF3aW5nQnJ1c2gud2lkdGggPSBTSEFQRV9EQVRBLmZyZWVEcmF3aW5nQnJ1c2hXaWR0aCAqICgxIC8gem9vbSk7XG4gIH1cblxuICBwdWJsaWMgYWRkVGV4dChjb2xvcjogc3RyaW5nLCBpbnB1dFRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgZmFicmljLklUZXh0KCd0ZXh0Jywge1xuICAgICAgZm9udEZhbWlseTogJ2FyaWFsIGJsYWNrJyxcbiAgICAgIGZvbnRTdHlsZTogJ2JvbGQnLFxuICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgIH0pO1xuXG4gICAgdGV4dC5zZXRDb2xvcihjb2xvcik7XG5cbiAgICB0aGlzLmNhbnZhcy5hZGQodGV4dCk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW1hZ2UoaW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShcbiAgICAgIChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgICAgY29uc3QgY2FudmFzID0gdGhpcy5jYW52YXM7XG5cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oaW1nKSB7XG4gICAgICAgICAgY29uc3QgZmFicmljSW1hZ2UgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7XG4gICAgICAgICAgICBhbmdsZTogMCxcbiAgICAgICAgICAgIHdpZHRoOiBpbWFnZS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogaW1hZ2UuaGVpZ2h0LFxuICAgICAgICAgICAgbGVmdDogU0hBUEVfREFUQS5sZWZ0LFxuICAgICAgICAgICAgdG9wOiBTSEFQRV9EQVRBLnRvcCxcbiAgICAgICAgICAgIHNjYWxlWDogMSxcbiAgICAgICAgICAgIHNjYWxlWTogMSxcbiAgICAgICAgICAgIGNvcm5lclNpemU6IFNIQVBFX0RBVEEuY29ybmVyU2l6ZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNhbnZhcy5hZGQoZmFicmljSW1hZ2UpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gaW1hZ2VVUkw7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRCYWNrZ3JvdW5kRnJvbVVSTChiYWNrZ3JvdW5kSW1hZ2VVUkw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMuY2FudmFzO1xuICAgIGNvbnN0IHJlc2l6ZSA9IHRoaXMucmVzaXplQ2FudmFzQW5kQ29tcHV0ZVNjYWxlRmFjdG9yO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgICAgKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoYmFja2dyb3VuZEltYWdlVVJMID09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgZl9pbWcgPSBuZXcgZmFicmljLkltYWdlKGltYWdlLCB7fSk7XG5cbiAgICAgICAgICBjb25zdCBzY2FsZURhdGEgPSByZXNpemUoZl9pbWcsIGNhbnZhcyk7XG5cbiAgICAgICAgICBjYW52YXMuc2V0QmFja2dyb3VuZEltYWdlKGZfaW1nLCBjYW52YXMucmVuZGVyQWxsLmJpbmQoY2FudmFzKSwge1xuICAgICAgICAgICAgc2NhbGVYOiBzY2FsZURhdGEuc2NhbGVGYWN0b3IsXG4gICAgICAgICAgICBzY2FsZVk6IHNjYWxlRGF0YS5zY2FsZUZhY3RvclxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2FudmFzLnJlbmRlckFsbCgpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1hZ2Uuc3JjID0gYmFja2dyb3VuZEltYWdlVVJMO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlc2l6ZUNhbnZhc0FuZENvbXB1dGVTY2FsZUZhY3RvcihmX2ltZzogZmFicmljLkltYWdlLCBjYW52YXM6IGZhYnJpYy5DYW52YXMpOiBTY2FsZURhdGEge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIGNhbnZhcy5zZXRXaWR0aChjb250YWluZXIuY2xpZW50V2lkdGgpO1xuICAgIGNhbnZhcy5zZXRIZWlnaHQoY29udGFpbmVyLmNsaWVudEhlaWdodCk7XG5cbiAgICBjb25zdCBjYW52YXNXaWR0aCA9IGNhbnZhcy5nZXRXaWR0aCgpO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNhbnZhcy5nZXRIZWlnaHQoKTtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IGZfaW1nLndpZHRoIC8gZl9pbWcuaGVpZ2h0O1xuICAgIGxldCBsZWZ0LCB0b3AsIHNjYWxlRmFjdG9yO1xuXG4gICAgaWYgKGNhbnZhc0FzcGVjdCA8PSBpbWdBc3BlY3QpIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzV2lkdGggLyBmX2ltZy53aWR0aDtcbiAgICAgIGxlZnQgPSAwO1xuICAgICAgdG9wID0gLShmX2ltZy5oZWlnaHQgKiBzY2FsZUZhY3RvciAtIGNhbnZhc0hlaWdodCkgLyAyO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc0hlaWdodCAvIGZfaW1nLmhlaWdodDtcbiAgICAgIHRvcCA9IDA7XG4gICAgICBsZWZ0ID0gLShmX2ltZy53aWR0aCAqIHNjYWxlRmFjdG9yIC0gY2FudmFzV2lkdGgpIC8gMjtcbiAgICB9XG4gICAgcmV0dXJuIHsgc2NhbGVGYWN0b3I6IHNjYWxlRmFjdG9yLCBsZWZ0OiBsZWZ0LCB0b3A6IHRvcCB9O1xuICB9XG5cbiAgcHVibGljIG9uT3JpZW50YXRpb25DaGFuZ2UoKSB7XG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IHRoaXMuY2FudmFzLmdldFdpZHRoLCB5OiB0aGlzLmNhbnZhcy5nZXRIZWlnaHQgfTtcbiAgICB0aGlzLmNyb3BJbWFnZSgpO1xuICB9XG5cbiAgcHVibGljIGNoYW5nZVNlbGVjdGVkT2JqZWN0c0ZpbGxDb2xvcihjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIG9iamVjdC5zZXRDb2xvcihjb2xvcik7XG4gICAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBjaGFuZ2VTZWxlY3RlZE9iamVjdHNTdHJva2VDb2xvcihjb2xvcjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIGlmIChvYmplY3QudHlwZSA9PT0gJ2ktdGV4dCcpIHtcbiAgICAgICAgICBvYmplY3Quc2V0Q29sb3IoY29sb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9iamVjdC5zdHJva2UgPSBjb2xvcjtcbiAgICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlU2VsZWN0ZWRPYmplY3RzKCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICB0aGlzLmNhbnZhcy5yZW1vdmUob2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FudmFzLmRpc2NhcmRBY3RpdmVPYmplY3QoKTtcbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBicmluZ1NlbGVjdGVkT2JqZWN0c1RvRnJvbnQoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBhY3RpdmVPYmplY3RzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzLmJyaW5nVG9Gcm9udChvYmplY3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZW5kU2VsZWN0ZWRPYmplY3RzVG9CYWNrKCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICB0aGlzLmNhbnZhcy5zZW5kVG9CYWNrKG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGpzb25Gcm9tQ2FudmFzKCk6IEpTT04ge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy50b0pTT04oKTtcbiAgfVxuXG4gIHB1YmxpYyBsb2FkZnJvbUpzb24oanNvbjogSlNPTik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIHRoaXMuY2FudmFzLnNldFdpZHRoKGNvbnRhaW5lci5jbGllbnRXaWR0aCk7XG4gICAgdGhpcy5jYW52YXMuc2V0SGVpZ2h0KGNvbnRhaW5lci5jbGllbnRIZWlnaHQpO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgICAgKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmFkanVzdENhbnZhcyhqc29uKTtcbiAgICAgICAgdGhpcy5jYW52YXMubG9hZEZyb21KU09OKGpzb24sIHRoaXMuY2FudmFzLnJlbmRlckFsbC5iaW5kKHRoaXMuY2FudmFzKSk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFkanVzdENhbnZhcyhqc29uOiBKU09OKTogdm9pZCB7XG4gICAgY29uc3QgYmFja2dyb3VuZEltYWdlID0ganNvblsnYmFja2dyb3VuZEltYWdlJ107XG5cbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFxuICAgICAgJ2Rpdi1jYW52YXMtY29udGFpbmVyJ1xuICAgIClbMF07XG5cbiAgICBjb25zdCB3aWR0aCA9IGJhY2tncm91bmRJbWFnZVsnd2lkdGgnXTtcbiAgICBjb25zdCBoZWlnaHQgPSBiYWNrZ3JvdW5kSW1hZ2VbJ2hlaWdodCddO1xuXG4gICAgY29uc3QgY2FudmFzV2lkdGggPSBjb250YWluZXIuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgY2FudmFzSGVpZ2h0ID0gY29udGFpbmVyLmNsaWVudEhlaWdodDtcblxuICAgIGNvbnN0IGNhbnZhc0FzcGVjdCA9IGNhbnZhc1dpZHRoIC8gY2FudmFzSGVpZ2h0O1xuICAgIGNvbnN0IGltZ0FzcGVjdCA9IHdpZHRoIC8gaGVpZ2h0O1xuICAgIGxldCBzY2FsZUZhY3RvcjtcblxuICAgIGlmIChjYW52YXNBc3BlY3QgPD0gaW1nQXNwZWN0KSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc1dpZHRoIC8gd2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNjYWxlRmFjdG9yID0gY2FudmFzSGVpZ2h0IC8gaGVpZ2h0O1xuICAgIH1cblxuICAgIGNvbnN0IG9iamVjdFNjYWxlID0gc2NhbGVGYWN0b3IgLyBiYWNrZ3JvdW5kSW1hZ2VbJ3NjYWxlWCddO1xuXG4gICAgYmFja2dyb3VuZEltYWdlWydzY2FsZVgnXSA9IHNjYWxlRmFjdG9yO1xuICAgIGJhY2tncm91bmRJbWFnZVsnc2NhbGVZJ10gPSBzY2FsZUZhY3RvcjtcblxuICAgIHRoaXMuY2FudmFzLnNldFdpZHRoKHdpZHRoICogc2NhbGVGYWN0b3IpO1xuICAgIHRoaXMuY2FudmFzLnNldEhlaWdodChoZWlnaHQgKiBzY2FsZUZhY3Rvcik7XG5cbiAgICBjb25zdCBvYmplY3RzID0ganNvblsnb2JqZWN0cyddO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvYmplY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzW2ldWydsZWZ0J10gKj0gb2JqZWN0U2NhbGU7XG4gICAgICBvYmplY3RzW2ldWyd0b3AnXSAqPSBvYmplY3RTY2FsZTtcbiAgICAgIG9iamVjdHNbaV1bJ3NjYWxlWCddICo9IG9iamVjdFNjYWxlO1xuICAgICAgb2JqZWN0c1tpXVsnc2NhbGVZJ10gKj0gb2JqZWN0U2NhbGU7XG4gICAgfVxuXG4gICAgdGhpcy5jYW52YXMuc2VsZWN0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcblxuICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICB9XG5cbiAgcHVibGljIGV4cG9ydEltYWdlQXNEYXRhVVJMKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0SXRlbShpdGVtTnVtYmVyOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNhbnZhcy5zZXRBY3RpdmVPYmplY3QodGhpcy5jYW52YXMuaXRlbShpdGVtTnVtYmVyKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0SW5kZXhPZihhY3RpdmVPYmplY3QpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkuaW5kZXhPZihhY3RpdmVPYmplY3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3RMYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGl0ZW1OdW1iZXIgPSB0aGlzLmNhbnZhcy5nZXRPYmplY3RzKCkubGVuZ3RoIC0gMTtcbiAgICBjb25zdCBvYmplY3QgPSB0aGlzLmNhbnZhcy5pdGVtKGl0ZW1OdW1iZXIpO1xuICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChvYmplY3QpO1xuICAgIG9iamVjdC5lbnRlckVkaXRpbmcoKTtcbiAgfVxuXG4gIHByaXZhdGUgbWFya1NlbGVjdGVkT2JqZWN0c0RpcnR5KCk6IHZvaWQge1xuICAgIGNvbnN0IGFjdGl2ZU9iamVjdHMgPSB0aGlzLmNhbnZhcy5nZXRBY3RpdmVPYmplY3RzKCk7XG5cbiAgICBpZiAoYWN0aXZlT2JqZWN0cykge1xuICAgICAgZm9yIChjb25zdCBvYmplY3Qgb2YgYWN0aXZlT2JqZWN0cykge1xuICAgICAgICBvYmplY3Quc2V0KCdkaXJ0eScsIHRydWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhZGRTZWxlY3Rpb25SZWN0YW5nbGUoKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlID0gbmV3IGZhYnJpYy5SZWN0KHtcbiAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICBvcmlnaW5YOiAnbGVmdCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIHN0cm9rZTogJyNjY2MnLFxuICAgICAgc3Ryb2tlRGFzaEFycmF5OiBbMiwgMl0sXG4gICAgICBvcGFjaXR5OiAxLFxuICAgICAgd2lkdGg6IDEsXG4gICAgICBoZWlnaHQ6IDFcbiAgICB9KTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS52aXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5jYW52YXMuYWRkKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgYWp1c3RDcm9wUmVjdGFuZ2xlRnJvbU1vdXNlKGV2ZW50OiBNb3VzZUV2ZW50KTogYm9vbGVhbiB7XG4gICAgY29uc3QgeCA9IE1hdGgubWluKGV2ZW50LmxheWVyWCwgdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgeSA9IE1hdGgubWluKGV2ZW50LmxheWVyWSwgdGhpcy5tb3VzZVBvc2l0aW9uLnkpLFxuICAgICAgdyA9IE1hdGguYWJzKGV2ZW50LmxheWVyWCAtIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIGggPSBNYXRoLmFicyhldmVudC5sYXllclkgLSB0aGlzLm1vdXNlUG9zaXRpb24ueSk7XG5cbiAgICBpZiAoIXcgfHwgIWgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGVcbiAgICAgIC5zZXQoJ3RvcCcsIHkpXG4gICAgICAuc2V0KCdsZWZ0JywgeClcbiAgICAgIC5zZXQoJ3dpZHRoJywgdylcbiAgICAgIC5zZXQoJ2hlaWdodCcsIGgpO1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzdGFydFNlbGVjdGluZ0Nyb3BSZWN0YW5nbGVGcm9tTW91c2UoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNyb3BTdGFydGluZ1Bvc2l0aW9uID0geyB4OiB0aGlzLmNhbnZhcy5sZWZ0LCB5OiB0aGlzLmNhbnZhcy50b3AgfTtcblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS5sZWZ0ID0gZXZlbnQubGF5ZXJYO1xuICAgIHRoaXMuY3JvcFJlY3RhbmdsZS50b3AgPSBldmVudC5sYXllclk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnNldENvb3JkcygpO1xuXG4gICAgdGhpcy5tb3VzZVBvc2l0aW9uID0ge3g6IGV2ZW50LmxheWVyWCwgeTogZXZlbnQubGF5ZXJZIH07XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUudmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuYnJpbmdUb0Zyb250KHRoaXMuY3JvcFJlY3RhbmdsZSk7XG4gIH1cblxuICBwdWJsaWMgY3JvcEltYWdlKCk6IHZvaWQge1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdDtcbiAgICBjb25zdCB0b3AgPSB0aGlzLmNyb3BSZWN0YW5nbGUudG9wO1xuXG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmNyb3BSZWN0YW5nbGUud2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5jcm9wUmVjdGFuZ2xlLmhlaWdodDtcblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXG4gICAgICAnZGl2LWNhbnZhcy1jb250YWluZXInXG4gICAgKVswXTtcblxuICAgIGNvbnN0IGNhbnZhc1dpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IGNhbnZhc0hlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XG5cbiAgICBjb25zdCBjYW52YXNBc3BlY3QgPSBjYW52YXNXaWR0aCAvIGNhbnZhc0hlaWdodDtcbiAgICBjb25zdCBpbWdBc3BlY3QgPSB3aWR0aCAvIGhlaWdodDtcbiAgICBsZXQgc2NhbGVGYWN0b3I7XG5cbiAgICBpZiAoY2FudmFzQXNwZWN0IDw9IGltZ0FzcGVjdCkge1xuICAgICAgc2NhbGVGYWN0b3IgPSBjYW52YXNXaWR0aCAvIHdpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2FsZUZhY3RvciA9IGNhbnZhc0hlaWdodCAvIGhlaWdodDtcbiAgICB9XG5cbiAgICB0aGlzLmNhbnZhcy5zZXRXaWR0aCh3aWR0aCAqIHNjYWxlRmFjdG9yKTtcbiAgICB0aGlzLmNhbnZhcy5zZXRIZWlnaHQoaGVpZ2h0ICogc2NhbGVGYWN0b3IpO1xuXG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLnNjYWxlWCAqPSBzY2FsZUZhY3RvcjtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2Uuc2NhbGVZICo9IHNjYWxlRmFjdG9yO1xuXG4gICAgdGhpcy5jYW52YXMuYmFja2dyb3VuZEltYWdlLmxlZnQgLT0gbGVmdDtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UubGVmdCAqPSBzY2FsZUZhY3RvcjtcbiAgICB0aGlzLmNhbnZhcy5iYWNrZ3JvdW5kSW1hZ2UudG9wIC09IHRvcCAtIHNjYWxlRmFjdG9yO1xuICAgIHRoaXMuY2FudmFzLmJhY2tncm91bmRJbWFnZS50b3AgKj0gc2NhbGVGYWN0b3I7XG5cbiAgICB0aGlzLm1vdmVBbGxPYmplY3RzSW5DYW52YXMoLTEgKiBsZWZ0LCAtMSAqIHRvcCwgc2NhbGVGYWN0b3IpO1xuXG4gICAgdGhpcy5jYW52YXMuc2VsZWN0YWJsZSA9IHRydWU7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gdHJ1ZTtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUudmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgdGhpcy5jYW52YXMucmVtb3ZlKHRoaXMuY3JvcFJlY3RhbmdsZSk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgfVxuXG4gIHB1YmxpYyBhanVzdENyb3BSZWN0YW5nbGUoZXZlbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF07XG5cbiAgICBjb25zdCByZWN0ID0gZXZlbnQudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgY29uc3QgeCA9IE1hdGgubWluKHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQsIHRoaXMubW91c2VQb3NpdGlvbi54KSxcbiAgICAgIHkgPSBNYXRoLm1pbih0b3VjaC5jbGllbnRZIC0gcmVjdC50b3AsIHRoaXMubW91c2VQb3NpdGlvbi55KSxcbiAgICAgIHcgPSBNYXRoLmFicyh0b3VjaC5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gdGhpcy5tb3VzZVBvc2l0aW9uLngpLFxuICAgICAgaCA9IE1hdGguYWJzKHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCAtIHRoaXMubW91c2VQb3NpdGlvbi55KTtcblxuICAgIGlmICghdyB8fCAhaCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMuY3JvcFJlY3RhbmdsZVxuICAgICAgLnNldCgnbGVmdCcsIHgpXG4gICAgICAuc2V0KCd0b3AnLCB5KVxuICAgICAgLnNldCgnd2lkdGgnLCB3KVxuICAgICAgLnNldCgnaGVpZ2h0JywgaCk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHVibGljIHN0YXJ0U2VsZWN0aW5nQ3JvcFJlY3RhbmdsZShldmVudCk6IHZvaWQge1xuICAgIHRoaXMuY3JvcFN0YXJ0aW5nUG9zaXRpb24gPSB7IHg6IHRoaXMuY2FudmFzLmxlZnQsIHk6IHRoaXMuY2FudmFzLnRvcCB9O1xuXG4gICAgY29uc3QgdG91Y2ggPSBldmVudC50b3VjaGVzWzBdO1xuICAgIGNvbnN0IHJlY3QgPSBldmVudC50YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUubGVmdCA9IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQ7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnRvcCA9IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcDtcbiAgICB0aGlzLmNyb3BSZWN0YW5nbGUuc2V0Q29vcmRzKCk7XG5cbiAgICB0aGlzLm1vdXNlUG9zaXRpb24gPSB7IHg6IHRvdWNoLmNsaWVudFggLSByZWN0LmxlZnQsIHk6IHRvdWNoLmNsaWVudFkgLSByZWN0LnRvcCB9O1xuXG4gICAgdGhpcy5jYW52YXMucmVuZGVyQWxsKCk7XG4gICAgdGhpcy5jcm9wUmVjdGFuZ2xlLnZpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzLmJyaW5nVG9Gcm9udCh0aGlzLmNyb3BSZWN0YW5nbGUpO1xuICB9XG5cbiAgcHVibGljIGRpc2FibGVTZWxlY3Rpb24oKSB7XG4gICAgdGhpcy5jYW52YXMuc2VsZWN0aW9uID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIG1vdmVBbGxPYmplY3RzSW5DYW52YXMoeDogbnVtYmVyLCB5OiBudW1iZXIsIHNjYWxlRmFjdG9yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBvYmplY3RzID0gdGhpcy5jYW52YXMuZ2V0T2JqZWN0cygpO1xuICAgIGZvciAoY29uc3Qgb2JqIG9mIG9iamVjdHMpIHtcbiAgICAgIG9iai5sZWZ0ICs9IHg7XG4gICAgICBvYmoubGVmdCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zY2FsZVggKj0gc2NhbGVGYWN0b3I7XG4gICAgICBvYmoudG9wICs9IHk7XG4gICAgICBvYmouc2NhbGVZICo9IHNjYWxlRmFjdG9yO1xuICAgICAgb2JqLnRvcCAqPSBzY2FsZUZhY3RvcjtcbiAgICAgIG9iai5zZXRDb29yZHMoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ3JvdXBTZWxlY3RlZE9iamVjdHMoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlT2JqZWN0cyA9IHRoaXMuY2FudmFzLmdldEFjdGl2ZU9iamVjdHMoKTtcblxuICAgIGlmIChhY3RpdmVPYmplY3RzKSB7XG4gICAgICBjb25zdCBvYmplY3RzID0gW107XG5cbiAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIGFjdGl2ZU9iamVjdHMpIHtcbiAgICAgICAgb2JqZWN0cy5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbGV0ZVNlbGVjdGVkT2JqZWN0cygpO1xuXG4gICAgICBjb25zdCBncm91cCA9IG5ldyBmYWJyaWMuR3JvdXAob2JqZWN0cyk7XG4gICAgICB0aGlzLmNhbnZhcy5hZGQoZ3JvdXApO1xuICAgICAgZ3JvdXAuc2V0Q29vcmRzKCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnNldEFjdGl2ZU9iamVjdChncm91cCk7XG5cbiAgICAgIHRoaXMuY2FudmFzLnJlbmRlckFsbCgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXN0UGFuUG9zaXRpb24oZXZlbnQpIHtcbiAgICB0aGlzLmxhc3RQYW5Qb3NpdGlvbiA9IG5ldyBmYWJyaWMuUG9pbnQoZXZlbnQudG91Y2hlc1swXS5jbGllbnRYLCBldmVudC50b3VjaGVzWzBdLmNsaWVudFkpO1xuICB9XG5cbiAgcHVibGljIHBhbkNhbnZhcyhldmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGRlbHRhID0gbmV3IGZhYnJpYy5Qb2ludChcbiAgICAgIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMubGFzdFBhblBvc2l0aW9uLngsXG4gICAgICBldmVudC50b3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLmxhc3RQYW5Qb3NpdGlvbi55XG4gICAgKTtcblxuICAgIHRoaXMuY2FudmFzLnJlbGF0aXZlUGFuKGRlbHRhKTtcbiAgICB0aGlzLnByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCk7XG5cbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgICB0aGlzLnNldExhc3RQYW5Qb3NpdGlvbihldmVudCk7XG4gIH1cblxuICBwcml2YXRlIHByZXZlbnRQYW5PdXRzaWRlQ2FudmFzKCkge1xuICAgIGNvbnN0IGNhbnZhc1ZpZXdQb3J0ID0gdGhpcy5jYW52YXMudmlld3BvcnRUcmFuc2Zvcm07XG5cbiAgICBjb25zdCBpbWFnZUhlaWdodCA9IHRoaXMuY2FudmFzLmhlaWdodCAqIGNhbnZhc1ZpZXdQb3J0WzBdO1xuICAgIGNvbnN0IGltYWdlV2lkdGggPSB0aGlzLmNhbnZhcy53aWR0aCAqIGNhbnZhc1ZpZXdQb3J0WzBdO1xuXG4gICAgY29uc3QgYm90dG9tRW5kUG9pbnQgPSB0aGlzLmNhbnZhcy5oZWlnaHQgKiAoY2FudmFzVmlld1BvcnRbMF0gLSAxKTtcbiAgICBpZiAoY2FudmFzVmlld1BvcnRbNV0gPj0gMCB8fCAtYm90dG9tRW5kUG9pbnQgPiBjYW52YXNWaWV3UG9ydFs1XSkge1xuICAgICAgICBjYW52YXNWaWV3UG9ydFs1XSA9IChjYW52YXNWaWV3UG9ydFs1XSA+PSAwKSA/IDAgOiAtYm90dG9tRW5kUG9pbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgcmlnaHRFbmRQb2ludCA9IHRoaXMuY2FudmFzLndpZHRoICogKGNhbnZhc1ZpZXdQb3J0WzBdIC0gMSk7XG4gICAgaWYgKGNhbnZhc1ZpZXdQb3J0WzRdID49IDAgfHwgLXJpZ2h0RW5kUG9pbnQgPiBjYW52YXNWaWV3UG9ydFs0XSkge1xuICAgICAgICBjYW52YXNWaWV3UG9ydFs0XSA9IChjYW52YXNWaWV3UG9ydFs0XSA+PSAwKSA/IDAgOiAtcmlnaHRFbmRQb2ludDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgem9vbShldmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHBvaW50ID0gbmV3IGZhYnJpYy5Qb2ludChldmVudC5jZW50ZXIueCwgZXZlbnQuY2VudGVyLnkpO1xuXG4gICAgbGV0IHpvb20gPSB0aGlzLmNhbnZhcy5nZXRab29tKCk7XG4gICAgaWYgKGV2ZW50LmFkZGl0aW9uYWxFdmVudCA9PT0gJ3BpbmNob3V0Jykge1xuICAgICAgem9vbSAqPSAxLjA1O1xuICAgIH1cbiAgICBpZiAoZXZlbnQuYWRkaXRpb25hbEV2ZW50ID09PSAncGluY2hpbicpIHtcbiAgICAgIHpvb20gLz0gMS4wNTtcbiAgICB9XG5cbiAgICBpZiAoem9vbSA8IDEpIHtcbiAgICAgIHpvb20gPSAxO1xuICAgICAgdGhpcy5jYW52YXMuem9vbVRvUG9pbnQobmV3IGZhYnJpYy5Qb2ludCgwLCAwKSwgem9vbSk7XG4gICAgICB0aGlzLmNhbnZhcy5hYnNvbHV0ZVBhbihuZXcgZmFicmljLlBvaW50KDAsIDApKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHpvb20gPiAxMCkge1xuICAgICAgICB6b29tID0gMTA7XG4gICAgICB9XG4gICAgICB0aGlzLmNhbnZhcy56b29tVG9Qb2ludChwb2ludCwgem9vbSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRGcmVlRHJhd2luZ0JydXNoV2lkdGhGcm9tWm9vbSh6b29tKTtcbiAgICB0aGlzLmNhbnZhcy5yZW5kZXJBbGwoKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgRXZlbnRFbWl0dGVyLCB0cmFuc2l0aW9uLCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aW9uU2hlZXRDb250cm9sbGVyIH0gZnJvbSAnaW9uaWMtYW5ndWxhcic7XG5pbXBvcnQgeyBHZXN0dXJlIH0gZnJvbSAnaW9uaWMtYW5ndWxhci9nZXN0dXJlcy9nZXN0dXJlJztcbmltcG9ydCB7IEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlIH0gZnJvbSAnLi8uLi9jb25zdGFudHMvYXZhaWxhYmxlLWdlb21ldHJpYy1zaGFwZXMnO1xuaW1wb3J0IHsgQ2FudmFzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuLy4uL3NlcnZpY2VzL2NhbnZhcy1tYW5hZ2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgZmFicmljIH0gZnJvbSAnZmFicmljJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tIFwiQG5neC10cmFuc2xhdGUvY29yZVwiO1xuXG5jb25zdCBCbGFjayA9ICcjMDAwMDAwJztcbmNvbnN0IFRyYW5zcGFyZW50ID0gJ3RyYW5zcGFyZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLW1vYmlsZS1za2V0Y2gtdG9vbCcsXG4gIHRlbXBsYXRlOiBgPGlvbi1jb250ZW50PlxuICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJkaXYtY2FudmFzLWNvbnRhaW5lclwiXG4gICAgICAgICh0b3VjaHN0YXJ0KT1cIm1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAgICAgKHRvdWNobW92ZSk9XCJtb3VzZU1vdmUoJGV2ZW50KVwiXG4gICAgICAgICh0b3VjaGVuZCk9XCJtb3VzZVVwKCRldmVudClcIlxuICAgICAgICAjcGluY2hFbGVtZW50XG4gICAgPlxuICAgICAgICA8Y2FudmFzIGlkPVwiY2FudmFzXCI+PC9jYW52YXM+XG5cbiAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJjb2xvci1waWNrZXJcIlxuICAgICAgICAgICAgKm5nSWY9XCJpc1NlbGVjdGluZ0NvbG9yXCJcbiAgICAgICAgPlxuICAgICAgICAgICAgPGlvbi1ncmlkIGZpeGVkPlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NjAwMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2MDAwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NjMzMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2MzMwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NjY2MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2NjYwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDY2MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwNjYwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDAwNjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwMDA2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NjAwNjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2MDA2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzAwMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0NDMDAwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzY2MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0NDNjYwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQ0NDMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0NDQ0MwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMENDMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwQ0MwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDAwQ0NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwMDBDQycpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDQzAwQ0NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0NDMDBDQycpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjAwMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGMDAwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjgwMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGODAwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkZGMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGRkYwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMEZGMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwRkYwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDAwRkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwMDBGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjAwRkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGMDBGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjY2NjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGNjY2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkIyNjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGQjI2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkZGNjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGRkY2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NkZGNjZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2RkY2NicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2NjY2RkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzY2NjZGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjY2RkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGNjZGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjk5OTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGOTk5OScpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkNDOTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGQ0M5OScpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkZGOTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGRkY5OScpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM5OUZGOTlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzk5RkY5OScpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM5OTk5RkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzk5OTlGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRjk5RkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGOTlGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuXG4gICAgICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNGRkZGRkZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0ZGRkZGRicpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiNDMEMwQzBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignI0MwQzBDMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM4MDgwODBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzgwODA4MCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiM2MDYwNjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzYwNjA2MCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMzMDMwMzBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzYwNjA2MCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgICAgICA8aW9uLWNvbFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU9XCJiYWNrZ3JvdW5kOiMwMDAwMDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHRhcCk9XCJzZXRDb2xvcignIzAwMDAwMCcpXCJcbiAgICAgICAgICAgICAgICAgICAgPsOCwqBcbiAgICAgICAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICAgIDwvaW9uLWdyaWQ+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9pb24tY29udGVudD5cblxuPGlvbi1mb290ZXI+XG4gICAgPGlvbi10b29sYmFyPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZGl2LWVkaXQtdG9vbGJhclwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnV0dG9uLWVkaXQtdG9vbGJhclwiXG4gICAgICAgICAgICAgICAgaW9uLWJ1dHRvblxuICAgICAgICAgICAgICAgIGxhcmdlXG4gICAgICAgICAgICAgICAgW2NsZWFyXT1cInRydWVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJwcmVzZW50U2hhcGVBY3Rpb25TaGVldCgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZhcyBmYS1zaGFwZXNcIlxuICAgICAgICAgICAgICAgICAgICBpZD1cImljb25cIlxuICAgICAgICAgICAgICAgID48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnV0dG9uLWVkaXQtdG9vbGJhclwiXG4gICAgICAgICAgICAgICAgaW9uLWJ1dHRvblxuICAgICAgICAgICAgICAgIGxhcmdlXG4gICAgICAgICAgICAgICAgW2NsZWFyXT1cInRydWVcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJwcmVzZW50UGljdG9ncmFtc0FjdGlvblNoZWV0KClcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaGFzUGljdG9ncmFtc1wiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGlcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmYXMgZmEtaW1hZ2VzXCJcbiAgICAgICAgICAgICAgICAgICAgaWQ9XCJpY29uXCJcbiAgICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBjbGFzcz1cImJ1dHRvbi1lZGl0LXRvb2xiYXJcIlxuICAgICAgICAgICAgICAgIGlvbi1idXR0b25cbiAgICAgICAgICAgICAgICBsYXJnZVxuICAgICAgICAgICAgICAgIFtjbGVhcl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwicHJlc2VudEVkaXRBY3Rpb25TaGVldCgpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZhcyBmYS1lZGl0XCJcbiAgICAgICAgICAgICAgICAgICAgaWQ9XCJpY29uXCJcbiAgICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBjbGFzcz1cImJ1dHRvbi1lZGl0LXRvb2xiYXJcIlxuICAgICAgICAgICAgICAgIGlvbi1idXR0b25cbiAgICAgICAgICAgICAgICBsYXJnZVxuICAgICAgICAgICAgICAgIFtjbGVhcl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZHJhdygpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZhcyBmYS1wZW5jaWwtYWx0XCJcbiAgICAgICAgICAgICAgICAgICAgaWQ9XCJpY29uXCJcbiAgICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBjbGFzcz1cImJ1dHRvbi1lZGl0LXRvb2xiYXJcIlxuICAgICAgICAgICAgICAgIGlvbi1idXR0b25cbiAgICAgICAgICAgICAgICBsYXJnZVxuICAgICAgICAgICAgICAgIFtjbGVhcl09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25Db2xvckNsaWNrZWQoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGlcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmYXMgZmEtcGFsZXR0ZVwiXG4gICAgICAgICAgICAgICAgICAgIGlkPVwiaWNvblwiXG4gICAgICAgICAgICAgICAgPjwvaT5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJidXR0b24tZWRpdC10b29sYmFyXCJcbiAgICAgICAgICAgICAgICBpb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgbGFyZ2VcbiAgICAgICAgICAgICAgICBbY2xlYXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInVuZG8oKVwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJpc1VuZG9BdmFpbGFibGVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxpXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmFzIGZhLXVuZG9cIlxuICAgICAgICAgICAgICAgICAgICBpZD1cImljb25cIlxuICAgICAgICAgICAgICAgID48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8L2Rpdj5cbiAgICA8L2lvbi10b29sYmFyPlxuPC9pb24tZm9vdGVyPlxuYCxcbiAgc3R5bGVzOiBbYC5kaXYtY2FudmFzLWNvbnRhaW5lcnt0ZXh0LWFsaWduOmNlbnRlcjtoZWlnaHQ6MTAwJTt3aWR0aDoxMDAlOy1vLW9iamVjdC1maXQ6Y29udGFpbjtvYmplY3QtZml0OmNvbnRhaW59LnNjcm9sbC1jb250ZW50e3BhZGRpbmc6MCFpbXBvcnRhbnQ7b3ZlcmZsb3cteTpoaWRkZW59LmRpdi1lZGl0LXRvb2xiYXJ7dGV4dC1hbGlnbjpjZW50ZXJ9LmJ1dHRvbi1lZGl0LXRvb2xiYXJ7cGFkZGluZzo0JSFpbXBvcnRhbnQ7bWFyZ2luOjAhaW1wb3J0YW50fS5hY3Rpb24tc2hlZXQtYnV0dG9ue2ZvbnQtZmFtaWx5OkZvbnRBd2Vzb21lLEFyaWFsfS5jb2xvci1waWNrZXJ7cG9zaXRpb246YWJzb2x1dGU7d2lkdGg6MTAwJTtoZWlnaHQ6YXV0bztib3R0b206MDtsZWZ0OjB9I2ljb257Y29sb3I6I2IzMjAxN31gXSxcbiAgcHJvdmlkZXJzOiBbQ2FudmFzTWFuYWdlclNlcnZpY2VdXG59KVxuZXhwb3J0IGNsYXNzIE1vYmlsZVNrZXRjaFRvb2xDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBnZXN0dXJlOiBHZXN0dXJlO1xuICBAVmlld0NoaWxkKCdwaW5jaEVsZW1lbnQnKSBlbGVtZW50O1xuXG4gIHB1YmxpYyBmaWxsQ29sb3I6IHN0cmluZztcbiAgcHVibGljIHN0cm9rZUNvbG9yOiBzdHJpbmc7XG4gIHB1YmxpYyBpc0Nyb3BwaW5nOiBib29sZWFuO1xuICBwdWJsaWMgaXNVbmRvQXZhaWxhYmxlOiBib29sZWFuO1xuICBwdWJsaWMgaXNTZWxlY3RpbmdDb2xvcjogYm9vbGVhbjtcbiAgcHVibGljIGlzRHJhd2luZzogYm9vbGVhbjtcblxuICBASW5wdXQoKSBwdWJsaWMgaW1hZ2VEYXRhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBsb2FkZWRKc29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBpY29uc1BhdGg6IHN0cmluZztcbiAgQElucHV0KCkgcHVibGljIGljb25zOiBbc3RyaW5nXTtcblxuICBAT3V0cHV0KCkgcHVibGljIGNhbnZhcyA9IG5ldyBFdmVudEVtaXR0ZXI8ZmFicmljLkNhbnZhcz4oKTtcblxuICBwcml2YXRlIGlzTG9hZGVkOiBib29sZWFuO1xuICBwcml2YXRlIGlzUGFubmluZzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwcmV2aW91c0ltYWdlRGF0YTogc3RyaW5nO1xuICBwcml2YXRlIGN1cnJlbnRKc29uOiBKU09OO1xuICBwcml2YXRlIHByZXZpb3VzSnNvbjogSlNPTjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aW9uU2hlZXRDdHJsOiBBY3Rpb25TaGVldENvbnRyb2xsZXIsXG4gICAgcHJpdmF0ZSBjYW52YXNNYW5hZ2VyU2VydmljZTogQ2FudmFzTWFuYWdlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5zdHJva2VDb2xvciA9IEJsYWNrO1xuICAgIHRoaXMuZmlsbENvbG9yID0gVHJhbnNwYXJlbnQ7XG4gICAgdGhpcy5pc0Nyb3BwaW5nID0gZmFsc2U7XG4gICAgdGhpcy5pc0xvYWRlZCA9IGZhbHNlO1xuICAgIHRoaXMuaXNVbmRvQXZhaWxhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5pc1NlbGVjdGluZ0NvbG9yID0gZmFsc2U7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAodGhpcy5pbWFnZURhdGEpIHtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW1wdHlDYW52YXMoKTtcbiAgICAgIGlmICh0aGlzLmxvYWRlZEpzb24gPT0gbnVsbCB8fCB0aGlzLmxvYWRlZEpzb24ubGVuZ3RoIDwgMTApIHtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5zZXRCYWNrZ3JvdW5kRnJvbVVSTCh0aGlzLmltYWdlRGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnByZXZpb3VzSnNvbiA9IEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKTtcbiAgICAgICAgdGhpcy5jdXJyZW50SnNvbiA9IHRoaXMucHJldmlvdXNKc29uO1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlXG4gICAgICAgICAgLmxvYWRmcm9tSnNvbihKU09OLnBhcnNlKHRoaXMubG9hZGVkSnNvbikpO1xuICAgICAgfVxuICAgICAgdGhpcy5pc0xvYWRlZCA9IHRydWU7XG4gICAgICB0aGlzLnByZXZpb3VzSW1hZ2VEYXRhID0gdGhpcy5pbWFnZURhdGE7XG4gICAgfVxuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgaWYgKHRoaXMuaXNMb2FkZWQpIHtcbiAgICAgIGlmICh0aGlzLmxvYWRlZEpzb24gPT09IG51bGwgfHwgdGhpcy5sb2FkZWRKc29uLmxlbmd0aCA8IDEwIHx8IHRoaXMuaW1hZ2VEYXRhICE9PSB0aGlzLnByZXZpb3VzSW1hZ2VEYXRhKSB7XG4gICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZW1wdHlDYW52YXMoKTtcbiAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5zZXRCYWNrZ3JvdW5kRnJvbVVSTCh0aGlzLmltYWdlRGF0YSk7XG4gICAgICAgIHRoaXMucHJldmlvdXNJbWFnZURhdGEgPSB0aGlzLmltYWdlRGF0YTtcbiAgICAgICAgdGhpcy5jdXJyZW50SnNvbiA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMubG9hZGVkSnNvbiAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5jdXJyZW50SnNvbikpIHtcbiAgICAgICAgICB0aGlzLnByZXZpb3VzSnNvbiA9IEpTT04ucGFyc2UodGhpcy5sb2FkZWRKc29uKTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRKc29uID0gdGhpcy5wcmV2aW91c0pzb247XG4gICAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZVxuICAgICAgICAgICAgLmxvYWRmcm9tSnNvbihKU09OLnBhcnNlKHRoaXMubG9hZGVkSnNvbikpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmdlc3R1cmUgPSBuZXcgR2VzdHVyZSh0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCk7XG4gICAgdGhpcy5nZXN0dXJlLmxpc3RlbigpO1xuICAgIHRoaXMuZ2VzdHVyZS5vbigncGluY2gnLCAkZXZlbnQgPT4gdGhpcy5waW5jaCgkZXZlbnQpKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZ2VzdHVyZS5kZXN0cm95KCk7XG59XG5cbiAgcHJpdmF0ZSBwaW5jaEV2ZW50KGV2ZW50KSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmVtcHR5Q2FudmFzKCk7XG4gIH1cblxuICBnZXQgaGFzUGljdG9ncmFtcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISghdGhpcy5pY29ucyk7XG4gIH1cblxuICBwdWJsaWMgYWRkVGV4dCgpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZFRleHQodGhpcy5zdHJva2VDb2xvciwgJ3RleHQgJyk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgYWRkU2hhcGUoc2hhcGU6IHN0cmluZykge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgdGhpcy5maWxsQ29sb3IsXG4gICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZVtzaGFwZV1cbiAgICApO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGFkZEltYWdlKHNvdXJjZTogc3RyaW5nKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRJbWFnZSh0aGlzLmljb25zUGF0aCArIHNvdXJjZSk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlU3Ryb2tlQ29sb3IoKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5jaGFuZ2VTZWxlY3RlZE9iamVjdHNTdHJva2VDb2xvcihcbiAgICAgIHRoaXMuc3Ryb2tlQ29sb3JcbiAgICApO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0RnJlZURyYXdpbmdCcnVzaENvbG9yKHRoaXMuc3Ryb2tlQ29sb3IpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIGJyaW5nRm93YXJkKCkge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYnJpbmdTZWxlY3RlZE9iamVjdHNUb0Zyb250KCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgc2VuZFRvQmFjaygpIHtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNlbmRTZWxlY3RlZE9iamVjdHNUb0JhY2soKTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBjcm9wKCkge1xuICAgIHRoaXMuaXNDcm9wcGluZyA9IHRydWU7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5kaXNhYmxlU2VsZWN0aW9uKCk7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRTZWxlY3Rpb25SZWN0YW5nbGUoKTtcbiAgICB0aGlzLmlzVW5kb0F2YWlsYWJsZSA9IHRydWU7XG4gICAgdGhpcy5wcmV2aW91c0pzb24gPSB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmpzb25Gcm9tQ2FudmFzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgZGVsZXRlU2VsZWN0aW9uKCkge1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuZGVsZXRlU2VsZWN0ZWRPYmplY3RzKCk7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgbW91c2VVcChldmVudCkge1xuICAgIGlmICh0aGlzLmlzQ3JvcHBpbmcpIHtcbiAgICAgIHRoaXMuaXNDcm9wcGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5jcm9wSW1hZ2UoKTtcbiAgICAgIHRoaXMuaXNVbmRvQXZhaWxhYmxlID0gdHJ1ZTtcbiAgICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBtb3VzZU1vdmUoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5pc0Nyb3BwaW5nKSB7XG4gICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFqdXN0Q3JvcFJlY3RhbmdsZShldmVudCk7XG4gICAgfSBlbHNlIGlmIChldmVudC50b3VjaGVzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnBhbkNhbnZhcyhldmVudCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG1vdXNlRG93bihldmVudCkge1xuICAgIGlmICh0aGlzLmlzQ3JvcHBpbmcpIHtcbiAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc3RhcnRTZWxlY3RpbmdDcm9wUmVjdGFuZ2xlKGV2ZW50KTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuc2V0TGFzdFBhblBvc2l0aW9uKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcGluY2goZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2Uuem9vbShldmVudCk7XG4gIH1cblxuICBwdWJsaWMgZ3JvdXAoKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5ncm91cFNlbGVjdGVkT2JqZWN0cygpO1xuICAgIHRoaXMuZW1pdENhbnZhcygpO1xuICB9XG5cbiAgcHVibGljIHVuZG8oKSB7XG4gICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5sb2FkZnJvbUpzb24odGhpcy5wcmV2aW91c0pzb24pO1xuICAgIHRoaXMuaXNVbmRvQXZhaWxhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0Q2FudmFzKCk7XG4gIH1cblxuICBwdWJsaWMgb25Db2xvckNsaWNrZWQoKSB7XG4gICAgdGhpcy5pc1NlbGVjdGluZ0NvbG9yID0gdHJ1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb2xvcihjb2xvcjogc3RyaW5nKSB7XG4gICAgdGhpcy5zdHJva2VDb2xvciA9IGNvbG9yO1xuICAgIHRoaXMuY2hhbmdlU3Ryb2tlQ29sb3IoKTtcbiAgICB0aGlzLmlzU2VsZWN0aW5nQ29sb3IgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXRDYW52YXMoKTtcbiAgfVxuXG4gIHB1YmxpYyBkcmF3KCkge1xuICAgIHRoaXMuaXNEcmF3aW5nID0gIXRoaXMuaXNEcmF3aW5nO1xuICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UudG9nZ2xlRnJlZURyYXdpbmcoKTtcbiAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLnNldEZyZWVEcmF3aW5nQnJ1c2hDb2xvcih0aGlzLnN0cm9rZUNvbG9yKTtcbiAgfVxuXG4gIHByaXZhdGUgZGlzYWJsZURyYXdpbmcoKSB7XG4gICAgaWYgKHRoaXMuaXNEcmF3aW5nKSB7XG4gICAgICB0aGlzLmlzRHJhd2luZyA9IGZhbHNlO1xuICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS50b2dnbGVGcmVlRHJhd2luZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNsYXRlU2hhcGVCdXR0b25zVGV4dCgpOiBBcnJheTxTdHJpbmc+IHtcbiAgICBjb25zdCB0cmFuc2xhdGlvbkFycmF5ID0gW107XG4gICAgdHJhbnNsYXRpb25BcnJheS5wdXNoKHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ3JlY3RhbmdsZScpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgndHJpYW5nbGUnKSk7XG4gICAgdHJhbnNsYXRpb25BcnJheS5wdXNoKHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2NpcmNsZScpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnbGluZScpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnY3Jvc3MnKSk7XG4gICAgdHJhbnNsYXRpb25BcnJheS5wdXNoKHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ3RleHQnKSk7XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uQXJyYXk7XG4gIH1cblxuICBwdWJsaWMgcHJlc2VudFNoYXBlQWN0aW9uU2hlZXQoKSB7XG4gICAgdGhpcy5kaXNhYmxlRHJhd2luZygpO1xuXG4gICAgY29uc3QgdGl0bGVUZXh0ID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnYWRkR2VvbWV0cmljU2hhcGUnKTtcbiAgICBjb25zdCBidXR0b25zVGV4dCA9IHRoaXMudHJhbnNsYXRlU2hhcGVCdXR0b25zVGV4dCgpO1xuICAgIGxldCBpID0gMDtcblxuICAgIGNvbnN0IGFjdGlvblNoZWV0ID0gdGhpcy5hY3Rpb25TaGVldEN0cmwuY3JlYXRlKHtcbiAgICAgIHRpdGxlOiB0aXRsZVRleHQsXG4gICAgICBidXR0b25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjBjOCAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuYWRkR2VvbWV0cmljU2hhcGUoXG4gICAgICAgICAgICAgIHRoaXMuc3Ryb2tlQ29sb3IsXG4gICAgICAgICAgICAgIHRoaXMuZmlsbENvbG9yLFxuICAgICAgICAgICAgICBBdmFpbGFibGVHZW9tZXRyaWNTaGFwZS5SZWN0YW5nbGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYwZDggICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgICAgICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgICAgICAgICAgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuVHJpYW5nbGVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYxMTEgICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgICAgICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgICAgICAgICAgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuQ2lyY2xlXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMDY4ICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYW52YXNNYW5hZ2VyU2VydmljZS5hZGRHZW9tZXRyaWNTaGFwZShcbiAgICAgICAgICAgICAgdGhpcy5zdHJva2VDb2xvcixcbiAgICAgICAgICAgICAgdGhpcy5maWxsQ29sb3IsXG4gICAgICAgICAgICAgIEF2YWlsYWJsZUdlb21ldHJpY1NoYXBlLkxpbmVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYwNjcgICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZEdlb21ldHJpY1NoYXBlKFxuICAgICAgICAgICAgICB0aGlzLnN0cm9rZUNvbG9yLFxuICAgICAgICAgICAgICB0aGlzLmZpbGxDb2xvcixcbiAgICAgICAgICAgICAgQXZhaWxhYmxlR2VvbWV0cmljU2hhcGUuQ3Jvc3NcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdGV4dDogJ1xcdWYwMzEgICAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNhbnZhc01hbmFnZXJTZXJ2aWNlLmFkZFRleHQodGhpcy5zdHJva2VDb2xvciwgJycpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuICAgIGFjdGlvblNoZWV0LnByZXNlbnQoKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNsYXRlRWRpdEJ1dHRvbnNUZXh0KCk6IEFycmF5PFN0cmluZz4ge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uQXJyYXkgPSBbXTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnY3JvcCcpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnZ3JvdXAnKSk7XG4gICAgdHJhbnNsYXRpb25BcnJheS5wdXNoKHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2JyaW5nVG9Gcm9udCcpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnc2VuZFRvQmFjaycpKTtcbiAgICB0cmFuc2xhdGlvbkFycmF5LnB1c2godGhpcy50cmFuc2xhdGUuaW5zdGFudCgnZGVsZXRlJykpO1xuICAgIHJldHVybiB0cmFuc2xhdGlvbkFycmF5O1xuICB9XG5cbiAgcHVibGljIHByZXNlbnRFZGl0QWN0aW9uU2hlZXQoKSB7XG4gICAgdGhpcy5kaXNhYmxlRHJhd2luZygpO1xuXG4gICAgY29uc3QgdGl0bGVUZXh0ID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnZWRpdGlvbicpO1xuXG4gICAgY29uc3QgYnV0dG9uc1RleHQgPSB0aGlzLnRyYW5zbGF0ZUVkaXRCdXR0b25zVGV4dCgpO1xuICAgIGxldCBpID0gMDtcblxuICAgIGNvbnN0IGFjdGlvblNoZWV0ID0gdGhpcy5hY3Rpb25TaGVldEN0cmwuY3JlYXRlKHtcbiAgICAgIHRpdGxlOiB0aXRsZVRleHQsXG4gICAgICBidXR0b25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjEyNSAnICsgYnV0dG9uc1RleHRbaSsrXSxcbiAgICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNyb3AoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjI0NyAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ3JvdXAoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjBkZSAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYnJpbmdGb3dhcmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB0ZXh0OiAnXFx1ZjBkZCAgICcgKyBidXR0b25zVGV4dFtpKytdLFxuICAgICAgICAgIGhhbmRsZXI6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2VuZFRvQmFjaygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHRleHQ6ICdcXHVmMWY4ICAgJyArIGJ1dHRvbnNUZXh0W2krK10sXG4gICAgICAgICAgaGFuZGxlcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZWxldGVTZWxlY3Rpb24oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9KTtcbiAgICBhY3Rpb25TaGVldC5wcmVzZW50KCk7XG4gIH1cblxuICBwdWJsaWMgcHJlc2VudFBpY3RvZ3JhbXNBY3Rpb25TaGVldCgpIHtcbiAgICB0aGlzLmRpc2FibGVEcmF3aW5nKCk7XG5cbiAgICBjb25zdCBidXR0b25zID0gW107XG4gICAgY29uc3QgYWN0aW9uU2hlZXRTdHlsZXMgPSBbXTtcbiAgICBjb25zdCBpbWFnZXMgPSB0aGlzLmljb25zO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1hZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgICBzdHlsZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgIHN0eWxlLmlubmVySFRNTCA9XG4gICAgICAgICcuY3VzdG9tQ1NTQ2xhc3MnICtcbiAgICAgICAgaSArXG4gICAgICAgICd7YmFja2dyb3VuZDogdXJsKCcgK1xuICAgICAgICBcIidcIiArXG4gICAgICAgIHRoaXMuaWNvbnNQYXRoICtcbiAgICAgICAgaW1hZ2VzW2ldICtcbiAgICAgICAgXCInXCIgK1xuICAgICAgICAnKSBuby1yZXBlYXQgIWltcG9ydGFudDtwYWRkaW5nLWxlZnQ6NTBweCAhaW1wb3J0YW50O2hlaWdodDo4MHB4OyBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBsZWZ0IGNlbnRlciAhaW1wb3J0YW50O30nO1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgICBhY3Rpb25TaGVldFN0eWxlcy5wdXNoKHN0eWxlKTtcbiAgICAgIGJ1dHRvbnMucHVzaCh7XG4gICAgICAgIHJvbGU6ICdkZXN0cnVjdGl2ZScsXG4gICAgICAgIHRleHQ6IGltYWdlc1tpXSxcbiAgICAgICAgY3NzQ2xhc3M6ICdjdXN0b21DU1NDbGFzcycgKyBpLFxuICAgICAgICBoYW5kbGVyOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRJbWFnZShpbWFnZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCB0aXRsZVRleHQgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdhZGRQaWN0b2dyYW0nKTtcblxuICAgIGNvbnN0IGFjdGlvblNoZWV0ID0gdGhpcy5hY3Rpb25TaGVldEN0cmwuY3JlYXRlKHtcbiAgICAgIHRpdGxlOiB0aXRsZVRleHQsXG4gICAgICBidXR0b25zOiBidXR0b25zXG4gICAgfSk7XG4gICAgYWN0aW9uU2hlZXQub25EaWREaXNtaXNzKCgpID0+IHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0aW9uU2hlZXRTdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGFjdGlvblNoZWV0U3R5bGVzW2ldLnBhcmVudE5vZGUgIT0gbnVsbCkge1xuICAgICAgICAgIGFjdGlvblNoZWV0U3R5bGVzW2ldLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoYWN0aW9uU2hlZXRTdHlsZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBhY3Rpb25TaGVldC5wcmVzZW50KCk7XG4gIH1cblxuICBwdWJsaWMgZW1pdENhbnZhcygpIHtcbiAgICB0aGlzLmNhbnZhcy5lbWl0KHRoaXMuY2FudmFzTWFuYWdlclNlcnZpY2UuY2FudmFzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJb25pY01vZHVsZSB9IGZyb20gJ2lvbmljLWFuZ3VsYXInO1xuXG5pbXBvcnQgeyBNb2JpbGVTa2V0Y2hUb29sQ29tcG9uZW50IH0gZnJvbSAnLi9tb2JpbGUtY29tcG9uZW50L21vYmlsZS1za2V0Y2gtdG9vbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2FudmFzTWFuYWdlclNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2NhbnZhcy1tYW5hZ2VyLnNlcnZpY2UnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBJb25pY01vZHVsZV0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIE1vYmlsZVNrZXRjaFRvb2xDb21wb25lbnQsXG4gIF0sXG4gIHByb3ZpZGVyczogW1xuICAgIENhbnZhc01hbmFnZXJTZXJ2aWNlLFxuICBdLFxuICBleHBvcnRzOiBbTW9iaWxlU2tldGNoVG9vbENvbXBvbmVudF1cbn0pXG5leHBvcnQgY2xhc3MgU2tldGNoVG9vbE1vZHVsZSB7fVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsQUFBTyx1QkFBTSxVQUFVLEdBQUc7SUFDeEIsS0FBSyxFQUFFLEdBQUc7SUFDVixNQUFNLEVBQUUsR0FBRztJQUNYLElBQUksRUFBRSxFQUFFO0lBQ1IsR0FBRyxFQUFFLEVBQUU7SUFDUCxNQUFNLEVBQUUsR0FBRztJQUNYLE1BQU0sRUFBRSxFQUFFO0lBQ1YscUJBQXFCLEVBQUUsRUFBRTtJQUN6QixVQUFVLEVBQUUsRUFBRTtDQUNmLENBQUM7Ozs7OztBQ1RGO0lB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
\No newline at end of file