@blox/material
Version:
Material Components for Angular
453 lines • 52.8 kB
JavaScript
import { ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, Renderer2, Self, Inject, HostListener, forwardRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { MDCDialogFoundation, util, cssClasses } from '@material/dialog';
import { ponyfill } from '@material/dom';
import { MdcEventRegistry } from '../../utils/mdc.event.registry';
import { MdcButtonDirective } from '../button/mdc.button.directive';
import { AbstractMdcFocusInitial, AbstractMdcFocusTrap } from '../focus-trap/abstract.mdc.focus-trap';
import { HasId } from '../abstract/mixin.mdc.hasid';
import { applyMixins } from '../../utils/mixins';
class MdcDialogTitleDirectiveBase {
}
MdcDialogTitleDirectiveBase.decorators = [
{ type: Directive }
];
applyMixins(MdcDialogTitleDirectiveBase, [HasId]);
/**
* Directive for the title of an `mdcDialog`.
* A title is optional. If used, it should be the first child of an `mdcDialogSurface`.
* Please note that there should be no whitespace separating the start/end tag and the title
* itself. (The easiest way to achieve this is to *not* set the `preserveWhitespaces` option to
* `true` the `angularCompilerOptions`).
*/
export class MdcDialogTitleDirective extends MdcDialogTitleDirectiveBase {
constructor() {
super(...arguments);
/** @internal */
this._cls = true;
}
ngOnInit() {
this.initId();
}
}
MdcDialogTitleDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogTitle]'
},] }
];
MdcDialogTitleDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__title',] }]
};
class MdcDialogContentDirectiveBase {
}
MdcDialogContentDirectiveBase.decorators = [
{ type: Directive }
];
applyMixins(MdcDialogContentDirectiveBase, [HasId]);
/**
* Directive for the content part of an `mdcDialog`.
* This should be added as a child element of an `mdcDialogSurface`.
*/
export class MdcDialogContentDirective extends MdcDialogContentDirectiveBase {
constructor(_elm) {
super();
this._elm = _elm;
/** @internal */
this._cls = true;
}
ngOnInit() {
this.initId();
}
}
MdcDialogContentDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogContent]'
},] }
];
MdcDialogContentDirective.ctorParameters = () => [
{ type: ElementRef }
];
MdcDialogContentDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__content',] }]
};
/**
* Directive for the actions (footer) of an `mdcDialog`.
* This is an (optional) last child of the `mdcDialogSurface` directive.
* This directive should contain buttons, for that should use the `mdcButton`
* directive.
*
* Action buttons should typically close the dialog, and should therefore
* also set a value for the `mdcDialogTrigger` directive.
*/
export class MdcDialogActionsDirective {
constructor(_rndr) {
this._rndr = _rndr;
/** @internal */
this._cls = true;
}
ngAfterContentInit() {
this.initButtons();
this._buttons.changes.subscribe(() => {
this.initButtons();
});
}
initButtons() {
this._buttons.forEach(btn => {
this._rndr.addClass(btn._elm.nativeElement, 'mdc-dialog__button');
});
}
}
MdcDialogActionsDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogActions]',
},] }
];
MdcDialogActionsDirective.ctorParameters = () => [
{ type: Renderer2 }
];
MdcDialogActionsDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__actions',] }],
_buttons: [{ type: ContentChildren, args: [MdcButtonDirective, { descendants: true },] }]
};
/**
* Any element within a dialog may include this directive (and assigne a non empty value to it)
* to indicate that interacting with it should close the dialog with the specified action.
*
* This action is then reflected via the `action` field in the `closing` and `closed` events of
* the dialog. A value of `close` will also trigger the `cancel` event of the dialog, and a value of
* `accept` will trigger the `accept` event.
*
* Any action buttons within the dialog that equate to a dismissal with no further action should
* use set `mdcDialogTrigger="close"`. This will make it easy to handle all such interactions consistently
* (via either the `cancel`, `closing`, or `closed` events), while separately handling other actions.
*/
export class MdcDialogTriggerDirective {
constructor(_elm) {
this._elm = _elm;
/**
* Set the `action` value that should be send to `closing` and `closed` events when a user
* interacts with this element. (When set to an empty string the button/element will not be wired
* to close the dialog).
*/
this.mdcDialogTrigger = null;
}
}
MdcDialogTriggerDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogTrigger]'
},] }
];
MdcDialogTriggerDirective.ctorParameters = () => [
{ type: ElementRef }
];
MdcDialogTriggerDirective.propDecorators = {
mdcDialogTrigger: [{ type: Input }]
};
/**
* This directive can be used to mark one of the dialogs action buttons as the default action.
* This action will then be triggered by pressing the enter key while the dialog has focus.
* The default action also will receive focus when the dialog is opened. Unless another
* element within the dialog has the `mdcFocusInitial` directive.
*/
export class MdcDialogDefaultDirective extends AbstractMdcFocusInitial {
constructor(_elm) {
super();
this._elm = _elm;
/** @internal */ this.priority = 0; // must be lower than prio of MdcFocusInitialDirective
}
}
MdcDialogDefaultDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogDefault]',
providers: [{ provide: AbstractMdcFocusInitial, useExisting: forwardRef(() => MdcDialogDefaultDirective) }]
},] }
];
MdcDialogDefaultDirective.ctorParameters = () => [
{ type: ElementRef }
];
/**
* Directive for the surface of a dialog. The surface contains the actual content of a dialog,
* wrapped in elements with the `mdcDialogHeader`, `mdcDialogContent`, and `mdcDialogActions`
* directives.
*
* # Accessibility
* * The role attribute will be set to `alertdialog` by default
* * The `aria-modal` attribute will be set to `true` by default
* * If there is an `mdcDialogTitle`, the `aria-labelledBy` attribute will be set to the id
* of that element (and a unique id will be assigned to it, if none was provided)
* * If there is an `mdcDialogContent`, the `aria-describedby` attribute will be set to the
* id of that element (and a unique id will be assigned to it, if none was provided)
*/
export class MdcDialogSurfaceDirective {
constructor() {
/** @internal */
this._cls = true;
/** @internal */
this._role = 'alertdialog';
/** @internal */
this._modal = 'true';
/** @internal */
this._labelledBy = null;
/** @internal */
this._describedBy = null;
}
ngAfterContentInit() {
this._titles.changes.subscribe(() => this.setAriaLabels());
this._contents.changes.subscribe(() => this.setAriaLabels());
this.setAriaLabels();
}
setAriaLabels() {
var _a, _b;
this._labelledBy = (_a = this._titles.first) === null || _a === void 0 ? void 0 : _a.id;
this._describedBy = (_b = this._contents.first) === null || _b === void 0 ? void 0 : _b.id;
}
}
MdcDialogSurfaceDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogSurface]'
},] }
];
MdcDialogSurfaceDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__surface',] }],
_role: [{ type: HostBinding, args: ['attr.role',] }],
_modal: [{ type: HostBinding, args: ['attr.aria-modal',] }],
_labelledBy: [{ type: HostBinding, args: ['attr.aria-labelledby',] }],
_describedBy: [{ type: HostBinding, args: ['attr.aria-describedby',] }],
_titles: [{ type: ContentChildren, args: [MdcDialogTitleDirective,] }],
_contents: [{ type: ContentChildren, args: [MdcDialogContentDirective,] }]
};
/**
* This directive should be the first child of an `mdcDialog`, and contains the `mdcDialogSurface`.
*/
export class MdcDialogContainerDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDialogContainerDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogContainer]'
},] }
];
MdcDialogContainerDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__container',] }]
};
/**
* Directive for the backdrop of a dialog. The backdrop provides the styles for overlaying the
* page content when the dialog is opened. This guides user attention to the dialog.
*/
export class MdcDialogScrimDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDialogScrimDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialogScrim]'
},] }
];
MdcDialogScrimDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog__scrim',] }]
};
/**
* Directive for creating a modal dialog with Material Design styling. The dialog should have two
* child elements: a surface (marked with the <code>mdcDialogSurface</code> directive), and a
* backdrop (marked with the <code>mdcDialogBackdrop</code> directive).
*
* When the dialog is opened, it will activate a focus trap on the elements within the dialog,
* so that the surface behind the dialog is not accessible. See `mdcFocusTrap` for more information.
*/
export class MdcDialogDirective {
constructor(_elm, _rndr, _registry, _focusTrap, doc) {
this._elm = _elm;
this._rndr = _rndr;
this._registry = _registry;
this._focusTrap = _focusTrap;
/** @internal */
this._cls = true;
/** @internal */
this._surface = null;
/**
* Event emitted when the user accepts the dialog, e.g. by pressing enter or clicking the button
* with `mdcDialogTrigger="accept"`.
*/
this.accept = new EventEmitter();
/**
* Event emitted when the user cancels the dialog, e.g. by clicking outside the dialog, pressing the escape key,
* or clicking an element with `mdcDialogTrigger="close"`.
*/
this.cancel = new EventEmitter();
/**
* Event emitted when the dialog starts opening.
*/
this.opening = new EventEmitter();
/**
* Event emitted when the dialog is opened.
*/
this.opened = new EventEmitter();
/**
* Event emitted when the dialog starts closing. The 'action' field contains the reason for closing, see
* `mdcDialogTrigger` for more information.
*/
this.closing = new EventEmitter();
/**
* Event emitted when the dialog is closed. The 'action' field contains the reason for closing, see
* `mdcDialogTrigger` for more information.
*/
this.closed = new EventEmitter();
this._onDocumentKeydown = (event) => this.onDocumentKeydown(event);
this.focusTrapHandle = null;
this.mdcAdapter = {
addClass: (className) => this._rndr.addClass(this._elm.nativeElement, className),
removeClass: (className) => this._rndr.removeClass(this._elm.nativeElement, className),
addBodyClass: (className) => this._rndr.addClass(this.document.body, className),
removeBodyClass: (className) => this._rndr.removeClass(this.document.body, className),
areButtonsStacked: () => { var _a, _b; return ((_a = this._footers) === null || _a === void 0 ? void 0 : _a.first) ? util.areTopsMisaligned((_b = this._footers.first) === null || _b === void 0 ? void 0 : _b._buttons.map(b => b._elm.nativeElement)) : false; },
clickDefaultButton: () => { var _a, _b; return (_b = (_a = this._defaultActions) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b._elm.nativeElement.click(); },
eventTargetMatches: (target, selector) => target ? ponyfill.matches(target, selector) : false,
getActionFromEvent: (evt) => {
const action = this.closest(evt.target, this._triggers.toArray());
return (action === null || action === void 0 ? void 0 : action.mdcDialogTrigger) || null;
},
getInitialFocusEl: () => null,
hasClass: (className) => {
if (className === cssClasses.STACKED)
return false; // currently not supporting (auto-)stacking of buttons
return this._elm.nativeElement.classList.contains(className);
},
isContentScrollable: () => { var _a; return util.isScrollable((_a = this._content) === null || _a === void 0 ? void 0 : _a._elm.nativeElement); },
notifyClosed: (action) => {
this.closed.emit({ action });
},
notifyClosing: (action) => {
this.document.removeEventListener('keydown', this._onDocumentKeydown);
this.closing.emit({ action });
if (action === 'accept')
this.accept.emit();
else if (action === 'close')
this.cancel.emit();
},
notifyOpened: () => {
this.opened.emit();
},
notifyOpening: () => {
this.document.addEventListener('keydown', this._onDocumentKeydown);
this.opening.emit();
},
releaseFocus: () => this.untrapFocus(),
// we're currently not supporting auto-stacking, cause we can't just reverse buttons in the dom
// and expect that to not break stuff in angular:
reverseButtons: () => undefined,
trapFocus: () => this.trapFocus()
};
this.foundation = null;
this.document = doc; // work around ngc issue https://github.com/angular/angular/issues/20351
}
ngAfterContentInit() {
this.foundation = new MDCDialogFoundation(this.mdcAdapter);
this.foundation.init();
this.foundation.setAutoStackButtons(false); // currently not supported
}
ngOnDestroy() {
var _a;
this.document.removeEventListener('keydown', this._onDocumentKeydown);
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.destroy();
this.foundation = null;
}
/**
* Call this method to open the dialog.
*/
open() {
this.foundation.open();
}
/**
* Call this method to close the dialog with the specified action, e.g. `accept` to indicate an acceptance action
* (and trigger the `accept` event), or `close` to indicate dismissal (and trigger the `cancel` event).
*/
close(action = 'close') {
this.foundation.close(action);
}
/**
* Recalculates layout and automatically adds/removes modifier classes (for instance to detect if the dialog content
* should be scrollable)
*/
layout() {
this.foundation.layout();
}
trapFocus() {
this.untrapFocus();
if (this._focusTrap)
this.focusTrapHandle = this._focusTrap.trapFocus();
}
untrapFocus() {
if (this.focusTrapHandle && this.focusTrapHandle.active) {
this.focusTrapHandle.untrap();
this.focusTrapHandle = null;
}
}
/** @internal */
onClick(event) {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleClick(event);
}
/** @internal */
onKeydown(event) {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event);
}
/** @internal */
onDocumentKeydown(event) {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleDocumentKeydown(event);
}
get _content() {
return this._contents.first;
}
closest(elm, choices) {
let match = elm;
while (match && match !== this._elm.nativeElement) {
for (let i = 0; i != choices.length; ++i) {
if (choices[i]._elm.nativeElement === match)
return choices[i];
}
match = match.parentElement;
}
return null;
}
}
MdcDialogDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDialog]',
exportAs: 'mdcDialog'
},] }
];
MdcDialogDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 },
{ type: MdcEventRegistry },
{ type: AbstractMdcFocusTrap, decorators: [{ type: Optional }, { type: Self }] },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
MdcDialogDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-dialog',] }],
_surface: [{ type: ContentChild, args: [MdcDialogSurfaceDirective,] }],
_triggers: [{ type: ContentChildren, args: [MdcDialogTriggerDirective, { descendants: true },] }],
_contents: [{ type: ContentChildren, args: [MdcDialogContentDirective, { descendants: true },] }],
_footers: [{ type: ContentChildren, args: [MdcDialogActionsDirective, { descendants: true },] }],
_defaultActions: [{ type: ContentChildren, args: [MdcDialogDefaultDirective, { descendants: true },] }],
accept: [{ type: Output }],
cancel: [{ type: Output }],
opening: [{ type: Output }],
opened: [{ type: Output }],
closing: [{ type: Output }],
closed: [{ type: Output }],
onClick: [{ type: HostListener, args: ['click', ['$event'],] }],
onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }]
};
export const DIALOG_DIRECTIVES = [
MdcDialogDirective, MdcDialogTitleDirective, MdcDialogContentDirective, MdcDialogSurfaceDirective, MdcDialogContainerDirective,
MdcDialogActionsDirective, MdcDialogTriggerDirective, MdcDialogDefaultDirective, MdcDialogScrimDirective
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLmRpYWxvZy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kaWFsb2cvbWRjLmRpYWxvZy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQzFGLFFBQVEsRUFBRSxNQUFNLEVBQWEsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3SCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLG1CQUFtQixFQUFvQixJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQW1CLE1BQU0sdUNBQXVDLENBQUM7QUFDdkgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVqRCxNQUNNLDJCQUEyQjs7O1lBRGhDLFNBQVM7O0FBR1YsV0FBVyxDQUFDLDJCQUEyQixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsRDs7Ozs7O0dBTUc7QUFJSCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsMkJBQTJCO0lBSHhFOztRQUlJLGdCQUFnQjtRQUNpQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBS2pFLENB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QUFNO3FCQUlOLE1BQU07c0JBS04sTUFBTTtxQkFLTixNQUFNO3NCQXdHTixZQUFZLFNBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO3dCQUtoQyxZQUFZLFNBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDOztBQTBCdkMsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUc7SUFDN0Isa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUseUJBQXlCLEVBQUUseUJBQXlCLEVBQUUsMkJBQTJCO0lBQzlILHlCQUF5QixFQUFFLHlCQUF5QixFQUFFLHlCQUF5QixFQUFFLHVCQUF1QjtDQUMzRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSW5wdXQsXG4gICAgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFF1ZXJ5TGlzdCwgUmVuZGVyZXIyLCBTZWxmLCBJbmplY3QsIEhvc3RMaXN0ZW5lciwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTURDRGlhbG9nRm91bmRhdGlvbiwgTURDRGlhbG9nQWRhcHRlciwgdXRpbCwgY3NzQ2xhc3NlcyB9IGZyb20gJ0BtYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgcG9ueWZpbGwgfSBmcm9tICdAbWF0ZXJpYWwvZG9tJ1xuaW1wb3J0IHsgTWRjRXZlbnRSZWdpc3RyeSB9IGZyb20gJy4uLy4uL3V0aWxzL21kYy5ldmVudC5yZWdpc3RyeSc7XG5pbXBvcnQgeyBNZGNCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuLi9idXR0b24vbWRjLmJ1dHRvbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwsIEFic3RyYWN0TWRjRm9jdXNUcmFwLCBGb2N1c1RyYXBIYW5kbGUgfSBmcm9tICcuLi9mb2N1cy10cmFwL2Fic3RyYWN0Lm1kYy5mb2N1cy10cmFwJztcbmltcG9ydCB7IEhhc0lkIH0gZnJvbSAnLi4vYWJzdHJhY3QvbWl4aW4ubWRjLmhhc2lkJztcbmltcG9ydCB7IGFwcGx5TWl4aW5zIH0gZnJvbSAnLi4vLi4vdXRpbHMvbWl4aW5zJztcblxuQERpcmVjdGl2ZSgpXG5jbGFzcyBNZGNEaWFsb2dUaXRsZURpcmVjdGl2ZUJhc2Uge31cbmludGVyZmFjZSBNZGNEaWFsb2dUaXRsZURpcmVjdGl2ZUJhc2UgZXh0ZW5kcyBIYXNJZCB7fVxuYXBwbHlNaXhpbnMoTWRjRGlhbG9nVGl0bGVEaXJlY3RpdmVCYXNlLCBbSGFzSWRdKTtcbi8qKlxuICogRGlyZWN0aXZlIGZvciB0aGUgdGl0bGUgb2YgYW4gYG1kY0RpYWxvZ2AuXG4gKiBBIHRpdGxlIGlzIG9wdGlvbmFsLiBJZiB1c2VkLCBpdCBzaG91bGQgYmUgdGhlIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEaWFsb2dTdXJmYWNlYC5cbiAqIFBsZWFzZSBub3RlIHRoYXQgdGhlcmUgc2hvdWxkIGJlIG5vIHdoaXRlc3BhY2Ugc2VwYXJhdGluZyB0aGUgc3RhcnQvZW5kIHRhZyBhbmQgdGhlIHRpdGxlXG4gKiBpdHNlbGYuIChUaGUgZWFzaWVzdCB3YXkgdG8gYWNoaWV2ZSB0aGlzIGlzIHRvICpub3QqIHNldCB0aGUgYHByZXNlcnZlV2hpdGVzcGFjZXNgIG9wdGlvbiB0b1xuICogYHRydWVgIHRoZSBgYW5ndWxhckNvbXBpbGVyT3B0aW9uc2ApLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEaWFsb2dUaXRsZV0nXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlIGV4dGVuZHMgTWRjRGlhbG9nVGl0bGVEaXJlY3RpdmVCYXNlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX190aXRsZScpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdElkKCk7XG4gICAgfVxufVxuXG5ARGlyZWN0aXZlKClcbmNsYXNzIE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmVCYXNlIHt9XG5pbnRlcmZhY2UgTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZUJhc2UgZXh0ZW5kcyBIYXNJZCB7fVxuYXBwbHlNaXhpbnMoTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZUJhc2UsIFtIYXNJZF0pO1xuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBjb250ZW50IHBhcnQgb2YgYW4gYG1kY0RpYWxvZ2AuXG4gKiBUaGlzIHNob3VsZCBiZSBhZGRlZCBhcyBhIGNoaWxkIGVsZW1lbnQgb2YgYW4gYG1kY0RpYWxvZ1N1cmZhY2VgLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEaWFsb2dDb250ZW50XSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZSBleHRlbmRzIE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmVCYXNlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19jb250ZW50JykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZikge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmluaXRJZCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBhY3Rpb25zIChmb290ZXIpIG9mIGFuIGBtZGNEaWFsb2dgLlxuICogVGhpcyBpcyBhbiAob3B0aW9uYWwpIGxhc3QgY2hpbGQgb2YgdGhlIGBtZGNEaWFsb2dTdXJmYWNlYCBkaXJlY3RpdmUuXG4gKiBUaGlzIGRpcmVjdGl2ZSBzaG91bGQgY29udGFpbiBidXR0b25zLCBmb3IgdGhhdCBzaG91bGQgdXNlIHRoZSBgbWRjQnV0dG9uYFxuICogZGlyZWN0aXZlLlxuICogXG4gKiBBY3Rpb24gYnV0dG9ucyBzaG91bGQgdHlwaWNhbGx5IGNsb3NlIHRoZSBkaWFsb2csIGFuZCBzaG91bGQgdGhlcmVmb3JlXG4gKiBhbHNvIHNldCBhIHZhbHVlIGZvciB0aGUgYG1kY0RpYWxvZ1RyaWdnZXJgIGRpcmVjdGl2ZS5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nQWN0aW9uc10nLFxufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZ19fYWN0aW9ucycpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0J1dHRvbkRpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX2J1dHRvbnM/OiBRdWVyeUxpc3Q8TWRjQnV0dG9uRGlyZWN0aXZlPjtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3JuZHI6IFJlbmRlcmVyMikge1xuICAgIH1cblxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICAgICAgdGhpcy5pbml0QnV0dG9ucygpO1xuICAgICAgICB0aGlzLl9idXR0b25zIS5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmluaXRCdXR0b25zKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEJ1dHRvbnMoKSB7XG4gICAgICAgIHRoaXMuX2J1dHRvbnMhLmZvckVhY2goYnRuID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3JuZHIuYWRkQ2xhc3MoYnRuLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kaWFsb2dfX2J1dHRvbicpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbi8qKlxuICogQW55IGVsZW1lbnQgd2l0aGluIGEgZGlhbG9nIG1heSBpbmNsdWRlIHRoaXMgZGlyZWN0aXZlIChhbmQgYXNzaWduZSBhIG5vbiBlbXB0eSB2YWx1ZSB0byBpdClcbiAqIHRvIGluZGljYXRlIHRoYXQgaW50ZXJhY3Rpbmcgd2l0aCBpdCBzaG91bGQgY2xvc2UgdGhlIGRpYWxvZyB3aXRoIHRoZSBzcGVjaWZpZWQgYWN0aW9uLlxuICogXG4gKiBUaGlzIGFjdGlvbiBpcyB0aGVuIHJlZmxlY3RlZCB2aWEgdGhlIGBhY3Rpb25gIGZpZWxkIGluIHRoZSBgY2xvc2luZ2AgYW5kIGBjbG9zZWRgIGV2ZW50cyBvZlxuICogdGhlIGRpYWxvZy4gQSB2YWx1ZSBvZiBgY2xvc2VgIHdpbGwgYWxzbyB0cmlnZ2VyIHRoZSBgY2FuY2VsYCBldmVudCBvZiB0aGUgZGlhbG9nLCBhbmQgYSB2YWx1ZSBvZlxuICogYGFjY2VwdGAgd2lsbCB0cmlnZ2VyIHRoZSBgYWNjZXB0YCBldmVudC5cbiAqIFxuICogQW55IGFjdGlvbiBidXR0b25zIHdpdGhpbiB0aGUgZGlhbG9nIHRoYXQgZXF1YXRlIHRvIGEgZGlzbWlzc2FsIHdpdGggbm8gZnVydGhlciBhY3Rpb24gc2hvdWxkXG4gKiB1c2Ugc2V0IGBtZGNEaWFsb2dUcmlnZ2VyPVwiY2xvc2VcImAuIFRoaXMgd2lsbCBtYWtlIGl0IGVhc3kgdG8gaGFuZGxlIGFsbCBzdWNoIGludGVyYWN0aW9ucyBjb25zaXN0ZW50bHlcbiAqICh2aWEgZWl0aGVyIHRoZSBgY2FuY2VsYCwgYGNsb3NpbmdgLCBvciBgY2xvc2VkYCBldmVudHMpLCB3aGlsZSBzZXBhcmF0ZWx5IGhhbmRsaW5nIG90aGVyIGFjdGlvbnMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ1RyaWdnZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dUcmlnZ2VyRGlyZWN0aXZlIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZikge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYGFjdGlvbmAgdmFsdWUgdGhhdCBzaG91bGQgYmUgc2VuZCB0byBgY2xvc2luZ2AgYW5kIGBjbG9zZWRgIGV2ZW50cyB3aGVuIGEgdXNlclxuICAgICAqIGludGVyYWN0cyB3aXRoIHRoaXMgZWxlbWVudC4gKFdoZW4gc2V0IHRvIGFuIGVtcHR5IHN0cmluZyB0aGUgYnV0dG9uL2VsZW1lbnQgd2lsbCBub3QgYmUgd2lyZWRcbiAgICAgKiB0byBjbG9zZSB0aGUgZGlhbG9nKS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBtZGNEaWFsb2dUcmlnZ2VyOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbn1cblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBjYW4gYmUgdXNlZCB0byBtYXJrIG9uZSBvZiB0aGUgZGlhbG9ncyBhY3Rpb24gYnV0dG9ucyBhcyB0aGUgZGVmYXVsdCBhY3Rpb24uXG4gKiBUaGlzIGFjdGlvbiB3aWxsIHRoZW4gYmUgdHJpZ2dlcmVkIGJ5IHByZXNzaW5nIHRoZSBlbnRlciBrZXkgd2hpbGUgdGhlIGRpYWxvZyBoYXMgZm9jdXMuXG4gKiBUaGUgZGVmYXVsdCBhY3Rpb24gYWxzbyB3aWxsIHJlY2VpdmUgZm9jdXMgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC4gVW5sZXNzIGFub3RoZXJcbiAqIGVsZW1lbnQgd2l0aGluIHRoZSBkaWFsb2cgaGFzIHRoZSBgbWRjRm9jdXNJbml0aWFsYCBkaXJlY3RpdmUuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ0RlZmF1bHRdJyxcbiAgICBwcm92aWRlcnM6IFt7cHJvdmlkZTogQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1kY0RpYWxvZ0RlZmF1bHREaXJlY3RpdmUpIH1dXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ0RlZmF1bHREaXJlY3RpdmUgZXh0ZW5kcyBBYnN0cmFjdE1kY0ZvY3VzSW5pdGlhbCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqLyByZWFkb25seSBwcmlvcml0eSA9IDA7IC8vIG11c3QgYmUgbG93ZXIgdGhhbiBwcmlvIG9mIE1kY0ZvY3VzSW5pdGlhbERpcmVjdGl2ZVxuXG4gICAgY29uc3RydWN0b3IocHVibGljIF9lbG06IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG59XG5cbi8qKlxuICogRGlyZWN0aXZlIGZvciB0aGUgc3VyZmFjZSBvZiBhIGRpYWxvZy4gVGhlIHN1cmZhY2UgY29udGFpbnMgdGhlIGFjdHVhbCBjb250ZW50IG9mIGEgZGlhbG9nLFxuICogd3JhcHBlZCBpbiBlbGVtZW50cyB3aXRoIHRoZSBgbWRjRGlhbG9nSGVhZGVyYCwgYG1kY0RpYWxvZ0NvbnRlbnRgLCBhbmQgYG1kY0RpYWxvZ0FjdGlvbnNgXG4gKiBkaXJlY3RpdmVzLlxuICogXG4gKiAjIEFjY2Vzc2liaWxpdHlcbiAqICogVGhlIHJvbGUgYXR0cmlidXRlIHdpbGwgYmUgc2V0IHRvIGBhbGVydGRpYWxvZ2AgYnkgZGVmYXVsdFxuICogKiBUaGUgYGFyaWEtbW9kYWxgIGF0dHJpYnV0ZSB3aWxsIGJlIHNldCB0byBgdHJ1ZWAgYnkgZGVmYXVsdFxuICogKiBJZiB0aGVyZSBpcyBhbiBgbWRjRGlhbG9nVGl0bGVgLCB0aGUgYGFyaWEtbGFiZWxsZWRCeWAgYXR0cmlidXRlIHdpbGwgYmUgc2V0IHRvIHRoZSBpZFxuICogICBvZiB0aGF0IGVsZW1lbnQgKGFuZCBhIHVuaXF1ZSBpZCB3aWxsIGJlIGFzc2lnbmVkIHRvIGl0LCBpZiBub25lIHdhcyBwcm92aWRlZClcbiAqICogSWYgdGhlcmUgaXMgYW4gYG1kY0RpYWxvZ0NvbnRlbnRgLCB0aGUgYGFyaWEtZGVzY3JpYmVkYnlgIGF0dHJpYnV0ZSB3aWxsIGJlIHNldCB0byB0aGVcbiAqICAgaWQgb2YgdGhhdCBlbGVtZW50IChhbmQgYSB1bmlxdWUgaWQgd2lsbCBiZSBhc3NpZ25lZCB0byBpdCwgaWYgbm9uZSB3YXMgcHJvdmlkZWQpXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ1N1cmZhY2VdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dTdXJmYWNlRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19zdXJmYWNlJykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJykgX3JvbGUgPSAnYWxlcnRkaWFsb2cnO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1tb2RhbCcpIF9tb2RhbCA9ICd0cnVlJztcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtbGFiZWxsZWRieScpIF9sYWJlbGxlZEJ5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtZGVzY3JpYmVkYnknKSBfZGVzY3JpYmVkQnk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlKSBfdGl0bGVzPzogUXVlcnlMaXN0PE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dDb250ZW50RGlyZWN0aXZlKSBfY29udGVudHM/OiBRdWVyeUxpc3Q8TWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZT47XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgICAgIHRoaXMuX3RpdGxlcyEuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zZXRBcmlhTGFiZWxzKCkpO1xuICAgICAgICB0aGlzLl9jb250ZW50cyEuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zZXRBcmlhTGFiZWxzKCkpO1xuICAgICAgICB0aGlzLnNldEFyaWFMYWJlbHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEFyaWFMYWJlbHMoKSB7XG4gICAgICAgIHRoaXMuX2xhYmVsbGVkQnkgPSB0aGlzLl90aXRsZXMhLmZpcnN0Py5pZDtcbiAgICAgICAgdGhpcy5fZGVzY3JpYmVkQnkgPSB0aGlzLl9jb250ZW50cyEuZmlyc3Q/LmlkO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBzaG91bGQgYmUgdGhlIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEaWFsb2dgLCBhbmQgY29udGFpbnMgdGhlIGBtZGNEaWFsb2dTdXJmYWNlYC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nQ29udGFpbmVyXSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRGlhbG9nQ29udGFpbmVyRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19jb250YWluZXInKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBiYWNrZHJvcCBvZiBhIGRpYWxvZy4gVGhlIGJhY2tkcm9wIHByb3ZpZGVzIHRoZSBzdHlsZXMgZm9yIG92ZXJsYXlpbmcgdGhlXG4gKiBwYWdlIGNvbnRlbnQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC4gVGhpcyBndWlkZXMgdXNlciBhdHRlbnRpb24gdG8gdGhlIGRpYWxvZy5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nU2NyaW1dJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dTY3JpbURpcmVjdGl2ZSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZ19fc2NyaW0nKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIGNyZWF0aW5nIGEgbW9kYWwgZGlhbG9nIHdpdGggTWF0ZXJpYWwgRGVzaWduIHN0eWxpbmcuIFRoZSBkaWFsb2cgc2hvdWxkIGhhdmUgdHdvXG4gKiBjaGlsZCBlbGVtZW50czogYSBzdXJmYWNlIChtYXJrZWQgd2l0aCB0aGUgPGNvZGU+bWRjRGlhbG9nU3VyZmFjZTwvY29kZT4gZGlyZWN0aXZlKSwgYW5kIGFcbiAqIGJhY2tkcm9wIChtYXJrZWQgd2l0aCB0aGUgPGNvZGU+bWRjRGlhbG9nQmFja2Ryb3A8L2NvZGU+IGRpcmVjdGl2ZSkuXG4gKiBcbiAqIFdoZW4gdGhlIGRpYWxvZyBpcyBvcGVuZWQsIGl0IHdpbGwgYWN0aXZhdGUgYSBmb2N1cyB0cmFwIG9uIHRoZSBlbGVtZW50cyB3aXRoaW4gdGhlIGRpYWxvZyxcbiAqIHNvIHRoYXQgdGhlIHN1cmZhY2UgYmVoaW5kIHRoZSBkaWFsb2cgaXMgbm90IGFjY2Vzc2libGUuIFNlZSBgbWRjRm9jdXNUcmFwYCBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nXScsXG4gICAgZXhwb3J0QXM6ICdtZGNEaWFsb2cnXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ0RpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZycpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkKE1kY0RpYWxvZ1N1cmZhY2VEaXJlY3RpdmUpIF9zdXJmYWNlOiBNZGNEaWFsb2dTdXJmYWNlRGlyZWN0aXZlIHwgbnVsbCA9IG51bGw7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oTWRjRGlhbG9nVHJpZ2dlckRpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX3RyaWdnZXJzPzogUXVlcnlMaXN0PE1kY0RpYWxvZ1RyaWdnZXJEaXJlY3RpdmU+O1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmUsIHtkZXNjZW5kYW50czogdHJ1ZX0pIF9jb250ZW50cz86IFF1ZXJ5TGlzdDxNZGNEaWFsb2dDb250ZW50RGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfZm9vdGVycz86IFF1ZXJ5TGlzdDxNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dEZWZhdWx0RGlyZWN0aXZlLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfZGVmYXVsdEFjdGlvbnM/OiBRdWVyeUxpc3Q8TWRjRGlhbG9nRGVmYXVsdERpcmVjdGl2ZT47XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIGFjY2VwdHMgdGhlIGRpYWxvZywgZS5nLiBieSBwcmVzc2luZyBlbnRlciBvciBjbGlja2luZyB0aGUgYnV0dG9uXG4gICAgICogd2l0aCBgbWRjRGlhbG9nVHJpZ2dlcj1cImFjY2VwdFwiYC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgYWNjZXB0OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIGNhbmNlbHMgdGhlIGRpYWxvZywgZS5nLiBieSBjbGlja2luZyBvdXRzaWRlIHRoZSBkaWFsb2csIHByZXNzaW5nIHRoZSBlc2NhcGUga2V5LFxuICAgICAqIG9yIGNsaWNraW5nIGFuIGVsZW1lbnQgd2l0aCBgbWRjRGlhbG9nVHJpZ2dlcj1cImNsb3NlXCJgLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSByZWFkb25seSBjYW5jZWw6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGRpYWxvZyBzdGFydHMgb3BlbmluZy5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbmluZzogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbmVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBkaWFsb2cgc3RhcnRzIGNsb3NpbmcuIFRoZSAnYWN0aW9uJyBmaWVsZCBjb250YWlucyB0aGUgcmVhc29uIGZvciBjbG9zaW5nLCBzZWVcbiAgICAgKiBgbWRjRGlhbG9nVHJpZ2dlcmAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGNsb3Npbmc6IEV2ZW50RW1pdHRlcjx7YWN0aW9uOiBzdHJpbmd9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGRpYWxvZyBpcyBjbG9zZWQuIFRoZSAnYWN0aW9uJyBmaWVsZCBjb250YWlucyB0aGUgcmVhc29uIGZvciBjbG9zaW5nLCBzZWVcbiAgICAgKiBgbWRjRGlhbG9nVHJpZ2dlcmAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGNsb3NlZDogRXZlbnRFbWl0dGVyPHthY3Rpb246IHN0cmluZ30+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHByaXZhdGUgX29uRG9jdW1lbnRLZXlkb3duID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB0aGlzLm9uRG9jdW1lbnRLZXlkb3duKGV2ZW50KTtcbiAgICBwcml2YXRlIGZvY3VzVHJhcEhhbmRsZTogRm9jdXNUcmFwSGFuZGxlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBtZGNBZGFwdGVyOiBNRENEaWFsb2dBZGFwdGVyID0ge1xuICAgICAgICBhZGRDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLmFkZENsYXNzKHRoaXMuX2VsbS5uYXRpdmVFbGVtZW50LCBjbGFzc05hbWUpLFxuICAgICAgICByZW1vdmVDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLnJlbW92ZUNsYXNzKHRoaXMuX2VsbS5uYXRpdmVFbGVtZW50LCBjbGFzc05hbWUpLFxuICAgICAgICBhZGRCb2R5Q2xhc3M6IChjbGFzc05hbWU6IHN0cmluZykgPT4gdGhpcy5fcm5kci5hZGRDbGFzcyh0aGlzLmRvY3VtZW50LmJvZHksIGNsYXNzTmFtZSksXG4gICAgICAgIHJlbW92ZUJvZHlDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLnJlbW92ZUNsYXNzKHRoaXMuZG9jdW1lbnQuYm9keSwgY2xhc3NOYW1lKSxcbiAgICAgICAgYXJlQnV0dG9uc1N0YWNrZWQ6ICgpID0+IHRoaXMuX2Zvb3RlcnM/LmZpcnN0ID8gdXRpbC5hcmVUb3BzTWlzYWxpZ25lZCh0aGlzLl9mb290ZXJzLmZpcnN0Py5fYnV0dG9ucyEubWFwKGIgPT4gYi5fZWxtLm5hdGl2ZUVsZW1lbnQpKSA6IGZhbHNlLFxuICAgICAgICBjbGlja0RlZmF1bHRCdXR0b246ICgpID0+IHRoaXMuX2RlZmF1bHRBY3Rpb25zPy5maXJzdD8uX2VsbS5uYXRpdmVFbGVtZW50LmNsaWNrKCksXG4gICAgICAgIGV2ZW50VGFyZ2V0TWF0Y2hlczogKHRhcmdldCwgc2VsZWN0b3IpID0+IHRhcmdldCA/IHBvbnlmaWxsLm1hdGNoZXModGFyZ2V0IGFzIEVsZW1lbnQsIHNlbGVjdG9yKSA6IGZhbHNlLFxuICAgICAgICBnZXRBY3Rpb25Gcm9tRXZlbnQ6IChldnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNsb3Nlc3QoZXZ0LnRhcmdldCBhcyBFbGVtZW50LCB0aGlzLl90cmlnZ2VycyEudG9BcnJheSgpKTtcbiAgICAgICAgICAgIHJldHVybiBhY3Rpb24/Lm1kY0RpYWxvZ1RyaWdnZXIgfHwgbnVsbDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0SW5pdGlhbEZvY3VzRWw6ICgpID0+IG51bGwsIC8vIGlnbm9yZWQgaW4gb3VyIGltcGxlbWVudGF0aW9uLiBtZGNGb2N1c1RyYXAgZGV0ZXJtaW5lcyB0aGlzIGJ5IGl0c2VsZlxuICAgICAgICBoYXNDbGFzczogKGNsYXNzTmFtZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gY3NzQ2xhc3Nlcy5TVEFDS0VEKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gY3VycmVudGx5IG5vdCBzdXBwb3J0aW5nIChhdXRvLSlzdGFja2luZyBvZiBidXR0b25zXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGlzQ29udGVudFNjcm9sbGFibGU6ICgpID0+IHV0aWwuaXNTY3JvbGxhYmxlKHRoaXMuX2NvbnRlbnQ/Ll9lbG0ubmF0aXZlRWxlbWVudCksXG4gICAgICAgIG5vdGlmeUNsb3NlZDogKGFjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbG9zZWQuZW1pdCh7YWN0aW9ufSk7XG4gICAgICAgIH0sXG4gICAgICAgIG5vdGlmeUNsb3Npbmc6IChhY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuX29uRG9jdW1lbnRLZXlkb3duKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2luZy5lbWl0KHthY3Rpb259KTtcbiAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdhY2NlcHQnKVxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXB0LmVtaXQoKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGFjdGlvbiA9PT0gJ2Nsb3NlJylcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbC5lbWl0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIG5vdGlmeU9wZW5lZDogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVuZWQuZW1pdCgpO1xuICAgICAgICB9LFxuICAgICAgICBub3RpZnlPcGVuaW5nOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLl9vbkRvY3VtZW50S2V5ZG93bik7XG4gICAgICAgICAgICB0aGlzLm9wZW5pbmcuZW1pdCgpO1xuICAgICAgICB9LFxuICAgICAgICByZWxlYXNlRm9jdXM6ICgpID0+IHRoaXMudW50cmFwRm9jdXMoKSxcbiAgICAgICAgLy8gd2UncmUgY3VycmVudGx5IG5vdCBzdXBwb3J0aW5nIGF1dG8tc3RhY2tpbmcsIGNhdXNlIHdlIGNhbid0IGp1c3QgcmV2ZXJzZSBidXR0b25zIGluIHRoZSBkb21cbiAgICAgICAgLy8gYW5kIGV4cGVjdCB0aGF0IHRvIG5vdCBicmVhayBzdHVmZiBpbiBhbmd1bGFyOlxuICAgICAgICByZXZlcnNlQnV0dG9uczogKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgICB0cmFwRm9jdXM6ICgpID0+IHRoaXMudHJhcEZvY3VzKClcbiAgICB9O1xuICAgIHByaXZhdGUgZm91bmRhdGlvbjogTURDRGlhbG9nRm91bmRhdGlvbiB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfZWxtOiBFbGVtZW50UmVmLCBwcml2YXRlIF9ybmRyOiBSZW5kZXJlcjIsIHByaXZhdGUgX3JlZ2lzdHJ5OiBNZGNFdmVudFJlZ2lzdHJ5LFxuICAgICAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgX2ZvY3VzVHJhcDogQWJzdHJhY3RNZGNGb2N1c1RyYXAsXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIGRvYzogYW55KSB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50ID0gZG9jIGFzIERvY3VtZW50OyAvLyB3b3JrIGFyb3VuZCBuZ2MgaXNzdWUgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMjAzNTFcbiAgICB9XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbiA9IG5ldyBNRENEaWFsb2dGb3VuZGF0aW9uKHRoaXMubWRjQWRhcHRlcik7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbi5pbml0KCk7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbi5zZXRBdXRvU3RhY2tCdXR0b25zKGZhbHNlKTsgLy8gY3VycmVudGx5IG5vdCBzdXBwb3J0ZWRcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5fb25Eb2N1bWVudEtleWRvd24pO1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24/LmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHRvIG9wZW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBvcGVuKCkge1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24hLm9wZW4oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHRvIGNsb3NlIHRoZSBkaWFsb2cgd2l0aC