@blox/material
Version:
Material Components for Angular
392 lines • 44.5 kB
JavaScript
import { ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, Inject, Optional, Self, HostListener } from '@angular/core';
import { MDCDismissibleDrawerFoundation, MDCModalDrawerFoundation } from '@material/drawer';
import { asBoolean } from '../../utils/value.utils';
import { DOCUMENT } from '@angular/common';
import { AbstractMdcFocusTrap } from '../focus-trap/abstract.mdc.focus-trap';
import { MdcListItemDirective } from '../list/mdc.list.directive';
/**
* Directive for the title of a drawer. The use of this directive is optional.
* If used, it should be placed as first element inside an `mdcDrawerHeader`
*/
export class MdcDrawerTitleDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDrawerTitleDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerTitle]'
},] }
];
MdcDrawerTitleDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer__title',] }]
};
/**
* Directive for the subtitle of a drawer. The use of this directive is optional.
* If used, it should be placed as a sibling element of `mdcDrawerTitle`
* inside an `mdcDrawerHeader`
*/
export class MdcDrawerSubtitleDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDrawerSubtitleDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerSubtitle]'
},] }
];
MdcDrawerSubtitleDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer__subtitle',] }]
};
/**
* A toolbar header is an optional first child of an `mdcDrawer`.
* The header will not scroll with the rest of the drawer content, so is a
* good place to place titles and account switchers.
*
* Directives that are typically used inside an `mdcDrawerHeader`:
* `mdcDrawerTitle`, and `mdcDrawerSubTitle`
*/
export class MdcDrawerHeaderDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDrawerHeaderDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerHeader]'
},] }
];
MdcDrawerHeaderDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer__header',] }]
};
/**
* Directive for the drawer content. You would typically also apply the `mdcList`
* or `mdcListGroup` directive to the drawer content (see the examples).
*/
export class MdcDrawerContentDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDrawerContentDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerContent]'
},] }
];
MdcDrawerContentDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer__content',] }]
};
export class MdcDrawerScrimDirective {
constructor() {
/** @internal */
this._cls = true;
}
}
MdcDrawerScrimDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerScrim]'
},] }
];
MdcDrawerScrimDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer-scrim',] }]
};
/**
* Directive for a (navigation) drawer. The following drawer types are
* supported:
* * `permanent`: the default type if none was specified.
* * `dismissible`: the drawer is hidden by default, and can slide into view.
* Typically used when navigation is not common, and the main app content is
* prioritized.
* * `modal`: the drawer is hidden by default. When activated, the drawer is elevated
* above the UI of the app. It uses a scrim to block interaction with the rest of
* the app with a scrim.
*
* Drawers may contain an `mdcDrawerHeader`, and should contain an `mdcDrawerContent`
* directive.
*/
export class MdcDrawerDirective {
constructor(_elm, _rndr, doc, _focusTrap) {
this._elm = _elm;
this._rndr = _rndr;
this._focusTrap = _focusTrap;
/** @internal */
this._cls = true;
this._onDocumentClick = (event) => this.onDocumentClick(event);
this.focusTrapHandle = null;
this.type = 'permanent';
this.previousFocus = null;
this._open = null;
this.mdcAdapter = {
addClass: (className) => this._rndr.addClass(this._elm.nativeElement, className),
removeClass: (className) => this._rndr.removeClass(this._elm.nativeElement, className),
hasClass: (className) => this._elm.nativeElement.classList.contains(className),
elementHasClass: (element, className) => element.classList.contains(className),
saveFocus: () => this.previousFocus = this.document.activeElement,
restoreFocus: () => {
const prev = this.previousFocus;
if (prev && prev.focus && this._elm.nativeElement.contains(this.document.activeElement))
prev.focus();
},
focusActiveNavigationItem: () => {
const active = this._items.find(item => item.active);
active === null || active === void 0 ? void 0 : active._elm.nativeElement.focus();
},
notifyClose: () => {
this.fixOpenClose(false);
this.afterClosed.emit();
this.document.removeEventListener('click', this._onDocumentClick);
},
notifyOpen: () => {
this.fixOpenClose(true);
this.afterOpened.emit();
if (this.type === 'modal')
this.document.addEventListener('click', this._onDocumentClick);
},
trapFocus: () => this.trapFocus(),
releaseFocus: () => this.untrapFocus()
};
this.foundation = null; // MDCModalDrawerFoundation extends MDCDismissibleDrawerFoundation
/**
* Event emitted when the drawer is opened or closed. The event value will be
* `true` when the drawer is opened, and `false` when the
* drawer is closed. (When this event is triggered, the drawer is starting to open/close,
* but the animation may not have fully completed yet)
*/
this.openChange = new EventEmitter();
/**
* Event emitted after the drawer has fully opened. When this event is emitted the full
* opening animation has completed, and the drawer is visible.
*/
this.afterOpened = new EventEmitter();
/**
* Event emitted after the drawer has fully closed. When this event is emitted the full
* closing animation has completed, and the drawer is not visible anymore.
*/
this.afterClosed = new EventEmitter();
this.document = doc; // work around ngc issue https://github.com/angular/angular/issues/20351
}
ngAfterContentInit() {
this.initDrawer();
}
ngOnDestroy() {
this.destroyDrawer();
}
destroyDrawer() {
// when foundation is reconstructed and then .open() is called,
// if these classes are still available the foundation assumes open was already called,
// and it won't do anything:
this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--animate');
this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--closing');
this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--open');
this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--opening');
if (this.foundation) {
this.document.removeEventListener('click', this._onDocumentClick);
this.foundation.destroy();
this.foundation = null;
}
}
initDrawer() {
this.destroyDrawer();
let newFoundation = null;
const thiz = this;
if (this.type === 'dismissible')
newFoundation = new class extends MDCDismissibleDrawerFoundation {
close() {
const emit = thiz._open;
thiz._open = false;
super.close();
emit ? thiz.openChange.emit(thiz._open) : undefined;
}
open() {
const emit = !thiz._open;
thiz._open = true;
super.open();
emit ? thiz.openChange.emit(thiz._open) : undefined;
}
}(this.mdcAdapter);
else if (this.type === 'modal')
newFoundation = new class extends MDCModalDrawerFoundation {
close() {
const emit = thiz._open;
thiz._open = false;
super.close();
emit ? thiz.openChange.emit(thiz._open) : undefined;
}
open() {
const emit = !thiz._open;
thiz._open = true;
super.open();
emit ? thiz.openChange.emit(thiz._open) : undefined;
}
}(this.mdcAdapter);
// else: permanent drawer -> doesn't need a foundation, just styling
if (newFoundation) {
this.foundation = newFoundation;
newFoundation.init();
if (this._open)
newFoundation.open();
}
}
/** @internal */
get _isModal() {
return this.type === 'modal';
}
/** @internal */
get _isDismisible() {
return this.type === 'dismissible';
}
/**
* Set the type of drawer. Either `permanent`, `dismissible`, or `modal`.
* The default type is `permanent`.
*/
get mdcDrawer() {
return this.type;
}
set mdcDrawer(value) {
if (value !== 'dismissible' && value !== 'modal')
value = 'permanent';
if (value !== this.type) {
this.type = value;
this.initDrawer();
}
}
/**
* Input to open (assign value `true`) or close (assign value `false`)
* the drawer.
*/
get open() {
return !!this._open;
}
set open(value) {
let newValue = asBoolean(value);
if (newValue !== this._open) {
if (this.foundation) {
newValue ? this.foundation.open() : this.foundation.close();
}
else {
this._open = newValue;
this.openChange.emit(newValue);
}
}
}
fixOpenClose(open) {
// the foundation ignores calls to open/close while an opening/closing animation is running.
// so when the animation ends, we're just going to try again
// (needs to be done in the next micro cycle, because otherwise foundation will still think it's
// running the opening/closing animation):
Promise.resolve().then(() => {
if (this._open !== open) {
if (this._open)
this.foundation.open();
else
this.foundation.close();
}
});
}
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 */
onKeydown(event) {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event);
}
/** @internal */
handleTransitionEnd(event) {
var _a;
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleTransitionEnd(event);
}
/** @internal */
onDocumentClick(event) {
var _a;
if (this.type === 'modal') {
// instead of listening to click event on mdcDrawerScrim (which would require wiring between
// mdcDrawerScrim and mdcDrawer), we just listen to document clicks.
let el = event.target;
while (el) {
if (el === this._elm.nativeElement)
return;
el = el.parentElement;
}
(_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleScrimClick();
}
}
}
MdcDrawerDirective.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawer]'
},] }
];
MdcDrawerDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
{ type: AbstractMdcFocusTrap, decorators: [{ type: Optional }, { type: Self }] }
];
MdcDrawerDirective.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer',] }],
_items: [{ type: ContentChildren, args: [MdcListItemDirective, { descendants: true },] }],
openChange: [{ type: Output }],
afterOpened: [{ type: Output }],
afterClosed: [{ type: Output }],
_isModal: [{ type: HostBinding, args: ['class.mdc-drawer--modal',] }],
_isDismisible: [{ type: HostBinding, args: ['class.mdc-drawer--dismissible',] }],
mdcDrawer: [{ type: Input }],
open: [{ type: Input }],
onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
handleTransitionEnd: [{ type: HostListener, args: ['transitionend', ['$event'],] }]
};
/**
* Use this directive for marking the sibling element after a dismissible `mdcDrawer`.
* This will apply styling so that the open/close animations work correctly.
*/
export class MdcDrawerAppContent {
constructor() {
/** @internal */
this._cls = true;
}
/**
* Set this to false to disable the styling for sibbling app content of a dismissible drawer.
* This is typically only used when your `mdcDrawer` type is dynamic. In those cases you can
* disable the `mdcDrawerAppContent` when you set your drawer type to anything other than
* `dismissible`.
*/
get mdcDrawerAppContent() {
return this._cls;
}
set mdcDrawerAppContent(value) {
this._cls = asBoolean(value);
}
}
MdcDrawerAppContent.decorators = [
{ type: Directive, args: [{
selector: '[mdcDrawerAppContent]'
},] }
];
MdcDrawerAppContent.propDecorators = {
_cls: [{ type: HostBinding, args: ['class.mdc-drawer-app-content',] }],
mdcDrawerAppContent: [{ type: Input }]
};
export const DRAWER_DIRECTIVES = [
MdcDrawerTitleDirective,
MdcDrawerSubtitleDirective,
MdcDrawerHeaderDirective,
MdcDrawerContentDirective,
MdcDrawerScrimDirective,
MdcDrawerDirective,
MdcDrawerAppContent
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLmRyYXdlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kcmF3ZXIvbWRjLmRyYXdlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixlQUFlLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUN4RixLQUFLLEVBQWEsTUFBTSxFQUFhLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxFQUFFLDhCQUE4QixFQUFFLHdCQUF3QixFQUFvQixNQUFNLGtCQUFrQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLG9CQUFvQixFQUFtQixNQUFNLHVDQUF1QyxDQUFDO0FBQzlGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWxFOzs7R0FHRztBQUlILE1BQU0sT0FBTyx1QkFBdUI7SUFIcEM7UUFJSSxnQkFBZ0I7UUFDaUMsU0FBSSxHQUFHLElBQUksQ0FBQztJQUNqRSxDQUFDOzs7WUFOQSxTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGtCQUFrQjthQUMvQjs7O21CQUdJLFdBQVcsU0FBQyx5QkFBeUI7O0FBRzFDOzs7O0dBSUc7QUFJSCxNQUFNLE9BQU8sMEJBQTBCO0lBSHZDO1FBSUksZ0JBQWdCO1FBQ29DLFNBQUksR0FBRyxJQUFJLENBQUM7SUFDcEUsQ0FBQzs7O1lBTkEsU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxxQkFBcUI7YUFDbEM7OzttQkFHSSxXQUFXLFNBQUMsNEJBQTRCOztBQUc3Qzs7Ozs7OztHQU9HO0FBSUgsTUFBTSxPQUFPLHdCQUF3QjtJQUhyQztRQUlJLGdCQUFnQjtRQUNrQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xFLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsbUJBQW1CO2FBQ2hDOzs7bUJBR0ksV0FBVyxTQUFDLDBCQUEwQjs7QUFHM0M7OztHQUdHO0FBSUgsTUFBTSxPQUFPLHlCQUF5QjtJQUh0QztRQUlJLGdCQUFnQjtRQUNtQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25FLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsb0JBQW9CO2FBQ2pDOzs7bUJBR0ksV0FBVyxTQUFDLDJCQUEyQjs7QUFNNUMsTUFBTSxPQUFPLHVCQUF1QjtJQUhwQztRQUlJLGdCQUFnQjtRQUNnQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2hFLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsa0JBQWtCO2FBQy9COzs7bUJBR0ksV0FBVyxTQUFDLHdCQUF3Qjs7QUFHekM7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUlILE1BQU0sT0FBTyxrQkFBa0I7SUEyRDNCLFlBQW1CLElBQWdCLEVBQVksS0FBZ0IsRUFBb0IsR0FBUSxFQUMzRCxVQUFnQztRQUQ3QyxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQVksVUFBSyxHQUFMLEtBQUssQ0FBVztRQUMvQixlQUFVLEdBQVYsVUFBVSxDQUFzQjtRQTNEaEUsZ0JBQWdCO1FBQzBCLFNBQUksR0FBRyxJQUFJLENBQUM7UUFHOUMscUJBQWdCLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RFLG9CQUFlLEdBQTJCLElBQUksQ0FBQztRQUMvQyxTQUFJLEdBQTBDLFdBQVcsQ0FBQztRQUMxRCxrQkFBYSxHQUFzQyxJQUFJLENBQUM7UUFDeEQsVUFBSyxHQUFtQixJQUFJLENBQUM7UUFFN0IsZUFBVSxHQUFxQjtZQUNuQyxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQztZQUNqRixXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQztZQUN0RixRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1lBQzlFLGVBQWUsRUFBRSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQztZQUM5RSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWE7WUFDakUsWUFBWSxFQUFFLEdBQUcsRUFBRTtnQkFDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBd0MsQ0FBQztnQkFDM0QsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7b0JBQ25GLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixDQUFDO1lBQ0QseUJBQXlCLEVBQUUsR0FBRyxFQUFFO2dCQUM1QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHO1lBQ3ZDLENBQUM7WUFDRCxXQUFXLEVBQUUsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxVQUFVLEVBQUUsR0FBRyxFQUFFO2dCQUNiLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxPQUFPO29CQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0QsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDakMsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7U0FDekMsQ0FBQztRQUNNLGVBQVUsR0FBMEMsSUFBSSxDQUFDLENBQUMsa0VBQWtFO1FBQ3BJOzs7OztXQUtHO1FBQ2dCLGVBQVUsR0FBMEIsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUNuRjs7O1dBR0c7UUFDZ0IsZ0JBQVcsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN4RTs7O1dBR0c7UUFDZ0IsZ0JBQVcsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUlwRSxJQUFJLENBQUMsUUFBUSxHQUFHLEdBQWUsQ0FBQyxDQUFDLHdFQUF3RTtJQUM3RyxDQUFDO0lBRUQsa0JBQWtCO1FBQ2QsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxXQUFXO1FBQ1AsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxhQUFhO1FBQ2pCLCtEQUErRDtRQUMvRCx1RkFBdUY7UUFDdkYsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUscUJBQXFCLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDdkUsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBRU8sVUFBVTtRQUNkLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLGFBQWEsR0FBMEMsSUFBSSxDQUFDO1FBQ2hFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYTtZQUMzQixhQUFhLEdBQUcsSUFBSSxLQUFNLFNBQVEsOEJBQThCO2dCQUM1RCxLQUFLO29CQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ3hCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUNuQixLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2QsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDeEQsQ0FBQztnQkFDRCxJQUFJO29CQUNBLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7b0JBQ2xCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDYixJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUN4RCxDQUFDO2FBQ0osQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDbEIsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLE9BQU87WUFDMUIsYUFBYSxHQUFHLElBQUksS0FBTSxTQUFRLHdCQUF3QjtnQkFDdEQsS0FBSztvQkFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUN4QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDbkIsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNkLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ3hELENBQUM7Z0JBQ0QsSUFBSTtvQkFDQSxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO29CQUNsQixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDeEQsQ0FBQzthQUNKLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZCLG9FQUFvRTtRQUNwRSxJQUFJLGFBQWEsRUFBRTtZQUNmLElBQUksQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO1lBQ2hDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxLQUFLO2dCQUNWLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUM1QjtJQUNMLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsSUFBNEMsUUFBUTtRQUNoRCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsSUFBa0QsYUFBYTtRQUMzRCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFhLFNBQVM7UUFDbEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUE0QztRQUN0RCxJQUFJLEtBQUssS0FBSyxhQUFhLElBQUksS0FBSyxLQUFLLE9BQU87WUFDNUMsS0FBSyxHQUFHLFdBQVcsQ0FBQztRQUN4QixJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBQ2xCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNyQjtJQUNMLENBQUM7SUFJRDs7O09BR0c7SUFDSCxJQUFhLElBQUk7UUFDYixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxLQUFjO1FBQ25CLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDakIsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQy9EO2lCQUFNO2dCQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDO2dCQUN0QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNsQztTQUNKO0lBQ0wsQ0FBQztJQUlPLFlBQVksQ0FBQyxJQUFhO1FBQzlCLDRGQUE0RjtRQUM1Riw0REFBNEQ7UUFDNUQsZ0dBQWdHO1FBQ2hHLDBDQUEwQztRQUMxQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN4QixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO2dCQUNyQixJQUFJLElBQUksQ0FBQyxLQUFLO29CQUNWLElBQUksQ0FBQyxVQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7O29CQUV4QixJQUFJLENBQUMsVUFBVyxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ2hDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sU0FBUztRQUNiLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLElBQUksQ0FBQyxVQUFVO1lBQ2YsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzNELENBQUM7SUFFTyxXQUFXO1FBQ2YsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFO1lBQ3JELElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7U0FDL0I7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCO0lBQ3FCLFNBQVMsQ0FBQyxLQUFvQjs7UUFDL0QsTUFBQSxJQUFJLENBQUMsVUFBVSwwQ0FBRSxhQUFhLENBQUMsS0FBSyxFQUFFO0lBQzFDLENBQUM7SUFFRCxnQkFBZ0I7SUFDMkIsbUJBQW1CLENBQUMsS0FBc0I7O1FBQ2pGLE1BQUEsSUFBSSxDQUFDLFVBQVUsMENBQUUsbUJBQW1CLENBQUMsS0FBSyxFQUFFO0lBQ2hELENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsZUFBZSxDQUFDLEtBQWlCOztRQUM3QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBQ3ZCLDRGQUE0RjtZQUM1RixvRUFBb0U7WUFDcEUsSUFBSSxFQUFFLEdBQW1CLEtBQUssQ0FBQyxNQUFpQixDQUFDO1lBQ2pELE9BQU8sRUFBRSxFQUFFO2dCQUNQLElBQUksRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtvQkFDOUIsT0FBTztnQkFDWCxFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQzthQUN6QjtZQUNELE1BQUMsSUFBSSxDQUFDLFVBQXVDLDBDQUFFLGdCQUFnQixHQUFHO1NBQ3JFO0lBQ0wsQ0FBQzs7O1lBM09KLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsYUFBYTthQUMxQjs7O1lBckZzRCxVQUFVO1lBQ3hCLFNBQVM7NENBZ0pvQixNQUFNLFNBQUMsUUFBUTtZQTVJNUUsb0JBQW9CLHVCQTZJcEIsUUFBUSxZQUFJLElBQUk7OzttQkExRHBCLFdBQVcsU0FBQyxrQkFBa0I7cUJBRTlCLGVBQWUsU0FBQyxvQkFBb0IsRUFBRSxFQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUM7eUJBMkN6RCxNQUFNOzBCQUtOLE1BQU07MEJBS04sTUFBTTt1QkEwRU4sV0FBVyxTQUFDLHlCQUF5Qjs0QkFLckMsV0FBVyxTQUFDLCtCQUErQjt3QkFRM0MsS0FBSzttQkFtQkwsS0FBSzt3QkErQ0wsWUFBWSxTQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztrQ0FLbEMsWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7QUFvQjdDOzs7R0FHRztBQUlILE1BQU0sT0FBTyxtQkFBbUI7SUFIaEM7UUFJSSxnQkFBZ0I7UUFDNkIsU0FBSSxHQUFHLElBQUksQ0FBQztJQWlCN0QsQ0FBQztJQWZHOzs7OztPQUtHO0lBQ0gsSUFBYSxtQkFBbUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLG1CQUFtQixDQUFDLEtBQWM7UUFDbEMsSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQzs7O1lBbkJKLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsdUJBQXVCO2FBQ3BDOzs7bUJBR0ksV0FBVyxTQUFDLDhCQUE4QjtrQ0FRMUMsS0FBSzs7QUFXVixNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRztJQUM3Qix1QkFBdUI7SUFDdkIsMEJBQTBCO0lBQzFCLHdCQUF3QjtJQUN4Qix5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLGtCQUFrQjtJQUNsQixtQkFBbUI7Q0FDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbnRlbnRDaGlsZHJlbiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LCBPbkRlc3Ryb3ksIE91dHB1dCwgUXVlcnlMaXN0LCBSZW5kZXJlcjIsIEluamVjdCwgT3B0aW9uYWwsIFNlbGYsIEhvc3RMaXN0ZW5lciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9uLCBNRENNb2RhbERyYXdlckZvdW5kYXRpb24sIE1EQ0RyYXdlckFkYXB0ZXIgfSBmcm9tICdAbWF0ZXJpYWwvZHJhd2VyJztcbmltcG9ydCB7IGFzQm9vbGVhbiB9IGZyb20gJy4uLy4uL3V0aWxzL3ZhbHVlLnV0aWxzJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEFic3RyYWN0TWRjRm9jdXNUcmFwLCBGb2N1c1RyYXBIYW5kbGUgfSBmcm9tICcuLi9mb2N1cy10cmFwL2Fic3RyYWN0Lm1kYy5mb2N1cy10cmFwJztcbmltcG9ydCB7IE1kY0xpc3RJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vbGlzdC9tZGMubGlzdC5kaXJlY3RpdmUnO1xuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIHRpdGxlIG9mIGEgZHJhd2VyLiBUaGUgdXNlIG9mIHRoaXMgZGlyZWN0aXZlIGlzIG9wdGlvbmFsLlxuICogSWYgdXNlZCwgaXQgc2hvdWxkIGJlIHBsYWNlZCBhcyBmaXJzdCBlbGVtZW50IGluc2lkZSBhbiBgbWRjRHJhd2VySGVhZGVyYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJUaXRsZV0nXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RyYXdlclRpdGxlRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZHJhd2VyX190aXRsZScpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xufVxuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIHN1YnRpdGxlIG9mIGEgZHJhd2VyLiBUaGUgdXNlIG9mIHRoaXMgZGlyZWN0aXZlIGlzIG9wdGlvbmFsLlxuICogSWYgdXNlZCwgaXQgc2hvdWxkIGJlIHBsYWNlZCBhcyBhIHNpYmxpbmcgZWxlbWVudCBvZiBgbWRjRHJhd2VyVGl0bGVgXG4gKiBpbnNpZGUgYW4gYG1kY0RyYXdlckhlYWRlcmBcbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRHJhd2VyU3VidGl0bGVdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJTdWJ0aXRsZURpcmVjdGl2ZSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRyYXdlcl9fc3VidGl0bGUnKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBBIHRvb2xiYXIgaGVhZGVyIGlzIGFuIG9wdGlvbmFsIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEcmF3ZXJgLlxuICogVGhlIGhlYWRlciB3aWxsIG5vdCBzY3JvbGwgd2l0aCB0aGUgcmVzdCBvZiB0aGUgZHJhd2VyIGNvbnRlbnQsIHNvIGlzIGFcbiAqIGdvb2QgcGxhY2UgdG8gcGxhY2UgdGl0bGVzIGFuZCBhY2NvdW50IHN3aXRjaGVycy5cbiAqIFxuICogRGlyZWN0aXZlcyB0aGF0IGFyZSB0eXBpY2FsbHkgdXNlZCBpbnNpZGUgYW4gYG1kY0RyYXdlckhlYWRlcmA6XG4gKiBgbWRjRHJhd2VyVGl0bGVgLCBhbmQgYG1kY0RyYXdlclN1YlRpdGxlYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJIZWFkZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJIZWFkZXJEaXJlY3RpdmUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXJfX2hlYWRlcicpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xufVxuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIGRyYXdlciBjb250ZW50LiBZb3Ugd291bGQgdHlwaWNhbGx5IGFsc28gYXBwbHkgdGhlIGBtZGNMaXN0YFxuICogb3IgYG1kY0xpc3RHcm91cGAgZGlyZWN0aXZlIHRvIHRoZSBkcmF3ZXIgY29udGVudCAoc2VlIHRoZSBleGFtcGxlcykuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RyYXdlckNvbnRlbnRdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJDb250ZW50RGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZHJhd2VyX19jb250ZW50JykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG59XG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RyYXdlclNjcmltXSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRHJhd2VyU2NyaW1EaXJlY3RpdmUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItc2NyaW0nKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIGEgKG5hdmlnYXRpb24pIGRyYXdlci4gVGhlIGZvbGxvd2luZyBkcmF3ZXIgdHlwZXMgYXJlXG4gKiBzdXBwb3J0ZWQ6XG4gKiAqIGBwZXJtYW5lbnRgOiB0aGUgZGVmYXVsdCB0eXBlIGlmIG5vbmUgd2FzIHNwZWNpZmllZC5cbiAqICogYGRpc21pc3NpYmxlYDogdGhlIGRyYXdlciBpcyBoaWRkZW4gYnkgZGVmYXVsdCwgYW5kIGNhbiBzbGlkZSBpbnRvIHZpZXcuXG4gKiAgIFR5cGljYWxseSB1c2VkIHdoZW4gbmF2aWdhdGlvbiBpcyBub3QgY29tbW9uLCBhbmQgdGhlIG1haW4gYXBwIGNvbnRlbnQgaXNcbiAqICAgcHJpb3JpdGl6ZWQuXG4gKiAqIGBtb2RhbGA6IHRoZSBkcmF3ZXIgaXMgaGlkZGVuIGJ5IGRlZmF1bHQuIFdoZW4gYWN0aXZhdGVkLCB0aGUgZHJhd2VyIGlzIGVsZXZhdGVkXG4gKiAgIGFib3ZlIHRoZSBVSSBvZiB0aGUgYXBwLiBJdCB1c2VzIGEgc2NyaW0gdG8gYmxvY2sgaW50ZXJhY3Rpb24gd2l0aCB0aGUgcmVzdCBvZlxuICogICB0aGUgYXBwIHdpdGggYSBzY3JpbS5cbiAqIFxuICogRHJhd2VycyBtYXkgY29udGFpbiBhbiBgbWRjRHJhd2VySGVhZGVyYCwgYW5kIHNob3VsZCBjb250YWluIGFuIGBtZGNEcmF3ZXJDb250ZW50YFxuICogZGlyZWN0aXZlLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXInKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNMaXN0SXRlbURpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX2l0ZW1zPzogUXVlcnlMaXN0PE1kY0xpc3RJdGVtRGlyZWN0aXZlPjtcbiAgICBwcml2YXRlIF9vbkRvY3VtZW50Q2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHRoaXMub25Eb2N1bWVudENsaWNrKGV2ZW50KTtcbiAgICBwcml2YXRlIGZvY3VzVHJhcEhhbmRsZTogRm9jdXNUcmFwSGFuZGxlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB0eXBlOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnID0gJ3Blcm1hbmVudCc7XG4gICAgcHJpdmF0ZSBwcmV2aW91c0ZvY3VzOiBFbGVtZW50IHwgSFRNTE9yU1ZHRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgX29wZW46IGJvb2xlYW4gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudDtcbiAgICBwcml2YXRlIG1kY0FkYXB0ZXI6IE1EQ0RyYXdlckFkYXB0ZXIgPSB7XG4gICAgICAgIGFkZENsYXNzOiAoY2xhc3NOYW1lKSA9PiAgdGhpcy5fcm5kci5hZGRDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgY2xhc3NOYW1lKSxcbiAgICAgICAgcmVtb3ZlQ2xhc3M6IChjbGFzc05hbWUpID0+IHRoaXMuX3JuZHIucmVtb3ZlQ2xhc3ModGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQsIGNsYXNzTmFtZSksXG4gICAgICAgIGhhc0NsYXNzOiAoY2xhc3NOYW1lKSA9PiB0aGlzLl9lbG0ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSxcbiAgICAgICAgZWxlbWVudEhhc0NsYXNzOiAoZWxlbWVudCwgY2xhc3NOYW1lKSA9PiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpLFxuICAgICAgICBzYXZlRm9jdXM6ICgpID0+IHRoaXMucHJldmlvdXNGb2N1cyA9IHRoaXMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICAgICAgcmVzdG9yZUZvY3VzOiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcmV2ID0gdGhpcy5wcmV2aW91c0ZvY3VzIGFzIEhUTUxPclNWR0VsZW1lbnQgfCBudWxsO1xuICAgICAgICAgICAgaWYgKHByZXYgJiYgcHJldi5mb2N1cyAmJiB0aGlzLl9lbG0ubmF0aXZlRWxlbWVudC5jb250YWlucyh0aGlzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKVxuICAgICAgICAgICAgICAgIHByZXYuZm9jdXMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZm9jdXNBY3RpdmVOYXZpZ2F0aW9uSXRlbTogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy5faXRlbXMhLmZpbmQoaXRlbSA9PiBpdGVtLmFjdGl2ZSk7XG4gICAgICAgICAgICBhY3RpdmU/Ll9lbG0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9LFxuICAgICAgICBub3RpZnlDbG9zZTogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5maXhPcGVuQ2xvc2UoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5hZnRlckNsb3NlZC5lbWl0KCk7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25Eb2N1bWVudENsaWNrKTtcbiAgICAgICAgfSxcbiAgICAgICAgbm90aWZ5T3BlbjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5maXhPcGVuQ2xvc2UodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmFmdGVyT3BlbmVkLmVtaXQoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdtb2RhbCcpXG4gICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uRG9jdW1lbnRDbGljayk7XG4gICAgICAgIH0sXG4gICAgICAgIHRyYXBGb2N1czogKCkgPT4gdGhpcy50cmFwRm9jdXMoKSxcbiAgICAgICAgcmVsZWFzZUZvY3VzOiAoKSA9PiB0aGlzLnVudHJhcEZvY3VzKClcbiAgICB9O1xuICAgIHByaXZhdGUgZm91bmRhdGlvbjogTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9uIHwgbnVsbCA9IG51bGw7IC8vIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbiBleHRlbmRzIE1EQ0Rpc21pc3NpYmxlRHJhd2VyRm91bmRhdGlvblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZHJhd2VyIGlzIG9wZW5lZCBvciBjbG9zZWQuIFRoZSBldmVudCB2YWx1ZSB3aWxsIGJlXG4gICAgICogYHRydWVgIHdoZW4gdGhlIGRyYXdlciBpcyBvcGVuZWQsIGFuZCBgZmFsc2VgIHdoZW4gdGhlXG4gICAgICogZHJhd2VyIGlzIGNsb3NlZC4gKFdoZW4gdGhpcyBldmVudCBpcyB0cmlnZ2VyZWQsIHRoZSBkcmF3ZXIgaXMgc3RhcnRpbmcgdG8gb3Blbi9jbG9zZSxcbiAgICAgKiBidXQgdGhlIGFuaW1hdGlvbiBtYXkgbm90IGhhdmUgZnVsbHkgY29tcGxldGVkIHlldClcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbkNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgYWZ0ZXIgdGhlIGRyYXdlciBoYXMgZnVsbHkgb3BlbmVkLiBXaGVuIHRoaXMgZXZlbnQgaXMgZW1pdHRlZCB0aGUgZnVsbFxuICAgICAqIG9wZW5pbmcgYW5pbWF0aW9uIGhhcyBjb21wbGV0ZWQsIGFuZCB0aGUgZHJhd2VyIGlzIHZpc2libGUuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGFmdGVyT3BlbmVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCBhZnRlciB0aGUgZHJhd2VyIGhhcyBmdWxseSBjbG9zZWQuIFdoZW4gdGhpcyBldmVudCBpcyBlbWl0dGVkIHRoZSBmdWxsXG4gICAgICogY2xvc2luZyBhbmltYXRpb24gaGFzIGNvbXBsZXRlZCwgYW5kIHRoZSBkcmF3ZXIgaXMgbm90IHZpc2libGUgYW55bW9yZS5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgYWZ0ZXJDbG9zZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZiwgcHJvdGVjdGVkIF9ybmRyOiBSZW5kZXJlcjIsIEBJbmplY3QoRE9DVU1FTlQpIGRvYzogYW55LFxuICAgICAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgX2ZvY3VzVHJhcDogQWJzdHJhY3RNZGNGb2N1c1RyYXApIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvYyBhcyBEb2N1bWVudDsgLy8gd29yayBhcm91bmQgbmdjIGlzc3VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzIwMzUxXG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLmluaXREcmF3ZXIoKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95RHJhd2VyKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZXN0cm95RHJhd2VyKCkge1xuICAgICAgICAvLyB3aGVuIGZvdW5kYXRpb24gaXMgcmVjb25zdHJ1Y3RlZCBhbmQgdGhlbiAub3BlbigpIGlzIGNhbGxlZCxcbiAgICAgICAgLy8gaWYgdGhlc2UgY2xhc3NlcyBhcmUgc3RpbGwgYXZhaWxhYmxlIHRoZSBmb3VuZGF0aW9uIGFzc3VtZXMgb3BlbiB3YXMgYWxyZWFkeSBjYWxsZWQsXG4gICAgICAgIC8vIGFuZCBpdCB3b24ndCBkbyBhbnl0aGluZzpcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLWFuaW1hdGUnKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLWNsb3NpbmcnKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLW9wZW4nKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLW9wZW5pbmcnKTtcbiAgICAgICAgaWYgKHRoaXMuZm91bmRhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uRG9jdW1lbnRDbGljayk7XG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdERyYXdlcigpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95RHJhd2VyKCk7XG4gICAgICAgIGxldCBuZXdGb3VuZGF0aW9uOiBNRENEaXNtaXNzaWJsZURyYXdlckZvdW5kYXRpb24gfCBudWxsID0gbnVsbDtcbiAgICAgICAgY29uc3QgdGhpeiA9IHRoaXM7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdkaXNtaXNzaWJsZScpXG4gICAgICAgICAgICBuZXdGb3VuZGF0aW9uID0gbmV3IGNsYXNzIGV4dGVuZHMgTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9ue1xuICAgICAgICAgICAgICAgIGNsb3NlKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWl0ID0gdGhpei5fb3BlbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpei5fb3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICBlbWl0ID8gdGhpei5vcGVuQ2hhbmdlLmVtaXQodGhpei5fb3BlbikgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9wZW4oKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtaXQgPSAhdGhpei5fb3BlbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpei5fb3BlbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyLm9wZW4oKTtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCA/IHRoaXoub3BlbkNoYW5nZS5lbWl0KHRoaXouX29wZW4pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0odGhpcy5tZGNBZGFwdGVyKTtcbiAgICAgICAgZWxzZSBpZiAodGhpcy50eXBlID09PSAnbW9kYWwnKVxuICAgICAgICAgICAgbmV3Rm91bmRhdGlvbiA9IG5ldyBjbGFzcyBleHRlbmRzIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbntcbiAgICAgICAgICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1pdCA9IHRoaXouX29wZW47XG4gICAgICAgICAgICAgICAgICAgIHRoaXouX29wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCA/IHRoaXoub3BlbkNoYW5nZS5lbWl0KHRoaXouX29wZW4pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvcGVuKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWl0ID0gIXRoaXouX29wZW47XG4gICAgICAgICAgICAgICAgICAgIHRoaXouX29wZW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBzdXBlci5vcGVuKCk7XG4gICAgICAgICAgICAgICAgICAgIGVtaXQgPyB0aGl6Lm9wZW5DaGFuZ2UuZW1pdCh0aGl6Ll9vcGVuKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KHRoaXMubWRjQWRhcHRlcik7XG4gICAgICAgIC8vIGVsc2U6IHBlcm1hbmVudCBkcmF3ZXIgLT4gZG9lc24ndCBuZWVkIGEgZm91bmRhdGlvbiwganVzdCBzdHlsaW5nXG4gICAgICAgIGlmIChuZXdGb3VuZGF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24gPSBuZXdGb3VuZGF0aW9uO1xuICAgICAgICAgICAgbmV3Rm91bmRhdGlvbi5pbml0KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3BlbilcbiAgICAgICAgICAgICAgICBuZXdGb3VuZGF0aW9uLm9wZW4oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItLW1vZGFsJykgZ2V0IF9pc01vZGFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnbW9kYWwnO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItLWRpc21pc3NpYmxlJykgZ2V0IF9pc0Rpc21pc2libGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkaXNtaXNzaWJsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB0eXBlIG9mIGRyYXdlci4gRWl0aGVyIGBwZXJtYW5lbnRgLCBgZGlzbWlzc2libGVgLCBvciBgbW9kYWxgLlxuICAgICAqIFRoZSBkZWZhdWx0IHR5cGUgaXMgYHBlcm1hbmVudGAuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG1kY0RyYXdlcigpOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZTtcbiAgICB9XG5cbiAgICBzZXQgbWRjRHJhd2VyKHZhbHVlOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gJ2Rpc21pc3NpYmxlJyAmJiB2YWx1ZSAhPT0gJ21vZGFsJylcbiAgICAgICAgICAgIHZhbHVlID0gJ3Blcm1hbmVudCc7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdGhpcy50eXBlKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuaW5pdERyYXdlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX21kY0RyYXdlcjogJ3Blcm1hbmVudCcgfCAnZGlzbWlzc2libGUnIHwgJ21vZGFsJyB8ICcnO1xuXG4gICAgLyoqXG4gICAgICogSW5wdXQgdG8gb3BlbiAoYXNzaWduIHZhbHVlIGB0cnVlYCkgb3IgY2xvc2UgKGFzc2lnbiB2YWx1ZSBgZmFsc2VgKVxuICAgICAqIHRoZSBkcmF3ZXIuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG9wZW4oKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX29wZW47XG4gICAgfVxuXG4gICAgc2V0IG9wZW4odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgbGV0IG5ld1ZhbHVlID0gYXNCb29sZWFuKHZhbHVlKTtcbiAgICAgICAgaWYgKG5ld1ZhbHVlICE9PSB0aGlzLl9vcGVuKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5mb3VuZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgbmV3VmFsdWUgPyB0aGlzLmZvdW5kYXRpb24ub3BlbigpIDogdGhpcy5mb3VuZGF0aW9uLmNsb3NlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX29wZW4gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChuZXdWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfb3BlbjogYm9vbGVhbiB8ICcnO1xuXG4gICAgcHJpdmF0ZSBmaXhPcGVuQ2xvc2Uob3BlbjogYm9vbGVhbikge1xuICAgICAgICAvLyB0aGUgZm91bmRhdGlvbiBpZ25vcmVzIGNhbGxzIHRvIG9wZW4vY2xvc2Ugd2hpbGUgYW4gb3BlbmluZy9jbG9zaW5nIGFuaW1hdGlvbiBpcyBydW5uaW5nLlxuICAgICAgICAvLyBzbyB3aGVuIHRoZSBhbmltYXRpb24gZW5kcywgd2UncmUganVzdCBnb2luZyB0byB0cnkgYWdhaW5cbiAgICAgICAgLy8gKG5lZWRzIHRvIGJlIGRvbmUgaW4gdGhlIG5leHQgbWljcm8gY3ljbGUsIGJlY2F1c2Ugb3RoZXJ3aXNlIGZvdW5kYXRpb24gd2lsbCBzdGlsbCB0aGluayBpdCdzXG4gICAgICAgIC8vIHJ1bm5pbmcgdGhlIG9wZW5pbmcvY2xvc2luZyBhbmltYXRpb24pOlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vcGVuICE9PSBvcGVuKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29wZW4pXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm91bmRhdGlvbiEub3BlbigpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uIS5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRyYXBGb2N1cygpIHtcbiAgICAgICAgdGhpcy51bnRyYXBGb2N1cygpO1xuICAgICAgICBpZiAodGhpcy5fZm9jdXNUcmFwKVxuICAgICAgICAgICAgdGhpcy5mb2N1c1RyYXBIYW5kbGUgPSB0aGlzLl9mb2N1c1RyYXAudHJhcEZvY3VzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bnRyYXBGb2N1cygpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9jdXNUcmFwSGFuZGxlICYmIHRoaXMuZm9jdXNUcmFwSGFuZGxlLmFjdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c1RyYXBIYW5kbGUudW50cmFwKCk7XG4gICAgICAgICAgICB0aGlzLmZvY3VzVHJhcEhhbmRsZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24/LmhhbmRsZUtleWRvd24oZXZlbnQpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgWyckZXZlbnQnXSkgaGFuZGxlVHJhbnNpdGlvbkVuZChldmVudDogVHJhbnNpdGlvbkV2ZW50KSB7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbj8uaGFuZGxlVHJhbnNpdGlvbkVuZChldmVudCk7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnbW9kYWwnKSB7XG4gICAgICAgICAgICAvLyBpbnN0ZWFkIG9mIGxpc3RlbmluZyB0byBjbGljayBldmVudCBvbiBtZGNEcmF3ZXJTY3JpbSAod2hpY2ggd291bGQgcmVxdWlyZSB3aXJpbmcgYmV0d2VlblxuICAgICAgICAgICAgLy8gbWRjRHJhd2VyU2NyaW0gYW5kIG1kY0RyYXdlciksIHdlIGp1c3QgbGlzdGVuIHRvIGRvY3VtZW50IGNsaWNrcy5cbiAgICAgICAgICAgIGxldCBlbDogRWxlbWVudCB8IG51bGwgPSBldmVudC50YXJnZXQgYXMgRWxlbWVudDtcbiAgICAgICAgICAgIHdoaWxlIChlbCkge1xuICAgICAgICAgICAgICAgIGlmIChlbCA9PT0gdGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAodGhpcy5mb3VuZGF0aW9uIGFzIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbik/LmhhbmRsZVNjcmltQ2xpY2soKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBVc2UgdGhpcyBkaXJlY3RpdmUgZm9yIG1hcmtpbmcgdGhlIHNpYmxpbmcgZWxlbWVudCBhZnRlciBhIGRpc21pc3NpYmxlIGBtZGNEcmF3ZXJgLlxuICogVGhpcyB3aWxsIGFwcGx5IHN0eWxpbmcgc28gdGhhdCB0aGUgb3Blbi9jbG9zZSBhbmltYXRpb25zIHdvcmsgY29ycmVjdGx5LlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJBcHBDb250ZW50XSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRHJhd2VyQXBwQ29udGVudCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRyYXdlci1hcHAtY29udGVudCcpIF9jbHMgPSB0cnVlO1xuXG4gICAgLyoqXG4gICAgICogU2V0IHRoaXMgdG8gZmFsc2UgdG8gZGlzYWJsZSB0aGUgc3R5bGluZyBmb3Igc2liYmxpbmcgYXBwIGNvbnRlbnQgb2YgYSBkaXNtaXNzaWJsZSBkcmF3ZXIuXG4gICAgICogVGhpcyBpcyB0eXBpY2FsbHkgb25seSB1c2VkIHdoZW4geW91ciBgbWRjRHJhd2VyYCB0eXBlIGlzIGR5bmFtaWMuIEluIHRob3NlIGNhc2VzIHlvdSBjYW5cbiAgICAgKiBkaXNhYmxlIHRoZSBgbWRjRHJhd2VyQXBwQ29udGVudGAgd2hlbiB5b3Ugc2V0IHlvdXIgZHJhd2VyIHR5cGUgdG8gYW55dGhpbmcgb3RoZXIgdGhhblxuICAgICAqIGBkaXNtaXNzaWJsZWAuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG1kY0RyYXdlckFwcENvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbHM7XG4gICAgfVxuXG4gICAgc2V0IG1kY0RyYXdlckFwcENvbnRlbnQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fY2xzID0gYXNCb29sZWFuKHZhbHVlKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbWRjRHJhd2VyQXBwQ29udGVudDogYm9vbGVhbiB8ICcnO1xufVxuXG5leHBvcnQgY29uc3QgRFJBV0VSX0RJUkVDVElWRVMgPSBbXG4gICAgTWRjRHJhd2VyVGl0bGVEaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyU3VidGl0bGVEaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VySGVhZGVyRGlyZWN0aXZlLFxuICAgIE1kY0RyYXdlckNvbnRlbnREaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyU2NyaW1EaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyRGlyZWN0aXZlLFxuICAgIE1kY0RyYXdlckFwcENvbnRlbnRcbl07XG4iXX0=