@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
369 lines • 49.1 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ElementRef, HostListener, Injector, Input, ViewChild } from '@angular/core';
import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager';
import { filter, take } from 'rxjs/operators';
import { SmeSchemaProperty } from '../../../schema/schema-decorator';
import { SimplePropertySchemaFieldLoaderComponent } from '../../../schema/schema-field-host.component';
import { SchemaPrimitiveType } from '../../../schema/schema-models';
import { SmeInternalFormFieldComponent } from '../form-field.component';
import { fromMonacoEvent, Monaco } from './monaco';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "../form-field-accessor.directive";
import * as i3 from "../form-field-validator.directive";
import * as i4 from "../form-field-async-validator.directive";
import * as i5 from "@angular/common";
import * as i6 from "../../validation-alert/validation-alert.component";
import * as i7 from "../../form-field-layout/form-field-layout.component";
const _c0 = ["editor"];
const _c1 = ["type", "code"];
function CodeFormFieldComponent_sme_validation_alert_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "sme-validation-alert", 4);
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵproperty("alert", ctx_r1.alert);
} }
/* eslint-disable max-len */
/* eslint-enable max-len */
export class CodeFormFieldLoaderComponent extends SimplePropertySchemaFieldLoaderComponent {
}
/** @nocollapse */ CodeFormFieldLoaderComponent.ɵfac = /** @pureOrBreakMyCode */ function () { let ɵCodeFormFieldLoaderComponent_BaseFactory; return function CodeFormFieldLoaderComponent_Factory(t) { return (ɵCodeFormFieldLoaderComponent_BaseFactory || (ɵCodeFormFieldLoaderComponent_BaseFactory = i0.ɵɵgetInheritedFactory(CodeFormFieldLoaderComponent)))(t || CodeFormFieldLoaderComponent); }; }();
/** @nocollapse */ CodeFormFieldLoaderComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: CodeFormFieldLoaderComponent, selectors: [["ng-component"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 12, consts: [["type", "code", 3, "ngModel", "name", "label", "language", "options", "required", "description", "readonly", "disabled", "pendingMessage", "customAsyncValidateDisabled", "customAsyncValidateDebounceTime", "ngModelChange", "customValidate", "customAsyncValidate"], ["field", ""]], template: function CodeFormFieldLoaderComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "sme-form-field", 0, 1);
i0.ɵɵlistener("ngModelChange", function CodeFormFieldLoaderComponent_Template_sme_form_field_ngModelChange_0_listener($event) { return ctx.data = $event; })("customValidate", function CodeFormFieldLoaderComponent_Template_sme_form_field_customValidate_0_listener($event) { return ctx.resolveFunction(ctx.propertySchema.customValidation)($event); })("customAsyncValidate", function CodeFormFieldLoaderComponent_Template_sme_form_field_customAsyncValidate_0_listener($event) { return ctx.propertySchema.customAsyncValidation && ctx.resolveFunction(ctx.propertySchema.customAsyncValidation.handler)($event); });
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("ngModel", ctx.data)("name", ctx.propertySchema.name)("label", ctx.localize(ctx.propertySchema.label))("language", ctx.propertySchema.options && ctx.propertySchema.options.language)("options", ctx.propertySchema.options && ctx.propertySchema.options.options)("required", ctx.propertySchema.required)("description", ctx.localize(ctx.propertySchema.description))("readonly", !!ctx.evalExpression(ctx.propertySchema.readonlyCondition))("disabled", !!(ctx.propertySchema.disabledCondition && ctx.evalExpression(ctx.propertySchema.disabledCondition)))("pendingMessage", ctx.propertySchema.customAsyncValidation && ctx.localize(ctx.propertySchema.customAsyncValidation.pendingMessage))("customAsyncValidateDisabled", ctx.shouldCustomAsyncValidationBeDisabled())("customAsyncValidateDebounceTime", ctx.propertySchema.customAsyncValidation && +ctx.propertySchema.customAsyncValidation.handler);
} }, dependencies: function () { return [i1.NgControlStatus, i1.RequiredValidator, i1.NgModel, CodeFormFieldComponent, i2.FormFieldAccessorDirective, i3.FormFieldValidatorDirective, i4.FormFieldAsyncValidatorDirective]; }, encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CodeFormFieldLoaderComponent, [{
type: Component,
args: [{
template: `
<sme-form-field #field type="code" [(ngModel)]="data" [name]="propertySchema.name" [label]="localize(propertySchema.label)"
[language]="propertySchema.options && propertySchema.options.language"
[options]="propertySchema.options && propertySchema.options.options"
[required]="propertySchema.required" [description]="localize(propertySchema.description)"
[readonly]="!!evalExpression(propertySchema.readonlyCondition)"
[disabled]="!!(propertySchema.disabledCondition && evalExpression(propertySchema.disabledCondition))"
(customValidate)="resolveFunction(propertySchema.customValidation)($event)"
(customAsyncValidate)="propertySchema.customAsyncValidation && resolveFunction(propertySchema.customAsyncValidation.handler)($event)"
[pendingMessage]="propertySchema.customAsyncValidation && localize(propertySchema.customAsyncValidation.pendingMessage)"
[customAsyncValidateDisabled]="shouldCustomAsyncValidationBeDisabled()"
[customAsyncValidateDebounceTime]="propertySchema.customAsyncValidation && +propertySchema.customAsyncValidation.handler"
></sme-form-field>
`
}]
}], null, null); })();
/**
* Accessible text field implementation
*/
let CodeFormFieldComponent = class CodeFormFieldComponent extends SmeInternalFormFieldComponent {
/**
* Initializes a new instance of the TextFormFieldComponent
*/
constructor(injector) {
super(injector);
// set initial values for field
this.language = 'plaintext';
this.editorSubscriptions = [];
// start subscriptions
this.subscriptions.push(
// begin loading monaco library
Monaco.loadMonacoEditor().pipe(take(1)).subscribe(() => {
// start monaco subscriptions
this.subscriptions.push(fromMonacoEvent(monaco.editor.onDidCreateEditor).pipe(filter(editor => editor === this.editor)).subscribe((editor) => this.onEditorCreated(editor)));
// create initial monaco editor
this.createEditor();
}));
}
/**
* The source name to use for logging
*/
get logSourceName() {
return 'CodeFormFieldComponent';
}
/**
* The current monaco editor instance
*/
get editor() {
return this.internalEditor;
}
/**
* The current monaco editor instance
*/
get model() {
return this.editor ? this.editor.getModel() : null;
}
/**
* Implementation of angular AfterViewInit interface
*/
ngAfterViewInit() {
super.ngAfterViewInit();
this.createEditor();
}
/**
* Implementation of angular OnChanges interface
*/
ngOnChanges(changes) {
super.ngOnInit();
const updateEditorOnChangesTo = ['options', 'language', 'readonly'];
if (!!this.editor && updateEditorOnChangesTo.some(prop => !!changes.prop)) {
this.createEditor();
}
}
/**
* Implementation of angular OnDestroy interface
*/
ngOnDestroy() {
super.ngOnDestroy();
this.disposeEditor();
}
/**
* Keydown handler for this form field
*/
onKeyDown(event) {
// prevent our own global handlers from affecting cursor control in monaco
const keyCodes = [
KeyCode.DownArrow,
KeyCode.UpArrow,
KeyCode.LeftArrow,
KeyCode.RightArrow,
KeyCode.Home,
KeyCode.End,
KeyCode.PageUp,
KeyCode.PageDown,
KeyCode.Tab
];
if (keyCodes.includes(event.keyCode)) {
event.stopPropagation();
}
}
/**
* Scrolls and centers to a given position within the editor
* @param position The @see monaco.IPosition to scroll to
*/
scrollTo(position) {
this.editor.revealLineInCenter(position.lineNumber);
this.editor.setPosition(position);
const scrollTop = this.editor.getTopForPosition(position.lineNumber, position.column);
this.editor.setScrollTop(scrollTop);
}
/**
* Finds a range from a starting keyword to an ending keyword.
*/
findKeyword(keyword) {
if (!this.editor || MsftSme.isNullOrWhiteSpace(keyword)) {
return null;
}
const match = this.editor.getModel().findNextMatch(keyword, { lineNumber: 0, column: 0 }, false, false, '', false);
return match ? match.range : null;
}
/**
* Finds a range from a starting keyword to an ending keyword.
*/
findKeywordRange(startKeyword, endKeyword) {
// fail to find if there is no editor, or args are invalid
if (!this.editor || MsftSme.isNullOrWhiteSpace(startKeyword) || MsftSme.isNullOrWhiteSpace(endKeyword)) {
return null;
}
// find start keyword
const model = this.editor.getModel();
const startMatch = model.findNextMatch(startKeyword, { lineNumber: 0, column: 0 }, false, false, '', false);
// fail if no start keyword
if (!startMatch) {
return null;
}
// find end keyword starting from end of start keyword
const endMatch = model.findNextMatch(endKeyword, startMatch.range.getEndPosition(), false, false, '', false);
// fail if no end keyword
if (!endMatch) {
return null;
}
// Create and return our found range
return new monaco.Range(startMatch.range.startLineNumber, startMatch.range.startColumn, endMatch.range.startLineNumber, endMatch.range.endColumn);
}
/**
* Creates the idBag used by this component to store unique element ids.
* id values will be assigned be the @see BaseComponent super class.
*/
createIdBag() {
return {
detailsSpan: ''
};
}
/**
* Applies the focus to this form control
*/
focus() {
if (this.editor) {
this.editor.focus();
}
}
/**
* When ngModel's value changes, update the editors value to reflect it
*/
onValueChanged(value) {
if (this.editor && !MsftSme.isNullOrUndefined(value)) {
this.editor.setValue(value);
}
super.onValueChanged(value);
}
/**
* On layout changed event handler, occurs every time the layout has been changed.
*/
onLayoutChanged() {
const orientation = this.calculatedOrientation;
super.onLayoutChanged();
// if orientation has not changed, then layout now, otherwise,
// layout will be done in onOrientationChanged
if (this.editor && orientation !== this.calculatedOrientation) {
this.editor.layout();
}
}
/**
* Occurs every time the orientation has been changed.
*/
onOrientationChanged() {
super.onOrientationChanged();
if (this.editor) {
this.editor.layout();
}
}
/**
* Initializes the monaco editor
*/
createEditor() {
// make sure editor host and monaco are both loaded
if (!(this.editorHost && this.editorHost.nativeElement) || !Monaco.isEditorModuleLoaded) {
return;
}
// destroy the editor if it already exists
this.disposeEditor();
// generate new construction options
const options = this.createEditorConstructionOptions();
// create the editor
this.internalEditor = monaco.editor.create(this.editorHost.nativeElement, options);
// listen for editor changes
this.editorSubscriptions.push(fromMonacoEvent(this.editor.onDidChangeModelContent).subscribe((event) => this.onEditorContentChanged(event)));
this.onLayoutChanged();
}
/**
* Creates new construction options for the editor based on the current inputs to this control
*/
createEditorConstructionOptions() {
// create merged options from inputs and custom options
return {
// default options
theme: MsftSme.self().Resources.theme === 'dark' ? 'vs-dark' : 'vs',
lineNumbers: 'off',
minimap: { enabled: false },
value: this.value,
language: this.language,
readOnly: this.readonly,
ariaLabel: this.label,
tabFocusMode: false,
// override with custom options
...this.options
};
}
/**
* Occurs when the editor is created or recreated
*/
onEditorCreated(editor) {
if (this.readonly) {
const inputAreaElement = this.editorHost.nativeElement.querySelector('.inputarea');
if (inputAreaElement) {
while (inputAreaElement.attributes.length > 0) {
inputAreaElement.removeAttribute(inputAreaElement.attributes[0].name);
}
inputAreaElement.setAttribute('aria-readonly', 'true');
}
}
}
/**
* Occurs when the editors content has changed.
* @param event the @see monaco.editor.IModelContentChangedEvent event object
*/
onEditorContentChanged(event) {
const value = this.model.getValue();
if (this.value !== value) {
this.value = value;
this.ngModel.control.updateValueAndValidity();
}
}
/**
* Occurs when the editor is being disposed
*/
disposeEditor() {
if (!this.editor) {
return;
}
this.editorSubscriptions.forEach(s => { if (!s.closed) {
s.unsubscribe();
} });
this.editorSubscriptions = [];
this.editor.dispose();
this.internalEditor = null;
}
};
/** @nocollapse */ CodeFormFieldComponent.ɵfac = function CodeFormFieldComponent_Factory(t) { return new (t || CodeFormFieldComponent)(i0.ɵɵdirectiveInject(i0.Injector)); };
/** @nocollapse */ CodeFormFieldComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: CodeFormFieldComponent, selectors: [["sme-form-field", "type", "code"]], viewQuery: function CodeFormFieldComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c0, 7);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.editorHost = _t.first);
} }, hostBindings: function CodeFormFieldComponent_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵlistener("keydown", function CodeFormFieldComponent_keydown_HostBindingHandler($event) { return ctx.onKeyDown($event); });
} }, inputs: { language: "language", options: "options" }, features: [i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature], attrs: _c1, decls: 4, vars: 2, consts: [[3, "formField"], ["sme-lint-disable", "", 1, "sme-code-editor", "sme-form-field-editor"], ["editor", ""], [3, "alert", 4, "ngIf"], [3, "alert"]], template: function CodeFormFieldComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "sme-form-field-layout", 0);
i0.ɵɵelement(1, "div", 1, 2);
i0.ɵɵtemplate(3, CodeFormFieldComponent_sme_validation_alert_3_Template, 1, 1, "sme-validation-alert", 3);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("formField", ctx);
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngIf", !ctx.compact);
} }, dependencies: [i5.NgIf, i6.ValidationAlertComponent, i7.FormFieldLayoutComponent], encapsulation: 2 });
CodeFormFieldComponent = __decorate([
SmeSchemaProperty({
type: SchemaPrimitiveType.String,
format: 'code',
description: 'A multiline code editor binding to string data.',
loaderComponent: CodeFormFieldLoaderComponent,
optionProperties: [
{
type: SchemaPrimitiveType.String,
format: 'textbox',
name: 'language',
required: true,
label: 'resources:strings:MsftSmeShell.Angular.SchemaForm.Editor.PropertyForm.CodeEditor.Language.label',
description: 'resources:strings:MsftSmeShell.Angular.SchemaForm.Editor.PropertyForm.CodeEditor.Language.description'
},
{
type: SchemaPrimitiveType.Object,
format: 'json-text-editor',
name: 'options',
defaultValue: {},
label: 'resources:strings:MsftSmeShell.Angular.SchemaForm.Editor.PropertyForm.CodeEditor.Options.label',
description: 'resources:strings:MsftSmeShell.Angular.SchemaForm.Editor.PropertyForm.CodeEditor.Options.description'
}
]
}),
__metadata("design:paramtypes", [Injector])
], CodeFormFieldComponent);
export { CodeFormFieldComponent };
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CodeFormFieldComponent, [{
type: Component,
args: [{ selector: 'sme-form-field[type="code"]', template: "<sme-form-field-layout [formField]=\"this\">\r\n <div #editor class=\"sme-code-editor sme-form-field-editor\" sme-lint-disable></div>\r\n <sme-validation-alert *ngIf=\"!compact\" [alert]=\"alert\"></sme-validation-alert>\r\n</sme-form-field-layout>\r\n" }]
}], function () { return [{ type: i0.Injector }]; }, { language: [{
type: Input
}], options: [{
type: Input
}], editorHost: [{
type: ViewChild,
args: ['editor', { static: true }]
}], onKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1mb3JtLWZpZWxkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2FuZ3VsYXIvc3JjL2NvbnRyb2xzL2Zvcm0vZm9ybS1maWVsZC9jb2RlL2NvZGUtZm9ybS1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9mb3JtL2Zvcm0tZmllbGQvY29kZS9jb2RlLWZvcm0tZmllbGQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFDWSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUErQyxTQUFTLEVBQzlILE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxRUFBcUUsQ0FBQztBQUU5RixPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSx3Q0FBd0MsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3BFLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7SUNSakQsMENBQThFOzs7SUFBdkMsb0NBQWU7O0FEVXhELDRCQUE0QjtBQWlCNUIsMkJBQTJCO0FBQzNCLE1BQU0sT0FBTyw0QkFBNkIsU0FBUSx3Q0FBd0M7O21VQUE3RSw0QkFBNEIsU0FBNUIsNEJBQTRCOzhHQUE1Qiw0QkFBNEI7UUFmckMsNENBV0s7UUFYOEIsNEpBQWtCLDRI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QUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbmplY3RvciwgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBLZXlDb2RlIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9kYXRhL2FjY2Vzc2liaWxpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBmaWx0ZXIsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IFNtZVNjaGVtYVByb3BlcnR5IH0gZnJvbSAnLi4vLi4vLi4vc2NoZW1hL3NjaGVtYS1kZWNvcmF0b3InO1xyXG5pbXBvcnQgeyBTaW1wbGVQcm9wZXJ0eVNjaGVtYUZpZWxkTG9hZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vc2NoZW1hL3NjaGVtYS1maWVsZC1ob3N0LmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFNjaGVtYVByaW1pdGl2ZVR5cGUgfSBmcm9tICcuLi8uLi8uLi9zY2hlbWEvc2NoZW1hLW1vZGVscyc7XHJcbmltcG9ydCB7IFNtZUludGVybmFsRm9ybUZpZWxkQ29tcG9uZW50IH0gZnJvbSAnLi4vZm9ybS1maWVsZC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBmcm9tTW9uYWNvRXZlbnQsIE1vbmFjbyB9IGZyb20gJy4vbW9uYWNvJztcclxuXHJcbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICB0ZW1wbGF0ZTogYFxyXG4gICAgPHNtZS1mb3JtLWZpZWxkICNmaWVsZCB0eXBlPVwiY29kZVwiIFsobmdNb2RlbCldPVwiZGF0YVwiIFtuYW1lXT1cInByb3BlcnR5U2NoZW1hLm5hbWVcIiBbbGFiZWxdPVwibG9jYWxpemUocHJvcGVydHlTY2hlbWEubGFiZWwpXCJcclxuICAgICAgICBbbGFuZ3VhZ2VdPVwicHJvcGVydHlTY2hlbWEub3B0aW9ucyAmJiBwcm9wZXJ0eVNjaGVtYS5vcHRpb25zLmxhbmd1YWdlXCJcclxuICAgICAgICBbb3B0aW9uc109XCJwcm9wZXJ0eVNjaGVtYS5vcHRpb25zICYmIHByb3BlcnR5U2NoZW1hLm9wdGlvbnMub3B0aW9uc1wiXHJcbiAgICAgICAgW3JlcXVpcmVkXT1cInByb3BlcnR5U2NoZW1hLnJlcXVpcmVkXCIgW2Rlc2NyaXB0aW9uXT1cImxvY2FsaXplKHByb3BlcnR5U2NoZW1hLmRlc2NyaXB0aW9uKVwiXHJcbiAgICAgICAgW3JlYWRvbmx5XT1cIiEhZXZhbEV4cHJlc3Npb24ocHJvcGVydHlTY2hlbWEucmVhZG9ubHlDb25kaXRpb24pXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiISEocHJvcGVydHlTY2hlbWEuZGlzYWJsZWRDb25kaXRpb24gJiYgZXZhbEV4cHJlc3Npb24ocHJvcGVydHlTY2hlbWEuZGlzYWJsZWRDb25kaXRpb24pKVwiXHJcbiAgICAgICAgKGN1c3RvbVZhbGlkYXRlKT1cInJlc29sdmVGdW5jdGlvbihwcm9wZXJ0eVNjaGVtYS5jdXN0b21WYWxpZGF0aW9uKSgkZXZlbnQpXCJcclxuICAgICAgICAoY3VzdG9tQXN5bmNWYWxpZGF0ZSk9XCJwcm9wZXJ0eVNjaGVtYS5jdXN0b21Bc3luY1ZhbGlkYXRpb24gJiYgcmVzb2x2ZUZ1bmN0aW9uKHByb3BlcnR5U2NoZW1hLmN1c3RvbUFzeW5jVmFsaWRhdGlvbi5oYW5kbGVyKSgkZXZlbnQpXCJcclxuICAgICAgICBbcGVuZGluZ01lc3NhZ2VdPVwicHJvcGVydHlTY2hlbWEuY3VzdG9tQXN5bmNWYWxpZGF0aW9uICYmIGxvY2FsaXplKHByb3BlcnR5U2NoZW1hLmN1c3RvbUFzeW5jVmFsaWRhdGlvbi5wZW5kaW5nTWVzc2FnZSlcIlxyXG4gICAgICAgIFtjdXN0b21Bc3luY1ZhbGlkYXRlRGlzYWJsZWRdPVwic2hvdWxkQ3VzdG9tQXN5bmNWYWxpZGF0aW9uQmVEaXNhYmxlZCgpXCJcclxuICAgICAgICBbY3VzdG9tQXN5bmNWYWxpZGF0ZURlYm91bmNlVGltZV09XCJwcm9wZXJ0eVNjaGVtYS5jdXN0b21Bc3luY1ZhbGlkYXRpb24gJiYgK3Byb3BlcnR5U2NoZW1hLmN1c3RvbUFzeW5jVmFsaWRhdGlvbi5oYW5kbGVyXCJcclxuICAgICAgICA+PC9zbWUtZm9ybS1maWVsZD5cclxuICAgIGBcclxufSlcclxuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXHJcbmV4cG9ydCBjbGFzcyBDb2RlRm9ybUZpZWxkTG9hZGVyQ29tcG9uZW50IGV4dGVuZHMgU2ltcGxlUHJvcGVydHlTY2hlbWFGaWVsZExvYWRlckNvbXBvbmVudCB7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBY2Nlc3NpYmxlIHRleHQgZmllbGQgaW1wbGVtZW50YXRpb25cclxuICovXHJcbkBTbWVTY2hlbWFQcm9wZXJ0eSh7XHJcbiAgICB0eXBlOiBTY2hlbWFQcmltaXRpdmVUeXBlLlN0cmluZyxcclxuICAgIGZvcm1hdDogJ2NvZGUnLFxyXG4gICAgZGVzY3JpcHRpb246ICdBIG11bHRpbGluZSBjb2RlIGVkaXRvciBiaW5kaW5nIHRvIHN0cmluZyBkYXRhLicsXHJcbiAgICBsb2FkZXJDb21wb25lbnQ6IENvZGVGb3JtRmllbGRMb2FkZXJDb21wb25lbnQsXHJcbiAgICBvcHRpb25Qcm9wZXJ0aWVzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0eXBlOiBTY2hlbWFQcmltaXRpdmVUeXBlLlN0cmluZyxcclxuICAgICAgICAgICAgZm9ybWF0OiAndGV4dGJveCcsXHJcbiAgICAgICAgICAgIG5hbWU6ICdsYW5ndWFnZScsXHJcbiAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxyXG4gICAgICAgICAgICBsYWJlbDogJ3Jlc291cmNlczpzdHJpbmdzOk1zZnRTbWVTaGVsbC5Bbmd1bGFyLlNjaGVtYUZvcm0uRWRpdG9yLlByb3BlcnR5Rm9ybS5Db2RlRWRpdG9yLkxhbmd1YWdlLmxhYmVsJyxcclxuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdyZXNvdXJjZXM6c3RyaW5nczpNc2Z0U21lU2hlbGwuQW5ndWxhci5TY2hlbWFGb3JtLkVkaXRvci5Qcm9wZXJ0eUZvcm0uQ29kZUVkaXRvci5MYW5ndWFnZS5kZXNjcmlwdGlvbidcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgICAgdHlwZTogU2NoZW1hUHJpbWl0aXZlVHlwZS5PYmplY3QsXHJcbiAgICAgICAgICAgIGZvcm1hdDogJ2pzb24tdGV4dC1lZGl0b3InLFxyXG4gICAgICAgICAgICBuYW1lOiAnb3B0aW9ucycsXHJcbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZToge30sXHJcbiAgICAgICAgICAgIGxhYmVsOiAncmVzb3VyY2VzOnN0cmluZ3M6TXNmdFNtZVNoZWxsLkFuZ3VsYXIuU2NoZW1hRm9ybS5FZGl0b3IuUHJvcGVydHlGb3JtLkNvZGVFZGl0b3IuT3B0aW9ucy5sYWJlbCcsXHJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAncmVzb3VyY2VzOnN0cmluZ3M6TXNmdFNtZVNoZWxsLkFuZ3VsYXIuU2NoZW1hRm9ybS5FZGl0b3IuUHJvcGVydHlGb3JtLkNvZGVFZGl0b3IuT3B0aW9ucy5kZXNjcmlwdGlvbidcclxuICAgICAgICB9XHJcbiAgICBdXHJcbn0pXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdzbWUtZm9ybS1maWVsZFt0eXBlPVwiY29kZVwiXScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vY29kZS1mb3JtLWZpZWxkLmNvbXBvbmVudC5odG1sJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQ29kZUZvcm1GaWVsZENvbXBvbmVudCBleHRlbmRzIFNtZUludGVybmFsRm9ybUZpZWxkQ29tcG9uZW50PHN0cmluZz4gaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBzb3VyY2UgbmFtZSB0byB1c2UgZm9yIGxvZ2dpbmdcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIGdldCBsb2dTb3VyY2VOYW1lKCkge1xyXG4gICAgICAgIHJldHVybiAnQ29kZUZvcm1GaWVsZENvbXBvbmVudCc7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbGFuZ3VhZ2Ugb2YgdGhlIGNvZGUgaW4gdGhlIGVkaXRvclxyXG4gICAgICovXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGxhbmd1YWdlOiBzdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgbW9uYWNvIGVkaXRvciBjb25zdHJ1Y3Rpb24gb3B0aW9ucy4gV2hlbiBwcm92aWRlZCwgb3ZlcnJpZGVzIHRoZSBkZWZhdWx0IGJlaGF2aW9ycyBvZiB0aGlzIGNvbnRyb2xcclxuICAgICAqL1xyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBvcHRpb25zOiBtb25hY28uZWRpdG9yLklTdGFuZGFsb25lRWRpdG9yQ29uc3RydWN0aW9uT3B0aW9ucztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRoZSBjdXJyZW50IG1vbmFjbyBlZGl0b3IgaW5zdGFuY2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldCBlZGl0b3IoKTogbW9uYWNvLmVkaXRvci5JU3RhbmRhbG9uZUNvZGVFZGl0b3Ige1xyXG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsRWRpdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGN1cnJlbnQgbW9uYWNvIGVkaXRvciBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZ2V0IG1vZGVsKCk6IG1vbmFjby5lZGl0b3IuSVRleHRNb2RlbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWRpdG9yID8gdGhpcy5lZGl0b3IuZ2V0TW9kZWwoKSA6IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgdGhhdCB3ZSB1c2UgdG8gY29udGFpbiB0aGUgbW9uYWNvIHRleHQgZWRpdG9yXHJcbiAgICAgKi9cclxuICAgIEBWaWV3Q2hpbGQoJ2VkaXRvcicsIHsgc3RhdGljOiB0cnVlIH0pXHJcbiAgICBwcml2YXRlIGVkaXRvckhvc3Q6IEVsZW1lbnRSZWY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBpbnRlcm5hbCBwbGFjZWhvbGRlciBmb3IgdGhlIGN1cnJlbnQgbW9uYWNvIGVkaXRvciBpbnN0YW5jZS5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpbnRlcm5hbEVkaXRvcjogbW9uYWNvLmVkaXRvci5JU3RhbmRhbG9uZUNvZGVFZGl0b3I7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFja2luZyBtZWNoYW5pc20gZm9yIHN1YnNjcmlwdGlvbnMgZm9yIHRoZSBjdXJyZW50IGVkaXRvciBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGVkaXRvclN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIFRleHRGb3JtRmllbGRDb21wb25lbnRcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgaW5qZWN0b3I6IEluamVjdG9yXHJcbiAgICApIHtcclxuICAgICAgICBzdXBlcihpbmplY3Rvcik7XHJcbiAgICAgICAgLy8gc2V0IGluaXRpYWwgdmFsdWVzIGZvciBmaWVsZFxyXG4gICAgICAgIHRoaXMubGFuZ3VhZ2UgPSAncGxhaW50ZXh0JztcclxuICAgICAgICB0aGlzLmVkaXRvclN1YnNjcmlwdGlvbnMgPSBbXTtcclxuICAgICAgICAvLyBzdGFydCBzdWJzY3JpcHRpb25zXHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXHJcbiAgICAgICAgICAgIC8vIGJlZ2luIGxvYWRpbmcgbW9uYWNvIGxpYnJhcnlcclxuICAgICAgICAgICAgTW9uYWNvLmxvYWRNb25hY29FZGl0b3IoKS5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBzdGFydCBtb25hY28gc3Vic2NyaXB0aW9uc1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgZnJvbU1vbmFjb0V2ZW50KG1vbmFjby5lZGl0b3Iub25EaWRDcmVhdGVFZGl0b3IpLnBpcGUoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihlZGl0b3IgPT4gZWRpdG9yID09PSB0aGlzLmVkaXRvcilcclxuICAgICAgICAgICAgICAgICAgICApLnN1YnNjcmliZSgoZWRpdG9yKSA9PiB0aGlzLm9uRWRpdG9yQ3JlYXRlZChlZGl0b3IpKVxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSBpbml0aWFsIG1vbmFjbyBlZGl0b3JcclxuICAgICAgICAgICAgICAgIHRoaXMuY3JlYXRlRWRpdG9yKCk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEltcGxlbWVudGF0aW9uIG9mIGFuZ3VsYXIgQWZ0ZXJWaWV3SW5pdCBpbnRlcmZhY2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICBzdXBlci5uZ0FmdGVyVmlld0luaXQoKTtcclxuICAgICAgICB0aGlzLmNyZWF0ZUVkaXRvcigpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW1wbGVtZW50YXRpb24gb2YgYW5ndWxhciBPbkNoYW5nZXMgaW50ZXJmYWNlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICAgICAgc3VwZXIubmdPbkluaXQoKTtcclxuICAgICAgICBjb25zdCB1cGRhdGVFZGl0b3JPbkNoYW5nZXNUbyA9IFsnb3B0aW9ucycsICdsYW5ndWFnZScsICdyZWFkb25seSddO1xyXG4gICAgICAgIGlmICghIXRoaXMuZWRpdG9yICYmIHVwZGF0ZUVkaXRvck9uQ2hhbmdlc1RvLnNvbWUocHJvcCA9PiAhIWNoYW5nZXMucHJvcCkpIHtcclxuICAgICAgICAgICAgdGhpcy5jcmVhdGVFZGl0b3IoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBsZW1lbnRhdGlvbiBvZiBhbmd1bGFyIE9uRGVzdHJveSBpbnRlcmZhY2VcclxuICAgICAqL1xyXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xyXG4gICAgICAgIHN1cGVyLm5nT25EZXN0cm95KCk7XHJcbiAgICAgICAgdGhpcy5kaXNwb3NlRWRpdG9yKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBLZXlkb3duIGhhbmRsZXIgZm9yIHRoaXMgZm9ybSBmaWVsZFxyXG4gICAgICovXHJcbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcclxuICAgIHB1YmxpYyBvbktleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICAvLyBwcmV2ZW50IG91ciBvd24gZ2xvYmFsIGhhbmRsZXJzIGZyb20gYWZmZWN0aW5nIGN1cnNvciBjb250cm9sIGluIG1vbmFjb1xyXG4gICAgICAgIGNvbnN0IGtleUNvZGVzID0gW1xyXG4gICAgICAgICAgICBLZXlDb2RlLkRvd25BcnJvdyxcclxuICAgICAgICAgICAgS2V5Q29kZS5VcEFycm93LFxyXG4gICAgICAgICAgICBLZXlDb2RlLkxlZnRBcnJvdyxcclxuICAgICAgICAgICAgS2V5Q29kZS5SaWdodEFycm93LFxyXG4gICAgICAgICAgICBLZXlDb2RlLkhvbWUsXHJcbiAgICAgICAgICAgIEtleUNvZGUuRW5kLFxyXG4gICAgICAgICAgICBLZXlDb2RlLlBhZ2VVcCxcclxuICAgICAgICAgICAgS2V5Q29kZS5QYWdlRG93bixcclxuICAgICAgICAgICAgS2V5Q29kZS5UYWJcclxuICAgICAgICBdO1xyXG4gICAgICAgIGlmIChrZXlDb2Rlcy5pbmNsdWRlcyhldmVudC5rZXlDb2RlKSkge1xyXG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTY3JvbGxzIGFuZCBjZW50ZXJzIHRvIGEgZ2l2ZW4gcG9zaXRpb24gd2l0aGluIHRoZSBlZGl0b3JcclxuICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgQHNlZSBtb25hY28uSVBvc2l0aW9uIHRvIHNjcm9sbCB0b1xyXG4gICAgICovXHJcbiAgICBwdWJsaWMgc2Nyb2xsVG8ocG9zaXRpb246IG1vbmFjby5JUG9zaXRpb24pIHtcclxuICAgICAgICB0aGlzLmVkaXRvci5yZXZlYWxMaW5lSW5DZW50ZXIocG9zaXRpb24ubGluZU51bWJlcik7XHJcbiAgICAgICAgdGhpcy5lZGl0b3Iuc2V0UG9zaXRpb24ocG9zaXRpb24pO1xyXG4gICAgICAgIGNvbnN0IHNjcm9sbFRvcCA9IHRoaXMuZWRpdG9yLmdldFRvcEZvclBvc2l0aW9uKHBvc2l0aW9uLmxpbmVOdW1iZXIsIHBvc2l0aW9uLmNvbHVtbik7XHJcbiAgICAgICAgdGhpcy5lZGl0b3Iuc2V0U2Nyb2xsVG9wKHNjcm9sbFRvcCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kcyBhIHJhbmdlIGZyb20gYSBzdGFydGluZyBrZXl3b3JkIHRvIGFuIGVuZGluZyBrZXl3b3JkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZmluZEtleXdvcmQoa2V5d29yZDogc3RyaW5nKTogbW9uYWNvLlJhbmdlIHtcclxuICAgICAgICBpZiAoIXRoaXMuZWRpdG9yIHx8IE1zZnRTbWUuaXNOdWxsT3JXaGl0ZVNwYWNlKGtleXdvcmQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCBtYXRjaCA9IHRoaXMuZWRpdG9yLmdldE1vZGVsKCkuZmluZE5leHRNYXRjaChrZXl3b3JkLCB7IGxpbmVOdW1iZXI6IDAsIGNvbHVtbjogMCB9LCBmYWxzZSwgZmFsc2UsICcnLCBmYWxzZSk7XHJcbiAgICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2gucmFuZ2UgOiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmluZHMgYSByYW5nZSBmcm9tIGEgc3RhcnRpbmcga2V5d29yZCB0byBhbiBlbmRpbmcga2V5d29yZC5cclxuICAgICAqL1xyXG4gICAgcHVibGljIGZpbmRLZXl3b3JkUmFuZ2Uoc3RhcnRLZXl3b3JkOiBzdHJpbmcsIGVuZEtleXdvcmQ6IHN0cmluZyk6IG1vbmFjby5SYW5nZSB7XHJcbiAgICAgICAgLy8gZmFpbCB0byBmaW5kIGlmIHRoZXJlIGlzIG5vIGVkaXRvciwgb3IgYXJncyBhcmUgaW52YWxpZFxyXG4gICAgICAgIGlmICghdGhpcy5lZGl0b3IgfHwgTXNmdFNtZS5pc051bGxPcldoaXRlU3BhY2Uoc3RhcnRLZXl3b3JkKSB8fCBNc2Z0U21lLmlzTnVsbE9yV2hpdGVTcGFjZShlbmRLZXl3b3JkKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZmluZCBzdGFydCBrZXl3b3JkXHJcbiAgICAgICAgY29uc3QgbW9kZWwgPSB0aGlzLmVkaXRvci5nZXRNb2RlbCgpO1xyXG4gICAgICAgIGNvbnN0IHN0YXJ0TWF0Y2ggPSBtb2RlbC5maW5kTmV4dE1hdGNoKHN0YXJ0S2V5d29yZCwgeyBsaW5lTnVtYmVyOiAwLCBjb2x1bW46IDAgfSwgZmFsc2UsIGZhbHNlLCAnJywgZmFsc2UpO1xyXG4gICAgICAgIC8vIGZhaWwgaWYgbm8gc3RhcnQga2V5d29yZFxyXG4gICAgICAgIGlmICghc3RhcnRNYXRjaCkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICAgIC8vIGZpbmQgZW5kIGtleXdvcmQgc3RhcnRpbmcgZnJvbSBlbmQgb2Ygc3RhcnQga2V5d29yZFxyXG4gICAgICAgIGNvbnN0IGVuZE1hdGNoID0gbW9kZWwuZmluZE5leHRNYXRjaChlbmRLZXl3b3JkLCBzdGFydE1hdGNoLnJhbmdlLmdldEVuZFBvc2l0aW9uKCksIGZhbHNlLCBmYWxzZSwgJycsIGZhbHNlKTtcclxuICAgICAgICAvLyBmYWlsIGlmIG5vIGVuZCBrZXl3b3JkXHJcbiAgICAgICAgaWYgKCFlbmRNYXRjaCkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIG91ciBmb3VuZCByYW5nZVxyXG4gICAgICAgIHJldHVybiBuZXcgbW9uYWNvLlJhbmdlKFxyXG4gICAgICAgICAgICBzdGFydE1hdGNoLnJhbmdlLnN0YXJ0TGluZU51bWJlcixcclxuICAgICAgICAgICAgc3RhcnRNYXRjaC5yYW5nZS5zdGFydENvbHVtbixcclxuICAgICAgICAgICAgZW5kTWF0Y2gucmFuZ2Uuc3RhcnRMaW5lTnVtYmVyLFxyXG4gICAgICAgICAgICBlbmRNYXRjaC5yYW5nZS5lbmRDb2x1bW5cclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyB0aGUgaWRCYWcgdXNlZCBieSB0aGlzIGNvbXBvbmVudCB0byBzdG9yZSB1bmlxdWUgZWxlbWVudCBpZHMuXHJcbiAgICAgKiBpZCB2YWx1ZXMgd2lsbCBiZSBhc3NpZ25lZCBiZSB0aGUgQHNlZSBCYXNlQ29tcG9uZW50IHN1cGVyIGNsYXNzLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgY3JlYXRlSWRCYWcoKTogTXNmdFNtZS5TdHJpbmdNYXA8c3RyaW5nPiB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZGV0YWlsc1NwYW46ICcnXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpZXMgdGhlIGZvY3VzIHRvIHRoaXMgZm9ybSBjb250cm9sXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBmb2N1cygpIHtcclxuICAgICAgICBpZiAodGhpcy5lZGl0b3IpIHtcclxuICAgICAgICAgICAgdGhpcy5lZGl0b3IuZm9jdXMoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXaGVuIG5nTW9kZWwncyB2YWx1ZSBjaGFuZ2VzLCB1cGRhdGUgdGhlIGVkaXRvcnMgdmFsdWUgdG8gcmVmbGVjdCBpdFxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgb25WYWx1ZUNoYW5nZWQodmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIGlmICh0aGlzLmVkaXRvciAmJiAhTXNmdFNtZS5pc051bGxPclVuZGVmaW5lZCh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5lZGl0b3Iuc2V0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3VwZXIub25WYWx1ZUNoYW5nZWQodmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT24gbGF5b3V0IGNoYW5nZWQgZXZlbnQgaGFuZGxlciwgb2NjdXJzIGV2ZXJ5IHRpbWUgdGhlIGxheW91dCBoYXMgYmVlbiBjaGFuZ2VkLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgb25MYXlvdXRDaGFuZ2VkKCkge1xyXG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gdGhpcy5jYWxjdWxhdGVkT3JpZW50YXRpb247XHJcbiAgICAgICAgc3VwZXIub25MYXlvdXRDaGFuZ2VkKCk7XHJcbiAgICAgICAgLy8gaWYgb3JpZW50YXRpb24gaGFzIG5vdCBjaGFuZ2VkLCB0aGVuIGxheW91dCBub3csIG90aGVyd2lzZSxcclxuICAgICAgICAvLyBsYXlvdXQgd2lsbCBiZSBkb25lIGluIG9uT3JpZW50YXRpb25DaGFuZ2VkXHJcbiAgICAgICAgaWYgKHRoaXMuZWRpdG9yICYmIG9yaWVudGF0aW9uICE9PSB0aGlzLmNhbGN1bGF0ZWRPcmllbnRhdGlvbikge1xyXG4gICAgICAgICAgICB0aGlzLmVkaXRvci5sYXlvdXQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAqIE9jY3VycyBldmVyeSB0aW1lIHRoZSBvcmllbnRhdGlvbiBoYXMgYmVlbiBjaGFuZ2VkLlxyXG4gICAgKi9cclxuICAgIHByb3RlY3RlZCBvbk9yaWVudGF0aW9uQ2hhbmdlZCgpIHtcclxuICAgICAgICBzdXBlci5vbk9yaWVudGF0aW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgIGlmICh0aGlzLmVkaXRvcikge1xyXG4gICAgICAgICAgICB0aGlzLmVkaXRvci5sYXlvdXQoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgbW9uYWNvIGVkaXRvclxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNyZWF0ZUVkaXRvcigpIHtcclxuICAgICAgICAvLyBtYWtlIHN1cmUgZWRpdG9yIGhvc3QgYW5kIG1vbmFjbyBhcmUgYm90aCBsb2FkZWRcclxuICAgICAgICBpZiAoISh0aGlzLmVkaXRvckhvc3QgJiYgdGhpcy5lZGl0b3JIb3N0Lm5hdGl2ZUVsZW1lbnQpIHx8ICFNb25hY28uaXNFZGl0b3JNb2R1bGVMb2FkZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gZGVzdHJveSB0aGUgZWRpdG9yIGlmIGl0IGFscmVhZHkgZXhpc3RzXHJcbiAgICAgICAgdGhpcy5kaXNwb3NlRWRpdG9yKCk7XHJcblxyXG4gICAgICAgIC8vIGdlbmVyYXRlIG5ldyBjb25zdHJ1Y3Rpb24gb3B0aW9uc1xyXG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmNyZWF0ZUVkaXRvckNvbnN0cnVjdGlvbk9wdGlvbnMoKTtcclxuXHJcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBlZGl0b3JcclxuICAgICAgICB0aGlzLmludGVybmFsRWRpdG9yID0gbW9uYWNvLmVkaXRvci5jcmVhdGUodGhpcy5lZGl0b3JIb3N0Lm5hdGl2ZUVsZW1lbnQsIG9wdGlvbnMpO1xyXG5cclxuICAgICAgICAvLyBsaXN0ZW4gZm9yIGVkaXRvciBjaGFuZ2VzXHJcbiAgICAgICAgdGhpcy5lZGl0b3JTdWJzY3JpcHRpb25zLnB1c2goXHJcbiAgICAgICAgICAgIGZyb21Nb25hY29FdmVudCh0aGlzLmVkaXRvci5vbkRpZENoYW5nZU1vZGVsQ29udGVudCkuc3Vic2NyaWJlKChldmVudCkgPT4gdGhpcy5vbkVkaXRvckNvbnRlbnRDaGFuZ2VkKGV2ZW50KSlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICB0aGlzLm9uTGF5b3V0Q2hhbmdlZCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBuZXcgY29uc3RydWN0aW9uIG9wdGlvbnMgZm9yIHRoZSBlZGl0b3IgYmFzZWQgb24gdGhlIGN1cnJlbnQgaW5wdXRzIHRvIHRoaXMgY29udHJvbFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGNyZWF0ZUVkaXRvckNvbnN0cnVjdGlvbk9wdGlvbnMoKTogbW9uYWNvLmVkaXRvci5JU3RhbmRhbG9uZUVkaXRvckNvbnN0cnVjdGlvbk9wdGlvbnMge1xyXG4gICAgICAgIC8vIGNyZWF0ZSBtZXJnZWQgb3B0aW9ucyBmcm9tIGlucHV0cyBhbmQgY3VzdG9tIG9wdGlvbnNcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAvLyBkZWZhdWx0IG9wdGlvbnNcclxuICAgICAgICAgICAgdGhlbWU6IE1zZnRTbWUuc2VsZigpLlJlc291cmNlcy50aGVtZSA9PT0gJ2RhcmsnID8gJ3ZzLWRhcmsnIDogJ3ZzJyxcclxuICAgICAgICAgICAgbGluZU51bWJlcnM6ICdvZmYnLFxyXG4gICAgICAgICAgICBtaW5pbWFwOiB7IGVuYWJsZWQ6IGZhbHNlIH0sXHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnZhbHVlLFxyXG4gICAgICAgICAgICBsYW5ndWFnZTogdGhpcy5sYW5ndWFnZSxcclxuICAgICAgICAgICAgcmVhZE9ubHk6IHRoaXMucmVhZG9ubHksXHJcbiAgICAgICAgICAgIGFyaWFMYWJlbDogdGhpcy5sYWJlbCxcclxuICAgICAgICAgICAgdGFiRm9jdXNNb2RlOiBmYWxzZSxcclxuICAgICAgICAgICAgLy8gb3ZlcnJpZGUgd2l0aCBjdXN0b20gb3B0aW9uc1xyXG4gICAgICAgICAgICAuLi50aGlzLm9wdGlvbnNcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogT2NjdXJzIHdoZW4gdGhlIGVkaXRvciBpcyBjcmVhdGVkIG9yIHJlY3JlYXRlZFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIG9uRWRpdG9yQ3JlYXRlZChlZGl0b3I6IG1vbmFjby5lZGl0b3IuSUNvZGVFZGl0b3IpIHtcclxuICAgICAgICBpZiAodGhpcy5yZWFkb25seSkge1xyXG4gICAgICAgICAgICBjb25zdCBpbnB1dEFyZWFFbGVtZW50ID0gPEhUTUxFbGVtZW50PnRoaXMuZWRpdG9ySG9zdC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5pbnB1dGFyZWEnKTtcclxuICAgICAgICAgICAgaWYgKGlucHV0QXJlYUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChpbnB1dEFyZWFFbGVtZW50LmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlucHV0QXJlYUVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGlucHV0QXJlYUVsZW1lbnQuYXR0cmlidXRlc1swXS5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlucHV0QXJlYUVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLXJlYWRvbmx5JywgJ3RydWUnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE9jY3VycyB3aGVuIHRoZSBlZGl0b3JzIGNvbnRlbnQgaGFzIGNoYW5nZWQuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnQgdGhlIEBzZWUgbW9uYWNvLmVkaXRvci5JTW9kZWxDb250ZW50Q2hhbmdlZEV2ZW50IGV2ZW50IG9iamVjdFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIG9uRWRpdG9yQ29udGVudENoYW5nZWQoZXZlbnQ6IG1vbmFjby5lZGl0b3IuSU1vZGVsQ29udGVudENoYW5nZWRFdmVudCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5tb2RlbC5nZXRWYWx1ZSgpO1xyXG4gICAgICAgIGlmICh0aGlzLnZhbHVlICE9PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMubmdNb2RlbC5jb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPY2N1cnMgd2hlbiB0aGUgZWRpdG9yIGlzIGJlaW5nIGRpc3Bvc2VkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZGlzcG9zZUVkaXRvcigpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZWRpdG9yKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5lZGl0b3JTdWJzY3JpcHRpb25zLmZvckVhY2gocyA9PiB7IGlmICghcy5jbG9zZWQpIHsgcy51bnN1YnNjcmliZSgpOyB9IH0pO1xyXG4gICAgICAgIHRoaXMuZWRpdG9yU3Vic2NyaXB0aW9ucyA9IFtdO1xyXG4gICAgICAgIHRoaXMuZWRpdG9yLmRpc3Bvc2UoKTtcclxuICAgICAgICB0aGlzLmludGVybmFsRWRpdG9yID0gbnVsbDtcclxuICAgIH1cclxufVxyXG4iLCI8c21lLWZvcm0tZmllbGQtbGF5b3V0IFtmb3JtRmllbGRdPVwidGhpc1wiPlxyXG4gIDxkaXYgI2VkaXRvciBjbGFzcz1cInNtZS1jb2RlLWVkaXRvciBzbWUtZm9ybS1maWVsZC1lZGl0b3JcIiBzbWUtbGludC1kaXNhYmxlPjwvZGl2PlxyXG4gIDxzbWUtdmFsaWRhdGlvbi1hbGVydCAqbmdJZj1cIiFjb21wYWN0XCIgW2FsZXJ0XT1cImFsZXJ0XCI+PC9zbWUtdmFsaWRhdGlvbi1hbGVydD5cclxuPC9zbWUtZm9ybS1maWVsZC1sYXlvdXQ+XHJcbiJdfQ==