ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
251 lines (250 loc) • 32.5 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { __decorate } from "tslib";
import { Platform } from '@angular/cdk/platform';
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, forwardRef, Input, NgZone, Output, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { BehaviorSubject, combineLatest, fromEvent, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, map, takeUntil } from 'rxjs/operators';
import { warn } from 'ng-zorro-antd/core/logger';
import { inNextTick, InputBoolean } from 'ng-zorro-antd/core/util';
import { NzCodeEditorService } from './code-editor.service';
export class NzCodeEditorComponent {
constructor(nzCodeEditorService, ngZone, elementRef, platform) {
this.nzCodeEditorService = nzCodeEditorService;
this.ngZone = ngZone;
this.platform = platform;
this.nzEditorMode = 'normal';
this.nzOriginalText = '';
this.nzLoading = false;
this.nzFullControl = false;
this.nzEditorInitialized = new EventEmitter();
this.editorOptionCached = {};
this.destroy$ = new Subject();
this.resize$ = new Subject();
this.editorOption$ = new BehaviorSubject({});
this.editorInstance = null;
this.value = '';
this.modelSet = false;
this.onDidChangeContentDisposable = null;
this.onChange = (_value) => { };
this.onTouch = () => { };
this.el = elementRef.nativeElement;
this.el.classList.add('ant-code-editor');
}
set nzEditorOption(value) {
this.editorOption$.next(value);
}
/**
* Initialize a monaco editor instance.
*/
ngAfterViewInit() {
if (!this.platform.isBrowser) {
return;
}
this.nzCodeEditorService.requestToInit().subscribe(option => this.setup(option));
}
ngOnDestroy() {
if (this.onDidChangeContentDisposable) {
this.onDidChangeContentDisposable.dispose();
this.onDidChangeContentDisposable = null;
}
if (this.editorInstance) {
this.editorInstance.dispose();
this.editorInstance = null;
}
this.destroy$.next();
this.destroy$.complete();
}
writeValue(value) {
this.value = value;
this.setValue();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouch = fn;
}
layout() {
this.resize$.next();
}
setup(option) {
inNextTick().subscribe(() => {
this.editorOptionCached = option;
this.registerOptionChanges();
this.initMonacoEditorInstance();
this.registerResizeChange();
this.setValue();
if (!this.nzFullControl) {
this.setValueEmitter();
}
this.nzEditorInitialized.emit(this.editorInstance);
});
}
registerOptionChanges() {
combineLatest([this.editorOption$, this.nzCodeEditorService.option$])
.pipe(takeUntil(this.destroy$))
.subscribe(([selfOpt, defaultOpt]) => {
this.editorOptionCached = Object.assign(Object.assign(Object.assign({}, this.editorOptionCached), defaultOpt), selfOpt);
this.updateOptionToMonaco();
});
}
initMonacoEditorInstance() {
this.ngZone.runOutsideAngular(() => {
this.editorInstance =
this.nzEditorMode === 'normal'
? monaco.editor.create(this.el, Object.assign({}, this.editorOptionCached))
: monaco.editor.createDiffEditor(this.el, Object.assign({}, this.editorOptionCached));
});
}
registerResizeChange() {
this.ngZone.runOutsideAngular(() => {
fromEvent(window, 'resize')
.pipe(debounceTime(300), takeUntil(this.destroy$))
.subscribe(() => {
this.layout();
});
this.resize$
.pipe(takeUntil(this.destroy$), filter(() => !!this.editorInstance), map(() => ({
width: this.el.clientWidth,
height: this.el.clientHeight
})), distinctUntilChanged((a, b) => a.width === b.width && a.height === b.height), debounceTime(50))
.subscribe(() => {
this.editorInstance.layout();
});
});
}
setValue() {
if (!this.editorInstance) {
return;
}
if (this.nzFullControl && this.value) {
warn(`should not set value when you are using full control mode! It would result in ambiguous data flow!`);
return;
}
if (this.nzEditorMode === 'normal') {
if (this.modelSet) {
const model = this.editorInstance.getModel();
this.preservePositionAndSelections(() => model.setValue(this.value));
}
else {
this.editorInstance.setModel(monaco.editor.createModel(this.value, this.editorOptionCached.language));
this.modelSet = true;
}
}
else {
if (this.modelSet) {
const model = this.editorInstance.getModel();
this.preservePositionAndSelections(() => {
model.modified.setValue(this.value);
model.original.setValue(this.nzOriginalText);
});
}
else {
const language = this.editorOptionCached.language;
this.editorInstance.setModel({
original: monaco.editor.createModel(this.nzOriginalText, language),
modified: monaco.editor.createModel(this.value, language)
});
this.modelSet = true;
}
}
}
/**
* {@link editor.ICodeEditor}#setValue resets the cursor position to the start of the document.
* This helper memorizes the cursor position and selections and restores them after the given
* function has been called.
*/
preservePositionAndSelections(fn) {
if (!this.editorInstance) {
fn();
return;
}
const position = this.editorInstance.getPosition();
const selections = this.editorInstance.getSelections();
fn();
if (position) {
this.editorInstance.setPosition(position);
}
if (selections) {
this.editorInstance.setSelections(selections);
}
}
setValueEmitter() {
const model = (this.nzEditorMode === 'normal'
? this.editorInstance.getModel()
: this.editorInstance.getModel().modified);
// The `onDidChangeContent` returns a disposable object (an object with `dispose()` method) which will cleanup
// the listener. The callback, that we pass to `onDidChangeContent`, captures `this`. This leads to a circular reference
// (`nz-code-editor -> monaco -> nz-code-editor`) and prevents the `nz-code-editor` from being GC'd.
this.onDidChangeContentDisposable = model.onDidChangeContent(() => {
this.emitValue(model.getValue());
});
}
emitValue(value) {
if (this.value === value) {
// If the value didn't change there's no reason to send an update.
// Specifically this may happen during an update from the model (writeValue) where sending an update to the model would actually be incorrect.
return;
}
this.value = value;
// We're re-entering the Angular zone only if the value has been changed since there's a `return` expression previously.
// This won't cause "dead" change detections (basically when the `tick()` has been run, but there's nothing to update).
this.ngZone.run(() => {
this.onChange(value);
});
}
updateOptionToMonaco() {
if (this.editorInstance) {
this.editorInstance.updateOptions(Object.assign({}, this.editorOptionCached));
}
}
}
NzCodeEditorComponent.decorators = [
{ type: Component, args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'nz-code-editor',
exportAs: 'nzCodeEditor',
template: `
<div class="ant-code-editor-loading" *ngIf="nzLoading">
<nz-spin></nz-spin>
</div>
<div class="ant-code-editor-toolkit" *ngIf="nzToolkit">
<ng-template [ngTemplateOutlet]="nzToolkit"></ng-template>
</div>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzCodeEditorComponent),
multi: true
}
]
},] }
];
NzCodeEditorComponent.ctorParameters = () => [
{ type: NzCodeEditorService },
{ type: NgZone },
{ type: ElementRef },
{ type: Platform }
];
NzCodeEditorComponent.propDecorators = {
nzEditorMode: [{ type: Input }],
nzOriginalText: [{ type: Input }],
nzLoading: [{ type: Input }],
nzFullControl: [{ type: Input }],
nzToolkit: [{ type: Input }],
nzEditorOption: [{ type: Input }],
nzEditorInitialized: [{ type: Output }]
};
__decorate([
InputBoolean()
], NzCodeEditorComponent.prototype, "nzLoading", void 0);
__decorate([
InputBoolean()
], NzCodeEditorComponent.prototype, "nzFullControl", void 0);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZS1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jb2RlLWVkaXRvci9jb2RlLWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHOztBQUVILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBQ0wsTUFBTSxFQUVOLE1BQU0sRUFFTixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxRSxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJNUYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRWpELE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFnQzVELE1BQU0sT0FBTyxxQkFBcUI7SUEyQmhDLFlBQ1UsbUJBQXdDLEVBQ3hDLE1BQWMsRUFDdEIsVUFBc0IsRUFDZCxRQUFrQjtRQUhsQix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFFZCxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBM0JuQixpQkFBWSxHQUFpQixRQUFRLENBQUM7UUFDdEMsbUJBQWMsR0FBRyxFQUFFLENBQUM7UUFD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UUFFRCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQix3SEFBd0g7UUFDeEgsdUhBQXVIO1FBQ3ZILElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLG1CQUFNLElBQUksQ0FBQyxrQkFBa0IsRUFBRyxDQUFDO1NBQ25FO0lBQ0gsQ0FBQzs7O1lBMVFGLFNBQVMsU0FBQztnQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7Z0JBQ3JDLFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLFFBQVEsRUFBRSxjQUFjO2dCQUN4QixRQUFRLEVBQUU7Ozs7Ozs7O0dBUVQ7Z0JBQ0QsU0FBUyxFQUFFO29CQUNUO3dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7d0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUM7d0JBQ3BELEtBQUssRUFBRSxJQUFJO3FCQUNaO2lCQUNGO2FBQ0Y7OztZQS9CUSxtQkFBbUI7WUFoQjFCLE1BQU07WUFKTixVQUFVO1lBTEgsUUFBUTs7OzJCQTZEZCxLQUFLOzZCQUNMLEtBQUs7d0JBQ0wsS0FBSzs0QkFDTCxLQUFLO3dCQUNMLEtBQUs7NkJBRUwsS0FBSztrQ0FJTCxNQUFNOztBQVJrQjtJQUFmLFlBQVksRUFBRTt3REFBbUI7QUFDbEI7SUFBZixZQUFZLEVBQUU7NERBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIGZyb21FdmVudCwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgZmlsdGVyLCBtYXAsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgZWRpdG9yLCBJRGlzcG9zYWJsZSB9IGZyb20gJ21vbmFjby1lZGl0b3InO1xuXG5pbXBvcnQgeyB3YXJuIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL2xvZ2dlcic7XG5pbXBvcnQgeyBCb29sZWFuSW5wdXQsIE56U2FmZUFueSwgT25DaGFuZ2VUeXBlLCBPblRvdWNoZWRUeXBlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IGluTmV4dFRpY2ssIElucHV0Qm9vbGVhbiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcblxuaW1wb3J0IHsgTnpDb2RlRWRpdG9yU2VydmljZSB9IGZyb20gJy4vY29kZS1lZGl0b3Iuc2VydmljZSc7XG5pbXBvcnQgeyBEaWZmRWRpdG9yT3B0aW9ucywgRWRpdG9yT3B0aW9ucywgSm9pbmVkRWRpdG9yT3B0aW9ucywgTnpFZGl0b3JNb2RlIH0gZnJvbSAnLi90eXBpbmdzJztcblxuLy8gSW1wb3J0IHR5cGVzIGZyb20gbW9uYWNvIGVkaXRvci5cbmltcG9ydCBJVGV4dE1vZGVsID0gZWRpdG9yLklUZXh0TW9kZWw7XG5pbXBvcnQgSVN0YW5kYWxvbmVDb2RlRWRpdG9yID0gZWRpdG9yLklTdGFuZGFsb25lQ29kZUVkaXRvcjtcbmltcG9ydCBJU3RhbmRhbG9uZURpZmZFZGl0b3IgPSBlZGl0b3IuSVN0YW5kYWxvbmVEaWZmRWRpdG9yO1xuXG5kZWNsYXJlIGNvbnN0IG1vbmFjbzogTnpTYWZlQW55O1xuXG5AQ29tcG9uZW50KHtcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHNlbGVjdG9yOiAnbnotY29kZS1lZGl0b3InLFxuICBleHBvcnRBczogJ256Q29kZUVkaXRvcicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImFudC1jb2RlLWVkaXRvci1sb2FkaW5nXCIgKm5nSWY9XCJuekxvYWRpbmdcIj5cbiAgICAgIDxuei1zcGluPjwvbnotc3Bpbj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJhbnQtY29kZS1lZGl0b3ItdG9vbGtpdFwiICpuZ0lmPVwibnpUb29sa2l0XCI+XG4gICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwibnpUb29sa2l0XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOekNvZGVFZGl0b3JDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgTnpDb2RlRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256TG9hZGluZzogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbnpGdWxsQ29udHJvbDogQm9vbGVhbklucHV0O1xuXG4gIEBJbnB1dCgpIG56RWRpdG9yTW9kZTogTnpFZGl0b3JNb2RlID0gJ25vcm1hbCc7XG4gIEBJbnB1dCgpIG56T3JpZ2luYWxUZXh0ID0gJyc7XG4gIEBJbnB1dCgpIEBJbnB1dEJvb2xlYW4oKSBuekxvYWRpbmcgPSBmYWxzZTtcbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIG56RnVsbENvbnRyb2wgPSBmYWxzZTtcbiAgQElucHV0KCkgbnpUb29sa2l0PzogVGVtcGxhdGVSZWY8dm9pZD47XG5cbiAgQElucHV0KCkgc2V0IG56RWRpdG9yT3B0aW9uKHZhbHVlOiBKb2luZWRFZGl0b3JPcHRpb25zKSB7XG4gICAgdGhpcy5lZGl0b3JPcHRpb24kLm5leHQodmFsdWUpO1xuICB9XG5cbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56RWRpdG9ySW5pdGlhbGl6ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPElTdGFuZGFsb25lQ29kZUVkaXRvciB8IElTdGFuZGFsb25lRGlmZkVkaXRvcj4oKTtcblxuICBlZGl0b3JPcHRpb25DYWNoZWQ6IEpvaW5lZEVkaXRvck9wdGlvbnMgPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGVsOiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVzaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgZWRpdG9yT3B0aW9uJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Sm9pbmVkRWRpdG9yT3B0aW9ucz4oe30pO1xuICBwcml2YXRlIGVkaXRvckluc3RhbmNlOiBJU3RhbmRhbG9uZUNvZGVFZGl0b3IgfCBJU3RhbmRhbG9uZURpZmZFZGl0b3IgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB2YWx1ZSA9ICcnO1xuICBwcml2YXRlIG1vZGVsU2V0ID0gZmFsc2U7XG4gIHByaXZhdGUgb25EaWRDaGFuZ2VDb250ZW50RGlzcG9zYWJsZTogSURpc3Bvc2FibGUgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIG56Q29kZUVkaXRvclNlcnZpY2U6IE56Q29kZUVkaXRvclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgcGxhdGZvcm06IFBsYXRmb3JtXG4gICkge1xuICAgIHRoaXMuZWwgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKCdhbnQtY29kZS1lZGl0b3InKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGEgbW9uYWNvIGVkaXRvciBpbnN0YW5jZS5cbiAgICovXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGxhdGZvcm0uaXNCcm93c2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubnpDb2RlRWRpdG9yU2VydmljZS5yZXF1ZXN0VG9Jbml0KCkuc3Vic2NyaWJlKG9wdGlvbiA9PiB0aGlzLnNldHVwKG9wdGlvbikpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub25EaWRDaGFuZ2VDb250ZW50RGlzcG9zYWJsZSkge1xuICAgICAgdGhpcy5vbkRpZENoYW5nZUNvbnRlbnREaXNwb3NhYmxlLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMub25EaWRDaGFuZ2VDb250ZW50RGlzcG9zYWJsZSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZWRpdG9ySW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuZWRpdG9ySW5zdGFuY2UuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5lZGl0b3JJbnN0YW5jZSA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMuc2V0VmFsdWUoKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IE9uQ2hhbmdlVHlwZSk6IE56U2FmZUFueSB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IE9uVG91Y2hlZFR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2ggPSBmbjtcbiAgfVxuXG4gIG9uQ2hhbmdlOiBPbkNoYW5nZVR5cGUgPSAoX3ZhbHVlOiBzdHJpbmcpID0+IHt9O1xuXG4gIG9uVG91Y2g6IE9uVG91Y2hlZFR5cGUgPSAoKSA9PiB7fTtcblxuICBsYXlvdXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZXNpemUkLm5leHQoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0dXAob3B0aW9uOiBKb2luZWRFZGl0b3JPcHRpb25zKTogdm9pZCB7XG4gICAgaW5OZXh0VGljaygpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmVkaXRvck9wdGlvbkNhY2hlZCA9IG9wdGlvbjtcbiAgICAgIHRoaXMucmVnaXN0ZXJPcHRpb25DaGFuZ2VzKCk7XG4gICAgICB0aGlzLmluaXRNb25hY29FZGl0b3JJbnN0YW5jZSgpO1xuICAgICAgdGhpcy5yZWdpc3RlclJlc2l6ZUNoYW5nZSgpO1xuICAgICAgdGhpcy5zZXRWYWx1ZSgpO1xuXG4gICAgICBpZiAoIXRoaXMubnpGdWxsQ29udHJvbCkge1xuICAgICAgICB0aGlzLnNldFZhbHVlRW1pdHRlcigpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm56RWRpdG9ySW5pdGlhbGl6ZWQuZW1pdCh0aGlzLmVkaXRvckluc3RhbmNlISk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyT3B0aW9uQ2hhbmdlcygpOiB2b2lkIHtcbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLmVkaXRvck9wdGlvbiQsIHRoaXMubnpDb2RlRWRpdG9yU2VydmljZS5vcHRpb24kXSlcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtzZWxmT3B0LCBkZWZhdWx0T3B0XSkgPT4ge1xuICAgICAgICB0aGlzLmVkaXRvck9wdGlvbkNhY2hlZCA9IHtcbiAgICAgICAgICAuLi50aGlzLmVkaXRvck9wdGlvbkNhY2hlZCxcbiAgICAgICAgICAuLi5kZWZhdWx0T3B0LFxuICAgICAgICAgIC4uLnNlbGZPcHRcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy51cGRhdGVPcHRpb25Ub01vbmFjbygpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGluaXRNb25hY29FZGl0b3JJbnN0YW5jZSgpOiB2b2lkIHtcbiAgICB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICB0aGlzLmVkaXRvckluc3RhbmNlID1cbiAgICAgICAgdGhpcy5uekVkaXRvck1vZGUgPT09ICdub3JtYWwnXG4gICAgICAgICAgPyBtb25hY28uZWRpdG9yLmNyZWF0ZSh0aGlzLmVsLCB7IC4uLnRoaXMuZWRpdG9yT3B0aW9uQ2FjaGVkIH0pXG4gICAgICAgICAgOiBtb25hY28uZWRpdG9yLmNyZWF0ZURpZmZFZGl0b3IodGhpcy5lbCwge1xuICAgICAgICAgICAgICAuLi4odGhpcy5lZGl0b3JPcHRpb25DYWNoZWQgYXMgRGlmZkVkaXRvck9wdGlvbnMpXG4gICAgICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVnaXN0ZXJSZXNpemVDaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpXG4gICAgICAgIC5waXBlKGRlYm91bmNlVGltZSgzMDApLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubGF5b3V0KCk7XG4gICAgICAgIH0pO1xuXG4gICAgICB0aGlzLnJlc2l6ZSRcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLFxuICAgICAgICAgIGZpbHRlcigoKSA9PiAhIXRoaXMuZWRpdG9ySW5zdGFuY2UpLFxuICAgICAgICAgIG1hcCgoKSA9PiAoe1xuICAgICAgICAgICAgd2lkdGg6IHRoaXMuZWwuY2xpZW50V2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuZWwuY2xpZW50SGVpZ2h0XG4gICAgICAgICAgfSkpLFxuICAgICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChhLCBiKSA9PiBhLndpZHRoID09PSBiLndpZHRoICYmIGEuaGVpZ2h0ID09PSBiLmhlaWdodCksXG4gICAgICAgICAgZGVib3VuY2VUaW1lKDUwKVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZWRpdG9ySW5zdGFuY2UhLmxheW91dCgpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VmFsdWUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRvckluc3RhbmNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubnpGdWxsQ29udHJvbCAmJiB0aGlzLnZhbHVlKSB7XG4gICAgICB3YXJuKGBzaG91bGQgbm90IHNldCB2YWx1ZSB3aGVuIHlvdSBhcmUgdXNpbmcgZnVsbCBjb250cm9sIG1vZGUhIEl0IHdvdWxkIHJlc3VsdCBpbiBhbWJpZ3VvdXMgZGF0YSBmbG93IWApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm56RWRpdG9yTW9kZSA9PT0gJ25vcm1hbCcpIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsU2V0KSB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gdGhpcy5lZGl0b3JJbnN0YW5jZS5nZXRNb2RlbCgpIGFzIElUZXh0TW9kZWw7XG4gICAgICAgIHRoaXMucHJlc2VydmVQb3NpdGlvbkFuZFNlbGVjdGlvbnMoKCkgPT4gbW9kZWwuc2V0VmFsdWUodGhpcy52YWx1ZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgKHRoaXMuZWRpdG9ySW5zdGFuY2UgYXMgSVN0YW5kYWxvbmVDb2RlRWRpdG9yKS5zZXRNb2RlbChcbiAgICAgICAgICBtb25hY28uZWRpdG9yLmNyZWF0ZU1vZGVsKHRoaXMudmFsdWUsICh0aGlzLmVkaXRvck9wdGlvbkNhY2hlZCBhcyBFZGl0b3JPcHRpb25zKS5sYW5ndWFnZSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5tb2RlbFNldCA9IHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLm1vZGVsU2V0KSB7XG4gICAgICAgIGNvbnN0IG1vZGVsID0gKHRoaXMuZWRpdG9ySW5zdGFuY2UgYXMgSVN0YW5kYWxvbmVEaWZmRWRpdG9yKS5nZXRNb2RlbCgpITtcbiAgICAgICAgdGhpcy5wcmVzZXJ2ZVBvc2l0aW9uQW5kU2VsZWN0aW9ucygoKSA9PiB7XG4gICAgICAgICAgbW9kZWwubW9kaWZpZWQuc2V0VmFsdWUodGhpcy52YWx1ZSk7XG4gICAgICAgICAgbW9kZWwub3JpZ2luYWwuc2V0VmFsdWUodGhpcy5uek9yaWdpbmFsVGV4dCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbGFuZ3VhZ2UgPSAodGhpcy5lZGl0b3JPcHRpb25DYWNoZWQgYXMgRWRpdG9yT3B0aW9ucykubGFuZ3VhZ2U7XG4gICAgICAgICh0aGlzLmVkaXRvckluc3RhbmNlIGFzIElTdGFuZGFsb25lRGlmZkVkaXRvcikuc2V0TW9kZWwoe1xuICAgICAgICAgIG9yaWdpbmFsOiBtb25hY28uZWRpdG9yLmNyZWF0ZU1vZGVsKHRoaXMubnpPcmlnaW5hbFRleHQsIGxhbmd1YWdlKSxcbiAgICAgICAgICBtb2RpZmllZDogbW9uYWNvLmVkaXRvci5jcmVhdGVNb2RlbCh0aGlzLnZhbHVlLCBsYW5ndWFnZSlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kZWxTZXQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgZWRpdG9yLklDb2RlRWRpdG9yfSNzZXRWYWx1ZSByZXNldHMgdGhlIGN1cnNvciBwb3NpdGlvbiB0byB0aGUgc3RhcnQgb2YgdGhlIGRvY3VtZW50LlxuICAgKiBUaGlzIGhlbHBlciBtZW1vcml6ZXMgdGhlIGN1cnNvciBwb3NpdGlvbiBhbmQgc2VsZWN0aW9ucyBhbmQgcmVzdG9yZXMgdGhlbSBhZnRlciB0aGUgZ2l2ZW5cbiAgICogZnVuY3Rpb24gaGFzIGJlZW4gY2FsbGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBwcmVzZXJ2ZVBvc2l0aW9uQW5kU2VsZWN0aW9ucyhmbjogKCkgPT4gdW5rbm93bik6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0b3JJbnN0YW5jZSkge1xuICAgICAgZm4oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuZWRpdG9ySW5zdGFuY2UuZ2V0UG9zaXRpb24oKTtcbiAgICBjb25zdCBzZWxlY3Rpb25zID0gdGhpcy5lZGl0b3JJbnN0YW5jZS5nZXRTZWxlY3Rpb25zKCk7XG5cbiAgICBmbigpO1xuXG4gICAgaWYgKHBvc2l0aW9uKSB7XG4gICAgICB0aGlzLmVkaXRvckluc3RhbmNlLnNldFBvc2l0aW9uKHBvc2l0aW9uKTtcbiAgICB9XG4gICAgaWYgKHNlbGVjdGlvbnMpIHtcbiAgICAgIHRoaXMuZWRpdG9ySW5zdGFuY2Uuc2V0U2VsZWN0aW9ucyhzZWxlY3Rpb25zKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFZhbHVlRW1pdHRlcigpOiB2b2lkIHtcbiAgICBjb25zdCBtb2RlbCA9IChcbiAgICAgIHRoaXMubnpFZGl0b3JNb2RlID09PSAnbm9ybWFsJ1xuICAgICAgICA/ICh0aGlzLmVkaXRvckluc3RhbmNlIGFzIElTdGFuZGFsb25lQ29kZUVkaXRvcikuZ2V0TW9kZWwoKVxuICAgICAgICA6ICh0aGlzLmVkaXRvckluc3RhbmNlIGFzIElTdGFuZGFsb25lRGlmZkVkaXRvcikuZ2V0TW9kZWwoKSEubW9kaWZpZWRcbiAgICApIGFzIElUZXh0TW9kZWw7XG5cbiAgICAvLyBUaGUgYG9uRGlkQ2hhbmdlQ29udGVudGAgcmV0dXJucyBhIGRpc3Bvc2FibGUgb2JqZWN0IChhbiBvYmplY3Qgd2l0aCBgZGlzcG9zZSgpYCBtZXRob2QpIHdoaWNoIHdpbGwgY2xlYW51cFxuICAgIC8vIHRoZSBsaXN0ZW5lci4gVGhlIGNhbGxiYWNrLCB0aGF0IHdlIHBhc3MgdG8gYG9uRGlkQ2hhbmdlQ29udGVudGAsIGNhcHR1cmVzIGB0aGlzYC4gVGhpcyBsZWFkcyB0byBhIGNpcmN1bGFyIHJlZmVyZW5jZVxuICAgIC8vIChgbnotY29kZS1lZGl0b3IgLT4gbW9uYWNvIC0+IG56LWNvZGUtZWRpdG9yYCkgYW5kIHByZXZlbnRzIHRoZSBgbnotY29kZS1lZGl0b3JgIGZyb20gYmVpbmcgR0MnZC5cbiAgICB0aGlzLm9uRGlkQ2hhbmdlQ29udGVudERpc3Bvc2FibGUgPSBtb2RlbC5vbkRpZENoYW5nZUNvbnRlbnQoKCkgPT4ge1xuICAgICAgdGhpcy5lbWl0VmFsdWUobW9kZWwuZ2V0VmFsdWUoKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRWYWx1ZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmFsdWUgPT09IHZhbHVlKSB7XG4gICAgICAvLyBJZiB0aGUgdmFsdWUgZGlkbid0IGNoYW5nZSB0aGVyZSdzIG5vIHJlYXNvbiB0byBzZW5kIGFuIHVwZGF0ZS5cbiAgICAgIC8vIFNwZWNpZmljYWxseSB0aGlzIG1heSBoYXBwZW4gZHVyaW5nIGFuIHVwZGF0ZSBmcm9tIHRoZSBtb2RlbCAod3JpdGVWYWx1ZSkgd2hlcmUgc2VuZGluZyBhbiB1cGRhdGUgdG8gdGhlIG1vZGVsIHdvdWxkIGFjdHVhbGx5IGJlIGluY29ycmVjdC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgLy8gV2UncmUgcmUtZW50ZXJpbmcgdGhlIEFuZ3VsYXIgem9uZSBvbmx5IGlmIHRoZSB2YWx1ZSBoYXMgYmVlbiBjaGFuZ2VkIHNpbmNlIHRoZXJlJ3MgYSBgcmV0dXJuYCBleHByZXNzaW9uIHByZXZpb3VzbHkuXG4gICAgLy8gVGhpcyB3b24ndCBjYXVzZSBcImRlYWRcIiBjaGFuZ2UgZGV0ZWN0aW9ucyAoYmFzaWNhbGx5IHdoZW4gdGhlIGB0aWNrKClgIGhhcyBiZWVuIHJ1biwgYnV0IHRoZXJlJ3Mgbm90aGluZyB0byB1cGRhdGUpLlxuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICB0aGlzLm9uQ2hhbmdlKHZhbHVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlT3B0aW9uVG9Nb25hY28oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdG9ySW5zdGFuY2UpIHtcbiAgICAgIHRoaXMuZWRpdG9ySW5zdGFuY2UudXBkYXRlT3B0aW9ucyh7IC4uLnRoaXMuZWRpdG9yT3B0aW9uQ2FjaGVkIH0pO1xuICAgIH1cbiAgfVxufVxuIl19