UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

461 lines 62.9 kB
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