ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
581 lines • 74.6 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { FocusKeyManager } from '@angular/cdk/a11y';
import { coerceNumberProperty } from '@angular/cdk/coercion';
import { DOWN_ARROW, ENTER, LEFT_ARROW, RIGHT_ARROW, SPACE, UP_ARROW, hasModifierKey } from '@angular/cdk/keycodes';
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, booleanAttribute } from '@angular/core';
import { Subject, animationFrameScheduler, asapScheduler, merge, of } from 'rxjs';
import { auditTime, takeUntil } from 'rxjs/operators';
import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill';
import { NzTabAddButtonComponent } from './tab-add-button.component';
import { NzTabNavItemDirective } from './tab-nav-item.directive';
import { NzTabNavOperationComponent } from './tab-nav-operation.component';
import { NzTabScrollListDirective } from './tab-scroll-list.directive';
import { NzTabsInkBarDirective } from './tabs-ink-bar.directive';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/overlay";
import * as i2 from "ng-zorro-antd/cdk/resize-observer";
import * as i3 from "@angular/cdk/bidi";
const RESIZE_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
const CSS_TRANSFORM_TIME = 150;
export class NzTabNavBarComponent {
get selectedIndex() {
return this._selectedIndex;
}
set selectedIndex(value) {
const newValue = coerceNumberProperty(value);
if (this._selectedIndex !== newValue) {
this._selectedIndex = value;
this.selectedIndexChanged = true;
if (this.keyManager) {
this.keyManager.updateActiveItem(value);
}
}
}
/** Tracks which element has focus; used for keyboard navigation */
get focusIndex() {
return this.keyManager ? this.keyManager.activeItemIndex : 0;
}
/** When the focus index is set, we must manually send focus to the correct label */
set focusIndex(value) {
if (!this.isValidIndex(value) || this.focusIndex === value || !this.keyManager) {
return;
}
this.keyManager.setActiveItem(value);
}
get showAddButton() {
return this.hiddenItems.length === 0 && this.addable;
}
constructor(cdr, ngZone, viewportRuler, nzResizeObserver, dir) {
this.cdr = cdr;
this.ngZone = ngZone;
this.viewportRuler = viewportRuler;
this.nzResizeObserver = nzResizeObserver;
this.dir = dir;
this.indexFocused = new EventEmitter();
this.selectFocusedIndex = new EventEmitter();
this.addClicked = new EventEmitter();
this.tabScroll = new EventEmitter();
this.position = 'horizontal';
this.addable = false;
this.hideBar = false;
this.addIcon = 'plus';
this.inkBarAnimated = true;
this.translate = null;
this.transformX = 0;
this.transformY = 0;
this.pingLeft = false;
this.pingRight = false;
this.pingTop = false;
this.pingBottom = false;
this.hiddenItems = [];
this.destroy$ = new Subject();
this._selectedIndex = 0;
this.wrapperWidth = 0;
this.wrapperHeight = 0;
this.scrollListWidth = 0;
this.scrollListHeight = 0;
this.operationWidth = 0;
this.operationHeight = 0;
this.addButtonWidth = 0;
this.addButtonHeight = 0;
this.selectedIndexChanged = false;
}
ngAfterViewInit() {
const dirChange = this.dir ? this.dir.change.asObservable() : of(null);
const resize = this.viewportRuler.change(150);
const realign = () => {
this.updateScrollListPosition();
this.alignInkBarToSelectedTab();
};
this.keyManager = new FocusKeyManager(this.items)
.withHorizontalOrientation(this.getLayoutDirection())
.withWrap();
this.keyManager.updateActiveItem(this.selectedIndex);
reqAnimFrame(realign);
merge(this.nzResizeObserver.observe(this.navWarpRef), this.nzResizeObserver.observe(this.navListRef))
.pipe(takeUntil(this.destroy$), auditTime(16, RESIZE_SCHEDULER))
.subscribe(() => {
realign();
});
merge(dirChange, resize, this.items.changes)
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
Promise.resolve().then(realign);
this.keyManager.withHorizontalOrientation(this.getLayoutDirection());
});
this.keyManager.change.pipe(takeUntil(this.destroy$)).subscribe(newFocusIndex => {
this.indexFocused.emit(newFocusIndex);
this.setTabFocus(newFocusIndex);
this.scrollToTab(this.keyManager.activeItem);
});
}
ngAfterContentChecked() {
if (this.selectedIndexChanged) {
this.updateScrollListPosition();
this.alignInkBarToSelectedTab();
this.selectedIndexChanged = false;
this.cdr.markForCheck();
}
}
ngOnDestroy() {
clearTimeout(this.lockAnimationTimeoutId);
clearTimeout(this.cssTransformTimeWaitingId);
this.destroy$.next();
this.destroy$.complete();
}
onSelectedFromMenu(tab) {
const tabIndex = this.items.toArray().findIndex(e => e === tab);
if (tabIndex !== -1) {
this.keyManager.updateActiveItem(tabIndex);
if (this.focusIndex !== this.selectedIndex) {
this.selectFocusedIndex.emit(this.focusIndex);
this.scrollToTab(tab);
}
}
}
onOffsetChange(e) {
if (this.position === 'horizontal') {
if (!this.lockAnimationTimeoutId) {
if (this.transformX >= 0 && e.x > 0) {
return;
}
if (this.transformX <= this.wrapperWidth - this.scrollListWidth && e.x < 0) {
return;
}
}
e.event.preventDefault();
this.transformX = this.clampTransformX(this.transformX + e.x);
this.setTransform(this.transformX, 0);
}
else {
if (!this.lockAnimationTimeoutId) {
if (this.transformY >= 0 && e.y > 0) {
return;
}
if (this.transformY <= this.wrapperHeight - this.scrollListHeight && e.y < 0) {
return;
}
}
e.event.preventDefault();
this.transformY = this.clampTransformY(this.transformY + e.y);
this.setTransform(0, this.transformY);
}
this.lockAnimation();
this.setVisibleRange();
this.setPingStatus();
}
handleKeydown(event) {
const inNavigationList = this.navWarpRef.nativeElement.contains(event.target);
if (hasModifierKey(event) || !inNavigationList) {
return;
}
switch (event.keyCode) {
case LEFT_ARROW:
case UP_ARROW:
case RIGHT_ARROW:
case DOWN_ARROW:
this.lockAnimation();
this.keyManager.onKeydown(event);
break;
case ENTER:
case SPACE:
if (this.focusIndex !== this.selectedIndex) {
this.selectFocusedIndex.emit(this.focusIndex);
}
break;
default:
this.keyManager.onKeydown(event);
}
}
isValidIndex(index) {
if (!this.items) {
return true;
}
const tab = this.items ? this.items.toArray()[index] : null;
return !!tab && !tab.disabled;
}
scrollToTab(tab) {
if (!this.items.find(e => e === tab)) {
return;
}
const tabs = this.items.toArray();
if (this.position === 'horizontal') {
let newTransform = this.transformX;
if (this.getLayoutDirection() === 'rtl') {
const right = tabs[0].left + tabs[0].width - tab.left - tab.width;
if (right < this.transformX) {
newTransform = right;
}
else if (right + tab.width > this.transformX + this.wrapperWidth) {
newTransform = right + tab.width - this.wrapperWidth;
}
}
else if (tab.left < -this.transformX) {
newTransform = -tab.left;
}
else if (tab.left + tab.width > -this.transformX + this.wrapperWidth) {
newTransform = -(tab.left + tab.width - this.wrapperWidth);
}
this.transformX = newTransform;
this.transformY = 0;
this.setTransform(newTransform, 0);
}
else {
let newTransform = this.transformY;
if (tab.top < -this.transformY) {
newTransform = -tab.top;
}
else if (tab.top + tab.height > -this.transformY + this.wrapperHeight) {
newTransform = -(tab.top + tab.height - this.wrapperHeight);
}
this.transformY = newTransform;
this.transformX = 0;
this.setTransform(0, newTransform);
}
clearTimeout(this.cssTransformTimeWaitingId);
this.cssTransformTimeWaitingId = setTimeout(() => {
this.setVisibleRange();
}, CSS_TRANSFORM_TIME);
}
lockAnimation() {
if (!this.lockAnimationTimeoutId) {
this.ngZone.runOutsideAngular(() => {
this.navListRef.nativeElement.style.transition = 'none';
this.lockAnimationTimeoutId = setTimeout(() => {
this.navListRef.nativeElement.style.transition = '';
this.lockAnimationTimeoutId = undefined;
}, CSS_TRANSFORM_TIME);
});
}
}
setTransform(x, y) {
this.navListRef.nativeElement.style.transform = `translate(${x}px, ${y}px)`;
}
clampTransformX(transform) {
const scrollWidth = this.wrapperWidth - this.scrollListWidth;
if (this.getLayoutDirection() === 'rtl') {
return Math.max(Math.min(scrollWidth, transform), 0);
}
else {
return Math.min(Math.max(scrollWidth, transform), 0);
}
}
clampTransformY(transform) {
return Math.min(Math.max(this.wrapperHeight - this.scrollListHeight, transform), 0);
}
updateScrollListPosition() {
this.resetSizes();
this.transformX = this.clampTransformX(this.transformX);
this.transformY = this.clampTransformY(this.transformY);
this.setVisibleRange();
this.setPingStatus();
if (this.keyManager) {
this.keyManager.updateActiveItem(this.keyManager.activeItemIndex);
if (this.keyManager.activeItem) {
this.scrollToTab(this.keyManager.activeItem);
}
}
}
resetSizes() {
this.addButtonWidth = this.addBtnRef ? this.addBtnRef.getElementWidth() : 0;
this.addButtonHeight = this.addBtnRef ? this.addBtnRef.getElementHeight() : 0;
this.operationWidth = this.operationRef.getElementWidth();
this.operationHeight = this.operationRef.getElementHeight();
this.wrapperWidth = this.navWarpRef.nativeElement.offsetWidth || 0;
this.wrapperHeight = this.navWarpRef.nativeElement.offsetHeight || 0;
this.scrollListHeight = this.navListRef.nativeElement.offsetHeight || 0;
this.scrollListWidth = this.navListRef.nativeElement.offsetWidth || 0;
}
alignInkBarToSelectedTab() {
const selectedItem = this.items && this.items.length ? this.items.toArray()[this.selectedIndex] : null;
const selectedItemElement = selectedItem ? selectedItem.elementRef.nativeElement : null;
if (selectedItemElement) {
/**
* .ant-tabs-nav-list - Target offset parent element
* └──.ant-tabs-tab
* └──.ant-tabs-tab-btn - Currently focused element
*/
this.inkBar.alignToElement(selectedItemElement.parentElement);
}
}
setPingStatus() {
const ping = {
top: false,
right: false,
bottom: false,
left: false
};
const navWarp = this.navWarpRef.nativeElement;
if (this.position === 'horizontal') {
if (this.getLayoutDirection() === 'rtl') {
ping.right = this.transformX > 0;
ping.left = this.transformX + this.wrapperWidth < this.scrollListWidth;
}
else {
ping.left = this.transformX < 0;
ping.right = -this.transformX + this.wrapperWidth < this.scrollListWidth;
}
}
else {
ping.top = this.transformY < 0;
ping.bottom = -this.transformY + this.wrapperHeight < this.scrollListHeight;
}
Object.keys(ping).forEach(pos => {
const className = `ant-tabs-nav-wrap-ping-${pos}`;
if (ping[pos]) {
navWarp.classList.add(className);
}
else {
navWarp.classList.remove(className);
}
});
}
setVisibleRange() {
let unit;
let position;
let transformSize;
let basicSize;
let tabContentSize;
let addSize;
const tabs = this.items.toArray();
const DEFAULT_SIZE = { width: 0, height: 0, left: 0, top: 0, right: 0 };
const getOffset = (index) => {
let offset;
const size = tabs[index] || DEFAULT_SIZE;
if (position === 'right') {
offset = tabs[0].left + tabs[0].width - tabs[index].left - tabs[index].width;
}
else {
offset = size[position];
}
return offset;
};
if (this.position === 'horizontal') {
unit = 'width';
basicSize = this.wrapperWidth;
tabContentSize = this.scrollListWidth - (this.hiddenItems.length ? this.operationWidth : 0);
addSize = this.addButtonWidth;
transformSize = Math.abs(this.transformX);
if (this.getLayoutDirection() === 'rtl') {
position = 'right';
this.pingRight = this.transformX > 0;
this.pingLeft = this.transformX + this.wrapperWidth < this.scrollListWidth;
}
else {
this.pingLeft = this.transformX < 0;
this.pingRight = -this.transformX + this.wrapperWidth < this.scrollListWidth;
position = 'left';
}
}
else {
unit = 'height';
basicSize = this.wrapperHeight;
tabContentSize = this.scrollListHeight - (this.hiddenItems.length ? this.operationHeight : 0);
addSize = this.addButtonHeight;
position = 'top';
transformSize = -this.transformY;
this.pingTop = this.transformY < 0;
this.pingBottom = -this.transformY + this.wrapperHeight < this.scrollListHeight;
}
let mergedBasicSize = basicSize;
if (tabContentSize + addSize > basicSize) {
mergedBasicSize = basicSize - addSize;
}
if (!tabs.length) {
this.hiddenItems = [];
this.cdr.markForCheck();
return;
}
const len = tabs.length;
let endIndex = len;
for (let i = 0; i < len; i += 1) {
const offset = getOffset(i);
const size = tabs[i] || DEFAULT_SIZE;
if (offset + size[unit] > transformSize + mergedBasicSize) {
endIndex = i - 1;
break;
}
}
let startIndex = 0;
for (let i = len - 1; i >= 0; i -= 1) {
const offset = getOffset(i);
if (offset < transformSize) {
startIndex = i + 1;
break;
}
}
const startHiddenTabs = tabs.slice(0, startIndex);
const endHiddenTabs = tabs.slice(endIndex + 1);
this.hiddenItems = [...startHiddenTabs, ...endHiddenTabs];
this.cdr.markForCheck();
}
getLayoutDirection() {
return this.dir && this.dir.value === 'rtl' ? 'rtl' : 'ltr';
}
setTabFocus(_tabIndex) { }
ngOnChanges(changes) {
const { position } = changes;
// The first will be aligning in ngAfterViewInit
if (position && !position.isFirstChange()) {
this.alignInkBarToSelectedTab();
this.lockAnimation();
this.updateScrollListPosition();
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NzTabNavBarComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1.ViewportRuler }, { token: i2.NzResizeObserver }, { token: i3.Directionality }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.1", type: NzTabNavBarComponent, isStandalone: true, selector: "nz-tabs-nav", inputs: { position: "position", addable: ["addable", "addable", booleanAttribute], hideBar: ["hideBar", "hideBar", booleanAttribute], addIcon: "addIcon", inkBarAnimated: "inkBarAnimated", extraTemplate: "extraTemplate", selectedIndex: "selectedIndex" }, outputs: { indexFocused: "indexFocused", selectFocusedIndex: "selectFocusedIndex", addClicked: "addClicked", tabScroll: "tabScroll" }, host: { listeners: { "keydown": "handleKeydown($event)" }, classAttribute: "ant-tabs-nav" }, queries: [{ propertyName: "items", predicate: NzTabNavItemDirective, descendants: true }], viewQueries: [{ propertyName: "navWarpRef", first: true, predicate: ["navWarp"], descendants: true, static: true }, { propertyName: "navListRef", first: true, predicate: ["navList"], descendants: true, static: true }, { propertyName: "operationRef", first: true, predicate: NzTabNavOperationComponent, descendants: true, static: true }, { propertyName: "addBtnRef", first: true, predicate: NzTabAddButtonComponent, descendants: true }, { propertyName: "inkBar", first: true, predicate: NzTabsInkBarDirective, descendants: true, static: true }], exportAs: ["nzTabsNav"], usesOnChanges: true, ngImport: i0, template: `
<div
class="ant-tabs-nav-wrap"
[class.ant-tabs-nav-wrap-ping-left]="pingLeft"
[class.ant-tabs-nav-wrap-ping-right]="pingRight"
[class.ant-tabs-nav-wrap-ping-top]="pingTop"
[class.ant-tabs-nav-wrap-ping-bottom]="pingBottom"
#navWarp
>
<div
class="ant-tabs-nav-list"
#navList
nzTabScrollList
(offsetChange)="onOffsetChange($event)"
(tabScroll)="tabScroll.emit($event)"
role="tablist"
>
<ng-content></ng-content>
@if (showAddButton) {
<button
role="tab"
[attr.tabindex]="-1"
nz-tab-add-button
[addIcon]="addIcon"
(click)="addClicked.emit()"
></button>
}
<div nz-tabs-ink-bar [hidden]="hideBar" [position]="position" [animated]="inkBarAnimated"></div>
</div>
</div>
<nz-tab-nav-operation
(addClicked)="addClicked.emit()"
(selected)="onSelectedFromMenu($event)"
[addIcon]="addIcon"
[addable]="addable"
[items]="hiddenItems"
></nz-tab-nav-operation>
@if (extraTemplate) {
<div class="ant-tabs-extra-content">
<ng-template [ngTemplateOutlet]="extraTemplate"></ng-template>
</div>
}
`, isInline: true, dependencies: [{ kind: "directive", type: NzTabScrollListDirective, selector: "[nzTabScrollList]", outputs: ["offsetChange", "tabScroll"] }, { kind: "component", type: NzTabAddButtonComponent, selector: "nz-tab-add-button, button[nz-tab-add-button]", inputs: ["addIcon"] }, { kind: "directive", type: NzTabsInkBarDirective, selector: "nz-tabs-ink-bar, [nz-tabs-ink-bar]", inputs: ["position", "animated"] }, { kind: "component", type: NzTabNavOperationComponent, selector: "nz-tab-nav-operation", inputs: ["items", "addable", "addIcon"], outputs: ["addClicked", "selected"], exportAs: ["nzTabNavOperation"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.1", ngImport: i0, type: NzTabNavBarComponent, decorators: [{
type: Component,
args: [{
selector: 'nz-tabs-nav',
exportAs: 'nzTabsNav',
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
template: `
<div
class="ant-tabs-nav-wrap"
[class.ant-tabs-nav-wrap-ping-left]="pingLeft"
[class.ant-tabs-nav-wrap-ping-right]="pingRight"
[class.ant-tabs-nav-wrap-ping-top]="pingTop"
[class.ant-tabs-nav-wrap-ping-bottom]="pingBottom"
#navWarp
>
<div
class="ant-tabs-nav-list"
#navList
nzTabScrollList
(offsetChange)="onOffsetChange($event)"
(tabScroll)="tabScroll.emit($event)"
role="tablist"
>
<ng-content></ng-content>
@if (showAddButton) {
<button
role="tab"
[attr.tabindex]="-1"
nz-tab-add-button
[addIcon]="addIcon"
(click)="addClicked.emit()"
></button>
}
<div nz-tabs-ink-bar [hidden]="hideBar" [position]="position" [animated]="inkBarAnimated"></div>
</div>
</div>
<nz-tab-nav-operation
(addClicked)="addClicked.emit()"
(selected)="onSelectedFromMenu($event)"
[addIcon]="addIcon"
[addable]="addable"
[items]="hiddenItems"
></nz-tab-nav-operation>
@if (extraTemplate) {
<div class="ant-tabs-extra-content">
<ng-template [ngTemplateOutlet]="extraTemplate"></ng-template>
</div>
}
`,
host: {
class: 'ant-tabs-nav',
'(keydown)': 'handleKeydown($event)'
},
imports: [
NzTabScrollListDirective,
NzTabAddButtonComponent,
NzTabsInkBarDirective,
NzTabNavOperationComponent,
NgTemplateOutlet
],
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.ViewportRuler }, { type: i2.NzResizeObserver }, { type: i3.Directionality }], propDecorators: { indexFocused: [{
type: Output
}], selectFocusedIndex: [{
type: Output
}], addClicked: [{
type: Output
}], tabScroll: [{
type: Output
}], position: [{
type: Input
}], addable: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], hideBar: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], addIcon: [{
type: Input
}], inkBarAnimated: [{
type: Input
}], extraTemplate: [{
type: Input
}], selectedIndex: [{
type: Input
}], navWarpRef: [{
type: ViewChild,
args: ['navWarp', { static: true }]
}], navListRef: [{
type: ViewChild,
args: ['navList', { static: true }]
}], operationRef: [{
type: ViewChild,
args: [NzTabNavOperationComponent, { static: true }]
}], addBtnRef: [{
type: ViewChild,
args: [NzTabAddButtonComponent, { static: false }]
}], inkBar: [{
type: ViewChild,
args: [NzTabsInkBarDirective, { static: true }]
}], items: [{
type: ContentChildren,
args: [NzTabNavItemDirective, { descendants: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLW5hdi1iYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy90YWJzL3RhYi1uYXYtYmFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFcEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXBILE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFHTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULGVBQWUsRUFFZixZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFJTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNqQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSTNELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzNFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3ZFLE9BQU8sRUFB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QUFRO3NCQUFoQixLQUFLO2dCQUNrQyxPQUFPO3NCQUE5QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUNFLE9BQU87c0JBQTlDLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBQzdCLE9BQU87c0JBQWYsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBR0YsYUFBYTtzQkFEaEIsS0FBSztnQkFla0MsVUFBVTtzQkFBakQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNFLFVBQVU7c0JBQWpELFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFDbUIsWUFBWTtzQkFBcEUsU0FBUzt1QkFBQywwQkFBMEIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ0EsU0FBUztzQkFBL0QsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBQ0QsTUFBTTtzQkFBekQsU0FBUzt1QkFBQyxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBQ2EsS0FBSztzQkFBbkUsZUFBZTt1QkFBQyxxQkFBcUIsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBGb2N1c0tleU1hbmFnZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBEaXJlY3Rpb24sIERpcmVjdGlvbmFsaXR5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHsgY29lcmNlTnVtYmVyUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgRE9XTl9BUlJPVywgRU5URVIsIExFRlRfQVJST1csIFJJR0hUX0FSUk9XLCBTUEFDRSwgVVBfQVJST1csIGhhc01vZGlmaWVyS2V5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IFZpZXdwb3J0UnVsZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgYm9vbGVhbkF0dHJpYnV0ZVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QsIGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyLCBhc2FwU2NoZWR1bGVyLCBtZXJnZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGF1ZGl0VGltZSwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBOelJlc2l6ZU9ic2VydmVyIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jZGsvcmVzaXplLW9ic2VydmVyJztcbmltcG9ydCB7IHJlcUFuaW1GcmFtZSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9wb2x5ZmlsbCc7XG5pbXBvcnQgeyBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuXG5pbXBvcnQgeyBOelRhYlBvc2l0aW9uTW9kZSwgTnpUYWJTY3JvbGxFdmVudCwgTnpUYWJTY3JvbGxMaXN0T2Zmc2V0RXZlbnQgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgTnpUYWJBZGRCdXR0b25Db21wb25lbnQgfSBmcm9tICcuL3RhYi1hZGQtYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelRhYk5hdkl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL3RhYi1uYXYtaXRlbS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnpUYWJOYXZPcGVyYXRpb25Db21wb25lbnQgfSBmcm9tICcuL3RhYi1uYXYtb3BlcmF0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOelRhYlNjcm9sbExpc3REaXJlY3RpdmUgfSBmcm9tICcuL3RhYi1zY3JvbGwtbGlzdC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnpUYWJzSW5rQmFyRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJzLWluay1iYXIuZGlyZWN0aXZlJztcblxuY29uc3QgUkVTSVpFX1NDSEVEVUxFUiA9IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgIT09ICd1bmRlZmluZWQnID8gYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIgOiBhc2FwU2NoZWR1bGVyO1xuY29uc3QgQ1NTX1RSQU5TRk9STV9USU1FID0gMTUwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10YWJzLW5hdicsXG4gIGV4cG9ydEFzOiAnbnpUYWJzTmF2JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiYW50LXRhYnMtbmF2LXdyYXBcIlxuICAgICAgW2NsYXNzLmFudC10YWJzLW5hdi13cmFwLXBpbmctbGVmdF09XCJwaW5nTGVmdFwiXG4gICAgICBbY2xhc3MuYW50LXRhYnMtbmF2LXdyYXAtcGluZy1yaWdodF09XCJwaW5nUmlnaHRcIlxuICAgICAgW2NsYXNzLmFudC10YWJzLW5hdi13cmFwLXBpbmctdG9wXT1cInBpbmdUb3BcIlxuICAgICAgW2NsYXNzLmFudC10YWJzLW5hdi13cmFwLXBpbmctYm90dG9tXT1cInBpbmdCb3R0b21cIlxuICAgICAgI25hdldhcnBcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtbmF2LWxpc3RcIlxuICAgICAgICAjbmF2TGlzdFxuICAgICAgICBuelRhYlNjcm9sbExpc3RcbiAgICAgICAgKG9mZnNldENoYW5nZSk9XCJvbk9mZnNldENoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgKHRhYlNjcm9sbCk9XCJ0YWJTY3JvbGwuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgcm9sZT1cInRhYmxpc3RcIlxuICAgICAgPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgIEBpZiAoc2hvd0FkZEJ1dHRvbikge1xuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHJvbGU9XCJ0YWJcIlxuICAgICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwiLTFcIlxuICAgICAgICAgICAgbnotdGFiLWFkZC1idXR0b25cbiAgICAgICAgICAgIFthZGRJY29uXT1cImFkZEljb25cIlxuICAgICAgICAgICAgKGNsaWNrKT1cImFkZENsaWNrZWQuZW1pdCgpXCJcbiAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgPGRpdiBuei10YWJzLWluay1iYXIgW2hpZGRlbl09XCJoaWRlQmFyXCIgW3Bvc2l0aW9uXT1cInBvc2l0aW9uXCIgW2FuaW1hdGVkXT1cImlua0JhckFuaW1hdGVkXCI+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8bnotdGFiLW5hdi1vcGVyYXRpb25cbiAgICAgIChhZGRDbGlja2VkKT1cImFkZENsaWNrZWQuZW1pdCgpXCJcbiAgICAgIChzZWxlY3RlZCk9XCJvblNlbGVjdGVkRnJvbU1lbnUoJGV2ZW50KVwiXG4gICAgICBbYWRkSWNvbl09XCJhZGRJY29uXCJcbiAgICAgIFthZGRhYmxlXT1cImFkZGFibGVcIlxuICAgICAgW2l0ZW1zXT1cImhpZGRlbkl0ZW1zXCJcbiAgICA+PC9uei10YWItbmF2LW9wZXJhdGlvbj5cbiAgICBAaWYgKGV4dHJhVGVtcGxhdGUpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJhbnQtdGFicy1leHRyYS1jb250ZW50XCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJleHRyYVRlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgYCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYW50LXRhYnMtbmF2JyxcbiAgICAnKGtleWRvd24pJzogJ2hhbmRsZUtleWRvd24oJGV2ZW50KSdcbiAgfSxcbiAgaW1wb3J0czogW1xuICAgIE56VGFiU2Nyb2xsTGlzdERpcmVjdGl2ZSxcbiAgICBOelRhYkFkZEJ1dHRvbkNvbXBvbmVudCxcbiAgICBOelRhYnNJbmtCYXJEaXJlY3RpdmUsXG4gICAgTnpUYWJOYXZPcGVyYXRpb25Db21wb25lbnQsXG4gICAgTmdUZW1wbGF0ZU91dGxldFxuICBdLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIE56VGFiTmF2QmFyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgaW5kZXhGb2N1c2VkOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgc2VsZWN0Rm9jdXNlZEluZGV4OiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgYWRkQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IHRhYlNjcm9sbCA9IG5ldyBFdmVudEVtaXR0ZXI8TnpUYWJTY3JvbGxFdmVudD4oKTtcblxuICBASW5wdXQoKSBwb3NpdGlvbjogTnpUYWJQb3NpdGlvbk1vZGUgPSAnaG9yaXpvbnRhbCc7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBhZGRhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBoaWRlQmFyOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGFkZEljb246IHN0cmluZyB8IFRlbXBsYXRlUmVmPE56U2FmZUFueT4gPSAncGx1cyc7XG4gIEBJbnB1dCgpIGlua0JhckFuaW1hdGVkID0gdHJ1ZTtcbiAgQElucHV0KCkgZXh0cmFUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPHZvaWQ+O1xuXG4gIEBJbnB1dCgpXG4gIGdldCBzZWxlY3RlZEluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgodmFsdWU6IG51bWJlcikge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gY29lcmNlTnVtYmVyUHJvcGVydHkodmFsdWUpO1xuICAgIGlmICh0aGlzLl9zZWxlY3RlZEluZGV4ICE9PSBuZXdWYWx1ZSkge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IHZhbHVlO1xuICAgICAgdGhpcy5zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IHRydWU7XG4gICAgICBpZiAodGhpcy5rZXlNYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMua2V5TWFuYWdlci51cGRhdGVBY3RpdmVJdGVtKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBAVmlld0NoaWxkKCduYXZXYXJwJywgeyBzdGF0aWM6IHRydWUgfSkgbmF2V2FycFJlZiE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCduYXZMaXN0JywgeyBzdGF0aWM6IHRydWUgfSkgbmF2TGlzdFJlZiE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKE56VGFiTmF2T3BlcmF0aW9uQ29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KSBvcGVyYXRpb25SZWYhOiBOelRhYk5hdk9wZXJhdGlvbkNvbXBvbmVudDtcbiAgQFZpZXdDaGlsZChOelRhYkFkZEJ1dHRvbkNvbXBvbmVudCwgeyBzdGF0aWM6IGZhbHNlIH0pIGFkZEJ0blJlZiE6IE56VGFiQWRkQnV0dG9uQ29tcG9uZW50O1xuICBAVmlld0NoaWxkKE56VGFic0lua0JhckRpcmVjdGl2ZSwgeyBzdGF0aWM6IHRydWUgfSkgaW5rQmFyITogTnpUYWJzSW5rQmFyRGlyZWN0aXZlO1xuICBAQ29udGVudENoaWxkcmVuKE56VGFiTmF2SXRlbURpcmVjdGl2ZSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KSBpdGVtcyE6IFF1ZXJ5TGlzdDxOelRhYk5hdkl0ZW1EaXJlY3RpdmU+O1xuXG4gIC8qKiBUcmFja3Mgd2hpY2ggZWxlbWVudCBoYXMgZm9jdXM7IHVzZWQgZm9yIGtleWJvYXJkIG5hdmlnYXRpb24gKi9cbiAgZ2V0IGZvY3VzSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5rZXlNYW5hZ2VyID8gdGhpcy5rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCEgOiAwO1xuICB9XG5cbiAgLyoqIFdoZW4gdGhlIGZvY3VzIGluZGV4IGlzIHNldCwgd2UgbXVzdCBtYW51YWxseSBzZW5kIGZvY3VzIHRvIHRoZSBjb3JyZWN0IGxhYmVsICovXG4gIHNldCBmb2N1c0luZGV4KHZhbHVlOiBudW1iZXIpIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZEluZGV4KHZhbHVlKSB8fCB0aGlzLmZvY3VzSW5kZXggPT09IHZhbHVlIHx8ICF0aGlzLmtleU1hbmFnZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmtleU1hbmFnZXIuc2V0QWN0aXZlSXRlbSh2YWx1ZSk7XG4gIH1cblxuICBnZXQgc2hvd0FkZEJ1dHRvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5oaWRkZW5JdGVtcy5sZW5ndGggPT09IDAgJiYgdGhpcy5hZGRhYmxlO1xuICB9XG5cbiAgdHJhbnNsYXRlOiBudWxsIHwgc3RyaW5nID0gbnVsbDtcbiAgdHJhbnNmb3JtWCA9IDA7XG4gIHRyYW5zZm9ybVkgPSAwO1xuICBwaW5nTGVmdCA9IGZhbHNlO1xuICBwaW5nUmlnaHQgPSBmYWxzZTtcbiAgcGluZ1RvcCA9IGZhbHNlO1xuICBwaW5nQm90dG9tID0gZmFsc2U7XG4gIGhpZGRlbkl0ZW1zOiBOelRhYk5hdkl0ZW1EaXJlY3RpdmVbXSA9IFtdO1xuXG4gIHByaXZhdGUga2V5TWFuYWdlciE6IEZvY3VzS2V5TWFuYWdlcjxOelRhYk5hdkl0ZW1EaXJlY3RpdmU+O1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSBfc2VsZWN0ZWRJbmRleCA9IDA7XG4gIHByaXZhdGUgd3JhcHBlcldpZHRoID0gMDtcbiAgcHJpdmF0ZSB3cmFwcGVySGVpZ2h0ID0gMDtcbiAgcHJpdmF0ZSBzY3JvbGxMaXN0V2lkdGggPSAwO1xuICBwcml2YXRlIHNjcm9sbExpc3RIZWlnaHQgPSAwO1xuICBwcml2YXRlIG9wZXJhdGlvbldpZHRoID0gMDtcbiAgcHJpdmF0ZSBvcGVyYXRpb25IZWlnaHQgPSAwO1xuICBwcml2YXRlIGFkZEJ1dHRvbldpZHRoID0gMDtcbiAgcHJpdmF0ZSBhZGRCdXR0b25IZWlnaHQgPSAwO1xuICBwcml2YXRlIHNlbGVjdGVkSW5kZXhDaGFuZ2VkID0gZmFsc2U7XG4gIHByaXZhdGUgbG9ja0FuaW1hdGlvblRpbWVvdXRJZD86IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+O1xuICBwcml2YXRlIGNzc1RyYW5zZm9ybVRpbWVXYWl0aW5nSWQ/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHZpZXdwb3J0UnVsZXI6IFZpZXdwb3J0UnVsZXIsXG4gICAgcHJpdmF0ZSBuelJlc2l6ZU9ic2VydmVyOiBOelJlc2l6ZU9ic2VydmVyLFxuICAgIHByaXZhdGUgZGlyOiBEaXJlY3Rpb25hbGl0eVxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IGRpckNoYW5nZSA9IHRoaXMuZGlyID8gdGhpcy5kaXIuY2hhbmdlLmFzT2JzZXJ2YWJsZSgpIDogb2YobnVsbCk7XG4gICAgY29uc3QgcmVzaXplID0gdGhpcy52aWV3cG9ydFJ1bGVyLmNoYW5nZSgxNTApO1xuXG4gICAgY29uc3QgcmVhbGlnbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgIHRoaXMudXBkYXRlU2Nyb2xsTGlzdFBvc2l0aW9uKCk7XG4gICAgICB0aGlzLmFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpO1xuICAgIH07XG4gICAgdGhpcy5rZXlNYW5hZ2VyID0gbmV3IEZvY3VzS2V5TWFuYWdlcjxOelRhYk5hdkl0ZW1EaXJlY3RpdmU+KHRoaXMuaXRlbXMpXG4gICAgICAud2l0aEhvcml6b250YWxPcmllbnRhdGlvbih0aGlzLmdldExheW91dERpcmVjdGlvbigpKVxuICAgICAgLndpdGhXcmFwKCk7XG4gICAgdGhpcy5rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0odGhpcy5zZWxlY3RlZEluZGV4KTtcblxuICAgIHJlcUFuaW1GcmFtZShyZWFsaWduKTtcblxuICAgIG1lcmdlKHRoaXMubnpSZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMubmF2V2FycFJlZiksIHRoaXMubnpSZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMubmF2TGlzdFJlZikpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCksIGF1ZGl0VGltZSgxNiwgUkVTSVpFX1NDSEVEVUxFUikpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgcmVhbGlnbigpO1xuICAgICAgfSk7XG4gICAgbWVyZ2UoZGlyQ2hhbmdlLCByZXNpemUsIHRoaXMuaXRlbXMuY2hhbmdlcylcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKHJlYWxpZ24pO1xuICAgICAgICB0aGlzLmtleU1hbmFnZXIud2l0aEhvcml6b250YWxPcmllbnRhdGlvbih0aGlzLmdldExheW91dERpcmVjdGlvbigpKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5rZXlNYW5hZ2VyLmNoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKG5ld0ZvY3VzSW5kZXggPT4ge1xuICAgICAgdGhpcy5pbmRleEZvY3VzZWQuZW1pdChuZXdGb2N1c0luZGV4KTtcbiAgICAgIHRoaXMuc2V0VGFiRm9jdXMobmV3Rm9jdXNJbmRleCk7XG4gICAgICB0aGlzLnNjcm9sbFRvVGFiKHRoaXMua2V5TWFuYWdlci5hY3RpdmVJdGVtISk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleENoYW5nZWQpIHtcbiAgICAgIHRoaXMudXBkYXRlU2Nyb2xsTGlzdFBvc2l0aW9uKCk7XG4gICAgICB0aGlzLmFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpO1xuICAgICAgdGhpcy5zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMubG9ja0FuaW1hdGlvblRpbWVvdXRJZCk7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY3NzVHJhbnNmb3JtVGltZVdhaXRpbmdJZCk7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgb25TZWxlY3RlZEZyb21NZW51KHRhYjogTnpUYWJOYXZJdGVtRGlyZWN0aXZlKTogdm9pZCB7XG4gICAgY29uc3QgdGFiSW5kZXggPSB0aGlzLml0ZW1zLnRvQXJyYXkoKS5maW5kSW5kZXgoZSA9PiBlID09PSB0YWIpO1xuICAgIGlmICh0YWJJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMua2V5TWFuYWdlci51cGRhdGVBY3RpdmVJdGVtKHRhYkluZGV4KTtcbiAgICAgIGlmICh0aGlzLmZvY3VzSW5kZXggIT09IHRoaXMuc2VsZWN0ZWRJbmRleCkge1xuICAgICAgICB0aGlzLnNlbGVjdEZvY3VzZWRJbmRleC5lbWl0KHRoaXMuZm9jdXNJbmRleCk7XG4gICAgICAgIHRoaXMuc2Nyb2xsVG9UYWIodGFiKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbk9mZnNldENoYW5nZShlOiBOelRhYlNjcm9sbExpc3RPZmZzZXRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnBvc2l0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIGlmICghdGhpcy5sb2NrQW5pbWF0aW9uVGltZW91dElkKSB7XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybVggPj0gMCAmJiBlLnggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRyYW5zZm9ybVggPD0gdGhpcy53cmFwcGVyV2lkdGggLSB0aGlzLnNjcm9sbExpc3RXaWR0aCAmJiBlLnggPCAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlLmV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLnRyYW5zZm9ybVggPSB0aGlzLmNsYW1wVHJhbnNmb3JtWCh0aGlzLnRyYW5zZm9ybVggKyBlLngpO1xuICAgICAgdGhpcy5zZXRUcmFuc2Zvcm0odGhpcy50cmFuc2Zvcm1YLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF0aGlzLmxvY2tBbmltYXRpb25UaW1lb3V0SWQpIHtcbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtWSA+PSAwICYmIGUueSA+IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhbnNmb3JtWSA8PSB0aGlzLndyYXBwZXJIZWlnaHQgLSB0aGlzLnNjcm9sbExpc3RIZWlnaHQgJiYgZS55IDwgMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZS5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy50cmFuc2Zvcm1ZID0gdGhpcy5jbGFtcFRyYW5zZm9ybVkodGhpcy50cmFuc2Zvcm1ZICsgZS55KTtcbiAgICAgIHRoaXMuc2V0VHJhbnNmb3JtKDAsIHRoaXMudHJhbnNmb3JtWSk7XG4gICAgfVxuXG4gICAgdGhpcy5sb2NrQW5pbWF0aW9uKCk7XG4gICAgdGhpcy5zZXRWaXNpYmxlUmFuZ2UoKTtcbiAgICB0aGlzLnNldFBpbmdTdGF0dXMoKTtcbiAgfVxuXG4gIGhhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBpbk5hdmlnYXRpb25MaXN0ID0gdGhpcy5uYXZXYXJwUmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KTtcbiAgICBpZiAoaGFzTW9kaWZpZXJLZXkoZXZlbnQpIHx8ICFpbk5hdmlnYXRpb25MaXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChldmVudC5rZXlDb2RlKSB7XG4gICAgICBjYXNlIExFRlRfQVJST1c6XG4gICAgICBjYXNlIFVQX0FSUk9XOlxuICAgICAgY2FzZSBSSUdIVF9BUlJPVzpcbiAgICAgIGNhc2UgRE9XTl9BUlJPVzpcbiAgICAgICAgdGhpcy5sb2NrQW5pbWF0aW9uKCk7XG4gICAgICAgIHRoaXMua2V5TWFuYWdlci5vbktleWRvd24oZXZlbnQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRU5URVI6XG4gICAgICBjYXNlIFNQQUNFOlxuICAgICAgICBpZiAodGhpcy5mb2N1c0luZGV4ICE9PSB0aGlzLnNlbGVjdGVkSW5kZXgpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdEZvY3VzZWRJbmRleC5lbWl0KHRoaXMuZm9jdXNJbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aGlzLmtleU1hbmFnZXIub25LZXlkb3duKGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWRJbmRleChpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLml0ZW1zKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB0YWIgPSB0aGlzLml0ZW1zID8gdGhpcy5pdGVtcy50b0FycmF5KClbaW5kZXhdIDogbnVsbDtcbiAgICByZXR1cm4gISF0YWIgJiYgIXRhYi5kaXNhYmxlZDtcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9UYWIodGFiOiBOelRhYk5hdkl0ZW1EaXJlY3RpdmUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXRlbXMuZmluZChlID0+IGUgPT09IHRhYikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdGFicyA9IHRoaXMuaXRlbXMudG9BcnJheSgpO1xuXG4gICAgaWYgKHRoaXMucG9zaXRpb24gPT09ICdob3Jpem9udGFsJykge1xuICAgICAgbGV0IG5ld1RyYW5zZm9ybSA9IHRoaXMudHJhbnNmb3JtWDtcbiAgICAgIGlmICh0aGlzLmdldExheW91dERpcmVjdGlvbigpID09PSAncnRsJykge1xuICAgICAgICBjb25zdCByaWdodCA9IHRhYnNbMF0ubGVmdCArIHRhYnNbMF0ud2lkdGggLSB0YWIubGVmdCAtIHRhYi53aWR0aDtcblxuICAgICAgICBpZiAocmlnaHQgPCB0aGlzLnRyYW5zZm9ybVgpIHtcbiAgICAgICAgICBuZXdUcmFuc2Zvcm0gPSByaWdodDtcbiAgICAgICAgfSBlbHNlIGlmIChyaWdodCArIHRhYi53aWR0aCA+IHRoaXMudHJhbnNmb3JtWCArIHRoaXMud3JhcHBlcldpZHRoKSB7XG4gICAgICAgICAgbmV3VHJhbnNmb3JtID0gcmlnaHQgKyB0YWIud2lkdGggLSB0aGlzLndyYXBwZXJXaWR0aDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0YWIubGVmdCA8IC10aGlzLnRyYW5zZm9ybVgpIHtcbiAgICAgICAgbmV3VHJhbnNmb3JtID0gLXRhYi5sZWZ0O1xuICAgICAgfSBlbHNlIGlmICh0YWIubGVmdCArIHRhYi53aWR0aCA+IC10aGlzLnRyYW5zZm9ybVggKyB0aGlzLndyYXBwZXJXaWR0aCkge1xuICAgICAgICBuZXdUcmFuc2Zvcm0gPSAtKHRhYi5sZWZ0ICsgdGFiLndpZHRoIC0gdGhpcy53cmFwcGVyV2lkdGgpO1xuICAgICAgfVxuICAgICAgdGhpcy50cmFuc2Zvcm1YID0gbmV3VHJhbnNmb3JtO1xuICAgICAgdGhpcy50cmFuc2Zvcm1ZID0gMDtcbiAgICAgIHRoaXMuc2V0VHJhbnNmb3JtKG5ld1RyYW5zZm9ybSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBuZXdUcmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybVk7XG5cbiAgICAgIGlmICh0YWIudG9wIDwgLXRoaXMudHJhbnNmb3JtWSkge1xuICAgICAgICBuZXdUcmFuc2Zvcm0gPSAtdGFiLnRvcDtcbiAgICAgIH0gZWxzZSBpZiAodGFiLnRvcCArIHRhYi5oZWlnaHQgPiAtdGhpcy50cmFuc2Zvcm1ZICsgdGhpcy53cmFwcGVySGVpZ2h0KSB7XG4gICAgICAgIG5ld1RyYW5zZm9ybSA9IC0odGFiLnRvcCArIHRhYi5oZWlnaHQgLSB0aGlzLndyYXBwZXJIZWlnaHQpO1xuICAgICAgfVxuICAgICAgdGhpcy50cmFuc2Zvcm1ZID0gbmV3VHJhbnNmb3JtO1xuICAgICAgdGhpcy50cmFuc2Zvcm1YID0gMDtcbiAgICAgIHRoaXMuc2V0VHJhbnNmb3JtKDAsIG5ld1RyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY3NzVHJhbnNmb3JtVGltZVdhaXRpbmdJZCk7XG4gICAgdGhpcy5jc3NUcmFuc2Zvcm1UaW1lV2FpdGluZ0lkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNldFZpc2libGVSYW5nZSgpO1xuICAgIH0sIENTU19UUkFOU0ZPUk1fVElNRSk7XG4gIH1cblxuICBwcml2YXRlIGxvY2tBbmltYXRpb24oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmxvY2tBbmltYXRpb25UaW1lb3V0SWQpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgdGhpcy5uYXZMaXN0UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbiA9ICdub25lJztcbiAgICAgICAgdGhpcy5sb2NrQW5pbWF0aW9uVGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5uYXZMaXN0UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbiA9ICcnO1xuICAgICAgICAgIHRoaXMubG9ja0FuaW1hdGlvblRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSwgQ1NTX1RSQU5TRk9STV9USU1FKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0VHJhbnNmb3JtKHg6IG51bWJlciwgeTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5uYXZMaXN0UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgke3h9cHgsICR7eX1weClgO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGFtcFRyYW5zZm9ybVgodHJhbnNmb3JtOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IHNjcm9sbFdpZHRoID0gdGhpcy53cmFwcGVyV2lkdGggLSB0aGlzLnNjcm9sbExpc3RXaWR0aDtcbiAgICBpZiAodGhpcy5nZXRMYXlvdXREaXJlY3Rpb24oKSA9PT0gJ3J0bCcpIHtcbiAgICAgIHJldHVybiBNYXRoLm1heChNYXRoLm1pbihzY3JvbGxXaWR0aCwgdHJhbnNmb3JtKSwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heChzY3JvbGxXaWR0aCwgdHJhbnNmb3JtKSwgMCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjbGFtcFRyYW5zZm9ybVkodHJhbnNmb3JtOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiBNYXRoLm1pbihNYXRoLm1heCh0aGlzLndyYXBwZXJIZWlnaHQgLSB0aGlzLnNjcm9sbExpc3RIZWlnaHQsIHRyYW5zZm9ybSksIDApO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTY3JvbGxMaXN0UG9zaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldFNpemVzKCk7XG4gICAgdGhpcy50cmFuc2Zvcm1YID0gdGhpcy5jbGFtcFRyYW5zZm9ybVgodGhpcy50cmFuc2Zvcm1YKTtcbiAgICB0aGlzLnRyYW5zZm9ybVkgPSB0aGlzLmNsYW1wVHJhbnNmb3JtWSh0aGlzLnRyYW5zZm9ybVkpO1xuICAgIHRoaXMuc2V0VmlzaWJsZVJhbmdlKCk7XG4gICAgdGhpcy5zZXRQaW5nU3RhdHVzKCk7XG4gICAgaWYgKHRoaXMua2V5TWFuYWdlcikge1xuICAgICAgdGhpcy5rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0odGhpcy5rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCEpO1xuICAgICAgaWYgKHRoaXMua2V5TWFuYWdlci5hY3RpdmVJdGVtKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsVG9UYWIodGhpcy5rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTaXplcygpOiB2b2lkIHtcbiAgICB0aGlzLmFkZEJ1dHRvbldpZHRoID0gdGhpcy5hZGRCdG5SZWYgPyB0aGlzLmFkZEJ0blJlZi5nZXRFbGVtZW50V2lkdGgoKSA6IDA7XG4gICAgdGhpcy5hZGRCdXR0b25IZWlnaHQgPSB0aGlzLmFkZEJ0blJlZiA/IHRoaXMuYWRkQnRuUmVmLmdldEVsZW1lbnRIZWlnaHQoKSA6IDA7XG4gICAgdGhpcy5vcGVyYXRpb25XaWR0aCA9IHRoaXMub3BlcmF0aW9uUmVmLmdldEVsZW1lbnRXaWR0aCgpO1xuICAgIHRoaXMub3BlcmF0aW9uSGVpZ2h0ID0gdGhpcy5vcGVyYXRpb25SZWYuZ2V0RWxlbWVudEhlaWdodCgpO1xuICAgIHRoaXMud3JhcHBlcldpZHRoID0gdGhpcy5uYXZXYXJwUmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMDtcbiAgICB0aGlzLndyYXBwZXJIZWlnaHQgPSB0aGlzLm5hdldhcnBSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgMDtcbiAgICB0aGlzLnNjcm9sbExpc3RIZWlnaHQgPSB0aGlzLm5hdkxpc3RSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgMDtcbiAgICB0aGlzLnNjcm9sbExpc3RXaWR0aCA9IHRoaXMubmF2TGlzdFJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIHx8IDA7XG4gIH1cblxuICBwcml2YXRlIGFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZEl0ZW0gPSB0aGlzLml0ZW1zICYmIHRoaXMuaXRlbXMubGVuZ3RoID8gdGhpcy5pdGVtcy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XSA6IG51bGw7XG4gICAgY29uc3Qgc2VsZWN0ZWRJdGVtRWxlbWVudCA9IHNlbGVjdGVkSXRlbSA/IHNlbGVjdGVkSXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgOiBudWxsO1xuXG4gICAgaWYgKHNlbGVjdGVkSXRlbUVsZW1lbnQpIHtcbiAgICAgIC8qKlxuICAgICAgICogLmFudC10YWJzLW5hdi1saXN0IC0gVGFyZ2V0IG9mZnNldCBwYXJlbnQgZWxlbWVudFxuICAgICAgICogICDilJTilIDilIAuYW50LXRhYnMtdGFiXG4gICAgICAgKiAgICAgICAg4pSU4pSA4pSALmFudC10YWJzLXRhYi1idG4gLSBDdXJyZW50bHkgZm9jdXNlZCBlbGVtZW50XG4gICAgICAgKi9cbiAgICAgIHRoaXMuaW5rQmFyLmFsaWduVG9FbGVtZW50KHNlbGVjdGVkSXRlbUVsZW1lbnQucGFyZW50RWxlbWVudCEpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0UGluZ1N0YXR1cygpOiB2b2lkIHtcbiAgICBjb25zdCBwaW5nID0ge1xuICAgICAgdG9wOiBmYWxzZSxcbiAgICAgIHJpZ2h0OiBmYWxzZSxcbiAgICAgIGJvdHRvbTogZmFsc2UsXG4gICAgICBsZWZ0OiBmYWxzZVxuICAgIH07XG4gICAgY29uc3QgbmF2V2FycCA9IHRoaXMubmF2V2FycFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGlmICh0aGlzLnBvc2l0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIGlmICh0aGlzLmdldExheW91dERpcmVjdGlvbigpID09PSAncnRsJykge1xuICAgICAgICBwaW5nLnJpZ2h0ID0gdGhpcy50cmFuc2Zvcm1YID4gMDtcbiAgICAgICAgcGluZy5sZWZ0ID0gdGhpcy50cmFuc2Zvcm1YICsgdGhpcy53cmFwcGVyV2lkdGggPCB0aGlzLnNjcm9sbExpc3RXaWR0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBpbmcubGVmdCA9IHRoaXMudHJhbnNmb3JtWCA8IDA7XG4gICAgICAgIHBpbmcucmlnaHQgPSAtdGhpcy50cmFuc2Zvcm1YICsgdGhpcy53cmFwcGVyV2lkdGggPCB0aGlzLnNjcm9sbExpc3RXaWR0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcGluZy50b3AgPSB0aGlzLnRyYW5zZm9ybVkgPCAwO1xuICAgICAgcGluZy5ib3R0b20gPSAtdGhpcy50cmFuc2Zvcm1ZICsgdGhpcy53cmFwcGVySGVpZ2h0IDwgdGhpcy5zY3JvbGxMaXN0SGVpZ2h0O1xuICAgIH1cblxuICAgIChPYmplY3Qua2V5cyhwaW5nKSBhcyBBcnJheTwndG9wJyB8ICdyaWdodCcgfCAnYm90dG9tJyB8ICdsZWZ0Jz4pLmZvckVhY2gocG9zID0+IHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGBhbnQtdGFicy1uYXYtd3JhcC1waW5nLSR7cG9zfWA7XG4gICAgICBpZiAocGluZ1twb3NdKSB7XG4gICAgICAgIG5hdldhcnAuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmF2V2FycC5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldFZpc2libGVSYW5nZSgpOiB2b2lkIHtcbiAgICBsZXQgdW5pdDogJ3dpZHRoJyB8ICdoZWlnaHQnO1xuICAgIGxldCBwb3NpdGlvbjogJ2xlZnQnIHwgJ3RvcCcgfCAncmlnaHQnO1xuICAgIGxldCB0cmFuc2Zvcm1TaXplOiBudW1iZXI7XG4gICAgbGV0IGJhc2ljU2l6ZTogbnVtYmVyO1xuICAgIGxldCB0YWJDb250ZW50U2l6ZTogbnVtYmVyO1xuICAgIGxldCBhZGRTaXplOiBudW1iZXI7XG4gICAgY29uc3QgdGFicyA9IHRoaXMuaXRlbXMudG9BcnJheSgpO1xuICAgIGNvbnN0IERFRkFVTFRfU0laRSA9IHsgd2lkdGg6IDAsIGhlaWdodDogMCwgbGVmdDogMCwgdG9wOiAwLCByaWdodDogMCB9O1xuXG4gICAgY29uc3QgZ2V0T2Zmc2V0ID0gKGluZGV4OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICAgICAgbGV0IG9mZnNldDogbnVtYmVyO1xuICAgICAgY29uc3Qgc2l6ZSA9IHRhYnNbaW5kZXhdIHx8IERFRkFVTFRfU0laRTtcbiAgICAgIGlmIChwb3NpdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICBvZmZzZXQgPSB0YWJzWzBdLmxlZnQgKyB0YWJzWzBdLndpZHRoIC0gdGFic1tpbmRleF0ubGVmdCAtIHRhYnNbaW5kZXhdLndpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2Zmc2V0ID0gc2l6ZVtwb3NpdGlvbl07XG4gICAgICB9XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH07XG5cbiAgICBpZiAodGhpcy5wb3NpdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB1bml0ID0gJ3dpZHRoJztcbiAgICAgIGJhc2ljU2l6ZSA9IHRoaXMud3JhcHBlcldpZHRoO1xuICAgICAgdGFiQ29udGVudFNpemUgPSB0aGlzLnNjcm9sbExpc3RXaWR0aCAtICh0aGlzLmhpZGRlbkl0ZW1zLmxlbmd0aCA/IHRoaXMub3BlcmF0aW9uV2lkdGggOiAwKTtcbiAgICAgIGFkZFNpemUgPSB0aGlzLmFkZEJ1dHRvbldpZHRoO1xuICAgICAgdHJhbnNmb3JtU2l6ZSA9IE1hdGguYWJzKHRoaXMudHJhbnNmb3JtWCk7XG4gICAgICBpZiAodGhpcy5nZXRMYXlvdXREaXJlY3Rpb24oKSA9PT0gJ3J0bCcpIHtcbiAgICAgICAgcG9zaXRpb24gPSAncmlnaHQnO1xuICAgICAgICB0aGlzLnBpbmdSaWdodCA9IHRoaXMudHJhbnNmb3JtWCA+IDA7XG4gICAgICAgIHRoaXMucGluZ0xlZnQgPSB0aGlzLnRyYW5zZm9ybVggKyB0aGlzLndyYXBwZXJXaWR0aCA8IHRoaXMuc2Nyb2xsTGlzdFdpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5waW5nTGVmdCA9IHRoaXMudHJhbnNmb3JtWCA8IDA7XG4gICAgICAgIHRoaXMucGluZ1JpZ2h0ID0gLXRoaXMudHJhbnNmb3JtWCArIHRoaXMud3JhcHBlcldpZHRoIDwgdGhpcy5zY3JvbGxMaXN0V2lkdGg7XG4gICAgICAgIHBvc2l0aW9uID0gJ2xlZnQnO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB1bml0ID0gJ2hlaWdodCc7XG4gICAgICBiYXNpY1NpemUgPSB0aGlzLndyYXBwZXJIZWlnaHQ7XG4gICAgICB0YWJDb250ZW50U2l6ZSA9IHRoaXMuc2Nyb2xsTGlzdEhlaWdodCAtICh0aGlzLmhpZGRlbkl0ZW1zLmxlbmd0aCA/IHRoaXMub3BlcmF0aW9uSGVpZ2h0IDogMCk7XG4gICAgICBhZGRTaXplID0gdGhpcy5hZGRCdXR0b25IZWlnaHQ7XG4gICAgICBwb3NpdGlvbiA9ICd0b3AnO1xuICAgICAgdHJhbnNmb3JtU2l6ZSA9IC10aGlzLnRyYW5zZm9ybVk7XG4gICAgICB0aGlzLnBpbmdUb3AgPSB0aGlzLnRyYW5zZm9ybVkgPCAwO1xuICAgICAgdGhpcy5waW5nQm90dG9tID0gLXRoaXMudHJhbnNmb3JtWSArIHRoaXMud3JhcHBlckhlaWdodCA8IHRoaXMuc2Nyb2xsTGlzdEhlaWdodDtcbiAgICB9XG5cbiAgICBsZXQgbWVyZ2VkQmFzaWNTaXplID0gYmFzaWNTaXplO1xuICAgIGlmICh0YWJDb250ZW50U2l6ZSArIGFkZFNpemUgPiBiYXNpY1NpemUpIHtcbiAgICAgIG1lcmdlZEJhc2ljU2l6ZSA9IGJhc2ljU2l6ZSAtIGFkZFNpemU7XG4gICAgfVxuXG4gICAgaWYgKCF0YWJzLmxlbmd0aCkge1xuICAgICAgdGhpcy5oaWRkZW5JdGVtcyA9IFtdO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbGVuID0gdGFicy5sZW5ndGg7XG4gICAgbGV0IGVuZEluZGV4ID0gbGVuO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IGdldE9mZnNldChpKTtcbiAgICAgIGNvbnN0IHNpemUgPSB0YWJzW2ldIHx8IERFRkFVTFRfU0laRTtcbiAgICAgIGlmIChvZmZzZXQgKyBzaXplW3VuaXRdID4gdHJhbnNmb3JtU2l6ZSArIG1lcmdlZEJhc2ljU2l6ZSkge1xuICAgICAgICBlbmRJbmRleCA9IGkgLSAxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgc3RhcnRJbmRleCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IGxlbiAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICBjb25zdCBvZmZzZXQgPSBnZXRPZmZzZXQoaSk7XG4gICAgICBpZiAob2Zmc2V0IDwgdHJhbnNmb3JtU2l6ZSkge1xuICAgICAgICBzdGFydEluZGV4ID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0SGlkZGVuVGFicyA9IHRhYnMuc2xpY2UoMCwgc3RhcnRJbmRleCk7XG4gICAgY29uc3QgZW5kSGlkZGVuVGFicyA9IHRhYnMuc2xpY2UoZW5kSW5kZXggKyAxKTtcbiAgICB0aGlzLmhpZGRlbkl0ZW1zID0gWy4uLnN0YXJ0SGlkZGVuVGFicywgLi4uZW5kSGlkZGVuVGFic107XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGdldExheW91dERpcmVjdGlvbigpOiBEaXJlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLmRpciAmJiB0aGlzLmRpci52YWx1ZSA9PT0gJ3J0bCcgPyAncnRsJyA6ICdsdHInO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRUYWJGb2N1cyhfdGFiSW5kZXg6IG51bWJlcik6IHZvaWQge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgeyBwb3NpdGlvbiB9ID0gY2hhbmdlcztcbiAgICAvLyBUaGUgZmlyc3Qgd2lsbCBiZSBhbGlnbmluZyBpbiBuZ0FmdGVyVmlld0luaXRcbiAgICBpZiAocG9zaXRpb24gJiYgIXBvc2l0aW9uLmlzRmlyc3RDaGFuZ2UoKSkge1xuICAgICAgdGhpcy5hbGlnbklua0JhclRvU2VsZWN0ZWRUYWIoKTtcbiAgICAgIHRoaXMubG9ja0FuaW1hdGlvbigpO1xuICAgICAgdGhpcy51cGRhdGVTY3JvbGxMaXN0UG9zaXRpb24oKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==