@ngstack/code-editor
Version:
Code editor component for Angular applications.
221 lines • 25.8 kB
JavaScript
import { Component, ChangeDetectionStrategy, ViewEncapsulation, ViewChild, Input, Output, EventEmitter, HostListener, inject } from '@angular/core';
import { CodeEditorService } from '../services/code-editor.service';
import { TypescriptDefaultsService } from '../services/typescript-defaults.service';
import { JavascriptDefaultsService } from '../services/javascript-defaults.service';
import { JsonDefaultsService } from '../services/json-defaults.service';
import * as i0 from "@angular/core";
export class CodeEditorComponent {
constructor() {
// private _value = '';
this.defaultOptions = {
lineNumbers: 'on',
contextmenu: false,
minimap: {
enabled: false
}
};
// @Input()
// set value(v: string) {
// if (v !== this._value) {
// this._value = v;
// this.setEditorValue(v);
// this.valueChanged.emit(v);
// }
// }
// get value(): string {
// return this._value;
// }
/**
* Editor theme. Defaults to `vs`.
*
* Allowed values: `vs`, `vs-dark` or `hc-black`.
* @memberof CodeEditorComponent
*/
this.theme = 'vs';
/**
* Editor options.
*
* See https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html for more details.
*
* @memberof CodeEditorComponent
*/
this.options = {};
/**
* Toggle readonly state of the editor.
*
* @memberof CodeEditorComponent
*/
this.readOnly = false;
/**
* An event emitted when the text content of the model have changed.
*/
this.valueChanged = new EventEmitter();
/**
* An event emitted when the code model value is changed.
*/
this.codeModelChanged = new EventEmitter();
/**
* An event emitted when the contents of the underlying editor model have changed.
*/
this.modelContentChanged = new EventEmitter();
/**
* Raised when editor finished loading all its components.
*/
this.loaded = new EventEmitter();
this.editorService = inject(CodeEditorService);
this.typescriptDefaults = inject(TypescriptDefaultsService);
this.javascriptDefaults = inject(JavascriptDefaultsService);
this.jsonDefaults = inject(JsonDefaultsService);
}
/**
* The instance of the editor.
*/
get editor() {
return this._editor;
}
set editor(value) {
this._editor = value;
}
ngOnDestroy() {
if (this.editor) {
this.editor.dispose();
this.editor = null;
}
if (this._model) {
this._model.dispose();
this._model = null;
}
}
ngOnChanges(changes) {
const codeModel = changes['codeModel'];
const readOnly = changes['readOnly'];
const theme = changes['theme'];
if (codeModel && !codeModel.firstChange) {
this.updateModel(codeModel.currentValue);
}
if (readOnly && !readOnly.firstChange) {
if (this.editor) {
this.editor.updateOptions({
readOnly: readOnly.currentValue
});
}
}
if (theme && !theme.firstChange) {
this.editorService.setTheme(theme.currentValue);
}
}
onResize() {
if (this.editor) {
this.editor.layout();
}
}
async ngAfterViewInit() {
this.setupEditor();
this.loaded.emit(this);
}
setupEditor() {
const domElement = this.editorContent.nativeElement;
const settings = {
value: '',
language: 'text',
uri: `code-${Date.now()}`,
...this.codeModel
};
this._model = this.editorService.createModel(settings.value, settings.language, settings.uri);
const options = Object.assign({}, this.defaultOptions, this.options, {
readOnly: this.readOnly,
theme: this.theme,
model: this._model
});
this.editor = this.editorService.createEditor(domElement, options);
this._model.onDidChangeContent((e) => {
this.modelContentChanged.emit(e);
const newValue = this._model.getValue();
if (this.codeModel) {
this.codeModel.value = newValue;
}
this.valueChanged.emit(newValue);
});
this.setupDependencies(this.codeModel);
this.codeModelChanged.emit({ sender: this, value: this.codeModel });
}
runEditorAction(id, args) {
this.editor.getAction(id)?.run(args);
}
formatDocument() {
this.runEditorAction('editor.action.formatDocument');
}
setupDependencies(model) {
if (!model) {
return;
}
const { language } = model;
if (language) {
const lang = language.toLowerCase();
switch (lang) {
case 'typescript':
if (model.dependencies) {
this.editorService.loadTypings(model.dependencies);
}
break;
case 'javascript':
if (model.dependencies) {
this.editorService.loadTypings(model.dependencies);
}
break;
case 'json':
if (model.schemas) {
this.jsonDefaults.addSchemas(model.uri, model.schemas);
}
break;
default:
break;
}
}
}
setEditorValue(value) {
// Fix for value change while dispose in process.
setTimeout(() => {
if (this._model) {
this._model.setValue(value);
}
});
}
updateModel(model) {
if (model) {
this.setEditorValue(model.value);
this.editorService.setModelLanguage(this._model, model.language);
this.setupDependencies(model);
this.codeModelChanged.emit({ sender: this, value: model });
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: CodeEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.10", type: CodeEditorComponent, isStandalone: true, selector: "ngs-code-editor", inputs: { codeModel: "codeModel", theme: "theme", options: "options", readOnly: "readOnly" }, outputs: { valueChanged: "valueChanged", codeModelChanged: "codeModelChanged", modelContentChanged: "modelContentChanged", loaded: "loaded" }, host: { listeners: { "window:resize": "onResize()" }, classAttribute: "ngs-code-editor" }, viewQueries: [{ propertyName: "editorContent", first: true, predicate: ["editor"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div id=\"editor\" #editor class=\"monaco-editor editor\"></div>\n", styles: [".editor{width:100%;height:inherit;min-height:200px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: CodeEditorComponent, decorators: [{
type: Component,
args: [{ selector: 'ngs-code-editor', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'ngs-code-editor' }, template: "<div id=\"editor\" #editor class=\"monaco-editor editor\"></div>\n", styles: [".editor{width:100%;height:inherit;min-height:200px}\n"] }]
}], propDecorators: { editorContent: [{
type: ViewChild,
args: ['editor', { static: true }]
}], codeModel: [{
type: Input
}], theme: [{
type: Input
}], options: [{
type: Input
}], readOnly: [{
type: Input
}], valueChanged: [{
type: Output
}], codeModelChanged: [{
type: Output
}], modelContentChanged: [{
type: Output
}], loaded: [{
type: Output
}], onResize: [{
type: HostListener,
args: ['window:resize']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29kZS1lZGl0b3Ivc3JjL2xpYi9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb2RlLWVkaXRvci9zcmMvbGliL2NvZGUtZWRpdG9yL2NvZGUtZWRpdG9yLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUlqQixTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBRVosWUFBWSxFQUNaLE1BQU0sRUFDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNwRixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7QUFvQnhFLE1BQU0sT0FBTyxtQkFBbUI7SUFYaEM7UUFnQkUsdUJBQXVCO1FBRWYsbUJBQWMsR0FBZ0Q7WUFDcEUsV0FBVyxFQUFFLElBQUk7WUFDakIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsT0FBTyxFQUFFO2dCQUNQLE9BQU8sRUFBRSxLQUFLO2FBQ2Y7U0FDRixDQUFDO1FBbUJGLFdBQVc7UUFDWCx5QkFBeUI7UUFDekIsNkJBQTZCO1FBQzdCLHVCQUF1QjtRQUN2Qiw4QkFBOEI7UUFDOUIsaUNBQWlDO1FBQ2pDLE1BQU07UUFDTixJQUFJO1FBRUosd0JBQXdCO1FBQ3hCLHdCQUF3QjtRQUN4QixJQUFJO1FBRUo7Ozs7O1dBS0c7UUFFSCxVQUFLLEdBQUcsSUFBSSxD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QUFRO3NCQURQLEtBQUs7Z0JBT04sWUFBWTtzQkFEWCxNQUFNO2dCQU9QLGdCQUFnQjtzQkFEZixNQUFNO2dCQU9QLG1CQUFtQjtzQkFEbEIsTUFBTTtnQkFPUCxNQUFNO3NCQURMLE1BQU07Z0JBMkNQLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBBZnRlclZpZXdJbml0LFxuICBWaWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgSG9zdExpc3RlbmVyLFxuICBpbmplY3Rcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb2RlRWRpdG9yU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2NvZGUtZWRpdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgVHlwZXNjcmlwdERlZmF1bHRzU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3R5cGVzY3JpcHQtZGVmYXVsdHMuc2VydmljZSc7XG5pbXBvcnQgeyBKYXZhc2NyaXB0RGVmYXVsdHNTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvamF2YXNjcmlwdC1kZWZhdWx0cy5zZXJ2aWNlJztcbmltcG9ydCB7IEpzb25EZWZhdWx0c1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9qc29uLWRlZmF1bHRzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL2NvZGUubW9kZWwnO1xuaW1wb3J0IHsgZWRpdG9yIH0gZnJvbSAnbW9uYWNvLWVkaXRvcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZU1vZGVsQ2hhbmdlZEV2ZW50IHtcbiAgc2VuZGVyOiBDb2RlRWRpdG9yQ29tcG9uZW50O1xuICB2YWx1ZTogQ29kZU1vZGVsO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICduZ3MtY29kZS1lZGl0b3InLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICB0ZW1wbGF0ZVVybDogJy4vY29kZS1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jb2RlLWVkaXRvci5jb21wb25lbnQuY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgaG9zdDogeyBjbGFzczogJ25ncy1jb2RlLWVkaXRvcicgfVxufSlcbmV4cG9ydCBjbGFzcyBDb2RlRWRpdG9yQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXRcbntcbiAgcHJpdmF0ZSBfZWRpdG9yOiBlZGl0b3IuSUNvZGVFZGl0b3I7XG4gIHByaXZhdGUgX21vZGVsOiBlZGl0b3IuSVRleHRNb2RlbDtcbiAgLy8gcHJpdmF0ZSBfdmFsdWUgPSAnJztcblxuICBwcml2YXRlIGRlZmF1bHRPcHRpb25zOiBlZGl0b3IuSVN0YW5kYWxvbmVFZGl0b3JDb25zdHJ1Y3Rpb25PcHRpb25zID0ge1xuICAgIGxpbmVOdW1iZXJzOiAnb24nLFxuICAgIGNvbnRleHRtZW51OiBmYWxzZSxcbiAgICBtaW5pbWFwOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogVGhlIGluc3RhbmNlIG9mIHRoZSBlZGl0b3IuXG4gICAqL1xuICBnZXQgZWRpdG9yKCk6IGVkaXRvci5JQ29kZUVkaXRvciB7XG4gICAgcmV0dXJuIHRoaXMuX2VkaXRvcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXQgZWRpdG9yKHZhbHVlOiBlZGl0b3IuSUNvZGVFZGl0b3IpIHtcbiAgICB0aGlzLl9lZGl0b3IgPSB2YWx1ZTtcbiAgfVxuXG4gIEBWaWV3Q2hpbGQoJ2VkaXRvcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGVkaXRvckNvbnRlbnQ6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIEBJbnB1dCgpXG4gIGNvZGVNb2RlbDogQ29kZU1vZGVsO1xuXG4gIC8vIEBJbnB1dCgpXG4gIC8vIHNldCB2YWx1ZSh2OiBzdHJpbmcpIHtcbiAgLy8gICBpZiAodiAhPT0gdGhpcy5fdmFsdWUpIHtcbiAgLy8gICAgIHRoaXMuX3ZhbHVlID0gdjtcbiAgLy8gICAgIHRoaXMuc2V0RWRpdG9yVmFsdWUodik7XG4gIC8vICAgICB0aGlzLnZhbHVlQ2hhbmdlZC5lbWl0KHYpO1xuICAvLyAgIH1cbiAgLy8gfVxuXG4gIC8vIGdldCB2YWx1ZSgpOiBzdHJpbmcge1xuICAvLyAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgLy8gfVxuXG4gIC8qKlxuICAgKiBFZGl0b3IgdGhlbWUuIERlZmF1bHRzIHRvIGB2c2AuXG4gICAqXG4gICAqIEFsbG93ZWQgdmFsdWVzOiBgdnNgLCBgdnMtZGFya2Agb3IgYGhjLWJsYWNrYC5cbiAgICogQG1lbWJlcm9mIENvZGVFZGl0b3JDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIHRoZW1lID0gJ3ZzJztcblxuICAvKipcbiAgICogRWRpdG9yIG9wdGlvbnMuXG4gICAqXG4gICAqIFNlZSBodHRwczovL21pY3Jvc29mdC5naXRodWIuaW8vbW9uYWNvLWVkaXRvci9kb2NzLmh0bWwjaW50ZXJmYWNlcy9lZGl0b3IuSVN0YW5kYWxvbmVFZGl0b3JDb25zdHJ1Y3Rpb25PcHRpb25zLmh0bWwgZm9yIG1vcmUgZGV0YWlscy5cbiAgICpcbiAgICogQG1lbWJlcm9mIENvZGVFZGl0b3JDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIG9wdGlvbnM6IGVkaXRvci5JU3RhbmRhbG9uZUVkaXRvckNvbnN0cnVjdGlvbk9wdGlvbnMgPSB7fTtcblxuICAvKipcbiAgICogVG9nZ2xlIHJlYWRvbmx5IHN0YXRlIG9mIHRoZSBlZGl0b3IuXG4gICAqXG4gICAqIEBtZW1iZXJvZiBDb2RlRWRpdG9yQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoKVxuICByZWFkT25seSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIHRleHQgY29udGVudCBvZiB0aGUgbW9kZWwgaGF2ZSBjaGFuZ2VkLlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHZhbHVlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBlbWl0dGVkIHdoZW4gdGhlIGNvZGUgbW9kZWwgdmFsdWUgaXMgY2hhbmdlZC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBjb2RlTW9kZWxDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxDb2RlTW9kZWxDaGFuZ2VkRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgY29udGVudHMgb2YgdGhlIHVuZGVybHlpbmcgZWRpdG9yIG1vZGVsIGhhdmUgY2hhbmdlZC5cbiAgICovXG4gIEBPdXRwdXQoKVxuICBtb2RlbENvbnRlbnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxlZGl0b3IuSU1vZGVsQ29udGVudENoYW5nZWRFdmVudD4oKTtcblxuICAvKipcbiAgICogUmFpc2VkIHdoZW4gZWRpdG9yIGZpbmlzaGVkIGxvYWRpbmcgYWxsIGl0cyBjb21wb25lbnRzLlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q29kZUVkaXRvckNvbXBvbmVudD4oKTtcblxuICBwcm90ZWN0ZWQgZWRpdG9yU2VydmljZSA9IGluamVjdChDb2RlRWRpdG9yU2VydmljZSk7XG4gIHByb3RlY3RlZCB0eXBlc2NyaXB0RGVmYXVsdHMgPSBpbmplY3QoVHlwZXNjcmlwdERlZmF1bHRzU2VydmljZSk7XG4gIHByb3RlY3RlZCBqYXZhc2NyaXB0RGVmYXVsdHMgPSBpbmplY3QoSmF2YXNjcmlwdERlZmF1bHRzU2VydmljZSk7XG4gIHByb3RlY3RlZCBqc29uRGVmYXVsdHMgPSBpbmplY3QoSnNvbkRlZmF1bHRzU2VydmljZSk7XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuZWRpdG9yKSB7XG4gICAgICB0aGlzLmVkaXRvci5kaXNwb3NlKCk7XG4gICAgICB0aGlzLmVkaXRvciA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX21vZGVsKSB7XG4gICAgICB0aGlzLl9tb2RlbC5kaXNwb3NlKCk7XG4gICAgICB0aGlzLl9tb2RlbCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGNvbnN0IGNvZGVNb2RlbCA9IGNoYW5nZXNbJ2NvZGVNb2RlbCddO1xuICAgIGNvbnN0IHJlYWRPbmx5ID0gY2hhbmdlc1sncmVhZE9ubHknXTtcbiAgICBjb25zdCB0aGVtZSA9IGNoYW5nZXNbJ3RoZW1lJ107XG5cbiAgICBpZiAoY29kZU1vZGVsICYmICFjb2RlTW9kZWwuZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMudXBkYXRlTW9kZWwoY29kZU1vZGVsLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHJlYWRPbmx5ICYmICFyZWFkT25seS5maXJzdENoYW5nZSkge1xuICAgICAgaWYgKHRoaXMuZWRpdG9yKSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLnVwZGF0ZU9wdGlvbnMoe1xuICAgICAgICAgIHJlYWRPbmx5OiByZWFkT25seS5jdXJyZW50VmFsdWVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoZW1lICYmICF0aGVtZS5maXJzdENoYW5nZSkge1xuICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLnNldFRoZW1lKHRoZW1lLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScpXG4gIG9uUmVzaXplKCkge1xuICAgIGlmICh0aGlzLmVkaXRvcikge1xuICAgICAgdGhpcy5lZGl0b3IubGF5b3V0KCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuc2V0dXBFZGl0b3IoKTtcbiAgICB0aGlzLmxvYWRlZC5lbWl0KHRoaXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cEVkaXRvcigpIHtcbiAgICBjb25zdCBkb21FbGVtZW50ID0gdGhpcy5lZGl0b3JDb250ZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICB2YWx1ZTogJycsXG4gICAgICBsYW5ndWFnZTogJ3RleHQnLFxuICAgICAgdXJpOiBgY29kZS0ke0RhdGUubm93KCl9YCxcbiAgICAgIC4uLnRoaXMuY29kZU1vZGVsXG4gICAgfTtcblxuICAgIHRoaXMuX21vZGVsID0gdGhpcy5lZGl0b3JTZXJ2aWNlLmNyZWF0ZU1vZGVsKFxuICAgICAgc2V0dGluZ3MudmFsdWUsXG4gICAgICBzZXR0aW5ncy5sYW5ndWFnZSxcbiAgICAgIHNldHRpbmdzLnVyaVxuICAgICk7XG5cbiAgICBjb25zdCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5kZWZhdWx0T3B0aW9ucywgdGhpcy5vcHRpb25zLCB7XG4gICAgICByZWFkT25seTogdGhpcy5yZWFkT25seSxcbiAgICAgIHRoZW1lOiB0aGlzLnRoZW1lLFxuICAgICAgbW9kZWw6IHRoaXMuX21vZGVsXG4gICAgfSk7XG5cbiAgICB0aGlzLmVkaXRvciA9IHRoaXMuZWRpdG9yU2VydmljZS5jcmVhdGVFZGl0b3IoZG9tRWxlbWVudCwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLl9tb2RlbC5vbkRpZENoYW5nZUNvbnRlbnQoKGU6IGVkaXRvci5JTW9kZWxDb250ZW50Q2hhbmdlZEV2ZW50KSA9PiB7XG4gICAgICB0aGlzLm1vZGVsQ29udGVudENoYW5nZWQuZW1pdChlKTtcblxuICAgICAgY29uc3QgbmV3VmFsdWUgPSB0aGlzLl9tb2RlbC5nZXRWYWx1ZSgpO1xuICAgICAgaWYgKHRoaXMuY29kZU1vZGVsKSB7XG4gICAgICAgIHRoaXMuY29kZU1vZGVsLnZhbHVlID0gbmV3VmFsdWU7XG4gICAgICB9XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlZC5lbWl0KG5ld1ZhbHVlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuc2V0dXBEZXBlbmRlbmNpZXModGhpcy5jb2RlTW9kZWwpO1xuICAgIHRoaXMuY29kZU1vZGVsQ2hhbmdlZC5lbWl0KHsgc2VuZGVyOiB0aGlzLCB2YWx1ZTogdGhpcy5jb2RlTW9kZWwgfSk7XG4gIH1cblxuICBydW5FZGl0b3JBY3Rpb24oaWQ6IHN0cmluZywgYXJncz86IHVua25vd24pIHtcbiAgICB0aGlzLmVkaXRvci5nZXRBY3Rpb24oaWQpPy5ydW4oYXJncyk7XG4gIH1cblxuICBmb3JtYXREb2N1bWVudCgpIHtcbiAgICB0aGlzLnJ1bkVkaXRvckFjdGlvbignZWRpdG9yLmFjdGlvbi5mb3JtYXREb2N1bWVudCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cERlcGVuZGVuY2llcyhtb2RlbDogQ29kZU1vZGVsKSB7XG4gICAgaWYgKCFtb2RlbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgbGFuZ3VhZ2UgfSA9IG1vZGVsO1xuXG4gICAgaWYgKGxhbmd1YWdlKSB7XG4gICAgICBjb25zdCBsYW5nID0gbGFuZ3VhZ2UudG9Mb3dlckNhc2UoKTtcblxuICAgICAgc3dpdGNoIChsYW5nKSB7XG4gICAgICAgIGNhc2UgJ3R5cGVzY3JpcHQnOlxuICAgICAgICAgIGlmIChtb2RlbC5kZXBlbmRlbmNpZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5sb2FkVHlwaW5ncyhtb2RlbC5kZXBlbmRlbmNpZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnamF2YXNjcmlwdCc6XG4gICAgICAgICAgaWYgKG1vZGVsLmRlcGVuZGVuY2llcykge1xuICAgICAgICAgICAgdGhpcy5lZGl0b3JTZXJ2aWNlLmxvYWRUeXBpbmdzKG1vZGVsLmRlcGVuZGVuY2llcyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdqc29uJzpcbiAgICAgICAgICBpZiAobW9kZWwuc2NoZW1hcykge1xuICAgICAgICAgICAgdGhpcy5qc29uRGVmYXVsdHMuYWRkU2NoZW1hcyhtb2RlbC51cmksIG1vZGVsLnNjaGVtYXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldEVkaXRvclZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAvLyBGaXggZm9yIHZhbHVlIGNoYW5nZSB3aGlsZSBkaXNwb3NlIGluIHByb2Nlc3MuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fbW9kZWwpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwuc2V0VmFsdWUodmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVNb2RlbChtb2RlbDogQ29kZU1vZGVsKSB7XG4gICAgaWYgKG1vZGVsKSB7XG4gICAgICB0aGlzLnNldEVkaXRvclZhbHVlKG1vZGVsLnZhbHVlKTtcbiAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5zZXRNb2RlbExhbmd1YWdlKHRoaXMuX21vZGVsLCBtb2RlbC5sYW5ndWFnZSk7XG4gICAgICB0aGlzLnNldHVwRGVwZW5kZW5jaWVzKG1vZGVsKTtcbiAgICAgIHRoaXMuY29kZU1vZGVsQ2hhbmdlZC5lbWl0KHsgc2VuZGVyOiB0aGlzLCB2YWx1ZTogbW9kZWwgfSk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGlkPVwiZWRpdG9yXCIgI2VkaXRvciBjbGFzcz1cIm1vbmFjby1lZGl0b3IgZWRpdG9yXCI+PC9kaXY+XG4iXX0=