UNPKG

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.

966 lines 103 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('html2canvas'), require('rxjs'), require('rxjs/operators'), require('@angular/material'), require('@angular/cdk/overlay'), require('@angular/common'), require('@angular/forms')) :
    typeof define === 'function' && define.amd ? define('ng-feedback', ['exports', '@angular/core', 'html2canvas', 'rxjs', 'rxjs/operators', '@angular/material', '@angular/cdk/overlay', '@angular/common', '@angular/forms'], factory) :
    (factory((global['ng-feedback'] = {}),global.ng.core,global.html2canvas,global.rxjs,global.rxjs.operators,global.ng.material,global.ng.cdk.overlay,global.ng.common,global.ng.forms));
}(this, (function (exports,core,html2canvas,rxjs,operators,material,overlay,common,forms) { 'use strict';

    html2canvas = html2canvas && html2canvas.hasOwnProperty('default') ? html2canvas['default'] : html2canvas;

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var Feedback = /** @class */ (function () {
        function Feedback() {
        }
        return Feedback;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackService = /** @class */ (function () {
        function FeedbackService() {
            this.initialVariables = {};
            this.highlightedColor = 'yellow';
            this.hiddenColor = 'black';
            this.screenshotCanvasSource = new rxjs.Subject();
            this.screenshotCanvas$ = this.screenshotCanvasSource.asObservable();
            this.feedbackSource = new rxjs.Subject();
            this.feedback$ = this.feedbackSource.asObservable();
            this.isDraggingToolbarSource = new rxjs.Subject();
            this.isDraggingToolbar$ = this.isDraggingToolbarSource.asObservable();
        }
        /**
         * @return {?}
         */
        FeedbackService.prototype.initScreenshotCanvas = /**
         * @return {?}
         */
            function () {
                var _this = this;
                /** @type {?} */
                var body = document.body;
                html2canvas(body, {
                    logging: false,
                    width: document.documentElement.clientWidth,
                    height: document.documentElement.clientHeight,
                    x: document.documentElement.scrollLeft,
                    y: document.documentElement.scrollTop,
                    allowTaint: true
                }).then(function (bodyCanvas) {
                    _this.screenshotCanvasSource.next(bodyCanvas);
                });
            };
        /**
         * @param {?} canvas
         * @return {?}
         */
        FeedbackService.prototype.setCanvas = /**
         * @param {?} canvas
         * @return {?}
         */
            function (canvas) {
                this.screenshotCanvasSource.next(canvas);
            };
        /**
         * @param {?} feedback
         * @return {?}
         */
        FeedbackService.prototype.setFeedback = /**
         * @param {?} feedback
         * @return {?}
         */
            function (feedback) {
                this.feedbackSource.next(feedback);
            };
        /**
         * @param {?} isDragging
         * @return {?}
         */
        FeedbackService.prototype.setIsDraggingToolbar = /**
         * @param {?} isDragging
         * @return {?}
         */
            function (isDragging) {
                this.isDraggingToolbarSource.next(isDragging);
            };
        /**
         * @param {?} canvas
         * @return {?}
         */
        FeedbackService.prototype.getImgEle = /**
         * @param {?} canvas
         * @return {?}
         */
            function (canvas) {
                /** @type {?} */
                var img = canvas.toDataURL('image/png');
                /** @type {?} */
                var imageEle = document.createElement('img');
                imageEle.setAttribute('src', img);
                Object.assign(imageEle.style, {
                    position: 'absolute',
                    top: '50%',
                    right: '0',
                    left: '0',
                    margin: '0 auto',
                    maxHeight: '100%',
                    maxWidth: '100%',
                    transform: 'translateY(-50%)'
                });
                return imageEle;
            };
        /**
         * @return {?}
         */
        FeedbackService.prototype.hideBackDrop = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var dialogBackDrop = /** @type {?} */ (document.getElementsByClassName('dialogBackDrop')[0]);
                dialogBackDrop.style.backgroundColor = 'initial';
            };
        /**
         * @return {?}
         */
        FeedbackService.prototype.showBackDrop = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var dialogBackDrop = /** @type {?} */ (document.getElementsByClassName('dialogBackDrop')[0]);
                if (!dialogBackDrop.getAttribute('data-html2canvas-ignore')) {
                    dialogBackDrop.setAttribute('data-html2canvas-ignore', 'true');
                }
                dialogBackDrop.style.backgroundColor = 'rgba(0, 0, 0, .288)';
            };
        FeedbackService.decorators = [
            { type: core.Injectable }
        ];
        return FeedbackService;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var Rectangle = /** @class */ (function () {
        function Rectangle() {
            this.windowScrollY = window.scrollY;
            this.windowScrollX = window.scrollX;
        }
        return Rectangle;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackDialogComponent = /** @class */ (function () {
        function FeedbackDialogComponent(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 {?}
         */
        FeedbackDialogComponent.prototype.ngAfterViewInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                this.feedbackService.screenshotCanvas$.subscribe(function (canvas) {
                    _this.showSpinner = false;
                    _this.feedback.screenshot = canvas.toDataURL('image/png');
                    _this.screenshotEle = _this.feedbackService.getImgEle(canvas);
                    _this.appendScreenshot();
                });
                this.feedbackService.isDraggingToolbar$.subscribe(function (isDragging) {
                    if (isDragging) {
                        _this.destroyCanvasListeners();
                    }
                    else {
                        _this.addCanvasListeners();
                    }
                });
                this.dialogRef.afterClosed().subscribe(function (sendNow) {
                    if (sendNow === true) {
                        _this.feedbackService.setFeedback(_this.feedback);
                    }
                });
                this.feedbackService.showBackDrop();
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.expandDrawingBoard = /**
         * @return {?}
         */
            function () {
                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 {?}
         */
        FeedbackDialogComponent.prototype.onEscapeKeyDownHandler = /**
         * @param {?} evt
         * @return {?}
         */
            function (evt) {
                this.showToolbar = false;
                this.includeScreenshot = true;
                this.detector.detectChanges();
                this.dialogRef.close('key down esc to close');
            };
        /**
         * @param {?} manipulation
         * @return {?}
         */
        FeedbackDialogComponent.prototype.manipulate = /**
         * @param {?} manipulation
         * @return {?}
         */
            function (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 {?}
         */
        FeedbackDialogComponent.prototype.startDraw = /**
         * @param {?} color
         * @return {?}
         */
            function (color) {
                this.drawColor = color;
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.isIncludeScreenshot = /**
         * @return {?}
         */
            function () {
                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 {?}
         */
        FeedbackDialogComponent.prototype.appendScreenshot = /**
         * @return {?}
         */
            function () {
                if (this.screenshotParent) {
                    this.screenshotParent.nativeElement.appendChild(this.screenshotEle);
                }
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.initBackgroundCanvas = /**
         * @return {?}
         */
            function () {
                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 {?}
         */
        FeedbackDialogComponent.prototype.drawContainerRect = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var drawContext = this.drawCanvas.getContext('2d');
                /** @type {?} */
                var width = this.scrollWidth;
                /** @type {?} */
                var 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 {?}
         */
        FeedbackDialogComponent.prototype.drawRectangle = /**
         * @param {?} rect
         * @return {?}
         */
            function (rect) {
                var _this = this;
                /** @type {?} */
                var 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(function (tmpRect) {
                        if (tmpRect.color === _this.feedbackService.highlightedColor) {
                            context.clearRect(tmpRect.startX, tmpRect.startY, tmpRect.width, tmpRect.height);
                        }
                    });
                }
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.addCanvasListeners = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var mouseUp = rxjs.fromEvent(document.documentElement, 'mouseup');
                /** @type {?} */
                var mouseMove = rxjs.fromEvent(document.documentElement, 'mousemove');
                /** @type {?} */
                var mouseDown = rxjs.fromEvent(document.documentElement, 'mousedown');
                /** @type {?} */
                var scroll = rxjs.fromEvent(window, 'scroll');
                this.manuallyDrawRect(mouseDown, mouseMove, mouseUp);
                this.autoDrawRect(mouseMove);
                this.changeRectPosition(scroll);
            };
        /**
         * @param {?} scroll
         * @return {?}
         */
        FeedbackDialogComponent.prototype.changeRectPosition = /**
         * @param {?} scroll
         * @return {?}
         */
            function (scroll) {
                var _this = this;
                scroll.subscribe(function (event) {
                    /** @type {?} */
                    var currentWindowScrollX = window.scrollX;
                    /** @type {?} */
                    var currentWindowScrollY = window.scrollY;
                    _this.rectangles.forEach(function (rect) {
                        rect.startY = rect.startY - (currentWindowScrollY - rect.windowScrollY);
                        rect.startX = rect.startX - (currentWindowScrollX - rect.windowScrollX);
                        rect.windowScrollY = currentWindowScrollY;
                        rect.windowScrollX = currentWindowScrollX;
                    });
                    _this.drawPersistCanvasRectangles();
                }, function (error) { return console.error(error); });
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.destroyCanvasListeners = /**
         * @return {?}
         */
            function () {
                if (this.manuallyDrawRect$) {
                    this.manuallyDrawRect$.unsubscribe();
                }
                if (this.autoDrawRect$) {
                    this.autoDrawRect$.unsubscribe();
                }
            };
        /**
         * @param {?} mouseDown
         * @param {?} mouseMove
         * @param {?} mouseUp
         * @return {?}
         */
        FeedbackDialogComponent.prototype.manuallyDrawRect = /**
         * @param {?} mouseDown
         * @param {?} mouseMove
         * @param {?} mouseUp
         * @return {?}
         */
            function (mouseDown, mouseMove, mouseUp) {
                var _this = this;
                /** @type {?} */
                var mouseDrag = mouseDown.pipe(operators.mergeMap(function (mouseDownEvent) {
                    if (_this.showToolbarTips) {
                        _this.showToolbarTips = false;
                    }
                    _this.autoDrawRect$.unsubscribe();
                    _this.isDrawingRect = true;
                    /** @type {?} */
                    var newRectangle = new Rectangle();
                    newRectangle.startX = mouseDownEvent.clientX;
                    newRectangle.startY = mouseDownEvent.clientY;
                    newRectangle.color = _this.drawColor;
                    return mouseMove.pipe(operators.map(function (mouseMoveEvent) {
                        newRectangle.width = mouseMoveEvent.clientX - mouseDownEvent.clientX;
                        newRectangle.height = mouseMoveEvent.clientY - mouseDownEvent.clientY;
                        return newRectangle;
                    }), operators.finalize(function () {
                        // click to draw rectangle
                        if (newRectangle.width === undefined || newRectangle.height === undefined ||
                            newRectangle.width === 0 || newRectangle.height === 0) {
                            /** @type {?} */
                            var 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;
                    }), operators.takeUntil(mouseUp));
                }));
                this.manuallyDrawRect$ = mouseDrag.subscribe(function (rec) {
                    _this.drawPersistCanvasRectangles();
                    _this.drawRectangle(rec);
                });
            };
        /**
         * @param {?} mouseMove
         * @return {?}
         */
        FeedbackDialogComponent.prototype.autoDrawRect = /**
         * @param {?} mouseMove
         * @return {?}
         */
            function (mouseMove) {
                var _this = this;
                this.autoDrawRect$ = mouseMove.subscribe({
                    next: function (mouseMoveEvent) {
                        _this.drawPersistCanvasRectangles();
                        _this.drawTempCanvasRectangle(mouseMoveEvent);
                    },
                    error: function (err) { return console.error('something wrong occurred: ' + err); },
                });
            };
        /**
         * @return {?}
         */
        FeedbackDialogComponent.prototype.drawPersistCanvasRectangles = /**
         * @return {?}
         */
            function () {
                var _this = this;
                this.drawContainerRect();
                this.rectangles.forEach(function (tmpRect) {
                    _this.drawRectangle(tmpRect);
                });
            };
        /**
         * @param {?} event
         * @return {?}
         */
        FeedbackDialogComponent.prototype.drawTempCanvasRectangle = /**
         * @param {?} event
         * @return {?}
         */
            function (event) {
                /** @type {?} */
                var rectangle = null;
                /** @type {?} */
                var clientX = event.clientX;
                /** @type {?} */
                var clientY = event.clientY;
                /** @type {?} */
                var els = document.elementsFromPoint(clientX, clientY);
                /** @type {?} */
                var el = els[2];
                if ((!this.isExcludeRect(els)) && el && this.elCouldBeHighlighted.indexOf(el.nodeName.toLowerCase()) > -1) {
                    rectangle = new Rectangle();
                    /** @type {?} */
                    var 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 {?}
         */
        FeedbackDialogComponent.prototype.closeRect = /**
         * @param {?} index
         * @return {?}
         */
            function (index) {
                this.rectangles.splice(index, 1);
                this.drawPersistCanvasRectangles();
            };
        /**
         * @param {?} elements
         * @return {?}
         */
        FeedbackDialogComponent.prototype.isExcludeRect = /**
         * @param {?} elements
         * @return {?}
         */
            function (elements) {
                /** @type {?} */
                var result = elements.some(function (el) {
                    return el.getAttribute('exclude-rect') === 'true';
                });
                return result;
            };
        FeedbackDialogComponent.decorators = [
            { type: core.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 = function () {
            return [
                { type: material.MatDialogRef },
                { type: FeedbackService },
                { type: core.ChangeDetectorRef },
                { type: core.ElementRef }
            ];
        };
        FeedbackDialogComponent.propDecorators = {
            screenshotParent: [{ type: core.ViewChild, args: ['screenshotParent',] }],
            onEscapeKeyDownHandler: [{ type: core.HostListener, args: ['document:keydown.escape', ['$event'],] }]
        };
        return FeedbackDialogComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackToolbarComponent = /** @class */ (function () {
        function FeedbackToolbarComponent(el, feedbackService) {
            this.el = el;
            this.feedbackService = feedbackService;
            this.manipulate = new core.EventEmitter();
            this.disableToolbarTips = false;
            this.isSwitch = false;
            this.isDragging = false;
            this.vars = {};
            this.vars = feedbackService.initialVariables;
        }
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.ngAfterViewInit = /**
         * @return {?}
         */
            function () {
                /** @type {?} */
                var elStyle = this.el.nativeElement.style;
                elStyle.position = 'absolute';
                elStyle.left = '43%';
                elStyle.top = '60%';
                this.addDragListenerOnMoveBtn();
            };
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.ngOnChanges = /**
         * @return {?}
         */
            function () {
                this.isSwitch = this.drawColor !== this.feedbackService.highlightedColor;
            };
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.done = /**
         * @return {?}
         */
            function () {
                this.manipulate.emit('done');
            };
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.toggleHighlight = /**
         * @return {?}
         */
            function () {
                this.isSwitch = false;
                this.manipulate.emit(this.feedbackService.highlightedColor);
            };
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.toggleHide = /**
         * @return {?}
         */
            function () {
                this.isSwitch = true;
                this.manipulate.emit(this.feedbackService.hiddenColor);
            };
        /**
         * @return {?}
         */
        FeedbackToolbarComponent.prototype.addDragListenerOnMoveBtn = /**
         * @return {?}
         */
            function () {
                var _this = this;
                /** @type {?} */
                var mouseUp = rxjs.fromEvent(this.toggleMoveBtn.nativeElement, 'mouseup');
                /** @type {?} */
                var mouseMove = rxjs.fromEvent(document.documentElement, 'mousemove');
                /** @type {?} */
                var mouseDown = rxjs.fromEvent(this.toggleMoveBtn.nativeElement, 'mousedown');
                /** @type {?} */
                var mouseDrag = mouseDown.pipe(operators.mergeMap(function (md) {
                    _this.feedbackService.setIsDraggingToolbar(true);
                    /** @type {?} */
                    var startX = md.offsetX;
                    /** @type {?} */
                    var startY = md.offsetY;
                    _this.disableToolbarTips = true;
                    _this.isDragging = true;
                    // Calculate dif with mousemove until mouseup
                    return mouseMove.pipe(operators.map(function (mm) {
                        mm.preventDefault();
                        return {
                            left: mm.clientX - startX,
                            top: mm.clientY - startY
                        };
                    }), operators.finalize(function () {
                        _this.isDragging = false;
                        _this.disableToolbarTips = false;
                        _this.feedbackService.setIsDraggingToolbar(false);
                    }), operators.takeUntil(mouseUp));
                }));
                mouseDrag.subscribe(function (pos) {
                    _this.el.nativeElement.style.left = pos.left + 'px';
                    _this.el.nativeElement.style.top = pos.top + 'px';
                });
            };
        FeedbackToolbarComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'feedback-toolbar',
                        template: "<div exclude-rect=\"true\" class=\"toolbar\">\r\n  <div class=\"move-toolbar\" #toggleMove [matTooltip]=\"vars['moveToolbarTip']\" [matTooltipDisabled]=\"disableToolbarTips\">\r\n    <svg focusable=\"false\" aria-label=\"Drag\" fill=\"#BDBDBD\" height=\"56\" width=\"16\"\r\n         viewBox=\"-2 2 12 12\">\r\n      <circle cx=\"1.5\" cy=\"1.5\" r=\"1.5\"></circle>\r\n      <circle cx=\"1.5\" cy=\"7.5\" r=\"1.5\"></circle>\r\n      <circle cx=\"1.5\" cy=\"13.5\" r=\"1.5\"></circle>\r\n      <circle cx=\"6.5\" cy=\"1.5\" r=\"1.5\"></circle>\r\n      <circle cx=\"6.5\" cy=\"7.5\" r=\"1.5\"></circle>\r\n      <circle cx=\"6.5\" cy=\"13.5\" r=\"1.5\"></circle>\r\n    </svg>\r\n  </div>\r\n  <button #highlightBtn (click)=\"toggleHighlight()\" [matTooltip]=\"vars['highlightTip']\"\r\n          [matTooltipDisabled]=\"disableToolbarTips\" class=\"highlight-toggle\" [ngClass]=\"{'deepen-color': !isSwitch}\">\r\n    <span class=\"toggle\">\r\n      <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\" height=\"36\" width=\"36\"\r\n           fill=\"#ffd740\">\r\n        <path d=\"M3 3h18v18H3z\"></path>\r\n      </svg>\r\n\r\n      <svg focusable=\"false\" aria-label=\"\" fill=\"#757575\" viewBox=\"0 0 24 24\"\r\n           height=\"36\" width=\"36\" [ngClass]=\"{'toggle-decorator': !isSwitch}\" *ngIf=\"!isSwitch\">\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>\r\n  </button>\r\n  <button (click)=\"toggleHide()\" [matTooltip]=\"vars['hideTip']\" [matTooltipDisabled]=\"disableToolbarTips\"\r\n          class=\"hide-toggle\" [ngClass]=\"{'deepen-color': isSwitch}\">\r\n    <span class=\"toggle\">\r\n      <svg focusable=\"false\" aria-label=\"\" viewBox=\"0 0 24 24\" height=\"36\" width=\"36\"\r\n           fill=\"#000\">\r\n        <path d=\"M3 3h18v18H3z\"></path>\r\n      </svg>\r\n      <svg focusable=\"false\" aria-label=\"\" fill=\"#757575\" viewBox=\"0 0 24 24\"\r\n           height=\"36\" width=\"36\" [ngClass]=\"{'toggle-decorator': isSwitch}\" *ngIf=\"isSwitch\">\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>\r\n  </button>\r\n  <button mat-button class=\"merge-button\" (click)=\"done()\">{{vars['editDoneLabel']}}</button>\r\n</div>\r\n",
                        styles: [".toolbar{align-items:center;background-color:#fff;border-radius:2px;box-shadow:rgba(0,0,0,.14) 0 24px 38px 3px,rgba(0,0,0,.12) 0 9px 46px 8px,rgba(0,0,0,.2) 0 11px 15px -7px;cursor:pointer;display:-webkit-inline-flex;flex-direction:row;height:56px;min-width:232px;pointer-events:auto;overflow:visible;position:absolute;margin:0 auto;width:228px;bottom:0;top:25%;left:0;right:0;z-index:999}.move-toolbar{cursor:-webkit-grab;height:56px;padding:0 12px;position:relative}.move-toolbar:active{cursor:-webkit-grabbing}.toggle{display:inline-block;position:relative;height:36px;width:36px}.toggle-decorator{left:0;position:absolute;top:0}.highlight-toggle{align-items:center;background-color:#fff;border:none;box-sizing:border-box;cursor:pointer;display:-webkit-flex;justify-content:center;outline:0;padding:10px;pointer-events:auto;position:relative;height:56px;width:56px}.deepen-color{background-color:#e0e0e0!important}.hide-toggle{align-items:center;background-color:#fff;border:none;box-sizing:border-box;cursor:pointer;display:-webkit-flex;justify-content:center;outline:0;padding:10px;pointer-events:auto;position:relative;height:56px;width:56px}.merge-button{padding:0!important;margin:0 10px!important;min-width:56px;color:#4285f4}"]
                    }] }
        ];
        /** @nocollapse */
        FeedbackToolbarComponent.ctorParameters = function () {
            return [
                { type: core.ElementRef },
                { type: FeedbackService }
            ];
        };
        FeedbackToolbarComponent.propDecorators = {
            drawColor: [{ type: core.Input }],
            manipulate: [{ type: core.Output }],
            toggleMoveBtn: [{ type: core.ViewChild, args: ['toggleMove',] }]
        };
        return FeedbackToolbarComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackRectangleComponent = /** @class */ (function () {
        function FeedbackRectangleComponent(feedbackService) {
            this.feedbackService = feedbackService;
            this.close = new core.EventEmitter();
            this.showCloseTag = false;
        }
        /**
         * @return {?}
         */
        FeedbackRectangleComponent.prototype.onMouseEnter = /**
         * @return {?}
         */
            function () {
                this.showCloseTag = this.noHover === false;
            };
        /**
         * @return {?}
         */
        FeedbackRectangleComponent.prototype.onMouseLeave = /**
         * @return {?}
         */
            function () {
                this.showCloseTag = false;
            };
        /**
         * @return {?}
         */
        FeedbackRectangleComponent.prototype.onClose = /**
         * @return {?}
         */
            function () {
                this.close.emit();
            };
        FeedbackRectangleComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'feedback-rectangle',
                        template: "<div exclude-rect=\"true\" class=\"rect\" [ngStyle]=\"{'left.px': rectangle.startX,\r\n                              'top.px': rectangle.startY,\r\n                              'width.px': rectangle.width ,\r\n                              'height.px': rectangle.height }\"\r\n    [ngClass]=\"{'highlight': rectangle.color === feedbackService.highlightedColor,\r\n                'hide': rectangle.color !== feedbackService.highlightedColor,\r\n                'noHover': noHover}\">\r\n  <span exclude-rect=\"true\" class=\"close\" *ngIf=\"showCloseTag\" (click)=\"onClose()\">\r\n    <svg viewBox=\"0 0 1024 1024\"\r\n         width=\"16\" height=\"16\">\r\n        <path\r\n          d=\"M896 224l-96-96-288 288-288-288-96 96 288 288-288 288 96 96 288-288 288 288 96-96-288-288 288-288z\"></path>\r\n    </svg>\r\n  </span>\r\n</div>\r\n",
                        styles: [".rect{position:fixed;background:0 0;z-index:3}.highlight:not(.noHover):hover{cursor:default;background:rgba(55,131,249,.2)}.hide{background-color:#000}.hide:not(.noHover):hover{background-color:rgba(31,31,31,.75)}.rect .close{width:24px;height:24px;background:#fff;border-radius:50%;justify-content:center;align-items:center;color:#999;position:absolute;right:-12px;top:-12px;cursor:pointer;display:flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"]
                    }] }
        ];
        /** @nocollapse */
        FeedbackRectangleComponent.ctorParameters = function () {
            return [
                { type: FeedbackService }
            ];
        };
        FeedbackRectangleComponent.propDecorators = {
            rectangle: [{ type: core.Input }],
            noHover: [{ type: core.Input }],
            close: [{ type: core.Output }],
            onMouseEnter: [{ type: core.HostListener, args: ['mouseenter',] }],
            onMouseLeave: [{ type: core.HostListener, args: ['mouseleave',] }]
        };
        return FeedbackRectangleComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackDirective = /** @class */ (function () {
        function FeedbackDirective(dialogRef, feedbackService, overlay$$1) {
            var _this = this;
            this.dialogRef = dialogRef;
            this.feedbackService = feedbackService;
            this.title = 'Send feedback';
            this.placeholder = 'Describe your issue or share your ideas';
            this.editTip = 'Click to highlight or hide info';
            this.checkboxLabel = 'Include screenshot';
            this.cancelLabel = 'CANCEL';
            this.sendLabel = 'SEND';
            this.moveToolbarTip = 'move toolbar';
            this.drawRectTip = 'Draw using yellow to highlight issues or black to hide sensitive info';
            this.highlightTip = 'highlight issues';
            this.hideTip = 'hide sensitive info';
            this.editDoneLabel = 'DONE';
            this.send = new core.EventEmitter();
            this.feedbackService.feedback$.subscribe(function (feedback) {
                _this.send.emit(feedback);
            });
            this.overlay = overlay$$1;
        }
        /**
         * @return {?}
         */
        FeedbackDirective.prototype.onClick = /**
         * @return {?}
         */
            function () {
                this.openFeedbackDialog();
            };
        /**
         * @return {?}
         */
        FeedbackDirective.prototype.openFeedbackDialog = /**
         * @return {?}
         */
            function () {
                this.feedbackService.initScreenshotCanvas();
                /** @type {?} */
                var dialogRef = this.dialogRef.open(FeedbackDialogComponent, {
                    panelClass: 'feedbackDialog',
                    backdropClass: 'dialogBackDrop',
                    disableClose: true,
                    height: 'auto',
                    width: 'auto',
                    scrollStrategy: this.overlay.scrollStrategies.reposition()
                });
            };
        /**
         * @return {?}
         */
        FeedbackDirective.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                this.feedbackService.initialVariables = {
                    title: this.title,
                    placeholder: this.placeholder,
                    editTip: this.editTip,
                    checkboxLabel: this.checkboxLabel,
                    cancelLabel: this.cancelLabel,
                    sendLabel: this.sendLabel,
                    moveToolbarTip: this.moveToolbarTip,
                    drawRectTip: this.drawRectTip,
                    highlightTip: this.highlightTip,
                    hideTip: this.hideTip,
                    editDoneLabel: this.editDoneLabel
                };
            };
        FeedbackDirective.decorators = [
            { type: core.Directive, args: [{ selector: '[feedback]' },] }
        ];
        /** @nocollapse */
        FeedbackDirective.ctorParameters = function () {
            return [
                { type: material.MatDialog },
                { type: FeedbackService },
                { type: overlay.Overlay }
            ];
        };
        FeedbackDirective.propDecorators = {
            title: [{ type: core.Input }],
            placeholder: [{ type: core.Input }],
            editTip: [{ type: core.Input }],
            checkboxLabel: [{ type: core.Input }],
            cancelLabel: [{ type: core.Input }],
            sendLabel: [{ type: core.Input }],
            moveToolbarTip: [{ type: core.Input }],
            drawRectTip: [{ type: core.Input }],
            highlightTip: [{ type: core.Input }],
            hideTip: [{ type: core.Input }],
            editDoneLabel: [{ type: core.Input }],
            send: [{ type: core.Output }],
            onClick: [{ type: core.HostListener, args: ['click',] }]
        };
        return FeedbackDirective;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FeedbackModule = /** @class */ (function () {
        function FeedbackModule() {
        }
        FeedbackModule.decorators = [
            { type: core.NgModule, args: [{
                        declarations: [
                            FeedbackDialogComponent,
                            FeedbackToolbarComponent,
                            FeedbackRectangleComponent,
                            FeedbackDirective
                        ],
                        imports: [
                            material.MatDialogModule,
                            material.MatButtonModule,
                            material.MatIconModule,
                            material.MatInputModule,
                            material.MatTooltipModule,
                            common.CommonModule,
                            forms.FormsModule,
                            material.MatCheckboxModule,
                            material.MatProgressSpinnerModule
                        ],
                        exports: [
                            FeedbackDirective
                        ],
                        entryComponents: [
                            FeedbackDialogComponent
                        ],
                        providers: [
                            FeedbackService
                        ]
                    },] }
        ];
        return FeedbackModule;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */

    exports.FeedbackModule = FeedbackModule;
    exports.ɵa = FeedbackDialogComponent;
    exports.ɵd = FeedbackRectangleComponent;
    exports.ɵc = FeedbackToolbarComponent;
    exports.ɵe = FeedbackDirective;
    exports.ɵb = FeedbackService;

    Object.defineProperty(exports, '__esModule', { value: true });

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctZmVlZGJhY2sudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9uZy1mZWVkYmFjay9saWIvZW50aXR5L2ZlZWRiYWNrLnRzIiwibmc6Ly9uZy1mZWVkYmFjay9saWIvZmVlZGJhY2suc2VydmljZS50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2VudGl0eS9yZWN0YW5nbGUudHMiLCJuZzovL25nLWZlZWRiYWNrL2xpYi9mZWVkYmFjay1kaWFsb2cvZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudC50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLXRvb2xiYXIvZmVlZGJhY2stdG9vbGJhci5jb21wb25lbnQudHMiLCJuZzovL25nLWZlZWRiYWNrL2xpYi9mZWVkYmFjay1yZWN0YW5nbGUvZmVlZGJhY2stcmVjdGFuZ2xlLmNvbXBvbmVudC50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLmRpcmVjdGl2ZS50cyIsIm5nOi8vbmctZmVlZGJhY2svbGliL2ZlZWRiYWNrLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRmVlZGJhY2sge1xyXG4gIHB1YmxpYyBkZXNjcmlwdGlvbjogc3RyaW5nO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90OiBzdHJpbmc7XHJcbn1cclxuIiwiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IGh0bWwyY2FudmFzIGZyb20gJ2h0bWwyY2FudmFzJztcclxuaW1wb3J0IHtTdWJqZWN0LCBPYnNlcnZhYmxlfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtGZWVkYmFja30gZnJvbSAnLi9lbnRpdHkvZmVlZGJhY2snOyAvLyBpbXBvcnQgT2JzZXJ2YWJsZSB0byBzb2x2ZSBidWlsZCBpc3N1ZVxyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tTZXJ2aWNlIHtcclxuICBwdWJsaWMgaW5pdGlhbFZhcmlhYmxlczogb2JqZWN0ID0ge307XHJcbiAgcHVibGljIGhpZ2hsaWdodGVkQ29sb3IgPSAneWVsbG93JztcclxuICBwdWJsaWMgaGlkZGVuQ29sb3IgPSAnYmxhY2snO1xyXG4gIHByaXZhdGUgc2NyZWVuc2hvdENhbnZhc1NvdXJjZSA9IG5ldyBTdWJqZWN0PEhUTUxDYW52YXNFbGVtZW50PigpO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90Q2FudmFzJDogT2JzZXJ2YWJsZTxIVE1MQ2FudmFzRWxlbWVudD4gPSB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgZmVlZGJhY2tTb3VyY2UgPSBuZXcgU3ViamVjdDxGZWVkYmFjaz4oKTtcclxuICBwdWJsaWMgZmVlZGJhY2skOiBPYnNlcnZhYmxlPEZlZWRiYWNrPiA9IHRoaXMuZmVlZGJhY2tTb3VyY2UuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIHByaXZhdGUgaXNEcmFnZ2luZ1Rvb2xiYXJTb3VyY2UgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG4gIHB1YmxpYyBpc0RyYWdnaW5nVG9vbGJhciQ6IE9ic2VydmFibGU8Ym9vbGVhbj4gPSB0aGlzLmlzRHJhZ2dpbmdUb29sYmFyU291cmNlLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuXHJcbiAgcHVibGljIGluaXRTY3JlZW5zaG90Q2FudmFzKCkge1xyXG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XHJcbiAgICBjb25zdCBib2R5ID0gZG9jdW1lbnQuYm9keTtcclxuICAgIGh0bWwyY2FudmFzKGJvZHksIHtcclxuICAgICAgbG9nZ2luZzogZmFsc2UsXHJcbiAgICAgIHdpZHRoOiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgsXHJcbiAgICAgIGhlaWdodDogZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCxcclxuICAgICAgeDogZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQsXHJcbiAgICAgIHk6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AsXHJcbiAgICAgIGFsbG93VGFpbnQgOiB0cnVlXHJcbiAgICB9KS50aGVuKGJvZHlDYW52YXMgPT4ge1xyXG4gICAgICB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UubmV4dChib2R5Q2FudmFzKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldENhbnZhcyhjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KTogdm9pZCB7XHJcbiAgICB0aGlzLnNjcmVlbnNob3RDYW52YXNTb3VyY2UubmV4dChjYW52YXMpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldEZlZWRiYWNrKGZlZWRiYWNrOiBGZWVkYmFjayk6IHZvaWQge1xyXG4gICAgdGhpcy5mZWVkYmFja1NvdXJjZS5uZXh0KGZlZWRiYWNrKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRJc0RyYWdnaW5nVG9vbGJhcihpc0RyYWdnaW5nOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRHJhZ2dpbmdUb29sYmFyU291cmNlLm5leHQoaXNEcmFnZ2luZyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0SW1nRWxlKGNhbnZhcyk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGltZyA9IGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpLFxyXG4gICAgICAgICAgaW1hZ2VFbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcclxuICAgIGltYWdlRWxlLnNldEF0dHJpYnV0ZSgnc3JjJywgaW1nKTtcclxuICAgIE9iamVjdC5hc3NpZ24oaW1hZ2VFbGUuc3R5bGUsIHtcclxuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXHJcbiAgICAgIHRvcDogJzUwJScsXHJcbiAgICAgIHJpZ2h0OiAnMCcsXHJcbiAgICAgIGxlZnQ6ICcwJyxcclxuICAgICAgbWFyZ2luOiAnMCBhdXRvJyxcclxuICAgICAgbWF4SGVpZ2h0OiAnMTAwJScsXHJcbiAgICAgIG1heFdpZHRoOiAnMTAwJScsXHJcbiAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoLTUwJSknXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBpbWFnZUVsZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBoaWRlQmFja0Ryb3AoKSB7XHJcbiAgICBjb25zdCBkaWFsb2dCYWNrRHJvcCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2RpYWxvZ0JhY2tEcm9wJylbMF0gYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBkaWFsb2dCYWNrRHJvcC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAnaW5pdGlhbCc7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2hvd0JhY2tEcm9wKCkge1xyXG4gICAgY29uc3QgZGlhbG9nQmFja0Ryb3AgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdkaWFsb2dCYWNrRHJvcCcpWzBdIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYgKCFkaWFsb2dCYWNrRHJvcC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaHRtbDJjYW52YXMtaWdub3JlJykpIHtcclxuICAgICAgZGlhbG9nQmFja0Ryb3Auc2V0QXR0cmlidXRlKCdkYXRhLWh0bWwyY2FudmFzLWlnbm9yZScsICd0cnVlJyk7XHJcbiAgICB9XHJcbiAgICBkaWFsb2dCYWNrRHJvcC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAncmdiYSgwLCAwLCAwLCAuMjg4KSc7XHJcbiAgfVxyXG59XHJcbiIsImV4cG9ydCBjbGFzcyBSZWN0YW5nbGUge1xyXG4gIHB1YmxpYyBzdGFydFg6IG51bWJlcjtcclxuICBwdWJsaWMgc3RhcnRZOiBudW1iZXI7XHJcbiAgcHVibGljIHdpZHRoOiBudW1iZXI7XHJcbiAgcHVibGljIGhlaWdodDogbnVtYmVyO1xyXG4gIHB1YmxpYyBjb2xvcjogc3RyaW5nO1xyXG4gIHB1YmxpYyB3aW5kb3dTY3JvbGxZOiBudW1iZXIgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICBwdWJsaWMgd2luZG93U2Nyb2xsWDogbnVtYmVyID0gd2luZG93LnNjcm9sbFg7XHJcbn1cclxuIiwiaW1wb3J0IHtmcm9tLCBmcm9tRXZlbnQgYXMgb2JzZXJ2YWJsZUZyb21FdmVudCwgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7dGFrZVVudGlsLCBmaW5hbGl6ZSwgbWFwLCBtZXJnZU1hcCwgdGltZW91dCwgc2tpcFdoaWxlLCBmaWx0ZXIsIHNjYW4sIGZpcnN0fSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7Q29tcG9uZW50LCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIENoYW5nZURldGVjdG9yUmVmLCBIb3N0TGlzdGVuZXIsIFJlbmRlcmVyMn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7TWF0RGlhbG9nUmVmfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2t9IGZyb20gJy4uL2VudGl0eS9mZWVkYmFjayc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7UmVjdGFuZ2xlfSBmcm9tICcuLi9lbnRpdHkvcmVjdGFuZ2xlJztcclxuaW1wb3J0IHtlbGVtZW50fSBmcm9tICdwcm90cmFjdG9yJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZmVlZGJhY2stZGlhbG9nJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9mZWVkYmFjay1kaWFsb2cuY29tcG9uZW50LmNzcyddXHJcbn0pXHJcblxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tEaWFsb2dDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcclxuICBwdWJsaWMgc2hvd1Rvb2xiYXIgPSBmYWxzZTtcclxuICBwdWJsaWMgdmFyczogb2JqZWN0ID0ge307XHJcbiAgcHVibGljIGZlZWRiYWNrID0gbmV3IEZlZWRiYWNrKCk7XHJcbiAgcHVibGljIGluY2x1ZGVTY3JlZW5zaG90OiBib29sZWFuID0gdHJ1ZTtcclxuICBwdWJsaWMgc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gIHB1YmxpYyBzY3JlZW5zaG90RWxlOiBIVE1MRWxlbWVudDtcclxuICBwdWJsaWMgZHJhd0NhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XHJcbiAgcHVibGljIHNob3dUb29sYmFyVGlwczogYm9vbGVhbiA9IHRydWU7XHJcbiAgQFZpZXdDaGlsZCgnc2NyZWVuc2hvdFBhcmVudCcpXHJcbiAgcHVibGljIHNjcmVlbnNob3RQYXJlbnQ6IEVsZW1lbnRSZWY7XHJcbiAgcHVibGljIGRyYXdDb2xvcjogc3RyaW5nID0gdGhpcy5mZWVkYmFja1NlcnZpY2UuaGlnaGxpZ2h0ZWRDb2xvcjtcclxuICBwdWJsaWMgcmVjdGFuZ2xlczogUmVjdGFuZ2xlW10gPSBbXTtcclxuICBwcml2YXRlIHNjcm9sbFdpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoO1xyXG4gIHByaXZhdGUgc2Nyb2xsSGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodDtcclxuICBwcml2YXRlIGVsQ291bGRCZUhpZ2hsaWdodGVkID0gWydidXR0b24nLCAnYScsICdzcGFuJywgJ2VtJywgJ2knLCAnaDEnLCAnaDInLCAnaDMnLCAnaDQnLFxyXG4gICAgJ2g1JywgJ2g2JywgJ3AnLCAnc3Ryb25nJywgJ3NtYWxsJywgJ3N1YicsICdzdXAnLCAnYicsICd0aW1lJywgJ2ltZycsXHJcbiAgICAndmlkZW8nLCAnaW5wdXQnLCAnbGFiZWwnLCAnc2VsZWN0JywgJ3RleHRhcmVhJywgJ2FydGljbGUnLCAnc3VtbWFyeScsICdzZWN0aW9uJ107XHJcbiAgLy8gdGhlIGZsYWcgZmllbGQgJ2lzTWFudWFsbHlEcmF3UmVjdCcgdG8gc29sdmUgY29uZmxpY3QgYmV0d2VlbiBtYW51YWxseSBkcmF3IGFuZCBhdXRvIGRyYXdcclxuICBwcml2YXRlIG1hbnVhbGx5RHJhd1JlY3QkOiBTdWJzY3JpcHRpb247XHJcbiAgcHJpdmF0ZSBhdXRvRHJhd1JlY3QkOiBTdWJzY3JpcHRpb247XHJcbiAgcHVibGljIGlzRHJhd2luZ1JlY3Q6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPEZlZWRiYWNrRGlhbG9nQ29tcG9uZW50PixcclxuICAgICAgICAgICAgICBwcml2YXRlIGZlZWRiYWNrU2VydmljZTogRmVlZGJhY2tTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHtcclxuICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgRmVlZGJhY2soKTtcclxuICAgIHRoaXMuZmVlZGJhY2suZGVzY3JpcHRpb24gPSAnJztcclxuICAgIHRoaXMudmFycyA9IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmluaXRpYWxWYXJpYWJsZXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2NyZWVuc2hvdENhbnZhcyQuc3Vic2NyaWJlKChjYW52YXMpID0+IHtcclxuICAgICAgdGhpcy5zaG93U3Bpbm5lciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrLnNjcmVlbnNob3QgPSBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcclxuICAgICAgdGhpcy5zY3JlZW5zaG90RWxlID0gdGhpcy5mZWVkYmFja1NlcnZpY2UuZ2V0SW1nRWxlKGNhbnZhcyk7XHJcbiAgICAgIHRoaXMuYXBwZW5kU2NyZWVuc2hvdCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaXNEcmFnZ2luZ1Rvb2xiYXIkLnN1YnNjcmliZSgoaXNEcmFnZ2luZykgPT4ge1xyXG4gICAgICBpZiAoaXNEcmFnZ2luZykge1xyXG4gICAgICAgIHRoaXMuZGVzdHJveUNhbnZhc0xpc3RlbmVycygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuYWRkQ2FudmFzTGlzdGVuZXJzKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKChzZW5kTm93KSA9PiB7XHJcbiAgICAgIGlmIChzZW5kTm93ID09PSB0cnVlKSB7XHJcbiAgICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2V0RmVlZGJhY2sodGhpcy5mZWVkYmFjayk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2hvd0JhY2tEcm9wKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZXhwYW5kRHJhd2luZ0JvYXJkKCkge1xyXG4gICAgdGhpcy5zaG93VG9vbGJhciA9IHRydWU7XHJcbiAgICBpZiAoIXRoaXMuZHJhd0NhbnZhcykge1xyXG4gICAgICB0aGlzLmRldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgdGhpcy5pbml0QmFja2dyb3VuZENhbnZhcygpO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWRlQmFja0Ryb3AoKTtcclxuICAgIH1cclxuICAgIHRoaXMuYWRkQ2FudmFzTGlzdGVuZXJzKCk7XHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5kcmF3Q2FudmFzKTtcclxuICAgIHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZGVCYWNrRHJvcCgpO1xyXG4gICAgY29uc29sZS5sb2coJ2V4cGFuZCB0aGUgYm9hcmQnKTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJywgWyckZXZlbnQnXSlcclxuICBwdWJsaWMgb25Fc2NhcGVLZXlEb3duSGFuZGxlcihldnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgIHRoaXMuc2hvd1Rvb2xiYXIgPSBmYWxzZTtcclxuICAgIHRoaXMuaW5jbHVkZVNjcmVlbnNob3QgPSB0cnVlO1xyXG4gICAgdGhpcy5kZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgna2V5IGRvd24gZXNjIHRvIGNsb3NlJyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbWFuaXB1bGF0ZShtYW5pcHVsYXRpb246IHN0cmluZykge1xyXG4gICAgaWYgKG1hbmlwdWxhdGlvbiA9PT0gJ2RvbmUnKSB7XHJcbiAgICAgIHRoaXMuc2hvd1Rvb2xiYXJUaXBzID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gICAgICB0aGlzLmRlc3Ryb3lDYW52YXNMaXN0ZW5lcnMoKTtcclxuICAgICAgdGhpcy5zaG93VG9vbGJhciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmRldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcclxuICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaW5pdFNjcmVlbnNob3RDYW52YXMoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc3RhcnREcmF3KG1hbmlwdWxhdGlvbik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc3RhcnREcmF3KGNvbG9yOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuZHJhd0NvbG9yID0gY29sb3I7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgaXNJbmNsdWRlU2NyZWVuc2hvdCgpIHtcclxuICAgIGlmICh0aGlzLmluY2x1ZGVTY3JlZW5zaG90KSB7XHJcbiAgICAgIHRoaXMuZGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICB0aGlzLnNob3dTcGlubmVyID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuYXBwZW5kU2NyZWVuc2hvdCgpO1xyXG4gICAgICB0aGlzLmZlZWRiYWNrLnNjcmVlbnNob3QgPSB0aGlzLnNjcmVlbnNob3RFbGUuZ2V0QXR0cmlidXRlKCdzcmMnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRlbGV0ZSB0aGlzLmZlZWRiYWNrWydzY3JlZW5zaG90J107XHJcbiAgICAgIHRoaXMuc2hvd1NwaW5uZXIgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhcHBlbmRTY3JlZW5zaG90KCkge1xyXG4gICAgaWYgKHRoaXMuc2NyZWVuc2hvdFBhcmVudCkgeyB0aGlzLnNjcmVlbnNob3RQYXJlbnQubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnNjcmVlbnNob3RFbGUpOyB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRCYWNrZ3JvdW5kQ2FudmFzKCkge1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RyYXctY2FudmFzJykgYXMgSFRNTENhbnZhc0VsZW1lbnQ7XHJcbiAgICAvLyBUaGUgY2FudmFzIHRvIGRyYXcsIG11c3QgdXNlIHRoaXMgd2F5IHRvIGluaXRpYWwgdGhlIGhlaWdodCBhbmQgd2lkdGhcclxuICAgIHRoaXMuZHJhd0NhbnZhcy5zdHlsZS5oZWlnaHQgPSB0aGlzLnNjcm9sbEhlaWdodCArICcnO1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLnN0eWxlLndpZHRoID0gdGhpcy5zY3JvbGxXaWR0aCArICcnO1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLmhlaWdodCA9IHRoaXMuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgdGhpcy5kcmF3Q2FudmFzLndpZHRoID0gdGhpcy5zY3JvbGxXaWR0aDtcclxuICAgIHRoaXMuZHJhd0NvbnRhaW5lclJlY3QoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0NvbnRhaW5lclJlY3QoKSB7XHJcbiAgICBjb25zdCBkcmF3Q29udGV4dCA9IHRoaXMuZHJhd0NhbnZhcy5nZXRDb250ZXh0KCcyZCcpLFxyXG4gICAgICB3aWR0aCA9IHRoaXMuc2Nyb2xsV2lkdGgsXHJcbiAgICAgIGhlaWdodCA9IHRoaXMuc2Nyb2xsSGVpZ2h0O1xyXG4gICAgZHJhd0NvbnRleHQuYmVnaW5QYXRoKCk7XHJcbiAgICBkcmF3Q29udGV4dC5maWxsU3R5bGUgPSAncmdiYSgwLDAsMCwwLjMpJztcclxuICAgIGRyYXdDb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcclxuICAgIGRyYXdDb250ZXh0LmZpbGxSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOyAvLyBkcmF3IHRoZSByZWN0YW5nbGVcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd1JlY3RhbmdsZShyZWN0OiBSZWN0YW5nbGUpIHtcclxuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmRyYXdDYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcclxuICAgIGNvbnRleHQubGluZUpvaW4gPSAncm91bmQnO1xyXG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcclxuICAgIGlmIChyZWN0LmNvbG9yID09PSB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWRkZW5Db2xvcikge1xyXG4gICAgICBjb250ZXh0LmZpbGxTdHlsZSA9ICdyZ2JhKDMxLCAzMSwgMzEsIDAuNzUpJztcclxuICAgICAgY29udGV4dC5maWxsUmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgY29udGV4dC5yZWN0KHJlY3Quc3RhcnRYLCByZWN0LnN0YXJ0WSwgcmVjdC53aWR0aCwgcmVjdC5oZWlnaHQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dC5jbGVhclJlY3QocmVjdC5zdGFydFgsIHJlY3Quc3RhcnRZLCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7XHJcbiAgICAgIGNvbnRleHQubGluZVdpZHRoID0gNTtcclxuICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IHJlY3QuY29sb3I7XHJcbiAgICAgIGNvbnRleHQucmVjdChyZWN0LnN0YXJ0WCwgcmVjdC5zdGFydFksIHJlY3Qud2lkdGgsIHJlY3QuaGVpZ2h0KTtcclxuICAgICAgY29udGV4dC5zdHJva2UoKTtcclxuICAgICAgY29udGV4dC5jbGVhclJlY3QocmVjdC5zdGFydFgsIHJlY3Quc3RhcnRZLCByZWN0LndpZHRoLCByZWN0LmhlaWdodCk7XHJcbiAgICAgIHRoaXMucmVjdGFuZ2xlcy5mb3JFYWNoKHRtcFJlY3QgPT4ge1xyXG4gICAgICAgIGlmICh0bXBSZWN0LmNvbG9yID09PSB0aGlzLmZlZWRiYWNrU2VydmljZS5oaWdobGlnaHRlZENvbG9yKSB7XHJcbiAgICAgICAgICBjb250ZXh0LmNsZWFyUmVjdCh0bXBSZWN0LnN0YXJ0WCwgdG1wUmVjdC5zdGFydFksIHRtcFJlY3Qud2lkdGgsIHRtcFJlY3QuaGVpZ2h0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRDYW52YXNMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCBtb3VzZVVwID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZXVwJyksXHJcbiAgICAgICAgICBtb3VzZU1vdmUgPSBvYnNlcnZhYmxlRnJvbUV2ZW50KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgJ21vdXNlbW92ZScpLFxyXG4gICAgICAgICAgbW91c2VEb3duID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZWRvd24nKSxcclxuICAgICAgICAgIHNjcm9sbCA9IG9ic2VydmFibGVGcm9tRXZlbnQod2luZG93LCAnc2Nyb2xsJyk7XHJcblxyXG4gICAgdGhpcy5tYW51YWxseURyYXdSZWN0KG1vdXNlRG93biwgbW91c2VNb3ZlLCBtb3VzZVVwKTtcclxuICAgIHRoaXMuYXV0b0RyYXdSZWN0KG1vdXNlTW92ZSk7XHJcbiAgICB0aGlzLmNoYW5nZVJlY3RQb3NpdGlvbihzY3JvbGwpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGFuZ2VSZWN0UG9zaXRpb24oc2Nyb2xsOiBPYnNlcnZhYmxlPEV2ZW50Pikge1xyXG4gICAgc2Nyb2xsLnN1YnNjcmliZShcclxuICAgICAgZXZlbnQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGN1cnJlbnRXaW5kb3dTY3JvbGxYID0gd2luZG93LnNjcm9sbFgsXHJcbiAgICAgICAgICAgICAgY3VycmVudFdpbmRvd1Njcm9sbFkgPSB3aW5kb3cuc2Nyb2xsWTtcclxuICAgICAgICB0aGlzLnJlY3RhbmdsZXMuZm9yRWFjaChyZWN0ID0+IHtcclxuICAgICAgICAgIHJlY3Quc3RhcnRZID0gcmVjdC5zdGFydFkgLSAoY3VycmVudFdpbmRvd1Njcm9sbFkgLSByZWN0LndpbmRvd1Njcm9sbFkpO1xyXG4gICAgICAgICAgcmVjdC5zdGFydFggPSByZWN0LnN0YXJ0WCAtIChjdXJyZW50V2luZG93U2Nyb2xsWCAtIHJlY3Qud2luZG93U2Nyb2xsWCk7XHJcbiAgICAgICAgICByZWN0LndpbmRvd1Njcm9sbFkgPSBjdXJyZW50V2luZG93U2Nyb2xsWTtcclxuICAgICAgICAgIHJlY3Qud2luZG93U2Nyb2xsWCA9IGN1cnJlbnRXaW5kb3dTY3JvbGxYO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yID0+IGNvbnNvbGUuZXJyb3IoZXJyb3IpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZXN0cm95Q2FudmFzTGlzdGVuZXJzKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMubWFudWFsbHlEcmF3UmVjdCQpIHsgdGhpcy5tYW51YWxseURyYXdSZWN0JC51bnN1YnNjcmliZSgpOyB9XHJcbiAgICBpZiAodGhpcy5hdXRvRHJhd1JlY3QkKSB7IHRoaXMuYXV0b0RyYXdSZWN0JC51bnN1YnNjcmliZSgpOyB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG1hbnVhbGx5RHJhd1JlY3QobW91c2VEb3duOiBPYnNlcnZhYmxlPEV2ZW50PiwgbW91c2VNb3ZlOiBPYnNlcnZhYmxlPEV2ZW50PiwgbW91c2VVcDogT2JzZXJ2YWJsZTxFdmVudD4pOiB2b2lkIHtcclxuICAgIGNvbnN0IG1vdXNlRHJhZyA9IG1vdXNlRG93bi5waXBlKG1lcmdlTWFwKChtb3VzZURvd25FdmVudDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgICBpZiAodGhpcy5zaG93VG9vbGJhclRpcHMpIHsgdGhpcy5zaG93VG9vbGJhclRpcHMgPSBmYWxzZTsgfVxyXG4gICAgICB0aGlzLmF1dG9EcmF3UmVjdCQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgdGhpcy5pc0RyYXdpbmdSZWN0ID0gdHJ1ZTtcclxuXHJcbiAgICAgIGNvbnN0IG5ld1JlY3RhbmdsZSA9IG5ldyBSZWN0YW5nbGUoKTtcclxuICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WCA9IG1vdXNlRG93bkV2ZW50LmNsaWVudFg7XHJcbiAgICAgIG5ld1JlY3RhbmdsZS5zdGFydFkgPSBtb3VzZURvd25FdmVudC5jbGllbnRZO1xyXG4gICAgICBuZXdSZWN0YW5nbGUuY29sb3IgPSB0aGlzLmRyYXdDb2xvcjtcclxuXHJcbiAgICAgIHJldHVybiBtb3VzZU1vdmUucGlwZShcclxuICAgICAgICBtYXAoKG1vdXNlTW92ZUV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgICBuZXdSZWN0YW5nbGUud2lkdGggPSBtb3VzZU1vdmVFdmVudC5jbGllbnRYIC0gbW91c2VEb3duRXZlbnQuY2xpZW50WDtcclxuICAgICAgICAgIG5ld1JlY3RhbmdsZS5oZWlnaHQgPSBtb3VzZU1vdmVFdmVudC5jbGllbnRZIC0gbW91c2VEb3duRXZlbnQuY2xpZW50WTtcclxuICAgICAgICAgIHJldHVybiBuZXdSZWN0YW5nbGU7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xyXG4gICAgICAgICAgLy8gY2xpY2sgdG8gZHJhdyByZWN0YW5nbGVcclxuICAgICAgICAgIGlmIChuZXdSZWN0YW5nbGUud2lkdGggPT09IHVuZGVmaW5lZCB8fCBuZXdSZWN0YW5nbGUuaGVpZ2h0ID09PSB1bmRlZmluZWQgfHxcclxuICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLndpZHRoID09PSAwIHx8IG5ld1JlY3RhbmdsZS5oZWlnaHQgPT09IDApIHtcclxuICAgICAgICAgICAgY29uc3QgcmVjdCA9IHRoaXMuZHJhd1RlbXBDYW52YXNSZWN0YW5nbGUobW91c2VEb3duRXZlbnQpO1xyXG4gICAgICAgICAgICBpZiAocmVjdCkgeyB0aGlzLnJlY3RhbmdsZXMucHVzaChyZWN0KTsgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIGRyYWcgdG8gZHJhdyByZWN0YW5nbGVcclxuICAgICAgICAgICAgaWYgKG5ld1JlY3RhbmdsZS5oZWlnaHQgPCAwKSB7XHJcbiAgICAgICAgICAgICAgbmV3UmVjdGFuZ2xlLnN0YXJ0WSA9IG5ld1JlY3RhbmdsZS5zdGFydFkgKyBuZXdSZWN0YW5nbGUuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS5oZWlnaHQgPSBNYXRoLmFicyhuZXdSZWN0YW5nbGUuaGVpZ2h0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAobmV3UmVjdGFuZ2xlLndpZHRoIDwgMCkge1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS5zdGFydFggPSBuZXdSZWN0YW5nbGUuc3RhcnRYICsgbmV3UmVjdGFuZ2xlLndpZHRoO1xyXG4gICAgICAgICAgICAgIG5ld1JlY3RhbmdsZS53aWR0aCA9IE1hdGguYWJzKG5ld1JlY3RhbmdsZS53aWR0aCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5yZWN0YW5nbGVzLnB1c2gobmV3UmVjdGFuZ2xlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgICAgICB0aGlzLmF1dG9EcmF3UmVjdChtb3VzZU1vdmUpO1xyXG4gICAgICAgICAgdGhpcy5pc0RyYXdpbmdSZWN0ID0gZmFsc2U7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgdGFrZVVudGlsKG1vdXNlVXApKTtcclxuICAgIH0pKTtcclxuXHJcbiAgICB0aGlzLm1hbnVhbGx5RHJhd1JlY3QkID0gbW91c2VEcmFnLnN1YnNjcmliZShcclxuICAgICAgKHJlYykgPT4ge1xyXG4gICAgICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKHJlYyk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGF1dG9EcmF3UmVjdChtb3VzZU1vdmU6IE9ic2VydmFibGU8RXZlbnQ+KTogdm9pZCB7XHJcbiAgICB0aGlzLmF1dG9EcmF3UmVjdCQgPSBtb3VzZU1vdmUuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKG1vdXNlTW92ZUV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XHJcbiAgICAgICAgdGhpcy5kcmF3UGVyc2lzdENhbnZhc1JlY3RhbmdsZXMoKTtcclxuICAgICAgICB0aGlzLmRyYXdUZW1wQ2FudmFzUmVjdGFuZ2xlKG1vdXNlTW92ZUV2ZW50KTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IGVyciA9PiBjb25zb2xlLmVycm9yKCdzb21ldGhpbmcgd3Jvbmcgb2NjdXJyZWQ6ICcgKyBlcnIpLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRyYXdQZXJzaXN0Q2FudmFzUmVjdGFuZ2xlcygpIHtcclxuICAgIHRoaXMuZHJhd0NvbnRhaW5lclJlY3QoKTtcclxuICAgIHRoaXMucmVjdGFuZ2xlcy5mb3JFYWNoKHRtcFJlY3QgPT4ge1xyXG4gICAgICB0aGlzLmRyYXdSZWN0YW5nbGUodG1wUmVjdCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd1RlbXBDYW52YXNSZWN0YW5nbGUoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGxldCByZWN0YW5nbGU6IFJlY3RhbmdsZSA9IG51bGw7XHJcbiAgICBjb25zdCBjbGllbnRYID0gZXZlbnQuY2xpZW50WCxcclxuICAgICAgICAgIGNsaWVudFkgPSBldmVudC5jbGllbnRZLFxyXG4gICAgICAgICAgZWxzID0gZG9jdW1lbnQuZWxlbWVudHNGcm9tUG9pbnQoY2xpZW50WCwgY2xpZW50WSksXHJcbiAgICAgICAgICBlbCA9IGVsc1syXTtcclxuICAgIGlmICgoIXRoaXMuaXNFeGNsdWRlUmVjdChlbHMpKSAmJiBlbCAmJiB0aGlzLmVsQ291bGRCZUhpZ2hsaWdodGVkLmluZGV4T2YoZWwubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgPiAtMSkge1xyXG4gICAgICByZWN0YW5nbGUgPSBuZXcgUmVjdGFuZ2xlKCk7XHJcbiAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgdGhpcy5kcmF3Q2FudmFzLnN0eWxlLmN1cnNvciA9ICdwb2ludGVyJztcclxuXHJcbiAgICAgIE9iamVjdC5hc3NpZ24ocmVjdGFuZ2xlLCB7XHJcbiAgICAgICAgc3RhcnRYOiByZWN0LmxlZnQsXHJcbiAgICAgICAgc3RhcnRZOiByZWN0LnRvcCxcclxuICAgICAgICB3aWR0aDogcmVjdC53aWR0aCxcclxuICAgICAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0LFxyXG4gICAgICAgIGNvbG9yOiB0aGlzLmRyYXdDb2xvclxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKHJlY3RhbmdsZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmRyYXdDYW52YXMuc3R5bGUuY3Vyc29yID0gJ2Nyb3NzaGFpcic7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVjdGFuZ2xlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGNsb3NlUmVjdChpbmRleDogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnJlY3RhbmdsZXMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIHRoaXMuZHJhd1BlcnNpc3RDYW52YXNSZWN0YW5nbGVzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGlzRXhjbHVkZVJlY3QoZWxlbWVudHM6IEVsZW1lbnRbXSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3QgcmVzdWx0ID0gZWxlbWVudHMuc29tZSggZWwgPT4ge1xyXG4gICAgICByZXR1cm4gZWwuZ2V0QXR0cmlidXRlKCdleGNsdWRlLXJlY3QnKSA9PT0gJ3RydWUnO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQge2Zyb21FdmVudCBhcyBvYnNlcnZhYmxlRnJvbUV2ZW50fSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7dGFrZVVudGlsLCBmaW5hbGl6ZSwgbWFwLCBtZXJnZU1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQge0NvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBBZnRlclZpZXdJbml0LCBWaWV3Q2hpbGQsIE9uQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuXHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2ZlZWRiYWNrLXRvb2xiYXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9mZWVkYmFjay10b29sYmFyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9mZWVkYmFjay10b29sYmFyLmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrVG9vbGJhckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcyB7XHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZHJhd0NvbG9yOiBzdHJpbmc7XHJcbiAgQE91dHB1dCgpXHJcbiAgcHVibGljIG1hbmlwdWxhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBwdWJsaWMgZGlzYWJsZVRvb2xiYXJUaXBzID0gZmFsc2U7XHJcbiAgQFZpZXdDaGlsZCgndG9nZ2xlTW92ZScpXHJcbiAgcHJpdmF0ZSB0b2dnbGVNb3ZlQnRuOiBFbGVtZW50UmVmO1xyXG4gIHB1YmxpYyBpc1N3aXRjaCA9IGZhbHNlO1xyXG4gIHB1YmxpYyBpc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgcHVibGljIHZhcnM6IG9iamVjdCA9IHt9O1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWw6IEVsZW1lbnRSZWYsIHByaXZhdGUgZmVlZGJhY2tTZXJ2aWNlOiBGZWVkYmFja1NlcnZpY2UpIHtcclxuICAgIHRoaXMudmFycyA9IGZlZWRiYWNrU2VydmljZS5pbml0aWFsVmFyaWFibGVzO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGNvbnN0IGVsU3R5bGUgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuc3R5bGU7XHJcbiAgICBlbFN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcclxuICAgIGVsU3R5bGUubGVmdCA9ICc0MyUnO1xyXG4gICAgZWxTdHlsZS50b3AgPSAnNjAlJztcclxuICAgIHRoaXMuYWRkRHJhZ0xpc3RlbmVyT25Nb3ZlQnRuKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoKSB7XHJcbiAgICB0aGlzLmlzU3dpdGNoID0gdGhpcy5kcmF3Q29sb3IgIT09IHRoaXMuZmVlZGJhY2tTZXJ2aWNlLmhpZ2hsaWdodGVkQ29sb3I7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZG9uZSgpIHtcclxuICAgIHRoaXMubWFuaXB1bGF0ZS5lbWl0KCdkb25lJyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdG9nZ2xlSGlnaGxpZ2h0KCkge1xyXG4gICAgdGhpcy5pc1N3aXRjaCA9IGZhbHNlO1xyXG4gICAgdGhpcy5tYW5pcHVsYXRlLmVtaXQodGhpcy5mZWVkYmFja1NlcnZpY2UuaGlnaGxpZ2h0ZWRDb2xvcik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdG9nZ2xlSGlkZSgpIHtcclxuICAgIHRoaXMuaXNTd2l0Y2ggPSB0cnVlO1xyXG4gICAgdGhpcy5tYW5pcHVsYXRlLmVtaXQodGhpcy5mZWVkYmFja1NlcnZpY2UuaGlkZGVuQ29sb3IpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFkZERyYWdMaXN0ZW5lck9uTW92ZUJ0bigpIHtcclxuICAgIGNvbnN0IG1vdXNlVXAgPSBvYnNlcnZhYmxlRnJvbUV2ZW50KHRoaXMudG9nZ2xlTW92ZUJ0bi5uYXRpdmVFbGVtZW50LCAnbW91c2V1cCcpO1xyXG4gICAgY29uc3QgbW91c2VNb3ZlID0gb2JzZXJ2YWJsZUZyb21FdmVudChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsICdtb3VzZW1vdmUnKTtcclxuICAgIGNvbnN0IG1vdXNlRG93biA9IG9ic2VydmFibGVGcm9tRXZlbnQodGhpcy50b2dnbGVNb3ZlQnRuLm5hdGl2ZUVsZW1lbnQsICdtb3VzZWRvd24nKTtcclxuICAgIGNvbnN0IG1vdXNlRHJhZyA9IG1vdXNlRG93bi5waXBlKG1lcmdlTWFwKChtZDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5zZXRJc0RyYWdnaW5nVG9vbGJhcih0cnVlKTtcclxuICAgICAgY29uc3Qgc3RhcnRYID0gbWQub2Zmc2V0WDtcclxuICAgICAgY29uc3Qgc3RhcnRZID0gbWQub2Zmc2V0WTtcclxuICAgICAgdGhpcy5kaXNhYmxlVG9vbGJhclRpcHMgPSB0cnVlO1xyXG4gICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICAvLyBDYWxjdWxhdGUgZGlmIHdpdGggbW91c2Vtb3ZlIHVudGlsIG1vdXNldXBcclxuICAgICAgcmV0dXJuIG1vdXNlTW92ZS5waXBlKFxyXG4gICAgICAgIG1hcCgobW06IE1vdXNlRXZlbnQpID0+IHtcclxuICAgICAgICAgIG1tLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICBsZWZ0OiBtbS5jbGllbnRYIC0gc3RhcnRYLFxyXG4gICAgICAgICAgICB0b3A6IG1tLmNsaWVudFkgLSBzdGFydFlcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgZmluYWxpemUoKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLmRpc2FibGVUb29sYmFyVGlwcyA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy5mZWVkYmFja1NlcnZpY2Uuc2V0SXNEcmFnZ2luZ1Rvb2xiYXIoZmFsc2UpO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIHRha2VVbnRpbChtb3VzZVVwKSk7XHJcbiAgICB9KSk7XHJcbiAgICBtb3VzZURyYWcuc3Vic2NyaWJlKFxyXG4gICAgICAocG9zKSA9PiB7XHJcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLmxlZnQgPSBwb3MubGVmdCArICdweCc7XHJcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LnN0eWxlLnRvcCA9IHBvcy50b3AgKyAncHgnO1xyXG4gICAgICB9KTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtSZWN0YW5nbGV9IGZyb20gJy4uL2VudGl0eS9yZWN0YW5nbGUnO1xyXG5pbXBvcnQge0ZlZWRiYWNrU2VydmljZX0gZnJvbSAnLi4vZmVlZGJhY2suc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2ZlZWRiYWNrLXJlY3RhbmdsZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2ZlZWRiYWNrLXJlY3RhbmdsZS5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZmVlZGJhY2stcmVjdGFuZ2xlLmNvbXBvbmVudC5jc3MnXVxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrUmVjdGFuZ2xlQ29tcG9uZW50IHtcclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyByZWN0YW5nbGU6IFJlY3RhbmdsZTtcclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBub0hvdmVyOiBib29sZWFuO1xyXG4gIEBPdXRwdXQoKVxyXG4gIHB1YmxpYyBjbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuICBwdWJsaWMgc2hvd0Nsb3NlVGFnOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBmZWVkYmFja1NlcnZpY2U6IEZlZWRiYWNrU2VydmljZSkge1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VlbnRlcicpXHJcbiAgcHVibGljIG9uTW91c2VFbnRlcigpOiB2b2lkIHtcclxuICAgIHRoaXMuc2hvd0Nsb3NlVGFnID0gdGhpcy5ub0hvdmVyID09PSBmYWxzZTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gIHB1YmxpYyBvbk1vdXNlTGVhdmUoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNob3dDbG9zZVRhZyA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uQ2xvc2UoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsb3NlLmVtaXQoKTtcclxuICB9XHJcblxyXG5cclxufVxyXG4iLCJpbXBvcnQge0RpcmVjdGl2ZSwgSG9zdExpc3RlbmVyLCBFdmVudEVtaXR0ZXIsIE91dHB1dCwgSW5wdXQsIE9uSW5pdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7TWF0RGlhbG9nfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2tEaWFsb2dDb21wb25lbnR9IGZyb20gJy4vZmVlZGJhY2stZGlhbG9nL2ZlZWRiYWNrLWRpYWxvZy5jb21wb25lbnQnO1xyXG5pbXBvcnQge0ZlZWRiYWNrU2VydmljZX0gZnJvbSAnLi9mZWVkYmFjay5zZXJ2aWNlJztcclxuaW1wb3J0IHtPdmVybGF5fSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XHJcblxyXG5ARGlyZWN0aXZlKHtzZWxlY3RvcjogJ1tmZWVkYmFja10nfSlcclxuZXhwb3J0IGNsYXNzIEZlZWRiYWNrRGlyZWN0aXZlIGltcGxlbWVudHMgT25Jbml0IHtcclxuICBwcml2YXRlIG92ZXJsYXk6IE92ZXJsYXk7XHJcbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZyA9ICdTZW5kIGZlZWRiYWNrJztcclxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ0Rlc2NyaWJlIHlvdXIgaXNzdWUgb3Igc2hhcmUgeW91ciBpZGVhcyc7XHJcbiAgQElucHV0KCkgZWRpdFRpcCA9ICdDbGljayB0byBoaWdobGlnaHQgb3IgaGlkZSBpbmZvJztcclxuICBASW5wdXQoKSBjaGVja2JveExhYmVsID0gJ0luY2x1ZGUgc2NyZWVuc2hvdCc7XHJcbiAgQElucHV0KCkgY2FuY2VsTGFiZWwgPSAnQ0FOQ0VMJztcclxuICBASW5wdXQoKSBzZW5kTGFiZWwgPSAnU0VORCc7XHJcbiAgQElucHV0KCkgbW92ZVRvb2xiYXJUaXAgPSAnbW92ZSB0b29sYmFyJztcclxuICBASW5wdXQoKSBkcmF3UmVjdFRpcCA9ICdEcmF3IHVzaW5nIHllbGxvdyB0byBoaWdobGlnaHQgaXNzdWVzIG9yIGJsYWNrIHRvIGhpZGUgc2Vuc2l0aXZlIGluZm8nO1xyXG4gIEBJbnB1dCgpIGhpZ2hsaWdodFRpcCA9ICdoaWdobGlnaHQgaXNzdWVzJztcclxuICBASW5wdXQoKSBoaWRlVGlwID0gJ2hpZGUgc2Vuc2l0aXZlIGluZm8nO1xyXG4gIEBJbnB1dCgpIGVkaXREb25lTGFiZWwgPSAnRE9ORSc7XHJcbiAgQE91dHB1dCgpIHB1YmxpYyBzZW5kID0gbmV3IEV2ZW50RW1pdHRlcjxvYmplY3Q+KCk7XHJcblxyXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIGRpYWxvZ1JlZjogTWF0RGlhbG9nLCBwcml2YXRlIGZlZWRiYWNrU2VydmljZTogRmVlZGJhY2tTZXJ2aWNlLCBvdmVybGF5OiBPdmVybGF5KSB7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5mZWVkYmFjayQuc3Vic2NyaWJlKFxyXG4gICAgICAoZmVlZGJhY2spID0+IHtcclxuICAgICAgICB0aGlzLnNlbmQuZW1pdChmZWVkYmFjayk7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgICB0aGlzLm92ZXJsYXkgPSBvdmVybGF5O1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignY2xpY2snKVxyXG4gIHB1YmxpYyBvbkNsaWNrKCkge1xyXG4gICAgdGhpcy5vcGVuRmVlZGJhY2tEaWFsb2coKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvcGVuRmVlZGJhY2tEaWFsb2coKSB7XHJcbiAgICB0aGlzLmZlZWRiYWNrU2VydmljZS5pbml0U2NyZWVuc2hvdENhbnZhcygpO1xyXG4gICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5kaWFsb2dSZWYub3BlbihGZWVkYmFja0RpYWxvZ0NvbXBvbmVudCwge1xyXG4gICAgICBwYW5lbENsYXNzOiAnZmVlZGJhY2tEaWFsb2cnLFxyXG4gICAgICBiYWNrZHJvcENsYXNzOiAnZGlhbG9nQmFja0Ryb3AnLFxyXG4gICAgICBkaXNhYmxlQ2xvc2U6IHRydWUsXHJcbiAgICAgIGhlaWdodDogJ2F1dG8nLFxyXG4gICAgICB3aWR0aDogJ2F1dG8nLFxyXG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5mZWVkYmFja1NlcnZpY2UuaW5pdGlhbFZhcmlhYmxlcyA9IHtcclxuICAgICAgdGl0bGU6IHRoaXMudGl0bGUsXHJcbiAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLnBsYWNlaG9sZGVyLFxyXG4gICAgICBlZGl0VGlwOiB0aGlzLmVkaXRUaXAsXHJcbiAgICAgIGNoZWNrYm94TGFiZWw6IHRoaXMuY2hlY2tib3hMYWJlbCxcclxuICAgICAgY2FuY2VsTGFiZWw6IHRoaXMuY2FuY2VsTGFiZWwsXHJcbiAgICAgIHNlbmRMYWJlbDogdGhpcy5zZW5kTGFiZWwsXHJcbiAgICAgIG1vdmVUb29sYmFyVGlwOiB0aGlzLm1vdmVUb29sYmFyVGlwLFxyXG4gICAgICBkcmF3UmVjdFRpcDogdGhpcy5kcmF3UmVjdFRpcCxcclxuICAgICAgaGlnaGxpZ2h0VGlwOiB0aGlzLmhpZ2hsaWdodFRpcCxcclxuICAgICAgaGlkZVRpcDogdGhpcy5oaWRlVGlwLFxyXG4gICAgICBlZGl0RG9uZUxhYmVsOiB0aGlzLmVkaXREb25lTGFiZWxcclxuICAgIH07XHJcbiAgfVxyXG5cclxufVxyXG4iLCJpbXBvcnQge05nTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtDb21tb25Nb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7Rm9ybXNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHtGZWVkYmFja0RpYWxvZ0NvbXBvbmVudH0gZnJvbSAnLi9mZWVkYmFjay1kaWFsb2cvZmVlZGJhY2stZGlhbG9nLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7RmVlZGJhY2tUb29sYmFyQ29tcG9uZW50fSBmcm9tICcuL2ZlZWRiYWNrLXRvb2xiYXIvZmVlZGJhY2stdG9vbGJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQge0ZlZWRiYWNrUmVjdGFuZ2xlQ29tcG9uZW50fSBmcm9tICcuL2ZlZWRiYWNrLXJlY3RhbmdsZS9mZWVkYmFjay1yZWN0YW5nbGUuY29tcG9uZW50JztcclxuaW1wb3J0IHtcclxuICBNYXREaWFsb2dNb2R1bGUsXHJcbiAgTWF0QnV0dG9uTW9kdWxlLFxyXG4gIE1hdEljb25Nb2R1bGUsXHJcbiAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgTWF0VG9vbHRpcE1vZHVsZSxcclxuICBNYXRDaGVja2JveE1vZHVsZSxcclxuICBNYXRQcm9ncmVzc1NwaW5uZXJNb2R1bGVcclxufSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbCc7XHJcbmltcG9ydCB7RmVlZGJhY2tTZXJ2aWNlfSBmcm9tICcuL2ZlZWRiYWNrLnNlcnZpY2UnO1xyXG5pbXBvcnQge0ZlZWRiYWNrRGlyZWN0aXZlfSBmcm9tICcuL2ZlZWRiYWNrLmRpcmVjdGl2ZSc7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGRlY2xhcmF0aW9uczogW1xyXG4gICAgRmVlZGJhY2tEaWFsb2dDb21wb25lbnQsXHJcbiAgICBGZWVkYmFja1Rvb2xiYXJDb21wb25lbnQsXHJcbiAgICBGZWVkYmFja1JlY3RhbmdsZUNvbXBvbmVudCxcclxuICAgIEZlZWRiYWNrRGlyZWN0aXZlXHJcbiAgXSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBNYXREaWFsb2dNb2R1bGUsXHJcbiAgICBNYXRCdXR0b25Nb2R1bGUsXHJcbiAgICBNYXRJY29uTW9kdWxlLFxyXG4gICAgTWF0SW5wdXRNb2R1bGUsXHJcbiAgICBNYXRUb29sdGlwTW9kdWxlLFxyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgRm9ybXNNb2R1bGUsXHJcbiAgICBNYXRDaGVja2JveE1vZHVsZSxcclxuICAgIE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZVxyXG4gIF0sXHJcbiAgZXhwb3J0czogW1xyXG4gICAgRmVlZGJhY2tEaXJlY3RpdmVcclxuICBdLFxyXG4gIGVudHJ5Q29tcG9uZW50czogW1xyXG4gICAgRmVlZGJhY2tEaWFsb2dDb21wb25lbnRcclxuICBdLFxyXG4gIHByb3ZpZGVyczogW1xyXG4gICAgRmVlZGJhY2tTZXJ2aWNlXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tNb2R1bGUge1xyXG59XHJcbiJdLCJuYW1lcyI6WyJTdWJqZWN0IiwiSW5qZWN0YWJsZSIsIm9ic2VydmFibGVGcm9tRXZlbnQiLCJtZXJnZU1hcCIsIm1hcCIsImZpbmFsaXplIiwidGFrZVVudGlsIiwiQ29tcG9uZW50IiwiTWF0RGlhbG9nUmVmIiwiQ2hhbmdlRGV0ZWN0b3JSZWYiLCJFbGVtZW50UmVmIiwiVmlld0NoaWxkIiwiSG9zdExpc3RlbmVyIiwiRXZlbnRFbWl0dGVyIiwiSW5wdXQiLCJPdXRwdXQiLCJvdmVybGF5IiwiRGlyZWN0aXZlIiwiTWF0RGlhbG9nIiwiT3ZlcmxheSIsIk5nTW9kdWxlIiwiTWF0RGlhbG9nTW9kdWxlIiwiTWF0QnV0dG9uTW9kdWxlIiwiTWF0SWNvbk1vZHVsZSIsIk1hdElucHV0TW9kdWxlIiwiTWF0VG9vbHRpcE1vZHVsZSIsIkNvbW1vbk1vZHVsZSIsIkZvcm1zTW9kdWxlIiwiTWF0Q2hlY2tib3hNb2R1bGUiLCJNYXRQcm9ncmVzc1NwaW5uZXJNb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztJQUFBLElBQUE7Ozt1QkFBQTtRQUdDLENBQUE7Ozs7OztBQ0hEOztvQ0FPb0MsRUFBRTtvQ0FDVixRQUFROytCQUNiLE9BQU87MENBQ0ssSUFBSUEsWUFBTyxFQUFxQjtxQ0FDUCxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxFQUFFO2tDQUUzRSxJQUFJQSxZQUFPLEVBQVk7NkJBQ1AsSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUU7MkNBRXpDLElBQUlBLFlBQU8sRUFBVztzQ0FDUCxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFOzs7OztRQUdyRiw4Q0FBb0I7Ozs7OztnQkFFekIsSUFB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