@joniras/ngx-editor2
Version:
WYSIWYG Editor for Angular 8+
258 lines • 29.7 kB
JavaScript
import { __decorate } from "tslib";
import { Component, OnInit, Input, Output, ViewChild, EventEmitter, Renderer2, forwardRef, ElementRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { CommandExecutorService } from '../common/services/command-executor.service';
import { MessageService } from '../common/services/message.service';
import { ngxTextEditorConfig } from '../common/ngx-text-editor.defaults';
import * as Utils from '../common/utils/ngx-text-editor.utils';
var NgxTextEditorComponent = /** @class */ (function () {
/**
* @param _messageService service to send message to the editor message component
* @param _commandExecutor executes command from the toolbar
* @param _renderer access and manipulate the dom element
*/
function NgxTextEditorComponent(_messageService, _commandExecutor, _renderer) {
this._messageService = _messageService;
this._commandExecutor = _commandExecutor;
this._renderer = _renderer;
/**
* The editor can be resized vertically.
*
* `basic` resizer enables the html5 reszier. Check here https://www.w3schools.com/cssref/css3_pr_resize.asp
*
* `stack` resizer enable a resizer that looks like as if in https://stackoverflow.com
*/
this.resizer = 'stack';
/**
* The config property is a JSON object
*
* All avaibale inputs inputs can be provided in the configuration as JSON
* inputs provided directly are considered as top priority
*/
this.config = ngxTextEditorConfig;
/** emits `blur` event when focused out from the textarea */
this.blur = new EventEmitter();
/** emits `focus` event when focused in to the textarea */
this.focus = new EventEmitter();
/** emits `uploadImage` event when image is selected */
this.uploadImage = new EventEmitter();
this.Utils = Utils;
}
NgxTextEditorComponent_1 = NgxTextEditorComponent;
/**
* events
*/
NgxTextEditorComponent.prototype.onTextAreaFocus = function () {
this.focus.emit('focus');
};
/** focus the text area when the editor is focussed */
NgxTextEditorComponent.prototype.onEditorFocus = function () {
this.textArea.nativeElement.focus();
};
/**
* Executed from the contentEditable section while the input property changes
* @param innerHTML html string from contentEditable
*/
NgxTextEditorComponent.prototype.onContentChange = function (innerHTML) {
if (typeof this.onChange === 'function') {
this.onChange(innerHTML);
this.togglePlaceholder(innerHTML);
}
};
NgxTextEditorComponent.prototype.onTextAreaBlur = function () {
/** save selection if focussed out */
this._commandExecutor.savedSelection = Utils.saveSelection();
if (typeof this.onTouched === 'function') {
this.onTouched();
}
this.blur.emit('blur');
};
/**
* Executed when the image from the disc is selected
* @param image uploaded file object
*/
NgxTextEditorComponent.prototype.onUploadImage = function (image) {
this.uploadImage.emit(image);
};
/**
* resizing text area
*
* @param offsetY vertical height of the eidtable portion of the editor
*/
NgxTextEditorComponent.prototype.resizeTextArea = function (offsetY) {
var newHeight = parseInt(this.height, 10);
newHeight += offsetY;
this.height = newHeight + 'px';
this.textArea.nativeElement.style.height = this.height;
};
/**
* editor actions, i.e., executes command from toolbar
*
* @param commandName name of the command to be executed
*/
NgxTextEditorComponent.prototype.executeCommand = function (commandName) {
try {
this._commandExecutor.execute(commandName);
}
catch (error) {
this._messageService.sendMessage(error.message);
}
};
/**
* Write a new value to the element.
*
* @param value value to be executed when there is a change in contenteditable
*/
NgxTextEditorComponent.prototype.writeValue = function (value) {
this.togglePlaceholder(value);
if (value === null || value === undefined || value === '' || value === '<br>') {
value = null;
}
this.refreshView(value);
};
/**
* Set the function to be called
* when the control receives a change event.
*
* @param fn a function
*/
NgxTextEditorComponent.prototype.registerOnChange = function (fn) {
this.onChange = fn;
};
/**
* Set the function to be called
* when the control receives a touch event.
*
* @param fn a function
*/
NgxTextEditorComponent.prototype.registerOnTouched = function (fn) {
this.onTouched = fn;
};
/**
* refresh view/HTML of the editor
*
* @param value html string from the editor
*/
NgxTextEditorComponent.prototype.refreshView = function (value) {
var normalizedValue = value === null ? '' : value;
this._renderer.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue);
};
/**
* toggles placeholder based on input string
*
* @param value A HTML string from the editor
*/
NgxTextEditorComponent.prototype.togglePlaceholder = function (value) {
if (!value || value === '<br>' || value === '') {
this._renderer.addClass(this.ngxWrapper.nativeElement, 'show-placeholder');
}
else {
this._renderer.removeClass(this.ngxWrapper.nativeElement, 'show-placeholder');
}
};
/**
* returns a json containing input params
*/
NgxTextEditorComponent.prototype.getCollectiveParams = function () {
return {
editable: this.editable,
spellcheck: this.spellcheck,
placeholder: this.placeholder,
translate: this.translate,
height: this.height,
minHeight: this.minHeight,
width: this.width,
minWidth: this.minWidth,
enableToolbar: this.enableToolbar,
showToolbar: this.showToolbar,
imageEndPoint: this.imageEndPoint,
toolbar: this.toolbar
};
};
NgxTextEditorComponent.prototype.ngOnInit = function () {
/**
* set configuration
*/
this.config = this.Utils.getEditorConfiguration(this.config, ngxTextEditorConfig, this.getCollectiveParams());
this.height = this.height || this.textArea.nativeElement.offsetHeight;
this.executeCommand('enableObjectResizing');
};
var NgxTextEditorComponent_1;
NgxTextEditorComponent.ctorParameters = function () { return [
{ type: MessageService },
{ type: CommandExecutorService },
{ type: Renderer2 }
]; };
__decorate([
Input()
], NgxTextEditorComponent.prototype, "editable", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "spellcheck", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "placeholder", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "translate", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "height", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "minHeight", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "width", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "minWidth", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "toolbar", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "resizer", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "config", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "showToolbar", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "enableToolbar", void 0);
__decorate([
Input()
], NgxTextEditorComponent.prototype, "imageEndPoint", void 0);
__decorate([
Output()
], NgxTextEditorComponent.prototype, "blur", void 0);
__decorate([
Output()
], NgxTextEditorComponent.prototype, "focus", void 0);
__decorate([
Output()
], NgxTextEditorComponent.prototype, "uploadImage", void 0);
__decorate([
ViewChild('ngxTextArea', { static: true })
], NgxTextEditorComponent.prototype, "textArea", void 0);
__decorate([
ViewChild('ngxWrapper', { static: true })
], NgxTextEditorComponent.prototype, "ngxWrapper", void 0);
NgxTextEditorComponent = NgxTextEditorComponent_1 = __decorate([
Component({
selector: 'ngx-text-editor',
template: "<div class=\"ngx-text-editor\"\r\n id=\"ngxTextEditor\"\r\n [style.width]=\"config['width']\"\r\n [style.minWidth]=\"config['minWidth']\"\r\n tabindex=\"0\"\r\n (focus)=\"onEditorFocus()\">\r\n\r\n <ngx-text-editor-toolbar [config]=\"config\"\r\n (execute)=\"executeCommand($event)\"\r\n (uploadImage)=\"onUploadImage($event)\"></ngx-text-editor-toolbar>\r\n\r\n <!-- text area -->\r\n <div #ngxWrapper\r\n class=\"ngx-wrapper\">\r\n <div #ngxTextArea\r\n class=\"ngx-text-editor-textarea\"\r\n [attr.contenteditable]=\"config['editable']\"\r\n (input)=\"onContentChange($event.target.innerHTML)\"\r\n [attr.translate]=\"config['translate']\"\r\n [attr.spellcheck]=\"config['spellcheck']\"\r\n [style.height]=\"config['height']\"\r\n [style.minHeight]=\"config['minHeight']\"\r\n [style.resize]=\"Utils?.canResize(resizer)\"\r\n (focus)=\"onTextAreaFocus()\"\r\n (blur)=\"onTextAreaBlur()\"></div>\r\n\r\n <span class=\"ngx-text-editor-placeholder\">\r\n {{ placeholder || config['placeholder'] }}\r\n </span>\r\n </div>\r\n\r\n <ngx-text-editor-message></ngx-text-editor-message>\r\n\r\n <ngx-grippie *ngIf=\"resizer === 'stack'\"></ngx-grippie>\r\n</div>\r\n",
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return NgxTextEditorComponent_1; }),
multi: true
}],
styles: [".ngx-text-editor{position:relative}.ngx-text-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);display:block;color:#868e96;opacity:1}.ngx-text-editor .ngx-wrapper{position:relative}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea{min-height:5rem;padding:.5rem .8rem 1rem;border:1px solid #ddd;background-color:transparent;overflow-x:hidden;overflow-y:auto;z-index:2;position:relative}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea.focus,.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea:focus{outline:0}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.ngx-text-editor .ngx-wrapper .ngx-text-editor-textarea::before{content:normal!important}.ngx-text-editor .ngx-wrapper ::ng-deep p{margin-bottom:0}.ngx-text-editor .ngx-wrapper .ngx-text-editor-placeholder{display:none;position:absolute;top:0;padding:.5rem .8rem 1rem .9rem;z-index:1;color:#6c757d;opacity:1}.ngx-text-editor .ngx-wrapper.show-placeholder .ngx-text-editor-placeholder{display:block}"]
})
], NgxTextEditorComponent);
return NgxTextEditorComponent;
}());
export { NgxTextEditorComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRleHQtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bqb25pcmFzL25neC1lZGl0b3IyLyIsInNvdXJjZXMiOlsibmd4LXRleHQtZWRpdG9yL25neC10ZXh0LWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMzSCxPQUFPLEVBQUMsaUJBQWlCLEVBQXVCLE1BQU0sZ0JBQWdCLENBQUM7QUFFdkUsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sNkNBQTZDLENBQUM7QUFDbkYsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBRWxFLE9BQU8sRUFBQyxtQkFBbUIsRUFBQyxNQUFNLG9DQUFvQyxDQUFDO0FBQ3ZFLE9BQU8sS0FBSyxLQUFLLE1BQU0sdUNBQXVDLENBQUM7QUFjL0Q7SUFpRkU7Ozs7T0FJRztJQUNILGdDQUNVLGVBQThCLEVBQzlCLGdCQUF1QyxFQUN2QyxTQUFtQjtRQUZuQixvQkFBZSxHQUFmLGVBQWUsQ0FBZTtRQUM5QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXVCO1FBQ3ZDLGNBQVMsR0FBVCxTQUFTLENBQVU7UUFuRDdCOzs7Ozs7V0FNRztRQUNNLFlBQU8sR0FBRyxPQUFPLENBQUM7UUFFM0I7Ozs7O1dBS0c7UUFDTSxXQUFNLEdBQUcsbUJBQW1CLENBQUM7UUFXdEMsNERBQTREO1FBQ2xELFNBQUksR0FBd0IsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUVqRSwwREFBMEQ7UUFDaEQsVUFBSyxHQUF3QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBRWxFLHVEQUF1RDtRQUM3QyxnQkFBVyxHQUFrQyxJQUFJLFlBQVksRUFBb0IsQ0FBQztRQUty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LHMwQ0FBK0M7WUFJL0MsU0FBUyxFQUFDLENBQUM7b0JBQ1QsT0FBTyxFQUFNLGlCQUFpQjtvQkFDOUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxjQUFNLE9BQUEsd0JBQXNCLEVBQXRCLENBQXNCLENBQUM7b0JBQ3JELEtBQUssRUFBUSxJQUFJO2lCQUNsQixDQUFDOztTQUNILENBQUM7T0FDVyxzQkFBc0IsQ0F1UGxDO0lBQUQsNkJBQUM7Q0FBQSxBQXZQRCxJQXVQQztTQXZQWSxzQkFBc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgT25Jbml0LCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGQsIEV2ZW50RW1pdHRlciwgUmVuZGVyZXIyLCBmb3J3YXJkUmVmLCBFbGVtZW50UmVmfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtOR19WQUxVRV9BQ0NFU1NPUiwgQ29udHJvbFZhbHVlQWNjZXNzb3J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCB7Q29tbWFuZEV4ZWN1dG9yU2VydmljZX0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL2NvbW1hbmQtZXhlY3V0b3Iuc2VydmljZSc7XHJcbmltcG9ydCB7TWVzc2FnZVNlcnZpY2V9IGZyb20gJy4uL2NvbW1vbi9zZXJ2aWNlcy9tZXNzYWdlLnNlcnZpY2UnO1xyXG5cclxuaW1wb3J0IHtuZ3hUZXh0RWRpdG9yQ29uZmlnfSBmcm9tICcuLi9jb21tb24vbmd4LXRleHQtZWRpdG9yLmRlZmF1bHRzJztcclxuaW1wb3J0ICogYXMgVXRpbHMgZnJvbSAnLi4vY29tbW9uL3V0aWxzL25neC10ZXh0LWVkaXRvci51dGlscyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogICAgJ25neC10ZXh0LWVkaXRvcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL25neC10ZXh0LWVkaXRvci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOltcclxuICAgICcuL25neC10ZXh0LWVkaXRvci5jb21wb25lbnQuc2NzcydcclxuICBdLFxyXG4gIHByb3ZpZGVyczpbe1xyXG4gICAgcHJvdmlkZTogICAgIE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG4gICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmd4VGV4dEVkaXRvckNvbXBvbmVudCksXHJcbiAgICBtdWx0aTogICAgICAgdHJ1ZVxyXG4gIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ3hUZXh0RWRpdG9yQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XHJcbiAgLyoqIFNwZWNpZmllcyB3ZWF0aGVyIHRoZSB0ZXh0YXJlYSB0byBiZSBlZGl0YWJsZSBvciBub3QgKi9cclxuICBASW5wdXQoKSBlZGl0YWJsZTpib29sZWFuO1xyXG5cclxuICAvKiogVGhlIHNwZWxsY2hlY2sgcHJvcGVydHkgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgdG8gaGF2ZSBpdHMgc3BlbGxpbmcgYW5kIGdyYW1tYXIgY2hlY2tlZCBvciBub3QuICovXHJcbiAgQElucHV0KCkgc3BlbGxjaGVjazpib29sZWFuO1xyXG5cclxuICAvKiogUGxhY2Vob2xkZXIgZm9yIHRoZSB0ZXh0QXJlYSAqL1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOnN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHRyYW5zbGF0ZSBwcm9wZXJ0eSBzcGVjaWZpZXMgd2hldGhlciB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IHNob3VsZCBiZSB0cmFuc2xhdGVkIG9yIG5vdC5cclxuICAgKlxyXG4gICAqIENoZWNrIGh0dHBzOi8vd3d3Lnczc2Nob29scy5jb20vdGFncy9hdHRfZ2xvYmFsX3RyYW5zbGF0ZS5hc3AgZm9yIG1vcmUgaW5mb3JtYXRpb24gYW5kIGJyb3dzZXIgc3VwcG9ydFxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHRyYW5zbGF0ZTpzdHJpbmc7XHJcblxyXG4gIC8qKiBTZXRzIGhlaWdodCBvZiB0aGUgZWRpdG9yICovXHJcbiAgQElucHV0KCkgaGVpZ2h0OnN0cmluZztcclxuXHJcbiAgLyoqIFNldHMgbWluaW11bSBoZWlnaHQgZm9yIHRoZSBlZGl0b3IgKi9cclxuICBASW5wdXQoKSBtaW5IZWlnaHQ6c3RyaW5nO1xyXG5cclxuICAvKiogU2V0cyBXaWR0aCBvZiB0aGUgZWRpdG9yICovXHJcbiAgQElucHV0KCkgd2lkdGg6c3RyaW5nO1xyXG5cclxuICAvKiogU2V0cyBtaW5pbXVtIHdpZHRoIG9mIHRoZSBlZGl0b3IgKi9cclxuICBASW5wdXQoKSBtaW5XaWR0aDpzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvb2xiYXIgYWNjZXB0cyBhbiBhcnJheSB3aGljaCBzcGVjaWZpZXMgdGhlIG9wdGlvbnMgdG8gYmUgZW5hYmxlZCBmb3IgdGhlIHRvb2xiYXJcclxuICAgKlxyXG4gICAqIENoZWNrIG5neFRleHRFZGl0b3JDb25maWcgZm9yIHRvb2xiYXIgY29uZmlndXJhdGlvblxyXG4gICAqXHJcbiAgICogUGFzc2luZyBhbiBlbXB0eSBhcnJheSB3aWxsIGVuYWJsZSBhbGwgdG9vbGJhclxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHRvb2xiYXI6T2JqZWN0O1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZWRpdG9yIGNhbiBiZSByZXNpemVkIHZlcnRpY2FsbHkuXHJcbiAgICpcclxuICAgKiBgYmFzaWNgIHJlc2l6ZXIgZW5hYmxlcyB0aGUgaHRtbDUgcmVzemllci4gQ2hlY2sgaGVyZSBodHRwczovL3d3dy53M3NjaG9vbHMuY29tL2Nzc3JlZi9jc3MzX3ByX3Jlc2l6ZS5hc3BcclxuICAgKlxyXG4gICAqIGBzdGFja2AgcmVzaXplciBlbmFibGUgYSByZXNpemVyIHRoYXQgbG9va3MgbGlrZSBhcyBpZiBpbiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tXHJcbiAgICovXHJcbiAgQElucHV0KCkgcmVzaXplciA9ICdzdGFjayc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBjb25maWcgcHJvcGVydHkgaXMgYSBKU09OIG9iamVjdFxyXG4gICAqXHJcbiAgICogQWxsIGF2YWliYWxlIGlucHV0cyBpbnB1dHMgY2FuIGJlIHByb3ZpZGVkIGluIHRoZSBjb25maWd1cmF0aW9uIGFzIEpTT05cclxuICAgKiBpbnB1dHMgcHJvdmlkZWQgZGlyZWN0bHkgYXJlIGNvbnNpZGVyZWQgYXMgdG9wIHByaW9yaXR5XHJcbiAgICovXHJcbiAgQElucHV0KCkgY29uZmlnID0gbmd4VGV4dEVkaXRvckNvbmZpZztcclxuXHJcbiAgLyoqIFdlYXRoZXIgdG8gc2hvdyBvciBoaWRlIHRvb2xiYXIgKi9cclxuICBASW5wdXQoKSBzaG93VG9vbGJhcjpib29sZWFuO1xyXG5cclxuICAvKiogV2VhdGhlciB0byBlbmFibGUgb3IgZGlzYWJsZSB0aGUgdG9vbGJhciAqL1xyXG4gIEBJbnB1dCgpIGVuYWJsZVRvb2xiYXI6Ym9vbGVhbjtcclxuXHJcbiAgLyoqIEVuZHBvaW50IGZvciB3aGljaCB0aGUgaW1hZ2UgdG8gYmUgdXBsb2FkZWQgKi9cclxuICBASW5wdXQoKSBpbWFnZUVuZFBvaW50OnN0cmluZztcclxuXHJcbiAgLyoqIGVtaXRzIGBibHVyYCBldmVudCB3aGVuIGZvY3VzZWQgb3V0IGZyb20gdGhlIHRleHRhcmVhICovXHJcbiAgQE91dHB1dCgpIGJsdXI6RXZlbnRFbWl0dGVyPHN0cmluZz4gPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuXHJcbiAgLyoqIGVtaXRzIGBmb2N1c2AgZXZlbnQgd2hlbiBmb2N1c2VkIGluIHRvIHRoZSB0ZXh0YXJlYSAqL1xyXG4gIEBPdXRwdXQoKSBmb2N1czpFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG5cclxuICAvKiogZW1pdHMgYHVwbG9hZEltYWdlYCBldmVudCB3aGVuIGltYWdlIGlzIHNlbGVjdGVkICovXHJcbiAgQE91dHB1dCgpIHVwbG9hZEltYWdlOkV2ZW50RW1pdHRlcjxIVE1MSW5wdXRFbGVtZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8SFRNTElucHV0RWxlbWVudD4oKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnbmd4VGV4dEFyZWEnLCB7IHN0YXRpYzogdHJ1ZSB9KSB0ZXh0QXJlYTphbnk7XHJcbiAgQFZpZXdDaGlsZCgnbmd4V3JhcHBlcicsIHsgc3RhdGljOiB0cnVlIH0pIG5neFdyYXBwZXI6YW55O1xyXG5cclxuICBwdWJsaWMgVXRpbHM6YW55ID0gVXRpbHM7XHJcblxyXG4gIHByaXZhdGUgb25DaGFuZ2U6KHZhbHVlOnN0cmluZykgPT4gdm9pZDtcclxuICBwcml2YXRlIG9uVG91Y2hlZDooKSA9PiB2b2lkO1xyXG5cclxuICAvKipcclxuICAgKiBAcGFyYW0gX21lc3NhZ2VTZXJ2aWNlIHNlcnZpY2UgdG8gc2VuZCBtZXNzYWdlIHRvIHRoZSBlZGl0b3IgbWVzc2FnZSBjb21wb25lbnRcclxuICAgKiBAcGFyYW0gX2NvbW1hbmRFeGVjdXRvciBleGVjdXRlcyBjb21tYW5kIGZyb20gdGhlIHRvb2xiYXJcclxuICAgKiBAcGFyYW0gX3JlbmRlcmVyIGFjY2VzcyBhbmQgbWFuaXB1bGF0ZSB0aGUgZG9tIGVsZW1lbnRcclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX21lc3NhZ2VTZXJ2aWNlOk1lc3NhZ2VTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBfY29tbWFuZEV4ZWN1dG9yOkNvbW1hbmRFeGVjdXRvclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9yZW5kZXJlcjpSZW5kZXJlcjIpIHsgfVxyXG5cclxuICAvKipcclxuICAgKiBldmVudHNcclxuICAgKi9cclxuICBvblRleHRBcmVhRm9jdXMoKTp2b2lkIHtcclxuICAgIHRoaXMuZm9jdXMuZW1pdCgnZm9jdXMnKTtcclxuICB9XHJcblxyXG4gIC8qKiBmb2N1cyB0aGUgdGV4dCBhcmVhIHdoZW4gdGhlIGVkaXRvciBpcyBmb2N1c3NlZCAqL1xyXG4gIG9uRWRpdG9yRm9jdXMoKSB7XHJcbiAgICB0aGlzLnRleHRBcmVhLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4ZWN1dGVkIGZyb20gdGhlIGNvbnRlbnRFZGl0YWJsZSBzZWN0aW9uIHdoaWxlIHRoZSBpbnB1dCBwcm9wZXJ0eSBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGlubmVySFRNTCBodG1sIHN0cmluZyBmcm9tIGNvbnRlbnRFZGl0YWJsZVxyXG4gICAqL1xyXG4gIG9uQ29udGVudENoYW5nZShpbm5lckhUTUw6c3RyaW5nKTp2b2lkIHtcclxuICAgIGlmICh0eXBlb2YgdGhpcy5vbkNoYW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICB0aGlzLm9uQ2hhbmdlKGlubmVySFRNTCk7XHJcbiAgICAgIHRoaXMudG9nZ2xlUGxhY2Vob2xkZXIoaW5uZXJIVE1MKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uVGV4dEFyZWFCbHVyKCk6dm9pZCB7XHJcbiAgICAvKiogc2F2ZSBzZWxlY3Rpb24gaWYgZm9jdXNzZWQgb3V0ICovXHJcbiAgICB0aGlzLl9jb21tYW5kRXhlY3V0b3Iuc2F2ZWRTZWxlY3Rpb24gPSBVdGlscy5zYXZlU2VsZWN0aW9uKCk7XHJcblxyXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9uVG91Y2hlZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICB0aGlzLm9uVG91Y2hlZCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5ibHVyLmVtaXQoJ2JsdXInKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4ZWN1dGVkIHdoZW4gdGhlIGltYWdlIGZyb20gdGhlIGRpc2MgaXMgc2VsZWN0ZWRcclxuICAgKiBAcGFyYW0gaW1hZ2UgdXBsb2FkZWQgZmlsZSBvYmplY3RcclxuICAgKi9cclxuICBvblVwbG9hZEltYWdlKGltYWdlOkhUTUxJbnB1dEVsZW1lbnQpOnZvaWQge1xyXG4gICAgdGhpcy51cGxvYWRJbWFnZS5lbWl0KGltYWdlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHJlc2l6aW5nIHRleHQgYXJlYVxyXG4gICAqXHJcbiAgICogQHBhcmFtIG9mZnNldFkgdmVydGljYWwgaGVpZ2h0IG9mIHRoZSBlaWR0YWJsZSBwb3J0aW9uIG9mIHRoZSBlZGl0b3JcclxuICAgKi9cclxuICByZXNpemVUZXh0QXJlYShvZmZzZXRZOm51bWJlcik6dm9pZCB7XHJcbiAgICBsZXQgbmV3SGVpZ2h0ID0gcGFyc2VJbnQodGhpcy5oZWlnaHQsIDEwKTtcclxuICAgIG5ld0hlaWdodCArPSBvZmZzZXRZO1xyXG5cclxuICAgIHRoaXMuaGVpZ2h0ID0gbmV3SGVpZ2h0ICsgJ3B4JztcclxuICAgIHRoaXMudGV4dEFyZWEubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGVkaXRvciBhY3Rpb25zLCBpLmUuLCBleGVjdXRlcyBjb21tYW5kIGZyb20gdG9vbGJhclxyXG4gICAqXHJcbiAgICogQHBhcmFtIGNvbW1hbmROYW1lIG5hbWUgb2YgdGhlIGNvbW1hbmQgdG8gYmUgZXhlY3V0ZWRcclxuICAgKi9cclxuICBleGVjdXRlQ29tbWFuZChjb21tYW5kTmFtZTpzdHJpbmcpOnZvaWQge1xyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5fY29tbWFuZEV4ZWN1dG9yLmV4ZWN1dGUoY29tbWFuZE5hbWUpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgdGhpcy5fbWVzc2FnZVNlcnZpY2Uuc2VuZE1lc3NhZ2UoZXJyb3IubWVzc2FnZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBXcml0ZSBhIG5ldyB2YWx1ZSB0byB0aGUgZWxlbWVudC5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB2YWx1ZSB2YWx1ZSB0byBiZSBleGVjdXRlZCB3aGVuIHRoZXJlIGlzIGEgY2hhbmdlIGluIGNvbnRlbnRlZGl0YWJsZVxyXG4gICAqL1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6YW55KTp2b2lkIHtcclxuICAgIHRoaXMudG9nZ2xlUGxhY2Vob2xkZXIodmFsdWUpO1xyXG5cclxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJyB8fCB2YWx1ZSA9PT0gJzxicj4nKSB7XHJcbiAgICAgIHZhbHVlID0gbnVsbDtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnJlZnJlc2hWaWV3KHZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldCB0aGUgZnVuY3Rpb24gdG8gYmUgY2FsbGVkXHJcbiAgICogd2hlbiB0aGUgY29udHJvbCByZWNlaXZlcyBhIGNoYW5nZSBldmVudC5cclxuICAgKlxyXG4gICAqIEBwYXJhbSBmbiBhIGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjphbnkpOnZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IHRoZSBmdW5jdGlvbiB0byBiZSBjYWxsZWRcclxuICAgKiB3aGVuIHRoZSBjb250cm9sIHJlY2VpdmVzIGEgdG91Y2ggZXZlbnQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0gZm4gYSBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOmFueSk6dm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmVmcmVzaCB2aWV3L0hUTUwgb2YgdGhlIGVkaXRvclxyXG4gICAqXHJcbiAgICogQHBhcmFtIHZhbHVlIGh0bWwgc3RyaW5nIGZyb20gdGhlIGVkaXRvclxyXG4gICAqL1xyXG4gIHJlZnJlc2hWaWV3KHZhbHVlOnN0cmluZyk6dm9pZCB7XHJcbiAgICBjb25zdCBub3JtYWxpemVkVmFsdWUgPSB2YWx1ZSA9PT0gbnVsbCA/ICcnIDogdmFsdWU7XHJcblxyXG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0UHJvcGVydHkodGhpcy50ZXh0QXJlYS5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgbm9ybWFsaXplZFZhbHVlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHRvZ2dsZXMgcGxhY2Vob2xkZXIgYmFzZWQgb24gaW5wdXQgc3RyaW5nXHJcbiAgICpcclxuICAgKiBAcGFyYW0gdmFsdWUgQSBIVE1MIHN0cmluZyBmcm9tIHRoZSBlZGl0b3JcclxuICAgKi9cclxuICB0b2dnbGVQbGFjZWhvbGRlcih2YWx1ZTphbnkpOnZvaWQge1xyXG4gICAgaWYgKCF2YWx1ZSB8fCB2YWx1ZSA9PT0gJzxicj4nIHx8IHZhbHVlID09PSAnJykge1xyXG4gICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyh0aGlzLm5neFdyYXBwZXIubmF0aXZlRWxlbWVudCwgJ3Nob3ctcGxhY2Vob2xkZXInKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMubmd4V3JhcHBlci5uYXRpdmVFbGVtZW50LCAnc2hvdy1wbGFjZWhvbGRlcicpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogcmV0dXJucyBhIGpzb24gY29udGFpbmluZyBpbnB1dCBwYXJhbXNcclxuICAgKi9cclxuICBnZXRDb2xsZWN0aXZlUGFyYW1zKCk6YW55IHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGVkaXRhYmxlOnRoaXMuZWRpdGFibGUsXHJcbiAgICAgIHNwZWxsY2hlY2s6dGhpcy5zcGVsbGNoZWNrLFxyXG4gICAgICBwbGFjZWhvbGRlcjp0aGlzLnBsYWNlaG9sZGVyLFxyXG4gICAgICB0cmFuc2xhdGU6dGhpcy50cmFuc2xhdGUsXHJcbiAgICAgIGhlaWdodDp0aGlzLmhlaWdodCxcclxuICAgICAgbWluSGVpZ2h0OnRoaXMubWluSGVpZ2h0LFxyXG4gICAgICB3aWR0aDp0aGlzLndpZHRoLFxyXG4gICAgICBtaW5XaWR0aDp0aGlzLm1pbldpZHRoLFxyXG4gICAgICBlbmFibGVUb29sYmFyOnRoaXMuZW5hYmxlVG9vbGJhcixcclxuICAgICAgc2hvd1Rvb2xiYXI6dGhpcy5zaG93VG9vbGJhcixcclxuICAgICAgaW1hZ2VFbmRQb2ludDp0aGlzLmltYWdlRW5kUG9pbnQsXHJcbiAgICAgIHRvb2xiYXI6dGhpcy50b29sYmFyXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAvKipcclxuICAgICAqIHNldCBjb25maWd1cmF0aW9uXHJcbiAgICAgKi9cclxuICAgIHRoaXMuY29uZmlnID0gdGhpcy5VdGlscy5nZXRFZGl0b3JDb25maWd1cmF0aW9uKHRoaXMuY29uZmlnLCBuZ3hUZXh0RWRpdG9yQ29uZmlnLCB0aGlzLmdldENvbGxlY3RpdmVQYXJhbXMoKSk7XHJcblxyXG4gICAgdGhpcy5oZWlnaHQgPSB0aGlzLmhlaWdodCB8fCB0aGlzLnRleHRBcmVhLm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgIHRoaXMuZXhlY3V0ZUNvbW1hbmQoJ2VuYWJsZU9iamVjdFJlc2l6aW5nJyk7XHJcbiAgfVxyXG59XHJcbiJdfQ==