@seethelemurcricut/ngx-contextmenu
Version:
An Angular component to show a context menu on an arbitrary component
378 lines (377 loc) • 33.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { OverlayRef } from '@angular/cdk/overlay';
import { ChangeDetectorRef, Component, ElementRef, Inject, Input, Optional, Renderer2, ViewChild, ViewChildren, } from '@angular/core';
import { EventEmitter, Output, QueryList, HostListener } from '@angular/core';
import { Subscription } from 'rxjs';
import { CONTEXT_MENU_OPTIONS } from './contextMenu.tokens';
import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
/**
* @record
*/
export function ILinkConfig() { }
function ILinkConfig_tsickle_Closure_declarations() {
/** @type {?} */
ILinkConfig.prototype.click;
/** @type {?|undefined} */
ILinkConfig.prototype.enabled;
/** @type {?} */
ILinkConfig.prototype.html;
}
var /** @type {?} */ ARROW_LEFT_KEYCODE = 37;
var ContextMenuContentComponent = /** @class */ (function () {
function ContextMenuContentComponent(changeDetector, elementRef, options, renderer) {
this.changeDetector = changeDetector;
this.elementRef = elementRef;
this.options = options;
this.renderer = renderer;
this.menuItems = [];
this.isLeaf = false;
this.execute = new EventEmitter();
this.openSubMenu = new EventEmitter();
this.closeLeafMenu = new EventEmitter();
this.closeAllMenus = new EventEmitter();
this.autoFocus = false;
this.useBootstrap4 = false;
this.subscription = new Subscription();
if (options) {
this.autoFocus = options.autoFocus;
this.useBootstrap4 = options.useBootstrap4;
}
}
/**
* @return {?}
*/
ContextMenuContentComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
this.menuItems.forEach(function (menuItem) {
menuItem.currentItem = _this.item;
_this.subscription.add(menuItem.execute.subscribe(function (event) { return _this.execute.emit(tslib_1.__assign({}, event, { menuItem: menuItem })); }));
});
var /** @type {?} */ queryList = new QueryList();
queryList.reset(this.menuItems);
this._keyManager = new ActiveDescendantKeyManager(queryList).withWrap();
var /** @type {?} */ elementHeight = 14;
this.menuItems.forEach(function (inMenuItem) {
elementHeight += inMenuItem.divider ? 19 : 26;
});
(/** @type {?} */ (this.elementRef.nativeElement)).style.height = elementHeight + 'px';
};
/**
* @return {?}
*/
ContextMenuContentComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
if (this.autoFocus) {
setTimeout(function () { return _this.focus(); });
}
this.overlay.updatePosition();
};
/**
* @return {?}
*/
ContextMenuContentComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.subscription.unsubscribe();
};
/**
* @return {?}
*/
ContextMenuContentComponent.prototype.focus = /**
* @return {?}
*/
function () {
if (this.autoFocus) {
this.menuElement.nativeElement.focus();
}
};
/**
* @param {?} $event
* @return {?}
*/
ContextMenuContentComponent.prototype.stopEvent = /**
* @param {?} $event
* @return {?}
*/
function ($event) {
$event.stopPropagation();
};
/**
* @param {?} menuItem
* @return {?}
*/
ContextMenuContentComponent.prototype.isMenuItemEnabled = /**
* @param {?} menuItem
* @return {?}
*/
function (menuItem) {
return this.evaluateIfFunction(menuItem && menuItem.enabled);
};
/**
* @param {?} menuItem
* @return {?}
*/
ContextMenuContentComponent.prototype.isMenuItemVisible = /**
* @param {?} menuItem
* @return {?}
*/
function (menuItem) {
return this.evaluateIfFunction(menuItem && menuItem.visible);
};
/**
* @param {?} value
* @return {?}
*/
ContextMenuContentComponent.prototype.evaluateIfFunction = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (value instanceof Function) {
return value(this.item);
}
return value;
};
/**
* @param {?} link
* @return {?}
*/
ContextMenuContentComponent.prototype.isDisabled = /**
* @param {?} link
* @return {?}
*/
function (link) {
return link.enabled && !link.enabled(this.item);
};
/**
* @param {?} event
* @return {?}
*/
ContextMenuContentComponent.prototype.onKeyEvent = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (!this.isLeaf) {
return;
}
this._keyManager.onKeydown(event);
};
/**
* @param {?=} event
* @return {?}
*/
ContextMenuContentComponent.prototype.keyboardOpenSubMenu = /**
* @param {?=} event
* @return {?}
*/
function (event) {
if (!this.isLeaf) {
return;
}
this.cancelEvent(event);
var /** @type {?} */ menuItem = this.menuItems[this._keyManager.activeItemIndex];
if (menuItem) {
this.onOpenSubMenu(menuItem);
}
};
/**
* @param {?=} event
* @return {?}
*/
ContextMenuContentComponent.prototype.keyboardMenuItemSelect = /**
* @param {?=} event
* @return {?}
*/
function (event) {
if (!this.isLeaf) {
return;
}
this.cancelEvent(event);
var /** @type {?} */ menuItem = this.menuItems[this._keyManager.activeItemIndex];
if (menuItem) {
this.onMenuItemSelect(menuItem, event);
}
};
/**
* @param {?} event
* @return {?}
*/
ContextMenuContentComponent.prototype.onCloseLeafMenu = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (!this.isLeaf) {
return;
}
this.cancelEvent(event);
this.closeLeafMenu.emit({ exceptRootMenu: event.keyCode === ARROW_LEFT_KEYCODE, event: event });
};
/**
* @param {?} event
* @return {?}
*/
ContextMenuContentComponent.prototype.closeMenu = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event.type === 'click' && event.button === 2) {
return;
}
this.closeAllMenus.emit({ event: event });
};
/**
* @param {?} menuItem
* @param {?=} event
* @return {?}
*/
ContextMenuContentComponent.prototype.onOpenSubMenu = /**
* @param {?} menuItem
* @param {?=} event
* @return {?}
*/
function (menuItem, event) {
var /** @type {?} */ anchorElementRef = this.menuItemElements.toArray()[this._keyManager.activeItemIndex];
var /** @type {?} */ anchorElement = anchorElementRef && anchorElementRef.nativeElement;
this.openSubMenu.emit({
anchorElement: anchorElement,
contextMenu: menuItem.subMenu,
event: event,
item: this.item,
parentContextMenu: this,
});
};
/**
* @param {?} menuItem
* @param {?} event
* @return {?}
*/
ContextMenuContentComponent.prototype.onMenuItemSelect = /**
* @param {?} menuItem
* @param {?} event
* @return {?}
*/
function (menuItem, event) {
event.preventDefault();
event.stopPropagation();
this.onOpenSubMenu(menuItem, event);
if (!menuItem.subMenu) {
menuItem.triggerExecute(this.item, event);
}
};
/**
* @param {?} event
* @return {?}
*/
ContextMenuContentComponent.prototype.cancelEvent = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (!event) {
return;
}
var /** @type {?} */ target = event.target;
if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(target.tagName) > -1 || target.isContentEditable) {
return;
}
event.preventDefault();
event.stopPropagation();
};
ContextMenuContentComponent.decorators = [
{ type: Component, args: [{
selector: 'context-menu-content',
styles: [
".passive {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: normal;\n line-height: @line-height-base;\n white-space: nowrap;\n }\n .hasSubMenu:before {\n content: \"\u25B6\";\n float: right;\n }",
],
template: "<div class=\"dropdown open show ngx-contextmenu\" [ngClass]=\"menuClass\" tabindex=\"0\">\n <ul #menu class=\"dropdown-menu show\" style=\"position: static; float: none;\" tabindex=\"0\">\n <li #li *ngFor=\"let menuItem of menuItems; let i = index\" [class.disabled]=\"!isMenuItemEnabled(menuItem)\"\n [class.divider]=\"menuItem.divider\" [class.dropdown-divider]=\"useBootstrap4 && menuItem.divider\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [attr.role]=\"menuItem.divider ? 'separator' : undefined\">\n <a *ngIf=\"!menuItem.divider && !menuItem.passive\" href [class.dropdown-item]=\"useBootstrap4\"\n [class.active]=\"menuItem.isActive && isMenuItemEnabled(menuItem)\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\" [class.hasSubMenu]=\"!!menuItem.subMenu\"\n (click)=\"onMenuItemSelect(menuItem, $event)\" (mouseenter)=\"onOpenSubMenu(menuItem, $event)\">\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </a>\n\n <span (click)=\"stopEvent($event)\" (contextmenu)=\"stopEvent($event)\" class=\"passive\"\n *ngIf=\"!menuItem.divider && menuItem.passive\" [class.dropdown-item]=\"useBootstrap4\"\n [class.disabled]=\"useBootstrap4 && !isMenuItemEnabled(menuItem)\">\n <ng-template [ngTemplateOutlet]=\"menuItem.template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-template>\n </span>\n </li>\n </ul>\n </div>\n ",
},] },
];
/** @nocollapse */
ContextMenuContentComponent.ctorParameters = function () { return [
{ type: ChangeDetectorRef },
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CONTEXT_MENU_OPTIONS,] }] },
{ type: Renderer2 }
]; };
ContextMenuContentComponent.propDecorators = {
menuItems: [{ type: Input }],
item: [{ type: Input }],
event: [{ type: Input }],
parentContextMenu: [{ type: Input }],
menuClass: [{ type: Input }],
overlay: [{ type: Input }],
isLeaf: [{ type: Input }],
execute: [{ type: Output }],
openSubMenu: [{ type: Output }],
closeLeafMenu: [{ type: Output }],
closeAllMenus: [{ type: Output }],
menuElement: [{ type: ViewChild, args: ['menu',] }],
menuItemElements: [{ type: ViewChildren, args: ['li',] }],
onKeyEvent: [{ type: HostListener, args: ['window:keydown.ArrowDown', ['$event'],] }, { type: HostListener, args: ['window:keydown.ArrowUp', ['$event'],] }],
keyboardOpenSubMenu: [{ type: HostListener, args: ['window:keydown.ArrowRight', ['$event'],] }],
keyboardMenuItemSelect: [{ type: HostListener, args: ['window:keydown.Enter', ['$event'],] }, { type: HostListener, args: ['window:keydown.Space', ['$event'],] }],
onCloseLeafMenu: [{ type: HostListener, args: ['window:keydown.Escape', ['$event'],] }, { type: HostListener, args: ['window:keydown.ArrowLeft', ['$event'],] }],
closeMenu: [{ type: HostListener, args: ['document:click', ['$event'],] }, { type: HostListener, args: ['document:contextmenu', ['$event'],] }]
};
return ContextMenuContentComponent;
}());
export { ContextMenuContentComponent };
function ContextMenuContentComponent_tsickle_Closure_declarations() {
/** @type {?} */
ContextMenuContentComponent.prototype.menuItems;
/** @type {?} */
ContextMenuContentComponent.prototype.item;
/** @type {?} */
ContextMenuContentComponent.prototype.event;
/** @type {?} */
ContextMenuContentComponent.prototype.parentContextMenu;
/** @type {?} */
ContextMenuContentComponent.prototype.menuClass;
/** @type {?} */
ContextMenuContentComponent.prototype.overlay;
/** @type {?} */
ContextMenuContentComponent.prototype.isLeaf;
/** @type {?} */
ContextMenuContentComponent.prototype.execute;
/** @type {?} */
ContextMenuContentComponent.prototype.openSubMenu;
/** @type {?} */
ContextMenuContentComponent.prototype.closeLeafMenu;
/** @type {?} */
ContextMenuContentComponent.prototype.closeAllMenus;
/** @type {?} */
ContextMenuContentComponent.prototype.menuElement;
/** @type {?} */
ContextMenuContentComponent.prototype.menuItemElements;
/** @type {?} */
ContextMenuContentComponent.prototype.autoFocus;
/** @type {?} */
ContextMenuContentComponent.prototype.useBootstrap4;
/** @type {?} */
ContextMenuContentComponent.prototype._keyManager;
/** @type {?} */
ContextMenuContentComponent.prototype.subscription;
/** @type {?} */
ContextMenuContentComponent.prototype.changeDetector;
/** @type {?} */
ContextMenuContentComponent.prototype.elementRef;
/** @type {?} */
ContextMenuContentComponent.prototype.options;
/** @type {?} */
ContextMenuContentComponent.prototype.renderer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BzZWV0aGVsZW11cmNyaWN1dC9uZ3gtY29udGV4dG1lbnUvIiwic291cmNlcyI6WyJsaWIvY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBRUgsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBQ1IsU0FBUyxFQUNULFNBQVMsRUFDVCxZQUFZLEdBQ2YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUlwQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7Ozs7Ozs7OztBQVEvRCxxQkFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUM7O0lBOEQ1QixxQ0FDVSxnQkFDQSxZQUU4QixPQUE0QixFQUMzRDtRQUpDLG1CQUFjLEdBQWQsY0FBYztRQUNkLGVBQVUsR0FBVixVQUFVO1FBRW9CLFlBQU8sR0FBUCxPQUFPLENBQXFCO1FBQzNELGFBQVEsR0FBUixRQUFRO3lCQXhCdUMsRUFBRTtzQkFNakMsS0FBSzt1QkFFMUIsSUFBSSxZQUFZLEVBQUU7MkJBQytDLElBQUksWUFBWSxFQUFFOzZCQUNwQixJQUFJLFlBQVksRUFBRTs2QkFDZixJQUFJLFlBQVksRUFBRTt5QkFJckUsS0FBSzs2QkFDRCxLQUFLOzRCQUVTLElBQUksWUFBWSxFQUFFO1FBUXJELEVBQUUsQ0FB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RmpCLFlBQVksU0FBQywwQkFBMEIsRUFBRSxDQUFDLFFBQVEsQ0FBQyxjQUNuRCxZQUFZLFNBQUMsd0JBQXdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7c0NBUWpELFlBQVksU0FBQywyQkFBMkIsRUFBRSxDQUFDLFFBQVEsQ0FBQzt5Q0FZcEQsWUFBWSxTQUFDLHNCQUFzQixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQy9DLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztrQ0FZL0MsWUFBWSxTQUFDLHVCQUF1QixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ2hELFlBQVksU0FBQywwQkFBMEIsRUFBRSxDQUFDLFFBQVEsQ0FBQzs0QkFTbkQsWUFBWSxTQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ3pDLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7c0NBbE5sRDs7U0FzRWEsMkJBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2xvc2VMZWFmTWVudUV2ZW50LCBJQ29udGV4dE1lbnVDbGlja0V2ZW50IH0gZnJvbSAnLi9jb250ZXh0TWVudS5zZXJ2aWNlJztcbmltcG9ydCB7IE92ZXJsYXlSZWYgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgSW5qZWN0LFxuICAgIElucHV0LFxuICAgIE9wdGlvbmFsLFxuICAgIFJlbmRlcmVyMixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUXVlcnlMaXN0LCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL2NvbnRleHRNZW51Lml0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IElDb250ZXh0TWVudU9wdGlvbnMgfSBmcm9tICcuL2NvbnRleHRNZW51Lm9wdGlvbnMnO1xuaW1wb3J0IHsgQ09OVEVYVF9NRU5VX09QVElPTlMgfSBmcm9tICcuL2NvbnRleHRNZW51LnRva2Vucyc7XG5pbXBvcnQgeyBBY3RpdmVEZXNjZW5kYW50S2V5TWFuYWdlciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcblxuZXhwb3J0IGludGVyZmFjZSBJTGlua0NvbmZpZyB7XG4gIGNsaWNrOiAoaXRlbTogYW55LCAkZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBlbmFibGVkPzogKGl0ZW06IGFueSkgPT4gYm9vbGVhbjtcbiAgaHRtbDogKGl0ZW06IGFueSkgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBBUlJPV19MRUZUX0tFWUNPREUgPSAzNztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY29udGV4dC1tZW51LWNvbnRlbnQnLFxuICBzdHlsZXM6IFtcbiAgICBgLnBhc3NpdmUge1xuICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgIHBhZGRpbmc6IDNweCAyMHB4O1xuICAgICAgIGNsZWFyOiBib3RoO1xuICAgICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgICAgbGluZS1oZWlnaHQ6IEBsaW5lLWhlaWdodC1iYXNlO1xuICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgIH1cbiAgICAuaGFzU3ViTWVudTpiZWZvcmUge1xuICAgICAgY29udGVudDogXCJcXHUyNUI2XCI7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgfWAsXG4gIF0sXG4gIHRlbXBsYXRlOlxuICBgPGRpdiBjbGFzcz1cImRyb3Bkb3duIG9wZW4gc2hvdyBuZ3gtY29udGV4dG1lbnVcIiBbbmdDbGFzc109XCJtZW51Q2xhc3NcIiB0YWJpbmRleD1cIjBcIj5cbiAgICAgIDx1bCAjbWVudSBjbGFzcz1cImRyb3Bkb3duLW1lbnUgc2hvd1wiIHN0eWxlPVwicG9zaXRpb246IHN0YXRpYzsgZmxvYXQ6IG5vbmU7XCIgdGFiaW5kZXg9XCIwXCI+XG4gICAgICAgIDxsaSAjbGkgKm5nRm9yPVwibGV0IG1lbnVJdGVtIG9mIG1lbnVJdGVtczsgbGV0IGkgPSBpbmRleFwiIFtjbGFzcy5kaXNhYmxlZF09XCIhaXNNZW51SXRlbUVuYWJsZWQobWVudUl0ZW0pXCJcbiAgICAgICAgICAgIFtjbGFzcy5kaXZpZGVyXT1cIm1lbnVJdGVtLmRpdmlkZXJcIiBbY2xhc3MuZHJvcGRvd24tZGl2aWRlcl09XCJ1c2VCb290c3RyYXA0ICYmIG1lbnVJdGVtLmRpdmlkZXJcIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJtZW51SXRlbS5pc0FjdGl2ZSAmJiBpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2F0dHIucm9sZV09XCJtZW51SXRlbS5kaXZpZGVyID8gJ3NlcGFyYXRvcicgOiB1bmRlZmluZWRcIj5cbiAgICAgICAgICA8YSAqbmdJZj1cIiFtZW51SXRlbS5kaXZpZGVyICYmICFtZW51SXRlbS5wYXNzaXZlXCIgaHJlZiBbY2xhc3MuZHJvcGRvd24taXRlbV09XCJ1c2VCb290c3RyYXA0XCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwibWVudUl0ZW0uaXNBY3RpdmUgJiYgaXNNZW51SXRlbUVuYWJsZWQobWVudUl0ZW0pXCJcbiAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJ1c2VCb290c3RyYXA0ICYmICFpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIiBbY2xhc3MuaGFzU3ViTWVudV09XCIhIW1lbnVJdGVtLnN1Yk1lbnVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW0sICRldmVudClcIiAobW91c2VlbnRlcik9XCJvbk9wZW5TdWJNZW51KG1lbnVJdGVtLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibWVudUl0ZW0udGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGl0ZW0gfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9hPlxuXG4gICAgICAgICAgPHNwYW4gKGNsaWNrKT1cInN0b3BFdmVudCgkZXZlbnQpXCIgKGNvbnRleHRtZW51KT1cInN0b3BFdmVudCgkZXZlbnQpXCIgY2xhc3M9XCJwYXNzaXZlXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cIiFtZW51SXRlbS5kaXZpZGVyICYmIG1lbnVJdGVtLnBhc3NpdmVcIiBbY2xhc3MuZHJvcGRvd24taXRlbV09XCJ1c2VCb290c3RyYXA0XCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuZGlzYWJsZWRdPVwidXNlQm9vdHN0cmFwNCAmJiAhaXNNZW51SXRlbUVuYWJsZWQobWVudUl0ZW0pXCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibWVudUl0ZW0udGVtcGxhdGVcIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyAkaW1wbGljaXQ6IGl0ZW0gfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2xpPlxuICAgICAgPC91bD5cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBwdWJsaWMgbWVudUl0ZW1zOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmVbXSA9IFtdO1xuICBASW5wdXQoKSBwdWJsaWMgaXRlbTogYW55O1xuICBASW5wdXQoKSBwdWJsaWMgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50O1xuICBASW5wdXQoKSBwdWJsaWMgcGFyZW50Q29udGV4dE1lbnU6IENvbnRleHRNZW51Q29udGVudENvbXBvbmVudDtcbiAgQElucHV0KCkgcHVibGljIG1lbnVDbGFzczogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgb3ZlcmxheTogT3ZlcmxheVJlZjtcbiAgQElucHV0KCkgcHVibGljIGlzTGVhZiA9IGZhbHNlO1xuICBAT3V0cHV0KCkgcHVibGljIGV4ZWN1dGU6IEV2ZW50RW1pdHRlcjx7IGV2ZW50OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCwgaXRlbTogYW55LCBtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlIH0+XG4gICAgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb3BlblN1Yk1lbnU6IEV2ZW50RW1pdHRlcjxJQ29udGV4dE1lbnVDbGlja0V2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBjbG9zZUxlYWZNZW51OiBFdmVudEVtaXR0ZXI8Q2xvc2VMZWFmTWVudUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBjbG9zZUFsbE1lbnVzOiBFdmVudEVtaXR0ZXI8eyBldmVudDogTW91c2VFdmVudCB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQFZpZXdDaGlsZCgnbWVudScpIHB1YmxpYyBtZW51RWxlbWVudDogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZHJlbignbGknKSBwdWJsaWMgbWVudUl0ZW1FbGVtZW50czogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xuXG4gIHB1YmxpYyBhdXRvRm9jdXMgPSBmYWxzZTtcbiAgcHVibGljIHVzZUJvb3RzdHJhcDQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfa2V5TWFuYWdlcjogQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXI8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPjtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChDT05URVhUX01FTlVfT1BUSU9OUykgcHJpdmF0ZSBvcHRpb25zOiBJQ29udGV4dE1lbnVPcHRpb25zLFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyLFxuICApIHtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgdGhpcy5hdXRvRm9jdXMgPSBvcHRpb25zLmF1dG9Gb2N1cztcbiAgICAgIHRoaXMudXNlQm9vdHN0cmFwNCA9IG9wdGlvbnMudXNlQm9vdHN0cmFwNDtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgIHRoaXMubWVudUl0ZW1zLmZvckVhY2goKG1lbnVJdGVtKSA9PiB7XG4gICAgICAgICAgbWVudUl0ZW0uY3VycmVudEl0ZW0gPSB0aGlzLml0ZW07XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKFxuICAgICAgICAgICAgICBtZW51SXRlbS5leGVjdXRlLnN1YnNjcmliZSgoZXZlbnQpID0+IHRoaXMuZXhlY3V0ZS5lbWl0KHsgLi4uZXZlbnQsIG1lbnVJdGVtIH0pKVxuICAgICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHF1ZXJ5TGlzdCA9IG5ldyBRdWVyeUxpc3Q8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPigpO1xuICAgICAgcXVlcnlMaXN0LnJlc2V0KHRoaXMubWVudUl0ZW1zKTtcbiAgICAgIHRoaXMuX2tleU1hbmFnZXIgPSBuZXcgQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXI8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPihcbiAgICAgICAgICBxdWVyeUxpc3RcbiAgICAgICkud2l0aFdyYXAoKTtcblxuICAgICAgbGV0IGVsZW1lbnRIZWlnaHQgPSAxNDtcblxuICAgICAgdGhpcy5tZW51SXRlbXMuZm9yRWFjaCgoaW5NZW51SXRlbSkgPT4ge1xuICAgICAgICAgIGVsZW1lbnRIZWlnaHQgKz0gaW5NZW51SXRlbS5kaXZpZGVyID8gMTkgOiAyNjtcbiAgICAgIH0pO1xuXG4gICAgICAodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLmhlaWdodCA9IGVsZW1lbnRIZWlnaHQgKyAncHgnO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGlmICh0aGlzLmF1dG9Gb2N1cykge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmZvY3VzKCkpO1xuICAgIH1cbiAgICB0aGlzLm92ZXJsYXkudXBkYXRlUG9zaXRpb24oKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBmb2N1cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMubWVudUVsZW1lbnQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIHN0b3BFdmVudCgkZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBwdWJsaWMgaXNNZW51SXRlbUVuYWJsZWQobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmV2YWx1YXRlSWZGdW5jdGlvbihtZW51SXRlbSAmJiBtZW51SXRlbS5lbmFibGVkKTtcbiAgfVxuXG4gIHB1YmxpYyBpc01lbnVJdGVtVmlzaWJsZShtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZXZhbHVhdGVJZkZ1bmN0aW9uKG1lbnVJdGVtICYmIG1lbnVJdGVtLnZpc2libGUpO1xuICB9XG5cbiAgcHVibGljIGV2YWx1YXRlSWZGdW5jdGlvbih2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgcmV0dXJuIHZhbHVlKHRoaXMuaXRlbSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBpc0Rpc2FibGVkKGxpbms6IElMaW5rQ29uZmlnKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGxpbmsuZW5hYmxlZCAmJiAhbGluay5lbmFibGVkKHRoaXMuaXRlbSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd0Rvd24nLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd1VwJywgWyckZXZlbnQnXSlcbiAgcHVibGljIG9uS2V5RXZlbnQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNMZWFmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2tleU1hbmFnZXIub25LZXlkb3duKGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXlkb3duLkFycm93UmlnaHQnLCBbJyRldmVudCddKVxuICBwdWJsaWMga2V5Ym9hcmRPcGVuU3ViTWVudShldmVudD86IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNMZWFmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY2FuY2VsRXZlbnQoZXZlbnQpO1xuICAgIGNvbnN0IG1lbnVJdGVtID0gdGhpcy5tZW51SXRlbXNbdGhpcy5fa2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXhdO1xuICAgIGlmIChtZW51SXRlbSkge1xuICAgICAgdGhpcy5vbk9wZW5TdWJNZW51KG1lbnVJdGVtKTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5FbnRlcicsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXlkb3duLlNwYWNlJywgWyckZXZlbnQnXSlcbiAgcHVibGljIGtleWJvYXJkTWVudUl0ZW1TZWxlY3QoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNhbmNlbEV2ZW50KGV2ZW50KTtcbiAgICBjb25zdCBtZW51SXRlbSA9IHRoaXMubWVudUl0ZW1zW3RoaXMuX2tleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4XTtcbiAgICBpZiAobWVudUl0ZW0pIHtcbiAgICAgIHRoaXMub25NZW51SXRlbVNlbGVjdChtZW51SXRlbSwgZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXlkb3duLkVzY2FwZScsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzprZXlkb3duLkFycm93TGVmdCcsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBvbkNsb3NlTGVhZk1lbnUoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNMZWFmKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY2FuY2VsRXZlbnQoZXZlbnQpO1xuICAgIHRoaXMuY2xvc2VMZWFmTWVudS5lbWl0KHsgZXhjZXB0Um9vdE1lbnU6IGV2ZW50LmtleUNvZGUgPT09IEFSUk9XX0xFRlRfS0VZQ09ERSwgZXZlbnQgfSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNvbnRleHRtZW51JywgWyckZXZlbnQnXSlcbiAgcHVibGljIGNsb3NlTWVudShldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC50eXBlID09PSAnY2xpY2snICYmIGV2ZW50LmJ1dHRvbiA9PT0gMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsb3NlQWxsTWVudXMuZW1pdCh7ZXZlbnR9KTtcbiAgfVxuXG4gIHB1YmxpYyBvbk9wZW5TdWJNZW51KG1lbnVJdGVtOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUsIGV2ZW50PzogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBhbmNob3JFbGVtZW50UmVmID0gdGhpcy5tZW51SXRlbUVsZW1lbnRzLnRvQXJyYXkoKVt0aGlzLl9rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleF07XG4gICAgY29uc3QgYW5jaG9yRWxlbWVudCA9IGFuY2hvckVsZW1lbnRSZWYgJiYgYW5jaG9yRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIHRoaXMub3BlblN1Yk1lbnUuZW1pdCh7XG4gICAgICBhbmNob3JFbGVtZW50LFxuICAgICAgY29udGV4dE1lbnU6IG1lbnVJdGVtLnN1Yk1lbnUsXG4gICAgICBldmVudCxcbiAgICAgIGl0ZW06IHRoaXMuaXRlbSxcbiAgICAgIHBhcmVudENvbnRleHRNZW51OiB0aGlzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSwgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm9uT3BlblN1Yk1lbnUobWVudUl0ZW0sIGV2ZW50KTtcbiAgICBpZiAoIW1lbnVJdGVtLnN1Yk1lbnUpIHtcbiAgICAgIG1lbnVJdGVtLnRyaWdnZXJFeGVjdXRlKHRoaXMuaXRlbSwgZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FuY2VsRXZlbnQoZXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0OiBIVE1MRWxlbWVudCA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAoWydJTlBVVCcsICdURVhUQVJFQScsICdTRUxFQ1QnXS5pbmRleE9mKHRhcmdldC50YWdOYW1lKSA+IC0xIHx8IHRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cbn1cbiJdfQ==