UNPKG

angular-xml-editor

Version:
363 lines (362 loc) 31.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { XMLCursorPositions } from './code/cursor/xmlCursorPos.class'; import { DomDummyNodeManager } from './code/dummyNodes/domDummyNodeManager.class'; import { Component, Input, ViewChild, Output, EventEmitter, Renderer2, forwardRef, ViewEncapsulation, ElementRef } from '@angular/core'; import { AngularXmlEditorService } from './angular-xml-editor.service'; import { Xml2html } from './code/xml-html-converter/xml2html.class'; import { Html2xml } from './code/xml-html-converter/html2xml.class'; var AngularXmlEditorComponent = /** @class */ (function () { function AngularXmlEditorComponent(_renderer, editorService) { this._renderer = _renderer; this.editorService = editorService; this.isDebugMode = false; this.valueChange = new EventEmitter(); // actualXmlCursor: XmlCursor = new XmlCursor(); this.domDummyNodeManager = new DomDummyNodeManager(); } Object.defineProperty(AngularXmlEditorComponent.prototype, "config", { get: /** * @return {?} */ function () { if (this.editorContext !== undefined && this.editorContext.config !== undefined) { return this.editorContext && this.editorContext.config; } return undefined; }, enumerable: true, configurable: true }); Object.defineProperty(AngularXmlEditorComponent.prototype, "editorContextId", { set: /** * @param {?} value * @return {?} */ function (value) { if (!value) { return; } this.editorContext = this.editorService.getEditorContext(value); }, enumerable: true, configurable: true }); Object.defineProperty(AngularXmlEditorComponent.prototype, "debugMode", { set: /** * @param {?} value * @return {?} */ function (value) { this.isDebugMode = value; }, enumerable: true, configurable: true }); /** * @return {?} */ AngularXmlEditorComponent.prototype.ngOnChanges = /** * @return {?} */ function () { }; /** * @return {?} */ AngularXmlEditorComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { }; /** * @return {?} */ AngularXmlEditorComponent.prototype.onLostFocus = /** * @return {?} */ function () { this.editorContext.saveSelection(); // save selection on lost focus if (typeof this.onTouchedFunction === 'function') { this.onTouchedFunction(); } return; }; /** * @return {?} */ AngularXmlEditorComponent.prototype.onGotFocus = /** * @return {?} */ function () { this.editorContext.restoreSelection(); this.textArea.nativeElement.focus(); // set focus to the text area }; /** * @return {?} */ AngularXmlEditorComponent.prototype.clicked = /** * @return {?} */ function () { }; /** * @return {?} */ AngularXmlEditorComponent.prototype.mousedown = /** * @return {?} */ function () { }; /** * @param {?} mouseEvent * @return {?} */ AngularXmlEditorComponent.prototype.mouseup = /** * @param {?} mouseEvent * @return {?} */ function (mouseEvent) { return this.editorContext.mouseUp(mouseEvent); }; /** * @param {?} text * @return {?} */ AngularXmlEditorComponent.prototype.pasted = /** * @param {?} text * @return {?} */ function (text) { return this.editorContext.pasted(text); }; /** * @return {?} */ AngularXmlEditorComponent.prototype.copied = /** * @return {?} */ function () { return this.editorContext.copied(); }; /** * @param {?} event * @return {?} */ AngularXmlEditorComponent.prototype.keyDown = /** * @param {?} event * @return {?} */ function (event) { return this.editorContext.keyDown(event); }; /** * @param {?} event * @return {?} */ AngularXmlEditorComponent.prototype.keyUp = /** * @param {?} event * @return {?} */ function (event) { return this.editorContext.keyUp(event); }; // exec(): boolean { // let userSelection: Selection; // if (window.getSelection) { // userSelection = window.getSelection(); // this.editorBreadCrumb.showSelection(userSelection); // this.actualXmlCursor.StartPos.SetCursor(userSelection.anchorNode, XMLCursorPositionen.CursorInsideTextNode, userSelection.anchorOffset); // this.commander.setCursorPos(this.actualXmlCursor.StartPos); // } // this.domDummyNodeManager.UpdateDummyNodes(this.actualXmlCursor.xmlDocumentRootNode, false); // return false; // } /** * @param {?} xml * @return {?} */ AngularXmlEditorComponent.prototype.showXml = /** * @param {?} xml * @return {?} */ function (xml) { if (this.textArea && this.editorContext && this.editorContext.config && this.editorContext.config.rules) { if (xml === undefined) { return; } /** @type {?} */ var xml2html = new Xml2html(this.editorContext.config.rules); /** @type {?} */ var html = xml2html.ToHtml(xml); /** @type {?} */ var normalizedValue = xml === null ? '' : html; this._renderer.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue); } }; /* START OF ControlValueAccessor (see https://angular.io/api/forms/ControlValueAccessor ) */ /** * Sets the function called when the control gets a change event */ /** * Sets the function called when the control gets a change event * @param {?} func * @return {?} */ AngularXmlEditorComponent.prototype.registerOnChange = /** * Sets the function called when the control gets a change event * @param {?} func * @return {?} */ function (func) { this.onChangeFunction = func; }; /** * Sets the function called when the control gets a touch event */ /** * Sets the function called when the control gets a touch event * @param {?} func * @return {?} */ AngularXmlEditorComponent.prototype.registerOnTouched = /** * Sets the function called when the control gets a touch event * @param {?} func * @return {?} */ function (func) { this.onTouchedFunction = func; }; /** * Write the new value to the element */ /** * Write the new value to the element * @param {?} value * @return {?} */ AngularXmlEditorComponent.prototype.writeValue = /** * Write the new value to the element * @param {?} value * @return {?} */ function (value) { if (this.editorContext && this.editorContext.config) { if (value === null || value === undefined || value === '') { value = undefined; } this.showXml(value); if (value === undefined) { this.editorContext.actualCursor.xmlDocumentRootNode = undefined; } else { /** @type {?} */ var el = /** @type {?} */ (this.textArea.nativeElement); /** @type {?} */ var node = /** @type {?} */ (el.firstChild); this.editorContext.actualCursor.xmlDocumentRootNode = node; this.editorContext.actualCursor.StartPos.SetCursor(this.editorContext.actualCursor.xmlDocumentRootNode, XMLCursorPositions.CursorOnCompleteNode); this.domDummyNodeManager.UpdateDummyNodes(this.editorContext.actualCursor.xmlDocumentRootNode); } } }; /** * Executed from the contenteditable section while the input property changes * @param html html string from contenteditable */ /** * Executed from the contenteditable section while the input property changes * @param {?} html html string from contenteditable * @return {?} */ AngularXmlEditorComponent.prototype.onContentChange = /** * Executed from the contenteditable section while the input property changes * @param {?} html html string from contenteditable * @return {?} */ function (html) { if (typeof this.onChangeFunction === 'function') { /** @type {?} */ var html2xml = new Html2xml(this.editorContext.config.rules); /** @type {?} */ var xml = html2xml.ToXml(html); /** @type {?} */ var normalizedValue = xml === null ? '' : xml; this.onChangeFunction(normalizedValue); } return; }; /** * sets the disabled state for this element */ /** * sets the disabled state for this element * @param {?} isDisabled * @return {?} */ AngularXmlEditorComponent.prototype.setDisabledState = /** * sets the disabled state for this element * @param {?} isDisabled * @return {?} */ function (isDisabled) { /** @type {?} */ var div = this.textArea.nativeElement; /** @type {?} */ var action = isDisabled ? 'addClass' : 'removeClass'; this._renderer[action](div, 'disabled'); }; AngularXmlEditorComponent.decorators = [ { type: Component, args: [{ selector: 'axed-editor', template: "<div\r\n *ngIf=\"config\"\r\n #editor\r\n class=\"axed axed-textarea showtags debugOff\"\r\n (focus)=\"onGotFocus()\"\r\n [attr.contenteditable]=\"true\"\r\n [style.height]=\"config.height\"\r\n [style.width]=\"config.width\"\r\n (input)=\"onContentChange($event.target.innerHTML)\"\r\n (blur)=\"onLostFocus()\"\r\n (click)=\"clicked()\"\r\n (mousedown)=\"mousedown()\"\r\n (mouseup)=\"mouseup($event)\"\r\n (keyup)=\"keyUp($event)\"\r\n (keydown)=\"keyDown($event)\"\r\n (copy)=\"copied()\"\r\n (paste)=\"pasted($event.clipboardData.getData('text/plain'))\"\r\n></div>\r\n", encapsulation: ViewEncapsulation.None, // to prevent the scss to rename the class names and not match the new generated xml dom providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(function () { return AngularXmlEditorComponent; }), multi: true } ], styles: ["a{cursor:pointer}.axed-textarea{min-height:150px;overflow:auto;margin-top:5px;resize:vertical;outline:0;--font-size:15px;--topBottomTagPadding:2px;--tagIndent:20px;font-size:var(--font-size);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif}.axed-textarea.showtags{line-height:calc(var(--font-size) + (var(--topBottomTagPadding) * 2) + 10px)}.axed-textarea.showtags div::after,.axed-textarea.showtags div::before{background:orange;white-space:pre-wrap;border:1px solid #778899}.axed-textarea.showtags div::after,.axed-textarea.showtags div:not(.xmlTagNoClosing)::before{content:\" \" attr(data-tagname) \" \";padding:var(--topBottomTagPadding) 0 var(--topBottomTagPadding);margin:0 2px 2px}.axed-textarea.showtags div:not(.xmlTagNoClosing)::after{content:\" \" attr(data-tagname);padding-right:7px;border-radius:10px 0 0 10px}.axed-textarea.showtags div:not(.xmlTagNoClosing)::before{border-radius:0 10px 10px 0}.axed-textarea.showtags div[data-attributes].xmlTagNoClosing:not([data-attributes=''])::after,.axed-textarea.showtags div[data-attributes]:not([data-attributes='']):not(.xmlTagNoClosing)::before{content:\" \" attr(data-tagname) \" \" attr(data-attributes) \" \"}.axed-textarea.showtags div.comment::after,.axed-textarea.showtags div.comment::before{content:' ' 'comment' ' ';background-color:#d3d3d3}.axed-textarea div div:not(.floating){margin-left:var(--tagIndent)}.tagElement>.dummyNode.parent{color:red}div.floating{display:inline}span.dummyNode.beforefirstTag{float:left;width:0}.axed-textarea.debug span.dummyNode{background-color:red;width:inherit}.axed-textarea.debug span.dummyNode.beforefirstTag{background-color:violet;width:inherit}.axed-textarea.showtags div.selected,.axed-textarea.showtags div.selected::after,.axed-textarea.showtags div.selected::before{background:#add8e6!important;color:#fff}[data-tagname=parsererror],[data-tagname=parsererror] div,[data-tagname=parsererror] div ::after,[data-tagname=parsererror] div::before,[data-tagname=parsererror]::after,[data-tagname=parsererror]::before{background:red!important;color:#fff!important;font-weight:700!important;font-size:20px!important;line-height:32px!important}.angular-editor{position:relative}.angular-editor ::ng-deep [contenteditable=true]:empty:before{content:attr(placeholder);display:block;color:#868e96;opacity:1}.angular-editor .axed-wrapper{position:relative}.angular-editor .axed-wrapper .axed-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}.angular-editor .axed-wrapper .axed-textarea.focus,.angular-editor .axed-wrapper .axed-textarea:focus{outline:0}.angular-editor .axed-wrapper .axed-textarea ::ng-deep blockquote{margin-left:1rem;border-left:.2em solid #dfe2e5;padding-left:.5rem}.angular-editor .axed-wrapper ::ng-deep p{margin-bottom:0}.angular-editor .axed-wrapper .axed-placeholder{display:none;position:absolute;top:0;padding:.5rem .8rem 1rem .9rem;z-index:1;color:#6c757d;opacity:.75}.angular-editor .axed-wrapper.show-placeholder .angular-editor-placeholder{display:block}.angular-editor .axed-wrapper.disabled{cursor:not-allowed;opacity:.5;pointer-events:none}.axed-attribute-editor-toolbar{min-height:100px;font:100 .8rem/15px Roboto,Arial,sans-serif;background-color:#f5f5f5;padding:15px;border:1px solid #ddd;margin:0}.axed-attribute-editor-toolbar input,.axed-attribute-editor-toolbar select{width:100%}"] }] } ]; /** @nocollapse */ AngularXmlEditorComponent.ctorParameters = function () { return [ { type: Renderer2 }, { type: AngularXmlEditorService } ]; }; AngularXmlEditorComponent.propDecorators = { config: [{ type: Input, args: ['config',] }], editorContextId: [{ type: Input, args: ['editorContextId',] }], debugMode: [{ type: Input, args: ['debugMode',] }], textArea: [{ type: ViewChild, args: ['editor',] }], editorWrapper: [{ type: ViewChild, args: ['editorWrapper',] }], valueChange: [{ type: Output }] }; return AngularXmlEditorComponent; }()); export { AngularXmlEditorComponent }; if (false) { /** @type {?} */ AngularXmlEditorComponent.prototype.editorContext; /** @type {?} */ AngularXmlEditorComponent.prototype.isDebugMode; /** @type {?} */ AngularXmlEditorComponent.prototype.textArea; /** @type {?} */ AngularXmlEditorComponent.prototype.editorWrapper; /** @type {?} */ AngularXmlEditorComponent.prototype.valueChange; /** @type {?} */ AngularXmlEditorComponent.prototype.domDummyNodeManager; /** @type {?} */ AngularXmlEditorComponent.prototype.onTouchedFunction; /** @type {?} */ AngularXmlEditorComponent.prototype.onChangeFunction; /** @type {?} */ AngularXmlEditorComponent.prototype._renderer; /** @type {?} */ AngularXmlEditorComponent.prototype.editorService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci14bWwtZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXIteG1sLWVkaXRvci8iLCJzb3VyY2VzIjpbImxpYi9hbmd1bGFyLXhtbC1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbEYsT0FBTyxFQUFFLFNBQVMsRUFBYSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBYSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUosT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFdkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQzs7SUF1RGxFLG1DQUFvQixTQUFvQixFQUFVLGFBQXNDO1FBQXBFLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFBVSxrQkFBYSxHQUFiLGFBQWEsQ0FBeUI7MkJBckMxRSxLQUFLOzJCQTZCRSxJQUFJLFlBQVksRUFBRTs7bUNBR2pCLElBQUksbUJBQW1CLEVBQUU7S0FLNkM7SUFuQzVGLHNCQUNJLDZDQUFNOzs7O1FBRFY7WUFFRSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtnQkFDL0UsT0FBTyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO2FBQ3hEO1lBQ0QsT0FBTyxTQUFT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QkFDdkUsdUJBQXVCOzs7eUJBdUI3QixLQUFLLFNBQUMsUUFBUTtrQ0FRZCxLQUFLLFNBQUMsaUJBQWlCOzRCQVF2QixLQUFLLFNBQUMsV0FBVzsyQkFLakIsU0FBUyxTQUFDLFFBQVE7Z0NBRWxCLFNBQVMsU0FBQyxlQUFlOzhCQUd6QixNQUFNOztvQ0F0RFQ7O1NBd0JhLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgWG1sRWRpdG9yQ29uZmlnIH0gZnJvbSAnLi9jb2RlL3htbEVkaXRvckNvbmZpZyc7XHJcbmltcG9ydCB7IFhNTEN1cnNvclBvc2l0aW9ucyB9IGZyb20gJy4vY29kZS9jdXJzb3IveG1sQ3Vyc29yUG9zLmNsYXNzJztcclxuaW1wb3J0IHsgRG9tRHVtbXlOb2RlTWFuYWdlciB9IGZyb20gJy4vY29kZS9kdW1teU5vZGVzL2RvbUR1bW15Tm9kZU1hbmFnZXIuY2xhc3MnO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIE9uQ2hhbmdlcywgSW5wdXQsIFZpZXdDaGlsZCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIFJlbmRlcmVyMiwgZm9yd2FyZFJlZiwgVmlld0VuY2Fwc3VsYXRpb24sIE9uRGVzdHJveSwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBBbmd1bGFyWG1sRWRpdG9yU2VydmljZSB9IGZyb20gJy4vYW5ndWxhci14bWwtZWRpdG9yLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBYbWxFZGl0b3JDb250ZXh0IH0gZnJvbSAnLi9jb2RlL3htbEVkaXRvckNvbnRleHQuY2xhc3MnO1xyXG5pbXBvcnQgeyBYbWwyaHRtbCB9IGZyb20gJy4vY29kZS94bWwtaHRtbC1jb252ZXJ0ZXIveG1sMmh0bWwuY2xhc3MnO1xyXG5pbXBvcnQgeyBIdG1sMnhtbCB9IGZyb20gJy4vY29kZS94bWwtaHRtbC1jb252ZXJ0ZXIvaHRtbDJ4bWwuY2xhc3MnO1xyXG5pbXBvcnQgeyBEZWJ1Z0NvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3NyYy92aWV3JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXhlZC1lZGl0b3InLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9hbmd1bGFyLXhtbC1lZGl0b3IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2FuZ3VsYXIteG1sLWVkaXRvci5jb21wb25lbnQuc2NzcyddLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsIC8vIHRvIHByZXZlbnQgdGhlIHNjc3MgdG8gcmVuYW1lIHRoZSBjbGFzcyBuYW1lcyBhbmQgbm90IG1hdGNoIHRoZSBuZXcgZ2VuZXJhdGVkIHhtbCBkb21cclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IEFuZ3VsYXJYbWxFZGl0b3JDb21wb25lbnQpLFxyXG4gICAgICBtdWx0aTogdHJ1ZVxyXG4gICAgfVxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEFuZ3VsYXJYbWxFZGl0b3JDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgZWRpdG9yQ29udGV4dDogWG1sRWRpdG9yQ29udGV4dDtcclxuICBpc0RlYnVnTW9kZSA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoJ2NvbmZpZycpXHJcbiAgZ2V0IGNvbmZpZygpOiBYbWxFZGl0b3JDb25maWcge1xyXG4gICAgaWYgKHRoaXMuZWRpdG9yQ29udGV4dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0ICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWc7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCdlZGl0b3JDb250ZXh0SWQnKVxyXG4gIHNldCBlZGl0b3JDb250ZXh0SWQodmFsdWU6IHN0cmluZykge1xyXG4gICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLmVkaXRvckNvbnRleHQgPSB0aGlzLmVkaXRvclNlcnZpY2UuZ2V0RWRpdG9yQ29udGV4dCh2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoJ2RlYnVnTW9kZScpXHJcbiAgc2V0IGRlYnVnTW9kZSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgdGhpcy5pc0RlYnVnTW9kZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgQFZpZXdDaGlsZCgnZWRpdG9yJylcclxuICB0ZXh0QXJlYTogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdlZGl0b3JXcmFwcGVyJylcclxuICBlZGl0b3JXcmFwcGVyOiBFbGVtZW50UmVmO1xyXG5cclxuICBAT3V0cHV0KClcclxuICBwdWJsaWMgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIC8vIGFjdHVhbFhtbEN1cnNvcjogWG1sQ3Vyc29yID0gbmV3IFhtbEN1cnNvcigpO1xyXG4gIGRvbUR1bW15Tm9kZU1hbmFnZXIgPSBuZXcgRG9tRHVtbXlOb2RlTWFuYWdlcigpO1xyXG5cclxuICBwcml2YXRlIG9uVG91Y2hlZEZ1bmN0aW9uOiAoKSA9PiB2b2lkO1xyXG4gIHByaXZhdGUgb25DaGFuZ2VGdW5jdGlvbjogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQ7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsIHByaXZhdGUgZWRpdG9yU2VydmljZTogQW5ndWxhclhtbEVkaXRvclNlcnZpY2UpIHt9XHJcblxyXG4gIG5nT25DaGFuZ2VzKCkge31cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7fVxyXG5cclxuICBvbkxvc3RGb2N1cygpIHtcclxuICAgIHRoaXMuZWRpdG9yQ29udGV4dC5zYXZlU2VsZWN0aW9uKCk7IC8vIHNhdmUgc2VsZWN0aW9uIG9uIGxvc3QgZm9jdXNcclxuICAgIGlmICh0eXBlb2YgdGhpcy5vblRvdWNoZWRGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICB0aGlzLm9uVG91Y2hlZEZ1bmN0aW9uKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBvbkdvdEZvY3VzKCkge1xyXG4gICAgdGhpcy5lZGl0b3JDb250ZXh0LnJlc3RvcmVTZWxlY3Rpb24oKTtcclxuICAgIHRoaXMudGV4dEFyZWEubmF0aXZlRWxlbWVudC5mb2N1cygpOyAvLyBzZXQgZm9jdXMgdG8gdGhlIHRleHQgYXJlYVxyXG4gIH1cclxuXHJcbiAgY2xpY2tlZCgpIHt9XHJcblxyXG4gIG1vdXNlZG93bigpIHt9XHJcblxyXG4gIG1vdXNldXAobW91c2VFdmVudDogTW91c2VFdmVudCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5tb3VzZVVwKG1vdXNlRXZlbnQpO1xyXG4gIH1cclxuXHJcbiAgcGFzdGVkKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5wYXN0ZWQodGV4dCk7XHJcbiAgfVxyXG5cclxuICBjb3BpZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0LmNvcGllZCgpO1xyXG4gIH1cclxuXHJcbiAga2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yQ29udGV4dC5rZXlEb3duKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIGtleVVwKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5lZGl0b3JDb250ZXh0LmtleVVwKGV2ZW50KTtcclxuICB9XHJcblxyXG4gIC8vIGV4ZWMoKTogYm9vbGVhbiB7XHJcbiAgLy8gICBsZXQgdXNlclNlbGVjdGlvbjogU2VsZWN0aW9uO1xyXG4gIC8vICAgaWYgKHdpbmRvdy5nZXRTZWxlY3Rpb24pIHtcclxuICAvLyAgICAgdXNlclNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAvLyAgICAgdGhpcy5lZGl0b3JCcmVhZENydW1iLnNob3dTZWxlY3Rpb24odXNlclNlbGVjdGlvbik7XHJcbiAgLy8gICAgIHRoaXMuYWN0dWFsWG1sQ3Vyc29yLlN0YXJ0UG9zLlNldEN1cnNvcih1c2VyU2VsZWN0aW9uLmFuY2hvck5vZGUsIFhNTEN1cnNvclBvc2l0aW9uZW4uQ3Vyc29ySW5zaWRlVGV4dE5vZGUsIHVzZXJTZWxlY3Rpb24uYW5jaG9yT2Zmc2V0KTtcclxuICAvLyAgICAgdGhpcy5jb21tYW5kZXIuc2V0Q3Vyc29yUG9zKHRoaXMuYWN0dWFsWG1sQ3Vyc29yLlN0YXJ0UG9zKTtcclxuICAvLyAgIH1cclxuXHJcbiAgLy8gICB0aGlzLmRvbUR1bW15Tm9kZU1hbmFnZXIuVXBkYXRlRHVtbXlOb2Rlcyh0aGlzLmFjdHVhbFhtbEN1cnNvci54bWxEb2N1bWVudFJvb3ROb2RlLCBmYWxzZSk7XHJcblxyXG4gIC8vICAgcmV0dXJuIGZhbHNlO1xyXG4gIC8vIH1cclxuXHJcbiAgc2hvd1htbCh4bWw6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMudGV4dEFyZWEgJiYgdGhpcy5lZGl0b3JDb250ZXh0ICYmIHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcgJiYgdGhpcy5lZGl0b3JDb250ZXh0LmNvbmZpZy5ydWxlcykge1xyXG4gICAgICBpZiAoeG1sID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHhtbDJodG1sID0gbmV3IFhtbDJodG1sKHRoaXMuZWRpdG9yQ29udGV4dC5jb25maWcucnVsZXMpO1xyXG4gICAgICBjb25zdCBodG1sID0geG1sMmh0bWwuVG9IdG1sKHhtbCk7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHhtbCA9PT0gbnVsbCA/ICcnIDogaHRtbDtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0UHJvcGVydHkodGhpcy50ZXh0QXJlYS5uYXRpdmVFbGVtZW50LCAnaW5uZXJIVE1MJywgbm9ybWFsaXplZFZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qIFNUQVJUIE9GIENvbnRyb2xWYWx1ZUFjY2Vzc29yICAoc2VlIGh0dHBzOi8vYW5ndWxhci5pby9hcGkvZm9ybXMvQ29udHJvbFZhbHVlQWNjZXNzb3IgKSAqL1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBnZXRzIGEgY2hhbmdlIGV2ZW50XHJcbiAgICovXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmdW5jOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2VGdW5jdGlvbiA9IGZ1bmM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgY29udHJvbCBnZXRzIGEgdG91Y2ggZXZlbnRcclxuICAgKi9cclxuICByZWdpc3Rlck9uVG91Y2hlZChmdW5jOiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkRnVuY3Rpb24gPSBmdW5jO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogV3JpdGUgdGhlIG5ldyB2YWx1ZSB0byB0aGUgZWxlbWVudFxyXG4gICAqL1xyXG4gIHdyaXRlVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZWRpdG9yQ29udGV4dCAmJiB0aGlzLmVkaXRvckNvbnRleHQuY29uZmlnKSB7XHJcbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykge1xyXG4gICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLnNob3dYbWwodmFsdWUpO1xyXG5cclxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB0aGlzLmVkaXRvckNvbnRleHQuYWN0dWFsQ3Vyc29yLnhtbERvY3VtZW50Um9vdE5vZGUgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgZWwgPSB0aGlzLnRleHRBcmVhLm5hdGl2ZUVsZW1lbnQgYXMgRWxlbWVudDtcclxuICAgICAgICBjb25zdCBub2RlID0gZWwuZmlyc3RDaGlsZCBhcyBFbGVtZW50O1xyXG4gICAgICAgIHRoaXMuZWRpdG9yQ29udGV4dC5hY3R1YWxDdXJzb3IueG1sRG9jdW1lbnRSb290Tm9kZSA9IG5vZGU7XHJcbiAgICAgICAgdGhpcy5lZGl0b3JDb250ZXh0LmFjdHVhbEN1cnNvci5TdGFydFBvcy5TZXRDdXJzb3IodGhpcy5lZGl0b3JDb250ZXh0LmFjdHVhbEN1cnNvci54bWxEb2N1bWVudFJvb3ROb2RlLCBYTUxDdXJzb3JQb3NpdGlvbnMuQ3Vyc29yT25Db21wbGV0ZU5vZGUpO1xyXG4gICAgICAgIHRoaXMuZG9tRHVtbXlOb2RlTWFuYWdlci5VcGRhdGVEdW1teU5vZGVzKHRoaXMuZWRpdG9yQ29udGV4dC5hY3R1YWxDdXJzb3IueG1sRG9jdW1lbnRSb290Tm9kZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4ZWN1dGVkIGZyb20gdGhlIGNvbnRlbnRlZGl0YWJsZSBzZWN0aW9uIHdoaWxlIHRoZSBpbnB1dCBwcm9wZXJ0eSBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGh0bWwgaHRtbCBzdHJpbmcgZnJvbSBjb250ZW50ZWRpdGFibGVcclxuICAgKi9cclxuICBvbkNvbnRlbnRDaGFuZ2UoaHRtbDogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBpZiAodHlwZW9mIHRoaXMub25DaGFuZ2VGdW5jdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zdCBodG1sMnhtbCA9IG5ldyBIdG1sMnhtbCh0aGlzLmVkaXRvckNvbnRleHQuY29uZmlnLnJ1bGVzKTtcclxuICAgICAgY29uc3QgeG1sID0gaHRtbDJ4bWwuVG9YbWwoaHRtbCk7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHhtbCA9PT0gbnVsbCA/ICcnIDogeG1sO1xyXG4gICAgICB0aGlzLm9uQ2hhbmdlRnVuY3Rpb24obm9ybWFsaXplZFZhbHVlKTtcclxuICAgIH1cclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHNldHMgdGhlIGRpc2FibGVkIHN0YXRlIGZvciB0aGlzIGVsZW1lbnRcclxuICAgKi9cclxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIGNvbnN0IGRpdiA9IHRoaXMudGV4dEFyZWEubmF0aXZlRWxlbWVudDtcclxuICAgIGNvbnN0IGFjdGlvbiA9IGlzRGlzYWJsZWQgPyAnYWRkQ2xhc3MnIDogJ3JlbW92ZUNsYXNzJztcclxuICAgIHRoaXMuX3JlbmRlcmVyW2FjdGlvbl0oZGl2LCAnZGlzYWJsZWQnKTtcclxuICB9XHJcblxyXG4gIC8qIEVORCBPRiBDb250cm9sVmFsdWVBY2Nlc3NvciAqL1xyXG59XHJcbiJdfQ==