UNPKG

@blox/material

Version:

Material Components for Angular

370 lines 49.1 kB
import { ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, Self, HostListener } from '@angular/core'; import { cssClasses as listCssClasses } from '@material/list'; import { MDCMenuFoundation, cssClasses, strings, DefaultFocusState } from '@material/menu'; import { MdcMenuSurfaceDirective } from '../menu-surface/mdc.menu-surface.directive'; import { MdcListDirective, MdcListFunction } from '../list/mdc.list.directive'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; // attributes on list-items that we maintain ourselves, so should be ignored // in the adapter: const ANGULAR_ITEM_ATTRIBUTES = [ strings.ARIA_CHECKED_ATTR, strings.ARIA_DISABLED_ATTR ]; // classes on list-items that we maintain ourselves, so should be ignored // in the adapter: const ANGULAR_ITEM_CLASSES = [ listCssClasses.LIST_ITEM_DISABLED_CLASS, cssClasses.MENU_SELECTED_LIST_ITEM ]; export var FocusOnOpen; (function (FocusOnOpen) { FocusOnOpen[FocusOnOpen["first"] = 0] = "first"; FocusOnOpen[FocusOnOpen["last"] = 1] = "last"; FocusOnOpen[FocusOnOpen["root"] = -1] = "root"; })(FocusOnOpen || (FocusOnOpen = {})); ; let nextId = 1; /** * Directive for a spec aligned material design Menu. * This directive should wrap an `mdcList`. The `mdcList` contains the menu items (and possible separators). * * An `mdcMenu` element will also match with the selector of the menu surface directive, documented * <a href="/components/menu-surface#mdcMenuSurface">here: mdcMenuSurface</a>. The * <a href="/components/menu-surface#mdcMenuAnchor">mdcMenuAnchor API</a> is documented on the same page. * * # Accessibility * * * For `role` and `aria-*` attributes on the list, see documentation for `mdcList`. * * The best way to open the menu by user interaction is to use the `mdcMenuTrigger` directive * on the interaction element (e.g. button). This takes care of following ARIA recommended practices * for focusing the correct element, and maintaining proper `aria-*` and `role` attributes on the * interaction element, menu, and list. * * When opening the `mdcMenuSurface` programmatic, the program is responsible for all of this. * (including focusing an element of the menu or the menu itself). * * The `mdcList` will be made focusable by setting a `"tabindex"="-1"` attribute. * * The `mdcList` will get an `aria-orientation=vertical` attribute. * * The `mdcList` will get an `aria-hidden=true` attribute when the menu surface is closed. */ export class MdcMenuDirective { constructor(_elm, rndr, surface) { this._elm = _elm; this.rndr = rndr; this.surface = surface; this.onDestroy$ = new Subject(); this.onListChange$ = new Subject(); /** @internal */ this.itemsChanged = new EventEmitter(); /** @internal */ this.itemValuesChanged = new EventEmitter(); /** @internal */ this._cls = true; this._id = null; this.cachedId = null; this._function = MdcListFunction.menu; this._lastList = null; /** * Event emitted when the user selects a value. The passed object contains a value * (set to the <code>value</code> of the selected list item), and an index * (set to the index of the selected list item). */ this.pick = new EventEmitter(); this.mdcAdapter = { addClassToElementAtIndex: (index, className) => { var _a, _b; // ignore classes we maintain ourselves if (!ANGULAR_ITEM_CLASSES.find(c => c === className)) { const elm = (_b = (_a = this._list) === null || _a === void 0 ? void 0 : _a.getItem(index)) === null || _b === void 0 ? void 0 : _b._elm.nativeElement; if (elm) this.rndr.addClass(elm, className); } }, removeClassFromElementAtIndex: (index, className) => { var _a, _b; // ignore classes we maintain ourselves if (!ANGULAR_ITEM_CLASSES.find(c => c === className)) { const elm = (_b = (_a = this._list) === null || _a === void 0 ? void 0 : _a.getItem(index)) === null || _b === void 0 ? void 0 : _b._elm.nativeElement; if (elm) this.rndr.addClass(elm, className); } }, addAttributeToElementAtIndex: (index, attr, value) => { var _a, _b; // ignore attributes we maintain ourselves if (!ANGULAR_ITEM_ATTRIBUTES.find(a => a === attr)) { const elm = (_b = (_a = this._list) === null || _a === void 0 ? void 0 : _a.getItem(index)) === null || _b === void 0 ? void 0 : _b._elm.nativeElement; if (elm) this.rndr.setAttribute(elm, attr, value); } }, removeAttributeFromElementAtIndex: (index, attr) => { var _a, _b; // ignore attributes we maintain ourselves if (!ANGULAR_ITEM_ATTRIBUTES.find(a => a === attr)) { const elm = (_b = (_a = this._list) === null || _a === void 0 ? void 0 : _a.getItem(index)) === null || _b === void 0 ? void 0 : _b._elm.nativeElement; if (elm) this.rndr.removeAttribute(elm, attr); } }, elementContainsClass: (element, className) => element.classList.contains(className), closeSurface: (skipRestoreFocus) => { if (skipRestoreFocus) this.surface.closeWithoutFocusRestore(); else this.surface.open = false; }, getElementIndex: (element) => { var _a; return (_a = this._list) === null || _a === void 0 ? void 0 : _a._items.toArray().findIndex(i => i._elm.nativeElement === element); }, notifySelected: (evtData) => { this.pick.emit({ index: evtData.index, value: this._list._items.toArray()[evtData.index].value }); }, getMenuItemCount: () => { var _a; return ((_a = this._list) === null || _a === void 0 ? void 0 : _a._items.length) || 0; }, focusItemAtIndex: (index) => { var _a; return (_a = this._list.getItem(index)) === null || _a === void 0 ? void 0 : _a._elm.nativeElement.focus(); }, focusListRoot: () => { var _a; return (_a = this._list) === null || _a === void 0 ? void 0 : _a._elm.nativeElement.focus(); }, getSelectedSiblingOfItemAtIndex: () => -1, isSelectableItemAtIndex: () => false // menuSelectionGroup not yet supported }; this.foundation = null; } ngOnInit() { // Force setter to be called in case id was not specified. this.id = this.id; } ngAfterContentInit() { this._lastList = this._listQuery.first; this._listQuery.changes.subscribe(() => { var _a; if (this._lastList !== this._listQuery.first) { this.onListChange$.next(); (_a = this._lastList) === null || _a === void 0 ? void 0 : _a._setFunction(MdcListFunction.plain); this._lastList = this._listQuery.first; this.destroyFoundation(); if (this._lastList) this.initAll(); } }); this.surface.afterOpened.pipe(takeUntil(this.onDestroy$)).subscribe(() => { var _a, _b; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleMenuSurfaceOpened(); // reset default focus state for programmatic opening of menu; // interactive opening sets the default when the open is triggered // (see openAndFocus) (_b = this.foundation) === null || _b === void 0 ? void 0 : _b.setDefaultFocusState(DefaultFocusState.NONE); }); this.surface.openChange.pipe(takeUntil(this.onDestroy$)).subscribe(() => { if (this._list) this._list._hidden = !this.surface.open; }); if (this._lastList) this.initAll(); } ngOnDestroy() { this.onListChange$.next(); this.onListChange$.complete(); this.onDestroy$.next(); this.onDestroy$.complete(); this.destroyFoundation(); } initAll() { var _a, _b; Promise.resolve().then(() => this._lastList._setFunction(this._function)); this.initFoundation(); this.subscribeItemActions(); (_a = this._lastList) === null || _a === void 0 ? void 0 : _a.itemsChanged.pipe(takeUntil(this.onListChange$)).subscribe(() => this.itemsChanged.emit()); (_b = this._lastList) === null || _b === void 0 ? void 0 : _b.itemValuesChanged.pipe(takeUntil(this.onListChange$)).subscribe(() => this.itemValuesChanged.emit()); } initFoundation() { this.foundation = new MDCMenuFoundation(this.mdcAdapter); this.foundation.init(); // suitable for programmatic opening, program can focus whatever element it wants: this.foundation.setDefaultFocusState(DefaultFocusState.NONE); if (this._list) this._list._hidden = !this.surface.open; } destroyFoundation() { if (this.foundation) { this.foundation.destroy(); this.foundation = null; } } subscribeItemActions() { var _a; (_a = this._lastList) === null || _a === void 0 ? void 0 : _a.itemAction.pipe(takeUntil(this.onListChange$)).subscribe(data => { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleItemAction(this._list.getItem(data.index)._elm.nativeElement); }); } /** @docs-private */ get id() { return this._id; } set id(value) { this._id = value || this._newId(); } /** @internal */ _newId() { this.cachedId = this.cachedId || `mdc-menu-${nextId++}`; return this.cachedId; } /** @docs-private */ get open() { return this.surface.open; } /** @docs-private */ openAndFocus(focus) { var _a, _b, _c; switch (focus) { case FocusOnOpen.first: (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.setDefaultFocusState(DefaultFocusState.FIRST_ITEM); break; case FocusOnOpen.last: (_b = this.foundation) === null || _b === void 0 ? void 0 : _b.setDefaultFocusState(DefaultFocusState.LAST_ITEM); break; case FocusOnOpen.root: default: (_c = this.foundation) === null || _c === void 0 ? void 0 : _c.setDefaultFocusState(DefaultFocusState.LIST_ROOT); } this.surface.open = true; } /** @internal */ doClose() { this.surface.open = false; } /** @internal */ set _listFunction(val) { this._function = val; if (this._lastList) // otherwise this will happen in ngAfterContentInit this._list._setFunction(val); } /** @internal */ get _list() { return this._listQuery.first; } /** @internal */ _onKeydown(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event); } } MdcMenuDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcMenu],[mdcSelectMenu]', exportAs: 'mdcMenu' },] } ]; MdcMenuDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: MdcMenuSurfaceDirective, decorators: [{ type: Self }] } ]; MdcMenuDirective.propDecorators = { itemsChanged: [{ type: Output }], itemValuesChanged: [{ type: Output }], _cls: [{ type: HostBinding, args: ['class.mdc-menu',] }], pick: [{ type: Output }], _listQuery: [{ type: ContentChildren, args: [MdcListDirective,] }], id: [{ type: HostBinding }, { type: Input }], _onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }] }; /** * * # Accessibility * * * `Enter`, `Space`, and `Down Arrow` keys open the menu and place focus on the first item. * * `Up Arrow` opens the menu and places focus on the last item * * Click/Touch events set focus to the mdcList root element * * * Attribute `role=button` will be set if the element is not already a button element. * * Attribute `aria-haspopup=menu` will be set if an `mdcMenu` is attached. * * Attribute `aria-expanded` will be set while the attached menu is open * * Attribute `aria-controls` will be set to the id of the attached menu. (And a unique id will be generated, * if none was set on the menu). * * `Enter`, `Space`, and `Down-Arrow` will open the menu with the first menu item focused. * * `Up-Arrow` will open the menu with the last menu item focused. * * Mouse/Touch events will open the menu with the list root element focused. The list root element * will handle keyboard navigation once it receives focus. */ export class MdcMenuTriggerDirective { constructor(elm) { /** @internal */ this._role = 'button'; this._mdcMenuTrigger = null; this.down = { enter: false, space: false }; if (elm.nativeElement.nodeName.toUpperCase() === 'BUTTON') this._role = null; } /** @internal */ onClick() { var _a, _b; if (this.down.enter || this.down.space) (_a = this._mdcMenuTrigger) === null || _a === void 0 ? void 0 : _a.openAndFocus(FocusOnOpen.first); else (_b = this._mdcMenuTrigger) === null || _b === void 0 ? void 0 : _b.openAndFocus(FocusOnOpen.root); } /** @internal */ onKeydown(event) { var _a, _b; this.setDown(event, true); const { key, keyCode } = event; if (key === 'ArrowUp' || keyCode === 38) (_a = this._mdcMenuTrigger) === null || _a === void 0 ? void 0 : _a.openAndFocus(FocusOnOpen.last); else if (key === 'ArrowDown' || keyCode === 40) (_b = this._mdcMenuTrigger) === null || _b === void 0 ? void 0 : _b.openAndFocus(FocusOnOpen.first); } /** @internal */ onKeyup(event) { this.setDown(event, false); } /** @internal */ get _hasPopup() { return this._mdcMenuTrigger ? 'menu' : null; } /** @internal */ get _expanded() { var _a; return ((_a = this._mdcMenuTrigger) === null || _a === void 0 ? void 0 : _a.open) ? 'true' : null; } /** @internal */ get _ariaControls() { var _a; return (_a = this._mdcMenuTrigger) === null || _a === void 0 ? void 0 : _a.id; } get mdcMenuTrigger() { return this._mdcMenuTrigger; } set mdcMenuTrigger(value) { if (value && value.openAndFocus) this._mdcMenuTrigger = value; else this._mdcMenuTrigger = null; } setDown(event, isDown) { const { key, keyCode } = event; if (key === 'Enter' || keyCode === 13) this.down.enter = isDown; else if (key === 'Space' || keyCode === 32) this.down.space = isDown; } } MdcMenuTriggerDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcMenuTrigger]', },] } ]; MdcMenuTriggerDirective.ctorParameters = () => [ { type: ElementRef } ]; MdcMenuTriggerDirective.propDecorators = { _role: [{ type: HostBinding, args: ['attr.role',] }], onClick: [{ type: HostListener, args: ['click',] }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }], onKeyup: [{ type: HostListener, args: ['keyup', ['$event'],] }], _hasPopup: [{ type: HostBinding, args: ['attr.aria-haspopup',] }], _expanded: [{ type: HostBinding, args: ['attr.aria-expanded',] }], _ariaControls: [{ type: HostBinding, args: ['attr.aria-controls',] }], mdcMenuTrigger: [{ type: Input }] }; export const MENU_DIRECTIVES = [ MdcMenuDirective, MdcMenuTriggerDirective ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLm1lbnUuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvbWVudS9tZGMubWVudS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixlQUFlLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUMxRixLQUFLLEVBQWEsTUFBTSxFQUFhLFNBQVMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxVQUFVLElBQUksY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGlCQUFpQixFQUFrQixVQUFVLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0csT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDckYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQy9FLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBZ0IzQyw0RUFBNEU7QUFDNUUsa0JBQWtCO0FBQ2xCLE1BQU0sdUJBQXVCLEdBQUc7SUFDNUIsT0FBTyxDQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0I7Q0FDeEQsQ0FBQztBQUNGLHlFQUF5RTtBQUN6RSxrQkFBa0I7QUFDbEIsTUFBTSxvQkFBb0IsR0FBRztJQUN6QixjQUFjLENBQUMsd0JBQXdCLEVBQUUsVUFBVSxDQUFDLHVCQUF1QjtDQUM5RSxDQUFDO0FBRUYsTUFBTSxDQUFOLElBQVksV0FBNEM7QUFBeEQsV0FBWSxXQUFXO0lBQUUsK0NBQVMsQ0FBQTtJQUFFLDZDQUFRLENBQUE7SUFBRSw4Q0FBUyxDQUFBO0FB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LEVBQUUsQ0FBQyxRQUFRLENBQUM7c0JBVWxDLFlBQVksU0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7d0JBS2hDLFdBQVcsU0FBQyxvQkFBb0I7d0JBS2hDLFdBQVcsU0FBQyxvQkFBb0I7NEJBS2hDLFdBQVcsU0FBQyxvQkFBb0I7NkJBSWhDLEtBQUs7O0FBb0JWLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRztJQUMzQixnQkFBZ0IsRUFBRSx1QkFBdUI7Q0FDNUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbnRlbnRDaGlsZHJlbiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RCaW5kaW5nLFxuICBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQsIFF1ZXJ5TGlzdCwgUmVuZGVyZXIyLCBTZWxmLCBIb3N0TGlzdGVuZXIsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY3NzQ2xhc3NlcyBhcyBsaXN0Q3NzQ2xhc3NlcyB9IGZyb20gJ0BtYXRlcmlhbC9saXN0JztcbmltcG9ydCB7IE1EQ01lbnVGb3VuZGF0aW9uLCBNRENNZW51QWRhcHRlciwgY3NzQ2xhc3Nlcywgc3RyaW5ncywgRGVmYXVsdEZvY3VzU3RhdGUgfSBmcm9tICdAbWF0ZXJpYWwvbWVudSc7XG5pbXBvcnQgeyBNZGNNZW51U3VyZmFjZURpcmVjdGl2ZSB9IGZyb20gJy4uL21lbnUtc3VyZmFjZS9tZGMubWVudS1zdXJmYWNlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBNZGNMaXN0RGlyZWN0aXZlLCBNZGNMaXN0RnVuY3Rpb24gfSBmcm9tICcuLi9saXN0L21kYy5saXN0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8qKlxuICogRGF0YSBzZW5kIGJ5IHRoZSA8Y29kZT5waWNrPC9jb2RlPiBldmVudCBvZiA8Y29kZT5NZGNNZW51RGlyZWN0aXZlPC9jb2RlPi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZGNNZW51U2VsZWN0aW9uIHtcbiAgICAvKipcbiAgICAgKiBUaGUgPGNvZGU+dmFsdWU8L2NvZGU+IG9mIHRoZSBzZWxlY3RlZCBtZW51IGl0ZW0gKDxjb2RlPk1kY0xpc3RJdGVtRGlyZWN0aXZlPC9jb2RlPikuXG4gICAgICovXG4gICAgdmFsdWU6IGFueSxcbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggb2YgdGhlIHNlbGVjdGVkIG1lbnUgaXRlbSAoPGNvZGU+TWRjTGlzdEl0ZW1EaXJlY3RpdmU8L2NvZGU+KS5cbiAgICAgKi9cbiAgICBpbmRleDogbnVtYmVyXG59XG5cbi8vIGF0dHJpYnV0ZXMgb24gbGlzdC1pdGVtcyB0aGF0IHdlIG1haW50YWluIG91cnNlbHZlcywgc28gc2hvdWxkIGJlIGlnbm9yZWRcbi8vIGluIHRoZSBhZGFwdGVyOlxuY29uc3QgQU5HVUxBUl9JVEVNX0FUVFJJQlVURVMgPSBbXG4gICAgc3RyaW5ncy5BUklBX0NIRUNLRURfQVRUUiwgc3RyaW5ncy5BUklBX0RJU0FCTEVEX0FUVFJcbl07XG4vLyBjbGFzc2VzIG9uIGxpc3QtaXRlbXMgdGhhdCB3ZSBtYWludGFpbiBvdXJzZWx2ZXMsIHNvIHNob3VsZCBiZSBpZ25vcmVkXG4vLyBpbiB0aGUgYWRhcHRlcjpcbmNvbnN0IEFOR1VMQVJfSVRFTV9DTEFTU0VTID0gW1xuICAgIGxpc3RDc3NDbGFzc2VzLkxJU1RfSVRFTV9ESVNBQkxFRF9DTEFTUywgY3NzQ2xhc3Nlcy5NRU5VX1NFTEVDVEVEX0xJU1RfSVRFTVxuXTtcblxuZXhwb3J0IGVudW0gRm9jdXNPbk9wZW4ge2ZpcnN0ID0gMCwgbGFzdCA9IDEsIHJvb3QgPSAtMX07XG5sZXQgbmV4dElkID0gMTtcblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIGEgc3BlYyBhbGlnbmVkIG1hdGVyaWFsIGRlc2lnbiBNZW51LlxuICogVGhpcyBkaXJlY3RpdmUgc2hvdWxkIHdyYXAgYW4gYG1kY0xpc3RgLiBUaGUgYG1kY0xpc3RgIGNvbnRhaW5zIHRoZSBtZW51IGl0ZW1zIChhbmQgcG9zc2libGUgc2VwYXJhdG9ycykuXG4gKiBcbiAqIEFuIGBtZGNNZW51YCBlbGVtZW50IHdpbGwgYWxzbyBtYXRjaCB3aXRoIHRoZSBzZWxlY3RvciBvZiB0aGUgbWVudSBzdXJmYWNlIGRpcmVjdGl2ZSwgZG9jdW1lbnRlZFxuICogPGEgaHJlZj1cIi9jb21wb25lbnRzL21lbnUtc3VyZmFjZSNtZGNNZW51U3VyZmFjZVwiPmhlcmU6IG1kY01lbnVTdXJmYWNlPC9hPi4gVGhlXG4gKiA8YSBocmVmPVwiL2NvbXBvbmVudHMvbWVudS1zdXJmYWNlI21kY01lbnVBbmNob3JcIj5tZGNNZW51QW5jaG9yIEFQSTwvYT4gaXMgZG9jdW1lbnRlZCBvbiB0aGUgc2FtZSBwYWdlLlxuICogXG4gKiAjIEFjY2Vzc2liaWxpdHlcbiAqIFxuICogKiBGb3IgYHJvbGVgIGFuZCBgYXJpYS0qYCBhdHRyaWJ1dGVzIG9uIHRoZSBsaXN0LCBzZWUgZG9jdW1lbnRhdGlvbiBmb3IgYG1kY0xpc3RgLlxuICogKiBUaGUgYmVzdCB3YXkgdG8gb3BlbiB0aGUgbWVudSBieSB1c2VyIGludGVyYWN0aW9uIGlzIHRvIHVzZSB0aGUgYG1kY01lbnVUcmlnZ2VyYCBkaXJlY3RpdmVcbiAqICAgb24gdGhlIGludGVyYWN0aW9uIGVsZW1lbnQgKGUuZy4gYnV0dG9uKS4gVGhpcyB0YWtlcyBjYXJlIG9mIGZvbGxvd2luZyBBUklBIHJlY29tbWVuZGVkIHByYWN0aWNlc1xuICogICBmb3IgZm9jdXNpbmcgdGhlIGNvcnJlY3QgZWxlbWVudCwgYW5kIG1haW50YWluaW5nIHByb3BlciBgYXJpYS0qYCBhbmQgYHJvbGVgIGF0dHJpYnV0ZXMgb24gdGhlXG4gKiAgIGludGVyYWN0aW9uIGVsZW1lbnQsIG1lbnUsIGFuZCBsaXN0LlxuICogKiBXaGVuIG9wZW5pbmcgdGhlIGBtZGNNZW51U3VyZmFjZWAgcHJvZ3JhbW1hdGljLCB0aGUgcHJvZ3JhbSBpcyByZXNwb25zaWJsZSBmb3IgYWxsIG9mIHRoaXMuXG4gKiAgIChpbmNsdWRpbmcgZm9jdXNpbmcgYW4gZWxlbWVudCBvZiB0aGUgbWVudSBvciB0aGUgbWVudSBpdHNlbGYpLlxuICogKiBUaGUgYG1kY0xpc3RgIHdpbGwgYmUgbWFkZSBmb2N1c2FibGUgYnkgc2V0dGluZyBhIGBcInRhYmluZGV4XCI9XCItMVwiYCBhdHRyaWJ1dGUuXG4gKiAqIFRoZSBgbWRjTGlzdGAgd2lsbCBnZXQgYW4gYGFyaWEtb3JpZW50YXRpb249dmVydGljYWxgIGF0dHJpYnV0ZS5cbiAqICogVGhlIGBtZGNMaXN0YCB3aWxsIGdldCBhbiBgYXJpYS1oaWRkZW49dHJ1ZWAgYXR0cmlidXRlIHdoZW4gdGhlIG1lbnUgc3VyZmFjZSBpcyBjbG9zZWQuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY01lbnVdLFttZGNTZWxlY3RNZW51XScsXG4gICAgZXhwb3J0QXM6ICdtZGNNZW51J1xufSlcbmV4cG9ydCBjbGFzcyBNZGNNZW51RGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAgIHByaXZhdGUgb25EZXN0cm95JDogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKTtcbiAgICBwcml2YXRlIG9uTGlzdENoYW5nZSQ6IFN1YmplY3Q8YW55PiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBPdXRwdXQoKSByZWFkb25seSBpdGVtc0NoYW5nZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGl0ZW1WYWx1ZXNDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLW1lbnUnKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbiAgICBwcml2YXRlIF9pZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBjYWNoZWRJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBfZnVuY3Rpb24gPSBNZGNMaXN0RnVuY3Rpb24ubWVudTtcbiAgICBwcml2YXRlIF9sYXN0TGlzdDogTWRjTGlzdERpcmVjdGl2ZSB8IG51bGw9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHVzZXIgc2VsZWN0cyBhIHZhbHVlLiBUaGUgcGFzc2VkIG9iamVjdCBjb250YWlucyBhIHZhbHVlXG4gICAgICogKHNldCB0byB0aGUgPGNvZGU+dmFsdWU8L2NvZGU+IG9mIHRoZSBzZWxlY3RlZCBsaXN0IGl0ZW0pLCBhbmQgYW4gaW5kZXhcbiAgICAgKiAoc2V0IHRvIHRoZSBpbmRleCBvZiB0aGUgc2VsZWN0ZWQgbGlzdCBpdGVtKS5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgcGljazogRXZlbnRFbWl0dGVyPE1kY01lbnVTZWxlY3Rpb24+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0xpc3REaXJlY3RpdmUpIF9saXN0UXVlcnk/OiBRdWVyeUxpc3Q8TWRjTGlzdERpcmVjdGl2ZT47XG4gICAgcHJpdmF0ZSBtZGNBZGFwdGVyOiBNRENNZW51QWRhcHRlciA9IHtcbiAgICAgICAgYWRkQ2xhc3NUb0VsZW1lbnRBdEluZGV4OiAoaW5kZXgsIGNsYXNzTmFtZSkgPT4ge1xuICAgICAgICAgICAgLy8gaWdub3JlIGNsYXNzZXMgd2UgbWFpbnRhaW4gb3Vyc2VsdmVzXG4gICAgICAgICAgICBpZiAoIUFOR1VMQVJfSVRFTV9DTEFTU0VTLmZpbmQoYyA9PiBjID09PSBjbGFzc05hbWUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZWxtID0gdGhpcy5fbGlzdD8uZ2V0SXRlbShpbmRleCk/Ll9lbG0ubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICAgICAgICBpZiAoZWxtKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJuZHIuYWRkQ2xhc3MoZWxtLCBjbGFzc05hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICByZW1vdmVDbGFzc0Zyb21FbGVtZW50QXRJbmRleDogKGluZGV4LCBjbGFzc05hbWUpID0+IHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBjbGFzc2VzIHdlIG1haW50YWluIG91cnNlbHZlc1xuICAgICAgICAgICAgaWYgKCFBTkdVTEFSX0lURU1fQ0xBU1NFUy5maW5kKGMgPT4gYyA9PT0gY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsbSA9IHRoaXMuX2xpc3Q/LmdldEl0ZW0oaW5kZXgpPy5fZWxtLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGVsbSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ybmRyLmFkZENsYXNzKGVsbSwgY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgYWRkQXR0cmlidXRlVG9FbGVtZW50QXRJbmRleDogKGluZGV4LCBhdHRyLCB2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgLy8gaWdub3JlIGF0dHJpYnV0ZXMgd2UgbWFpbnRhaW4gb3Vyc2VsdmVzXG4gICAgICAgICAgICBpZiAoIUFOR1VMQVJfSVRFTV9BVFRSSUJVVEVTLmZpbmQoYSA9PiBhID09PSBhdHRyKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVsbSA9IHRoaXMuX2xpc3Q/LmdldEl0ZW0oaW5kZXgpPy5fZWxtLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgaWYgKGVsbSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ybmRyLnNldEF0dHJpYnV0ZShlbG0sIGF0dHIsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVtb3ZlQXR0cmlidXRlRnJvbUVsZW1lbnRBdEluZGV4OiAoaW5kZXgsIGF0dHIpID0+IHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBhdHRyaWJ1dGVzIHdlIG1haW50YWluIG91cnNlbHZlc1xuICAgICAgICAgICAgaWYgKCFBTkdVTEFSX0lURU1fQVRUUklCVVRFUy5maW5kKGEgPT4gYSA9PT0gYXR0cikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbG0gPSB0aGlzLl9saXN0Py5nZXRJdGVtKGluZGV4KT8uX2VsbS5uYXRpdmVFbGVtZW50O1xuICAgICAgICAgICAgICAgIGlmIChlbG0pXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm5kci5yZW1vdmVBdHRyaWJ1dGUoZWxtLCBhdHRyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZWxlbWVudENvbnRhaW5zQ2xhc3M6IChlbGVtZW50LCBjbGFzc05hbWUpID0+IGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSksXG4gICAgICAgIGNsb3NlU3VyZmFjZTogKHNraXBSZXN0b3JlRm9jdXMpID0+IHtcbiAgICAgICAgICAgIGlmIChza2lwUmVzdG9yZUZvY3VzKVxuICAgICAgICAgICAgICAgIHRoaXMuc3VyZmFjZS5jbG9zZVdpdGhvdXRGb2N1c1Jlc3RvcmUoKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLnN1cmZhY2Uub3BlbiA9IGZhbHNlO1xuICAgICAgICB9LFxuICAgICAgICBnZXRFbGVtZW50SW5kZXg6IChlbGVtZW50KSA9PiB0aGlzLl9saXN0Py5faXRlbXMhLnRvQXJyYXkoKS5maW5kSW5kZXgoaSA9PiBpLl9lbG0ubmF0aXZlRWxlbWVudCA9PT0gZWxlbWVudCksXG4gICAgICAgIG5vdGlmeVNlbGVjdGVkOiAoZXZ0RGF0YSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5waWNrLmVtaXQoe2luZGV4OiBldnREYXRhLmluZGV4LCB2YWx1ZTogdGhpcy5fbGlzdC5faXRlbXMhLnRvQXJyYXkoKVtldnREYXRhLmluZGV4XS52YWx1ZX0pO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNZW51SXRlbUNvdW50OiAoKSA9PiB0aGlzLl9saXN0Py5faXRlbXMhLmxlbmd0aCB8fCAwLFxuICAgICAgICBmb2N1c0l0ZW1BdEluZGV4OiAoaW5kZXgpID0+IHRoaXMuX2xpc3QuZ2V0SXRlbShpbmRleCk/Ll9lbG0ubmF0aXZlRWxlbWVudC5mb2N1cygpLFxuICAgICAgICBmb2N1c0xpc3RSb290OiAoKSA9PiB0aGlzLl9saXN0Py5fZWxtLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKSxcbiAgICAgICAgZ2V0U2VsZWN0ZWRTaWJsaW5nT2ZJdGVtQXRJbmRleDogKCkgPT4gLTEsIC8vIG1lbnVTZWxlY3Rpb25Hcm91cCBub3QgeWV0IHN1cHBvcnRlZFxuICAgICAgICBpc1NlbGVjdGFibGVJdGVtQXRJbmRleDogKCkgPT4gZmFsc2UgLy8gbWVudVNlbGVjdGlvbkdyb3VwIG5vdCB5ZXQgc3VwcG9ydGVkXG4gICAgfTtcbiAgICBwcml2YXRlIGZvdW5kYXRpb246IE1EQ01lbnVGb3VuZGF0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZiwgcHJpdmF0ZSBybmRyOiBSZW5kZXJlcjIsIEBTZWxmKCkgcHJpdmF0ZSBzdXJmYWNlOiBNZGNNZW51U3VyZmFjZURpcmVjdGl2ZSkge1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICAvLyBGb3JjZSBzZXR0ZXIgdG8gYmUgY2FsbGVkIGluIGNhc2UgaWQgd2FzIG5vdCBzcGVjaWZpZWQuXG4gICAgICAgIHRoaXMuaWQgPSB0aGlzLmlkO1xuICAgIH1cblxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICAgICAgdGhpcy5fbGFzdExpc3QgPSB0aGlzLl9saXN0UXVlcnkhLmZpcnN0O1xuICAgICAgICB0aGlzLl9saXN0UXVlcnkhLmNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sYXN0TGlzdCAhPT0gdGhpcy5fbGlzdFF1ZXJ5IS5maXJzdCkge1xuICAgICAgICAgICAgICAgIHRoaXMub25MaXN0Q2hhbmdlJC5uZXh0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbGFzdExpc3Q/Ll9zZXRGdW5jdGlvbihNZGNMaXN0RnVuY3Rpb24ucGxhaW4pO1xuICAgICAgICAgICAgICAgIHRoaXMuX2xhc3RMaXN0ID0gdGhpcy5fbGlzdFF1ZXJ5IS5maXJzdDtcbiAgICAgICAgICAgICAgICB0aGlzLmRlc3Ryb3lGb3VuZGF0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2xhc3RMaXN0KVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXRBbGwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3VyZmFjZS5hZnRlck9wZW5lZC5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uPy5oYW5kbGVNZW51U3VyZmFjZU9wZW5lZCgpO1xuICAgICAgICAgICAgLy8gcmVzZXQgZGVmYXVsdCBmb2N1cyBzdGF0ZSBmb3IgcHJvZ3JhbW1hdGljIG9wZW5pbmcgb2YgbWVudTtcbiAgICAgICAgICAgIC8vIGludGVyYWN0aXZlIG9wZW5pbmcgc2V0cyB0aGUgZGVmYXVsdCB3aGVuIHRoZSBvcGVuIGlzIHRyaWdnZXJlZFxuICAgICAgICAgICAgLy8gKHNlZSBvcGVuQW5kRm9jdXMpXG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24/LnNldERlZmF1bHRGb2N1c1N0YXRlKERlZmF1bHRGb2N1c1N0YXRlLk5PTkUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdXJmYWNlLm9wZW5DaGFuZ2UucGlwZSh0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9saXN0KVxuICAgICAgICAgICAgICAgIHRoaXMuX2xpc3QuX2hpZGRlbiA9ICF0aGlzLnN1cmZhY2Uub3BlbjtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLl9sYXN0TGlzdClcbiAgICAgICAgICAgIHRoaXMuaW5pdEFsbCgpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLm9uTGlzdENoYW5nZSQubmV4dCgpOyB0aGlzLm9uTGlzdENoYW5nZSQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5vbkRlc3Ryb3kkLm5leHQoKTsgdGhpcy5vbkRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuZGVzdHJveUZvdW5kYXRpb24oKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRBbGwoKSB7XG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdGhpcy5fbGFzdExpc3QhLl9zZXRGdW5jdGlvbih0aGlzLl9mdW5jdGlvbikpO1xuICAgICAgICB0aGlzLmluaXRGb3VuZGF0aW9uKCk7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlSXRlbUFjdGlvbnMoKTtcbiAgICAgICAgdGhpcy5fbGFzdExpc3Q/Lml0ZW1zQ2hhbmdlZC5waXBlKHRha2VVbnRpbCh0aGlzLm9uTGlzdENoYW5nZSQpKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5pdGVtc0NoYW5nZWQuZW1pdCgpKTtcbiAgICAgICAgdGhpcy5fbGFzdExpc3Q/Lml0ZW1WYWx1ZXNDaGFuZ2VkLnBpcGUodGFrZVVudGlsKHRoaXMub25MaXN0Q2hhbmdlJCkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLml0ZW1WYWx1ZXNDaGFuZ2VkLmVtaXQoKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0Rm91bmRhdGlvbigpIHtcbiAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbmV3IE1EQ01lbnVGb3VuZGF0aW9uKHRoaXMubWRjQWRhcHRlcik7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbi5pbml0KCk7XG4gICAgICAgIC8vIHN1aXRhYmxlIGZvciBwcm9ncmFtbWF0aWMgb3BlbmluZywgcHJvZ3JhbSBjYW4gZm9jdXMgd2hhdGV2ZXIgZWxlbWVudCBpdCB3YW50czpcbiAgICAgICAgdGhpcy5mb3VuZGF0aW9uLnNldERlZmF1bHRGb2N1c1N0YXRlKERlZmF1bHRGb2N1c1N0YXRlLk5PTkUpO1xuICAgICAgICBpZiAodGhpcy5fbGlzdClcbiAgICAgICAgICAgIHRoaXMuX2xpc3QuX2hpZGRlbiA9ICF0aGlzLnN1cmZhY2Uub3BlbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRlc3Ryb3lGb3VuZGF0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5mb3VuZGF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3Vic2NyaWJlSXRlbUFjdGlvbnMoKSB7XG4gICAgICAgIHRoaXMuX2xhc3RMaXN0Py5pdGVtQWN0aW9uLnBpcGUodGFrZVVudGlsKHRoaXMub25MaXN0Q2hhbmdlJCkpLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgICAgICAgIHRoaXMuZm91bmRhdGlvbj8uaGFuZGxlSXRlbUFjdGlvbih0aGlzLl9saXN0LmdldEl0ZW0oZGF0YS5pbmRleCkhLl9lbG0ubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKiBAZG9jcy1wcml2YXRlICovXG4gICAgQEhvc3RCaW5kaW5nKClcbiAgICBASW5wdXQoKSBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pZDtcbiAgICB9XG4gIFxuICAgIHNldCBpZCh2YWx1ZTogc3RyaW5nIHwgbnVsbCkge1xuICAgICAgICB0aGlzLl9pZCA9IHZhbHVlIHx8IHRoaXMuX25ld0lkKCk7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIF9uZXdJZCgpOiBzdHJpbmcge1xuICAgICAgICB0aGlzLmNhY2hlZElkID0gdGhpcy5jYWNoZWRJZCB8fCBgbWRjLW1lbnUtJHtuZXh0SWQrK31gO1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZWRJZDtcbiAgICB9XG5cbiAgICAvKiogQGRvY3MtcHJpdmF0ZSAqL1xuICAgIGdldCBvcGVuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdXJmYWNlLm9wZW47XG4gICAgfVxuXG4gICAgLyoqIEBkb2NzLXByaXZhdGUgKi9cbiAgICBvcGVuQW5kRm9jdXMoZm9jdXM6IEZvY3VzT25PcGVuKSB7XG4gICAgICAgIHN3aXRjaCAoZm9jdXMpIHtcbiAgICAgICAgICAgIGNhc2UgRm9jdXNPbk9wZW4uZmlyc3Q6XG4gICAgICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uPy5zZXREZWZhdWx0Rm9jdXNTdGF0ZShEZWZhdWx0Rm9jdXNTdGF0ZS5GSVJTVF9JVEVNKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRm9jdXNPbk9wZW4ubGFzdDpcbiAgICAgICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24/LnNldERlZmF1bHRGb2N1c1N0YXRlKERlZmF1bHRGb2N1c1N0YXRlLkxBU1RfSVRFTSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEZvY3VzT25PcGVuLnJvb3Q6XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRoaXMuZm91bmRhdGlvbj8uc2V0RGVmYXVsdEZvY3VzU3RhdGUoRGVmYXVsdEZvY3VzU3RhdGUuTElTVF9ST09UKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN1cmZhY2Uub3BlbiA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIGRvQ2xvc2UoKSB7XG4gICAgICAgIHRoaXMuc3VyZmFjZS5vcGVuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHNldCBfbGlzdEZ1bmN0aW9uKHZhbDogTWRjTGlzdEZ1bmN0aW9uKSB7XG4gICAgICAgIHRoaXMuX2Z1bmN0aW9uID0gdmFsO1xuICAgICAgICBpZiAodGhpcy5fbGFzdExpc3QpIC8vIG90aGVyd2lzZSB0aGlzIHdpbGwgaGFwcGVuIGluIG5nQWZ0ZXJDb250ZW50SW5pdFxuICAgICAgICAgICAgdGhpcy5fbGlzdC5fc2V0RnVuY3Rpb24odmFsKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgZ2V0IF9saXN0KCk6IE1kY0xpc3REaXJlY3RpdmUge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGlzdFF1ZXJ5IS5maXJzdDtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pIF9vbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5mb3VuZGF0aW9uPy5oYW5kbGVLZXlkb3duKGV2ZW50KTtcbiAgICB9XG59XG5cbi8qKlxuICogXG4gKiAjIEFjY2Vzc2liaWxpdHlcbiAqIFxuICogKiBgRW50ZXJgLCBgU3BhY2VgLCBhbmQgYERvd24gQXJyb3dgIGtleXMgb3BlbiB0aGUgbWVudSBhbmQgcGxhY2UgZm9jdXMgb24gdGhlIGZpcnN0IGl0ZW0uXG4gKiAqIGBVcCBBcnJvd2Agb3BlbnMgdGhlIG1lbnUgYW5kIHBsYWNlcyBmb2N1cyBvbiB0aGUgbGFzdCBpdGVtXG4gKiAqIENsaWNrL1RvdWNoIGV2ZW50cyBzZXQgZm9jdXMgdG8gdGhlIG1kY0xpc3Qgcm9vdCBlbGVtZW50XG4gKiBcbiAqICogQXR0cmlidXRlIGByb2xlPWJ1dHRvbmAgd2lsbCBiZSBzZXQgaWYgdGhlIGVsZW1lbnQgaXMgbm90IGFscmVhZHkgYSBidXR0b24gZWxlbWVudC5cbiAqICogQXR0cmlidXRlIGBhcmlhLWhhc3BvcHVwPW1lbnVgIHdpbGwgYmUgc2V0IGlmIGFuIGBtZGNNZW51YCBpcyBhdHRhY2hlZC5cbiAqICogQXR0cmlidXRlIGBhcmlhLWV4cGFuZGVkYCB3aWxsIGJlIHNldCB3aGlsZSB0aGUgYXR0YWNoZWQgbWVudSBpcyBvcGVuXG4gKiAqIEF0dHJpYnV0ZSBgYXJpYS1jb250cm9sc2Agd2lsbCBiZSBzZXQgdG8gdGhlIGlkIG9mIHRoZSBhdHRhY2hlZCBtZW51LiAoQW5kIGEgdW5pcXVlIGlkIHdpbGwgYmUgZ2VuZXJhdGVkLFxuICogICBpZiBub25lIHdhcyBzZXQgb24gdGhlIG1lbnUpLlxuICogKiBgRW50ZXJgLCBgU3BhY2VgLCBhbmQgYERvd24tQXJyb3dgIHdpbGwgb3BlbiB0aGUgbWVudSB3aXRoIHRoZSBmaXJzdCBtZW51IGl0ZW0gZm9jdXNlZC5cbiAqICogYFVwLUFycm93YCB3aWxsIG9wZW4gdGhlIG1lbnUgd2l0aCB0aGUgbGFzdCBtZW51IGl0ZW0gZm9jdXNlZC5cbiAqICogTW91c2UvVG91Y2ggZXZlbnRzIHdpbGwgb3BlbiB0aGUgbWVudSB3aXRoIHRoZSBsaXN0IHJvb3QgZWxlbWVudCBmb2N1c2VkLiBUaGUgbGlzdCByb290IGVsZW1lbnRcbiAqICAgd2lsbCBoYW5kbGUga2V5Ym9hcmQgbmF2aWdhdGlvbiBvbmNlIGl0IHJlY2VpdmVzIGZvY3VzLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNNZW51VHJpZ2dlcl0nLFxufSlcbmV4cG9ydCBjbGFzcyBNZGNNZW51VHJpZ2dlckRpcmVjdGl2ZSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJykgX3JvbGU6IHN0cmluZyB8IG51bGwgPSAnYnV0dG9uJztcbiAgICBwcml2YXRlIF9tZGNNZW51VHJpZ2dlcjogTWRjTWVudURpcmVjdGl2ZSB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgZG93biA9IHtcbiAgICAgICAgZW50ZXI6IGZhbHNlLFxuICAgICAgICBzcGFjZTogZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihlbG06IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgaWYgKGVsbS5uYXRpdmVFbGVtZW50Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCVVRUT04nKVxuICAgICAgICAgICAgdGhpcy5fcm9sZSA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJykgb25DbGljaygpIHtcbiAgICAgICAgaWYgKHRoaXMuZG93bi5lbnRlciB8fCB0aGlzLmRvd24uc3BhY2UpXG4gICAgICAgICAgICB0aGlzLl9tZGNNZW51VHJpZ2dlcj8ub3BlbkFuZEZvY3VzKEZvY3VzT25PcGVuLmZpcnN0KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5fbWRjTWVudVRyaWdnZXI/Lm9wZW5BbmRGb2N1cyhGb2N1c09uT3Blbi5yb290KTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLnNldERvd24oZXZlbnQsIHRydWUpO1xuICAgICAgICBjb25zdCB7a2V5LCBrZXlDb2RlfSA9IGV2ZW50O1xuICAgICAgICBpZiAoa2V5ID09PSAnQXJyb3dVcCcgfHwga2V5Q29kZSA9PT0gMzgpXG4gICAgICAgICAgICB0aGlzLl9tZGNNZW51VHJpZ2dlcj8ub3BlbkFuZEZvY3VzKEZvY3VzT25PcGVuLmxhc3QpO1xuICAgICAgICBlbHNlIGlmIChrZXkgPT09ICdBcnJvd0Rvd24nIHx8IGtleUNvZGUgPT09IDQwKVxuICAgICAgICAgICAgdGhpcy5fbWRjTWVudVRyaWdnZXI/Lm9wZW5BbmRGb2N1cyhGb2N1c09uT3Blbi5maXJzdCk7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2tleXVwJywgWyckZXZlbnQnXSkgb25LZXl1cChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLnNldERvd24oZXZlbnQsIGZhbHNlKTtcbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtaGFzcG9wdXAnKSBnZXQgX2hhc1BvcHVwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWRjTWVudVRyaWdnZXIgPyAnbWVudScgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1leHBhbmRlZCcpIGdldCBfZXhwYW5kZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZGNNZW51VHJpZ2dlcj8ub3BlbiA/ICd0cnVlJyA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5hcmlhLWNvbnRyb2xzJykgZ2V0IF9hcmlhQ29udHJvbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tZGNNZW51VHJpZ2dlcj8uaWQ7XG4gICAgfVxuXG4gICAgQElucHV0KCkgZ2V0IG1kY01lbnVUcmlnZ2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWRjTWVudVRyaWdnZXI7XG4gICAgfVxuXG4gICAgc2V0IG1kY01lbnVUcmlnZ2VyKHZhbHVlOiBNZGNNZW51RGlyZWN0aXZlIHwgbnVsbCkge1xuICAgICAgICBpZiAodmFsdWUgJiYgdmFsdWUub3BlbkFuZEZvY3VzKVxuICAgICAgICAgICAgdGhpcy5fbWRjTWVudVRyaWdnZXIgPSB2YWx1ZTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5fbWRjTWVudVRyaWdnZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0RG93bihldmVudDogS2V5Ym9hcmRFdmVudCwgaXNEb3duOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IHtrZXksIGtleUNvZGV9ID0gZXZlbnQ7XG4gICAgICAgIGlmIChrZXkgPT09ICdFbnRlcicgfHwga2V5Q29kZSA9PT0gMTMpXG4gICAgICAgICAgICB0aGlzLmRvd24uZW50ZXIgPSBpc0Rvd247XG4gICAgICAgIGVsc2UgaWYgKGtleSA9PT0gJ1NwYWNlJyB8fCBrZXlDb2RlID09PSAzMilcbiAgICAgICAgICAgIHRoaXMuZG93bi5zcGFjZSA9IGlzRG93bjtcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBNRU5VX0RJUkVDVElWRVMgPSBbXG4gICAgTWRjTWVudURpcmVjdGl2ZSwgTWRjTWVudVRyaWdnZXJEaXJlY3RpdmVcbl07XG4iXX0=