UNPKG

@avdbrink/ngx-contextmenu

Version:

An Angular component to show a context menu on an arbitrary component

353 lines (351 loc) 31.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import { OverlayRef } from '@angular/cdk/overlay'; import { ChangeDetectorRef, Component, ElementRef, Inject, Input, Optional, Renderer, 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; } const /** @type {?} */ ARROW_LEFT_KEYCODE = 37; export class ContextMenuContentComponent { /** * @param {?} changeDetector * @param {?} elementRef * @param {?} options * @param {?} renderer */ constructor(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.highlightParentItems = false; this.subscription = new Subscription(); if (options) { this.autoFocus = options.autoFocus; this.useBootstrap4 = options.useBootstrap4; this.highlightParentItems = options.highlightParentItems; } } /** * @return {?} */ ngOnInit() { this.menuItems.forEach(menuItem => { menuItem.currentItem = this.item; this.subscription.add(menuItem.execute.subscribe(event => this.execute.emit(Object.assign({}, event, { menuItem })))); }); const /** @type {?} */ queryList = new QueryList(); queryList.reset(this.menuItems); this._keyManager = new ActiveDescendantKeyManager(queryList).withWrap(); } /** * @return {?} */ ngAfterViewInit() { if (this.autoFocus) { setTimeout(() => this.focus()); } this.overlay.updatePosition(); } /** * @return {?} */ ngOnDestroy() { this.subscription.unsubscribe(); } /** * @return {?} */ focus() { if (this.autoFocus) { this.menuElement.nativeElement.focus(); } } /** * @param {?} $event * @return {?} */ stopEvent($event) { $event.stopPropagation(); } /** * @param {?} menuItem * @return {?} */ isMenuItemEnabled(menuItem) { return this.evaluateIfFunction(menuItem && menuItem.enabled); } /** * @param {?} menuItem * @return {?} */ isMenuItemVisible(menuItem) { return this.evaluateIfFunction(menuItem && menuItem.visible); } /** * @param {?} value * @return {?} */ evaluateIfFunction(value) { if (value instanceof Function) { return value(this.item); } return value; } /** * @param {?} link * @return {?} */ isDisabled(link) { return link.enabled && !link.enabled(this.item); } /** * @param {?} event * @return {?} */ onKeyEvent(event) { if (!this.isLeaf) { return; } this._keyManager.onKeydown(event); } /** * @param {?=} event * @return {?} */ keyboardOpenSubMenu(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); const /** @type {?} */ menuItem = this.menuItems[this._keyManager.activeItemIndex]; if (menuItem) { this.onOpenSubMenu(menuItem); } } /** * @param {?=} event * @return {?} */ keyboardMenuItemSelect(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); const /** @type {?} */ menuItem = this.menuItems[this._keyManager.activeItemIndex]; if (menuItem) { this.onMenuItemSelect(menuItem, event); } } /** * @param {?} event * @return {?} */ onCloseLeafMenu(event) { if (!this.isLeaf) { return; } this.cancelEvent(event); this.closeLeafMenu.emit({ exceptRootMenu: event.keyCode === ARROW_LEFT_KEYCODE, event }); } /** * @param {?} event * @return {?} */ closeMenu(event) { if (event.type === 'click' && event.button === 2) { return; } this.closeAllMenus.emit({ event }); } /** * @param {?} menuItem * @param {?=} event * @return {?} */ onOpenSubMenu(menuItem, event) { const /** @type {?} */ anchorElementRef = this.menuItemElements.toArray()[this._keyManager.activeItemIndex]; const /** @type {?} */ anchorElement = anchorElementRef && anchorElementRef.nativeElement; if (this.highlightParentItems) { this.menuItems.forEach(item => item.isActiveParent = (item === menuItem && menuItem.subMenu)); } this.openSubMenu.emit({ anchorElement, contextMenu: menuItem.subMenu, event, item: this.item, parentContextMenu: this, }); } /** * @param {?} menuItem * @param {?} event * @return {?} */ onMenuItemSelect(menuItem, event) { event.preventDefault(); event.stopPropagation(); this.onOpenSubMenu(menuItem, event); if (!menuItem.subMenu) { menuItem.triggerExecute(this.item, event); } } /** * @param {?} event * @return {?} */ cancelEvent(event) { if (!event) { return; } const /** @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 { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: @line-height-base; white-space: nowrap; } .hasSubMenu:before { content: "\u25B6"; float: right; } .activeParent { text-decoration: none; color: #262626; background-color: #f5f5f5; }`, ], template: `<div class="dropdown open show ngx-contextmenu" [ngClass]="menuClass" tabindex="0"> <ul #menu class="dropdown-menu show" style="position: static; float: none;" tabindex="0"> <li #li *ngFor="let menuItem of menuItems; let i = index" [class.disabled]="!isMenuItemEnabled(menuItem)" [class.divider]="menuItem.divider" [class.dropdown-divider]="useBootstrap4 && menuItem.divider" [class.active]="menuItem.isActive && isMenuItemEnabled(menuItem)" [attr.role]="menuItem.divider ? 'separator' : undefined"> <a *ngIf="!menuItem.divider && !menuItem.passive" href [class.dropdown-item]="useBootstrap4" [class.active]="menuItem.isActive && isMenuItemEnabled(menuItem)" [class.activeParent]="highlightParentItems && menuItem.isActiveParent && isMenuItemEnabled(menuItem)" [class.disabled]="useBootstrap4 && !isMenuItemEnabled(menuItem)" [class.hasSubMenu]="!!menuItem.subMenu" (click)="onMenuItemSelect(menuItem, $event)" (mouseenter)="onOpenSubMenu(menuItem, $event)"> <ng-template [ngTemplateOutlet]="menuItem.template" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template> </a> <span (click)="stopEvent($event)" (contextmenu)="stopEvent($event)" class="passive" *ngIf="!menuItem.divider && menuItem.passive" [class.dropdown-item]="useBootstrap4" [class.disabled]="useBootstrap4 && !isMenuItemEnabled(menuItem)"> <ng-template [ngTemplateOutlet]="menuItem.template" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template> </span> </li> </ul> </div> `, },] }, ]; /** @nocollapse */ ContextMenuContentComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: ElementRef }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CONTEXT_MENU_OPTIONS,] }] }, { type: Renderer } ]; 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'],] }] }; 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.highlightParentItems; /** @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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhdmRicmluay9uZ3gtY29udGV4dG1lbnUvIiwic291cmNlcyI6WyJsaWIvY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQ0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFFSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLFFBQVEsRUFDUixRQUFRLEVBQ1IsU0FBUyxFQUNULFlBQVksR0FDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFxQixNQUFNLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSXBDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7Ozs7Ozs7O0FBUS9ELHVCQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQWdEOUIsTUFBTTs7Ozs7OztJQXFCSixZQUNVLGdCQUNBLFlBRThCLE9BQTRCLEVBQzNEO1FBSkMsbUJBQWMsR0FBZCxjQUFjO1FBQ2QsZUFBVSxHQUFWLFVBQVU7UUFFb0IsWUFBTyxHQUFQLE9BQU8sQ0FBcUI7UUFDM0QsYUFBUSxHQUFSLFFBQVE7eUJBekJ1QyxFQUFFO3NCQU1qQyxLQUFLO3VCQUUxQixJQUFJLFlBQVksRUFBRTsyQkFDK0MsSUFBSSxZQUFZLEVBQUU7NkJBQ3BCLElBQUksWUFBWSxFQUFFOzZCQUNmLElBQUksWUFBWSxFQUFFO3lCQUlyRSxLQUFLOzZCQUNELEtBQUs7b0NBQ0UsS0FBSzs0QkFFRSxJQUFJLFlBQVksRUFB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QUFFLENBQUMsUUFBUSxDQUFDLGNBQy9DLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQzs4QkFZL0MsWUFBWSxTQUFDLHVCQUF1QixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ2hELFlBQVksU0FBQywwQkFBMEIsRUFBRSxDQUFDLFFBQVEsQ0FBQzt3QkFTbkQsWUFBWSxTQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ3pDLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsb3NlTGVhZk1lbnVFdmVudCwgSUNvbnRleHRNZW51Q2xpY2tFdmVudCB9IGZyb20gJy4vY29udGV4dE1lbnUuc2VydmljZSc7XG5pbXBvcnQgeyBPdmVybGF5UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEluamVjdCxcbiAgICBJbnB1dCxcbiAgICBPcHRpb25hbCxcbiAgICBSZW5kZXJlcixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUXVlcnlMaXN0LCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL2NvbnRleHRNZW51Lml0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IElDb250ZXh0TWVudU9wdGlvbnMgfSBmcm9tICcuL2NvbnRleHRNZW51Lm9wdGlvbnMnO1xuaW1wb3J0IHsgQ09OVEVYVF9NRU5VX09QVElPTlMgfSBmcm9tICcuL2NvbnRleHRNZW51LnRva2Vucyc7XG5pbXBvcnQgeyBBY3RpdmVEZXNjZW5kYW50S2V5TWFuYWdlciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcblxuZXhwb3J0IGludGVyZmFjZSBJTGlua0NvbmZpZyB7XG4gIGNsaWNrOiAoaXRlbTogYW55LCAkZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBlbmFibGVkPzogKGl0ZW06IGFueSkgPT4gYm9vbGVhbjtcbiAgaHRtbDogKGl0ZW06IGFueSkgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBBUlJPV19MRUZUX0tFWUNPREUgPSAzNztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY29udGV4dC1tZW51LWNvbnRlbnQnLFxuICBzdHlsZXM6IFtcbiAgICBgLnBhc3NpdmUge1xuICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgIHBhZGRpbmc6IDNweCAyMHB4O1xuICAgICAgIGNsZWFyOiBib3RoO1xuICAgICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgICAgbGluZS1oZWlnaHQ6IEBsaW5lLWhlaWdodC1iYXNlO1xuICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgIH1cbiAgICAuaGFzU3ViTWVudTpiZWZvcmUge1xuICAgICAgY29udGVudDogXCJcXHUyNUI2XCI7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgfVxuICAgIC5hY3RpdmVQYXJlbnQge1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICAgIGNvbG9yOiAjMjYyNjI2O1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjVmNTtcbiAgICB9YCxcbiAgXSxcbiAgdGVtcGxhdGU6XG4gIGA8ZGl2IGNsYXNzPVwiZHJvcGRvd24gb3BlbiBzaG93IG5neC1jb250ZXh0bWVudVwiIFtuZ0NsYXNzXT1cIm1lbnVDbGFzc1wiIHRhYmluZGV4PVwiMFwiPlxuICAgICAgPHVsICNtZW51IGNsYXNzPVwiZHJvcGRvd24tbWVudSBzaG93XCIgc3R5bGU9XCJwb3NpdGlvbjogc3RhdGljOyBmbG9hdDogbm9uZTtcIiB0YWJpbmRleD1cIjBcIj5cbiAgICAgICAgPGxpICNsaSAqbmdGb3I9XCJsZXQgbWVudUl0ZW0gb2YgbWVudUl0ZW1zOyBsZXQgaSA9IGluZGV4XCIgW2NsYXNzLmRpc2FibGVkXT1cIiFpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmRpdmlkZXJdPVwibWVudUl0ZW0uZGl2aWRlclwiIFtjbGFzcy5kcm9wZG93bi1kaXZpZGVyXT1cInVzZUJvb3RzdHJhcDQgJiYgbWVudUl0ZW0uZGl2aWRlclwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIm1lbnVJdGVtLmlzQWN0aXZlICYmIGlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtKVwiXG4gICAgICAgICAgICBbYXR0ci5yb2xlXT1cIm1lbnVJdGVtLmRpdmlkZXIgPyAnc2VwYXJhdG9yJyA6IHVuZGVmaW5lZFwiPlxuICAgICAgICAgIDxhICpuZ0lmPVwiIW1lbnVJdGVtLmRpdmlkZXIgJiYgIW1lbnVJdGVtLnBhc3NpdmVcIiBocmVmIFtjbGFzcy5kcm9wZG93bi1pdGVtXT1cInVzZUJvb3RzdHJhcDRcIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJtZW51SXRlbS5pc0FjdGl2ZSAmJiBpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZVBhcmVudF09XCJoaWdobGlnaHRQYXJlbnRJdGVtcyAmJiBtZW51SXRlbS5pc0FjdGl2ZVBhcmVudCAmJiBpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cInVzZUJvb3RzdHJhcDQgJiYgIWlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtKVwiIFtjbGFzcy5oYXNTdWJNZW51XT1cIiEhbWVudUl0ZW0uc3ViTWVudVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25NZW51SXRlbVNlbGVjdChtZW51SXRlbSwgJGV2ZW50KVwiIChtb3VzZWVudGVyKT1cIm9uT3BlblN1Yk1lbnUobWVudUl0ZW0sICRldmVudClcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJtZW51SXRlbS50ZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L2E+XG5cbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwic3RvcEV2ZW50KCRldmVudClcIiAoY29udGV4dG1lbnUpPVwic3RvcEV2ZW50KCRldmVudClcIiBjbGFzcz1cInBhc3NpdmVcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiIW1lbnVJdGVtLmRpdmlkZXIgJiYgbWVudUl0ZW0ucGFzc2l2ZVwiIFtjbGFzcy5kcm9wZG93bi1pdGVtXT1cInVzZUJvb3RzdHJhcDRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJ1c2VCb290c3RyYXA0ICYmICFpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJtZW51SXRlbS50ZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB7XG4gIEBJbnB1dCgpIHB1YmxpYyBtZW51SXRlbXM6IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZVtdID0gW107XG4gIEBJbnB1dCgpIHB1YmxpYyBpdGVtOiBhbnk7XG4gIEBJbnB1dCgpIHB1YmxpYyBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG4gIEBJbnB1dCgpIHB1YmxpYyBwYXJlbnRDb250ZXh0TWVudTogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50O1xuICBASW5wdXQoKSBwdWJsaWMgbWVudUNsYXNzOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBvdmVybGF5OiBPdmVybGF5UmVmO1xuICBASW5wdXQoKSBwdWJsaWMgaXNMZWFmID0gZmFsc2U7XG4gIEBPdXRwdXQoKSBwdWJsaWMgZXhlY3V0ZTogRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LCBpdGVtOiBhbnksIG1lbnVJdGVtOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfT5cbiAgICA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvcGVuU3ViTWVudTogRXZlbnRFbWl0dGVyPElDb250ZXh0TWVudUNsaWNrRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIGNsb3NlTGVhZk1lbnU6IEV2ZW50RW1pdHRlcjxDbG9zZUxlYWZNZW51RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIGNsb3NlQWxsTWVudXM6IEV2ZW50RW1pdHRlcjx7IGV2ZW50OiBNb3VzZUV2ZW50IH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAVmlld0NoaWxkKCdtZW51JykgcHVibGljIG1lbnVFbGVtZW50OiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkcmVuKCdsaScpIHB1YmxpYyBtZW51SXRlbUVsZW1lbnRzOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG5cbiAgcHVibGljIGF1dG9Gb2N1cyA9IGZhbHNlO1xuICBwdWJsaWMgdXNlQm9vdHN0cmFwNCA9IGZhbHNlO1xuICBwdWJsaWMgaGlnaGxpZ2h0UGFyZW50SXRlbXMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfa2V5TWFuYWdlcjogQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXI8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPjtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChDT05URVhUX01FTlVfT1BUSU9OUykgcHJpdmF0ZSBvcHRpb25zOiBJQ29udGV4dE1lbnVPcHRpb25zLFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIsXG4gICkge1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLmF1dG9Gb2N1cyA9IG9wdGlvbnMuYXV0b0ZvY3VzO1xuICAgICAgdGhpcy51c2VCb290c3RyYXA0ID0gb3B0aW9ucy51c2VCb290c3RyYXA0O1xuICAgICAgdGhpcy5oaWdobGlnaHRQYXJlbnRJdGVtcyA9IG9wdGlvbnMuaGlnaGxpZ2h0UGFyZW50SXRlbXM7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5tZW51SXRlbXMuZm9yRWFjaChtZW51SXRlbSA9PiB7XG4gICAgICBtZW51SXRlbS5jdXJyZW50SXRlbSA9IHRoaXMuaXRlbTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChtZW51SXRlbS5leGVjdXRlLnN1YnNjcmliZShldmVudCA9PiB0aGlzLmV4ZWN1dGUuZW1pdCh7IC4uLmV2ZW50LCBtZW51SXRlbSB9KSkpO1xuICAgIH0pO1xuICAgIGNvbnN0IHF1ZXJ5TGlzdCA9IG5ldyBRdWVyeUxpc3Q8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPigpO1xuICAgIHF1ZXJ5TGlzdC5yZXNldCh0aGlzLm1lbnVJdGVtcyk7XG4gICAgdGhpcy5fa2V5TWFuYWdlciA9IG5ldyBBY3RpdmVEZXNjZW5kYW50S2V5TWFuYWdlcjxDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmU+KHF1ZXJ5TGlzdCkud2l0aFdyYXAoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5hdXRvRm9jdXMpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5mb2N1cygpKTtcbiAgICB9XG4gICAgdGhpcy5vdmVybGF5LnVwZGF0ZVBvc2l0aW9uKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgZm9jdXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXV0b0ZvY3VzKSB7XG4gICAgICB0aGlzLm1lbnVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBzdG9wRXZlbnQoJGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHVibGljIGlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5ldmFsdWF0ZUlmRnVuY3Rpb24obWVudUl0ZW0gJiYgbWVudUl0ZW0uZW5hYmxlZCk7XG4gIH1cblxuICBwdWJsaWMgaXNNZW51SXRlbVZpc2libGUobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmV2YWx1YXRlSWZGdW5jdGlvbihtZW51SXRlbSAmJiBtZW51SXRlbS52aXNpYmxlKTtcbiAgfVxuXG4gIHB1YmxpYyBldmFsdWF0ZUlmRnVuY3Rpb24odmFsdWU6IGFueSk6IGFueSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHJldHVybiB2YWx1ZSh0aGlzLml0ZW0pO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgaXNEaXNhYmxlZChsaW5rOiBJTGlua0NvbmZpZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBsaW5rLmVuYWJsZWQgJiYgIWxpbmsuZW5hYmxlZCh0aGlzLml0ZW0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uQXJyb3dEb3duJywgWyckZXZlbnQnXSlcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uQXJyb3dVcCcsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBvbktleUV2ZW50KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9rZXlNYW5hZ2VyLm9uS2V5ZG93bihldmVudCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd1JpZ2h0JywgWyckZXZlbnQnXSlcbiAgcHVibGljIGtleWJvYXJkT3BlblN1Yk1lbnUoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNhbmNlbEV2ZW50KGV2ZW50KTtcbiAgICBjb25zdCBtZW51SXRlbSA9IHRoaXMubWVudUl0ZW1zW3RoaXMuX2tleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4XTtcbiAgICBpZiAobWVudUl0ZW0pIHtcbiAgICAgIHRoaXMub25PcGVuU3ViTWVudShtZW51SXRlbSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uRW50ZXInLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5TcGFjZScsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBrZXlib2FyZE1lbnVJdGVtU2VsZWN0KGV2ZW50PzogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0xlYWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jYW5jZWxFdmVudChldmVudCk7XG4gICAgY29uc3QgbWVudUl0ZW0gPSB0aGlzLm1lbnVJdGVtc1t0aGlzLl9rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleF07XG4gICAgaWYgKG1lbnVJdGVtKSB7XG4gICAgICB0aGlzLm9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW0sIGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5Fc2NhcGUnLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd0xlZnQnLCBbJyRldmVudCddKVxuICBwdWJsaWMgb25DbG9zZUxlYWZNZW51KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNhbmNlbEV2ZW50KGV2ZW50KTtcbiAgICB0aGlzLmNsb3NlTGVhZk1lbnUuZW1pdCh7IGV4Y2VwdFJvb3RNZW51OiBldmVudC5rZXlDb2RlID09PSBBUlJPV19MRUZUX0tFWUNPREUsIGV2ZW50IH0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjb250ZXh0bWVudScsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBjbG9zZU1lbnUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2NsaWNrJyAmJiBldmVudC5idXR0b24gPT09IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jbG9zZUFsbE1lbnVzLmVtaXQoe2V2ZW50fSk7XG4gIH1cblxuICBwdWJsaWMgb25PcGVuU3ViTWVudShtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlLCBldmVudD86IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgYW5jaG9yRWxlbWVudFJlZiA9IHRoaXMubWVudUl0ZW1FbGVtZW50cy50b0FycmF5KClbdGhpcy5fa2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXhdO1xuICAgIGNvbnN0IGFuY2hvckVsZW1lbnQgPSBhbmNob3JFbGVtZW50UmVmICYmIGFuY2hvckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBpZiAodGhpcy5oaWdobGlnaHRQYXJlbnRJdGVtcykgeyBcbiAgICAgIHRoaXMubWVudUl0ZW1zLmZvckVhY2goaXRlbSA9PiBpdGVtLmlzQWN0aXZlUGFyZW50ID0gKGl0ZW0gPT09IG1lbnVJdGVtICYmIG1lbnVJdGVtLnN1Yk1lbnUpICk7XG4gICAgfVxuICAgIHRoaXMub3BlblN1Yk1lbnUuZW1pdCh7XG4gICAgICBhbmNob3JFbGVtZW50LFxuICAgICAgY29udGV4dE1lbnU6IG1lbnVJdGVtLnN1Yk1lbnUsXG4gICAgICBldmVudCxcbiAgICAgIGl0ZW06IHRoaXMuaXRlbSxcbiAgICAgIHBhcmVudENvbnRleHRNZW51OiB0aGlzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSwgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm9uT3BlblN1Yk1lbnUobWVudUl0ZW0sIGV2ZW50KTtcbiAgICBpZiAoIW1lbnVJdGVtLnN1Yk1lbnUpIHtcbiAgICAgIG1lbnVJdGVtLnRyaWdnZXJFeGVjdXRlKHRoaXMuaXRlbSwgZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FuY2VsRXZlbnQoZXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0OiBIVE1MRWxlbWVudCA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAoWydJTlBVVCcsICdURVhUQVJFQScsICdTRUxFQ1QnXS5pbmRleE9mKHRhcmdldC50YWdOYW1lKSA+IC0xIHx8IHRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cbn1cbiJdfQ==