theme-lib
Version:
This is a simple example Angular Library published to npm.
470 lines • 40.1 kB
JavaScript
/**
* @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==