@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
333 lines • 44.9 kB
JavaScript
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { AuthorizationManager } from '@microsoft/windows-admin-center-sdk/core/security/authorization-manager';
import { AppContextService } from '../../service/app-context.service';
import { ValidationAlertSeverity } from '../form/validation-alert/validation-alert';
import { EnvironmentModule } from '@microsoft/windows-admin-center-sdk/core/manifest/environment-modules';
import * as i0 from "@angular/core";
import * as i1 from "../../service/app-context.service";
import * as i2 from "@angular/common";
import * as i3 from "@angular/forms";
import * as i4 from "../form/form-field/checkbox/checkbox-form-field.component";
import * as i5 from "../form/form-field/password/password-form-field.component";
import * as i6 from "../form/form-field/radio-group/classic/radio-group-form-field.component";
import * as i7 from "../form/form-field/text/text-form-field.component";
import * as i8 from "../form/validators/capslock.directive";
import * as i9 from "../form/form-field/options-form-field/form-field-option.component";
import * as i10 from "../form/form-field/form-field-accessor.directive";
import * as i11 from "../form/form-field/form-field-validator.directive";
import * as i12 from "../form/fieldset/fieldset.directive";
import * as i13 from "../../pipes/format-pipe";
const _c0 = ["manageAsForm"];
function NodeCredentialsFormComponent_ng_template_2_ng_template_3_sme_form_field_0_Template(rf, ctx) { if (rf & 1) {
const _r8 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field", 7);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_ng_template_3_sme_form_field_0_Template_sme_form_field_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r7 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r7.useLaps = $event); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r5 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("ngModel", ctx_r5.useLaps)("label", ctx_r5.strings.UseLaps.label);
} }
function NodeCredentialsFormComponent_ng_template_2_ng_template_3_fieldset_1_Template(rf, ctx) { if (rf & 1) {
const _r10 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "fieldset", 8)(1, "sme-form-field", 9);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_ng_template_3_fieldset_1_Template_sme_form_field_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r9 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r9.lapsLocalAdminName = $event); });
i0.ɵɵelementEnd()();
} if (rf & 2) {
const ctx_r6 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("disabled", !ctx_r6.useLaps);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngModel", ctx_r6.lapsLocalAdminName)("label", ctx_r6.strings.lapsLocalAdminName.label)("placeholder", ctx_r6.strings.lapsLocalAdminName.placeholder);
} }
function NodeCredentialsFormComponent_ng_template_2_ng_template_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵtemplate(0, NodeCredentialsFormComponent_ng_template_2_ng_template_3_sme_form_field_0_Template, 1, 2, "sme-form-field", 5);
i0.ɵɵtemplate(1, NodeCredentialsFormComponent_ng_template_2_ng_template_3_fieldset_1_Template, 2, 4, "fieldset", 6);
} if (rf & 2) {
const ctx_r3 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("ngIf", !ctx_r3.isServiceMode);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", !ctx_r3.isServiceMode);
} }
function NodeCredentialsFormComponent_ng_template_2_ng_template_5_sme_form_field_2_Template(rf, ctx) { if (rf & 1) {
const _r13 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field", 13);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_ng_template_5_sme_form_field_2_Template_sme_form_field_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r12 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r12.applyToAll = $event); })("customValidate", function NodeCredentialsFormComponent_ng_template_2_ng_template_5_sme_form_field_2_Template_sme_form_field_customValidate_0_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r14 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r14.validateApplyToAll($event)); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r11 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("ngModel", ctx_r11.applyToAll)("label", ctx_r11.strings.ApplyToAll.label);
} }
function NodeCredentialsFormComponent_ng_template_2_ng_template_5_Template(rf, ctx) { if (rf & 1) {
const _r16 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field", 10);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_ng_template_5_Template_sme_form_field_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r15 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r15.username = $event); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(1, "sme-form-field", 11);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_ng_template_5_Template_sme_form_field_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r17 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r17.password = $event); });
i0.ɵɵelementEnd();
i0.ɵɵtemplate(2, NodeCredentialsFormComponent_ng_template_2_ng_template_5_sme_form_field_2_Template, 1, 2, "sme-form-field", 12);
} if (rf & 2) {
const ctx_r4 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("ngModel", ctx_r4.username)("required", true)("label", ctx_r4.strings.Username.label)("placeholder", ctx_r4.strings.Username.placeholder);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngModel", ctx_r4.password)("required", true)("label", ctx_r4.strings.Password.label)("placeholder", ctx_r4.strings.Password.placeholder);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r4.showApplyToAll);
} }
function NodeCredentialsFormComponent_ng_template_2_Template(rf, ctx) { if (rf & 1) {
const _r19 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field", 3);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_2_Template_sme_form_field_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r18 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r18.useGlobalAuth = $event); })("customValidate", function NodeCredentialsFormComponent_ng_template_2_Template_sme_form_field_customValidate_0_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r20 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r20.validateAuthType($event)); });
i0.ɵɵelementStart(1, "sme-option", 4);
i0.ɵɵpipe(2, "smeFormat");
i0.ɵɵtemplate(3, NodeCredentialsFormComponent_ng_template_2_ng_template_3_Template, 2, 2, "ng-template");
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "sme-option", 4);
i0.ɵɵtemplate(5, NodeCredentialsFormComponent_ng_template_2_ng_template_5_Template, 3, 9, "ng-template");
i0.ɵɵelementEnd()();
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵproperty("ngModel", ctx_r1.useGlobalAuth)("immediateValidation", true);
i0.ɵɵadvance(1);
i0.ɵɵproperty("value", true)("label", i0.ɵɵpipeBind2(2, 6, ctx_r1.strings.UseGlobalAuth.labelFormat, ctx_r1.globalUsername || ctx_r1.myAccount));
i0.ɵɵadvance(3);
i0.ɵɵproperty("value", false)("label", ctx_r1.strings.UsePerNodeAuth.label);
} }
function NodeCredentialsFormComponent_ng_template_3_sme_form_field_3_Template(rf, ctx) { if (rf & 1) {
const _r23 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field", 13);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_3_sme_form_field_3_Template_sme_form_field_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r22 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r22.applyToAll = $event); })("customValidate", function NodeCredentialsFormComponent_ng_template_3_sme_form_field_3_Template_sme_form_field_customValidate_0_listener($event) { i0.ɵɵrestoreView(_r23); const ctx_r24 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r24.validateApplyToAll($event)); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r21 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("ngModel", ctx_r21.applyToAll)("label", ctx_r21.strings.ApplyToAll.label);
} }
function NodeCredentialsFormComponent_ng_template_3_Template(rf, ctx) { if (rf & 1) {
const _r26 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 14)(1, "sme-form-field", 10);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_3_Template_sme_form_field_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r25 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r25.username = $event); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(2, "sme-form-field", 11);
i0.ɵɵlistener("ngModelChange", function NodeCredentialsFormComponent_ng_template_3_Template_sme_form_field_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r27 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r27.password = $event); });
i0.ɵɵelementEnd();
i0.ɵɵtemplate(3, NodeCredentialsFormComponent_ng_template_3_sme_form_field_3_Template, 1, 2, "sme-form-field", 12);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngModel", ctx_r2.username)("required", true)("label", ctx_r2.strings.Username.label)("placeholder", ctx_r2.strings.Username.placeholder);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngModel", ctx_r2.password)("required", true)("label", ctx_r2.strings.Password.label)("placeholder", ctx_r2.strings.Password.placeholder);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r2.showApplyToAll);
} }
/**
* Credentials Form Component:
*
* TODO:
* 1. Convert to using angular form controls
* 2. Convert to be a form control
* 3. The authentication flow is expected to change drastically between now and GA.
* It doesn't make sense to put much effort into this control at this time
*/
export class NodeCredentialsFormComponent {
/**
* Initializes a new instance of the NodeCredentialsForm class.
*/
constructor(appContextService) {
this.appContextService = appContextService;
this.strings = MsftSme.getStrings().MsftSmeShell.Angular.NodeCredentialsForm;
this.hasPerNodeCredentials = false;
/**
* Model to hold internal form field values;
*/
this.model = {
username: '',
password: '',
applyToAll: false,
useLaps: false,
lapsLocalAdminName: '',
useGlobalAuth: false
};
this.credentialsChanged = new EventEmitter();
this.authorizationMethodChanged = new EventEmitter();
this.showApplyToAll = true;
this.isServiceMode = false;
this.noChoice = false;
this.myAccount = EnvironmentModule.isGatewayLinux ?
this.strings.UseGlobalAuth.myLinuxAccount : this.strings.UseGlobalAuth.myWindowsAccount;
}
/**
* Gets or sets the Username
*/
set username(value) {
this.model.username = value;
this.updateAuthorizationCredentials();
}
get username() {
return this.model.username;
}
/**
* Gets or sets the password
*/
set password(value) {
this.model.password = value;
this.updateAuthorizationCredentials();
}
get password() {
return this.model.password;
}
/**
* Gets or sets a value indicating if these settings should be applied to all nodes
*/
set applyToAll(value) {
this.model.applyToAll = value;
this.updateAuthorizationCredentials();
}
get applyToAll() {
return this.model.applyToAll;
}
/**
* Gets or sets a value indicating if LAPS should be used
*/
set useLaps(value) {
this.model.useLaps = value;
this.updateAuthorizationCredentials();
}
get useLaps() {
return this.model.useLaps;
}
/**
* Gets or sets the laps Local Admin Name
*/
set lapsLocalAdminName(value) {
this.model.lapsLocalAdminName = value;
this.updateAuthorizationCredentials();
}
get lapsLocalAdminName() {
return this.model.lapsLocalAdminName;
}
/**
* Gets or sets a value indicating if global auth should be used
*/
set useGlobalAuth(value) {
this.model.useGlobalAuth = value;
this.updateAuthorizationCredentials();
}
get useGlobalAuth() {
return this.model.useGlobalAuth;
}
reset(nodeName) {
// TODO: handle no nodeNames provided
this.applyToAll = false;
this.manageAsForm.form.controls.username.reset();
this.manageAsForm.form.controls.password.reset();
this.useLaps = false;
this.lapsLocalAdminName = AuthorizationManager.defaultLapsLocalAdminName; // Show default value, users can change.
this.useGlobalAuth = true;
this.hasPerNodeCredentials = Object.keys(this.appContextService.authorizationManager.nodeTokens).length > 0;
const nodeToken = this.appContextService.authorizationManager.nodeTokens[nodeName];
const globalToken = this.appContextService.authorizationManager.manageAsToken;
if (nodeToken) {
this.useGlobalAuth = false;
this.username = nodeToken.username;
}
if (globalToken) {
this.globalUsername = globalToken.username;
}
}
updateAuthorizationCredentials() {
const authCreds = {
username: this.username,
password: this.password,
applyToAllNodes: this.applyToAll,
useLaps: false,
lapsLocalAdminName: this.lapsLocalAdminName
};
if (!this.noChoice && this.useGlobalAuth) {
authCreds.username = null;
authCreds.password = null;
authCreds.applyToAllNodes = false;
authCreds.useLaps = this.useLaps;
authCreds.lapsLocalAdminName = this.lapsLocalAdminName;
}
this.credentialsChanged.next(authCreds);
// capture whether the form has a "Local administrator password" form fields
this.authorizationMethodChanged.emit(this.useGlobalAuth);
}
/**
* Validate the auth type field
* @param event the validation event
*/
validateAuthType(event) {
const alerts = {};
if (!this.useGlobalAuth) {
alerts['useGlobalAuth'] = {
valid: true,
message: this.strings.UseGlobalAuth.warning,
severity: ValidationAlertSeverity.Warning
};
}
else if (this.isServiceMode) {
alerts['serviceMode'] = {
valid: true,
message: this.strings.deploymentGuideMessage,
severity: ValidationAlertSeverity.Warning
};
}
MsftSme.deepAssign(event.alerts, alerts);
}
/**
* Validate the apply to all field
* @param event the validation event
*/
validateApplyToAll(event) {
const alerts = {};
if (!this.useGlobalAuth && this.hasPerNodeCredentials && this.applyToAll) {
alerts['hasPerNodeCredentials'] = {
valid: true,
message: this.strings.ApplyToAll.warning,
severity: ValidationAlertSeverity.Warning
};
}
MsftSme.deepAssign(event.alerts, alerts);
}
}
/** @nocollapse */ NodeCredentialsFormComponent.ɵfac = function NodeCredentialsFormComponent_Factory(t) { return new (t || NodeCredentialsFormComponent)(i0.ɵɵdirectiveInject(i1.AppContextService)); };
/** @nocollapse */ NodeCredentialsFormComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: NodeCredentialsFormComponent, selectors: [["sme-node-credentials-form"]], viewQuery: function NodeCredentialsFormComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c0, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.manageAsForm = _t.first);
} }, inputs: { showApplyToAll: "showApplyToAll", isServiceMode: "isServiceMode", formId: "formId", noChoice: "noChoice" }, outputs: { credentialsChanged: "credentialsChanged", authorizationMethodChanged: "authorizationMethodChanged" }, decls: 4, vars: 3, consts: [["name", "manageAs", 3, "id"], ["manageAsForm", "ngForm"], [3, "ngIf"], ["type", "radiogroup", "name", "authType", 3, "ngModel", "immediateValidation", "ngModelChange", "customValidate"], [3, "value", "label"], ["type", "checkbox", "name", "useLaps", 3, "ngModel", "label", "ngModelChange", 4, "ngIf"], [3, "disabled", 4, "ngIf"], ["type", "checkbox", "name", "useLaps", 3, "ngModel", "label", "ngModelChange"], [3, "disabled"], ["type", "text", "name", "lapsLocalAdminName", 3, "ngModel", "label", "placeholder", "ngModelChange"], ["type", "text", "name", "username", 3, "ngModel", "required", "label", "placeholder", "ngModelChange"], ["type", "password", "name", "password", 3, "ngModel", "required", "label", "placeholder", "ngModelChange"], ["type", "checkbox", "name", "applyToAll", 3, "ngModel", "label", "ngModelChange", "customValidate", 4, "ngIf"], ["type", "checkbox", "name", "applyToAll", 3, "ngModel", "label", "ngModelChange", "customValidate"], [1, "sme-padding-top-sm"]], template: function NodeCredentialsFormComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "form", 0, 1);
i0.ɵɵtemplate(2, NodeCredentialsFormComponent_ng_template_2_Template, 6, 9, "ng-template", 2);
i0.ɵɵtemplate(3, NodeCredentialsFormComponent_ng_template_3_Template, 4, 9, "ng-template", 2);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("id", ctx.formId);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", !ctx.noChoice);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.noChoice);
} }, dependencies: [i2.NgIf, i3.ɵNgNoValidate, i3.NgControlStatus, i3.NgControlStatusGroup, i3.RequiredValidator, i3.NgModel, i3.NgForm, i4.CheckboxFormFieldComponent, i5.PasswordFormFieldComponent, i6.RadioGroupFormFieldComponent, i7.TextFormFieldComponent, i8.CapsLockValidatorDirective, i9.FormFieldOptionComponent, i10.FormFieldAccessorDirective, i11.FormFieldValidatorDirective, i12.FieldsetDirective, i13.FormatPipe], encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NodeCredentialsFormComponent, [{
type: Component,
args: [{ selector: 'sme-node-credentials-form', template: "<form name=\"manageAs\" [id]=\"formId\" #manageAsForm=\"ngForm\">\r\n <ng-template [ngIf]=\"!noChoice\">\r\n <sme-form-field type=\"radiogroup\" name=\"authType\" [(ngModel)]=\"useGlobalAuth\" (customValidate)=\"validateAuthType($event)\" [immediateValidation]=\"true\">\r\n <sme-option [value]=\"true\" [label]=\"strings.UseGlobalAuth.labelFormat | smeFormat:(globalUsername || myAccount)\">\r\n <ng-template>\r\n <sme-form-field *ngIf=\"!isServiceMode\" type=\"checkbox\" name=\"useLaps\" [(ngModel)]=\"useLaps\" [label]=\"strings.UseLaps.label\"></sme-form-field>\r\n <fieldset *ngIf=\"!isServiceMode\" [disabled]=\"!useLaps\">\r\n <sme-form-field type=\"text\" name=\"lapsLocalAdminName\" [(ngModel)]=\"lapsLocalAdminName\" [label]=\"strings.lapsLocalAdminName.label\" [placeholder]=\"strings.lapsLocalAdminName.placeholder\"></sme-form-field>\r\n </fieldset>\r\n </ng-template>\r\n </sme-option>\r\n <sme-option [value]=\"false\" [label]=\"strings.UsePerNodeAuth.label\">\r\n <ng-template>\r\n <sme-form-field type=\"text\" name=\"username\" [(ngModel)]=\"username\" [required]=\"true\" [label]=\"strings.Username.label\" [placeholder]=\"strings.Username.placeholder\"></sme-form-field>\r\n <sme-form-field type=\"password\" name=\"password\" [(ngModel)]=\"password\" [required]=\"true\" [label]=\"strings.Password.label\" [placeholder]=\"strings.Password.placeholder\"></sme-form-field>\r\n <sme-form-field *ngIf=\"showApplyToAll\" type=\"checkbox\" name=\"applyToAll\" [(ngModel)]=\"applyToAll\" [label]=\"strings.ApplyToAll.label\" (customValidate)=\"validateApplyToAll($event)\"></sme-form-field>\r\n </ng-template>\r\n </sme-option>\r\n </sme-form-field>\r\n </ng-template>\r\n <ng-template [ngIf]=\"noChoice\">\r\n <div class=\"sme-padding-top-sm\">\r\n <sme-form-field type=\"text\" name=\"username\" [(ngModel)]=\"username\" [required]=\"true\" [label]=\"strings.Username.label\" [placeholder]=\"strings.Username.placeholder\"></sme-form-field>\r\n <sme-form-field type=\"password\" name=\"password\" [(ngModel)]=\"password\" [required]=\"true\" [label]=\"strings.Password.label\" [placeholder]=\"strings.Password.placeholder\"></sme-form-field>\r\n <sme-form-field *ngIf=\"showApplyToAll\" type=\"checkbox\" name=\"applyToAll\" [(ngModel)]=\"applyToAll\" [label]=\"strings.ApplyToAll.label\" (customValidate)=\"validateApplyToAll($event)\"></sme-form-field>\r\n </div>\r\n </ng-template>\r\n</form>" }]
}], function () { return [{ type: i1.AppContextService }]; }, { credentialsChanged: [{
type: Output
}], authorizationMethodChanged: [{
type: Output
}], showApplyToAll: [{
type: Input
}], isServiceMode: [{
type: Input
}], formId: [{
type: Input
}], noChoice: [{
type: Input
}], manageAsForm: [{
type: ViewChild,
args: ['manageAsForm']
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1jcmVkZW50aWFscy1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL25vZGUtY3JlZGVudGlhbHMtZm9ybS9ub2RlLWNyZWRlbnRpYWxzLWZvcm0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvbm9kZS1jcmVkZW50aWFscy1mb3JtL25vZGUtY3JlZGVudGlhbHMtZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxFQUE0QixvQkFBb0IsRUFBRSxNQUFNLHlFQUF5RSxDQUFDO0FBRXpJLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRXRFLE9BQU8sRUFBb0IsdUJBQXVCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN0RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1RUFBdUUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lDRnRGLHlDQUE0SDtJQUF0RCwwUkFBcUI7SUFBaUMsaUJBQWlCOzs7SUFBdkUsd0NBQXFCLHVDQUFBOzs7O0lBQzNGLG1DQUF1RCx3QkFBQTtJQUNHLGdTQUFnQztJQUFtRyxpQkFBaUIsRUFBQTs7O0lBRDdLLDBDQUFxQjtJQUNJLGVBQWdDO0lBQWhDLG1EQUFnQyxrREFBQSw4REFBQTs7O0lBRjFGLCtIQUE2STtJQUM3SSxtSEFFVzs7O0lBSE0sNENBQW9CO0lBQzFCLGVBQW9CO0lBQXBCLDRDQUFvQjs7OztJQVMvQiwwQ0FBbUw7SUFBMUcsZ1NBQXdCLHNP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Q0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7T0FHRztJQUNJLGtCQUFrQixDQUFDLEtBQStCO1FBQ3JELE1BQU0sTUFBTSxHQUFxQixFQUFFLENBQUM7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLHFCQUFxQixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDdEUsTUFBTSxDQUFDLHVCQUF1QixDQUFDLEdBQUc7Z0JBQzlCLEtBQUssRUFBRSxJQUFJO2dCQUNYLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPO2dCQUN4QyxRQUFRLEVBQUUsdUJBQXVCLENBQUMsT0FBTzthQUM1QyxDQUFDO1NBQ0w7UUFFRCxPQUFPLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDN0MsQ0FBQzs7MkhBck1RLDRCQUE0Qjs4R0FBNUIsNEJBQTRCOzs7Ozs7UUN0QnpDLGtDQUEyRDtRQUN2RCw2RkFrQmM7UUFDZCw2RkFNYztRQUNsQixpQkFBTzs7UUEzQmUsK0JBQWE7UUFDbEIsZUFBa0I7UUFBbEIsb0NBQWtCO1FBbUJsQixlQUFpQjtRQUFqQixtQ0FBaUI7O3VGREVyQiw0QkFBNEI7Y0FieEMsU0FBUzsyQkFDSSwyQkFBMkI7b0VBaUc5QixrQkFBa0I7a0JBRHhCLE1BQU07WUFJQSwwQkFBMEI7a0JBRGhDLE1BQU07WUFJQSxjQUFjO2tCQURwQixLQUFLO1lBSUMsYUFBYTtrQkFEbkIsS0FBSztZQUlDLE1BQU07a0JBRFosS0FBSztZQUlDLFFBQVE7a0JBRGQsS0FBSztZQUlDLFlBQVk7a0JBRGxCLFNBQVM7bUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTmdGb3JtIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBBdXRob3JpemF0aW9uQ3JlZGVudGlhbHMsIEF1dGhvcml6YXRpb25NYW5hZ2VyIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9zZWN1cml0eS9hdXRob3JpemF0aW9uLW1hbmFnZXInO1xyXG5pbXBvcnQgeyBTdHJpbmdzIH0gZnJvbSAnLi4vLi4vZ2VuZXJhdGVkL3N0cmluZ3MnO1xyXG5pbXBvcnQgeyBBcHBDb250ZXh0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2UvYXBwLWNvbnRleHQuc2VydmljZSc7XHJcbmltcG9ydCB7IENoZWNrVmFsaWRhdGlvbkV2ZW50QXJncyB9IGZyb20gJy4uL2Zvcm0vZm9ybS1maWVsZC9mb3JtLWZpZWxkLXZhbGlkYXRvci5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBWYWxpZGF0aW9uQWxlcnRzLCBWYWxpZGF0aW9uQWxlcnRTZXZlcml0eSB9IGZyb20gJy4uL2Zvcm0vdmFsaWRhdGlvbi1hbGVydC92YWxpZGF0aW9uLWFsZXJ0JztcclxuaW1wb3J0IHsgRW52aXJvbm1lbnRNb2R1bGUgfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL21hbmlmZXN0L2Vudmlyb25tZW50LW1vZHVsZXMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1ub2RlLWNyZWRlbnRpYWxzLWZvcm0nLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL25vZGUtY3JlZGVudGlhbHMtZm9ybS5jb21wb25lbnQuaHRtbCdcclxufSlcclxuLyoqXHJcbiAqIENyZWRlbnRpYWxzIEZvcm0gQ29tcG9uZW50OlxyXG4gKlxyXG4gKiBUT0RPOlxyXG4gKiAxLiBDb252ZXJ0IHRvIHVzaW5nIGFuZ3VsYXIgZm9ybSBjb250cm9sc1xyXG4gKiAyLiBDb252ZXJ0IHRvIGJlIGEgZm9ybSBjb250cm9sXHJcbiAqIDMuIFRoZSBhdXRoZW50aWNhdGlvbiBmbG93IGlzIGV4cGVjdGVkIHRvIGNoYW5nZSBkcmFzdGljYWxseSBiZXR3ZWVuIG5vdyBhbmQgR0EuXHJcbiAqICAgIEl0IGRvZXNuJ3QgbWFrZSBzZW5zZSB0byBwdXQgbXVjaCBlZmZvcnQgaW50byB0aGlzIGNvbnRyb2wgYXQgdGhpcyB0aW1lXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgTm9kZUNyZWRlbnRpYWxzRm9ybUNvbXBvbmVudCB7XHJcbiAgICBwdWJsaWMgc3RyaW5ncyA9IE1zZnRTbWUuZ2V0U3RyaW5nczxTdHJpbmdzPigpLk1zZnRTbWVTaGVsbC5Bbmd1bGFyLk5vZGVDcmVkZW50aWFsc0Zvcm07XHJcbiAgICBwdWJsaWMgaGFzUGVyTm9kZUNyZWRlbnRpYWxzID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgZ2xvYmFsVXNlcm5hbWU6IHN0cmluZztcclxuICAgIHB1YmxpYyBteUFjY291bnQ6IHN0cmluZztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgb3Igc2V0cyB0aGUgVXNlcm5hbWVcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCB1c2VybmFtZSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5tb2RlbC51c2VybmFtZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQXV0aG9yaXphdGlvbkNyZWRlbnRpYWxzKCk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IHVzZXJuYW1lKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudXNlcm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIG9yIHNldHMgdGhlIHBhc3N3b3JkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgcGFzc3dvcmQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubW9kZWwucGFzc3dvcmQgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUF1dGhvcml6YXRpb25DcmVkZW50aWFscygpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIGdldCBwYXNzd29yZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnBhc3N3b3JkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBvciBzZXRzIGEgdmFsdWUgaW5kaWNhdGluZyBpZiB0aGVzZSBzZXR0aW5ncyBzaG91bGQgYmUgYXBwbGllZCB0byBhbGwgbm9kZXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCBhcHBseVRvQWxsKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5tb2RlbC5hcHBseVRvQWxsID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVBdXRob3JpemF0aW9uQ3JlZGVudGlhbHMoKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgYXBwbHlUb0FsbCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5hcHBseVRvQWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBvciBzZXRzIGEgdmFsdWUgaW5kaWNhdGluZyBpZiBMQVBTIHNob3VsZCBiZSB1c2VkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgdXNlTGFwcyh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMubW9kZWwudXNlTGFwcyA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQXV0aG9yaXphdGlvbkNyZWRlbnRpYWxzKCk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IHVzZUxhcHMoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudXNlTGFwcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgb3Igc2V0cyB0aGUgbGFwcyBMb2NhbCBBZG1pbiBOYW1lXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzZXQgbGFwc0xvY2FsQWRtaW5OYW1lKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLm1vZGVsLmxhcHNMb2NhbEFkbWluTmFtZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQXV0aG9yaXphdGlvbkNyZWRlbnRpYWxzKCk7XHJcbiAgICB9XHJcbiAgICBwdWJsaWMgZ2V0IGxhcHNMb2NhbEFkbWluTmFtZSgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLmxhcHNMb2NhbEFkbWluTmFtZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgb3Igc2V0cyBhIHZhbHVlIGluZGljYXRpbmcgaWYgZ2xvYmFsIGF1dGggc2hvdWxkIGJlIHVzZWRcclxuICAgICAqL1xyXG4gICAgcHVibGljIHNldCB1c2VHbG9iYWxBdXRoKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5tb2RlbC51c2VHbG9iYWxBdXRoID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy51cGRhdGVBdXRob3JpemF0aW9uQ3JlZGVudGlhbHMoKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXQgdXNlR2xvYmFsQXV0aCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC51c2VHbG9iYWxBdXRoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTW9kZWwgdG8gaG9sZCBpbnRlcm5hbCBmb3JtIGZpZWxkIHZhbHVlcztcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBtb2RlbCA9IHtcclxuICAgICAgICB1c2VybmFtZTogJycsXHJcbiAgICAgICAgcGFzc3dvcmQ6ICcnLFxyXG4gICAgICAgIGFwcGx5VG9BbGw6IGZhbHNlLFxyXG4gICAgICAgIHVzZUxhcHM6IGZhbHNlLFxyXG4gICAgICAgIGxhcHNMb2NhbEFkbWluTmFtZTogJycsXHJcbiAgICAgICAgdXNlR2xvYmFsQXV0aDogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgY3JlZGVudGlhbHNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxBdXRob3JpemF0aW9uQ3JlZGVudGlhbHM+KCk7XHJcblxyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgYXV0aG9yaXphdGlvbk1ldGhvZENoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEJvb2xlYW4+KCk7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzaG93QXBwbHlUb0FsbCA9IHRydWU7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBpc1NlcnZpY2VNb2RlID0gZmFsc2U7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBmb3JtSWQ6IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIG5vQ2hvaWNlID0gZmFsc2U7XHJcblxyXG4gICAgQFZpZXdDaGlsZCgnbWFuYWdlQXNGb3JtJylcclxuICAgIHB1YmxpYyBtYW5hZ2VBc0Zvcm06IE5nRm9ybTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBOb2RlQ3JlZGVudGlhbHNGb3JtIGNsYXNzLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcENvbnRleHRTZXJ2aWNlOiBBcHBDb250ZXh0U2VydmljZSkge1xyXG4gICAgICAgIHRoaXMubXlBY2NvdW50ID0gRW52aXJvbm1lbnRNb2R1bGUuaXNHYXRld2F5TGludXggP1xyXG4gICAgICAgICAgICB0aGlzLnN0cmluZ3MuVXNlR2xvYmFsQXV0aC5teUxpbnV4QWNjb3VudCA6IHRoaXMuc3RyaW5ncy5Vc2VHbG9iYWxBdXRoLm15V2luZG93c0FjY291bnQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlc2V0KG5vZGVOYW1lOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgICAgICAvLyBUT0RPOiBoYW5kbGUgbm8gbm9kZU5hbWVzIHByb3ZpZGVkXHJcbiAgICAgICAgdGhpcy5hcHBseVRvQWxsID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VBc0Zvcm0uZm9ybS5jb250cm9scy51c2VybmFtZS5yZXNldCgpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlQXNGb3JtLmZvcm0uY29udHJvbHMucGFzc3dvcmQucmVzZXQoKTtcclxuICAgICAgICB0aGlzLnVzZUxhcHMgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmxhcHNMb2NhbEFkbWluTmFtZSA9IEF1dGhvcml6YXRpb25NYW5hZ2VyLmRlZmF1bHRMYXBzTG9jYWxBZG1pbk5hbWU7IC8vIFNob3cgZGVmYXVsdCB2YWx1ZSwgdXNlcnMgY2FuIGNoYW5nZS5cclxuICAgICAgICB0aGlzLnVzZUdsb2JhbEF1dGggPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuaGFzUGVyTm9kZUNyZWRlbnRpYWxzID0gT2JqZWN0LmtleXModGhpcy5hcHBDb250ZXh0U2VydmljZS5hdXRob3JpemF0aW9uTWFuYWdlci5ub2RlVG9rZW5zKS5sZW5ndGggPiAwO1xyXG5cclxuICAgICAgICBjb25zdCBub2RlVG9rZW4gPSB0aGlzLmFwcENvbnRleHRTZXJ2aWNlLmF1dGhvcml6YXRpb25NYW5hZ2VyLm5vZGVUb2tlbnNbbm9kZU5hbWVdO1xyXG4gICAgICAgIGNvbnN0IGdsb2JhbFRva2VuID0gdGhpcy5hcHBDb250ZXh0U2VydmljZS5hdXRob3JpemF0aW9uTWFuYWdlci5tYW5hZ2VBc1Rva2VuO1xyXG5cclxuICAgICAgICBpZiAobm9kZVRva2VuKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXNlR2xvYmFsQXV0aCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnVzZXJuYW1lID0gbm9kZVRva2VuLnVzZXJuYW1lO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGdsb2JhbFRva2VuKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2xvYmFsVXNlcm5hbWUgPSBnbG9iYWxUb2tlbi51c2VybmFtZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZUF1dGhvcml6YXRpb25DcmVkZW50aWFscygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBhdXRoQ3JlZHM6IEF1dGhvcml6YXRpb25DcmVkZW50aWFscyA9IHtcclxuICAgICAgICAgICAgdXNlcm5hbWU6IHRoaXMudXNlcm5hbWUsXHJcbiAgICAgICAgICAgIHBhc3N3b3JkOiB0aGlzLnBhc3N3b3JkLFxyXG4gICAgICAgICAgICBhcHBseVRvQWxsTm9kZXM6IHRoaXMuYXBwbHlUb0FsbCxcclxuICAgICAgICAgICAgdXNlTGFwczogZmFsc2UsIC8vIEJ5IGRlZmF1bHQgdXNlTGFwcyBzaG91bGQgYmUgZmFsc2VcclxuICAgICAgICAgICAgbGFwc0xvY2FsQWRtaW5OYW1lOiB0aGlzLmxhcHNMb2NhbEFkbWluTmFtZVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5ub0Nob2ljZSAmJiB0aGlzLnVzZUdsb2JhbEF1dGgpIHtcclxuICAgICAgICAgICAgYXV0aENyZWRzLnVzZXJuYW1lID0gbnVsbDtcclxuICAgICAgICAgICAgYXV0aENyZWRzLnBhc3N3b3JkID0gbnVsbDtcclxuICAgICAgICAgICAgYXV0aENyZWRzLmFwcGx5VG9BbGxOb2RlcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBhdXRoQ3JlZHMudXNlTGFwcyA9IHRoaXMudXNlTGFwcztcclxuICAgICAgICAgICAgYXV0aENyZWRzLmxhcHNMb2NhbEFkbWluTmFtZSA9IHRoaXMubGFwc0xvY2FsQWRtaW5OYW1lO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5jcmVkZW50aWFsc0NoYW5nZWQubmV4dChhdXRoQ3JlZHMpO1xyXG4gICAgICAgIC8vIGNhcHR1cmUgd2hldGhlciB0aGUgZm9ybSBoYXMgYSBcIkxvY2FsIGFkbWluaXN0cmF0b3IgcGFzc3dvcmRcIiBmb3JtIGZpZWxkc1xyXG4gICAgICAgIHRoaXMuYXV0aG9yaXphdGlvbk1ldGhvZENoYW5nZWQuZW1pdCh0aGlzLnVzZUdsb2JhbEF1dGgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVmFsaWRhdGUgdGhlIGF1dGggdHlwZSBmaWVsZFxyXG4gICAgICogQHBhcmFtIGV2ZW50IHRoZSB2YWxpZGF0aW9uIGV2ZW50XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB2YWxpZGF0ZUF1dGhUeXBlKGV2ZW50OiBDaGVja1ZhbGlkYXRpb25FdmVudEFyZ3MpIHtcclxuICAgICAgICBjb25zdCBhbGVydHM6IFZhbGlkYXRpb25BbGVydHMgPSB7fTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLnVzZUdsb2JhbEF1dGgpIHtcclxuICAgICAgICAgICAgYWxlcnRzWyd1c2VHbG9iYWxBdXRoJ10gPSB7XHJcbiAgICAgICAgICAgICAgICB2YWxpZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHRoaXMuc3RyaW5ncy5Vc2VHbG9iYWxBdXRoLndhcm5pbmcsXHJcbiAgICAgICAgICAgICAgICBzZXZlcml0eTogVmFsaWRhdGlvbkFsZXJ0U2V2ZXJpdHkuV2FybmluZ1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1NlcnZpY2VNb2RlKSB7XHJcbiAgICAgICAgICAgIGFsZXJ0c1snc2VydmljZU1vZGUnXSA9IHtcclxuICAgICAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogdGhpcy5zdHJpbmdzLmRlcGxveW1lbnRHdWlkZU1lc3NhZ2UsXHJcbiAgICAgICAgICAgICAgICBzZXZlcml0eTogVmFsaWRhdGlvbkFsZXJ0U2V2ZXJpdHkuV2FybmluZ1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTXNmdFNtZS5kZWVwQXNzaWduKGV2ZW50LmFsZXJ0cywgYWxlcnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFZhbGlkYXRlIHRoZSBhcHBseSB0byBhbGwgZmllbGRcclxuICAgICAqIEBwYXJhbSBldmVudCB0aGUgdmFsaWRhdGlvbiBldmVudFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgdmFsaWRhdGVBcHBseVRvQWxsKGV2ZW50OiBDaGVja1ZhbGlkYXRpb25FdmVudEFyZ3MpIHtcclxuICAgICAgICBjb25zdCBhbGVydHM6IFZhbGlkYXRpb25BbGVydHMgPSB7fTtcclxuICAgICAgICBpZiAoIXRoaXMudXNlR2xvYmFsQXV0aCAmJiB0aGlzLmhhc1Blck5vZGVDcmVkZW50aWFscyAmJiB0aGlzLmFwcGx5VG9BbGwpIHtcclxuICAgICAgICAgICAgYWxlcnRzWydoYXNQZXJOb2RlQ3JlZGVudGlhbHMnXSA9IHtcclxuICAgICAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogdGhpcy5zdHJpbmdzLkFwcGx5VG9BbGwud2FybmluZyxcclxuICAgICAgICAgICAgICAgIHNldmVyaXR5OiBWYWxpZGF0aW9uQWxlcnRTZXZlcml0eS5XYXJuaW5nXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBNc2Z0U21lLmRlZXBBc3NpZ24oZXZlbnQuYWxlcnRzLCBhbGVydHMpO1xyXG4gICAgfVxyXG59XHJcbiIsIjxmb3JtIG5hbWU9XCJtYW5hZ2VBc1wiIFtpZF09XCJmb3JtSWRcIiAjbWFuYWdlQXNGb3JtPVwibmdGb3JtXCI+XHJcbiAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIW5vQ2hvaWNlXCI+XHJcbiAgICAgICAgPHNtZS1mb3JtLWZpZWxkIHR5cGU9XCJyYWRpb2dyb3VwXCIgbmFtZT1cImF1dGhUeXBlXCIgWyhuZ01vZGVsKV09XCJ1c2VHbG9iYWxBdXRoXCIgKGN1c3RvbVZhbGlkYXRlKT1cInZhbGlkYXRlQXV0aFR5cGUoJGV2ZW50KVwiIFtpbW1lZGlhdGVWYWxpZGF0aW9uXT1cInRydWVcIj5cclxuICAgICAgICAgICAgPHNtZS1vcHRpb24gW3ZhbHVlXT1cInRydWVcIiBbbGFiZWxdPVwic3RyaW5ncy5Vc2VHbG9iYWxBdXRoLmxhYmVsRm9ybWF0IHwgc21lRm9ybWF0OihnbG9iYWxVc2VybmFtZSB8fCBteUFjY291bnQpXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNtZS1mb3JtLWZpZWxkICpuZ0lmPVwiIWlzU2VydmljZU1vZGVcIiB0eXBlPVwiY2hlY2tib3hcIiBuYW1lPVwidXNlTGFwc1wiIFsobmdNb2RlbCldPVwidXNlTGFwc1wiIFtsYWJlbF09XCJzdHJpbmdzLlVzZUxhcHMubGFiZWxcIj48L3NtZS1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgIDxmaWVsZHNldCAqbmdJZj1cIiFpc1NlcnZpY2VNb2RlXCIgW2Rpc2FibGVkXT1cIiF1c2VMYXBzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzbWUtZm9ybS1maWVsZCB0eXBlPVwidGV4dFwiIG5hbWU9XCJsYXBzTG9jYWxBZG1pbk5hbWVcIiBbKG5nTW9kZWwpXT1cImxhcHNMb2NhbEFkbWluTmFtZVwiIFtsYWJlbF09XCJzdHJpbmdzLmxhcHNMb2NhbEFkbWluTmFtZS5sYWJlbFwiIFtwbGFjZWhvbGRlcl09XCJzdHJpbmdzLmxhcHNMb2NhbEFkbWluTmFtZS5wbGFjZWhvbGRlclwiPjwvc21lLWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9maWVsZHNldD5cclxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgIDwvc21lLW9wdGlvbj5cclxuICAgICAgICAgICAgPHNtZS1vcHRpb24gW3ZhbHVlXT1cImZhbHNlXCIgW2xhYmVsXT1cInN0cmluZ3MuVXNlUGVyTm9kZUF1dGgubGFiZWxcIj5cclxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgICAgICAgICA8c21lLWZvcm0tZmllbGQgdHlwZT1cInRleHRcIiBuYW1lPVwidXNlcm5hbWVcIiBbKG5nTW9kZWwpXT1cInVzZXJuYW1lXCIgW3JlcXVpcmVkXT1cInRydWVcIiBbbGFiZWxdPVwic3RyaW5ncy5Vc2VybmFtZS5sYWJlbFwiIFtwbGFjZWhvbGRlcl09XCJzdHJpbmdzLlVzZXJuYW1lLnBsYWNlaG9sZGVyXCI+PC9zbWUtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICA8c21lLWZvcm0tZmllbGQgdHlwZT1cInBhc3N3b3JkXCIgbmFtZT1cInBhc3N3b3JkXCIgWyhuZ01vZGVsKV09XCJwYXNzd29yZFwiIFtyZXF1aXJlZF09XCJ0cnVlXCIgW2xhYmVsXT1cInN0cmluZ3MuUGFzc3dvcmQubGFiZWxcIiBbcGxhY2Vob2xkZXJdPVwic3RyaW5ncy5QYXNzd29yZC5wbGFjZWhvbGRlclwiPjwvc21lLWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgPHNtZS1mb3JtLWZpZWxkICpuZ0lmPVwic2hvd0FwcGx5VG9BbGxcIiB0eXBlPVwiY2hlY2tib3hcIiBuYW1lPVwiYXBwbHlUb0FsbFwiIFsobmdNb2RlbCldPVwiYXBwbHlUb0FsbFwiIFtsYWJlbF09XCJzdHJpbmdzLkFwcGx5VG9BbGwubGFiZWxcIiAoY3VzdG9tVmFsaWRhdGUpPVwidmFsaWRhdGVBcHBseVRvQWxsKCRldmVudClcIj48L3NtZS1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgPC9zbWUtb3B0aW9uPlxyXG4gICAgICAgIDwvc21lLWZvcm0tZmllbGQ+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIm5vQ2hvaWNlXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNtZS1wYWRkaW5nLXRvcC1zbVwiPlxyXG4gICAgICAgICAgICA8c21lLWZvcm0tZmllbGQgdHlwZT1cInRleHRcIiBuYW1lPVwidXNlcm5hbWVcIiBbKG5nTW9kZWwpXT1cInVzZXJuYW1lXCIgW3JlcXVpcmVkXT1cInRydWVcIiBbbGFiZWxdPVwic3RyaW5ncy5Vc2VybmFtZS5sYWJlbFwiIFtwbGFjZWhvbGRlcl09XCJzdHJpbmdzLlVzZXJuYW1lLnBsYWNlaG9sZGVyXCI+PC9zbWUtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgPHNtZS1mb3JtLWZpZWxkIHR5cGU9XCJwYXNzd29yZFwiIG5hbWU9XCJwYXNzd29yZFwiIFsobmdNb2RlbCldPVwicGFzc3dvcmRcIiBbcmVxdWlyZWRdPVwidHJ1ZVwiIFtsYWJlbF09XCJzdHJpbmdzLlBhc3N3b3JkLmxhYmVsXCIgW3BsYWNlaG9sZGVyXT1cInN0cmluZ3MuUGFzc3dvcmQucGxhY2Vob2xkZXJcIj48L3NtZS1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICA8c21lLWZvcm0tZmllbGQgKm5nSWY9XCJzaG93QXBwbHlUb0FsbFwiIHR5cGU9XCJjaGVja2JveFwiIG5hbWU9XCJhcHBseVRvQWxsXCIgWyhuZ01vZGVsKV09XCJhcHBseVRvQWxsXCIgW2xhYmVsXT1cInN0cmluZ3MuQXBwbHlUb0FsbC5sYWJlbFwiIChjdXN0b21WYWxpZGF0ZSk9XCJ2YWxpZGF0ZUFwcGx5VG9BbGwoJGV2ZW50KVwiPjwvc21lLWZvcm0tZmllbGQ+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG48L2Zvcm0+Il19