UNPKG

@uiowa/uiowa-account

Version:

Angular library to manage MFK and UNI Account output

585 lines 64.7 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/forms'), require('@uiowa/digit-only'), require('@angular/common'), require('@ng-bootstrap/ng-bootstrap')) :
    typeof define === 'function' && define.amd ? define('@uiowa/uiowa-account', ['exports', '@angular/core', '@angular/forms', '@uiowa/digit-only', '@angular/common', '@ng-bootstrap/ng-bootstrap'], factory) :
    (factory((global.uiowa = global.uiowa || {}, global.uiowa['uiowa-account'] = {}),global.ng.core,global.ng.forms,global['@uiowa/digit-only'],global.ng.common,global['@ng-bootstrap/ng-bootstrap']));
}(this, (function (exports,core,forms,digitOnly,common,ngBootstrap) { 'use strict';

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var AccountStringComponent = /** @class */ (function () {
        function AccountStringComponent() {
            this.options = [];
            this.output = [];
        }
        /**
         * @return {?}
         */
        AccountStringComponent.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                this.account.elements.forEach(function (element, index) {
                    _this.output.push({
                        value: _this.getElementOutput(element.webApiProperty, index),
                        display: element.display,
                        showDelimeter: _this.account.showDelimeter(index)
                    });
                });
            };
        /**
         * @param {?} property
         * @return {?}
         */
        AccountStringComponent.prototype.getOverrideValue = /**
         * @param {?} property
         * @return {?}
         */
            function (property) {
                /** @type {?} */
                var element = this.options.find(function (x) { return x.name === property; });
                if (element) {
                    return element.display;
                }
            };
        /**
         * @param {?} property
         * @param {?} index
         * @return {?}
         */
        AccountStringComponent.prototype.getElementOutput = /**
         * @param {?} property
         * @param {?} index
         * @return {?}
         */
            function (property, index) {
                if (this.options.length > 0) {
                    /** @type {?} */
                    var overrideValue = this.getOverrideValue(property);
                    if (overrideValue) {
                        return overrideValue;
                    }
                }
                return this.account.getElementString(index);
            };
        AccountStringComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'uiowa-account-string',
                        template: "\n  <span *ngFor=\"let element of output\" placement=\"bottom\" ngbTooltip=\"{{element.display}}\">{{element.value}}<span\n    *ngIf=\"element.showDelimeter\">{{account.delimiter}}</span></span>\n  "
                    }] }
        ];
        /** @nocollapse */
        AccountStringComponent.ctorParameters = function () { return []; };
        AccountStringComponent.propDecorators = {
            account: [{ type: core.Input }],
            options: [{ type: core.Input }]
        };
        return AccountStringComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var Account = /** @class */ (function () {
        function Account(value, delimiter, elements, defaultString) {
            if (value === void 0) {
                value = null;
            }
            if (delimiter === void 0) {
                delimiter = '-';
            }
            if (elements === void 0) {
                elements = [];
            }
            if (defaultString === void 0) {
                defaultString = 'X';
            }
            this.elements = elements;
            this.value = value;
            this.delimiter = delimiter;
            this.valueAry = this.value.split(this.delimiter);
            this.defaultString = defaultString;
        }
        /**
         * @param {?} index
         * @return {?}
         */
        Account.prototype.getElementString = /**
         * @param {?} index
         * @return {?}
         */
            function (index) {
                /** @type {?} */
                var value = this.valueAry[index];
                if (!value) {
                    /** @type {?} */
                    var element = this.elements[index];
                    if (element.isRequired) {
                        for (var i = 1; i <= element.size; i++) {
                            value = value + this.defaultString;
                        }
                    }
                }
                return value;
            };
        /**
         * @param {?} index
         * @param {?=} leaveOptionalEnd
         * @return {?}
         */
        Account.prototype.showDelimeter = /**
         * @param {?} index
         * @param {?=} leaveOptionalEnd
         * @return {?}
         */
            function (index, leaveOptionalEnd) {
                if (leaveOptionalEnd === void 0) {
                    leaveOptionalEnd = false;
                }
                if (this.lastElementIsOptionalAndEmpty(index) && !leaveOptionalEnd) {
                    return false;
                }
                if (!this.indexIsTheLastElement(index)) {
                    return true;
                }
                return false;
            };
        /**
         * @param {?} index
         * @return {?}
         */
        Account.prototype.indexIsTheLastElement = /**
         * @param {?} index
         * @return {?}
         */
            function (index) {
                return index === this.elements.length - 1;
            };
        /**
         * @param {?} index
         * @return {?}
         */
        Account.prototype.lastElementIsOptionalAndEmpty = /**
         * @param {?} index
         * @return {?}
         */
            function (index) {
                if (index + 2 === this.elements.length) {
                    if (!this.elements[index + 1].isRequired && !this.valueAry[index + 1]) {
                        return true;
                    }
                }
                return false;
            };
        return Account;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var Element = /** @class */ (function () {
        function Element(display, size, webapiproperty, isRequired) {
            if (size === void 0) {
                size = 0;
            }
            if (webapiproperty === void 0) {
                webapiproperty = null;
            }
            this.display = display;
            this.size = size;
            this.webApiProperty = webapiproperty;
            this.isRequired = isRequired;
        }
        return Element;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var FieldOption = /** @class */ (function () {
        function FieldOption(name, display, defaultValue) {
            if (defaultValue === void 0) {
                defaultValue = '';
            }
            this.name = name;
            this.display = display;
            this.defaultValue = defaultValue;
        }
        return FieldOption;
    }());

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0

    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.

    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (b.hasOwnProperty(p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    /**
     * @template T
     */
    var /**
     * @template T
     */ ElementInputBase = /** @class */ (function () {
        function ElementInputBase(options) {
            if (options === void 0) {
                options = {};
            }
            this.value = options.value;
            this.key = options.key || '';
            this.label = options.label || '';
            this.required = !!options.required;
            this.order = options.order === undefined ? 1 : options.order;
            this.controlType = options.controlType || '';
            this.id = options.id || '';
            this.size = options.size || 10;
            this.display = options.display || '';
        }
        return ElementInputBase;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var ElementInputText = /** @class */ (function (_super) {
        __extends(ElementInputText, _super);
        function ElementInputText(options) {
            if (options === void 0) {
                options = {};
            }
            var _this = _super.call(this, options) || this;
            _this.controlType = 'textbox';
            _this.type = 'string';
            _this.type = options['type'];
            return _this;
        }
        return ElementInputText;
    }(ElementInputBase));

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var ElementInputHidden = /** @class */ (function (_super) {
        __extends(ElementInputHidden, _super);
        function ElementInputHidden(options) {
            if (options === void 0) {
                options = {};
            }
            var _this = _super.call(this, options) || this;
            _this.controlType = 'hidden';
            _this.type = 'string';
            _this.type = options['type'];
            return _this;
        }
        return ElementInputHidden;
    }(ElementInputBase));

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

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var InputControlService = /** @class */ (function () {
        function InputControlService() {
        }
        /**
         * @param {?} questions
         * @return {?}
         */
        InputControlService.prototype.toFormGroup = /**
         * @param {?} questions
         * @return {?}
         */
            function (questions) {
                /** @type {?} */
                var group = {};
                questions.forEach(function (question) {
                    group[question.key] = question.required
                        ? new forms.FormControl(question.value || '', forms.Validators.required)
                        : new forms.FormControl(question.value || '');
                });
                return new forms.FormGroup(group);
            };
        InputControlService.decorators = [
            { type: core.Injectable }
        ];
        /** @nocollapse */
        InputControlService.ctorParameters = function () { return []; };
        return InputControlService;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var AccountInputComponent = /** @class */ (function () {
        function AccountInputComponent(inputControlService) {
            this.inputControlService = inputControlService;
            this.options = [];
            this.index = 0;
            this.accountChange = new core.EventEmitter();
            this.questions = [];
        }
        /**
         * @return {?}
         */
        AccountInputComponent.prototype.ngOnInit = /**
         * @return {?}
         */
            function () {
                var _this = this;
                this.account.elements.forEach(function (element, loopIndex) {
                    if (_this.options.find(function (x) { return x.name === element.webApiProperty; })) {
                        /** @type {?} */
                        var hiddenOption = _this.options.find(function (x) { return x.name === element.webApiProperty; });
                        _this.questions.push(new ElementInputHidden({
                            value: hiddenOption.defaultValue,
                            label: element.display,
                            key: element.webApiProperty + '_' + _this.index,
                            size: element.size,
                            display: hiddenOption.display,
                            id: element.webApiProperty + '_' + _this.index
                        }));
                    }
                    else {
                        _this.questions.push(new ElementInputText({
                            value: _this.account.getElementString(loopIndex),
                            label: element.display,
                            key: element.webApiProperty + '_' + _this.index,
                            size: element.size,
                            name: element.webApiProperty,
                            id: element.webApiProperty + '_' + _this.index
                        }));
                    }
                });
                this.form = this.inputControlService.toFormGroup(this.questions);
                this.accountString = this.parse(this.questions, this.account.delimiter);
            };
        /**
         * @return {?}
         */
        AccountInputComponent.prototype.parseAccount = /**
         * @return {?}
         */
            function () {
                return this.parse(this.questions, this.account.delimiter);
            };
        /**
         * @param {?} questions
         * @param {?} delimeter
         * @return {?}
         */
        AccountInputComponent.prototype.parse = /**
         * @param {?} questions
         * @param {?} delimeter
         * @return {?}
         */
            function (questions, delimeter) {
                var _this = this;
                /** @type {?} */
                var accountString = '';
                questions.forEach(function (x, index) {
                    accountString += x.value;
                    if (_this.account.showDelimeter(index, true)) {
                        accountString += delimeter;
                    }
                });
                return accountString;
            };
        /**
         * @param {?} e
         * @return {?}
         */
        AccountInputComponent.prototype.paste = /**
         * @param {?} e
         * @return {?}
         */
            function (e) {
                /** @type {?} */
                var pastedInput = e.clipboardData.getData('text/plain').trim();
                e.preventDefault();
                if (!pastedInput) {
                    return;
                }
                this.pasteAccount(pastedInput.split(this.account.delimiter));
                this.accountChange.emit(this.parseAccount());
            };
        /**
         * @param {?} input
         * @return {?}
         */
        AccountInputComponent.prototype.pasteAccount = /**
         * @param {?} input
         * @return {?}
         */
            function (input) {
                var _this = this;
                input.forEach(function (x, index) {
                    if (index + 1 <= _this.questions.length &&
                        !(_this.questions[index].controlType === 'hidden') &&
                        !isNaN(+x) &&
                        _this.questions[index].size === x.trim().length) {
                        _this.form.controls[_this.questions[index].id].patchValue(x);
                    }
                });
            };
        /**
         * @param {?} e
         * @return {?}
         */
        AccountInputComponent.prototype.onKeyup = /**
         * @param {?} e
         * @return {?}
         */
            function (e) {
                this.accountChange.emit(this.parseAccount());
                if ((e.keyCode < 48 || e.keyCode > 57) && (e.keyCode < 96 || e.keyCode > 105)) {
                    return; // only numbers can trigger auto jump feature.
                }
                /** @type {?} */
                var currentInputId = e.target['id'];
                if (this.form.controls[currentInputId].value.length === e.target['maxLength']) {
                    /** @type {?} */
                    var currentQuestionIndex = this.questions.findIndex(function (x) { return x.key === currentInputId; });
                    var _loop_1 = function (i) {
                        if (this_1.questions[i].controlType === 'hidden') {
                            return "continue";
                        }
                        /** @type {?} */
                        var nextInput = this_1.questions[i];
                        /** @type {?} */
                        var nextInputField = this_1.formInputs.find(function (v) { return v.el.nativeElement['id'] === nextInput.key; });
                        nextInputField.el.nativeElement.focus();
                        return "break";
                    };
                    var this_1 = this;
                    for (var i = currentQuestionIndex + 1; i < this.questions.length; i++) {
                        var state_1 = _loop_1(i);
                        if (state_1 === "break")
                            break;
                    }
                }
            };
        /**
         * @param {?} e
         * @return {?}
         */
        AccountInputComponent.prototype.onKeydown = /**
         * @param {?} e
         * @return {?}
         */
            function (e) {
                if (e.keyCode !== 9) {
                    return;
                }
                if (e.target['readOnly']) {
                    return;
                }
                while (this.form.controls[e.target['id']].value.length < e.target['maxLength']) {
                    this.form.controls[e.target['id']].patchValue(this.form.controls[e.target['id']].value.concat(0));
                }
            };
        AccountInputComponent.decorators = [
            { type: core.Component, args: [{
                        selector: 'uiowa-account-input',
                        template: "<div id=\"account-container\">\n  <form (ngSubmit)=\"null\" [formGroup]=\"form\">\n    <div *ngFor=\"let question of questions\" class=\"account-field\" [style.width.rem]=\"question.size + 1\">\n      <div [formGroup]=\"form\">\n        <label [attr.for]=\"question.id\" class=\"account-field-label\">{{question.label}}</label>\n\n        <div [ngSwitch]=\"question.controlType\" [ngClass]=\"{hiddenLabel: question.controlType === 'hidden'}\">\n\n          <input *ngSwitchCase=\"'textbox'\" [formControlName]=\"question.key\" [id]=\"question.id\" [type]=\"question.controlType\"\n            [attr.maxlength]=\"question.size\" [style.width.rem]=\"question.size+1\" [attr.maxlength]=\"question.size\"\n            inputmode=\"numeric\" pattern=\"[0-9]*\" digitOnly class=\"form-control\" (keydown)=\"onKeydown($event)\" (keyup)=\"onKeyup($event)\"\n            (paste)=\"paste($event)\">\n          <input *ngSwitchCase=\"'hidden'\" [formControlName]=\"question.key\" [id]=\"question.id\" [type]=\"question.controlType\"\n            [attr.maxlength]=\"question.size\" [style.width.rem]=\"question.size\">\n          <span *ngSwitchCase=\"'hidden'\">{{question.display}}</span>\n        </div>\n      </div>\n    </div>\n  </form>\n</div>\n",
                        providers: [InputControlService],
                        styles: [":host{display:inline-flex}.account-field{display:inline-block;vertical-align:bottom;margin-right:.25rem}.account-field .form-control{padding:.375rem!important;text-align:center;font-size:1rem;font-weight:400;font-style:normal;font-variant:normal}label.account-field-label{display:block;font-size:.625rem;margin-bottom:0;text-align:center;white-space:nowrap}div.hiddenLabel{margin-top:7px;text-align:center;padding-bottom:6px}"]
                    }] }
        ];
        /** @nocollapse */
        AccountInputComponent.ctorParameters = function () {
            return [
                { type: InputControlService }
            ];
        };
        AccountInputComponent.propDecorators = {
            account: [{ type: core.Input }],
            options: [{ type: core.Input }],
            index: [{ type: core.Input }],
            accountChange: [{ type: core.Output }],
            formInputs: [{ type: core.ViewChildren, args: [digitOnly.DigitOnlyDirective,] }]
        };
        return AccountInputComponent;
    }());

    /**
     * @fileoverview added by tsickle
     * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
     */
    var UiowaAccountModule = /** @class */ (function () {
        function UiowaAccountModule() {
        }
        UiowaAccountModule.decorators = [
            { type: core.NgModule, args: [{
                        imports: [common.CommonModule, ngBootstrap.NgbModule, digitOnly.DigitOnlyModule, forms.ReactiveFormsModule, forms.FormsModule],
                        declarations: [AccountStringComponent, AccountInputComponent],
                        exports: [AccountStringComponent, AccountInputComponent]
                    },] }
        ];
        return UiowaAccountModule;
    }());

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

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

    exports.AccountStringComponent = AccountStringComponent;
    exports.UiowaAccountModule = UiowaAccountModule;
    exports.Account = Account;
    exports.Element = Element;
    exports.FieldOption = FieldOption;
    exports.ElementInputText = ElementInputText;
    exports.ElementInputBase = ElementInputBase;
    exports.ElementInputHidden = ElementInputHidden;
    exports.ɵa = AccountInputComponent;
    exports.ɵb = InputControlService;

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

})));

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWlvd2EtdWlvd2EtYWNjb3VudC51bWQuanMubWFwIiwic291cmNlcyI6WyJuZzovL0B1aW93YS91aW93YS1hY2NvdW50L2xpYi9hY2NvdW50LXN0cmluZy9hY2NvdW50LXN0cmluZy5jb21wb25lbnQudHMiLCJuZzovL0B1aW93YS91aW93YS1hY2NvdW50L2xpYi9tb2RlbHMvYWNjb3VudC50cyIsIm5nOi8vQHVpb3dhL3Vpb3dhLWFjY291bnQvbGliL21vZGVscy9lbGVtZW50LnRzIiwibmc6Ly9AdWlvd2EvdWlvd2EtYWNjb3VudC9saWIvbW9kZWxzL2ZpZWxkLW9wdGlvbi50cyIsIm5vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCJuZzovL0B1aW93YS91aW93YS1hY2NvdW50L2xpYi9tb2RlbHMvZWxlbWVudC1pbnB1dC1iYXNlLnRzIiwibmc6Ly9AdWlvd2EvdWlvd2EtYWNjb3VudC9saWIvbW9kZWxzL2VsZW1lbnQtaW5wdXQtdGV4dC50cyIsIm5nOi8vQHVpb3dhL3Vpb3dhLWFjY291bnQvbGliL21vZGVscy9lbGVtZW50LWlucHV0LWhpZGRlbi50cyIsIm5nOi8vQHVpb3dhL3Vpb3dhLWFjY291bnQvbGliL2lucHV0LWNvbnRyb2wuc2VydmljZS50cyIsIm5nOi8vQHVpb3dhL3Vpb3dhLWFjY291bnQvbGliL2FjY291bnQtaW5wdXQvYWNjb3VudC1pbnB1dC5jb21wb25lbnQudHMiLCJuZzovL0B1aW93YS91aW93YS1hY2NvdW50L2xpYi91aW93YS1hY2NvdW50Lm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjY291bnQsIEZpZWxkT3B0aW9uIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndWlvd2EtYWNjb3VudC1zdHJpbmcnLFxuICB0ZW1wbGF0ZTogYFxuICA8c3BhbiAqbmdGb3I9XCJsZXQgZWxlbWVudCBvZiBvdXRwdXRcIiBwbGFjZW1lbnQ9XCJib3R0b21cIiBuZ2JUb29sdGlwPVwie3tlbGVtZW50LmRpc3BsYXl9fVwiPnt7ZWxlbWVudC52YWx1ZX19PHNwYW5cbiAgICAqbmdJZj1cImVsZW1lbnQuc2hvd0RlbGltZXRlclwiPnt7YWNjb3VudC5kZWxpbWl0ZXJ9fTwvc3Bhbj48L3NwYW4+XG4gIGBcbn0pXG5leHBvcnQgY2xhc3MgQWNjb3VudFN0cmluZ0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpXG4gIGFjY291bnQ6IEFjY291bnQ7XG4gIEBJbnB1dCgpXG4gIG9wdGlvbnM/OiBGaWVsZE9wdGlvbltdID0gW107XG4gIGNvbnN0cnVjdG9yKCkge31cblxuICBvdXRwdXQgPSBbXTtcbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5hY2NvdW50LmVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICB0aGlzLm91dHB1dC5wdXNoKHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZ2V0RWxlbWVudE91dHB1dChlbGVtZW50LndlYkFwaVByb3BlcnR5LCBpbmRleCksXG4gICAgICAgIGRpc3BsYXk6IGVsZW1lbnQuZGlzcGxheSxcbiAgICAgICAgc2hvd0RlbGltZXRlcjogdGhpcy5hY2NvdW50LnNob3dEZWxpbWV0ZXIoaW5kZXgpXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3ZlcnJpZGVWYWx1ZShwcm9wZXJ0eTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5vcHRpb25zLmZpbmQoeCA9PiB4Lm5hbWUgPT09IHByb3BlcnR5KTtcbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQuZGlzcGxheTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldEVsZW1lbnRPdXRwdXQocHJvcGVydHk6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBvdmVycmlkZVZhbHVlID0gdGhpcy5nZXRPdmVycmlkZVZhbHVlKHByb3BlcnR5KTtcbiAgICAgIGlmIChvdmVycmlkZVZhbHVlKSB7XG4gICAgICAgIHJldHVybiBvdmVycmlkZVZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hY2NvdW50LmdldEVsZW1lbnRTdHJpbmcoaW5kZXgpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBFbGVtZW50IH0gZnJvbSAnLi9lbGVtZW50JztcblxuZXhwb3J0IGNsYXNzIEFjY291bnQge1xuICB2YWx1ZTogc3RyaW5nO1xuICBkZWxpbWl0ZXI6IHN0cmluZztcbiAgZWxlbWVudHM6IEVsZW1lbnRbXTtcbiAgZGVmYXVsdFN0cmluZzogc3RyaW5nO1xuXG4gIHByaXZhdGUgdmFsdWVBcnk6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHZhbHVlOiBzdHJpbmcgPSBudWxsLCBkZWxpbWl0ZXI6IHN0cmluZyA9ICctJywgZWxlbWVudHM6IEVsZW1lbnRbXSA9IFtdLCBkZWZhdWx0U3RyaW5nOiBzdHJpbmcgPSAnWCcpIHtcbiAgICB0aGlzLmVsZW1lbnRzID0gZWxlbWVudHM7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMuZGVsaW1pdGVyID0gZGVsaW1pdGVyO1xuICAgIHRoaXMudmFsdWVBcnkgPSB0aGlzLnZhbHVlLnNwbGl0KHRoaXMuZGVsaW1pdGVyKTtcbiAgICB0aGlzLmRlZmF1bHRTdHJpbmcgPSBkZWZhdWx0U3RyaW5nO1xuICB9XG5cbiAgZ2V0RWxlbWVudFN0cmluZyhpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBsZXQgdmFsdWUgPSB0aGlzLnZhbHVlQXJ5W2luZGV4XTtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5lbGVtZW50c1tpbmRleF07XG4gICAgICBpZiAoZWxlbWVudC5pc1JlcXVpcmVkKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IGVsZW1lbnQuc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZSArIHRoaXMuZGVmYXVsdFN0cmluZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBzaG93RGVsaW1ldGVyKGluZGV4OiBudW1iZXIsIGxlYXZlT3B0aW9uYWxFbmQ6IGJvb2xlYW4gPSBmYWxzZSk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmxhc3RFbGVtZW50SXNPcHRpb25hbEFuZEVtcHR5KGluZGV4KSAmJiAhbGVhdmVPcHRpb25hbEVuZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaW5kZXhJc1RoZUxhc3RFbGVtZW50KGluZGV4KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgaW5kZXhJc1RoZUxhc3RFbGVtZW50KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaW5kZXggPT09IHRoaXMuZWxlbWVudHMubGVuZ3RoIC0gMTtcbiAgfVxuXG4gIHByaXZhdGUgbGFzdEVsZW1lbnRJc09wdGlvbmFsQW5kRW1wdHkoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmIChpbmRleCArIDIgPT09IHRoaXMuZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBpZiAoIXRoaXMuZWxlbWVudHNbaW5kZXggKyAxXS5pc1JlcXVpcmVkICYmICF0aGlzLnZhbHVlQXJ5W2luZGV4ICsgMV0pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIEVsZW1lbnQge1xuICBkaXNwbGF5OiBzdHJpbmc7XG4gIHNpemU6IG51bWJlcjtcbiAgd2ViQXBpUHJvcGVydHk6IHN0cmluZztcbiAgaXNSZXF1aXJlZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBkaXNwbGF5OiBzdHJpbmcsXG4gICAgc2l6ZTogbnVtYmVyID0gMCxcbiAgICB3ZWJhcGlwcm9wZXJ0eTogc3RyaW5nID0gbnVsbCxcbiAgICBpc1JlcXVpcmVkOiBib29sZWFuXG4gICkge1xuICAgIHRoaXMuZGlzcGxheSA9IGRpc3BsYXk7XG4gICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgICB0aGlzLndlYkFwaVByb3BlcnR5ID0gd2ViYXBpcHJvcGVydHk7XG4gICAgdGhpcy5pc1JlcXVpcmVkID0gaXNSZXF1aXJlZDtcbiAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIEZpZWxkT3B0aW9uIHtcbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IG5hbWU6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGRpc3BsYXk6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGRlZmF1bHRWYWx1ZTogc3RyaW5nID0gJycpIHt9XG59XG4iLCIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxyXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxyXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXHJcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXHJcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXHJcblxyXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcclxuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDApXHJcbiAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgZXhwb3J0cykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAoIWV4cG9ydHMuaGFzT3duUHJvcGVydHkocCkpIGV4cG9ydHNbcF0gPSBtW3BdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XHJcbiAgICByZXN1bHQuZGVmYXVsdCA9IG1vZDtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcbiIsImV4cG9ydCBjbGFzcyBFbGVtZW50SW5wdXRCYXNlPFQ+IHtcbiAgdmFsdWU6IFQ7XG4gIGtleTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICByZXF1aXJlZDogYm9vbGVhbjtcbiAgb3JkZXI6IG51bWJlcjtcbiAgY29udHJvbFR5cGU6IHN0cmluZztcbiAgaWQ6IHN0cmluZztcbiAgc2l6ZTogbnVtYmVyO1xuICBkaXNwbGF5OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgb3B0aW9uczoge1xuICAgICAgdmFsdWU/OiBUO1xuICAgICAga2V5Pzogc3RyaW5nO1xuICAgICAgbGFiZWw/OiBzdHJpbmc7XG4gICAgICByZXF1aXJlZD86IGJvb2xlYW47XG4gICAgICBvcmRlcj86IG51bWJlcjtcbiAgICAgIGNvbnRyb2xUeXBlPzogc3RyaW5nO1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICBzaXplPzogbnVtYmVyO1xuICAgICAgZGlzcGxheT86IHN0cmluZztcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgdGhpcy5rZXkgPSBvcHRpb25zLmtleSB8fCAnJztcbiAgICB0aGlzLmxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCAnJztcbiAgICB0aGlzLnJlcXVpcmVkID0gISFvcHRpb25zLnJlcXVpcmVkO1xuICAgIHRoaXMub3JkZXIgPSBvcHRpb25zLm9yZGVyID09PSB1bmRlZmluZWQgPyAxIDogb3B0aW9ucy5vcmRlcjtcbiAgICB0aGlzLmNvbnRyb2xUeXBlID0gb3B0aW9ucy5jb250cm9sVHlwZSB8fCAnJztcbiAgICB0aGlzLmlkID0gb3B0aW9ucy5pZCB8fCAnJztcbiAgICB0aGlzLnNpemUgPSBvcHRpb25zLnNpemUgfHwgMTA7XG4gICAgdGhpcy5kaXNwbGF5ID0gb3B0aW9ucy5kaXNwbGF5IHx8ICcnO1xuICB9XG59XG4iLCJpbXBvcnQgeyBFbGVtZW50SW5wdXRCYXNlIH0gZnJvbSAnLi9lbGVtZW50LWlucHV0LWJhc2UnO1xuXG5leHBvcnQgY2xhc3MgRWxlbWVudElucHV0VGV4dCBleHRlbmRzIEVsZW1lbnRJbnB1dEJhc2U8c3RyaW5nPiB7XG4gIGNvbnRyb2xUeXBlID0gJ3RleHRib3gnO1xuICB0eXBlID0gJ3N0cmluZyc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczoge30gPSB7fSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMudHlwZSA9IG9wdGlvbnNbJ3R5cGUnXTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRWxlbWVudElucHV0QmFzZSB9IGZyb20gJy4vZWxlbWVudC1pbnB1dC1iYXNlJztcblxuZXhwb3J0IGNsYXNzIEVsZW1lbnRJbnB1dEhpZGRlbiBleHRlbmRzIEVsZW1lbnRJbnB1dEJhc2U8c3RyaW5nPiB7XG4gIGNvbnRyb2xUeXBlID0gJ2hpZGRlbic7XG4gIHR5cGUgPSAnc3RyaW5nJztcbiAgY29uc3RydWN0b3Iob3B0aW9uczoge30gPSB7fSkge1xuICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMudHlwZSA9IG9wdGlvbnNbJ3R5cGUnXTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgRWxlbWVudElucHV0QmFzZSB9IGZyb20gJy4vbW9kZWxzL2VsZW1lbnQtaW5wdXQtYmFzZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJbnB1dENvbnRyb2xTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIHRvRm9ybUdyb3VwKHF1ZXN0aW9uczogRWxlbWVudElucHV0QmFzZTxhbnk+W10pIHtcbiAgICBjb25zdCBncm91cDogYW55ID0ge307XG5cbiAgICBxdWVzdGlvbnMuZm9yRWFjaChxdWVzdGlvbiA9PiB7XG4gICAgICBncm91cFtxdWVzdGlvbi5rZXldID0gcXVlc3Rpb24ucmVxdWlyZWRcbiAgICAgICAgPyBuZXcgRm9ybUNvbnRyb2wocXVlc3Rpb24udmFsdWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWQpXG4gICAgICAgIDogbmV3IEZvcm1Db250cm9sKHF1ZXN0aW9uLnZhbHVlIHx8ICcnKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IEZvcm1Hcm91cChncm91cCk7XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIFZpZXdDaGlsZHJlbiwgUXVlcnlMaXN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY2NvdW50LCBGaWVsZE9wdGlvbiwgRWxlbWVudElucHV0QmFzZSwgRWxlbWVudElucHV0VGV4dCwgRWxlbWVudElucHV0SGlkZGVuIH0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IElucHV0Q29udHJvbFNlcnZpY2UgfSBmcm9tICcuLi9pbnB1dC1jb250cm9sLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGlnaXRPbmx5RGlyZWN0aXZlIH0gZnJvbSAnQHVpb3dhL2RpZ2l0LW9ubHknO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd1aW93YS1hY2NvdW50LWlucHV0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FjY291bnQtaW5wdXQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9hY2NvdW50LWlucHV0LmNvbXBvbmVudC5jc3MnXSxcbiAgcHJvdmlkZXJzOiBbSW5wdXRDb250cm9sU2VydmljZV1cbn0pXG5leHBvcnQgY2xhc3MgQWNjb3VudElucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KClcbiAgYWNjb3VudDogQWNjb3VudDtcbiAgQElucHV0KClcbiAgb3B0aW9ucz86IEZpZWxkT3B0aW9uW10gPSBbXTtcbiAgQElucHV0KClcbiAgaW5kZXggPSAwO1xuXG4gIEBPdXRwdXQoKVxuICBhY2NvdW50Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgQFZpZXdDaGlsZHJlbihEaWdpdE9ubHlEaXJlY3RpdmUpXG4gIGZvcm1JbnB1dHM6IFF1ZXJ5TGlzdDxEaWdpdE9ubHlEaXJlY3RpdmU+O1xuXG4gIHF1ZXN0aW9uczogRWxlbWVudElucHV0QmFzZTxhbnk+W10gPSBbXTtcbiAgZm9ybTogRm9ybUdyb3VwO1xuICBhY2NvdW50U3RyaW5nOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBpbnB1dENvbnRyb2xTZXJ2aWNlOiBJbnB1dENvbnRyb2xTZXJ2aWNlKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuYWNjb3VudC5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50LCBsb29wSW5kZXgpID0+IHtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZmluZCh4ID0+IHgubmFtZSA9PT0gZWxlbWVudC53ZWJBcGlQcm9wZXJ0eSkpIHtcbiAgICAgICAgY29uc3QgaGlkZGVuT3B0aW9uID0gdGhpcy5vcHRpb25zLmZpbmQoeCA9PiB4Lm5hbWUgPT09IGVsZW1lbnQud2ViQXBpUHJvcGVydHkpO1xuICAgICAgICB0aGlzLnF1ZXN0aW9ucy5wdXNoKFxuICAgICAgICAgIG5ldyBFbGVtZW50SW5wdXRIaWRkZW4oe1xuICAgICAgICAgICAgdmFsdWU6IGhpZGRlbk9wdGlvbi5kZWZhdWx0VmFsdWUsXG4gICAgICAgICAgICBsYWJlbDogZWxlbWVudC5kaXNwbGF5LFxuICAgICAgICAgICAga2V5OiBlbGVtZW50LndlYkFwaVByb3BlcnR5ICsgJ18nICsgdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHNpemU6IGVsZW1lbnQuc2l6ZSxcbiAgICAgICAgICAgIGRpc3BsYXk6IGhpZGRlbk9wdGlvbi5kaXNwbGF5LFxuICAgICAgICAgICAgaWQ6IGVsZW1lbnQud2ViQXBpUHJvcGVydHkgKyAnXycgKyB0aGlzLmluZGV4XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucXVlc3Rpb25zLnB1c2goXG4gICAgICAgICAgbmV3IEVsZW1lbnRJbnB1dFRleHQoe1xuICAgICAgICAgICAgdmFsdWU6IHRoaXMuYWNjb3VudC5nZXRFbGVtZW50U3RyaW5nKGxvb3BJbmRleCksXG4gICAgICAgICAgICBsYWJlbDogZWxlbWVudC5kaXNwbGF5LFxuICAgICAgICAgICAga2V5OiBlbGVtZW50LndlYkFwaVByb3BlcnR5ICsgJ18nICsgdGhpcy5pbmRleCxcbiAgICAgICAgICAgIHNpemU6IGVsZW1lbnQuc2l6ZSxcbiAgICAgICAgICAgIG5hbWU6IGVsZW1lbnQud2ViQXBpUHJvcGVydHksXG4gICAgICAgICAgICBpZDogZWxlbWVudC53ZWJBcGlQcm9wZXJ0eSArICdfJyArIHRoaXMuaW5kZXhcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5mb3JtID0gdGhpcy5pbnB1dENvbnRyb2xTZXJ2aWNlLnRvRm9ybUdyb3VwKHRoaXMucXVlc3Rpb25zKTtcbiAgICB0aGlzLmFjY291bnRTdHJpbmcgPSB0aGlzLnBhcnNlKHRoaXMucXVlc3Rpb25zLCB0aGlzLmFjY291bnQuZGVsaW1pdGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VBY2NvdW50KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2UodGhpcy5xdWVzdGlvbnMsIHRoaXMuYWNjb3VudC5kZWxpbWl0ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZShxdWVzdGlvbnM6IEVsZW1lbnRJbnB1dEJhc2U8YW55PltdLCBkZWxpbWV0ZXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IGFjY291bnRTdHJpbmcgPSAnJztcbiAgICBxdWVzdGlvbnMuZm9yRWFjaCgoeCwgaW5kZXgpID0+IHtcbiAgICAgIGFjY291bnRTdHJpbmcgKz0geC52YWx1ZTtcbiAgICAgIGlmICh0aGlzLmFjY291bnQuc2hvd0RlbGltZXRlcihpbmRleCwgdHJ1ZSkpIHtcbiAgICAgICAgYWNjb3VudFN0cmluZyArPSBkZWxpbWV0ZXI7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY291bnRTdHJpbmc7XG4gIH1cblxuICBwYXN0ZShlOiBDbGlwYm9hcmRFdmVudCkge1xuICAgIGNvbnN0IHBhc3RlZElucHV0OiBzdHJpbmcgPSBlLmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9wbGFpbicpLnRyaW0oKTtcblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIXBhc3RlZElucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucGFzdGVBY2NvdW50KHBhc3RlZElucHV0LnNwbGl0KHRoaXMuYWNjb3VudC5kZWxpbWl0ZXIpKTtcbiAgICB0aGlzLmFjY291bnRDaGFuZ2UuZW1pdCh0aGlzLnBhcnNlQWNjb3VudCgpKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFzdGVBY2NvdW50KGlucHV0OiBzdHJpbmdbXSkge1xuICAgIGlucHV0LmZvckVhY2goKHgsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGluZGV4ICsgMSA8PSB0aGlzLnF1ZXN0aW9ucy5sZW5ndGggJiZcbiAgICAgICAgISh0aGlzLnF1ZXN0aW9uc1tpbmRleF0uY29udHJvbFR5cGUgPT09ICdoaWRkZW4nKSAmJlxuICAgICAgICAhaXNOYU4oK3gpICYmXG4gICAgICAgIHRoaXMucXVlc3Rpb25zW2luZGV4XS5zaXplID09PSB4LnRyaW0oKS5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICB0aGlzLmZvcm0uY29udHJvbHNbdGhpcy5xdWVzdGlvbnNbaW5kZXhdLmlkXS5wYXRjaFZhbHVlKHgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25LZXl1cChlOiBLZXlib2FyZEV2ZW50KSB7XG4gICAgdGhpcy5hY2NvdW50Q2hhbmdlLmVtaXQodGhpcy5wYXJzZUFjY291bnQoKSk7XG4gICAgaWYgKChlLmtleUNvZGUgPCA0OCB8fCBlLmtleUNvZGUgPiA1NykgJiYgKGUua2V5Q29kZSA8IDk2IHx8IGUua2V5Q29kZSA+IDEwNSkpIHtcbiAgICAgIHJldHVybjsgLy8gb25seSBudW1iZXJzIGNhbiB0cmlnZ2VyIGF1dG8ganVtcCBmZWF0dXJlLlxuICAgIH1cbiAgICBjb25zdCBjdXJyZW50SW5wdXRJZCA9IGUudGFyZ2V0WydpZCddO1xuICAgIGlmICh0aGlzLmZvcm0uY29udHJvbHNbY3VycmVudElucHV0SWRdLnZhbHVlLmxlbmd0aCA9PT0gZS50YXJnZXRbJ21heExlbmd0aCddKSB7XG4gICAgICBjb25zdCBjdXJyZW50UXVlc3Rpb25JbmRleCA9IHRoaXMucXVlc3Rpb25zLmZpbmRJbmRleCh4ID0+IHgua2V5ID09PSBjdXJyZW50SW5wdXRJZCk7XG4gICAgICBmb3IgKGxldCBpID0gY3VycmVudFF1ZXN0aW9uSW5kZXggKyAxOyBpIDwgdGhpcy5xdWVzdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHRoaXMucXVlc3Rpb25zW2ldLmNvbnRyb2xUeXBlID09PSAnaGlkZGVuJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5leHRJbnB1dCA9IHRoaXMucXVlc3Rpb25zW2ldO1xuICAgICAgICBjb25zdCBuZXh0SW5wdXRGaWVsZCA9IHRoaXMuZm9ybUlucHV0cy5maW5kKHYgPT4gdi5lbC5uYXRpdmVFbGVtZW50WydpZCddID09PSBuZXh0SW5wdXQua2V5KTtcbiAgICAgICAgbmV4dElucHV0RmllbGQuZWwubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbktleWRvd24oZTogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChlLmtleUNvZGUgIT09IDkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGUudGFyZ2V0WydyZWFkT25seSddKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgd2hpbGUgKHRoaXMuZm9ybS5jb250cm9sc1tlLnRhcmdldFsnaWQnXV0udmFsdWUubGVuZ3RoIDwgZS50YXJnZXRbJ21heExlbmd0aCddKSB7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHNbZS50YXJnZXRbJ2lkJ11dLnBhdGNoVmFsdWUodGhpcy5mb3JtLmNvbnRyb2xzW2UudGFyZ2V0WydpZCddXS52YWx1ZS5jb25jYXQoMCkpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBBY2NvdW50U3RyaW5nQ29tcG9uZW50IH0gZnJvbSAnLi9hY2NvdW50LXN0cmluZy9hY2NvdW50LXN0cmluZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgTmdiTW9kdWxlIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgQWNjb3VudElucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9hY2NvdW50LWlucHV0L2FjY291bnQtaW5wdXQuY29tcG9uZW50JztcbmltcG9ydCB7IERpZ2l0T25seU1vZHVsZSB9IGZyb20gJ0B1aW93YS9kaWdpdC1vbmx5JztcbmltcG9ydCB7IEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5ATmdNb2R1bGUoe1xuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBOZ2JNb2R1bGUsIERpZ2l0T25seU1vZHVsZSwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgRm9ybXNNb2R1bGVdLFxuICBkZWNsYXJhdGlvbnM6IFtBY2NvdW50U3RyaW5nQ29tcG9uZW50LCBBY2NvdW50SW5wdXRDb21wb25lbnRdLFxuICBleHBvcnRzOiBbQWNjb3VudFN0cmluZ0NvbXBvbmVudCwgQWNjb3VudElucHV0Q29tcG9uZW50XVxufSlcbmV4cG9ydCBjbGFzcyBVaW93YUFjY291bnRNb2R1bGUge31cbiJdLCJuYW1lcyI6WyJDb21wb25lbnQiLCJJbnB1dCIsInRzbGliXzEuX19leHRlbmRzIiwiRm9ybUNvbnRyb2wiLCJWYWxpZGF0b3JzIiwiRm9ybUdyb3VwIiwiSW5qZWN0YWJsZSIsIkV2ZW50RW1pdHRlciIsIk91dHB1dCIsIlZpZXdDaGlsZHJlbiIsIkRpZ2l0T25seURpcmVjdGl2ZSIsIk5nTW9kdWxlIiwiQ29tbW9uTW9kdWxlIiwiTmdiTW9kdWxlIiwiRGlnaXRPbmx5TW9kdWxlIiwiUmVhY3RpdmVGb3Jtc01vZHVsZSIsIkZvcm1zTW9kdWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBQUE7UUFlRTtZQURBLFlBQU8sR0FBbUIsRUFBRSxDQUFDO1lBRzdCLFdBQU0sR0FBRyxFQUFFLENBQUM7U0FGSTs7OztRQUdoQix5Q0FBUTs7O1lBQVI7Z0JBQUEsaUJBUUM7Z0JBUEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLEtBQUs7b0JBQzNDLEtBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO3dCQUNmLEtBQUssRUFBRSxLQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUM7d0JBQzNELE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTzt3QkFDeEIsYUFBYSxFQUFFLEtBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztxQkFDakQsQ0FBQyxDQUFDO2lCQUNKLENBQUMsQ0FBQzthQUNKOzs7OztRQUVPLGlEQUFnQjs7OztZQUF4QixVQUF5QixRQUFnQjs7b0JBQ2pDLE9BQU8sR0FBRyxJQUFJLENBQUMs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