raonkeditor-angular
Version:
Angular component for RAON K Editor.
374 lines • 46.2 kB
JavaScript
/**
* @license Copyright (c) 2003-2022, RAONWIZ DevTeam. All rights reserved.
*/
import { Component, NgZone, Input, Output, EventEmitter, forwardRef, ElementRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { getRaonwizComponentNamespace } from 'raonwiz-integrations-common';
export class RaonkEditorComponent {
constructor(elementRef, ngZone) {
this.elementRef = elementRef;
this.ngZone = ngZone;
/**
* The id of the component
*/
this.id = "";
/**
* The component type
*/
this.componentType = 'RAONKEDITOR';
/**
* RAON K Editor script url address. Script will be loaded only if RAONKEDITOR namespace is missing.
*/
this.componentUrl = '/raonkeditor/js/raonkeditor.js';
/**
* Tag name of the component.
*
* The default tag is `div`.
*/
this.tagName = 'div';
/**
* The runtimes of the component interface.
*/
this.runtimes = "html5" /* HTML5 */;
/**
* Fired when the component namespace
* is loaded. It only triggers once, no matter how many components are initialised.
*/
this.namespaceLoaded = new EventEmitter();
this.change = new EventEmitter();
/**
* event.
*/
this.creationComplete = new EventEmitter();
this.afterChangeMode = new EventEmitter();
this.onError = new EventEmitter();
this.onLanguageDefinition = new EventEmitter();
this.afterPopupShow = new EventEmitter();
this.agentInstall = new EventEmitter();
this.beforeInsertUrl = new EventEmitter();
this.mouse = new EventEmitter();
this.command = new EventEmitter();
this.key = new EventEmitter();
this.resized = new EventEmitter();
this.documentEditComplete = new EventEmitter();
this.pasteImage = new EventEmitter();
this.wordCount = new EventEmitter();
this.beforePaste = new EventEmitter();
this.customAction = new EventEmitter();
this.fullScreen = new EventEmitter();
this.setComplete = new EventEmitter();
this.setInsertComplete = new EventEmitter();
this.closeInstallPopup = new EventEmitter();
this.setForbiddenWordComplete = new EventEmitter();
this.drag = new EventEmitter();
this.focus = new EventEmitter();
this.dialogLoaded = new EventEmitter();
this.beforeInsertHyperlink = new EventEmitter();
/**
* If the component is view-mode before the component instance is created, it remembers that state,
* so the component can become view-mode once it is ready.
*/
this._readOnly = null;
this._viewMode = null;
this._data = null;
this._destroyed = false;
}
/**
* Keeps track of the component's data.
*
* It's also decorated as an input which is useful when not using the ngModel.
*
* See https://angular.io/api/forms/NgModel to learn more.
*/
set data(data) {
console.log("this.id: " + this.id + ", data : " + data);
if (data === this._data) {
return;
}
if (this.instance) {
RAONKEDITOR.SetHtmlContents(data, this.id);
return;
}
this._data = data;
}
get data() {
return this._data;
}
/**
* When set to `true`, the editor becomes readonly mode.
*/
set readOnly(isReadOnly) {
if (this.instance) {
RAONKEDITOR.SetReadOnly(isReadOnly, '', this.id);
return;
}
// Delay setting mode
this._readOnly = isReadOnly;
}
get readOnly() {
if (this.instance) {
return RAONKEDITOR.GetEditorByName(this.id)._BODY.contentEditable;
}
return this._readOnly;
}
/**
* When set to `true`, the editor becomes view mode.
*/
set viewMode(isViewMode) {
if (this.instance) {
RAONKEDITOR.SetEditorMode(isViewMode ? 'view' : 'edit', this.id);
return;
}
// Delay setting mode
this._viewMode = isViewMode;
}
get viewMode() {
if (this.instance) {
let retValue;
switch (RAONKEDITOR.GetEditorByName(this.id)._config.mode.toLowerCase()) {
case 'edit':
retValue = false;
break;
default:
retValue = true;
break;
}
return retValue;
}
return this._viewMode;
}
ngAfterViewInit() {
getRaonwizComponentNamespace(this.componentType, this.componentUrl, namespace => {
this.namespaceLoaded.emit(namespace);
}).then((namespace) => {
// Check if component instance was destroyed before `ngAfterViewInit` call (#110).
// Here, `this.instance` is still not initialized and so additional flag is needed.
if (this._destroyed) {
return;
}
this.ngZone.runOutsideAngular(this.createComponent.bind(this, namespace));
}).catch(window.console.error);
}
ngOnDestroy() {
this._destroyed = true;
this.ngZone.runOutsideAngular(() => {
if (this.instance) {
if (RAONKEDITOR._ExternalComponentMap.has(this.id)) {
RAONKEDITOR._ExternalComponentMap.delete(this.id);
}
if (RAONKEDITOR._ExternalEventRetValueMap.has(this.id)) {
RAONKEDITOR._ExternalEventRetValueMap.delete(this.id);
}
RAONKEDITOR.Destroy(this.id, false);
this.instance = null;
}
});
}
writeValue(value) {
this.data = value;
}
registerOnChange(callback) {
this.onChange = callback;
}
registerOnTouched(callback) {
this.onTouched = callback;
}
getComponentUniqueName() {
return "raonkeditor_" + Math.random()
.toString(36)
.replace(/[^a-z]+/g, '')
.substr(0, 5);
}
createComponent(namespace) {
let _uniqueName = this.getComponentUniqueName();
(typeof this.id === 'undefined') && (this.id = _uniqueName);
const element = document.createElement(this.tagName);
element.id = "componentHolder_" + _uniqueName;
this.elementRef.nativeElement.appendChild(element);
// view state may change during instance initialization.
(this._viewMode !== null) && (this.viewMode = this._viewMode);
// default config
let _compConfig = {
Id: this.id,
EditorHolder: element.id,
Runtimes: this.runtimes,
Mode: this._viewMode ? 'view' : 'edit',
ReturnEventKeyboard: '1',
ReturnEventFocus: '1',
ReturnEventCommand: '1',
Event: this.subscribe()
};
_compConfig = namespace.util.objectExtend(true, this.config, _compConfig);
// for event callback
(typeof namespace._ExternalComponentMap === 'undefined') && (namespace._ExternalComponentMap = new Map());
namespace._ExternalComponentMap.set(this.id, this);
(typeof namespace._ExternalEventRetValueMap === 'undefined') && (namespace._ExternalEventRetValueMap = new Map());
var _componentObject = new RAONKEditor(_compConfig);
_componentObject.name = element.id;
this.instance = _componentObject;
}
subscribe() {
let _configEvent = {};
const ComponentEvents = [
'CreationComplete',
'AfterChangeMode',
'OnError',
'OnLanguageDefinition',
'AfterPopupShow',
'AgentInstall',
'BeforeInsertUrl',
'Mouse',
'Command',
'Key',
'Resized',
'DocumentEditComplete',
'PasteImage',
'WordCount',
'BeforePaste',
'CustomAction',
'FullScreen',
'SetComplete',
'SetInsertComplete',
'CloseInstallPopup',
'SetForbiddenWordComplete',
'Drag',
'Focus',
'DialogLoaded',
'BeforeInsertHyperlink'
];
ComponentEvents.forEach(function (evtName) {
_configEvent[evtName] = (componentName, paramObj) => {
// Set default value
switch (evtName) {
case 'BeforePaste':
RAONKEDITOR._ExternalEventRetValueMap.set(componentName, paramObj.strHtml);
break;
case 'BeforeInsertUrl':
RAONKEDITOR._ExternalEventRetValueMap.set(componentName, paramObj.strUrl);
break;
case 'BeforeInsertHyperlink':
RAONKEDITOR._ExternalEventRetValueMap.set(componentName, paramObj); // url
break;
}
if (RAONKEDITOR._ExternalComponentMap.has(componentName)) {
let _this = RAONKEDITOR._ExternalComponentMap.get(componentName);
_this.ngZone.run(() => {
switch (evtName) {
case 'Focus':
if (_this.onTouched) {
_this.onTouched();
}
break;
case 'Command':
_this.propagateChange(evtName, { componentName: componentName, paramObj: paramObj });
break;
case 'Key':
if (paramObj.strEventName === 'keyup') {
_this.propagateChange(evtName, { componentName: componentName, paramObj: paramObj });
}
break;
case 'CreationComplete':
if (_this.data && typeof _this.data !== 'undefined' && _this.data !== '') {
RAONKEDITOR.SetHtmlContents(_this.data, _this.id);
}
// Data may be changed by content filtering.
_this._data = RAONKEDITOR.GetEditorByName(_this.id)._BODY.innerHTML;
break;
case 'SetComplete':
// Data may be changed by content filtering.
_this._data = RAONKEDITOR.GetEditorByName(_this.id)._BODY.innerHTML;
break;
}
_this[_this.capitalize(evtName)].emit({ componentName: componentName, paramObj: paramObj });
});
}
// return event
let _retValue = "";
switch (evtName) {
case 'BeforePaste':
case 'BeforeInsertUrl':
case 'BeforeInsertHyperlink':
if (RAONKEDITOR._ExternalEventRetValueMap.has(componentName)) {
_retValue = RAONKEDITOR._ExternalEventRetValueMap.get(componentName);
RAONKEDITOR._ExternalEventRetValueMap.delete(componentName); // Initialization
return _retValue;
}
break;
}
};
});
return _configEvent;
}
capitalize(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
}
propagateChange(eventName, eventParams) {
this.ngZone.run(() => {
const newData = RAONKEDITOR.GetEditorByName(this.id)._BODY.innerHTML;
this.change.emit(eventParams);
if (newData === this.data) {
return;
}
this._data = newData;
if (this.onChange) {
this.onChange(newData);
}
});
}
}
RaonkEditorComponent.decorators = [
{ type: Component, args: [{
selector: 'RaonkEditor',
template: '<ng-template></ng-template>',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => RaonkEditorComponent),
multi: true,
}
]
},] }
];
RaonkEditorComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: NgZone }
];
RaonkEditorComponent.propDecorators = {
id: [{ type: Input }],
config: [{ type: Input }],
componentType: [{ type: Input }],
componentUrl: [{ type: Input }],
tagName: [{ type: Input }],
runtimes: [{ type: Input }],
data: [{ type: Input }],
readOnly: [{ type: Input }],
viewMode: [{ type: Input }],
namespaceLoaded: [{ type: Output }],
change: [{ type: Output }],
creationComplete: [{ type: Output }],
afterChangeMode: [{ type: Output }],
onError: [{ type: Output }],
onLanguageDefinition: [{ type: Output }],
afterPopupShow: [{ type: Output }],
agentInstall: [{ type: Output }],
beforeInsertUrl: [{ type: Output }],
mouse: [{ type: Output }],
command: [{ type: Output }],
key: [{ type: Output }],
resized: [{ type: Output }],
documentEditComplete: [{ type: Output }],
pasteImage: [{ type: Output }],
wordCount: [{ type: Output }],
beforePaste: [{ type: Output }],
customAction: [{ type: Output }],
fullScreen: [{ type: Output }],
setComplete: [{ type: Output }],
setInsertComplete: [{ type: Output }],
closeInstallPopup: [{ type: Output }],
setForbiddenWordComplete: [{ type: Output }],
drag: [{ type: Output }],
focus: [{ type: Output }],
dialogLoaded: [{ type: Output }],
beforeInsertHyperlink: [{ type: Output }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFvbmtlZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Jhb25rZWRpdG9yL3Jhb25rZWRpdG9yLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sRUFDTixTQUFTLEVBQ1QsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFVBQVUsRUFDVixVQUFVLEVBRVYsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUVOLGlCQUFpQixFQUNqQixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBcUIzRSxNQUFNLE9BQU8sb0JBQW9CO0lBc0xoQyxZQUFxQixVQUFzQixFQUFVLE1BQWM7UUFBOUMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFVLFdBQU0sR0FBTixNQUFNLENBQVE7UUFyTG5FOztXQUVHO1FBQ08sT0FBRSxHQUFHLEVBQUUsQ0FBQztRQVFsQjs7V0FFRztRQUNPLGtCQUFhLEdBQUUsYUFBYSxDQUFDO1FBRXZDOztXQUVHO1FBQ00saUJBQVksR0FBRyxnQ0FBZ0MsQ0FBQztRQUV6RDs7OztXQUlHO1FBQ00sWUFBTyxHQUFHLEtBQUssQ0FBQztRQUV6Qjs7V0FFRztRQUNNLGFBQVEsdUJBQW9EO1FBZ0ZyRTs7O1dBR0c7UUFDTyxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUF5QixDQUFDO1FBRTVELFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBeUIsQ0FBQztRQUU3RDs7V0FFRztRQUNPLHFCQUFnQixHQUFHLElBQUksWUFBWSxFQUF5QixDQUFDO1FBQzdELG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQXlCLENBQUM7UUFDNUQsWUFBTyxHQUFHLElBQUksWUFBWSxFQUF5QixDQUFDO1FBQ3BELHlCQUFvQixHQUFHLElBQUksWUFBWSxFQUF5QixDQUFDO1FBQ2pFLG1CQUFj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SzsyQkFLTixLQUFLO3NCQU9MLEtBQUs7dUJBS0wsS0FBSzttQkFTTCxLQUFLO3VCQXNCSixLQUFLO3VCQXFCTixLQUFLOzhCQWdDTCxNQUFNO3FCQUVOLE1BQU07K0JBS04sTUFBTTs4QkFDTixNQUFNO3NCQUNOLE1BQU07bUNBQ04sTUFBTTs2QkFDTixNQUFNOzJCQUNOLE1BQU07OEJBQ04sTUFBTTtvQkFDTixNQUFNO3NCQUNOLE1BQU07a0JBQ04sTUFBTTtzQkFFTixNQUFNO21DQUNOLE1BQU07eUJBQ04sTUFBTTt3QkFDTixNQUFNOzBCQUNOLE1BQU07MkJBQ04sTUFBTTt5QkFDTixNQUFNOzBCQUNOLE1BQU07Z0NBQ04sTUFBTTtnQ0FDTixNQUFNO3VDQUNOLE1BQU07bUJBQ04sTUFBTTtvQkFDTixNQUFNOzJCQUNOLE1BQU07b0NBQ04sTUFBTSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBAbGljZW5zZSBDb3B5cmlnaHQgKGMpIDIwMDMtMjAyMiwgUkFPTldJWiBEZXZUZWFtLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7XHJcblx0Q29tcG9uZW50LFxyXG5cdE5nWm9uZSxcclxuXHRJbnB1dCxcclxuXHRPdXRwdXQsXHJcblx0RXZlbnRFbWl0dGVyLFxyXG5cdGZvcndhcmRSZWYsXHJcblx0RWxlbWVudFJlZixcclxuXHRBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3lcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7XHJcblx0Q29udHJvbFZhbHVlQWNjZXNzb3IsXHJcblx0TkdfVkFMVUVfQUNDRVNTT1JcclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5pbXBvcnQgeyBnZXRSYW9ud2l6Q29tcG9uZW50TmFtZXNwYWNlIH0gZnJvbSAncmFvbndpei1pbnRlZ3JhdGlvbnMtY29tbW9uJztcclxuXHJcbmltcG9ydCB7IFJhb25rRWRpdG9yIH0gZnJvbSAnLi9yYW9ua2VkaXRvcic7XHJcblxyXG5kZWNsYXJlIGxldCBSQU9OS0VESVRPUjogYW55O1xyXG5kZWNsYXJlIGxldCBSQU9OS0VkaXRvcjogYW55O1xyXG5kZWNsYXJlIGxldCBLRURJVE9SVE9QOiBhbnk7XHJcblxyXG5AQ29tcG9uZW50KCB7XHJcblx0c2VsZWN0b3I6ICdSYW9ua0VkaXRvcicsXHJcblx0dGVtcGxhdGU6ICc8bmctdGVtcGxhdGU+PC9uZy10ZW1wbGF0ZT4nLFxyXG5cclxuXHRwcm92aWRlcnM6IFtcclxuXHRcdHtcclxuXHRcdFx0cHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcblx0XHRcdHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCAoKSA9PiBSYW9ua0VkaXRvckNvbXBvbmVudCApLFxyXG5cdFx0XHRtdWx0aTogdHJ1ZSxcclxuXHRcdH1cclxuXHRdXHJcbn0gKVxyXG5cclxuZXhwb3J0IGNsYXNzIFJhb25rRWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XHJcblx0LyoqXHJcblx0ICogVGhlIGlkIG9mIHRoZSBjb21wb25lbnRcclxuXHQgKi9cclxuXHQgQElucHV0KCkgaWQgPSBcIlwiO1xyXG5cclxuXHJcblx0LyoqXHJcblx0ICogVGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGNvbXBvbmVudC5cclxuXHQgKi9cclxuXHRASW5wdXQoKSBjb25maWc/OiBSYW9ua0VkaXRvci5Db25maWc7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFRoZSBjb21wb25lbnQgdHlwZVxyXG5cdCAqL1xyXG5cdCBASW5wdXQoKSBjb21wb25lbnRUeXBlPSAnUkFPTktFRElUT1InO1xyXG5cclxuXHQvKipcclxuXHQgKiBSQU9OIEsgRWRpdG9yIHNjcmlwdCB1cmwgYWRkcmVzcy4gU2NyaXB0IHdpbGwgYmUgbG9hZGVkIG9ubHkgaWYgUkFPTktFRElUT1IgbmFtZXNwYWNlIGlzIG1pc3NpbmcuXHJcblx0ICovXHJcblx0QElucHV0KCkgY29tcG9uZW50VXJsID0gJy9yYW9ua2VkaXRvci9qcy9yYW9ua2VkaXRvci5qcyc7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFRhZyBuYW1lIG9mIHRoZSBjb21wb25lbnQuXHJcblx0ICpcclxuXHQgKiBUaGUgZGVmYXVsdCB0YWcgaXMgYGRpdmAuXHJcblx0ICovXHJcblx0QElucHV0KCkgdGFnTmFtZSA9ICdkaXYnO1xyXG5cdFxyXG5cdC8qKlxyXG5cdCAqIFRoZSBydW50aW1lcyBvZiB0aGUgY29tcG9uZW50IGludGVyZmFjZS5cclxuXHQgKi9cclxuXHRASW5wdXQoKSBydW50aW1lczogUmFvbmtFZGl0b3IuUnVudGltZXMgPSBSYW9ua0VkaXRvci5SdW50aW1lcy5IVE1MNTtcclxuXHJcblx0LyoqXHJcblx0ICogS2VlcHMgdHJhY2sgb2YgdGhlIGNvbXBvbmVudCdzIGRhdGEuXHJcblx0ICpcclxuXHQgKiBJdCdzIGFsc28gZGVjb3JhdGVkIGFzIGFuIGlucHV0IHdoaWNoIGlzIHVzZWZ1bCB3aGVuIG5vdCB1c2luZyB0aGUgbmdNb2RlbC5cclxuXHQgKlxyXG5cdCAqIFNlZSBodHRwczovL2FuZ3VsYXIuaW8vYXBpL2Zvcm1zL05nTW9kZWwgdG8gbGVhcm4gbW9yZS5cclxuXHQgKi9cclxuXHRASW5wdXQoKSBzZXQgZGF0YSggZGF0YTogc3RyaW5nICkge1xyXG5cdFx0Y29uc29sZS5sb2coXCJ0aGlzLmlkOiBcIiArIHRoaXMuaWQgKyBcIiwgZGF0YSA6IFwiICsgZGF0YSk7XHJcblxyXG5cdFx0aWYgKCBkYXRhID09PSB0aGlzLl9kYXRhICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCB0aGlzLmluc3RhbmNlICkge1xyXG5cdFx0XHRSQU9OS0VESVRPUi5TZXRIdG1sQ29udGVudHMoIGRhdGEsIHRoaXMuaWQgKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cdH1cclxuXHJcblx0Z2V0IGRhdGEoKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiB0aGlzLl9kYXRhO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogV2hlbiBzZXQgdG8gYHRydWVgLCB0aGUgZWRpdG9yIGJlY29tZXMgcmVhZG9ubHkgbW9kZS5cclxuXHQgKi9cclxuXHQgQElucHV0KCkgc2V0IHJlYWRPbmx5KCBpc1JlYWRPbmx5OiBib29sZWFuICkge1xyXG5cdFx0aWYgKCB0aGlzLmluc3RhbmNlICkge1xyXG5cdFx0XHRSQU9OS0VESVRPUi5TZXRSZWFkT25seSggaXNSZWFkT25seSwgJycsIHRoaXMuaWQgKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIERlbGF5IHNldHRpbmcgbW9kZVxyXG5cdFx0dGhpcy5fcmVhZE9ubHkgPSBpc1JlYWRPbmx5O1xyXG5cdH1cclxuXHJcblx0Z2V0IHJlYWRPbmx5KCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCB0aGlzLmluc3RhbmNlICkge1xyXG5cdFx0XHRyZXR1cm4gUkFPTktFRElUT1IuR2V0RWRpdG9yQnlOYW1lKHRoaXMuaWQpLl9CT0RZLmNvbnRlbnRFZGl0YWJsZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcy5fcmVhZE9ubHk7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBXaGVuIHNldCB0byBgdHJ1ZWAsIHRoZSBlZGl0b3IgYmVjb21lcyB2aWV3IG1vZGUuXHJcblx0ICovXHJcblx0QElucHV0KCkgc2V0IHZpZXdNb2RlKCBpc1ZpZXdNb2RlOiBib29sZWFuICkge1xyXG5cdFx0aWYgKCB0aGlzLmluc3RhbmNlICkge1xyXG5cdFx0XHRSQU9OS0VESVRPUi5TZXRFZGl0b3JNb2RlKCBpc1ZpZXdNb2RlPyd2aWV3JzonZWRpdCcsIHRoaXMuaWQgKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIERlbGF5IHNldHRpbmcgbW9kZVxyXG5cdFx0dGhpcy5fdmlld01vZGUgPSBpc1ZpZXdNb2RlO1xyXG5cdH1cclxuXHJcblx0Z2V0IHZpZXdNb2RlKCk6IGJvb2xlYW4ge1xyXG5cdFx0aWYgKCB0aGlzLmluc3RhbmNlICkge1xyXG5cdFx0XHRsZXQgcmV0VmFsdWU7XHJcblx0XHRcdHN3aXRjaChSQU9OS0VESVRPUi5HZXRFZGl0b3JCeU5hbWUodGhpcy5pZCkuX2NvbmZpZy5tb2RlLnRvTG93ZXJDYXNlKCkpIHtcclxuXHRcdFx0XHRjYXNlICdlZGl0JzpcclxuXHRcdFx0XHRcdHJldFZhbHVlID0gZmFsc2U7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHRcdFx0cmV0VmFsdWUgPSB0cnVlO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHRcdFx0XHJcblx0XHRcdHJldHVybiByZXRWYWx1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcy5fdmlld01vZGU7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBGaXJlZCB3aGVuIHRoZSBjb21wb25lbnQgbmFtZXNwYWNlXHJcblx0ICogaXMgbG9hZGVkLiBJdCBvbmx5IHRyaWdnZXJzIG9uY2UsIG5vIG1hdHRlciBob3cgbWFueSBjb21wb25lbnRzIGFyZSBpbml0aWFsaXNlZC5cclxuXHQgKi9cclxuXHRAT3V0cHV0KCkgbmFtZXNwYWNlTG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblxyXG5cdEBPdXRwdXQoKSBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHRcclxuXHQvKipcclxuXHQgKiBldmVudC5cclxuXHQgKi9cclxuXHRAT3V0cHV0KCkgY3JlYXRpb25Db21wbGV0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBhZnRlckNoYW5nZU1vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHRAT3V0cHV0KCkgb25FcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBvbkxhbmd1YWdlRGVmaW5pdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBhZnRlclBvcHVwU2hvdyA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBhZ2VudEluc3RhbGwgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHRAT3V0cHV0KCkgYmVmb3JlSW5zZXJ0VXJsID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIG1vdXNlID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGNvbW1hbmQgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHRAT3V0cHV0KCkga2V5ID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblxyXG5cdEBPdXRwdXQoKSByZXNpemVkID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGRvY3VtZW50RWRpdENvbXBsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIHBhc3RlSW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHRAT3V0cHV0KCkgd29yZENvdW50ID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGJlZm9yZVBhc3RlID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGN1c3RvbUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBmdWxsU2NyZWVuID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIHNldENvbXBsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIHNldEluc2VydENvbXBsZXRlID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGNsb3NlSW5zdGFsbFBvcHVwID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIHNldEZvcmJpZGRlbldvcmRDb21wbGV0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBkcmFnID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcjxSYW9ua0VkaXRvci5FdmVudEluZm8+KCk7XHJcblx0QE91dHB1dCgpIGRpYWxvZ0xvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8UmFvbmtFZGl0b3IuRXZlbnRJbmZvPigpO1xyXG5cdEBPdXRwdXQoKSBiZWZvcmVJbnNlcnRIeXBlcmxpbmsgPSBuZXcgRXZlbnRFbWl0dGVyPFJhb25rRWRpdG9yLkV2ZW50SW5mbz4oKTtcclxuXHJcblx0LyoqXHJcblx0ICogQSBjYWxsYmFjayBleGVjdXRlZCB3aGVuIHRoZSBjb250ZW50IG9mIHRoZSBjb21wb25lbnQgY2hhbmdlcy4gUGFydCBvZiB0aGVcclxuXHQgKiBgQ29udHJvbFZhbHVlQWNjZXNzb3JgIChodHRwczovL2FuZ3VsYXIuaW8vYXBpL2Zvcm1zL0NvbnRyb2xWYWx1ZUFjY2Vzc29yKSBpbnRlcmZhY2UuXHJcblx0ICpcclxuXHQgKiBOb3RlOiBVbnNldCB1bmxlc3MgdGhlIGNvbXBvbmVudCB1c2VzIHRoZSBgbmdNb2RlbGAuXHJcblx0ICovXHJcblx0b25DaGFuZ2U/OiAoIGRhdGE6IHN0cmluZyApID0+IHZvaWQ7XHJcblxyXG5cdC8qKlxyXG5cdCAqIEEgY2FsbGJhY2sgZXhlY3V0ZWQgd2hlbiB0aGUgY29tcG9uZW50IGhhcyBiZWVuIGJsdXJyZWQuIFBhcnQgb2YgdGhlXHJcblx0ICogYENvbnRyb2xWYWx1ZUFjY2Vzc29yYCAoaHR0cHM6Ly9hbmd1bGFyLmlvL2FwaS9mb3Jtcy9Db250cm9sVmFsdWVBY2Nlc3NvcikgaW50ZXJmYWNlLlxyXG5cdCAqXHJcblx0ICogTm90ZTogVW5zZXQgdW5sZXNzIHRoZSBjb21wb25lbnQgdXNlcyB0aGUgYG5nTW9kZWxgLlxyXG5cdCAqL1xyXG5cdG9uVG91Y2hlZD86ICgpID0+IHZvaWQ7XHJcblxyXG5cdC8qKlxyXG5cdCAqIFRoZSBpbnN0YW5jZSBvZiB0aGUgY29tcG9uZW50IGNyZWF0ZWQuXHJcblx0ICovXHJcblx0aW5zdGFuY2U6IGFueTtcclxuXHJcblx0LyoqXHJcblx0ICogSWYgdGhlIGNvbXBvbmVudCBpcyB2aWV3LW1vZGUgYmVmb3JlIHRoZSBjb21wb25lbnQgaW5zdGFuY2UgaXMgY3JlYXRlZCwgaXQgcmVtZW1iZXJzIHRoYXQgc3RhdGUsXHJcblx0ICogc28gdGhlIGNvbXBvbmVudCBjYW4gYmVjb21lIHZpZXctbW9kZSBvbmNlIGl0IGlzIHJlYWR5LlxyXG5cdCAqL1xyXG5cdHByaXZhdGUgX3JlYWRPbmx5OiBib29sZWFuID0gbnVsbDtcclxuXHRwcml2YXRlIF92aWV3TW9kZTogYm9vbGVhbiA9IG51bGw7XHJcblxyXG5cdHByaXZhdGUgX2RhdGE6IHN0cmluZyA9IG51bGw7XHJcblxyXG5cdHByaXZhdGUgX2Rlc3Ryb3llZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHRjb25zdHJ1Y3RvciggcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwcml2YXRlIG5nWm9uZTogTmdab25lICkge31cclxuXHJcblx0bmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG5cdFx0Z2V0UmFvbndpekNvbXBvbmVudE5hbWVzcGFjZSggdGhpcy5jb21wb25lbnRUeXBlLCB0aGlzLmNvbXBvbmVudFVybCwgbmFtZXNwYWNlID0+IHtcclxuXHRcdFx0dGhpcy5uYW1lc3BhY2VMb2FkZWQuZW1pdCggbmFtZXNwYWNlICk7XHJcblx0XHR9ICkudGhlbiggKG5hbWVzcGFjZSkgPT4ge1xyXG5cdFx0XHQvLyBDaGVjayBpZiBjb21wb25lbnQgaW5zdGFuY2Ugd2FzIGRlc3Ryb3llZCBiZWZvcmUgYG5nQWZ0ZXJWaWV3SW5pdGAgY2FsbCAoIzExMCkuXHJcblx0XHRcdC8vIEhlcmUsIGB0aGlzLmluc3RhbmNlYCBpcyBzdGlsbCBub3QgaW5pdGlhbGl6ZWQgYW5kIHNvIGFkZGl0aW9uYWwgZmxhZyBpcyBuZWVkZWQuXHJcblx0XHRcdGlmICggdGhpcy5fZGVzdHJveWVkICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoIHRoaXMuY3JlYXRlQ29tcG9uZW50LmJpbmQoIHRoaXMsIG5hbWVzcGFjZSApICk7XHJcblx0XHR9ICkuY2F0Y2goIHdpbmRvdy5jb25zb2xlLmVycm9yICk7XHJcblxyXG5cdH1cclxuXHJcblx0bmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcblx0XHR0aGlzLl9kZXN0cm95ZWQgPSB0cnVlO1xyXG5cclxuXHRcdHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCAoKSA9PiB7XHJcblx0XHRcdGlmICggdGhpcy5pbnN0YW5jZSApIHtcclxuXHRcdFx0XHRpZihSQU9OS0VESVRPUi5fRXh0ZXJuYWxDb21wb25lbnRNYXAuaGFzKHRoaXMuaWQpKSB7XHJcblx0XHRcdFx0XHRSQU9OS0VESVRPUi5fRXh0ZXJuYWxDb21wb25lbnRNYXAuZGVsZXRlKHRoaXMuaWQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZihSQU9OS0VESVRPUi5fRXh0ZXJuYWxFdmVudFJldFZhbHVlTWFwLmhhcyh0aGlzLmlkKSkge1xyXG5cdFx0XHRcdFx0UkFPTktFRElUT1IuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcC5kZWxldGUodGhpcy5pZCk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRSQU9OS0VESVRPUi5EZXN0cm95KHRoaXMuaWQsIGZhbHNlKTtcclxuXHRcdFx0XHR0aGlzLmluc3RhbmNlID0gbnVsbDtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH1cclxuXHJcblx0d3JpdGVWYWx1ZSggdmFsdWU6IHN0cmluZyApOiB2b2lkIHtcclxuXHRcdHRoaXMuZGF0YSA9IHZhbHVlO1xyXG5cdH1cclxuXHJcblx0cmVnaXN0ZXJPbkNoYW5nZSggY2FsbGJhY2s6ICggZGF0YTogc3RyaW5nICkgPT4gdm9pZCApOiB2b2lkIHtcclxuXHRcdHRoaXMub25DaGFuZ2UgPSBjYWxsYmFjaztcclxuXHR9XHJcblxyXG5cdHJlZ2lzdGVyT25Ub3VjaGVkKCBjYWxsYmFjazogKCkgPT4gdm9pZCApOiB2b2lkIHtcclxuXHRcdHRoaXMub25Ub3VjaGVkID0gY2FsbGJhY2s7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGdldENvbXBvbmVudFVuaXF1ZU5hbWUoKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBcInJhb25rZWRpdG9yX1wiICsgTWF0aC5yYW5kb20oKVxyXG5cdFx0LnRvU3RyaW5nKCAzNiApXHJcblx0XHQucmVwbGFjZSggL1teYS16XSsvZywgJycgKVxyXG5cdFx0LnN1YnN0ciggMCwgNSApO1xyXG5cdH1cclxuXHJcblx0cHJpdmF0ZSBjcmVhdGVDb21wb25lbnQobmFtZXNwYWNlKTogdm9pZCB7XHJcblx0XHRsZXQgX3VuaXF1ZU5hbWUgPSB0aGlzLmdldENvbXBvbmVudFVuaXF1ZU5hbWUoKTtcclxuXHRcdFxyXG5cdFx0KHR5cGVvZiB0aGlzLmlkID09PSAndW5kZWZpbmVkJykgJiYgKHRoaXMuaWQgPSBfdW5pcXVlTmFtZSk7XHJcblx0XHRcclxuXHRcdGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCB0aGlzLnRhZ05hbWUgKTtcclxuXHRcdGVsZW1lbnQuaWQgPSBcImNvbXBvbmVudEhvbGRlcl9cIiArIF91bmlxdWVOYW1lO1xyXG5cdFx0dGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQoIGVsZW1lbnQgKTtcclxuXHRcdFxyXG5cdFx0Ly8gdmlldyBzdGF0ZSBtYXkgY2hhbmdlIGR1cmluZyBpbnN0YW5jZSBpbml0aWFsaXphdGlvbi5cclxuXHRcdCh0aGlzLl92aWV3TW9kZSAhPT0gbnVsbCkgJiYgKHRoaXMudmlld01vZGUgPSB0aGlzLl92aWV3TW9kZSk7XHJcblxyXG5cdFx0Ly8gZGVmYXVsdCBjb25maWdcclxuXHRcdGxldCBfY29tcENvbmZpZyA9IHtcclxuXHRcdFx0SWQ6IHRoaXMuaWQsXHJcblx0XHRcdEVkaXRvckhvbGRlcjogZWxlbWVudC5pZCxcclxuXHRcdFx0UnVudGltZXM6IHRoaXMucnVudGltZXMsXHJcblx0XHRcdE1vZGU6IHRoaXMuX3ZpZXdNb2RlID8gJ3ZpZXcnIDogJ2VkaXQnLFxyXG5cdFx0XHRcclxuXHRcdFx0UmV0dXJuRXZlbnRLZXlib2FyZDogJzEnLFxyXG5cdFx0XHRSZXR1cm5FdmVudEZvY3VzOiAnMScsXHJcblx0XHRcdFJldHVybkV2ZW50Q29tbWFuZDogJzEnLFxyXG5cclxuXHRcdFx0RXZlbnQ6IHRoaXMuc3Vic2NyaWJlKClcclxuXHRcdH07XHJcblxyXG5cdFx0X2NvbXBDb25maWcgPSBuYW1lc3BhY2UudXRpbC5vYmplY3RFeHRlbmQoIHRydWUsIHRoaXMuY29uZmlnLCBfY29tcENvbmZpZyApO1xyXG5cclxuXHRcdC8vIGZvciBldmVudCBjYWxsYmFja1xyXG5cdFx0KHR5cGVvZiBuYW1lc3BhY2UuX0V4dGVybmFsQ29tcG9uZW50TWFwID09PSAndW5kZWZpbmVkJykgJiYgKG5hbWVzcGFjZS5fRXh0ZXJuYWxDb21wb25lbnRNYXAgPSBuZXcgTWFwKCkpO1xyXG5cdFx0bmFtZXNwYWNlLl9FeHRlcm5hbENvbXBvbmVudE1hcC5zZXQodGhpcy5pZCwgdGhpcyk7XHJcblxyXG5cdFx0KHR5cGVvZiBuYW1lc3BhY2UuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcCA9PT0gJ3VuZGVmaW5lZCcpICYmIChuYW1lc3BhY2UuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcCA9IG5ldyBNYXAoKSk7XHJcblxyXG5cdFx0dmFyIF9jb21wb25lbnRPYmplY3QgPSBuZXcgUkFPTktFZGl0b3IoIF9jb21wQ29uZmlnICk7XHJcblx0XHRfY29tcG9uZW50T2JqZWN0Lm5hbWUgPSBlbGVtZW50LmlkO1xyXG5cdFx0dGhpcy5pbnN0YW5jZSA9IF9jb21wb25lbnRPYmplY3Q7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIHN1YnNjcmliZSgpOiBhbnkge1xyXG5cdFx0bGV0IF9jb25maWdFdmVudCA9IHt9O1xyXG5cclxuXHRcdGNvbnN0IENvbXBvbmVudEV2ZW50cyA9IFtcclxuXHRcdFx0J0NyZWF0aW9uQ29tcGxldGUnLFxyXG5cdFx0XHQnQWZ0ZXJDaGFuZ2VNb2RlJyxcclxuXHRcdFx0J09uRXJyb3InLFxyXG5cdFx0XHQnT25MYW5ndWFnZURlZmluaXRpb24nLFxyXG5cdFx0XHQnQWZ0ZXJQb3B1cFNob3cnLFxyXG5cdFx0XHQnQWdlbnRJbnN0YWxsJyxcclxuXHRcdFx0J0JlZm9yZUluc2VydFVybCcsXHJcblx0XHRcdCdNb3VzZScsXHJcblx0XHRcdCdDb21tYW5kJyxcclxuXHRcdFx0J0tleScsXHJcblx0XHRcdCdSZXNpemVkJyxcclxuXHRcdFx0J0RvY3VtZW50RWRpdENvbXBsZXRlJyxcclxuXHRcdFx0J1Bhc3RlSW1hZ2UnLFxyXG5cdFx0XHQnV29yZENvdW50JyxcclxuXHRcdFx0J0JlZm9yZVBhc3RlJyxcclxuXHRcdFx0J0N1c3RvbUFjdGlvbicsXHJcblx0XHRcdCdGdWxsU2NyZWVuJyxcclxuXHRcdFx0J1NldENvbXBsZXRlJyxcclxuXHRcdFx0J1NldEluc2VydENvbXBsZXRlJyxcclxuXHRcdFx0J0Nsb3NlSW5zdGFsbFBvcHVwJyxcclxuXHRcdFx0J1NldEZvcmJpZGRlbldvcmRDb21wbGV0ZScsXHJcblx0XHRcdCdEcmFnJyxcclxuXHRcdFx0J0ZvY3VzJyxcclxuXHRcdFx0J0RpYWxvZ0xvYWRlZCcsXHJcblx0XHRcdCdCZWZvcmVJbnNlcnRIeXBlcmxpbmsnXHJcblx0XHRdIGFzIGNvbnN0O1xyXG5cclxuXHRcdENvbXBvbmVudEV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGV2dE5hbWUpIHtcclxuXHRcdFx0X2NvbmZpZ0V2ZW50W2V2dE5hbWVdID0gKGNvbXBvbmVudE5hbWU6IGFueSwgcGFyYW1PYmo6IGFueSkgPT4ge1xyXG5cdFx0XHRcdC8vIFNldCBkZWZhdWx0IHZhbHVlXHJcblx0XHRcdFx0c3dpdGNoKGV2dE5hbWUpIHtcclxuXHRcdFx0XHRcdGNhc2UgJ0JlZm9yZVBhc3RlJzpcclxuXHRcdFx0XHRcdFx0UkFPTktFRElUT1IuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcC5zZXQoY29tcG9uZW50TmFtZSwgcGFyYW1PYmouc3RySHRtbCk7XHJcblx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0Y2FzZSAnQmVmb3JlSW5zZXJ0VXJsJzpcclxuXHRcdFx0XHRcdFx0UkFPTktFRElUT1IuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcC5zZXQoY29tcG9uZW50TmFtZSwgcGFyYW1PYmouc3RyVXJsKTtcclxuXHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRjYXNlICdCZWZvcmVJbnNlcnRIeXBlcmxpbmsnOlxyXG5cdFx0XHRcdFx0XHRSQU9OS0VESVRPUi5fRXh0ZXJuYWxFdmVudFJldFZhbHVlTWFwLnNldChjb21wb25lbnROYW1lLCBwYXJhbU9iaik7IC8vIHVybFxyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGlmKFJBT05LRURJVE9SLl9FeHRlcm5hbENvbXBvbmVudE1hcC5oYXMoY29tcG9uZW50TmFtZSkpIHtcclxuXHRcdFx0XHRcdGxldCBfdGhpcyA9IFJBT05LRURJVE9SLl9FeHRlcm5hbENvbXBvbmVudE1hcC5nZXQoY29tcG9uZW50TmFtZSk7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdF90aGlzLm5nWm9uZS5ydW4oICgpID0+IHtcclxuXHRcdFx0XHRcdFx0c3dpdGNoKGV2dE5hbWUpIHtcclxuXHRcdFx0XHRcdFx0XHRjYXNlICdGb2N1cyc6XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIF90aGlzLm9uVG91Y2hlZCApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0X3RoaXMub25Ub3VjaGVkKCk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0XHRjYXNlICdDb21tYW5kJzpcclxuXHRcdFx0XHRcdFx0XHRcdF90aGlzLnByb3BhZ2F0ZUNoYW5nZShldnROYW1lLCB7IGNvbXBvbmVudE5hbWU6IGNvbXBvbmVudE5hbWUsIHBhcmFtT2JqOiBwYXJhbU9iaiB9KTtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHRcdGNhc2UgJ0tleSc6XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHBhcmFtT2JqLnN0ckV2ZW50TmFtZSA9PT0gJ2tleXVwJyApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0X3RoaXMucHJvcGFnYXRlQ2hhbmdlKGV2dE5hbWUsIHsgY29tcG9uZW50TmFtZTogY29tcG9uZW50TmFtZSwgcGFyYW1PYmo6IHBhcmFtT2JqIH0pO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0Y2FzZSAnQ3JlYXRpb25Db21wbGV0ZSc6XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoX3RoaXMuZGF0YSAmJiB0eXBlb2YgX3RoaXMuZGF0YSAhPT0gJ3VuZGVmaW5lZCcgJiYgX3RoaXMuZGF0YSAhPT0gJycpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0UkFPTktFRElUT1IuU2V0SHRtbENvbnRlbnRzKCBfdGhpcy5kYXRhLCBfdGhpcy5pZCApO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRGF0YSBtYXkgYmUgY2hhbmdlZCBieSBjb250ZW50IGZpbHRlcmluZy5cclxuXHRcdFx0XHRcdFx0XHRcdF90aGlzLl9kYXRhID0gUkFPTktFRElUT1IuR2V0RWRpdG9yQnlOYW1lKCBfdGhpcy5pZCApLl9CT0RZLmlubmVySFRNTDtcclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHRcdGNhc2UgJ1NldENvbXBsZXRlJzpcclxuXHRcdFx0XHRcdFx0XHRcdC8vIERhdGEgbWF5IGJlIGNoYW5nZWQgYnkgY29udGVudCBmaWx0ZXJpbmcuXHJcblx0XHRcdFx0XHRcdFx0XHRfdGhpcy5fZGF0YSA9IFJBT05LRURJVE9SLkdldEVkaXRvckJ5TmFtZSggX3RoaXMuaWQgKS5fQk9EWS5pbm5lckhUTUw7XHJcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0X3RoaXNbIF90aGlzLmNhcGl0YWxpemUoZXZ0TmFtZSkgXS5lbWl0KCB7IGNvbXBvbmVudE5hbWU6IGNvbXBvbmVudE5hbWUsIHBhcmFtT2JqOiBwYXJhbU9iaiB9ICk7XHJcblx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyByZXR1cm4gZXZlbnRcclxuXHRcdFx0XHRsZXQgX3JldFZhbHVlID0gXCJcIjtcclxuXHRcdFx0XHRzd2l0Y2goZXZ0TmFtZSkge1xyXG5cdFx0XHRcdFx0Y2FzZSAnQmVmb3JlUGFzdGUnOlxyXG5cdFx0XHRcdFx0Y2FzZSAnQmVmb3JlSW5zZXJ0VXJsJzpcclxuXHRcdFx0XHRcdGNhc2UgJ0JlZm9yZUluc2VydEh5cGVybGluayc6XHJcblx0XHRcdFx0XHRcdGlmKFJBT05LRURJVE9SLl9FeHRlcm5hbEV2ZW50UmV0VmFsdWVNYXAuaGFzKGNvbXBvbmVudE5hbWUpKSB7XHJcblx0XHRcdFx0XHRcdFx0X3JldFZhbHVlID0gUkFPTktFRElUT1IuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcC5nZXQoY29tcG9uZW50TmFtZSk7XHJcblx0XHRcdFx0XHRcdFx0UkFPTktFRElUT1IuX0V4dGVybmFsRXZlbnRSZXRWYWx1ZU1hcC5kZWxldGUoY29tcG9uZW50TmFtZSk7IC8vIEluaXRpYWxpemF0aW9uXHJcblx0XHRcdFx0XHRcdFx0XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIF9yZXRWYWx1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBfY29uZmlnRXZlbnQ7XHJcblx0fVxyXG5cclxuXHRwcml2YXRlIGNhcGl0YWxpemUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIHN0ci5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIHN0ci5zbGljZSgxKTtcclxuXHR9XHJcblxyXG5cdHByaXZhdGUgcHJvcGFnYXRlQ2hhbmdlKCBldmVudE5hbWU6IHN0cmluZywgZXZlbnRQYXJhbXM6IGFueSApOiB2b2lkIHtcclxuXHRcdHRoaXMubmdab25lLnJ1biggKCkgPT4ge1xyXG5cdFx0XHRjb25zdCBuZXdEYXRhID0gUkFPTktFRElUT1IuR2V0RWRpdG9yQnlOYW1lKCB0aGlzLmlkICkuX0JPRFkuaW5uZXJIVE1MO1xyXG5cdFx0XHRcclxuXHRcdFx0dGhpcy5jaGFuZ2UuZW1pdCggZXZlbnRQYXJhbXMgKTtcclxuXHJcblx0XHRcdGlmICggbmV3RGF0YSA9PT0gdGhpcy5kYXRhICkge1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dGhpcy5fZGF0YSA9IG5ld0RhdGE7XHJcblxyXG5cdFx0XHRpZiAoIHRoaXMub25DaGFuZ2UgKSB7XHJcblx0XHRcdFx0dGhpcy5vbkNoYW5nZSggbmV3RGF0YSApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fVxyXG59XHJcbiJdfQ==