UNPKG

@xui/components

Version:

xUI Components for Angular

159 lines 25.9 kB
import { ChangeDetectionStrategy, Component, EventEmitter, input, Output, signal } from '@angular/core'; import { ComponentPortal } from '@angular/cdk/portal'; import { animate, state, style, transition, trigger, useAnimation } from '@angular/animations'; import { bounce } from '../utils/animations'; import { delay } from '../utils'; import { XuiSnackBar } from '../snack-bar'; import { SaveResetSnackbar } from './settings-snackbar'; import * as i0 from "@angular/core"; import * as i1 from "../snack-bar"; import * as i2 from "../icon/icon"; import * as i3 from "@angular/cdk/portal"; import * as i4 from "@angular/cdk/a11y"; import * as i5 from "@ngx-translate/core"; export class XuiSettings { constructor(snackBar) { this.snackBar = snackBar; this.canExit = true; this._animationState = false; this._mouseDown = false; this._menuFocused = false; this._focusedItem = signal(null); this._defaultPage = signal(1); this._isOpened = signal(false); this._openedAnimation = signal('closed'); this.items = input(); this.afterClosed = new EventEmitter(); this.stateChanged = (canExit) => { this.canExit = canExit; if (!canExit) { if (!this.snackbarRef) { this.snackbarRef = this.snackBar.openFromComponent(SaveResetSnackbar, { panelClass: 'x-settings-snackbar-panel', duration: undefined, data: { save: async () => { try { await this.instance?.save(); await this.hideSnackbar(); } catch (e) { // TODO: show error snackbar } }, reset: async () => { await this.instance?.reset(); await this.hideSnackbar(); } } }); } } else { this.hideSnackbar(); } }; } open(page = 1) { this._defaultPage.set(page); this._isOpened.set(true); this._openedAnimation.set('opened'); this._navigate(this._defaultPage()); } async close() { if (!this.canExit) { this._animationState = true; this.snackbarRef?.instance.alert(); return; } this._openedAnimation.set('closed'); await delay(100); this._isOpened.set(false); this.afterClosed.emit(); } attached(ref) { this.instance = ref.instance; this.instance.stateChanged = this.stateChanged; } _navigate(idx) { if (this.instance) { if (!this.canExit) { return; } } const item = this.items()?.[idx]; if (item) { this._defaultPage.set(idx); this._focusedItem.set(idx); if (item.action) { item.action(); } else if (item.component) { this._portal = new ComponentPortal(item.component); } } } _focusPrev() { let cur = this._focusedItem() ?? this.items()?.length ?? 0; do { cur--; if (cur < 0) { cur = (this.items()?.length ?? 1) - 1; } } while (this.items()?.[cur].type !== 'item'); this._focusedItem.set(cur); } _focusNext() { let cur = this._focusedItem() ?? this.items()?.length ?? 0; do { cur++; if (cur >= (this.items()?.length ?? 0)) { cur = 0; } } while (this.items()?.[cur].type !== 'item'); this._focusedItem.set(cur); } async hideSnackbar() { await this.snackbarRef?.instance.close(); this.snackbarRef?.dismiss(); this.snackbarRef = undefined; this.canExit = true; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiSettings, deps: [{ token: i1.XuiSnackBar }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: XuiSettings, selector: "xui-settings", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { afterClosed: "afterClosed" }, host: { listeners: { "document:keydown.escape": "close()" } }, ngImport: i0, template: "<dialog class=\"x-settings-dialog\" [open]=\"_isOpened()\" cdkTrapFocus cdkTrapFocusAutoCapture>\n <div\n class=\"x-settings\"\n [@open]=\"_openedAnimation()\"\n [@bounce]=\"_animationState\"\n (@bounce.done)=\"_animationState = false\"\n >\n <div class=\"x-settings-menu\">\n <nav\n tabindex=\"0\"\n (keydown.enter)=\"_navigate(_focusedItem() ?? 0)\"\n (keydown.space)=\"_navigate(_focusedItem() ?? 0)\"\n (keydown.arrowDown)=\"_focusNext()\"\n (keydown.arrowUp)=\"_focusPrev()\"\n (mousedown)=\"_mouseDown = true\"\n (mouseup)=\"_mouseDown = false\"\n (focusin)=\"_menuFocused = !_mouseDown\"\n (focusout)=\"_menuFocused = false\"\n >\n @for (item of items(); track item; let i = $index) {\n <div\n [class.x-settings-menu-item]=\"item.type === 'item'\"\n [class.x-settings-menu-item-active]=\"i === _defaultPage()\"\n [class.x-settings-menu-item-focus]=\"i === _focusedItem() && _menuFocused\"\n [class.x-settings-menu-category]=\"item.type === 'category'\"\n [class.x-settings-menu-divider]=\"item.type === 'divider'\"\n [class.x-settings-menu-red]=\"item.critical\"\n (click)=\"_navigate(i); _menuFocused = false\"\n >\n {{ item.name ? (item.name | translate) : '' }}\n </div>\n }\n </nav>\n </div>\n <div class=\"x-settings-right\">\n <div class=\"x-settings-content\">\n <ng-template [cdkPortalOutlet]=\"_portal\" (attached)=\"attached($event)\" />\n </div>\n\n <div class=\"x-settings-close-anchor\">\n <div class=\"x-settings-close\" (click)=\"close()\">\n <xui-icon tabindex=\"0\" (keydown.space)=\"close()\" (keydown.enter)=\"close()\" icon=\"cancel\"></xui-icon>\n ESC\n </div>\n </div>\n </div>\n </div>\n</dialog>\n", dependencies: [{ kind: "component", type: i2.XuiIcon, selector: "xui-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "icon"], exportAs: ["xuiIcon"] }, { kind: "directive", type: i3.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "directive", type: i4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }], animations: [ trigger('bounce', [transition('* => *', useAnimation(bounce))]), trigger('open', [ state('closed', style({ opacity: 0, transform: 'scale(1.05)' })), state('opened', style({ opacity: 1, transform: 'scale(1)' })), transition('* => *', animate(100)) ]) ], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: XuiSettings, decorators: [{ type: Component, args: [{ selector: 'xui-settings', changeDetection: ChangeDetectionStrategy.OnPush, animations: [ trigger('bounce', [transition('* => *', useAnimation(bounce))]), trigger('open', [ state('closed', style({ opacity: 0, transform: 'scale(1.05)' })), state('opened', style({ opacity: 1, transform: 'scale(1)' })), transition('* => *', animate(100)) ]) ], host: { '(document:keydown.escape)': 'close()' }, template: "<dialog class=\"x-settings-dialog\" [open]=\"_isOpened()\" cdkTrapFocus cdkTrapFocusAutoCapture>\n <div\n class=\"x-settings\"\n [@open]=\"_openedAnimation()\"\n [@bounce]=\"_animationState\"\n (@bounce.done)=\"_animationState = false\"\n >\n <div class=\"x-settings-menu\">\n <nav\n tabindex=\"0\"\n (keydown.enter)=\"_navigate(_focusedItem() ?? 0)\"\n (keydown.space)=\"_navigate(_focusedItem() ?? 0)\"\n (keydown.arrowDown)=\"_focusNext()\"\n (keydown.arrowUp)=\"_focusPrev()\"\n (mousedown)=\"_mouseDown = true\"\n (mouseup)=\"_mouseDown = false\"\n (focusin)=\"_menuFocused = !_mouseDown\"\n (focusout)=\"_menuFocused = false\"\n >\n @for (item of items(); track item; let i = $index) {\n <div\n [class.x-settings-menu-item]=\"item.type === 'item'\"\n [class.x-settings-menu-item-active]=\"i === _defaultPage()\"\n [class.x-settings-menu-item-focus]=\"i === _focusedItem() && _menuFocused\"\n [class.x-settings-menu-category]=\"item.type === 'category'\"\n [class.x-settings-menu-divider]=\"item.type === 'divider'\"\n [class.x-settings-menu-red]=\"item.critical\"\n (click)=\"_navigate(i); _menuFocused = false\"\n >\n {{ item.name ? (item.name | translate) : '' }}\n </div>\n }\n </nav>\n </div>\n <div class=\"x-settings-right\">\n <div class=\"x-settings-content\">\n <ng-template [cdkPortalOutlet]=\"_portal\" (attached)=\"attached($event)\" />\n </div>\n\n <div class=\"x-settings-close-anchor\">\n <div class=\"x-settings-close\" (click)=\"close()\">\n <xui-icon tabindex=\"0\" (keydown.space)=\"close()\" (keydown.enter)=\"close()\" icon=\"cancel\"></xui-icon>\n ESC\n </div>\n </div>\n </div>\n </div>\n</dialog>\n" }] }], ctorParameters: () => [{ type: i1.XuiSnackBar }], propDecorators: { afterClosed: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3h1aS9zcmMvc2V0dGluZ3Mvc2V0dGluZ3MudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzL3h1aS9zcmMvc2V0dGluZ3Mvc2V0dGluZ3MuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFnQixZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEgsT0FBTyxFQUE4QixlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRixPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMvRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLEVBQWUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3hELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7O0FBOEJ4RCxNQUFNLE9BQU8sV0FBVztJQWtCdEIsWUFBb0IsUUFBcUI7UUFBckIsYUFBUSxHQUFSLFFBQVEsQ0FBYTtRQWZqQyxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBR3ZCLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsaUJBQVksR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO1FBQzNDLGlCQUFZLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLGNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIs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O3dCQUNWLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQy9ELE9BQU8sQ0FBQyxNQUFNLEVBQUU7NEJBQ2QsS0FBSyxDQUNILFFBQVEsRUFDUixLQUFLLENBQUM7Z0NBQ0osT0FBTyxFQUFFLENBQUM7Z0NBQ1YsU0FBUyxFQUFFLGFBQWE7NkJBQ3pCLENBQUMsQ0FDSDs0QkFDRCxLQUFLLENBQ0gsUUFBUSxFQUNSLEtBQUssQ0FBQztnQ0FDSixPQUFPLEVBQUUsQ0FBQztnQ0FDVixTQUFTLEVBQUUsVUFBVTs2QkFDdEIsQ0FBQyxDQUNIOzRCQUNELFVBQVUsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO3lCQUNuQyxDQUFDO3FCQUNILFFBQ0s7d0JBQ0osMkJBQTJCLEVBQUUsU0FBUztxQkFDdkM7Z0ZBa0JTLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBDb21wb25lbnRSZWYsIEV2ZW50RW1pdHRlciwgaW5wdXQsIE91dHB1dCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDZGtQb3J0YWxPdXRsZXRBdHRhY2hlZFJlZiwgQ29tcG9uZW50UG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5pbXBvcnQgeyBNZW51SXRlbSwgU2V0dGluZ3NQYWdlIH0gZnJvbSAnLi9zZXR0aW5ncy50eXBlcyc7XG5pbXBvcnQgeyBhbmltYXRlLCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIsIHVzZUFuaW1hdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgYm91bmNlIH0gZnJvbSAnLi4vdXRpbHMvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7IFNuYWNrQmFyUmVmLCBYdWlTbmFja0JhciB9IGZyb20gJy4uL3NuYWNrLWJhcic7XG5pbXBvcnQgeyBTYXZlUmVzZXRTbmFja2JhciB9IGZyb20gJy4vc2V0dGluZ3Mtc25hY2tiYXInO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd4dWktc2V0dGluZ3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGVVcmw6ICdzZXR0aW5ncy5odG1sJyxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ2JvdW5jZScsIFt0cmFuc2l0aW9uKCcqID0+IConLCB1c2VBbmltYXRpb24oYm91bmNlKSldKSxcbiAgICB0cmlnZ2VyKCdvcGVuJywgW1xuICAgICAgc3RhdGUoXG4gICAgICAgICdjbG9zZWQnLFxuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgb3BhY2l0eTogMCxcbiAgICAgICAgICB0cmFuc2Zvcm06ICdzY2FsZSgxLjA1KSdcbiAgICAgICAgfSlcbiAgICAgICksXG4gICAgICBzdGF0ZShcbiAgICAgICAgJ29wZW5lZCcsXG4gICAgICAgIHN0eWxlKHtcbiAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgIHRyYW5zZm9ybTogJ3NjYWxlKDEpJ1xuICAgICAgICB9KVxuICAgICAgKSxcbiAgICAgIHRyYW5zaXRpb24oJyogPT4gKicsIGFuaW1hdGUoMTAwKSlcbiAgICBdKVxuICBdLFxuICBob3N0OiB7XG4gICAgJyhkb2N1bWVudDprZXlkb3duLmVzY2FwZSknOiAnY2xvc2UoKSdcbiAgfVxufSlcbmV4cG9ydCBjbGFzcyBYdWlTZXR0aW5ncyB7XG4gIHByaXZhdGUgaW5zdGFuY2U/OiBTZXR0aW5nc1BhZ2U7XG4gIHByaXZhdGUgc25hY2tiYXJSZWY/OiBTbmFja0JhclJlZjxTYXZlUmVzZXRTbmFja2Jhcj47XG4gIHByaXZhdGUgY2FuRXhpdCA9IHRydWU7XG5cbiAgX3BvcnRhbD86IENvbXBvbmVudFBvcnRhbDxTZXR0aW5nc1BhZ2U+O1xuICBfYW5pbWF0aW9uU3RhdGUgPSBmYWxzZTtcbiAgX21vdXNlRG93biA9IGZhbHNlO1xuICBfbWVudUZvY3VzZWQgPSBmYWxzZTtcblxuICBfZm9jdXNlZEl0ZW0gPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIF9kZWZhdWx0UGFnZSA9IHNpZ25hbCgxKTtcbiAgX2lzT3BlbmVkID0gc2lnbmFsKGZhbHNlKTtcbiAgX29wZW5lZEFuaW1hdGlvbiA9IHNpZ25hbDwnb3BlbmVkJyB8ICdjbG9zZWQnPignY2xvc2VkJyk7XG5cbiAgaXRlbXMgPSBpbnB1dDxNZW51SXRlbVtdPigpO1xuICBAT3V0cHV0KCkgYWZ0ZXJDbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzbmFja0JhcjogWHVpU25hY2tCYXIpIHt9XG5cbiAgc3RhdGVDaGFuZ2VkID0gKGNhbkV4aXQ6IGJvb2xlYW4pID0+IHtcbiAgICB0aGlzLmNhbkV4aXQgPSBjYW5FeGl0O1xuXG4gICAgaWYgKCFjYW5FeGl0KSB7XG4gICAgICBpZiAoIXRoaXMuc25hY2tiYXJSZWYpIHtcbiAgICAgICAgdGhpcy5zbmFja2JhclJlZiA9IHRoaXMuc25hY2tCYXIub3BlbkZyb21Db21wb25lbnQoU2F2ZVJlc2V0U25hY2tiYXIsIHtcbiAgICAgICAgICBwYW5lbENsYXNzOiAneC1zZXR0aW5ncy1zbmFja2Jhci1wYW5lbCcsXG4gICAgICAgICAgZHVyYXRpb246IHVuZGVmaW5lZCEsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgc2F2ZTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaW5zdGFuY2U/LnNhdmUoKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmhpZGVTbmFja2JhcigpO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogc2hvdyBlcnJvciBzbmFja2JhclxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVzZXQ6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbnN0YW5jZT8ucmVzZXQoKTtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5oaWRlU25hY2tiYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhpZGVTbmFja2JhcigpO1xuICAgIH1cbiAgfTtcblxuICBvcGVuKHBhZ2UgPSAxKSB7XG4gICAgdGhpcy5fZGVmYXVsdFBhZ2Uuc2V0KHBhZ2UpO1xuICAgIHRoaXMuX2lzT3BlbmVkLnNldCh0cnVlKTtcbiAgICB0aGlzLl9vcGVuZWRBbmltYXRpb24uc2V0KCdvcGVuZWQnKTtcbiAgICB0aGlzLl9uYXZpZ2F0ZSh0aGlzLl9kZWZhdWx0UGFnZSgpKTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlKCkge1xuICAgIGlmICghdGhpcy5jYW5FeGl0KSB7XG4gICAgICB0aGlzLl9hbmltYXRpb25TdGF0ZSA9IHRydWU7XG4gICAgICB0aGlzLnNuYWNrYmFyUmVmPy5pbnN0YW5jZS5hbGVydCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX29wZW5lZEFuaW1hdGlvbi5zZXQoJ2Nsb3NlZCcpO1xuICAgIGF3YWl0IGRlbGF5KDEwMCk7XG4gICAgdGhpcy5faXNPcGVuZWQuc2V0KGZhbHNlKTtcbiAgICB0aGlzLmFmdGVyQ2xvc2VkLmVtaXQoKTtcbiAgfVxuXG4gIGF0dGFjaGVkKHJlZjogQ2RrUG9ydGFsT3V0bGV0QXR0YWNoZWRSZWYpIHtcbiAgICB0aGlzLmluc3RhbmNlID0gKHJlZiBhcyBDb21wb25lbnRSZWY8U2V0dGluZ3NQYWdlPikuaW5zdGFuY2U7XG4gICAgdGhpcy5pbnN0YW5jZS5zdGF0ZUNoYW5nZWQgPSB0aGlzLnN0YXRlQ2hhbmdlZDtcbiAgfVxuXG4gIF9uYXZpZ2F0ZShpZHg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmluc3RhbmNlKSB7XG4gICAgICBpZiAoIXRoaXMuY2FuRXhpdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbSA9IHRoaXMuaXRlbXMoKT8uW2lkeF07XG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIHRoaXMuX2RlZmF1bHRQYWdlLnNldChpZHgpO1xuICAgICAgdGhpcy5fZm9jdXNlZEl0ZW0uc2V0KGlkeCk7XG5cbiAgICAgIGlmIChpdGVtLmFjdGlvbikge1xuICAgICAgICBpdGVtLmFjdGlvbigpO1xuICAgICAgfSBlbHNlIGlmIChpdGVtLmNvbXBvbmVudCkge1xuICAgICAgICB0aGlzLl9wb3J0YWwgPSBuZXcgQ29tcG9uZW50UG9ydGFsKGl0ZW0uY29tcG9uZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfZm9jdXNQcmV2KCkge1xuICAgIGxldCBjdXIgPSB0aGlzLl9mb2N1c2VkSXRlbSgpID8/IHRoaXMuaXRlbXMoKT8ubGVuZ3RoID8/IDA7XG5cbiAgICBkbyB7XG4gICAgICBjdXItLTtcbiAgICAgIGlmIChjdXIgPCAwKSB7XG4gICAgICAgIGN1ciA9ICh0aGlzLml0ZW1zKCk/Lmxlbmd0aCA/PyAxKSAtIDE7XG4gICAgICB9XG4gICAgfSB3aGlsZSAodGhpcy5pdGVtcygpPy5bY3VyXS50eXBlICE9PSAnaXRlbScpO1xuICAgIHRoaXMuX2ZvY3VzZWRJdGVtLnNldChjdXIpO1xuICB9XG5cbiAgX2ZvY3VzTmV4dCgpIHtcbiAgICBsZXQgY3VyID0gdGhpcy5fZm9jdXNlZEl0ZW0oKSA/PyB0aGlzLml0ZW1zKCk/Lmxlbmd0aCA/PyAwO1xuXG4gICAgZG8ge1xuICAgICAgY3VyKys7XG4gICAgICBpZiAoY3VyID49ICh0aGlzLml0ZW1zKCk/Lmxlbmd0aCA/PyAwKSkge1xuICAgICAgICBjdXIgPSAwO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKHRoaXMuaXRlbXMoKT8uW2N1cl0udHlwZSAhPT0gJ2l0ZW0nKTtcbiAgICB0aGlzLl9mb2N1c2VkSXRlbS5zZXQoY3VyKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGlkZVNuYWNrYmFyKCkge1xuICAgIGF3YWl0IHRoaXMuc25hY2tiYXJSZWY/Lmluc3RhbmNlLmNsb3NlKCk7XG4gICAgdGhpcy5zbmFja2JhclJlZj8uZGlzbWlzcygpO1xuICAgIHRoaXMuc25hY2tiYXJSZWYgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5jYW5FeGl0ID0gdHJ1ZTtcbiAgfVxufVxuIiwiPGRpYWxvZyBjbGFzcz1cIngtc2V0dGluZ3MtZGlhbG9nXCIgW29wZW5dPVwiX2lzT3BlbmVkKClcIiBjZGtUcmFwRm9jdXMgY2RrVHJhcEZvY3VzQXV0b0NhcHR1cmU+XG4gIDxkaXZcbiAgICBjbGFzcz1cIngtc2V0dGluZ3NcIlxuICAgIFtAb3Blbl09XCJfb3BlbmVkQW5pbWF0aW9uKClcIlxuICAgIFtAYm91bmNlXT1cIl9hbmltYXRpb25TdGF0ZVwiXG4gICAgKEBib3VuY2UuZG9uZSk9XCJfYW5pbWF0aW9uU3RhdGUgPSBmYWxzZVwiXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwieC1zZXR0aW5ncy1tZW51XCI+XG4gICAgICA8bmF2XG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIChrZXlkb3duLmVudGVyKT1cIl9uYXZpZ2F0ZShfZm9jdXNlZEl0ZW0oKSA/PyAwKVwiXG4gICAgICAgIChrZXlkb3duLnNwYWNlKT1cIl9uYXZpZ2F0ZShfZm9jdXNlZEl0ZW0oKSA/PyAwKVwiXG4gICAgICAgIChrZXlkb3duLmFycm93RG93bik9XCJfZm9jdXNOZXh0KClcIlxuICAgICAgICAoa2V5ZG93bi5hcnJvd1VwKT1cIl9mb2N1c1ByZXYoKVwiXG4gICAgICAgIChtb3VzZWRvd24pPVwiX21vdXNlRG93biA9IHRydWVcIlxuICAgICAgICAobW91c2V1cCk9XCJfbW91c2VEb3duID0gZmFsc2VcIlxuICAgICAgICAoZm9jdXNpbik9XCJfbWVudUZvY3VzZWQgPSAhX21vdXNlRG93blwiXG4gICAgICAgIChmb2N1c291dCk9XCJfbWVudUZvY3VzZWQgPSBmYWxzZVwiXG4gICAgICA+XG4gICAgICAgIEBmb3IgKGl0ZW0gb2YgaXRlbXMoKTsgdHJhY2sgaXRlbTsgbGV0IGkgPSAkaW5kZXgpIHtcbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBbY2xhc3MueC1zZXR0aW5ncy1tZW51LWl0ZW1dPVwiaXRlbS50eXBlID09PSAnaXRlbSdcIlxuICAgICAgICAgICAgW2NsYXNzLngtc2V0dGluZ3MtbWVudS1pdGVtLWFjdGl2ZV09XCJpID09PSBfZGVmYXVsdFBhZ2UoKVwiXG4gICAgICAgICAgICBbY2xhc3MueC1zZXR0aW5ncy1tZW51LWl0ZW0tZm9jdXNdPVwiaSA9PT0gX2ZvY3VzZWRJdGVtKCkgJiYgX21lbnVGb2N1c2VkXCJcbiAgICAgICAgICAgIFtjbGFzcy54LXNldHRpbmdzLW1lbnUtY2F0ZWdvcnldPVwiaXRlbS50eXBlID09PSAnY2F0ZWdvcnknXCJcbiAgICAgICAgICAgIFtjbGFzcy54LXNldHRpbmdzLW1lbnUtZGl2aWRlcl09XCJpdGVtLnR5cGUgPT09ICdkaXZpZGVyJ1wiXG4gICAgICAgICAgICBbY2xhc3MueC1zZXR0aW5ncy1tZW51LXJlZF09XCJpdGVtLmNyaXRpY2FsXCJcbiAgICAgICAgICAgIChjbGljayk9XCJfbmF2aWdhdGUoaSk7IF9tZW51Rm9jdXNlZCA9IGZhbHNlXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyBpdGVtLm5hbWUgPyAoaXRlbS5uYW1lIHwgdHJhbnNsYXRlKSA6ICcnIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvbmF2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ4LXNldHRpbmdzLXJpZ2h0XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwieC1zZXR0aW5ncy1jb250ZW50XCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbY2RrUG9ydGFsT3V0bGV0XT1cIl9wb3J0YWxcIiAoYXR0YWNoZWQpPVwiYXR0YWNoZWQoJGV2ZW50KVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cIngtc2V0dGluZ3MtY2xvc2UtYW5jaG9yXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ4LXNldHRpbmdzLWNsb3NlXCIgKGNsaWNrKT1cImNsb3NlKClcIj5cbiAgICAgICAgICA8eHVpLWljb24gdGFiaW5kZXg9XCIwXCIgKGtleWRvd24uc3BhY2UpPVwiY2xvc2UoKVwiIChrZXlkb3duLmVudGVyKT1cImNsb3NlKClcIiBpY29uPVwiY2FuY2VsXCI+PC94dWktaWNvbj5cbiAgICAgICAgICBFU0NcbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2RpYWxvZz5cbiJdfQ==