UNPKG

@catull/igniteui-angular

Version:

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

493 lines 55.8 kB
import { __decorate, __metadata, __values } 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 = {})); var IgxTabsComponent = /** @class */ (function () { function IgxTabsComponent(_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; } IgxTabsComponent_1 = IgxTabsComponent; Object.defineProperty(IgxTabsComponent.prototype, "selectedIndex", { /** * 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: function () { return this._selectedIndex; }, set: function (index) { var newIndex = typeof index !== 'number' ? parseInt(index, 10) : index; if (this._selectedIndex !== newIndex) { if (this.tabs && this.tabs.length > 0) { var newTab = this.tabs.toArray()[newIndex]; if (newTab) { this.performSelectionChange(newTab); } } else { this._selectedIndex = newIndex; } } }, enumerable: true, configurable: true }); Object.defineProperty(IgxTabsComponent.prototype, "tabs", { /** * 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: function () { if (this.hasContentTabs) { return this.contentTabs; } return this.viewTabs; }, enumerable: true, configurable: true }); Object.defineProperty(IgxTabsComponent.prototype, "hasContentTabs", { /** *@hidden */ get: function () { return (this.contentTabs && this.contentTabs.length > 0); }, enumerable: true, configurable: true }); Object.defineProperty(IgxTabsComponent.prototype, "cssClass", { /** * @hidden */ get: function () { var defaultStyle = "igx-tabs"; var fixedStyle = "igx-tabs--fixed"; var iconStyle = "igx-tabs--icons"; var iconLabelFoundInGroups = this.groups.find(function (group) { return group.icon != null && group.label != null; }); var iconLabelFoundInTabs = this.contentTabs.find(function (tab) { return tab.icon != null && tab.label != null; }); var 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; }, enumerable: true, configurable: true }); /** * @hidden */ IgxTabsComponent.prototype.scrollLeft = function (event) { this.scroll(false); }; /** * @hidden */ IgxTabsComponent.prototype.scrollRight = function (event) { this.scroll(true); }; /** * @hidden */ IgxTabsComponent.prototype.scrollElement = function (element, scrollRight) { var viewPortWidth = this.viewPort.nativeElement.offsetWidth; this.offset = (scrollRight) ? element.offsetWidth + element.offsetLeft - viewPortWidth : element.offsetLeft; this.itemsContainer.nativeElement.style.transform = "translate(" + -this.offset + "px)"; }; Object.defineProperty(IgxTabsComponent.prototype, "selectedTabItem", { /** * Gets the selected `IgxTabItemComponent`. * ``` * const selectedItem = this.myTabComponent.selectedTabItem; * ``` */ get: function () { if (this.tabs && this.selectedIndex !== undefined) { return this.tabs.toArray()[this.selectedIndex]; } }, enumerable: true, configurable: true }); /** * @hidden */ IgxTabsComponent.prototype.ngAfterViewInit = function () { var _this = this; if (this._selectedIndex === -1) { this.tabs.forEach(function (t) { if (t.isSelected) { _this._selectedIndex = t.index; } }); } if (!this.hasContentTabs && (this.selectedIndex < 0 || this.selectedIndex >= this.groups.length)) { this._selectedIndex = 0; } requestAnimationFrame(function () { var newTab = _this.tabs.toArray()[_this._selectedIndex]; if (newTab) { _this.performSelection(newTab); } else { _this.hideIndicator(); } }); this._groupChanges$ = this.groups.changes.subscribe(function () { _this.resetSelectionOnCollectionChanged(); }); this._ngZone.runOutsideAngular(function () { _this._resizeObserver = new ResizeObserver(function () { if (!_this.hasContentTabs && _this._selectedIndex >= 0 && _this._selectedIndex < _this.tabs.length) { var newTab = _this.tabs.toArray()[_this._selectedIndex]; _this.transformContentAnimation(newTab, 0); } }); _this._resizeObserver.observe(_this.tabsContainer.nativeElement); }); }; /** * @hidden */ IgxTabsComponent.prototype.ngOnDestroy = function () { var _this = this; if (this._groupChanges$) { this._groupChanges$.unsubscribe(); } this._ngZone.runOutsideAngular(function () { _this._resizeObserver.disconnect(); }); }; IgxTabsComponent.prototype.resetSelectionOnCollectionChanged = function () { var _this = this; requestAnimationFrame(function () { var 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(); } }); }; IgxTabsComponent.prototype.scroll = function (scrollRight) { var e_1, _a; var tabsArray = this.tabs.toArray(); try { for (var tabsArray_1 = __values(tabsArray), tabsArray_1_1 = tabsArray_1.next(); !tabsArray_1_1.done; tabsArray_1_1 = tabsArray_1.next()) { var tab = tabsArray_1_1.value; var 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; } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (tabsArray_1_1 && !tabsArray_1_1.done && (_a = tabsArray_1.return)) _a.call(tabsArray_1); } finally { if (e_1) throw e_1.error; } } }; /** * @hidden */ IgxTabsComponent.prototype.performSelectionChange = function (newTab) { var 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); }; IgxTabsComponent.prototype.performDeselection = function (oldTab) { oldTab.setSelectedInternal(false); var oldTabRelatedGroup = this.groups.toArray()[oldTab.index]; if (oldTabRelatedGroup) { oldTabRelatedGroup.setSelectedInternal(false); } this._selectedIndex = -1; this.onTabItemDeselected.emit({ tab: oldTab, group: oldTabRelatedGroup }); }; IgxTabsComponent.prototype.performSelection = function (newTab) { var _this = this; newTab.setSelectedInternal(true); this._selectedIndex = newTab.index; var 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(function () { // 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); } }); }; IgxTabsComponent.prototype.bringNewTabIntoView = function (newTab) { var 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 var viewPortOffsetWidth = this.viewPort.nativeElement.offsetWidth; var 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) IgxTabsComponent.prototype.transformContentAnimation = function (tab, duration) { var 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 */ IgxTabsComponent.prototype.transformIndicatorAnimation = function (element, duration) { if (duration === void 0) { 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)"; } }; IgxTabsComponent.prototype.hideIndicator = function () { if (this.selectedIndicator) { this.selectedIndicator.nativeElement.style.visibility = 'hidden'; } }; var IgxTabsComponent_1; IgxTabsComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: NgZone } ]; }; __decorate([ ContentChildren(forwardRef(function () { return IgxTabsGroupComponent; })), __metadata("design:type", QueryList) ], IgxTabsComponent.prototype, "groups", void 0); __decorate([ ContentChildren(forwardRef(function () { return 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(function () { return 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); return IgxTabsComponent; }()); export { IgxTabsComponent }; /** * @hidden */ var IgxTabsModule = /** @class */ (function () { function IgxTabsModule() { } IgxTabsModule = __decorate([ NgModule({ declarations: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], exports: [IgxTabsComponent, IgxTabsGroupComponent, IgxTabItemComponent, IgxTabItemTemplateDirective, IgxRightButtonStyleDirective, IgxLeftButtonStyleDirective], imports: [CommonModule, IgxBadgeModule, IgxIconModule, IgxRippleModule] }) ], IgxTabsModule); return IgxTabsModule; }()); export { IgxTabsModule }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnMvdGFicy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0gsYUFBYSxFQUNiLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFNBQVMsRUFDVCxNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzFELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN4RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzNELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9ELE9BQU8sRUFBRSwyQkFBMkIsRUFBRSw0QkFBNEIsRUFBRSwyQkFBMkIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzNILE9BQU8sRUFBRSxXQUFXLEVBQWtCLE1BQU0sZUFBZSxDQUFDO0FBQzVELE9BQU8sY0FBYyxNQUFNLDBCQUEwQixDQUFDO0FBRXRELE1BQU0sQ0FBTixJQUFZLFFBR1g7QUFIRCxXQUFZLFFBQVE7SUFDaEIsMkJBQWUsQ0FBQTtJQUNmLHFDQUF5QixDQUFBO0FBQzdCLENBQUMsRUFIVyxRQUFRLEtBQVIsUUFBUSxRQUduQjtBQVFEO0lBcVFJLDBCQUFvQixRQUFvQixFQUFVLE9BQWU7UUFBN0MsYUFBUSxHQUFSLFFBQVEsQ0FBWTtR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O2tDQUN2QixVQUFVO3NEQUFDO0lBUzVCO1FBREMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxjQUFNLE9BQUEsbUJBQW1CLEVBQW5CLENBQW1CLENBQUMsQ0FBQztrQ0FDbkMsU0FBUztzREFBc0I7SUE4Q2hEO1FBREMsV0FBVyxDQUFDLFlBQVksQ0FBQzs7O29EQXlCekI7SUEvTlEsZ0JBQWdCO1FBTjVCLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxVQUFVO1lBQ3BCLHUzQ0FBa0M7WUFDbEMsU0FBUyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxrQkFBZ0IsRUFBRSxDQUFDO1NBQ3ZFLENBQUM7eUNBdVFnQyxVQUFVLEVBQW1CLE1BQU07T0FyUXhELGdCQUFnQixDQWdjNUI7SUFBRCx1QkFBQztDQUFBLEFBaGNELElBZ2NDO1NBaGNZLGdCQUFnQjtBQWtjN0I7O0dBRUc7QUFpQkg7SUFBQTtJQUNBLENBQUM7SUFEWSxhQUFhO1FBaEJ6QixRQUFRLENBQUM7WUFDTixZQUFZLEVBQUUsQ0FBQyxnQkFBZ0I7Z0JBQzNCLHFCQUFxQjtnQkFDckIsbUJBQW1CO2dCQUNuQiwyQkFBMkI7Z0JBQzNCLDRCQUE0QjtnQkFDNUIsMkJBQTJCLENBQUM7WUFDaEMsT0FBTyxFQUFFLENBQUMsZ0JBQWdCO2dCQUN0QixxQkFBcUI7Z0JBQ3JCLG1CQUFtQjtnQkFDbkIsMkJBQTJCO2dCQUMzQiw0QkFBNEI7Z0JBQzVCLDJCQUEyQixDQUFDO1lBQ2hDLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQztTQUMxRSxDQUFDO09BRVcsYUFBYSxDQUN6QjtJQUFELG9CQUFDO0NBQUEsQUFERCxJQUNDO1NBRFksYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdDaGlsZHJlbixcbiAgICBPbkRlc3Ryb3ksXG4gICAgTmdab25lXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJZ3hCYWRnZU1vZHVsZSB9IGZyb20gJy4uL2JhZGdlL2JhZGdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hSaXBwbGVNb2R1bGUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL3JpcHBsZS9yaXBwbGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IElneEljb25Nb2R1bGUgfSBmcm9tICcuLi9pY29uL2luZGV4JztcbmltcG9ydCB7IElneFRhYkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL3RhYi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hUYWJzR3JvdXBDb21wb25lbnQgfSBmcm9tICcuL3RhYnMtZ3JvdXAuY29tcG9uZW50JztcbmltcG9ydCB7IElneExlZnRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4UmlnaHRCdXR0b25TdHlsZURpcmVjdGl2ZSwgSWd4VGFiSXRlbVRlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJzLmRpcmVjdGl2ZXMnO1xuaW1wb3J0IHsgSWd4VGFic0Jhc2UsIElneFRhYkl0ZW1CYXNlIH0gZnJvbSAnLi90YWJzLmNvbW1vbic7XG5pbXBvcnQgUmVzaXplT2JzZXJ2ZXIgZnJvbSAncmVzaXplLW9ic2VydmVyLXBvbHlmaWxsJztcblxuZXhwb3J0IGVudW0gVGFic1R5cGUge1xuICAgIEZJWEVEID0gJ2ZpeGVkJyxcbiAgICBDT05URU5URklUID0gJ2NvbnRlbnRmaXQnXG59XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnaWd4LXRhYnMnLFxuICAgIHRlbXBsYXRlVXJsOiAndGFicy5jb21wb25lbnQuaHRtbCcsXG4gICAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBJZ3hUYWJzQmFzZSwgdXNlRXhpc3Rpbmc6IElneFRhYnNDb21wb25lbnQgfV1cbn0pXG5cbmV4cG9ydCBjbGFzcyBJZ3hUYWJzQ29tcG9uZW50IGltcGxlbWVudHMgSWd4VGFic0Jhc2UsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqXG4gICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJzR3JvdXBDb21wb25lbnRgcy5cbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGNvbnN0IGdyb3VwSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50Lmdyb3VwcztcbiAgICAqIGBgYFxuICAgICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihmb3J3YXJkUmVmKCgpID0+IElneFRhYnNHcm91cENvbXBvbmVudCkpXG4gICAgcHVibGljIGdyb3VwczogUXVlcnlMaXN0PElneFRhYnNHcm91cENvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAqIFByb3ZpZGVzIGFuIG9ic2VydmFibGUgY29sbGVjdGlvbiBvZiBhbGwgYElneFRhYkl0ZW1Db21wb25lbnRgcyBkZWZpbmVkIGluIHRoZSBwYWdlLlxuICAgICogYGBgdHlwZXNjcmlwdFxuICAgICogY29uc3QgdGFiSXRlbXMgPSB0aGlzLm15VGFiQ29tcG9uZW50LmNvbnRlbnRUYWJzO1xuICAgICogYGBgXG4gICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFiSXRlbUNvbXBvbmVudCkpXG4gICAgcHVibGljIGNvbnRlbnRUYWJzOiBRdWVyeUxpc3Q8SWd4VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAqIEFuIEBJbnB1dCBwcm9wZXJ0eSB0aGF0IHNldHMgdGhlIHZhbHVlIG9mIHRoZSBgc2VsZWN0ZWRJbmRleGAuXG4gICAgKiBEZWZhdWx0IHZhbHVlIGlzIDAuXG4gICAgKiBgYGBodG1sXG4gICAgKiA8aWd4LXRhYnMgc2VsZWN0ZWRJbmRleD1cIjFcIj5cbiAgICAqIGBgYFxuICAgICpcbiAgICAqIFR3by13YXkgZGF0YSBiaW5kaW5nLlxuICAgICogYGBgaHRtbFxuICAgICogPGlneC10YWJzIFsoc2VsZWN0ZWRJbmRleCldPVwibW9kZWwuc2VsZWN0ZWRJbmRleFwiPlxuICAgICogYGBgXG4gICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgc2VsZWN0ZWRJbmRleCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHNlbGVjdGVkSW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgICAgICBjb25zdCBuZXdJbmRleCA9IHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicgPyBwYXJzZUludChpbmRleCwgMTApIDogaW5kZXg7XG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3RlZEluZGV4ICE9PSBuZXdJbmRleCkge1xuICAgICAgICAgICAgaWYgKHRoaXMudGFicyAmJiB0aGlzLnRhYnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1RhYiA9IHRoaXMudGFicy50b0FycmF5KClbbmV3SW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmIChuZXdUYWIpIHtcbiAgICAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb25DaGFuZ2UobmV3VGFiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBuZXdJbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqQGhpZGRlblxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBzZWxlY3RlZEluZGV4Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSB0YWIgaGVhZGVyIHNpemluZyBtb2RlLiBZb3UgY2FuIGNob29zZSBiZXR3ZWVuIGBjb250ZW50Zml0YCBvciBgZml4ZWRgLlxuICAgICAqIEJ5IGRlZmF1bHQgdGhlIGhlYWRlciBzaXppbmcgbW9kZSBpcyBgY29udGVudGZpdGAuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtdGFicyB0YWJzVHlwZT1cImZpeGVkXCI+XG4gICAgICogICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIkhPTUVcIj5Ib21lPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiA8L2lneC10YWJzPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgndGFic1R5cGUnKVxuICAgIHB1YmxpYyB0YWJzVHlwZTogc3RyaW5nIHwgVGFic1R5cGUgPSAnY29udGVudGZpdCc7XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGNsYXNzID0gJyc7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBkZXNlbGVjdGVkLlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LXRhYnMgKG9uVGFiSXRlbURlc2VsZWN0ZWQpPVwiaXRlbURlc2VsZWN0ZWQoJGV2ZW50KVwiPlxuICAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiAgICAgIDxpZ3gtdGFicy1ncm91cCBsYWJlbD1cIlRhYiAyXCI+VGhpcyBpcyBUYWIgMiBjb250ZW50LjwvaWd4LXRhYnMtZ3JvdXA+XG4gICAgICogPC9pZ3gtdGFicz5cbiAgICAgKiBgYGBcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogaXRlbURlc2VsZWN0ZWQoZSl7XG4gICAgICogICAgICBjb25zdCB0YWJHcm91cCA9IGUuZ3JvdXA7XG4gICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvblRhYkl0ZW1EZXNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgLyoqXG4gICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBzZWxlY3RlZC5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtdGFicyAob25UYWJJdGVtU2VsZWN0ZWQpPVwiaXRlbVNlbGVjdGVkKCRldmVudClcIj5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDJcIj5UaGlzIGlzIFRhYiAyIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqIDwvaWd4LXRhYnM+XG4gICAgKiBgYGBcbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGl0ZW1TZWxlY3RlZChlKXtcbiAgICAqICAgICAgY29uc3QgdGFiR3JvdXAgPSBlLmdyb3VwO1xuICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgKiB9XG4gICAgKiBgYGBcbiAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvblRhYkl0ZW1TZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdjb250ZW50c0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGNvbnRlbnRzQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ2hlYWRlckNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGhlYWRlckNvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdpdGVtc0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHVibGljIGl0ZW1zQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3NlbGVjdGVkSW5kaWNhdG9yJylcbiAgICBwdWJsaWMgc2VsZWN0ZWRJbmRpY2F0b3I6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAqIEBoaWRkZW5cbiAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3RhYnNDb250YWluZXInLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHB1YmxpYyB0YWJzQ29udGFpbmVyOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBWaWV3Q2hpbGQoJ3ZpZXdQb3J0JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgICBwdWJsaWMgdmlld1BvcnQ6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJJdGVtQ29tcG9uZW50YHMuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHRhYkl0ZW1zID0gdGhpcy5teVRhYkNvbXBvbmVudC52aWV3VGFicztcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFiSXRlbUNvbXBvbmVudCkpXG4gICAgcHVibGljIHZpZXdUYWJzOiBRdWVyeUxpc3Q8SWd4VGFiSXRlbUNvbXBvbmVudD47XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlcyBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gb2YgYWxsIGBJZ3hUYWJJdGVtQ29tcG9uZW50YHMuXG4gICAgICogRmlyc3QgdHJ5IHRvIGdldCB0aGVtIGFzIGNvbnRlbnQgY2hpbGRyZW4gaWYgbm90IGF2YWlsYWJsZSBnZXQgdGhlbSBhcyB2aWV3IGNoaWxkcmVuLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0YWJJdGVtcyA9IHRoaXMubXlUYWJDb21wb25lbnQudGFicztcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHRhYnMoKTogUXVlcnlMaXN0PElneFRhYkl0ZW1Db21wb25lbnQ+IHtcbiAgICAgICAgaWYgKHRoaXMuaGFzQ29udGVudFRhYnMpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRUYWJzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZpZXdUYWJzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgaGFzQ29udGVudFRhYnMoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAodGhpcy5jb250ZW50VGFicyAmJiB0aGlzLmNvbnRlbnRUYWJzLmxlbmd0aCA+IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2FsY3VsYXRlZFdpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHZpc2libGVJdGVtc1dpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG9mZnNldCA9IDA7XG5cbiAgICBwcml2YXRlIF9ncm91cENoYW5nZXMkOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgIHByaXZhdGUgX3Jlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuY2xhc3MnKVxuICAgIHB1YmxpYyBnZXQgY3NzQ2xhc3MoKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRTdHlsZSA9IGBpZ3gtdGFic2A7XG4gICAgICAgIGNvbnN0IGZpeGVkU3R5bGUgPSBgaWd4LXRhYnMtLWZpeGVkYDtcbiAgICAgICAgY29uc3QgaWNvblN0eWxlID0gYGlneC10YWJzLS1pY29uc2A7XG4gICAgICAgIGNvbnN0IGljb25MYWJlbEZvdW5kSW5Hcm91cHMgPSB0aGlzLmdyb3Vwcy5maW5kKChncm91cCkgPT4gZ3JvdXAuaWNvbiAhPSBudWxsICYmIGdyb3VwLmxhYmVsICE9IG51bGwpO1xuICAgICAgICBjb25zdCBpY29uTGFiZWxGb3VuZEluVGFicyA9IHRoaXMuY29udGVudFRhYnMuZmluZCgodGFiKSA9PiB0YWIuaWNvbiAhPSBudWxsICYmIHRhYi5sYWJlbCAhPSBudWxsKTtcbiAgICAgICAgbGV0IGNzcztcbiAgICAgICAgc3dpdGNoIChUYWJzVHlwZVt0aGlzLnRhYnNUeXBlLnRvVXBwZXJDYXNlKCldKSB7XG4gICAgICAgICAgICBjYXNlIFRhYnNUeXBlLkZJWEVEOiB7XG4gICAgICAgICAgICAgICAgY3NzID0gZml4ZWRTdHlsZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICBjc3MgPSBkZWZhdWx0U3R5bGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMYXlvdXQgZml4IGZvciBpdGVtcyB3aXRoIGljb25zXG4gICAgICAgIGlmIChpY29uTGFiZWxGb3VuZEluR3JvdXBzICE9PSB1bmRlZmluZWQgfHwgaWNvbkxhYmVsRm91bmRJblRhYnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3NzID0gYCR7Y3NzfSAke2ljb25TdHlsZX1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke2Nzc30gJHt0aGlzLmNsYXNzfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzY3JvbGxMZWZ0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbFJpZ2h0KGV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Nyb2xsKHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2Nyb2xsRWxlbWVudChlbGVtZW50OiBhbnksIHNjcm9sbFJpZ2h0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHZpZXdQb3J0V2lkdGggPSB0aGlzLnZpZXdQb3J0Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgdGhpcy5vZmZzZXQgPSAoc2Nyb2xsUmlnaHQpID8gZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCAtIHZpZXdQb3J0V2lkdGggOiBlbGVtZW50Lm9mZnNldExlZnQ7XG4gICAgICAgIHRoaXMuaXRlbXNDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7LXRoaXMub2Zmc2V0fXB4KWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgc2VsZWN0ZWQgYElneFRhYkl0ZW1Db21wb25lbnRgLlxuICAgICAqIGBgYFxuICAgICAqIGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMubXlUYWJDb21wb25lbnQuc2VsZWN0ZWRUYWJJdGVtO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldCBzZWxlY3RlZFRhYkl0ZW0oKTogSWd4VGFiSXRlbUNvbXBvbmVudCB7XG4gICAgICAgIGlmICh0aGlzLnRhYnMgJiYgdGhpcy5zZWxlY3RlZEluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRhYnMudG9BcnJheSgpW3RoaXMuc2VsZWN0ZWRJbmRleF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSkge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICBpZiAodGhpcy5fc2VsZWN0ZWRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMudGFicy5mb3JFYWNoKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHQuaXNTZWxlY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gdC5pbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5oYXNDb250ZW50VGFicyAmJiAodGhpcy5zZWxlY3RlZEluZGV4IDwgMCB8fCB0aGlzLnNlbGVjdGVkSW5kZXggPj0gdGhpcy5ncm91cHMubGVuZ3RoKSkge1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLl9zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgIGlmIChuZXdUYWIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb24obmV3VGFiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSW5kaWNhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX2dyb3VwQ2hhbmdlcyQgPSB0aGlzLmdyb3Vwcy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0U2VsZWN0aW9uT25Db2xsZWN0aW9uQ2hhbmdlZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5oYXNDb250ZW50VGFicyAmJiB0aGlzLl9zZWxlY3RlZEluZGV4ID49IDAgJiYgdGhpcy5fc2VsZWN0ZWRJbmRleCA8IHRoaXMudGFicy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLl9zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2Zvcm1Db250ZW50QW5pbWF0aW9uKG5ld1RhYiwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy50YWJzQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fZ3JvdXBDaGFuZ2VzJCkge1xuICAgICAgICAgICAgdGhpcy5fZ3JvdXBDaGFuZ2VzJC51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZU9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNldFNlbGVjdGlvbk9uQ29sbGVjdGlvbkNoYW5nZWQoKTogdm9pZCB7XG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50VGFiID0gdGhpcy50YWJzLnRvQXJyYXkoKVt0aGlzLnNlbGVjdGVkSW5kZXhdO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRUYWIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBlcmZvcm1TZWxlY3Rpb25DaGFuZ2UoY3VycmVudFRhYik7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleCA+PSB0aGlzLnRhYnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKHRoaXMudGFicy5sYXN0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oaWRlSW5kaWNhdG9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2Nyb2xsKHNjcm9sbFJpZ2h0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRhYnNBcnJheSA9IHRoaXMudGFicy50b0FycmF5KCk7XG4gICAgICAgIGZvciAoY29uc3QgdGFiIG9mIHRhYnNBcnJheSkge1xuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRhYi5uYXRpdmVUYWJJdGVtLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoc2Nyb2xsUmlnaHQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5vZmZzZXRXaWR0aCArIGVsZW1lbnQub2Zmc2V0TGVmdCA+IHRoaXMudmlld1BvcnQubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCArIHRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudChlbGVtZW50LCBzY3JvbGxSaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQub2Zmc2V0V2lkdGggKyBlbGVtZW50Lm9mZnNldExlZnQgPj0gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxFbGVtZW50KGVsZW1lbnQsIHNjcm9sbFJpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBwZXJmb3JtU2VsZWN0aW9uQ2hhbmdlKG5ld1RhYjogSWd4VGFiSXRlbUJhc2UpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2xkVGFiID0gdGhpcy5zZWxlY3RlZFRhYkl0ZW07XG4gICAgICAgIGlmIChvbGRUYWIpI