UNPKG

angular-rich-text-editor

Version:

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

296 lines 33.2 kB
import { Inject, Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { RICHTEXTEDITOR_ASSETS_PATH } from './paths'; import * as i0 from "@angular/core"; export class RichTextEditorService { assetsPath; currentEditor = null; // Reference to the current RTE component contentSubject = new BehaviorSubject(''); // Observable for content changes content$ = this.contentSubject.asObservable(); constructor(assetsPath) { this.assetsPath = assetsPath; } getContentCssUrl() { return `${this.assetsPath}/runtime/richtexteditor_content.css`; } getPreviewCssUrl() { return `${this.assetsPath}/runtime/richtexteditor_preview.css`; } getPreviewScriptUrl() { return `${this.assetsPath}/runtime/richtexteditor_preview.js`; } // Simple editor management setCurrentEditor(component) { this.currentEditor = component; } clearCurrentEditor() { this.currentEditor = null; this.contentSubject.next(''); } // Content manipulation methods insertContentAtCursor(content) { if (!this.currentEditor) { console.warn('[RTE Service] No editor is currently active'); return false; } try { this.currentEditor.insertContentAtCursor(content); // Update the observable after insertion const newContent = this.getContent(); this.contentSubject.next(newContent); return true; } catch (error) { console.error('[RTE Service] Failed to insert content:', error); return false; } } /** * Get HTML content from current editor * @returns HTML string (empty string if no content/editor) */ getContent() { if (!this.currentEditor?.editorInstance) { console.warn('[RTE Service] No active editor found'); return ''; } try { const htmlContent = this.currentEditor.editorInstance.getHTMLCode(); // Handle null/undefined cases if (htmlContent === null || htmlContent === undefined) { return this.getContentFallback(); } return htmlContent; } catch (error) { console.error('[RTE Service] Failed to get content:', error); return this.getContentFallback(); } } /** * Fallback method to retrieve content */ getContentFallback() { try { // Try to get from iframe directly const iframe = this.currentEditor?.editorContainer?.nativeElement?.querySelector('iframe'); if (iframe?.contentDocument?.body) { return iframe.contentDocument.body.innerHTML || ''; } // Try to get from component's value if (this.currentEditor?.value) { return this.currentEditor.value; } return ''; } catch (error) { console.error('[RTE Service] Fallback retrieval failed:', error); return ''; } } /** * Set HTML content for current editor */ setContent(content) { if (!this.currentEditor?.editorInstance) { console.warn('[RTE Service] No active editor found'); return false; } try { this.currentEditor.editorInstance.setHTMLCode(content); // Ensure component state is synced if (this.currentEditor.value !== content) { this.currentEditor.value = content; } // Trigger change event if needed if (this.currentEditor.onChange) { this.currentEditor.onChange(content); } // Update observable this.contentSubject.next(content); return true; } catch (error) { console.error('[RTE Service] Failed to set content:', error); return false; } } /** * Clear editor content */ clearContent() { return this.setContent('<p><br></p>'); } /** * Focus current editor */ focus() { if (!this.currentEditor) { console.warn('[RTE Service] No active editor found'); return false; } try { // Try editor's focus method first if (this.currentEditor.editorInstance?.focus) { this.currentEditor.editorInstance.focus(); return true; } // Fallback to iframe focus const iframe = this.currentEditor.editorContainer?.nativeElement?.querySelector('iframe'); if (iframe?.contentDocument?.body) { iframe.contentDocument.body.focus(); return true; } return false; } catch (error) { console.error('[RTE Service] Failed to focus editor:', error); return false; } } /** * Execute command on the editor */ executeCommand(command, value) { if (!this.currentEditor?.editorInstance) { console.warn('[RTE Service] No active editor found'); return false; } try { // Try editor's execCommand if available if (typeof this.currentEditor.editorInstance.execCommand === 'function') { this.currentEditor.editorInstance.execCommand(command, false, value); return true; } // Fallback to iframe execCommand const iframe = this.currentEditor.editorContainer?.nativeElement?.querySelector('iframe'); if (iframe?.contentDocument) { iframe.contentDocument.execCommand(command, false, value); return true; } return false; } catch (error) { console.error('[RTE Service] Failed to execute command:', error); return false; } } /** * Get selected text from editor */ getSelectedText() { if (!this.currentEditor?.editorContainer) { return ''; } try { const iframe = this.currentEditor.editorContainer.nativeElement.querySelector('iframe'); if (iframe?.contentWindow) { const selection = iframe.contentWindow.getSelection(); return selection ? selection.toString() : ''; } return ''; } catch (error) { console.error('[RTE Service] Failed to get selected text:', error); return ''; } } /** * Check if content is empty */ isContentEmpty() { const content = this.getContent(); if (!content) return true; // Create a temporary div to parse HTML const div = document.createElement('div'); div.innerHTML = content; // Get text content and clean it const text = div.textContent?.replace(/\u00A0/g, '').trim() || ''; // Check if only contains empty tags const cleaned = div.innerHTML .replace(/<br\s*\/?>/gi, '') .replace(/<div>(\s|&nbsp;)*<\/div>/gi, '') .replace(/<p>(\s|&nbsp;)*<\/p>/gi, '') .replace(/&nbsp;/gi, '') .trim(); return !text && cleaned.length === 0; } /** * Get character count */ getCharacterCount() { const content = this.getContent(); if (!content) return 0; const div = document.createElement('div'); div.innerHTML = content; const text = div.textContent?.replace(/\u00A0/g, '').trim() || ''; return text.length; } /** * Get word count */ getWordCount() { const content = this.getContent(); if (!content) return 0; const div = document.createElement('div'); div.innerHTML = content; const text = div.textContent?.replace(/\u00A0/g, '').trim() || ''; if (!text) return 0; const words = text.match(/\b\w+\b/g); return words ? words.length : 0; } // Check if editor is readonly isReadonly() { return this.currentEditor?.readonly || false; } // Check if editor is available isAvailable() { return !!this.currentEditor?.editorInstance; } /** * Hide all floating panels (useful for cleanup) */ hideFloatingPanels() { if (this.currentEditor?.hideAllFloatPanels) { this.currentEditor.hideAllFloatPanels(); } } /** * Removes the last inserted image with a temporary blob or data URL. */ removeLastPlaceholderImage() { if (!this.currentEditor) return false; const iframe = this.currentEditor?.editorContainer?.nativeElement?.querySelector('iframe'); const body = iframe?.contentDocument?.body; if (!body) return false; const images = Array.from(body.querySelectorAll('img')); for (let i = images.length - 1; i >= 0; i--) { const img = images[i]; if (img.src.startsWith('blob:') || img.src.startsWith('data:')) { img.parentElement?.removeChild(img); console.debug('[RTE Service] Removed temporary placeholder image.'); return true; } } return false; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorService, deps: [{ token: RICHTEXTEDITOR_ASSETS_PATH }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorService, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RichTextEditorService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [RICHTEXTEDITOR_ASSETS_PATH] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmljaC10ZXh0LWVkaXRvci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvcmljaC10ZXh0LWVkaXRvci9zcmMvbGliL3JpY2gtdGV4dC1lZGl0b3Iuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFZckQsTUFBTSxPQUFPLHFCQUFxQjtJQU93QjtJQU5oRCxhQUFhLEdBQVEsSUFBSSxDQUFDLENBQUMseUNBQXlDO0lBQ3BFLGNBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBUyxFQUFFLENBQUMsQ0FBQztJQUV6RCxpQ0FBaUM7SUFDMUIsUUFBUSxHQUF1QixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBRXpFLFlBQXdELFVBQWtCO1FBQWxCLGVBQVUsR0FBVixVQUFVLENBQVE7SUFBRyxDQUFDO0lBRTlFLGdCQUFnQjtRQUNkLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxxQ0FBcUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsZ0JBQWdCO1FBQ2QsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLHFDQUFxQyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxtQkFBbUI7UUFDakIsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLG9DQUFvQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCwyQkFBMkI7SUFDM0IsZ0JBQWdCLENBQUMsU0FBYztRQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFB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LENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFeEQsS0FBSyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDNUMsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBcUIsQ0FBQztZQUMxQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQy9ELEdBQUcsQ0FBQyxhQUFhLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNwQyxPQUFPLENBQUMsS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7Z0JBQ3BFLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7d0dBNVVVLHFCQUFxQixrQkFPWiwwQkFBMEI7NEdBUG5DLHFCQUFxQixjQUZwQixNQUFNOzs0RkFFUCxxQkFBcUI7a0JBSGpDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFRYyxNQUFNOzJCQUFDLDBCQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBSSUNIVEVYVEVESVRPUl9BU1NFVFNfUEFUSCB9IGZyb20gJy4vcGF0aHMnO1xuXG4vLyBJbnRlcmZhY2UgZm9yIGVkaXRvciBpbnN0YW5jZSBtYW5hZ2VtZW50XG5leHBvcnQgaW50ZXJmYWNlIFJURUluc3RhbmNlIHtcbiAgaWQ6IHN0cmluZztcbiAgY29tcG9uZW50OiBhbnk7IC8vIFJlZmVyZW5jZSB0byB0aGUgUmljaFRleHRFZGl0b3JDb21wb25lbnRcbiAgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBSaWNoVGV4dEVkaXRvclNlcnZpY2Uge1xuICBwcml2YXRlIGN1cnJlbnRFZGl0b3I6IGFueSA9IG51bGw7IC8vIFJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBSVEUgY29tcG9uZW50XG4gIHByaXZhdGUgY29udGVudFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuXG4gIC8vIE9ic2VydmFibGUgZm9yIGNvbnRlbnQgY2hhbmdlc1xuICBwdWJsaWMgY29udGVudCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuY29udGVudFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChSSUNIVEVYVEVESVRPUl9BU1NFVFNfUEFUSCkgcHJpdmF0ZSBhc3NldHNQYXRoOiBzdHJpbmcpIHt9XG5cbiAgZ2V0Q29udGVudENzc1VybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLmFzc2V0c1BhdGh9L3J1bnRpbWUvcmljaHRleHRlZGl0b3JfY29udGVudC5jc3NgO1xuICB9XG5cbiAgZ2V0UHJldmlld0Nzc1VybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLmFzc2V0c1BhdGh9L3J1bnRpbWUvcmljaHRleHRlZGl0b3JfcHJldmlldy5jc3NgO1xuICB9XG5cbiAgZ2V0UHJldmlld1NjcmlwdFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLmFzc2V0c1BhdGh9L3J1bnRpbWUvcmljaHRleHRlZGl0b3JfcHJldmlldy5qc2A7XG4gIH1cblxuICAvLyBTaW1wbGUgZWRpdG9yIG1hbmFnZW1lbnRcbiAgc2V0Q3VycmVudEVkaXRvcihjb21wb25lbnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudEVkaXRvciA9IGNvbXBvbmVudDtcbiAgfVxuXG4gIGNsZWFyQ3VycmVudEVkaXRvcigpOiB2b2lkIHtcbiAgICB0aGlzLmN1cnJlbnRFZGl0b3IgPSBudWxsO1xuICAgIHRoaXMuY29udGVudFN1YmplY3QubmV4dCgnJyk7XG4gIH1cblxuICAvLyBDb250ZW50IG1hbmlwdWxhdGlvbiBtZXRob2RzXG4gIGluc2VydENvbnRlbnRBdEN1cnNvcihjb250ZW50OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEVkaXRvcikge1xuICAgICAgY29uc29sZS53YXJuKCdbUlRFIFNlcnZpY2VdIE5vIGVkaXRvciBpcyBjdXJyZW50bHkgYWN0aXZlJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY3VycmVudEVkaXRvci5pbnNlcnRDb250ZW50QXRDdXJzb3IoY29udGVudCk7XG4gICAgICAvLyBVcGRhdGUgdGhlIG9ic2VydmFibGUgYWZ0ZXIgaW5zZXJ0aW9uXG4gICAgICBjb25zdCBuZXdDb250ZW50ID0gdGhpcy5nZXRDb250ZW50KCk7XG4gICAgICB0aGlzLmNvbnRlbnRTdWJqZWN0Lm5leHQobmV3Q29udGVudCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW1JURSBTZXJ2aWNlXSBGYWlsZWQgdG8gaW5zZXJ0IGNvbnRlbnQ6JywgZXJyb3IpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgSFRNTCBjb250ZW50IGZyb20gY3VycmVudCBlZGl0b3JcbiAgICogQHJldHVybnMgSFRNTCBzdHJpbmcgKGVtcHR5IHN0cmluZyBpZiBubyBjb250ZW50L2VkaXRvcilcbiAgICovXG4gIGdldENvbnRlbnQoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEVkaXRvcj8uZWRpdG9ySW5zdGFuY2UpIHtcbiAgICAgIGNvbnNvbGUud2FybignW1JURSBTZXJ2aWNlXSBObyBhY3RpdmUgZWRpdG9yIGZvdW5kJyk7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGh0bWxDb250ZW50ID0gdGhpcy5jdXJyZW50RWRpdG9yLmVkaXRvckluc3RhbmNlLmdldEhUTUxDb2RlKCk7XG5cbiAgICAgIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZCBjYXNlc1xuICAgICAgaWYgKGh0bWxDb250ZW50ID09PSBudWxsIHx8IGh0bWxDb250ZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29udGVudEZhbGxiYWNrKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBodG1sQ29udGVudDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW1JURSBTZXJ2aWNlXSBGYWlsZWQgdG8gZ2V0IGNvbnRlbnQ6JywgZXJyb3IpO1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29udGVudEZhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZhbGxiYWNrIG1ldGhvZCB0byByZXRyaWV2ZSBjb250ZW50XG4gICAqL1xuICBwcml2YXRlIGdldENvbnRlbnRGYWxsYmFjaygpOiBzdHJpbmcge1xuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgdG8gZ2V0IGZyb20gaWZyYW1lIGRpcmVjdGx5XG4gICAgICBjb25zdCBpZnJhbWUgPVxuICAgICAgICB0aGlzLmN1cnJlbnRFZGl0b3I/LmVkaXRvckNvbnRhaW5lcj8ubmF0aXZlRWxlbWVudD8ucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAnaWZyYW1lJ1xuICAgICAgICApO1xuICAgICAgaWYgKGlmcmFtZT8uY29udGVudERvY3VtZW50Py5ib2R5KSB7XG4gICAgICAgIHJldHVybiBpZnJhbWUuY29udGVudERvY3VtZW50LmJvZHkuaW5uZXJIVE1MIHx8ICcnO1xuICAgICAgfVxuXG4gICAgICAvLyBUcnkgdG8gZ2V0IGZyb20gY29tcG9uZW50J3MgdmFsdWVcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRFZGl0b3I/LnZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRFZGl0b3IudmFsdWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAnJztcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW1JURSBTZXJ2aWNlXSBGYWxsYmFjayByZXRyaWV2YWwgZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IEhUTUwgY29udGVudCBmb3IgY3VycmVudCBlZGl0b3JcbiAgICovXG4gIHNldENvbnRlbnQoY29udGVudDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRFZGl0b3I/LmVkaXRvckluc3RhbmNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tSVEUgU2VydmljZV0gTm8gYWN0aXZlIGVkaXRvciBmb3VuZCcpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmN1cnJlbnRFZGl0b3IuZWRpdG9ySW5zdGFuY2Uuc2V0SFRNTENvZGUoY29udGVudCk7XG5cbiAgICAgIC8vIEVuc3VyZSBjb21wb25lbnQgc3RhdGUgaXMgc3luY2VkXG4gICAgICBpZiAodGhpcy5jdXJyZW50RWRpdG9yLnZhbHVlICE9PSBjb250ZW50KSB7XG4gICAgICAgIHRoaXMuY3VycmVudEVkaXRvci52YWx1ZSA9IGNvbnRlbnQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFRyaWdnZXIgY2hhbmdlIGV2ZW50IGlmIG5lZWRlZFxuICAgICAgaWYgKHRoaXMuY3VycmVudEVkaXRvci5vbkNoYW5nZSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRFZGl0b3Iub25DaGFuZ2UoY29udGVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFVwZGF0ZSBvYnNlcnZhYmxlXG4gICAgICB0aGlzLmNvbnRlbnRTdWJqZWN0Lm5leHQoY29udGVudCk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbUlRFIFNlcnZpY2VdIEZhaWxlZCB0byBzZXQgY29udGVudDonLCBlcnJvcik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGVkaXRvciBjb250ZW50XG4gICAqL1xuICBjbGVhckNvbnRlbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0Q29udGVudCgnPHA+PGJyPjwvcD4nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2N1cyBjdXJyZW50IGVkaXRvclxuICAgKi9cbiAgZm9jdXMoKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRFZGl0b3IpIHtcbiAgICAgIGNvbnNvbGUud2FybignW1JURSBTZXJ2aWNlXSBObyBhY3RpdmUgZWRpdG9yIGZvdW5kJyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFRyeSBlZGl0b3IncyBmb2N1cyBtZXRob2QgZmlyc3RcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRFZGl0b3IuZWRpdG9ySW5zdGFuY2U/LmZvY3VzKSB7XG4gICAgICAgIHRoaXMuY3VycmVudEVkaXRvci5lZGl0b3JJbnN0YW5jZS5mb2N1cygpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gRmFsbGJhY2sgdG8gaWZyYW1lIGZvY3VzXG4gICAgICBjb25zdCBpZnJhbWUgPVxuICAgICAgICB0aGlzLmN1cnJlbnRFZGl0b3IuZWRpdG9yQ29udGFpbmVyPy5uYXRpdmVFbGVtZW50Py5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAgICdpZnJhbWUnXG4gICAgICAgICk7XG4gICAgICBpZiAoaWZyYW1lPy5jb250ZW50RG9jdW1lbnQ/LmJvZHkpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnREb2N1bWVudC5ib2R5LmZvY3VzKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1tSVEUgU2VydmljZV0gRmFpbGVkIHRvIGZvY3VzIGVkaXRvcjonLCBlcnJvcik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgY29tbWFuZCBvbiB0aGUgZWRpdG9yXG4gICAqL1xuICBleGVjdXRlQ29tbWFuZChjb21tYW5kOiBzdHJpbmcsIHZhbHVlPzogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRFZGl0b3I/LmVkaXRvckluc3RhbmNlKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tSVEUgU2VydmljZV0gTm8gYWN0aXZlIGVkaXRvciBmb3VuZCcpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgZWRpdG9yJ3MgZXhlY0NvbW1hbmQgaWYgYXZhaWxhYmxlXG4gICAgICBpZiAodHlwZW9mIHRoaXMuY3VycmVudEVkaXRvci5lZGl0b3JJbnN0YW5jZS5leGVjQ29tbWFuZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLmN1cnJlbnRFZGl0b3IuZWRpdG9ySW5zdGFuY2UuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIEZhbGxiYWNrIHRvIGlmcmFtZSBleGVjQ29tbWFuZFxuICAgICAgY29uc3QgaWZyYW1lID1cbiAgICAgICAgdGhpcy5jdXJyZW50RWRpdG9yLmVkaXRvckNvbnRhaW5lcj8ubmF0aXZlRWxlbWVudD8ucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAnaWZyYW1lJ1xuICAgICAgICApO1xuICAgICAgaWYgKGlmcmFtZT8uY29udGVudERvY3VtZW50KSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50RG9jdW1lbnQuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignW1JURSBTZXJ2aWNlXSBGYWlsZWQgdG8gZXhlY3V0ZSBjb21tYW5kOicsIGVycm9yKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHNlbGVjdGVkIHRleHQgZnJvbSBlZGl0b3JcbiAgICovXG4gIGdldFNlbGVjdGVkVGV4dCgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jdXJyZW50RWRpdG9yPy5lZGl0b3JDb250YWluZXIpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgaWZyYW1lID1cbiAgICAgICAgdGhpcy5jdXJyZW50RWRpdG9yLmVkaXRvckNvbnRhaW5lci5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICAgJ2lmcmFtZSdcbiAgICAgICAgKTtcbiAgICAgIGlmIChpZnJhbWU/LmNvbnRlbnRXaW5kb3cpIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gaWZyYW1lLmNvbnRlbnRXaW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb24gPyBzZWxlY3Rpb24udG9TdHJpbmcoKSA6ICcnO1xuICAgICAgfVxuICAgICAgcmV0dXJuICcnO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbUlRFIFNlcnZpY2VdIEZhaWxlZCB0byBnZXQgc2VsZWN0ZWQgdGV4dDonLCBlcnJvcik7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGNvbnRlbnQgaXMgZW1wdHlcbiAgICovXG4gIGlzQ29udGVudEVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKTtcblxuICAgIGlmICghY29udGVudCkgcmV0dXJuIHRydWU7XG5cbiAgICAvLyBDcmVhdGUgYSB0ZW1wb3JhcnkgZGl2IHRvIHBhcnNlIEhUTUxcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYuaW5uZXJIVE1MID0gY29udGVudDtcblxuICAgIC8vIEdldCB0ZXh0IGNvbnRlbnQgYW5kIGNsZWFuIGl0XG4gICAgY29uc3QgdGV4dCA9IGRpdi50ZXh0Q29udGVudD8ucmVwbGFjZSgvXFx1MDBBMC9nLCAnJykudHJpbSgpIHx8ICcnO1xuXG4gICAgLy8gQ2hlY2sgaWYgb25seSBjb250YWlucyBlbXB0eSB0YWdzXG4gICAgY29uc3QgY2xlYW5lZCA9IGRpdi5pbm5lckhUTUxcbiAgICAgIC5yZXBsYWNlKC88YnJcXHMqXFwvPz4vZ2ksICcnKVxuICAgICAgLnJlcGxhY2UoLzxkaXY+KFxcc3wmbmJzcDspKjxcXC9kaXY+L2dpLCAnJylcbiAgICAgIC5yZXBsYWNlKC88cD4oXFxzfCZuYnNwOykqPFxcL3A+L2dpLCAnJylcbiAgICAgIC5yZXBsYWNlKC8mbmJzcDsvZ2ksICcnKVxuICAgICAgLnRyaW0oKTtcblxuICAgIHJldHVybiAhdGV4dCAmJiBjbGVhbmVkLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgY2hhcmFjdGVyIGNvdW50XG4gICAqL1xuICBnZXRDaGFyYWN0ZXJDb3VudCgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKTtcbiAgICBpZiAoIWNvbnRlbnQpIHJldHVybiAwO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmlubmVySFRNTCA9IGNvbnRlbnQ7XG4gICAgY29uc3QgdGV4dCA9IGRpdi50ZXh0Q29udGVudD8ucmVwbGFjZSgvXFx1MDBBMC9nLCAnJykudHJpbSgpIHx8ICcnO1xuXG4gICAgcmV0dXJuIHRleHQubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB3b3JkIGNvdW50XG4gICAqL1xuICBnZXRXb3JkQ291bnQoKTogbnVtYmVyIHtcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5nZXRDb250ZW50KCk7XG4gICAgaWYgKCFjb250ZW50KSByZXR1cm4gMDtcblxuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBjb250ZW50O1xuICAgIGNvbnN0IHRleHQgPSBkaXYudGV4dENvbnRlbnQ/LnJlcGxhY2UoL1xcdTAwQTAvZywgJycpLnRyaW0oKSB8fCAnJztcblxuICAgIGlmICghdGV4dCkgcmV0dXJuIDA7XG5cbiAgICBjb25zdCB3b3JkcyA9IHRleHQubWF0Y2goL1xcYlxcdytcXGIvZyk7XG4gICAgcmV0dXJuIHdvcmRzID8gd29yZHMubGVuZ3RoIDogMDtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGVkaXRvciBpcyByZWFkb25seVxuICBpc1JlYWRvbmx5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnRFZGl0b3I/LnJlYWRvbmx5IHx8IGZhbHNlO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgZWRpdG9yIGlzIGF2YWlsYWJsZVxuICBpc0F2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmN1cnJlbnRFZGl0b3I/LmVkaXRvckluc3RhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEhpZGUgYWxsIGZsb2F0aW5nIHBhbmVscyAodXNlZnVsIGZvciBjbGVhbnVwKVxuICAgKi9cbiAgaGlkZUZsb2F0aW5nUGFuZWxzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmN1cnJlbnRFZGl0b3I/LmhpZGVBbGxGbG9hdFBhbmVscykge1xuICAgICAgdGhpcy5jdXJyZW50RWRpdG9yLmhpZGVBbGxGbG9hdFBhbmVscygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBsYXN0IGluc2VydGVkIGltYWdlIHdpdGggYSB0ZW1wb3JhcnkgYmxvYiBvciBkYXRhIFVSTC5cbiAgICovXG4gIHJlbW92ZUxhc3RQbGFjZWhvbGRlckltYWdlKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5jdXJyZW50RWRpdG9yKSByZXR1cm4gZmFsc2U7XG5cbiAgICBjb25zdCBpZnJhbWUgPVxuICAgICAgdGhpcy5jdXJyZW50RWRpdG9yPy5lZGl0b3JDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ/LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAgICdpZnJhbWUnXG4gICAgICApO1xuICAgIGNvbnN0IGJvZHkgPSBpZnJhbWU/LmNvbnRlbnREb2N1bWVudD8uYm9keTtcblxuICAgIGlmICghYm9keSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgY29uc3QgaW1hZ2VzID0gQXJyYXkuZnJvbShib2R5LnF1ZXJ5U2VsZWN0b3JBbGwoJ2ltZycpKTtcblxuICAgIGZvciAobGV0IGkgPSBpbWFnZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IGltZyA9IGltYWdlc1tpXSBhcyBIVE1MSW1hZ2VFbGVtZW50O1xuICAgICAgaWYgKGltZy5zcmMuc3RhcnRzV2l0aCgnYmxvYjonKSB8fCBpbWcuc3JjLnN0YXJ0c1dpdGgoJ2RhdGE6JykpIHtcbiAgICAgICAgaW1nLnBhcmVudEVsZW1lbnQ/LnJlbW92ZUNoaWxkKGltZyk7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoJ1tSVEUgU2VydmljZV0gUmVtb3ZlZCB0ZW1wb3JhcnkgcGxhY2Vob2xkZXIgaW1hZ2UuJyk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19