You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
578 lines
77 KiB
578 lines
77 KiB
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import { FocusMonitor, isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader, } from '@angular/cdk/a11y';
|
|
import { Directionality } from '@angular/cdk/bidi';
|
|
import { ENTER, LEFT_ARROW, RIGHT_ARROW, SPACE } from '@angular/cdk/keycodes';
|
|
import { Overlay, OverlayConfig, } from '@angular/cdk/overlay';
|
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
import { Directive, ElementRef, EventEmitter, HostBinding, HostListener, Inject, InjectionToken, Input, Optional, Output, Self, ViewContainerRef, } from '@angular/core';
|
|
import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
import { asapScheduler, merge, of as observableOf, Subscription } from 'rxjs';
|
|
import { delay, filter, take, takeUntil } from 'rxjs/operators';
|
|
import { _MatMenuBase } from './menu';
|
|
import { throwMatMenuMissingError, throwMatMenuRecursiveError } from './menu-errors';
|
|
import { MatMenuItem } from './menu-item';
|
|
import { MAT_MENU_PANEL } from './menu-panel';
|
|
/** Injection token that determines the scroll handling while the menu is open. */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from '@angular/cdk/overlay';
|
|
import * as ɵngcc2 from './menu-item';
|
|
import * as ɵngcc3 from '@angular/cdk/bidi';
|
|
import * as ɵngcc4 from '@angular/cdk/a11y';
|
|
export const MAT_MENU_SCROLL_STRATEGY = new InjectionToken('mat-menu-scroll-strategy');
|
|
/** @docs-private */
|
|
export function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay) {
|
|
return () => overlay.scrollStrategies.reposition();
|
|
}
|
|
/** @docs-private */
|
|
export const MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
|
|
provide: MAT_MENU_SCROLL_STRATEGY,
|
|
deps: [Overlay],
|
|
useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
|
|
};
|
|
/** Default top padding of the menu panel. */
|
|
export const MENU_PANEL_TOP_PADDING = 8;
|
|
/** Options for binding a passive event listener. */
|
|
const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
|
|
// TODO(andrewseguin): Remove the kebab versions in favor of camelCased attribute selectors
|
|
export class _MatMenuTriggerBase {
|
|
constructor(_overlay, _element, _viewContainerRef, scrollStrategy, parentMenu,
|
|
// `MatMenuTrigger` is commonly used in combination with a `MatMenuItem`.
|
|
// tslint:disable-next-line: lightweight-tokens
|
|
_menuItemInstance, _dir,
|
|
// TODO(crisbeto): make the _focusMonitor required when doing breaking changes.
|
|
// @breaking-change 8.0.0
|
|
_focusMonitor) {
|
|
this._overlay = _overlay;
|
|
this._element = _element;
|
|
this._viewContainerRef = _viewContainerRef;
|
|
this._menuItemInstance = _menuItemInstance;
|
|
this._dir = _dir;
|
|
this._focusMonitor = _focusMonitor;
|
|
this._overlayRef = null;
|
|
this._menuOpen = false;
|
|
this._closingActionsSubscription = Subscription.EMPTY;
|
|
this._hoverSubscription = Subscription.EMPTY;
|
|
this._menuCloseSubscription = Subscription.EMPTY;
|
|
/**
|
|
* Handles touch start events on the trigger.
|
|
* Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
|
|
*/
|
|
this._handleTouchStart = (event) => {
|
|
if (!isFakeTouchstartFromScreenReader(event)) {
|
|
this._openedBy = 'touch';
|
|
}
|
|
};
|
|
// Tracking input type is necessary so it's possible to only auto-focus
|
|
// the first item of the list when the menu is opened via the keyboard
|
|
this._openedBy = undefined;
|
|
this._ariaHaspopup = true;
|
|
/**
|
|
* Whether focus should be restored when the menu is closed.
|
|
* Note that disabling this option can have accessibility implications
|
|
* and it's up to you to manage focus, if you decide to turn it off.
|
|
*/
|
|
this.restoreFocus = true;
|
|
/** Event emitted when the associated menu is opened. */
|
|
this.menuOpened = new EventEmitter();
|
|
/**
|
|
* Event emitted when the associated menu is opened.
|
|
* @deprecated Switch to `menuOpened` instead
|
|
* @breaking-change 8.0.0
|
|
*/
|
|
// tslint:disable-next-line:no-output-on-prefix
|
|
this.onMenuOpen = this.menuOpened;
|
|
/** Event emitted when the associated menu is closed. */
|
|
this.menuClosed = new EventEmitter();
|
|
/**
|
|
* Event emitted when the associated menu is closed.
|
|
* @deprecated Switch to `menuClosed` instead
|
|
* @breaking-change 8.0.0
|
|
*/
|
|
// tslint:disable-next-line:no-output-on-prefix
|
|
this.onMenuClose = this.menuClosed;
|
|
this._scrollStrategy = scrollStrategy;
|
|
this._parentMaterialMenu = parentMenu instanceof _MatMenuBase ? parentMenu : undefined;
|
|
_element.nativeElement.addEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
|
|
if (_menuItemInstance) {
|
|
_menuItemInstance._triggersSubmenu = this.triggersSubmenu();
|
|
}
|
|
}
|
|
get _ariaExpanded() {
|
|
return this.menuOpen || null;
|
|
}
|
|
get _ariaControl() {
|
|
return this.menuOpen ? this.menu.panelId : null;
|
|
}
|
|
/**
|
|
* @deprecated
|
|
* @breaking-change 8.0.0
|
|
*/
|
|
get _deprecatedMatMenuTriggerFor() { return this.menu; }
|
|
set _deprecatedMatMenuTriggerFor(v) {
|
|
this.menu = v;
|
|
}
|
|
/** References the menu instance that the trigger is associated with. */
|
|
get menu() { return this._menu; }
|
|
set menu(menu) {
|
|
if (menu === this._menu) {
|
|
return;
|
|
}
|
|
this._menu = menu;
|
|
this._menuCloseSubscription.unsubscribe();
|
|
if (menu) {
|
|
if (menu === this._parentMaterialMenu && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
throwMatMenuRecursiveError();
|
|
}
|
|
this._menuCloseSubscription = menu.close.subscribe((reason) => {
|
|
this._destroyMenu(reason);
|
|
// If a click closed the menu, we should close the entire chain of nested menus.
|
|
if ((reason === 'click' || reason === 'tab') && this._parentMaterialMenu) {
|
|
this._parentMaterialMenu.closed.emit(reason);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
ngAfterContentInit() {
|
|
this._checkMenu();
|
|
this._handleHover();
|
|
}
|
|
ngOnDestroy() {
|
|
if (this._overlayRef) {
|
|
this._overlayRef.dispose();
|
|
this._overlayRef = null;
|
|
}
|
|
this._element.nativeElement.removeEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
|
|
this._menuCloseSubscription.unsubscribe();
|
|
this._closingActionsSubscription.unsubscribe();
|
|
this._hoverSubscription.unsubscribe();
|
|
}
|
|
/** Whether the menu is open. */
|
|
get menuOpen() {
|
|
return this._menuOpen;
|
|
}
|
|
/** The text direction of the containing app. */
|
|
get dir() {
|
|
return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
|
}
|
|
/** Whether the menu triggers a sub-menu or a top-level one. */
|
|
triggersSubmenu() {
|
|
return !!(this._menuItemInstance && this._parentMaterialMenu);
|
|
}
|
|
/** Toggles the menu between the open and closed states. */
|
|
toggleMenu() {
|
|
return this._menuOpen ? this.closeMenu() : this.openMenu();
|
|
}
|
|
/** Opens the menu. */
|
|
openMenu() {
|
|
if (this._menuOpen) {
|
|
return;
|
|
}
|
|
this._checkMenu();
|
|
const overlayRef = this._createOverlay();
|
|
const overlayConfig = overlayRef.getConfig();
|
|
this._setPosition(overlayConfig.positionStrategy);
|
|
overlayConfig.hasBackdrop = this.menu.hasBackdrop == null ? !this.triggersSubmenu() :
|
|
this.menu.hasBackdrop;
|
|
overlayRef.attach(this._getPortal());
|
|
if (this.menu.lazyContent) {
|
|
this.menu.lazyContent.attach(this.menuData);
|
|
}
|
|
this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
|
|
this._initMenu();
|
|
if (this.menu instanceof _MatMenuBase) {
|
|
this.menu._startAnimation();
|
|
}
|
|
}
|
|
/** Closes the menu. */
|
|
closeMenu() {
|
|
this.menu.close.emit();
|
|
}
|
|
/**
|
|
* Focuses the menu trigger.
|
|
* @param origin Source of the menu trigger's focus.
|
|
*/
|
|
focus(origin, options) {
|
|
if (this._focusMonitor && origin) {
|
|
this._focusMonitor.focusVia(this._element, origin, options);
|
|
}
|
|
else {
|
|
this._element.nativeElement.focus(options);
|
|
}
|
|
}
|
|
/**
|
|
* Updates the position of the menu to ensure that it fits all options within the viewport.
|
|
*/
|
|
updatePosition() {
|
|
var _a;
|
|
(_a = this._overlayRef) === null || _a === void 0 ? void 0 : _a.updatePosition();
|
|
}
|
|
/** Closes the menu and does the necessary cleanup. */
|
|
_destroyMenu(reason) {
|
|
if (!this._overlayRef || !this.menuOpen) {
|
|
return;
|
|
}
|
|
const menu = this.menu;
|
|
this._closingActionsSubscription.unsubscribe();
|
|
this._overlayRef.detach();
|
|
// Always restore focus if the user is navigating using the keyboard or the menu was opened
|
|
// programmatically. We don't restore for non-root triggers, because it can prevent focus
|
|
// from making it back to the root trigger when closing a long chain of menus by clicking
|
|
// on the backdrop.
|
|
if (this.restoreFocus && (reason === 'keydown' || !this._openedBy || !this.triggersSubmenu())) {
|
|
this.focus(this._openedBy);
|
|
}
|
|
this._openedBy = undefined;
|
|
if (menu instanceof _MatMenuBase) {
|
|
menu._resetAnimation();
|
|
if (menu.lazyContent) {
|
|
// Wait for the exit animation to finish before detaching the content.
|
|
menu._animationDone
|
|
.pipe(filter(event => event.toState === 'void'), take(1),
|
|
// Interrupt if the content got re-attached.
|
|
takeUntil(menu.lazyContent._attached))
|
|
.subscribe({
|
|
next: () => menu.lazyContent.detach(),
|
|
// No matter whether the content got re-attached, reset the menu.
|
|
complete: () => this._setIsMenuOpen(false)
|
|
});
|
|
}
|
|
else {
|
|
this._setIsMenuOpen(false);
|
|
}
|
|
}
|
|
else {
|
|
this._setIsMenuOpen(false);
|
|
if (menu.lazyContent) {
|
|
menu.lazyContent.detach();
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* This method sets the menu state to open and focuses the first item if
|
|
* the menu was opened via the keyboard.
|
|
*/
|
|
_initMenu() {
|
|
this.menu.parentMenu = this.triggersSubmenu() ? this._parentMaterialMenu : undefined;
|
|
this.menu.direction = this.dir;
|
|
this._setMenuElevation();
|
|
this.menu.focusFirstItem(this._openedBy || 'program');
|
|
this._setIsMenuOpen(true);
|
|
}
|
|
/** Updates the menu elevation based on the amount of parent menus that it has. */
|
|
_setMenuElevation() {
|
|
if (this.menu.setElevation) {
|
|
let depth = 0;
|
|
let parentMenu = this.menu.parentMenu;
|
|
while (parentMenu) {
|
|
depth++;
|
|
parentMenu = parentMenu.parentMenu;
|
|
}
|
|
this.menu.setElevation(depth);
|
|
}
|
|
}
|
|
// set state rather than toggle to support triggers sharing a menu
|
|
_setIsMenuOpen(isOpen) {
|
|
this._menuOpen = isOpen;
|
|
this._menuOpen ? this.menuOpened.emit() : this.menuClosed.emit();
|
|
if (this.triggersSubmenu()) {
|
|
this._menuItemInstance._setHighlighted(isOpen);
|
|
}
|
|
}
|
|
/**
|
|
* This method checks that a valid instance of MatMenu has been passed into
|
|
* matMenuTriggerFor. If not, an exception is thrown.
|
|
*/
|
|
_checkMenu() {
|
|
if (!this.menu && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
throwMatMenuMissingError();
|
|
}
|
|
}
|
|
/**
|
|
* This method creates the overlay from the provided menu's template and saves its
|
|
* OverlayRef so that it can be attached to the DOM when openMenu is called.
|
|
*/
|
|
_createOverlay() {
|
|
if (!this._overlayRef) {
|
|
const config = this._getOverlayConfig();
|
|
this._subscribeToPositions(config.positionStrategy);
|
|
this._overlayRef = this._overlay.create(config);
|
|
// Consume the `keydownEvents` in order to prevent them from going to another overlay.
|
|
// Ideally we'd also have our keyboard event logic in here, however doing so will
|
|
// break anybody that may have implemented the `MatMenuPanel` themselves.
|
|
this._overlayRef.keydownEvents().subscribe();
|
|
}
|
|
return this._overlayRef;
|
|
}
|
|
/**
|
|
* This method builds the configuration object needed to create the overlay, the OverlayState.
|
|
* @returns OverlayConfig
|
|
*/
|
|
_getOverlayConfig() {
|
|
return new OverlayConfig({
|
|
positionStrategy: this._overlay.position()
|
|
.flexibleConnectedTo(this._element)
|
|
.withLockedPosition()
|
|
.withGrowAfterOpen()
|
|
.withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel'),
|
|
backdropClass: this.menu.backdropClass || 'cdk-overlay-transparent-backdrop',
|
|
panelClass: this.menu.overlayPanelClass,
|
|
scrollStrategy: this._scrollStrategy(),
|
|
direction: this._dir
|
|
});
|
|
}
|
|
/**
|
|
* Listens to changes in the position of the overlay and sets the correct classes
|
|
* on the menu based on the new position. This ensures the animation origin is always
|
|
* correct, even if a fallback position is used for the overlay.
|
|
*/
|
|
_subscribeToPositions(position) {
|
|
if (this.menu.setPositionClasses) {
|
|
position.positionChanges.subscribe(change => {
|
|
const posX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
|
|
const posY = change.connectionPair.overlayY === 'top' ? 'below' : 'above';
|
|
this.menu.setPositionClasses(posX, posY);
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Sets the appropriate positions on a position strategy
|
|
* so the overlay connects with the trigger correctly.
|
|
* @param positionStrategy Strategy whose position to update.
|
|
*/
|
|
_setPosition(positionStrategy) {
|
|
let [originX, originFallbackX] = this.menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'];
|
|
let [overlayY, overlayFallbackY] = this.menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'];
|
|
let [originY, originFallbackY] = [overlayY, overlayFallbackY];
|
|
let [overlayX, overlayFallbackX] = [originX, originFallbackX];
|
|
let offsetY = 0;
|
|
if (this.triggersSubmenu()) {
|
|
// When the menu is a sub-menu, it should always align itself
|
|
// to the edges of the trigger, instead of overlapping it.
|
|
overlayFallbackX = originX = this.menu.xPosition === 'before' ? 'start' : 'end';
|
|
originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
|
|
offsetY = overlayY === 'bottom' ? MENU_PANEL_TOP_PADDING : -MENU_PANEL_TOP_PADDING;
|
|
}
|
|
else if (!this.menu.overlapTrigger) {
|
|
originY = overlayY === 'top' ? 'bottom' : 'top';
|
|
originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
|
|
}
|
|
positionStrategy.withPositions([
|
|
{ originX, originY, overlayX, overlayY, offsetY },
|
|
{ originX: originFallbackX, originY, overlayX: overlayFallbackX, overlayY, offsetY },
|
|
{
|
|
originX,
|
|
originY: originFallbackY,
|
|
overlayX,
|
|
overlayY: overlayFallbackY,
|
|
offsetY: -offsetY
|
|
},
|
|
{
|
|
originX: originFallbackX,
|
|
originY: originFallbackY,
|
|
overlayX: overlayFallbackX,
|
|
overlayY: overlayFallbackY,
|
|
offsetY: -offsetY
|
|
}
|
|
]);
|
|
}
|
|
/** Returns a stream that emits whenever an action that should close the menu occurs. */
|
|
_menuClosingActions() {
|
|
const backdrop = this._overlayRef.backdropClick();
|
|
const detachments = this._overlayRef.detachments();
|
|
const parentClose = this._parentMaterialMenu ? this._parentMaterialMenu.closed : observableOf();
|
|
const hover = this._parentMaterialMenu ? this._parentMaterialMenu._hovered().pipe(filter(active => active !== this._menuItemInstance), filter(() => this._menuOpen)) : observableOf();
|
|
return merge(backdrop, parentClose, hover, detachments);
|
|
}
|
|
/** Handles mouse presses on the trigger. */
|
|
_handleMousedown(event) {
|
|
if (!isFakeMousedownFromScreenReader(event)) {
|
|
// Since right or middle button clicks won't trigger the `click` event,
|
|
// we shouldn't consider the menu as opened by mouse in those cases.
|
|
this._openedBy = event.button === 0 ? 'mouse' : undefined;
|
|
// Since clicking on the trigger won't close the menu if it opens a sub-menu,
|
|
// we should prevent focus from moving onto it via click to avoid the
|
|
// highlight from lingering on the menu item.
|
|
if (this.triggersSubmenu()) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
/** Handles key presses on the trigger. */
|
|
_handleKeydown(event) {
|
|
const keyCode = event.keyCode;
|
|
// Pressing enter on the trigger will trigger the click handler later.
|
|
if (keyCode === ENTER || keyCode === SPACE) {
|
|
this._openedBy = 'keyboard';
|
|
}
|
|
if (this.triggersSubmenu() && ((keyCode === RIGHT_ARROW && this.dir === 'ltr') ||
|
|
(keyCode === LEFT_ARROW && this.dir === 'rtl'))) {
|
|
this._openedBy = 'keyboard';
|
|
this.openMenu();
|
|
}
|
|
}
|
|
/** Handles click events on the trigger. */
|
|
_handleClick(event) {
|
|
if (this.triggersSubmenu()) {
|
|
// Stop event propagation to avoid closing the parent menu.
|
|
event.stopPropagation();
|
|
this.openMenu();
|
|
}
|
|
else {
|
|
this.toggleMenu();
|
|
}
|
|
}
|
|
/** Handles the cases where the user hovers over the trigger. */
|
|
_handleHover() {
|
|
// Subscribe to changes in the hovered item in order to toggle the panel.
|
|
if (!this.triggersSubmenu() || !this._parentMaterialMenu) {
|
|
return;
|
|
}
|
|
this._hoverSubscription = this._parentMaterialMenu._hovered()
|
|
// Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
|
|
// with different data and triggers), we have to delay it by a tick to ensure that
|
|
// it won't be closed immediately after it is opened.
|
|
.pipe(filter(active => active === this._menuItemInstance && !active.disabled), delay(0, asapScheduler))
|
|
.subscribe(() => {
|
|
this._openedBy = 'mouse';
|
|
// If the same menu is used between multiple triggers, it might still be animating
|
|
// while the new trigger tries to re-open it. Wait for the animation to finish
|
|
// before doing so. Also interrupt if the user moves to another item.
|
|
if (this.menu instanceof _MatMenuBase && this.menu._isAnimating) {
|
|
// We need the `delay(0)` here in order to avoid
|
|
// 'changed after checked' errors in some cases. See #12194.
|
|
this.menu._animationDone
|
|
.pipe(take(1), delay(0, asapScheduler), takeUntil(this._parentMaterialMenu._hovered()))
|
|
.subscribe(() => this.openMenu());
|
|
}
|
|
else {
|
|
this.openMenu();
|
|
}
|
|
});
|
|
}
|
|
/** Gets the portal that should be attached to the overlay. */
|
|
_getPortal() {
|
|
// Note that we can avoid this check by keeping the portal on the menu panel.
|
|
// While it would be cleaner, we'd have to introduce another required method on
|
|
// `MatMenuPanel`, making it harder to consume.
|
|
if (!this._portal || this._portal.templateRef !== this.menu.templateRef) {
|
|
this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef);
|
|
}
|
|
return this._portal;
|
|
}
|
|
}
|
|
_MatMenuTriggerBase.ɵfac = function _MatMenuTriggerBase_Factory(t) { return new (t || _MatMenuTriggerBase)(ɵngcc0.ɵɵdirectiveInject(ɵngcc1.Overlay), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ElementRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ViewContainerRef), ɵngcc0.ɵɵdirectiveInject(MAT_MENU_SCROLL_STRATEGY), ɵngcc0.ɵɵdirectiveInject(MAT_MENU_PANEL, 8), ɵngcc0.ɵɵdirectiveInject(ɵngcc2.MatMenuItem, 10), ɵngcc0.ɵɵdirectiveInject(ɵngcc3.Directionality, 8), ɵngcc0.ɵɵdirectiveInject(ɵngcc4.FocusMonitor)); };
|
|
_MatMenuTriggerBase.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: _MatMenuTriggerBase, hostVars: 3, hostBindings: function _MatMenuTriggerBase_HostBindings(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵlistener("mousedown", function _MatMenuTriggerBase_mousedown_HostBindingHandler($event) { return ctx._handleMousedown($event); })("keydown", function _MatMenuTriggerBase_keydown_HostBindingHandler($event) { return ctx._handleKeydown($event); })("click", function _MatMenuTriggerBase_click_HostBindingHandler($event) { return ctx._handleClick($event); });
|
|
} if (rf & 2) {
|
|
ɵngcc0.ɵɵattribute("aria-haspopup", ctx._ariaHaspopup)("aria-expanded", ctx._ariaExpanded)("aria-controls", ctx._ariaControl);
|
|
} }, inputs: { restoreFocus: ["matMenuTriggerRestoreFocus", "restoreFocus"], _deprecatedMatMenuTriggerFor: ["mat-menu-trigger-for", "_deprecatedMatMenuTriggerFor"], menu: ["matMenuTriggerFor", "menu"], menuData: ["matMenuTriggerData", "menuData"] }, outputs: { menuOpened: "menuOpened", onMenuOpen: "onMenuOpen", menuClosed: "menuClosed", onMenuClose: "onMenuClose" } });
|
|
_MatMenuTriggerBase.ctorParameters = () => [
|
|
{ type: Overlay },
|
|
{ type: ElementRef },
|
|
{ type: ViewContainerRef },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_SCROLL_STRATEGY,] }] },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_PANEL,] }, { type: Optional }] },
|
|
{ type: MatMenuItem, decorators: [{ type: Optional }, { type: Self }] },
|
|
{ type: Directionality, decorators: [{ type: Optional }] },
|
|
{ type: FocusMonitor }
|
|
];
|
|
_MatMenuTriggerBase.propDecorators = {
|
|
_ariaExpanded: [{ type: HostBinding, args: ['attr.aria-expanded',] }],
|
|
_ariaControl: [{ type: HostBinding, args: ['attr.aria-controls',] }],
|
|
_ariaHaspopup: [{ type: HostBinding, args: ['attr.aria-haspopup',] }],
|
|
_deprecatedMatMenuTriggerFor: [{ type: Input, args: ['mat-menu-trigger-for',] }],
|
|
menu: [{ type: Input, args: ['matMenuTriggerFor',] }],
|
|
menuData: [{ type: Input, args: ['matMenuTriggerData',] }],
|
|
restoreFocus: [{ type: Input, args: ['matMenuTriggerRestoreFocus',] }],
|
|
menuOpened: [{ type: Output }],
|
|
onMenuOpen: [{ type: Output }],
|
|
menuClosed: [{ type: Output }],
|
|
onMenuClose: [{ type: Output }],
|
|
_handleMousedown: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
|
|
_handleKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
|
|
_handleClick: [{ type: HostListener, args: ['click', ['$event'],] }]
|
|
};
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(_MatMenuTriggerBase, [{
|
|
type: Directive
|
|
}], function () { return [{ type: ɵngcc1.Overlay }, { type: ɵngcc0.ElementRef }, { type: ɵngcc0.ViewContainerRef }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_MENU_SCROLL_STRATEGY]
|
|
}] }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_MENU_PANEL]
|
|
}, {
|
|
type: Optional
|
|
}] }, { type: ɵngcc2.MatMenuItem, decorators: [{
|
|
type: Optional
|
|
}, {
|
|
type: Self
|
|
}] }, { type: ɵngcc3.Directionality, decorators: [{
|
|
type: Optional
|
|
}] }, { type: ɵngcc4.FocusMonitor }]; }, { _ariaHaspopup: [{
|
|
type: HostBinding,
|
|
args: ['attr.aria-haspopup']
|
|
}], restoreFocus: [{
|
|
type: Input,
|
|
args: ['matMenuTriggerRestoreFocus']
|
|
}], menuOpened: [{
|
|
type: Output
|
|
}], onMenuOpen: [{
|
|
type: Output
|
|
}], menuClosed: [{
|
|
type: Output
|
|
}], onMenuClose: [{
|
|
type: Output
|
|
}], _ariaExpanded: [{
|
|
type: HostBinding,
|
|
args: ['attr.aria-expanded']
|
|
}], _ariaControl: [{
|
|
type: HostBinding,
|
|
args: ['attr.aria-controls']
|
|
}], _deprecatedMatMenuTriggerFor: [{
|
|
type: Input,
|
|
args: ['mat-menu-trigger-for']
|
|
}], menu: [{
|
|
type: Input,
|
|
args: ['matMenuTriggerFor']
|
|
}],
|
|
/** Handles mouse presses on the trigger. */
|
|
_handleMousedown: [{
|
|
type: HostListener,
|
|
args: ['mousedown', ['$event']]
|
|
}],
|
|
/** Handles key presses on the trigger. */
|
|
_handleKeydown: [{
|
|
type: HostListener,
|
|
args: ['keydown', ['$event']]
|
|
}],
|
|
/** Handles click events on the trigger. */
|
|
_handleClick: [{
|
|
type: HostListener,
|
|
args: ['click', ['$event']]
|
|
}], menuData: [{
|
|
type: Input,
|
|
args: ['matMenuTriggerData']
|
|
}] }); })();
|
|
/** Directive applied to an element that should trigger a `mat-menu`. */
|
|
export class MatMenuTrigger extends _MatMenuTriggerBase {
|
|
}
|
|
MatMenuTrigger.ɵfac = /*@__PURE__*/ function () { let ɵMatMenuTrigger_BaseFactory; return function MatMenuTrigger_Factory(t) { return (ɵMatMenuTrigger_BaseFactory || (ɵMatMenuTrigger_BaseFactory = ɵngcc0.ɵɵgetInheritedFactory(MatMenuTrigger)))(t || MatMenuTrigger); }; }();
|
|
MatMenuTrigger.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: MatMenuTrigger, selectors: [["", "mat-menu-trigger-for", ""], ["", "matMenuTriggerFor", ""]], hostAttrs: [1, "mat-menu-trigger"], exportAs: ["matMenuTrigger"], features: [ɵngcc0.ɵɵInheritDefinitionFeature] });
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatMenuTrigger, [{
|
|
type: Directive,
|
|
args: [{
|
|
selector: `[mat-menu-trigger-for], [matMenuTriggerFor]`,
|
|
host: {
|
|
'class': 'mat-menu-trigger'
|
|
},
|
|
exportAs: 'matMenuTrigger'
|
|
}]
|
|
}], null, null); })();
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS10cmlnZ2VyLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbWF0ZXJpYWwvbWVudS9tZW51LXRyaWdnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUVILE9BQU8sRUFDTCxZQUFZLEVBRVosK0JBQStCLEVBQy9CLGdDQUFnQyxHQUNqQyxNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBWSxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDNUUsT0FBTyxFQUdMLE9BQU8sRUFDUCxhQUFhLEdBSWQsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDbkQsT0FBTyxFQUVMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLGNBQWMsRUFDZCxLQUFLLEVBRUwsUUFBUSxFQUNSLE1BQU0sRUFDTixJQUFJLEVBQ0osZ0JBQWdCLEdBQ2pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQywrQkFBK0IsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3RFLE9BQU8sRUFBQyxhQUFhLEVBQUUsS0FBSyxFQUFjLEVBQUUsSUFBSSxZQUFZLEVBQUUsWUFBWSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3hGLE9BQU8sRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RCxPQUFPLEVBQUMsWUFBWSxFQUFrQixNQUFNLFFBQVEsQ0FBQztBQUNyRCxPQUFPLEVBQUMsd0JBQXdCLEVBQUUsMEJBQTBCLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFD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QUd6QyxNQUFNO0FBQUsseUJBUVgsTUFBTTtBQUFLLHlCQUdYLE1BQU07QUFBSywwQkFRWCxNQUFNO0FBQUssK0JBc1VYLFlBQVksU0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUM7QUFDbEMsNkJBZ0JGLFlBQVksU0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUM7QUFDaEMsMkJBaUJGLFlBQVksU0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7QUFDL0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7b0JBQUU7QUF5RE4sd0VBQXdFO0FBUXhFLE1BQU0sT0FBTyxjQUFlLFNBQVEsbUJBQW1CO0FBQUc7MENBUHpELFNBQVMsU0FBQyxrQkFDVCxRQUFRLEVBQUUsNkNBQTZDLGtCQUN2RCxJQUFJLEVBQUUsc0JBQ0osT0FBTyxFQUFFLGtCQUFrQixtQkFDNUIsa0JBQ0QsUUFBUSxFQUFFLGdCQUFnQjtTQUMzQjs7Ozs7Ozs7OzswQkFDSTtBQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7XG4gIEZvY3VzTW9uaXRvcixcbiAgRm9jdXNPcmlnaW4sXG4gIGlzRmFrZU1vdXNlZG93bkZyb21TY3JlZW5SZWFkZXIsXG4gIGlzRmFrZVRvdWNoc3RhcnRGcm9tU2NyZWVuUmVhZGVyLFxufSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQge0RpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7RU5URVIsIExFRlRfQVJST1csIFJJR0hUX0FSUk9XLCBTUEFDRX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7XG4gIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSxcbiAgSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXG4gIE92ZXJsYXksXG4gIE92ZXJsYXlDb25maWcsXG4gIE92ZXJsYXlSZWYsXG4gIFNjcm9sbFN0cmF0ZWd5LFxuICBWZXJ0aWNhbENvbm5lY3Rpb25Qb3MsXG59IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7VGVtcGxhdGVQb3J0YWx9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIEluamVjdCxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFNlbGYsXG4gIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHthc2FwU2NoZWR1bGVyLCBtZXJnZSwgT2JzZXJ2YWJsZSwgb2YgYXMgb2JzZXJ2YWJsZU9mLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWxheSwgZmlsdGVyLCB0YWtlLCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7X01hdE1lbnVCYXNlLCBNZW51Q2xvc2VSZWFzb259IGZyb20gJy4vbWVudSc7XG5pbXBvcnQge3Rocm93TWF0TWVudU1pc3NpbmdFcnJvciwgdGhyb3dNYXRNZW51UmVjdXJzaXZlRXJyb3J9IGZyb20gJy4vbWVudS1lcnJvcnMnO1xuaW1wb3J0IHtNYXRNZW51SXRlbX0gZnJvbSAnLi9tZW51LWl0ZW0nO1xuaW1wb3J0IHtNQVRfTUVOVV9QQU5FTCwgTWF0TWVudVBhbmVsfSBmcm9tICcuL21lbnUtcGFuZWwnO1xuaW1wb3J0IHtNZW51UG9zaXRpb25YLCBNZW51UG9zaXRpb25ZfSBmcm9tICcuL21lbnUtcG9zaXRpb25zJztcblxuLyoqIEluamVjdGlvbiB0b2tlbiB0aGF0IGRldGVybWluZXMgdGhlIHNjcm9sbCBoYW5kbGluZyB3aGlsZSB0aGUgbWVudSBpcyBvcGVuLiAqL1xuZXhwb3J0IGNvbnN0IE1BVF9NRU5VX1NDUk9MTF9TVFJBVEVHWSA9XG4gICAgbmV3IEluamVjdGlvblRva2VuPCgpID0+IFNjcm9sbFN0cmF0ZWd5PignbWF0LW1lbnUtc2Nyb2xsLXN0cmF0ZWd5Jyk7XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgZnVuY3Rpb24gTUFUX01FTlVfU0NST0xMX1NUUkFURUdZX0ZBQ1RPUlkob3ZlcmxheTogT3ZlcmxheSk6ICgpID0+IFNjcm9sbFN0cmF0ZWd5IHtcbiAgcmV0dXJuICgpID0+IG92ZXJsYXkuc2Nyb2xsU3RyYXRlZ2llcy5yZXBvc2l0aW9uKCk7XG59XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgY29uc3QgTUFUX01FTlVfU0NST0xMX1NUUkFURUdZX0ZBQ1RPUllfUFJPVklERVIgPSB7XG4gIHByb3ZpZGU6IE1BVF9NRU5VX1NDUk9MTF9TVFJBVEVHWSxcbiAgZGVwczogW092ZXJsYXldLFxuICB1c2VGYWN0b3J5OiBNQVRfTUVOVV9TQ1JPTExfU1RSQVRFR1lfRkFDVE9SWSxcbn07XG5cbi8qKiBEZWZhdWx0IHRvcCBwYWRkaW5nIG9mIHRoZSBtZW51IHBhbmVsLiAqL1xuZXhwb3J0IGNvbnN0IE1FTlVfUEFORUxfVE9QX1BBRERJTkcgPSA4O1xuXG4vKiogT3B0aW9ucyBmb3IgYmluZGluZyBhIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXIuICovXG5jb25zdCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zKHtwYXNzaXZlOiB0cnVlfSk7XG5cbi8vIFRPRE8oYW5kcmV3c2VndWluKTogUmVtb3ZlIHRoZSBrZWJhYiB2ZXJzaW9ucyBpbiBmYXZvciBvZiBjYW1lbENhc2VkIGF0dHJpYnV0ZSBzZWxlY3RvcnNcblxuQERpcmVjdGl2ZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgX01hdE1lbnVUcmlnZ2VyQmFzZSBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgX3BvcnRhbDogVGVtcGxhdGVQb3J0YWw7XG4gIHByaXZhdGUgX292ZXJsYXlSZWY6IE92ZXJsYXlSZWYgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfbWVudU9wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBfY2xvc2luZ0FjdGlvbnNTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG4gIHByaXZhdGUgX2hvdmVyU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuICBwcml2YXRlIF9tZW51Q2xvc2VTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG4gIHByaXZhdGUgX3Njcm9sbFN0cmF0ZWd5OiAoKSA9PiBTY3JvbGxTdHJhdGVneTtcblxuICAvKipcbiAgICogV2UncmUgc3BlY2lmaWNhbGx5IGxvb2tpbmcgZm9yIGEgYE1hdE1lbnVgIGhlcmUgc2luY2UgdGhlIGdlbmVyaWMgYE1hdE1lbnVQYW5lbGBcbiAgICogaW50ZXJmYWNlIGxhY2tzIHNvbWUgZnVuY3Rpb25hbGl0eSBhcm91bmQgbmVzdGVkIG1lbnVzIGFuZCBhbmltYXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBfcGFyZW50TWF0ZXJpYWxNZW51OiBfTWF0TWVudUJhc2UgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIEhhbmRsZXMgdG91Y2ggc3RhcnQgZXZlbnRzIG9uIHRoZSB0cmlnZ2VyLlxuICAgKiBOZWVkcyB0byBiZSBhbiBhcnJvdyBmdW5jdGlvbiBzbyB3ZSBjYW4gZWFzaWx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGFuZCByZW1vdmVFdmVudExpc3RlbmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlVG91Y2hTdGFydCA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmICghaXNGYWtlVG91Y2hzdGFydEZyb21TY3JlZW5SZWFkZXIoZXZlbnQpKSB7XG4gICAgICB0aGlzLl9vcGVuZWRCeSA9ICd0b3VjaCc7XG4gICAgfVxuICB9XG5cbiAgLy8gVHJhY2tpbmcgaW5wdXQgdHlwZSBpcyBuZWNlc3Nhcnkgc28gaXQncyBwb3NzaWJsZSB0byBvbmx5IGF1dG8tZm9jdXNcbiAgLy8gdGhlIGZpcnN0IGl0ZW0gb2YgdGhlIGxpc3Qgd2hlbiB0aGUgbWVudSBpcyBvcGVuZWQgdmlhIHRoZSBrZXlib2FyZFxuICBfb3BlbmVkQnk6IEV4Y2x1ZGU8Rm9jdXNPcmlnaW4sICdwcm9ncmFtJyB8IG51bGw+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5hcmlhLWV4cGFuZGVkJylcbiAgLy8gTmVlZCB0cCB1c2UgZ2V0dGVyIGZvciBIb3N0QmluZGluZ1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tcHJpdmF0ZS1nZXR0ZXJzXG4gIGdldCBfYXJpYUV4cGFuZGVkKCkge1xuICAgIHJldHVybiB0aGlzLm1lbnVPcGVuIHx8IG51bGw7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1jb250cm9scycpXG4gIC8vIE5lZWQgdHAgdXNlIGdldHRlciBmb3IgSG9zdEJpbmRpbmdcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXByaXZhdGUtZ2V0dGVyc1xuICBnZXQgX2FyaWFDb250cm9sKCkge1xuICAgIHJldHVybiB0aGlzLm1lbnVPcGVuID8gdGhpcy5tZW51LnBhbmVsSWQgOiBudWxsO1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtaGFzcG9wdXAnKSBfYXJpYUhhc3BvcHVwID0gdHJ1ZTtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWRcbiAgICogQGJyZWFraW5nLWNoYW5nZSA4LjAuMFxuICAgKi9cbiAgQElucHV0KCdtYXQtbWVudS10cmlnZ2VyLWZvcicpXG4gIGdldCBfZGVwcmVjYXRlZE1hdE1lbnVUcmlnZ2VyRm9yKCk6IE1hdE1lbnVQYW5lbCB7IHJldHVybiB0aGlzLm1lbnU7IH1cbiAgc2V0IF9kZXByZWNhdGVkTWF0TWVudVRyaWdnZXJGb3IodjogTWF0TWVudVBhbmVsKSB7XG4gICAgdGhpcy5tZW51ID0gdjtcbiAgfVxuXG4gIC8qKiBSZWZlcmVuY2VzIHRoZSBtZW51IGluc3RhbmNlIHRoYXQgdGhlIHRyaWdnZXIgaXMgYXNzb2NpYXRlZCB3aXRoLiAqL1xuICBASW5wdXQoJ21hdE1lbnVUcmlnZ2VyRm9yJylcbiAgZ2V0IG1lbnUoKSB7IHJldHVybiB0aGlzLl9tZW51OyB9XG4gIHNldCBtZW51KG1lbnU6IE1hdE1lbnVQYW5lbCkge1xuICAgIGlmIChtZW51ID09PSB0aGlzLl9tZW51KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbWVudSA9IG1lbnU7XG4gICAgdGhpcy5fbWVudUNsb3NlU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG5cbiAgICBpZiAobWVudSkge1xuICAgICAgaWYgKG1lbnUgPT09IHRoaXMuX3BhcmVudE1hdGVyaWFsTWVudSAmJiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgICB0aHJvd01hdE1lbnVSZWN1cnNpdmVFcnJvcigpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9tZW51Q2xvc2VTdWJzY3JpcHRpb24gPSBtZW51LmNsb3NlLnN1YnNjcmliZSgocmVhc29uOiBNZW51Q2xvc2VSZWFzb24pID0+IHtcbiAgICAgICAgdGhpcy5fZGVzdHJveU1lbnUocmVhc29uKTtcblxuICAgICAgICAvLyBJZiBhIGNsaWNrIGNsb3NlZCB0aGUgbWVudSwgd2Ugc2hvdWxkIGNsb3NlIHRoZSBlbnRpcmUgY2hhaW4gb2YgbmVzdGVkIG1lbnVzLlxuICAgICAgICBpZiAoKHJlYXNvbiA9PT0gJ2NsaWNrJyB8fCByZWFzb24gPT09ICd0YWInKSAmJiB0aGlzLl9wYXJlbnRNYXRlcmlhbE1lbnUpIHtcbiAgICAgICAgICB0aGlzLl9wYXJlbnRNYXRlcmlhbE1lbnUuY2xvc2VkLmVtaXQocmVhc29uKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgX21lbnU6IE1hdE1lbnVQYW5lbDtcblxuICAvKiogRGF0YSB0byBiZSBwYXNzZWQgYWxvbmcgdG8gYW55IGxhemlseS1yZW5kZXJlZCBjb250ZW50LiAqL1xuICBASW5wdXQoJ21hdE1lbnVUcmlnZ2VyRGF0YScpIG1lbnVEYXRhOiBhbnk7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZm9jdXMgc2hvdWxkIGJlIHJlc3RvcmVkIHdoZW4gdGhlIG1lbnUgaXMgY2xvc2VkLlxuICAgKiBOb3RlIHRoYXQgZGlzYWJsaW5nIHRoaXMgb3B0aW9uIGNhbiBoYXZlIGFjY2Vzc2liaWxpdHkgaW1wbGljYXRpb25zXG4gICAqIGFuZCBpdCdzIHVwIHRvIHlvdSB0byBtYW5hZ2UgZm9jdXMsIGlmIHlvdSBkZWNpZGUgdG8gdHVybiBpdCBvZmYuXG4gICAqL1xuICBASW5wdXQoJ21hdE1lbnVUcmlnZ2VyUmVzdG9yZUZvY3VzJykgcmVzdG9yZUZvY3VzOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBhc3NvY2lhdGVkIG1lbnUgaXMgb3BlbmVkLiAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgbWVudU9wZW5lZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8qKlxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGFzc29jaWF0ZWQgbWVudSBpcyBvcGVuZWQuXG4gICAqIEBkZXByZWNhdGVkIFN3aXRjaCB0byBgbWVudU9wZW5lZGAgaW5zdGVhZFxuICAgKiBAYnJlYWtpbmctY2hhbmdlIDguMC4wXG4gICAqL1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tb3V0cHV0LW9uLXByZWZpeFxuICBAT3V0cHV0KCkgcmVhZG9ubHkgb25NZW51T3BlbjogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gdGhpcy5tZW51T3BlbmVkO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGFzc29jaWF0ZWQgbWVudSBpcyBjbG9zZWQuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSBtZW51Q2xvc2VkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgYXNzb2NpYXRlZCBtZW51IGlzIGNsb3NlZC5cbiAgICogQGRlcHJlY2F0ZWQgU3dpdGNoIHRvIGBtZW51Q2xvc2VkYCBpbnN0ZWFkXG4gICAqIEBicmVha2luZy1jaGFuZ2UgOC4wLjBcbiAgICovXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1vdXRwdXQtb24tcHJlZml4XG4gIEBPdXRwdXQoKSByZWFkb25seSBvbk1lbnVDbG9zZTogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gdGhpcy5tZW51Q2xvc2VkO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX292ZXJsYXk6IE92ZXJsYXksXG4gICAgICAgICAgICAgIHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgICAgICAgICAgICBwcml2YXRlIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgICAgICAgICAgICBASW5qZWN0KE1BVF9NRU5VX1NDUk9MTF9TVFJBVEVHWSkgc2Nyb2xsU3RyYXRlZ3k6IGFueSxcbiAgICAgICAgICAgICAgQEluamVjdChNQVRfTUVOVV9QQU5FTCkgQE9wdGlvbmFsKCkgcGFyZW50TWVudTogTWF0TWVudVBhbmVsLFxuICAgICAgICAgICAgICAvLyBgTWF0TWVudVRyaWdnZXJgIGlzIGNvbW1vbmx5IHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBhIGBNYXRNZW51SXRlbWAuXG4gICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbGlnaHR3ZWlnaHQtdG9rZW5zXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBTZWxmKCkgcHJpdmF0ZSBfbWVudUl0ZW1JbnN0YW5jZTogTWF0TWVudUl0ZW0sXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIHByaXZhdGUgX2RpcjogRGlyZWN0aW9uYWxpdHksXG4gICAgICAgICAgICAgIC8vIFRPRE8oY3Jpc2JldG8pOiBtYWtlIHRoZSBfZm9jdXNNb25pdG9yIHJlcXVpcmVkIHdoZW4gZG9pbmcgYnJlYWtpbmcgY2hhbmdlcy5cbiAgICAgICAgICAgICAgLy8gQGJyZWFraW5nLWNoYW5nZSA4LjAuMFxuICAgICAgICAgICAgICBwcml2YXRlIF9mb2N1c01vbml0b3I/OiBGb2N1c01vbml0b3IpIHtcbiAgICB0aGlzLl9zY3JvbGxTdHJhdGVneSA9IHNjcm9sbFN0cmF0ZWd5O1xuICAgIHRoaXMuX3BhcmVudE1hdGVyaWFsTWVudSA9IHBhcmVudE1lbnUgaW5zdGFuY2VvZiBfTWF0TWVudUJhc2UgPyBwYXJlbnRNZW51IDogdW5kZWZpbmVkO1xuXG4gICAgX2VsZW1lbnQubmF0aXZlRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5faGFuZGxlVG91Y2hTdGFydCxcbiAgICAgICAgcGFzc2l2ZUV2ZW50TGlzdGVuZXJPcHRpb25zKTtcblxuICAgIGlmIChfbWVudUl0ZW1JbnN0YW5jZSkge1xuICAgICAgX21lbnVJdGVtSW5zdGFuY2UuX3RyaWdnZXJzU3VibWVudSA9IHRoaXMudHJpZ2dlcnNTdWJtZW51KCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuX2NoZWNrTWVudSgpO1xuICAgIHRoaXMuX2hhbmRsZUhvdmVyKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZikge1xuICAgICAgdGhpcy5fb3ZlcmxheVJlZi5kaXNwb3NlKCk7XG4gICAgICB0aGlzLl9vdmVybGF5UmVmID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuX2hhbmRsZVRvdWNoU3RhcnQsXG4gICAgICAgIHBhc3NpdmVFdmVudExpc3RlbmVyT3B0aW9ucyk7XG5cbiAgICB0aGlzLl9tZW51Q2xvc2VTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9jbG9zaW5nQWN0aW9uc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX2hvdmVyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgbWVudSBpcyBvcGVuLiAqL1xuICBnZXQgbWVudU9wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX21lbnVPcGVuO1xuICB9XG5cbiAgLyoqIFRoZSB0ZXh0IGRpcmVjdGlvbiBvZiB0aGUgY29udGFpbmluZyBhcHAuICovXG4gIGdldCBkaXIoKTogRGlyZWN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5fZGlyICYmIHRoaXMuX2Rpci52YWx1ZSA9PT0gJ3J0bCcgPyAncnRsJyA6ICdsdHInO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIG1lbnUgdHJpZ2dlcnMgYSBzdWItbWVudSBvciBhIHRvcC1sZXZlbCBvbmUuICovXG4gIHRyaWdnZXJzU3VibWVudSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISEodGhpcy5fbWVudUl0ZW1JbnN0YW5jZSAmJiB0aGlzLl9wYXJlbnRNYXRlcmlhbE1lbnUpO1xuICB9XG5cbiAgLyoqIFRvZ2dsZXMgdGhlIG1lbnUgYmV0d2VlbiB0aGUgb3BlbiBhbmQgY2xvc2VkIHN0YXRlcy4gKi9cbiAgdG9nZ2xlTWVudSgpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5fbWVudU9wZW4gPyB0aGlzLmNsb3NlTWVudSgpIDogdGhpcy5vcGVuTWVudSgpO1xuICB9XG5cbiAgLyoqIE9wZW5zIHRoZSBtZW51LiAqL1xuICBvcGVuTWVudSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fbWVudU9wZW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGVja01lbnUoKTtcblxuICAgIGNvbnN0IG92ZXJsYXlSZWYgPSB0aGlzLl9jcmVhdGVPdmVybGF5KCk7XG4gICAgY29uc3Qgb3ZlcmxheUNvbmZpZyA9IG92ZXJsYXlSZWYuZ2V0Q29uZmlnKCk7XG5cbiAgICB0aGlzLl9zZXRQb3NpdGlvbihvdmVybGF5Q29uZmlnLnBvc2l0aW9uU3RyYXRlZ3kgYXMgRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5KTtcbiAgICBvdmVybGF5Q29uZmlnLmhhc0JhY2tkcm9wID0gdGhpcy5tZW51Lmhhc0JhY2tkcm9wID09IG51bGwgPyAhdGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSA6XG4gICAgICAgIHRoaXMubWVudS5oYXNCYWNrZHJvcDtcbiAgICBvdmVybGF5UmVmLmF0dGFjaCh0aGlzLl9nZXRQb3J0YWwoKSk7XG5cbiAgICBpZiAodGhpcy5tZW51LmxhenlDb250ZW50KSB7XG4gICAgICB0aGlzLm1lbnUubGF6eUNvbnRlbnQuYXR0YWNoKHRoaXMubWVudURhdGEpO1xuICAgIH1cblxuICAgIHRoaXMuX2Nsb3NpbmdBY3Rpb25zU3Vic2NyaXB0aW9uID0gdGhpcy5fbWVudUNsb3NpbmdBY3Rpb25zKCkuc3Vic2NyaWJlKCgpID0+IHRoaXMuY2xvc2VNZW51KCkpO1xuICAgIHRoaXMuX2luaXRNZW51KCk7XG5cbiAgICBpZiAodGhpcy5tZW51IGluc3RhbmNlb2YgX01hdE1lbnVCYXNlKSB7XG4gICAgICB0aGlzLm1lbnUuX3N0YXJ0QW5pbWF0aW9uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENsb3NlcyB0aGUgbWVudS4gKi9cbiAgY2xvc2VNZW51KCk6IHZvaWQge1xuICAgIHRoaXMubWVudS5jbG9zZS5lbWl0KCk7XG4gIH1cblxuICAvKipcbiAgICogRm9jdXNlcyB0aGUgbWVudSB0cmlnZ2VyLlxuICAgKiBAcGFyYW0gb3JpZ2luIFNvdXJjZSBvZiB0aGUgbWVudSB0cmlnZ2VyJ3MgZm9jdXMuXG4gICAqL1xuICBmb2N1cyhvcmlnaW4/OiBGb2N1c09yaWdpbiwgb3B0aW9ucz86IEZvY3VzT3B0aW9ucykge1xuICAgIGlmICh0aGlzLl9mb2N1c01vbml0b3IgJiYgb3JpZ2luKSB7XG4gICAgICB0aGlzLl9mb2N1c01vbml0b3IuZm9jdXNWaWEodGhpcy5fZWxlbWVudCwgb3JpZ2luLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZWxlbWVudC5uYXRpdmVFbGVtZW50LmZvY3VzKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBwb3NpdGlvbiBvZiB0aGUgbWVudSB0byBlbnN1cmUgdGhhdCBpdCBmaXRzIGFsbCBvcHRpb25zIHdpdGhpbiB0aGUgdmlld3BvcnQuXG4gICAqL1xuICB1cGRhdGVQb3NpdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9vdmVybGF5UmVmPy51cGRhdGVQb3NpdGlvbigpO1xuICB9XG5cbiAgLyoqIENsb3NlcyB0aGUgbWVudSBhbmQgZG9lcyB0aGUgbmVjZXNzYXJ5IGNsZWFudXAuICovXG4gIHByaXZhdGUgX2Rlc3Ryb3lNZW51KHJlYXNvbjogTWVudUNsb3NlUmVhc29uKSB7XG4gICAgaWYgKCF0aGlzLl9vdmVybGF5UmVmIHx8ICF0aGlzLm1lbnVPcGVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbWVudSA9IHRoaXMubWVudTtcbiAgICB0aGlzLl9jbG9zaW5nQWN0aW9uc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX292ZXJsYXlSZWYuZGV0YWNoKCk7XG5cbiAgICAvLyBBbHdheXMgcmVzdG9yZSBmb2N1cyBpZiB0aGUgdXNlciBpcyBuYXZpZ2F0aW5nIHVzaW5nIHRoZSBrZXlib2FyZCBvciB0aGUgbWVudSB3YXMgb3BlbmVkXG4gICAgLy8gcHJvZ3JhbW1hdGljYWxseS4gV2UgZG9uJ3QgcmVzdG9yZSBmb3Igbm9uLXJvb3QgdHJpZ2dlcnMsIGJlY2F1c2UgaXQgY2FuIHByZXZlbnQgZm9jdXNcbiAgICAvLyBmcm9tIG1ha2luZyBpdCBiYWNrIHRvIHRoZSByb290IHRyaWdnZXIgd2hlbiBjbG9zaW5nIGEgbG9uZyBjaGFpbiBvZiBtZW51cyBieSBjbGlja2luZ1xuICAgIC8vIG9uIHRoZSBiYWNrZHJvcC5cbiAgICBpZiAodGhpcy5yZXN0b3JlRm9jdXMgJiYgKHJlYXNvbiA9PT0gJ2tleWRvd24nIHx8ICF0aGlzLl9vcGVuZWRCeSB8fCAhdGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSkpIHtcbiAgICAgIHRoaXMuZm9jdXModGhpcy5fb3BlbmVkQnkpO1xuICAgIH1cblxuICAgIHRoaXMuX29wZW5lZEJ5ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKG1lbnUgaW5zdGFuY2VvZiBfTWF0TWVudUJhc2UpIHtcbiAgICAgIG1lbnUuX3Jlc2V0QW5pbWF0aW9uKCk7XG5cbiAgICAgIGlmIChtZW51LmxhenlDb250ZW50KSB7XG4gICAgICAgIC8vIFdhaXQgZm9yIHRoZSBleGl0IGFuaW1hdGlvbiB0byBmaW5pc2ggYmVmb3JlIGRldGFjaGluZyB0aGUgY29udGVudC5cbiAgICAgICAgbWVudS5fYW5pbWF0aW9uRG9uZVxuICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgZmlsdGVyKGV2ZW50ID0+IGV2ZW50LnRvU3RhdGUgPT09ICd2b2lkJyksXG4gICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgLy8gSW50ZXJydXB0IGlmIHRoZSBjb250ZW50IGdvdCByZS1hdHRhY2hlZC5cbiAgICAgICAgICAgIHRha2VVbnRpbChtZW51LmxhenlDb250ZW50Ll9hdHRhY2hlZClcbiAgICAgICAgICApXG4gICAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgICBuZXh0OiAoKSA9PiBtZW51LmxhenlDb250ZW50IS5kZXRhY2goKSxcbiAgICAgICAgICAgIC8vIE5vIG1hdHRlciB3aGV0aGVyIHRoZSBjb250ZW50IGdvdCByZS1hdHRhY2hlZCwgcmVzZXQgdGhlIG1lbnUuXG4gICAgICAgICAgICBjb21wbGV0ZTogKCkgPT4gdGhpcy5fc2V0SXNNZW51T3BlbihmYWxzZSlcbiAgICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3NldElzTWVudU9wZW4oZmFsc2UpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXRJc01lbnVPcGVuKGZhbHNlKTtcblxuICAgICAgaWYgKG1lbnUubGF6eUNvbnRlbnQpIHtcbiAgICAgICAgbWVudS5sYXp5Q29udGVudC5kZXRhY2goKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc2V0cyB0aGUgbWVudSBzdGF0ZSB0byBvcGVuIGFuZCBmb2N1c2VzIHRoZSBmaXJzdCBpdGVtIGlmXG4gICAqIHRoZSBtZW51IHdhcyBvcGVuZWQgdmlhIHRoZSBrZXlib2FyZC5cbiAgICovXG4gIHByaXZhdGUgX2luaXRNZW51KCk6IHZvaWQge1xuICAgIHRoaXMubWVudS5wYXJlbnRNZW51ID0gdGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSA/IHRoaXMuX3BhcmVudE1hdGVyaWFsTWVudSA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLm1lbnUuZGlyZWN0aW9uID0gdGhpcy5kaXI7XG4gICAgdGhpcy5fc2V0TWVudUVsZXZhdGlvbigpO1xuICAgIHRoaXMubWVudS5mb2N1c0ZpcnN0SXRlbSh0aGlzLl9vcGVuZWRCeSB8fCAncHJvZ3JhbScpO1xuICAgIHRoaXMuX3NldElzTWVudU9wZW4odHJ1ZSk7XG4gIH1cblxuICAvKiogVXBkYXRlcyB0aGUgbWVudSBlbGV2YXRpb24gYmFzZWQgb24gdGhlIGFtb3VudCBvZiBwYXJlbnQgbWVudXMgdGhhdCBpdCBoYXMuICovXG4gIHByaXZhdGUgX3NldE1lbnVFbGV2YXRpb24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubWVudS5zZXRFbGV2YXRpb24pIHtcbiAgICAgIGxldCBkZXB0aCA9IDA7XG4gICAgICBsZXQgcGFyZW50TWVudSA9IHRoaXMubWVudS5wYXJlbnRNZW51O1xuXG4gICAgICB3aGlsZSAocGFyZW50TWVudSkge1xuICAgICAgICBkZXB0aCsrO1xuICAgICAgICBwYXJlbnRNZW51ID0gcGFyZW50TWVudS5wYXJlbnRNZW51O1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1lbnUuc2V0RWxldmF0aW9uKGRlcHRoKTtcbiAgICB9XG4gIH1cblxuICAvLyBzZXQgc3RhdGUgcmF0aGVyIHRoYW4gdG9nZ2xlIHRvIHN1cHBvcnQgdHJpZ2dlcnMgc2hhcmluZyBhIG1lbnVcbiAgcHJpdmF0ZSBfc2V0SXNNZW51T3Blbihpc09wZW46IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLl9tZW51T3BlbiA9IGlzT3BlbjtcbiAgICB0aGlzLl9tZW51T3BlbiA/IHRoaXMubWVudU9wZW5lZC5lbWl0KCkgOiB0aGlzLm1lbnVDbG9zZWQuZW1pdCgpO1xuXG4gICAgaWYgKHRoaXMudHJpZ2dlcnNTdWJtZW51KCkpIHtcbiAgICAgIHRoaXMuX21lbnVJdGVtSW5zdGFuY2UuX3NldEhpZ2hsaWdodGVkKGlzT3Blbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGNoZWNrcyB0aGF0IGEgdmFsaWQgaW5zdGFuY2Ugb2YgTWF0TWVudSBoYXMgYmVlbiBwYXNzZWQgaW50b1xuICAgKiBtYXRNZW51VHJpZ2dlckZvci4gSWYgbm90LCBhbiBleGNlcHRpb24gaXMgdGhyb3duLlxuICAgKi9cbiAgcHJpdmF0ZSBfY2hlY2tNZW51KCkge1xuICAgIGlmICghdGhpcy5tZW51ICYmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpKSB7XG4gICAgICB0aHJvd01hdE1lbnVNaXNzaW5nRXJyb3IoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgY3JlYXRlcyB0aGUgb3ZlcmxheSBmcm9tIHRoZSBwcm92aWRlZCBtZW51J3MgdGVtcGxhdGUgYW5kIHNhdmVzIGl0c1xuICAgKiBPdmVybGF5UmVmIHNvIHRoYXQgaXQgY2FuIGJlIGF0dGFjaGVkIHRvIHRoZSBET00gd2hlbiBvcGVuTWVudSBpcyBjYWxsZWQuXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVPdmVybGF5KCk6IE92ZXJsYXlSZWYge1xuICAgIGlmICghdGhpcy5fb3ZlcmxheVJlZikge1xuICAgICAgY29uc3QgY29uZmlnID0gdGhpcy5fZ2V0T3ZlcmxheUNvbmZpZygpO1xuICAgICAgdGhpcy5fc3Vic2NyaWJlVG9Qb3NpdGlvbnMoY29uZmlnLnBvc2l0aW9uU3RyYXRlZ3kgYXMgRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5KTtcbiAgICAgIHRoaXMuX292ZXJsYXlSZWYgPSB0aGlzLl9vdmVybGF5LmNyZWF0ZShjb25maWcpO1xuXG4gICAgICAvLyBDb25zdW1lIHRoZSBga2V5ZG93bkV2ZW50c2AgaW4gb3JkZXIgdG8gcHJldmVudCB0aGVtIGZyb20gZ29pbmcgdG8gYW5vdGhlciBvdmVybGF5LlxuICAgICAgLy8gSWRlYWxseSB3ZSdkIGFsc28gaGF2ZSBvdXIga2V5Ym9hcmQgZXZlbnQgbG9naWMgaW4gaGVyZSwgaG93ZXZlciBkb2luZyBzbyB3aWxsXG4gICAgICAvLyBicmVhayBhbnlib2R5IHRoYXQgbWF5IGhhdmUgaW1wbGVtZW50ZWQgdGhlIGBNYXRNZW51UGFuZWxgIHRoZW1zZWx2ZXMuXG4gICAgICB0aGlzLl9vdmVybGF5UmVmLmtleWRvd25FdmVudHMoKS5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fb3ZlcmxheVJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBidWlsZHMgdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IG5lZWRlZCB0byBjcmVhdGUgdGhlIG92ZXJsYXksIHRoZSBPdmVybGF5U3RhdGUuXG4gICAqIEByZXR1cm5zIE92ZXJsYXlDb25maWdcbiAgICovXG4gIHByaXZhdGUgX2dldE92ZXJsYXlDb25maWcoKTogT3ZlcmxheUNvbmZpZyB7XG4gICAgcmV0dXJuIG5ldyBPdmVybGF5Q29uZmlnKHtcbiAgICAgIHBvc2l0aW9uU3RyYXRlZ3k6IHRoaXMuX292ZXJsYXkucG9zaXRpb24oKVxuICAgICAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHRoaXMuX2VsZW1lbnQpXG4gICAgICAgICAgLndpdGhMb2NrZWRQb3NpdGlvbigpXG4gICAgICAgICAgLndpdGhHcm93QWZ0ZXJPcGVuKClcbiAgICAgICAgICAud2l0aFRyYW5zZm9ybU9yaWdpbk9uKCcubWF0LW1lbnUtcGFuZWwsIC5tYXQtbWRjLW1lbnUtcGFuZWwnKSxcbiAgICAgIGJhY2tkcm9wQ2xhc3M6IHRoaXMubWVudS5iYWNrZHJvcENsYXNzIHx8ICdjZGstb3ZlcmxheS10cmFuc3BhcmVudC1iYWNrZHJvcCcsXG4gICAgICBwYW5lbENsYXNzOiB0aGlzLm1lbnUub3ZlcmxheVBhbmVsQ2xhc3MsXG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5fc2Nyb2xsU3RyYXRlZ3koKSxcbiAgICAgIGRpcmVjdGlvbjogdGhpcy5fZGlyXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVucyB0byBjaGFuZ2VzIGluIHRoZSBwb3NpdGlvbiBvZiB0aGUgb3ZlcmxheSBhbmQgc2V0cyB0aGUgY29ycmVjdCBjbGFzc2VzXG4gICAqIG9uIHRoZSBtZW51IGJhc2VkIG9uIHRoZSBuZXcgcG9zaXRpb24uIFRoaXMgZW5zdXJlcyB0aGUgYW5pbWF0aW9uIG9yaWdpbiBpcyBhbHdheXNcbiAgICogY29ycmVjdCwgZXZlbiBpZiBhIGZhbGxiYWNrIHBvc2l0aW9uIGlzIHVzZWQgZm9yIHRoZSBvdmVybGF5LlxuICAgKi9cbiAgcHJpdmF0ZSBfc3Vic2NyaWJlVG9Qb3NpdGlvbnMocG9zaXRpb246IEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnUuc2V0UG9zaXRpb25DbGFzc2VzKSB7XG4gICAgICBwb3NpdGlvbi5wb3NpdGlvbkNoYW5nZXMuc3Vic2NyaWJlKGNoYW5nZSA9PiB7XG4gICAgICAgIGNvbnN0IHBvc1g6IE1lbnVQb3NpdGlvblggPSBjaGFuZ2UuY29ubmVjdGlvblBhaXIub3ZlcmxheVggPT09ICdzdGFydCcgPyAnYWZ0ZXInIDogJ2JlZm9yZSc7XG4gICAgICAgIGNvbnN0IHBvc1k6IE1lbnVQb3NpdGlvblkgPSBjaGFuZ2UuY29ubmVjdGlvblBhaXIub3ZlcmxheVkgPT09ICd0b3AnID8gJ2JlbG93JyA6ICdhYm92ZSc7XG5cbiAgICAgICAgdGhpcy5tZW51LnNldFBvc2l0aW9uQ2xhc3NlcyEocG9zWCwgcG9zWSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgYXBwcm9wcmlhdGUgcG9zaXRpb25zIG9uIGEgcG9zaXRpb24gc3RyYXRlZ3lcbiAgICogc28gdGhlIG92ZXJsYXkgY29ubmVjdHMgd2l0aCB0aGUgdHJpZ2dlciBjb3JyZWN0bHkuXG4gICAqIEBwYXJhbSBwb3NpdGlvblN0cmF0ZWd5IFN0cmF0ZWd5IHdob3NlIHBvc2l0aW9uIHRvIHVwZGF0ZS5cbiAgICovXG4gIHByaXZhdGUgX3NldFBvc2l0aW9uKHBvc2l0aW9uU3RyYXRlZ3k6IEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneSkge1xuICAgIGxldCBbb3JpZ2luWCwgb3JpZ2luRmFsbGJhY2tYXTogSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3NbXSA9XG4gICAgICAgIHRoaXMubWVudS54UG9zaXRpb24gPT09ICdiZWZvcmUnID8gWydlbmQnLCAnc3RhcnQnXSA6IFsnc3RhcnQnLCAnZW5kJ107XG5cbiAgICBsZXQgW292ZXJsYXlZLCBvdmVybGF5RmFsbGJhY2tZXTogVmVydGljYWxDb25uZWN0aW9uUG9zW10gPVxuICAgICAgICB0aGlzLm1lbnUueVBvc2l0aW9uID09PSAnYWJvdmUnID8gWydib3R0b20nLCAndG9wJ10gOiBbJ3RvcCcsICdib3R0b20nXTtcblxuICAgIGxldCBbb3JpZ2luWSwgb3JpZ2luRmFsbGJhY2tZXSA9IFtvdmVybGF5WSwgb3ZlcmxheUZhbGxiYWNrWV07XG4gICAgbGV0IFtvdmVybGF5WCwgb3ZlcmxheUZhbGxiYWNrWF0gPSBbb3JpZ2luWCwgb3JpZ2luRmFsbGJhY2tYXTtcbiAgICBsZXQgb2Zmc2V0WSA9IDA7XG5cbiAgICBpZiAodGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSkge1xuICAgICAgLy8gV2hlbiB0aGUgbWVudSBpcyBhIHN1Yi1tZW51LCBpdCBzaG91bGQgYWx3YXlzIGFsaWduIGl0c2VsZlxuICAgICAgLy8gdG8gdGhlIGVkZ2VzIG9mIHRoZSB0cmlnZ2VyLCBpbnN0ZWFkIG9mIG92ZXJsYXBwaW5nIGl0LlxuICAgICAgb3ZlcmxheUZhbGxiYWNrWCA9IG9yaWdpblggPSB0aGlzLm1lbnUueFBvc2l0aW9uID09PSAnYmVmb3JlJyA/ICdzdGFydCcgOiAnZW5kJztcbiAgICAgIG9yaWdpbkZhbGxiYWNrWCA9IG92ZXJsYXlYID0gb3JpZ2luWCA9PT0gJ2VuZCcgPyAnc3RhcnQnIDogJ2VuZCc7XG4gICAgICBvZmZzZXRZID0gb3ZlcmxheVkgPT09ICdib3R0b20nID8gTUVOVV9QQU5FTF9UT1BfUEFERElORyA6IC1NRU5VX1BBTkVMX1RPUF9QQURESU5HO1xuICAgIH0gZWxzZSBpZiAoIXRoaXMubWVudS5vdmVybGFwVHJpZ2dlcikge1xuICAgICAgb3JpZ2luWSA9IG92ZXJsYXlZID09PSAndG9wJyA/ICdib3R0b20nIDogJ3RvcCc7XG4gICAgICBvcmlnaW5GYWxsYmFja1kgPSBvdmVybGF5RmFsbGJhY2tZID09PSAndG9wJyA/ICdib3R0b20nIDogJ3RvcCc7XG4gICAgfVxuXG4gICAgcG9zaXRpb25TdHJhdGVneS53aXRoUG9zaXRpb25zKFtcbiAgICAgIHtvcmlnaW5YLCBvcmlnaW5ZLCBvdmVybGF5WCwgb3ZlcmxheVksIG9mZnNldFl9LFxuICAgICAge29yaWdpblg6IG9yaWdpbkZhbGxiYWNrWCwgb3JpZ2luWSwgb3ZlcmxheVg6IG92ZXJsYXlGYWxsYmFja1gsIG92ZXJsYXlZLCBvZmZzZXRZfSxcbiAgICAgIHtcbiAgICAgICAgb3JpZ2luWCxcbiAgICAgICAgb3JpZ2luWTogb3JpZ2luRmFsbGJhY2tZLFxuICAgICAgICBvdmVybGF5WCxcbiAgICAgICAgb3ZlcmxheVk6IG92ZXJsYXlGYWxsYmFja1ksXG4gICAgICAgIG9mZnNldFk6IC1vZmZzZXRZXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBvcmlnaW5YOiBvcmlnaW5GYWxsYmFja1gsXG4gICAgICAgIG9yaWdpblk6IG9yaWdpbkZhbGxiYWNrWSxcbiAgICAgICAgb3ZlcmxheVg6IG92ZXJsYXlGYWxsYmFja1gsXG4gICAgICAgIG92ZXJsYXlZOiBvdmVybGF5RmFsbGJhY2tZLFxuICAgICAgICBvZmZzZXRZOiAtb2Zmc2V0WVxuICAgICAgfVxuICAgIF0pO1xuICB9XG5cbiAgLyoqIFJldHVybnMgYSBzdHJlYW0gdGhhdCBlbWl0cyB3aGVuZXZlciBhbiBhY3Rpb24gdGhhdCBzaG91bGQgY2xvc2UgdGhlIG1lbnUgb2NjdXJzLiAqL1xuICBwcml2YXRlIF9tZW51Q2xvc2luZ0FjdGlvbnMoKSB7XG4gICAgY29uc3QgYmFja2Ryb3AgPSB0aGlzLl9vdmVybGF5UmVmIS5iYWNrZHJvcENsaWNrKCk7XG4gICAgY29uc3QgZGV0YWNobWVudHMgPSB0aGlzLl9vdmVybGF5UmVmIS5kZXRhY2htZW50cygpO1xuICAgIGNvbnN0IHBhcmVudENsb3NlID0gdGhpcy5fcGFyZW50TWF0ZXJpYWxNZW51ID8gdGhpcy5fcGFyZW50TWF0ZXJpYWxNZW51LmNsb3NlZCA6IG9ic2VydmFibGVPZigpO1xuICAgIGNvbnN0IGhvdmVyID0gdGhpcy5fcGFyZW50TWF0ZXJpYWxNZW51ID8gdGhpcy5fcGFyZW50TWF0ZXJpYWxNZW51Ll9ob3ZlcmVkKCkucGlwZShcbiAgICAgIGZpbHRlcihhY3RpdmUgPT4gYWN0aXZlICE9PSB0aGlzLl9tZW51SXRlbUluc3RhbmNlKSxcbiAgICAgIGZpbHRlcigoKSA9PiB0aGlzLl9tZW51T3BlbilcbiAgICApIDogb2JzZXJ2YWJsZU9mKCk7XG5cbiAgICByZXR1cm4gbWVyZ2UoYmFja2Ryb3AsIHBhcmVudENsb3NlIGFzIE9ic2VydmFibGU8TWVudUNsb3NlUmVhc29uPiwgaG92ZXIsIGRldGFjaG1lbnRzKTtcbiAgfVxuXG4gIC8qKiBIYW5kbGVzIG1vdXNlIHByZXNzZXMgb24gdGhlIHRyaWdnZXIuICovXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZG93bicsIFsnJGV2ZW50J10pXG4gIF9oYW5kbGVNb3VzZWRvd24oZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIWlzRmFrZU1vdXNlZG93bkZyb21TY3JlZW5SZWFkZXIoZXZlbnQpKSB7XG4gICAgICAvLyBTaW5jZSByaWdodCBvciBtaWRkbGUgYnV0dG9uIGNsaWNrcyB3b24ndCB0cmlnZ2VyIHRoZSBgY2xpY2tgIGV2ZW50LFxuICAgICAgLy8gd2Ugc2hvdWxkbid0IGNvbnNpZGVyIHRoZSBtZW51IGFzIG9wZW5lZCBieSBtb3VzZSBpbiB0aG9zZSBjYXNlcy5cbiAgICAgIHRoaXMuX29wZW5lZEJ5ID0gZXZlbnQuYnV0dG9uID09PSAwID8gJ21vdXNlJyA6IHVuZGVmaW5lZDtcblxuICAgICAgLy8gU2luY2UgY2xpY2tpbmcgb24gdGhlIHRyaWdnZXIgd29uJ3QgY2xvc2UgdGhlIG1lbnUgaWYgaXQgb3BlbnMgYSBzdWItbWVudSxcbiAgICAgIC8vIHdlIHNob3VsZCBwcmV2ZW50IGZvY3VzIGZyb20gbW92aW5nIG9udG8gaXQgdmlhIGNsaWNrIHRvIGF2b2lkIHRoZVxuICAgICAgLy8gaGlnaGxpZ2h0IGZyb20gbGluZ2VyaW5nIG9uIHRoZSBtZW51IGl0ZW0uXG4gICAgICBpZiAodGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBIYW5kbGVzIGtleSBwcmVzc2VzIG9uIHRoZSB0cmlnZ2VyLiAqL1xuICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcbiAgX2hhbmRsZUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcblxuICAgIC8vIFByZXNzaW5nIGVudGVyIG9uIHRoZSB0cmlnZ2VyIHdpbGwgdHJpZ2dlciB0aGUgY2xpY2sgaGFuZGxlciBsYXRlci5cbiAgICBpZiAoa2V5Q29kZSA9PT0gRU5URVIgfHwga2V5Q29kZSA9PT0gU1BBQ0UpIHtcbiAgICAgIHRoaXMuX29wZW5lZEJ5ID0gJ2tleWJvYXJkJztcbiAgICB9XG5cbiAgICBpZiAodGhpcy50cmlnZ2Vyc1N1Ym1lbnUoKSAmJiAoXG4gICAgICAgICAgICAoa2V5Q29kZSA9PT0gUklHSFRfQVJST1cgJiYgdGhpcy5kaXIgPT09ICdsdHInKSB8fFxuICAgICAgICAgICAgKGtleUNvZGUgPT09IExFRlRfQVJST1cgJiYgdGhpcy5kaXIgPT09ICdydGwnKSkpIHtcbiAgICAgIHRoaXMuX29wZW5lZEJ5ID0gJ2tleWJvYXJkJztcbiAgICAgIHRoaXMub3Blbk1lbnUoKTtcbiAgICB9XG4gIH1cblxuICAvKiogSGFuZGxlcyBjbGljayBldmVudHMgb24gdGhlIHRyaWdnZXIuICovXG4gIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJywgWyckZXZlbnQnXSlcbiAgX2hhbmRsZUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMudHJpZ2dlcnNTdWJtZW51KCkpIHtcbiAgICAgIC8vIFN0b3AgZXZlbnQgcHJvcGFnYXRpb24gdG8gYXZvaWQgY2xvc2luZyB0aGUgcGFyZW50IG1lbnUuXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHRoaXMub3Blbk1lbnUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2dnbGVNZW51KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEhhbmRsZXMgdGhlIGNhc2VzIHdoZXJlIHRoZSB1c2VyIGhvdmVycyBvdmVyIHRoZSB0cmlnZ2VyLiAqL1xuICBwcml2YXRlIF9oYW5kbGVIb3ZlcigpIHtcbiAgICAvLyBTdWJzY3JpYmUgdG8gY2hhbmdlcyBpbiB0aGUgaG92ZXJlZCBpdGVtIGluIG9yZGVyIHRvIHRvZ2dsZSB0aGUgcGFuZWwuXG4gICAgaWYgKCF0aGlzLnRyaWdnZXJzU3VibWVudSgpIHx8ICF0aGlzLl9wYXJlbnRNYXRlcmlhbE1lbnUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9ob3ZlclN1YnNjcmlwdGlvbiA9IHRoaXMuX3BhcmVudE1hdGVyaWFsTWVudS5faG92ZXJlZCgpXG4gICAgICAvLyBTaW5jZSB3ZSBtaWdodCBoYXZlIG11bHRpcGxlIGNvbXBldGluZyB0cmlnZ2VycyBmb3IgdGhlIHNhbWUgbWVudSAoZS5nLiBhIHN1Yi1tZW51XG4gICAgICAvLyB3aXRoIGRpZmZlcmVudCBkYXRhIGFuZCB0cmlnZ2VycyksIHdlIGhhdmUgdG8gZGVsYXkgaXQgYnkgYSB0aWNrIHRvIGVuc3VyZSB0aGF0XG4gICAgICAvLyBpdCB3b24ndCBiZSBjbG9zZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgaXQgaXMgb3BlbmVkLlxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcihhY3RpdmUgPT4gYWN0aXZlID09PSB0aGlzLl9tZW51SXRlbUluc3RhbmNlICYmICFhY3RpdmUuZGlzYWJsZWQpLFxuICAgICAgICBkZWxheSgwLCBhc2FwU2NoZWR1bGVyKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX29wZW5lZEJ5ID0gJ21vdXNlJztcblxuICAgICAgICAvLyBJZiB0aGUgc2FtZSBtZW51IGlzIHVzZWQgYmV0d2VlbiBtdWx0aXBsZSB0cmlnZ2VycywgaXQgbWlnaHQgc3RpbGwgYmUgYW5pbWF0aW5nXG4gICAgICAgIC8vIHdoaWxlIHRoZSBuZXcgdHJpZ2dlciB0cmllcyB0byByZS1vcGVuIGl0LiBXYWl0IGZvciB0aGUgYW5pbWF0aW9uIHRvIGZpbmlzaFxuICAgICAgICAvLyBiZWZvcmUgZG9pbmcgc28uIEFsc28gaW50ZXJydXB0IGlmIHRoZSB1c2VyIG1vdmVzIHRvIGFub3RoZXIgaXRlbS5cbiAgICAgICAgaWYgKHRoaXMubWVudSBpbnN0YW5jZW9mIF9NYXRNZW51QmFzZSAmJiB0aGlzLm1lbnUuX2lzQW5pbWF0aW5nKSB7XG4gICAgICAgICAgLy8gV2UgbmVlZCB0aGUgYGRlbGF5KDApYCBoZXJlIGluIG9yZGVyIHRvIGF2b2lkXG4gICAgICAgICAgLy8gJ2NoYW5nZWQgYWZ0ZXIgY2hlY2tlZCcgZXJyb3JzIGluIHNvbWUgY2FzZXMuIFNlZSAjMTIxOTQuXG4gICAgICAgICAgdGhpcy5tZW51Ll9hbmltYXRpb25Eb25lXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpLCBkZWxheSgwLCBhc2FwU2NoZWR1bGVyKSwgdGFrZVVudGlsKHRoaXMuX3BhcmVudE1hdGVyaWFsTWVudSEuX2hvdmVyZWQoKSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMub3Blbk1lbnUoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5vcGVuTWVudSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBHZXRzIHRoZSBwb3J0YWwgdGhhdCBzaG91bGQgYmUgYXR0YWNoZWQgdG8gdGhlIG92ZXJsYXkuICovXG4gIHByaXZhdGUgX2dldFBvcnRhbCgpOiBUZW1wbGF0ZVBvcnRhbCB7XG4gICAgLy8gTm90ZSB0aGF0IHdlIGNhbiBhdm9pZCB0aGlzIGNoZWNrIGJ5IGtlZXBpbmcgdGhlIHBvcnRhbCBvbiB0aGUgbWVudSBwYW5lbC5cbiAgICAvLyBXaGlsZSBpdCB3b3VsZCBiZSBjbGVhbmVyLCB3ZSdkIGhhdmUgdG8gaW50cm9kdWNlIGFub3RoZXIgcmVxdWlyZWQgbWV0aG9kIG9uXG4gICAgLy8gYE1hdE1lbnVQYW5lbGAsIG1ha2luZyBpdCBoYXJkZXIgdG8gY29uc3VtZS5cbiAgICBpZiAoIXRoaXMuX3BvcnRhbCB8fCB0aGlzLl9wb3J0YWwudGVtcGxhdGVSZWYgIT09IHRoaXMubWVudS50ZW1wbGF0ZVJlZikge1xuICAgICAgdGhpcy5fcG9ydGFsID0gbmV3IFRlbXBsYXRlUG9ydGFsKHRoaXMubWVudS50ZW1wbGF0ZVJlZiwgdGhpcy5fdmlld0NvbnRhaW5lclJlZik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3BvcnRhbDtcbiAgfVxuXG59XG5cbi8qKiBEaXJlY3RpdmUgYXBwbGllZCB0byBhbiBlbGVtZW50IHRoYXQgc2hvdWxkIHRyaWdnZXIgYSBgbWF0LW1lbnVgLiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiBgW21hdC1tZW51LXRyaWdnZXItZm9yXSwgW21hdE1lbnVUcmlnZ2VyRm9yXWAsXG4gIGhvc3Q6IHtcbiAgICAnY2xhc3MnOiAnbWF0LW1lbnUtdHJpZ2dlcicsXG4gIH0sXG4gIGV4cG9ydEFzOiAnbWF0TWVudVRyaWdnZXInXG59KVxuZXhwb3J0IGNsYXNzIE1hdE1lbnVUcmlnZ2VyIGV4dGVuZHMgX01hdE1lbnVUcmlnZ2VyQmFzZSB7fVxuIl19
|