UNPKG

@angular-mdl/core

Version:

Angular components, directives and styles based on material design lite https://getmdl.io.

439 lines 49.6 kB
import { Component, ContentChild, ContentChildren, ElementRef, EventEmitter, Inject, Injectable, InjectionToken, Input, NgZone, Optional, Output, QueryList, Renderer2, ViewEncapsulation, } from "@angular/core"; import { EventManager } from "@angular/platform-browser"; import { MdlLayoutHeaderComponent } from "./mdl-layout-header.component"; import { MdlLayoutDrawerComponent } from "./mdl-layout-drawer.component"; import { MdlLayoutContentComponent } from "./mdl-layout-content.component"; import { BehaviorSubject } from "rxjs"; import { toBoolean } from "../common/boolean-property"; import { toNumber } from "../common/number.property"; import { MdlError } from "../common/mdl-error"; import { MdlLayoutMediatorService } from "./mdl-layout-mediator.service"; import * as i0 from "@angular/core"; import * as i1 from "@angular/platform-browser"; import * as i2 from "./mdl-layout-mediator.service"; import * as i3 from "../icon/mdl-icon.component"; import * as i4 from "@angular/common"; const ESCAPE = 27; const STANDARD = "standard"; const WATERFALL = "waterfall"; const SCROLL = "scroll"; /** * The LAYOUT_SCREEN_SIZE_THRESHOLD can be changed at the root module. Just provide a value for this InjectionToken: * * providers: [ * {provide:LAYOUT_SCREEN_SIZE_THRESHOLD, useValue: 768 } * ] * * you also need to change the scss variable to the same value: $layout-screen-size-threshold: 768px. * * It should be clear that this can only be used if you are using the scss and not the pre compiled css from getmdl.io. * */ export const LAYOUT_SCREEN_SIZE_THRESHOLD = new InjectionToken("layoutScreenSizeThreshold"); export class MdLUnsupportedLayoutTypeError extends MdlError { constructor(type) { /* istanbul ignore next */ super(`Layout type "${type}" isn't supported by mdl-layout (allowed: standard, waterfall, scroll).`); } } export class MdlScreenSizeService { constructor(ngZone, layoutScreenSizeThreshold) { this.layoutScreenSizeThreshold = layoutScreenSizeThreshold; this.sizesSubject = new BehaviorSubject(false); this.windowMediaQueryListener = null; // if no value is injected the default size wil be used. same as $layout-screen-size-threshold in scss if (!this.layoutScreenSizeThreshold) { this.layoutScreenSizeThreshold = 1024; } // do not try to access the window object if rendered on the server if (typeof window === "object" && "matchMedia" in window) { const query = window.matchMedia(`(max-width: ${this.layoutScreenSizeThreshold}px)`); const queryListener = () => { ngZone.run(() => { this.sizesSubject.next(query.matches); }); }; // - addEventListener not working in Safari // eslint-disable-next-line query.addListener(queryListener); this.windowMediaQueryListener = () => { // eslint-disable-next-line query.removeListener(queryListener); }; // set the initial state this.sizesSubject.next(query.matches); } } isSmallScreen() { return this.sizesSubject.value; } sizes() { return this.sizesSubject.asObservable(); } destroy() { if (this.windowMediaQueryListener) { this.windowMediaQueryListener(); this.windowMediaQueryListener = null; } } } MdlScreenSizeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlScreenSizeService, deps: [{ token: i0.NgZone }, { token: LAYOUT_SCREEN_SIZE_THRESHOLD, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); MdlScreenSizeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlScreenSizeService, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlScreenSizeService, decorators: [{ type: Injectable, args: [{ providedIn: "root", }] }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [LAYOUT_SCREEN_SIZE_THRESHOLD] }] }]; } }); export class MdlLayoutComponent { constructor(renderer, evm, el, screenSizeService, layoutMediatorService) { this.renderer = renderer; this.evm = evm; this.el = el; this.screenSizeService = screenSizeService; this.layoutMediatorService = layoutMediatorService; // will be set to undefined, if not a direct child or not present in 2.0.0 i // n 2.0.1 it is now the grand child drawer again :( this.drawers = new QueryList(); // eslint-disable-next-line this.mode = STANDARD; // eslint-disable-next-line this.selectedTabEmitter = new EventEmitter(); // eslint-disable-next-line this.mouseoverTabEmitter = new EventEmitter(); // eslint-disable-next-line this.mouseoutTabEmitter = new EventEmitter(); // eslint-disable-next-line // eslint-disable-next-line @angular-eslint/no-output-on-prefix this.onOpen = new EventEmitter(); // eslint-disable-next-line // eslint-disable-next-line @angular-eslint/no-output-on-prefix this.onClose = new EventEmitter(); this.isDrawerVisible = false; this.isSmallScreen = false; this.isFixedDrawerIntern = false; this.isFixedHeaderIntern = false; this.isSeamedIntern = false; this.selectedIndexIntern = 0; this.isNoDrawerIntern = false; this.subscriptions = []; } get isFixedDrawer() { return this.isFixedDrawerIntern; } set isFixedDrawer(value) { this.isFixedDrawerIntern = toBoolean(value); } get isFixedHeader() { return this.isFixedHeaderIntern; } set isFixedHeader(value) { this.isFixedHeaderIntern = toBoolean(value); } get isSeamed() { return this.isSeamedIntern; } set isSeamed(value) { this.isSeamedIntern = toBoolean(value); } get selectedIndex() { return this.selectedIndexIntern ? this.selectedIndexIntern : 0; } set selectedIndex(value) { this.selectedIndexIntern = toNumber(value); } get isNoDrawer() { return this.isNoDrawerIntern; } set isNoDrawer(value) { this.isNoDrawerIntern = toBoolean(value); } ngAfterContentInit() { this.validateMode(); if (this.header && this.content && this.content.tabs) { this.header.tabs = this.content.tabs; this.updateSelectedTabIndex(); } if (this.header && this.header.tabs) { this.subscriptions.push(this.layoutMediatorService .onTabMouseOut() .subscribe((tab) => { this.onTabMouseout(tab); })); this.subscriptions.push(this.layoutMediatorService .onTabMouseover() .subscribe((tab) => { this.onTabMouseover(tab); })); this.subscriptions.push(this.layoutMediatorService .onTabSelected() .subscribe((tab) => { this.tabSelected(tab); })); } } ngOnChanges(changes) { if (changes["selectedIndex"]) { this.updateSelectedTabIndex(); } } toggleDrawer() { this.isDrawerVisible = !this.isDrawerVisible; if (this.drawers && this.drawers.length > 0) { this.setDrawerVisible(this.isDrawerVisible); } } closeDrawer() { this.isDrawerVisible = false; if (this.drawers && this.drawers.length > 0) { this.setDrawerVisible(false); } } openDrawer() { this.isDrawerVisible = true; if (this.drawers && this.drawers.length > 0) { this.setDrawerVisible(true); } } obfuscatorKeyDown($event) { if ($event.keyCode === ESCAPE) { this.toggleDrawer(); } } ngOnDestroy() { if (this.scrollListener) { this.scrollListener(); this.scrollListener = undefined; } this.subscriptions.forEach((sub) => sub.unsubscribe()); } closeDrawerOnSmallScreens() { if (this.isSmallScreen && this.isDrawerVisible) { this.closeDrawer(); } } openDrawerOnSmallScreens() { if (this.isSmallScreen && !this.isDrawerVisible) { this.openDrawer(); } } hasDrawer() { return !!(this.drawers && this.drawers.length > 0); } tabSelected(tab) { const index = this.header?.tabs.toArray().indexOf(tab); if (index !== this.selectedIndex) { this.selectedIndex = index; this.updateSelectedTabIndex(); this.selectedTabEmitter.emit({ index: this.selectedIndex }); } } onTabMouseover(tab) { const index = this.header?.tabs.toArray().indexOf(tab); this.mouseoverTabEmitter.emit({ index }); } onTabMouseout(tab) { const index = this.header?.tabs.toArray().indexOf(tab); this.mouseoutTabEmitter.emit({ index }); } updateSelectedTabIndex() { if (this.header && this.header.tabs) { this.header.tabs.forEach((tab) => (tab.isActive = false)); if (this.header.tabs.toArray().length > 0 && this.selectedIndex < this.header.tabs.toArray().length && this.selectedIndex !== -1) { this.header.tabs.toArray()[this.selectedIndex].isActive = true; } } } validateMode() { if (this.mode === "") { this.mode = STANDARD; } if ([STANDARD, WATERFALL, SCROLL].indexOf(this.mode) === -1) { throw new MdLUnsupportedLayoutTypeError(this.mode); } if (this.header) { // inform the header about the mode this.header.mode = this.mode; this.header.isSeamed = this.isSeamed; } if (this.content) { this.scrollListener = this.renderer.listen(this.content.el, "scroll", () => { this.onScroll(this.content?.el.scrollTop); return true; }); this.screenSizeService.sizes().subscribe((isSmall) => { this.onQueryChange(isSmall); }); } } onScroll(scrollTop) { if (this.mode !== WATERFALL) { return; } if (this.header?.isAnimating) { return; } const headerVisible = !this.isSmallScreen || this.isFixedHeader; if (this.header) { if (scrollTop != null && scrollTop > 0 && !this.header.isCompact) { this.header.isCompact = true; if (headerVisible) { this.header.isAnimating = true; } } else if (scrollTop != null && scrollTop <= 0 && this.header.isCompact) { this.header.isCompact = false; if (headerVisible) { this.header.isAnimating = true; } } } } onQueryChange(isSmall) { if (isSmall) { this.isSmallScreen = true; } else { this.isSmallScreen = false; this.closeDrawer(); } } setDrawerVisible(visible) { this.drawers.first.isDrawerVisible = visible; if (this.drawers.first.isDrawerVisible) { this.onOpen.emit(); } else { this.onClose.emit(); } } } MdlLayoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlLayoutComponent, deps: [{ token: i0.Renderer2 }, { token: i1.EventManager }, { token: i0.ElementRef }, { token: MdlScreenSizeService }, { token: i2.MdlLayoutMediatorService }], target: i0.ɵɵFactoryTarget.Component }); MdlLayoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MdlLayoutComponent, selector: "mdl-layout", inputs: { mode: ["mdl-layout-mode", "mode"], isFixedDrawer: ["mdl-layout-fixed-drawer", "isFixedDrawer"], isFixedHeader: ["mdl-layout-fixed-header", "isFixedHeader"], isSeamed: ["mdl-layout-header-seamed", "isSeamed"], selectedIndex: ["mdl-layout-tab-active-index", "selectedIndex"], isNoDrawer: ["mdl-layout-no-drawer-button", "isNoDrawer"] }, outputs: { selectedTabEmitter: "mdl-layout-tab-active-changed", mouseoverTabEmitter: "mdl-layout-tab-mouseover", mouseoutTabEmitter: "mdl-layout-tab-mouseout", onOpen: "open", onClose: "close" }, queries: [{ propertyName: "header", first: true, predicate: MdlLayoutHeaderComponent, descendants: true }, { propertyName: "content", first: true, predicate: MdlLayoutContentComponent, descendants: true, static: true }, { propertyName: "drawers", predicate: MdlLayoutDrawerComponent }], exportAs: ["mdlLayout"], usesOnChanges: true, ngImport: i0, template: ` <div class="mdl-layout__container" [ngClass]="{ 'has-scrolling-header': mode === 'scroll' }" > <div class="mdl-layout is-upgraded" [ngClass]="{ 'is-small-screen': isSmallScreen, 'mdl-layout--fixed-drawer': isFixedDrawer, 'mdl-layout--fixed-header': isFixedHeader, 'mdl-layout--fixed-tabs': 'tabs.toArray().length > 0' }" > <ng-content select="mdl-layout-header"></ng-content> <ng-content select="mdl-layout-drawer"></ng-content> <div *ngIf="drawers.length > 0 && isNoDrawer === false" class="mdl-layout__drawer-button" (click)="toggleDrawer()" > <mdl-icon>&#xE5D2;</mdl-icon> </div> <ng-content select="mdl-layout-content"></ng-content> <div class="mdl-layout__obfuscator" [ngClass]="{ 'is-visible': isDrawerVisible }" (click)="toggleDrawer()" (keydown)="obfuscatorKeyDown($event)" ></div> </div> </div> `, isInline: true, dependencies: [{ kind: "component", type: i3.MdlIconComponent, selector: "mdl-icon" }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlLayoutComponent, decorators: [{ type: Component, args: [{ selector: "mdl-layout", template: ` <div class="mdl-layout__container" [ngClass]="{ 'has-scrolling-header': mode === 'scroll' }" > <div class="mdl-layout is-upgraded" [ngClass]="{ 'is-small-screen': isSmallScreen, 'mdl-layout--fixed-drawer': isFixedDrawer, 'mdl-layout--fixed-header': isFixedHeader, 'mdl-layout--fixed-tabs': 'tabs.toArray().length > 0' }" > <ng-content select="mdl-layout-header"></ng-content> <ng-content select="mdl-layout-drawer"></ng-content> <div *ngIf="drawers.length > 0 && isNoDrawer === false" class="mdl-layout__drawer-button" (click)="toggleDrawer()" > <mdl-icon>&#xE5D2;</mdl-icon> </div> <ng-content select="mdl-layout-content"></ng-content> <div class="mdl-layout__obfuscator" [ngClass]="{ 'is-visible': isDrawerVisible }" (click)="toggleDrawer()" (keydown)="obfuscatorKeyDown($event)" ></div> </div> </div> `, exportAs: "mdlLayout", encapsulation: ViewEncapsulation.None, }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i1.EventManager }, { type: i0.ElementRef }, { type: MdlScreenSizeService }, { type: i2.MdlLayoutMediatorService }]; }, propDecorators: { header: [{ type: ContentChild, args: [MdlLayoutHeaderComponent] }], drawers: [{ type: ContentChildren, args: [MdlLayoutDrawerComponent, { descendants: false }] }], content: [{ type: ContentChild, args: [MdlLayoutContentComponent, { static: true }] }], mode: [{ type: Input, args: ["mdl-layout-mode"] }], selectedTabEmitter: [{ type: Output, args: ["mdl-layout-tab-active-changed"] }], mouseoverTabEmitter: [{ type: Output, args: ["mdl-layout-tab-mouseover"] }], mouseoutTabEmitter: [{ type: Output, args: ["mdl-layout-tab-mouseout"] }], // eslint-disable-next-line @angular-eslint/no-output-on-prefix onOpen: [{ type: Output, args: ["open"] }], // eslint-disable-next-line @angular-eslint/no-output-on-prefix onClose: [{ type: Output, args: ["close"] }], isFixedDrawer: [{ type: Input, args: ["mdl-layout-fixed-drawer"] }], isFixedHeader: [{ type: Input, args: ["mdl-layout-fixed-header"] }], isSeamed: [{ type: Input, args: ["mdl-layout-header-seamed"] }], selectedIndex: [{ type: Input, args: ["mdl-layout-tab-active-index"] }], isNoDrawer: [{ type: Input, args: ["mdl-layout-no-drawer-button"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRsLWxheW91dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb3JlL3NyYy9saWIvbGF5b3V0L21kbC1sYXlvdXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLGVBQWUsRUFDZixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixVQUFVLEVBQ1YsY0FBYyxFQUNkLEtBQUssRUFDTCxNQUFNLEVBR04sUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsU0FBUyxFQUVULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDekUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDekUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0UsT0FBTyxFQUFFLGVBQWUsRUFBcUMsTUFBTSxNQUFNLENBQUM7QUFDMUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7Ozs7OztBQUd6RSxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFFbEIsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDO0FBQzVCLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUM5QixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUM7QUFFeEI7Ozs7Ozs7Ozs7O0dBV0c7QUFD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S0FBSzt1QkFBQyx5QkFBeUI7Z0JBVTVCLGFBQWE7c0JBRGhCLEtBQUs7dUJBQUMseUJBQXlCO2dCQVU1QixRQUFRO3NCQURYLEtBQUs7dUJBQUMsMEJBQTBCO2dCQVU3QixhQUFhO3NCQURoQixLQUFLO3VCQUFDLDZCQUE2QjtnQkFVaEMsVUFBVTtzQkFEYixLQUFLO3VCQUFDLDZCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgUmVuZGVyZXIyLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEV2ZW50TWFuYWdlciB9IGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyXCI7XG5pbXBvcnQgeyBNZGxMYXlvdXRIZWFkZXJDb21wb25lbnQgfSBmcm9tIFwiLi9tZGwtbGF5b3V0LWhlYWRlci5jb21wb25lbnRcIjtcbmltcG9ydCB7IE1kbExheW91dERyYXdlckNvbXBvbmVudCB9IGZyb20gXCIuL21kbC1sYXlvdXQtZHJhd2VyLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgTWRsTGF5b3V0Q29udGVudENvbXBvbmVudCB9IGZyb20gXCIuL21kbC1sYXlvdXQtY29udGVudC5jb21wb25lbnRcIjtcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHRvQm9vbGVhbiB9IGZyb20gXCIuLi9jb21tb24vYm9vbGVhbi1wcm9wZXJ0eVwiO1xuaW1wb3J0IHsgdG9OdW1iZXIgfSBmcm9tIFwiLi4vY29tbW9uL251bWJlci5wcm9wZXJ0eVwiO1xuaW1wb3J0IHsgTWRsRXJyb3IgfSBmcm9tIFwiLi4vY29tbW9uL21kbC1lcnJvclwiO1xuaW1wb3J0IHsgTWRsTGF5b3V0TWVkaWF0b3JTZXJ2aWNlIH0gZnJvbSBcIi4vbWRsLWxheW91dC1tZWRpYXRvci5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBNZGxMYXlvdXRUYWJQYW5lbENvbXBvbmVudCB9IGZyb20gXCIuL21kbC1sYXlvdXQtdGFiLXBhbmVsLmNvbXBvbmVudFwiO1xuXG5jb25zdCBFU0NBUEUgPSAyNztcblxuY29uc3QgU1RBTkRBUkQgPSBcInN0YW5kYXJkXCI7XG5jb25zdCBXQVRFUkZBTEwgPSBcIndhdGVyZmFsbFwiO1xuY29uc3QgU0NST0xMID0gXCJzY3JvbGxcIjtcblxuLyoqXG4gKiBUaGUgTEFZT1VUX1NDUkVFTl9TSVpFX1RIUkVTSE9MRCBjYW4gYmUgY2hhbmdlZCBhdCB0aGUgcm9vdCBtb2R1bGUuIEp1c3QgcHJvdmlkZSBhIHZhbHVlIGZvciB0aGlzIEluamVjdGlvblRva2VuOlxuICpcbiAqIHByb3ZpZGVyczogW1xuICogIHtwcm92aWRlOkxBWU9VVF9TQ1JFRU5fU0laRV9USFJFU0hPTEQsIHVzZVZhbHVlOiA3NjggfVxuICogXVxuICpcbiAqIHlvdSBhbHNvIG5lZWQgdG8gY2hhbmdlIHRoZSBzY3NzIHZhcmlhYmxlIHRvIHRoZSBzYW1lIHZhbHVlOiAkbGF5b3V0LXNjcmVlbi1zaXplLXRocmVzaG9sZDogNzY4cHguXG4gKlxuICogSXQgc2hvdWxkIGJlIGNsZWFyIHRoYXQgdGhpcyBjYW4gb25seSBiZSB1c2VkIGlmIHlvdSBhcmUgdXNpbmcgdGhlIHNjc3MgYW5kIG5vdCB0aGUgcHJlIGNvbXBpbGVkIGNzcyBmcm9tIGdldG1kbC5pby5cbiAqXG4gKi9cbmV4cG9ydCBjb25zdCBMQVlPVVRfU0NSRUVOX1NJWkVfVEhSRVNIT0xEID0gbmV3IEluamVjdGlvblRva2VuPG51bWJlcj4oXG4gIFwibGF5b3V0U2NyZWVuU2l6ZVRocmVzaG9sZFwiXG4pO1xuXG5leHBvcnQgY2xhc3MgTWRMVW5zdXBwb3J0ZWRMYXlvdXRUeXBlRXJyb3IgZXh0ZW5kcyBNZGxFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHR5cGU6IHN0cmluZykge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgc3VwZXIoXG4gICAgICBgTGF5b3V0IHR5cGUgXCIke3R5cGV9XCIgaXNuJ3Qgc3VwcG9ydGVkIGJ5IG1kbC1sYXlvdXQgKGFsbG93ZWQ6IHN0YW5kYXJkLCB3YXRlcmZhbGwsIHNjcm9sbCkuYFxuICAgICk7XG4gIH1cbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiBcInJvb3RcIixcbn0pXG5leHBvcnQgY2xhc3MgTWRsU2NyZWVuU2l6ZVNlcnZpY2Uge1xuICBwcml2YXRlIHNpemVzU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihcbiAgICBmYWxzZVxuICApO1xuXG4gIHByaXZhdGUgd2luZG93TWVkaWFRdWVyeUxpc3RlbmVyOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBuZ1pvbmU6IE5nWm9uZSxcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoTEFZT1VUX1NDUkVFTl9TSVpFX1RIUkVTSE9MRClcbiAgICBwdWJsaWMgbGF5b3V0U2NyZWVuU2l6ZVRocmVzaG9sZDogbnVtYmVyXG4gICkge1xuICAgIC8vIGlmIG5vIHZhbHVlIGlzIGluamVjdGVkIHRoZSBkZWZhdWx0IHNpemUgd2lsIGJlIHVzZWQuIHNhbWUgYXMgJGxheW91dC1zY3JlZW4tc2l6ZS10aHJlc2hvbGQgaW4gc2Nzc1xuICAgIGlmICghdGhpcy5sYXlvdXRTY3JlZW5TaXplVGhyZXNob2xkKSB7XG4gICAgICB0aGlzLmxheW91dFNjcmVlblNpemVUaHJlc2hvbGQgPSAxMDI0O1xuICAgIH1cblxuICAgIC8vIGRvIG5vdCB0cnkgdG8gYWNjZXNzIHRoZSB3aW5kb3cgb2JqZWN0IGlmIHJlbmRlcmVkIG9uIHRoZSBzZXJ2ZXJcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIiAmJiBcIm1hdGNoTWVkaWFcIiBpbiB3aW5kb3cpIHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBNZWRpYVF1ZXJ5TGlzdCA9IHdpbmRvdy5tYXRjaE1lZGlhKFxuICAgICAgICBgKG1heC13aWR0aDogJHt0aGlzLmxheW91dFNjcmVlblNpemVUaHJlc2hvbGR9cHgpYFxuICAgICAgKTtcblxuICAgICAgY29uc3QgcXVlcnlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgbmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zaXplc1N1YmplY3QubmV4dChxdWVyeS5tYXRjaGVzKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgLy8gLSBhZGRFdmVudExpc3RlbmVyIG5vdCB3b3JraW5nIGluIFNhZmFyaVxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICBxdWVyeS5hZGRMaXN0ZW5lcihxdWVyeUxpc3RlbmVyKTtcbiAgICAgIHRoaXMud2luZG93TWVkaWFRdWVyeUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgcXVlcnkucmVtb3ZlTGlzdGVuZXIocXVlcnlMaXN0ZW5lcik7XG4gICAgICB9O1xuICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHN0YXRlXG4gICAgICB0aGlzLnNpemVzU3ViamVjdC5uZXh0KHF1ZXJ5Lm1hdGNoZXMpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBpc1NtYWxsU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNpemVzU3ViamVjdC52YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBzaXplcygpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5zaXplc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndpbmRvd01lZGlhUXVlcnlMaXN0ZW5lcikge1xuICAgICAgdGhpcy53aW5kb3dNZWRpYVF1ZXJ5TGlzdGVuZXIoKTtcbiAgICAgIHRoaXMud2luZG93TWVkaWFRdWVyeUxpc3RlbmVyID0gbnVsbDtcbiAgICB9XG4gIH1cbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcIm1kbC1sYXlvdXRcIixcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cIm1kbC1sYXlvdXRfX2NvbnRhaW5lclwiXG4gICAgICBbbmdDbGFzc109XCJ7ICdoYXMtc2Nyb2xsaW5nLWhlYWRlcic6IG1vZGUgPT09ICdzY3JvbGwnIH1cIlxuICAgID5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJtZGwtbGF5b3V0IGlzLXVwZ3JhZGVkXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICdpcy1zbWFsbC1zY3JlZW4nOiBpc1NtYWxsU2NyZWVuLFxuICAgICAgICAgICdtZGwtbGF5b3V0LS1maXhlZC1kcmF3ZXInOiBpc0ZpeGVkRHJhd2VyLFxuICAgICAgICAgICdtZGwtbGF5b3V0LS1maXhlZC1oZWFkZXInOiBpc0ZpeGVkSGVhZGVyLFxuICAgICAgICAgICdtZGwtbGF5b3V0LS1maXhlZC10YWJzJzogJ3RhYnMudG9BcnJheSgpLmxlbmd0aCA+IDAnXG4gICAgICAgIH1cIlxuICAgICAgPlxuICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJtZGwtbGF5b3V0LWhlYWRlclwiPjwvbmctY29udGVudD5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwibWRsLWxheW91dC1kcmF3ZXJcIj48L25nLWNvbnRlbnQ+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdJZj1cImRyYXdlcnMubGVuZ3RoID4gMCAmJiBpc05vRHJhd2VyID09PSBmYWxzZVwiXG4gICAgICAgICAgY2xhc3M9XCJtZGwtbGF5b3V0X19kcmF3ZXItYnV0dG9uXCJcbiAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRHJhd2VyKClcIlxuICAgICAgICA+XG4gICAgICAgICAgPG1kbC1pY29uPiYjeEU1RDI7PC9tZGwtaWNvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm1kbC1sYXlvdXQtY29udGVudFwiPjwvbmctY29udGVudD5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwibWRsLWxheW91dF9fb2JmdXNjYXRvclwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwieyAnaXMtdmlzaWJsZSc6IGlzRHJhd2VyVmlzaWJsZSB9XCJcbiAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRHJhd2VyKClcIlxuICAgICAgICAgIChrZXlkb3duKT1cIm9iZnVzY2F0b3JLZXlEb3duKCRldmVudClcIlxuICAgICAgICA+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgZXhwb3J0QXM6IFwibWRsTGF5b3V0XCIsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG59KVxuZXhwb3J0IGNsYXNzIE1kbExheW91dENvbXBvbmVudFxuICBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzXG57XG4gIEBDb250ZW50Q2hpbGQoTWRsTGF5b3V0SGVhZGVyQ29tcG9uZW50KVxuICBoZWFkZXI6IE1kbExheW91dEhlYWRlckNvbXBvbmVudCB8IHVuZGVmaW5lZDtcbiAgLy8gd2lsbCBiZSBzZXQgdG8gdW5kZWZpbmVkLCBpZiBub3QgYSBkaXJlY3QgY2hpbGQgb3Igbm90IHByZXNlbnQgaW4gMi4wLjAgaVxuICAvLyBuIDIuMC4xIGl0IGlzIG5vdyB0aGUgZ3JhbmQgY2hpbGQgZHJhd2VyIGFnYWluIDooXG4gIEBDb250ZW50Q2hpbGRyZW4oTWRsTGF5b3V0RHJhd2VyQ29tcG9uZW50LCB7IGRlc2NlbmRhbnRzOiBmYWxzZSB9KVxuICBkcmF3ZXJzOiBRdWVyeUxpc3Q8TWRsTGF5b3V0RHJhd2VyQ29tcG9uZW50PiA9IG5ldyBRdWVyeUxpc3Q8TWRsTGF5b3V0RHJhd2VyQ29tcG9uZW50PigpO1xuICBAQ29udGVudENoaWxkKE1kbExheW91dENvbnRlbnRDb21wb25lbnQsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGNvbnRlbnQ6IE1kbExheW91dENvbnRlbnRDb21wb25lbnQgfCB1bmRlZmluZWQ7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIEBJbnB1dChcIm1kbC1sYXlvdXQtbW9kZVwiKVxuICBtb2RlOiBzdHJpbmcgPSBTVEFOREFSRDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIEBPdXRwdXQoXCJtZGwtbGF5b3V0LXRhYi1hY3RpdmUtY2hhbmdlZFwiKVxuICBzZWxlY3RlZFRhYkVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBAT3V0cHV0KFwibWRsLWxheW91dC10YWItbW91c2VvdmVyXCIpXG4gIG1vdXNlb3ZlclRhYkVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBAT3V0cHV0KFwibWRsLWxheW91dC10YWItbW91c2VvdXRcIilcbiAgbW91c2VvdXRUYWJFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgQE91dHB1dChcIm9wZW5cIilcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtb24tcHJlZml4XG4gIG9uT3BlbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gIEBPdXRwdXQoXCJjbG9zZVwiKVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1vbi1wcmVmaXhcbiAgb25DbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgaXNEcmF3ZXJWaXNpYmxlID0gZmFsc2U7XG4gIGlzU21hbGxTY3JlZW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBzY3JvbGxMaXN0ZW5lcjpcbiAgICB8ICgoXG4gICAgICAgIHRhcmdldD86IFwid2luZG93XCIgfCBcImRvY3VtZW50XCIgfCBcImJvZHlcIiB8IHVua25vd24sXG4gICAgICAgIGV2ZW50TmFtZT86IHN0cmluZyxcbiAgICAgICAgY2FsbGJhY2s/OiAoZXZlbnQ6IEV2ZW50KSA9PiBib29sZWFuIHwgdm9pZFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIGlzRml4ZWREcmF3ZXJJbnRlcm4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBpc0ZpeGVkSGVhZGVySW50ZXJuID0gZmFsc2U7XG4gIHByaXZhdGUgaXNTZWFtZWRJbnRlcm4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBzZWxlY3RlZEluZGV4SW50ZXJuOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkID0gMDtcbiAgcHJpdmF0ZSBpc05vRHJhd2VySW50ZXJuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIGV2bTogRXZlbnRNYW5hZ2VyLFxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBzY3JlZW5TaXplU2VydmljZTogTWRsU2NyZWVuU2l6ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBsYXlvdXRNZWRpYXRvclNlcnZpY2U6IE1kbExheW91dE1lZGlhdG9yU2VydmljZVxuICApIHt9XG5cbiAgQElucHV0KFwibWRsLWxheW91dC1maXhlZC1kcmF3ZXJcIilcbiAgZ2V0IGlzRml4ZWREcmF3ZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNGaXhlZERyYXdlckludGVybjtcbiAgfVxuXG4gIHNldCBpc0ZpeGVkRHJhd2VyKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgdGhpcy5pc0ZpeGVkRHJhd2VySW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIEBJbnB1dChcIm1kbC1sYXlvdXQtZml4ZWQtaGVhZGVyXCIpXG4gIGdldCBpc0ZpeGVkSGVhZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzRml4ZWRIZWFkZXJJbnRlcm47XG4gIH1cblxuICBzZXQgaXNGaXhlZEhlYWRlcih2YWx1ZTogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIHRoaXMuaXNGaXhlZEhlYWRlckludGVybiA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gIH1cblxuICBASW5wdXQoXCJtZGwtbGF5b3V0LWhlYWRlci1zZWFtZWRcIilcbiAgZ2V0IGlzU2VhbWVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzU2VhbWVkSW50ZXJuO1xuICB9XG5cbiAgc2V0IGlzU2VhbWVkKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgdGhpcy5pc1NlYW1lZEludGVybiA9IHRvQm9vbGVhbih2YWx1ZSk7XG4gIH1cblxuICBASW5wdXQoXCJtZGwtbGF5b3V0LXRhYi1hY3RpdmUtaW5kZXhcIilcbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEluZGV4SW50ZXJuID8gdGhpcy5zZWxlY3RlZEluZGV4SW50ZXJuIDogMDtcbiAgfVxuXG4gIHNldCBzZWxlY3RlZEluZGV4KHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnNlbGVjdGVkSW5kZXhJbnRlcm4gPSB0b051bWJlcih2YWx1ZSk7XG4gIH1cblxuICBASW5wdXQoXCJtZGwtbGF5b3V0LW5vLWRyYXdlci1idXR0b25cIilcbiAgZ2V0IGlzTm9EcmF3ZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNOb0RyYXdlckludGVybjtcbiAgfVxuXG4gIHNldCBpc05vRHJhd2VyKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgdGhpcy5pc05vRHJhd2VySW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlTW9kZSgpO1xuXG4gICAgaWYgKHRoaXMuaGVhZGVyICYmIHRoaXMuY29udGVudCAmJiB0aGlzLmNvbnRlbnQudGFicykge1xuICAgICAgdGhpcy5oZWFkZXIudGFicyA9IHRoaXMuY29udGVudC50YWJzO1xuICAgICAgdGhpcy51cGRhdGVTZWxlY3RlZFRhYkluZGV4KCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGVhZGVyICYmIHRoaXMuaGVhZGVyLnRhYnMpIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICB0aGlzLmxheW91dE1lZGlhdG9yU2VydmljZVxuICAgICAgICAgIC5vblRhYk1vdXNlT3V0KClcbiAgICAgICAgICAuc3Vic2NyaWJlKCh0YWI6IE1kbExheW91dFRhYlBhbmVsQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uVGFiTW91c2VvdXQodGFiKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICAgIHRoaXMubGF5b3V0TWVkaWF0b3JTZXJ2aWNlXG4gICAgICAgICAgLm9uVGFiTW91c2VvdmVyKClcbiAgICAgICAgICAuc3Vic2NyaWJlKCh0YWI6IE1kbExheW91dFRhYlBhbmVsQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uVGFiTW91c2VvdmVyKHRhYik7XG4gICAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICB0aGlzLmxheW91dE1lZGlhdG9yU2VydmljZVxuICAgICAgICAgIC5vblRhYlNlbGVjdGVkKClcbiAgICAgICAgICAuc3Vic2NyaWJlKCh0YWI6IE1kbExheW91dFRhYlBhbmVsQ29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRhYlNlbGVjdGVkKHRhYik7XG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1tcInNlbGVjdGVkSW5kZXhcIl0pIHtcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRUYWJJbmRleCgpO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZURyYXdlcigpOiB2b2lkIHtcbiAgICB0aGlzLmlzRHJhd2VyVmlzaWJsZSA9ICF0aGlzLmlzRHJhd2VyVmlzaWJsZTtcbiAgICBpZiAodGhpcy5kcmF3ZXJzICYmIHRoaXMuZHJhd2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldERyYXdlclZpc2libGUodGhpcy5pc0RyYXdlclZpc2libGUpO1xuICAgIH1cbiAgfVxuXG4gIGNsb3NlRHJhd2VyKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEcmF3ZXJWaXNpYmxlID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuZHJhd2VycyAmJiB0aGlzLmRyYXdlcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5zZXREcmF3ZXJWaXNpYmxlKGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICBvcGVuRHJhd2VyKCk6IHZvaWQge1xuICAgIHRoaXMuaXNEcmF3ZXJWaXNpYmxlID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5kcmF3ZXJzICYmIHRoaXMuZHJhd2Vycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNldERyYXdlclZpc2libGUodHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgb2JmdXNjYXRvcktleURvd24oJGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCRldmVudC5rZXlDb2RlID09PSBFU0NBUEUpIHtcbiAgICAgIHRoaXMudG9nZ2xlRHJhd2VyKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2Nyb2xsTGlzdGVuZXIpIHtcbiAgICAgIHRoaXMuc2Nyb2xsTGlzdGVuZXIoKTtcbiAgICAgIHRoaXMuc2Nyb2xsTGlzdGVuZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzdWIpID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgfVxuXG4gIGNsb3NlRHJhd2VyT25TbWFsbFNjcmVlbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNTbWFsbFNjcmVlbiAmJiB0aGlzLmlzRHJhd2VyVmlzaWJsZSkge1xuICAgICAgdGhpcy5jbG9zZURyYXdlcigpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5EcmF3ZXJPblNtYWxsU2NyZWVucygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1NtYWxsU2NyZWVuICYmICF0aGlzLmlzRHJhd2VyVmlzaWJsZSkge1xuICAgICAgdGhpcy5vcGVuRHJhd2VyKCk7XG4gICAgfVxuICB9XG5cbiAgaGFzRHJhd2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRyYXdlcnMgJiYgdGhpcy5kcmF3ZXJzLmxlbmd0aCA+IDApO1xuICB9XG5cbiAgcHJpdmF0ZSB0YWJTZWxlY3RlZCh0YWI6IE1kbExheW91dFRhYlBhbmVsQ29tcG9uZW50KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmhlYWRlcj8udGFicy50b0FycmF5KCkuaW5kZXhPZih0YWIpO1xuICAgIGlmIChpbmRleCAhPT0gdGhpcy5zZWxlY3RlZEluZGV4KSB7XG4gICAgICB0aGlzLnNlbGVjdGVkSW5kZXggPSBpbmRleDtcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRUYWJJbmRleCgpO1xuICAgICAgdGhpcy5zZWxlY3RlZFRhYkVtaXR0ZXIuZW1pdCh7IGluZGV4OiB0aGlzLnNlbGVjdGVkSW5kZXggfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblRhYk1vdXNlb3Zlcih0YWI6IE1kbExheW91dFRhYlBhbmVsQ29tcG9uZW50KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmhlYWRlcj8udGFicy50b0FycmF5KCkuaW5kZXhPZih0YWIpO1xuICAgIHRoaXMubW91c2VvdmVyVGFiRW1pdHRlci5lbWl0KHsgaW5kZXggfSk7XG4gIH1cblxuICBwcml2YXRlIG9uVGFiTW91c2VvdXQodGFiOiBNZGxMYXlvdXRUYWJQYW5lbENvbXBvbmVudCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5oZWFkZXI/LnRhYnMudG9BcnJheSgpLmluZGV4T2YodGFiKTtcbiAgICB0aGlzLm1vdXNlb3V0VGFiRW1pdHRlci5lbWl0KHsgaW5kZXggfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVNlbGVjdGVkVGFiSW5kZXgoKSB7XG4gICAgaWYgKHRoaXMuaGVhZGVyICYmIHRoaXMuaGVhZGVyLnRhYnMpIHtcbiAgICAgIHRoaXMuaGVhZGVyLnRhYnMuZm9yRWFjaCgodGFiKSA9PiAodGFiLmlzQWN0aXZlID0gZmFsc2UpKTtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5oZWFkZXIudGFicy50b0FycmF5KCkubGVuZ3RoID4gMCAmJlxuICAgICAgICB0aGlzLnNlbGVjdGVkSW5kZXggPCB0aGlzLmhlYWRlci50YWJzLnRvQXJyYXkoKS5sZW5ndGggJiZcbiAgICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ICE9PSAtMVxuICAgICAgKSB7XG4gICAgICAgIHRoaXMuaGVhZGVyLnRhYnMudG9BcnJheSgpW3RoaXMuc2VsZWN0ZWRJbmRleF0uaXNBY3RpdmUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVNb2RlKCkge1xuICAgIGlmICh0aGlzLm1vZGUgPT09IFwiXCIpIHtcbiAgICAgIHRoaXMubW9kZSA9IFNUQU5EQVJEO1xuICAgIH1cbiAgICBpZiAoW1NUQU5EQVJELCBXQVRFUkZBTEwsIFNDUk9MTF0uaW5kZXhPZih0aGlzLm1vZGUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IE1kTFVuc3VwcG9ydGVkTGF5b3V0VHlwZUVycm9yKHRoaXMubW9kZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaGVhZGVyKSB7XG4gICAgICAvLyBpbmZvcm0gdGhlIGhlYWRlciBhYm91dCB0aGUgbW9kZVxuICAgICAgdGhpcy5oZWFkZXIubW9kZSA9IHRoaXMubW9kZTtcbiAgICAgIHRoaXMuaGVhZGVyLmlzU2VhbWVkID0gdGhpcy5pc1NlYW1lZDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb250ZW50KSB7XG4gICAgICB0aGlzLnNjcm9sbExpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oXG4gICAgICAgIHRoaXMuY29udGVudC5lbCxcbiAgICAgICAgXCJzY3JvbGxcIixcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRoaXMub25TY3JvbGwodGhpcy5jb250ZW50Py5lbC5zY3JvbGxUb3ApO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgICB0aGlzLnNjcmVlblNpemVTZXJ2aWNlLnNpemVzKCkuc3Vic2NyaWJlKChpc1NtYWxsOiBib29sZWFuKSA9PiB7XG4gICAgICAgIHRoaXMub25RdWVyeUNoYW5nZShpc1NtYWxsKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25TY3JvbGwoc2Nyb2xsVG9wOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSBXQVRFUkZBTEwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oZWFkZXI/LmlzQW5pbWF0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVyVmlzaWJsZSA9ICF0aGlzLmlzU21hbGxTY3JlZW4gfHwgdGhpcy5pc0ZpeGVkSGVhZGVyO1xuICAgIGlmICh0aGlzLmhlYWRlcikge1xuICAgICAgaWYgKHNjcm9sbFRvcCAhPSBudWxsICYmIHNjcm9sbFRvcCA+IDAgJiYgIXRoaXMuaGVhZGVyLmlzQ29tcGFjdCkge1xuICAgICAgICB0aGlzLmhlYWRlci5pc0NvbXBhY3QgPSB0cnVlO1xuICAgICAgICBpZiAoaGVhZGVyVmlzaWJsZSkge1xuICAgICAgICAgIHRoaXMuaGVhZGVyLmlzQW5pbWF0aW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzY3JvbGxUb3AgIT0gbnVsbCAmJiBzY3JvbGxUb3AgPD0gMCAmJiB0aGlzLmhlYWRlci5pc0NvbXBhY3QpIHtcbiAgICAgICAgdGhpcy5oZWFkZXIuaXNDb21wYWN0ID0gZmFsc2U7XG4gICAgICAgIGlmIChoZWFkZXJWaXNpYmxlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXIuaXNBbmltYXRpbmcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblF1ZXJ5Q2hhbmdlKGlzU21hbGw6IGJvb2xlYW4pIHtcbiAgICBpZiAoaXNTbWFsbCkge1xuICAgICAgdGhpcy5pc1NtYWxsU2NyZWVuID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pc1NtYWxsU2NyZWVuID0gZmFsc2U7XG4gICAgICB0aGlzLmNsb3NlRHJhd2VyKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXREcmF3ZXJWaXNpYmxlKHZpc2libGU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRyYXdlcnMuZmlyc3QuaXNEcmF3ZXJWaXNpYmxlID0gdmlzaWJsZTtcbiAgICBpZiAodGhpcy5kcmF3ZXJzLmZpcnN0LmlzRHJhd2VyVmlzaWJsZSkge1xuICAgICAgdGhpcy5vbk9wZW4uZW1pdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uQ2xvc2UuZW1pdCgpO1xuICAgIH1cbiAgfVxufVxuIl19