UNPKG

@catull/igniteui-angular

Version:

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

452 lines 52.6 kB
var IgxTabsComponent_1; import { __decorate, __metadata } from "tslib"; import { CommonModule } from '@angular/common'; import { AfterViewInit, Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, Input, NgModule, Output, QueryList, ViewChild, ViewChildren, OnDestroy, NgZone } from '@angular/core'; import { IgxBadgeModule } from '../badge/badge.component'; import { IgxRippleModule } from '../directives/ripple/ripple.directive'; import { IgxIconModule } from '../icon/index'; import { IgxTabItemComponent } from './tab-item.component'; import { IgxTabsGroupComponent } from './tabs-group.component'; import { IgxLeftButtonStyleDirective, IgxRightButtonStyleDirective, IgxTabItemTemplateDirective } from './tabs.directives'; import { IgxTabsBase } from './tabs.common'; import ResizeObserver from 'resize-observer-polyfill'; export var TabsType; (function (TabsType) { TabsType["FIXED"] = "fixed"; TabsType["CONTENTFIT"] = "contentfit"; })(TabsType || (TabsType = {})); let IgxTabsComponent = IgxTabsComponent_1 = class IgxTabsComponent { constructor(_element, _ngZone) { this._element = _element; this._ngZone = _ngZone; /** *@hidden */ this.selectedIndexChange = new EventEmitter(); /** * Defines the tab header sizing mode. You can choose between `contentfit` or `fixed`. * By default the header sizing mode is `contentfit`. * ```html * <igx-tabs tabsType="fixed"> * <igx-tabs-group label="HOME">Home</igx-tabs-group> * </igx-tabs> * ``` */ this.tabsType = 'contentfit'; /** * @hidden */ this.class = ''; /** * Emitted when a tab item is deselected. * ```html * <igx-tabs (onTabItemDeselected)="itemDeselected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemDeselected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` */ this.onTabItemDeselected = new EventEmitter(); /** * Emitted when a tab item is selected. * ```html * <igx-tabs (onTabItemSelected)="itemSelected($event)"> * <igx-tabs-group label="Tab 1">This is Tab 1 content.</igx-tabs-group> * <igx-tabs-group label="Tab 2">This is Tab 2 content.</igx-tabs-group> * </igx-tabs> * ``` * ```typescript * itemSelected(e){ * const tabGroup = e.group; * const tabItem = e.tab; * } * ``` */ this.onTabItemSelected = new EventEmitter(); /** * @hidden */ this.offset = 0; this._selectedIndex = -1; } /** * An @Input property that sets the value of the `selectedIndex`. * Default value is 0. * ```html * <igx-tabs selectedIndex="1"> * ``` * * Two-way data binding. * ```html * <igx-tabs [(selectedIndex)]="model.selectedIndex"> * ``` */ get selectedIndex() { return this._selectedIndex; } set selectedIndex(index) { const newIndex = typeof index !== 'number' ? parseInt(index, 10) : index; if (this._selectedIndex !== newIndex) { if (this.tabs && this.tabs.length > 0) { const newTab = this.tabs.toArray()[newIndex]; if (newTab) { this.performSelectionChange(newTab); } } else { this._selectedIndex = newIndex; } } } /** * Provides an observable collection of all `IgxTabItemComponent`s. * First try to get them as content children if not available get them as view children. * ```typescript * const tabItems = this.myTabComponent.tabs; * ``` */ get tabs() { if (this.hasContentTabs) { return this.contentTabs; } return this.viewTabs; } /** *@hidden */ get hasContentTabs() { return (this.contentTabs && this.contentTabs.length > 0); } /** * @hidden */ get cssClass() { const defaultStyle = `igx-tabs`; const fixedStyle = `igx-tabs--fixed`; const iconStyle = `igx-tabs--icons`; const iconLabelFoundInGroups = this.groups.find((group) => group.icon != null && group.label != null); const iconLabelFoundInTabs = this.contentTabs.find((tab) => tab.icon != null && tab.label != null); let css; switch (TabsType[this.tabsType.toUpperCase()]) { case TabsType.FIXED: { css = fixedStyle; break; } default: { css = defaultStyle; break; } } // Layout fix for items with icons if (iconLabelFoundInGroups !== undefined || iconLabelFoundInTabs !== undefined) { css = `${css} ${iconStyle}`; } return `${css} ${this.class}`; } /** * @hidden */ scrollLeft(event) { this.scroll(false); } /** * @hidden */ scrollRight(event) { this.scroll(true); } /** * @hidden */ scrollElement(element, scrollRight) { const viewPortWidth = this.viewPort.nativeElement.offsetWidth; this.offset = (scrollRight) ? element.offsetWidth + element.offsetLeft - viewPortWidth : element.offsetLeft; this.itemsContainer.nativeElement.style.transform = `translate(${-this.offset}px)`; } /** * Gets the selected `IgxTabItemComponent`. * ``` * const selectedItem = this.myTabComponent.selectedTabItem; * ``` */ get selectedTabItem() { if (this.tabs && this.selectedIndex !== undefined) { return this.tabs.toArray()[this.selectedIndex]; } } /** * @hidden */ ngAfterViewInit() { if (this._selectedIndex === -1) { this.tabs.forEach((t) => { if (t.isSelected) { this._selectedIndex = t.index; } }); } if (!this.hasContentTabs && (this.selectedIndex < 0 || this.selectedIndex >= this.groups.length)) { this._selectedIndex = 0; } requestAnimationFrame(() => { const newTab = this.tabs.toArray()[this._selectedIndex]; if (newTab) { this.performSelection(newTab); } else { this.hideIndicator(); } }); this._groupChanges$ = this.groups.changes.subscribe(() => { this.resetSelectionOnCollectionChanged(); }); this._ngZone.runOutsideAngular(() => { this._resizeObserver = new ResizeObserver(() => { if (!this.hasContentTabs && this._selectedIndex >= 0 && this._selectedIndex < this.tabs.length) { const newTab = this.tabs.toArray()[this._selectedIndex]; this.transformContentAnimation(newTab, 0); } }); this._resizeObserver.observe(this.tabsContainer.nativeElement); }); } /** * @hidden */ ngOnDestroy() { if (this._groupChanges$) { this._groupChanges$.unsubscribe(); } this._ngZone.runOutsideAngular(() => { this._resizeObserver.disconnect(); }); } resetSelectionOnCollectionChanged() { requestAnimationFrame(() => { const currentTab = this.tabs.toArray()[this.selectedIndex]; if (currentTab) { this.performSelectionChange(currentTab); } else if (this.selectedIndex >= this.tabs.length) { this.performSelectionChange(this.tabs.last); } else { this.hideIndicator(); } }); } scroll(scrollRight) { const tabsArray = this.tabs.toArray(); for (const tab of tabsArray) { const element = tab.nativeTabItem.nativeElement; if (scrollRight) { if (element.offsetWidth + element.offsetLeft > this.viewPort.nativeElement.offsetWidth + this.offset) { this.scrollElement(element, scrollRight); break; } } else { if (element.offsetWidth + element.offsetLeft >= this.offset) { this.scrollElement(element, scrollRight); break; } } } } /** * @hidden */ performSelectionChange(newTab) { const oldTab = this.selectedTabItem; if (oldTab) { this.performDeselection(oldTab); } if (newTab) { this.performSelection(newTab); } else { // if there is no new selected tab hide the selection indicator this.hideIndicator(); } this.selectedIndexChange.emit(this._selectedIndex); } performDeselection(oldTab) { oldTab.setSelectedInternal(false); const oldTabRelatedGroup = this.groups.toArray()[oldTab.index]; if (oldTabRelatedGroup) { oldTabRelatedGroup.setSelectedInternal(false); } this._selectedIndex = -1; this.onTabItemDeselected.emit({ tab: oldTab, group: oldTabRelatedGroup }); } performSelection(newTab) { newTab.setSelectedInternal(true); this._selectedIndex = newTab.index; let newTabRelatedGroup = null; if (!this.hasContentTabs && this.groups) { newTabRelatedGroup = this.groups.toArray()[newTab.index]; if (newTabRelatedGroup) { newTabRelatedGroup.setSelectedInternal(true); } } this.onTabItemSelected.emit({ tab: newTab, group: newTabRelatedGroup }); requestAnimationFrame(() => { // bring the new selected tab into view if it is not this.bringNewTabIntoView(newTab); // animate the new selection indicator this.transformIndicatorAnimation(newTab.nativeTabItem.nativeElement); // animate the new tab's group content if (!this.hasContentTabs) { this.transformContentAnimation(newTab, 0.2); } }); } bringNewTabIntoView(newTab) { const tabNativeElement = newTab.nativeTabItem.nativeElement; // Scroll left if there is need if (tabNativeElement.offsetLeft < this.offset) { this.scrollElement(tabNativeElement, false); } // Scroll right if there is need const viewPortOffsetWidth = this.viewPort.nativeElement.offsetWidth; const delta = (tabNativeElement.offsetLeft + tabNativeElement.offsetWidth) - (viewPortOffsetWidth + this.offset); // Fix for IE 11, a difference is accumulated from the widths calculations if (delta > 1) { this.scrollElement(tabNativeElement, true); } } /** * @hidden */ // animation for the new panel/group (not needed for tab only mode) transformContentAnimation(tab, duration) { const contentOffset = this.tabsContainer.nativeElement.offsetWidth * tab.index; this.contentsContainer.nativeElement.style.transitionDuration = duration > 0 ? `${duration}s` : 'initial'; this.contentsContainer.nativeElement.style.transform = `translate(${-contentOffset}px)`; } /** * @hidden */ transformIndicatorAnimation(element, duration = 0.3) { if (this.selectedIndicator) { this.selectedIndicator.nativeElement.style.visibility = 'visible'; this.selectedIndicator.nativeElement.style.transitionDuration = duration > 0 ? `${duration}s` : 'initial'; this.selectedIndicator.nativeElement.style.width = `${element.offsetWidth}px`; this.selectedIndicator.nativeElement.style.transform = `translate(${element.offsetLeft}px)`; } } hideIndicator() { if (this.selectedIndicator) { this.selectedIndicator.nativeElement.style.visibility = 'hidden'; } } }; IgxTabsComponent.ctorParameters = () => [ { type: ElementRef }, { type: NgZone } ]; __decorate([ ContentChildren(forwardRef(() => IgxTabsGroupComponent)), __metadata("design:type", QueryList) ], IgxTabsComponent.prototype, "groups", void 0); __decorate([ ContentChildren(forwardRef(() => IgxTabItemComponent)), __metadata("design:type", QueryList) ], IgxTabsComponent.prototype, "contentTabs", void 0); __decorate([ Input(), __metadata("design:type", Number), __metadata("design:paramtypes", [Number]) ], IgxTabsComponent.prototype, "selectedIndex", null); __decorate([ Output(), __metadata("design:type", Object) ], IgxTabsComponent.prototype, "selectedIndexChange", void 0); __decorate([ Input('tabsType'), __metadata("design:type", String) ], IgxTabsComponent.prototype, "tabsType", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxTabsComponent.prototype, "class", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxTabsComponent.prototype, "onTabItemDeselected", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxTabsComponent.prototype, "onTabItemSelected", void 0); __decorate([ ViewChild('contentsContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "contentsContainer", void 0); __decorate([ ViewChild('headerContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "headerContainer", void 0); __decorate([ ViewChild('itemsContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "itemsContainer", void 0); __decorate([ ViewChild('selectedIndicator'), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "selectedIndicator", void 0); __decorate([ ViewChild('tabsContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "tabsContainer", void 0); __decorate([ ViewChild('viewPort', { static: true }), __metadata("design:type", ElementRef) ], IgxTabsComponent.prototype, "viewPort", void 0); __decorate([ ViewChildren(forwardRef(() => IgxTabItemComponent)), __metadata("design:type", QueryList) ], IgxTabsComponent.prototype, "viewTabs", void 0); __decorate([ HostBinding('attr.class'), __metadata("design:type", Object), __metadata("design:paramtypes", []) ], IgxTabsComponent.prototype, "cssClass", null); IgxTabsComponent = IgxTabsComponent_1 = __decorate([ Component({ selector: 'igx-tabs', template: "<!-- TODO Remove tab container from here -->\n<div #tabsContainer>\n <div class=\"igx-tabs__header\" #headerContainer>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollLeft($event)\" igxLeftButtonStyle>\n <igx-icon fontSet=\"material\">navigate_before</igx-icon>\n </button>\n <div class=\"igx-tabs__header-wrapper-fixed\" #viewPort>\n <div #itemsContainer class=\"igx-tabs__header-wrapper-fluid\">\n <ng-container *ngIf=\"!hasContentTabs\">\n <igx-tab-item igxRipple *ngFor=\"let group of groups\" [relatedGroup]=\"group\">\n </igx-tab-item>\n </ng-container>\n <ng-content select=\"igx-tab-item\"></ng-content>\n <div #selectedIndicator *ngIf=\"groups.length > 0 || contentTabs.length > 0\" class=\"igx-tabs__header-menu-item-indicator\"></div>\n </div>\n </div>\n <button igxRipple class=\"igx-tabs__header-button\" igxButton=\"icon\" (click)=\"scrollRight($event)\" igxRightButtonStyle>\n <igx-icon fontSet=\"material\">navigate_next</igx-icon>\n </button>\n </div>\n <div class=\"igx-tabs__content-fixed\">\n <div #contentsContainer class=\"igx-tabs__content-fluid\">\n <ng-content></ng-content>\n </div>\n </div>\n</div>", providers: [{ provide: IgxTabsBase, useExisting: IgxTabsComponent_1 }] }), __metadata("design:paramtypes", [ElementRef, NgZone]) ], IgxTabsComponent); export { IgxTabsComponent }; /** * @hidden */ let IgxTabsModule = class IgxTabsModule { }; IgxTabsModule = __decorate([ NgModule({ declarations: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], exports: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], imports: [CommonModule, IgxBadgeModule, IgxIconModule, IgxRippleModule] }) ], IgxTabsModule); export { IgxTabsModule }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnMvdGFicy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNILGFBQWEsRUFDYixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixTQUFTLEVBQ1QsTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsNEJBQTRCLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzSCxPQUFPLEVBQUUsV0FBVyxFQUFrQixNQUFNLGVBQWUsQ0FBQztBQUM1RCxPQUFPLGNBQWMsTUFBTSwwQkFBMEIsQ0FBQztBQUV0RCxNQUFNLENBQU4sSUFBWSxRQUdYO0FBSEQsV0FBWSxRQUFRO0lBQ2hCLDJCQUFlLENBQUE7SUFDZixxQ0FBeUIsQ0FBQTtBQUM3QixDQUFDLEVBSFcsUUFBUSxLQUFSLFFBQVEsUUFHbkI7QUFRRCxJQUFhLGdCQUFnQix3QkFBN0IsTUFBYSxnQkFBZ0I7SUFxUXpCLFlBQW9CLFFBQW9CLEVBQVUs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LENBQUM7UUFDUCxRQUFRLEVBQUUsVUFBVTtRQUNwQix1M0NBQWtDO1FBQ2xDLFNBQVMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsa0JBQWdCLEVBQUUsQ0FBQztLQUN2RSxDQUFDO3FDQXVRZ0MsVUFBVSxFQUFtQixNQUFNO0dBclF4RCxnQkFBZ0IsQ0FnYzVCO1NBaGNZLGdCQUFnQjtBQWtjN0I7O0dBRUc7QUFpQkgsSUFBYSxhQUFhLEdBQTFCLE1BQWEsYUFBYTtDQUN6QixDQUFBO0FBRFksYUFBYTtJQWhCekIsUUFBUSxDQUFDO1FBQ04sWUFBWSxFQUFFLENBQUMsZ0JBQWdCO1lBQzNCLHFCQUFxQjtZQUNyQixtQkFBbUI7WUFDbkIsMkJBQTJCO1lBQzNCLDRCQUE0QjtZQUM1QiwyQkFBMkIsQ0FBQztRQUNoQyxPQUFPLEVBQUUsQ0FBQyxnQkFBZ0I7WUFDdEIscUJBQXFCO1lBQ3JCLG1CQUFtQjtZQUNuQiwyQkFBMkI7WUFDM0IsNEJBQTRCO1lBQzVCLDJCQUEyQixDQUFDO1FBQ2hDLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQztLQUMxRSxDQUFDO0dBRVcsYUFBYSxDQUN6QjtTQURZLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgZm9yd2FyZFJlZixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbnB1dCxcbiAgICBOZ01vZHVsZSxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3Q2hpbGRyZW4sXG4gICAgT25EZXN0cm95LFxuICAgIE5nWm9uZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSWd4QmFkZ2VNb2R1bGUgfSBmcm9tICcuLi9iYWRnZS9iYWRnZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4UmlwcGxlTW9kdWxlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy9yaXBwbGUvcmlwcGxlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hJY29uTW9kdWxlIH0gZnJvbSAnLi4vaWNvbi9pbmRleCc7XG5pbXBvcnQgeyBJZ3hUYWJJdGVtQ29tcG9uZW50IH0gZnJvbSAnLi90YWItaXRlbS5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4VGFic0dyb3VwQ29tcG9uZW50IH0gZnJvbSAnLi90YWJzLWdyb3VwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hMZWZ0QnV0dG9uU3R5bGVEaXJlY3RpdmUsIElneFJpZ2h0QnV0dG9uU3R5bGVEaXJlY3RpdmUsIElneFRhYkl0ZW1UZW1wbGF0ZURpcmVjdGl2ZSB9IGZyb20gJy4vdGFicy5kaXJlY3RpdmVzJztcbmltcG9ydCB7IElneFRhYnNCYXNlLCBJZ3hUYWJJdGVtQmFzZSB9IGZyb20gJy4vdGFicy5jb21tb24nO1xuaW1wb3J0IFJlc2l6ZU9ic2VydmVyIGZyb20gJ3Jlc2l6ZS1vYnNlcnZlci1wb2x5ZmlsbCc7XG5cbmV4cG9ydCBlbnVtIFRhYnNUeXBlIHtcbiAgICBGSVhFRCA9ICdmaXhlZCcsXG4gICAgQ09OVEVOVEZJVCA9ICdjb250ZW50Zml0J1xufVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2lneC10YWJzJyxcbiAgICB0ZW1wbGF0ZVVybDogJ3RhYnMuY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW3sgcHJvdmlkZTogSWd4VGFic0Jhc2UsIHVzZUV4aXN0aW5nOiBJZ3hUYWJzQ29tcG9uZW50IH1dXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4VGFic0NvbXBvbmVudCBpbXBsZW1lbnRzIElneFRhYnNCYXNlLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICAgIC8qKlxuICAgICogUHJvdmlkZXMgYW4gb2JzZXJ2YWJsZSBjb2xsZWN0aW9uIG9mIGFsbCBgSWd4VGFic0dyb3VwQ29tcG9uZW50YHMuXG4gICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgKiBjb25zdCBncm91cEl0ZW1zID0gdGhpcy5teVRhYkNvbXBvbmVudC5ncm91cHM7XG4gICAgKiBgYGBcbiAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBJZ3hUYWJzR3JvdXBDb21wb25lbnQpKVxuICAgIHB1YmxpYyBncm91cHM6IFF1ZXJ5TGlzdDxJZ3hUYWJzR3JvdXBDb21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJJdGVtQ29tcG9uZW50YHMgZGVmaW5lZCBpbiB0aGUgcGFnZS5cbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGNvbnN0IHRhYkl0ZW1zID0gdGhpcy5teVRhYkNvbXBvbmVudC5jb250ZW50VGFicztcbiAgICAqIGBgYFxuICAgICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYkl0ZW1Db21wb25lbnQpKVxuICAgIHB1YmxpYyBjb250ZW50VGFiczogUXVlcnlMaXN0PElneFRhYkl0ZW1Db21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgKiBBbiBASW5wdXQgcHJvcGVydHkgdGhhdCBzZXRzIHRoZSB2YWx1ZSBvZiB0aGUgYHNlbGVjdGVkSW5kZXhgLlxuICAgICogRGVmYXVsdCB2YWx1ZSBpcyAwLlxuICAgICogYGBgaHRtbFxuICAgICogPGlneC10YWJzIHNlbGVjdGVkSW5kZXg9XCIxXCI+XG4gICAgKiBgYGBcbiAgICAqXG4gICAgKiBUd28td2F5IGRhdGEgYmluZGluZy5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtdGFicyBbKHNlbGVjdGVkSW5kZXgpXT1cIm1vZGVsLnNlbGVjdGVkSW5kZXhcIj5cbiAgICAqIGBgYFxuICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGVkSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gICAgfVxuXG4gICAgcHVibGljIHNldCBzZWxlY3RlZEluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgbmV3SW5kZXggPSB0eXBlb2YgaW5kZXggIT09ICdudW1iZXInID8gcGFyc2VJbnQoaW5kZXgsIDEwKSA6IGluZGV4O1xuICAgICAgICBpZiAodGhpcy5fc2VsZWN0ZWRJbmRleCAhPT0gbmV3SW5kZXgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRhYnMgJiYgdGhpcy50YWJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdUYWIgPSB0aGlzLnRhYnMudG9BcnJheSgpW25ld0luZGV4XTtcbiAgICAgICAgICAgICAgICBpZiAobmV3VGFiKSB7XG4gICAgICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKG5ld1RhYik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gbmV3SW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgc2VsZWN0ZWRJbmRleENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyB0aGUgdGFiIGhlYWRlciBzaXppbmcgbW9kZS4gWW91IGNhbiBjaG9vc2UgYmV0d2VlbiBgY29udGVudGZpdGAgb3IgYGZpeGVkYC5cbiAgICAgKiBCeSBkZWZhdWx0IHRoZSBoZWFkZXIgc2l6aW5nIG1vZGUgaXMgYGNvbnRlbnRmaXRgLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LXRhYnMgdGFic1R5cGU9XCJmaXhlZFwiPlxuICAgICAqICAgICA8aWd4LXRhYnMtZ3JvdXAgbGFiZWw9XCJIT01FXCI+SG9tZTwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgICogPC9pZ3gtdGFicz5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBASW5wdXQoJ3RhYnNUeXBlJylcbiAgICBwdWJsaWMgdGFic1R5cGU6IHN0cmluZyB8IFRhYnNUeXBlID0gJ2NvbnRlbnRmaXQnO1xuXG4gICAgLyoqXG4gICAgKiBAaGlkZGVuXG4gICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBjbGFzcyA9ICcnO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCB3aGVuIGEgdGFiIGl0ZW0gaXMgZGVzZWxlY3RlZC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC10YWJzIChvblRhYkl0ZW1EZXNlbGVjdGVkKT1cIml0ZW1EZXNlbGVjdGVkKCRldmVudClcIj5cbiAgICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAxXCI+VGhpcyBpcyBUYWIgMSBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgICogICAgICA8aWd4LXRhYnMtZ3JvdXAgbGFiZWw9XCJUYWIgMlwiPlRoaXMgaXMgVGFiIDIgY29udGVudC48L2lneC10YWJzLWdyb3VwPlxuICAgICAqIDwvaWd4LXRhYnM+XG4gICAgICogYGBgXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGl0ZW1EZXNlbGVjdGVkKGUpe1xuICAgICAqICAgICAgY29uc3QgdGFiR3JvdXAgPSBlLmdyb3VwO1xuICAgICAqICAgICAgY29uc3QgdGFiSXRlbSA9IGUudGFiO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25UYWJJdGVtRGVzZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICogRW1pdHRlZCB3aGVuIGEgdGFiIGl0ZW0gaXMgc2VsZWN0ZWQuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LXRhYnMgKG9uVGFiSXRlbVNlbGVjdGVkKT1cIml0ZW1TZWxlY3RlZCgkZXZlbnQpXCI+XG4gICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAxXCI+VGhpcyBpcyBUYWIgMSBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAyXCI+VGhpcyBpcyBUYWIgMiBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgKiA8L2lneC10YWJzPlxuICAgICogYGBgXG4gICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgKiBpdGVtU2VsZWN0ZWQoZSl7XG4gICAgKiAgICAgIGNvbnN0IHRhYkdyb3VwID0gZS5ncm91cDtcbiAgICAqICAgICAgY29uc3QgdGFiSXRlbSA9IGUudGFiO1xuICAgICogfVxuICAgICogYGBgXG4gICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25UYWJJdGVtU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29udGVudHNDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHB1YmxpYyBjb250ZW50c0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdoZWFkZXJDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHB1YmxpYyBoZWFkZXJDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnaXRlbXNDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHB1YmxpYyBpdGVtc0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdzZWxlY3RlZEluZGljYXRvcicpXG4gICAgcHVibGljIHNlbGVjdGVkSW5kaWNhdG9yOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgKiBAaGlkZGVuXG4gICAgKi9cbiAgICBAVmlld0NoaWxkKCd0YWJzQ29udGFpbmVyJywgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBwdWJsaWMgdGFic0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCd2aWV3UG9ydCcsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIHZpZXdQb3J0OiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYW4gb2JzZXJ2YWJsZSBjb2xsZWN0aW9uIG9mIGFsbCBgSWd4VGFiSXRlbUNvbXBvbmVudGBzLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0YWJJdGVtcyA9IHRoaXMubXlUYWJDb21wb25lbnQudmlld1RhYnM7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQFZpZXdDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYkl0ZW1Db21wb25lbnQpKVxuICAgIHB1YmxpYyB2aWV3VGFiczogUXVlcnlMaXN0PElneFRhYkl0ZW1Db21wb25lbnQ+O1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYW4gb2JzZXJ2YWJsZSBjb2xsZWN0aW9uIG9mIGFsbCBgSWd4VGFiSXRlbUNvbXBvbmVudGBzLlxuICAgICAqIEZpcnN0IHRyeSB0byBnZXQgdGhlbSBhcyBjb250ZW50IGNoaWxkcmVuIGlmIG5vdCBhdmFpbGFibGUgZ2V0IHRoZW0gYXMgdmlldyBjaGlsZHJlbi5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogY29uc3QgdGFiSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50LnRhYnM7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCB0YWJzKCk6IFF1ZXJ5TGlzdDxJZ3hUYWJJdGVtQ29tcG9uZW50PiB7XG4gICAgICAgIGlmICh0aGlzLmhhc0NvbnRlbnRUYWJzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50VGFicztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52aWV3VGFicztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKkBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGhhc0NvbnRlbnRUYWJzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKHRoaXMuY29udGVudFRhYnMgJiYgdGhpcy5jb250ZW50VGFicy5sZW5ndGggPiAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGNhbGN1bGF0ZWRXaWR0aDogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyB2aXNpYmxlSXRlbXNXaWR0aDogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBvZmZzZXQgPSAwO1xuXG4gICAgcHJpdmF0ZSBfZ3JvdXBDaGFuZ2VzJDogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX3NlbGVjdGVkSW5kZXggPSAtMTtcbiAgICBwcml2YXRlIF9yZXNpemVPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmNsYXNzJylcbiAgICBwdWJsaWMgZ2V0IGNzc0NsYXNzKCkge1xuICAgICAgICBjb25zdCBkZWZhdWx0U3R5bGUgPSBgaWd4LXRhYnNgO1xuICAgICAgICBjb25zdCBmaXhlZFN0eWxlID0gYGlneC10YWJzLS1maXhlZGA7XG4gICAgICAgIGNvbnN0IGljb25TdHlsZSA9IGBpZ3gtdGFicy0taWNvbnNgO1xuICAgICAgICBjb25zdCBpY29uTGFiZWxGb3VuZEluR3JvdXBzID0gdGhpcy5ncm91cHMuZmluZCgoZ3JvdXApID0+IGdyb3VwLmljb24gIT0gbnVsbCAmJiBncm91cC5sYWJlbCAhPSBudWxsKTtcbiAgICAgICAgY29uc3QgaWNvbkxhYmVsRm91bmRJblRhYnMgPSB0aGlzLmNvbnRlbnRUYWJzLmZpbmQoKHRhYikgPT4gdGFiLmljb24gIT0gbnVsbCAmJiB0YWIubGFiZWwgIT0gbnVsbCk7XG4gICAgICAgIGxldCBjc3M7XG4gICAgICAgIHN3aXRjaCAoVGFic1R5cGVbdGhpcy50YWJzVHlwZS50b1VwcGVyQ2FzZSgpXSkge1xuICAgICAgICAgICAgY2FzZSBUYWJzVHlwZS5GSVhFRDoge1xuICAgICAgICAgICAgICAgIGNzcyA9IGZpeGVkU3R5bGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY3NzID0gZGVmYXVsdFN0eWxlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTGF5b3V0IGZpeCBmb3IgaXRlbXMgd2l0aCBpY29uc1xuICAgICAgICBpZiAoaWNvbkxhYmVsRm91bmRJbkdyb3VwcyAhPT0gdW5kZWZpbmVkIHx8IGljb25MYWJlbEZvdW5kSW5UYWJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNzcyA9IGAke2Nzc30gJHtpY29uU3R5bGV9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgJHtjc3N9ICR7dGhpcy5jbGFzc31gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2Nyb2xsTGVmdChldmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNjcm9sbChmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzY3JvbGxSaWdodChldmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNjcm9sbCh0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbEVsZW1lbnQoZWxlbWVudDogYW55LCBzY3JvbGxSaWdodDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCB2aWV3UG9ydFdpZHRoID0gdGhpcy52aWV3UG9ydC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoO1xuXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gKHNjcm9sbFJpZ2h0KSA/IGVsZW1lbnQub2Zmc2V0V2lkdGggKyBlbGVtZW50Lm9mZnNldExlZnQgLSB2aWV3UG9ydFdpZHRoIDogZWxlbWVudC5vZmZzZXRMZWZ0O1xuICAgICAgICB0aGlzLml0ZW1zQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgkey10aGlzLm9mZnNldH1weClgO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHNlbGVjdGVkIGBJZ3hUYWJJdGVtQ29tcG9uZW50YC5cbiAgICAgKiBgYGBcbiAgICAgKiBjb25zdCBzZWxlY3RlZEl0ZW0gPSB0aGlzLm15VGFiQ29tcG9uZW50LnNlbGVjdGVkVGFiSXRlbTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXQgc2VsZWN0ZWRUYWJJdGVtKCk6IElneFRhYkl0ZW1Db21wb25lbnQge1xuICAgICAgICBpZiAodGhpcy50YWJzICYmIHRoaXMuc2VsZWN0ZWRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLnNlbGVjdGVkSW5kZXhdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfZWxlbWVudDogRWxlbWVudFJlZiwgcHJpdmF0ZSBfbmdab25lOiBOZ1pvbmUpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGVkSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnRhYnMuZm9yRWFjaCgodCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0LmlzU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHQuaW5kZXg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuaGFzQ29udGVudFRhYnMgJiYgKHRoaXMuc2VsZWN0ZWRJbmRleCA8IDAgfHwgdGhpcy5zZWxlY3RlZEluZGV4ID49IHRoaXMuZ3JvdXBzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMudGFicy50b0FycmF5KClbdGhpcy5fc2VsZWN0ZWRJbmRleF07XG4gICAgICAgICAgICBpZiAobmV3VGFiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uKG5ld1RhYik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUluZGljYXRvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9ncm91cENoYW5nZXMkID0gdGhpcy5ncm91cHMuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZXNldFNlbGVjdGlvbk9uQ29sbGVjdGlvbkNoYW5nZWQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaGFzQ29udGVudFRhYnMgJiYgdGhpcy5fc2VsZWN0ZWRJbmRleCA+PSAwICYmIHRoaXMuX3NlbGVjdGVkSW5kZXggPCB0aGlzLnRhYnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMudGFicy50b0FycmF5KClbdGhpcy5fc2VsZWN0ZWRJbmRleF07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNmb3JtQ29udGVudEFuaW1hdGlvbihuZXdUYWIsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLl9yZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMudGFic0NvbnRhaW5lci5uYXRpdmVFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2dyb3VwQ2hhbmdlcyQpIHtcbiAgICAgICAgICAgIHRoaXMuX2dyb3VwQ2hhbmdlcyQudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9yZXNpemVPYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRTZWxlY3Rpb25PbkNvbGxlY3Rpb25DaGFuZ2VkKCk6IHZvaWQge1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudFRhYiA9IHRoaXMudGFicy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50VGFiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKGN1cnJlbnRUYWIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlbGVjdGVkSW5kZXggPj0gdGhpcy50YWJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMucGVyZm9ybVNlbGVjdGlvbkNoYW5nZSh0aGlzLnRhYnMubGFzdCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUluZGljYXRvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNjcm9sbChzY3JvbGxSaWdodDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCB0YWJzQXJyYXkgPSB0aGlzLnRhYnMudG9BcnJheSgpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYiBvZiB0YWJzQXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0YWIubmF0aXZlVGFiSXRlbS5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgaWYgKHNjcm9sbFJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQub2Zmc2V0V2lkdGggKyBlbGVtZW50Lm9mZnNldExlZnQgPiB0aGlzLnZpZXdQb3J0Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggKyB0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQoZWxlbWVudCwgc2Nyb2xsUmlnaHQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm9mZnNldFdpZHRoICsgZWxlbWVudC5vZmZzZXRMZWZ0ID49IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudChlbGVtZW50LCBzY3JvbGxSaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgcGVyZm9ybVNlbGVjdGlvbkNoYW5nZShuZXdUYWI6IElneFRhYkl0ZW1CYXNlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG9sZFRhYiA9IHRoaXMuc2VsZWN0ZWRUYWJJdGVtO1xuICAgICAgICBpZiAob2xkVGFiKSB7XG4gICAgICAgICAgICB0aGlzLnBlcmZvcm1EZXNlbGVjdGlvbihvbGRUYWIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZXdUYWIpIHtcbiAgICAgICAgICAgIHRoaXMucGVyZm9ybVNlbGVjdGlvbihuZXdUYWIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gbmV3IHNlbGVjdGVkIHRhYiBoaWRlIHRoZSBzZWxlY3Rpb24gaW5kaWNhdG9yXG4gICAgICAgICAgICB0aGlzLmhpZGVJbmRpY2F0b3IoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kZXhDaGFuZ2UuZW1pdCh0aGlzLl9zZWxlY3RlZEluZGV4KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHBlcmZvcm1EZXNlbGVjdGlvbihvbGRUYWI6IElneFRhYkl0ZW1CYXNlKTogdm9pZCB7XG4gICAgICAgIG9sZFRhYi5zZXRTZWxlY3RlZEludGVybmFsKGZhbHNlKTtcbiAgICAgICAgY29uc3Qgb2xkVGFiUmVsYXRlZEdyb3VwID0gdGhpcy5ncm91cHMudG9BcnJheSgpW29sZFRhYi5pbmRleF07XG4gICAgICAgIGlmIChvbGRUYWJSZWxhdGVkR3JvdXApIHtcbiAgICAgICAgICAgIG9sZFRhYlJlbGF0ZWRHcm91cC5zZXRTZWxlY3RlZEludGVybmFsKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgIHRoaXMub25UYWJJdGVtRGVzZWxlY3RlZC5lbWl0KHsgdGFiOiBvbGRUYWIsIGdyb3VwOiBvbGRUYWJSZWxhdGVkR3JvdXAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwZXJmb3JtU2VsZWN0aW9uKG5ld1RhYjogSWd4VGFiSXRlbUJhc2UpOiB2b2lkIHtcbiAgICAgICAgbmV3VGFiLnNldFNlbGVjdGVkSW50ZXJuYWwodHJ1ZSk7XG4gICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBuZXdUYWIuaW5kZXg7XG5cbiAgICAgICAgbGV0IG5ld1RhYlJlbGF0ZWRHcm91cCA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5oYXNDb250ZW50VGFicyAmJiB0aGlzLmdyb3Vwcykge1xuICAgICAgICAgICAgbmV3VGFiUmVsYXRlZEdyb3VwID0gdGhpcy5ncm91cHMudG9BcnJheSgpW25ld1RhYi5pbmRleF07XG4gICAgICAgICAgICBpZiAobmV3VGFiUmVsYXRlZEdyb3VwKSB7XG4gICAgICAgICAgICAgICAgbmV3VGFiUmVsYXRlZEdyb3VwLnNldFNlbGVjdGVkSW50ZXJuYWwodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9uVGFiSXRlbVNlbGVjdGVkLmVtaXQoeyB0YWI6IG5ld1RhYiwgZ3JvdXA6IG5ld1RhYlJlbGF0ZWRHcm91cCB9KTtcblxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgLy8gYnJpbmcgdGhlIG5ldyBzZWxlY3RlZCB0YWIgaW50byB2aWV3IGlmIGl0IGlzIG5vdFxuICAgICAgICAgICAgdGhpcy5icmluZ05ld1RhYkludG9WaWV3KG5ld1RhYik7XG4gICAgICAgICAgICAvLyBhbmltYXRlIHRoZSBuZXcgc2VsZWN0aW9uIGluZGljYXRvclxuICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1JbmRpY2F0b3JBbmltYXRpb24obmV3VGFiLm5hdGl2ZVRhYkl0ZW0ubmF0aXZlRWxlbWVudCk7XG4gICAgICAgICAgICAvLyBhbmltYXRlIHRoZSBuZXcgdGFiJ3MgZ3JvdXAgY29udGVudFxuICAgICAgICAgICAgaWYgKCF0aGlzLmhhc0NvbnRlbnRUYWJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1Db250ZW50QW5pbWF0aW9uKG5ld1RhYiwgMC4yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBicmluZ05ld1RhYkludG9WaWV3KG5ld1RhYjogSWd4VGFiSXRlbUJhc2UpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGFiTmF0aXZlRWxlbWVudCA9IG5ld1RhYi5uYXRpdmVUYWJJdGVtLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgICAgLy8gU2Nyb2xsIGxlZnQgaWYgdGhlcmUgaXMgbmVlZFxuICAgICAgICBpZiAodGFiTmF0aXZlRWxlbWVudC5vZmZzZXRMZWZ0IDwgdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudCh0YWJOYXRpdmVFbGVtZW50LCBmYWxzZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTY3JvbGwgcmlnaHQgaWYgdGhlcmUgaXMgbmVlZFxuICAgICAgICBjb25zdCB2aWV3UG9ydE9mZnNldFdpZHRoID0gdGhpcy52aWV3UG9ydC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICBjb25zdCBkZWx0YSA9ICh0YWJOYXRpdmVFbGVtZW50Lm9mZnNldExlZnQgKyB0YWJOYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoKSAtICh2aWV3UG9ydE9mZnNldFdpZHRoICsgdGhpcy5vZmZzZXQpO1xuXG4gICAgICAgIC8vIEZpeCBmb3IgSUUgMTEsIGEgZGlmZmVyZW5jZSBpcyBhY2N1bXVsYXRlZCBmcm9tIHRoZSB3aWR0aHMgY2FsY3VsYXRpb25zXG4gICAgICAgIGlmIChkZWx0YSA+IDEp