@avdbrink/ngx-contextmenu
Version:
An Angular component to show a context menu on an arbitrary component
353 lines (351 loc) • 31.7 kB
JavaScript
/**
* @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: -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BhdmRicmluay9uZ3gtY29udGV4dG1lbnUvIiwic291cmNlcyI6WyJsaWIvY29udGV4dE1lbnVDb250ZW50LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQ0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFFSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLFFBQVEsRUFDUixRQUFRLEVBQ1IsU0FBUyxFQUNULFlBQVksR0FDZixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFxQixNQUFNLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSXBDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzVELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7Ozs7Ozs7O0FBUS9ELHVCQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQWdEOUIsTUFBTTs7Ozs7OztJQXFCSixZQUNVLGdCQUNBLFlBRThCLE9BQTRCLEVBQzNEO1FBSkMsbUJBQWMsR0FBZCxjQUFjO1FBQ2QsZUFBVSxHQUFWLFVBQVU7UUFFb0IsWUFBTyxHQUFQLE9BQU8sQ0FBcUI7UUFDM0QsYUFBUSxHQUFSLFFBQVE7eUJBekJ1QyxFQUFFO3NCQU1qQyxLQUFLO3VCQUUxQixJQUFJLFlBQVksRUFBRTsyQkFDK0MsSUFBSSxZQUFZLEVBQUU7NkJBQ3BCLElBQUksWUFBWSxFQUFFOzZCQUNmLElBQUksWUFBWSxFQUFFO3lCQUlyRSxLQUFLOzZCQUNELEtBQUs7b0NBQ0UsS0FBSzs0QkFFRSxJQUFJLFlBQVksRUFBRTtRQVFyRCxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ1osSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQ25DLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztZQUMzQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1NBQzFEO0tBQ0Y7Ozs7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUU7WUFDaEMsUUFBUSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLG1CQUFNLEtBQUssSUFBRSxRQUFRLElBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdkcsQ0FBQyxDQUFDO1FBQ0gsdUJBQU0sU0FBUyxHQUFHLElBQUksU0FBUyxFQUE0QixDQUFDO1FBQzVELFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSwwQkFBMEIsQ0FBMkIsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7S0FDbkc7Ozs7SUFFRCxlQUFlO1FBQ2IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDbkIsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1NBQ2hDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztLQUMvQjs7OztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0tBQ2pDOzs7O0lBRUQsS0FBSztRQUNILEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ25CLElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3hDO0tBQ0Y7Ozs7O0lBRUQsU0FBUyxDQUFDLE1BQWtCO1FBQzFCLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztLQUMxQjs7Ozs7SUFFTSxpQkFBaUIsQ0FBQyxRQUFrQztRQUN6RCxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7Ozs7OztJQUd4RCxpQkFBaUIsQ0FBQyxRQUFrQztRQUN6RCxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7Ozs7OztJQUd4RCxrQkFBa0IsQ0FBQyxLQUFVO1FBQ2xDLEVBQUUsQ0FBQyxDQUFDLEtBQUssWUFBWSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3pCO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQzs7Ozs7O0lBR1IsVUFBVSxDQUFDLElBQWlCO1FBQ2pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Ozs7OztJQUszQyxVQUFVLENBQUMsS0FBb0I7UUFDcEMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUNqQixNQUFNLENBQUM7U0FDUjtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ25DOzs7OztJQUdNLG1CQUFtQixDQUFDLEtBQXFCO1FBQzlDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDakIsTUFBTSxDQUFDO1NBQ1I7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLHVCQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbEUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNiLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7U0FDOUI7S0FDRjs7Ozs7SUFJTSxzQkFBc0IsQ0FBQyxLQUFxQjtRQUNqRCxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sQ0FBQztTQUNSO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN4Qix1QkFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDYixJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3hDO0tBQ0Y7Ozs7O0lBSU0sZUFBZSxDQUFDLEtBQW9CO1FBQ3pDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDakIsTUFBTSxDQUFDO1NBQ1I7UUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsY0FBYyxFQUFFLEtBQUssQ0FBQyxPQUFPLEtBQUssa0JBQWtCLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztLQUMxRjs7Ozs7SUFJTSxTQUFTLENBQUMsS0FBaUI7UUFDaEMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pELE1BQU0sQ0FBQztTQUNSO1FBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBQyxLQUFLLEVBQUMsQ0FBQyxDQUFDO0tBQ2xDOzs7Ozs7SUFFTSxhQUFhLENBQUMsUUFBa0MsRUFBRSxLQUFrQztRQUN6Rix1QkFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzRix1QkFBTSxhQUFhLEdBQUcsZ0JBQWdCLElBQUksZ0JBQWdCLENBQUMsYUFBYSxDQUFDO1FBQ3pFLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUUsQ0FBQztTQUNoRztRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO1lBQ3BCLGFBQWE7WUFDYixXQUFXLEVBQUUsUUFBUSxDQUFDLE9BQU87WUFDN0IsS0FBSztZQUNMLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLGlCQUFpQixFQUFFLElBQUk7U0FDeEIsQ0FBQyxDQUFDOzs7Ozs7O0lBR0UsZ0JBQWdCLENBQUMsUUFBa0MsRUFBRSxLQUFpQztRQUMzRixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDdEIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzNDOzs7Ozs7SUFHSyxXQUFXLENBQUMsS0FBSztRQUN2QixFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDWCxNQUFNLENBQUM7U0FDUjtRQUVELHVCQUFNLE1BQU0sR0FBZ0IsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUN6QyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1lBQzdGLE1BQU0sQ0FBQztTQUNSO1FBRUQsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQzs7OztZQTNOM0IsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxzQkFBc0I7Z0JBQ2hDLE1BQU0sRUFBRTtvQkFDTjs7Ozs7Ozs7Ozs7Ozs7OztNQWdCRTtpQkFDSDtnQkFDRCxRQUFRLEVBQ1I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkM7YUFDRjs7OztZQXZFRyxpQkFBaUI7WUFFakIsVUFBVTs0Q0E4RlQsUUFBUSxZQUNSLE1BQU0sU0FBQyxvQkFBb0I7WUEzRjVCLFFBQVE7Ozt3QkFtRVQsS0FBSzttQkFDTCxLQUFLO29CQUNMLEtBQUs7Z0NBQ0wsS0FBSzt3QkFDTCxLQUFLO3NCQUNMLEtBQUs7cUJBQ0wsS0FBSztzQkFDTCxNQUFNOzBCQUVOLE1BQU07NEJBQ04sTUFBTTs0QkFDTixNQUFNOzBCQUNOLFNBQVMsU0FBQyxNQUFNOytCQUNoQixZQUFZLFNBQUMsSUFBSTt5QkF1RWpCLFlBQVksU0FBQywwQkFBMEIsRUFBRSxDQUFDLFFBQVEsQ0FBQyxjQUNuRCxZQUFZLFNBQUMsd0JBQXdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7a0NBUWpELFlBQVksU0FBQywyQkFBMkIsRUFBRSxDQUFDLFFBQVEsQ0FBQztxQ0FZcEQsWUFBWSxTQUFDLHNCQUFzQixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQy9DLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQzs4QkFZL0MsWUFBWSxTQUFDLHVCQUF1QixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ2hELFlBQVksU0FBQywwQkFBMEIsRUFBRSxDQUFDLFFBQVEsQ0FBQzt3QkFTbkQsWUFBWSxTQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDLGNBQ3pDLFlBQVksU0FBQyxzQkFBc0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsb3NlTGVhZk1lbnVFdmVudCwgSUNvbnRleHRNZW51Q2xpY2tFdmVudCB9IGZyb20gJy4vY29udGV4dE1lbnUuc2VydmljZSc7XG5pbXBvcnQgeyBPdmVybGF5UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEluamVjdCxcbiAgICBJbnB1dCxcbiAgICBPcHRpb25hbCxcbiAgICBSZW5kZXJlcixcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgT25EZXN0cm95LCBPbkluaXQsIE91dHB1dCwgUXVlcnlMaXN0LCBIb3N0TGlzdGVuZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfSBmcm9tICcuL2NvbnRleHRNZW51Lml0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IElDb250ZXh0TWVudU9wdGlvbnMgfSBmcm9tICcuL2NvbnRleHRNZW51Lm9wdGlvbnMnO1xuaW1wb3J0IHsgQ09OVEVYVF9NRU5VX09QVElPTlMgfSBmcm9tICcuL2NvbnRleHRNZW51LnRva2Vucyc7XG5pbXBvcnQgeyBBY3RpdmVEZXNjZW5kYW50S2V5TWFuYWdlciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcblxuZXhwb3J0IGludGVyZmFjZSBJTGlua0NvbmZpZyB7XG4gIGNsaWNrOiAoaXRlbTogYW55LCAkZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICBlbmFibGVkPzogKGl0ZW06IGFueSkgPT4gYm9vbGVhbjtcbiAgaHRtbDogKGl0ZW06IGFueSkgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBBUlJPV19MRUZUX0tFWUNPREUgPSAzNztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY29udGV4dC1tZW51LWNvbnRlbnQnLFxuICBzdHlsZXM6IFtcbiAgICBgLnBhc3NpdmUge1xuICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgIHBhZGRpbmc6IDNweCAyMHB4O1xuICAgICAgIGNsZWFyOiBib3RoO1xuICAgICAgIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gICAgICAgbGluZS1oZWlnaHQ6IEBsaW5lLWhlaWdodC1iYXNlO1xuICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgIH1cbiAgICAuaGFzU3ViTWVudTpiZWZvcmUge1xuICAgICAgY29udGVudDogXCJcXHUyNUI2XCI7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgfVxuICAgIC5hY3RpdmVQYXJlbnQge1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICAgIGNvbG9yOiAjMjYyNjI2O1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2Y1ZjVmNTtcbiAgICB9YCxcbiAgXSxcbiAgdGVtcGxhdGU6XG4gIGA8ZGl2IGNsYXNzPVwiZHJvcGRvd24gb3BlbiBzaG93IG5neC1jb250ZXh0bWVudVwiIFtuZ0NsYXNzXT1cIm1lbnVDbGFzc1wiIHRhYmluZGV4PVwiMFwiPlxuICAgICAgPHVsICNtZW51IGNsYXNzPVwiZHJvcGRvd24tbWVudSBzaG93XCIgc3R5bGU9XCJwb3NpdGlvbjogc3RhdGljOyBmbG9hdDogbm9uZTtcIiB0YWJpbmRleD1cIjBcIj5cbiAgICAgICAgPGxpICNsaSAqbmdGb3I9XCJsZXQgbWVudUl0ZW0gb2YgbWVudUl0ZW1zOyBsZXQgaSA9IGluZGV4XCIgW2NsYXNzLmRpc2FibGVkXT1cIiFpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmRpdmlkZXJdPVwibWVudUl0ZW0uZGl2aWRlclwiIFtjbGFzcy5kcm9wZG93bi1kaXZpZGVyXT1cInVzZUJvb3RzdHJhcDQgJiYgbWVudUl0ZW0uZGl2aWRlclwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIm1lbnVJdGVtLmlzQWN0aXZlICYmIGlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtKVwiXG4gICAgICAgICAgICBbYXR0ci5yb2xlXT1cIm1lbnVJdGVtLmRpdmlkZXIgPyAnc2VwYXJhdG9yJyA6IHVuZGVmaW5lZFwiPlxuICAgICAgICAgIDxhICpuZ0lmPVwiIW1lbnVJdGVtLmRpdmlkZXIgJiYgIW1lbnVJdGVtLnBhc3NpdmVcIiBocmVmIFtjbGFzcy5kcm9wZG93bi1pdGVtXT1cInVzZUJvb3RzdHJhcDRcIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJtZW51SXRlbS5pc0FjdGl2ZSAmJiBpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZVBhcmVudF09XCJoaWdobGlnaHRQYXJlbnRJdGVtcyAmJiBtZW51SXRlbS5pc0FjdGl2ZVBhcmVudCAmJiBpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIlxuICAgICAgICAgICAgW2NsYXNzLmRpc2FibGVkXT1cInVzZUJvb3RzdHJhcDQgJiYgIWlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtKVwiIFtjbGFzcy5oYXNTdWJNZW51XT1cIiEhbWVudUl0ZW0uc3ViTWVudVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25NZW51SXRlbVNlbGVjdChtZW51SXRlbSwgJGV2ZW50KVwiIChtb3VzZWVudGVyKT1cIm9uT3BlblN1Yk1lbnUobWVudUl0ZW0sICRldmVudClcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJtZW51SXRlbS50ZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L2E+XG5cbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwic3RvcEV2ZW50KCRldmVudClcIiAoY29udGV4dG1lbnUpPVwic3RvcEV2ZW50KCRldmVudClcIiBjbGFzcz1cInBhc3NpdmVcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiIW1lbnVJdGVtLmRpdmlkZXIgJiYgbWVudUl0ZW0ucGFzc2l2ZVwiIFtjbGFzcy5kcm9wZG93bi1pdGVtXT1cInVzZUJvb3RzdHJhcDRcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5kaXNhYmxlZF09XCJ1c2VCb290c3RyYXA0ICYmICFpc01lbnVJdGVtRW5hYmxlZChtZW51SXRlbSlcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJtZW51SXRlbS50ZW1wbGF0ZVwiIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBDb250ZXh0TWVudUNvbnRlbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB7XG4gIEBJbnB1dCgpIHB1YmxpYyBtZW51SXRlbXM6IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZVtdID0gW107XG4gIEBJbnB1dCgpIHB1YmxpYyBpdGVtOiBhbnk7XG4gIEBJbnB1dCgpIHB1YmxpYyBldmVudDogTW91c2VFdmVudCB8IEtleWJvYXJkRXZlbnQ7XG4gIEBJbnB1dCgpIHB1YmxpYyBwYXJlbnRDb250ZXh0TWVudTogQ29udGV4dE1lbnVDb250ZW50Q29tcG9uZW50O1xuICBASW5wdXQoKSBwdWJsaWMgbWVudUNsYXNzOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBvdmVybGF5OiBPdmVybGF5UmVmO1xuICBASW5wdXQoKSBwdWJsaWMgaXNMZWFmID0gZmFsc2U7XG4gIEBPdXRwdXQoKSBwdWJsaWMgZXhlY3V0ZTogRXZlbnRFbWl0dGVyPHsgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50LCBpdGVtOiBhbnksIG1lbnVJdGVtOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUgfT5cbiAgICA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvcGVuU3ViTWVudTogRXZlbnRFbWl0dGVyPElDb250ZXh0TWVudUNsaWNrRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIGNsb3NlTGVhZk1lbnU6IEV2ZW50RW1pdHRlcjxDbG9zZUxlYWZNZW51RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIGNsb3NlQWxsTWVudXM6IEV2ZW50RW1pdHRlcjx7IGV2ZW50OiBNb3VzZUV2ZW50IH0+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAVmlld0NoaWxkKCdtZW51JykgcHVibGljIG1lbnVFbGVtZW50OiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkcmVuKCdsaScpIHB1YmxpYyBtZW51SXRlbUVsZW1lbnRzOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG5cbiAgcHVibGljIGF1dG9Gb2N1cyA9IGZhbHNlO1xuICBwdWJsaWMgdXNlQm9vdHN0cmFwNCA9IGZhbHNlO1xuICBwdWJsaWMgaGlnaGxpZ2h0UGFyZW50SXRlbXMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfa2V5TWFuYWdlcjogQWN0aXZlRGVzY2VuZGFudEtleU1hbmFnZXI8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPjtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBPcHRpb25hbCgpXG4gICAgQEluamVjdChDT05URVhUX01FTlVfT1BUSU9OUykgcHJpdmF0ZSBvcHRpb25zOiBJQ29udGV4dE1lbnVPcHRpb25zLFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIsXG4gICkge1xuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICB0aGlzLmF1dG9Gb2N1cyA9IG9wdGlvbnMuYXV0b0ZvY3VzO1xuICAgICAgdGhpcy51c2VCb290c3RyYXA0ID0gb3B0aW9ucy51c2VCb290c3RyYXA0O1xuICAgICAgdGhpcy5oaWdobGlnaHRQYXJlbnRJdGVtcyA9IG9wdGlvbnMuaGlnaGxpZ2h0UGFyZW50SXRlbXM7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5tZW51SXRlbXMuZm9yRWFjaChtZW51SXRlbSA9PiB7XG4gICAgICBtZW51SXRlbS5jdXJyZW50SXRlbSA9IHRoaXMuaXRlbTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZChtZW51SXRlbS5leGVjdXRlLnN1YnNjcmliZShldmVudCA9PiB0aGlzLmV4ZWN1dGUuZW1pdCh7IC4uLmV2ZW50LCBtZW51SXRlbSB9KSkpO1xuICAgIH0pO1xuICAgIGNvbnN0IHF1ZXJ5TGlzdCA9IG5ldyBRdWVyeUxpc3Q8Q29udGV4dE1lbnVJdGVtRGlyZWN0aXZlPigpO1xuICAgIHF1ZXJ5TGlzdC5yZXNldCh0aGlzLm1lbnVJdGVtcyk7XG4gICAgdGhpcy5fa2V5TWFuYWdlciA9IG5ldyBBY3RpdmVEZXNjZW5kYW50S2V5TWFuYWdlcjxDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmU+KHF1ZXJ5TGlzdCkud2l0aFdyYXAoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAodGhpcy5hdXRvRm9jdXMpIHtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5mb2N1cygpKTtcbiAgICB9XG4gICAgdGhpcy5vdmVybGF5LnVwZGF0ZVBvc2l0aW9uKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgZm9jdXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXV0b0ZvY3VzKSB7XG4gICAgICB0aGlzLm1lbnVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBzdG9wRXZlbnQoJGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHVibGljIGlzTWVudUl0ZW1FbmFibGVkKG1lbnVJdGVtOiBDb250ZXh0TWVudUl0ZW1EaXJlY3RpdmUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5ldmFsdWF0ZUlmRnVuY3Rpb24obWVudUl0ZW0gJiYgbWVudUl0ZW0uZW5hYmxlZCk7XG4gIH1cblxuICBwdWJsaWMgaXNNZW51SXRlbVZpc2libGUobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmV2YWx1YXRlSWZGdW5jdGlvbihtZW51SXRlbSAmJiBtZW51SXRlbS52aXNpYmxlKTtcbiAgfVxuXG4gIHB1YmxpYyBldmFsdWF0ZUlmRnVuY3Rpb24odmFsdWU6IGFueSk6IGFueSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgIHJldHVybiB2YWx1ZSh0aGlzLml0ZW0pO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgaXNEaXNhYmxlZChsaW5rOiBJTGlua0NvbmZpZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBsaW5rLmVuYWJsZWQgJiYgIWxpbmsuZW5hYmxlZCh0aGlzLml0ZW0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uQXJyb3dEb3duJywgWyckZXZlbnQnXSlcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uQXJyb3dVcCcsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBvbktleUV2ZW50KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9rZXlNYW5hZ2VyLm9uS2V5ZG93bihldmVudCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd1JpZ2h0JywgWyckZXZlbnQnXSlcbiAgcHVibGljIGtleWJvYXJkT3BlblN1Yk1lbnUoZXZlbnQ/OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNhbmNlbEV2ZW50KGV2ZW50KTtcbiAgICBjb25zdCBtZW51SXRlbSA9IHRoaXMubWVudUl0ZW1zW3RoaXMuX2tleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4XTtcbiAgICBpZiAobWVudUl0ZW0pIHtcbiAgICAgIHRoaXMub25PcGVuU3ViTWVudShtZW51SXRlbSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmtleWRvd24uRW50ZXInLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5TcGFjZScsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBrZXlib2FyZE1lbnVJdGVtU2VsZWN0KGV2ZW50PzogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0xlYWYpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jYW5jZWxFdmVudChldmVudCk7XG4gICAgY29uc3QgbWVudUl0ZW0gPSB0aGlzLm1lbnVJdGVtc1t0aGlzLl9rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleF07XG4gICAgaWYgKG1lbnVJdGVtKSB7XG4gICAgICB0aGlzLm9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW0sIGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5Fc2NhcGUnLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5ZG93bi5BcnJvd0xlZnQnLCBbJyRldmVudCddKVxuICBwdWJsaWMgb25DbG9zZUxlYWZNZW51KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzTGVhZikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNhbmNlbEV2ZW50KGV2ZW50KTtcbiAgICB0aGlzLmNsb3NlTGVhZk1lbnUuZW1pdCh7IGV4Y2VwdFJvb3RNZW51OiBldmVudC5rZXlDb2RlID09PSBBUlJPV19MRUZUX0tFWUNPREUsIGV2ZW50IH0pO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjb250ZXh0bWVudScsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBjbG9zZU1lbnUoZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2NsaWNrJyAmJiBldmVudC5idXR0b24gPT09IDIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jbG9zZUFsbE1lbnVzLmVtaXQoe2V2ZW50fSk7XG4gIH1cblxuICBwdWJsaWMgb25PcGVuU3ViTWVudShtZW51SXRlbTogQ29udGV4dE1lbnVJdGVtRGlyZWN0aXZlLCBldmVudD86IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgYW5jaG9yRWxlbWVudFJlZiA9IHRoaXMubWVudUl0ZW1FbGVtZW50cy50b0FycmF5KClbdGhpcy5fa2V5TWFuYWdlci5hY3RpdmVJdGVtSW5kZXhdO1xuICAgIGNvbnN0IGFuY2hvckVsZW1lbnQgPSBhbmNob3JFbGVtZW50UmVmICYmIGFuY2hvckVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBpZiAodGhpcy5oaWdobGlnaHRQYXJlbnRJdGVtcykgeyBcbiAgICAgIHRoaXMubWVudUl0ZW1zLmZvckVhY2goaXRlbSA9PiBpdGVtLmlzQWN0aXZlUGFyZW50ID0gKGl0ZW0gPT09IG1lbnVJdGVtICYmIG1lbnVJdGVtLnN1Yk1lbnUpICk7XG4gICAgfVxuICAgIHRoaXMub3BlblN1Yk1lbnUuZW1pdCh7XG4gICAgICBhbmNob3JFbGVtZW50LFxuICAgICAgY29udGV4dE1lbnU6IG1lbnVJdGVtLnN1Yk1lbnUsXG4gICAgICBldmVudCxcbiAgICAgIGl0ZW06IHRoaXMuaXRlbSxcbiAgICAgIHBhcmVudENvbnRleHRNZW51OiB0aGlzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG9uTWVudUl0ZW1TZWxlY3QobWVudUl0ZW06IENvbnRleHRNZW51SXRlbURpcmVjdGl2ZSwgZXZlbnQ6IE1vdXNlRXZlbnQgfCBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm9uT3BlblN1Yk1lbnUobWVudUl0ZW0sIGV2ZW50KTtcbiAgICBpZiAoIW1lbnVJdGVtLnN1Yk1lbnUpIHtcbiAgICAgIG1lbnVJdGVtLnRyaWdnZXJFeGVjdXRlKHRoaXMuaXRlbSwgZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FuY2VsRXZlbnQoZXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIWV2ZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0OiBIVE1MRWxlbWVudCA9IGV2ZW50LnRhcmdldDtcbiAgICBpZiAoWydJTlBVVCcsICdURVhUQVJFQScsICdTRUxFQ1QnXS5pbmRleE9mKHRhcmdldC50YWdOYW1lKSA+IC0xIHx8IHRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cbn1cbiJdfQ==