UNPKG

@stratio/egeo

Version:
548 lines 44.1 kB
/** * @fileoverview added by tsickle * Generated from: lib/st-dropdown-menu/st-dropdown-menu.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; /* * © 2017 Stratio Big Data Inc., Sucursal en España. * * This software is licensed under the Apache License, Version 2.0. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the terms of the License for more details. * * SPDX-License-Identifier: Apache-2.0. */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2, ViewChild } from '@angular/core'; import { StPopOffset, StPopPlacement } from '../st-pop/st-pop.model'; import { ARROW_KEY_CODE, StDropDownMenuItem, StDropDownVisualMode } from './st-dropdown-menu.interface'; /** * \@description {Component} [Dropdown Menu] * This directive show a dropdown menu list in element that you attach * * * \@model * * [Menu items] {./st-dropdown-menu.interface.ts#StDropDownMenuItem} * * \@example * * {html} * * ``` * <st-dropdown-menu [items]="list" [active]="show" (change)="onChange(event)"> * <button class="button button-primary" (click)="show = !show">Show menu</button> * </st-dropdown-menu> * ``` */ var StDropdownMenuComponent = /** @class */ (function () { function StDropdownMenuComponent(el, cd, renderer) { this.el = el; this.cd = cd; this.renderer = renderer; /** * \@Input {boolean} [active=false] Show or hide list */ this.active = false; /** * \@Input {StDropDownMenuItem[] | StDropDownMenuGroup[]} [items=\[\]] List of items or groups of them to show in menu */ this.items = []; /* tslint:disable-next-line:max-line-length */ /** * \@Input {StPopPlacement} [placement=StPopPlacement.BOTTOM_START] Possible positions of menu with respect element to attach */ this.placement = StPopPlacement.BOTTOM_START; /** * \@Input {string} [emptyListMessage=''] Message to show in case of empty list */ this.emptyListMessage = ''; /** * \@Input {StDropDownMenuItem | undefined} [selectedItem=undefined] Define selected item without passing as property */ this.selectedItem = undefined; /** * \@Input {StDropDownMenuItem | undefined} [itemsBeforeScroll=undefined] Define selected item without passing as property */ this.itemsBeforeScroll = 8; /** * \@Input {boolean} [moveSelected=true] If true, move selected item to top in menu when open */ this.moveSelected = true; /** * \@Input {boolean} [styleSelected=true] If true, apply class selected to selected item */ this.styleSelected = true; /** * \@Input {boolean} [isLoading=true] If true, show loader at the end of the list */ this.isLoading = false; /** * \@Input {StPopOffset} [offset={x: 0 , y: 0}] For position with offset in x o y axis */ this.offset = { x: 0, y: 0 }; /** * \@Input {boolean} [openToLeft=false] For calculating all positions from the right corner */ this.openToLeft = false; /** * \@Input {StDropdownVisualMode} [visualMode=StDropDownVisualMode.OPTION_LIST] It is needed to specify the styles applied to the list. * By default is displayed as a normal option list */ this.visualMode = StDropDownVisualMode.OPTION_LIST; /** * \@Input {boolean} [keyBoardMove=false] It is needed to activate navigation through options using the keyboard */ this.keyBoardMove = false; /** * \@output {StDropDownMenuItem} [change] Event emitted when user select an item */ this.change = new EventEmitter(); /** * \@output {any} [scrollAtBottom] Event emitted when scroll reach the end of the list */ this.scrollAtBottom = new EventEmitter(); this.widthMenu = '0px'; this._itemHeight = 42; this._focusedOptionPos = -1; } /** * @return {?} */ StDropdownMenuComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this.keyBoardMove) { this._focusListenerFn = this.renderer.listen('document', 'keydown', this.arrowKeyListener.bind(this)); } }; Object.defineProperty(StDropdownMenuComponent.prototype, "componentId", { get: /** * @return {?} */ function () { /** @type {?} */ var id = ((/** @type {?} */ (this.el.nativeElement))).getAttribute('id'); return id !== undefined && id !== null ? id : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "menuId", { get: /** * @return {?} */ function () { return this.componentId !== null ? this.componentId + "-menu" : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "isItemGroup", { get: /** * @return {?} */ function () { return this.isDropDownGroup(this.items); }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "menuMaxHeight", { get: /** * @return {?} */ function () { return this.itemsBeforeScroll ? this._itemHeight * this.itemsBeforeScroll + "px" : null; }, enumerable: true, configurable: true }); Object.defineProperty(StDropdownMenuComponent.prototype, "listClasses", { get: /** * @return {?} */ function () { return { 'st-dropdown-menu': true, 'active': this.active, 'menu-list': this.displayAsMenuList() }; }, enumerable: true, configurable: true }); /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.getItemId = /** * @param {?} value * @return {?} */ function (value) { return this.componentId !== null && value !== undefined ? this.componentId + "-option-" + this.getItemValueMerged(value) : null; }; /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.isDropDownGroup = /** * @param {?} value * @return {?} */ function (value) { return value && value.length > 0 && ((/** @type {?} */ (value[0]))).title !== undefined; }; /** * @return {?} */ StDropdownMenuComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { this.updateWidth(); }; /** * @param {?} changes * @return {?} */ StDropdownMenuComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { var _this = this; if (changes && changes.active && changes.active.currentValue && this.selectedItem && this.moveSelected) { // Only can do this functionality with timeout because we need to wait for angular to load new DOM // with items before move scroll setTimeout((/** * @return {?} */ function () { if (_this.itemListElement) { /** @type {?} */ var parent_1 = _this.itemListElement.nativeElement; /** @type {?} */ var listOfElements = parent_1.getElementsByClassName('selected'); if (listOfElements && listOfElements.length > 0) { /** @type {?} */ var target = ((/** @type {?} */ (listOfElements.item(0)))); parent_1.scrollTop = target.offsetTop - parent_1.offsetTop; } } })); } else { if (changes && changes.active && !changes.active.currentValue) { this._focusedOptionPos = -1; } } }; /** * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.onChange = /** * @param {?} value * @return {?} */ function (value) { this.change.emit(value); }; /** * @return {?} */ StDropdownMenuComponent.prototype.onHandleScroll = /** * @return {?} */ function () { /** @type {?} */ var element = this.itemListElement.nativeElement; if (element.scrollHeight - element.scrollTop === element.clientHeight && !this.isLoading) { this.scrollAtBottom.emit(); } }; /** * @return {?} */ StDropdownMenuComponent.prototype.updateWidth = /** * @return {?} */ function () { var _this = this; /** @type {?} */ var button = this.buttonElement.nativeElement; setTimeout((/** * @return {?} */ function () { if (button.children && button.children.length > 0) { _this.widthMenu = button.children[0].getBoundingClientRect().width + 'px'; } else { _this.widthMenu = button.getBoundingClientRect().width + 'px'; } _this.cd.markForCheck(); })); }; /** * @return {?} */ StDropdownMenuComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { if (this._focusListenerFn) { this._focusListenerFn(); } }; /** * @private * @return {?} */ StDropdownMenuComponent.prototype.displayAsMenuList = /** * @private * @return {?} */ function () { return this.visualMode === StDropDownVisualMode.MENU_LIST; }; /** * @private * @param {?} value * @return {?} */ StDropdownMenuComponent.prototype.getItemValueMerged = /** * @private * @param {?} value * @return {?} */ function (value) { return value.toString().replace(/\s+/g, '_'); }; /** * @private * @return {?} */ StDropdownMenuComponent.prototype.getSelectedItemPosition = /** * @private * @return {?} */ function () { var _this = this; if (this.selectedItem && this.items) { /** @type {?} */ var _items_1 = []; if (this.isDropDownGroup(this.items)) { this.items.forEach((/** * @param {?} item * @return {?} */ function (item) { if (((/** @type {?} */ (item))).items) { _items_1.push.apply(_items_1, tslib_1.__spread(((/** @type {?} */ (item))).items)); } else { _items_1.push(((/** @type {?} */ (item)))); } })); } else { _items_1 = this.items; } return _items_1.findIndex((/** * @param {?} item * @return {?} */ function (item) { return item.value === _this.selectedItem.value; })); } else { return -1; } }; /** * @private * @param {?} e * @return {?} */ StDropdownMenuComponent.prototype.arrowKeyListener = /** * @private * @param {?} e * @return {?} */ function (e) { /** @type {?} */ var selectedItemPosition = this.getSelectedItemPosition(); if (selectedItemPosition > -1) { this._focusedOptionPos = selectedItemPosition; } /** @type {?} */ var nextFocus; if (e.code === ARROW_KEY_CODE.ARROW_DOWN || e.code === ARROW_KEY_CODE.ARROW_UP) { event.preventDefault(); /** @type {?} */ var options = this.el.nativeElement.querySelectorAll('.st-dropdown-menu-item'); nextFocus = e.code === ARROW_KEY_CODE.ARROW_DOWN || this._focusedOptionPos === -1 ? 1 : -1; this._focusedOptionPos = this._focusedOptionPos + nextFocus; if (this._focusedOptionPos < 0) { this._focusedOptionPos = options.length - 1; } else if (this._focusedOptionPos > options.length - 1) { this._focusedOptionPos = 0; } if (options[this._focusedOptionPos]) { options[this._focusedOptionPos].focus(); } } this.cd.markForCheck(); }; StDropdownMenuComponent.decorators = [ { type: Component, args: [{ selector: 'st-dropdown-menu', template: "<!--\n\n \u00A9 2017 Stratio Big Data Inc., Sucursal en Espa\u00F1a.\n\n This software is licensed under the Apache License, Version 2.0.\n This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n See the terms of the License for more details.\n\n SPDX-License-Identifier: Apache-2.0.\n\n-->\n<st-pop [hidden]=\"!active\" [placement]=\"placement\" [offset]=\"offset\" [openToLeft]=\"openToLeft\">\n\n <div pop-button #buttonId>\n <ng-content></ng-content>\n </div>\n\n <div pop-content [style.z-index]=\"9\" class=\"dropdown-content\">\n\n <div *ngIf=\"active\" [ngClass]=\"listClasses\" [style.minWidth]='widthMenu'>\n <ng-content select=[dropdown-header]></ng-content>\n <ul *ngIf=\"!isItemGroup && ((items && items.length) || emptyListMessage)\" [attr.aria-hidden]=\"!active\"\n aria-label=\"submenu\" [style.maxHeight]=\"menuMaxHeight\"\n [attr.id]=\"menuId\" #itemList\n (scroll)=\"onHandleScroll()\">\n <st-dropdown-menu-item\n *ngFor=\"let item of items; let i = index\"\n [attr.id]=\"getItemId(item.value)\"\n [index]=\"i\"\n [item]=\"item\"\n [selectedItem]=\"selectedItem\"\n [styleSelected]=\"styleSelected\"\n (change)=\"onChange($event)\">\n </st-dropdown-menu-item>\n <div *ngIf=\"isLoading\" class=\"spinner-container\">\n <st-spinner class=\"spinner\"></st-spinner>\n </div>\n <div *ngIf=\"!items || !items.length\" class=\"without-results st-dropdown-menu-without-results\"\n [style.maxWidth]='widthMenu'>\n {{emptyListMessage}}\n </div>\n </ul>\n\n <div *ngIf=\"isItemGroup\">\n <ul [attr.aria-hidden]=\"!active\" aria-label=\"submenu\" [style.maxHeight]=\"menuMaxHeight\"\n [attr.id]=\"menuId\" #itemList>\n <li class=\"st-dropdown-menu-parent\" *ngFor=\"let group of items\">\n <h3>\n <span>{{ group.title }}</span>\n </h3>\n <ul>\n <st-dropdown-menu-item\n *ngFor=\"let item of group.items || []; let i = index\"\n [attr.id]=\"getItemId(item.value)\"\n [index]=\"i\"\n [item]=\"item\"\n [selectedItem]=\"selectedItem\"\n [styleSelected]=\"styleSelected\"\n (change)=\"onChange($event)\">\n </st-dropdown-menu-item>\n\n <div class=\"without-results st-dropdown-menu-without-results\" [style.maxWidth]='widthMenu'\n *ngIf=\"!group || !group.items || !group.items.length\">\n {{emptyListMessage}}\n </div>\n </ul>\n </li>\n <div *ngIf=\"isLoading\" class=\"spinner-container\">\n <st-spinner class=\"spinner\"></st-spinner>\n </div>\n </ul>\n </div>\n <ng-content select=[dropdown-footer]></ng-content>\n </div>\n </div>\n</st-pop>\n", changeDetection: ChangeDetectionStrategy.OnPush }] } ]; /** @nocollapse */ StDropdownMenuComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: Renderer2 } ]; }; StDropdownMenuComponent.propDecorators = { active: [{ type: Input }], items: [{ type: Input }], placement: [{ type: Input }], emptyListMessage: [{ type: Input }], selectedItem: [{ type: Input }], itemsBeforeScroll: [{ type: Input }], moveSelected: [{ type: Input }], styleSelected: [{ type: Input }], isLoading: [{ type: Input }], offset: [{ type: Input }], openToLeft: [{ type: Input }], visualMode: [{ type: Input }], keyBoardMove: [{ type: Input }], change: [{ type: Output }], scrollAtBottom: [{ type: Output }], buttonElement: [{ type: ViewChild, args: ['buttonId', { static: false },] }], itemListElement: [{ type: ViewChild, args: ['itemList', { static: false },] }], updateWidth: [{ type: HostListener, args: ['window:resize',] }, { type: HostListener, args: ['window:load',] }] }; return StDropdownMenuComponent; }()); export { StDropdownMenuComponent }; if (false) { /** * \@Input {boolean} [active=false] Show or hide list * @type {?} */ StDropdownMenuComponent.prototype.active; /** * \@Input {StDropDownMenuItem[] | StDropDownMenuGroup[]} [items=\[\]] List of items or groups of them to show in menu * @type {?} */ StDropdownMenuComponent.prototype.items; /** * \@Input {StPopPlacement} [placement=StPopPlacement.BOTTOM_START] Possible positions of menu with respect element to attach * @type {?} */ StDropdownMenuComponent.prototype.placement; /** * \@Input {string} [emptyListMessage=''] Message to show in case of empty list * @type {?} */ StDropdownMenuComponent.prototype.emptyListMessage; /** * \@Input {StDropDownMenuItem | undefined} [selectedItem=undefined] Define selected item without passing as property * @type {?} */ StDropdownMenuComponent.prototype.selectedItem; /** * \@Input {StDropDownMenuItem | undefined} [itemsBeforeScroll=undefined] Define selected item without passing as property * @type {?} */ StDropdownMenuComponent.prototype.itemsBeforeScroll; /** * \@Input {boolean} [moveSelected=true] If true, move selected item to top in menu when open * @type {?} */ StDropdownMenuComponent.prototype.moveSelected; /** * \@Input {boolean} [styleSelected=true] If true, apply class selected to selected item * @type {?} */ StDropdownMenuComponent.prototype.styleSelected; /** * \@Input {boolean} [isLoading=true] If true, show loader at the end of the list * @type {?} */ StDropdownMenuComponent.prototype.isLoading; /** * \@Input {StPopOffset} [offset={x: 0 , y: 0}] For position with offset in x o y axis * @type {?} */ StDropdownMenuComponent.prototype.offset; /** * \@Input {boolean} [openToLeft=false] For calculating all positions from the right corner * @type {?} */ StDropdownMenuComponent.prototype.openToLeft; /** * \@Input {StDropdownVisualMode} [visualMode=StDropDownVisualMode.OPTION_LIST] It is needed to specify the styles applied to the list. * By default is displayed as a normal option list * @type {?} */ StDropdownMenuComponent.prototype.visualMode; /** * \@Input {boolean} [keyBoardMove=false] It is needed to activate navigation through options using the keyboard * @type {?} */ StDropdownMenuComponent.prototype.keyBoardMove; /** * \@output {StDropDownMenuItem} [change] Event emitted when user select an item * @type {?} */ StDropdownMenuComponent.prototype.change; /** * \@output {any} [scrollAtBottom] Event emitted when scroll reach the end of the list * @type {?} */ StDropdownMenuComponent.prototype.scrollAtBottom; /** @type {?} */ StDropdownMenuComponent.prototype.buttonElement; /** @type {?} */ StDropdownMenuComponent.prototype.itemListElement; /** @type {?} */ StDropdownMenuComponent.prototype.widthMenu; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._itemHeight; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._focusedOptionPos; /** * @type {?} * @private */ StDropdownMenuComponent.prototype._focusListenerFn; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.el; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.cd; /** * @type {?} * @private */ StDropdownMenuComponent.prototype.renderer; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3QtZHJvcGRvd24tbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3RyYXRpby9lZ2VvLyIsInNvdXJjZXMiOlsibGliL3N0LWRyb3Bkb3duLW1lbnUvc3QtZHJvcGRvd24tbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQVVBLE9BQU8sRUFFSix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUNOLFNBQVMsRUFFVCxTQUFTLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRSxPQUFPLEVBQUUsY0FBYyxFQUF1QixrQkFBa0IsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFCN0g7SUFxREcsaUNBQW9CLEVBQWMsRUFBVSxFQUFxQixFQUFVLFFBQW1CO1FBQTFFLE9BQUUsR0FBRixFQUFFLENBQVk7UUFBVSxPQUFFLEdBQUYsRUFBRSxDQUFtQjtRQUFVLGFBQVEsR0FBUixRQUFRLENBQVc7Ozs7UUE3Q3JGLFdBQU0sR0FBWSxLQUFLLENBQUM7Ozs7UUFFeEIsVUFBSyxHQUFpRCxFQUFFLENBQUM7Ozs7O1FBR3pELGNBQVMsR0FBbUIsY0FBYyxDQUFDLFlBQVksQ0FBQzs7OztRQUV4RCxxQkFBZ0IsR0FBVyxFQUFFLENBQUM7Ozs7UUFFOUIsaUJBQVksR0FBdUIsU0FBUyxDQUFDOzs7O1FBRTdDLHNCQUFpQixHQUFXLENBQUMsQ0FBQzs7OztRQUU5QixpQkFBWSxHQUFZLElBQUksQ0FBQzs7OztRQUU3QixrQkFBYSxHQUFZLElBQUksQ0FBQzs7OztRQUU5QixjQUFTLEdBQVksS0FBSyxDQUFDOzs7O1FBRTNCLFdBQU0sR0FBZ0IsRUFBRSxD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QUFDLFVBQVUsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUM7a0NBQ3JDLFNBQVMsU0FBQyxVQUFVLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDOzhCQWtGckMsWUFBWSxTQUFDLGVBQWUsY0FDNUIsWUFBWSxTQUFDLGFBQWE7O0lBc0U5Qiw4QkFBQztDQUFBLEFBdE1ELElBc01DO1NBak1ZLHVCQUF1Qjs7Ozs7O0lBR2pDLHlDQUFpQzs7Ozs7SUFFakMsd0NBQWtFOzs7OztJQUdsRSw0Q0FBaUU7Ozs7O0lBRWpFLG1EQUF1Qzs7Ozs7SUFFdkMsK0NBQXNEOzs7OztJQUV0RCxvREFBdUM7Ozs7O0lBRXZDLCtDQUFzQzs7Ozs7SUFFdEMsZ0RBQXVDOzs7OztJQUV2Qyw0Q0FBb0M7Ozs7O0lBRXBDLHlDQUE4Qzs7Ozs7SUFFOUMsNkNBQXFDOzs7Ozs7SUFJckMsNkNBQTZFOzs7OztJQUc3RSwrQ0FBdUM7Ozs7O0lBR3ZDLHlDQUE0Rjs7Ozs7SUFHNUYsaURBQXNFOztJQUV0RSxnREFBa0U7O0lBQ2xFLGtEQUFvRTs7SUFFcEUsNENBQTBCOzs7OztJQUUxQiw4Q0FBaUM7Ozs7O0lBQ2pDLG9EQUF1Qzs7Ozs7SUFDdkMsbURBQXFDOzs7OztJQUV6QixxQ0FBc0I7Ozs7O0lBQUUscUNBQTZCOzs7OztJQUFFLDJDQUEyQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiDCqSAyMDE3IFN0cmF0aW8gQmlnIERhdGEgSW5jLiwgU3VjdXJzYWwgZW4gRXNwYcOxYS5cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZO1xuICogd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS5cbiAqIFNlZSB0aGUgdGVybXMgb2YgdGhlIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMC5cbiAqL1xuaW1wb3J0IHtcbiAgIEFmdGVyVmlld0luaXQsXG4gICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgQ29tcG9uZW50LFxuICAgRWxlbWVudFJlZixcbiAgIEV2ZW50RW1pdHRlcixcbiAgIEhvc3RMaXN0ZW5lcixcbiAgIElucHV0LFxuICAgT25DaGFuZ2VzLFxuICAgT25EZXN0cm95LFxuICAgT25Jbml0LFxuICAgT3V0cHV0LFxuICAgUmVuZGVyZXIyLFxuICAgU2ltcGxlQ2hhbmdlcyxcbiAgIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgU3RQb3BPZmZzZXQsIFN0UG9wUGxhY2VtZW50IH0gZnJvbSAnLi4vc3QtcG9wL3N0LXBvcC5tb2RlbCc7XG5pbXBvcnQgeyBBUlJPV19LRVlfQ09ERSwgU3REcm9wRG93bk1lbnVHcm91cCwgU3REcm9wRG93bk1lbnVJdGVtLCBTdERyb3BEb3duVmlzdWFsTW9kZSB9IGZyb20gJy4vc3QtZHJvcGRvd24tbWVudS5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiB7Q29tcG9uZW50fSBbRHJvcGRvd24gTWVudV1cbiAqIFRoaXMgZGlyZWN0aXZlIHNob3cgYSBkcm9wZG93biBtZW51IGxpc3QgaW4gZWxlbWVudCB0aGF0IHlvdSBhdHRhY2hcbiAqXG4gKlxuICogQG1vZGVsXG4gKlxuICogICBbTWVudSBpdGVtc10gey4vc3QtZHJvcGRvd24tbWVudS5pbnRlcmZhY2UudHMjU3REcm9wRG93bk1lbnVJdGVtfVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICoge2h0bWx9XG4gKlxuICogYGBgXG4gKiA8c3QtZHJvcGRvd24tbWVudSBbaXRlbXNdPVwibGlzdFwiIFthY3RpdmVdPVwic2hvd1wiIChjaGFuZ2UpPVwib25DaGFuZ2UoZXZlbnQpXCI+XG4gKiAgICA8YnV0dG9uIGNsYXNzPVwiYnV0dG9uIGJ1dHRvbi1wcmltYXJ5XCIgKGNsaWNrKT1cInNob3cgPSAhc2hvd1wiPlNob3cgbWVudTwvYnV0dG9uPlxuICogPC9zdC1kcm9wZG93bi1tZW51PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgc2VsZWN0b3I6ICdzdC1kcm9wZG93bi1tZW51JyxcbiAgIHRlbXBsYXRlVXJsOiAnLi9zdC1kcm9wZG93bi1tZW51LmNvbXBvbmVudC5odG1sJyxcbiAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFN0RHJvcGRvd25NZW51Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG5cbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFthY3RpdmU9ZmFsc2VdIFNob3cgb3IgaGlkZSBsaXN0ICovXG4gICBASW5wdXQoKSBhY3RpdmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgIC8qKiBASW5wdXQge1N0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdfSBbaXRlbXM9XFxbXFxdXSBMaXN0IG9mIGl0ZW1zIG9yIGdyb3VwcyBvZiB0aGVtIHRvIHNob3cgaW4gbWVudSAqL1xuICAgQElucHV0KCkgaXRlbXM6IFN0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdID0gW107XG4gICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoICovXG4gICAvKiogQElucHV0IHtTdFBvcFBsYWNlbWVudH0gW3BsYWNlbWVudD1TdFBvcFBsYWNlbWVudC5CT1RUT01fU1RBUlRdIFBvc3NpYmxlIHBvc2l0aW9ucyBvZiBtZW51IHdpdGggcmVzcGVjdCBlbGVtZW50IHRvIGF0dGFjaCAqL1xuICAgQElucHV0KCkgcGxhY2VtZW50OiBTdFBvcFBsYWNlbWVudCA9IFN0UG9wUGxhY2VtZW50LkJPVFRPTV9TVEFSVDtcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW2VtcHR5TGlzdE1lc3NhZ2U9JyddIE1lc3NhZ2UgdG8gc2hvdyBpbiBjYXNlIG9mIGVtcHR5IGxpc3QgKi9cbiAgIEBJbnB1dCgpIGVtcHR5TGlzdE1lc3NhZ2U6IHN0cmluZyA9ICcnO1xuICAgLyoqIEBJbnB1dCB7U3REcm9wRG93bk1lbnVJdGVtIHwgdW5kZWZpbmVkfSBbc2VsZWN0ZWRJdGVtPXVuZGVmaW5lZF0gRGVmaW5lIHNlbGVjdGVkIGl0ZW0gd2l0aG91dCBwYXNzaW5nIGFzIHByb3BlcnR5ICovXG4gICBASW5wdXQoKSBzZWxlY3RlZEl0ZW06IFN0RHJvcERvd25NZW51SXRlbSA9IHVuZGVmaW5lZDtcbiAgIC8qKiBASW5wdXQge1N0RHJvcERvd25NZW51SXRlbSB8IHVuZGVmaW5lZH0gW2l0ZW1zQmVmb3JlU2Nyb2xsPXVuZGVmaW5lZF0gRGVmaW5lIHNlbGVjdGVkIGl0ZW0gd2l0aG91dCBwYXNzaW5nIGFzIHByb3BlcnR5ICovXG4gICBASW5wdXQoKSBpdGVtc0JlZm9yZVNjcm9sbDogbnVtYmVyID0gODtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFttb3ZlU2VsZWN0ZWQ9dHJ1ZV0gSWYgdHJ1ZSwgbW92ZSBzZWxlY3RlZCBpdGVtIHRvIHRvcCBpbiBtZW51IHdoZW4gb3BlbiAqL1xuICAgQElucHV0KCkgbW92ZVNlbGVjdGVkOiBib29sZWFuID0gdHJ1ZTtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtzdHlsZVNlbGVjdGVkPXRydWVdIElmIHRydWUsIGFwcGx5IGNsYXNzIHNlbGVjdGVkIHRvIHNlbGVjdGVkIGl0ZW0gKi9cbiAgIEBJbnB1dCgpIHN0eWxlU2VsZWN0ZWQ6IGJvb2xlYW4gPSB0cnVlO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2lzTG9hZGluZz10cnVlXSBJZiB0cnVlLCBzaG93IGxvYWRlciBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0ICovXG4gICBASW5wdXQoKSBpc0xvYWRpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgIC8qKiBASW5wdXQge1N0UG9wT2Zmc2V0fSBbb2Zmc2V0PXt4OiAwICwgeTogMH1dIEZvciBwb3NpdGlvbiB3aXRoIG9mZnNldCBpbiB4IG8geSBheGlzICovXG4gICBASW5wdXQoKSBvZmZzZXQ6IFN0UG9wT2Zmc2V0ID0geyB4OiAwLCB5OiAwIH07XG4gICAvKiogQElucHV0IHtib29sZWFufSBbb3BlblRvTGVmdD1mYWxzZV0gRm9yIGNhbGN1bGF0aW5nIGFsbCBwb3NpdGlvbnMgZnJvbSB0aGUgcmlnaHQgY29ybmVyICovXG4gICBASW5wdXQoKSBvcGVuVG9MZWZ0OiBib29sZWFuID0gZmFsc2U7XG4gICAvKiogQElucHV0IHtTdERyb3Bkb3duVmlzdWFsTW9kZX0gW3Zpc3VhbE1vZGU9U3REcm9wRG93blZpc3VhbE1vZGUuT1BUSU9OX0xJU1RdIEl0IGlzIG5lZWRlZCB0byBzcGVjaWZ5IHRoZSBzdHlsZXMgYXBwbGllZCB0byB0aGUgbGlzdC5cbiAgICAqICBCeSBkZWZhdWx0IGlzIGRpc3BsYXllZCBhcyBhIG5vcm1hbCBvcHRpb24gbGlzdFxuICAgICovXG4gICBASW5wdXQoKSB2aXN1YWxNb2RlOiBTdERyb3BEb3duVmlzdWFsTW9kZSA9IFN0RHJvcERvd25WaXN1YWxNb2RlLk9QVElPTl9MSVNUO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2tleUJvYXJkTW92ZT1mYWxzZV0gSXQgaXMgbmVlZGVkIHRvIGFjdGl2YXRlIG5hdmlnYXRpb24gdGhyb3VnaCBvcHRpb25zIHVzaW5nIHRoZSBrZXlib2FyZFxuICAgICovXG4gICBASW5wdXQoKSBrZXlCb2FyZE1vdmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgLyoqIEBvdXRwdXQge1N0RHJvcERvd25NZW51SXRlbX0gW2NoYW5nZV0gRXZlbnQgZW1pdHRlZCB3aGVuIHVzZXIgc2VsZWN0IGFuIGl0ZW0gKi9cbiAgIEBPdXRwdXQoKSBjaGFuZ2U6IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+ID0gbmV3IEV2ZW50RW1pdHRlcjxTdERyb3BEb3duTWVudUl0ZW0+KCk7XG5cbiAgIC8qKiBAb3V0cHV0IHthbnl9IFtzY3JvbGxBdEJvdHRvbV0gRXZlbnQgZW1pdHRlZCB3aGVuIHNjcm9sbCByZWFjaCB0aGUgZW5kIG9mIHRoZSBsaXN0ICovXG4gICBAT3V0cHV0KCkgc2Nyb2xsQXRCb3R0b206IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgIEBWaWV3Q2hpbGQoJ2J1dHRvbklkJywge3N0YXRpYzogZmFsc2V9KSBidXR0b25FbGVtZW50OiBFbGVtZW50UmVmO1xuICAgQFZpZXdDaGlsZCgnaXRlbUxpc3QnLCB7c3RhdGljOiBmYWxzZX0pIGl0ZW1MaXN0RWxlbWVudDogRWxlbWVudFJlZjtcblxuICAgd2lkdGhNZW51OiBzdHJpbmcgPSAnMHB4JztcblxuICAgcHJpdmF0ZSBfaXRlbUhlaWdodDogbnVtYmVyID0gNDI7XG4gICBwcml2YXRlIF9mb2N1c2VkT3B0aW9uUG9zOiBudW1iZXIgPSAtMTtcbiAgIHByaXZhdGUgX2ZvY3VzTGlzdGVuZXJGbjogKCkgPT4gdm9pZDtcblxuICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZiwgcHJpdmF0ZSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMikge1xuICAgfVxuXG4gICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLmtleUJvYXJkTW92ZSkge1xuICAgICAgICAgdGhpcy5fZm9jdXNMaXN0ZW5lckZuID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oJ2RvY3VtZW50JywgJ2tleWRvd24nLCB0aGlzLmFycm93S2V5TGlzdGVuZXIuYmluZCh0aGlzKSk7XG4gICAgICB9XG4gICB9XG5cbiAgIGdldCBjb21wb25lbnRJZCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgIGNvbnN0IGlkID0gKHRoaXMuZWwubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgICAgcmV0dXJuIGlkICE9PSB1bmRlZmluZWQgJiYgaWQgIT09IG51bGwgPyBpZCA6IG51bGw7XG4gICB9XG5cbiAgIGdldCBtZW51SWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRJZCAhPT0gbnVsbCA/IGAke3RoaXMuY29tcG9uZW50SWR9LW1lbnVgIDogbnVsbDtcbiAgIH1cblxuICAgZ2V0IGlzSXRlbUdyb3VwKCk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuaXNEcm9wRG93bkdyb3VwKHRoaXMuaXRlbXMpO1xuICAgfVxuXG4gICBnZXQgbWVudU1heEhlaWdodCgpOiBzdHJpbmcge1xuICAgICAgcmV0dXJuIHRoaXMuaXRlbXNCZWZvcmVTY3JvbGwgPyBgJHt0aGlzLl9pdGVtSGVpZ2h0ICogdGhpcy5pdGVtc0JlZm9yZVNjcm9sbH1weGAgOiBudWxsO1xuICAgfVxuXG4gICBnZXQgbGlzdENsYXNzZXMoKTogYW55IHtcbiAgICAgIHJldHVybiB7ICdzdC1kcm9wZG93bi1tZW51JzogdHJ1ZSwgJ2FjdGl2ZSc6IHRoaXMuYWN0aXZlLCAnbWVudS1saXN0JzogdGhpcy5kaXNwbGF5QXNNZW51TGlzdCgpIH07XG4gICB9XG5cbiAgIGdldEl0ZW1JZCh2YWx1ZTogYW55IHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRJZCAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gYCR7dGhpcy5jb21wb25lbnRJZH0tb3B0aW9uLSR7dGhpcy5nZXRJdGVtVmFsdWVNZXJnZWQodmFsdWUpfWAgOiBudWxsO1xuICAgfVxuXG4gICBpc0Ryb3BEb3duR3JvdXAodmFsdWU6IFN0RHJvcERvd25NZW51SXRlbVtdIHwgU3REcm9wRG93bk1lbnVHcm91cFtdKTogdmFsdWUgaXMgU3REcm9wRG93bk1lbnVHcm91cFtdIHtcbiAgICAgIHJldHVybiB2YWx1ZSAmJiB2YWx1ZS5sZW5ndGggPiAwICYmICg8U3REcm9wRG93bk1lbnVHcm91cD52YWx1ZVswXSkudGl0bGUgIT09IHVuZGVmaW5lZDtcbiAgIH1cblxuICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgdGhpcy51cGRhdGVXaWR0aCgpO1xuICAgfVxuXG4gICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgICBpZiAoY2hhbmdlcyAmJiBjaGFuZ2VzLmFjdGl2ZSAmJiBjaGFuZ2VzLmFjdGl2ZS5jdXJyZW50VmFsdWUgJiYgdGhpcy5zZWxlY3RlZEl0ZW0gJiYgdGhpcy5tb3ZlU2VsZWN0ZWQpIHtcbiAgICAgICAgIC8vIE9ubHkgY2FuIGRvIHRoaXMgZnVuY3Rpb25hbGl0eSB3aXRoIHRpbWVvdXQgYmVjYXVzZSB3ZSBuZWVkIHRvIHdhaXQgZm9yIGFuZ3VsYXIgdG8gbG9hZCBuZXcgRE9NXG4gICAgICAgICAvLyB3aXRoIGl0ZW1zIGJlZm9yZSBtb3ZlIHNjcm9sbFxuICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pdGVtTGlzdEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudDogSFRNTEVsZW1lbnQgPSB0aGlzLml0ZW1MaXN0RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgICAgY29uc3QgbGlzdE9mRWxlbWVudHM6IGFueSA9IHBhcmVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdzZWxlY3RlZCcpO1xuICAgICAgICAgICAgICAgaWYgKGxpc3RPZkVsZW1lbnRzICYmIGxpc3RPZkVsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldDogSFRNTEVsZW1lbnQgPSAobGlzdE9mRWxlbWVudHMuaXRlbSgwKSBhcyBIVE1MRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICBwYXJlbnQuc2Nyb2xsVG9wID0gdGFyZ2V0Lm9mZnNldFRvcCAtIHBhcmVudC5vZmZzZXRUb3A7XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICBpZiAoY2hhbmdlcyAmJiBjaGFuZ2VzLmFjdGl2ZSAmJiAhY2hhbmdlcy5hY3RpdmUuY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9mb2N1c2VkT3B0aW9uUG9zID0gLTE7XG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIG9uQ2hhbmdlKHZhbHVlOiBTdERyb3BEb3duTWVudUl0ZW0pOiB2b2lkIHtcbiAgICAgIHRoaXMuY2hhbmdlLmVtaXQodmFsdWUpO1xuICAgfVxuXG4gICBvbkhhbmRsZVNjcm9sbCgpOiB2b2lkIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLml0ZW1MaXN0RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKGVsZW1lbnQuc2Nyb2xsSGVpZ2h0IC0gZWxlbWVudC5zY3JvbGxUb3AgPT09IGVsZW1lbnQuY2xpZW50SGVpZ2h0ICYmICF0aGlzLmlzTG9hZGluZykge1xuICAgICAgICAgdGhpcy5zY3JvbGxBdEJvdHRvbS5lbWl0KCk7XG4gICAgICB9XG4gICB9XG5cbiAgIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICAgQEhvc3RMaXN0ZW5lcignd2luZG93OmxvYWQnKVxuICAgdXBkYXRlV2lkdGgoKTogdm9pZCB7XG4gICAgICBjb25zdCBidXR0b246IEhUTUxFbGVtZW50ID0gdGhpcy5idXR0b25FbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgIGlmIChidXR0b24uY2hpbGRyZW4gJiYgYnV0dG9uLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGhNZW51ID0gYnV0dG9uLmNoaWxkcmVuWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoICsgJ3B4JztcbiAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLndpZHRoTWVudSA9IGJ1dHRvbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCArICdweCc7XG4gICAgICAgICB9XG4gICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgIH1cblxuICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5fZm9jdXNMaXN0ZW5lckZuKSB7XG4gICAgICAgICB0aGlzLl9mb2N1c0xpc3RlbmVyRm4oKTtcbiAgICAgIH1cbiAgIH1cblxuICAgcHJpdmF0ZSBkaXNwbGF5QXNNZW51TGlzdCgpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnZpc3VhbE1vZGUgPT09IFN0RHJvcERvd25WaXN1YWxNb2RlLk1FTlVfTElTVDtcbiAgIH1cblxuICAgcHJpdmF0ZSBnZXRJdGVtVmFsdWVNZXJnZWQodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKS5yZXBsYWNlKC9cXHMrL2csICdfJyk7XG4gICB9XG5cbiAgIHByaXZhdGUgZ2V0U2VsZWN0ZWRJdGVtUG9zaXRpb24oKTogbnVtYmVyIHtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkSXRlbSAmJiB0aGlzLml0ZW1zKSB7XG4gICAgICAgICBsZXQgX2l0ZW1zOiBTdERyb3BEb3duTWVudUl0ZW1bXSA9IFtdO1xuICAgICAgICAgaWYgKHRoaXMuaXNEcm9wRG93bkdyb3VwKHRoaXMuaXRlbXMpKSB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW06IFN0RHJvcERvd25NZW51SXRlbSB8IFN0RHJvcERvd25NZW51R3JvdXApID0+IHtcbiAgICAgICAgICAgICAgIGlmICgoPFN0RHJvcERvd25NZW51R3JvdXA+IGl0ZW0pLml0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICBfaXRlbXMucHVzaCguLi4oPFN0RHJvcERvd25NZW51R3JvdXA+IGl0ZW0pLml0ZW1zKTtcbiAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBfaXRlbXMucHVzaCgoPFN0RHJvcERvd25NZW51SXRlbT4gaXRlbSkpO1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgX2l0ZW1zID0gdGhpcy5pdGVtcztcbiAgICAgICAgIH1cbiAgICAgICAgIHJldHVybiBfaXRlbXMuZmluZEluZGV4KGl0ZW0gPT4gaXRlbS52YWx1ZSA9PT0gdGhpcy5zZWxlY3RlZEl0ZW0udmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgIH1cblxuICAgcHJpdmF0ZSBhcnJvd0tleUxpc3RlbmVyKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkSXRlbVBvc2l0aW9uID0gdGhpcy5nZXRTZWxlY3RlZEl0ZW1Qb3NpdGlvbigpO1xuICAgICAgaWYgKHNlbGVjdGVkSXRlbVBvc2l0aW9uID4gLTEpIHtcbiAgICAgICAgIHRoaXMuX2ZvY3VzZWRPcHRpb25Qb3MgPSBzZWxlY3RlZEl0ZW1Qb3NpdGlvbjtcbiAgICAgIH1cbiAgICAgIGxldCBuZXh0Rm9jdXM6IG51bWJlcjtcbiAgICAgIGlmIChlLmNvZGUgPT09IEFSUk9XX0tFWV9DT0RFLkFSUk9XX0RPV04gfHwgZS5jb2RlID09PSBBUlJPV19LRVlfQ09ERS5BUlJPV19VUCkge1xuICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgIGNvbnN0IG9wdGlvbnM6IEhUTUxMSUVsZW1lbnRbXSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuc3QtZHJvcGRvd24tbWVudS1pdGVtJyk7XG4gICAgICAgICBuZXh0Rm9jdXMgPSBlLmNvZGUgPT09IEFSUk9XX0tFWV9DT0RFLkFSUk9XX0RPV04gfHwgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9PT0gLTEgPyAxIDogLTE7XG4gICAgICAgICB0aGlzLl9mb2N1c2VkT3B0aW9uUG9zID0gdGhpcy5fZm9jdXNlZE9wdGlvblBvcyArIG5leHRGb2N1cztcbiAgICAgICAgIGlmICh0aGlzLl9mb2N1c2VkT3B0aW9uUG9zIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9IG9wdGlvbnMubGVuZ3RoIC0gMTtcbiAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fZm9jdXNlZE9wdGlvblBvcyA+IG9wdGlvbnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZE9wdGlvblBvcyA9IDA7XG4gICAgICAgICB9XG4gICAgICAgICBpZiAob3B0aW9uc1t0aGlzLl9mb2N1c2VkT3B0aW9uUG9zXSkge1xuICAgICAgICAgICAgb3B0aW9uc1t0aGlzLl9mb2N1c2VkT3B0aW9uUG9zXS5mb2N1cygpO1xuICAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgIH1cbn1cbiJdfQ==