ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
638 lines • 58.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: tabs-nav.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __decorate, __metadata } from "tslib";
/**
* 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
*/
/** code from https://github.com/angular/material2 */
import { Directionality } from '@angular/cdk/bidi';
import { Platform } from '@angular/cdk/platform';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, EventEmitter, Input, NgZone, Optional, Output, QueryList, Renderer2, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { NzResizeService } from 'ng-zorro-antd/core/services';
import { InputBoolean, pxToNumber } from 'ng-zorro-antd/core/util';
import { merge, of as observableOf, Subject } from 'rxjs';
import { startWith, takeUntil } from 'rxjs/operators';
import { NzTabLabelDirective } from './tab-label.directive';
import { NzTabsInkBarDirective } from './tabs-ink-bar.directive';
/** @type {?} */
var EXAGGERATED_OVERSCROLL = 64;
var NzTabsNavComponent = /** @class */ (function () {
function NzTabsNavComponent(elementRef, ngZone, renderer, cdr, platform, resizeService, dir) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.cdr = cdr;
this.platform = platform;
this.resizeService = resizeService;
this.dir = dir;
this._tabPositionMode = 'horizontal';
this._scrollDistance = 0;
this._selectedIndex = 0;
this.destroy$ = new Subject();
this.showPaginationControls = false;
this.disableScrollAfter = true;
this.disableScrollBefore = true;
this.selectedIndexChanged = false;
this.realignInkBar = null;
this.nzOnNextClick = new EventEmitter();
this.nzOnPrevClick = new EventEmitter();
this.nzAnimated = true;
this.nzHideBar = false;
this.nzShowPagination = true;
this.nzType = 'line';
this.nzTabPosition = 'top';
}
Object.defineProperty(NzTabsNavComponent.prototype, "nzPositionMode", {
get: /**
* @return {?}
*/
function () {
return this._tabPositionMode;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
var _this = this;
this._tabPositionMode = value;
this.alignInkBarToSelectedTab();
if (this.nzShowPagination) {
Promise.resolve().then((/**
* @return {?}
*/
function () {
_this.updatePagination();
}));
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzTabsNavComponent.prototype, "selectedIndex", {
get: /**
* @return {?}
*/
function () {
return this._selectedIndex;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this.selectedIndexChanged = this._selectedIndex !== value;
this._selectedIndex = value;
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
NzTabsNavComponent.prototype.onContentChanges = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var textContent = this.elementRef.nativeElement.textContent;
// We need to diff the text content of the header, because the MutationObserver callback
// will fire even if the text content didn't change which is inefficient and is prone
// to infinite loops if a poorly constructed expression is passed in (see #14249).
if (textContent !== this.currentTextContent) {
this.currentTextContent = textContent;
this.ngZone.run((/**
* @return {?}
*/
function () {
if (_this.nzShowPagination) {
_this.updatePagination();
}
_this.alignInkBarToSelectedTab();
_this.cdr.markForCheck();
}));
}
};
/**
* @param {?} scrollDir
* @return {?}
*/
NzTabsNavComponent.prototype.scrollHeader = /**
* @param {?} scrollDir
* @return {?}
*/
function (scrollDir) {
if (scrollDir === 'before' && !this.disableScrollBefore) {
this.nzOnPrevClick.emit();
}
else if (scrollDir === 'after' && !this.disableScrollAfter) {
this.nzOnNextClick.emit();
}
// Move the scroll distance one-third the length of the tab list's viewport.
this.scrollDistance += ((scrollDir === 'before' ? -1 : 1) * this.viewWidthHeightPix) / 3;
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.ngAfterContentChecked = /**
* @return {?}
*/
function () {
if (this.tabLabelCount !== this.listOfNzTabLabelDirective.length) {
if (this.nzShowPagination) {
this.updatePagination();
}
this.tabLabelCount = this.listOfNzTabLabelDirective.length;
this.cdr.markForCheck();
}
if (this.selectedIndexChanged) {
this.scrollToLabel(this._selectedIndex);
if (this.nzShowPagination) {
this.checkScrollingControls();
}
this.alignInkBarToSelectedTab();
this.selectedIndexChanged = false;
this.cdr.markForCheck();
}
if (this.scrollDistanceChanged) {
if (this.nzShowPagination) {
this.updateTabScrollPosition();
}
this.scrollDistanceChanged = false;
this.cdr.markForCheck();
}
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.ngAfterContentInit = /**
* @return {?}
*/
function () {
var _this = this;
this.realignInkBar = this.ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
/** @type {?} */
var dirChange = _this.dir ? _this.dir.change : observableOf(null);
/** @type {?} */
var resize = typeof window !== 'undefined' ? _this.resizeService.subscribe().pipe(takeUntil(_this.destroy$)) : observableOf(null);
return merge(dirChange, resize)
.pipe(startWith(null))
.subscribe((/**
* @return {?}
*/
function () {
if (_this.nzShowPagination) {
_this.updatePagination();
}
_this.alignInkBarToSelectedTab();
}));
}));
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy$.next();
this.destroy$.complete();
if (this.realignInkBar) {
this.realignInkBar.unsubscribe();
}
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.updateTabScrollPosition = /**
* @return {?}
*/
function () {
/** @type {?} */
var scrollDistance = this.scrollDistance;
if (this.nzPositionMode === 'horizontal') {
/** @type {?} */
var translateX = this.getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance;
this.renderer.setStyle(this.navListElement.nativeElement, 'transform', "translate3d(" + translateX + "px, 0, 0)");
}
else {
this.renderer.setStyle(this.navListElement.nativeElement, 'transform', "translate3d(0," + -scrollDistance + "px, 0)");
}
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.updatePagination = /**
* @return {?}
*/
function () {
this.checkPaginationEnabled();
this.checkScrollingControls();
this.updateTabScrollPosition();
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.checkPaginationEnabled = /**
* @return {?}
*/
function () {
/** @type {?} */
var isEnabled = this.tabListScrollWidthHeightPix > this.tabListScrollOffSetWidthHeight;
if (!isEnabled) {
this.scrollDistance = 0;
}
if (isEnabled !== this.showPaginationControls) {
this.cdr.markForCheck();
}
this.showPaginationControls = isEnabled;
};
/**
* @param {?} labelIndex
* @return {?}
*/
NzTabsNavComponent.prototype.scrollToLabel = /**
* @param {?} labelIndex
* @return {?}
*/
function (labelIndex) {
/** @type {?} */
var selectedLabel = this.listOfNzTabLabelDirective ? this.listOfNzTabLabelDirective.toArray()[labelIndex] : null;
if (selectedLabel) {
// The view length is the visible width of the tab labels.
/** @type {?} */
var labelBeforePos = void 0;
/** @type {?} */
var labelAfterPos = void 0;
if (this.nzPositionMode === 'horizontal') {
if (this.getLayoutDirection() === 'ltr') {
labelBeforePos = selectedLabel.getOffsetLeft();
labelAfterPos = labelBeforePos + selectedLabel.getOffsetWidth();
}
else {
labelAfterPos = this.navListElement.nativeElement.offsetWidth - selectedLabel.getOffsetLeft();
labelBeforePos = labelAfterPos - selectedLabel.getOffsetWidth();
}
}
else {
labelBeforePos = selectedLabel.getOffsetTop();
labelAfterPos = labelBeforePos + selectedLabel.getOffsetHeight();
}
/** @type {?} */
var beforeVisiblePos = this.scrollDistance;
/** @type {?} */
var afterVisiblePos = this.scrollDistance + this.viewWidthHeightPix;
if (labelBeforePos < beforeVisiblePos) {
// Scroll header to move label to the before direction
this.scrollDistance -= beforeVisiblePos - labelBeforePos + EXAGGERATED_OVERSCROLL;
}
else if (labelAfterPos > afterVisiblePos) {
// Scroll header to move label to the after direction
this.scrollDistance += labelAfterPos - afterVisiblePos + EXAGGERATED_OVERSCROLL;
}
}
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.checkScrollingControls = /**
* @return {?}
*/
function () {
// Check if the pagination arrows should be activated.
this.disableScrollBefore = this.scrollDistance === 0;
this.disableScrollAfter = this.scrollDistance === this.getMaxScrollDistance();
this.cdr.markForCheck();
};
/**
* Determines what is the maximum length in pixels that can be set for the scroll distance. This
* is equal to the difference in width between the tab list container and tab header container.
*
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
* should be called sparingly.
*/
/**
* Determines what is the maximum length in pixels that can be set for the scroll distance. This
* is equal to the difference in width between the tab list container and tab header container.
*
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
* should be called sparingly.
* @return {?}
*/
NzTabsNavComponent.prototype.getMaxScrollDistance = /**
* Determines what is the maximum length in pixels that can be set for the scroll distance. This
* is equal to the difference in width between the tab list container and tab header container.
*
* This is an expensive call that forces a layout reflow to compute box and scroll metrics and
* should be called sparingly.
* @return {?}
*/
function () {
return this.tabListScrollWidthHeightPix - this.viewWidthHeightPix || 0;
};
Object.defineProperty(NzTabsNavComponent.prototype, "scrollDistance", {
get: /**
* @return {?}
*/
function () {
return this._scrollDistance;
},
/** Sets the distance in pixels that the tab header should be transformed in the X-axis. */
set: /**
* Sets the distance in pixels that the tab header should be transformed in the X-axis.
* @param {?} v
* @return {?}
*/
function (v) {
this._scrollDistance = Math.max(0, Math.min(this.getMaxScrollDistance(), v));
// Mark that the scroll distance has changed so that after the view is checked, the CSS
// transformation can move the header.
this.scrollDistanceChanged = true;
this.checkScrollingControls();
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzTabsNavComponent.prototype, "viewWidthHeightPix", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var PAGINATION_PIX = 0;
if (this.showPaginationControls) {
PAGINATION_PIX = this.navContainerScrollPaddingPix;
}
if (this.nzPositionMode === 'horizontal') {
return this.navContainerElement.nativeElement.offsetWidth - PAGINATION_PIX;
}
else {
return this.navContainerElement.nativeElement.offsetHeight - PAGINATION_PIX;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzTabsNavComponent.prototype, "navContainerScrollPaddingPix", {
get: /**
* @return {?}
*/
function () {
if (this.platform.isBrowser) {
/** @type {?} */
var navContainer = this.navContainerElement.nativeElement;
/** @type {?} */
var originStyle = window.getComputedStyle
? window.getComputedStyle(navContainer)
: ((/** @type {?} */ (navContainer))).currentStyle;
if (this.nzPositionMode === 'horizontal') {
return pxToNumber(originStyle.paddingLeft) + pxToNumber(originStyle.paddingRight);
}
else {
return pxToNumber(originStyle.paddingTop) + pxToNumber(originStyle.paddingBottom);
}
}
else {
return 0;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzTabsNavComponent.prototype, "tabListScrollWidthHeightPix", {
get: /**
* @return {?}
*/
function () {
if (this.nzPositionMode === 'horizontal') {
return this.navListElement.nativeElement.scrollWidth;
}
else {
return this.navListElement.nativeElement.scrollHeight;
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(NzTabsNavComponent.prototype, "tabListScrollOffSetWidthHeight", {
get: /**
* @return {?}
*/
function () {
if (this.nzPositionMode === 'horizontal') {
return this.scrollListElement.nativeElement.offsetWidth;
}
else {
return this.elementRef.nativeElement.offsetHeight;
}
},
enumerable: true,
configurable: true
});
/**
* @return {?}
*/
NzTabsNavComponent.prototype.getLayoutDirection = /**
* @return {?}
*/
function () {
return this.dir && this.dir.value === 'rtl' ? 'rtl' : 'ltr';
};
/**
* @return {?}
*/
NzTabsNavComponent.prototype.alignInkBarToSelectedTab = /**
* @return {?}
*/
function () {
if (this.nzType === 'line') {
/** @type {?} */
var selectedLabelWrapper = this.listOfNzTabLabelDirective && this.listOfNzTabLabelDirective.length
? this.listOfNzTabLabelDirective.toArray()[this.selectedIndex].elementRef.nativeElement
: null;
if (this.nzTabsInkBarDirective) {
this.nzTabsInkBarDirective.alignToElement(selectedLabelWrapper);
}
}
};
NzTabsNavComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-tabs-nav',
exportAs: 'nzTabsNav',
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
template: "\n <div style=\"float:right;\" *ngIf=\"nzTabBarExtraContent\" class=\"ant-tabs-extra-content\">\n <ng-template [ngTemplateOutlet]=\"nzTabBarExtraContent\"></ng-template>\n </div>\n <div class=\"ant-tabs-nav-container\" [class.ant-tabs-nav-container-scrolling]=\"showPaginationControls\" #navContainerElement>\n <span\n class=\"ant-tabs-tab-prev\"\n (click)=\"scrollHeader('before')\"\n [class.ant-tabs-tab-btn-disabled]=\"disableScrollBefore\"\n [class.ant-tabs-tab-arrow-show]=\"showPaginationControls\"\n >\n <span class=\"ant-tabs-tab-prev-icon\">\n <i nz-icon [nzType]=\"nzPositionMode === 'horizontal' ? 'left' : 'up'\" class=\"ant-tabs-tab-prev-icon-target\"></i>\n </span>\n </span>\n <span\n class=\"ant-tabs-tab-next\"\n (click)=\"scrollHeader('after')\"\n [class.ant-tabs-tab-btn-disabled]=\"disableScrollAfter\"\n [class.ant-tabs-tab-arrow-show]=\"showPaginationControls\"\n >\n <span class=\"ant-tabs-tab-next-icon\">\n <i nz-icon [nzType]=\"nzPositionMode === 'horizontal' ? 'right' : 'down'\" class=\"ant-tabs-tab-next-icon-target\"></i>\n </span>\n </span>\n <div class=\"ant-tabs-nav-wrap\">\n <div class=\"ant-tabs-nav-scroll\" #scrollListElement>\n <div class=\"ant-tabs-nav\" [class.ant-tabs-nav-animated]=\"nzAnimated\" #navListElement (cdkObserveContent)=\"onContentChanges()\">\n <div>\n <ng-content></ng-content>\n </div>\n <div\n nz-tabs-ink-bar\n [hidden]=\"nzHideBar\"\n [nzAnimated]=\"nzAnimated\"\n [nzPositionMode]=\"nzPositionMode\"\n style=\"display: block;\"\n ></div>\n </div>\n </div>\n </div>\n </div>\n ",
host: {
'[class.ant-tabs-bar]': 'true',
'[class.ant-tabs-card-bar]': "nzType === 'card'",
'[class.ant-tabs-top-bar]': "nzTabPosition === 'top'",
'[class.ant-tabs-bottom-bar]': "nzTabPosition === 'bottom'",
'[class.ant-tabs-left-bar]': "nzTabPosition === 'left'",
'[class.ant-tabs-right-bar]': "nzTabPosition === 'right'",
'[class.ant-tabs-small-bar]': "nzSize === 'small'",
'[class.ant-tabs-default-bar]': "nzSize === 'default'",
'[class.ant-tabs-large-bar]': "nzSize === 'large'"
}
}] }
];
/** @nocollapse */
NzTabsNavComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: NgZone },
{ type: Renderer2 },
{ type: ChangeDetectorRef },
{ type: Platform },
{ type: NzResizeService },
{ type: Directionality, decorators: [{ type: Optional }] }
]; };
NzTabsNavComponent.propDecorators = {
listOfNzTabLabelDirective: [{ type: ContentChildren, args: [NzTabLabelDirective,] }],
nzTabsInkBarDirective: [{ type: ViewChild, args: [NzTabsInkBarDirective, { static: true },] }],
navContainerElement: [{ type: ViewChild, args: ['navContainerElement', { static: true },] }],
navListElement: [{ type: ViewChild, args: ['navListElement', { static: true },] }],
scrollListElement: [{ type: ViewChild, args: ['scrollListElement', { static: true },] }],
nzOnNextClick: [{ type: Output }],
nzOnPrevClick: [{ type: Output }],
nzTabBarExtraContent: [{ type: Input }],
nzAnimated: [{ type: Input }],
nzHideBar: [{ type: Input }],
nzShowPagination: [{ type: Input }],
nzType: [{ type: Input }],
nzSize: [{ type: Input }],
nzTabPosition: [{ type: Input }],
nzPositionMode: [{ type: Input }],
selectedIndex: [{ type: Input }]
};
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTabsNavComponent.prototype, "nzAnimated", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTabsNavComponent.prototype, "nzHideBar", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTabsNavComponent.prototype, "nzShowPagination", void 0);
return NzTabsNavComponent;
}());
export { NzTabsNavComponent };
if (false) {
/** @type {?} */
NzTabsNavComponent.ngAcceptInputType_nzAnimated;
/** @type {?} */
NzTabsNavComponent.ngAcceptInputType_nzHideBar;
/** @type {?} */
NzTabsNavComponent.ngAcceptInputType_nzShowPagination;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype._tabPositionMode;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype._scrollDistance;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype._selectedIndex;
/**
* Cached text content of the header.
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.currentTextContent;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.destroy$;
/** @type {?} */
NzTabsNavComponent.prototype.showPaginationControls;
/** @type {?} */
NzTabsNavComponent.prototype.disableScrollAfter;
/** @type {?} */
NzTabsNavComponent.prototype.disableScrollBefore;
/** @type {?} */
NzTabsNavComponent.prototype.selectedIndexChanged;
/** @type {?} */
NzTabsNavComponent.prototype.realignInkBar;
/** @type {?} */
NzTabsNavComponent.prototype.tabLabelCount;
/** @type {?} */
NzTabsNavComponent.prototype.scrollDistanceChanged;
/** @type {?} */
NzTabsNavComponent.prototype.listOfNzTabLabelDirective;
/** @type {?} */
NzTabsNavComponent.prototype.nzTabsInkBarDirective;
/** @type {?} */
NzTabsNavComponent.prototype.navContainerElement;
/** @type {?} */
NzTabsNavComponent.prototype.navListElement;
/** @type {?} */
NzTabsNavComponent.prototype.scrollListElement;
/** @type {?} */
NzTabsNavComponent.prototype.nzOnNextClick;
/** @type {?} */
NzTabsNavComponent.prototype.nzOnPrevClick;
/** @type {?} */
NzTabsNavComponent.prototype.nzTabBarExtraContent;
/** @type {?} */
NzTabsNavComponent.prototype.nzAnimated;
/** @type {?} */
NzTabsNavComponent.prototype.nzHideBar;
/** @type {?} */
NzTabsNavComponent.prototype.nzShowPagination;
/** @type {?} */
NzTabsNavComponent.prototype.nzType;
/** @type {?} */
NzTabsNavComponent.prototype.nzSize;
/** @type {?} */
NzTabsNavComponent.prototype.nzTabPosition;
/** @type {?} */
NzTabsNavComponent.prototype.elementRef;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.ngZone;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.renderer;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.cdr;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.platform;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.resizeService;
/**
* @type {?}
* @private
*/
NzTabsNavComponent.prototype.dir;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy1uYXYuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC90YWJzLyIsInNvdXJjZXMiOlsidGFicy1uYXYuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBTUEsT0FBTyxFQUFhLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBR0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sRUFFTixRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsV0FBVyxFQUNYLFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRTlELE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksWUFBWSxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDeEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUU1RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7SUFFM0Qsc0JBQXNCLEdBQUcsRUFBRTtBQUdqQztJQXVIRSw0QkFDUyxVQUFzQixFQUNyQixNQUFjLEVBQ2QsUUFBbUIsRUFDbkIsR0FBc0IsRUFDdEIsUUFBa0IsRUFDbEIsYUFBOEIsRUFDbEIsR0FBbUI7UUFOaEMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUNyQixXQUFNLEdBQU4s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Z0RBQTBCOztJQUMxQixpREFBMkI7O0lBQzNCLGtEQUE2Qjs7SUFDN0IsMkNBQTBDOztJQUMxQywyQ0FBdUI7O0lBQ3ZCLG1EQUFnQzs7SUFDaEMsdURBQWlHOztJQUNqRyxtREFBa0c7O0lBQ2xHLGlEQUFxRzs7SUFDckcsNENBQTJGOztJQUMzRiwrQ0FBaUc7O0lBQ2pHLDJDQUE0RDs7SUFDNUQsMkNBQTREOztJQUM1RCxrREFBa0Q7O0lBQ2xELHdDQUEyQzs7SUFDM0MsdUNBQTJDOztJQUMzQyw4Q0FBaUQ7O0lBQ2pELG9DQUF5Qjs7SUFDekIsb0NBQWdDOztJQUNoQywyQ0FBOEM7O0lBNEI1Qyx3Q0FBNkI7Ozs7O0lBQzdCLG9DQUFzQjs7Ozs7SUFDdEIsc0NBQTJCOzs7OztJQUMzQixpQ0FBOEI7Ozs7O0lBQzlCLHNDQUEwQjs7Ozs7SUFDMUIsMkNBQXNDOzs7OztJQUN0QyxpQ0FBdUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vKiogY29kZSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL21hdGVyaWFsMiAqL1xuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFJlbmRlcmVyMixcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOelJlc2l6ZVNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvc2VydmljZXMnO1xuaW1wb3J0IHsgQm9vbGVhbklucHV0LCBOelNhZmVBbnksIE56U2l6ZUxEU1R5cGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgSW5wdXRCb29sZWFuLCBweFRvTnVtYmVyIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3V0aWwnO1xuaW1wb3J0IHsgbWVyZ2UsIG9mIGFzIG9ic2VydmFibGVPZiwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzdGFydFdpdGgsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgTnpUYWJMYWJlbERpcmVjdGl2ZSB9IGZyb20gJy4vdGFiLWxhYmVsLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBOelRhYlBvc2l0aW9uLCBOelRhYlBvc2l0aW9uTW9kZSB9IGZyb20gJy4vdGFibGUudHlwZXMnO1xuaW1wb3J0IHsgTnpUYWJzSW5rQmFyRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJzLWluay1iYXIuZGlyZWN0aXZlJztcblxuY29uc3QgRVhBR0dFUkFURURfT1ZFUlNDUk9MTCA9IDY0O1xuZXhwb3J0IHR5cGUgU2Nyb2xsRGlyZWN0aW9uID0gJ2FmdGVyJyB8ICdiZWZvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduei10YWJzLW5hdicsXG4gIGV4cG9ydEFzOiAnbnpUYWJzTmF2JyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgc3R5bGU9XCJmbG9hdDpyaWdodDtcIiAqbmdJZj1cIm56VGFiQmFyRXh0cmFDb250ZW50XCIgY2xhc3M9XCJhbnQtdGFicy1leHRyYS1jb250ZW50XCI+XG4gICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibnpUYWJCYXJFeHRyYUNvbnRlbnRcIj48L25nLXRlbXBsYXRlPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJhbnQtdGFicy1uYXYtY29udGFpbmVyXCIgW2NsYXNzLmFudC10YWJzLW5hdi1jb250YWluZXItc2Nyb2xsaW5nXT1cInNob3dQYWdpbmF0aW9uQ29udHJvbHNcIiAjbmF2Q29udGFpbmVyRWxlbWVudD5cbiAgICAgIDxzcGFuXG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtdGFiLXByZXZcIlxuICAgICAgICAoY2xpY2spPVwic2Nyb2xsSGVhZGVyKCdiZWZvcmUnKVwiXG4gICAgICAgIFtjbGFzcy5hbnQtdGFicy10YWItYnRuLWRpc2FibGVkXT1cImRpc2FibGVTY3JvbGxCZWZvcmVcIlxuICAgICAgICBbY2xhc3MuYW50LXRhYnMtdGFiLWFycm93LXNob3ddPVwic2hvd1BhZ2luYXRpb25Db250cm9sc1wiXG4gICAgICA+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXRhYnMtdGFiLXByZXYtaWNvblwiPlxuICAgICAgICAgIDxpIG56LWljb24gW256VHlwZV09XCJuelBvc2l0aW9uTW9kZSA9PT0gJ2hvcml6b250YWwnID8gJ2xlZnQnIDogJ3VwJ1wiIGNsYXNzPVwiYW50LXRhYnMtdGFiLXByZXYtaWNvbi10YXJnZXRcIj48L2k+XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvc3Bhbj5cbiAgICAgIDxzcGFuXG4gICAgICAgIGNsYXNzPVwiYW50LXRhYnMtdGFiLW5leHRcIlxuICAgICAgICAoY2xpY2spPVwic2Nyb2xsSGVhZGVyKCdhZnRlcicpXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLXRhYi1idG4tZGlzYWJsZWRdPVwiZGlzYWJsZVNjcm9sbEFmdGVyXCJcbiAgICAgICAgW2NsYXNzLmFudC10YWJzLXRhYi1hcnJvdy1zaG93XT1cInNob3dQYWdpbmF0aW9uQ29udHJvbHNcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImFudC10YWJzLXRhYi1uZXh0LWljb25cIj5cbiAgICAgICAgICA8aSBuei1pY29uIFtuelR5cGVdPVwibnpQb3NpdGlvbk1vZGUgPT09ICdob3Jpem9udGFsJyA/ICdyaWdodCcgOiAnZG93bidcIiBjbGFzcz1cImFudC10YWJzLXRhYi1uZXh0LWljb24tdGFyZ2V0XCI+PC9pPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L3NwYW4+XG4gICAgICA8ZGl2IGNsYXNzPVwiYW50LXRhYnMtbmF2LXdyYXBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFudC10YWJzLW5hdi1zY3JvbGxcIiAjc2Nyb2xsTGlzdEVsZW1lbnQ+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFudC10YWJzLW5hdlwiIFtjbGFzcy5hbnQtdGFicy1uYXYtYW5pbWF0ZWRdPVwibnpBbmltYXRlZFwiICNuYXZMaXN0RWxlbWVudCAoY2RrT2JzZXJ2ZUNvbnRlbnQpPVwib25Db250ZW50Q2hhbmdlcygpXCI+XG4gICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgbnotdGFicy1pbmstYmFyXG4gICAgICAgICAgICAgIFtoaWRkZW5dPVwibnpIaWRlQmFyXCJcbiAgICAgICAgICAgICAgW256QW5pbWF0ZWRdPVwibnpBbmltYXRlZFwiXG4gICAgICAgICAgICAgIFtuelBvc2l0aW9uTW9kZV09XCJuelBvc2l0aW9uTW9kZVwiXG4gICAgICAgICAgICAgIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7XCJcbiAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuYW50LXRhYnMtYmFyXSc6ICd0cnVlJyxcbiAgICAnW2NsYXNzLmFudC10YWJzLWNhcmQtYmFyXSc6IGBuelR5cGUgPT09ICdjYXJkJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy10b3AtYmFyXSc6IGBuelRhYlBvc2l0aW9uID09PSAndG9wJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy1ib3R0b20tYmFyXSc6IGBuelRhYlBvc2l0aW9uID09PSAnYm90dG9tJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy1sZWZ0LWJhcl0nOiBgbnpUYWJQb3NpdGlvbiA9PT0gJ2xlZnQnYCxcbiAgICAnW2NsYXNzLmFudC10YWJzLXJpZ2h0LWJhcl0nOiBgbnpUYWJQb3NpdGlvbiA9PT0gJ3JpZ2h0J2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy1zbWFsbC1iYXJdJzogYG56U2l6ZSA9PT0gJ3NtYWxsJ2AsXG4gICAgJ1tjbGFzcy5hbnQtdGFicy1kZWZhdWx0LWJhcl0nOiBgbnpTaXplID09PSAnZGVmYXVsdCdgLFxuICAgICdbY2xhc3MuYW50LXRhYnMtbGFyZ2UtYmFyXSc6IGBuelNpemUgPT09ICdsYXJnZSdgXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTnpUYWJzTmF2Q29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256QW5pbWF0ZWQ6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256SGlkZUJhcjogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpTaG93UGFnaW5hdGlvbjogQm9vbGVhbklucHV0O1xuXG4gIHByaXZhdGUgX3RhYlBvc2l0aW9uTW9kZTogTnpUYWJQb3NpdGlvbk1vZGUgPSAnaG9yaXpvbnRhbCc7XG4gIHByaXZhdGUgX3Njcm9sbERpc3RhbmNlID0gMDtcbiAgcHJpdmF0ZSBfc2VsZWN0ZWRJbmRleCA9IDA7XG4gIC8qKiBDYWNoZWQgdGV4dCBjb250ZW50IG9mIHRoZSBoZWFkZXIuICovXG4gIHByaXZhdGUgY3VycmVudFRleHRDb250ZW50Pzogc3RyaW5nO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgc2hvd1BhZ2luYXRpb25Db250cm9scyA9IGZhbHNlO1xuICBkaXNhYmxlU2Nyb2xsQWZ0ZXIgPSB0cnVlO1xuICBkaXNhYmxlU2Nyb2xsQmVmb3JlID0gdHJ1ZTtcbiAgc2VsZWN0ZWRJbmRleENoYW5nZWQgPSBmYWxzZTtcbiAgcmVhbGlnbklua0JhcjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG4gIHRhYkxhYmVsQ291bnQ/OiBudW1iZXI7XG4gIHNjcm9sbERpc3RhbmNlQ2hhbmdlZD86IGJvb2xlYW47XG4gIEBDb250ZW50Q2hpbGRyZW4oTnpUYWJMYWJlbERpcmVjdGl2ZSkgbGlzdE9mTnpUYWJMYWJlbERpcmVjdGl2ZSE6IFF1ZXJ5TGlzdDxOelRhYkxhYmVsRGlyZWN0aXZlPjtcbiAgQFZpZXdDaGlsZChOelRhYnNJbmtCYXJEaXJlY3RpdmUsIHsgc3RhdGljOiB0cnVlIH0pIG56VGFic0lua0JhckRpcmVjdGl2ZSE6IE56VGFic0lua0JhckRpcmVjdGl2ZTtcbiAgQFZpZXdDaGlsZCgnbmF2Q29udGFpbmVyRWxlbWVudCcsIHsgc3RhdGljOiB0cnVlIH0pIG5hdkNvbnRhaW5lckVsZW1lbnQhOiBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50PjtcbiAgQFZpZXdDaGlsZCgnbmF2TGlzdEVsZW1lbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBuYXZMaXN0RWxlbWVudCE6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuICBAVmlld0NoaWxkKCdzY3JvbGxMaXN0RWxlbWVudCcsIHsgc3RhdGljOiB0cnVlIH0pIHNjcm9sbExpc3RFbGVtZW50ITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG4gIEBPdXRwdXQoKSByZWFkb25seSBuek9uTmV4dENsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpPblByZXZDbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQElucHV0KCkgbnpUYWJCYXJFeHRyYUNvbnRlbnQ/OiBUZW1wbGF0ZVJlZjx2b2lkPjtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56QW5pbWF0ZWQgPSB0cnVlO1xuICBASW5wdXQoKSBASW5wdXRCb29sZWFuKCkgbnpIaWRlQmFyID0gZmFsc2U7XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuelNob3dQYWdpbmF0aW9uID0gdHJ1ZTtcbiAgQElucHV0KCkgbnpUeXBlID0gJ2xpbmUnO1xuICBASW5wdXQoKSBuelNpemU/OiBOelNpemVMRFNUeXBlO1xuICBASW5wdXQoKSBuelRhYlBvc2l0aW9uOiBOelRhYlBvc2l0aW9uID0gJ3RvcCc7XG5cbiAgQElucHV0KClcbiAgc2V0IG56UG9zaXRpb25Nb2RlKHZhbHVlOiBOelRhYlBvc2l0aW9uTW9kZSkge1xuICAgIHRoaXMuX3RhYlBvc2l0aW9uTW9kZSA9IHZhbHVlO1xuICAgIHRoaXMuYWxpZ25JbmtCYXJUb1NlbGVjdGVkVGFiKCk7XG4gICAgaWYgKHRoaXMubnpTaG93UGFnaW5hdGlvbikge1xuICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IG56UG9zaXRpb25Nb2RlKCk6IE56VGFiUG9zaXRpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5fdGFiUG9zaXRpb25Nb2RlO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHNlbGVjdGVkSW5kZXgodmFsdWU6IG51bWJlcikge1xuICAgIHRoaXMuc2VsZWN0ZWRJbmRleENoYW5nZWQgPSB0aGlzLl9zZWxlY3RlZEluZGV4ICE9PSB2YWx1ZTtcbiAgICB0aGlzLl9zZWxlY3RlZEluZGV4ID0gdmFsdWU7XG4gIH1cblxuICBnZXQgc2VsZWN0ZWRJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZEluZGV4O1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgIHByaXZhdGUgcmVzaXplU2VydmljZTogTnpSZXNpemVTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGlyOiBEaXJlY3Rpb25hbGl0eVxuICApIHt9XG5cbiAgb25Db250ZW50Q2hhbmdlcygpOiB2b2lkIHtcbiAgICBjb25zdCB0ZXh0Q29udGVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnRleHRDb250ZW50O1xuICAgIC8vIFdlIG5lZWQgdG8gZGlmZiB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBoZWFkZXIsIGJlY2F1c2UgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgY2FsbGJhY2tcbiAgICAvLyB3aWxsIGZpcmUgZXZlbiBpZiB0aGUgdGV4dCBjb250ZW50IGRpZG4ndCBjaGFuZ2Ugd2hpY2ggaXMgaW5lZmZpY2llbnQgYW5kIGlzIHByb25lXG4gICAgLy8gdG8gaW5maW5pdGUgbG9vcHMgaWYgYSBwb29ybHkgY29uc3RydWN0ZWQgZXhwcmVzc2lvbiBpcyBwYXNzZWQgaW4gKHNlZSAjMTQyNDkpLlxuICAgIGlmICh0ZXh0Q29udGVudCAhPT0gdGhpcy5jdXJyZW50VGV4dENvbnRlbnQpIHtcbiAgICAgIHRoaXMuY3VycmVudFRleHRDb250ZW50ID0gdGV4dENvbnRlbnQ7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5uelNob3dQYWdpbmF0aW9uKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVQYWdpbmF0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hbGlnbklua0JhclRvU2VsZWN0ZWRUYWIoKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzY3JvbGxIZWFkZXIoc2Nyb2xsRGlyOiBTY3JvbGxEaXJlY3Rpb24pOiB2b2lkIHtcbiAgICBpZiAoc2Nyb2xsRGlyID09PSAnYmVmb3JlJyAmJiAhdGhpcy5kaXNhYmxlU2Nyb2xsQmVmb3JlKSB7XG4gICAgICB0aGlzLm56T25QcmV2Q2xpY2suZW1pdCgpO1xuICAgIH0gZWxzZSBpZiAoc2Nyb2xsRGlyID09PSAnYWZ0ZXInICYmICF0aGlzLmRpc2FibGVTY3JvbGxBZnRlcikge1xuICAgICAgdGhpcy5uek9uTmV4dENsaWNrLmVtaXQoKTtcbiAgICB9XG4gICAgLy8gTW92ZSB0aGUgc2Nyb2xsIGRpc3RhbmNlIG9uZS10aGlyZCB0aGUgbGVuZ3RoIG9mIHRoZSB0YWIgbGlzdCdzIHZpZXdwb3J0LlxuICAgIHRoaXMuc2Nyb2xsRGlzdGFuY2UgKz0gKChzY3JvbGxEaXIgPT09ICdiZWZvcmUnID8gLTEgOiAxKSAqIHRoaXMudmlld1dpZHRoSGVpZ2h0UGl4KSAvIDM7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGFiTGFiZWxDb3VudCAhPT0gdGhpcy5saXN0T2ZOelRhYkxhYmVsRGlyZWN0aXZlLmxlbmd0aCkge1xuICAgICAgaWYgKHRoaXMubnpTaG93UGFnaW5hdGlvbikge1xuICAgICAgICB0aGlzLnVwZGF0ZVBhZ2luYXRpb24oKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudGFiTGFiZWxDb3VudCA9IHRoaXMubGlzdE9mTnpUYWJMYWJlbERpcmVjdGl2ZS5sZW5ndGg7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRJbmRleENoYW5nZWQpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9MYWJlbCh0aGlzLl9zZWxlY3RlZEluZGV4KTtcbiAgICAgIGlmICh0aGlzLm56U2hvd1BhZ2luYXRpb24pIHtcbiAgICAgICAgdGhpcy5jaGVja1Njcm9sbGluZ0NvbnRyb2xzKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmFsaWduSW5rQmFyVG9TZWxlY3RlZFRhYigpO1xuICAgICAgdGhpcy5zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNjcm9sbERpc3RhbmNlQ2hhbmdlZCkge1xuICAgICAgaWYgKHRoaXMubnpTaG93UGFnaW5hdGlvbikge1xuICAgICAgICB0aGlzLnVwZGF0ZVRhYlNjcm9sbFBvc2l0aW9uKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnNjcm9sbERpc3RhbmNlQ2hhbmdlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVhbGlnbklua0JhciA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IGRpckNoYW5nZSA9IHRoaXMuZGlyID8gdGhpcy5kaXIuY2hhbmdlIDogb2JzZXJ2YWJsZU9mKG51bGwpO1xuICAgICAgY29uc3QgcmVzaXplID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB0aGlzLnJlc2l6ZVNlcnZpY2Uuc3Vic2NyaWJlKCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpIDogb