igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
589 lines • 42.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { CommonModule } from '@angular/common';
import { Component, ContentChildren, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Input, NgModule, Output, QueryList, ViewChild, ViewChildren } 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';
/** @enum {string} */
var TabsType = {
FIXED: 'fixed',
CONTENTFIT: 'contentfit',
};
export { TabsType };
var IgxTabsComponent = /** @class */ (function () {
function IgxTabsComponent(_element) {
this._element = _element;
/**
* 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 = 0;
}
Object.defineProperty(IgxTabsComponent.prototype, "selectedIndex", {
/**
* An @Input property that sets the value of the `selectedIndex`.
* Default value is 0.
* ```html
* <igx-tabs selectedIndex="1">
* ```
*/
get: /**
* An \@Input property that sets the value of the `selectedIndex`.
* Default value is 0.
* ```html
* <igx-tabs selectedIndex="1">
* ```
* @return {?}
*/
function () {
return this._selectedIndex;
},
set: /**
* @param {?} index
* @return {?}
*/
function (index) {
this._selectedIndex = index;
this.setSelectedGroup();
},
enumerable: true,
configurable: true
});
Object.defineProperty(IgxTabsComponent.prototype, "cssClass", {
/**
* @hidden
*/
get: /**
* @hidden
* @return {?}
*/
function () {
/** @type {?} */
var defaultStyle = "igx-tabs";
/** @type {?} */
var fixedStyle = "igx-tabs--fixed";
/** @type {?} */
var iconStyle = "igx-tabs--icons";
/** @type {?} */
var iconLabelFound = this.groups.find(function (group) { return group.icon != null && group.label != null; });
/** @type {?} */
var css;
switch (TabsType[this.tabsType.toUpperCase()]) {
case TabsType.FIXED: {
css = fixedStyle;
break;
}
default: {
css = defaultStyle;
break;
}
}
// Layout fix for items with icons
if (iconLabelFound !== undefined) {
css = css + " " + iconStyle;
}
return css + " " + this.class;
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
/**
* @hidden
* @param {?} args
* @return {?}
*/
IgxTabsComponent.prototype.selectedGroupHandler = /**
* @hidden
* @param {?} args
* @return {?}
*/
function (args) {
var _this = this;
/** @type {?} */
var prevSelectedIndex = this.selectedIndex;
if (prevSelectedIndex !== -1 && this.groups.toArray()[prevSelectedIndex] !== undefined) {
this.onTabItemDeselected.emit({
tab: this.groups.toArray()[prevSelectedIndex].relatedTab,
group: this.groups.toArray()[prevSelectedIndex]
});
}
this.selectedIndex = args.group.index;
this.groups.forEach(function (p) {
if (p.index !== _this.selectedIndex) {
_this.deselectGroup(p);
}
});
};
/**
* @hidden
*/
/**
* @hidden
* @param {?} event
* @return {?}
*/
IgxTabsComponent.prototype.scrollLeft = /**
* @hidden
* @param {?} event
* @return {?}
*/
function (event) {
this.scroll(false);
};
/**
* @hidden
*/
/**
* @hidden
* @param {?} event
* @return {?}
*/
IgxTabsComponent.prototype.scrollRight = /**
* @hidden
* @param {?} event
* @return {?}
*/
function (event) {
this.scroll(true);
};
/**
* @hidden
*/
/**
* @hidden
* @param {?} element
* @param {?} scrollRight
* @return {?}
*/
IgxTabsComponent.prototype.scrollElement = /**
* @hidden
* @param {?} element
* @param {?} scrollRight
* @return {?}
*/
function (element, scrollRight) {
/** @type {?} */
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: /**
* Gets the selected `IgxTabItemComponent`.
* ```
* const selectedItem = this.myTabComponent.selectedTabItem;
* ```
* @return {?}
*/
function () {
if (this.tabs && this.selectedIndex !== undefined) {
return this.tabs.toArray()[this.selectedIndex];
}
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
/**
* @hidden
* @return {?}
*/
IgxTabsComponent.prototype.ngAfterViewInit = /**
* @hidden
* @return {?}
*/
function () {
var _this = this;
this.setSelectedGroup();
this._groupChanges$ = this.groups.changes.subscribe(function () {
_this.resetSelectionOnCollectionChanged();
});
};
/**
* @hidden
*/
/**
* @hidden
* @return {?}
*/
IgxTabsComponent.prototype.ngOnDestroy = /**
* @hidden
* @return {?}
*/
function () {
if (this._groupChanges$) {
this._groupChanges$.unsubscribe();
}
};
/**
* @private
* @return {?}
*/
IgxTabsComponent.prototype.setSelectedGroup = /**
* @private
* @return {?}
*/
function () {
var _this = this;
requestAnimationFrame(function () {
if (_this.selectedIndex <= 0 || _this.selectedIndex >= _this.groups.length) {
// if nothing is selected - select the first tabs group
_this.selectGroupByIndex(0);
}
else {
_this.selectGroupByIndex(_this.selectedIndex);
}
});
};
/**
* @private
* @return {?}
*/
IgxTabsComponent.prototype.resetSelectionOnCollectionChanged = /**
* @private
* @return {?}
*/
function () {
var _this = this;
setTimeout(function () {
if (_this.groups.toArray()[_this.selectedIndex] !== undefined) {
// persist the selected index and applied it to the new collection
_this.selectGroupByIndex(_this.selectedIndex);
}
else {
if (_this.selectedIndex >= _this.groups.length) {
// in case the selected index is no longer valid, select the last group in the new collection
_this.selectGroupByIndex(_this.groups.length - 1);
}
}
}, 0);
};
/**
* @private
* @param {?} selectedIndex
* @return {?}
*/
IgxTabsComponent.prototype.selectGroupByIndex = /**
* @private
* @param {?} selectedIndex
* @return {?}
*/
function (selectedIndex) {
/** @type {?} */
var selectableGroups = this.groups.filter(function (selectableGroup) { return !selectableGroup.disabled; });
/** @type {?} */
var group = selectableGroups[selectedIndex];
if (group) {
group.select(0);
}
};
/**
* @private
* @param {?} group
* @return {?}
*/
IgxTabsComponent.prototype.deselectGroup = /**
* @private
* @param {?} group
* @return {?}
*/
function (group) {
// Cannot deselect the selected tab - this will mean that there will be not selected tab left
if (group.disabled || this.selectedTabItem.index === group.index) {
return;
}
group.isSelected = false;
group.relatedTab.tabindex = -1;
};
/**
* @private
* @param {?} scrollRight
* @return {?}
*/
IgxTabsComponent.prototype.scroll = /**
* @private
* @param {?} scrollRight
* @return {?}
*/
function (scrollRight) {
var e_1, _a;
/** @type {?} */
var tabsArray = this.tabs.toArray();
try {
for (var tabsArray_1 = tslib_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;
/** @type {?} */
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; }
}
};
IgxTabsComponent.decorators = [
{ type: Component, args: [{
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 <igx-tab-item igxRipple *ngFor=\"let group of groups\" [id]=\"'igx-tab-item-' + group.index\" [attr.aria-label]=\"group.label\"\n [attr.aria-disabled]=\"group.disabled\" [attr.aria-selected]=\"group.isSelected\" [attr.aria-controls]=\"'igx-tab-item-group-'+ group.index\"\n [ngClass]=\"{\n 'igx-tabs__header-menu-item': !group.isSelected && !group.disabled,\n 'igx-tabs__header-menu-item--selected': group.isSelected,\n 'igx-tabs__header-menu-item--disabled': group.disabled }\" [relatedGroup]=\"group\" role=\"tab\">\n </igx-tab-item>\n <div #selectedIndicator *ngIf=\"groups.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 }]
}] }
];
/** @nocollapse */
IgxTabsComponent.ctorParameters = function () { return [
{ type: ElementRef }
]; };
IgxTabsComponent.propDecorators = {
groups: [{ type: ContentChildren, args: [forwardRef(function () { return IgxTabsGroupComponent; }),] }],
selectedIndex: [{ type: Input }],
tabsType: [{ type: Input, args: ['tabsType',] }],
class: [{ type: Input }],
onTabItemDeselected: [{ type: Output }],
onTabItemSelected: [{ type: Output }],
contentsContainer: [{ type: ViewChild, args: ['contentsContainer',] }],
headerContainer: [{ type: ViewChild, args: ['headerContainer',] }],
itemsContainer: [{ type: ViewChild, args: ['itemsContainer',] }],
selectedIndicator: [{ type: ViewChild, args: ['selectedIndicator',] }],
tabsContainer: [{ type: ViewChild, args: ['tabsContainer',] }],
viewPort: [{ type: ViewChild, args: ['viewPort',] }],
tabs: [{ type: ViewChildren, args: [forwardRef(function () { return IgxTabItemComponent; }),] }],
cssClass: [{ type: HostBinding, args: ['attr.class',] }],
selectedGroupHandler: [{ type: HostListener, args: ['onTabItemSelected', ['$event'],] }]
};
return IgxTabsComponent;
}());
export { IgxTabsComponent };
if (false) {
/**
* Provides an observable collection of all `IgxTabsGroupComponent`s.
* ```typescript
* const groupItems = this.myTabComponent.tabs;
* ```
* @type {?}
*/
IgxTabsComponent.prototype.groups;
/**
* 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>
* ```
* @type {?}
*/
IgxTabsComponent.prototype.tabsType;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.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;
* }
* ```
* @type {?}
*/
IgxTabsComponent.prototype.onTabItemDeselected;
/**
* 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;
* }
* ```
* @type {?}
*/
IgxTabsComponent.prototype.onTabItemSelected;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.contentsContainer;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.headerContainer;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.itemsContainer;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.selectedIndicator;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.tabsContainer;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.viewPort;
/**
* Provides an observable collection of all `IgxTabItemComponent`s.
* ```typescript
* const tabItems = this.myTabComponent.tabs;
* ```
* @type {?}
*/
IgxTabsComponent.prototype.tabs;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.calculatedWidth;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.visibleItemsWidth;
/**
* @hidden
* @type {?}
*/
IgxTabsComponent.prototype.offset;
/**
* @type {?}
* @private
*/
IgxTabsComponent.prototype._groupChanges$;
/**
* @type {?}
* @private
*/
IgxTabsComponent.prototype._selectedIndex;
/**
* @type {?}
* @private
*/
IgxTabsComponent.prototype._element;
}
/**
* @hidden
*/
var IgxTabsModule = /** @class */ (function () {
function IgxTabsModule() {
}
IgxTabsModule.decorators = [
{ type: NgModule, args: [{
declarations: [IgxTabsComponent,
IgxTabsGroupComponent,
IgxTabItemComponent,
IgxTabItemTemplateDirective,
IgxRightButtonStyleDirective,
IgxLeftButtonStyleDirective],
exports: [IgxTabsComponent,
IgxTabsGroupComponent,
IgxTabItemComponent,
IgxTabItemTemplateDirective,
IgxRightButtonStyleDirective,
IgxLeftButtonStyleDirective],
imports: [CommonModule, IgxBadgeModule, IgxIconModule, IgxRippleModule]
},] }
];
return IgxTabsModule;
}());
export { IgxTabsModule };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnMvdGFicy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUVILFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFFZixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDL0QsT0FBTyxFQUFFLDJCQUEyQixFQUFFLDRCQUE0QixFQUFFLDJCQUEyQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDM0gsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7O0lBR3hDLE9BQVEsT0FBTztJQUNmLFlBQWEsWUFBWTs7O0FBRzdCO0lBNE9JLDBCQUFvQixRQUFvQjtRQUFwQixhQUFRLEdBQVIsUUFBUSxDQUFZOzs7Ozs7Ozs7O1FBaE1qQyxhQUFRLEdBQXNCLFlBQVksQ0FBQzs7OztRQU0zQyxVQUFLLEdBQUcsRUFBRSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7O1FBaUJELHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7UUFp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QkEsUUFBUSxTQUFDO29CQUNOLFlBQVksRUFBRSxDQUFDLGdCQUFnQjt3QkFDM0IscUJBQXFCO3dCQUNyQixtQkFBbUI7d0JBQ25CLDJCQUEyQjt3QkFDM0IsNEJBQTRCO3dCQUM1QiwyQkFBMkIsQ0FBQztvQkFDaEMsT0FBTyxFQUFFLENBQUMsZ0JBQWdCO3dCQUN0QixxQkFBcUI7d0JBQ3JCLG1CQUFtQjt3QkFDbkIsMkJBQTJCO3dCQUMzQiw0QkFBNEI7d0JBQzVCLDJCQUEyQixDQUFDO29CQUNoQyxPQUFPLEVBQUUsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxlQUFlLENBQUM7aUJBQzFFOztJQUdELG9CQUFDO0NBQUEsQUFqQkQsSUFpQkM7U0FEWSxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQWZ0ZXJWaWV3SW5pdCxcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkcmVuLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdDaGlsZHJlbixcbiAgICBPbkRlc3Ryb3lcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IElneEJhZGdlTW9kdWxlIH0gZnJvbSAnLi4vYmFkZ2UvYmFkZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IElneFJpcHBsZU1vZHVsZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvcmlwcGxlL3JpcHBsZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSWd4SWNvbk1vZHVsZSB9IGZyb20gJy4uL2ljb24vaW5kZXgnO1xuaW1wb3J0IHsgSWd4VGFiSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vdGFiLWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IElneFRhYnNHcm91cENvbXBvbmVudCB9IGZyb20gJy4vdGFicy1ncm91cC5jb21wb25lbnQnO1xuaW1wb3J0IHsgSWd4TGVmdEJ1dHRvblN0eWxlRGlyZWN0aXZlLCBJZ3hSaWdodEJ1dHRvblN0eWxlRGlyZWN0aXZlLCBJZ3hUYWJJdGVtVGVtcGxhdGVEaXJlY3RpdmUgfSBmcm9tICcuL3RhYnMuZGlyZWN0aXZlcyc7XG5pbXBvcnQgeyBJZ3hUYWJzQmFzZSB9IGZyb20gJy4vdGFicy5jb21tb24nO1xuXG5leHBvcnQgZW51bSBUYWJzVHlwZSB7XG4gICAgRklYRUQgPSAnZml4ZWQnLFxuICAgIENPTlRFTlRGSVQgPSAnY29udGVudGZpdCdcbn1cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdpZ3gtdGFicycsXG4gICAgdGVtcGxhdGVVcmw6ICd0YWJzLmNvbXBvbmVudC5odG1sJyxcbiAgICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IElneFRhYnNCYXNlLCB1c2VFeGlzdGluZzogSWd4VGFic0NvbXBvbmVudCB9XVxufSlcblxuZXhwb3J0IGNsYXNzIElneFRhYnNDb21wb25lbnQgaW1wbGVtZW50cyBJZ3hUYWJzQmFzZSwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIC8qKlxuICAgICogUHJvdmlkZXMgYW4gb2JzZXJ2YWJsZSBjb2xsZWN0aW9uIG9mIGFsbCBgSWd4VGFic0dyb3VwQ29tcG9uZW50YHMuXG4gICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgKiBjb25zdCBncm91cEl0ZW1zID0gdGhpcy5teVRhYkNvbXBvbmVudC50YWJzO1xuICAgICogYGBgXG4gICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFic0dyb3VwQ29tcG9uZW50KSlcbiAgICBwdWJsaWMgZ3JvdXBzOiBRdWVyeUxpc3Q8SWd4VGFic0dyb3VwQ29tcG9uZW50PjtcblxuICAgIC8qKlxuICAgICogQW4gQElucHV0IHByb3BlcnR5IHRoYXQgc2V0cyB0aGUgdmFsdWUgb2YgdGhlIGBzZWxlY3RlZEluZGV4YC5cbiAgICAqIERlZmF1bHQgdmFsdWUgaXMgMC5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtdGFicyBzZWxlY3RlZEluZGV4PVwiMVwiPlxuICAgICogYGBgXG4gICAgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBnZXQgc2VsZWN0ZWRJbmRleCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IHNlbGVjdGVkSW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gaW5kZXg7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0ZWRHcm91cCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgdGhlIHRhYiBoZWFkZXIgc2l6aW5nIG1vZGUuIFlvdSBjYW4gY2hvb3NlIGJldHdlZW4gYGNvbnRlbnRmaXRgIG9yIGBmaXhlZGAuXG4gICAgICogQnkgZGVmYXVsdCB0aGUgaGVhZGVyIHNpemluZyBtb2RlIGlzIGBjb250ZW50Zml0YC5cbiAgICAgKiBgYGBodG1sXG4gICAgICogPGlneC10YWJzIHRhYnNUeXBlPVwiZml4ZWRcIj5cbiAgICAgKiAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiSE9NRVwiPkhvbWU8L2lneC10YWJzLWdyb3VwPlxuICAgICAqIDwvaWd4LXRhYnM+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KCd0YWJzVHlwZScpXG4gICAgcHVibGljIHRhYnNUeXBlOiBzdHJpbmcgfCBUYWJzVHlwZSA9ICdjb250ZW50Zml0JztcblxuICAgIC8qKlxuICAgICogQGhpZGRlblxuICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgY2xhc3MgPSAnJztcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgd2hlbiBhIHRhYiBpdGVtIGlzIGRlc2VsZWN0ZWQuXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtdGFicyAob25UYWJJdGVtRGVzZWxlY3RlZCk9XCJpdGVtRGVzZWxlY3RlZCgkZXZlbnQpXCI+XG4gICAgICogICAgICA8aWd4LXRhYnMtZ3JvdXAgbGFiZWw9XCJUYWIgMVwiPlRoaXMgaXMgVGFiIDEgY29udGVudC48L2lneC10YWJzLWdyb3VwPlxuICAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDJcIj5UaGlzIGlzIFRhYiAyIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAgKiA8L2lneC10YWJzPlxuICAgICAqIGBgYFxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBpdGVtRGVzZWxlY3RlZChlKXtcbiAgICAgKiAgICAgIGNvbnN0IHRhYkdyb3VwID0gZS5ncm91cDtcbiAgICAgKiAgICAgIGNvbnN0IHRhYkl0ZW0gPSBlLnRhYjtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBvblRhYkl0ZW1EZXNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgLyoqXG4gICAgKiBFbWl0dGVkIHdoZW4gYSB0YWIgaXRlbSBpcyBzZWxlY3RlZC5cbiAgICAqIGBgYGh0bWxcbiAgICAqIDxpZ3gtdGFicyAob25UYWJJdGVtU2VsZWN0ZWQpPVwiaXRlbVNlbGVjdGVkKCRldmVudClcIj5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDFcIj5UaGlzIGlzIFRhYiAxIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqICAgICAgPGlneC10YWJzLWdyb3VwIGxhYmVsPVwiVGFiIDJcIj5UaGlzIGlzIFRhYiAyIGNvbnRlbnQuPC9pZ3gtdGFicy1ncm91cD5cbiAgICAqIDwvaWd4LXRhYnM+XG4gICAgKiBgYGBcbiAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAqIGl0ZW1TZWxlY3RlZChlKXtcbiAgICAqICAgICAgY29uc3QgdGFiR3JvdXAgPSBlLmdyb3VwO1xuICAgICogICAgICBjb25zdCB0YWJJdGVtID0gZS50YWI7XG4gICAgKiB9XG4gICAgKiBgYGBcbiAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgb25UYWJJdGVtU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnY29udGVudHNDb250YWluZXInKVxuICAgIHB1YmxpYyBjb250ZW50c0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdoZWFkZXJDb250YWluZXInKVxuICAgIHB1YmxpYyBoZWFkZXJDb250YWluZXI6IEVsZW1lbnRSZWY7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQFZpZXdDaGlsZCgnaXRlbXNDb250YWluZXInKVxuICAgIHB1YmxpYyBpdGVtc0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCdzZWxlY3RlZEluZGljYXRvcicpXG4gICAgcHVibGljIHNlbGVjdGVkSW5kaWNhdG9yOiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgKiBAaGlkZGVuXG4gICAgKi9cbiAgICBAVmlld0NoaWxkKCd0YWJzQ29udGFpbmVyJylcbiAgICBwdWJsaWMgdGFic0NvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBAVmlld0NoaWxkKCd2aWV3UG9ydCcpXG4gICAgcHVibGljIHZpZXdQb3J0OiBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogUHJvdmlkZXMgYW4gb2JzZXJ2YWJsZSBjb2xsZWN0aW9uIG9mIGFsbCBgSWd4VGFiSXRlbUNvbXBvbmVudGBzLlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCB0YWJJdGVtcyA9IHRoaXMubXlUYWJDb21wb25lbnQudGFicztcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAVmlld0NoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4VGFiSXRlbUNvbXBvbmVudCkpXG4gICAgcHVibGljIHRhYnM6IFF1ZXJ5TGlzdDxJZ3hUYWJJdGVtQ29tcG9uZW50PjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2FsY3VsYXRlZFdpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHZpc2libGVJdGVtc1dpZHRoOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG9mZnNldCA9IDA7XG5cbiAgICBwcml2YXRlIF9ncm91cENoYW5nZXMkOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWRJbmRleCA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmNsYXNzJylcbiAgICBwdWJsaWMgZ2V0IGNzc0NsYXNzKCkge1xuICAgICAgICBjb25zdCBkZWZhdWx0U3R5bGUgPSBgaWd4LXRhYnNgO1xuICAgICAgICBjb25zdCBmaXhlZFN0eWxlID0gYGlneC10YWJzLS1maXhlZGA7XG4gICAgICAgIGNvbnN0IGljb25TdHlsZSA9IGBpZ3gtdGFicy0taWNvbnNgO1xuICAgICAgICBjb25zdCBpY29uTGFiZWxGb3VuZCA9IHRoaXMuZ3JvdXBzLmZpbmQoKGdyb3VwKSA9PiBncm91cC5pY29uICE9IG51bGwgJiYgZ3JvdXAubGFiZWwgIT0gbnVsbCk7XG4gICAgICAgIGxldCBjc3M7XG4gICAgICAgIHN3aXRjaCAoVGFic1R5cGVbdGhpcy50YWJzVHlwZS50b1VwcGVyQ2FzZSgpXSkge1xuICAgICAgICAgICAgY2FzZSBUYWJzVHlwZS5GSVhFRDoge1xuICAgICAgICAgICAgICAgIGNzcyA9IGZpeGVkU3R5bGU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgY3NzID0gZGVmYXVsdFN0eWxlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTGF5b3V0IGZpeCBmb3IgaXRlbXMgd2l0aCBpY29uc1xuICAgICAgICBpZiAoaWNvbkxhYmVsRm91bmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY3NzID0gYCR7Y3NzfSAke2ljb25TdHlsZX1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke2Nzc30gJHt0aGlzLmNsYXNzfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ29uVGFiSXRlbVNlbGVjdGVkJywgWyckZXZlbnQnXSlcbiAgICBwdWJsaWMgc2VsZWN0ZWRHcm91cEhhbmRsZXIoYXJncykge1xuICAgICAgICBjb25zdCBwcmV2U2VsZWN0ZWRJbmRleCA9IHRoaXMuc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgaWYgKHByZXZTZWxlY3RlZEluZGV4ICE9PSAtMSAmJiB0aGlzLmdyb3Vwcy50b0FycmF5KClbcHJldlNlbGVjdGVkSW5kZXhdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25UYWJJdGVtRGVzZWxlY3RlZC5lbWl0KFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdGFiOiB0aGlzLmdyb3Vwcy50b0FycmF5KClbcHJldlNlbGVjdGVkSW5kZXhdLnJlbGF0ZWRUYWIsXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwOiB0aGlzLmdyb3Vwcy50b0FycmF5KClbcHJldlNlbGVjdGVkSW5kZXhdXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kZXggPSBhcmdzLmdyb3VwLmluZGV4O1xuICAgICAgICB0aGlzLmdyb3Vwcy5mb3JFYWNoKChwKSA9PiB7XG4gICAgICAgICAgICBpZiAocC5pbmRleCAhPT0gdGhpcy5zZWxlY3RlZEluZGV4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXNlbGVjdEdyb3VwKHApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIHNjcm9sbExlZnQoZXZlbnQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zY3JvbGwoZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2Nyb2xsUmlnaHQoZXZlbnQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zY3JvbGwodHJ1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBzY3JvbGxFbGVtZW50KGVsZW1lbnQ6IGFueSwgc2Nyb2xsUmlnaHQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgdmlld1BvcnRXaWR0aCA9IHRoaXMudmlld1BvcnQubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcblxuICAgICAgICB0aGlzLm9mZnNldCA9IChzY3JvbGxSaWdodCkgPyBlbGVtZW50Lm9mZnNldFdpZHRoICsgZWxlbWVudC5vZmZzZXRMZWZ0IC0gdmlld1BvcnRXaWR0aCA6IGVsZW1lbnQub2Zmc2V0TGVmdDtcbiAgICAgICAgdGhpcy5pdGVtc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IGB0cmFuc2xhdGUoJHstdGhpcy5vZmZzZXR9cHgpYDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzZWxlY3RlZCBgSWd4VGFiSXRlbUNvbXBvbmVudGAuXG4gICAgICogYGBgXG4gICAgICogY29uc3Qgc2VsZWN0ZWRJdGVtID0gdGhpcy5teVRhYkNvbXBvbmVudC5zZWxlY3RlZFRhYkl0ZW07XG4gICAgICogYGBgXG4gICAgICovXG4gICAgZ2V0IHNlbGVjdGVkVGFiSXRlbSgpOiBJZ3hUYWJJdGVtQ29tcG9uZW50IHtcbiAgICAgICAgaWYgKHRoaXMudGFicyAmJiB0aGlzLnNlbGVjdGVkSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFicy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5zZXRTZWxlY3RlZEdyb3VwKCk7XG4gICAgICAgIHRoaXMuX2dyb3VwQ2hhbmdlcyQgPSB0aGlzLmdyb3Vwcy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0U2VsZWN0aW9uT25Db2xsZWN0aW9uQ2hhbmdlZCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5fZ3JvdXBDaGFuZ2VzJCkge1xuICAgICAgICAgICAgdGhpcy5fZ3JvdXBDaGFuZ2VzJC51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXRTZWxlY3RlZEdyb3VwKCk6IHZvaWQge1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleCA8PSAwIHx8IHRoaXMuc2VsZWN0ZWRJbmRleCA+PSB0aGlzLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiBub3RoaW5nIGlzIHNlbGVjdGVkIC0gc2VsZWN0IHRoZSBmaXJzdCB0YWJzIGdyb3VwXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RHcm91cEJ5SW5kZXgoMCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXBCeUluZGV4KHRoaXMuc2VsZWN0ZWRJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRTZWxlY3Rpb25PbkNvbGxlY3Rpb25DaGFuZ2VkKCk6IHZvaWQge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmdyb3Vwcy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgLy8gcGVyc2lzdCB0aGUgc2VsZWN0ZWQgaW5kZXggYW5kIGFwcGxpZWQgaXQgdG8gdGhlIG5ldyBjb2xsZWN0aW9uXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RHcm91cEJ5SW5kZXgodGhpcy5zZWxlY3RlZEluZGV4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleCA+PSB0aGlzLmdyb3Vwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaW4gY2FzZSB0aGUgc2VsZWN0ZWQgaW5kZXggaXMgbm8gbG9uZ2VyIHZhbGlkLCBzZWxlY3QgdGhlIGxhc3QgZ3JvdXAgaW4gdGhlIG5ldyBjb2xsZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0R3JvdXBCeUluZGV4KHRoaXMuZ3JvdXBzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZWxlY3RHcm91cEJ5SW5kZXgoc2VsZWN0ZWRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGFibGVHcm91cHMgPSB0aGlzLmdyb3Vwcy5maWx0ZXIoKHNlbGVjdGFibGVHcm91cCkgPT4gIXNlbGVjdGFibGVHcm91cC5kaXNhYmxlZCk7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gc2VsZWN0YWJsZUdyb3Vwc1tzZWxlY3RlZEluZGV4XTtcblxuICAgICAgICBpZiAoZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwLnNlbGVjdCgwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZGVzZWxlY3RHcm91cChncm91cDogSWd4VGFic0dyb3VwQ29tcG9uZW50KTogdm9pZCB7XG4gICAgICAgIC8vIENhbm5vdCBkZXNlbGVjdCB0aGUgc2VsZWN0ZWQgdGFiIC0gdGhpcyB3aWxsIG1lYW4gdGhhdCB0aGVyZSB3aWxsIGJlIG5vdCBzZWxlY3RlZCB0YWIgbGVmdFxuICAgICAgICBpZiAoZ3JvdXAuZGlzYWJsZWQgfHwgdGhpcy5zZWxlY3RlZFRhYkl0ZW0uaW5kZXggPT09IGdyb3VwLmluZGV4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBncm91cC5pc1NlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgIGdyb3VwLnJlbGF0ZWRUYWIudGFiaW5kZXggPSAtMTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNjcm9sbChzY3JvbGxSaWdodDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCB0YWJzQXJyYXkgPSB0aGlzLnRhYnMudG9BcnJheSgpO1xuICAgICAgICBmb3IgKGNvbnN0IHRhYiBvZiB0YWJzQXJyYXkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0YWIubmF0aXZlVGFiSXRlbS5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgaWYgKHNjcm9sbFJpZ2h0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQub2Zmc2V0V2lkdGggKyBlbGVtZW50Lm9mZnNldExlZnQgPiB0aGlzLnZpZXdQb3J0Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggKyB0aGlzLm9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEVsZW1lbnQoZWxlbWVudCwgc2Nyb2xsUmlnaHQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50Lm9mZnNldFdpZHRoICsgZWxlbWVudC5vZmZzZXRMZWZ0ID49IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsRWxlbWVudChlbGVtZW50LCBzY3JvbGxSaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbkBOZ01vZHVsZSh7XG4gICAgZGVjbGFyYXRpb25zOiBbSWd4VGFic0NvbXBvbmVudCxcbiAgICAgICAgSWd4VGFic0dyb3VwQ29tcG9uZW50LFxuICAgICAgICBJZ3hUYWJJdGVtQ29tcG9uZW50LFxuICAgICAgICBJZ3hUYWJJdGVtVGVtcGxhdGVEaXJlY3RpdmUsXG4gICAgICAgIElneFJpZ2h0QnV0dG9uU3R5bGVEaXJlY3RpdmUsXG4gICAgICAgIElneExlZnRCdXR0b25TdHlsZURpcmVjdGl2ZV0sXG4gICAgZXhwb3J0czogW0lneFRhYnNDb21wb25lbnQsXG4gICAgICAgIElneFRhYnNHcm91cENvbXBvbmVudCxcbiAgICAgICAgSWd4VGFiSXRlbUNvbXBvbmVudCxcbiAgICAgICAgSWd4VGFiSXRlbVRlbXBsYXRlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hSaWdodEJ1dHRvblN0eWxlRGlyZWN0aXZlLFxuICAgICAgICBJZ3hMZWZ0QnV0dG9uU3R5bGVEaXJlY3RpdmVdLFxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIElneEJhZGdlTW9kdWxlLCBJZ3hJY29uTW9kdWxlLCBJZ3hSaXBwbGVNb2R1bGVdXG59KVxuXG5leHBvcnQgY2xhc3MgSWd4VGFic01vZHVsZSB7XG59XG4iXX0=