@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
461 lines • 62.9 kB
JavaScript
import { Component, ComponentFactoryResolver, Directive, ElementRef, EventEmitter, Input, Optional, Output, QueryList, SkipSelf, ViewChild, ViewChildren, ViewContainerRef } from '@angular/core';
import { LogLevel } from '@microsoft/windows-admin-center-sdk/core/diagnostics/log-level';
import { Logging } from '@microsoft/windows-admin-center-sdk/core/diagnostics/logging';
import { FormFieldComponent } from '../form/form-field/form-field.component';
import { SchemaFieldContext, SchemaPrimitiveType } from '../schema/schema-models';
import { SchemaDataTypeStore } from '../schema/schema-store';
import * as i0 from "@angular/core";
const _c0 = ["fieldHost"];
const _c1 = ["field"];
/**
* Schema Form Component
* It takes the schema and data and other necessary inputs then dynamically renders the form UI.
*/
export class SchemaFieldHostComponent {
constructor(elementRef, viewContainer, componentFactoryResolver, parent) {
this.elementRef = elementRef;
this.viewContainer = viewContainer;
this.componentFactoryResolver = componentFactoryResolver;
this.parent = parent;
this.isInitialized = false;
this.dataTypeStore = new SchemaDataTypeStore();
this.formActionExecuted = new EventEmitter();
this.dataChange = new EventEmitter();
this.dataMarkedAsDirty = new EventEmitter();
this.elementRef.nativeElement.classList.add('sme-schema-field-host');
this.elementRef.nativeElement.classList.add('sme-layout-block');
}
get propertySchema() {
return this.internalPropertySchema;
}
set propertySchema(value) {
this.internalPropertySchema = value;
if (this.isInitialized) {
/* if (this.loaderComponentRef) {
this.loaderComponentRef.instance.propertySchema = this.propertySchema;
} */
this.renderLoaderComponent();
}
}
get data() {
return this.internalData;
}
set data(value) {
const isChanged = this.internalData === value;
this.internalData = value;
if (this.isInitialized) {
this.dataChange.emit(value);
if (this.loaderComponentRef) {
this.loaderComponentRef.instance.data = this.data;
this.loaderComponentRef.instance.context.formData = this.context.formData;
}
}
if (isChanged && this.isDirty()) {
this.executeFormAction('data change', { field: this.propertySchema.name, value: value });
}
}
ngOnInit() {
this.renderLoaderComponent();
this.isInitialized = true;
}
isValid() {
return this.loaderComponentRef.instance.isValid();
}
isDirty() {
return this.loaderComponentRef && this.loaderComponentRef.instance.isDirty();
}
markAsPristine() {
this.loaderComponentRef.instance.markAsPristine();
}
executeFormAction(action, data) {
if (!this.parent) {
this.formActionExecuted.emit({ action: action, data: data });
}
else {
let parent = this.parent;
while (parent.parent) {
parent = parent.parent;
}
parent.formActionExecuted.emit({ action: action, data: data });
}
}
getFormFieldLoaderComponent() {
return this.loaderComponentRef && this.loaderComponentRef.instance;
}
renderLoaderComponent() {
let type = this.propertySchema.type;
let format = this.propertySchema.format;
if (MsftSme.isNullOrUndefined(type)) {
type = SchemaPrimitiveType.Object;
if (!format) {
format = 'basic-form';
}
}
if (!format) {
const allRegistrations = this.dataTypeStore.getAllRegistrations();
allRegistrations.forEach(item => {
if (item.type === type && item.isDefaultFormat) {
format = item.format;
}
});
}
const registration = this.dataTypeStore.getDataTypeRegistration(type, format);
if (registration) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(registration.loaderComponent);
const viewContainerRef = this.fieldHost;
viewContainerRef.clear();
this.loaderComponentRef = viewContainerRef.createComponent(componentFactory);
this.loaderComponentRef.instance.propertySchema = this.propertySchema;
this.loaderComponentRef.instance.data = this.data;
this.loaderComponentRef.instance.context = { ...this.context };
if (this.parent) {
this.loaderComponentRef.instance.context.parentData = this.parent.data;
}
this.loaderComponentRef.instance.parentSchemaFieldHostComponent = this;
if (!!this.loaderComponentRef.instance.dataChange) {
this.loaderComponentRef.instance.dataChange.subscribe(data => {
this.internalData = data;
this.dataChange.emit(data);
});
}
}
}
}
/** @nocollapse */ SchemaFieldHostComponent.ɵfac = function SchemaFieldHostComponent_Factory(t) { return new (t || SchemaFieldHostComponent)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i0.ComponentFactoryResolver), i0.ɵɵdirectiveInject(SchemaFieldHostComponent, 12)); };
/** @nocollapse */ SchemaFieldHostComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: SchemaFieldHostComponent, selectors: [["sme-schema-field-host"]], viewQuery: function SchemaFieldHostComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c0, 7, ViewContainerRef);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fieldHost = _t.first);
} }, inputs: { context: "context", propertySchema: "propertySchema", data: "data" }, outputs: { formActionExecuted: "formActionExecuted", dataChange: "dataChange", dataMarkedAsDirty: "dataMarkedAsDirty" }, decls: 2, vars: 0, consts: [["fieldHost", ""]], template: function SchemaFieldHostComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "div", null, 0);
} }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchemaFieldHostComponent, [{
type: Component,
args: [{ selector: 'sme-schema-field-host', template: "<div #fieldHost></div>" }]
}], function () { return [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.ComponentFactoryResolver }, { type: SchemaFieldHostComponent, decorators: [{
type: SkipSelf
}, {
type: Optional
}] }]; }, { fieldHost: [{
type: ViewChild,
args: ['fieldHost', { read: ViewContainerRef, static: true }]
}], context: [{
type: Input
}], formActionExecuted: [{
type: Output
}], propertySchema: [{
type: Input
}], data: [{
type: Input
}], dataChange: [{
type: Output
}], dataMarkedAsDirty: [{
type: Output
}] }); })();
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class SchemaFieldLoaderComponentBase {
constructor() {
this.shouldStartToApplyAsyncValidator = false;
this.strings = MsftSme.getStrings();
this.badExpressions = [];
this.dataChange = new EventEmitter();
this.formActionExecuted = new EventEmitter();
}
get data() {
return this.internalData;
}
set data(value) {
this.internalData = value;
this.dataChange.emit(value);
}
get context() {
return this.internalContext;
}
set context(value) {
this.internalContext = value;
}
ngOnInit() {
setTimeout(() => {
this.shouldStartToApplyAsyncValidator = true;
});
}
isValid() {
return this.formFieldComponent && (this.formFieldComponent.disabled || this.formFieldComponent.isValid());
}
shouldCustomAsyncValidationBeDisabled() {
return !(this.shouldStartToApplyAsyncValidator
&& this.parentSchemaFieldHostComponent.propertySchema.customAsyncValidation
&& this.parentSchemaFieldHostComponent.propertySchema.customAsyncValidation.handler);
}
isDirty() {
return this.formFieldComponent && this.formFieldComponent.isDirty();
}
markAsPristine() {
if (this.formFieldComponent) {
this.formFieldComponent.markAsPristine();
}
}
evalExpression(expression) {
let result;
if (expression) {
if (this.badExpressions.indexOf(expression) === -1) {
try {
const caller = this.resolveComponentMember(expression.substring(0, expression.lastIndexOf('.')));
const expressionFunction = this.resolveComponentMember(expression);
if (caller && expressionFunction) {
result = expressionFunction.call(caller, this.context);
}
else {
if (expression === 'true') {
result = true;
}
}
}
catch (e) {
// eslint-disable-next-line no-console
console.error(e);
if (this.badExpressions.indexOf(expression) === -1) {
this.badExpressions.push(expression);
}
}
}
}
return result;
}
/**
* It resolves the object properties based on the given path with multiple levels of properties.
* An example of path is "location.zipCode".
*/
resolveComponentMember(path) {
if (path) {
if (path.indexOf('formData') === 0 || path.indexOf('formController') === 0 || path.indexOf('parentData') === 0) {
path = 'context.' + path;
}
const obj = this;
const pathSegments = path.split('.');
if (pathSegments.length === 1) {
return obj[path];
}
let currentObj = obj;
for (let i = 0; i < pathSegments.length; i++) {
currentObj = currentObj[pathSegments[i]];
if (currentObj === undefined || currentObj === null) {
break;
}
}
return currentObj;
}
return null;
}
resolveFunction(path) {
const defaultFunction = () => {
// Do nothing by default.
};
let resolvedFunction;
if (this.badExpressions.indexOf(path) === -1) {
if (path) {
const owner = this.resolveComponentMember(path.substring(0, path.lastIndexOf('.')));
if (owner) {
resolvedFunction = this.resolveComponentMember(path).bind(owner);
}
else {
this.badExpressions.push(path);
Logging.log({
level: LogLevel.Error,
message: 'Resolve Function Error',
params: {
string: path
},
source: 'SchemaFieldLoaderComponentBase.resolveFunction'
});
}
}
}
return resolvedFunction || defaultFunction;
}
localize(text) {
let result = '';
if (text) {
const cacheData = SchemaFieldLoaderComponentBase.localizationCache[text];
if (cacheData) {
result = cacheData;
}
else {
if (text.indexOf(SchemaFieldLoaderComponentBase.resourceKeyPrefix) === 0) {
const path = 'strings.' + text.substring(SchemaFieldLoaderComponentBase.resourceKeyPrefix.length);
result = this.resolveComponentMember(path);
}
else if (text.indexOf(SchemaFieldLoaderComponentBase.resourceActualTextPrefix) === 0) {
result = text.substring(SchemaFieldLoaderComponentBase.resourceActualTextPrefix.length);
}
if (!result) {
result = '[Failed to find localized string: ' + text + ']';
Logging.log({
level: LogLevel.Error,
message: result,
params: {
string: text
},
source: 'SchemaFieldLoaderComponentBase Localization Error: ' + text
});
}
SchemaFieldLoaderComponentBase.localizationCache[text] = result;
}
}
return result;
}
executeFormAction(action, data) {
this.parentSchemaFieldHostComponent.formActionExecuted.emit({ action: action, data: data });
}
}
SchemaFieldLoaderComponentBase.resourceKeyPrefix = 'resources:strings:';
SchemaFieldLoaderComponentBase.resourceActualTextPrefix = 'actual_string:';
SchemaFieldLoaderComponentBase.localizationCache = {};
/** @nocollapse */ SchemaFieldLoaderComponentBase.ɵfac = function SchemaFieldLoaderComponentBase_Factory(t) { return new (t || SchemaFieldLoaderComponentBase)(); };
/** @nocollapse */ SchemaFieldLoaderComponentBase.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SchemaFieldLoaderComponentBase, viewQuery: function SchemaFieldLoaderComponentBase_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c1, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.formFieldComponent = _t.first);
} }, inputs: { data: "data" }, outputs: { dataChange: "dataChange", formActionExecuted: "formActionExecuted" } });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SchemaFieldLoaderComponentBase, [{
type: Directive
}], null, { formFieldComponent: [{
type: ViewChild,
args: ['field']
}], data: [{
type: Input
}], dataChange: [{
type: Output
}], formActionExecuted: [{
type: Output
}] }); })();
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class SimplePropertySchemaFieldLoaderComponent extends SchemaFieldLoaderComponentBase {
}
/** @nocollapse */ SimplePropertySchemaFieldLoaderComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵSimplePropertySchemaFieldLoaderComponent_BaseFactory; return function SimplePropertySchemaFieldLoaderComponent_Factory(t) { return (ɵSimplePropertySchemaFieldLoaderComponent_BaseFactory || (ɵSimplePropertySchemaFieldLoaderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SimplePropertySchemaFieldLoaderComponent)))(t || SimplePropertySchemaFieldLoaderComponent); }; }();
/** @nocollapse */ SimplePropertySchemaFieldLoaderComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: SimplePropertySchemaFieldLoaderComponent, inputs: { propertySchema: "propertySchema" }, features: [i0.ɵɵInheritDefinitionFeature] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SimplePropertySchemaFieldLoaderComponent, [{
type: Directive
}], null, { propertySchema: [{
type: Input
}] }); })();
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class ObjectPropertySchemaFieldLoaderComponent extends SchemaFieldLoaderComponentBase {
isValid() {
let result = true;
if (!(!this.propertySchema.format || this.propertySchema.format === 'default' || !this.propertySchema.type)) {
result = super.isValid();
}
if (this.fieldHostComponents) {
const fieldHostComponents = this.fieldHostComponents.toArray();
if (result) {
for (let i = 0; i < fieldHostComponents.length; i++) {
if (!fieldHostComponents[i].isValid()) {
result = false;
break;
}
}
}
}
return result;
}
isDirty() {
let result = false;
if (!(!this.propertySchema.format || this.propertySchema.format === 'default' || this.propertySchema.format === 'tabbed-form')) {
result = super.isDirty();
}
const fieldHostComponents = this.fieldHostComponents.toArray();
if (!result) {
for (let i = 0; i < fieldHostComponents.length; i++) {
if (fieldHostComponents[i].isDirty()) {
result = true;
break;
}
}
}
return result;
}
markAsPristine() {
super.markAsPristine();
const fieldHostComponents = this.fieldHostComponents.toArray();
if (fieldHostComponents) {
for (let i = 0; i < fieldHostComponents.length; i++) {
fieldHostComponents[i].markAsPristine();
}
}
}
}
/** @nocollapse */ ObjectPropertySchemaFieldLoaderComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵObjectPropertySchemaFieldLoaderComponent_BaseFactory; return function ObjectPropertySchemaFieldLoaderComponent_Factory(t) { return (ɵObjectPropertySchemaFieldLoaderComponent_BaseFactory || (ɵObjectPropertySchemaFieldLoaderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ObjectPropertySchemaFieldLoaderComponent)))(t || ObjectPropertySchemaFieldLoaderComponent); }; }();
/** @nocollapse */ ObjectPropertySchemaFieldLoaderComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: ObjectPropertySchemaFieldLoaderComponent, viewQuery: function ObjectPropertySchemaFieldLoaderComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(SchemaFieldHostComponent, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fieldHostComponents = _t);
} }, inputs: { propertySchema: "propertySchema" }, features: [i0.ɵɵInheritDefinitionFeature] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ObjectPropertySchemaFieldLoaderComponent, [{
type: Directive
}], null, { fieldHostComponents: [{
type: ViewChildren,
args: [SchemaFieldHostComponent]
}], propertySchema: [{
type: Input
}] }); })();
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class ArrayPropertySchemaFieldLoaderComponent extends SchemaFieldLoaderComponentBase {
set fieldHostComponents(value) {
this.internalFieldHostComponents = value;
}
isValid() {
let result = super.isValid();
if (result) {
const fieldHostComponents = this.internalFieldHostComponents.toArray();
for (let i = 0; i < fieldHostComponents.length; i++) {
if (!fieldHostComponents[i].isValid()) {
result = false;
break;
}
}
}
return result;
}
isDirty() {
let result = super.isDirty();
if (!result) {
const fieldHostComponents = this.internalFieldHostComponents.toArray();
for (let i = 0; i < fieldHostComponents.length; i++) {
if (fieldHostComponents[i].isDirty()) {
result = true;
break;
}
}
}
return result;
}
markAsPristine() {
super.markAsPristine();
const fieldHostComponents = this.fieldHostComponents.toArray();
if (fieldHostComponents) {
for (let i = 0; i < fieldHostComponents.length; i++) {
fieldHostComponents[i].markAsPristine();
}
}
}
}
/** @nocollapse */ ArrayPropertySchemaFieldLoaderComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵArrayPropertySchemaFieldLoaderComponent_BaseFactory; return function ArrayPropertySchemaFieldLoaderComponent_Factory(t) { return (ɵArrayPropertySchemaFieldLoaderComponent_BaseFactory || (ɵArrayPropertySchemaFieldLoaderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ArrayPropertySchemaFieldLoaderComponent)))(t || ArrayPropertySchemaFieldLoaderComponent); }; }();
/** @nocollapse */ ArrayPropertySchemaFieldLoaderComponent.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: ArrayPropertySchemaFieldLoaderComponent, viewQuery: function ArrayPropertySchemaFieldLoaderComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(SchemaFieldHostComponent, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fieldHostComponents = _t);
} }, inputs: { propertySchema: "propertySchema" }, features: [i0.ɵɵInheritDefinitionFeature] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ArrayPropertySchemaFieldLoaderComponent, [{
type: Directive
}], null, { fieldHostComponents: [{
type: ViewChildren,
args: [SchemaFieldHostComponent]
}], propertySchema: [{
type: Input
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWZpZWxkLWhvc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvc2NoZW1hL3NjaGVtYS1maWVsZC1ob3N0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL3NjaGVtYS9zY2hlbWEtZmllbGQtaG9zdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUFFLHdCQUF3QixFQUFnQixTQUFTLEVBQUUsVUFBVSxFQUN4RSxZQUFZLEVBQUUsS0FBSyxFQUFVLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUNoSCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0VBQWdFLENBQUM7QUFDMUYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDhEQUE4RCxDQUFDO0FBRXZGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQzdFLE9BQU8sRUFDa0Isa0JBQWtCLEVBQ2pCLG1CQUFtQixFQUM1QyxNQUFNLHlCQUF5QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7O0FBRTdEOzs7R0FHRztBQUtILE1BQU0sT0FBTyx3QkFBd0I7SUF5RGpDLFlBQW9CLFVBQXNCLEVBQVUsYUFBK0IsRUFDdkUsd0JBQWtELEVBQWtDLE1BQWdDO1FBRDVHLGVBQVUsR0FBVixVQUFVLENBQVk7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBa0I7UUFDdkUsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUFrQyxXQUFNLEdBQU4sTUFBTSxDQUEwQjtRQXpEeEgsa0JBQWEsR0FB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QUFJLENBQUMsMkJBQTJCLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdkUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDakQsSUFBSSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtvQkFDbEMsTUFBTSxHQUFHLElBQUksQ0FBQztvQkFDZCxNQUFNO2lCQUNUO2FBQ0o7U0FDSjtRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFDTSxjQUFjO1FBQ2pCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2QixNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMvRCxJQUFJLG1CQUFtQixFQUFFO1lBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pELG1CQUFtQixDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQzNDO1NBQ0o7SUFDTCxDQUFDOzswWEEvQ1EsdUNBQXVDLFNBQXZDLHVDQUF1Qzt5SEFBdkMsdUNBQXVDO3VCQUVsQyx3QkFBd0I7Ozs7O3VGQUY3Qix1Q0FBdUM7Y0FGbkQsU0FBUztnQkFLTSxtQkFBbUI7a0JBRDlCLFlBQVk7bUJBQUMsd0JBQXdCO1lBTS9CLGNBQWM7a0JBRHBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQ29tcG9uZW50LCBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIENvbXBvbmVudFJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLFxyXG4gICAgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPcHRpb25hbCwgT3V0cHV0LCBRdWVyeUxpc3QsIFNraXBTZWxmLCBWaWV3Q2hpbGQsIFZpZXdDaGlsZHJlbiwgVmlld0NvbnRhaW5lclJlZlxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBMb2dMZXZlbCB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvZGlhZ25vc3RpY3MvbG9nLWxldmVsJztcclxuaW1wb3J0IHsgTG9nZ2luZyB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvZGlhZ25vc3RpY3MvbG9nZ2luZyc7XHJcbmltcG9ydCB7IFN0cmluZ3MgfSBmcm9tICcuLi8uLi9nZW5lcmF0ZWQvc3RyaW5ncyc7XHJcbmltcG9ydCB7IEZvcm1GaWVsZENvbXBvbmVudCB9IGZyb20gJy4uL2Zvcm0vZm9ybS1maWVsZC9mb3JtLWZpZWxkLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7XHJcbiAgICBTY2hlbWFBcnJheVByb3BlcnR5LCBTY2hlbWFGaWVsZENvbnRleHQsXHJcbiAgICBTY2hlbWFPYmplY3RQcm9wZXJ0eSwgU2NoZW1hUHJpbWl0aXZlVHlwZSwgU2NoZW1hUHJvcGVydHlcclxufSBmcm9tICcuLi9zY2hlbWEvc2NoZW1hLW1vZGVscyc7XHJcbmltcG9ydCB7IFNjaGVtYURhdGFUeXBlU3RvcmUgfSBmcm9tICcuLi9zY2hlbWEvc2NoZW1hLXN0b3JlJztcclxuXHJcbi8qKlxyXG4gKiBTY2hlbWEgRm9ybSBDb21wb25lbnRcclxuICogSXQgdGFrZXMgdGhlIHNjaGVtYSBhbmQgZGF0YSBhbmQgb3RoZXIgbmVjZXNzYXJ5IGlucHV0cyB0aGVuIGR5bmFtaWNhbGx5IHJlbmRlcnMgdGhlIGZvcm0gVUkuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnc21lLXNjaGVtYS1maWVsZC1ob3N0JyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9zY2hlbWEtZmllbGQtaG9zdC5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIFNjaGVtYUZpZWxkSG9zdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICBwcml2YXRlIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcclxuICAgIHByaXZhdGUgaW50ZXJuYWxEYXRhOiBhbnk7XHJcbiAgICBwcml2YXRlIGludGVybmFsUHJvcGVydHlTY2hlbWE6IFNjaGVtYVByb3BlcnR5O1xyXG5cclxuICAgIHByaXZhdGUgbG9hZGVyQ29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8YW55PjtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdmaWVsZEhvc3QnLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogdHJ1ZSB9KVxyXG4gICAgcHJpdmF0ZSBmaWVsZEhvc3Q6IFZpZXdDb250YWluZXJSZWY7XHJcblxyXG4gICAgcHJpdmF0ZSBkYXRhVHlwZVN0b3JlID0gbmV3IFNjaGVtYURhdGFUeXBlU3RvcmUoKTtcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGNvbnRleHQ6IFNjaGVtYUZpZWxkQ29udGV4dDtcclxuXHJcbiAgICBAT3V0cHV0KClcclxuICAgIHB1YmxpYyBmb3JtQWN0aW9uRXhlY3V0ZWQ6IEV2ZW50RW1pdHRlcjx7IGFjdGlvbjogc3RyaW5nLCBkYXRhOiBhbnkgfT4gPSBuZXcgRXZlbnRFbWl0dGVyPHsgYWN0aW9uOiBzdHJpbmcsIGRhdGE6IGFueSB9PigpO1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgZ2V0IHByb3BlcnR5U2NoZW1hKCk6IFNjaGVtYVByb3BlcnR5IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pbnRlcm5hbFByb3BlcnR5U2NoZW1hO1xyXG4gICAgfVxyXG4gICAgcHVibGljIHNldCBwcm9wZXJ0eVNjaGVtYSh2YWx1ZTogU2NoZW1hUHJvcGVydHkpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsUHJvcGVydHlTY2hlbWEgPSB2YWx1ZTtcclxuICAgICAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgIC8qIGlmICh0aGlzLmxvYWRlckNvbXBvbmVudFJlZikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2UucHJvcGVydHlTY2hlbWEgPSB0aGlzLnByb3BlcnR5U2NoZW1hO1xyXG4gICAgICAgICAgICB9ICovXHJcblxyXG4gICAgICAgICAgICB0aGlzLnJlbmRlckxvYWRlckNvbXBvbmVudCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGdldCBkYXRhKCk6IGFueSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxEYXRhO1xyXG4gICAgfVxyXG4gICAgcHVibGljIHNldCBkYXRhKHZhbHVlOiBhbnkpIHtcclxuICAgICAgICBjb25zdCBpc0NoYW5nZWQgPSB0aGlzLmludGVybmFsRGF0YSA9PT0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5pbnRlcm5hbERhdGEgPSB2YWx1ZTtcclxuICAgICAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGF0YUNoYW5nZS5lbWl0KHZhbHVlKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMubG9hZGVyQ29tcG9uZW50UmVmKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRlckNvbXBvbmVudFJlZi5pbnN0YW5jZS5kYXRhID0gdGhpcy5kYXRhO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2UuY29udGV4dC5mb3JtRGF0YSA9IHRoaXMuY29udGV4dC5mb3JtRGF0YTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoaXNDaGFuZ2VkICYmIHRoaXMuaXNEaXJ0eSgpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZXhlY3V0ZUZvcm1BY3Rpb24oJ2RhdGEgY2hhbmdlJywgeyBmaWVsZDogdGhpcy5wcm9wZXJ0eVNjaGVtYS5uYW1lLCB2YWx1ZTogdmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgZGF0YUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICAgIEBPdXRwdXQoKVxyXG4gICAgcHVibGljIGRhdGFNYXJrZWRBc0RpcnR5OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwcml2YXRlIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBjb21wb25lbnRGYWN0b3J5UmVzb2x2ZXI6IENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciwgQFNraXBTZWxmKCkgQE9wdGlvbmFsKCkgcHJpdmF0ZSBwYXJlbnQ6IFNjaGVtYUZpZWxkSG9zdENvbXBvbmVudCkge1xyXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3NtZS1zY2hlbWEtZmllbGQtaG9zdCcpO1xyXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3NtZS1sYXlvdXQtYmxvY2snKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJMb2FkZXJDb21wb25lbnQoKTtcclxuICAgICAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpc1ZhbGlkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAoPFNjaGVtYUZpZWxkTG9hZGVyQ29tcG9uZW50QmFzZT50aGlzLmxvYWRlckNvbXBvbmVudFJlZi5pbnN0YW5jZSkuaXNWYWxpZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBpc0RpcnR5KCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvYWRlckNvbXBvbmVudFJlZiAmJiAoPFNjaGVtYUZpZWxkTG9hZGVyQ29tcG9uZW50QmFzZT50aGlzLmxvYWRlckNvbXBvbmVudFJlZi5pbnN0YW5jZSkuaXNEaXJ0eSgpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIG1hcmtBc1ByaXN0aW5lKCk6IHZvaWQge1xyXG4gICAgICAgICg8U2NoZW1hRmllbGRMb2FkZXJDb21wb25lbnRCYXNlPnRoaXMubG9hZGVyQ29tcG9uZW50UmVmLmluc3RhbmNlKS5tYXJrQXNQcmlzdGluZSgpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIGV4ZWN1dGVGb3JtQWN0aW9uKGFjdGlvbjogc3RyaW5nLCBkYXRhOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMucGFyZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZm9ybUFjdGlvbkV4ZWN1dGVkLmVtaXQoeyBhY3Rpb246IGFjdGlvbiwgZGF0YTogZGF0YSB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5wYXJlbnQ7XHJcbiAgICAgICAgICAgIHdoaWxlIChwYXJlbnQucGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcmVudC5mb3JtQWN0aW9uRXhlY3V0ZWQuZW1pdCh7IGFjdGlvbjogYWN0aW9uLCBkYXRhOiBkYXRhIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHB1YmxpYyBnZXRGb3JtRmllbGRMb2FkZXJDb21wb25lbnQoKTogU2NoZW1hRmllbGRMb2FkZXJDb21wb25lbnRCYXNlIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb2FkZXJDb21wb25lbnRSZWYgJiYgdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2U7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSByZW5kZXJMb2FkZXJDb21wb25lbnQoKSB7XHJcbiAgICAgICAgbGV0IHR5cGUgPSB0aGlzLnByb3BlcnR5U2NoZW1hLnR5cGU7XHJcbiAgICAgICAgbGV0IGZvcm1hdCA9IHRoaXMucHJvcGVydHlTY2hlbWEuZm9ybWF0O1xyXG4gICAgICAgIGlmIChNc2Z0U21lLmlzTnVsbE9yVW5kZWZpbmVkKHR5cGUpKSB7XHJcbiAgICAgICAgICAgIHR5cGUgPSBTY2hlbWFQcmltaXRpdmVUeXBlLk9iamVjdDtcclxuICAgICAgICAgICAgaWYgKCFmb3JtYXQpIHtcclxuICAgICAgICAgICAgICAgIGZvcm1hdCA9ICdiYXNpYy1mb3JtJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZvcm1hdCkge1xyXG4gICAgICAgICAgICBjb25zdCBhbGxSZWdpc3RyYXRpb25zID0gdGhpcy5kYXRhVHlwZVN0b3JlLmdldEFsbFJlZ2lzdHJhdGlvbnMoKTtcclxuICAgICAgICAgICAgYWxsUmVnaXN0cmF0aW9ucy5mb3JFYWNoKGl0ZW0gPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0udHlwZSA9PT0gdHlwZSAmJiBpdGVtLmlzRGVmYXVsdEZvcm1hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9IGl0ZW0uZm9ybWF0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgcmVnaXN0cmF0aW9uID0gdGhpcy5kYXRhVHlwZVN0b3JlLmdldERhdGFUeXBlUmVnaXN0cmF0aW9uKHR5cGUsIGZvcm1hdCk7XHJcbiAgICAgICAgaWYgKHJlZ2lzdHJhdGlvbikge1xyXG4gICAgICAgICAgICBjb25zdCBjb21wb25lbnRGYWN0b3J5ID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkocmVnaXN0cmF0aW9uLmxvYWRlckNvbXBvbmVudCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHZpZXdDb250YWluZXJSZWYgPSB0aGlzLmZpZWxkSG9zdDtcclxuICAgICAgICAgICAgdmlld0NvbnRhaW5lclJlZi5jbGVhcigpO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRlckNvbXBvbmVudFJlZiA9IHZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudEZhY3RvcnkpO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRlckNvbXBvbmVudFJlZi5pbnN0YW5jZS5wcm9wZXJ0eVNjaGVtYSA9IHRoaXMucHJvcGVydHlTY2hlbWE7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZGVyQ29tcG9uZW50UmVmLmluc3RhbmNlLmRhdGEgPSB0aGlzLmRhdGE7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZGVyQ29tcG9uZW50UmVmLmluc3RhbmNlLmNvbnRleHQgPSB7IC4uLnRoaXMuY29udGV4dCB9O1xyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubG9hZGVyQ29tcG9uZW50UmVmLmluc3RhbmNlLmNvbnRleHQucGFyZW50RGF0YSA9IHRoaXMucGFyZW50LmRhdGE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2UucGFyZW50U2NoZW1hRmllbGRIb3N0Q29tcG9uZW50ID0gdGhpcztcclxuICAgICAgICAgICAgaWYgKCEhdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2UuZGF0YUNoYW5nZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkZXJDb21wb25lbnRSZWYuaW5zdGFuY2UuZGF0YUNoYW5nZS5zdWJzY3JpYmUoZGF0YSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnRlcm5hbERhdGEgPSBkYXRhO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0YUNoYW5nZS5lbWl0KGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkBEaXJlY3RpdmUoKVxyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2RpcmVjdGl2ZS1jbGFzcy1zdWZmaXhcclxuZXhwb3J0IGNsYXNzIFNjaGVtYUZpZWxkTG9hZGVyQ29tcG9uZW50QmFzZSBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlc291cmNlS2V5UHJlZml4ID0gJ3Jlc291cmNlczpzdHJpbmdzOic7XHJcbiAgICBwdWJsaWMgc3RhdGljIHJlc291cmNlQWN0dWFsVGV4dFByZWZpeCA9ICdhY3R1YWxfc3RyaW5nOic7XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgbG9jYWxpemF0aW9uQ2FjaGU6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcclxuXHJcbiAgICBwcml2YXRlIHNob3VsZFN0YXJ0VG9BcHBseUFzeW5jVmFsaWRhdG9yID0gZmFsc2U7XHJcblxyXG4gICAgcHJpdmF0ZSBzdHJpbmdzOiBTdHJpbmdzID0gTXNmdFNtZS5nZXRTdHJpbmdzPFN0cmluZ3M+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBiYWRFeHByZXNzaW9uczogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICBwcml2YXRlIGludGVybmFsRGF0YTogYW55O1xyXG4gICAgcHJpdmF0ZSBpbnRlcm5hbENvbnRleHQ6IFNjaGVtYUZpZWxkQ29udGV4dDtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdmaWVsZCcpXHJcbiAgICBwdWJsaWMgZm9ybUZpZWxkQ29tcG9uZW50OiBGb3JtRmllbGRDb21wb25lbnQ8U3RyaW5ncywgYW55PjtcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGdldCBkYXRhKCk6IGFueSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxEYXRhO1xyXG4gICAgfVxyXG4gICAgcHVibGljIHNldCBkYXRhKHZhbHVlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsRGF0YSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuZGF0YUNoYW5nZS5lbWl0KHZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICBAT3V0cHV0KClcclxuICAgIHB1YmxpYyBkYXRhQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgZm9ybUFjdGlvbkV4ZWN1dGVkOiBFdmVudEVtaXR0ZXI8eyBhY3Rpb246IHN0cmluZywgZGF0YTogYW55IH0+ID0gbmV3IEV2ZW50RW1pdHRlcjx7IGFjdGlvbjogc3RyaW5nLCBkYXRhOiBhbnkgfT4oKTtcclxuXHJcbiAgICBwdWJsaWMgcGFyZW50U2NoZW1hRmllbGRIb3N0Q29tcG9uZW50OiBTY2hlbWFGaWVsZEhvc3RDb21wb25lbnQ7XHJcblxyXG4gICAgcHVibGljIGdldCBjb250ZXh0KCk6IFNjaGVtYUZpZWxkQ29udGV4dCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxDb250ZXh0O1xyXG4gICAgfVxyXG4gICAgcHVibGljIHNldCBjb250ZXh0KHZhbHVlOiBTY2hlbWFGaWVsZENvbnRleHQpIHtcclxuICAgICAgICB0aGlzLmludGVybmFsQ29udGV4dCA9IHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5zaG91bGRTdGFydFRvQXBwbHlBc3luY1ZhbGlkYXRvciA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGlzVmFsaWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybUZpZWxkQ29tcG9uZW50ICYmICh0aGlzLmZvcm1GaWVsZENvbXBvbmVudC5kaXNhYmxlZCB8fCB0aGlzLmZvcm1GaWVsZENvbXBvbmVudC5pc1ZhbGlkKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzaG91bGRDdXN0b21Bc3luY1ZhbGlkYXRpb25CZURpc2FibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiAhKHRoaXMuc2hvdWxkU3RhcnRUb0FwcGx5QXN5bmNWYWxpZGF0b3JcclxuICAgICAgICAgICAgJiYgdGhpcy5wYXJlbnRTY2hlbWFGaWVsZEhvc3RDb21wb25lbnQucHJvcGVydHlTY2hlbWEuY3VzdG9tQXN5bmNWYWxpZGF0aW9uXHJcbiAgICAgICAgICAgICYmIHRoaXMucGFyZW50U2NoZW1hRmllbG