UNPKG

angular-rich-text-editor

Version:

A lightweight, configurable rich-text editor component for Angular applications.

665 lines (659 loc) 79.8 kB
import { Component, forwardRef, Input, ViewChild, Inject, Optional, } from '@angular/core'; import { NG_VALUE_ACCESSOR, NG_VALIDATORS, NgControl, } from '@angular/forms'; import { RTE_TOOLBAR_PRESETS, } from './rich-text-editor.constant'; import { RTE_LICENSE_KEY } from './rich-text-editor-license.token'; import { cleanToolbarString } from './utils/toolbar-cleaner'; import { EditorEventManager } from './utils/editor-event-manager'; import { patchRemoveChildIfDetached, safeCleanupFloatingPanels, } from './utils/dom-cleanup'; import { hasRequiredValidator, isTrulyEmpty } from './utils/validation-utils'; import * as i0 from "@angular/core"; import * as i1 from "./rich-text-editor.service"; import * as i2 from "@angular/common"; export class RichTextEditorComponent { injector; rteService; cdr; ngZone; globalLicenseKey; editorContainer; licenseKey = ''; config = {}; rtePreset = null; imageToolbarItems = null; excludedToolbarItems = []; initialContent = ''; errorMessages = { required: 'This field is required.', }; fileUploadHandler = () => { }; enableImageUpload = false; enableVideoEmbed = false; readonly = false; eventManager = null; editorInstance; value = ''; ngControl = null; changeTimer; isDestroyed = false; cleanupAttempts = 0; eventListeners = []; domCleanupTimer; onChange = (value) => { }; onTouched = () => { }; constructor(injector, rteService, cdr, ngZone, globalLicenseKey) { this.injector = injector; this.rteService = rteService; this.cdr = cdr; this.ngZone = ngZone; this.globalLicenseKey = globalLicenseKey; } ngOnInit() { patchRemoveChildIfDetached(); this.rteService.setCurrentEditor(this); try { this.ngControl = this.injector.get(NgControl); if (this.ngControl) { this.ngControl.valueAccessor = this; } } catch { // Safe fallback } } ngAfterViewInit() { // Run outside Angular zone to prevent change detection issues this.ngZone.runOutsideAngular(() => { setTimeout(() => { if (!this.isDestroyed) { this.initEditor(); } }, 100); }); } initEditor() { try { // Clean up any existing instance first this.cleanupExistingEditor(); const fullConfig = this.prepareConfiguration(); this._applyCustomStyles(); // Create editor instance this.editorInstance = new RichTextEditor(this.editorContainer.nativeElement, fullConfig); // Set initial content if (this.value) { this.editorInstance.setHTMLCode(this.value); } else if (this.initialContent) { this.value = this.initialContent; this.editorInstance.setHTMLCode(this.initialContent); this.ngZone.run(() => { this.onChange(this.initialContent); this.onTouched(); }); } if (this.readonly && this.editorInstance?.setReadOnly) { this.editorInstance.setReadOnly(true); } this.setupEventListeners(); // Update image toolbar if needed if (this.imageToolbarItems && this.editorInstance) { this.updateImageToolbar(); } } catch (error) { console.error('[RTE] Failed to initialize editor:', error); } } cleanupExistingEditor() { if (this.editorInstance) { try { // Remove all event listeners first this.removeAllEventListeners(); // Try to destroy the editor instance if (typeof this.editorInstance.destroy === 'function') { this.editorInstance.destroy(); } } catch (e) { console.warn('[RTE] Error during editor cleanup:', e); } this.editorInstance = null; } } setupEventListeners() { if (!this.editorInstance) return; this.eventManager = new EditorEventManager(this.editorInstance); const triggerUpdate = () => { if (this.changeTimer) clearTimeout(this.changeTimer); this.changeTimer = setTimeout(() => { if (this.isDestroyed || !this.editorInstance) return; this.ngZone.run(() => { try { const html = this.editorInstance.getHTMLCode() || ''; this.value = html; this.onChange(html); this.onTouched(); if (this.ngControl?.control) { const finalValue = isTrulyEmpty(html) ? '' : html; this.ngControl.control.setValue(finalValue, { emitEvent: false }); this.ngControl.control.updateValueAndValidity(); } } catch (error) { console.error('[RTE] Error in update handler:', error); } }); }, 150); }; // Change-related events this.eventManager.attachMany(['change', 'keyup', 'paste', 'input'], triggerUpdate); // Blur this.eventManager.attach('blur', () => { this.ngZone.run(() => { this.onTouched(); const control = this.ngControl?.control; if (control) { control.markAsTouched(); control.updateValueAndValidity(); } }); }); // Selection change (image toolbar) this.eventManager.attach('selectionchange', () => { setTimeout(() => this.checkImageSelection(), 100); }); } removeAllEventListeners() { this.eventManager?.detachAll(); this.eventManager = null; } updateImageToolbar() { if (this.editorInstance && this.imageToolbarItems) { const hasSlash = this.imageToolbarItems.includes('/'); let imageToolbarString = ''; if (hasSlash) { imageToolbarString = this.imageToolbarItems.join(''); } else { imageToolbarString = `{${this.imageToolbarItems.join(',')}}`; } if (this.editorInstance.config) { this.editorInstance.config.controltoolbar_IMG = imageToolbarString; } try { if (typeof this.editorInstance.setConfig === 'function') { this.editorInstance.setConfig('controltoolbar_IMG', imageToolbarString); } } catch (e) { // Some versions might not have setConfig } } } checkImageSelection() { if (!this.editorInstance || this.isDestroyed) return; try { const iframe = this.editorContainer.nativeElement.querySelector('iframe'); if (iframe?.contentWindow && iframe.contentDocument) { const selection = iframe.contentWindow.getSelection(); if (selection && selection.rangeCount > 0) { const range = selection.getRangeAt(0); const container = range.commonAncestorContainer; let imgElement = null; if (container.nodeType === Node.ELEMENT_NODE) { imgElement = container.querySelector('img'); } else if (container.parentElement) { imgElement = container.parentElement.closest('img'); } if (imgElement && this.imageToolbarItems) { this.editorInstance.updateToolbar && this.editorInstance.updateToolbar(); } } } } catch (e) { // Ignore errors during selection check } } writeValue(value) { const incomingValue = value ?? this.initialContent ?? ''; this.value = incomingValue; if (this.editorInstance && !this.isDestroyed) { const current = this.editorInstance.getHTMLCode() || ''; if (this.normalizeHtml(current) !== this.normalizeHtml(incomingValue)) { try { this.editorInstance.setHTMLCode(incomingValue); } catch (e) { console.warn('[RTE] Error setting HTML code:', e); } } } } normalizeHtml(html) { return (html || '') .replace(/\u00A0/g, '') .replace(/\s+/g, ' ') .replace(/<br\s*\/?>/gi, '') .replace(/<p>\s*<\/p>/gi, '') .trim(); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { const shouldDisable = isDisabled || this.readonly; if (this.editorInstance?.setReadOnly && !this.isDestroyed) { try { this.editorInstance.setReadOnly(shouldDisable); } catch (e) { console.warn('[RTE] Error setting disabled state:', e); } } } ngOnDestroy() { this.isDestroyed = true; // Clear timers if (this.changeTimer) { clearTimeout(this.changeTimer); } if (this.domCleanupTimer) { clearTimeout(this.domCleanupTimer); } // Clear service reference this.rteService.clearCurrentEditor(); // Schedule cleanup outside Angular zone this.ngZone.runOutsideAngular(() => { // Immediate cleanup attempt this.performCleanup(); // Schedule additional cleanup attempts this.domCleanupTimer = setTimeout(() => { this.performCleanup(); }, 100); }); } performCleanup() { // Remove event listeners this.removeAllEventListeners(); // Clean up editor instance if (this.editorInstance) { try { if (typeof this.editorInstance.destroy === 'function') { this.editorInstance.destroy(); } } catch (error) { // Silently ignore destroy errors } this.editorInstance = null; } // Clean up floating panels with safe DOM manipulation safeCleanupFloatingPanels(); } validate(control) { const value = control?.value || ''; const isEmpty = isTrulyEmpty(value); if (hasRequiredValidator(control) && isEmpty) { return { required: true }; } return null; } fixCharacterCount() { if (!this.editorInstance || this.isDestroyed) return; try { const html = this.editorInstance.getHTMLCode() || ''; const div = document.createElement('div'); div.innerHTML = html; const text = div.textContent || ''; const count = text.replace(/\u00A0/g, '').trim().length; const counter = this.editorContainer.nativeElement.querySelector('.character-count'); if (counter) { counter.textContent = `characters: ${count}`; } } catch (e) { // Ignore character count errors } } getCharacterCount() { try { const html = this.editorInstance?.getHTMLCode?.() || ''; const div = document.createElement('div'); div.innerHTML = html; const text = div.textContent || ''; return text.replace(/\u00A0/g, '').trim().length; } catch (e) { return 0; } } get showError() { const control = this.ngControl?.control; if (!control) return false; const isRequired = hasRequiredValidator(control); return !!(control.invalid && control.touched && (isRequired || control.errors?.['required'])); } get currentErrorMessage() { const errors = this.ngControl?.control?.errors; if (!errors) return null; const firstKey = Object.keys(errors)[0]; return this.errorMessages[firstKey] || 'Invalid field'; } getMobileExpandedToolbar() { const basicMobileTools = [ 'paragraphs:dropdown', 'paragraphs:toggle', 'fontname:toggle', 'fontsize:toggle', 'bold', 'italic', 'underline', 'fontname', 'fontsize', 'insertlink', 'insertemoji', 'insertimage', 'insertvideo', 'removeformat', 'code', 'toggleborder', 'fullscreenenter', 'fullscreenexit', 'undo', 'redo', 'togglemore', 'fontname:dropdown', 'fontsize:dropdown', ]; if (this.rtePreset && RTE_TOOLBAR_PRESETS[this.rtePreset]) { let fullToolbar = RTE_TOOLBAR_PRESETS[this.rtePreset]; for (const tool of basicMobileTools) { const escapedTool = tool.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const toolPattern = new RegExp(`\\b${escapedTool}\\b`, 'g'); fullToolbar = fullToolbar.replace(toolPattern, ''); } // 🧼 Clean both desktop/mobile exclusions fullToolbar = this.excludeToolbarItems(fullToolbar); return fullToolbar || this.getDefaultMobileExpandedToolbar(); } return this.getDefaultMobileExpandedToolbar(); } getDefaultMobileExpandedToolbar() { return `{strike,subscript,superscript}|{forecolor,backcolor}| {justifyleft,justifycenter,justifyright,justifyfull}| {insertorderedlist,insertunorderedlist}|{outdent,indent}| {inserthorizontalrule,insertblockquote,inserttable}| {cut,copy,paste,pastetext,pasteword}| {find,replace}|{selectall,print,spellcheck}|{help}`; } prepareConfiguration() { const baseConfig = { ...this.config }; if (!baseConfig.height) { baseConfig.height = 300; } const enhancedConfig = { ...baseConfig, license: this.globalLicenseKey || this.licenseKey, enableObjectResizing: true, enableImageUpload: this.enableImageUpload, enableVideoEmbed: this.enableVideoEmbed, file_upload_handler: (file, callback, optionalIndex, optionalFiles) => { const wrappedCallback = (url, errorCode) => { if (!url) { // 🚨 Upload failed — clean up placeholder this.rteService.removeLastPlaceholderImage(); console.warn('[RTE] Upload failed. Placeholder removed.'); } callback(url, errorCode); }; this.fileUploadHandler(file, wrappedCallback, optionalIndex, optionalFiles); }, content_changed_callback: () => this.fixCharacterCount(), showFloatingToolbar: false, forceDesktopMode: true, disableMobileMode: true, toolbarModeViewport: 'always-desktop', showBottomToolbar: false, contentCssUrl: '', toolbarMobile: 'basic', subtoolbar_more_mobile: this.getMobileExpandedToolbar(), showControlBoxOnImageSelection: true, enableImageFloatStyle: true, contentCSSText: ` /* Custom styles */ body { overflow-y: hidden; padding: 0px; margin: 0px; } body, table, p, div { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #414141; font-size: 14px; line-height: 1.6; } img { cursor: default; } `, }; if (this.imageToolbarItems && Array.isArray(this.imageToolbarItems)) { const hasSlash = this.imageToolbarItems.includes('/'); let imageToolbarString = ''; if (hasSlash) { imageToolbarString = this.imageToolbarItems.join(''); } else { imageToolbarString = `{${this.imageToolbarItems.join(',')}}`; } enhancedConfig.controltoolbar_IMG = imageToolbarString; enhancedConfig.imagecontrolbar = imageToolbarString; enhancedConfig.image_toolbar = imageToolbarString; } if (this.rtePreset && RTE_TOOLBAR_PRESETS[this.rtePreset]) { let fullToolbar = RTE_TOOLBAR_PRESETS[this.rtePreset]; fullToolbar = this.excludeToolbarItems(fullToolbar); enhancedConfig.toolbar = 'custom'; enhancedConfig.toolbar_custom = fullToolbar; } return enhancedConfig; } _applyCustomStyles() { if (!document.getElementById('rte-consistent-toolbar-styles')) { const styleEl = document.createElement('style'); styleEl.id = 'rte-consistent-toolbar-styles'; styleEl.innerHTML = ` /* Custom mobile styles to fix toolbar */ @media (max-width: 992px) { .rte-toolbar-desktop, .rte-toolbar { display: flex !important; flex-wrap: wrap !important; overflow-x: auto !important; white-space: nowrap !important; -webkit-overflow-scrolling: touch !important; max-width: 100% !important; padding: 4px 0 !important; } .rte-toolbar button, .rte-toolbar .rte-dropdown { flex-shrink: 0 !important; min-width: 28px !important; height: 28px !important; margin: 2px !important; } .rte-toolbar-desktop { display: flex !important; } } /* Force image toolbar visibility */ .rte-image-controlbox { display: block !important; opacity: 1 !important; visibility: visible !important; } /* Prevent orphaned floating panels */ rte-floatpanel { z-index: 10000; } `; document.head.appendChild(styleEl); } } insertContentAtCursor(content) { if (this.readonly || this.isDestroyed) return; try { if (!content || typeof content !== 'string' || !content.trim()) { console.warn('[RTE] Empty or invalid content passed to insertContentAtCursor'); return; } const iframe = this.editorContainer.nativeElement.querySelector('iframe'); if (!iframe?.contentWindow || !iframe.contentDocument) { console.warn('[RTE] iframe not found or inaccessible'); return; } const iframeDoc = iframe.contentDocument; const editableBody = iframeDoc.body; if (!editableBody?.isContentEditable) { console.warn('[RTE] iframe body is not editable'); return; } editableBody.focus(); const selection = iframe.contentWindow.getSelection(); if (!selection || selection.rangeCount === 0) { const fallbackRange = iframeDoc.createRange(); fallbackRange.selectNodeContents(editableBody); fallbackRange.collapse(false); selection.removeAllRanges(); selection.addRange(fallbackRange); } const range = selection.getRangeAt(0); range.deleteContents(); // ✅ Append a zero-width span to keep cursor inline const enhancedContent = `${content}<span class="caret-spot">&#8203;</span>`; // ✅ Insert as inline HTML fragment const fragment = range.createContextualFragment(enhancedContent); const lastNode = fragment.lastChild; range.insertNode(fragment); // ✅ Move caret after the inserted zero-width span if (lastNode && lastNode.nodeType === Node.ELEMENT_NODE) { const newRange = iframeDoc.createRange(); newRange.setStartAfter(lastNode); newRange.setEndAfter(lastNode); selection.removeAllRanges(); selection.addRange(newRange); } // Update Angular model const html = this.editorInstance.getHTMLCode(); this.value = html; this.ngZone.run(() => { this.onChange(html); this.onTouched(); if (this.ngControl?.control) { this.ngControl.control.setValue(html, { emitEvent: false }); this.ngControl.control.updateValueAndValidity(); } }); } catch (error) { console.error('[RTE] Failed to inject content into iframe:', error); } } hideAllFloatPanels() { safeCleanupFloatingPanels(); } excludeToolbarItems(toolbar) { if (!toolbar || !this.excludedToolbarItems?.length) return toolbar; for (const tool of this.excludedToolbarItems) { const escapedTool = tool.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const toolPattern = new RegExp(`\\b${escapedTool}\\b`, 'g'); toolbar = toolbar.replace(toolPattern, ''); } return cleanToolbarString(toolbar); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorComponent, deps: [{ token: i0.Injector }, { token: i1.RichTextEditorService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: RTE_LICENSE_KEY, optional: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RichTextEditorComponent, selector: "lib-rich-text-editor", inputs: { licenseKey: "licenseKey", config: "config", rtePreset: "rtePreset", imageToolbarItems: "imageToolbarItems", excludedToolbarItems: "excludedToolbarItems", initialContent: "initialContent", errorMessages: "errorMessages", fileUploadHandler: "fileUploadHandler", enableImageUpload: "enableImageUpload", enableVideoEmbed: "enableVideoEmbed", readonly: "readonly" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RichTextEditorComponent), multi: true, }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => RichTextEditorComponent), multi: true, }, ], viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, static: true }], ngImport: i0, template: ` <div #editorContainer [class.invalid]="showError"></div> <div class="error-message" *ngIf="showError"> {{ currentErrorMessage }} </div> `, isInline: true, styles: [":host{display:block;position:relative}.invalid{border:1px solid red}.error-message{color:red;font-size:12px;margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorComponent, decorators: [{ type: Component, args: [{ selector: 'lib-rich-text-editor', template: ` <div #editorContainer [class.invalid]="showError"></div> <div class="error-message" *ngIf="showError"> {{ currentErrorMessage }} </div> `, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RichTextEditorComponent), multi: true, }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => RichTextEditorComponent), multi: true, }, ], styles: [":host{display:block;position:relative}.invalid{border:1px solid red}.error-message{color:red;font-size:12px;margin-top:4px}\n"] }] }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.RichTextEditorService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [RTE_LICENSE_KEY] }] }], propDecorators: { editorContainer: [{ type: ViewChild, args: ['editorContainer', { static: true }] }], licenseKey: [{ type: Input }], config: [{ type: Input }], rtePreset: [{ type: Input }], imageToolbarItems: [{ type: Input }], excludedToolbarItems: [{ type: Input }], initialContent: [{ type: Input }], errorMessages: [{ type: Input }], fileUploadHandler: [{ type: Input }], enableImageUpload: [{ type: Input }], enableVideoEmbed: [{ type: Input }], readonly: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmljaC10ZXh0LWVkaXRvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9yaWNoLXRleHQtZWRpdG9yL3NyYy9saWIvcmljaC10ZXh0LWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxVQUFVLEVBQ1YsS0FBSyxFQUdMLFNBQVMsRUFHVCxNQUFNLEVBQ04sUUFBUSxHQUdULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxpQkFBaUIsRUFDakIsYUFBYSxFQUNiLFNBQVMsR0FJVixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE9BQU8sRUFDTCxtQkFBbUIsR0FHcEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUNMLDBCQUEwQixFQUMxQix5QkFBeUIsR0FDMUIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7QUFvRDlFLE1BQU0sT0FBTyx1QkFBdUI7SUF5Q3hCO0lBQ0E7SUFDQTtJQUNBO0lBQ3FDO0lBMUNDLGVBQWUsQ0FBYztJQUNwRSxVQUFVLEdBQVcsRUFBRSxDQUFDO0lBQ3hCLE1BQU0sR0FBeUIsRUFBRSxDQUFDO0lBQ2xDLFNBQVMsR0FBcUIsSUFBSSxDQUFDO0lBQ25DLGlCQUFpQixHQUFrQyxJQUFJLENBQUM7SUFDeEQsb0JBQW9CLEdBQWEsRUFBRSxDQUFDO0lBQ3BDLGNBQWMsR0FBVyxFQUFFLENBQUM7SUFFNUIsYUFBYSxHQUE4QjtRQUNsRCxRQUFRLEVBQUUseUJB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QUFHLEVBQUUsd0JBQXdCLENBQUM7NEJBQ3RELEtBQUssRUFBRSxJQUFJO3lCQUNaO3dCQUNEOzRCQUNFLE9BQU8sRUFBRSxhQUFhOzRCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSx3QkFBd0IsQ0FBQzs0QkFDdEQsS0FBSyxFQUFFLElBQUk7eUJBQ1o7cUJBQ0Y7OzBCQStDRSxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGVBQWU7eUNBMUNXLGVBQWU7c0JBQTlELFNBQVM7dUJBQUMsaUJBQWlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNyQyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtOLGlCQUFpQjtzQkFEaEIsS0FBSztnQkFRRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkLFxuICBBZnRlcl