@acrodata/code-editor
Version:
CodeMirror 6 wrapper for Angular
257 lines • 34.8 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation, booleanAttribute, forwardRef, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MergeView } from '@codemirror/merge';
import { Compartment } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { basicSetup, minimalSetup } from 'codemirror';
import { External } from './code-editor';
import * as i0 from "@angular/core";
export class DiffEditor {
constructor(_elementRef) {
this._elementRef = _elementRef;
/**
* The editor's built-in setup. The value can be set to
* [`basic`](https://codemirror.net/docs/ref/#codemirror.basicSetup),
* [`minimal`](https://codemirror.net/docs/ref/#codemirror.minimalSetup) or `null`.
*
* Don't support change dynamically!
*/
this.setup = 'basic';
/** The diff-editor's original value. */
this.originalValue = '';
/**
* The MergeView original config's
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*
* Don't support change dynamically!
*/
this.originalExtensions = [];
/** The diff-editor's modified value. */
this.modifiedValue = '';
/**
* The MergeView modified config's
* [extensions](https://codemirror.net/docs/ref/#state.EditorStateConfig.extensions).
*
* Don't support change dynamically!
*/
this.modifiedExtensions = [];
/**
* By default, the merge view will mark inserted and deleted text
* in changed chunks. Set this to false to turn that off.
*/
this.highlightChanges = true;
/** Controls whether a gutter marker is shown next to changed lines. */
this.gutter = true;
/** Whether the diff-editor is disabled. */
this.disabled = false;
/** Event emitted when the editor's original value changes. */
this.originalValueChange = new EventEmitter();
/** Event emitted when focus on the original editor. */
this.originalFocus = new EventEmitter();
/** Event emitted when blur on the original editor. */
this.originalBlur = new EventEmitter();
/** Event emitted when the editor's modified value changes. */
this.modifiedValueChange = new EventEmitter();
/** Event emitted when focus on the modified editor. */
this.modifiedFocus = new EventEmitter();
/** Event emitted when blur on the modified editor. */
this.modifiedBlur = new EventEmitter();
this._onChange = () => { };
this._onTouched = () => { };
this._updateListener = (editor) => {
return EditorView.updateListener.of(vu => {
if (vu.docChanged && !vu.transactions.some(tr => tr.annotation(External))) {
const value = vu.state.doc.toString();
if (editor == 'a') {
this._onChange({ original: value, modified: this.modifiedValue });
this.originalValue = value;
this.originalValueChange.emit(value);
}
else if (editor == 'b') {
this._onChange({ original: this.originalValue, modified: value });
this.modifiedValue = value;
this.modifiedValueChange.emit(value);
}
}
});
};
this._editableConf = new Compartment();
}
ngOnChanges(changes) {
if (changes['originalValue']) {
this.setValue('a', this.originalValue);
}
if (changes['modifiedValue']) {
this.setValue('b', this.modifiedValue);
}
if (changes['orientation']) {
this.mergeView?.reconfigure({ orientation: this.orientation });
}
if (changes['revertControls']) {
this.mergeView?.reconfigure({ revertControls: this.revertControls });
}
if (changes['renderRevertControl']) {
this.mergeView?.reconfigure({ renderRevertControl: this.renderRevertControl });
}
if (changes['highlightChanges']) {
this.mergeView?.reconfigure({ highlightChanges: this.highlightChanges });
}
if (changes['gutter']) {
this.mergeView?.reconfigure({ gutter: this.gutter });
}
if (changes['collapseUnchanged']) {
this.mergeView?.reconfigure({ collapseUnchanged: this.collapseUnchanged });
}
if (changes['diffConfig']) {
this.mergeView?.reconfigure({ diffConfig: this.diffConfig });
}
if (changes['disabled']) {
this.setEditable('a', !this.disabled);
this.setEditable('b', !this.disabled);
}
}
ngOnInit() {
this.mergeView = new MergeView({
parent: this._elementRef.nativeElement,
a: {
doc: this.originalValue,
extensions: [
this._updateListener('a'),
this._editableConf.of([]),
this.setup === 'basic' ? basicSetup : this.setup === 'minimal' ? minimalSetup : [],
...this.originalExtensions,
],
},
b: {
doc: this.modifiedValue,
extensions: [
this._updateListener('b'),
this._editableConf.of([]),
this.setup === 'basic' ? basicSetup : this.setup === 'minimal' ? minimalSetup : [],
...this.modifiedExtensions,
],
},
orientation: this.orientation,
revertControls: this.revertControls,
renderRevertControl: this.renderRevertControl,
highlightChanges: this.highlightChanges,
gutter: this.gutter,
collapseUnchanged: this.collapseUnchanged,
diffConfig: this.diffConfig,
});
this.mergeView?.a.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.originalFocus.emit();
});
this.mergeView?.a.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.originalBlur.emit();
});
this.mergeView?.b.contentDOM.addEventListener('focus', () => {
this._onTouched();
this.modifiedFocus.emit();
});
this.mergeView?.b.contentDOM.addEventListener('blur', () => {
this._onTouched();
this.modifiedBlur.emit();
});
this.setEditable('a', !this.disabled);
this.setEditable('b', !this.disabled);
}
ngOnDestroy() {
this.mergeView?.destroy();
}
writeValue(value) {
if (this.mergeView && value != null && typeof value === 'object') {
this.originalValue = value.original;
this.modifiedValue = value.modified;
this.setValue('a', value.original);
this.setValue('b', value.modified);
}
}
registerOnChange(fn) {
this._onChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.setEditable('a', !isDisabled);
this.setEditable('b', !isDisabled);
}
/** Sets diff-editor's value. */
setValue(editor, value) {
this.mergeView?.[editor].dispatch({
changes: { from: 0, to: this.mergeView[editor].state.doc.length, insert: value },
});
}
/** Sets diff-editor's editable state. */
setEditable(editor, value) {
this.mergeView?.[editor].dispatch({
effects: this._editableConf.reconfigure(EditorView.editable.of(value)),
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: DiffEditor, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.2.8", type: DiffEditor, isStandalone: true, selector: "diff-editor", inputs: { setup: "setup", originalValue: "originalValue", originalExtensions: "originalExtensions", modifiedValue: "modifiedValue", modifiedExtensions: "modifiedExtensions", orientation: "orientation", revertControls: "revertControls", renderRevertControl: "renderRevertControl", highlightChanges: ["highlightChanges", "highlightChanges", booleanAttribute], gutter: ["gutter", "gutter", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], collapseUnchanged: "collapseUnchanged", diffConfig: "diffConfig" }, outputs: { originalValueChange: "originalValueChange", originalFocus: "originalFocus", originalBlur: "originalBlur", modifiedValueChange: "modifiedValueChange", modifiedFocus: "modifiedFocus", modifiedBlur: "modifiedBlur" }, host: { classAttribute: "diff-editor" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DiffEditor),
multi: true,
},
], usesOnChanges: true, ngImport: i0, template: ``, isInline: true, styles: [".diff-editor{display:block}.diff-editor :is(.cm-mergeView,.cm-mergeViewEditors){height:100%}.diff-editor :is(.cm-mergeView .cm-editor,.cm-mergeView .cm-scroller){height:100%!important}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: DiffEditor, decorators: [{
type: Component,
args: [{ selector: 'diff-editor', standalone: true, template: ``, host: {
class: 'diff-editor',
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DiffEditor),
multi: true,
},
], styles: [".diff-editor{display:block}.diff-editor :is(.cm-mergeView,.cm-mergeViewEditors){height:100%}.diff-editor :is(.cm-mergeView .cm-editor,.cm-mergeView .cm-scroller){height:100%!important}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { setup: [{
type: Input
}], originalValue: [{
type: Input
}], originalExtensions: [{
type: Input
}], modifiedValue: [{
type: Input
}], modifiedExtensions: [{
type: Input
}], orientation: [{
type: Input
}], revertControls: [{
type: Input
}], renderRevertControl: [{
type: Input
}], highlightChanges: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], gutter: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], collapseUnchanged: [{
type: Input
}], diffConfig: [{
type: Input
}], originalValueChange: [{
type: Output
}], originalFocus: [{
type: Output
}], originalBlur: [{
type: Output
}], modifiedValueChange: [{
type: Output
}], modifiedFocus: [{
type: Output
}], modifiedBlur: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi1lZGl0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9jb2RlLWVkaXRvci9kaWZmLWVkaXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sRUFFTixpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLFVBQVUsR0FDWCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFjLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLEVBQWEsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFdEQsT0FBTyxFQUFFLFFBQVEsRUFBUyxNQUFNLGVBQWUsQ0FBQzs7QUEyQ2hELE1BQU0sT0FBTyxVQUFVO0lBcUZyQixZQUFvQixXQUFnQztRQUFoQyxnQkFBVyxHQUFYLFdBQVcsQ0FBcUI7UUFwRnBEOzs7Ozs7V0FNRztRQUNNLFVBQUssR0FBVSxPQUFPLENBQUM7UUFFaEMsd0NBQXdDO1FBQy9CLGtCQUFhLEdBQVcsRUFBRSxDQUFDO1FBRXBDOzs7OztXQUtHO1FBQ00sdUJBQWtCLEdBQWdCLEVBQUUsQ0FBQztRQUU5Qyx3Q0FBd0M7UUFDL0Isa0JBQWEsR0FBVyxFQUFFLENBQUM7UUFFcEM7Ozs7O1dBS0c7UUFDTSx1QkFBa0IsR0FBZ0IsRUFBRSxDQUFDO1FBVzlDOzs7V0FHRztRQUNxQyxxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFFaEUsdUVBQXVFO1FBQy9CLFdBQU0sR0FBRyxJQUFJLENBQUM7UUFFdEQsMkNBQTJDO1FBQ0gsYUFB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QyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRTtnQkFHRSxNQUFNO3NCQUE3QyxLQUFLO3VCQUFDLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFO2dCQUdFLFFBQVE7c0JBQS9DLEtBQUs7dUJBQUMsRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBUTdCLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxVQUFVO3NCQUFsQixLQUFLO2dCQUdJLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFHRyxhQUFhO3NCQUF0QixNQUFNO2dCQUdHLFlBQVk7c0JBQXJCLE1BQU07Z0JBR0csbUJBQW1CO3NCQUE1QixNQUFNO2dCQUdHLGFBQWE7c0JBQXRCLE1BQU07Z0JBR0csWUFBWTtzQkFBckIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIGZvcndhcmRSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBEaWZmQ29uZmlnLCBNZXJnZVZpZXcgfSBmcm9tICdAY29kZW1pcnJvci9tZXJnZSc7XG5pbXBvcnQgeyBDb21wYXJ0bWVudCwgRXh0ZW5zaW9uIH0gZnJvbSAnQGNvZGVtaXJyb3Ivc3RhdGUnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHsgYmFzaWNTZXR1cCwgbWluaW1hbFNldHVwIH0gZnJvbSAnY29kZW1pcnJvcic7XG5cbmltcG9ydCB7IEV4dGVybmFsLCBTZXR1cCB9IGZyb20gJy4vY29kZS1lZGl0b3InO1xuXG5leHBvcnQgdHlwZSBPcmllbnRhdGlvbiA9ICdhLWInIHwgJ2ItYSc7XG5leHBvcnQgdHlwZSBSZXZlcnRDb250cm9scyA9ICdhLXRvLWInIHwgJ2ItdG8tYSc7XG5leHBvcnQgdHlwZSBSZW5kZXJSZXZlcnRDb250cm9sID0gKCkgPT4gSFRNTEVsZW1lbnQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGlmZkVkaXRvck1vZGVsIHtcbiAgb3JpZ2luYWw6IHN0cmluZztcbiAgbW9kaWZpZWQ6IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZGlmZi1lZGl0b3InLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICB0ZW1wbGF0ZTogYGAsXG4gIHN0eWxlczogYFxuICAgIC5kaWZmLWVkaXRvciB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcblxuICAgICAgLmNtLW1lcmdlVmlldyxcbiAgICAgIC5jbS1tZXJnZVZpZXdFZGl0b3JzIHtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgfVxuXG4gICAgICAuY20tbWVyZ2VWaWV3IC5jbS1lZGl0b3IsXG4gICAgICAuY20tbWVyZ2VWaWV3IC5jbS1zY3JvbGxlciB7XG4gICAgICAgIGhlaWdodDogMTAwJSAhaW1wb3J0YW50O1xuICAgICAgfVxuICAgIH1cbiAgYCxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnZGlmZi1lZGl0b3InLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEaWZmRWRpdG9yKSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIERpZmZFZGl0b3IgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yJ3MgYnVpbHQtaW4gc2V0dXAuIFRoZSB2YWx1ZSBjYW4gYmUgc2V0IHRvXG4gICAqIFtgYmFzaWNgXShodHRwczovL2NvZGVtaXJyb3IubmV0L2RvY3MvcmVmLyNjb2RlbWlycm9yLmJhc2ljU2V0dXApLFxuICAgKiBbYG1pbmltYWxgXShodHRwczovL2NvZGVtaXJyb3IubmV0L2RvY3MvcmVmLyNjb2RlbWlycm9yLm1pbmltYWxTZXR1cCkgb3IgYG51bGxgLlxuICAgKlxuICAgKiBEb24ndCBzdXBwb3J0IGNoYW5nZSBkeW5hbWljYWxseSFcbiAgICovXG4gIEBJbnB1dCgpIHNldHVwOiBTZXR1cCA9ICdiYXNpYyc7XG5cbiAgLyoqIFRoZSBkaWZmLWVkaXRvcidzIG9yaWdpbmFsIHZhbHVlLiAqL1xuICBASW5wdXQoKSBvcmlnaW5hbFZhbHVlOiBzdHJpbmcgPSAnJztcblxuICAvKipcbiAgICogVGhlIE1lcmdlVmlldyBvcmlnaW5hbCBjb25maWcnc1xuICAgKiBbZXh0ZW5zaW9uc10oaHR0cHM6Ly9jb2RlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGVDb25maWcuZXh0ZW5zaW9ucykuXG4gICAqXG4gICAqIERvbid0IHN1cHBvcnQgY2hhbmdlIGR5bmFtaWNhbGx5IVxuICAgKi9cbiAgQElucHV0KCkgb3JpZ2luYWxFeHRlbnNpb25zOiBFeHRlbnNpb25bXSA9IFtdO1xuXG4gIC8qKiBUaGUgZGlmZi1lZGl0b3IncyBtb2RpZmllZCB2YWx1ZS4gKi9cbiAgQElucHV0KCkgbW9kaWZpZWRWYWx1ZTogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIFRoZSBNZXJnZVZpZXcgbW9kaWZpZWQgY29uZmlnJ3NcbiAgICogW2V4dGVuc2lvbnNdKGh0dHBzOi8vY29kZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkVkaXRvclN0YXRlQ29uZmlnLmV4dGVuc2lvbnMpLlxuICAgKlxuICAgKiBEb24ndCBzdXBwb3J0IGNoYW5nZSBkeW5hbWljYWxseSFcbiAgICovXG4gIEBJbnB1dCgpIG1vZGlmaWVkRXh0ZW5zaW9uczogRXh0ZW5zaW9uW10gPSBbXTtcblxuICAvKiogQ29udHJvbHMgd2hldGhlciBlZGl0b3IgQSBvciBlZGl0b3IgQiBpcyBzaG93biBmaXJzdC4gRGVmYXVsdHMgdG8gYFwiYS1iXCJgLiAqL1xuICBASW5wdXQoKSBvcmllbnRhdGlvbj86IE9yaWVudGF0aW9uO1xuXG4gIC8qKiBDb250cm9scyB3aGV0aGVyIHJldmVydCBjb250cm9scyBhcmUgc2hvd24gYmV0d2VlbiBjaGFuZ2VkIGNodW5rcy4gKi9cbiAgQElucHV0KCkgcmV2ZXJ0Q29udHJvbHM/OiBSZXZlcnRDb250cm9scztcblxuICAvKiogV2hlbiBnaXZlbiwgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgdG8gcmVuZGVyIHRoZSBidXR0b24gdG8gcmV2ZXJ0IGEgY2h1bmsuICovXG4gIEBJbnB1dCgpIHJlbmRlclJldmVydENvbnRyb2w/OiBSZW5kZXJSZXZlcnRDb250cm9sO1xuXG4gIC8qKlxuICAgKiBCeSBkZWZhdWx0LCB0aGUgbWVyZ2UgdmlldyB3aWxsIG1hcmsgaW5zZXJ0ZWQgYW5kIGRlbGV0ZWQgdGV4dFxuICAgKiBpbiBjaGFuZ2VkIGNodW5rcy4gU2V0IHRoaXMgdG8gZmFsc2UgdG8gdHVybiB0aGF0IG9mZi5cbiAgICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBoaWdobGlnaHRDaGFuZ2VzID0gdHJ1ZTtcblxuICAvKiogQ29udHJvbHMgd2hldGhlciBhIGd1dHRlciBtYXJrZXIgaXMgc2hvd24gbmV4dCB0byBjaGFuZ2VkIGxpbmVzLiAqL1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgZ3V0dGVyID0gdHJ1ZTtcblxuICAvKiogV2hldGhlciB0aGUgZGlmZi1lZGl0b3IgaXMgZGlzYWJsZWQuICovXG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGVuIGdpdmVuLCBsb25nIHN0cmV0Y2hlcyBvZiB1bmNoYW5nZWQgdGV4dCBhcmUgY29sbGFwc2VkLlxuICAgKiBgbWFyZ2luYCBnaXZlcyB0aGUgbnVtYmVyIG9mIGxpbmVzIHRvIGxlYXZlIHZpc2libGUgYWZ0ZXIvYmVmb3JlXG4gICAqIGEgY2hhbmdlIChkZWZhdWx0IGlzIDMpLCBhbmQgYG1pblNpemVgIGdpdmVzIHRoZSBtaW5pbXVtIGFtb3VudFxuICAgKiBvZiBjb2xsYXBzaWJsZSBsaW5lcyB0aGF0IG5lZWQgdG8gYmUgcHJlc2VudCAoZGVmYXVsdHMgdG8gNCkuXG4gICAqL1xuICBASW5wdXQoKSBjb2xsYXBzZVVuY2hhbmdlZD86IHsgbWFyZ2luPzogbnVtYmVyOyBtaW5TaXplPzogbnVtYmVyIH07XG5cbiAgLyoqIFBhc3Mgb3B0aW9ucyB0byB0aGUgZGlmZiBhbGdvcml0aG0uICovXG4gIEBJbnB1dCgpIGRpZmZDb25maWc/OiBEaWZmQ29uZmlnO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGVkaXRvcidzIG9yaWdpbmFsIHZhbHVlIGNoYW5nZXMuICovXG4gIEBPdXRwdXQoKSBvcmlnaW5hbFZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiBmb2N1cyBvbiB0aGUgb3JpZ2luYWwgZWRpdG9yLiAqL1xuICBAT3V0cHV0KCkgb3JpZ2luYWxGb2N1cyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIGJsdXIgb24gdGhlIG9yaWdpbmFsIGVkaXRvci4gKi9cbiAgQE91dHB1dCgpIG9yaWdpbmFsQmx1ciA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBlZGl0b3IncyBtb2RpZmllZCB2YWx1ZSBjaGFuZ2VzLiAqL1xuICBAT3V0cHV0KCkgbW9kaWZpZWRWYWx1ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gZm9jdXMgb24gdGhlIG1vZGlmaWVkIGVkaXRvci4gKi9cbiAgQE91dHB1dCgpIG1vZGlmaWVkRm9jdXMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiBibHVyIG9uIHRoZSBtb2RpZmllZCBlZGl0b3IuICovXG4gIEBPdXRwdXQoKSBtb2RpZmllZEJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSBfb25DaGFuZ2U6ICh2YWx1ZTogRGlmZkVkaXRvck1vZGVsKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgX29uVG91Y2hlZDogKCkgPT4gdm9pZCA9ICgpID0+IHt9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8RWxlbWVudD4pIHt9XG5cbiAgLyoqIFRoZSBtZXJnZSB2aWV3IGluc3RhbmNlLiAqL1xuICBtZXJnZVZpZXc/OiBNZXJnZVZpZXc7XG5cbiAgcHJpdmF0ZSBfdXBkYXRlTGlzdGVuZXIgPSAoZWRpdG9yOiAnYScgfCAnYicpID0+IHtcbiAgICByZXR1cm4gRWRpdG9yVmlldy51cGRhdGVMaXN0ZW5lci5vZih2dSA9PiB7XG4gICAgICBpZiAodnUuZG9jQ2hhbmdlZCAmJiAhdnUudHJhbnNhY3Rpb25zLnNvbWUodHIgPT4gdHIuYW5ub3RhdGlvbihFeHRlcm5hbCkpKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdnUuc3RhdGUuZG9jLnRvU3RyaW5nKCk7XG4gICAgICAgIGlmIChlZGl0b3IgPT0gJ2EnKSB7XG4gICAgICAgICAgdGhpcy5fb25DaGFuZ2UoeyBvcmlnaW5hbDogdmFsdWUsIG1vZGlmaWVkOiB0aGlzLm1vZGlmaWVkVmFsdWUgfSk7XG4gICAgICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlQ2hhbmdlLmVtaXQodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGVkaXRvciA9PSAnYicpIHtcbiAgICAgICAgICB0aGlzLl9vbkNoYW5nZSh7IG9yaWdpbmFsOiB0aGlzLm9yaWdpbmFsVmFsdWUsIG1vZGlmaWVkOiB2YWx1ZSB9KTtcbiAgICAgICAgICB0aGlzLm1vZGlmaWVkVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICB0aGlzLm1vZGlmaWVkVmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIF9lZGl0YWJsZUNvbmYgPSBuZXcgQ29tcGFydG1lbnQoKTtcblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXNbJ29yaWdpbmFsVmFsdWUnXSkge1xuICAgICAgdGhpcy5zZXRWYWx1ZSgnYScsIHRoaXMub3JpZ2luYWxWYWx1ZSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydtb2RpZmllZFZhbHVlJ10pIHtcbiAgICAgIHRoaXMuc2V0VmFsdWUoJ2InLCB0aGlzLm1vZGlmaWVkVmFsdWUpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snb3JpZW50YXRpb24nXSkge1xuICAgICAgdGhpcy5tZXJnZVZpZXc/LnJlY29uZmlndXJlKHsgb3JpZW50YXRpb246IHRoaXMub3JpZW50YXRpb24gfSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydyZXZlcnRDb250cm9scyddKSB7XG4gICAgICB0aGlzLm1lcmdlVmlldz8ucmVjb25maWd1cmUoeyByZXZlcnRDb250cm9sczogdGhpcy5yZXZlcnRDb250cm9scyB9KTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ3JlbmRlclJldmVydENvbnRyb2wnXSkge1xuICAgICAgdGhpcy5tZXJnZVZpZXc/LnJlY29uZmlndXJlKHsgcmVuZGVyUmV2ZXJ0Q29udHJvbDogdGhpcy5yZW5kZXJSZXZlcnRDb250cm9sIH0pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snaGlnaGxpZ2h0Q2hhbmdlcyddKSB7XG4gICAgICB0aGlzLm1lcmdlVmlldz8ucmVjb25maWd1cmUoeyBoaWdobGlnaHRDaGFuZ2VzOiB0aGlzLmhpZ2hsaWdodENoYW5nZXMgfSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydndXR0ZXInXSkge1xuICAgICAgdGhpcy5tZXJnZVZpZXc/LnJlY29uZmlndXJlKHsgZ3V0dGVyOiB0aGlzLmd1dHRlciB9KTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ2NvbGxhcHNlVW5jaGFuZ2VkJ10pIHtcbiAgICAgIHRoaXMubWVyZ2VWaWV3Py5yZWNvbmZpZ3VyZSh7IGNvbGxhcHNlVW5jaGFuZ2VkOiB0aGlzLmNvbGxhcHNlVW5jaGFuZ2VkIH0pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlc1snZGlmZkNvbmZpZyddKSB7XG4gICAgICB0aGlzLm1lcmdlVmlldz8ucmVjb25maWd1cmUoeyBkaWZmQ29uZmlnOiB0aGlzLmRpZmZDb25maWcgfSk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWydkaXNhYmxlZCddKSB7XG4gICAgICB0aGlzLnNldEVkaXRhYmxlKCdhJywgIXRoaXMuZGlzYWJsZWQpO1xuICAgICAgdGhpcy5zZXRFZGl0YWJsZSgnYicsICF0aGlzLmRpc2FibGVkKTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm1lcmdlVmlldyA9IG5ldyBNZXJnZVZpZXcoe1xuICAgICAgcGFyZW50OiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXG4gICAgICBhOiB7XG4gICAgICAgIGRvYzogdGhpcy5vcmlnaW5hbFZhbHVlLFxuICAgICAgICBleHRlbnNpb25zOiBbXG4gICAgICAgICAgdGhpcy5fdXBkYXRlTGlzdGVuZXIoJ2EnKSxcbiAgICAgICAgICB0aGlzLl9lZGl0YWJsZUNvbmYub2YoW10pLFxuICAgICAgICAgIHRoaXMuc2V0dXAgPT09ICdiYXNpYycgPyBiYXNpY1NldHVwIDogdGhpcy5zZXR1cCA9PT0gJ21pbmltYWwnID8gbWluaW1hbFNldHVwIDogW10sXG4gICAgICAgICAgLi4udGhpcy5vcmlnaW5hbEV4dGVuc2lvbnMsXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAgYjoge1xuICAgICAgICBkb2M6IHRoaXMubW9kaWZpZWRWYWx1ZSxcbiAgICAgICAgZXh0ZW5zaW9uczogW1xuICAgICAgICAgIHRoaXMuX3VwZGF0ZUxpc3RlbmVyKCdiJyksXG4gICAgICAgICAgdGhpcy5fZWRpdGFibGVDb25mLm9mKFtdKSxcbiAgICAgICAgICB0aGlzLnNldHVwID09PSAnYmFzaWMnID8gYmFzaWNTZXR1cCA6IHRoaXMuc2V0dXAgPT09ICdtaW5pbWFsJyA/IG1pbmltYWxTZXR1cCA6IFtdLFxuICAgICAgICAgIC4uLnRoaXMubW9kaWZpZWRFeHRlbnNpb25zLFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICAgIG9yaWVudGF0aW9uOiB0aGlzLm9yaWVudGF0aW9uLFxuICAgICAgcmV2ZXJ0Q29udHJvbHM6IHRoaXMucmV2ZXJ0Q29udHJvbHMsXG4gICAgICByZW5kZXJSZXZlcnRDb250cm9sOiB0aGlzLnJlbmRlclJldmVydENvbnRyb2wsXG4gICAgICBoaWdobGlnaHRDaGFuZ2VzOiB0aGlzLmhpZ2hsaWdodENoYW5nZXMsXG4gICAgICBndXR0ZXI6IHRoaXMuZ3V0dGVyLFxuICAgICAgY29sbGFwc2VVbmNoYW5nZWQ6IHRoaXMuY29sbGFwc2VVbmNoYW5nZWQsXG4gICAgICBkaWZmQ29uZmlnOiB0aGlzLmRpZmZDb25maWcsXG4gICAgfSk7XG5cbiAgICB0aGlzLm1lcmdlVmlldz8uYS5jb250ZW50RE9NLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgdGhpcy5fb25Ub3VjaGVkKCk7XG4gICAgICB0aGlzLm9yaWdpbmFsRm9jdXMuZW1pdCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tZXJnZVZpZXc/LmEuY29udGVudERPTS5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgKCkgPT4ge1xuICAgICAgdGhpcy5fb25Ub3VjaGVkKCk7XG4gICAgICB0aGlzLm9yaWdpbmFsQmx1ci5lbWl0KCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1lcmdlVmlldz8uYi5jb250ZW50RE9NLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgdGhpcy5fb25Ub3VjaGVkKCk7XG4gICAgICB0aGlzLm1vZGlmaWVkRm9jdXMuZW1pdCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5tZXJnZVZpZXc/LmIuY29udGVudERPTS5hZGRFdmVudExpc3RlbmVyKCdibHVyJywgKCkgPT4ge1xuICAgICAgdGhpcy5fb25Ub3VjaGVkKCk7XG4gICAgICB0aGlzLm1vZGlmaWVkQmx1ci5lbWl0KCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNldEVkaXRhYmxlKCdhJywgIXRoaXMuZGlzYWJsZWQpO1xuICAgIHRoaXMuc2V0RWRpdGFibGUoJ2InLCAhdGhpcy5kaXNhYmxlZCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLm1lcmdlVmlldz8uZGVzdHJveSgpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogRGlmZkVkaXRvck1vZGVsKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubWVyZ2VWaWV3ICYmIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgdGhpcy5vcmlnaW5hbFZhbHVlID0gdmFsdWUub3JpZ2luYWw7XG4gICAgICB0aGlzLm1vZGlmaWVkVmFsdWUgPSB2YWx1ZS5tb2RpZmllZDtcbiAgICAgIHRoaXMuc2V0VmFsdWUoJ2EnLCB2YWx1ZS5vcmlnaW5hbCk7XG4gICAgICB0aGlzLnNldFZhbHVlKCdiJywgdmFsdWUubW9kaWZpZWQpO1xuICAgIH1cbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogRGlmZkVkaXRvck1vZGVsKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5fb25Ub3VjaGVkID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB0aGlzLnNldEVkaXRhYmxlKCdhJywgIWlzRGlzYWJsZWQpO1xuICAgIHRoaXMuc2V0RWRpdGFibGUoJ2InLCAhaXNEaXNhYmxlZCk7XG4gIH1cblxuICAvKiogU2V0cyBkaWZmLWVkaXRvcidzIHZhbHVlLiAqL1xuICBzZXRWYWx1ZShlZGl0b3I6ICdhJyB8ICdiJywgdmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMubWVyZ2VWaWV3Py5bZWRpdG9yXS5kaXNwYXRjaCh7XG4gICAgICBjaGFuZ2VzOiB7IGZyb206IDAsIHRvOiB0aGlzLm1lcmdlVmlld1tlZGl0b3JdLnN0YXRlLmRvYy5sZW5ndGgsIGluc2VydDogdmFsdWUgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBTZXRzIGRpZmYtZWRpdG9yJ3MgZWRpdGFibGUgc3RhdGUuICovXG4gIHNldEVkaXRhYmxlKGVkaXRvcjogJ2EnIHwgJ2InLCB2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMubWVyZ2VWaWV3Py5bZWRpdG9yXS5kaXNwYXRjaCh7XG4gICAgICBlZmZlY3RzOiB0aGlzLl9lZGl0YWJsZUNvbmYucmVjb25maWd1cmUoRWRpdG9yVmlldy5lZGl0YWJsZS5vZih2YWx1ZSkpLFxuICAgIH0pO1xuICB9XG59XG4iXX0=