@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
711 lines • 63.5 kB
JavaScript
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