@tinymce/tinymce-angular
Version:
Official TinyMCE Angular Component
253 lines • 32.7 kB
JavaScript
/* eslint-disable @typescript-eslint/no-parameter-properties */
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { Component, forwardRef, Inject, Input, PLATFORM_ID, InjectionToken, Optional, ChangeDetectionStrategy } from '@angular/core';
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject, takeUntil } from 'rxjs';
import { getTinymce } from '../TinyMCE';
import { listenTinyMCEEvent, bindHandlers, isTextarea, mergePlugins, uuid, noop, isNullOrUndefined, setMode } from '../utils/Utils';
import * as DisabledUtils from '../utils/DisabledUtils';
import { Events } from './Events';
import { ScriptLoader } from '../utils/ScriptLoader';
import * as i0 from "@angular/core";
export const TINYMCE_SCRIPT_SRC = new InjectionToken('TINYMCE_SCRIPT_SRC');
const EDITOR_COMPONENT_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => EditorComponent),
multi: true
};
/**
* @see {@link https://www.tiny.cloud/docs/tinymce/7/angular-ref/} for the TinyMCE Angular Technical Reference
*/
export class EditorComponent extends Events {
cdRef;
platformId;
tinymceScriptSrc;
cloudChannel = '8';
apiKey = 'no-api-key';
licenseKey = 'gpl';
init;
id = '';
initialValue;
outputFormat;
inline;
tagName;
plugins;
toolbar;
modelEvents = 'change input undo redo';
allowedEvents;
ignoreEvents;
set readonly(val) {
this._readonly = val;
if (this._editor) {
setMode(this._editor, val ? 'readonly' : 'design');
}
}
get readonly() {
return this._readonly;
}
set disabled(val) {
this._disabled = val;
if (this._editor) {
if (DisabledUtils.isDisabledOptionSupported(this._editor)) {
this._editor.options.set('disabled', val ?? false);
}
else {
setMode(this._editor, val ? 'readonly' : 'design');
}
}
}
get disabled() {
return this._disabled;
}
get editor() {
return this._editor;
}
ngZone;
_elementRef;
_element;
_disabled;
_readonly;
_editor;
onTouchedCallback = noop;
onChangeCallback;
destroy$ = new Subject();
constructor(elementRef, ngZone, cdRef, platformId, tinymceScriptSrc) {
super();
this.cdRef = cdRef;
this.platformId = platformId;
this.tinymceScriptSrc = tinymceScriptSrc;
this._elementRef = elementRef;
this.ngZone = ngZone;
}
writeValue(value) {
if (this._editor && this._editor.initialized) {
this._editor.setContent(isNullOrUndefined(value) ? '' : value);
}
else {
this.initialValue = value === null ? undefined : value;
}
}
registerOnChange(fn) {
this.onChangeCallback = fn;
}
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
ngAfterViewInit() {
if (isPlatformBrowser(this.platformId)) {
this.id = this.id || uuid('tiny-angular');
this.inline = this.inline !== undefined ? this.inline !== false : !!(this.init?.inline);
this.createElement();
if (getTinymce() !== null) {
this.initialise();
}
else if (this._element && this._element.ownerDocument) {
// Caretaker note: the component might be destroyed before the script is loaded and its code is executed.
// This will lead to runtime exceptions if `initialise` will be called when the component has been destroyed.
ScriptLoader.load(this._element.ownerDocument, this.getScriptSrc())
.pipe(takeUntil(this.destroy$))
.subscribe(this.initialise);
}
}
}
ngOnDestroy() {
this.destroy$.next();
if (getTinymce() !== null) {
getTinymce().remove(this._editor);
}
}
createElement() {
const tagName = typeof this.tagName === 'string' ? this.tagName : 'div';
this._element = document.createElement(this.inline ? tagName : 'textarea');
if (this._element) {
const existingElement = document.getElementById(this.id);
if (existingElement && existingElement !== this._elementRef.nativeElement) {
/* eslint no-console: ["error", { allow: ["warn"] }] */
console.warn(`TinyMCE-Angular: an element with id [${this.id}] already exists. Editors with duplicate Id will not be able to mount`);
}
this._element.id = this.id;
if (isTextarea(this._element)) {
this._element.style.visibility = 'hidden';
}
this._elementRef.nativeElement.appendChild(this._element);
}
}
initialise = () => {
const finalInit = {
...this.init,
selector: undefined,
target: this._element,
inline: this.inline,
disabled: this.disabled,
readonly: this.readonly,
license_key: this.licenseKey,
plugins: mergePlugins((this.init && this.init.plugins), this.plugins),
toolbar: this.toolbar || (this.init && this.init.toolbar),
setup: (editor) => {
this._editor = editor;
listenTinyMCEEvent(editor, 'init', this.destroy$).subscribe(() => {
this.initEditor(editor);
});
bindHandlers(this, editor, this.destroy$);
if (this.init && typeof this.init.setup === 'function') {
this.init.setup(editor);
}
if (this.disabled === true) {
if (DisabledUtils.isDisabledOptionSupported(editor)) {
this._editor.options.set('disabled', this.disabled);
}
else {
this._editor.mode.set('readonly');
}
}
}
};
if (isTextarea(this._element)) {
this._element.style.visibility = '';
}
this.ngZone.runOutsideAngular(() => {
getTinymce().init(finalInit);
});
};
getScriptSrc() {
return isNullOrUndefined(this.tinymceScriptSrc) ?
`https://cdn.tiny.cloud/1/${this.apiKey}/tinymce/${this.cloudChannel}/tinymce.min.js` :
this.tinymceScriptSrc;
}
initEditor(editor) {
listenTinyMCEEvent(editor, 'blur', this.destroy$).subscribe(() => {
this.cdRef.markForCheck();
this.ngZone.run(() => this.onTouchedCallback());
});
listenTinyMCEEvent(editor, this.modelEvents, this.destroy$).subscribe(() => {
this.cdRef.markForCheck();
this.ngZone.run(() => this.emitOnChange(editor));
});
if (typeof this.initialValue === 'string') {
this.ngZone.run(() => {
editor.setContent(this.initialValue);
if (editor.getContent() !== this.initialValue) {
this.emitOnChange(editor);
}
if (this.onInitNgModel !== undefined) {
this.onInitNgModel.emit(editor);
}
});
}
}
emitOnChange(editor) {
if (this.onChangeCallback) {
this.onChangeCallback(editor.getContent({ format: this.outputFormat }));
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: EditorComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: PLATFORM_ID }, { token: TINYMCE_SCRIPT_SRC, optional: true }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.1.1", type: EditorComponent, isStandalone: true, selector: "editor", inputs: { cloudChannel: "cloudChannel", apiKey: "apiKey", licenseKey: "licenseKey", init: "init", id: "id", initialValue: "initialValue", outputFormat: "outputFormat", inline: "inline", tagName: "tagName", plugins: "plugins", toolbar: "toolbar", modelEvents: "modelEvents", allowedEvents: "allowedEvents", ignoreEvents: "ignoreEvents", readonly: "readonly", disabled: "disabled" }, providers: [EDITOR_COMPONENT_VALUE_ACCESSOR], usesInheritance: true, ngImport: i0, template: '', isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: EditorComponent, decorators: [{
type: Component,
args: [{ selector: 'editor', template: '', providers: [EDITOR_COMPONENT_VALUE_ACCESSOR], standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: Object, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [TINYMCE_SCRIPT_SRC]
}] }], propDecorators: { cloudChannel: [{
type: Input
}], apiKey: [{
type: Input
}], licenseKey: [{
type: Input
}], init: [{
type: Input
}], id: [{
type: Input
}], initialValue: [{
type: Input
}], outputFormat: [{
type: Input
}], inline: [{
type: Input
}], tagName: [{
type: Input
}], plugins: [{
type: Input
}], toolbar: [{
type: Input
}], modelEvents: [{
type: Input
}], allowedEvents: [{
type: Input
}], ignoreEvents: [{
type: Input
}], readonly: [{
type: Input
}], disabled: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RpbnltY2UtYW5ndWxhci1jb21wb25lbnQvc3JjL21haW4vdHMvZWRpdG9yL2VkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0RBQStEO0FBQy9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNsRSxPQUFPLEVBRUwsU0FBUyxFQUVULFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUdMLFdBQVcsRUFDWCxjQUFjLEVBQ2QsUUFBUSxFQUVSLHVCQUF1QixFQUN4QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDeEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDcEksT0FBTyxLQUFLLGFBQWEsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQVksTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7QUFLckQsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxjQUFjLENBQVMsb0JBQW9CLENBQUMsQ0FBQztBQUVuRixNQUFNLCtCQUErQixHQUFHO0lBQ3RDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxlQUFlLENB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SUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxRSxDQUFDO0lBQ0gsQ0FBQzt1R0FwTlUsZUFBZSxtR0FpRWhCLFdBQVcsYUFDQyxrQkFBa0I7MkZBbEU3QixlQUFlLG1iQVRmLENBQUUsK0JBQStCLENBQUUsaURBRnBDLEVBQUUsK0ZBSUQsWUFBWSw4QkFBRSxXQUFXOzsyRkFPekIsZUFBZTtrQkFiM0IsU0FBUzsrQkFDRSxRQUFRLFlBQ1IsRUFBRSxhQUVELENBQUUsK0JBQStCLENBQUUsY0FDbEMsSUFBSSxXQUNQLENBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBRSxtQkFDckIsdUJBQXVCLENBQUMsTUFBTTs7MEJBdUU1QyxNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLGtCQUFrQjt5Q0FoRXhCLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsTUFBTTtzQkFBckIsS0FBSztnQkFDVSxVQUFVO3NCQUF6QixLQUFLO2dCQUNVLElBQUk7c0JBQW5CLEtBQUs7Z0JBQ1UsRUFBRTtzQkFBakIsS0FBSztnQkFDVSxZQUFZO3NCQUEzQixLQUFLO2dCQUNVLFlBQVk7c0JBQTNCLEtBQUs7Z0JBQ1UsTUFBTTtzQkFBckIsS0FBSztnQkFDVSxPQUFPO3NCQUF0QixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFDVSxXQUFXO3NCQUExQixLQUFLO2dCQUNVLGFBQWE7c0JBQTVCLEtBQUs7Z0JBQ1UsWUFBWTtzQkFBM0IsS0FBSztnQkFFSyxRQUFRO3NCQURsQixLQUFLO2dCQWFLLFFBQVE7c0JBRGxCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcGFyYW1ldGVyLXByb3BlcnRpZXMgKi9cbmltcG9ydCB7IGlzUGxhdGZvcm1Ccm93c2VyLCBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uRGVzdHJveSxcbiAgUExBVEZPUk1fSUQsXG4gIEluamVjdGlvblRva2VuLFxuICBPcHRpb25hbCxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZ2V0VGlueW1jZSB9IGZyb20gJy4uL1RpbnlNQ0UnO1xuaW1wb3J0IHsgbGlzdGVuVGlueU1DRUV2ZW50LCBiaW5kSGFuZGxlcnMsIGlzVGV4dGFyZWEsIG1lcmdlUGx1Z2lucywgdXVpZCwgbm9vcCwgaXNOdWxsT3JVbmRlZmluZWQsIHNldE1vZGUgfSBmcm9tICcuLi91dGlscy9VdGlscyc7XG5pbXBvcnQgKiBhcyBEaXNhYmxlZFV0aWxzIGZyb20gJy4uL3V0aWxzL0Rpc2FibGVkVXRpbHMnO1xuaW1wb3J0IHsgRXZlbnRPYmosIEV2ZW50cyB9IGZyb20gJy4vRXZlbnRzJztcbmltcG9ydCB7IFNjcmlwdExvYWRlciB9IGZyb20gJy4uL3V0aWxzL1NjcmlwdExvYWRlcic7XG5pbXBvcnQgdHlwZSB7IEVkaXRvciBhcyBUaW55TUNFRWRpdG9yLCBUaW55TUNFIH0gZnJvbSAndGlueW1jZSc7XG5cbnR5cGUgRWRpdG9yT3B0aW9ucyA9IFBhcmFtZXRlcnM8VGlueU1DRVsnaW5pdCddPlswXTtcblxuZXhwb3J0IGNvbnN0IFRJTllNQ0VfU0NSSVBUX1NSQyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KCdUSU5ZTUNFX1NDUklQVF9TUkMnKTtcblxuY29uc3QgRURJVE9SX0NPTVBPTkVOVF9WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEVkaXRvckNvbXBvbmVudCksXG4gIG11bHRpOiB0cnVlXG59O1xuXG5leHBvcnQgdHlwZSBWZXJzaW9uID0gYCR7JzQnIHwgJzUnIHwgJzYnIHwgJzcnIHwgJzgnfSR7JycgfCAnLWRldicgfCAnLXRlc3RpbmcnIHwgYC4ke251bWJlcn1gIHwgYC4ke251bWJlcn0uJHtudW1iZXJ9YH1gO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdlZGl0b3InLFxuICB0ZW1wbGF0ZTogJycsXG4gIHN0eWxlczogWyAnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgfScgXSxcbiAgcHJvdmlkZXJzOiBbIEVESVRPUl9DT01QT05FTlRfVkFMVUVfQUNDRVNTT1IgXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogWyBDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlIF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuXG4vKipcbiAqIEBzZWUge0BsaW5rIGh0dHBzOi8vd3d3LnRpbnkuY2xvdWQvZG9jcy90aW55bWNlLzcvYW5ndWxhci1yZWYvfSBmb3IgdGhlIFRpbnlNQ0UgQW5ndWxhciBUZWNobmljYWwgUmVmZXJlbmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBFZGl0b3JDb21wb25lbnQgZXh0ZW5kcyBFdmVudHMgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25EZXN0cm95IHtcblxuICBASW5wdXQoKSBwdWJsaWMgY2xvdWRDaGFubmVsOiBWZXJzaW9uID0gJzgnO1xuICBASW5wdXQoKSBwdWJsaWMgYXBpS2V5ID0gJ25vLWFwaS1rZXknO1xuICBASW5wdXQoKSBwdWJsaWMgbGljZW5zZUtleSA9ICdncGwnO1xuICBASW5wdXQoKSBwdWJsaWMgaW5pdD86IEVkaXRvck9wdGlvbnM7XG4gIEBJbnB1dCgpIHB1YmxpYyBpZCA9ICcnO1xuICBASW5wdXQoKSBwdWJsaWMgaW5pdGlhbFZhbHVlPzogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgb3V0cHV0Rm9ybWF0PzogJ2h0bWwnIHwgJ3RleHQnO1xuICBASW5wdXQoKSBwdWJsaWMgaW5saW5lPzogYm9vbGVhbjtcbiAgQElucHV0KCkgcHVibGljIHRhZ05hbWU/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHB1YmxpYyBwbHVnaW5zPzogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgdG9vbGJhcj86IHN0cmluZyB8IHN0cmluZ1tdO1xuICBASW5wdXQoKSBwdWJsaWMgbW9kZWxFdmVudHMgPSAnY2hhbmdlIGlucHV0IHVuZG8gcmVkbyc7XG4gIEBJbnB1dCgpIHB1YmxpYyBhbGxvd2VkRXZlbnRzPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIEBJbnB1dCgpIHB1YmxpYyBpZ25vcmVFdmVudHM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgQElucHV0KClcbiAgcHVibGljIHNldCByZWFkb25seSh2YWwpIHtcbiAgICB0aGlzLl9yZWFkb25seSA9IHZhbDtcbiAgICBpZiAodGhpcy5fZWRpdG9yKSB7XG4gICAgICBzZXRNb2RlKHRoaXMuX2VkaXRvciwgdmFsID8gJ3JlYWRvbmx5JyA6ICdkZXNpZ24nKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IHJlYWRvbmx5KCkge1xuICAgIHJldHVybiB0aGlzLl9yZWFkb25seTtcbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBzZXQgZGlzYWJsZWQodmFsKSB7XG4gICAgdGhpcy5fZGlzYWJsZWQgPSB2YWw7XG4gICAgaWYgKHRoaXMuX2VkaXRvcikge1xuICAgICAgaWYgKERpc2FibGVkVXRpbHMuaXNEaXNhYmxlZE9wdGlvblN1cHBvcnRlZCh0aGlzLl9lZGl0b3IpKSB7XG4gICAgICAgIHRoaXMuX2VkaXRvci5vcHRpb25zLnNldCgnZGlzYWJsZWQnLCB2YWwgPz8gZmFsc2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2V0TW9kZSh0aGlzLl9lZGl0b3IsIHZhbCA/ICdyZWFkb25seScgOiAnZGVzaWduJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldCBkaXNhYmxlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGVkaXRvcigpIHtcbiAgICByZXR1cm4gdGhpcy5fZWRpdG9yO1xuICB9XG5cbiAgcHVibGljIG5nWm9uZTogTmdab25lO1xuXG4gIHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XG4gIHByaXZhdGUgX2VsZW1lbnQ/OiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBfZGlzYWJsZWQ/OiBib29sZWFuO1xuICBwcml2YXRlIF9yZWFkb25seT86IGJvb2xlYW47XG4gIHByaXZhdGUgX2VkaXRvcj86IFRpbnlNQ0VFZGl0b3I7XG5cbiAgcHJpdmF0ZSBvblRvdWNoZWRDYWxsYmFjayA9IG5vb3A7XG4gIHByaXZhdGUgb25DaGFuZ2VDYWxsYmFjazogYW55O1xuXG4gIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgY2RSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogT2JqZWN0LFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVElOWU1DRV9TQ1JJUFRfU1JDKSBwcml2YXRlIHRpbnltY2VTY3JpcHRTcmM/OiBzdHJpbmdcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9lbGVtZW50UmVmID0gZWxlbWVudFJlZjtcbiAgICB0aGlzLm5nWm9uZSA9IG5nWm9uZTtcbiAgfVxuXG4gIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2VkaXRvciAmJiB0aGlzLl9lZGl0b3IuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRoaXMuX2VkaXRvci5zZXRDb250ZW50KGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSA/ICcnIDogdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmluaXRpYWxWYWx1ZSA9IHZhbHVlID09PSBudWxsID8gdW5kZWZpbmVkIDogdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChfOiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWRDYWxsYmFjayA9IGZuO1xuICB9XG5cbiAgcHVibGljIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICB9XG5cbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgdGhpcy5pZCA9IHRoaXMuaWQgfHwgdXVpZCgndGlueS1hbmd1bGFyJyk7XG4gICAgICB0aGlzLmlubGluZSA9IHRoaXMuaW5saW5lICE9PSB1bmRlZmluZWQgPyB0aGlzLmlubGluZSAhPT0gZmFsc2UgOiAhISh0aGlzLmluaXQ/LmlubGluZSk7XG4gICAgICB0aGlzLmNyZWF0ZUVsZW1lbnQoKTtcbiAgICAgIGlmIChnZXRUaW55bWNlKCkgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXNlKCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX2VsZW1lbnQgJiYgdGhpcy5fZWxlbWVudC5vd25lckRvY3VtZW50KSB7XG4gICAgICAgIC8vIENhcmV0YWtlciBub3RlOiB0aGUgY29tcG9uZW50IG1pZ2h0IGJlIGRlc3Ryb3llZCBiZWZvcmUgdGhlIHNjcmlwdCBpcyBsb2FkZWQgYW5kIGl0cyBjb2RlIGlzIGV4ZWN1dGVkLlxuICAgICAgICAvLyBUaGlzIHdpbGwgbGVhZCB0byBydW50aW1lIGV4Y2VwdGlvbnMgaWYgYGluaXRpYWxpc2VgIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIGNvbXBvbmVudCBoYXMgYmVlbiBkZXN0cm95ZWQuXG4gICAgICAgIFNjcmlwdExvYWRlci5sb2FkKHRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudCwgdGhpcy5nZXRTY3JpcHRTcmMoKSlcbiAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgLnN1YnNjcmliZSh0aGlzLmluaXRpYWxpc2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcblxuICAgIGlmIChnZXRUaW55bWNlKCkgIT09IG51bGwpIHtcbiAgICAgIGdldFRpbnltY2UoKS5yZW1vdmUodGhpcy5fZWRpdG9yKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlRWxlbWVudCgpIHtcbiAgICBjb25zdCB0YWdOYW1lID0gdHlwZW9mIHRoaXMudGFnTmFtZSA9PT0gJ3N0cmluZycgPyB0aGlzLnRhZ05hbWUgOiAnZGl2JztcbiAgICB0aGlzLl9lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0aGlzLmlubGluZSA/IHRhZ05hbWUgOiAndGV4dGFyZWEnKTtcbiAgICBpZiAodGhpcy5fZWxlbWVudCkge1xuICAgICAgY29uc3QgZXhpc3RpbmdFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pZCk7XG4gICAgICBpZiAoZXhpc3RpbmdFbGVtZW50ICYmIGV4aXN0aW5nRWxlbWVudCAhPT0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSB7XG4gICAgICAgIC8qIGVzbGludCBuby1jb25zb2xlOiBbXCJlcnJvclwiLCB7IGFsbG93OiBbXCJ3YXJuXCJdIH1dICovXG4gICAgICAgIGNvbnNvbGUud2FybihgVGlueU1DRS1Bbmd1bGFyOiBhbiBlbGVtZW50IHdpdGggaWQgWyR7dGhpcy5pZH1dIGFscmVhZHkgZXhpc3RzLiBFZGl0b3JzIHdpdGggZHVwbGljYXRlIElkIHdpbGwgbm90IGJlIGFibGUgdG8gbW91bnRgKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2VsZW1lbnQuaWQgPSB0aGlzLmlkO1xuICAgICAgaWYgKGlzVGV4dGFyZWEodGhpcy5fZWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgICB9XG4gICAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5fZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGluaXRpYWxpc2UgPSAoKTogdm9pZCA9PiB7XG4gICAgY29uc3QgZmluYWxJbml0OiBFZGl0b3JPcHRpb25zID0ge1xuICAgICAgLi4udGhpcy5pbml0LFxuICAgICAgc2VsZWN0b3I6IHVuZGVmaW5lZCxcbiAgICAgIHRhcmdldDogdGhpcy5fZWxlbWVudCxcbiAgICAgIGlubGluZTogdGhpcy5pbmxpbmUsXG4gICAgICBkaXNhYmxlZDogdGhpcy5kaXNhYmxlZCxcbiAgICAgIHJlYWRvbmx5OiB0aGlzLnJlYWRvbmx5LFxuICAgICAgbGljZW5zZV9rZXk6IHRoaXMubGljZW5zZUtleSxcbiAgICAgIHBsdWdpbnM6IG1lcmdlUGx1Z2lucygodGhpcy5pbml0ICYmIHRoaXMuaW5pdC5wbHVnaW5zKSBhcyBzdHJpbmcsIHRoaXMucGx1Z2lucyksXG4gICAgICB0b29sYmFyOiB0aGlzLnRvb2xiYXIgfHwgKHRoaXMuaW5pdCAmJiB0aGlzLmluaXQudG9vbGJhciksXG4gICAgICBzZXR1cDogKGVkaXRvcjogVGlueU1DRUVkaXRvcikgPT4ge1xuICAgICAgICB0aGlzLl9lZGl0b3IgPSBlZGl0b3I7XG5cbiAgICAgICAgbGlzdGVuVGlueU1DRUV2ZW50KGVkaXRvciwgJ2luaXQnLCB0aGlzLmRlc3Ryb3kkKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaW5pdEVkaXRvcihlZGl0b3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBiaW5kSGFuZGxlcnModGhpcywgZWRpdG9yLCB0aGlzLmRlc3Ryb3kkKTtcblxuICAgICAgICBpZiAodGhpcy5pbml0ICYmIHR5cGVvZiB0aGlzLmluaXQuc2V0dXAgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aGlzLmluaXQuc2V0dXAoZWRpdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkID09PSB0cnVlKSB7XG4gICAgICAgICAgaWYgKERpc2FibGVkVXRpbHMuaXNEaXNhYmxlZE9wdGlvblN1cHBvcnRlZChlZGl0b3IpKSB7XG4gICAgICAgICAgICB0aGlzLl9lZGl0b3Iub3B0aW9ucy5zZXQoJ2Rpc2FibGVkJywgdGhpcy5kaXNhYmxlZCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2VkaXRvci5tb2RlLnNldCgncmVhZG9ubHknKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGlzVGV4dGFyZWEodGhpcy5fZWxlbWVudCkpIHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUudmlzaWJpbGl0eSA9ICcnO1xuICAgIH1cblxuICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGdldFRpbnltY2UoKS5pbml0KGZpbmFsSW5pdCk7XG4gICAgfSk7XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRTY3JpcHRTcmMoKSB7XG4gICAgcmV0dXJuIGlzTnVsbE9yVW5kZWZpbmVkKHRoaXMudGlueW1jZVNjcmlwdFNyYykgP1xuICAgICAgYGh0dHBzOi8vY2RuLnRpbnkuY2xvdWQvMS8ke3RoaXMuYXBpS2V5fS90aW55bWNlLyR7dGhpcy5jbG91ZENoYW5uZWx9L3RpbnltY2UubWluLmpzYCA6XG4gICAgICB0aGlzLnRpbnltY2VTY3JpcHRTcmM7XG4gIH1cblxuICBwcml2YXRlIGluaXRFZGl0b3IoZWRpdG9yOiBUaW55TUNFRWRpdG9yKSB7XG4gICAgbGlzdGVuVGlueU1DRUV2ZW50KGVkaXRvciwgJ2JsdXInLCB0aGlzLmRlc3Ryb3kkKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLm9uVG91Y2hlZENhbGxiYWNrKCkpO1xuICAgIH0pO1xuXG4gICAgbGlzdGVuVGlueU1DRUV2ZW50KGVkaXRvciwgdGhpcy5tb2RlbEV2ZW50cywgdGhpcy5kZXN0cm95JCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5lbWl0T25DaGFuZ2UoZWRpdG9yKSk7XG4gICAgfSk7XG5cbiAgICBpZiAodHlwZW9mIHRoaXMuaW5pdGlhbFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgZWRpdG9yLnNldENvbnRlbnQodGhpcy5pbml0aWFsVmFsdWUgYXMgc3RyaW5nKTtcbiAgICAgICAgaWYgKGVkaXRvci5nZXRDb250ZW50KCkgIT09IHRoaXMuaW5pdGlhbFZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5lbWl0T25DaGFuZ2UoZWRpdG9yKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vbkluaXROZ01vZGVsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLm9uSW5pdE5nTW9kZWwuZW1pdChlZGl0b3IgYXMgdW5rbm93biBhcyBFdmVudE9iajxhbnk+KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBlbWl0T25DaGFuZ2UoZWRpdG9yOiBUaW55TUNFRWRpdG9yKSB7XG4gICAgaWYgKHRoaXMub25DaGFuZ2VDYWxsYmFjaykge1xuICAgICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrKGVkaXRvci5nZXRDb250ZW50KHsgZm9ybWF0OiB0aGlzLm91dHB1dEZvcm1hdCB9KSk7XG4gICAgfVxuICB9XG59XG4iXX0=