UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

638 lines 58.4 kB
/** * @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