ng-feedback
Version:
An angular directive for sending feedback featuring Angular 6, Html2canvas, Angular Material, Rxjs, inspired by Google send feedback, based on angular-cli.
434 lines • 51.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { fromEvent as observableFromEvent } from 'rxjs';
import { takeUntil, finalize, map, mergeMap } from 'rxjs/operators';
import { Component, ViewChild, ElementRef, ChangeDetectorRef, HostListener } from '@angular/core';
import { MatDialogRef } from '@angular/material';
import { Feedback } from '../entity/feedback';
import { FeedbackService } from '../feedback.service';
import { Rectangle } from '../entity/rectangle';
export class FeedbackDialogComponent {
/**
* @param {?} dialogRef
* @param {?} feedbackService
* @param {?} detector
* @param {?} el
*/
constructor(dialogRef, feedbackService, detector, el) {
this.dialogRef = dialogRef;
this.feedbackService = feedbackService;
this.detector = detector;
this.el = el;
this.showToolbar = false;
this.vars = {};
this.feedback = new Feedback();
this.includeScreenshot = true;
this.showSpinner = true;
this.showToolbarTips = true;
this.drawColor = this.feedbackService.highlightedColor;
this.rectangles = [];
this.scrollWidth = document.documentElement.scrollWidth;
this.scrollHeight = document.documentElement.scrollHeight;
this.elCouldBeHighlighted = ['button', 'a', 'span', 'em', 'i', 'h1', 'h2', 'h3', 'h4',
'h5', 'h6', 'p', 'strong', 'small', 'sub', 'sup', 'b', 'time', 'img',
'video', 'input', 'label', 'select', 'textarea', 'article', 'summary', 'section'];
this.isDrawingRect = false;
this.feedback = new Feedback();
this.feedback.description = '';
this.vars = this.feedbackService.initialVariables;
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.feedbackService.screenshotCanvas$.subscribe((canvas) => {
this.showSpinner = false;
this.feedback.screenshot = canvas.toDataURL('image/png');
this.screenshotEle = this.feedbackService.getImgEle(canvas);
this.appendScreenshot();
});
this.feedbackService.isDraggingToolbar$.subscribe((isDragging) => {
if (isDragging) {
this.destroyCanvasListeners();
}
else {
this.addCanvasListeners();
}
});
this.dialogRef.afterClosed().subscribe((sendNow) => {
if (sendNow === true) {
this.feedbackService.setFeedback(this.feedback);
}
});
this.feedbackService.showBackDrop();
}
/**
* @return {?}
*/
expandDrawingBoard() {
this.showToolbar = true;
if (!this.drawCanvas) {
this.detector.detectChanges();
this.initBackgroundCanvas();
this.feedbackService.hideBackDrop();
}
this.addCanvasListeners();
this.el.nativeElement.appendChild(this.drawCanvas);
this.feedbackService.hideBackDrop();
console.log('expand the board');
}
/**
* @param {?} evt
* @return {?}
*/
onEscapeKeyDownHandler(evt) {
this.showToolbar = false;
this.includeScreenshot = true;
this.detector.detectChanges();
this.dialogRef.close('key down esc to close');
}
/**
* @param {?} manipulation
* @return {?}
*/
manipulate(manipulation) {
if (manipulation === 'done') {
this.showToolbarTips = false;
this.showSpinner = true;
this.destroyCanvasListeners();
this.showToolbar = false;
this.detector.detectChanges();
this.feedbackService.initScreenshotCanvas();
}
else {
this.startDraw(manipulation);
}
}
/**
* @param {?} color
* @return {?}
*/
startDraw(color) {
this.drawColor = color;
}
/**
* @return {?}
*/
isIncludeScreenshot() {
if (this.includeScreenshot) {
this.detector.detectChanges();
this.showSpinner = false;
this.appendScreenshot();
this.feedback.screenshot = this.screenshotEle.getAttribute('src');
}
else {
delete this.feedback['screenshot'];
this.showSpinner = true;
}
}
/**
* @return {?}
*/
appendScreenshot() {
if (this.screenshotParent) {
this.screenshotParent.nativeElement.appendChild(this.screenshotEle);
}
}
/**
* @return {?}
*/
initBackgroundCanvas() {
this.drawCanvas = /** @type {?} */ (document.getElementById('draw-canvas'));
// The canvas to draw, must use this way to initial the height and width
this.drawCanvas.style.height = this.scrollHeight + '';
this.drawCanvas.style.width = this.scrollWidth + '';
this.drawCanvas.height = this.scrollHeight;
this.drawCanvas.width = this.scrollWidth;
this.drawContainerRect();
}
/**
* @return {?}
*/
drawContainerRect() {
/** @type {?} */
const drawContext = this.drawCanvas.getContext('2d');
/** @type {?} */
const width = this.scrollWidth;
/** @type {?} */
const height = this.scrollHeight;
drawContext.beginPath();
drawContext.fillStyle = 'rgba(0,0,0,0.3)';
drawContext.clearRect(0, 0, width, height);
drawContext.fillRect(0, 0, width, height); // draw the rectangle
}
/**
* @param {?} rect
* @return {?}
*/
drawRectangle(rect) {
/** @type {?} */
const context = this.drawCanvas.getContext('2d');
context.lineJoin = 'round';
context.beginPath();
if (rect.color === this.feedbackService.hiddenColor) {
context.fillStyle = 'rgba(31, 31, 31, 0.75)';
context.fillRect(rect.startX, rect.startY, rect.width, rect.height);
context.rect(rect.startX, rect.startY, rect.width, rect.height);
}
else {
context.clearRect(rect.startX, rect.startY, rect.width, rect.height);
context.lineWidth = 5;
context.strokeStyle = rect.color;
context.rect(rect.startX, rect.startY, rect.width, rect.height);
context.stroke();
context.clearRect(rect.startX, rect.startY, rect.width, rect.height);
this.rectangles.forEach(tmpRect => {
if (tmpRect.color === this.feedbackService.highlightedColor) {
context.clearRect(tmpRect.startX, tmpRect.startY, tmpRect.width, tmpRect.height);
}
});
}
}
/**
* @return {?}
*/
addCanvasListeners() {
/** @type {?} */
const mouseUp = observableFromEvent(document.documentElement, 'mouseup');
/** @type {?} */
const mouseMove = observableFromEvent(document.documentElement, 'mousemove');
/** @type {?} */
const mouseDown = observableFromEvent(document.documentElement, 'mousedown');
/** @type {?} */
const scroll = observableFromEvent(window, 'scroll');
this.manuallyDrawRect(mouseDown, mouseMove, mouseUp);
this.autoDrawRect(mouseMove);
this.changeRectPosition(scroll);
}
/**
* @param {?} scroll
* @return {?}
*/
changeRectPosition(scroll) {
scroll.subscribe(event => {
/** @type {?} */
const currentWindowScrollX = window.scrollX;
/** @type {?} */
const currentWindowScrollY = window.scrollY;
this.rectangles.forEach(rect => {
rect.startY = rect.startY - (currentWindowScrollY - rect.windowScrollY);
rect.startX = rect.startX - (currentWindowScrollX - rect.windowScrollX);
rect.windowScrollY = currentWindowScrollY;
rect.windowScrollX = currentWindowScrollX;
});
this.drawPersistCanvasRectangles();
}, error => console.error(error));
}
/**
* @return {?}
*/
destroyCanvasListeners() {
if (this.manuallyDrawRect$) {
this.manuallyDrawRect$.unsubscribe();
}
if (this.autoDrawRect$) {
this.autoDrawRect$.unsubscribe();
}
}
/**
* @param {?} mouseDown
* @param {?} mouseMove
* @param {?} mouseUp
* @return {?}
*/
manuallyDrawRect(mouseDown, mouseMove, mouseUp) {
/** @type {?} */
const mouseDrag = mouseDown.pipe(mergeMap((mouseDownEvent) => {
if (this.showToolbarTips) {
this.showToolbarTips = false;
}
this.autoDrawRect$.unsubscribe();
this.isDrawingRect = true;
/** @type {?} */
const newRectangle = new Rectangle();
newRectangle.startX = mouseDownEvent.clientX;
newRectangle.startY = mouseDownEvent.clientY;
newRectangle.color = this.drawColor;
return mouseMove.pipe(map((mouseMoveEvent) => {
newRectangle.width = mouseMoveEvent.clientX - mouseDownEvent.clientX;
newRectangle.height = mouseMoveEvent.clientY - mouseDownEvent.clientY;
return newRectangle;
}), finalize(() => {
// click to draw rectangle
if (newRectangle.width === undefined || newRectangle.height === undefined ||
newRectangle.width === 0 || newRectangle.height === 0) {
/** @type {?} */
const rect = this.drawTempCanvasRectangle(mouseDownEvent);
if (rect) {
this.rectangles.push(rect);
}
}
else {
// drag to draw rectangle
if (newRectangle.height < 0) {
newRectangle.startY = newRectangle.startY + newRectangle.height;
newRectangle.height = Math.abs(newRectangle.height);
}
if (newRectangle.width < 0) {
newRectangle.startX = newRectangle.startX + newRectangle.width;
newRectangle.width = Math.abs(newRectangle.width);
}
this.rectangles.push(newRectangle);
}
this.drawPersistCanvasRectangles();
this.autoDrawRect(mouseMove);
this.isDrawingRect = false;
}), takeUntil(mouseUp));
}));
this.manuallyDrawRect$ = mouseDrag.subscribe((rec) => {
this.drawPersistCanvasRectangles();
this.drawRectangle(rec);
});
}
/**
* @param {?} mouseMove
* @return {?}
*/
autoDrawRect(mouseMove) {
this.autoDrawRect$ = mouseMove.subscribe({
next: (mouseMoveEvent) => {
this.drawPersistCanvasRectangles();
this.drawTempCanvasRectangle(mouseMoveEvent);
},
error: err => console.error('something wrong occurred: ' + err),
});
}
/**
* @return {?}
*/
drawPersistCanvasRectangles() {
this.drawContainerRect();
this.rectangles.forEach(tmpRect => {
this.drawRectangle(tmpRect);
});
}
/**
* @param {?} event
* @return {?}
*/
drawTempCanvasRectangle(event) {
/** @type {?} */
let rectangle = null;
/** @type {?} */
const clientX = event.clientX;
/** @type {?} */
const clientY = event.clientY;
/** @type {?} */
const els = document.elementsFromPoint(clientX, clientY);
/** @type {?} */
const el = els[2];
if ((!this.isExcludeRect(els)) && el && this.elCouldBeHighlighted.indexOf(el.nodeName.toLowerCase()) > -1) {
rectangle = new Rectangle();
/** @type {?} */
const rect = el.getBoundingClientRect();
this.drawCanvas.style.cursor = 'pointer';
Object.assign(rectangle, {
startX: rect.left,
startY: rect.top,
width: rect.width,
height: rect.height,
color: this.drawColor
});
this.drawRectangle(rectangle);
}
else {
this.drawCanvas.style.cursor = 'crosshair';
}
return rectangle;
}
/**
* @param {?} index
* @return {?}
*/
closeRect(index) {
this.rectangles.splice(index, 1);
this.drawPersistCanvasRectangles();
}
/**
* @param {?} elements
* @return {?}
*/
isExcludeRect(elements) {
/** @type {?} */
const result = elements.some(el => {
return el.getAttribute('exclude-rect') === 'true';
});
return result;
}
}
FeedbackDialogComponent.decorators = [
{ type: Component, args: [{
selector: 'feedback-dialog',
template: "<div class=\"dialog\" *ngIf=\"!showToolbar\" data-html2canvas-ignore=\"true\">\r\n <div class=\"dialog-title\">\r\n <div class=\"title-font\">\r\n {{vars['title']}}\r\n </div>\r\n </div>\r\n <div class=\"dialog-content\">\r\n <div class=\"description-tips\">\r\n <div *ngIf=\"feedback.description==''\">{{vars['placeholder']}}</div>\r\n </div>\r\n <textarea\r\n autofocus\r\n class=\"description\"\r\n [(ngModel)]=\"feedback.description\"\r\n ></textarea>\r\n </div>\r\n <div class=\"screenshot-checkbox\">\r\n <mat-checkbox [(ngModel)]=\"includeScreenshot\" (change)=\"isIncludeScreenshot()\">{{vars['checkboxLabel']}}</mat-checkbox>\r\n </div>\r\n\r\n <div #screenshotParent class=\"screenshot-content\" (click)=\"expandDrawingBoard()\" *ngIf=\"includeScreenshot\">\r\n <mat-spinner class=\"loading\" [diameter]=\"30\" ></mat-spinner>\r\n <div></div>\r\n <div class=\"screenshot-tips\" *ngIf=\"!showSpinner\">\r\n <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\">\r\n <path\r\n d=\"M21 17h-2.58l2.51 2.56c-.18.69-.73 1.26-1.41 1.44L17 18.5V21h-2v-6h6v2zM19 7h2v2h-2V7zm2-2h-2V3.08c1.1 0 2 .92 2 1.92zm-6-2h2v2h-2V3zm4 8h2v2h-2v-2zM9 21H7v-2h2v2zM5 9H3V7h2v2zm0-5.92V5H3c0-1 1-1.92 2-1.92zM5 17H3v-2h2v2zM9 5H7V3h2v2zm4 0h-2V3h2v2zm0 16h-2v-2h2v2zm-8-8H3v-2h2v2zm0 8.08C3.9 21.08 3 20 3 19h2v2.08z\"></path>\r\n </svg>\r\n <span class=\"screenshot-tips-content\">{{vars['editTip']}}</span>\r\n </div>\r\n </div>\r\n\r\n <mat-dialog-actions class=\"dialog-actions\" align=\"end\">\r\n <button mat-button (click)=\"dialogRef.close()\" class=\"action-button\">{{vars['cancelLabel']}}</button>\r\n <button mat-button (click)=\"dialogRef.close(true)\" class=\"submit-button action-button\">{{vars['sendLabel']}}</button>\r\n </mat-dialog-actions>\r\n</div>\r\n<div *ngIf=\"showToolbar\" data-html2canvas-ignore=\"true\">\r\n <div class=\"toolbar-tips\" *ngIf=\"showToolbarTips\">\r\n {{vars['drawRectTip']}}\r\n </div>\r\n\r\n <feedback-toolbar [drawColor]=\"drawColor\" (manipulate)=\"manipulate($event)\"></feedback-toolbar>\r\n</div>\r\n<div *ngFor=\"let rectangle of rectangles; index as index\" >\r\n <feedback-rectangle [rectangle]=\"rectangle\" [noHover]=\"!showToolbar || isDrawingRect\" (close)=\"closeRect(index)\">\r\n </feedback-rectangle>\r\n</div>\r\n<canvas id=\"draw-canvas\" class=\"drawCanvas\" [ngClass]=\"{'pointerCursor': !showToolbar}\"></canvas>\r\n",
styles: [".dialog{z-index:1000;position:relative;width:360px;background-color:#fff}.dialog-title{background-color:#607d8b;color:#fff;height:56px}.title-font{color:#fff;float:left;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:20px;line-height:56px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;padding:0 16px;margin:0}.dialog-content{display:-webkit-flex;flex-grow:1;height:200px;position:relative}.description{border:none;box-sizing:border-box;box-shadow:none;color:#212121;flex-grow:1;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:16px;line-height:normal;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;max-width:100%;outline:0;padding:18px 16px 0;resize:none;width:100%;height:inherit}.description-tips{color:#bdbdbd;display:block;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:16px;line-height:normal;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;left:0;position:absolute;padding:18px 16px 0;right:0}.screenshot-checkbox{padding:0 16px;background-color:#f8f8f8;height:40px;display:flex;flex-direction:column;justify-content:center}.screenshot-content{border:none;cursor:pointer;text-align:center;display:block;position:relative;padding:0;overflow:hidden;height:192px;width:100%;background:#ededed}.screenshot-tips{align-items:center;background-color:rgba(248,248,248,.6);border-radius:4px;box-sizing:border-box;display:-webkit-flex;flex-direction:column;justify-content:center;min-height:112px;width:224px;z-index:5;position:absolute;top:50%;right:0;bottom:0;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);margin:0 auto}.screenshot-content:hover .screenshot-tips{background-color:rgba(248,248,248,.8)}.screenshot-content:hover .screenshot-tips-content{color:#4285f4}.screenshot-content:hover svg{color:#4285f4;fill:currentColor}.screenshot-tips svg{color:#757575;fill:currentColor;height:48px;width:48px}.screenshot-tips-content{color:#757575;font-weight:400;font-size:14px;line-height:20px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;margin-top:12px}.dialog-actions{border-top:1px solid #e0e0e0}.submit-button{margin-right:8px!important;margin-left:5px!important;color:#4285f4}.action-button{font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:14px;height:35px;line-height:normal;margin:10px 0;padding:0 8px;position:relative;min-width:75px}.loading{margin:0 auto;position:absolute;top:45%;bottom:0;left:0;right:0}.mat-dialog-actions{padding:0!important}::ng-deep .feedbackDialog .mat-dialog-container{padding:0;overflow:visible;background-color:rgba(255,255,255,0);box-shadow:initial}.toolbar-tips{background-color:rgba(255,255,255,.6);border-radius:12px;color:#757575;font-style:normal;font-variant:normal;font-weight:400;font-stretch:normal;font-size:34px;line-height:40px;font-family:Roboto,RobotoDraft,Helvetica,Arial,sans-serif;margin-bottom:72px;padding:22px 0;text-align:center;visibility:visible;width:656px;height:auto;-webkit-animation:0s ease-in 5s forwards cssAnimation;animation:0s ease-in 5s forwards cssAnimation}@keyframes cssAnimation{to{width:0;height:0;overflow:hidden}}@-webkit-keyframes cssAnimation{to{width:0;height:0;visibility:hidden}}.drawCanvas{position:absolute;top:0;left:0;z-index:-1;margin:0 auto;cursor:crosshair}.pointerCursor{cursor:default!important}"]
}] }
];
/** @nocollapse */
FeedbackDialogComponent.ctorParameters = () => [
{ type: MatDialogRef },
{ type: FeedbackService },
{ type: ChangeDetectorRef },
{ type: ElementRef }
];
FeedbackDialogComponent.propDecorators = {
screenshotParent: [{ type: ViewChild, args: ['screenshotParent',] }],
onEscapeKeyDownHandler: [{ type: HostListener, args: ['document:keydown.escape', ['$event'],] }]
};
if (false) {
/** @type {?} */
FeedbackDialogComponent.prototype.showToolbar;
/** @type {?} */
FeedbackDialogComponent.prototype.vars;
/** @type {?} */
FeedbackDialogComponent.prototype.feedback;
/** @type {?} */
FeedbackDialogComponent.prototype.includeScreenshot;
/** @type {?} */
FeedbackDialogComponent.prototype.showSpinner;
/** @type {?} */
FeedbackDialogComponent.prototype.screenshotEle;
/** @type {?} */
FeedbackDialogComponent.prototype.drawCanvas;
/** @type {?} */
FeedbackDialogComponent.prototype.showToolbarTips;
/** @type {?} */
FeedbackDialogComponent.prototype.screenshotParent;
/** @type {?} */
FeedbackDialogComponent.prototype.drawColor;
/** @type {?} */
FeedbackDialogComponent.prototype.rectangles;
/** @type {?} */
FeedbackDialogComponent.prototype.scrollWidth;
/** @type {?} */
FeedbackDialogComponent.prototype.scrollHeight;
/** @type {?} */
FeedbackDialogComponent.prototype.elCouldBeHighlighted;
/** @type {?} */
FeedbackDialogComponent.prototype.manuallyDrawRect$;
/** @type {?} */
FeedbackDialogComponent.prototype.autoDrawRect$;
/** @type {?} */
FeedbackDialogComponent.prototype.isDrawingRect;
/** @type {?} */
FeedbackDialogComponent.prototype.dialogRef;
/** @type {?} */
FeedbackDialogComponent.prototype.feedbackService;
/** @type {?} */
FeedbackDialogComponent.prototype.detector;
/** @type {?} */
FeedbackDialogComponent.prototype.el;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWZlZWRiYWNrLyIsInNvdXJjZXMiOlsibGliL2ZlZWRiYWNrLWRpYWxvZy9mZWVkYmFjay1kaWFsb2cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQU8sU0FBUyxJQUFJLG1CQUFtQixFQUEyQixNQUFNLE1BQU0sQ0FBQztBQUV0RixPQUFPLEVBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUEwQyxNQUFNLGdCQUFnQixDQUFDO0FBQzNHLE9BQU8sRUFBQyxTQUFTLEVBQWlCLFNBQVMsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBQzFILE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUMvQyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQVM5QyxNQUFNOzs7Ozs7O0lBdUJKLFlBQW1CLFNBQWdELEVBQy9DLGlCQUNBLFVBQ0E7UUFIRCxjQUFTLEdBQVQsU0FBUyxDQUF1QztRQUMvQyxvQkFBZSxHQUFmLGVBQWU7UUFDZixhQUFRLEdBQVIsUUFBUTtRQUNSLE9BQUUsR0FBRixFQUFFOzJCQXpCRCxLQUFLO29CQUNKLEVBQUU7d0JBQ04sSUFBSSxRQUFRLEVBQUU7aUNBQ0ksSUFBSTsyQkFDbkIsSUFBSTsrQkFHUyxJQUFJO3lCQUdYLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCOzBCQUMvQixFQUFFOzJCQUNiLFFBQVEsQ0FBQyxlQUFlLENBQUMsV0FBVzs0QkFDbkMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxZQUFZO29DQUM3QixDQUFDLFFBQVEs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QixhQUFhLENBQUMsUUFBbUI7O1FBQ3ZDLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUUsRUFBRSxDQUFDLEVBQUU7WUFDakMsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxLQUFLLE1BQU0sQ0FBQztTQUNuRCxDQUFDLENBQUM7UUFDSCxPQUFPLE1BQU0sQ0FBQzs7OztZQXJTakIsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxpQkFBaUI7Z0JBQzNCLCs4RUFBK0M7O2FBRWhEOzs7O1lBWE8sWUFBWTtZQUVaLGVBQWU7WUFIa0MsaUJBQWlCO1lBQTdCLFVBQVU7OzsrQkF1QnBELFNBQVMsU0FBQyxrQkFBa0I7cUNBNEQ1QixZQUFZLFNBQUMseUJBQXlCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2Zyb20sIGZyb21FdmVudCBhcyBvYnNlcnZhYmxlRnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xyXG5cclxuaW1wb3J0IHt0YWtlVW50aWwsIGZpbmFsaXplLCBtYXAsIG1lcmdlTWFwLCB0aW1lb3V0LCBza2lwV2hpbGUsIGZpbHRlciwgc2NhbiwgZmlyc3R9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHtDb21wb25lbnQsIEFmdGVyVmlld0luaXQsIFZpZXdDaGlsZCwgRWxlbWVudFJlZiwgQ2hhbmdlRGV0ZWN0b3JSZWYsIEhvc3RMaXN0ZW5lciwgUmVuZGVyZXIyfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtNYXREaWFsb2dSZWZ9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsJztcclxuaW1wb3J0IHtGZWVkYmFja30gZnJvbSAnLi4vZW50aXR5L2ZlZWRiYWNrJztcclxuaW1wb3J0IHtGZWVkYmFja1NlcnZpY2V9IGZyb20gJy4uL2ZlZWRiYWNrLnNlcnZpY2UnO1xyXG5cclxuaW1wb3J0IHtSZWN0YW5nbGV9IGZyb20gJy4uL2VudGl0eS9yZWN0YW5nbGUnO1xyXG5pbXBvcnQge2VsZW1lbnR9IGZyb20gJ3Byb3RyYWN0b3InO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdmZWVkYmFjay1kaWFsb2cnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9mZWVkYmFjay1kaWFsb2cuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2ZlZWRiYWNrLWRpYWxvZy5jb21wb25lbnQuY3NzJ11cclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBGZWVkYmFja0RpYWxvZ0NvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xyXG4gIHB1YmxpYyBzaG93VG9vbGJhciA9IGZhbHNlO1xyXG4gIHB1YmxpYyB2YXJzOiBvYmplY3QgPSB7fTtcclxuICBwdWJsaWMgZmVlZGJhY2sgPSBuZXcgRmVlZGJhY2soKTtcclxuICBwdWJsaWMgaW5jbHVkZVNjcmVlbnNob3Q6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIHB1YmxpYyBzaG93U3Bpbm5lciA9IHRydWU7XHJcbiAgcHVibGljIHNjcmVlbnNob3RFbGU6IEhUTUxFbGVtZW50O1xyXG4gIHB1YmxpYyBkcmF3Q2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcclxuICBwdWJsaWMgc2hvd1Rvb2xiYXJUaXBzOiBib29sZWFuID0gdHJ1ZTtcclxuICBAVmlld0NoaWxkKCdzY3JlZW5zaG90UGFyZW50JylcclxuICBwdWJsaWMgc2NyZWVuc2hvdFBhcmVudDogRWxlbWVudFJlZjtcclxuICBwdWJsaWMgZHJhd0NvbG9yOiBzdHJpbmcgPSB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWdobGlnaHRlZENvbG9yO1xyXG4gIHB1YmxpYyByZWN0YW5nbGVzOiBSZWN0YW5nbGVbXSA9IFtdO1xyXG4gIHByaXZhdGUgc2Nyb2xsV2lkdGggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGg7XHJcbiAgcHJpdmF0ZSBzY3JvbGxIZWlnaHQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsSGVpZ2h0O1xyXG4gIHByaXZhdGUgZWxDb3VsZEJlSGlnaGxpZ2h0ZWQgPSBbJ2J1dHRvbicsICdhJywgJ3NwYW4nLCAnZW0nLCAnaScsICdoMScsICdoMicsICdoMycsICdoNCcsXHJcbiAgICAnaDUnLCAnaDYnLCAncCcsICdzdHJvbmcnLCAnc21hbGwnLCAnc3ViJywgJ3N1cCcsICdiJywgJ3RpbWUnLCAnaW1nJyxcclxuICAgICd2aWRlbycsICdpbnB1dCcsICdsYWJlbCcsICdzZWxlY3QnLCAndGV4dGFyZWEnLCAnYXJ0aWNsZScsICdzdW1tYXJ5JywgJ3NlY3Rpb24nXTtcclxuICAvLyB0aGUgZmxhZyBmaWVsZCAnaXNNYW51YWxseURyYXdSZWN0JyB0byBzb2x2ZSBjb25mbGljdCBiZXR3ZWVuIG1hbnVhbGx5IGRyYXcgYW5kIGF1dG8gZHJhd1xyXG4gIHByaXZhdGUgbWFudWFsbHlEcmF3UmVjdCQ6IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIGF1dG9EcmF3UmVjdCQ6IFN1YnNjcmlwdGlvbjtcclxuICBwdWJsaWMgaXNEcmF3aW5nUmVjdDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8RmVlZGJhY2tEaWFsb2dDb21wb25lbnQ+LFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZmVlZGJhY2tTZXJ2aWNlOiBGZWVkYmFja1NlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBkZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZikge1xyXG4gICAgdGhpcy5mZWVkYmFjayA9IG5ldyBGZWVkYmFjaygpO1xyXG4gICAgdGhpcy5mZWVkYmFjay5kZXNjcmlwdGlvbiA9ICcnO1xyXG4gICAgdGhpcy52YXJzID0gdGhpcy5mZWVkYmFja1NlcnZpY2UuaW5pdGlhbFZhcmlhYmxlcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5zY3JlZW5zaG90Q2FudmFzJC5zdWJzY3JpYmUoKGNhbnZhcykgPT4ge1xyXG4gICAgICB0aGlzLnNob3dTcGlubmVyID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuZmVlZGJhY2suc2NyZWVuc2hvdCA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpO1xyXG4gICAgICB0aGlzLnNjcmVlbnNob3RFbGUgPSB0aGlzLmZlZWRiYWNrU2VydmljZS5nZXRJbWdFbGUoY2FudmFzKTtcclxuICAgICAgdGhpcy5hcHBlbmRTY3JlZW5zaG90KCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5pc0RyYWdnaW5nVG9vbGJhciQuc3Vic2NyaWJlKChpc0RyYWdnaW5nKSA9PiB7XHJcbiAgICAgIGlmIChpc0RyYWdnaW5nKSB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95Q2FudmFzTGlzdGVuZXJzKCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5hZGRDYW52YXNMaXN0ZW5lcnMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5kaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoKHNlbmROb3cpID0+IHtcclxuICAgICAgaWYgKHNlbmROb3cgPT09IHRydWUpIHtcclxuICAgICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5zZXRGZWVkYmFjayh0aGlzLmZlZWRiYWNrKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5zaG93QmFja0Ryb3AoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBleHBhbmREcmF3aW5nQm9hcmQoKSB7XHJcbiAgICB0aGlzLnNob3dUb29sYmFyID0gdHJ1ZTtcclxuICAgIGlmICghdGhpcy5kcmF3Q2FudmFzKSB7XHJcbiAgICAgIHRoaXMuZGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICB0aGlzLmluaXRCYWNrZ3JvdW5kQ2FudmFzKCk7XHJcbiAgICAgIHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZGVCYWNrRHJvcCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hZGRDYW52YXNMaXN0ZW5lcnMoKTtcclxuICAgIHRoaXMuZWwubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmRyYXdDYW52YXMpO1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaGlkZUJhY2tEcm9wKCk7XHJcbiAgICBjb25zb2xlLmxvZygnZXhwYW5kIHRoZSBib2FyZCcpO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5lc2NhcGUnLCBbJyRldmVudCddKVxyXG4gIHB1YmxpYyBvbkVzY2FwZUtleURvd25IYW5kbGVyKGV2dDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgdGhpcy5zaG93VG9vbGJhciA9IGZhbHNlO1xyXG4gICAgdGhpcy5pbmNsdWRlU2NyZWVuc2hvdCA9IHRydWU7XHJcbiAgICB0aGlzLmRldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuICAgIHRoaXMuZGlhbG9nUmVmLmNsb3NlKCdrZXkgZG93biBlc2MgdG8gY2xvc2UnKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBtYW5pcHVsYXRlKG1hbmlwdWxhdGlvbjogc3RyaW5nKSB7XHJcbiAgICBpZiAobWFuaXB1bGF0aW9uID09PSAnZG9uZScpIHtcclxuICAgICAgdGhpcy5zaG93VG9vbGJhclRpcHMgPSBmYWxzZTtcclxuICAgICAgdGhpcy5zaG93U3Bpbm5lciA9IHRydWU7XHJcbiAgICAgIHRoaXMuZGVzdHJveUNhbnZhc0xpc3RlbmVycygpO1xyXG4gICAgICB0aGlzLnNob3dUb29sYmFyID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuZGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5pbml0U2NyZWVuc2hvdENhbnZhcygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zdGFydERyYXcobWFuaXB1bGF0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGFydERyYXcoY29sb3I6IHN0cmluZykge1xyXG4gICAgdGhpcy5kcmF3Q29sb3IgPSBjb2xvcjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpc0luY2x1ZGVTY3JlZW5zaG90KCkge1xyXG4gICAgaWYgKHRoaXMuaW5jbHVkZVNjcmVlbnNob3QpIHtcclxuICAgICAgdGhpcy5kZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgIHRoaXMuc2hvd1NwaW5uZXIgPSBmYWxzZTtcclxuICAgICAgdGhpcy5hcHBlbmRTY3JlZW5zaG90KCk7XHJcbiAgICAgIHRoaXMuZmVlZGJhY2suc2NyZWVuc2hvdCA9IHRoaXMuc2NyZWVuc2hvdEVsZS5nZXRBdHRyaWJ1dGUoJ3NyYycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZGVsZXRlIHRoaXMuZmVlZGJhY2tbJ3NjcmVlbnNob3QnXTtcclxuICAgICAgdGhpcy5zaG93U3Bpbm5lciA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFwcGVuZFNjcmVlbnNob3QoKSB7XHJcbiAgICBpZiAodGhpcy5zY3JlZW5zaG90UGFyZW50KSB7IHRoaXMuc2NyZWVuc2hvdFBhcmVudC5uYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuc2NyZWVuc2hvdEVsZSk7IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdEJhY2tncm91bmRDYW52YXMoKSB7XHJcbiAgICB0aGlzLmRyYXdDYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHJhdy1jYW52YXMnKSBhcyBIVE1MQ2FudmFzRWxlbWVudDtcclxuICAgIC8vIFRoZSBjYW52YXMgdG8gZHJhdywgbXVzdCB1c2UgdGhpcyB3YXkgdG8gaW5pdGlhbCB0aGUgaGVpZ2h0IGFuZCB3aWR0aFxyXG4gICAgdGhpcy5kcmF3Q2FudmFzLnN0eWxlLmhlaWdodCA9IHRoaXMuc2Nyb2xsSGVpZ2h0ICsgJyc7XHJcbiAgICB0aGlzLmRyYXdDYW52YXMuc3R5bGUud2lkdGggPSB0aGlzLnNjcm9sbFdpZHRoICsgJyc7XHJcbiAgICB0aGlzLmRyYXdDYW52YXMuaGVpZ2h0ID0gdGhpcy5zY3JvbGxIZWlnaHQ7XHJcbiAgICB0aGlzLmRyYXdDYW52YXMud2lkdGggPSB0aGlzLnNjcm9sbFdpZHRoO1xyXG4gICAgdGhpcy5kcmF3Q29udGFpbmVyUmVjdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3Q29udGFpbmVyUmVjdCgpIHtcclxuICAgIGNvbnN0IGRyYXdDb250ZXh0ID0gdGhpcy5kcmF3Q2FudmFzLmdldENvbnRleHQoJzJkJyksXHJcbiAgICAgIHdpZHRoID0gdGhpcy5zY3JvbGxXaWR0aCxcclxuICAgICAgaGVpZ2h0ID0gdGhpcy5zY3JvbGxIZWlnaHQ7XHJcbiAgICBkcmF3Q29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgIGRyYXdDb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDAsMCwwLDAuMyknO1xyXG4gICAgZHJhd0NvbnRleHQuY2xlYXJSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xyXG4gICAgZHJhd0NvbnRleHQuZmlsbFJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7IC8vIGRyYXcgdGhlIHJlY3RhbmdsZVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3UmVjdGFuZ2xlKHJlY3Q6IFJlY3RhbmdsZSkge1xyXG4gICAgY29uc3QgY29udGV4dCA9IHRoaXMuZHJhd0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgY29udGV4dC5saW5lSm9pbiA9ICdyb3VuZCc7XHJcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xyXG4gICAgaWYgKHJlY3QuY29sb3IgPT09IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZGRlbkNvbG9yKSB7XHJcbiAgICAgIGNvbnRleHQuZmlsbFN0eWxlID0gJ3JnYmEoMzEsIDMxLCAzMSwgMC43NSknO1xyXG4gICAgICBjb250ZXh0LmZpbGxSZWN0KHJlY3Quc3RhcnRYLCByZWN0LnN0YXJ0WSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpO1xyXG4gICAgICBjb250ZXh0LnJlY3QocmVjdC5zdGFydFgsIHJlY3Quc3RhcnRZLCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0LmNsZWFyUmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgY29udGV4dC5saW5lV2lkdGggPSA1O1xyXG4gICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gcmVjdC5jb2xvcjtcclxuICAgICAgY29udGV4dC5yZWN0KHJlY3Quc3RhcnRYLCByZWN0LnN0YXJ0WSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpO1xyXG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xyXG4gICAgICBjb250ZXh0LmNsZWFyUmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgdGhpcy5yZWN0YW5nbGVzLmZvckVhY2godG1wUmVjdCA9PiB7XHJcbiAgICAgICAgaWYgKHRtcFJlY3QuY29sb3IgPT09IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZ2hsaWdodGVkQ29sb3IpIHtcclxuICAgICAgICAgIGNvbnRleHQuY2xlYXJSZWN0KHRtcFJlY3Quc3RhcnRYLCB0bXBSZWN0LnN0YXJ0WSwgdG1wUmVjdC53aWR0aCwgdG1wUmVjdC5oZWlnaHQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFkZENhbnZhc0xpc3RlbmVycygpOiB2b2lkIHtcclxuICAgIGNvbnN0IG1vdXNlVXAgPSBvYnNlcnZhYmxlRnJvbUV2ZW50KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJ21vdXNldXAnKSxcclxuICAgICAgICAgIG1vdXNlTW92ZSA9IG9ic2VydmFibGVGcm9tRXZlbnQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCAnbW91c2Vtb3ZlJyksXHJcbiAgICAgICAgICBtb3VzZURvd24gPSBvYnNlcnZhYmxlRnJvbUV2ZW50KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJ21vdXNlZG93bicpLFxyXG4gICAgICAgICAgc2Nyb2xsID0gb2JzZXJ2YWJsZUZyb21FdmVudCh3aW5kb3csICdzY3JvbGwnKTtcclxuXHJcbiAgICB0aGlzLm1hbnVhbGx5RHJhd1JlY3QobW91c2VEb3duLCBtb3VzZU1vdmUsIG1vdXNlVXApO1xyXG4gICAgdGhpcy5hdXRvRHJhd1JlY3QobW91c2VNb3ZlKTtcclxuICAgIHRoaXMuY2hhbmdlUmVjdFBvc2l0aW9uKHNjcm9sbCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNoYW5nZVJlY3RQb3NpdGlvbihzY3JvbGw6IE9ic2VydmFibGU8RXZlbnQ+KSB7XHJcbiAgICBzY3JvbGwuc3Vic2NyaWJlKFxyXG4gICAgICBldmVudCA9PiB7XHJcbiAgICAgICAgY29uc3QgY3VycmVudFdpbmRvd1Njcm9sbFggPSB3aW5kb3cuc2Nyb2xsWCxcclxuICAgICAgICAgICAgICBjdXJyZW50V2luZG93U2Nyb2xsWSA9IHdpbmRvdy5zY3JvbGxZO1xyXG4gICAgICAgIHRoaXMucmVjdGFuZ2xlcy5mb3JFYWNoKHJlY3QgPT4ge1xyXG4gICAgICAgICAgcmVjdC5zdGFydFkgPSByZWN0LnN0YXJ0WSAtIChjdXJyZW50V2luZG93U2Nyb2xsWSAtIHJlY3Qud2luZG93U2Nyb2xsWSk7XHJcbiAgICAgICAgICByZWN0LnN0YXJ0WCA9IHJlY3Quc3RhcnRYIC0gKGN1cnJlbnRXaW5kb3dTY3JvbGxYIC0gcmVjdC53aW5kb3dTY3JvbGxYKTtcclxuICAgICAgICAgIHJlY3Qud2luZG93U2Nyb2xsWSA9IGN1cnJlbnRXaW5kb3dTY3JvbGxZO1xyXG4gICAgICAgICAgcmVjdC53aW5kb3dTY3JvbGxYID0gY3VycmVudFdpbmRvd1Njcm9sbFg7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3IgPT4gY29uc29sZS5lcnJvcihlcnJvcilcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRlc3Ryb3lDYW52YXNMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5tYW51YWxseURyYXdSZWN0JCkgeyB0aGlzLm1hbnVhbGx5RHJhd1JlY3QkLnVuc3Vic2NyaWJlKCk7IH1cclxuICAgIGlmICh0aGlzLmF1dG9EcmF3UmVjdCQpIHsgdGhpcy5hdXRvRHJhd1JlY3QkLnVuc3Vic2NyaWJlKCk7IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgbWFudWFsbHlEcmF3UmVjdChtb3VzZURvd246IE9ic2VydmFibGU8RXZlbnQ+LCBtb3VzZU1vdmU6IE9ic2VydmFibGU8RXZlbnQ+LCBtb3VzZVVwOiBPYnNlcnZhYmxlPEV2ZW50Pik6IHZvaWQge1xyXG4gICAgY29uc3QgbW91c2VEcmFnID0gbW91c2VEb3duLnBpcGUobWVyZ2VNYXAoKG1vdXNlRG93bkV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgIGlmICh0aGlzLnNob3dUb29sYmFyVGlwcykgeyB0aGlzLnNob3dUb29sYmFyVGlwcyA9IGZhbHNlOyB9XHJcbiAgICAgIHRoaXMuYXV0b0RyYXdSZWN0JC51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLmlzRHJhd2luZ1JlY3QgPSB0cnVlO1xyXG5cclxuICAgICAgY29uc3QgbmV3UmVjdGFuZ2xlID0gbmV3IFJlY3RhbmdsZSgpO1xyXG4gICAgICBuZXdSZWN0YW5nbGUuc3RhcnRYID0gbW91c2VEb3duRXZlbnQuY2xpZW50WDtcclxuICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WSA9IG1vdXNlRG93bkV2ZW50LmNsaWVudFk7XHJcbiAgICAgIG5ld1JlY3RhbmdsZS5jb2xvciA9IHRoaXMuZHJhd0NvbG9yO1xyXG5cclxuICAgICAgcmV0dXJuIG1vdXNlTW92ZS5waXBlKFxyXG4gICAgICAgIG1hcCgobW91c2VNb3ZlRXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcclxuICAgICAgICAgIG5ld1JlY3RhbmdsZS53aWR0aCA9IG1vdXNlTW92ZUV2ZW50LmNsaWVudFggLSBtb3VzZURvd25FdmVudC5jbGllbnRYO1xyXG4gICAgICAgICAgbmV3UmVjdGFuZ2xlLmhlaWdodCA9IG1vdXNlTW92ZUV2ZW50LmNsaWVudFkgLSBtb3VzZURvd25FdmVudC5jbGllbnRZO1xyXG4gICAgICAgICAgcmV0dXJuIG5ld1JlY3RhbmdsZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XHJcbiAgICAgICAgICAvLyBjbGljayB0byBkcmF3IHJlY3RhbmdsZVxyXG4gICAgICAgICAgaWYgKG5ld1JlY3RhbmdsZS53aWR0aCA9PT0gdW5kZWZpbmVkIHx8IG5ld1JlY3RhbmdsZS5oZWlnaHQgPT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICBuZXdSZWN0YW5nbGUud2lkdGggPT09IDAgfHwgbmV3UmVjdGFuZ2xlLmhlaWdodCA9PT0gMCkge1xyXG4gICAgICAgICAgICBjb25zdCByZWN0ID0gdGhpcy5kcmF3VGVtcENhbnZhc1JlY3RhbmdsZShtb3VzZURvd25FdmVudCk7XHJcbiAgICAgICAgICAgIGlmIChyZWN0KSB7IHRoaXMucmVjdGFuZ2xlcy5wdXNoKHJlY3QpOyB9XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gZHJhZyB0byBkcmF3IHJlY3RhbmdsZVxyXG4gICAgICAgICAgICBpZiAobmV3UmVjdGFuZ2xlLmhlaWdodCA8IDApIHtcclxuICAgICAgICAgICAgICBuZXdSZWN0YW5nbGUuc3RhcnRZID0gbmV3UmVjdGFuZ2xlLnN0YXJ0WSArIG5ld1JlY3RhbmdsZS5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLmhlaWdodCA9IE1hdGguYWJzKG5ld1JlY3RhbmdsZS5oZWlnaHQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChuZXdSZWN0YW5nbGUud2lkdGggPCAwKSB7XHJcbiAgICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WCA9IG5ld1JlY3RhbmdsZS5zdGFydFggKyBuZXdSZWN0YW5nbGUud2lkdGg7XHJcbiAgICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLndpZHRoID0gTWF0aC5hYnMobmV3UmVjdGFuZ2xlLndpZHRoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLnJlY3RhbmdsZXMucHVzaChuZXdSZWN0YW5nbGUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICAgICAgICAgIHRoaXMuYXV0b0RyYXdSZWN0KG1vdXNlTW92ZSk7XHJcbiAgICAgICAgICB0aGlzLmlzRHJhd2luZ1JlY3QgPSBmYWxzZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICB0YWtlVW50aWwobW91c2VVcCkpO1xyXG4gICAgfSkpO1xyXG5cclxuICAgIHRoaXMubWFudWFsbHlEcmF3UmVjdCQgPSBtb3VzZURyYWcuc3Vic2NyaWJlKFxyXG4gICAgICAocmVjKSA9PiB7XHJcbiAgICAgICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICAgICAgICB0aGlzLmRyYXdSZWN0YW5nbGUocmVjKTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXV0b0RyYXdSZWN0KG1vdXNlTW92ZTogT2JzZXJ2YWJsZTxFdmVudD4pOiB2b2lkIHtcclxuICAgIHRoaXMuYXV0b0RyYXdSZWN0JCA9IG1vdXNlTW92ZS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAobW91c2VNb3ZlRXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcclxuICAgICAgICB0aGlzLmRyYXdQZXJzaXN0Q2FudmFzUmVjdGFuZ2xlcygpO1xyXG4gICAgICAgIHRoaXMuZHJhd1RlbXBDYW52YXNSZWN0YW5nbGUobW91c2VNb3ZlRXZlbnQpO1xyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogZXJyID0+IGNvbnNvbGUuZXJyb3IoJ3NvbWV0aGluZyB3cm9uZyBvY2N1cnJlZDogJyArIGVyciksXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCkge1xyXG4gICAgdGhpcy5kcmF3Q29udGFpbmVyUmVjdCgpO1xyXG4gICAgdGhpcy5yZWN0YW5nbGVzLmZvckVhY2godG1wUmVjdCA9PiB7XHJcbiAgICAgIHRoaXMuZHJhd1JlY3RhbmdsZSh0bXBSZWN0KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3VGVtcENhbnZhc1JlY3RhbmdsZShldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgbGV0IHJlY3RhbmdsZTogUmVjdGFuZ2xlID0gbnVsbDtcclxuICAgIGNvbnN0IGNsaWVudFggPSBldmVudC5jbGllbnRYLFxyXG4gICAgICAgICAgY2xpZW50WSA9IGV2ZW50LmNsaWVudFksXHJcbiAgICAgICAgICBlbHMgPSBkb2N1bWVudC5lbGVtZW50c0Zyb21Qb2ludChjbGllbnRYLCBjbGllbnRZKSxcclxuICAgICAgICAgIGVsID0gZWxzWzJdO1xyXG4gICAgaWYgKCghdGhpcy5pc0V4Y2x1ZGVSZWN0KGVscykpICYmIGVsICYmIHRoaXMuZWxDb3VsZEJlSGlnaGxpZ2h0ZWQuaW5kZXhPZihlbC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKSA+IC0xKSB7XHJcbiAgICAgIHJlY3RhbmdsZSA9IG5ldyBSZWN0YW5nbGUoKTtcclxuICAgICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICB0aGlzLmRyYXdDYW52YXMuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xyXG5cclxuICAgICAgT2JqZWN0LmFzc2lnbihyZWN0YW5nbGUsIHtcclxuICAgICAgICBzdGFydFg6IHJlY3QubGVmdCxcclxuICAgICAgICBzdGFydFk6IHJlY3QudG9wLFxyXG4gICAgICAgIHdpZHRoOiByZWN0LndpZHRoLFxyXG4gICAgICAgIGhlaWdodDogcmVjdC5oZWlnaHQsXHJcbiAgICAgICAgY29sb3I6IHRoaXMuZHJhd0NvbG9yXHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLmRyYXdSZWN0YW5nbGUocmVjdGFuZ2xlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZHJhd0NhbnZhcy5zdHlsZS5jdXJzb3IgPSAnY3Jvc3NoYWlyJztcclxuICAgIH1cclxuICAgIHJldHVybiByZWN0YW5nbGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2xvc2VSZWN0KGluZGV4OiBudW1iZXIpIHtcclxuICAgIHRoaXMucmVjdGFuZ2xlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaXNFeGNsdWRlUmVjdChlbGVtZW50czogRWxlbWVudFtdKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCByZXN1bHQgPSBlbGVtZW50cy5zb21lKCBlbCA9PiB7XHJcbiAgICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoJ2V4Y2x1ZGUtcmVjdCcpID09PSAndHJ1ZSc7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG59XHJcbiJdfQ==