UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

711 lines 63.5 kB
import { __decorate, __metadata } from "tslib"; import { CommonModule } from '@angular/common'; import { AfterContentInit, AfterViewChecked, AfterViewInit, Component, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, NgModule, Output, QueryList, TemplateRef, ViewChild, ViewChildren } from '@angular/core'; import { IgxBadgeModule } from '../badge/badge.component'; import { IgxIconModule } from '../icon/index'; let NEXT_ID = 0; let IgxTabTemplateDirective = class IgxTabTemplateDirective { constructor(template) { this.template = template; } }; IgxTabTemplateDirective.ctorParameters = () => [ { type: TemplateRef } ]; IgxTabTemplateDirective = __decorate([ Directive({ selector: '[igxTab]' }), __metadata("design:paramtypes", [TemplateRef]) ], IgxTabTemplateDirective); export { IgxTabTemplateDirective }; /** * **Ignite UI for Angular Tab Bar** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tabbar.html) * * The Ignite UI Tab Bar enables the user to navigate among a number of content panels displayed in a single view. * * Example: * ```html * <igx-bottom-nav> * <igx-tab-panel label="Tab 1">Tab 1 Content</igx-tab-panel> * <igx-tab-panel label="Tab 2">Tab 2 Content</igx-tab-panel> * <igx-tab-panel label="Tab 3">Tab 3 Content</igx-tab-panel> * </igx-bottom-nav> * ``` */ let IgxBottomNavComponent = class IgxBottomNavComponent { constructor(_element) { this._element = _element; /** * Sets/gets the `id` of the tab bar. * If not set, the `id` of the first tab bar component will be `"igx-bottom-nav-0"`. * ```html * <igx-bottom-nav id = "my-first-tab-bar"></igx-bottom-nav> * ``` * ```typescript * let tabBarId = this.tabBar.id; * ``` * @memberof IgxBottomNavComponent */ this.id = `igx-bottom-nav-${NEXT_ID++}`; /** * Emits an event when a new tab is selected. * Provides references to the `IgxTabComponent` and `IgxTabPanelComponent` as event arguments. * ```html * <igx-bottom-nav (onTableSelected) = "onTabSelected($event)"><igx-bottom-nav> * ``` * @memberof IgxBottomNavComponent */ this.onTabSelected = new EventEmitter(); /** * Emits an event when a tab is deselected. * Provides references to the `IgxTabComponent` and `IgxTabPanelComponent` as event arguments. * ```html * <igx-bottom-nav (onTabDeselected) = "onTabDeselected($event)"><igx-bottom-nav> * ``` * @memberof IgxBottomNavComponent */ this.onTabDeselected = new EventEmitter(); /** * Gets the `index` of selected tab/panel in the respective collection. * ```typescript * let index = this.tabBar.selectedIndex; * ``` * @memberof IgxBottomNavComponent */ this.selectedIndex = -1; /** *@hidden */ this._itemStyle = 'igx-bottom-nav'; } /** * Gets the `IgxTabComponent` elements for this bottom navigation component. * First try to get them as content children if not available get them as view children. * ```typescript * let tabs: QueryList<IgxTabComponent> = this.tabBar.tabs; * ``` * @memberof IgxBottomNavComponent */ get tabs() { return this.hasContentTabs ? this.contentTabs : this.viewTabs; } /** * Gets the `itemStyle` of the tab bar. * ```typescript * let itemStyle = this.tabBar.itemStyle; * ``` * @memberof IgxBottomNavComponent */ get itemStyle() { return this._itemStyle; } /** *@hidden */ get hasContentTabs() { return (this.contentTabs && this.contentTabs.length > 0); } /** * Gets the selected tab in the tab bar. * ```typescript * let tab = this.tabBar.selectedTab; * ``` * @memberof IgxBottomNavComponent */ get selectedTab() { if (this.tabs && this.selectedIndex !== undefined) { return this.tabs.toArray()[this.selectedIndex]; } } /** *@hidden */ ngAfterViewInit() { // initial selection setTimeout(() => { if (this.selectedIndex === -1) { const selectablePanels = this.panels.filter((p) => !p.disabled); const panel = selectablePanels[0]; if (panel) { panel.select(); } } }, 0); } /** *@hidden */ _selectedPanelHandler(args) { if (this.hasContentTabs) { this.selectedIndex = args.tab.index; this.contentTabs.forEach((t) => { if (t !== args.tab) { this._deselectTab(t); } }); } else { if (args.panel) { this.selectedIndex = args.panel.index; this.panels.forEach((p) => { if (p.index !== this.selectedIndex) { this._deselectPanel(p); } }); } } } /** *@hidden */ _deselectPanel(panel) { // Cannot deselect the selected tab - this will mean that there will be not selected tab left if (panel.disabled || this.selectedTab.index === panel.index) { return; } panel.isSelected = false; this.onTabDeselected.emit({ tab: this.tabs[panel.index], panel }); } _deselectTab(aTab) { aTab.isSelected = false; this.onTabDeselected.emit({ tab: aTab, panel: null }); } }; IgxBottomNavComponent.ctorParameters = () => [ { type: ElementRef } ]; __decorate([ ViewChildren(forwardRef(() => IgxTabComponent)), __metadata("design:type", QueryList) ], IgxBottomNavComponent.prototype, "viewTabs", void 0); __decorate([ ContentChildren(forwardRef(() => IgxTabComponent)), __metadata("design:type", QueryList) ], IgxBottomNavComponent.prototype, "contentTabs", void 0); __decorate([ ContentChildren(forwardRef(() => IgxTabPanelComponent)), __metadata("design:type", QueryList) ], IgxBottomNavComponent.prototype, "panels", void 0); __decorate([ HostBinding('attr.id'), Input(), __metadata("design:type", Object) ], IgxBottomNavComponent.prototype, "id", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxBottomNavComponent.prototype, "onTabSelected", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxBottomNavComponent.prototype, "onTabDeselected", void 0); __decorate([ HostListener('onTabSelected', ['$event']), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], IgxBottomNavComponent.prototype, "_selectedPanelHandler", null); IgxBottomNavComponent = __decorate([ Component({ selector: 'igx-bottom-nav', template: "<div *ngIf=\"!hasContentTabs\">\n <ng-content></ng-content>\n</div>\n<div #tablist class=\"{{itemStyle}}__menu {{itemStyle}}__menu--bottom\" role=\"tablist\" aria-orientation=\"horizontal\">\n <ng-container *ngIf=\"!hasContentTabs\"> \n <igx-tab *ngFor=\"let panel of panels\" [relatedPanel]=\"panel\">\n </igx-tab>\n </ng-container>\n <ng-content select=\"igx-tab\"></ng-content>\n</div>", styles: [` :host { display: block; } `] }), __metadata("design:paramtypes", [ElementRef]) ], IgxBottomNavComponent); export { IgxBottomNavComponent }; // ================================= IgxTabPanelComponent ====================================== let IgxTabPanelComponent = class IgxTabPanelComponent { constructor(_tabBar, _element) { this._tabBar = _tabBar; this._element = _element; /** *@hidden */ this._itemStyle = 'igx-tab-panel'; /** *@hidden */ this._isSelected = false; /** * Gets the role of the tab panel. * ```typescript * let tabPanelRole = this.tabPanel.role; * ``` * @memberof IgxTabPanelComponent */ this.role = 'tabpanel'; } /** * Gets whether a tab panel will have `igx-bottom-nav__panel` class. * ```typescript * let styleClass = this.tabPanel.styleClass; * ``` * @memberof IgxTabPanelComponent */ get styleClass() { return (!this.isSelected); } /** * Sets/gets whether a tab panel is selected. * ```typescript * this.tabPanel.isSelected = true; * ``` * ```typescript * let isSelected = this.tabPanel.isSelected; * ``` * @memberof IgxTabPanelComponent */ get isSelected() { return this._isSelected; } set isSelected(newValue) { if (this._isSelected !== newValue) { if (newValue) { this.select(); } else { this._isSelected = newValue; } } } /** * Gets the `itemStyle` of the tab panel. * ```typescript * let itemStyle = this.tabPanel.itemStyle; * ``` * @memberof IgxTabPanelComponent */ get itemStyle() { return this._itemStyle; } /** * Gets the tab associated with the panel. * ```typescript * let tab = this.tabPanel.relatedTab; * ``` * @memberof IgxTabPanelComponent */ get relatedTab() { if (this._tabBar.tabs) { return this._tabBar.tabs.toArray()[this.index]; } } /** * Gets the changes and updates accordingly applied to the tab/panel. * * @memberof IgxTabComponent */ get changesCount() { return this.relatedTab ? this.relatedTab.changesCount : 0; } /** * Gets the index of a panel in the panels collection. * ```typescript * let panelIndex = this.tabPanel.index * ``` * @memberof IgxTabPanelComponent */ get index() { if (this._tabBar.panels) { return this._tabBar.panels.toArray().indexOf(this); } } /** * Gets the tab template. * ```typescript * let tabTemplate = this.tabPanel.customTabTemplate * ``` * @memberof IgxTabPanelComponent */ get customTabTemplate() { return this._tabTemplate; } /** * Sets the tab template. * ```typescript * this.tabPanel.customTabTemplate(tabTemplate); * ``` * @memberof IgxTabPanelComponent */ set customTabTemplate(template) { this._tabTemplate = template; } /** *@hidden */ ngAfterContentInit() { if (this.tabTemplate) { this._tabTemplate = this.tabTemplate.template; } } /** *@hidden */ ngAfterViewChecked() { this._element.nativeElement.setAttribute('aria-labelledby', `igx-tab-${this.index}`); this._element.nativeElement.setAttribute('id', `igx-bottom-nav__panel-${this.index}`); } /** * Selects the current tab and the tab panel. * ```typescript * this.tabPanel.select(); * ``` * @memberof IgxTabPanelComponent */ select() { if (this.disabled || this._tabBar.selectedIndex === this.index) { return; } this._isSelected = true; this._tabBar.onTabSelected.emit({ tab: this._tabBar.tabs.toArray()[this.index], panel: this }); } }; IgxTabPanelComponent.ctorParameters = () => [ { type: IgxBottomNavComponent }, { type: ElementRef } ]; __decorate([ Input(), __metadata("design:type", String) ], IgxTabPanelComponent.prototype, "label", void 0); __decorate([ Input(), __metadata("design:type", String) ], IgxTabPanelComponent.prototype, "icon", void 0); __decorate([ Input(), __metadata("design:type", Boolean) ], IgxTabPanelComponent.prototype, "disabled", void 0); __decorate([ HostBinding('attr.role'), __metadata("design:type", Object) ], IgxTabPanelComponent.prototype, "role", void 0); __decorate([ HostBinding('class.igx-bottom-nav__panel'), __metadata("design:type", Boolean), __metadata("design:paramtypes", []) ], IgxTabPanelComponent.prototype, "styleClass", null); __decorate([ HostBinding('class.igx-bottom-nav__panel--selected'), __metadata("design:type", Boolean), __metadata("design:paramtypes", [Boolean]) ], IgxTabPanelComponent.prototype, "isSelected", null); __decorate([ ContentChild(IgxTabTemplateDirective, { read: IgxTabTemplateDirective }), __metadata("design:type", IgxTabTemplateDirective) ], IgxTabPanelComponent.prototype, "tabTemplate", void 0); IgxTabPanelComponent = __decorate([ Component({ selector: 'igx-tab-panel', template: "<ng-content></ng-content>\n" }), __metadata("design:paramtypes", [IgxBottomNavComponent, ElementRef]) ], IgxTabPanelComponent); export { IgxTabPanelComponent }; // ======================================= IgxTabComponent ========================================== let IgxTabComponent = class IgxTabComponent { constructor(_tabBar, _element) { this._tabBar = _tabBar; this._element = _element; /** * Gets the `role` attribute. * ```typescript * let tabRole = this.tab.role; * ``` * @memberof IgxTabComponent */ this.role = 'tab'; /** * @hidden @internal */ this.id = 'igx-tab-' + this.index; /** * @hidden @internal */ this.ariaLabel = this.label; /** * @hidden @internal */ this.ariaDisabled = this.disabled; /** * @hidden @internal */ this.ariaSelected = this.isSelected; /** * @hidden @internal */ this.ariaControls = 'igx-tab-panel-' + this.index; /** *@hidden */ this._changesCount = 0; // changes and updates accordingly applied to the tab. this._disabled = false; this._selected = false; } /** * Sets/gets the `label` of the tab panel. * ```html * <igx-tab [label] = "'Tab label'"><igx-tab> * ``` * ```typescript * let tabLabel = this.tab.label; * ``` * @memberof IgxTabComponent */ get label() { return this.relatedPanel ? this.relatedPanel.label : this._label; } set label(newValue) { if (this.relatedPanel) { this.relatedPanel.label = newValue; } this._label = newValue; } /** * Sets/gets the `icon` of the tab panel. * ```html * <igx-tab [icon] = "tab_icon"><igx-tab> * ``` * ```typescript * let tabIcon = this.tab.icon; * ``` * @memberof IgxTabComponent */ get icon() { return this.relatedPanel ? this.relatedPanel.icon : this._icon; } set icon(newValue) { if (this.relatedPanel) { this.relatedPanel.icon = newValue; } this._icon = newValue; } /** * Gets the changes and updates accordingly applied to the tab. * * @memberof IgxTabComponent */ get changesCount() { return this._changesCount; } /** * Gets whether the tab is disabled. * ```typescript * let isDisabled = this.tab.disabled; * ``` * @memberof IgxTabComponent */ get disabled() { return this.relatedPanel ? this.relatedPanel.disabled : this._disabled; } set disabled(newValue) { if (this.relatedPanel) { this.relatedPanel.disabled = newValue; } else { this._disabled = newValue; } } /** * Gets whether the tab is selected. * ```typescript * let isSelected = this.tab.isSelected; * ``` * @memberof IgxTabComponent */ set isSelected(newValue) { if (this.relatedPanel) { this.relatedPanel.isSelected = newValue; } else if (this._selected !== newValue) { this._selected = newValue; if (this._selected) { this._tabBar.onTabSelected.emit({ tab: this, panel: null }); } } } get isSelected() { return this.relatedPanel ? this.relatedPanel.isSelected : this._selected; } get cssClassSelected() { return this.isSelected; } get cssClassDisabled() { return this.disabled; } get cssClass() { return (!this.disabled && !this.isSelected); } /** * Gets the `index` of the tab. * ```typescript * let tabIndex = this.tab.index; * ``` * @memberof IgxTabComponent */ get index() { if (this._tabBar.tabs) { return this._tabBar.tabs.toArray().indexOf(this); } } /** * Returns the `template` for this IgxTabComponent. * ```typescript * let tabItemTemplate = this.tabItem.template; * ``` * @memberof IgxTabComponent */ get template() { if (this.relatedPanel && this.relatedPanel.customTabTemplate) { return this.relatedPanel.customTabTemplate; } if (this.customTabTemplateDir) { return this.customTabTemplateDir.template; } return this.defaultTabTemplate; } /** * Returns the `context` object for the template of this `IgxTabComponent`. * ```typescript * let tabItemContext = this.tabItem.context; * ``` */ get context() { return this.relatedPanel ? this.relatedPanel : this; } /** * Selects the current tab and the associated panel. * ```typescript * this.tab.select(); * ``` * @memberof IgxTabComponent */ select() { if (this.relatedPanel) { this.relatedPanel.select(); } else { this._selected = true; this._tabBar.onTabSelected.emit({ tab: this, panel: null }); } } /** * @hidden */ onClick() { this.select(); } elementRef() { return this._element; } }; IgxTabComponent.ctorParameters = () => [ { type: IgxBottomNavComponent }, { type: ElementRef } ]; __decorate([ HostBinding('attr.role'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "role", void 0); __decorate([ HostBinding('attr.id'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "id", void 0); __decorate([ HostBinding('attr.aria-label'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "ariaLabel", void 0); __decorate([ HostBinding('attr.aria-disabled'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "ariaDisabled", void 0); __decorate([ HostBinding('attr.aria-selected'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "ariaSelected", void 0); __decorate([ HostBinding('attr.aria-controls'), __metadata("design:type", Object) ], IgxTabComponent.prototype, "ariaControls", void 0); __decorate([ Input(), __metadata("design:type", IgxTabPanelComponent) ], IgxTabComponent.prototype, "relatedPanel", void 0); __decorate([ Input(), __metadata("design:type", String), __metadata("design:paramtypes", [String]) ], IgxTabComponent.prototype, "label", null); __decorate([ Input(), __metadata("design:type", String), __metadata("design:paramtypes", [String]) ], IgxTabComponent.prototype, "icon", null); __decorate([ Input(), __metadata("design:type", Boolean), __metadata("design:paramtypes", [Boolean]) ], IgxTabComponent.prototype, "disabled", null); __decorate([ Input(), __metadata("design:type", Boolean), __metadata("design:paramtypes", [Boolean]) ], IgxTabComponent.prototype, "isSelected", null); __decorate([ HostBinding('class.igx-bottom-nav__menu-item--selected'), __metadata("design:type", Boolean), __metadata("design:paramtypes", []) ], IgxTabComponent.prototype, "cssClassSelected", null); __decorate([ HostBinding('class.igx-bottom-nav__menu-item--disabled'), __metadata("design:type", Boolean), __metadata("design:paramtypes", []) ], IgxTabComponent.prototype, "cssClassDisabled", null); __decorate([ HostBinding('class.igx-bottom-nav__menu-item'), __metadata("design:type", Boolean), __metadata("design:paramtypes", []) ], IgxTabComponent.prototype, "cssClass", null); __decorate([ ViewChild('defaultTabTemplate', { read: TemplateRef, static: true }), __metadata("design:type", TemplateRef) ], IgxTabComponent.prototype, "defaultTabTemplate", void 0); __decorate([ ContentChild(IgxTabTemplateDirective, { read: IgxTabTemplateDirective }), __metadata("design:type", IgxTabTemplateDirective) ], IgxTabComponent.prototype, "customTabTemplateDir", void 0); __decorate([ HostListener('click'), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], IgxTabComponent.prototype, "onClick", null); IgxTabComponent = __decorate([ Component({ selector: 'igx-tab', template: "<ng-template #defaultTabTemplate let-context>\n <div *ngIf=\"context.icon\" class=\"tab-icon\">\n <igx-icon fontSet=\"material\">{{context.icon}}</igx-icon>\n <igx-badge [value]=\"context.changesCount\" [hidden]=\"context.changesCount === 0\"></igx-badge>\n </div>\n <div *ngIf=\"context.label\" ngClass=\"tab-label\">{{context.label}}</div>\n</ng-template>\n<ng-container *ngTemplateOutlet=\"template; context: { $implicit: this.context }\">\n</ng-container>" }), __metadata("design:paramtypes", [IgxBottomNavComponent, ElementRef]) ], IgxTabComponent); export { IgxTabComponent }; /** * @hidden */ let IgxBottomNavModule = class IgxBottomNavModule { }; IgxBottomNavModule = __decorate([ NgModule({ declarations: [IgxBottomNavComponent, IgxTabPanelComponent, IgxTabComponent, IgxTabTemplateDirective], exports: [IgxBottomNavComponent, IgxTabPanelComponent, IgxTabComponent, IgxTabTemplateDirective], imports: [CommonModule, IgxBadgeModule, IgxIconModule] }) ], IgxBottomNavModule); export { IgxBottomNavModule }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvdGFiYmFyL3RhYmJhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osS0FBSyxFQUNMLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxFQUNULFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUNmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBUTlDLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztBQUtoQixJQUFhLHVCQUF1QixHQUFwQyxNQUFhLHVCQUF1QjtJQUVoQyxZQUFtQixRQUEwQjtRQUExQixhQUFRLEdBQVIsUUFBUSxDQUFrQjtJQUM3QyxDQUFDO0NBQ0osQ0FBQTs7WUFGZ0MsV0FBVzs7QUFGL0IsdUJBQXVCO0lBSG5DLFNBQVMsQ0FBQztRQUNQLFFBQVEsRUFBRSxVQUFVO0tBQ3ZCLENBQUM7cUNBRytCLFdBQVc7R0FGL0IsdUJBQXVCLENBSW5DO1NBSlksdUJBQXVCO0FBS3BDOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBVUgsSUFBYSxxQkFBcUIsR0FBbEMsTUFBYSxxQkFBcUI7SUE0SDlCLFlBQW9CLFFBQW9CO1FBQXBCLGFBQVEsR0FBUixRQUFRLENBQVk7UUFoRnhDOzs7Ozs7Ozs7O1dBVUc7UUFHSSxPQUFFLEdBQUcsa0JBQWtCLE9B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QUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxDQUFDOzhCQUN6Qyx1QkFBdUI7NkRBQUM7QUFvRHhEO0lBREMsWUFBWSxDQUFDLE9BQU8sQ0FBQzs7Ozs4Q0FHckI7QUExUFEsZUFBZTtJQUozQixTQUFTLENBQUM7UUFDUCxRQUFRLEVBQUUsU0FBUztRQUNuQiw4ZUFBaUM7S0FDcEMsQ0FBQztxQ0FrTytCLHFCQUFxQixFQUFvQixVQUFVO0dBak92RSxlQUFlLENBK1AzQjtTQS9QWSxlQUFlO0FBaVE1Qjs7R0FFRztBQU1ILElBQWEsa0JBQWtCLEdBQS9CLE1BQWEsa0JBQWtCO0NBQzlCLENBQUE7QUFEWSxrQkFBa0I7SUFMOUIsUUFBUSxDQUFDO1FBQ04sWUFBWSxFQUFFLENBQUMscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsZUFBZSxFQUFFLHVCQUF1QixDQUFDO1FBQ3JHLE9BQU8sRUFBRSxDQUFDLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQztRQUNoRyxPQUFPLEVBQUUsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsQ0FBQztLQUN6RCxDQUFDO0dBQ1csa0JBQWtCLENBQzlCO1NBRFksa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBBZnRlclZpZXdDaGVja2VkLFxuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRGlyZWN0aXZlLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdDaGlsZHJlblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElneEJhZGdlTW9kdWxlIH0gZnJvbSAnLi4vYmFkZ2UvYmFkZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IElCYXNlRXZlbnRBcmdzIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVNlbGVjdFRhYkV2ZW50QXJncyBleHRlbmRzIElCYXNlRXZlbnRBcmdzIHtcbiAgICB0YWI6IElneFRhYkNvbXBvbmVudDtcbiAgICBwYW5lbDogSWd4VGFiUGFuZWxDb21wb25lbnQ7XG59XG5cbmxldCBORVhUX0lEID0gMDtcblxuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbaWd4VGFiXSdcbn0pXG5leHBvcnQgY2xhc3MgSWd4VGFiVGVtcGxhdGVEaXJlY3RpdmUge1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+KSB7XG4gICAgfVxufVxuLyoqXG4gKiAqKklnbml0ZSBVSSBmb3IgQW5ndWxhciBUYWIgQmFyKiogLVxuICogW0RvY3VtZW50YXRpb25dKGh0dHBzOi8vd3d3LmluZnJhZ2lzdGljcy5jb20vcHJvZHVjdHMvaWduaXRlLXVpLWFuZ3VsYXIvYW5ndWxhci9jb21wb25lbnRzL3RhYmJhci5odG1sKVxuICpcbiAqIFRoZSBJZ25pdGUgVUkgVGFiIEJhciBlbmFibGVzIHRoZSB1c2VyIHRvIG5hdmlnYXRlIGFtb25nIGEgbnVtYmVyIG9mIGNvbnRlbnQgcGFuZWxzIGRpc3BsYXllZCBpbiBhIHNpbmdsZSB2aWV3LlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGBodG1sXG4gKiA8aWd4LWJvdHRvbS1uYXY+XG4gKiAgIDxpZ3gtdGFiLXBhbmVsIGxhYmVsPVwiVGFiIDFcIj5UYWIgMSBDb250ZW50PC9pZ3gtdGFiLXBhbmVsPlxuICogICA8aWd4LXRhYi1wYW5lbCBsYWJlbD1cIlRhYiAyXCI+VGFiIDIgQ29udGVudDwvaWd4LXRhYi1wYW5lbD5cbiAqICAgPGlneC10YWItcGFuZWwgbGFiZWw9XCJUYWIgM1wiPlRhYiAzIENvbnRlbnQ8L2lneC10YWItcGFuZWw+XG4gKiA8L2lneC1ib3R0b20tbmF2PlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LWJvdHRvbS1uYXYnLFxuICAgIHRlbXBsYXRlVXJsOiAndGFiLWJhci1jb250ZW50LmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZXM6IFtgXG4gICAgICAgIDpob3N0IHtcbiAgICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB9XG4gICAgYF1cbn0pXG5leHBvcnQgY2xhc3MgSWd4Qm90dG9tTmF2Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgSWd4VGFiQ29tcG9uZW50YCBlbGVtZW50cyBpbiB0aGUgdGFiIGJhciBjb21wb25lbnQgY3JlYXRlZCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgcGFuZWxzLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiczogUXVlcnlMaXN0PElneFRhYkNvbXBvbmVudD4gPSAgdGhpcy50YWJCYXIudmlld1RhYnM7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneEJvdHRvbU5hdkNvbXBvbmVudFxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBJZ3hUYWJDb21wb25lbnQpKVxuICAgIHB1YmxpYyB2aWV3VGFiczogUXVlcnlMaXN0PElneFRhYkNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgSWd4VGFiQ29tcG9uZW50YCBlbGVtZW50cyBpbiB0aGUgdGFiIGJhciBjb21wb25lbnQgZGVmaW5lZCBhcyBjb250ZW50IGNoaWxkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiczogUXVlcnlMaXN0PElneFRhYkNvbXBvbmVudD4gPSAgdGhpcy50YWJCYXIuY29udGVudFRhYnM7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneEJvdHRvbU5hdkNvbXBvbmVudFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBJZ3hUYWJDb21wb25lbnQpKVxuICAgIHB1YmxpYyBjb250ZW50VGFiczogUXVlcnlMaXN0PElneFRhYkNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgSWd4VGFiQ29tcG9uZW50YCBlbGVtZW50cyBmb3IgdGhpcyBib3R0b20gbmF2aWdhdGlvbiBjb21wb25lbnQuXG4gICAgICogRmlyc3QgdHJ5IHRvIGdldCB0aGVtIGFzIGNvbnRlbnQgY2hpbGRyZW4gaWYgbm90IGF2YWlsYWJsZSBnZXQgdGhlbSBhcyB2aWV3IGNoaWxkcmVuLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiczogUXVlcnlMaXN0PElneFRhYkNvbXBvbmVudD4gPSAgdGhpcy50YWJCYXIudGFicztcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCB0YWJzKCk6IFF1ZXJ5TGlzdDxJZ3hUYWJDb21wb25lbnQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQ29udGVudFRhYnMgPyB0aGlzLmNvbnRlbnRUYWJzIDogdGhpcy52aWV3VGFicztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgSWd4VGFiUGFuZWxDb21wb25lbnRgIGVsZW1lbnRzIGluIHRoZSB0YWIgYmFyIGNvbXBvbmVudC5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IHRhYlBhbmVsczogUXVlcnlMaXN0PElneFRhYlBhbmVsQ29tcG9uZW50PiA9IHRoaXMudGFiQmFyLnBhbmVscztcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYlBhbmVsQ29tcG9uZW50KSlcbiAgICBwdWJsaWMgcGFuZWxzOiBRdWVyeUxpc3Q8SWd4VGFiUGFuZWxDb21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzIHRoZSBgaWRgIG9mIHRoZSB0YWIgYmFyLlxuICAgICAqIElmIG5vdCBzZXQsIHRoZSBgaWRgIG9mIHRoZSBmaXJzdCB0YWIgYmFyIGNvbXBvbmVudCB3aWxsIGJlIGBcImlneC1ib3R0b20tbmF2LTBcImAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtYm90dG9tLW5hdiBpZCA9IFwibXktZmlyc3QtdGFiLWJhclwiPjwvaWd4LWJvdHRvbS1uYXY+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGxldCB0YWJCYXJJZCA9ICB0aGlzLnRhYkJhci5pZDtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmlkJylcbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBpZCA9IGBpZ3gtYm90dG9tLW5hdi0ke05FWFRfSUQrK31gO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgd2hlbiBhIG5ldyB0YWIgaXMgc2VsZWN0ZWQuXG4gICAgICogUHJvdmlkZXMgcmVmZXJlbmNlcyB0byB0aGUgYElneFRhYkNvbXBvbmVudGAgYW5kIGBJZ3hUYWJQYW5lbENvbXBvbmVudGAgYXMgZXZlbnQgYXJndW1lbnRzLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWJvdHRvbS1uYXYgKG9uVGFibGVTZWxlY3RlZCkgPSBcIm9uVGFiU2VsZWN0ZWQoJGV2ZW50KVwiPjxpZ3gtYm90dG9tLW5hdj5cbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvblRhYlNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxJU2VsZWN0VGFiRXZlbnRBcmdzPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgd2hlbiBhIHRhYiBpcyBkZXNlbGVjdGVkLlxuICAgICAqIFByb3ZpZGVzIHJlZmVyZW5jZXMgdG8gdGhlIGBJZ3hUYWJDb21wb25lbnRgIGFuZCBgSWd4VGFiUGFuZWxDb21wb25lbnRgIGFzIGV2ZW50IGFyZ3VtZW50cy5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC1ib3R0b20tbmF2IChvblRhYkRlc2VsZWN0ZWQpID0gXCJvblRhYkRlc2VsZWN0ZWQoJGV2ZW50KVwiPjxpZ3gtYm90dG9tLW5hdj5cbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvblRhYkRlc2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPElTZWxlY3RUYWJFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgaW5kZXhgIG9mIHNlbGVjdGVkIHRhYi9wYW5lbCBpbiB0aGUgcmVzcGVjdGl2ZSBjb2xsZWN0aW9uLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaW5kZXggPSAgdGhpcy50YWJCYXIuc2VsZWN0ZWRJbmRleDtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIHNlbGVjdGVkSW5kZXggPSAtMTtcblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGBpdGVtU3R5bGVgIG9mIHRoZSB0YWIgYmFyLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXRlbVN0eWxlID0gIHRoaXMudGFiQmFyLml0ZW1TdHlsZTtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4Qm90dG9tTmF2Q29tcG9uZW50XG4gICAgICovXG4gICAgcHVibGljIGdldCBpdGVtU3R5bGUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZW1TdHlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGhhc0NvbnRlbnRUYWJzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuY29udGVudFRhYnMgJiYgdGhpcy5jb250ZW50VGFicy5sZW5ndGggPiAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9pdGVtU3R5bGUgPSAnaWd4LWJvdHRvbS1uYXYnO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2VsZWN0ZWQgdGFiIGluIHRoZSB0YWIgYmFyLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiID0gIHRoaXMudGFiQmFyLnNlbGVjdGVkVGFiO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hCb3R0b21OYXZDb21wb25lbnRcbiAgICAgKi9cbiAgICBnZXQgc2VsZWN0ZWRUYWIoKTogSWd4VGFiQ29tcG9uZW50IHtcbiAgICAgICAgaWYgKHRoaXMudGFicyAmJiB0aGlzLnNlbGVjdGVkSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFicy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICAvLyBpbml0aWFsIHNlbGVjdGlvblxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0YWJsZVBhbmVscyA9IHRoaXMucGFuZWxzLmZpbHRlcigocCkgPT4gIXAuZGlzYWJsZWQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhbmVsID0gc2VsZWN0YWJsZVBhbmVsc1swXTtcbiAgICAgICAgICAgICAgICBpZiAocGFuZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFuZWwuc2VsZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdExpc3RlbmVyKCdvblRhYlNlbGVjdGVkJywgWyckZXZlbnQnXSlcbiAgICBwdWJsaWMgX3NlbGVjdGVkUGFuZWxIYW5kbGVyKGFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29udGVudFRhYnMpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IGFyZ3MudGFiLmluZGV4O1xuICAgICAgICAgICAgdGhpcy5jb250ZW50VGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHQgIT09IGFyZ3MudGFiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2Rlc2VsZWN0VGFiKHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGFyZ3MucGFuZWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkSW5kZXggPSBhcmdzLnBhbmVsLmluZGV4O1xuICAgICAgICAgICAgICAgIHRoaXMucGFuZWxzLmZvckVhY2goKHApID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHAuaW5kZXggIT09IHRoaXMuc2VsZWN0ZWRJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGVzZWxlY3RQYW5lbChwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICpAaGlkZGVuXG4gICAgICovXG4gICAgcHJpdmF0ZSBfZGVzZWxlY3RQYW5lbChwYW5lbDogSWd4VGFiUGFuZWxDb21wb25lbnQpIHtcbiAgICAgICAgLy8gQ2Fubm90IGRlc2VsZWN0IHRoZSBzZWxlY3RlZCB0YWIgLSB0aGlzIHdpbGwgbWVhbiB0aGF0IHRoZXJlIHdpbGwgYmUgbm90IHNlbGVjdGVkIHRhYiBsZWZ0XG4gICAgICAgIGlmIChwYW5lbC5kaXNhYmxlZCB8fCB0aGlzLnNlbGVjdGVkVGFiLmluZGV4ID09PSBwYW5lbC5pbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgcGFuZWwuaXNTZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLm9uVGFiRGVzZWxlY3RlZC5lbWl0KHsgdGFiOiB0aGlzLnRhYnNbcGFuZWwuaW5kZXhdLCBwYW5lbCB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9kZXNlbGVjdFRhYihhVGFiOiBJZ3hUYWJDb21wb25lbnQpIHtcbiAgICAgICAgYVRhYi5pc1NlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMub25UYWJEZXNlbGVjdGVkLmVtaXQoeyB0YWI6IGFUYWIsIHBhbmVsOiBudWxsIH0pO1xuICAgIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IElneFRhYlBhbmVsQ29tcG9uZW50ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LXRhYi1wYW5lbCcsXG4gICAgdGVtcGxhdGVVcmw6ICd0YWItcGFuZWwuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIElneFRhYlBhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3Q2hlY2tlZCB7XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9pdGVtU3R5bGUgPSAnaWd4LXRhYi1wYW5lbCc7XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIF9pc1NlbGVjdGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBTZXRzL2dldHMgdGhlIGBsYWJlbGAgb2YgdGhlIHRhYiBwYW5lbC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC10YWItcGFuZWwgW2xhYmVsXSA9IFwiJ1RhYiBwYW5lbCBsYWJlbCdcIj48aWd4LXRhYi1wYW5lbD5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IHRhYlBhbmVsTGFiZWwgPSB0aGlzLnRhYlBhbmVsLmxhYmVsO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hUYWJQYW5lbENvbXBvbmVudFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBsYWJlbDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzICB0aGUgYGljb25gIG9mIHRoZSB0YWIgcGFuZWwuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtdGFiLXBhbmVsIFtpY29uXSA9IFwicGFuZWxfaWNvblwiPjxpZ3gtdGFiLXBhbmVsPlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiUGFuZWxJY29uID0gIHRoaXMudGFiUGFuZWwuaWNvbjtcbiAgICAgKiBgYGBcbiAgICAgKiBAbWVtYmVyb2YgSWd4VGFiUGFuZWxDb21wb25lbnRcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgaWNvbjogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogU2V0cy9nZXRzIHdoZXRoZXIgdGhlIHRhYiBwYW5lbCBpcyBkaXNhYmxlZC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC10YWItcGFuZWwgW2Rpc2FibGVkXSA9IFwidHJ1ZVwiPjxpZ3gtdGFiLXBhbmVsPlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNEaXNhYmxlZCA9IHRoaXMudGFiUGFuZWwuZGlzYWJsZWQ7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneFRhYlBhbmVsQ29tcG9uZW50XG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGRpc2FibGVkOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcm9sZSBvZiB0aGUgdGFiIHBhbmVsLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgdGFiUGFuZWxSb2xlID0gdGhpcy50YWJQYW5lbC5yb2xlO1xuICAgICAqIGBgYFxuICAgICAqIEBtZW1iZXJvZiBJZ3hUYWJQYW5lbENvbXBvbmVudFxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJykgcHVibGljIHJvbGUgPSAndGFicGFuZWwnO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB3aGV0aGVyIGEgdGFiIHBhbmVsIHdpbGwgaGF2ZSBgaWd4LWJvdHRvbS1uYXZfX3BhbmVsYCBjbGFzcy5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IHN0eWxlQ2xhc3MgPSB0aGlzLnRhYlBhbmVsLnN0eWxlQ2xhc3M7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneFRhYlBhbmVsQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pZ3gtYm90dG9tLW5hdl9fcGFuZWwnKVxuICAgIGdldCBzdHlsZUNsYXNzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKCF0aGlzLmlzU2VsZWN0ZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMvZ2V0cyB3aGV0aGVyIGEgdGFiIHBhbmVsIGlzIHNlbGVjdGVkLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLnRhYlBhbmVsLmlzU2VsZWN0ZWQgPSB0cnVlO1xuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNTZWxlY3RlZCA9ICB0aGlzLnRhYlBhbmVsLmlzU2VsZWN0ZWQ7XG4gICAgICogYGBgXG4gICAgICogQG1lbWJlcm9mIElneFRhYlBhbmVsQ29tcG9uZW50XG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pZ3gtYm90dG9tLW5hdl9fcGFuZWwtLXNlbGVjdGVkJylcbiAgICBwdWJsaWMgZ2V0IGlzU2VsZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1NlbGVjdGVkO1xuICAgIH1cbiAgICBwdWJsaWMgc2V0IGlzU2VsZWN0ZWQobmV3VmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU2VsZWN0ZWQgIT09IG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICBpZiAobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc1NlbGVjdGVkID0gbmV3VmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgaXRlbVN