UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

614 lines 52.9 kB
/** * @fileoverview added by tsickle * Generated from: input-number.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, Output, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { fromEvent } from 'rxjs'; /** @type {?} */ const INPUT_NUMBER_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, // tslint:disable-next-line useExisting: forwardRef((/** * @return {?} */ () => InputNumberComponent)), multi: true }; export class InputNumberComponent { /** * @param {?} cdr * @param {?} el */ constructor(cdr, el) { this.cdr = cdr; this.el = el; this.max = 100; this.min = 0; this.step = 1; this.disabled = false; this.size = ''; this.autoFocus = false; this.allowEmpty = false; this.placeholder = ''; this.maxLength = 0; this.afterValueChanged = new EventEmitter(); this.whileValueChanging = new EventEmitter(); this.disabledInc = false; this.disabledDec = false; this.onTouchedCallback = (/** * @param {?} v * @return {?} */ (v) => { }); this.onChangeCallback = (/** * @param {?} v * @return {?} */ (v) => { }); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChangeCallback = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouchedCallback = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; this.toggleDisabled(isDisabled); } /** * @param {?} newValue * @return {?} */ writeValue(newValue) { this.lastEmittedValue = newValue; this.setValue(this.ensureValueInRange(newValue)); } /** * @private * @param {?} value * @return {?} */ valueMustBeValid(value) { return !isNaN(typeof value !== 'number' ? parseFloat(value) : value); } /** * @private * @param {?} min * @param {?} n * @param {?} max * @return {?} */ clamp(min, n, max) { return Math.max(min, Math.min(n, max)); } /** * @private * @param {?} value * @return {?} */ ensureValueInRange(value) { /** @type {?} */ let safeValue; if (this.allowEmpty && (value === null || value === undefined)) { safeValue = value; } else if (!this.valueMustBeValid(value)) { safeValue = this.min; } else { /** @type {?} */ let currentValue = value; if (!value) { currentValue = 0; } safeValue = this.clamp(this.min, currentValue, this.max); } return safeValue; } /** * @private * @param {?} value * @return {?} */ setValue(value) { this.value = value; this.valueInput = value; if (this.disabled) { return; } if (this.allowEmpty && (value === null || value === undefined)) { this.subscribeDecAction(); this.subscribeIncAction(); } else { if (!this.canDecrease()) { this.unsubscribeDecAction(); } else { this.subscribeDecAction(); } if (!this.canIncrease()) { this.unsubscribeIncAction(); } else { this.subscribeIncAction(); } } this.cdr.detectChanges(); } /** * @return {?} */ ngAfterViewInit() { this.registerListeners(); this.subscribeActions(); this.toggleDisabled(this.disabled); this.el.nativeElement.addEventListener('click', this.registerBlurListener.bind(this)); if (this.autoFocus) { this.el.nativeElement.click(); this.inputElement.nativeElement.focus(); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.hasOwnProperty('min') || changes.hasOwnProperty('max')) { this.checkRangeValues(this.min, this.max); } } /** * @return {?} */ ngOnDestroy() { this.unsubscribeActions(); } /** * @return {?} */ registerListeners() { if (this.incButton && this.incButton.nativeElement) { this.incListener = fromEvent(this.incButton.nativeElement, 'click'); } if (this.decButton && this.decButton.nativeElement) { this.decListener = fromEvent(this.decButton.nativeElement, 'click'); } } /** * @return {?} */ subscribeActions() { this.subscribeIncAction(); this.subscribeDecAction(); } /** * @return {?} */ subscribeIncAction() { if (this.incListener && !this.incAction) { this.incAction = this.incListener.subscribe(this.increaseValue.bind(this)); this.disabledInc = false; } } /** * @return {?} */ subscribeDecAction() { if (this.decListener && !this.decAction) { this.decAction = this.decListener.subscribe(this.decreaseValue.bind(this)); this.disabledDec = false; } } /** * @return {?} */ unsubscribeActions() { this.unsubscribeIncAction(); this.unsubscribeDecAction(); } /** * @return {?} */ unsubscribeIncAction() { if (this.incListener && this.incAction) { this.incAction.unsubscribe(); this.incAction = null; this.disabledInc = true; } } /** * @return {?} */ unsubscribeDecAction() { if (this.incListener && this.decAction) { this.decAction.unsubscribe(); this.decAction = null; this.disabledDec = true; } } /** * @private * @return {?} */ increaseValue() { if (this.canIncrease()) { if (this.allowEmpty && (this.value === null || this.value === undefined)) { this.updateValue(this.min); } else { /** @type {?} */ const decimals = this.getMaxDecimals(this.value); this.updateValue(parseFloat((this.value + this.step).toFixed(decimals))); } } } /** * @private * @return {?} */ decreaseValue() { if (this.canDecrease()) { if (this.allowEmpty && (this.value === null || this.value === undefined)) { this.updateValue(this.min); } else { /** @type {?} */ const decimals = this.getMaxDecimals(this.value); this.updateValue(parseFloat((this.value - this.step).toFixed(decimals))); } } } /** * @private * @return {?} */ canIncrease() { if (this.allowEmpty && (this.value === null || this.value === undefined)) { return (this.min + this.step) <= this.max; } else { return (this.value + this.step) <= this.max; } } /** * @private * @return {?} */ canDecrease() { if (this.allowEmpty && (this.value === null || this.value === undefined)) { return (this.min + this.step) <= this.max; } else { return (this.value - this.step) >= this.min; } } /** * @private * @param {?} disabled * @return {?} */ toggleDisabled(disabled) { if (disabled) { this.unsubscribeActions(); } else { this.subscribeActions(); } } /** * @param {?} event * @return {?} */ ensureValueIsValid(event) { event.stopPropagation(); /** @type {?} */ const newValue = event.target['value']; /** @type {?} */ const parseValue = parseFloat((/** @type {?} */ (newValue))); if (this.allowEmpty && newValue === '') { this.updateValue(this.ensureValueInRange(null)); } else if (!isNaN(parseValue)) { this.updateValue(this.ensureValueInRange(parseValue)); } else { this.updateValue(this.ensureValueInRange(this.value)); } } /** * @private * @param {?} minValue * @param {?} maxValue * @return {?} */ checkRangeValues(minValue, maxValue) { if (maxValue < minValue) { throw new Error(`max value must be greater than or equal to min value`); } } /** * @private * @param {?} value * @return {?} */ getDecimals(value) { /** @type {?} */ const valueString = value.toString(); /** @type {?} */ const integerLength = valueString.indexOf('.') + 1; return integerLength >= 0 ? valueString.length - integerLength : 0; } /** * @private * @param {?} currentValue * @return {?} */ getMaxDecimals(currentValue) { /** @type {?} */ const stepPrecision = this.getDecimals(this.step); /** @type {?} */ const currentValuePrecision = this.getDecimals((/** @type {?} */ (currentValue))); if (!currentValue) { return stepPrecision; } if (this.decimalLimit !== undefined && this.decimalLimit !== null) { return this.decimalLimit; } return Math.max(currentValuePrecision, stepPrecision); } /** * @param {?} event * @return {?} */ protectInput(event) { /** @type {?} */ let value = event.target['value']; /** @type {?} */ const input = String.fromCharCode(event.which); /** @type {?} */ const selectionStart = event.target['selectionStart']; /** @type {?} */ const selectionEnd = event.target['selectionEnd']; value = value.substring(0, selectionStart) + input + value.substring(selectionEnd); if (this.maxLength && value.length > this.maxLength) { event.preventDefault(); return; } if (this.reg && !value.match(new RegExp(this.reg))) { event.preventDefault(); return; } else if (value === '-' || value.match(/^\s*(-|\+)?\d+\.$/) || value.match(/^\s*(-|\+)?\d+\.[0-9]*0$/) || value.match(/^\s*(-|\+)0+$/)) { // indeterminate state return; } else if (value.match(/^\s*(-|\+)?(\d+|(\d*(\.\d*)))$/)) { event.preventDefault(); if (this.decimalLimit !== undefined && this.decimalLimit !== null) { value = parseFloat(value).toFixed(this.decimalLimit); } value = parseFloat((/** @type {?} */ (value))); if (!isNaN(value)) { this.valueInput = value; this.notifyWhileValueChanging(value); // updateValue会使输入游标跳到最后,这里设置输入游标归位 setTimeout((/** * @return {?} */ () => { event.target['setSelectionRange'](selectionStart + 1, selectionStart + 1); }), 0); return; } } else { event.preventDefault(); } } /** * @private * @return {?} */ notifyValueChange() { this.afterValueChanged.emit(this.value); this.onChangeCallback(this.value); } /** * @private * @param {?} value * @return {?} */ notifyWhileValueChanging(value) { this.whileValueChanging.emit(value); } /** * @private * @param {?} value * @return {?} */ updateValue(value) { this.setValue(value); if (this.lastEmittedValue !== value) { this.lastEmittedValue = value; this.notifyValueChange(); } } /** * @param {?} event * @return {?} */ handleBackspace(event) { if (event.key === 'Backspace') { /** @type {?} */ let oldValue = event.target['value']; /** @type {?} */ const selectionStart = event.target['selectionStart']; /** @type {?} */ const selectionEnd = event.target['selectionEnd']; /** @type {?} */ let newValue = oldValue.substring(0, selectionStart - 1) + oldValue.substring(selectionEnd); oldValue = oldValue === '' ? null : this.ensureValueInRange(oldValue); newValue = newValue === '' ? null : this.ensureValueInRange(newValue); if (oldValue !== newValue && newValue !== '-') { this.notifyWhileValueChanging(newValue); } } } /** * @return {?} */ registerBlurListener() { document.addEventListener('click', this.emitBlurEvent.bind(this), { capture: true, once: true, }); } /** * @param {?} event * @return {?} */ emitBlurEvent(event) { if (this.el.nativeElement !== event.target && !this.el.nativeElement.contains(event.target)) { this.el.nativeElement.dispatchEvent(new Event('blur', { bubbles: false })); } } } InputNumberComponent.decorators = [ { type: Component, args: [{ selector: 'd-input-number', template: "<div\r\n class=\"input-control-buttons\"\r\n [ngClass]=\"{\r\n disabled: disabled,\r\n 'devui-input-number-lg': size === 'lg',\r\n 'devui-input-number-sm': size === 'sm'\r\n }\"\r\n>\r\n <span class=\"input-control-button input-control-inc\" [ngClass]=\"{ disabled: disabledInc }\" #incButton>\r\n <svg class=\"devui-svg-icon-arrow\" width=\"15px\" height=\"15px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g id=\"chevron-up\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\r\n <polygon points=\"11.5 12 8 8.23076923 4.5 12 3 10.3846154 8 5 13 10.3846154\"></polygon>\r\n </g>\r\n </svg>\r\n </span>\r\n <span class=\"input-control-button input-control-dec\" [ngClass]=\"{ disabled: disabledDec }\" #decButton>\r\n <svg class=\"devui-svg-icon-arrow\" width=\"15px\" height=\"15px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g id=\"chevron-down\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\r\n <polygon points=\"4.5 5 8 8.76923077 11.5 5 13 6.61538462 8 12 3 6.61538462\"></polygon>\r\n </g>\r\n </svg>\r\n </span>\r\n</div>\r\n<div\r\n class=\"input-container\"\r\n [ngClass]=\"{\r\n 'devui-input-number-lg': size === 'lg',\r\n 'devui-input-number-sm': size === 'sm'\r\n }\"\r\n>\r\n <input\r\n class=\"input-box\"\r\n [(ngModel)]=\"valueInput\"\r\n [ngClass]=\"{ disabled: disabled }\"\r\n [placeholder]=\"placeholder\"\r\n [attr.readonly]=\"disabled ? '' : null\"\r\n (keypress)=\"protectInput($event)\"\r\n (blur)=\"ensureValueIsValid($event)\"\r\n (keydown)=\"handleBackspace($event)\"\r\n #inputElement\r\n />\r\n</div>\r\n", providers: [INPUT_NUMBER_CONTROL_VALUE_ACCESSOR], styles: [":host{display:inline-block;position:relative;width:80px}:host .disabled{cursor:not-allowed;opacity:.3}:host:hover .input-box:not(.disabled){border:1px solid #344899;padding-right:26px}:host:hover .input-control-buttons:not(.disabled){border-color:#344899;display:-webkit-box;display:flex}:host:focus-within .input-box:not(.disabled){border:1px solid #344899;padding-right:26px}:host:focus-within .input-control-buttons:not(.disabled){border-color:#344899;display:-webkit-box;display:flex}:host .input-box{box-sizing:border-box;padding:5px 10px;font-size:14px;color:#252b3a;vertical-align:middle;border:1px solid #adb0b8;border-radius:2px;outline:0;width:100%;background-color:#fff;line-height:20px;height:32px}:host .input-control-buttons{position:absolute;right:0;width:25px;height:100%;display:none;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;border:1px solid transparent;border-left-color:#adb0b8;box-sizing:border-box;line-height:100%}:host .input-control-buttons .input-control-button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;height:50%;line-height:50%;border-width:0 1px;cursor:pointer;-webkit-transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center}:host .input-control-buttons .input-control-button svg>g{fill:#252b3a}:host .input-control-buttons .input-control-button:not(.disabled):hover>svg>g{fill:#344899}.devui-input-number-lg>.input-box{font-size:18px;line-height:24px;height:46px}.devui-input-number-lg ::ng-deep .devui-svg-icon-arrow{width:16px;height:16px}.devui-input-number-sm>.input-box{font-size:12px;line-height:18px;height:30px}.devui-input-number-sm ::ng-deep .devui-svg-icon-arrow{width:13px;height:13px}.input-container{line-height:100%}"] }] } ]; /** @nocollapse */ InputNumberComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: ElementRef } ]; InputNumberComponent.propDecorators = { max: [{ type: Input }], min: [{ type: Input }], step: [{ type: Input }], disabled: [{ type: Input }], size: [{ type: Input }], decimalLimit: [{ type: Input }], autoFocus: [{ type: Input }], allowEmpty: [{ type: Input }], placeholder: [{ type: Input }], maxLength: [{ type: Input }], reg: [{ type: Input }], afterValueChanged: [{ type: Output }], whileValueChanging: [{ type: Output }], incButton: [{ type: ViewChild, args: ['incButton', { static: true },] }], decButton: [{ type: ViewChild, args: ['decButton', { static: true },] }], inputElement: [{ type: ViewChild, args: ['inputElement', { static: true },] }] }; if (false) { /** @type {?} */ InputNumberComponent.prototype.max; /** @type {?} */ InputNumberComponent.prototype.min; /** @type {?} */ InputNumberComponent.prototype.step; /** @type {?} */ InputNumberComponent.prototype.disabled; /** @type {?} */ InputNumberComponent.prototype.size; /** @type {?} */ InputNumberComponent.prototype.decimalLimit; /** @type {?} */ InputNumberComponent.prototype.autoFocus; /** @type {?} */ InputNumberComponent.prototype.allowEmpty; /** @type {?} */ InputNumberComponent.prototype.placeholder; /** @type {?} */ InputNumberComponent.prototype.maxLength; /** @type {?} */ InputNumberComponent.prototype.reg; /** @type {?} */ InputNumberComponent.prototype.afterValueChanged; /** @type {?} */ InputNumberComponent.prototype.whileValueChanging; /** @type {?} */ InputNumberComponent.prototype.incButton; /** @type {?} */ InputNumberComponent.prototype.decButton; /** @type {?} */ InputNumberComponent.prototype.inputElement; /** * @type {?} * @private */ InputNumberComponent.prototype.value; /** * @type {?} * @private */ InputNumberComponent.prototype.incListener; /** * @type {?} * @private */ InputNumberComponent.prototype.decListener; /** * @type {?} * @private */ InputNumberComponent.prototype.incAction; /** * @type {?} * @private */ InputNumberComponent.prototype.decAction; /** @type {?} */ InputNumberComponent.prototype.disabledInc; /** @type {?} */ InputNumberComponent.prototype.disabledDec; /** @type {?} */ InputNumberComponent.prototype.valueInput; /** @type {?} */ InputNumberComponent.prototype.lastEmittedValue; /** * @type {?} * @private */ InputNumberComponent.prototype.onTouchedCallback; /** * @type {?} * @private */ InputNumberComponent.prototype.onChangeCallback; /** * @type {?} * @private */ InputNumberComponent.prototype.cdr; /** * @type {?} * @private */ InputNumberComponent.prototype.el; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtbnVtYmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLWRldnVpL2lucHV0LW51bWJlci8iLCJzb3VyY2VzIjpbImlucHV0LW51bWJlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBR0wsTUFBTSxFQUVOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFFLFNBQVMsRUFBNEIsTUFBTSxNQUFNLENBQUM7O01BRXJELG1DQUFtQyxHQUFRO0lBQy9DLE9BQU8sRUFBRSxpQkFBaUI7O0lBRTFCLFdBQVcsRUFBRSxVQUFVOzs7SUFBQyxHQUFHLEVBQUUsQ0FBQyxvQkFBb0IsRUFBQztJQUNuRCxLQUFLLEVBQUUsSUFBSTtDQUNaO0FBV0QsTUFBTSxPQUFPLG9CQUFvQjs7Ozs7SUFpQy9CLFlBQW9CLEdBQXNCLEVBQVUsRUFBYztRQUE5QyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUFVLE9BQUUsR0FBRixFQUFFLENBQVk7UUFoQ3pELFFBQUcsR0FBRyxHQUFHLENBQUM7UUFDVixRQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1IsU0FBSSxHQUFHLENBQUMsQ0FBQztRQUNULGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsU0FBSSxHQUFrQixFQUFFLENBQUM7UUFFekIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLGdCQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLGNBQVMsR0FBRyxDQUFDLENBQUM7UUFFYixzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQy9DLHVCQUFrQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7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TixNQUFNO3dCQUNOLFNBQVMsU0FBQyxXQUFXLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO3dCQUN2QyxTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTsyQkFDdkMsU0FBUyxTQUFDLGNBQWMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Ozs7SUFmM0MsbUNBQW1COztJQUNuQixtQ0FBaUI7O0lBQ2pCLG9DQUFrQjs7SUFDbEIsd0NBQTBCOztJQUMxQixvQ0FBa0M7O0lBQ2xDLDRDQUFzQjs7SUFDdEIseUNBQTJCOztJQUMzQiwwQ0FBNEI7O0lBQzVCLDJDQUEwQjs7SUFDMUIseUNBQXVCOztJQUN2QixtQ0FBOEI7O0lBQzlCLGlEQUF5RDs7SUFDekQsa0RBQTBEOztJQUMxRCx5Q0FBZ0U7O0lBQ2hFLHlDQUFnRTs7SUFDaEUsNENBQXNFOzs7OztJQUV0RSxxQ0FBc0I7Ozs7O0lBQ3RCLDJDQUFxQzs7Ozs7SUFDckMsMkNBQXFDOzs7OztJQUNyQyx5Q0FBZ0M7Ozs7O0lBQ2hDLHlDQUFnQzs7SUFDaEMsMkNBQW9COztJQUNwQiwyQ0FBb0I7O0lBQ3BCLDBDQUFtQjs7SUFDbkIsZ0RBQXlCOzs7OztJQUV6QixpREFDQzs7Ozs7SUFFRCxnREFDQzs7Ozs7SUFDVyxtQ0FBOEI7Ozs7O0lBQUUsa0NBQXNCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBmb3J3YXJkUmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT3V0cHV0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVmlld0NoaWxkXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgZnJvbUV2ZW50LCBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuXHJcbmNvbnN0IElOUFVUX05VTUJFUl9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XHJcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXHJcbiAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gSW5wdXROdW1iZXJDb21wb25lbnQpLFxyXG4gIG11bHRpOiB0cnVlXHJcbn07XHJcblxyXG5leHBvcnQgdHlwZSBJbnB1dFNpemVUeXBlID0gJycgfCAnc20nIHwgJ2xnJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZC1pbnB1dC1udW1iZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9pbnB1dC1udW1iZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2lucHV0LW51bWJlci5jb21wb25lbnQuc2NzcyddLFxyXG4gIHByb3ZpZGVyczogW0lOUFVUX05VTUJFUl9DT05UUk9MX1ZBTFVFX0FDQ0VTU09SXVxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIElucHV0TnVtYmVyQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcclxuICBASW5wdXQoKSBtYXggPSAxMDA7XHJcbiAgQElucHV0KCkgbWluID0gMDtcclxuICBASW5wdXQoKSBzdGVwID0gMTtcclxuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHNpemU6IElucHV0U2l6ZVR5cGUgPSAnJztcclxuICBASW5wdXQoKSBkZWNpbWFsTGltaXQ7XHJcbiAgQElucHV0KCkgYXV0b0ZvY3VzID0gZmFsc2U7XHJcbiAgQElucHV0KCkgYWxsb3dFbXB0eSA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gJyc7XHJcbiAgQElucHV0KCkgbWF4TGVuZ3RoID0gMDtcclxuICBASW5wdXQoKSByZWc6IFJlZ0V4cCB8IHN0cmluZztcclxuICBAT3V0cHV0KCkgYWZ0ZXJWYWx1ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcclxuICBAT3V0cHV0KCkgd2hpbGVWYWx1ZUNoYW5naW5nID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcbiAgQFZpZXdDaGlsZCgnaW5jQnV0dG9uJywgeyBzdGF0aWM6IHRydWUgfSkgaW5jQnV0dG9uOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ2RlY0J1dHRvbicsIHsgc3RhdGljOiB0cnVlIH0pIGRlY0J1dHRvbjogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdpbnB1dEVsZW1lbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBpbnB1dEVsZW1lbnQ6IEVsZW1lbnRSZWY7XHJcblxyXG4gIHByaXZhdGUgdmFsdWU6IG51bWJlcjtcclxuICBwcml2YXRlIGluY0xpc3RlbmVyOiBPYnNlcnZhYmxlPGFueT47XHJcbiAgcHJpdmF0ZSBkZWNMaXN0ZW5lcjogT2JzZXJ2YWJsZTxhbnk+O1xyXG4gIHByaXZhdGUgaW5jQWN0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgcHJpdmF0ZSBkZWNBY3Rpb246IFN1YnNjcmlwdGlvbjtcclxuICBkaXNhYmxlZEluYyA9IGZhbHNlO1xyXG4gIGRpc2FibGVkRGVjID0gZmFsc2U7XHJcbiAgdmFsdWVJbnB1dDogbnVtYmVyO1xyXG4gIGxhc3RFbWl0dGVkVmFsdWU6IG51bWJlcjtcclxuXHJcbiAgcHJpdmF0ZSBvblRvdWNoZWRDYWxsYmFjayA9ICh2OiBhbnkpID0+IHtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25DaGFuZ2VDYWxsYmFjayA9ICh2OiBhbnkpID0+IHtcclxuICB9XHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIGVsOiBFbGVtZW50UmVmKSB7XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xyXG4gIH1cclxuXHJcbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XHJcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcclxuICAgIHRoaXMudG9nZ2xlRGlzYWJsZWQoaXNEaXNhYmxlZCk7XHJcbiAgfVxyXG5cclxuICB3cml0ZVZhbHVlKG5ld1ZhbHVlOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMubGFzdEVtaXR0ZWRWYWx1ZSA9IG5ld1ZhbHVlO1xyXG4gICAgdGhpcy5zZXRWYWx1ZSh0aGlzLmVuc3VyZVZhbHVlSW5SYW5nZShuZXdWYWx1ZSkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWx1ZU11c3RCZVZhbGlkKHZhbHVlOiBudW1iZXIpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAhaXNOYU4odHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyA/IHBhcnNlRmxvYXQodmFsdWUpIDogdmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjbGFtcChtaW46IG51bWJlciwgbjogbnVtYmVyLCBtYXg6IG51bWJlcikge1xyXG4gICAgcmV0dXJuIE1hdGgubWF4KG1pbiwgTWF0aC5taW4obiwgbWF4KSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGVuc3VyZVZhbHVlSW5SYW5nZSh2YWx1ZTogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG51bWJlciB7XHJcbiAgICBsZXQgc2FmZVZhbHVlO1xyXG4gICAgaWYgKHRoaXMuYWxsb3dFbXB0eSAmJiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkpIHtcclxuICAgICAgc2FmZVZhbHVlID0gdmFsdWU7XHJcbiAgICB9IGVsc2UgaWYgKCF0aGlzLnZhbHVlTXVzdEJlVmFsaWQodmFsdWUpKSB7XHJcbiAgICAgIHNhZmVWYWx1ZSA9IHRoaXMubWluO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IHZhbHVlO1xyXG4gICAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgICAgY3VycmVudFZhbHVlID0gMDtcclxuICAgICAgfVxyXG4gICAgICBzYWZlVmFsdWUgPSB0aGlzLmNsYW1wKHRoaXMubWluLCBjdXJyZW50VmFsdWUsIHRoaXMubWF4KTtcclxuICAgIH1cclxuICAgIHJldHVybiBzYWZlVmFsdWU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNldFZhbHVlKHZhbHVlOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogdm9pZCB7XHJcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICB0aGlzLnZhbHVlSW5wdXQgPSB2YWx1ZTtcclxuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7IHJldHVybjsgfVxyXG4gICAgaWYgKHRoaXMuYWxsb3dFbXB0eSAmJiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkpIHtcclxuICAgICAgdGhpcy5zdWJzY3JpYmVEZWNBY3Rpb24oKTtcclxuICAgICAgdGhpcy5zdWJzY3JpYmVJbmNBY3Rpb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghdGhpcy5jYW5EZWNyZWFzZSgpKSB7XHJcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZURlY0FjdGlvbigpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlRGVjQWN0aW9uKCk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKCF0aGlzLmNhbkluY3JlYXNlKCkpIHtcclxuICAgICAgICB0aGlzLnVuc3Vic2NyaWJlSW5jQWN0aW9uKCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zdWJzY3JpYmVJbmNBY3Rpb24oKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuXHJcbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5yZWdpc3Rlckxpc3RlbmVycygpO1xyXG4gICAgdGhpcy5zdWJzY3JpYmVBY3Rpb25zKCk7XHJcbiAgICB0aGlzLnRvZ2dsZURpc2FibGVkKHRoaXMuZGlzYWJsZWQpO1xyXG4gICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5yZWdpc3RlckJsdXJMaXN0ZW5lci5iaW5kKHRoaXMpKTtcclxuICAgIGlmICh0aGlzLmF1dG9Gb2N1cykge1xyXG4gICAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuY2xpY2soKTtcclxuICAgICAgdGhpcy5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ21pbicpIHx8IGNoYW5nZXMuaGFzT3duUHJvcGVydHkoJ21heCcpKSB7XHJcbiAgICAgIHRoaXMuY2hlY2tSYW5nZVZhbHVlcyh0aGlzLm1pbiwgdGhpcy5tYXgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlQWN0aW9ucygpO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJMaXN0ZW5lcnMoKSB7XHJcbiAgICBpZiAodGhpcy5pbmNCdXR0b24gJiYgdGhpcy5pbmNCdXR0b24ubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICB0aGlzLmluY0xpc3RlbmVyID0gZnJvbUV2ZW50KHRoaXMuaW5jQnV0dG9uLm5hdGl2ZUVsZW1lbnQsICdjbGljaycpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuZGVjQnV0dG9uICYmIHRoaXMuZGVjQnV0dG9uLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgdGhpcy5kZWNMaXN0ZW5lciA9IGZyb21FdmVudCh0aGlzLmRlY0J1dHRvbi5uYXRpdmVFbGVtZW50LCAnY2xpY2snKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN1YnNjcmliZUFjdGlvbnMoKSB7XHJcbiAgICB0aGlzLnN1YnNjcmliZUluY0FjdGlvbigpO1xyXG4gICAgdGhpcy5zdWJzY3JpYmVEZWNBY3Rpb24oKTtcclxuICB9XHJcblxyXG4gIHN1YnNjcmliZUluY0FjdGlvbigpIHtcclxuICAgIGlmICh0aGlzLmluY0xpc3RlbmVyICYmICF0aGlzLmluY0FjdGlvbikge1xyXG4gICAgICB0aGlzLmluY0FjdGlvbiA9IHRoaXMuaW5jTGlzdGVuZXIuc3Vic2NyaWJlKHRoaXMuaW5jcmVhc2VWYWx1ZS5iaW5kKHRoaXMpKTtcclxuICAgICAgdGhpcy5kaXNhYmxlZEluYyA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc3Vic2NyaWJlRGVjQWN0aW9uKCkge1xyXG4gICAgaWYgKHRoaXMuZGVjTGlzdGVuZXIgJiYgIXRoaXMuZGVjQWN0aW9uKSB7XHJcbiAgICAgIHRoaXMuZGVjQWN0aW9uID0gdGhpcy5kZWNMaXN0ZW5lci5zdWJzY3JpYmUodGhpcy5kZWNyZWFzZVZhbHVlLmJpbmQodGhpcykpO1xyXG4gICAgICB0aGlzLmRpc2FibGVkRGVjID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1bnN1YnNjcmliZUFjdGlvbnMoKSB7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlSW5jQWN0aW9uKCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlRGVjQWN0aW9uKCk7XHJcbiAgfVxyXG5cclxuICB1bnN1YnNjcmliZUluY0FjdGlvbigpIHtcclxuICAgIGlmICh0aGlzLmluY0xpc3RlbmVyICYmIHRoaXMuaW5jQWN0aW9uKSB7XHJcbiAgICAgIHRoaXMuaW5jQWN0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgIHRoaXMuaW5jQWN0aW9uID0gbnVsbDtcclxuICAgICAgdGhpcy5kaXNhYmxlZEluYyA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB1bnN1YnNjcmliZURlY0FjdGlvbigpIHtcclxuICAgIGlmICh0aGlzLmluY0xpc3RlbmVyICYmIHRoaXMuZGVjQWN0aW9uKSB7XHJcbiAgICAgIHRoaXMuZGVjQWN0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgIHRoaXMuZGVjQWN0aW9uID0gbnVsbDtcclxuICAgICAgdGhpcy5kaXNhYmxlZERlYyA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluY3JlYXNlVmFsdWUoKSB7XHJcbiAgICBpZiAodGhpcy5jYW5JbmNyZWFzZSgpKSB7XHJcbiAgICAgIGlmICh0aGlzLmFsbG93RW1wdHkgJiYgKHRoaXMudmFsdWUgPT09IG51bGwgfHwgdGhpcy52YWx1ZSA9PT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICAgIHRoaXMudXBkYXRlVmFsdWUodGhpcy5taW4pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGRlY2ltYWxzID0gdGhpcy5nZXRNYXhEZWNpbWFscyh0aGlzLnZhbHVlKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZVZhbHVlKHBhcnNlRmxvYXQoKHRoaXMudmFsdWUgKyB0aGlzLnN0ZXApLnRvRml4ZWQoZGVjaW1hbHMpKSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZGVjcmVhc2VWYWx1ZSgpIHtcclxuICAgIGlmICh0aGlzLmNhbkRlY3JlYXNlKCkpIHtcclxuICAgICAgaWYgKHRoaXMuYWxsb3dFbXB0eSAmJiAodGhpcy52YWx1ZSA9PT0gbnVsbCB8fCB0aGlzLnZhbHVlID09PSB1bmRlZmluZWQpKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVWYWx1ZSh0aGlzLm1pbik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZGVjaW1hbHMgPSB0aGlzLmdldE1heERlY2ltYWxzKHRoaXMudmFsdWUpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlVmFsdWUocGFyc2VGbG9hdCgodGhpcy52YWx1ZSAtIHRoaXMuc3RlcCkudG9GaXhlZChkZWNpbWFscykpKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjYW5JbmNyZWFzZSgpIHtcclxuICAgIGlmICh0aGlzLmFsbG93RW1wdHkgJiYgKHRoaXMudmFsdWUgPT09IG51bGwgfHwgdGhpcy52YWx1ZSA9PT0gdW5kZWZpbmVkKSkge1xyXG4gICAgICByZXR1cm4gKHRoaXMubWluICsgdGhpcy5zdGVwKSA8PSB0aGlzLm1heDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAodGhpcy52YWx1ZSArIHRoaXMuc3RlcCkgPD0gdGhpcy5tYXg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNhbkRlY3JlYXNlKCkge1xyXG4gICAgaWYgKHRoaXMuYWxsb3dFbXB0eSAmJiAodGhpcy52YWx1ZSA9PT0gbnVsbCB8fCB0aGlzLnZhbHVlID09PSB1bmRlZmluZWQpKSB7XHJcbiAgICAgIHJldHVybiAodGhpcy5taW4gKyB0aGlzLnN0ZXApIDw9IHRoaXMubWF4O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuICh0aGlzLnZhbHVlIC0gdGhpcy5zdGVwKSA+PSB0aGlzLm1pbjtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgdG9nZ2xlRGlzYWJsZWQoZGlzYWJsZWQ6IGJvb2xlYW4pIHtcclxuICAgIGlmIChkaXNhYmxlZCkge1xyXG4gICAgICB0aGlzLnVuc3Vic2NyaWJlQWN0aW9ucygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zdWJzY3JpYmVBY3Rpb25zKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBlbnN1cmVWYWx1ZUlzVmFsaWQoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuXHJcbiAgICBjb25zdCBuZXdWYWx1ZSA9IGV2ZW50LnRhcmdldFsndmFsdWUnXTtcclxuICAgIGNvbnN0IHBhcnNlVmFsdWUgPSBwYXJzZUZsb2F0KG5ld1ZhbHVlIGFzIHN0cmluZyk7XHJcbiAgICBpZiAodGhpcy5hbGxvd0VtcHR5ICYmIG5ld1ZhbHVlID09PSAnJykge1xyXG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlKHRoaXMuZW5zdXJlVmFsdWVJblJhbmdlKG51bGwpKTtcclxuICAgIH0gZWxzZSBpZiAoIWlzTmFOKHBhcnNlVmFsdWUpKSB7XHJcbiAgICAgIHRoaXMudXBkYXRlVmFsdWUodGhpcy5lbnN1cmVWYWx1ZUluUmFuZ2UocGFyc2VWYWx1ZSkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy51cGRhdGVWYWx1ZSh0aGlzLmVuc3VyZVZhbHVlSW5SYW5nZSh0aGlzLnZhbHVlKSk7XHJcbiAgICB9XHJcblxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja1JhbmdlVmFsdWVzKG1pblZhbHVlLCBtYXhWYWx1ZSkge1xyXG4gICAgaWYgKG1heFZhbHVlIDwgbWluVmFsdWUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtYXggdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbWluIHZhbHVlYCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldERlY2ltYWxzKHZhbHVlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgY29uc3QgdmFsdWVTdHJpbmcgPSB2YWx1ZS50b1N0cmluZygpO1xyXG4gICAgY29uc3QgaW50ZWdlckxlbmd0aCA9IHZhbHVlU3RyaW5nLmluZGV4T2YoJy4nKSArIDE7XHJcbiAgICByZXR1cm4gaW50ZWdlckxlbmd0aCA+PSAwID8gdmFsdWVTdHJpbmcubGVuZ3RoIC0gaW50ZWdlckxlbmd0aCA6IDA7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldE1heERlY2ltYWxzKGN1cnJlbnRWYWx1ZSkge1xyXG4gICAgY29uc3Qgc3RlcFByZWNpc2lvbiA9IHRoaXMuZ2V0RGVjaW1hbHModGhpcy5zdGVwKTtcclxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZVByZWNpc2lvbiA9IHRoaXMuZ2V0RGVjaW1hbHMoY3VycmVudFZhbHVlIGFzIG51bWJlcik7XHJcbiAgICBpZiAoIWN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICByZXR1cm4gc3RlcFByZWNpc2lvbjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLmRlY2ltYWxMaW1pdCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZGVjaW1hbExpbWl0ICE9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRlY2ltYWxMaW1pdDtcclxuICAgIH1cclxuICAgIHJldHVybiBNYXRoLm1heChjdXJyZW50VmFsdWVQcmVjaXNpb24sIHN0ZXBQcmVjaXNpb24pO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdElucHV0KGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICBsZXQgdmFsdWUgPSBldmVudC50YXJnZXRbJ3ZhbHVlJ107XHJcbiAgICBjb25zdCBpbnB1dCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZXZlbnQud2hpY2gpO1xyXG4gICAgY29uc3Qgc2VsZWN0aW9uU3RhcnQgPSBldmVudC50YXJnZXRbJ3NlbGVjdGlvblN0YXJ0J107XHJcbiAgICBjb25zdCBzZWxlY3Rpb25FbmQgPSBldmVudC50YXJnZXRbJ3NlbGVjdGlvbkVuZCddO1xyXG4gICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoMCwgc2VsZWN0aW9uU3RhcnQpICsgaW5wdXQgKyB2YWx1ZS5zdWJzdHJpbmcoc2VsZWN0aW9uRW5kKTtcclxuICAgIGlmICh0aGlzLm1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiB0aGlzLm1heExlbmd0aCkge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5yZWcgJiYgIXZhbHVlLm1hdGNoKG5ldyBSZWdFeHAodGhpcy5yZWcpKSkge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICB2YWx1ZSA9PT0gJy0nIHx8IHZhbHVlLm1hdGNoKC9eXFxzKigtfFxcKyk/XFxkK1xcLiQvKSB8fCB2YWx1ZS5tYXRjaCgvXlxccyooLXxcXCspP1xcZCtcXC5bMC05XSowJC8pIHx8IHZhbHVlLm1hdGNoKC9eXFxzKigtfFxcKykwKyQvKVxyXG4gICAgKSB7XHJcbiAgICAgIC8vIGluZGV0ZXJtaW5hdGUgc3RhdGVcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfSBlbHNlIGlmICh2YWx1ZS5tYXRjaCgvXlxccyooLXxcXCspPyhcXGQrfChcXGQqKFxcLlxcZCopKSkkLykpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmRlY2ltYWxMaW1pdCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZGVjaW1hbExpbWl0ICE9