UNPKG

ngx-mat-dropdown

Version:
681 lines 60.7 kB
/**
 * @fileoverview added by tsickle
 * Generated from: lib/mat-select-search/mat-select-search.component.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Inject, Input, ViewChild, HostBinding, Optional } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MatSelect } from '@angular/material/select';
import { delay, take, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { MatOption } from '@angular/material/core';
var MatSelectSearchComponent = /** @class */ (function () {
    function MatSelectSearchComponent(matSelect, changeDetectorRef, matOption) {
        if (matOption === void 0) { matOption = null; }
        this.matSelect = matSelect;
        this.changeDetectorRef = changeDetectorRef;
        this.matOption = matOption;
        /**
         * Label of the search placeholder
         */
        this.placeholderLabel = 'Search';
        this.multiple = false;
        this.showSearch = true;
        /**
         * Label to be shown when no entries are found. Set to null if no message should be shown.
         */
        this.noEntriesFoundLabel = 'No Data';
        this.onChange = (/**
         * @param {?} _
         * @return {?}
         */
        function (_) { });
        this.onTouched = (/**
         * @param {?} _
         * @return {?}
         */
        function (_) { });
        /**
         * Whether the backdrop class has been set
         */
        this.overlayClassSet = false;
        /**
         * Event that emits when the current value changes
         */
        this.change = new EventEmitter();
        this.AllClicked = new EventEmitter();
        /**
         * Subject that emits when the component has been destroyed.
         */
        this._onDestroy = new Subject();
    }
    Object.defineProperty(MatSelectSearchComponent.prototype, "isInsideMatOption", {
        //@ViewChild('innerSelectall', { read: ElementRef }) innerSelectall: ElementRef;
        get: 
        //@ViewChild('innerSelectall', { read: ElementRef }) innerSelectall: ElementRef;
        /**
         * @return {?}
         */
        function () {
            return !!this.matOption;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MatSelectSearchComponent.prototype, "value", {
        /** Current search value */
        get: /**
         * Current search value
         * @return {?}
         */
        function () {
            return this._value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype.ngOnInit = /**
     * @return {?}
     */
    function () {
        var _this = this;
        // set custom panel class
        /** @type {?} */
        var panelClass = 'mat-select-search-panel';
        if (this.matSelect.panelClass) {
            if (Array.isArray(this.matSelect.panelClass)) {
                this.matSelect.panelClass.push(panelClass);
            }
            else if (typeof this.matSelect.panelClass === 'string') {
                this.matSelect.panelClass = [this.matSelect.panelClass, panelClass];
            }
            else if (typeof this.matSelect.panelClass === 'object') {
                this.matSelect.panelClass[panelClass] = true;
            }
        }
        else {
            this.matSelect.panelClass = panelClass;
        }
        // set custom mat-option class if the component was placed inside a mat-option
        if (this.matOption) {
            this.matOption.disabled = true;
            this.matOption._getHostElement().classList.add('contains-mat-select-search');
        }
        // when the select dropdown panel is opened or closed
        this.matSelect.openedChange
            // .pipe(takeUntil(this._onDestroy))
            .pipe(delay(1), takeUntil(this._onDestroy))
            .subscribe((/**
         * @param {?} opened
         * @return {?}
         */
        function (opened) {
            if (opened) {
                // focus the search field when opening
                _this.getWidth();
                _this._focus();
            }
            else {
                // clear it when closing
                _this._reset();
            }
        }));
        // set the first item active after the options changed
        this.matSelect.openedChange
            .pipe(take(1))
            .pipe(takeUntil(this._onDestroy))
            .subscribe((/**
         * @return {?}
         */
        function () {
            _this._options = _this.matSelect.options;
            _this._options.changes
                .pipe(takeUntil(_this._onDestroy))
                .subscribe((/**
             * @return {?}
             */
            function () {
                /** @type {?} */
                var keyManager = _this.matSelect._keyManager;
                if (keyManager && _this.matSelect.panelOpen) {
                    // avoid "expression has been changed" error
                    setTimeout((/**
                     * @return {?}
                     */
                    function () {
                        keyManager.setFirstItemActive();
                        _this.getWidth();
                        // set no entries found class on mat option
                        if (_this.matOption) {
                            if (_this._noEntriesFound()) {
                                _this.matOption._getHostElement().classList.add('mat-select-search-no-entries-found');
                            }
                            else {
                                _this.matOption._getHostElement().classList.remove('mat-select-search-no-entries-found');
                            }
                        }
                    }), 1);
                }
            }));
        }));
        // detect changes when the input changes
        this.change
            .pipe(takeUntil(this._onDestroy))
            .subscribe((/**
         * @return {?}
         */
        function () {
            _this.changeDetectorRef.detectChanges();
        }));
        this.initMultipleHandling();
    };
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype.ngOnDestroy = /**
     * @return {?}
     */
    function () {
        this._onDestroy.next();
        this._onDestroy.complete();
    };
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype.ngAfterViewInit = /**
     * @return {?}
     */
    function () {
        var _this = this;
        setTimeout((/**
         * @return {?}
         */
        function () {
            _this.setOverlayClass();
        }));
        this.matSelect.openedChange
            .pipe(take(1), takeUntil(this._onDestroy)).subscribe((/**
         * @return {?}
         */
        function () {
            _this.matSelect.options.changes
                .pipe(takeUntil(_this._onDestroy))
                .subscribe((/**
             * @return {?}
             */
            function () {
                _this.changeDetectorRef.markForCheck();
            }));
        }));
    };
    /**
     * @param {?} event
     * @return {?}
     */
    MatSelectSearchComponent.prototype._handleKeydown = /**
     * @param {?} event
     * @return {?}
     */
    function (event) {
        if (event.keyCode === 32) {
            // do not propagate spaces to MatSelect, as this would select the currently active option
            event.stopPropagation();
        }
    };
    /**
     * @param {?} value
     * @return {?}
     */
    MatSelectSearchComponent.prototype.writeValue = /**
     * @param {?} value
     * @return {?}
     */
    function (value) {
        /** @type {?} */
        var valueChanged = value !== this._value;
        if (valueChanged) {
            this._value = value;
            this.change.emit({ type: 'Text', val: value });
        }
    };
    /**
     * @param {?} value
     * @return {?}
     */
    MatSelectSearchComponent.prototype.onInputChange = /**
     * @param {?} value
     * @return {?}
     */
    function (value) {
        /** @type {?} */
        var valueChanged = value !== this._value;
        if (valueChanged) {
            this._value = value;
            this.onChange({ type: 'Text', val: value });
            this.change.emit({ type: 'Text', val: value });
        }
    };
    /**
     * @param {?} value
     * @return {?}
     */
    MatSelectSearchComponent.prototype.onBlur = /**
     * @param {?} value
     * @return {?}
     */
    function (value) {
        this.writeValue(value);
        this.onTouched();
    };
    /**
     * @param {?} fn
     * @return {?}
     */
    MatSelectSearchComponent.prototype.registerOnChange = /**
     * @param {?} fn
     * @return {?}
     */
    function (fn) {
        this.onChange = fn;
    };
    /**
     * @param {?} fn
     * @return {?}
     */
    MatSelectSearchComponent.prototype.registerOnTouched = /**
     * @param {?} fn
     * @return {?}
     */
    function (fn) {
        this.onTouched = fn;
    };
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype._focus = /**
     * @return {?}
     */
    function () {
        if (!this.searchSelectInput || !this.matSelect.panel) {
            return;
        }
        // save and restore scrollTop of panel, since it will be reset by focus()
        // note: this is hacky
        /** @type {?} */
        var panel = this.matSelect.panel.nativeElement;
        /** @type {?} */
        var scrollTop = panel.scrollTop;
        // focus
        this.searchSelectInput.nativeElement.focus();
        panel.scrollTop = scrollTop;
    };
    /**
     * Resets the current search value
     * {boolean} focus whether to focus after resetting
     *
     */
    /**
     * Resets the current search value
     * {boolean} focus whether to focus after resetting
     *
     * @param {?=} focus
     * @return {?}
     */
    MatSelectSearchComponent.prototype._reset = /**
     * Resets the current search value
     * {boolean} focus whether to focus after resetting
     *
     * @param {?=} focus
     * @return {?}
     */
    function (focus) {
        if (!this.searchSelectInput) {
            return;
        }
        this.searchSelectInput.nativeElement.value = '';
        this.onInputChange('');
        if (focus) {
            this._focus();
        }
    };
    /**
     * Sets the overlay class  to correct offsetY
     * so that the selected option is at the position of the select box when opening
     */
    /**
     * Sets the overlay class  to correct offsetY
     * so that the selected option is at the position of the select box when opening
     * @private
     * @return {?}
     */
    MatSelectSearchComponent.prototype.setOverlayClass = /**
     * Sets the overlay class  to correct offsetY
     * so that the selected option is at the position of the select box when opening
     * @private
     * @return {?}
     */
    function () {
        var _this = this;
        if (this.overlayClassSet) {
            return;
        }
        /** @type {?} */
        var overlayClasses = ['cdk-overlay-pane-select-search'];
        if (!this.matOption) {
            // add offset to panel if component is not placed inside mat-option
            overlayClasses.push('cdk-overlay-pane-select-search-with-offset');
        }
        this.matSelect.overlayDir.attach
            .pipe(takeUntil(this._onDestroy))
            .subscribe((/**
         * @return {?}
         */
        function () {
            // note: this is hacky, but currently there is no better way to do this
            // note: this is hacky, but currently there is no better way to do this
            /** @type {?} */
            var element;
            /** @type {?} */
            var overlayElement;
            if (_this.searchSelectInput) {
                element = _this.searchSelectInput.nativeElement;
                while (element = element.parentElement) {
                    if (element.classList.contains('cdk-overlay-pane')) {
                        overlayElement = element;
                        break;
                    }
                }
            }
            if (overlayElement) {
                overlayClasses.forEach((/**
                 * @param {?} overlayClass
                 * @return {?}
                 */
                function (overlayClass) {
                    overlayElement.classList.add(overlayClass);
                }));
            }
        }));
        this.overlayClassSet = true;
    };
    /**
     * Initializes handling <mat-select [multiple]="true">
     * Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
     */
    /**
     * Initializes handling <mat-select [multiple]="true">
     * Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
     * @private
     * @return {?}
     */
    MatSelectSearchComponent.prototype.initMultipleHandling = /**
     * Initializes handling <mat-select [multiple]="true">
     * Note: to improve this code, mat-select should be extended to allow disabling resetting the selection while filtering.
     * @private
     * @return {?}
     */
    function () {
        var _this = this;
        // if <mat-select [multiple]="true">
        // store previously selected values and restore them when they are deselected
        // because the option is not available while we are currently filtering
        this.matSelect.valueChange
            .pipe(takeUntil(this._onDestroy))
            .subscribe((/**
         * @param {?} values
         * @return {?}
         */
        function (values) {
            if (_this.matSelect.multiple) {
                /** @type {?} */
                var restoreSelectedValues_1 = false;
                if (_this._value && _this._value.length
                    && _this.previousSelectedValues && Array.isArray(_this.previousSelectedValues)) {
                    if (!values || !Array.isArray(values)) {
                        values = [];
                    }
                    /** @type {?} */
                    var optionValues_1 = _this.matSelect.options.map((/**
                     * @param {?} option
                     * @return {?}
                     */
                    function (option) { return option.value; }));
                    _this.previousSelectedValues.forEach((/**
                     * @param {?} previousValue
                     * @return {?}
                     */
                    function (previousValue) {
                        if (values.indexOf(previousValue) === -1 && optionValues_1.indexOf(previousValue) === -1) {
                            // if a value that was selected before is deselected and not found in the options, it was deselected
                            // due to the filtering, so we restore it.
                            values.push(previousValue);
                            restoreSelectedValues_1 = true;
                        }
                    }));
                }
                if (restoreSelectedValues_1) {
                    _this.matSelect._onChange(values);
                }
                _this.previousSelectedValues = values;
            }
        }));
    };
    /**
     * @private
     * @return {?}
     */
    MatSelectSearchComponent.prototype.getWidth = /**
     * @private
     * @return {?}
     */
    function () {
        if (!this.innerSelectSearch || !this.innerSelectSearch.nativeElement) {
            return;
        }
        /** @type {?} */
        var element = this.innerSelectSearch.nativeElement;
        /** @type {?} */
        var panelElement;
        while (element = element.parentElement) {
            if (element.classList.contains('mat-select-panel')) {
                panelElement = element;
                break;
            }
        }
        if (panelElement) {
            this.innerSelectSearch.nativeElement.style.width = panelElement.clientWidth + 'px';
        }
        ////innerSelectall
        //if (!this.innerSelectall || !this.innerSelectall.nativeElement) {
        //    return;
        //}
        //let Selectallelement: HTMLElement = this.innerSelectall.nativeElement;
        //let SelectallpanelElement: HTMLElement;
        //while (Selectallelement = Selectallelement.parentElement) {
        //    if (Selectallelement.classList.contains('mat-select-panel')) {
        //        SelectallpanelElement = Selectallelement;
        //        break;
        //    }
        //}
        //if (SelectallpanelElement) {
        //    this.innerSelectall.nativeElement.style.width = SelectallpanelElement.clientWidth + 'px';
        //}
    };
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype._noEntriesFound = /**
     * @return {?}
     */
    function () {
        if (!this._options) {
            return;
        }
        if (this.matOption) {
            return this.noEntriesFoundLabel && this.value && this._options.length === 1;
        }
        else {
            return this.noEntriesFoundLabel && this.value && this._options.length === 0;
        }
    };
    /**
     * @param {?} change
     * @param {?} check
     * @return {?}
     */
    MatSelectSearchComponent.prototype.toggleSelection = /**
     * @param {?} change
     * @param {?} check
     * @return {?}
     */
    function (change, check) {
        if (change.checked) {
            //this.model.update.emit(this.values);
            this.onChange({ type: 'Check', val: change.checked });
            this.change.emit({ type: 'Check', val: change.checked });
        }
        else {
            this.onChange({ type: 'Check', val: change.checked });
            this.change.emit({ type: 'Check', val: change.checked });
        }
    };
    /**
     * @param {?} check
     * @return {?}
     */
    MatSelectSearchComponent.prototype.ischecked = /**
     * @param {?} check
     * @return {?}
     */
    function (check) {
        console.log(this.matSelect.options, this.matSelect.value);
        /** @type {?} */
        var selected = this.matSelect.selected;
        return this.matSelect.options && selected && selected.length > 0 && this.matSelect.options.length == selected.length;
    };
    /**
     * @return {?}
     */
    MatSelectSearchComponent.prototype.isIndeterminate = /**
     * @return {?}
     */
    function () {
        /** @type {?} */
        var selected = this.matSelect.selected;
        return this.matSelect.options && selected.length > 0 && selected.length < this.matSelect.options.length;
    };
    MatSelectSearchComponent.decorators = [
        { type: Component, args: [{
                    selector: 'mat-select-search',
                    template: "\r\n<input *ngIf=\"showSearch\" matInput class=\"mat-select-search-input mat-select-search-hidden\" />\r\n<input matInput class=\"mat-select-checkbox mat-select-search-hidden\"*ngIf=\"multiple\"  />\r\n\r\n<div #innerSelectSearch class=\"mat-select-search-inner\" *ngIf=\"showSearch\"\r\n     [ngClass]=\"{'mat-select-search-inner-multiple': matSelect.multiple}\">\r\n    <input matInput autocomplete=\"off\"\r\n           class=\"mat-select-search-input\"\r\n           #searchSelectInput\r\n           (keydown)=\"_handleKeydown($event)\"\r\n           (input)=\"onInputChange($event.target.value)\"\r\n           (blur)=\"onBlur($event.target.value)\"\r\n           placeholder=\"Search\" />\r\n    <button mat-button *ngIf=\"value\"\r\n            mat-icon-button\r\n            aria-label=\"Clear\"\r\n            (click)=\"_reset(true)\"\r\n            class=\"mat-select-search-clear\">\r\n        <mat-icon>close</mat-icon>\r\n    </button>\r\n</div>\r\n\r\n<div *ngIf=\"noEntriesFoundLabel && value && _options?.length === 0\"\r\n     class=\"mat-select-search-no-entries-found\">\r\n    {{noEntriesFoundLabel}}\r\n</div>\r\n",
                    providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef((/**
                             * @return {?}
                             */
                            function () { return MatSelectSearchComponent; })),
                            multi: true
                        }
                    ],
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    styles: [".mat-select-search-hidden{visibility:hidden}.mat-select-search-inner{position:absolute;top:0;width:calc(100% + 3px);border-bottom:1px solid #ccc;background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}.mat-select-search-inner.mat-select-search-inner-multiple{width:100%}::ng-deep .mat-select-search-panel{transform:none!important;overflow-x:hidden}.mat-select-search-input{padding:10px 30px 10px 10px;box-sizing:border-box}.mat-select-checkbox{padding:10px;box-sizing:border-box}.mat-select-search-no-entries-found{padding:10px}.mat-select-search-clear{position:absolute;right:4px;top:5px}:host.mat-select-search-inside-mat-option .mat-select-search-input{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-checkbox{padding-top:0;padding-bottom:0;height:3em;line-height:3em}:host.mat-select-search-inside-mat-option .mat-select-search-clear{top:3px}::ng-deep .cdk-overlay-pane-select-search.cdk-overlay-pane-select-search-with-offset{margin-top:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search{position:static;padding:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-icon{margin-right:0}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search .mat-option-pseudo-checkbox{display:none}::ng-deep .mat-option[aria-disabled=true].contains-mat-select-search.mat-select-search-no-entries-found{height:6em}.mat-select-all-inner{position:absolute;top:52px;width:calc(100% + 3px);background:#fff;z-index:100;font-size:inherit;box-shadow:none;border-radius:0;-webkit-transform:translate3d(0,0,0)}"]
                }] }
    ];
    /** @nocollapse */
    MatSelectSearchComponent.ctorParameters = function () { return [
        { type: MatSelect, decorators: [{ type: Inject, args: [MatSelect,] }] },
        { type: ChangeDetectorRef },
        { type: MatOption, decorators: [{ type: Optional }, { type: Inject, args: [MatOption,] }] }
    ]; };
    MatSelectSearchComponent.propDecorators = {
        placeholderLabel: [{ type: Input }],
        multiple: [{ type: Input, args: ['multiple',] }],
        showSearch: [{ type: Input, args: ['showSearch',] }],
        noEntriesFoundLabel: [{ type: Input }],
        searchSelectInput: [{ type: ViewChild, args: ['searchSelectInput', { read: ElementRef },] }],
        innerSelectSearch: [{ type: ViewChild, args: ['innerSelectSearch', { read: ElementRef },] }],
        isInsideMatOption: [{ type: HostBinding, args: ['class.mat-select-search-inside-mat-option',] }]
    };
    return MatSelectSearchComponent;
}());
export { MatSelectSearchComponent };
if (false) {
    /**
     * Label of the search placeholder
     * @type {?}
     */
    MatSelectSearchComponent.prototype.placeholderLabel;
    /** @type {?} */
    MatSelectSearchComponent.prototype.multiple;
    /** @type {?} */
    MatSelectSearchComponent.prototype.showSearch;
    /**
     * Label to be shown when no entries are found. Set to null if no message should be shown.
     * @type {?}
     */
    MatSelectSearchComponent.prototype.noEntriesFoundLabel;
    /**
     * Reference to the search input field
     * @type {?}
     */
    MatSelectSearchComponent.prototype.searchSelectInput;
    /** @type {?} */
    MatSelectSearchComponent.prototype.innerSelectSearch;
    /**
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype._value;
    /** @type {?} */
    MatSelectSearchComponent.prototype.onChange;
    /** @type {?} */
    MatSelectSearchComponent.prototype.onTouched;
    /**
     * Reference to the MatSelect options
     * @type {?}
     */
    MatSelectSearchComponent.prototype._options;
    /**
     * Previously selected values when using <mat-select [multiple]="true">
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype.previousSelectedValues;
    /**
     * Whether the backdrop class has been set
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype.overlayClassSet;
    /**
     * Event that emits when the current value changes
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype.change;
    /**
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype.AllClicked;
    /**
     * Subject that emits when the component has been destroyed.
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype._onDestroy;
    /** @type {?} */
    MatSelectSearchComponent.prototype.matSelect;
    /**
     * @type {?}
     * @private
     */
    MatSelectSearchComponent.prototype.changeDetectorRef;
    /** @type {?} */
    MatSelectSearchComponent.prototype.matOption;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW1hdC1kcm9wZG93bi8iLCJzb3VyY2VzIjpbImxpYi9tYXQtc2VsZWN0LXNlYXJjaC9tYXQtc2VsZWN0LXNlYXJjaC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUgsdUJBQXVCLEVBQUUsaUJBQWlCLEVBQzFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUM5RCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFFBQVEsRUFDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFHLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBR3RELE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRW5EO0lBd0RJLGtDQUFzQyxTQUFvQixFQUM5QyxpQkFBb0MsRUFBd0MsU0FBMkI7UUFBM0IsMEJBQUEsRUFBQSxnQkFBMkI7UUFEN0UsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUM5QyxzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQXdDLGNBQVMsR0FBVCxTQUFTLENBQWtCOzs7O1FBekMxRyxxQkFBZ0IsR0FBRyxRQUFRLENBQUM7UUFDbEIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUN4QixlQUFVLEdBQVksSUFBSSxDQUFDOzs7O1FBRXZDLHdCQUFtQixHQUFHLFNBQVMsQ0FBQztRQWdCekMsYUFBUTs7OztRQUFhLFVBQUMsQ0FBTSxJQUFPLENBQUMsRUFBQztRQUNyQyxjQUFTOzs7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QUFBLEFBM1hELElBMlhDO1NBOVdZLHdCQUF3Qjs7Ozs7O0lBR2pDLG9EQUFxQzs7SUFDckMsNENBQTZDOztJQUM3Qyw4Q0FBZ0Q7Ozs7O0lBRWhELHVEQUF5Qzs7Ozs7SUFHekMscURBQW9GOztJQUNwRixxREFBbUY7Ozs7O0lBVW5GLDBDQUF1Qjs7SUFFdkIsNENBQXFDOztJQUNyQyw2Q0FBc0M7Ozs7O0lBR3RDLDRDQUFzQzs7Ozs7O0lBR3RDLDBEQUFzQzs7Ozs7O0lBR3RDLG1EQUFnQzs7Ozs7O0lBR2hDLDBDQUF5Qzs7Ozs7SUFFekMsOENBQWlEOzs7Ozs7SUFFakQsOENBQXlDOztJQUc3Qiw2Q0FBOEM7Ozs7O0lBQ3RELHFEQUE0Qzs7SUFBRSw2Q0FBaUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQWZ0ZXJWaWV3SW5pdCxcclxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBmb3J3YXJkUmVmLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgUXVlcnlMaXN0LFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBPcHRpb25hbFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7ICBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xyXG5pbXBvcnQgeyAgIE1hdENoZWNrYm94Q2hhbmdlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xyXG5cclxuaW1wb3J0IHsgZGVsYXksIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBNYXRPcHRpb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdtYXQtc2VsZWN0LXNlYXJjaCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vbWF0LXNlbGVjdC1zZWFyY2guY29tcG9uZW50LnNjc3MnXSxcclxuICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdFNlbGVjdFNlYXJjaENvbXBvbmVudCksXHJcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgXSxcclxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRTZWxlY3RTZWFyY2hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xyXG5cclxuICAgIC8qKiBMYWJlbCBvZiB0aGUgc2VhcmNoIHBsYWNlaG9sZGVyICovXHJcbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlckxhYmVsID0gJ1NlYXJjaCc7XHJcbiAgICBASW5wdXQoJ211bHRpcGxlJykgbXVsdGlwbGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICAgIEBJbnB1dCgnc2hvd1NlYXJjaCcpIHNob3dTZWFyY2g6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLyoqIExhYmVsIHRvIGJlIHNob3duIHdoZW4gbm8gZW50cmllcyBhcmUgZm91bmQuIFNldCB0byBudWxsIGlmIG5vIG1lc3NhZ2Ugc2hvdWxkIGJlIHNob3duLiAqL1xyXG4gICAgQElucHV0KCkgbm9FbnRyaWVzRm91bmRMYWJlbCA9ICdObyBEYXRhJztcclxuXHJcbiAgICAvKiogUmVmZXJlbmNlIHRvIHRoZSBzZWFyY2ggaW5wdXQgZmllbGQgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ3NlYXJjaFNlbGVjdElucHV0JywgeyByZWFkOiBFbGVtZW50UmVmIH0pIHNlYXJjaFNlbGVjdElucHV0OiBFbGVtZW50UmVmO1xyXG4gICAgQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RTZWFyY2gnLCB7IHJlYWQ6IEVsZW1lbnRSZWZ9KSBpbm5lclNlbGVjdFNlYXJjaDogRWxlbWVudFJlZjtcclxuICAgIC8vQFZpZXdDaGlsZCgnaW5uZXJTZWxlY3RhbGwnLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSkgaW5uZXJTZWxlY3RhbGw6IEVsZW1lbnRSZWY7XHJcbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1hdC1zZWxlY3Qtc2VhcmNoLWluc2lkZS1tYXQtb3B0aW9uJylcclxuICAgIGdldCBpc0luc2lkZU1hdE9wdGlvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gISF0aGlzLm1hdE9wdGlvbjtcclxuICAgIH1cclxuICAgIC8qKiBDdXJyZW50IHNlYXJjaCB2YWx1ZSAqL1xyXG4gICAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gICAgfVxyXG4gICAgcHJpdmF0ZSBfdmFsdWU6IHN0cmluZztcclxuXHJcbiAgICBvbkNoYW5nZTogRnVuY3Rpb24gPSAoXzogYW55KSA9PiB7IH07XHJcbiAgICBvblRvdWNoZWQ6IEZ1bmN0aW9uID0gKF86IGFueSkgPT4geyB9O1xyXG5cclxuICAgIC8qKiBSZWZlcmVuY2UgdG8gdGhlIE1hdFNlbGVjdCBvcHRpb25zICovXHJcbiAgICBwdWJsaWMgX29wdGlvbnM6IFF1ZXJ5TGlzdDxNYXRPcHRpb24+O1xyXG5cclxuICAgIC8qKiBQcmV2aW91c2x5IHNlbGVjdGVkIHZhbHVlcyB3aGVuIHVzaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+Ki9cclxuICAgIHByaXZhdGUgcHJldmlvdXNTZWxlY3RlZFZhbHVlczogYW55W107XHJcblxyXG4gICAgLyoqIFdoZXRoZXIgdGhlIGJhY2tkcm9wIGNsYXNzIGhhcyBiZWVuIHNldCAqL1xyXG4gICAgcHJpdmF0ZSBvdmVybGF5Q2xhc3NTZXQgPSBmYWxzZTtcclxuXHJcbiAgICAvKiogRXZlbnQgdGhhdCBlbWl0cyB3aGVuIHRoZSBjdXJyZW50IHZhbHVlIGNoYW5nZXMgKi9cclxuICAgIHByaXZhdGUgY2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBBbGxDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG4gICAgLyoqIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gZGVzdHJveWVkLiAqL1xyXG4gICAgcHJpdmF0ZSBfb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcblxyXG4gICAgY29uc3RydWN0b3IoQEluamVjdChNYXRTZWxlY3QpIHB1YmxpYyBtYXRTZWxlY3Q6IE1hdFNlbGVjdCxcclxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZiwgQE9wdGlvbmFsKCkgQEluamVjdChNYXRPcHRpb24pIHB1YmxpYyBtYXRPcHRpb246IE1hdE9wdGlvbiA9IG51bGwpIHtcclxuXHJcblxyXG4gICAgfVxyXG5cclxuICAgIG5nT25Jbml0KCkge1xyXG4gICAgICAgIC8vIHNldCBjdXN0b20gcGFuZWwgY2xhc3NcclxuICAgICAgICBjb25zdCBwYW5lbENsYXNzID0gJ21hdC1zZWxlY3Qtc2VhcmNoLXBhbmVsJztcclxuICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcykge1xyXG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcy5wdXNoKHBhbmVsQ2xhc3MpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IFt0aGlzLm1hdFNlbGVjdC5wYW5lbENsYXNzLCBwYW5lbENsYXNzXTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubWF0U2VsZWN0LnBhbmVsQ2xhc3NbcGFuZWxDbGFzc10gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5tYXRTZWxlY3QucGFuZWxDbGFzcyA9IHBhbmVsQ2xhc3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNldCBjdXN0b20gbWF0LW9wdGlvbiBjbGFzcyBpZiB0aGUgY29tcG9uZW50IHdhcyBwbGFjZWQgaW5zaWRlIGEgbWF0LW9wdGlvblxyXG4gICAgICAgIGlmICh0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLm1hdE9wdGlvbi5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ2NvbnRhaW5zLW1hdC1zZWxlY3Qtc2VhcmNoJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHdoZW4gdGhlIHNlbGVjdCBkcm9wZG93biBwYW5lbCBpcyBvcGVuZWQgb3IgY2xvc2VkXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3BlbmVkQ2hhbmdlXHJcbiAgICAgICAgICAgIC8vIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIGRlbGF5KDEpLFxyXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSlcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChvcGVuZWQpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChvcGVuZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBmb2N1cyB0aGUgc2VhcmNoIGZpZWxkIHdoZW4gb3BlbmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0V2lkdGgoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFyIGl0IHdoZW4gY2xvc2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBzZXQgdGhlIGZpcnN0IGl0ZW0gYWN0aXZlIGFmdGVyIHRoZSBvcHRpb25zIGNoYW5nZWRcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcGVuZWRDaGFuZ2VcclxuICAgICAgICAgICAgLnBpcGUodGFrZSgxKSlcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuY2hhbmdlc1xyXG4gICAgICAgICAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBrZXlNYW5hZ2VyID0gdGhpcy5tYXRTZWxlY3QuX2tleU1hbmFnZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlNYW5hZ2VyICYmIHRoaXMubWF0U2VsZWN0LnBhbmVsT3Blbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgXCJleHByZXNzaW9uIGhhcyBiZWVuIGNoYW5nZWRcIiBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5TWFuYWdlci5zZXRGaXJzdEl0ZW1BY3RpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldFdpZHRoKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNldCBubyBlbnRyaWVzIGZvdW5kIGNsYXNzIG9uIG1hdCBvcHRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25vRW50cmllc0ZvdW5kKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5hZGQoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0T3B0aW9uLl9nZXRIb3N0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoJ21hdC1zZWxlY3Qtc2VhcmNoLW5vLWVudHJpZXMtZm91bmQnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gZGV0ZWN0IGNoYW5nZXMgd2hlbiB0aGUgaW5wdXQgY2hhbmdlc1xyXG4gICAgICAgIHRoaXMuY2hhbmdlXHJcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5pbml0TXVsdGlwbGVIYW5kbGluZygpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHRoaXMuX29uRGVzdHJveS5uZXh0KCk7XHJcbiAgICAgICAgdGhpcy5fb25EZXN0cm95LmNvbXBsZXRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnNldE92ZXJsYXlDbGFzcygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMubWF0U2VsZWN0Lm9wZW5lZENoYW5nZVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KVxyXG4gICAgICAgICAgICApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmNoYW5nZXNcclxuICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIFxyXG4gICAgX2hhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gMzIpIHtcclxuICAgICAgICAgICAgLy8gZG8gbm90IHByb3BhZ2F0ZSBzcGFjZXMgdG8gTWF0U2VsZWN0LCBhcyB0aGlzIHdvdWxkIHNlbGVjdCB0aGUgY3VycmVudGx5IGFjdGl2ZSBvcHRpb25cclxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcblxyXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgdmFsdWVDaGFuZ2VkID0gdmFsdWUgIT09IHRoaXMuX3ZhbHVlO1xyXG4gICAgICAgIGlmICh2YWx1ZUNoYW5nZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5jaGFuZ2UuZW1pdCh7IHR5cGU6ICdUZXh0JywgdmFsOiB2YWx1ZSB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgb25JbnB1dENoYW5nZSh2YWx1ZSkge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlQ2hhbmdlZCA9IHZhbHVlICE9PSB0aGlzLl92YWx1ZTtcclxuICAgICAgICBpZiAodmFsdWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnVGV4dCcsIHZhbDogdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG9uQmx1cih2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKHZhbHVlKTtcclxuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbikge1xyXG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XHJcbiAgICB9XHJcblxyXG4gICBcclxuICAgIHB1YmxpYyBfZm9jdXMoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNlYXJjaFNlbGVjdElucHV0IHx8ICF0aGlzLm1hdFNlbGVjdC5wYW5lbCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHNhdmUgYW5kIHJlc3RvcmUgc2Nyb2xsVG9wIG9mIHBhbmVsLCBzaW5jZSBpdCB3aWxsIGJlIHJlc2V0IGJ5IGZvY3VzKClcclxuICAgICAgICAvLyBub3RlOiB0aGlzIGlzIGhhY2t5XHJcbiAgICAgICAgY29uc3QgcGFuZWwgPSB0aGlzLm1hdFNlbGVjdC5wYW5lbC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IHBhbmVsLnNjcm9sbFRvcDtcclxuXHJcbiAgICAgICAgLy8gZm9jdXNcclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgcGFuZWwuc2Nyb2xsVG9wID0gc2Nyb2xsVG9wO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVzZXRzIHRoZSBjdXJyZW50IHNlYXJjaCB2YWx1ZVxyXG4gICAgICoge2Jvb2xlYW59IGZvY3VzIHdoZXRoZXIgdG8gZm9jdXMgYWZ0ZXIgcmVzZXR0aW5nXHJcbiAgICAgKiBcclxuICAgICAqL1xyXG4gICAgcHVibGljIF9yZXNldChmb2N1cz86IGJvb2xlYW4pIHtcclxuICAgICAgICBpZiAoIXRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlYXJjaFNlbGVjdElucHV0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcclxuICAgICAgICB0aGlzLm9uSW5wdXRDaGFuZ2UoJycpO1xyXG4gICAgICAgIGlmIChmb2N1cykge1xyXG4gICAgICAgICAgICB0aGlzLl9mb2N1cygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIG92ZXJsYXkgY2xhc3MgIHRvIGNvcnJlY3Qgb2Zmc2V0WVxyXG4gICAgICogc28gdGhhdCB0aGUgc2VsZWN0ZWQgb3B0aW9uIGlzIGF0IHRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0IGJveCB3aGVuIG9wZW5pbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBzZXRPdmVybGF5Q2xhc3MoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3ZlcmxheUNsYXNzU2V0KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgb3ZlcmxheUNsYXNzZXM6IHN0cmluZ1tdID0gWydjZGstb3ZlcmxheS1wYW5lLXNlbGVjdC1zZWFyY2gnXTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1hdE9wdGlvbikge1xyXG4gICAgICAgICAgICAvLyBhZGQgb2Zmc2V0IHRvIHBhbmVsIGlmIGNvbXBvbmVudCBpcyBub3QgcGxhY2VkIGluc2lkZSBtYXQtb3B0aW9uXHJcbiAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLnB1c2goJ2Nkay1vdmVybGF5LXBhbmUtc2VsZWN0LXNlYXJjaC13aXRoLW9mZnNldCcpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5tYXRTZWxlY3Qub3ZlcmxheURpci5hdHRhY2hcclxuICAgICAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gbm90ZTogdGhpcyBpcyBoYWNreSwgYnV0IGN1cnJlbnRseSB0aGVyZSBpcyBubyBiZXR0ZXIgd2F5IHRvIGRvIHRoaXNcclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgZWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgb3ZlcmxheUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VhcmNoU2VsZWN0SW5wdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gdGhpcy5zZWFyY2hTZWxlY3RJbnB1dC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnY2RrLW92ZXJsYXktcGFuZScpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGF5RWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChvdmVybGF5RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlDbGFzc2VzLmZvckVhY2gob3ZlcmxheUNsYXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmxheUVsZW1lbnQuY2xhc3NMaXN0LmFkZChvdmVybGF5Q2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5vdmVybGF5Q2xhc3NTZXQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIGhhbmRsaW5nIDxtYXQtc2VsZWN0IFttdWx0aXBsZV09XCJ0cnVlXCI+XHJcbiAgICAgKiBOb3RlOiB0byBpbXByb3ZlIHRoaXMgY29kZSwgbWF0LXNlbGVjdCBzaG91bGQgYmUgZXh0ZW5kZWQgdG8gYWxsb3cgZGlzYWJsaW5nIHJlc2V0dGluZyB0aGUgc2VsZWN0aW9uIHdoaWxlIGZpbHRlcmluZy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbml0TXVsdGlwbGVIYW5kbGluZygpIHtcclxuICAgICAgICAvLyBpZiA8bWF0LXNlbGVjdCBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxyXG4gICAgICAgIC8vIHN0b3JlIHByZXZpb3VzbHkgc2VsZWN0ZWQgdmFsdWVzIGFuZCByZXN0b3JlIHRoZW0gd2hlbiB0aGV5IGFyZSBkZXNlbGVjdGVkXHJcbiAgICAgICAgLy8gYmVjYXVzZSB0aGUgb3B0aW9uIGlzIG5vdCBhdmFpbGFibGUgd2hpbGUgd2UgYXJlIGN1cnJlbnRseSBmaWx0ZXJpbmdcclxuICAgICAgICB0aGlzLm1hdFNlbGVjdC52YWx1ZUNoYW5nZVxyXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgodmFsdWVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXRTZWxlY3QubXVsdGlwbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdG9yZVNlbGVjdGVkVmFsdWVzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlICYmIHRoaXMuX3ZhbHVlLmxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMgJiYgQXJyYXkuaXNBcnJheSh0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdmFsdWVzIHx8ICFBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvblZhbHVlcyA9IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubWFwKG9wdGlvbiA9PiBvcHRpb24udmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZpb3VzU2VsZWN0ZWRWYWx1ZXMuZm9yRWFjaChwcmV2aW91c1ZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXMuaW5kZXhPZihwcmV2aW91c1ZhbHVlKSA9PT0gLTEgJiYgb3B0aW9uVmFsdWVzLmluZGV4T2YocHJldmlvdXNWYWx1ZSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYSB2YWx1ZSB0aGF0IHdhcyBzZWxlY3RlZCBiZWZvcmUgaXMgZGVzZWxlY3RlZCBhbmQgbm90IGZvdW5kIGluIHRoZSBvcHRpb25zLCBpdCB3YXMgZGVzZWxlY3RlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1ZSB0byB0aGUgZmlsdGVyaW5nLCBzbyB3ZSByZXN0b3JlIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHByZXZpb3VzVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RvcmVTZWxlY3RlZFZhbHVlcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3RvcmVTZWxlY3RlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdFNlbGVjdC5fb25DaGFuZ2UodmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmlvdXNTZWxlY3RlZFZhbHVlcyA9IHZhbHVlcztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBnZXRXaWR0aCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2ggfHwgIXRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxldCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuaW5uZXJTZWxlY3RTZWFyY2gubmF0aXZlRWxlbWVudDtcclxuICAgICAgICBsZXQgcGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50RWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ21hdC1zZWxlY3QtcGFuZWwnKSkge1xyXG4gICAgICAgICAgICAgICAgcGFuZWxFbGVtZW50ID0gZWxlbWVudDtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwYW5lbEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5pbm5lclNlbGVjdFNlYXJjaC5uYXRpdmVFbGVtZW50LnN0eWxlLndpZHRoID0gcGFuZWxFbGVtZW50LmNsaWVudFdpZHRoICsgJ3B4JztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vLy9pbm5lclNlbGVjdGFsbFxyXG4gICAgICAgIC8vaWYgKCF0aGlzLmlubmVyU2VsZWN0YWxsIHx8ICF0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAvLyAgICByZXR1cm47XHJcbiAgICAgICAgLy99XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxsZWxlbWVudDogSFRNTEVsZW1lbnQgPSB0aGlzLmlubmVyU2VsZWN0YWxsLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgLy9sZXQgU2VsZWN0YWxscGFuZWxFbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICAgICAvL3doaWxlIChTZWxlY3RhbGxlbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudC5wYXJlbnRFbGVtZW50KSB7XHJcbiAgICAgICAgLy8gICAgaWYgKFNlbGVjdGFsbGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdtYXQtc2VsZWN0LXBhbmVsJykpIHtcclxuICAgICAgICAvLyAgICAgICAgU2VsZWN0YWxscGFuZWxFbGVtZW50ID0gU2VsZWN0YWxsZWxlbWVudDtcclxuICAgICAgICAvLyAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgLy8gICAgfVxyXG4gICAgICAgIC8vfVxyXG4gICAgICAgIC8vaWYgKFNlbGVjdGFsbHBhbmVsRWxlbWVudCkge1xyXG4gICAgICAgIC8vICAgIHRoaXMuaW5uZXJTZWxlY3RhbGwubmF0aXZlRWxlbWVudC5zdHlsZS53aWR0aCA9IFNlbGVjdGFsbHBhbmVsRWxlbWVudC5jbGllbnRXaWR0aCArICdweCc7XHJcbiAgICAgICAgLy99XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIF9ub0VudHJpZXNGb3VuZCgpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoIXRoaXMuX29wdGlvbnMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5tYXRPcHRpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9FbnRyaWVzRm91bmRMYWJlbCAmJiB0aGlzLnZhbHVlICYmIHRoaXMuX29wdGlvbnMubGVuZ3RoID09PSAxO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vRW50cmllc0ZvdW5kTGFiZWwgJiYgdGhpcy52YWx1ZSAmJiB0aGlzLl9vcHRpb25zLmxlbmd0aCA9PT0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0b2dnbGVTZWxlY3Rpb24oY2hhbmdlOiBNYXRDaGVja2JveENoYW5nZSwgY2hlY2spOiB2b2lkIHtcclxuICAgICAgICBpZiAoY2hhbmdlLmNoZWNrZWQpIHtcclxuICAgICAgICAgICAgLy90aGlzLm1vZGVsLnVwZGF0ZS5lbWl0KHRoaXMudmFsdWVzKTtcclxuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZSh7IHR5cGU6ICdDaGVjaycsIHZhbDogY2hhbmdlLmNoZWNrZWQgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlLmVtaXQoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoeyB0eXBlOiAnQ2hlY2snLCB2YWw6IGNoYW5nZS5jaGVja2VkIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KHsgdHlwZTogJ0NoZWNrJywgdmFsOiBjaGFuZ2UuY2hlY2tlZCB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaXNjaGVja2VkKGNoZWNrKTogYm9vbGVhbiB7XHJcbiAgICAgICAgY29uc29sZS5sb2codGhpcy5tYXRTZWxlY3Qub3B0aW9ucywgdGhpcy5tYXRTZWxlY3QudmFsdWUpO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZDogYW55ID0gdGhpcy5tYXRTZWxlY3Quc2VsZWN0ZWQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMgJiYgc2VsZWN0ZWQgJiYgc2VsZWN0ZWQubGVuZ3RoID4gMCAmJiB0aGlzLm1hdFNlbGVjdC5vcHRpb25zLmxlbmd0aCA9PSBzZWxlY3RlZC5sZW5ndGg7XHJcbiAgICB9XHJcbiAgICBpc0luZGV0ZXJtaW5hdGUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgbGV0IHNlbGVjdGVkOiBhbnkgPSB0aGlzLm1hdFNlbGVjdC5zZWxlY3RlZDtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXRTZWxlY3Qub3B0aW9ucyAmJiBzZWxlY3RlZC5sZW5ndGggPiAwICYmIHNlbGVjdGVkLmxlbmd0aCA8IHRoaXMubWF0U2VsZWN0Lm9wdGlvbnMubGVuZ3RoO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==