UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

470 lines 40.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* * @license * Copyright Akveo. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { Component, Input, Output, EventEmitter, HostBinding, Inject, } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { takeWhile, filter, map } from 'rxjs/operators'; import { NbMenuInternalService, NbMenuService } from './menu.service'; import { convertToBoolProperty } from '../helpers'; import { NB_WINDOW } from '../../theme.options'; import { animate, state, style, transition, trigger } from '@angular/animations'; /** @enum {string} */ const NbToggleStates = { Expanded: 'expanded', Collapsed: 'collapsed', }; export { NbToggleStates }; export class NbMenuItemComponent { /** * @param {?} menuService */ constructor(menuService) { this.menuService = menuService; this.menuItem = (/** @type {?} */ (null)); this.hoverItem = new EventEmitter(); this.toggleSubMenu = new EventEmitter(); this.selectItem = new EventEmitter(); this.itemClick = new EventEmitter(); this.alive = true; } /** * @return {?} */ ngDoCheck() { this.toggleState = this.menuItem.expanded ? NbToggleStates.Expanded : NbToggleStates.Collapsed; } /** * @return {?} */ ngAfterViewInit() { this.menuService.onSubmenuToggle() .pipe(takeWhile(() => this.alive), filter(({ item }) => item === this.menuItem), map(({ item }) => item.expanded)) .subscribe(isExpanded => this.toggleState = isExpanded ? NbToggleStates.Expanded : NbToggleStates.Collapsed); } /** * @return {?} */ ngOnDestroy() { this.alive = false; } /** * @param {?} item * @return {?} */ onToggleSubMenu(item) { this.toggleSubMenu.emit(item); } /** * @param {?} item * @return {?} */ onHoverItem(item) { this.hoverItem.emit(item); } /** * @param {?} item * @return {?} */ onSelectItem(item) { this.selectItem.emit(item); } /** * @param {?} item * @return {?} */ onItemClick(item) { this.itemClick.emit(item); } } NbMenuItemComponent.decorators = [ { type: Component, args: [{ selector: '[nbMenuItem]', template: "<span *ngIf=\"menuItem.group\">\r\n <i class=\"menu-icon {{ menuItem.icon }}\" *ngIf=\"menuItem.icon\"></i>\r\n {{ menuItem.title }}\r\n</span>\r\n<a *ngIf=\"menuItem.link && !menuItem.url && !menuItem.children && !menuItem.group\"\r\n [routerLink]=\"menuItem.link\"\r\n [queryParams]=\"menuItem.queryParams\"\r\n [fragment]=\"menuItem.fragment\"\r\n [attr.target]=\"menuItem.target\"\r\n [attr.title]=\"menuItem.title\"\r\n [class.active]=\"menuItem.selected\"\r\n (mouseenter)=\"onHoverItem(menuItem)\"\r\n (click)=\"onItemClick(menuItem);\">\r\n <i class=\"menu-icon {{ menuItem.icon }}\" *ngIf=\"menuItem.icon\"></i>\r\n <span class=\"menu-title\">{{ menuItem.title }}</span>\r\n</a>\r\n<a *ngIf=\"menuItem.url && !menuItem.children && !menuItem.link && !menuItem.group\"\r\n [attr.href]=\"menuItem.url\"\r\n [attr.target]=\"menuItem.target\"\r\n [attr.title]=\"menuItem.title\"\r\n [class.active]=\"menuItem.selected\"\r\n (mouseenter)=\"onHoverItem(menuItem)\"\r\n (click)=\"onSelectItem(menuItem)\">\r\n <i class=\"menu-icon {{ menuItem.icon }}\" *ngIf=\"menuItem.icon\"></i>\r\n <span class=\"menu-title\">{{ menuItem.title }}</span>\r\n</a>\r\n<a *ngIf=\"!menuItem.children && !menuItem.link && !menuItem.url && !menuItem.group\"\r\n [attr.target]=\"menuItem.target\"\r\n [attr.title]=\"menuItem.title\"\r\n [class.active]=\"menuItem.selected\"\r\n (mouseenter)=\"onHoverItem(menuItem)\"\r\n (click)=\"$event.preventDefault(); onItemClick(menuItem);\">\r\n <i class=\"menu-icon {{ menuItem.icon }}\" *ngIf=\"menuItem.icon\"></i>\r\n <span class=\"menu-title\">{{ menuItem.title }}</span>\r\n</a>\r\n<a *ngIf=\"menuItem.children\"\r\n (click)=\"$event.preventDefault(); onToggleSubMenu(menuItem);\"\r\n [attr.target]=\"menuItem.target\"\r\n [attr.title]=\"menuItem.title\"\r\n [class.active]=\"menuItem.selected\"\r\n (mouseenter)=\"onHoverItem(menuItem)\"\r\n href=\"#\">\r\n <i class=\"menu-icon {{ menuItem.icon }}\" *ngIf=\"menuItem.icon\"></i>\r\n <span class=\"menu-title\">{{ menuItem.title }}</span>\r\n <i class=\"ion chevron\" [class.ion-chevron-left]=\"!menuItem.expanded\"\r\n [class.ion-chevron-down]=\"menuItem.expanded\"></i>\r\n</a>\r\n<ul *ngIf=\"menuItem.children\"\r\n [class.collapsed]=\"!(menuItem.children && menuItem.expanded)\"\r\n [class.expanded]=\"menuItem.expanded\"\r\n [@toggle]=\"toggleState\"\r\n class=\"menu-items\">\r\n <ng-container *ngFor=\"let item of menuItem.children\">\r\n <li nbMenuItem *ngIf=\"!item.hidden\"\r\n [menuItem]=\"item\"\r\n [class.menu-group]=\"item.group\"\r\n (hoverItem)=\"onHoverItem($event)\"\r\n (toggleSubMenu)=\"onToggleSubMenu($event)\"\r\n (selectItem)=\"onSelectItem($event)\"\r\n (itemClick)=\"onItemClick($event)\"\r\n class=\"menu-item\">\r\n </li>\r\n </ng-container>\r\n</ul>\r\n", animations: [ trigger('toggle', [ state(NbToggleStates.Collapsed, style({ height: '0' })), state(NbToggleStates.Expanded, style({ height: '*' })), transition(`${NbToggleStates.Collapsed} <=> ${NbToggleStates.Expanded}`, animate(300)), ]), ] }] } ]; /** @nocollapse */ NbMenuItemComponent.ctorParameters = () => [ { type: NbMenuService } ]; NbMenuItemComponent.propDecorators = { menuItem: [{ type: Input }], hoverItem: [{ type: Output }], toggleSubMenu: [{ type: Output }], selectItem: [{ type: Output }], itemClick: [{ type: Output }] }; if (false) { /** @type {?} */ NbMenuItemComponent.prototype.menuItem; /** @type {?} */ NbMenuItemComponent.prototype.hoverItem; /** @type {?} */ NbMenuItemComponent.prototype.toggleSubMenu; /** @type {?} */ NbMenuItemComponent.prototype.selectItem; /** @type {?} */ NbMenuItemComponent.prototype.itemClick; /** * @type {?} * @private */ NbMenuItemComponent.prototype.alive; /** @type {?} */ NbMenuItemComponent.prototype.toggleState; /** * @type {?} * @private */ NbMenuItemComponent.prototype.menuService; } /* * Vertical menu component. * * Accepts a list of menu items and renders them accordingly. Supports multi-level menus. * * Basic example * @stacked-example(Showcase, menu/menu-showcase.component) * * ```ts * // ... * items: NbMenuItem[] = [ * { * title: home, * link: '/' * }, * { * title: dashboard, * link: 'dashboard' * } * ]; * // ... * <nb-menu [items]="items"></nb-menu> * ``` * ### Installation * * Import `NbMenuModule.forRoot()` to your app module. * ```ts * @NgModule({ * imports: [ * // ... * NbMenuModule.forRoot(), * ], * }) * export class AppModule { } * ``` * and `NbMenuModule` to your feature module where the component should be shown: * ```ts * @NgModule({ * imports: [ * // ... * NbMenuModule, * ], * }) * export class PageModule { } * ``` * ### Usage * * Two-level menu example * @stacked-example(Two Levels, menu/menu-children.component) * * @styles * * menu-font-family: * menu-font-size: * menu-font-weight: * menu-fg: * menu-bg: * menu-active-fg: * menu-active-bg: * menu-active-font-weight: * menu-submenu-bg: * menu-submenu-fg: * menu-submenu-active-fg: * menu-submenu-active-bg: * menu-submenu-active-border-color: * menu-submenu-active-shadow: * menu-submenu-hover-fg: * menu-submenu-hover-bg: * menu-submenu-item-border-width: * menu-submenu-item-border-radius: * menu-submenu-item-padding: * menu-submenu-item-container-padding: * menu-submenu-padding: * menu-group-font-weight: * menu-group-font-size: * menu-group-fg: * menu-group-padding * menu-item-padding: * menu-item-separator: * menu-icon-font-size: * menu-icon-margin: * menu-icon-color: * menu-icon-active-color: */ export class NbMenuComponent { /** * @param {?} window * @param {?} menuInternalService * @param {?} router */ constructor(window, menuInternalService, router) { this.window = window; this.menuInternalService = menuInternalService; this.router = router; this.alive = true; this.autoCollapseValue = false; } /* * Makes colors inverse based on current theme * @type boolean */ /** * @param {?} val * @return {?} */ set inverse(val) { this.inverseValue = convertToBoolProperty(val); } /* * Collapse all opened submenus on the toggle event * Default value is "false" * @type boolean */ /** * @param {?} val * @return {?} */ set autoCollapse(val) { this.autoCollapseValue = convertToBoolProperty(val); } /** * @return {?} */ ngOnInit() { this.menuInternalService.prepareItems(this.items); this.menuInternalService .onAddItem() .pipe(takeWhile(() => this.alive), filter((data) => this.compareTag(data.tag))) .subscribe(data => this.onAddItem(data)); this.menuInternalService .onNavigateHome() .pipe(takeWhile(() => this.alive), filter((data) => this.compareTag(data.tag))) .subscribe(() => this.navigateHome()); this.menuInternalService .onGetSelectedItem() .pipe(takeWhile(() => this.alive), filter((data) => this.compareTag(data.tag))) .subscribe((data) => { data.listener.next({ tag: this.tag, item: this.getSelectedItem(this.items) }); }); this.menuInternalService .onCollapseAll() .pipe(takeWhile(() => this.alive), filter((data) => this.compareTag(data.tag))) .subscribe(() => this.collapseAll()); this.router.events .pipe(takeWhile(() => this.alive), filter(event => event instanceof NavigationEnd)) .subscribe(() => { this.menuInternalService.selectFromUrl(this.items, this.tag, this.autoCollapseValue); }); } /** * @return {?} */ ngAfterViewInit() { setTimeout(() => this.menuInternalService.selectFromUrl(this.items, this.tag, this.autoCollapseValue)); } /** * @param {?} data * @return {?} */ onAddItem(data) { this.items.push(...data.items); this.menuInternalService.prepareItems(this.items); this.menuInternalService.selectFromUrl(this.items, this.tag, this.autoCollapseValue); } /** * @param {?} item * @return {?} */ onHoverItem(item) { this.menuInternalService.itemHover(item, this.tag); } /** * @param {?} item * @return {?} */ onToggleSubMenu(item) { if (this.autoCollapseValue) { this.menuInternalService.collapseAll(this.items, this.tag, item); } item.expanded = !item.expanded; this.menuInternalService.submenuToggle(item, this.tag); } // TODO: is not fired on page reload /** * @param {?} item * @return {?} */ onSelectItem(item) { this.menuInternalService.selectItem(item, this.items, this.autoCollapseValue, this.tag); } /** * @param {?} item * @return {?} */ onItemClick(item) { this.menuInternalService.itemClick(item, this.tag); } /** * @return {?} */ ngOnDestroy() { this.alive = false; } /** * @private * @return {?} */ navigateHome() { /** @type {?} */ const homeItem = this.getHomeItem(this.items); if (homeItem) { if (homeItem.link) { this.router.navigate([homeItem.link], { queryParams: homeItem.queryParams, fragment: homeItem.fragment }); } if (homeItem.url) { this.window.location.href = homeItem.url; } } } /** * @private * @return {?} */ collapseAll() { this.menuInternalService.collapseAll(this.items, this.tag); } /** * @private * @param {?} items * @return {?} */ getHomeItem(items) { for (const item of items) { if (item.home) { return item; } /** @type {?} */ const homeItem = item.children && this.getHomeItem(item.children); if (homeItem) { return homeItem; } } } /** * @private * @param {?} tag * @return {?} */ compareTag(tag) { return !tag || tag === this.tag; } /** * @private * @param {?} items * @return {?} */ getSelectedItem(items) { /** @type {?} */ let selected = null; items.forEach((item) => { if (item.selected) { selected = item; } if (item.selected && item.children && item.children.length > 0) { selected = this.getSelectedItem(item.children); } }); return selected; } } NbMenuComponent.decorators = [ { type: Component, args: [{ selector: 'nb-menu', template: ` <ul class="menu-items"> <ng-container *ngFor="let item of items"> <li nbMenuItem *ngIf="!item.hidden" [menuItem]="item" [class.menu-group]="item.group" (hoverItem)="onHoverItem($event)" (toggleSubMenu)="onToggleSubMenu($event)" (selectItem)="onSelectItem($event)" (itemClick)="onItemClick($event)" class="menu-item"> </li> </ng-container> </ul> `, styles: [":host /deep/{display:block}:host /deep/ .menu-item>.menu-items,:host /deep/ .menu-items{list-style-type:none;overflow:hidden}:host /deep/ .menu-item a{display:flex;color:inherit;text-decoration:none;align-items:center}:host /deep/ .menu-item a .menu-title{flex:1}[dir=rtl] :host /deep/ .menu-item a .menu-title{text-align:right}"] }] } ]; /** @nocollapse */ NbMenuComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [NB_WINDOW,] }] }, { type: NbMenuInternalService }, { type: Router } ]; NbMenuComponent.propDecorators = { inverseValue: [{ type: HostBinding, args: ['class.inverse',] }], tag: [{ type: Input }], items: [{ type: Input }], inverse: [{ type: Input }], autoCollapse: [{ type: Input }] }; if (false) { /** @type {?} */ NbMenuComponent.prototype.inverseValue; /** @type {?} */ NbMenuComponent.prototype.tag; /** @type {?} */ NbMenuComponent.prototype.items; /** * @type {?} * @private */ NbMenuComponent.prototype.alive; /** * @type {?} * @private */ NbMenuComponent.prototype.autoCollapseValue; /** * @type {?} * @private */ NbMenuComponent.prototype.window; /** * @type {?} * @private */ NbMenuComponent.prototype.menuInternalService; /** * @type {?} * @private */ NbMenuComponent.prototype.router; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9tZW51L21lbnUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQU1BLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBR1osV0FBVyxFQUVYLE1BQU0sR0FFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXhELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxxQkFBcUIsRUFBeUIsYUFBYSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0YsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7SUFHL0UsVUFBVyxVQUFVO0lBQ3JCLFdBQVksV0FBVzs7O0FBY3pCLE1BQU0sT0FBTyxtQkFBbUI7Ozs7SUFXOUIsWUFBb0IsV0FBMEI7UUFBMUIsZ0JBQVcsR0FBWCxXQUFXLENBQWU7UUFWckMsYUFBUSxHQUFHLG1CQUFZLElBQUksRUFBQSxDQUFDO1FBRTNCLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3BDLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN4QyxlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNyQyxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUV0QyxVQUFLLEdBQUcsSUFBSSxDQUFD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ICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFrdmVvLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIElucHV0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgT25Jbml0LFxyXG4gIE9uRGVzdHJveSxcclxuICBIb3N0QmluZGluZyxcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIEluamVjdCxcclxuICBEb0NoZWNrLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSb3V0ZXIsIE5hdmlnYXRpb25FbmQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVdoaWxlLCBmaWx0ZXIsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgTmJNZW51SW50ZXJuYWxTZXJ2aWNlLCBOYk1lbnVJdGVtLCBOYk1lbnVCYWcsIE5iTWVudVNlcnZpY2UgfSBmcm9tICcuL21lbnUuc2VydmljZSc7XHJcbmltcG9ydCB7IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSB9IGZyb20gJy4uL2hlbHBlcnMnO1xyXG5pbXBvcnQgeyBOQl9XSU5ET1cgfSBmcm9tICcuLi8uLi90aGVtZS5vcHRpb25zJztcclxuaW1wb3J0IHsgYW5pbWF0ZSwgc3RhdGUsIHN0eWxlLCB0cmFuc2l0aW9uLCB0cmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XHJcblxyXG5leHBvcnQgZW51bSBOYlRvZ2dsZVN0YXRlcyB7XHJcbiAgRXhwYW5kZWQgPSAnZXhwYW5kZWQnLFxyXG4gIENvbGxhcHNlZCA9ICdjb2xsYXBzZWQnLFxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ1tuYk1lbnVJdGVtXScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL21lbnUtaXRlbS5jb21wb25lbnQuaHRtbCcsXHJcbiAgYW5pbWF0aW9uczogW1xyXG4gICAgdHJpZ2dlcigndG9nZ2xlJywgW1xyXG4gICAgICBzdGF0ZShOYlRvZ2dsZVN0YXRlcy5Db2xsYXBzZWQsIHN0eWxlKHsgaGVpZ2h0OiAnMCcgfSkpLFxyXG4gICAgICBzdGF0ZShOYlRvZ2dsZVN0YXRlcy5FeHBhbmRlZCwgc3R5bGUoeyBoZWlnaHQ6ICcqJyB9KSksXHJcbiAgICAgIHRyYW5zaXRpb24oYCR7TmJUb2dnbGVTdGF0ZXMuQ29sbGFwc2VkfSA8PT4gJHtOYlRvZ2dsZVN0YXRlcy5FeHBhbmRlZH1gLCBhbmltYXRlKDMwMCkpLFxyXG4gICAgXSksXHJcbiAgXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5iTWVudUl0ZW1Db21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIG1lbnVJdGVtID0gPE5iTWVudUl0ZW0+bnVsbDtcclxuXHJcbiAgQE91dHB1dCgpIGhvdmVySXRlbSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIEBPdXRwdXQoKSB0b2dnbGVTdWJNZW51ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIHNlbGVjdEl0ZW0gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgaXRlbUNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIHByaXZhdGUgYWxpdmUgPSB0cnVlO1xyXG4gIHRvZ2dsZVN0YXRlOiBOYlRvZ2dsZVN0YXRlcztcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBtZW51U2VydmljZTogTmJNZW51U2VydmljZSkge31cclxuXHJcbiAgbmdEb0NoZWNrKCkge1xyXG4gICAgdGhpcy50b2dnbGVTdGF0ZSA9IHRoaXMubWVudUl0ZW0uZXhwYW5kZWQgPyBOYlRvZ2dsZVN0YXRlcy5FeHBhbmRlZCA6IE5iVG9nZ2xlU3RhdGVzLkNvbGxhcHNlZDtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHRoaXMubWVudVNlcnZpY2Uub25TdWJtZW51VG9nZ2xlKClcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZVdoaWxlKCgpID0+IHRoaXMuYWxpdmUpLFxyXG4gICAgICAgIGZpbHRlcigoeyBpdGVtIH0pID0+IGl0ZW0gPT09IHRoaXMubWVudUl0ZW0pLFxyXG4gICAgICAgIG1hcCgoeyBpdGVtIH06IE5iTWVudUJhZykgPT4gaXRlbS5leHBhbmRlZCksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZShpc0V4cGFuZGVkID0+IHRoaXMudG9nZ2xlU3RhdGUgPSBpc0V4cGFuZGVkID8gTmJUb2dnbGVTdGF0ZXMuRXhwYW5kZWQgOiBOYlRvZ2dsZVN0YXRlcy5Db2xsYXBzZWQpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmFsaXZlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBvblRvZ2dsZVN1Yk1lbnUoaXRlbTogTmJNZW51SXRlbSkge1xyXG4gICAgdGhpcy50b2dnbGVTdWJNZW51LmVtaXQoaXRlbSk7XHJcbiAgfVxyXG5cclxuICBvbkhvdmVySXRlbShpdGVtOiBOYk1lbnVJdGVtKSB7XHJcbiAgICB0aGlzLmhvdmVySXRlbS5lbWl0KGl0ZW0pO1xyXG4gIH1cclxuXHJcbiAgb25TZWxlY3RJdGVtKGl0ZW06IE5iTWVudUl0ZW0pIHtcclxuICAgIHRoaXMuc2VsZWN0SXRlbS5lbWl0KGl0ZW0pO1xyXG4gIH1cclxuXHJcbiAgb25JdGVtQ2xpY2soaXRlbTogTmJNZW51SXRlbSkge1xyXG4gICAgdGhpcy5pdGVtQ2xpY2suZW1pdChpdGVtKTtcclxuICB9XHJcbn1cclxuXHJcbi8qXHJcbiAqIFZlcnRpY2FsIG1lbnUgY29tcG9uZW50LlxyXG4gKlxyXG4gKiBBY2NlcHRzIGEgbGlzdCBvZiBtZW51IGl0ZW1zIGFuZCByZW5kZXJzIHRoZW0gYWNjb3JkaW5nbHkuIFN1cHBvcnRzIG11bHRpLWxldmVsIG1lbnVzLlxyXG4gKlxyXG4gKiBCYXNpYyBleGFtcGxlXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2hvd2Nhc2UsIG1lbnUvbWVudS1zaG93Y2FzZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqIGBgYHRzXHJcbiAqIC8vIC4uLlxyXG4gKiBpdGVtczogTmJNZW51SXRlbVtdID0gW1xyXG4gKiAge1xyXG4gKiAgICB0aXRsZTogaG9tZSxcclxuICogICAgbGluazogJy8nXHJcbiAqICB9LFxyXG4gKiAge1xyXG4gKiAgICB0aXRsZTogZGFzaGJvYXJkLFxyXG4gKiAgICBsaW5rOiAnZGFzaGJvYXJkJ1xyXG4gKiAgfVxyXG4gKiBdO1xyXG4gKiAvLyAuLi5cclxuICogPG5iLW1lbnUgW2l0ZW1zXT1cIml0ZW1zXCI+PC9uYi1tZW51PlxyXG4gKiBgYGBcclxuICogIyMjIEluc3RhbGxhdGlvblxyXG4gKlxyXG4gKiBJbXBvcnQgYE5iTWVudU1vZHVsZS5mb3JSb290KClgIHRvIHlvdXIgYXBwIG1vZHVsZS5cclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iTWVudU1vZHVsZS5mb3JSb290KCksXHJcbiAqICAgXSxcclxuICogfSlcclxuICogZXhwb3J0IGNsYXNzIEFwcE1vZHVsZSB7IH1cclxuICogYGBgXHJcbiAqIGFuZCBgTmJNZW51TW9kdWxlYCB0byB5b3VyIGZlYXR1cmUgbW9kdWxlIHdoZXJlIHRoZSBjb21wb25lbnQgc2hvdWxkIGJlIHNob3duOlxyXG4gKiBgYGB0c1xyXG4gKiBATmdNb2R1bGUoe1xyXG4gKiAgIGltcG9ydHM6IFtcclxuICogICBcdC8vIC4uLlxyXG4gKiAgICAgTmJNZW51TW9kdWxlLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBQYWdlTW9kdWxlIHsgfVxyXG4gKiBgYGBcclxuICogIyMjIFVzYWdlXHJcbiAqXHJcbiAqIFR3by1sZXZlbCBtZW51IGV4YW1wbGVcclxuICogQHN0YWNrZWQtZXhhbXBsZShUd28gTGV2ZWxzLCBtZW51L21lbnUtY2hpbGRyZW4uY29tcG9uZW50KVxyXG4gKlxyXG4gKiBAc3R5bGVzXHJcbiAqXHJcbiAqIG1lbnUtZm9udC1mYW1pbHk6XHJcbiAqIG1lbnUtZm9udC1zaXplOlxyXG4gKiBtZW51LWZvbnQtd2VpZ2h0OlxyXG4gKiBtZW51LWZnOlxyXG4gKiBtZW51LWJnOlxyXG4gKiBtZW51LWFjdGl2ZS1mZzpcclxuICogbWVudS1hY3RpdmUtYmc6XHJcbiAqIG1lbnUtYWN0aXZlLWZvbnQtd2VpZ2h0OlxyXG4gKiBtZW51LXN1Ym1lbnUtYmc6XHJcbiAqIG1lbnUtc3VibWVudS1mZzpcclxuICogbWVudS1zdWJtZW51LWFjdGl2ZS1mZzpcclxuICogbWVudS1zdWJtZW51LWFjdGl2ZS1iZzpcclxuICogbWVudS1zdWJtZW51LWFjdGl2ZS1ib3JkZXItY29sb3I6XHJcbiAqIG1lbnUtc3VibWVudS1hY3RpdmUtc2hhZG93OlxyXG4gKiBtZW51LXN1Ym1lbnUtaG92ZXItZmc6XHJcbiAqIG1lbnUtc3VibWVudS1ob3Zlci1iZzpcclxuICogbWVudS1zdWJtZW51LWl0ZW0tYm9yZGVyLXdpZHRoOlxyXG4gKiBtZW51LXN1Ym1lbnUtaXRlbS1ib3JkZXItcmFkaXVzOlxyXG4gKiBtZW51LXN1Ym1lbnUtaXRlbS1wYWRkaW5nOlxyXG4gKiBtZW51LXN1Ym1lbnUtaXRlbS1jb250YWluZXItcGFkZGluZzpcclxuICogbWVudS1zdWJtZW51LXBhZGRpbmc6XHJcbiAqIG1lbnUtZ3JvdXAtZm9udC13ZWlnaHQ6XHJcbiAqIG1lbnUtZ3JvdXAtZm9udC1zaXplOlxyXG4gKiBtZW51LWdyb3VwLWZnOlxyXG4gKiBtZW51LWdyb3VwLXBhZGRpbmdcclxuICogbWVudS1pdGVtLXBhZGRpbmc6XHJcbiAqIG1lbnUtaXRlbS1zZXBhcmF0b3I6XHJcbiAqIG1lbnUtaWNvbi1mb250LXNpemU6XHJcbiAqIG1lbnUtaWNvbi1tYXJnaW46XHJcbiAqIG1lbnUtaWNvbi1jb2xvcjpcclxuICogbWVudS1pY29uLWFjdGl2ZS1jb2xvcjpcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmItbWVudScsXHJcbiAgc3R5bGVVcmxzOiBbJy4vbWVudS5jb21wb25lbnQuc2NzcyddLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8dWwgY2xhc3M9XCJtZW51LWl0ZW1zXCI+XHJcbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIj5cclxuICAgICAgICA8bGkgbmJNZW51SXRlbSAqbmdJZj1cIiFpdGVtLmhpZGRlblwiXHJcbiAgICAgICAgICAgIFttZW51SXRlbV09XCJpdGVtXCJcclxuICAgICAgICAgICAgW2NsYXNzLm1lbnUtZ3JvdXBdPVwiaXRlbS5ncm91cFwiXHJcbiAgICAgICAgICAgIChob3Zlckl0ZW0pPVwib25Ib3Zlckl0ZW0oJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICh0b2dnbGVTdWJNZW51KT1cIm9uVG9nZ2xlU3ViTWVudSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgKHNlbGVjdEl0ZW0pPVwib25TZWxlY3RJdGVtKCRldmVudClcIlxyXG4gICAgICAgICAgICAoaXRlbUNsaWNrKT1cIm9uSXRlbUNsaWNrKCRldmVudClcIlxyXG4gICAgICAgICAgICBjbGFzcz1cIm1lbnUtaXRlbVwiPlxyXG4gICAgICAgIDwvbGk+XHJcbiAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgPC91bD5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmJNZW51Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaW52ZXJzZScpIGludmVyc2VWYWx1ZTogYm9vbGVhbjtcclxuXHJcbiAgLypcclxuICAgKiBUYWdzIGEgbWVudSB3aXRoIHNvbWUgSUQsIGNhbiBiZSBsYXRlciB1c2VkIGluIHRoZSBtZW51IHNlcnZpY2VcclxuICAgKiB0byBkZXRlcm1pbmUgd2hpY2ggbWVudSB0cmlnZ2VyZWQgdGhlIGFjdGlvbiwgaWYgbXVsdGlwbGUgbWVudXMgZXhpc3Qgb24gdGhlIHBhZ2UuXHJcbiAgICpcclxuICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHRhZzogc3RyaW5nO1xyXG5cclxuICAvKlxyXG4gICAqIExpc3Qgb2YgbWVudSBpdGVtcy5cclxuICAgKiBAdHlwZSBMaXN0PE5iTWVudUl0ZW0+IHwgTGlzdDxhbnk+IHwgYW55XHJcbiAgICovXHJcbiAgQElucHV0KCkgaXRlbXM6IE5iTWVudUl0ZW1bXTtcclxuXHJcbiAgLypcclxuICAgKiBNYWtlcyBjb2xvcnMgaW52ZXJzZSBiYXNlZCBvbiBjdXJyZW50IHRoZW1lXHJcbiAgICogQHR5cGUgYm9vbGVhblxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGludmVyc2UodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmludmVyc2VWYWx1ZSA9IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSh2YWwpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBDb2xsYXBzZSBhbGwgb3BlbmVkIHN1Ym1lbnVzIG9uIHRoZSB0b2dnbGUgZXZlbnRcclxuICAgKiBEZWZhdWx0IHZhbHVlIGlzIFwiZmFsc2VcIlxyXG4gICAqIEB0eXBlIGJvb2xlYW5cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBhdXRvQ29sbGFwc2UodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmF1dG9Db2xsYXBzZVZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFsaXZlOiBib29sZWFuID0gdHJ1ZTtcclxuICBwcml2YXRlIGF1dG9Db2xsYXBzZVZhbHVlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoTkJfV0lORE9XKSBwcml2YXRlIHdpbmRvdyxcclxuICAgICAgICAgICAgICBwcml2YXRlIG1lbnVJbnRlcm5hbFNlcnZpY2U6IE5iTWVudUludGVybmFsU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyKSB7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMubWVudUludGVybmFsU2VydmljZS5wcmVwYXJlSXRlbXModGhpcy5pdGVtcyk7XHJcblxyXG4gICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlXHJcbiAgICAgIC5vbkFkZEl0ZW0oKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSksXHJcbiAgICAgICAgZmlsdGVyKChkYXRhOiB7IHRhZzogc3RyaW5nOyBpdGVtczogTmJNZW51SXRlbVtdIH0pID0+IHRoaXMuY29tcGFyZVRhZyhkYXRhLnRhZykpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoZGF0YSA9PiB0aGlzLm9uQWRkSXRlbShkYXRhKSk7XHJcblxyXG4gICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlXHJcbiAgICAgIC5vbk5hdmlnYXRlSG9tZSgpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSxcclxuICAgICAgICBmaWx0ZXIoKGRhdGE6IHsgdGFnOiBzdHJpbmc7IGl0ZW1zOiBOYk1lbnVJdGVtW10gfSkgPT4gdGhpcy5jb21wYXJlVGFnKGRhdGEudGFnKSksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm5hdmlnYXRlSG9tZSgpKTtcclxuXHJcbiAgICB0aGlzLm1lbnVJbnRlcm5hbFNlcnZpY2VcclxuICAgICAgLm9uR2V0U2VsZWN0ZWRJdGVtKClcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZVdoaWxlKCgpID0+IHRoaXMuYWxpdmUpLFxyXG4gICAgICAgIGZpbHRlcigoZGF0YTogeyB0YWc6IHN0cmluZzsgbGlzdGVuZXI6IEJlaGF2aW9yU3ViamVjdDxOYk1lbnVCYWc+IH0pID0+IHRoaXMuY29tcGFyZVRhZyhkYXRhLnRhZykpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGE6IHsgdGFnOiBzdHJpbmc7IGxpc3RlbmVyOiBCZWhhdmlvclN1YmplY3Q8TmJNZW51QmFnPiB9KSA9PiB7XHJcbiAgICAgICAgZGF0YS5saXN0ZW5lci5uZXh0KHsgdGFnOiB0aGlzLnRhZywgaXRlbTogdGhpcy5nZXRTZWxlY3RlZEl0ZW0odGhpcy5pdGVtcykgfSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMubWVudUludGVybmFsU2VydmljZVxyXG4gICAgICAub25Db2xsYXBzZUFsbCgpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSxcclxuICAgICAgICBmaWx0ZXIoKGRhdGE6IHsgdGFnOiBzdHJpbmcgfSkgPT4gdGhpcy5jb21wYXJlVGFnKGRhdGEudGFnKSksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmNvbGxhcHNlQWxsKCkpO1xyXG5cclxuICAgIHRoaXMucm91dGVyLmV2ZW50c1xyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSksXHJcbiAgICAgICAgZmlsdGVyKGV2ZW50ID0+IGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlLnNlbGVjdEZyb21VcmwodGhpcy5pdGVtcywgdGhpcy50YWcsIHRoaXMuYXV0b0NvbGxhcHNlVmFsdWUpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlLnNlbGVjdEZyb21VcmwodGhpcy5pdGVtcywgdGhpcy50YWcsIHRoaXMuYXV0b0NvbGxhcHNlVmFsdWUpKTtcclxuICB9XHJcblxyXG4gIG9uQWRkSXRlbShkYXRhOiB7IHRhZzogc3RyaW5nOyBpdGVtczogTmJNZW51SXRlbVtdIH0pIHtcclxuICAgIHRoaXMuaXRlbXMucHVzaCguLi5kYXRhLml0ZW1zKTtcclxuXHJcbiAgICB0aGlzLm1lbnVJbnRlcm5hbFNlcnZpY2UucHJlcGFyZUl0ZW1zKHRoaXMuaXRlbXMpO1xyXG4gICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlLnNlbGVjdEZyb21VcmwodGhpcy5pdGVtcywgdGhpcy50YWcsIHRoaXMuYXV0b0NvbGxhcHNlVmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgb25Ib3Zlckl0ZW0oaXRlbTogTmJNZW51SXRlbSkge1xyXG4gICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlLml0ZW1Ib3ZlcihpdGVtLCB0aGlzLnRhZyk7XHJcbiAgfVxyXG5cclxuICBvblRvZ2dsZVN1Yk1lbnUoaXRlbTogTmJNZW51SXRlbSkge1xyXG4gICAgaWYgKHRoaXMuYXV0b0NvbGxhcHNlVmFsdWUpIHtcclxuICAgICAgdGhpcy5tZW51SW50ZXJuYWxTZXJ2aWNlLmNvbGxhcHNlQWxsKHRoaXMuaXRlbXMsIHRoaXMudGFnLCBpdGVtKTtcclxuICAgIH1cclxuICAgIGl0ZW0uZXhwYW5kZWQgPSAhaXRlbS5leHBhbmRlZDtcclxuICAgIHRoaXMubWVudUludGVybmFsU2VydmljZS5zdWJtZW51VG9nZ2xlKGl0ZW0sIHRoaXMudGFnKTtcclxuICB9XHJcblxyXG4gIC8vIFRPRE86IGlzIG5vdCBmaXJlZCBvbiBwYWdlIHJlbG9hZFxyXG4gIG9uU2VsZWN0SXRlbShpdGVtOiBOYk1lbnVJdGVtKSB7XHJcbiAgICB0aGlzLm1lbnVJbnRlcm5hbFNlcnZpY2Uuc2VsZWN0SXRlbShpdGVtLCB0aGlzLml0ZW1zLCB0aGlzLmF1dG9Db2xsYXBzZVZhbHVlLCB0aGlzLnRhZyk7XHJcbiAgfVxyXG5cclxuICBvbkl0ZW1DbGljayhpdGVtOiBOYk1lbnVJdGVtKSB7XHJcbiAgICB0aGlzLm1lbnVJbnRlcm5hbFNlcnZpY2UuaXRlbUNsaWNrKGl0ZW0sIHRoaXMudGFnKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5hbGl2ZSA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBuYXZpZ2F0ZUhvbWUoKSB7XHJcbiAgICBjb25zdCBob21lSXRlbSA9IHRoaXMuZ2V0SG9tZUl0ZW0odGhpcy5pdGVtcyk7XHJcblxyXG4gICAgaWYgKGhvbWVJdGVtKSB7XHJcbiAgICAgIGlmIChob21lSXRlbS5saW5rKSB7XHJcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW2hvbWVJdGVtLmxpbmtdLCB7IHF1ZXJ5UGFyYW1zOiBob21lSXRlbS5xdWVyeVBhcmFtcywgZnJhZ21lbnQ6IGhvbWVJdGVtLmZyYWdtZW50IH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaG9tZUl0ZW0udXJsKSB7XHJcbiAgICAgICAgdGhpcy53aW5kb3cubG9jYXRpb24uaHJlZiA9IGhvbWVJdGVtLnVybDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb2xsYXBzZUFsbCgpIHtcclxuICAgIHRoaXMubWVudUludGVybmFsU2VydmljZS5jb2xsYXBzZUFsbCh0aGlzLml0ZW1zLCB0aGlzLnRhZyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldEhvbWVJdGVtKGl0ZW1zOiBOYk1lbnVJdGVtW10pOiBOYk1lbnVJdGVtIHtcclxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xyXG4gICAgICBpZiAoaXRlbS5ob21lKSB7XHJcbiAgICAgICAgcmV0dXJuIGl0ZW07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGhvbWVJdGVtID0gaXRlbS5jaGlsZHJlbiAmJiB0aGlzLmdldEhvbWVJdGVtKGl0ZW0uY2hpbGRyZW4pO1xyXG4gICAgICBpZiAoaG9tZUl0ZW0pIHtcclxuICAgICAgICByZXR1cm4gaG9tZUl0ZW07XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgY29tcGFyZVRhZyh0YWc6IHN0cmluZykge1xyXG4gICAgcmV0dXJuICF0YWcgfHwgdGFnID09PSB0aGlzLnRhZztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0U2VsZWN0ZWRJdGVtKGl0ZW1zOiBOYk1lbnVJdGVtW10pOiBOYk1lbnVJdGVtIHtcclxuICAgIGxldCBzZWxlY3RlZCA9IG51bGw7XHJcbiAgICBpdGVtcy5mb3JFYWNoKChpdGVtOiBOYk1lbnVJdGVtKSA9PiB7XHJcbiAgICAgIGlmIChpdGVtLnNlbGVjdGVkKSB7XHJcbiAgICAgICAgc2VsZWN0ZWQgPSBpdGVtO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChpdGVtLnNlbGVjdGVkICYmIGl0ZW0uY2hpbGRyZW4gJiYgaXRlbS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgc2VsZWN0ZWQgPSB0aGlzLmdldFNlbGVjdGVkSXRlbShpdGVtLmNoaWxkcmVuKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gc2VsZWN0ZWQ7XHJcbiAgfVxyXG59XHJcbiJdfQ==