@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
430 lines • 53.8 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ChangeDetectorRef, Component, ElementRef, HostListener, Injector, Input } from '@angular/core';
import { Debounce } from '@microsoft/windows-admin-center-sdk/core/base/decorators/debounce.decorators';
import { Dom } from '@microsoft/windows-admin-center-sdk/core/dom/dom';
import { Subject } from 'rxjs';
import { CoreBaseComponent } from '../common/base.component';
import * as i0 from "@angular/core";
import * as i1 from "../backdrop/backdrop.component";
import * as i2 from "@angular/common";
import * as i3 from "../tooltip/tooltip.directive";
const _c0 = ["*"];
function DialogComponent_sme_backdrop_0_button_2_Template(rf, ctx) { if (rf & 1) {
const _r5 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 8);
i0.ɵɵlistener("click", function DialogComponent_sme_backdrop_0_button_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r4 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r4.onCloseClicked()); });
i0.ɵɵelement(1, "span", 9);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("title", ctx_r1.strings.MsftSmeShell.Angular.Common.close);
i0.ɵɵattribute("aria-label", ctx_r1.strings.MsftSmeShell.Angular.Common.close);
} }
function DialogComponent_sme_backdrop_0_span_9_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 10);
i0.ɵɵtext(1);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("id", ctx_r2.idBag.ariaLabelSpan);
i0.ɵɵadvance(1);
i0.ɵɵtextInterpolate(ctx_r2.ariaLabel);
} }
function DialogComponent_sme_backdrop_0_span_10_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 10);
i0.ɵɵtext(1);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r3 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("id", ctx_r3.idBag.ariaDescriptionSpan);
i0.ɵɵadvance(1);
i0.ɵɵtextInterpolate(ctx_r3.ariaDescription);
} }
function DialogComponent_sme_backdrop_0_Template(rf, ctx) { if (rf & 1) {
const _r7 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-backdrop", 1);
i0.ɵɵlistener("clicked", function DialogComponent_sme_backdrop_0_Template_sme_backdrop_clicked_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r6 = i0.ɵɵnextContext(); return i0.ɵɵresetView(!!ctx_r6.clickBackdrop ? ctx_r6.onBackgroundClicked() : ""); });
i0.ɵɵelementStart(1, "div", 2);
i0.ɵɵtemplate(2, DialogComponent_sme_backdrop_0_button_2_Template, 2, 2, "button", 3);
i0.ɵɵelementStart(3, "div", 4);
i0.ɵɵprojection(4);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(5, "div", 5);
i0.ɵɵprojection(6, 1);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(7, "div", 6);
i0.ɵɵprojection(8, 2);
i0.ɵɵelementEnd()();
i0.ɵɵtemplate(9, DialogComponent_sme_backdrop_0_span_9_Template, 2, 2, "span", 7);
i0.ɵɵtemplate(10, DialogComponent_sme_backdrop_0_span_10_Template, 2, 2, "span", 7);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵproperty("level", ctx_r0.dialogLevel)("showBackdrop", ctx_r0.showBackdrop)("allowBackgroundInteraction", ctx_r0.allowBackgroundInteraction);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngClass", ctx_r0.dialogClasses);
i0.ɵɵattribute("role", ctx_r0.dialogRole)("aria-hidden", !ctx_r0.visible)("aria-labelledby", ctx_r0.ariaLabel ? ctx_r0.idBag.ariaLabelSpan : "sme-dialog-title")("aria-describedby", ctx_r0.ariaDescription ? ctx_r0.idBag.ariaDescriptionSpan : "sme-dialog-desc");
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r0.closeButton);
i0.ɵɵadvance(7);
i0.ɵɵproperty("ngIf", ctx_r0.ariaLabel);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r0.ariaDescription);
} }
const _c1 = [[["sme-dialog-header"]], [["sme-dialog-content"]], [["sme-dialog-footer"]]];
const _c2 = ["sme-dialog-header", "sme-dialog-content", "sme-dialog-footer"];
/**
*
* @smeDoc {@label Dialog @id sme-dialog}
*
* @overview
* @file {@filepath ./examples/dialog-overview.md}
*
* @example {@label Basic Usage @id basic-usage}
* @file {@filename component.ts @filepath ./examples/dialog-example.component.ts}
* @file {@filename component.html @filepath ./examples/dialog-example.component.html}
*
* @example {@label Dialog Chain @id dialog-chain}
* @file {@filename component.ts @filepath ./examples/dialog-example-dialog-chain.component.ts}
* @file {@filename component.html @filepath ./examples/dialog-example-dialog-chain.component.html}
*
* @example {@label Full Screen Dialog @id full-screen-dialog}
* @file {@filename component.ts @filepath ./examples/dialog-example-full-screen-dialog.component.ts}
* @file {@filename component.html @filepath ./examples/dialog-example-full-screen-dialog.component.html}
*
*/
export class DialogHeaderComponent {
}
/** @nocollapse */ DialogHeaderComponent.ɵfac = function DialogHeaderComponent_Factory(t) { return new (t || DialogHeaderComponent)(); };
/** @nocollapse */ DialogHeaderComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DialogHeaderComponent, selectors: [["sme-dialog-header"]], ngContentSelectors: _c0, decls: 2, vars: 0, consts: [[1, "sme-padding-horizontal-lg", "sme-padding-vertical-sm"]], template: function DialogHeaderComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵelementStart(0, "div", 0);
i0.ɵɵprojection(1);
i0.ɵɵelementEnd();
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DialogHeaderComponent, [{
type: Component,
args: [{
selector: 'sme-dialog-header',
template: '<div class="sme-padding-horizontal-lg sme-padding-vertical-sm"><ng-content></ng-content></div>'
}]
}], null, null); })();
export class DialogContentComponent {
}
/** @nocollapse */ DialogContentComponent.ɵfac = function DialogContentComponent_Factory(t) { return new (t || DialogContentComponent)(); };
/** @nocollapse */ DialogContentComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DialogContentComponent, selectors: [["sme-dialog-content"]], ngContentSelectors: _c0, decls: 1, vars: 0, template: function DialogContentComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵprojection(0);
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DialogContentComponent, [{
type: Component,
args: [{
selector: 'sme-dialog-content',
template: '<ng-content></ng-content>'
}]
}], null, null); })();
export class DialogFooterComponent {
}
/** @nocollapse */ DialogFooterComponent.ɵfac = function DialogFooterComponent_Factory(t) { return new (t || DialogFooterComponent)(); };
/** @nocollapse */ DialogFooterComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DialogFooterComponent, selectors: [["sme-dialog-footer"]], ngContentSelectors: _c0, decls: 2, vars: 0, consts: [[1, "sme-layout-dialog-footer"]], template: function DialogFooterComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef();
i0.ɵɵelementStart(0, "div", 0);
i0.ɵɵprojection(1);
i0.ɵɵelementEnd();
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DialogFooterComponent, [{
type: Component,
args: [{
selector: 'sme-dialog-footer',
template: `<div class="sme-layout-dialog-footer">
<ng-content></ng-content></div>`
}]
}], null, null); })();
export var DialogCloseReason;
(function (DialogCloseReason) {
DialogCloseReason[DialogCloseReason["SoftDismiss"] = 0] = "SoftDismiss";
DialogCloseReason[DialogCloseReason["CloseButton"] = 1] = "CloseButton";
DialogCloseReason[DialogCloseReason["EscapeKey"] = 2] = "EscapeKey";
DialogCloseReason[DialogCloseReason["CompetingDialog"] = 3] = "CompetingDialog";
})(DialogCloseReason || (DialogCloseReason = {}));
export class DialogMode {
}
DialogMode.pane = 'pane';
DialogMode.widePane = 'wide-pane';
DialogMode.compact = 'compact';
DialogMode.compactSquare = 'compact-square';
DialogMode.fullscreen = 'fullscreen';
DialogMode.centered = 'centered';
DialogMode.centeredMedium = 'centered-medium';
DialogMode.centeredLarge = 'centered-large';
DialogMode.notification = 'notification';
export const modalDialog = 'modal';
export const alertDialog = 'alert';
export class DialogComponent extends CoreBaseComponent {
constructor(elementRef, changeDetectorRef, injector) {
super(injector);
this.elementRef = elementRef;
this.changeDetectorRef = changeDetectorRef;
this.dialogRole = 'alertdialog';
this.strings = MsftSme.getStrings();
this.dialogLevel = 1;
/**
* Whether to allow interaction with elements from outside the dialog especially to support the hovering events.
*/
this.allowBackgroundInteraction = false;
/**
* Whether to render the dialog background. False to hide the dialog container and make the background transparent.
* The background color then will be based on the dialog body.
*/
this.showBackdrop = true;
/**
* Whether to enable the feature of clicking outside of the dialog to close the current dialog.
* True means clicking outside the dialog will close the dialog. We want this to be set to false when there are forms in the dialog.
*/
this.clickBackdrop = true;
this.ariaLabel = '';
this.ariaDescription = '';
/**
* Dialog types. Mostly used for accessibility. Valid values:
* @see modalDialog = 'modal';
* @see alertDialog = "alert";
*/
this.dialogType = '';
/**
* Flag to determine whether the dialog should have a close button in top right or not
*/
this.closeButton = false;
/**
* Compact dialog can be full height when displaying on the right side of the screen.
* It can also be displayed in the middle of the screen that needs to be having paddings to each direction.
* This compactFullHeight to true will always be 100% height. Otherwise css would control the max height.
*/
this.compactFullHeight = false;
this.doAutoFocus = false;
this.isVisible = false;
this.mode = DialogMode.pane;
// Create closeRequested subject to notify dialogs when a close is requested and how it was requested (DialogCloseReason)
this.closeRequested = new Subject();
this.setDialogModeFromInput();
// setup dialog id and idBag
this.dialogId = DialogComponent.nextDialogId++;
this.idBag = this.createIdBag();
MsftSme.forEachKey(this.idBag, (key) => {
this.idBag[key] = `dialog-${this.dialogId.toString()}-${key}`;
});
}
/**
* The source name to use for logging
*/
get logSourceName() {
return 'DialogComponent';
}
/**
* Sets whether this should be an action pane or a centered dialog
*
* @deprecated Use dialogMode instead
* @param newValue if true, uses a left pane dialog, otherwise a centered dialog
*/
set actionPane(newValue) {
if (newValue) {
this.dialogMode = DialogMode.pane;
}
else {
this.dialogMode = DialogMode.centered;
}
this.setDialogModeFromInput();
}
/**
* Indicates the dialog mode to use
* @see DialogMode
*/
set dialogMode(mode) {
this.mode = mode;
}
get dialogMode() {
return this.mode;
}
set visible(visible) {
this.isVisible = visible;
this.doAutoFocus = visible;
}
get visible() {
return this.isVisible;
}
// document:keyup.escape is used so that a dialog is not closed when trying to close a tooltip
onKeyUp() {
if (this.visible) {
this.onEscapePressed();
}
}
/**
* Angular Life Cycle hook for After View Checked.
* When the visibility changes, we are going to focus on the first element that has the autofocus attribute
*/
ngAfterViewChecked() {
if (this.doAutoFocus) {
this.autoFocus();
}
}
/**
* Completed the closeRequested subject
*/
ngOnDestroy() {
this.closeRequested.complete();
}
/**
* Auto focus on first element that is focusable
*/
autoFocus() {
this.doAutoFocus = false;
if (this.elementRef.nativeElement) {
// If the dialog has a loading wheel, focus first goes to the loading wheel then gets lost.
// TO avoid this, we get the parent element or native element of the dialog, then get the first
// focusable element in that element
const element = this.elementRef.nativeElement.parentElement || this.elementRef.nativeElement;
const firstFocusable = Dom.getFirstFocusableDescendent(element);
if (firstFocusable) {
firstFocusable.focus();
}
}
}
/**
* Shows the dialog.
*/
show() {
this.visible = true;
}
/**
* Hides the dialog.
*/
hide() {
this.visible = false;
this.changeDetectorRef.detectChanges();
}
/**
* Notifies closeRequested subscribers that the backdrop has been clicked, requesting a soft dismiss
*/
onBackgroundClicked() {
this.closeRequested.next(DialogCloseReason.SoftDismiss);
}
/**
* Notifies closeRequested subscribers that the close button has been pressed, requesting a close button dismiss
*/
onCloseClicked() {
this.closeRequested.next(DialogCloseReason.CloseButton);
}
onEscapePressed() {
this.closeRequested.next(DialogCloseReason.EscapeKey);
}
ngOnChanges(changes) {
const dialogModeChange = changes['dialogMode'];
if (dialogModeChange && dialogModeChange.currentValue) {
this.setDialogModeFromInput();
}
}
setDialogModeFromInput() {
const newValue = this.dialogMode.toLowerCase().trim();
const classes = ['sme-layout-absolute', 'sme-scheme-dialog', 'sme-animation-transition-width-xs', 'sme-responsive-dialog'];
const commonPaneClasses = ['sme-position-vertical-none', 'sme-position-right-none'];
if (newValue === DialogMode.pane) {
classes.push(...commonPaneClasses, 'sme-layout-dialog-pane', 'sme-shadow-action-pane');
}
else if (newValue === DialogMode.widePane) {
classes.push(...commonPaneClasses, 'sme-layout-dialog-wide-pane', 'sme-shadow-action-pane');
}
else if (newValue === DialogMode.compact) {
classes.push(...commonPaneClasses, 'sme-layout-dialog-compact', 'sme-shadow-action-pane');
if (this.compactFullHeight) {
classes.push('sme-layout-dialog-compact-full-height');
}
}
else if (newValue === DialogMode.compactSquare) {
classes.push('sme-position-center', 'sme-layout-dialog-centered', 'sme-layout-dialog-compact-square', 'sme-shadow-dialog');
if (this.compactFullHeight) {
classes.push('sme-layout-dialog-compact-full-height');
}
}
else if (newValue === DialogMode.fullscreen) {
classes.push(...commonPaneClasses, 'sme-layout-dialog-fullscreen', 'sme-shadow-action-pane');
}
else if (newValue === DialogMode.centered) {
classes.push('sme-position-center', 'sme-layout-dialog-centered', 'sme-shadow-dialog');
}
else if (newValue === DialogMode.centeredMedium) {
classes.push('sme-position-center', 'sme-layout-dialog-centered-medium', 'sme-shadow-dialog');
}
else if (newValue === DialogMode.centeredLarge) {
classes.push('sme-position-center', 'sme-layout-dialog-centered-large', 'sme-shadow-dialog');
}
else if (newValue === DialogMode.notification) {
classes.push('sme-position-top-sm', 'sme-position-right-sm', 'sme-layout-dialog-notification', 'sme-shadow-dialog');
}
classes.push('sme-arrange-stack-v', 'sme-arrange-overflow-auto');
this.dialogClasses = classes;
// accessibility
if (this.dialogType) {
this.dialogRole = this.dialogType === modalDialog ? 'dialog' : 'alertdialog';
}
else {
// by default centered dialogs are considered as alerts
const alertModes = [DialogMode.centered, DialogMode.centeredLarge, DialogMode.compactSquare];
this.dialogRole = alertModes.some(mode => this.dialogMode === mode) ? 'alertdialog' : 'dialog';
}
}
/**
* Creates the idBag used by this component to store unique element ids.
*/
createIdBag() {
return {
ariaLabelSpan: '',
ariaDescriptionSpan: ''
};
}
}
/**
* Static constant to provide unique ids for each master view
*/
DialogComponent.nextDialogId = 0;
/** @nocollapse */ DialogComponent.ɵfac = function DialogComponent_Factory(t) { return new (t || DialogComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.Injector)); };
/** @nocollapse */ DialogComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DialogComponent, selectors: [["sme-dialog"]], hostBindings: function DialogComponent_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵlistener("keyup.escape", function DialogComponent_keyup_escape_HostBindingHandler() { return ctx.onKeyUp(); }, false, i0.ɵɵresolveDocument);
} }, inputs: { allowBackgroundInteraction: "allowBackgroundInteraction", showBackdrop: "showBackdrop", clickBackdrop: "clickBackdrop", ariaLabel: "ariaLabel", ariaDescription: "ariaDescription", actionPane: "actionPane", dialogMode: "dialogMode", dialogType: "dialogType", closeButton: "closeButton", compactFullHeight: "compactFullHeight" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], ngContentSelectors: _c2, decls: 1, vars: 1, consts: [["class", "sme-layout-absolute sme-position-inset-none", 3, "level", "showBackdrop", "allowBackgroundInteraction", "clicked", 4, "ngIf"], [1, "sme-layout-absolute", "sme-position-inset-none", 3, "level", "showBackdrop", "allowBackgroundInteraction", "clicked"], ["aria-modal", "true", 3, "ngClass"], ["class", "sme-button-trigger sme-button-auto-width sme-dialog-close-button", 3, "title", "click", 4, "ngIf"], [1, "sme-position-flex-none", "sme-focus-zone"], [1, "sme-layout-relative", "sme-position-flex-auto", "sme-padding-horizontal-lg", "sme-arrange-overflow-auto-y", "sme-arrange-overflow-hide-x", "sme-focus-zone", "sme-layout-responsive-zone-xs", "sme-dialog-content-wrapper"], [1, "sme-position-flex-none", "sme-focus-zone", "sme-padding-horizontal-lg", "sme-padding-vertical-sm"], ["class", "sme-screen-reader", 3, "id", 4, "ngIf"], [1, "sme-button-trigger", "sme-button-auto-width", "sme-dialog-close-button", 3, "title", "click"], [1, "sme-icon", "sme-icon-cancel"], [1, "sme-screen-reader", 3, "id"]], template: function DialogComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵprojectionDef(_c1);
i0.ɵɵtemplate(0, DialogComponent_sme_backdrop_0_Template, 11, 11, "sme-backdrop", 0);
} if (rf & 2) {
i0.ɵɵproperty("ngIf", ctx.visible);
} }, dependencies: [i1.BackdropComponent, i2.NgClass, i2.NgIf, i3.TooltipDirective], encapsulation: 2 });
__decorate([
Debounce(0),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], DialogComponent.prototype, "autoFocus", null);
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DialogComponent, [{
type: Component,
args: [{ selector: 'sme-dialog', template: "<sme-backdrop *ngIf=\"visible\" [level]=\"dialogLevel\" (clicked)=\"!!clickBackdrop ? onBackgroundClicked() : ''\"\r\n [showBackdrop]=\"showBackdrop\" [allowBackgroundInteraction]=\"allowBackgroundInteraction\"\r\n class=\"sme-layout-absolute sme-position-inset-none\">\r\n <div [ngClass]=\"dialogClasses\" [attr.role]=\"dialogRole\" [attr.aria-hidden]=\"!visible\"\r\n [attr.aria-labelledby]=\"ariaLabel ? idBag.ariaLabelSpan :'sme-dialog-title'\"\r\n [attr.aria-describedby]=\"ariaDescription ? idBag.ariaDescriptionSpan : 'sme-dialog-desc'\" aria-modal=\"true\">\r\n <button *ngIf=\"closeButton\" class=\"sme-button-trigger sme-button-auto-width sme-dialog-close-button\"\r\n (click)=\"onCloseClicked()\" [attr.aria-label]=\"strings.MsftSmeShell.Angular.Common.close\"\r\n [title]=\"strings.MsftSmeShell.Angular.Common.close\">\r\n <span class=\"sme-icon sme-icon-cancel\"></span>\r\n </button>\r\n <div class=\"sme-position-flex-none sme-focus-zone\">\r\n <ng-content select=\"sme-dialog-header\"></ng-content>\r\n </div>\r\n <div class=\"sme-layout-relative sme-position-flex-auto sme-padding-horizontal-lg sme-arrange-overflow-auto-y sme-arrange-overflow-hide-x sme-focus-zone sme-layout-responsive-zone-xs sme-dialog-content-wrapper\">\r\n <ng-content select=\"sme-dialog-content\"></ng-content>\r\n </div>\r\n <div class=\"sme-position-flex-none sme-focus-zone sme-padding-horizontal-lg sme-padding-vertical-sm\">\r\n <ng-content select=\"sme-dialog-footer\"></ng-content>\r\n </div>\r\n </div>\r\n <span *ngIf=\"ariaLabel\" class=\"sme-screen-reader\" [id]=\"idBag.ariaLabelSpan\">{{ariaLabel}}</span>\r\n <span *ngIf=\"ariaDescription\" class=\"sme-screen-reader\" [id]=\"idBag.ariaDescriptionSpan\">{{ariaDescription}}</span>\r\n</sme-backdrop>\r\n" }]
}], function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }]; }, { allowBackgroundInteraction: [{
type: Input
}], showBackdrop: [{
type: Input
}], clickBackdrop: [{
type: Input
}], ariaLabel: [{
type: Input
}], ariaDescription: [{
type: Input
}], actionPane: [{
type: Input
}], dialogMode: [{
type: Input
}], dialogType: [{
type: Input
}], closeButton: [{
type: Input
}], compactFullHeight: [{
type: Input
}], onKeyUp: [{
type: HostListener,
args: ['document:keyup.escape']
}], autoFocus: [] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL2RpYWxvZy9kaWFsb2cuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZGlhbG9nL2RpYWxvZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUVILGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixRQUFRLEVBQ1IsS0FBSyxFQUlSLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw4RUFBOEUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFDdkUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUvQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7SUNWekQsaUNBRXNEO0lBRHBELCtLQUFTLGVBQUEsdUJBQWdCLENBQUEsSUFBQztJQUUxQiwwQkFBOEM7SUFDaEQsaUJBQVM7OztJQUZQLHdFQUFtRDtJQUR4Qiw4RUFBNkQ7OztJQWM1RixnQ0FBNkU7SUFBQSxZQUFhO0lBQUEsaUJBQU87OztJQUEvQywrQ0FBMEI7SUFBQyxlQUFhO0lBQWIsc0NBQWE7OztJQUMxRixnQ0FBeUY7SUFBQSxZQUFtQjtJQUFBLGlCQUFPOzs7SUFBM0QscURBQWdDO0lBQUMsZUFBbUI7SUFBbkIsNENBQW1COzs7O0lBdEI5Ryx1Q0FFc0Q7SUFGRiwrS0FBVyx3Q0FBa0IsNEJBQXFCLEdBQUcsRUFBRSxDQUFBLElBQUM7SUFHMUcsOEJBRThHO0lBQzVHLHFGQUlTO0lBQ1QsOEJBQW1EO0lBQ2pELGtCQUFvRDtJQUN0RCxpQkFBTTtJQUNOLDhCQUFrTjtJ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QkEsa0NBQWE7O0FEb1B4QjtJQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Ozs7Z0RBYVg7dUZBM0tRLGVBQWU7Y0FKM0IsU0FBUzsyQkFDSSxZQUFZO29IQXFDTiwwQkFBMEI7a0JBQXpDLEtBQUs7WUFNVSxZQUFZO2tCQUEzQixLQUFLO1lBTVUsYUFBYTtrQkFBNUIsS0FBSztZQUNVLFNBQVM7a0JBQXhCLEtBQUs7WUFDVSxlQUFlO2tCQUE5QixLQUFLO1lBUWMsVUFBVTtrQkFBN0IsS0FBSztZQWVLLFVBQVU7a0JBRHBCLEtBQUs7WUFjVSxVQUFVO2tCQUF6QixLQUFLO1lBS1UsV0FBVztrQkFBMUIsS0FBSztZQU9VLGlCQUFpQjtrQkFBaEMsS0FBSztZQW9DQyxPQUFPO2tCQURiLFlBQVk7bUJBQUMsdUJBQXVCO1lBNEI5QixTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIEFmdGVyVmlld0NoZWNrZWQsXHJcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcclxuICAgIENvbXBvbmVudCxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbmplY3RvcixcclxuICAgIElucHV0LFxyXG4gICAgT25DaGFuZ2VzLFxyXG4gICAgT25EZXN0cm95LFxyXG4gICAgU2ltcGxlQ2hhbmdlc1xyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEZWJvdW5jZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kZWNvcmF0b3JzL2RlYm91bmNlLmRlY29yYXRvcnMnO1xyXG5pbXBvcnQgeyBEb20gfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL2RvbS9kb20nO1xyXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFN0cmluZ3MgfSBmcm9tICcuLi8uLi9nZW5lcmF0ZWQvc3RyaW5ncyc7XHJcbmltcG9ydCB7IENvcmVCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29tbW9uL2Jhc2UuY29tcG9uZW50JztcclxuXHJcbi8qKlxyXG4gKlxyXG4gKiBAc21lRG9jIHtAbGFiZWwgRGlhbG9nIEBpZCBzbWUtZGlhbG9nfVxyXG4gKlxyXG4gKiBAb3ZlcnZpZXdcclxuICogQGZpbGUge0BmaWxlcGF0aCAuL2V4YW1wbGVzL2RpYWxvZy1vdmVydmlldy5tZH1cclxuICpcclxuICogQGV4YW1wbGUge0BsYWJlbCBCYXNpYyBVc2FnZSBAaWQgYmFzaWMtdXNhZ2V9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50LnRzIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2RpYWxvZy1leGFtcGxlLmNvbXBvbmVudC50c31cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQuaHRtbCBAZmlsZXBhdGggLi9leGFtcGxlcy9kaWFsb2ctZXhhbXBsZS5jb21wb25lbnQuaHRtbH1cclxuICpcclxuICogQGV4YW1wbGUge0BsYWJlbCBEaWFsb2cgQ2hhaW4gQGlkIGRpYWxvZy1jaGFpbn1cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQudHMgQGZpbGVwYXRoIC4vZXhhbXBsZXMvZGlhbG9nLWV4YW1wbGUtZGlhbG9nLWNoYWluLmNvbXBvbmVudC50c31cclxuICogQGZpbGUge0BmaWxlbmFtZSBjb21wb25lbnQuaHRtbCBAZmlsZXBhdGggLi9leGFtcGxlcy9kaWFsb2ctZXhhbXBsZS1kaWFsb2ctY2hhaW4uY29tcG9uZW50Lmh0bWx9XHJcbiAqXHJcbiAqIEBleGFtcGxlIHtAbGFiZWwgRnVsbCBTY3JlZW4gRGlhbG9nIEBpZCBmdWxsLXNjcmVlbi1kaWFsb2d9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50LnRzIEBmaWxlcGF0aCAuL2V4YW1wbGVzL2RpYWxvZy1leGFtcGxlLWZ1bGwtc2NyZWVuLWRpYWxvZy5jb21wb25lbnQudHN9XHJcbiAqIEBmaWxlIHtAZmlsZW5hbWUgY29tcG9uZW50Lmh0bWwgQGZpbGVwYXRoIC4vZXhhbXBsZXMvZGlhbG9nLWV4YW1wbGUtZnVsbC1zY3JlZW4tZGlhbG9nLmNvbXBvbmVudC5odG1sfVxyXG4gKlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kaWFsb2ctaGVhZGVyJyxcclxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cInNtZS1wYWRkaW5nLWhvcml6b250YWwtbGcgc21lLXBhZGRpbmctdmVydGljYWwtc21cIj48bmctY29udGVudD48L25nLWNvbnRlbnQ+PC9kaXY+J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgRGlhbG9nSGVhZGVyQ29tcG9uZW50IHtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kaWFsb2ctY29udGVudCcsXHJcbiAgICB0ZW1wbGF0ZTogJzxuZy1jb250ZW50PjwvbmctY29udGVudD4nXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEaWFsb2dDb250ZW50Q29tcG9uZW50IHtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kaWFsb2ctZm9vdGVyJyxcclxuICAgIHRlbXBsYXRlOiBgPGRpdiBjbGFzcz1cInNtZS1sYXlvdXQtZGlhbG9nLWZvb3RlclwiPlxyXG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PjwvZGl2PmBcclxufSlcclxuZXhwb3J0IGNsYXNzIERpYWxvZ0Zvb3RlckNvbXBvbmVudCB7XHJcbn1cclxuXHJcbmV4cG9ydCBlbnVtIERpYWxvZ0Nsb3NlUmVhc29uIHtcclxuICAgIFNvZnREaXNtaXNzID0gMCxcclxuICAgIENsb3NlQnV0dG9uID0gMSxcclxuICAgIEVzY2FwZUtleSA9IDIsXHJcbiAgICBDb21wZXRpbmdEaWFsb2cgPSAzXHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBEaWFsb2dNb2RlIHtcclxuICAgIHB1YmxpYyBzdGF0aWMgcGFuZSA9ICdwYW5lJztcclxuICAgIHB1YmxpYyBzdGF0aWMgd2lkZVBhbmUgPSAnd2lkZS1wYW5lJztcclxuICAgIHB1YmxpYyBzdGF0aWMgY29tcGFjdCA9ICdjb21wYWN0JztcclxuICAgIHB1YmxpYyBzdGF0aWMgY29tcGFjdFNxdWFyZSA9ICdjb21wYWN0LXNxdWFyZSc7XHJcbiAgICBwdWJsaWMgc3RhdGljIGZ1bGxzY3JlZW4gPSAnZnVsbHNjcmVlbic7XHJcbiAgICBwdWJsaWMgc3RhdGljIGNlbnRlcmVkID0gJ2NlbnRlcmVkJztcclxuICAgIHB1YmxpYyBzdGF0aWMgY2VudGVyZWRNZWRpdW0gPSAnY2VudGVyZWQtbWVkaXVtJztcclxuICAgIHB1YmxpYyBzdGF0aWMgY2VudGVyZWRMYXJnZSA9ICdjZW50ZXJlZC1sYXJnZSc7XHJcbiAgICBwdWJsaWMgc3RhdGljIG5vdGlmaWNhdGlvbiA9ICdub3RpZmljYXRpb24nO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgbW9kYWxEaWFsb2cgPSAnbW9kYWwnO1xyXG5leHBvcnQgY29uc3QgYWxlcnREaWFsb2cgPSAnYWxlcnQnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1kaWFsb2cnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RpYWxvZy5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIERpYWxvZ0NvbXBvbmVudCBleHRlbmRzIENvcmVCYXNlQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyVmlld0NoZWNrZWQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgc291cmNlIG5hbWUgdG8gdXNlIGZvciBsb2dnaW5nXHJcbiAgICAgKi9cclxuICAgIHByb3RlY3RlZCBnZXQgbG9nU291cmNlTmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gJ0RpYWxvZ0NvbXBvbmVudCc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdGF0aWMgY29uc3RhbnQgdG8gcHJvdmlkZSB1bmlxdWUgaWRzIGZvciBlYWNoIG1hc3RlciB2aWV3XHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgc3RhdGljIG5leHREaWFsb2dJZCA9IDA7XHJcbiAgICBwdWJsaWMgZGlhbG9nQ2xhc3Nlczogc3RyaW5nW107XHJcbiAgICBwdWJsaWMgZGlhbG9nUm9sZSA9ICdhbGVydGRpYWxvZyc7XHJcblxyXG4gICAgcHVibGljIHN0cmluZ3MgPSBNc2Z0U21lLmdldFN0cmluZ3M8U3RyaW5ncz4oKTtcclxuXHJcbiAgICBwdWJsaWMgZGlhbG9nTGV2ZWwgPSAxO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBiYWcgb2YgaWRzIGdlbmVyYXRlZCB1c2luZyBAc2VlIHttYXN0ZXJWaWV3SWR9IGFuZCB0aGUgbWFwIHJldHVybmVkIGZyb20gQHNlZSB7Y3JlYXRlSWRCYWd9XHJcbiAgICAgKi9cclxuICAgIGRlY2xhcmUgcHVibGljIGlkQmFnOiBNc2Z0U21lLlN0cmluZ01hcDxzdHJpbmc+O1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgdW5pcXVlIGlkIG9mIHRoaXMgbWFzdGVyIHZpZXcuXHJcbiAgICAgKiBUaGlzIGlzIHVzZWZ1bCB3aGVuIG1hc3RlclZpZXdzIG5lZWQgdG8gdXNlIGFuIElEIGJ1dCBtYXkgYXBwZWFyIG11bHRpcGxlIHRpbWVzIG9uIHRoZSBzYW1lIHBhZ2UuXHJcbiAgICAgKiBVc2luZyB0aGlzIElEIGFzIHRoZSBiYXNpcyBmb3IgdGhlIGNvbnRyb2xzIGludGVybmFsIElEcyBnZW5lcmF0ZWQgaW4gQHNlZSB7Y3JlYXRlSWRCYWd9IGtlZXBzIHRoZSBJRHMgdW5pcXVlLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZGlhbG9nSWQ6IG51bWJlcjtcclxuICAgIHByb3RlY3RlZCBtb2RlOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRvIGFsbG93IGludGVyYWN0aW9uIHdpdGggZWxlbWVudHMgZnJvbSBvdXRzaWRlIHRoZSBkaWFsb2cgZXNwZWNpYWxseSB0byBzdXBwb3J0IHRoZSBob3ZlcmluZyBldmVudHMuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBhbGxvd0JhY2tncm91bmRJbnRlcmFjdGlvbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0byByZW5kZXIgdGhlIGRpYWxvZyBiYWNrZ3JvdW5kLiBGYWxzZSB0byBoaWRlIHRoZSBkaWFsb2cgY29udGFpbmVyIGFuZCBtYWtlIHRoZSBiYWNrZ3JvdW5kIHRyYW5zcGFyZW50LlxyXG4gICAgICogVGhlIGJhY2tncm91bmQgY29sb3IgdGhlbiB3aWxsIGJlIGJhc2VkIG9uIHRoZSBkaWFsb2cgYm9keS5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgcHVibGljIHNob3dCYWNrZHJvcCA9IHRydWU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGV0aGVyIHRvIGVuYWJsZSB0aGUgZmVhdHVyZSBvZiBjbGlja2luZyBvdXRzaWRlIG9mIHRoZSBkaWFsb2cgdG8gY2xvc2UgdGhlIGN1cnJlbnQgZGlhbG9nLlxyXG4gICAgICogVHJ1ZSBtZWFucyBjbGlja2luZyBvdXRzaWRlIHRoZSBkaWFsb2cgd2lsbCBjbG9zZSB0aGUgZGlhbG9nLiBXZSB3YW50IHRoaXMgdG8gYmUgc2V0IHRvIGZhbHNlIHdoZW4gdGhlcmUgYXJlIGZvcm1zIGluIHRoZSBkaWFsb2cuXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBjbGlja0JhY2tkcm9wID0gdHJ1ZTtcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBhcmlhTGFiZWwgPSAnJztcclxuICAgIEBJbnB1dCgpIHB1YmxpYyBhcmlhRGVzY3JpcHRpb24gPSAnJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldHMgd2hldGhlciB0aGlzIHNob3VsZCBiZSBhbiBhY3Rpb24gcGFuZSBvciBhIGNlbnRlcmVkIGRpYWxvZ1xyXG4gICAgICpcclxuICAgICAqIEBkZXByZWNhdGVkIFVzZSBkaWFsb2dNb2RlIGluc3RlYWRcclxuICAgICAqIEBwYXJhbSBuZXdWYWx1ZSBpZiB0cnVlLCB1c2VzIGEgbGVmdCBwYW5lIGRpYWxvZywgb3RoZXJ3aXNlIGEgY2VudGVyZWQgZGlhbG9nXHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBzZXQgYWN0aW9uUGFuZShuZXdWYWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIGlmIChuZXdWYWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmRpYWxvZ01vZGUgPSBEaWFsb2dNb2RlLnBhbmU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5kaWFsb2dNb2RlID0gRGlhbG9nTW9kZS5jZW50ZXJlZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2V0RGlhbG9nTW9kZUZyb21JbnB1dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5kaWNhdGVzIHRoZSBkaWFsb2cgbW9kZSB0byB1c2VcclxuICAgICAqIEBzZWUgRGlhbG9nTW9kZVxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHNldCBkaWFsb2dNb2RlKG1vZGU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubW9kZSA9IG1vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBkaWFsb2dNb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEaWFsb2cgdHlwZXMuIE1vc3RseSB1c2VkIGZvciBhY2Nlc3NpYmlsaXR5LiBWYWxpZCB2YWx1ZXM6XHJcbiAgICAgKiBAc2VlIG1vZGFsRGlhbG9nID0gJ21vZGFsJztcclxuICAgICAqIEBzZWUgYWxlcnREaWFsb2cgPSBcImFsZXJ0XCI7XHJcbiAgICAgKi9cclxuICAgIEBJbnB1dCgpIHB1YmxpYyBkaWFsb2dUeXBlID0gJyc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGbGFnIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBkaWFsb2cgc2hvdWxkIGhhdmUgYSBjbG9zZSBidXR0b24gaW4gdG9wIHJpZ2h0IG9yIG5vdFxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKSBwdWJsaWMgY2xvc2VCdXR0b24gPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhY3QgZGlhbG9nIGNhbiBiZSBmdWxsIGhlaWdodCB3aGVuIGRpc3BsYXlpbmcgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHNjcmVlbi5cclxuICAgICAqIEl0IGNhbiBhbHNvIGJlIGRpc3BsYXllZCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBzY3JlZW4gdGhhdCBuZWVkcyB0byBiZSBoYXZpbmcgcGFkZGluZ3MgdG8gZWFjaCBkaXJlY3Rpb24uXHJcbiAgICAgKiBUaGlzIGNvbXBhY3RGdWxsSGVpZ2h0IHRvIHRydWUgd2lsbCBhbHdheXMgYmUgMTAwJSBoZWlnaHQuIE90aGVyd2lzZSBjc3Mgd291bGQgY29udHJvbCB0aGUgbWF4IGhlaWdodC5cclxuICAgICAqL1xyXG4gICAgQElucHV0KCkgcHVibGljIGNvbXBhY3RGdWxsSGVpZ2h0ID0gZmFsc2U7XHJcblxyXG4gICAgcHVibGljIGNsb3NlUmVxdWVzdGVkOiBTdWJqZWN0PERpYWxvZ0Nsb3NlUmVhc29uPjtcclxuXHJcbiAgICBwcml2YXRlIGRvQXV0b0ZvY3VzID0gZmFsc2U7XHJcbiAgICBwcml2YXRlIGlzVmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgcHVibGljIHNldCB2aXNpYmxlKHZpc2libGU6IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9IHZpc2libGU7XHJcbiAgICAgICAgdGhpcy5kb0F1dG9Gb2N1cyA9IHZpc2libGU7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCB2aXNpYmxlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlzVmlzaWJsZTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgaW5qZWN0b3I6IEluamVjdG9yKSB7XHJcbiAgICAgICAgc3VwZXIoaW5qZWN0b3IpO1xyXG5cclxuICAgICAgICB0aGlzLm1vZGUgPSBEaWFsb2dNb2RlLnBhbmU7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBjbG9zZVJlcXVlc3RlZCBzdWJqZWN0IHRvIG5vdGlmeSBkaWFsb2dzIHdoZW4gYSBjbG9zZSBpcyByZXF1ZXN0ZWQgYW5kIGhvdyBpdCB3YXMgcmVxdWVzdGVkIChEaWFsb2dDbG9zZVJlYXNvbilcclxuICAgICAgICB0aGlzLmNsb3NlUmVxdWVzdGVkID0gbmV3IFN1YmplY3Q8RGlhbG9nQ2xvc2VSZWFzb24+KCk7XHJcbiAgICAgICAgdGhpcy5zZXREaWFsb2dNb2RlRnJvbUlucHV0KCk7XHJcblxyXG4gICAgICAgIC8vIHNldHVwIGRpYWxvZyBpZCBhbmQgaWRCYWdcclxuICAgICAgICB0aGlzLmRpYWxvZ0lkID0gRGlhbG9nQ29tcG9uZW50Lm5leHREaWFsb2dJZCsrO1xyXG4gICAgICAgIHRoaXMuaWRCYWcgPSB0aGlzLmNyZWF0ZUlkQmFnKCk7XHJcbiAgICAgICAgTXNmdFNtZS5mb3JFYWNoS2V5KHRoaXMuaWRCYWcsIChrZXkpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5pZEJhZ1trZXldID0gYGRpYWxvZy0ke3RoaXMuZGlhbG9nSWQudG9TdHJpbmcoKX0tJHtrZXl9YDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBkb2N1bWVudDprZXl1cC5lc2NhcGUgaXMgdXNlZCBzbyB0aGF0IGEgZGlhbG9nIGlzIG5vdCBjbG9zZWQgd2hlbiB0cnlpbmcgdG8gY2xvc2UgYSB0b29sdGlwXHJcbiAgICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXl1cC5lc2NhcGUnKVxyXG4gICAgcHVibGljIG9uS2V5VXAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudmlzaWJsZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uRXNjYXBlUHJlc3NlZCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuZ3VsYXIgTGlmZSBDeWNsZSBob29rIGZvciBBZnRlciBWaWV3IENoZWNrZWQuXHJcbiAgICAgKiBXaGVuIHRoZSB2aXNpYmlsaXR5IGNoYW5nZXMsIHdlIGFyZSBnb2luZyB0byBmb2N1cyBvbiB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IGhhcyB0aGUgYXV0b2ZvY3VzIGF0dHJpYnV0ZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbmdBZnRlclZpZXdDaGVja2VkKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmRvQXV0b0ZvY3VzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYXV0b0ZvY3VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGxldGVkIHRoZSBjbG9zZVJlcXVlc3RlZCBzdWJqZWN0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLmNsb3NlUmVxdWVzdGVkLmNvbXBsZXRlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBdXRvIGZvY3VzIG9uIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyBmb2N1c2FibGVcclxuICAgICAqL1xyXG4gICAgQERlYm91bmNlKDApXHJcbiAgICBwdWJsaWMgYXV0b0ZvY3VzKCkge1xyXG4gICAgICAgIHRoaXMuZG9BdXRvRm9jdXMgPSBmYWxzZTtcclxuICAgICAgICBpZiAodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGRpYWxvZyBoYXMgYSBsb2FkaW5nIHdoZWVsLCBmb2N1cyBmaXJzdCBnb2VzIHRvIHRoZSBsb2FkaW5nIHdoZWVsIHRoZW4gZ2V0cyBsb3N0LlxyXG4gICAgICAgICAgICAvLyBUTyBhdm9pZCB0aGlzLCB3ZSBnZXQgdGhlIHBhcmVudCBlbGVtZW50IG9yIG5hdGl2ZSBlbGVtZW50IG9mIHRoZSBkaWFsb2csIHRoZW4gZ2V0IHRoZSBmaXJzdFxyXG4gICAgICAgICAgICAvLyBmb2N1c2FibGUgZWxlbWVudCBpbiB0aGF0IGVsZW1lbnRcclxuICAgICAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnBhcmVudEVsZW1lbnQgfHwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0Rm9jdXNhYmxlID0gRG9tLmdldEZpcnN0Rm9jdXNhYmxlRGVzY2VuZGVudChlbGVtZW50KTtcclxuICAgICAgICAgICAgaWYgKGZpcnN0Rm9jdXNhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBmaXJzdEZvY3VzYWJsZS5mb2N1cygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2hvd3MgdGhlIGRpYWxvZy5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHNob3coKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhpZGVzIHRoZSBkaWFsb2cuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBoaWRlKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTm90aWZpZXMgY2xvc2VSZXF1ZXN0ZWQgc3Vic2NyaWJlcnMgdGhhdCB0aGUgYmFja2Ryb3AgaGFzIGJlZW4gY2xpY2tlZCwgcmVxdWVzdGluZyBhIHNvZnQgZGlzbWlzc1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25CYWNrZ3JvdW5kQ2xpY2tlZCgpIHtcclxuICAgICAgICB0aGlzLmNsb3NlUmVxdWVzdGVkLm5leHQoRGlhbG9nQ2xvc2VSZWFzb24uU29mdERpc21pc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTm90aWZpZXMgY2xvc2VSZXF1ZXN0ZWQgc3Vic2NyaWJlcnMgdGhhdCB0aGUgY2xvc2UgYnV0dG9uIGhhcyBiZWVuIHByZXNzZWQsIHJlcXVlc3RpbmcgYSBjbG9zZSBidXR0b24gZGlzbWlzc1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25DbG9zZUNsaWNrZWQoKSB7XHJcbiAgICAgICAgdGhpcy5jbG9zZVJlcXVlc3RlZC5uZXh0KERpYWxvZ0Nsb3NlUmVhc29uLkNsb3NlQnV0dG9uKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgb25Fc2NhcGVQcmVzc2VkKCkge1xyXG4gICAgICAgIHRoaXMuY2xvc2VSZXF1ZXN0ZWQubmV4dChEaWFsb2dDbG9zZVJlYXNvbi5Fc2NhcGVLZXkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XHJcbiAgICAgICAgY29uc3QgZGlhbG9nTW9kZUNoYW5nZSA9IGNoYW5nZXNbJ2RpYWxvZ01vZGUnXTtcclxuICAgICAgICBpZiAoZGlhbG9nTW9kZUNoYW5nZSAmJiBkaWFsb2dNb2RlQ2hhbmdlLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnNldERpYWxvZ01vZGVGcm9tSW5wdXQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIHNldERpYWxvZ01vZGVGcm9tSW5wdXQoKSB7XHJcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSB0aGlzLmRpYWxvZ01vZGUudG9Mb3dlckNhc2UoKS50cmltKCk7XHJcbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IFsnc21lLWxheW91dC1hYnNvbHV0ZScsICdzbWUtc2NoZW1lLWRpYWxvZycsICdzbWUtYW5pbWF0aW9uLXRyYW5zaXRpb24td2lkdGgteHMnLCAnc21lLXJlc3BvbnNpdmUtZGlhbG9nJ107XHJcbiAgICAgICAgY29uc3QgY29tbW9uUGFuZUNsYXNzZXMgPSBbJ3NtZS1wb3NpdGlvbi12ZXJ0aWNhbC1ub25lJywgJ3NtZS1wb3NpdGlvbi1yaWdodC1ub25lJ107XHJcblxyXG4gICAgICAgIGlmIChuZXdWYWx1ZSA9PT0gRGlhbG9nTW9kZS5wYW5lKSB7XHJcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaCguLi5jb21tb25QYW5lQ2xhc3NlcywgJ3NtZS1sYXlvdXQtZGlhbG9nLXBhbmUnLCAnc21lLXNoYWRvdy1hY3Rpb24tcGFuZScpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3VmFsdWUgPT09IERpYWxvZ01vZGUud2lkZVBhbmUpIHtcclxuICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKC4uLmNvbW1vblBhbmVDbGFzc2VzLCAnc21lLWxheW91dC1kaWFsb2ctd2lkZS1wYW5lJywgJ3NtZS1zaGFkb3ctYWN0aW9uLXBhbmUnKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG5ld1ZhbHVlID09PSBEaWFsb2dNb2RlLmNvbXBhY3QpIHtcclxuICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKC4uLmNvbW1vblBhbmVDbGFzc2VzLCAnc21lLWxheW91dC1kaWFsb2ctY29tcGFjdCcsICdzbWUtc2hhZG93LWFjdGlvbi1wYW5lJyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbXBhY3RGdWxsSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICBjbGFzc2VzLnB1c2goJ3NtZS1sYXlvdXQtZGlhbG9nLWNvbXBhY3QtZnVsbC1oZWlnaHQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3VmFsdWUgPT09IERpYWxvZ01vZGUuY29tcGFjdFNxdWFyZSkge1xyXG4gICAgICAgICAgICBjbGFzc2VzLnB1c2goJ3NtZS1wb3NpdGlvbi1jZW50ZXInLCAnc21lLWxheW91dC1kaWFsb2ctY2VudGVyZWQnLCAnc21lLWxheW91dC1kaWFsb2ctY29tcGFjdC1zcXVhcmUnLCAnc21lLXNoYWRvdy1kaWFsb2cnKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29tcGFjdEZ1bGxIZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnc21lLWxheW91dC1kaWFsb2ctY29tcGFjdC1mdWxsLWhlaWdodCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChuZXdWYWx1ZSA9PT0gRGlhbG9nTW9kZS5mdWxsc2NyZWVuKSB7XHJcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaCguLi5jb21tb25QYW5lQ2xhc3NlcywgJ3NtZS1sYXlvdXQtZGlhbG9nLWZ1bGxzY3JlZW4nLCAnc21lLXNoYWRvdy1hY3Rpb24tcGFuZScpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3VmFsdWUgPT09IERpYWxvZ01vZGUuY2VudGVyZWQpIHtcclxuICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKCdzbWUtcG9zaXRpb24tY2VudGVyJywgJ3NtZS1sYXlvdXQtZGlhbG9nLWNlbnRlcmVkJywgJ3NtZS1zaGFkb3ctZGlhbG9nJyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChuZXdWYWx1ZSA9PT0gRGlhbG9nTW9kZS5jZW50ZXJlZE1lZGl1bSkge1xyXG4gICAgICAgICAgICBjbGFzc2VzLnB1c2goJ3NtZS1wb3NpdGlvbi1jZW50ZXInLCAnc21lLWxheW91dC1kaWFsb2ctY2VudGVyZWQtbWVkaXVtJywgJ3NtZS1zaGFkb3ctZGlhbG9nJyk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChuZXdWYWx1ZSA9PT0gRGlhbG9nTW9kZS5jZW50ZXJlZExhcmdlKSB7XHJcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnc21lLXBvc2l0aW9uLWNlbnRlcicsICdzbWUtbGF5b3V0LWRpYWxvZy1jZW50ZXJlZC1sYXJnZScsICdzbWUtc2hhZG93LWRpYWxvZycpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobmV3VmFsdWUgPT09IERpYWxvZ01vZGUubm90aWZpY2F0aW9uKSB7XHJcbiAgICAgICAgICAgIGNsYXNzZXMucHVzaCgnc21lLXBvc2l0aW9uLXRvcC1zbScsICdzbWUtcG9zaXRpb24tcmlnaHQtc20nLCAnc21lLWxheW91dC1kaWFsb2ctbm90aWZpY2F0aW9uJywgJ3NtZS1zaGFkb3ctZGlhbG9nJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjbGFzc2VzLnB1c2goJ3NtZS1hcn