UNPKG

ng-zorro-antd-mobile

Version:

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

293 lines 47.1 kB
import { Component, Input, Output, QueryList, ViewChild, ElementRef, HostBinding, TemplateRef, EventEmitter, ContentChildren, ViewEncapsulation } from '@angular/core'; import { TabPaneComponent } from './tab-pane.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "./tab-pane-body.component"; import * as i3 from "./default-tab-bar.component"; export class TabsComponent { get activeTab() { return this.selectedKey; } set activeTab(value) { this.keyToSelect = value; } get tabBarPosition() { return this._tabBarPosition; } set tabBarPosition(position) { this._tabBarPosition = position; switch (position) { case 'top': this.amTabsTop = true; this.amTabsLeft = false; this.amTabsRight = false; this.amTabsBottom = false; break; case 'left': this.amTabsTop = false; this.amTabsLeft = true; this.amTabsRight = false; this.amTabsBottom = false; break; case 'bottom': this.amTabsTop = false; this.amTabsLeft = false; this.amTabsRight = false; this.amTabsBottom = true; break; case 'right': this.amTabsTop = false; this.amTabsLeft = false; this.amTabsRight = true; this.amTabsBottom = false; break; default: break; } } get tabDirection() { return this._tabDirection; } set tabDirection(direction) { this._tabDirection = direction; switch (direction) { case 'horizontal': this.amTabsHorizontal = true; this.amTabsVertical = false; break; case 'vertical': this.amTabsHorizontal = false; this.amTabsVertical = true; break; default: break; } } constructor() { this.prefixCls = 'am-tabs'; this.selectedKey = 0; this.keyToSelect = 0; this.paneMoveStyle = 'translate3d(0, 0, 0)'; this._startTime = 0; this._startPosition = 0; this._velocityThreshold = 0.3; this._tabDirection = 'horizontal'; this._tabBarPosition = 'top'; this.page = 5; this.swipeable = true; this.useOnPan = true; this.animated = true; this.distanceToChangeTab = 0.3; this.tabTitleSize = 0; this.tabBarActiveTextColor = ''; this.tabBarInactiveTextColor = ''; this.renderTabBar = null; this.tabBarBackgroundColor = '#FFF'; this.prerenderingSiblingsNumber = -1; this.tabBarTextStyle = {}; /** should be removed when https://github.com/angular/angular/issues/20810 resolved **/ this.tabPanesContent = null; this.onChange = new EventEmitter(); this.onTabClick = new EventEmitter(); this.amTabs = true; this.amTabsTop = true; this.amTabsLeft = false; this.amTabsRight = false; this.amTabsBottom = false; this.amTabsVertical = false; this.amTabsHorizontal = true; } clickTab(index) { if (this.selectedKey !== index) { this.keyToSelect = index; this.onTabClick.emit({ index: this.keyToSelect }); } } getCurrentTabPanes() { return this.tabPanesContent || this.tabPanes; } onTouchStart(event) { this._startTime = event.timeStamp; if (this.getCurrentTabPanes() && this.getCurrentTabPanes().length > 0) { if ('horizontal' === this._tabDirection) { this._startPosition = event && event.changedTouches && event.changedTouches[0] && event.changedTouches[0].clientX; } else if ('vertical' === this._tabDirection) { this._startPosition = event && event.changedTouches && event.changedTouches[0] && event.changedTouches[0].clientY; } } } onTouchMove(event) { if (this.getCurrentTabPanes() && this.getCurrentTabPanes().length > 0) { if ('horizontal' === this._tabDirection) { const distance = event.changedTouches[0].clientX - this._startPosition; if (distance < 0 && this.activeTab === this.getCurrentTabPanes().length - 1) { return; } else if (distance > 0 && this.activeTab === 0) { return; } // velocity 小于阈值才认为是pan操作 if (this.getVelocity(distance, event.timeStamp - this._startTime) <= this._velocityThreshold && this.useOnPan && this.swipeable && this.animated) { this.paneMoveStyle = 'translate3d(calc(-' + this.selectedKey * 100 + '% + ' + distance + 'px), 0, 0 )'; } } else if ('vertical' === this._tabDirection) { const distance = event.changedTouches[0].clientY - this._startPosition; if (distance < 0 && this.activeTab === this.getCurrentTabPanes().length - 1) { return; } else if (distance > 0 && this.activeTab === 0) { return; } if (this.getVelocity(distance, event.timeStamp - this._startTime) <= this._velocityThreshold && this.useOnPan && this.swipeable && this.animated) { this.paneMoveStyle = 'translate3d(0, calc(-' + this.selectedKey * 100 + '% + ' + distance + 'px, 0 )'; } } } } onTouchEnd(event) { if (this.getCurrentTabPanes() && this.getCurrentTabPanes().length > 0) { if ('horizontal' === this._tabDirection) { const distance = event.changedTouches[0].clientX - this._startPosition; const distanceToChangeTabPx = this.tabContent.nativeElement.offsetWidth * this.distanceToChangeTab; if ((this.getVelocity(distance, event.timeStamp - this._startTime) <= this._velocityThreshold && (this.useOnPan && this.swipeable && Math.abs(distance) > distanceToChangeTabPx)) || (this.getVelocity(distance, event.timeStamp - this._startTime) > this._velocityThreshold && (this.swipeable && Math.abs(distance) > distanceToChangeTabPx / 2))) { if (distance < 0 && this.activeTab < this.getCurrentTabPanes().length - 1) { this.keyToSelect++; } else if (distance > 0 && this.activeTab > 0) { this.keyToSelect--; } } this.paneMoveStyle = 'translate3d(-' + this.selectedKey * 100 + '%, 0, 0 )'; } else if ('vertical' === this._tabDirection) { const distance = event.changedTouches[0].clientY - this._startPosition; const distanceToChangeTabPx = this.tabContent.nativeElement.offsetHeight * this.distanceToChangeTab; if ((this.getVelocity(distance, event.timeStamp - this._startTime) <= this._velocityThreshold && (this.useOnPan && this.swipeable && Math.abs(distance) > distanceToChangeTabPx)) || (this.getVelocity(distance, event.timeStamp - this._startTime) > this._velocityThreshold && (this.swipeable && Math.abs(distance) > distanceToChangeTabPx / 2))) { if (distance < 0 && this.activeTab < this.getCurrentTabPanes().length - 1) { this.keyToSelect++; } else if (distance > 0 && this.activeTab > 0) { this.keyToSelect--; } } this.paneMoveStyle = 'translate3d(0, -' + this.selectedKey * 100 + '%, 0 )'; } } } ngAfterContentInit() { this.selectTabPane(this.keyToSelect); this.selectedKey = this.keyToSelect; } ngDoCheck() { if (this.keyToSelect !== this.selectedKey && this.getCurrentTabPanes() && this.getCurrentTabPanes().length > 0) { this.selectTabPane(this.keyToSelect); this.selectedKey = this.keyToSelect; this.onChange.emit({ index: this.selectedKey }); } } selectTabPane(index) { if (this.getCurrentTabPanes() && this.getCurrentTabPanes().length > 0) { const actualKeyToSelect = Math.min(this.getCurrentTabPanes().length - 1, Math.max(index || 0, 0)); if ('horizontal' === this._tabDirection) { this.paneMoveStyle = 'translate3d(-' + actualKeyToSelect * 100 + '%, 0, 0 )'; } else if ('vertical' === this._tabDirection) { this.paneMoveStyle = 'translate3d(0, -' + actualKeyToSelect * 100 + '%, 0 )'; } } } getVelocity(deltaDistance, deltaTime) { return Math.abs(deltaDistance / deltaTime); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: TabsComponent, selector: "Tabs, nzm-tabs", inputs: { page: "page", swipeable: "swipeable", useOnPan: "useOnPan", animated: "animated", tabBarUnderlineStyle: "tabBarUnderlineStyle", distanceToChangeTab: "distanceToChangeTab", tabTitleSize: "tabTitleSize", tabBarActiveTextColor: "tabBarActiveTextColor", tabBarInactiveTextColor: "tabBarInactiveTextColor", renderTabBar: "renderTabBar", tabBarBackgroundColor: "tabBarBackgroundColor", prerenderingSiblingsNumber: "prerenderingSiblingsNumber", tabBarTextStyle: "tabBarTextStyle", tabPanesContent: "tabPanesContent", activeTab: "activeTab", tabBarPosition: "tabBarPosition", tabDirection: "tabDirection" }, outputs: { onChange: "onChange", onTabClick: "onTabClick" }, host: { properties: { "class.am-tabs": "this.amTabs", "class.am-tabs-top": "this.amTabsTop", "class.am-tabs-left": "this.amTabsLeft", "class.am-tabs-right": "this.amTabsRight", "class.am-tabs-bottom": "this.amTabsBottom", "class.am-tabs-vertical": "this.amTabsVertical", "class.am-tabs-horizontal": "this.amTabsHorizontal" } }, queries: [{ propertyName: "tabPanes", predicate: TabPaneComponent }], viewQueries: [{ propertyName: "tabContent", first: true, predicate: ["TabContent"], descendants: true, static: true }, { propertyName: "defaultTabBar", first: true, predicate: ["DefaultTabBar"], descendants: true }], ngImport: i0, template: "<ng-container>\n <ng-template\n *ngIf=\"'top' === tabBarPosition || 'left' === tabBarPosition\"\n [ngTemplateOutlet]=\"renderTabBar || renderDefaultTabBar\"\n >\n </ng-template>\n <div\n #TabContent\n class=\"{{ prefixCls }}-content-wrap\"\n [ngClass]=\"{ 'am-tabs-content-wrap-animated': animated }\"\n [ngStyle]=\"{ transform: paneMoveStyle, webkitTransform: paneMoveStyle }\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n >\n <div\n tab-pane-body\n *ngFor=\"let tabPane of getCurrentTabPanes(); let i = index\"\n [content]=\"tabPane.content\"\n [active]=\"i === selectedKey\"\n [prerender]=\"\n prerenderingSiblingsNumber < 0 ||\n (selectedKey - i <= prerenderingSiblingsNumber && selectedKey - i + prerenderingSiblingsNumber >= 0)\n \"\n ></div>\n </div>\n <ng-template\n *ngIf=\"'bottom' === tabBarPosition || 'right' === tabBarPosition\"\n [ngTemplateOutlet]=\"renderTabBar || renderDefaultTabBar\"\n ></ng-template>\n</ng-container>\n\n<ng-template #renderDefaultTabBar>\n <DefaultTabBar\n #DefaultTabBar\n [page]=\"page\"\n [animated]=\"animated\"\n [activeTab]=\"selectedKey\"\n [tabTitleSize]=\"tabTitleSize\"\n [tabBarPosition]=\"tabBarPosition\"\n [tabBarUnderlineStyle]=\"tabBarUnderlineStyle\"\n [tabBarBackgroundColor]=\"tabBarBackgroundColor\"\n >\n <div\n #TabTitle\n *ngFor=\"let tabPane of getCurrentTabPanes(); let i = index\"\n class=\"{{ prefixCls }}-default-bar-tab\"\n [ngClass]=\"{\n 'am-tabs-default-bar-tab-active': i === selectedKey,\n 'am-tabs-default-bar-tab-disabled': tabPane.disabled\n }\"\n [ngStyle]=\"tabBarTextStyle\"\n [style.color]=\"i === selectedKey ? tabBarActiveTextColor : tabBarInactiveTextColor\"\n (click)=\"clickTab(i)\"\n >\n <ng-container *ngIf=\"tabPane.isTitleString; else titleTemplate\">\n {{ tabPane.title }}\n </ng-container>\n <ng-template #titleTemplate>\n <ng-template [ngTemplateOutlet]=\"tabPane.title\"></ng-template>\n </ng-template>\n </div>\n </DefaultTabBar>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.TabPaneBodyComponent, selector: "[tab-pane-body]", inputs: ["active", "loaded", "content", "prerender"] }, { kind: "component", type: i3.DefaultTabBarComponent, selector: "DefaultTabBar, nzm-default-tab-bar", inputs: ["page", "animated", "tabBarUnderlineStyle", "tabBarBackgroundColor", "tabTitleSize", "tabBarPosition", "activeTab"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: TabsComponent, decorators: [{ type: Component, args: [{ selector: 'Tabs, nzm-tabs', encapsulation: ViewEncapsulation.None, template: "<ng-container>\n <ng-template\n *ngIf=\"'top' === tabBarPosition || 'left' === tabBarPosition\"\n [ngTemplateOutlet]=\"renderTabBar || renderDefaultTabBar\"\n >\n </ng-template>\n <div\n #TabContent\n class=\"{{ prefixCls }}-content-wrap\"\n [ngClass]=\"{ 'am-tabs-content-wrap-animated': animated }\"\n [ngStyle]=\"{ transform: paneMoveStyle, webkitTransform: paneMoveStyle }\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd($event)\"\n >\n <div\n tab-pane-body\n *ngFor=\"let tabPane of getCurrentTabPanes(); let i = index\"\n [content]=\"tabPane.content\"\n [active]=\"i === selectedKey\"\n [prerender]=\"\n prerenderingSiblingsNumber < 0 ||\n (selectedKey - i <= prerenderingSiblingsNumber && selectedKey - i + prerenderingSiblingsNumber >= 0)\n \"\n ></div>\n </div>\n <ng-template\n *ngIf=\"'bottom' === tabBarPosition || 'right' === tabBarPosition\"\n [ngTemplateOutlet]=\"renderTabBar || renderDefaultTabBar\"\n ></ng-template>\n</ng-container>\n\n<ng-template #renderDefaultTabBar>\n <DefaultTabBar\n #DefaultTabBar\n [page]=\"page\"\n [animated]=\"animated\"\n [activeTab]=\"selectedKey\"\n [tabTitleSize]=\"tabTitleSize\"\n [tabBarPosition]=\"tabBarPosition\"\n [tabBarUnderlineStyle]=\"tabBarUnderlineStyle\"\n [tabBarBackgroundColor]=\"tabBarBackgroundColor\"\n >\n <div\n #TabTitle\n *ngFor=\"let tabPane of getCurrentTabPanes(); let i = index\"\n class=\"{{ prefixCls }}-default-bar-tab\"\n [ngClass]=\"{\n 'am-tabs-default-bar-tab-active': i === selectedKey,\n 'am-tabs-default-bar-tab-disabled': tabPane.disabled\n }\"\n [ngStyle]=\"tabBarTextStyle\"\n [style.color]=\"i === selectedKey ? tabBarActiveTextColor : tabBarInactiveTextColor\"\n (click)=\"clickTab(i)\"\n >\n <ng-container *ngIf=\"tabPane.isTitleString; else titleTemplate\">\n {{ tabPane.title }}\n </ng-container>\n <ng-template #titleTemplate>\n <ng-template [ngTemplateOutlet]=\"tabPane.title\"></ng-template>\n </ng-template>\n </div>\n </DefaultTabBar>\n</ng-template>\n" }] }], ctorParameters: () => [], propDecorators: { tabPanes: [{ type: ContentChildren, args: [TabPaneComponent, { descendants: false }] }], tabContent: [{ type: ViewChild, args: ['TabContent', { static: true }] }], defaultTabBar: [{ type: ViewChild, args: ['DefaultTabBar'] }], page: [{ type: Input }], swipeable: [{ type: Input }], useOnPan: [{ type: Input }], animated: [{ type: Input }], tabBarUnderlineStyle: [{ type: Input }], distanceToChangeTab: [{ type: Input }], tabTitleSize: [{ type: Input }], tabBarActiveTextColor: [{ type: Input }], tabBarInactiveTextColor: [{ type: Input }], renderTabBar: [{ type: Input }], tabBarBackgroundColor: [{ type: Input }], prerenderingSiblingsNumber: [{ type: Input }], tabBarTextStyle: [{ type: Input }], tabPanesContent: [{ type: Input }], activeTab: [{ type: Input }], tabBarPosition: [{ type: Input }], tabDirection: [{ type: Input }], onChange: [{ type: Output }], onTabClick: [{ type: Output }], amTabs: [{ type: HostBinding, args: ['class.am-tabs'] }], amTabsTop: [{ type: HostBinding, args: ['class.am-tabs-top'] }], amTabsLeft: [{ type: HostBinding, args: ['class.am-tabs-left'] }], amTabsRight: [{ type: HostBinding, args: ['class.am-tabs-right'] }], amTabsBottom: [{ type: HostBinding, args: ['class.am-tabs-bottom'] }], amTabsVertical: [{ type: HostBinding, args: ['class.am-tabs-vertical'] }], amTabsHorizontal: [{ type: HostBinding, args: ['class.am-tabs-horizontal'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL3RhYnMvdGFicy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9jb21wb25lbnRzL3RhYnMvdGFicy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBR04sU0FBUyxFQUNULFNBQVMsRUFDVCxVQUFVLEVBQ1YsV0FBVyxFQUNYLFdBQVcsRUFDWCxZQUFZLEVBQ1osZUFBZSxFQUNmLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7Ozs7QUFReEQsTUFBTSxPQUFPLGFBQWE7SUFpRHhCLElBQ0ksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDO0lBQ0QsSUFBSSxTQUFTLENBQUMsS0FBYTtRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFDSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUM5QixDQUFDO0lBQ0QsSUFBSSxjQUFjLENBQUMsUUFBNEI7UUFDN0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUM7UUFDaEMsUUFBUSxRQUFRLEVBQUU7WUFDaEIsS0FBSyxLQUFLO2dCQUNSLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztnQkFDeEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO2dCQUMxQixNQUFNO1lBQ1IsS0FBSyxNQUFNO2dCQUNULElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO2dCQUN2QixJ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U0FBUzt1QkFBQyxZQUFZLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUd6QyxhQUFhO3NCQURaLFNBQVM7dUJBQUMsZUFBZTtnQkFJMUIsSUFBSTtzQkFESCxLQUFLO2dCQUdOLFNBQVM7c0JBRFIsS0FBSztnQkFHTixRQUFRO3NCQURQLEtBQUs7Z0JBR04sUUFBUTtzQkFEUCxLQUFLO2dCQUdOLG9CQUFvQjtzQkFEbkIsS0FBSztnQkFHTixtQkFBbUI7c0JBRGxCLEtBQUs7Z0JBR04sWUFBWTtzQkFEWCxLQUFLO2dCQUdOLHFCQUFxQjtzQkFEcEIsS0FBSztnQkFHTix1QkFBdUI7c0JBRHRCLEtBQUs7Z0JBR04sWUFBWTtzQkFEWCxLQUFLO2dCQUdOLHFCQUFxQjtzQkFEcEIsS0FBSztnQkFHTiwwQkFBMEI7c0JBRHpCLEtBQUs7Z0JBR04sZUFBZTtzQkFEZCxLQUFLO2dCQUlOLGVBQWU7c0JBRGQsS0FBSztnQkFHRixTQUFTO3NCQURaLEtBQUs7Z0JBUUYsY0FBYztzQkFEakIsS0FBSztnQkFvQ0YsWUFBWTtzQkFEZixLQUFLO2dCQW9CTixRQUFRO3NCQURQLE1BQU07Z0JBR1AsVUFBVTtzQkFEVCxNQUFNO2dCQUlQLE1BQU07c0JBREwsV0FBVzt1QkFBQyxlQUFlO2dCQUc1QixTQUFTO3NCQURSLFdBQVc7dUJBQUMsbUJBQW1CO2dCQUdoQyxVQUFVO3NCQURULFdBQVc7dUJBQUMsb0JBQW9CO2dCQUdqQyxXQUFXO3NCQURWLFdBQVc7dUJBQUMscUJBQXFCO2dCQUdsQyxZQUFZO3NCQURYLFdBQVc7dUJBQUMsc0JBQXNCO2dCQUduQyxjQUFjO3NCQURiLFdBQVc7dUJBQUMsd0JBQXdCO2dCQUdyQyxnQkFBZ0I7c0JBRGYsV0FBVzt1QkFBQywwQkFBMEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIERvQ2hlY2ssXG4gIEFmdGVyQ29udGVudEluaXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBIb3N0QmluZGluZyxcbiAgVGVtcGxhdGVSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgQ29udGVudENoaWxkcmVuLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRhYlBhbmVDb21wb25lbnQgfSBmcm9tICcuL3RhYi1wYW5lLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBUYWJEaXJlY3Rpb24sIFRhYkJhclBvc2l0aW9uVHlwZSwgVGFic09uQ2hhbmdlRXZlbnQgfSBmcm9tICcuL1Byb3BzVHlwZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ1RhYnMsIG56bS10YWJzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYnMuY29tcG9uZW50Lmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIFRhYnNDb21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBBZnRlckNvbnRlbnRJbml0IHtcbiAgcHJlZml4Q2xzOiBzdHJpbmcgPSAnYW0tdGFicyc7XG4gIHNlbGVjdGVkS2V5OiBudW1iZXIgPSAwO1xuICBrZXlUb1NlbGVjdDogbnVtYmVyID0gMDtcbiAgcGFuZU1vdmVTdHlsZTogc3RyaW5nID0gJ3RyYW5zbGF0ZTNkKDAsIDAsIDApJztcblxuICBwcml2YXRlIF9zdGFydFRpbWU6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgX3N0YXJ0UG9zaXRpb246IG51bWJlciA9IDA7XG4gIHByaXZhdGUgX3ZlbG9jaXR5VGhyZXNob2xkOiBudW1iZXIgPSAwLjM7XG4gIHByaXZhdGUgX3RhYkRpcmVjdGlvbjogVGFiRGlyZWN0aW9uID0gJ2hvcml6b250YWwnO1xuICBwcml2YXRlIF90YWJCYXJQb3NpdGlvbjogVGFiQmFyUG9zaXRpb25UeXBlID0gJ3RvcCc7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihUYWJQYW5lQ29tcG9uZW50LCB7IGRlc2NlbmRhbnRzOiBmYWxzZSB9KVxuICB0YWJQYW5lczogUXVlcnlMaXN0PFRhYlBhbmVDb21wb25lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoJ1RhYkNvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICB0YWJDb250ZW50OiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdEZWZhdWx0VGFiQmFyJylcbiAgZGVmYXVsdFRhYkJhcjogRWxlbWVudFJlZjtcblxuICBASW5wdXQoKVxuICBwYWdlOiBudW1iZXIgPSA1O1xuICBASW5wdXQoKVxuICBzd2lwZWFibGU6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKVxuICB1c2VPblBhbjogYm9vbGVhbiA9IHRydWU7XG4gIEBJbnB1dCgpXG4gIGFuaW1hdGVkOiBib29sZWFuID0gdHJ1ZTtcbiAgQElucHV0KClcbiAgdGFiQmFyVW5kZXJsaW5lU3R5bGU6IG9iamVjdDtcbiAgQElucHV0KClcbiAgZGlzdGFuY2VUb0NoYW5nZVRhYjogbnVtYmVyID0gMC4zO1xuICBASW5wdXQoKVxuICB0YWJUaXRsZVNpemU6IG51bWJlciA9IDA7XG4gIEBJbnB1dCgpXG4gIHRhYkJhckFjdGl2ZVRleHRDb2xvcjogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpXG4gIHRhYkJhckluYWN0aXZlVGV4dENvbG9yOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KClcbiAgcmVuZGVyVGFiQmFyOiBUZW1wbGF0ZVJlZjx2b2lkPiA9IG51bGw7XG4gIEBJbnB1dCgpXG4gIHRhYkJhckJhY2tncm91bmRDb2xvcjogc3RyaW5nID0gJyNGRkYnO1xuICBASW5wdXQoKVxuICBwcmVyZW5kZXJpbmdTaWJsaW5nc051bWJlcjogbnVtYmVyID0gLTE7XG4gIEBJbnB1dCgpXG4gIHRhYkJhclRleHRTdHlsZTogb2JqZWN0ID0ge307XG4gIC8qKiBzaG91bGQgYmUgcmVtb3ZlZCB3aGVuIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzIwODEwIHJlc29sdmVkICoqL1xuICBASW5wdXQoKVxuICB0YWJQYW5lc0NvbnRlbnQ6IFF1ZXJ5TGlzdDxUYWJQYW5lQ29tcG9uZW50PiA9IG51bGw7XG4gIEBJbnB1dCgpXG4gIGdldCBhY3RpdmVUYWIoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEtleTtcbiAgfVxuICBzZXQgYWN0aXZlVGFiKHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLmtleVRvU2VsZWN0ID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgZ2V0IHRhYkJhclBvc2l0aW9uKCk6IFRhYkJhclBvc2l0aW9uVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYkJhclBvc2l0aW9uO1xuICB9XG4gIHNldCB0YWJCYXJQb3NpdGlvbihwb3NpdGlvbjogVGFiQmFyUG9zaXRpb25UeXBlKSB7XG4gICAgdGhpcy5fdGFiQmFyUG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgICBzd2l0Y2ggKHBvc2l0aW9uKSB7XG4gICAgICBjYXNlICd0b3AnOlxuICAgICAgICB0aGlzLmFtVGFic1RvcCA9IHRydWU7XG4gICAgICAgIHRoaXMuYW1UYWJzTGVmdCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFtVGFic1JpZ2h0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYW1UYWJzQm90dG9tID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIHRoaXMuYW1UYWJzVG9wID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYW1UYWJzTGVmdCA9IHRydWU7XG4gICAgICAgIHRoaXMuYW1UYWJzUmlnaHQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hbVRhYnNCb3R0b20gPSBmYWxzZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICB0aGlzLmFtVGFic1RvcCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFtVGFic0xlZnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hbVRhYnNSaWdodCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFtVGFic0JvdHRvbSA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICB0aGlzLmFtVGFic1RvcCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFtVGFic0xlZnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hbVRhYnNSaWdodCA9IHRydWU7XG4gICAgICAgIHRoaXMuYW1UYWJzQm90dG9tID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIGdldCB0YWJEaXJlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYkRpcmVjdGlvbjtcbiAgfVxuICBzZXQgdGFiRGlyZWN0aW9uKGRpcmVjdGlvbjogVGFiRGlyZWN0aW9uKSB7XG4gICAgdGhpcy5fdGFiRGlyZWN0aW9uID0gZGlyZWN0aW9uO1xuICAgIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgICBjYXNlICdob3Jpem9udGFsJzpcbiAgICAgICAgdGhpcy5hbVRhYnNIb3Jpem9udGFsID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5hbVRhYnNWZXJ0aWNhbCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZlcnRpY2FsJzpcbiAgICAgICAgdGhpcy5hbVRhYnNIb3Jpem9udGFsID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYW1UYWJzVmVydGljYWwgPSB0cnVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBAT3V0cHV0KClcbiAgb25DaGFuZ2U6IEV2ZW50RW1pdHRlcjxUYWJzT25DaGFuZ2VFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFRhYnNPbkNoYW5nZUV2ZW50PigpO1xuICBAT3V0cHV0KClcbiAgb25UYWJDbGljazogRXZlbnRFbWl0dGVyPFRhYnNPbkNoYW5nZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8VGFic09uQ2hhbmdlRXZlbnQ+KCk7XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5hbS10YWJzJylcbiAgYW1UYWJzOiBib29sZWFuID0gdHJ1ZTtcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5hbS10YWJzLXRvcCcpXG4gIGFtVGFic1RvcDogYm9vbGVhbiA9IHRydWU7XG4gIEBIb3N0QmluZGluZygnY2xhc3MuYW0tdGFicy1sZWZ0JylcbiAgYW1UYWJzTGVmdDogYm9vbGVhbiA9IGZhbHNlO1xuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmFtLXRhYnMtcmlnaHQnKVxuICBhbVRhYnNSaWdodDogYm9vbGVhbiA9IGZhbHNlO1xuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmFtLXRhYnMtYm90dG9tJylcbiAgYW1UYWJzQm90dG9tOiBib29sZWFuID0gZmFsc2U7XG4gIEBIb3N0QmluZGluZygnY2xhc3MuYW0tdGFicy12ZXJ0aWNhbCcpXG4gIGFtVGFic1ZlcnRpY2FsOiBib29sZWFuID0gZmFsc2U7XG4gIEBIb3N0QmluZGluZygnY2xhc3MuYW0tdGFicy1ob3Jpem9udGFsJylcbiAgYW1UYWJzSG9yaXpvbnRhbDogYm9vbGVhbiA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIGNsaWNrVGFiKGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZEtleSAhPT0gaW5kZXgpIHtcbiAgICAgIHRoaXMua2V5VG9TZWxlY3QgPSBpbmRleDtcbiAgICAgIHRoaXMub25UYWJDbGljay5lbWl0KHsgaW5kZXg6IHRoaXMua2V5VG9TZWxlY3QgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0Q3VycmVudFRhYlBhbmVzKCk6IFF1ZXJ5TGlzdDxUYWJQYW5lQ29tcG9uZW50PiB7XG4gICAgcmV0dXJuIHRoaXMudGFiUGFuZXNDb250ZW50IHx8IHRoaXMudGFiUGFuZXM7XG4gIH1cblxuICBvblRvdWNoU3RhcnQoZXZlbnQpIHtcbiAgICB0aGlzLl9zdGFydFRpbWUgPSBldmVudC50aW1lU3RhbXA7XG4gICAgaWYgKHRoaXMuZ2V0Q3VycmVudFRhYlBhbmVzKCkgJiYgdGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoJ2hvcml6b250YWwnID09PSB0aGlzLl90YWJEaXJlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5fc3RhcnRQb3NpdGlvbiA9XG4gICAgICAgICAgZXZlbnQgJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXMgJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0gJiYgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0uY2xpZW50WDtcbiAgICAgIH0gZWxzZSBpZiAoJ3ZlcnRpY2FsJyA9PT0gdGhpcy5fdGFiRGlyZWN0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0UG9zaXRpb24gPVxuICAgICAgICAgIGV2ZW50ICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdICYmIGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25Ub3VjaE1vdmUoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKSAmJiB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICgnaG9yaXpvbnRhbCcgPT09IHRoaXMuX3RhYkRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLl9zdGFydFBvc2l0aW9uO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPCAwICYmIHRoaXMuYWN0aXZlVGFiID09PSB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzdGFuY2UgPiAwICYmIHRoaXMuYWN0aXZlVGFiID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHZlbG9jaXR5IOWwj+S6jumYiOWAvOaJjeiupOS4uuaYr3BhbuaTjeS9nFxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5nZXRWZWxvY2l0eShkaXN0YW5jZSwgZXZlbnQudGltZVN0YW1wIC0gdGhpcy5fc3RhcnRUaW1lKSA8PSB0aGlzLl92ZWxvY2l0eVRocmVzaG9sZCAmJlxuICAgICAgICAgIHRoaXMudXNlT25QYW4gJiZcbiAgICAgICAgICB0aGlzLnN3aXBlYWJsZSAmJlxuICAgICAgICAgIHRoaXMuYW5pbWF0ZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5wYW5lTW92ZVN0eWxlID0gJ3RyYW5zbGF0ZTNkKGNhbGMoLScgKyB0aGlzLnNlbGVjdGVkS2V5ICogMTAwICsgJyUgKyAnICsgZGlzdGFuY2UgKyAncHgpLCAwLCAwICknO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCd2ZXJ0aWNhbCcgPT09IHRoaXMuX3RhYkRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLl9zdGFydFBvc2l0aW9uO1xuICAgICAgICBpZiAoZGlzdGFuY2UgPCAwICYmIHRoaXMuYWN0aXZlVGFiID09PSB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSBpZiAoZGlzdGFuY2UgPiAwICYmIHRoaXMuYWN0aXZlVGFiID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmdldFZlbG9jaXR5KGRpc3RhbmNlLCBldmVudC50aW1lU3RhbXAgLSB0aGlzLl9zdGFydFRpbWUpIDw9IHRoaXMuX3ZlbG9jaXR5VGhyZXNob2xkICYmXG4gICAgICAgICAgdGhpcy51c2VPblBhbiAmJlxuICAgICAgICAgIHRoaXMuc3dpcGVhYmxlICYmXG4gICAgICAgICAgdGhpcy5hbmltYXRlZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLnBhbmVNb3ZlU3R5bGUgPSAndHJhbnNsYXRlM2QoMCwgY2FsYygtJyArIHRoaXMuc2VsZWN0ZWRLZXkgKiAxMDAgKyAnJSArICcgKyBkaXN0YW5jZSArICdweCwgMCApJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uVG91Y2hFbmQoZXZlbnQpIHtcbiAgICBpZiAodGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKSAmJiB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICgnaG9yaXpvbnRhbCcgPT09IHRoaXMuX3RhYkRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFggLSB0aGlzLl9zdGFydFBvc2l0aW9uO1xuICAgICAgICBjb25zdCBkaXN0YW5jZVRvQ2hhbmdlVGFiUHggPSB0aGlzLnRhYkNvbnRlbnQubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCAqIHRoaXMuZGlzdGFuY2VUb0NoYW5nZVRhYjtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICh0aGlzLmdldFZlbG9jaXR5KGRpc3RhbmNlLCBldmVudC50aW1lU3RhbXAgLSB0aGlzLl9zdGFydFRpbWUpIDw9IHRoaXMuX3ZlbG9jaXR5VGhyZXNob2xkICYmXG4gICAgICAgICAgICAodGhpcy51c2VPblBhbiAmJiB0aGlzLnN3aXBlYWJsZSAmJiBNYXRoLmFicyhkaXN0YW5jZSkgPiBkaXN0YW5jZVRvQ2hhbmdlVGFiUHgpKSB8fFxuICAgICAgICAgICh0aGlzLmdldFZlbG9jaXR5KGRpc3RhbmNlLCBldmVudC50aW1lU3RhbXAgLSB0aGlzLl9zdGFydFRpbWUpID4gdGhpcy5fdmVsb2NpdHlUaHJlc2hvbGQgJiZcbiAgICAgICAgICAgICh0aGlzLnN3aXBlYWJsZSAmJiBNYXRoLmFicyhkaXN0YW5jZSkgPiBkaXN0YW5jZVRvQ2hhbmdlVGFiUHggLyAyKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKGRpc3RhbmNlIDwgMCAmJiB0aGlzLmFjdGl2ZVRhYiA8IHRoaXMuZ2V0Q3VycmVudFRhYlBhbmVzKCkubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5rZXlUb1NlbGVjdCsrO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZGlzdGFuY2UgPiAwICYmIHRoaXMuYWN0aXZlVGFiID4gMCkge1xuICAgICAgICAgICAgdGhpcy5rZXlUb1NlbGVjdC0tO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhbmVNb3ZlU3R5bGUgPSAndHJhbnNsYXRlM2QoLScgKyB0aGlzLnNlbGVjdGVkS2V5ICogMTAwICsgJyUsIDAsIDAgKSc7XG4gICAgICB9IGVsc2UgaWYgKCd2ZXJ0aWNhbCcgPT09IHRoaXMuX3RhYkRpcmVjdGlvbikge1xuICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLmNsaWVudFkgLSB0aGlzLl9zdGFydFBvc2l0aW9uO1xuICAgICAgICBjb25zdCBkaXN0YW5jZVRvQ2hhbmdlVGFiUHggPSB0aGlzLnRhYkNvbnRlbnQubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKiB0aGlzLmRpc3RhbmNlVG9DaGFuZ2VUYWI7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAodGhpcy5nZXRWZWxvY2l0eShkaXN0YW5jZSwgZXZlbnQudGltZVN0YW1wIC0gdGhpcy5fc3RhcnRUaW1lKSA8PSB0aGlzLl92ZWxvY2l0eVRocmVzaG9sZCAmJlxuICAgICAgICAgICAgKHRoaXMudXNlT25QYW4gJiYgdGhpcy5zd2lwZWFibGUgJiYgTWF0aC5hYnMoZGlzdGFuY2UpID4gZGlzdGFuY2VUb0NoYW5nZVRhYlB4KSkgfHxcbiAgICAgICAgICAodGhpcy5nZXRWZWxvY2l0eShkaXN0YW5jZSwgZXZlbnQudGltZVN0YW1wIC0gdGhpcy5fc3RhcnRUaW1lKSA+IHRoaXMuX3ZlbG9jaXR5VGhyZXNob2xkICYmXG4gICAgICAgICAgICAodGhpcy5zd2lwZWFibGUgJiYgTWF0aC5hYnMoZGlzdGFuY2UpID4gZGlzdGFuY2VUb0NoYW5nZVRhYlB4IC8gMikpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChkaXN0YW5jZSA8IDAgJiYgdGhpcy5hY3RpdmVUYWIgPCB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHRoaXMua2V5VG9TZWxlY3QrKztcbiAgICAgICAgICB9IGVsc2UgaWYgKGRpc3RhbmNlID4gMCAmJiB0aGlzLmFjdGl2ZVRhYiA+IDApIHtcbiAgICAgICAgICAgIHRoaXMua2V5VG9TZWxlY3QtLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYW5lTW92ZVN0eWxlID0gJ3RyYW5zbGF0ZTNkKDAsIC0nICsgdGhpcy5zZWxlY3RlZEtleSAqIDEwMCArICclLCAwICknO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLnNlbGVjdFRhYlBhbmUodGhpcy5rZXlUb1NlbGVjdCk7XG4gICAgdGhpcy5zZWxlY3RlZEtleSA9IHRoaXMua2V5VG9TZWxlY3Q7XG4gIH1cblxuICBuZ0RvQ2hlY2soKSB7XG4gICAgaWYgKHRoaXMua2V5VG9TZWxlY3QgIT09IHRoaXMuc2VsZWN0ZWRLZXkgJiYgdGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKSAmJiB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2VsZWN0VGFiUGFuZSh0aGlzLmtleVRvU2VsZWN0KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRLZXkgPSB0aGlzLmtleVRvU2VsZWN0O1xuICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KHsgaW5kZXg6IHRoaXMuc2VsZWN0ZWRLZXkgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3RUYWJQYW5lKGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKSAmJiB0aGlzLmdldEN1cnJlbnRUYWJQYW5lcygpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGFjdHVhbEtleVRvU2VsZWN0ID0gTWF0aC5taW4odGhpcy5nZXRDdXJyZW50VGFiUGFuZXMoKS5sZW5ndGggLSAxLCBNYXRoLm1heChpbmRleCB8fCAwLCAwKSk7XG4gICAgICBpZiAoJ2hvcml6b250YWwnID09PSB0aGlzLl90YWJEaXJlY3Rpb24pIHtcbiAgICAgICAgdGhpcy5wYW5lTW92ZVN0eWxlID0gJ3RyYW5zbGF0ZTNkKC0nICsgYWN0dWFsS2V5VG9TZWxlY3QgKiAxMDAgKyAnJSwgMCwgMCApJztcbiAgICAgIH0gZWxzZSBpZiAoJ3ZlcnRpY2FsJyA9PT0gdGhpcy5fdGFiRGlyZWN0aW9uKSB7XG4gICAgICAgIHRoaXMucGFuZU1vdmVTdHlsZSA9ICd0cmFuc2xhdGUzZCgwLCAtJyArIGFjdHVhbEtleVRvU2VsZWN0ICogMTAwICsgJyUsIDAgKSc7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRWZWxvY2l0eShkZWx0YURpc3RhbmNlLCBkZWx0YVRpbWUpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoZGVsdGFEaXN0YW5jZSAvIGRlbHRhVGltZSk7XG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXI+XG4gIDxuZy10ZW1wbGF0ZVxuICAgICpuZ0lmPVwiJ3RvcCcgPT09IHRhYkJhclBvc2l0aW9uIHx8ICdsZWZ0JyA9PT0gdGFiQmFyUG9zaXRpb25cIlxuICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInJlbmRlclRhYkJhciB8fCByZW5kZXJEZWZhdWx0VGFiQmFyXCJcbiAgPlxuICA8L25nLXRlbXBsYXRlPlxuICA8ZGl2XG4gICAgI1RhYkNvbnRlbnRcbiAgICBjbGFzcz1cInt7IHByZWZpeENscyB9fS1jb250ZW50LXdyYXBcIlxuICAgIFtuZ0NsYXNzXT1cInsgJ2FtLXRhYnMtY29udGVudC13cmFwLWFuaW1hdGVkJzogYW5pbWF0ZWQgfVwiXG4gICAgW25nU3R5bGVdPVwieyB0cmFuc2Zvcm06IHBhbmVNb3ZlU3R5bGUsIHdlYmtpdFRyYW5zZm9ybTogcGFuZU1vdmVTdHlsZSB9XCJcbiAgICAodG91Y2hzdGFydCk9XCJvblRvdWNoU3RhcnQoJGV2ZW50KVwiXG4gICAgKHRvdWNobW92ZSk9XCJvblRvdWNoTW92ZSgkZXZlbnQpXCJcbiAgICAodG91Y2hlbmQpPVwib25Ub3VjaEVuZCgkZXZlbnQpXCJcbiAgPlxuICAgIDxkaXZcbiAgICAgIHRhYi1wYW5lLWJvZHlcbiAgICAgICpuZ0Zvcj1cImxldCB0YWJQYW5lIG9mIGdldEN1cnJlbnRUYWJQYW5lcygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgIFtjb250ZW50XT1cInRhYlBhbmUuY29udGVudFwiXG4gICAgICBbYWN0aXZlXT1cImkgPT09IHNlbGVjdGVkS2V5XCJcbiAgICAgIFtwcmVyZW5kZXJdPVwiXG4gICAgICAgIHByZXJlbmRlcmluZ1NpYmxpbmdzTnVtYmVyIDwgMCB8fFxuICAgICAgICAoc2VsZWN0ZWRLZXkgLSBpIDw9IHByZXJlbmRlcmluZ1NpYmxpbmdzTnVtYmVyICYmIHNlbGVjdGVkS2V5IC0gaSArIHByZXJlbmRlcmluZ1NpYmxpbmdzTnVtYmVyID49IDApXG4gICAgICBcIlxuICAgID48L2Rpdj5cbiAgPC9kaXY+XG4gIDxuZy10ZW1wbGF0ZVxuICAgICpuZ0lmPVwiJ2JvdHRvbScgPT09IHRhYkJhclBvc2l0aW9uIHx8ICdyaWdodCcgPT09IHRhYkJhclBvc2l0aW9uXCJcbiAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJyZW5kZXJUYWJCYXIgfHwgcmVuZGVyRGVmYXVsdFRhYkJhclwiXG4gID48L25nLXRlbXBsYXRlPlxuPC9uZy1jb250YWluZXI+XG5cbjxuZy10ZW1wbGF0ZSAjcmVuZGVyRGVmYXVsdFRhYkJhcj5cbiAgPERlZmF1bHRUYWJCYXJcbiAgICAjRGVmYXVsdFRhYkJhclxuICAgIFtwYWdlXT1cInBhZ2VcIlxuICAgIFthbmltYXRlZF09XCJhbmltYXRlZFwiXG4gICAgW2FjdGl2ZVRhYl09XCJzZWxlY3RlZEtleVwiXG4gICAgW3RhYlRpdGxlU2l6ZV09XCJ0YWJUaXRsZVNpemVcIlxuICAgIFt0YWJCYXJQb3NpdGlvbl09XCJ0YWJCYXJQb3NpdGlvblwiXG4gICAgW3RhYkJhclVuZGVybGluZVN0eWxlXT1cInRhYkJhclVuZGVybGluZVN0eWxlXCJcbiAgICBbdGFiQmFyQmFja2dyb3VuZENvbG9yXT1cInRhYkJhckJhY2tncm91bmRDb2xvclwiXG4gID5cbiAgICA8ZGl2XG4gICAgICAjVGFiVGl0bGVcbiAgICAgICpuZ0Zvcj1cImxldCB0YWJQYW5lIG9mIGdldEN1cnJlbnRUYWJQYW5lcygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgIGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWRlZmF1bHQtYmFyLXRhYlwiXG4gICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICdhbS10YWJzLWRlZmF1bHQtYmFyLXRhYi1hY3RpdmUnOiBpID09PSBzZWxlY3RlZEtleSxcbiAgICAgICAgJ2FtLXRhYnMtZGVmYXVsdC1iYXItdGFiLWRpc2FibGVkJzogdGFiUGFuZS5kaXNhYmxlZFxuICAgICAgfVwiXG4gICAgICBbbmdTdHlsZV09XCJ0YWJCYXJUZXh0U3R5bGVcIlxuICAgICAgW3N0eWxlLmNvbG9yXT1cImkgPT09IHNlbGVjdGVkS2V5ID8gdGFiQmFyQWN0aXZlVGV4dENvbG9yIDogdGFiQmFySW5hY3RpdmVUZXh0Q29sb3JcIlxuICAgICAgKGNsaWNrKT1cImNsaWNrVGFiKGkpXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwidGFiUGFuZS5pc1RpdGxlU3RyaW5nOyBlbHNlIHRpdGxlVGVtcGxhdGVcIj5cbiAgICAgICAge3sgdGFiUGFuZS50aXRsZSB9fVxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctdGVtcGxhdGUgI3RpdGxlVGVtcGxhdGU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJ0YWJQYW5lLnRpdGxlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG4gIDwvRGVmYXVsdFRhYkJhcj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=