UNPKG

carbon-components-angular

Version:
386 lines 41.6 kB
import { Component, Input, Output, EventEmitter, HostBinding, HostListener, ContentChildren, ViewChild } from "@angular/core"; import { Subscription } from "rxjs"; import { TabHeaderBase } from "./tab-header.directive"; import { BaseTabHeader } from "./base-tab-header.component"; import * as i0 from "@angular/core"; import * as i1 from "carbon-components-angular/utils"; import * as i2 from "carbon-components-angular/i18n"; import * as i3 from "@angular/common"; export class TabHeaderGroup extends BaseTabHeader { constructor(elementRef, changeDetectorRef, eventService, renderer, i18n) { super(elementRef, changeDetectorRef, eventService, renderer); this.elementRef = elementRef; this.changeDetectorRef = changeDetectorRef; this.eventService = eventService; this.renderer = renderer; this.i18n = i18n; /** * i18n strings for overflow controls and the tab list `aria-label` fallback. */ this.translations = this.i18n.get().TABS; /** * When `true`, sets each tab panel `tabindex` to `-1` for navigation-style usage. */ this.isNavigation = false; /** * Emits when a tab close control is used (with `dismissable`). * The emitted value is the tab index. */ this.tabClose = new EventEmitter(); this.selectedSubscriptionTracker = new Subscription(); this.closeSubscriptionTracker = new Subscription(); /** * Index of the selected tab for keyboard logic. */ this.currentSelectedTab = 0; /** * Focused tab index when `followFocus` is false (manual activation). */ this.activeIndex = null; } get fullWidthClass() { return this.distributeWidth; } /** * We use taller rows when any header has a secondary label. */ get tallClass() { return this.hasSecondaryLabelTabs; } get hasSecondaryLabelTabs() { if (!this.tabHeaderQuery || this.type !== "contained") { return false; } return this.tabHeaderQuery.toArray().some(h => h.secondaryLabel != null && String(h.secondaryLabel).trim() !== ""); } /** * True when `fullWidth` applies (contained, fewer than 9 headers). */ get distributeWidth() { return (this.fullWidth && this.type === "contained" && (this.tabHeaderQuery ? this.tabHeaderQuery.length < 9 : false)); } keyboardInput(event) { const tabHeadersArray = this.tabHeaderQuery.toArray(); if (event.key === "ArrowRight") { if (this.currentSelectedTab < tabHeadersArray.length - 1) { event.preventDefault(); if (this.followFocus && !tabHeadersArray[this.currentSelectedTab + 1].disabled) { tabHeadersArray[this.currentSelectedTab + 1].selectTab(); } else { tabHeadersArray[this.currentSelectedTab + 1].focus(); this.currentSelectedTab++; } } else { event.preventDefault(); if (this.followFocus && !tabHeadersArray[0].disabled) { tabHeadersArray[0].selectTab(); } else { tabHeadersArray[0].focus(); this.currentSelectedTab = 0; } } } if (event.key === "ArrowLeft") { if (this.currentSelectedTab > 0) { event.preventDefault(); if (this.followFocus && !tabHeadersArray[this.currentSelectedTab - 1].disabled) { tabHeadersArray[this.currentSelectedTab - 1].selectTab(); } else { tabHeadersArray[this.currentSelectedTab - 1].focus(); this.currentSelectedTab--; } } else { event.preventDefault(); if (this.followFocus && !tabHeadersArray[tabHeadersArray.length - 1].disabled) { tabHeadersArray[tabHeadersArray.length - 1].selectTab(); } else { tabHeadersArray[tabHeadersArray.length - 1].focus(); this.currentSelectedTab = tabHeadersArray.length - 1; } } } if (event.key === "Home") { event.preventDefault(); if (this.followFocus && !tabHeadersArray[0].disabled) { tabHeadersArray[0].selectTab(); } else { tabHeadersArray[0].focus(); this.currentSelectedTab = 0; } } if (event.key === "End") { event.preventDefault(); if (this.followFocus && !tabHeadersArray[tabHeadersArray.length - 1].disabled) { tabHeadersArray[tabHeadersArray.length - 1].selectTab(); } else { tabHeadersArray[tabHeadersArray.length - 1].focus(); this.currentSelectedTab = tabHeadersArray.length - 1; } } if ((event.key === " ") && !this.followFocus) { tabHeadersArray[this.currentSelectedTab].selectTab(); } } ngOnInit() { this.eventService.on(window, "resize", () => this.handleScroll()); } ngAfterContentInit() { // Reallocate trackers because subscriptions are permanently closed after unsubscribe this.selectedSubscriptionTracker.unsubscribe(); this.closeSubscriptionTracker.unsubscribe(); this.selectedSubscriptionTracker = new Subscription(); this.closeSubscriptionTracker = new Subscription(); if (this.tabHeaderQuery) { this.tabHeaderQuery.toArray() .forEach(tabHeader => { tabHeader.cacheActive = this.cacheActive; tabHeader.dismissable = this.dismissable; tabHeader.paneTabIndex = this.isNavigation ? null : 0; }); } const headersArray = this.tabHeaderQuery.toArray(); headersArray.forEach(tabHeader => { this.selectedSubscriptionTracker.add(tabHeader.selected.subscribe(() => { this.currentSelectedTab = this.tabHeaderQuery.toArray().indexOf(tabHeader); // The Filter takes the current selected tab out, then all other headers are // deactivated and their associated pane references are also deactivated. this.tabHeaderQuery.toArray().filter(header => header !== tabHeader) .forEach(filteredHeader => { filteredHeader.active = false; if (filteredHeader.paneReference) { filteredHeader.paneReference.active = false; } }); })); this.closeSubscriptionTracker.add(tabHeader.tabClose.subscribe(() => { const index = this.tabHeaderQuery.toArray().indexOf(tabHeader); this.tabClose.emit(index); })); }); this.setFirstTab(); } ngOnDestroy() { this.selectedSubscriptionTracker.unsubscribe(); this.closeSubscriptionTracker.unsubscribe(); clearTimeout(this.scrollDebounceTimer); } ngOnChanges(changes) { if (this.tabHeaderQuery) { if (changes.cacheActive) { this.tabHeaderQuery.toArray().forEach(tabHeader => tabHeader.cacheActive = this.cacheActive); } if (changes.dismissable) { this.tabHeaderQuery.toArray().forEach(tabHeader => tabHeader.dismissable = this.dismissable); } if (changes.isNavigation) { this.tabHeaderQuery.toArray() .forEach(tabHeader => tabHeader.paneTabIndex = this.isNavigation ? null : 0); } } } getSelectedTab() { const selected = this.tabHeaderQuery.toArray()[this.currentSelectedTab]; if (selected) { return selected; } return { headingIsTemplate: false, heading: "" }; } /** * Determines which `Tab` is initially selected. */ setFirstTab() { setTimeout(() => { const headers = this.tabHeaderQuery.toArray(); let selectedHeader = headers.find(h => h.active || h.paneReference?.active); if (!selectedHeader && headers.length > 0) { selectedHeader = headers[0]; } if (selectedHeader) { selectedHeader.selectTab(); this.activeIndex = this.currentSelectedTab; this.changeDetectorRef.markForCheck(); } }); } } TabHeaderGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaderGroup, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.EventService }, { token: i0.Renderer2 }, { token: i2.I18n }], target: i0.ɵɵFactoryTarget.Component }); TabHeaderGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TabHeaderGroup, selector: "cds-tab-header-group, ibm-tab-header-group", inputs: { translations: "translations", isNavigation: "isNavigation" }, outputs: { tabClose: "tabClose" }, host: { listeners: { "keydown": "keyboardInput($event)" }, properties: { "class.cds--tabs--full-width": "this.fullWidthClass", "class.cds--tabs--tall": "this.tallClass" } }, queries: [{ propertyName: "tabHeaderQuery", predicate: TabHeaderBase }], viewQueries: [{ propertyName: "headerContainer", first: true, predicate: ["tabList"], descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: ` <button type="button" class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous" [ngClass]="{ 'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden }" [attr.aria-hidden]="leftOverflowNavButtonHidden" [attr.tabindex]="-1" [attr.aria-label]="translations.BUTTON_ARIA_LEFT" [attr.title]="translations.BUTTON_ARIA_LEFT" (click)="handleOverflowNavClick(-1, tabHeaderQuery.length)" (pointerdown)="handleOverflowNavMouseDown(-1)" (pointerup)="handleOverflowNavMouseUp()" (pointerleave)="handleOverflowNavMouseUp()" (pointerout)="handleOverflowNavMouseUp()" (pointercancel)="handleOverflowNavMouseUp()"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path> </svg> </button> <div class="cds--tab--list" role="tablist" [attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL" [attr.aria-labelledby]="ariaLabelledby || null" (scroll)="handleScroll()" #tabList> <ng-container [ngTemplateOutlet]="contentBefore"></ng-container> <ng-content></ng-content> <ng-container [ngTemplateOutlet]="contentAfter"></ng-container> </div> <button type="button" class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next" [ngClass]="{ 'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden }" [attr.aria-hidden]="rightOverflowNavButtonHidden" [attr.tabindex]="-1" [attr.aria-label]="translations.BUTTON_ARIA_RIGHT" [attr.title]="translations.BUTTON_ARIA_RIGHT" (click)="handleOverflowNavClick(1, tabHeaderQuery.length)" (pointerdown)="handleOverflowNavMouseDown(1)" (pointerup)="handleOverflowNavMouseUp()" (pointerleave)="handleOverflowNavMouseUp()" (pointerout)="handleOverflowNavMouseUp()" (pointercancel)="handleOverflowNavMouseUp()"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path> </svg> </button> `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TabHeaderGroup, decorators: [{ type: Component, args: [{ selector: "cds-tab-header-group, ibm-tab-header-group", template: ` <button type="button" class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--previous" [ngClass]="{ 'cds--tab--overflow-nav-button--hidden': leftOverflowNavButtonHidden }" [attr.aria-hidden]="leftOverflowNavButtonHidden" [attr.tabindex]="-1" [attr.aria-label]="translations.BUTTON_ARIA_LEFT" [attr.title]="translations.BUTTON_ARIA_LEFT" (click)="handleOverflowNavClick(-1, tabHeaderQuery.length)" (pointerdown)="handleOverflowNavMouseDown(-1)" (pointerup)="handleOverflowNavMouseUp()" (pointerleave)="handleOverflowNavMouseUp()" (pointerout)="handleOverflowNavMouseUp()" (pointercancel)="handleOverflowNavMouseUp()"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M5 8L10 3 10.7 3.7 6.4 8 10.7 12.3 10 13z"></path> </svg> </button> <div class="cds--tab--list" role="tablist" [attr.aria-label]="ariaLabel || translations.HEADER_ARIA_LABEL" [attr.aria-labelledby]="ariaLabelledby || null" (scroll)="handleScroll()" #tabList> <ng-container [ngTemplateOutlet]="contentBefore"></ng-container> <ng-content></ng-content> <ng-container [ngTemplateOutlet]="contentAfter"></ng-container> </div> <button type="button" class="cds--tab--overflow-nav-button cds--tab--overflow-nav-button--next" [ngClass]="{ 'cds--tab--overflow-nav-button--hidden': rightOverflowNavButtonHidden }" [attr.aria-hidden]="rightOverflowNavButtonHidden" [attr.tabindex]="-1" [attr.aria-label]="translations.BUTTON_ARIA_RIGHT" [attr.title]="translations.BUTTON_ARIA_RIGHT" (click)="handleOverflowNavClick(1, tabHeaderQuery.length)" (pointerdown)="handleOverflowNavMouseDown(1)" (pointerup)="handleOverflowNavMouseUp()" (pointerleave)="handleOverflowNavMouseUp()" (pointerout)="handleOverflowNavMouseUp()" (pointercancel)="handleOverflowNavMouseUp()"> <svg focusable="false" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M11 8L6 13 5.3 12.3 9.6 8 5.3 3.7 6 3z"></path> </svg> </button> ` }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.EventService }, { type: i0.Renderer2 }, { type: i2.I18n }]; }, propDecorators: { fullWidthClass: [{ type: HostBinding, args: ["class.cds--tabs--full-width"] }], tallClass: [{ type: HostBinding, args: ["class.cds--tabs--tall"] }], translations: [{ type: Input }], isNavigation: [{ type: Input }], tabClose: [{ type: Output }], tabHeaderQuery: [{ type: ContentChildren, args: [TabHeaderBase] }], headerContainer: [{ type: ViewChild, args: ["tabList", { static: true }] }], keyboardInput: [{ type: HostListener, args: ["keydown", ["$event"]] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiLWhlYWRlci1ncm91cC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGFicy90YWItaGVhZGVyLWdyb3VwLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUVULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osZUFBZSxFQU1mLFNBQVMsRUFJVCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSXBDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7Ozs7O0FBMEU1RCxNQUFNLE9BQU8sY0FBZSxTQUFRLGFBQWE7SUFxRWhELFlBQ1csVUFBc0IsRUFDdEIsaUJBQW9DLEVBQ3BDLFlBQTBCLEVBQzFCLFFBQW1CLEVBQ25CLElBQVU7UUFFcEIsS0FBSyxDQUFDLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFObkQsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsU0FBSSxHQUFKLElBQUksQ0FBTTtRQXhDckI7O1dBRUc7UUFDTSxpQkFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDO1FBRTdDOztXQUVHO1FBQ00saUJBQVksR0FBRyxLQUFLLENBQUM7UUFFOUI7OztXQUdHO1FBQ08sYUFBUSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBUXRFLGdDQUEyQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsNkJB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Ozs7Ozs7O0VBb0VUO2lCQUNEO3VNQUdnRCxjQUFjO3NCQUE3RCxXQUFXO3VCQUFDLDZCQUE2QjtnQkFPQSxTQUFTO3NCQUFsRCxXQUFXO3VCQUFDLHVCQUF1QjtnQkE0QjNCLFlBQVk7c0JBQXBCLEtBQUs7Z0JBS0csWUFBWTtzQkFBcEIsS0FBSztnQkFNSSxRQUFRO3NCQUFqQixNQUFNO2dCQUt5QixjQUFjO3NCQUE3QyxlQUFlO3VCQUFDLGFBQWE7Z0JBRVUsZUFBZTtzQkFBdEQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQXlCdEMsYUFBYTtzQkFEWixZQUFZO3VCQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0UXVlcnlMaXN0LFxuXHRJbnB1dCxcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXIsXG5cdEhvc3RCaW5kaW5nLFxuXHRIb3N0TGlzdGVuZXIsXG5cdENvbnRlbnRDaGlsZHJlbixcblx0QWZ0ZXJDb250ZW50SW5pdCxcblx0RWxlbWVudFJlZixcblx0T25DaGFuZ2VzLFxuXHRTaW1wbGVDaGFuZ2VzLFxuXHRDaGFuZ2VEZXRlY3RvclJlZixcblx0Vmlld0NoaWxkLFxuXHRPbkluaXQsXG5cdE9uRGVzdHJveSxcblx0UmVuZGVyZXIyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBFdmVudFNlcnZpY2UgfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci91dGlsc1wiO1xuaW1wb3J0IHsgSTE4biB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2kxOG5cIjtcblxuaW1wb3J0IHsgVGFiSGVhZGVyQmFzZSB9IGZyb20gXCIuL3RhYi1oZWFkZXIuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBCYXNlVGFiSGVhZGVyIH0gZnJvbSBcIi4vYmFzZS10YWItaGVhZGVyLmNvbXBvbmVudFwiO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLXRhYi1oZWFkZXItZ3JvdXAsIGlibS10YWItaGVhZGVyLWdyb3VwXCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGJ1dHRvblxuXHRcdFx0dHlwZT1cImJ1dHRvblwiXG5cdFx0XHRjbGFzcz1cImNkcy0tdGFiLS1vdmVyZmxvdy1uYXYtYnV0dG9uIGNkcy0tdGFiLS1vdmVyZmxvdy1uYXYtYnV0dG9uLS1wcmV2aW91c1wiXG5cdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdCdjZHMtLXRhYi0tb3ZlcmZsb3ctbmF2LWJ1dHRvbi0taGlkZGVuJzogbGVmdE92ZXJmbG93TmF2QnV0dG9uSGlkZGVuXG5cdFx0XHR9XCJcblx0XHRcdFthdHRyLmFyaWEtaGlkZGVuXT1cImxlZnRPdmVyZmxvd05hdkJ1dHRvbkhpZGRlblwiXG5cdFx0XHRbYXR0ci50YWJpbmRleF09XCItMVwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cInRyYW5zbGF0aW9ucy5CVVRUT05fQVJJQV9MRUZUXCJcblx0XHRcdFthdHRyLnRpdGxlXT1cInRyYW5zbGF0aW9ucy5CVVRUT05fQVJJQV9MRUZUXCJcblx0XHRcdChjbGljayk9XCJoYW5kbGVPdmVyZmxvd05hdkNsaWNrKC0xLCB0YWJIZWFkZXJRdWVyeS5sZW5ndGgpXCJcblx0XHRcdChwb2ludGVyZG93bik9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlRG93bigtMSlcIlxuXHRcdFx0KHBvaW50ZXJ1cCk9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlVXAoKVwiXG5cdFx0XHQocG9pbnRlcmxlYXZlKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyb3V0KT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyY2FuY2VsKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCI+XG5cdFx0XHQ8c3ZnXG5cdFx0XHRcdGZvY3VzYWJsZT1cImZhbHNlXCJcblx0XHRcdFx0cHJlc2VydmVBc3BlY3RSYXRpbz1cInhNaWRZTWlkIG1lZXRcIlxuXHRcdFx0XHR4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcblx0XHRcdFx0ZmlsbD1cImN1cnJlbnRDb2xvclwiXG5cdFx0XHRcdHdpZHRoPVwiMTZcIlxuXHRcdFx0XHRoZWlnaHQ9XCIxNlwiXG5cdFx0XHRcdHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuXHRcdFx0XHRhcmlhLWhpZGRlbj1cInRydWVcIj5cblx0XHRcdFx0PHBhdGggZD1cIk01IDhMMTAgMyAxMC43IDMuNyA2LjQgOCAxMC43IDEyLjMgMTAgMTN6XCI+PC9wYXRoPlxuXHRcdFx0PC9zdmc+XG5cdFx0PC9idXR0b24+XG5cdFx0PGRpdlxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRhYi0tbGlzdFwiXG5cdFx0XHRyb2xlPVwidGFibGlzdFwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbCB8fCB0cmFuc2xhdGlvbnMuSEVBREVSX0FSSUFfTEFCRUxcIlxuXHRcdFx0W2F0dHIuYXJpYS1sYWJlbGxlZGJ5XT1cImFyaWFMYWJlbGxlZGJ5IHx8IG51bGxcIlxuXHRcdFx0KHNjcm9sbCk9XCJoYW5kbGVTY3JvbGwoKVwiXG5cdFx0XHQjdGFiTGlzdD5cblx0XHRcdDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY29udGVudEJlZm9yZVwiPjwvbmctY29udGFpbmVyPlxuXHRcdFx0PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuXHRcdFx0PG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJjb250ZW50QWZ0ZXJcIj48L25nLWNvbnRhaW5lcj5cblx0XHQ8L2Rpdj5cblx0XHQ8YnV0dG9uXG5cdFx0XHR0eXBlPVwiYnV0dG9uXCJcblx0XHRcdGNsYXNzPVwiY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24gY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLW5leHRcIlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS10YWItLW92ZXJmbG93LW5hdi1idXR0b24tLWhpZGRlbic6IHJpZ2h0T3ZlcmZsb3dOYXZCdXR0b25IaWRkZW5cblx0XHRcdH1cIlxuXHRcdFx0W2F0dHIuYXJpYS1oaWRkZW5dPVwicmlnaHRPdmVyZmxvd05hdkJ1dHRvbkhpZGRlblwiXG5cdFx0XHRbYXR0ci50YWJpbmRleF09XCItMVwiXG5cdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cInRyYW5zbGF0aW9ucy5CVVRUT05fQVJJQV9SSUdIVFwiXG5cdFx0XHRbYXR0ci50aXRsZV09XCJ0cmFuc2xhdGlvbnMuQlVUVE9OX0FSSUFfUklHSFRcIlxuXHRcdFx0KGNsaWNrKT1cImhhbmRsZU92ZXJmbG93TmF2Q2xpY2soMSwgdGFiSGVhZGVyUXVlcnkubGVuZ3RoKVwiXG5cdFx0XHQocG9pbnRlcmRvd24pPVwiaGFuZGxlT3ZlcmZsb3dOYXZNb3VzZURvd24oMSlcIlxuXHRcdFx0KHBvaW50ZXJ1cCk9XCJoYW5kbGVPdmVyZmxvd05hdk1vdXNlVXAoKVwiXG5cdFx0XHQocG9pbnRlcmxlYXZlKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyb3V0KT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCJcblx0XHRcdChwb2ludGVyY2FuY2VsKT1cImhhbmRsZU92ZXJmbG93TmF2TW91c2VVcCgpXCI+XG5cdFx0XHQ8c3ZnXG5cdFx0XHRcdGZvY3VzYWJsZT1cImZhbHNlXCJcblx0XHRcdFx0cHJlc2VydmVBc3BlY3RSYXRpbz1cInhNaWRZTWlkIG1lZXRcIlxuXHRcdFx0XHR4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcblx0XHRcdFx0ZmlsbD1cImN1cnJlbnRDb2xvclwiXG5cdFx0XHRcdHdpZHRoPVwiMTZcIlxuXHRcdFx0XHRoZWlnaHQ9XCIxNlwiXG5cdFx0XHRcdHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuXHRcdFx0XHRhcmlhLWhpZGRlbj1cInRydWVcIj5cblx0XHRcdFx0PHBhdGggZD1cIk0xMSA4TDYgMTMgNS4zIDEyLjMgOS42IDggNS4zIDMuNyA2IDN6XCI+PC9wYXRoPlxuXHRcdFx0PC9zdmc+XG5cdFx0PC9idXR0b24+XG5cdGBcbn0pXG5leHBvcnQgY2xhc3MgVGFiSGVhZGVyR3JvdXAgZXh0ZW5kcyBCYXNlVGFiSGVhZGVyIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG5cblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS10YWJzLS1mdWxsLXdpZHRoXCIpIGdldCBmdWxsV2lkdGhDbGFzcygpIHtcblx0XHRyZXR1cm4gdGhpcy5kaXN0cmlidXRlV2lkdGg7XG5cdH1cblxuXHQvKipcblx0ICogV2UgdXNlIHRhbGxlciByb3dzIHdoZW4gYW55IGhlYWRlciBoYXMgYSBzZWNvbmRhcnkgbGFiZWwuXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXRhYnMtLXRhbGxcIikgZ2V0IHRhbGxDbGFzcygpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5oYXNTZWNvbmRhcnlMYWJlbFRhYnM7XG5cdH1cblxuXHRnZXQgaGFzU2Vjb25kYXJ5TGFiZWxUYWJzKCk6IGJvb2xlYW4ge1xuXHRcdGlmICghdGhpcy50YWJIZWFkZXJRdWVyeSB8fCB0aGlzLnR5cGUgIT09IFwiY29udGFpbmVkXCIpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpLnNvbWUoXG5cdFx0XHRoID0+XG5cdFx0XHRcdGguc2Vjb25kYXJ5TGFiZWwgIT0gbnVsbCAmJlxuXHRcdFx0XHRTdHJpbmcoaC5zZWNvbmRhcnlMYWJlbCkudHJpbSgpICE9PSBcIlwiXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcnVlIHdoZW4gYGZ1bGxXaWR0aGAgYXBwbGllcyAoY29udGFpbmVkLCBmZXdlciB0aGFuIDkgaGVhZGVycykuXG5cdCAqL1xuXHRnZXQgZGlzdHJpYnV0ZVdpZHRoKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAoXG5cdFx0XHR0aGlzLmZ1bGxXaWR0aCAmJlxuXHRcdFx0dGhpcy50eXBlID09PSBcImNvbnRhaW5lZFwiICYmXG5cdFx0XHQodGhpcy50YWJIZWFkZXJRdWVyeSA/IHRoaXMudGFiSGVhZGVyUXVlcnkubGVuZ3RoIDwgOSA6IGZhbHNlKVxuXHRcdCk7XG5cdH1cblx0LyoqXG5cdCAqIGkxOG4gc3RyaW5ncyBmb3Igb3ZlcmZsb3cgY29udHJvbHMgYW5kIHRoZSB0YWIgbGlzdCBgYXJpYS1sYWJlbGAgZmFsbGJhY2suXG5cdCAqL1xuXHRASW5wdXQoKSB0cmFuc2xhdGlvbnMgPSB0aGlzLmkxOG4uZ2V0KCkuVEFCUztcblxuXHQvKipcblx0ICogV2hlbiBgdHJ1ZWAsIHNldHMgZWFjaCB0YWIgcGFuZWwgYHRhYmluZGV4YCB0byBgLTFgIGZvciBuYXZpZ2F0aW9uLXN0eWxlIHVzYWdlLlxuXHQgKi9cblx0QElucHV0KCkgaXNOYXZpZ2F0aW9uID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIEVtaXRzIHdoZW4gYSB0YWIgY2xvc2UgY29udHJvbCBpcyB1c2VkICh3aXRoIGBkaXNtaXNzYWJsZWApLlxuXHQgKiBUaGUgZW1pdHRlZCB2YWx1ZSBpcyB0aGUgdGFiIGluZGV4LlxuXHQgKi9cblx0QE91dHB1dCgpIHRhYkNsb3NlOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuXG5cdC8qKlxuXHQgKiBQcm9qZWN0ZWQgdGFiIGhlYWRlcnMgKGBUYWJIZWFkZXJCYXNlYDogZGlyZWN0aXZlIG9yIGBjZHMtdGFiLWhlYWRlcmApLlxuXHQgKi9cblx0QENvbnRlbnRDaGlsZHJlbihUYWJIZWFkZXJCYXNlKSB0YWJIZWFkZXJRdWVyeTogUXVlcnlMaXN0PFRhYkhlYWRlckJhc2U+O1xuXG5cdEBWaWV3Q2hpbGQoXCJ0YWJMaXN0XCIsIHsgc3RhdGljOiB0cnVlIH0pIGhlYWRlckNvbnRhaW5lcjtcblx0c2VsZWN0ZWRTdWJzY3JpcHRpb25UcmFja2VyID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXHRjbG9zZVN1YnNjcmlwdGlvblRyYWNrZXIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cblx0LyoqXG5cdCAqIEluZGV4IG9mIHRoZSBzZWxlY3RlZCB0YWIgZm9yIGtleWJvYXJkIGxvZ2ljLlxuXHQgKi9cblx0Y3VycmVudFNlbGVjdGVkVGFiID0gMDtcblxuXHQvKipcblx0ICogRm9jdXNlZCB0YWIgaW5kZXggd2hlbiBgZm9sbG93Rm9jdXNgIGlzIGZhbHNlIChtYW51YWwgYWN0aXZhdGlvbikuXG5cdCAqL1xuXHRhY3RpdmVJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJvdGVjdGVkIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG5cdFx0cHJvdGVjdGVkIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcblx0XHRwcm90ZWN0ZWQgZXZlbnRTZXJ2aWNlOiBFdmVudFNlcnZpY2UsXG5cdFx0cHJvdGVjdGVkIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG5cdFx0cHJvdGVjdGVkIGkxOG46IEkxOG5cblx0KSB7XG5cdFx0c3VwZXIoZWxlbWVudFJlZiwgY2hhbmdlRGV0ZWN0b3JSZWYsIGV2ZW50U2VydmljZSwgcmVuZGVyZXIpO1xuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImtleWRvd25cIiwgW1wiJGV2ZW50XCJdKVxuXHRrZXlib2FyZElucHV0KGV2ZW50KSB7XG5cdFx0Y29uc3QgdGFiSGVhZGVyc0FycmF5ID0gdGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCk7XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkFycm93UmlnaHRcIikge1xuXHRcdFx0aWYgKHRoaXMuY3VycmVudFNlbGVjdGVkVGFiIDwgdGFiSGVhZGVyc0FycmF5Lmxlbmd0aCAtIDEpIHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMgJiYgIXRhYkhlYWRlcnNBcnJheVt0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYiArIDFdLmRpc2FibGVkKSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RoaXMuY3VycmVudFNlbGVjdGVkVGFiICsgMV0uc2VsZWN0VGFiKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RoaXMuY3VycmVudFNlbGVjdGVkVGFiICsgMV0uZm9jdXMoKTtcblx0XHRcdFx0XHR0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYisrO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZiAodGhpcy5mb2xsb3dGb2N1cyAmJiAhdGFiSGVhZGVyc0FycmF5WzBdLmRpc2FibGVkKSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5WzBdLnNlbGVjdFRhYigpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRhYkhlYWRlcnNBcnJheVswXS5mb2N1cygpO1xuXHRcdFx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dMZWZ0XCIpIHtcblx0XHRcdGlmICh0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYiA+IDApIHtcblx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMgJiYgIXRhYkhlYWRlcnNBcnJheVt0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYiAtIDFdLmRpc2FibGVkKSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RoaXMuY3VycmVudFNlbGVjdGVkVGFiIC0gMV0uc2VsZWN0VGFiKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RoaXMuY3VycmVudFNlbGVjdGVkVGFiIC0gMV0uZm9jdXMoKTtcblx0XHRcdFx0XHR0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYi0tO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRpZiAodGhpcy5mb2xsb3dGb2N1cyAmJiAhdGFiSGVhZGVyc0FycmF5W3RhYkhlYWRlcnNBcnJheS5sZW5ndGggLSAxXS5kaXNhYmxlZCkge1xuXHRcdFx0XHRcdHRhYkhlYWRlcnNBcnJheVt0YWJIZWFkZXJzQXJyYXkubGVuZ3RoIC0gMV0uc2VsZWN0VGFiKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RhYkhlYWRlcnNBcnJheS5sZW5ndGggLSAxXS5mb2N1cygpO1xuXHRcdFx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gdGFiSGVhZGVyc0FycmF5Lmxlbmd0aCAtIDE7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkhvbWVcIikge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdGlmICh0aGlzLmZvbGxvd0ZvY3VzICYmICF0YWJIZWFkZXJzQXJyYXlbMF0uZGlzYWJsZWQpIHtcblx0XHRcdFx0dGFiSGVhZGVyc0FycmF5WzBdLnNlbGVjdFRhYigpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGFiSGVhZGVyc0FycmF5WzBdLmZvY3VzKCk7XG5cdFx0XHRcdHRoaXMuY3VycmVudFNlbGVjdGVkVGFiID0gMDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkVuZFwiKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0aWYgKHRoaXMuZm9sbG93Rm9jdXMgJiYgIXRhYkhlYWRlcnNBcnJheVt0YWJIZWFkZXJzQXJyYXkubGVuZ3RoIC0gMV0uZGlzYWJsZWQpIHtcblx0XHRcdFx0dGFiSGVhZGVyc0FycmF5W3RhYkhlYWRlcnNBcnJheS5sZW5ndGggLSAxXS5zZWxlY3RUYWIoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRhYkhlYWRlcnNBcnJheVt0YWJIZWFkZXJzQXJyYXkubGVuZ3RoIC0gMV0uZm9jdXMoKTtcblx0XHRcdFx0dGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPSB0YWJIZWFkZXJzQXJyYXkubGVuZ3RoIC0gMTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoKGV2ZW50LmtleSA9PT0gXCIgXCIpICYmICF0aGlzLmZvbGxvd0ZvY3VzKSB7XG5cdFx0XHR0YWJIZWFkZXJzQXJyYXlbdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWJdLnNlbGVjdFRhYigpO1xuXHRcdH1cblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuZXZlbnRTZXJ2aWNlLm9uKHdpbmRvdyBhcyBhbnksIFwicmVzaXplXCIsICgpID0+IHRoaXMuaGFuZGxlU2Nyb2xsKCkpO1xuXHR9XG5cblx0bmdBZnRlckNvbnRlbnRJbml0KCkge1xuXHRcdC8vIFJlYWxsb2NhdGUgdHJhY2tlcnMgYmVjYXVzZSBzdWJzY3JpcHRpb25zIGFyZSBwZXJtYW5lbnRseSBjbG9zZWQgYWZ0ZXIgdW5zdWJzY3JpYmVcblx0XHR0aGlzLnNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlci51bnN1YnNjcmliZSgpO1xuXHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLnVuc3Vic2NyaWJlKCk7XG5cdFx0dGhpcy5zZWxlY3RlZFN1YnNjcmlwdGlvblRyYWNrZXIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cdFx0dGhpcy5jbG9zZVN1YnNjcmlwdGlvblRyYWNrZXIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cblx0XHRpZiAodGhpcy50YWJIZWFkZXJRdWVyeSkge1xuXHRcdFx0dGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KClcblx0XHRcdFx0LmZvckVhY2godGFiSGVhZGVyID0+IHtcblx0XHRcdFx0XHR0YWJIZWFkZXIuY2FjaGVBY3RpdmUgPSB0aGlzLmNhY2hlQWN0aXZlO1xuXHRcdFx0XHRcdHRhYkhlYWRlci5kaXNtaXNzYWJsZSA9IHRoaXMuZGlzbWlzc2FibGU7XG5cdFx0XHRcdFx0dGFiSGVhZGVyLnBhbmVUYWJJbmRleCA9IHRoaXMuaXNOYXZpZ2F0aW9uID8gbnVsbCA6IDA7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IGhlYWRlcnNBcnJheSA9IHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpO1xuXG5cdFx0aGVhZGVyc0FycmF5LmZvckVhY2godGFiSGVhZGVyID0+IHtcblx0XHRcdHRoaXMuc2VsZWN0ZWRTdWJzY3JpcHRpb25UcmFja2VyLmFkZChcblx0XHRcdFx0dGFiSGVhZGVyLnNlbGVjdGVkLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5jdXJyZW50U2VsZWN0ZWRUYWIgPSB0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKS5pbmRleE9mKHRhYkhlYWRlcik7XG5cdFx0XHRcdFx0Ly8gVGhlIEZpbHRlciB0YWtlcyB0aGUgY3VycmVudCBzZWxlY3RlZCB0YWIgb3V0LCB0aGVuIGFsbCBvdGhlciBoZWFkZXJzIGFyZVxuXHRcdFx0XHRcdC8vIGRlYWN0aXZhdGVkIGFuZCB0aGVpciBhc3NvY2lhdGVkIHBhbmUgcmVmZXJlbmNlcyBhcmUgYWxzbyBkZWFjdGl2YXRlZC5cblx0XHRcdFx0XHR0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKS5maWx0ZXIoaGVhZGVyID0+IGhlYWRlciAhPT0gdGFiSGVhZGVyKVxuXHRcdFx0XHRcdFx0LmZvckVhY2goZmlsdGVyZWRIZWFkZXIgPT4ge1xuXHRcdFx0XHRcdFx0XHRmaWx0ZXJlZEhlYWRlci5hY3RpdmUgPSBmYWxzZTtcblx0XHRcdFx0XHRcdFx0aWYgKGZpbHRlcmVkSGVhZGVyLnBhbmVSZWZlcmVuY2UpIHtcblx0XHRcdFx0XHRcdFx0XHRmaWx0ZXJlZEhlYWRlci5wYW5lUmVmZXJlbmNlLmFjdGl2ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLmFkZChcblx0XHRcdFx0dGFiSGVhZGVyLnRhYkNsb3NlLnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdFx0Y29uc3QgaW5kZXggPSB0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKS5pbmRleE9mKHRhYkhlYWRlcik7XG5cdFx0XHRcdFx0dGhpcy50YWJDbG9zZS5lbWl0KGluZGV4KTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLnNldEZpcnN0VGFiKCk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHR0aGlzLnNlbGVjdGVkU3Vic2NyaXB0aW9uVHJhY2tlci51bnN1YnNjcmliZSgpO1xuXHRcdHRoaXMuY2xvc2VTdWJzY3JpcHRpb25UcmFja2VyLnVuc3Vic2NyaWJlKCk7XG5cdFx0Y2xlYXJUaW1lb3V0KHRoaXMuc2Nyb2xsRGVib3VuY2VUaW1lcik7XG5cdH1cblxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG5cdFx0aWYgKHRoaXMudGFiSGVhZGVyUXVlcnkpIHtcblx0XHRcdGlmIChjaGFuZ2VzLmNhY2hlQWN0aXZlKSB7XG5cdFx0XHRcdHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpLmZvckVhY2godGFiSGVhZGVyID0+IHRhYkhlYWRlci5jYWNoZUFjdGl2ZSA9IHRoaXMuY2FjaGVBY3RpdmUpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoY2hhbmdlcy5kaXNtaXNzYWJsZSkge1xuXHRcdFx0XHR0aGlzLnRhYkhlYWRlclF1ZXJ5LnRvQXJyYXkoKS5mb3JFYWNoKHRhYkhlYWRlciA9PiB0YWJIZWFkZXIuZGlzbWlzc2FibGUgPSB0aGlzLmRpc21pc3NhYmxlKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNoYW5nZXMuaXNOYXZpZ2F0aW9uKSB7XG5cdFx0XHRcdHRoaXMudGFiSGVhZGVyUXVlcnkudG9BcnJheSgpXG5cdFx0XHRcdFx0LmZvckVhY2godGFiSGVhZGVyID0+IHRhYkhlYWRlci5wYW5lVGFiSW5kZXggPSB0aGlzLmlzTmF2aWdhdGlvbiA/IG51bGwgOiAwKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRnZXRTZWxlY3RlZFRhYigpOiBhbnkge1xuXHRcdGNvbnN0IHNlbGVjdGVkID0gdGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KClbdGhpcy5jdXJyZW50U2VsZWN0ZWRUYWJdO1xuXHRcdGlmIChzZWxlY3RlZCkge1xuXHRcdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0aGVhZGluZ0lzVGVtcGxhdGU6IGZhbHNlLFxuXHRcdFx0aGVhZGluZzogXCJcIlxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lcyB3aGljaCBgVGFiYCBpcyBpbml0aWFsbHkgc2VsZWN0ZWQuXG5cdCAqL1xuXHRwcm90ZWN0ZWQgc2V0Rmlyc3RUYWIoKSB7XG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRjb25zdCBoZWFkZXJzID0gdGhpcy50YWJIZWFkZXJRdWVyeS50b0FycmF5KCk7XG5cdFx0XHRsZXQgc2VsZWN0ZWRIZWFkZXIgPSBoZWFkZXJzLmZpbmQoaCA9PiBoLmFjdGl2ZSB8fCBoLnBhbmVSZWZlcmVuY2U/LmFjdGl2ZSk7XG5cdFx0XHRpZiAoIXNlbGVjdGVkSGVhZGVyICYmIGhlYWRlcnMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRzZWxlY3RlZEhlYWRlciA9IGhlYWRlcnNbMF07XG5cdFx0XHR9XG5cdFx0XHRpZiAoc2VsZWN0ZWRIZWFkZXIpIHtcblx0XHRcdFx0c2VsZWN0ZWRIZWFkZXIuc2VsZWN0VGFiKCk7XG5cdFx0XHRcdHRoaXMuYWN0aXZlSW5kZXggPSB0aGlzLmN1cnJlbnRTZWxlY3RlZFRhYjtcblx0XHRcdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuIl19