UNPKG

ngx-editor

Version:

The Rich Text Editor for Angular, Built on ProseMirror

138 lines 21.5 kB
import { Component, Input, } from '@angular/core'; import { NgxEditorError } from 'ngx-editor/utils'; import { MenuService } from './menu.service'; import * as i0 from "@angular/core"; import * as i1 from "./menu.service"; import * as i2 from "@angular/common"; import * as i3 from "./toggle-command/toggle-command.component"; import * as i4 from "./insert-command/insert-command.component"; import * as i5 from "./link/link.component"; import * as i6 from "./dropdown/dropdown.component"; import * as i7 from "./image/image.component"; import * as i8 from "./color-picker/color-picker.component"; export const DEFAULT_TOOLBAR = [ ['bold', 'italic'], ['code', 'blockquote'], ['underline', 'strike'], ['ordered_list', 'bullet_list'], [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], ['link', 'image'], ['text_color', 'background_color'], ['align_left', 'align_center', 'align_right', 'align_justify'], ['format_clear'], ]; export const TOOLBAR_MINIMAL = [ ['bold', 'italic'], [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], ['link', 'image'], ['text_color', 'background_color'], ]; export const TOOLBAR_FULL = [ ['bold', 'italic'], ['code', 'blockquote'], ['underline', 'strike'], ['ordered_list', 'bullet_list'], [{ heading: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }], ['link', 'image'], ['text_color', 'background_color'], ['align_left', 'align_center', 'align_right', 'align_justify'], ['horizontal_rule'], ]; const DEFAULT_COLOR_PRESETS = [ '#b60205', '#d93f0b', '#fbca04', '#0e8a16', '#006b75', '#1d76db', '#0052cc', '#5319e7', '#e99695', '#f9d0c4', '#fef2c0', '#c2e0c6', '#bfdadc', '#c5def5', '#bfd4f2', '#d4c5f9', ]; export class MenuComponent { constructor(menuService) { this.menuService = menuService; this.toolbar = TOOLBAR_MINIMAL; this.colorPresets = DEFAULT_COLOR_PRESETS; this.disabled = false; this.customMenuRef = null; this.dropdownPlacement = 'bottom'; this.toggleCommands = [ 'bold', 'italic', 'underline', 'strike', 'code', 'blockquote', 'ordered_list', 'bullet_list', 'align_left', 'align_center', 'align_right', 'align_justify', ]; this.insertCommands = [ 'horizontal_rule', 'format_clear', ]; this.iconContainerClass = ['NgxEditor__MenuItem', 'NgxEditor__MenuItem--Icon']; this.dropdownContainerClass = ['NgxEditor__Dropdown']; this.seperatorClass = ['NgxEditor__Seperator']; } get presets() { const col = 8; const colors = []; this.colorPresets.forEach((color, index) => { const row = Math.floor(index / col); if (!colors[row]) { colors.push([]); } colors[row].push(color); }); return colors; } trackByIndex(index) { return index; } isDropDown(item) { if (item?.heading) { return true; } return false; } getDropdownItems(item) { return item; } ngOnInit() { if (!this.editor) { throw new NgxEditorError('Required editor instance to initialize menu component'); } this.menuService.editor = this.editor; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: MenuComponent, deps: [{ token: i1.MenuService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: MenuComponent, selector: "ngx-editor-menu", inputs: { toolbar: "toolbar", colorPresets: "colorPresets", disabled: "disabled", editor: "editor", customMenuRef: "customMenuRef", dropdownPlacement: "dropdownPlacement" }, providers: [MenuService], ngImport: i0, template: "<div class=\"NgxEditor__MenuBar\"\n [ngClass]=\"{'NgxEditor--Disabled': disabled, 'NgxEditor__MenuBar--Reverse': dropdownPlacement === 'top'}\">\n\n <ng-container *ngFor=\"let toolbarItem of toolbar; let lastToolbarItem = last; trackBy: trackByIndex\">\n <ng-container *ngFor=\"let item of toolbarItem; let lastItem = last; trackBy: trackByIndex\">\n\n <!-- toggle icons -->\n <ngx-toggle-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"toggleCommands.includes(item)\">\n </ngx-toggle-command>\n\n <ngx-insert-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"insertCommands.includes(item)\">\n </ngx-insert-command>\n\n <!-- link -->\n <ngx-link [class]=\"iconContainerClass\" *ngIf=\"item === 'link'\"></ngx-link>\n\n <!-- image -->\n <ngx-image [class]=\"iconContainerClass\" *ngIf=\"item === 'image'\">\n </ngx-image>\n\n <!-- dropdown -->\n <ng-container *ngIf=\"isDropDown(item)\">\n <ngx-dropdown *ngFor=\"let dropdownItem of getDropdownItems(item) | keyvalue; trackBy: trackByIndex\"\n [class]=\"dropdownContainerClass\" [group]=\"dropdownItem.key\" [items]=\"dropdownItem.value\">\n </ngx-dropdown>\n </ng-container>\n\n <!-- text color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'text_color'\" type=\"text_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n <!-- background color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'background_color'\" type=\"background_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n\n <!-- seperator -->\n <div [class]=\"seperatorClass\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n </ng-container>\n\n <!-- custom menu -->\n <ng-container *ngIf=\"customMenuRef\">\n <ng-container [ngTemplateOutlet]=\"customMenuRef\"></ng-container>\n </ng-container>\n\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.ToggleCommandComponent, selector: "ngx-toggle-command", inputs: ["toolbarItem"] }, { kind: "component", type: i4.InsertCommandComponent, selector: "ngx-insert-command", inputs: ["toolbarItem"] }, { kind: "component", type: i5.LinkComponent, selector: "ngx-link" }, { kind: "component", type: i6.DropdownComponent, selector: "ngx-dropdown", inputs: ["group", "items"] }, { kind: "component", type: i7.ImageComponent, selector: "ngx-image" }, { kind: "component", type: i8.ColorPickerComponent, selector: "ngx-color-picker", inputs: ["presets", "type"] }, { kind: "pipe", type: i2.KeyValuePipe, name: "keyvalue" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: MenuComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-editor-menu', providers: [MenuService], template: "<div class=\"NgxEditor__MenuBar\"\n [ngClass]=\"{'NgxEditor--Disabled': disabled, 'NgxEditor__MenuBar--Reverse': dropdownPlacement === 'top'}\">\n\n <ng-container *ngFor=\"let toolbarItem of toolbar; let lastToolbarItem = last; trackBy: trackByIndex\">\n <ng-container *ngFor=\"let item of toolbarItem; let lastItem = last; trackBy: trackByIndex\">\n\n <!-- toggle icons -->\n <ngx-toggle-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"toggleCommands.includes(item)\">\n </ngx-toggle-command>\n\n <ngx-insert-command [toolbarItem]=\"item\" [class]=\"iconContainerClass\" *ngIf=\"insertCommands.includes(item)\">\n </ngx-insert-command>\n\n <!-- link -->\n <ngx-link [class]=\"iconContainerClass\" *ngIf=\"item === 'link'\"></ngx-link>\n\n <!-- image -->\n <ngx-image [class]=\"iconContainerClass\" *ngIf=\"item === 'image'\">\n </ngx-image>\n\n <!-- dropdown -->\n <ng-container *ngIf=\"isDropDown(item)\">\n <ngx-dropdown *ngFor=\"let dropdownItem of getDropdownItems(item) | keyvalue; trackBy: trackByIndex\"\n [class]=\"dropdownContainerClass\" [group]=\"dropdownItem.key\" [items]=\"dropdownItem.value\">\n </ngx-dropdown>\n </ng-container>\n\n <!-- text color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'text_color'\" type=\"text_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n <!-- background color picker -->\n <ngx-color-picker [class]=\"iconContainerClass\" *ngIf=\"item === 'background_color'\" type=\"background_color\"\n [presets]=\"presets\">\n </ngx-color-picker>\n\n <!-- seperator -->\n <div [class]=\"seperatorClass\" *ngIf=\"lastItem && !lastToolbarItem\"></div>\n </ng-container>\n </ng-container>\n\n <!-- custom menu -->\n <ng-container *ngIf=\"customMenuRef\">\n <ng-container [ngTemplateOutlet]=\"customMenuRef\"></ng-container>\n </ng-container>\n\n</div>\n" }] }], ctorParameters: function () { return [{ type: i1.MenuService }]; }, propDecorators: { toolbar: [{ type: Input }], colorPresets: [{ type: Input }], disabled: [{ type: Input }], editor: [{ type: Input }], customMenuRef: [{ type: Input }], dropdownPlacement: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWRpdG9yL3NyYy9saWIvbW9kdWxlcy9tZW51L21lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVkaXRvci9zcmMvbGliL21vZHVsZXMvbWVudS9tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQUUsS0FBSyxHQUVqQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7O0FBRzdDLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBWTtJQUN0QyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDbEIsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDO0lBQ3RCLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQztJQUN2QixDQUFDLGNBQWMsRUFBRSxhQUFhLENBQUM7SUFDL0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuRCxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7SUFDakIsQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUM7SUFDbEMsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxlQUFlLENBQUM7SUFDOUQsQ0FBQyxjQUFjLENBQUM7Q0FDakIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBWTtJQUN0QyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUM7SUFDbEIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLElBQUksRUFB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QUFJLENBQUM7U0FDYjtRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELGdCQUFnQixDQUFDLElBQWlCO1FBQ2hDLE9BQU8sSUFBdUIsQ0FBQztJQUNqQyxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2hCLE1BQU0sSUFBSSxjQUFjLENBQUMsdURBQXVELENBQUMsQ0FBQztTQUNuRjtRQUVELElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDeEMsQ0FBQzs4R0F6RVUsYUFBYTtrR0FBYixhQUFhLHdOQUhiLENBQUMsV0FBVyxDQUFDLDBCQ2hFMUIsdzlEQStDQTs7MkZEb0JhLGFBQWE7a0JBUHpCLFNBQVM7K0JBQ0UsaUJBQWlCLGFBR2hCLENBQUMsV0FBVyxDQUFDO2tHQUlmLE9BQU87c0JBQWYsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBJbnB1dCxcbiAgT25Jbml0LCBUZW1wbGF0ZVJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE5neEVkaXRvckVycm9yIH0gZnJvbSAnbmd4LWVkaXRvci91dGlscyc7XG5pbXBvcnQgeyBUb29sYmFyLCBUb29sYmFySXRlbSwgVG9vbGJhckRyb3Bkb3duIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgTWVudVNlcnZpY2UgfSBmcm9tICcuL21lbnUuc2VydmljZSc7XG5pbXBvcnQgRWRpdG9yIGZyb20gJy4uLy4uL0VkaXRvcic7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RPT0xCQVI6IFRvb2xiYXIgPSBbXG4gIFsnYm9sZCcsICdpdGFsaWMnXSxcbiAgWydjb2RlJywgJ2Jsb2NrcXVvdGUnXSxcbiAgWyd1bmRlcmxpbmUnLCAnc3RyaWtlJ10sXG4gIFsnb3JkZXJlZF9saXN0JywgJ2J1bGxldF9saXN0J10sXG4gIFt7IGhlYWRpbmc6IFsnaDEnLCAnaDInLCAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnXSB9XSxcbiAgWydsaW5rJywgJ2ltYWdlJ10sXG4gIFsndGV4dF9jb2xvcicsICdiYWNrZ3JvdW5kX2NvbG9yJ10sXG4gIFsnYWxpZ25fbGVmdCcsICdhbGlnbl9jZW50ZXInLCAnYWxpZ25fcmlnaHQnLCAnYWxpZ25fanVzdGlmeSddLFxuICBbJ2Zvcm1hdF9jbGVhciddLFxuXTtcblxuZXhwb3J0IGNvbnN0IFRPT0xCQVJfTUlOSU1BTDogVG9vbGJhciA9IFtcbiAgWydib2xkJywgJ2l0YWxpYyddLFxuICBbeyBoZWFkaW5nOiBbJ2gxJywgJ2gyJywgJ2gzJywgJ2g0JywgJ2g1JywgJ2g2J10gfV0sXG4gIFsnbGluaycsICdpbWFnZSddLFxuICBbJ3RleHRfY29sb3InLCAnYmFja2dyb3VuZF9jb2xvciddLFxuXTtcblxuZXhwb3J0IGNvbnN0IFRPT0xCQVJfRlVMTDogVG9vbGJhciA9IFtcbiAgWydib2xkJywgJ2l0YWxpYyddLFxuICBbJ2NvZGUnLCAnYmxvY2txdW90ZSddLFxuICBbJ3VuZGVybGluZScsICdzdHJpa2UnXSxcbiAgWydvcmRlcmVkX2xpc3QnLCAnYnVsbGV0X2xpc3QnXSxcbiAgW3sgaGVhZGluZzogWydoMScsICdoMicsICdoMycsICdoNCcsICdoNScsICdoNiddIH1dLFxuICBbJ2xpbmsnLCAnaW1hZ2UnXSxcbiAgWyd0ZXh0X2NvbG9yJywgJ2JhY2tncm91bmRfY29sb3InXSxcbiAgWydhbGlnbl9sZWZ0JywgJ2FsaWduX2NlbnRlcicsICdhbGlnbl9yaWdodCcsICdhbGlnbl9qdXN0aWZ5J10sXG4gIFsnaG9yaXpvbnRhbF9ydWxlJ10sXG5dO1xuXG5jb25zdCBERUZBVUxUX0NPTE9SX1BSRVNFVFMgPSBbXG4gICcjYjYwMjA1JyxcbiAgJyNkOTNmMGInLFxuICAnI2ZiY2EwNCcsXG4gICcjMGU4YTE2JyxcbiAgJyMwMDZiNzUnLFxuICAnIzFkNzZkYicsXG4gICcjMDA1MmNjJyxcbiAgJyM1MzE5ZTcnLFxuICAnI2U5OTY5NScsXG4gICcjZjlkMGM0JyxcbiAgJyNmZWYyYzAnLFxuICAnI2MyZTBjNicsXG4gICcjYmZkYWRjJyxcbiAgJyNjNWRlZjUnLFxuICAnI2JmZDRmMicsXG4gICcjZDRjNWY5Jyxcbl07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1lZGl0b3ItbWVudScsXG4gIHRlbXBsYXRlVXJsOiAnLi9tZW51LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbWVudS5jb21wb25lbnQuc2NzcyddLFxuICBwcm92aWRlcnM6IFtNZW51U2VydmljZV0sXG59KVxuXG5leHBvcnQgY2xhc3MgTWVudUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpIHRvb2xiYXI6IFRvb2xiYXIgPSBUT09MQkFSX01JTklNQUw7XG4gIEBJbnB1dCgpIGNvbG9yUHJlc2V0czogc3RyaW5nW10gPSBERUZBVUxUX0NPTE9SX1BSRVNFVFM7XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVkaXRvcjogRWRpdG9yO1xuICBASW5wdXQoKSBjdXN0b21NZW51UmVmOiBUZW1wbGF0ZVJlZjxhbnk+IHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGRyb3Bkb3duUGxhY2VtZW50OiAndG9wJyB8ICdib3R0b20nID0gJ2JvdHRvbSc7XG5cbiAgdG9nZ2xlQ29tbWFuZHM6IFRvb2xiYXJJdGVtW10gPSBbXG4gICAgJ2JvbGQnLFxuICAgICdpdGFsaWMnLFxuICAgICd1bmRlcmxpbmUnLFxuICAgICdzdHJpa2UnLFxuICAgICdjb2RlJyxcbiAgICAnYmxvY2txdW90ZScsXG4gICAgJ29yZGVyZWRfbGlzdCcsXG4gICAgJ2J1bGxldF9saXN0JyxcbiAgICAnYWxpZ25fbGVmdCcsXG4gICAgJ2FsaWduX2NlbnRlcicsXG4gICAgJ2FsaWduX3JpZ2h0JyxcbiAgICAnYWxpZ25fanVzdGlmeScsXG4gIF07XG5cbiAgaW5zZXJ0Q29tbWFuZHM6IFRvb2xiYXJJdGVtW10gPSBbXG4gICAgJ2hvcml6b250YWxfcnVsZScsXG4gICAgJ2Zvcm1hdF9jbGVhcicsXG4gIF07XG5cbiAgaWNvbkNvbnRhaW5lckNsYXNzID0gWydOZ3hFZGl0b3JfX01lbnVJdGVtJywgJ05neEVkaXRvcl9fTWVudUl0ZW0tLUljb24nXTtcbiAgZHJvcGRvd25Db250YWluZXJDbGFzcyA9IFsnTmd4RWRpdG9yX19Ecm9wZG93biddO1xuICBzZXBlcmF0b3JDbGFzcyA9IFsnTmd4RWRpdG9yX19TZXBlcmF0b3InXTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1lbnVTZXJ2aWNlOiBNZW51U2VydmljZSkgeyB9XG5cbiAgZ2V0IHByZXNldHMoKTogc3RyaW5nW11bXSB7XG4gICAgY29uc3QgY29sID0gODtcbiAgICBjb25zdCBjb2xvcnM6IHN0cmluZ1tdW10gPSBbXTtcblxuICAgIHRoaXMuY29sb3JQcmVzZXRzLmZvckVhY2goKGNvbG9yLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qgcm93ID0gTWF0aC5mbG9vcihpbmRleCAvIGNvbCk7XG5cbiAgICAgIGlmICghY29sb3JzW3Jvd10pIHtcbiAgICAgICAgY29sb3JzLnB1c2goW10pO1xuICAgICAgfVxuXG4gICAgICBjb2xvcnNbcm93XS5wdXNoKGNvbG9yKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBjb2xvcnM7XG4gIH1cblxuICB0cmFja0J5SW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgaXNEcm9wRG93bihpdGVtOiBUb29sYmFySXRlbSk6IGJvb2xlYW4ge1xuICAgIGlmICgoaXRlbSBhcyBUb29sYmFyRHJvcGRvd24pPy5oZWFkaW5nKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXREcm9wZG93bkl0ZW1zKGl0ZW06IFRvb2xiYXJJdGVtKTogVG9vbGJhckRyb3Bkb3duIHtcbiAgICByZXR1cm4gaXRlbSBhcyBUb29sYmFyRHJvcGRvd247XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgTmd4RWRpdG9yRXJyb3IoJ1JlcXVpcmVkIGVkaXRvciBpbnN0YW5jZSB0byBpbml0aWFsaXplIG1lbnUgY29tcG9uZW50Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5tZW51U2VydmljZS5lZGl0b3IgPSB0aGlzLmVkaXRvcjtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIk5neEVkaXRvcl9fTWVudUJhclwiXG4gIFtuZ0NsYXNzXT1cInsnTmd4RWRpdG9yLS1EaXNhYmxlZCc6IGRpc2FibGVkLCAnTmd4RWRpdG9yX19NZW51QmFyLS1SZXZlcnNlJzogZHJvcGRvd25QbGFjZW1lbnQgPT09ICd0b3AnfVwiPlxuXG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHRvb2xiYXJJdGVtIG9mIHRvb2xiYXI7IGxldCBsYXN0VG9vbGJhckl0ZW0gPSBsYXN0OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHRvb2xiYXJJdGVtOyBsZXQgbGFzdEl0ZW0gPSBsYXN0OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cblxuICAgICAgPCEtLSB0b2dnbGUgaWNvbnMgLS0+XG4gICAgICA8bmd4LXRvZ2dsZS1jb21tYW5kIFt0b29sYmFySXRlbV09XCJpdGVtXCIgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwidG9nZ2xlQ29tbWFuZHMuaW5jbHVkZXMoaXRlbSlcIj5cbiAgICAgIDwvbmd4LXRvZ2dsZS1jb21tYW5kPlxuXG4gICAgICA8bmd4LWluc2VydC1jb21tYW5kIFt0b29sYmFySXRlbV09XCJpdGVtXCIgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwiaW5zZXJ0Q29tbWFuZHMuaW5jbHVkZXMoaXRlbSlcIj5cbiAgICAgIDwvbmd4LWluc2VydC1jb21tYW5kPlxuXG4gICAgICA8IS0tIGxpbmsgLS0+XG4gICAgICA8bmd4LWxpbmsgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwiaXRlbSA9PT0gJ2xpbmsnXCI+PC9uZ3gtbGluaz5cblxuICAgICAgPCEtLSBpbWFnZSAtLT5cbiAgICAgIDxuZ3gtaW1hZ2UgW2NsYXNzXT1cImljb25Db250YWluZXJDbGFzc1wiICpuZ0lmPVwiaXRlbSA9PT0gJ2ltYWdlJ1wiPlxuICAgICAgPC9uZ3gtaW1hZ2U+XG5cbiAgICAgIDwhLS0gZHJvcGRvd24gLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNEcm9wRG93bihpdGVtKVwiPlxuICAgICAgICA8bmd4LWRyb3Bkb3duICpuZ0Zvcj1cImxldCBkcm9wZG93bkl0ZW0gb2YgZ2V0RHJvcGRvd25JdGVtcyhpdGVtKSB8IGtleXZhbHVlOyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIlxuICAgICAgICAgIFtjbGFzc109XCJkcm9wZG93bkNvbnRhaW5lckNsYXNzXCIgW2dyb3VwXT1cImRyb3Bkb3duSXRlbS5rZXlcIiBbaXRlbXNdPVwiZHJvcGRvd25JdGVtLnZhbHVlXCI+XG4gICAgICAgIDwvbmd4LWRyb3Bkb3duPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gdGV4dCBjb2xvciBwaWNrZXIgLS0+XG4gICAgICA8bmd4LWNvbG9yLXBpY2tlciBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAndGV4dF9jb2xvcidcIiB0eXBlPVwidGV4dF9jb2xvclwiXG4gICAgICAgIFtwcmVzZXRzXT1cInByZXNldHNcIj5cbiAgICAgIDwvbmd4LWNvbG9yLXBpY2tlcj5cbiAgICAgIDwhLS0gYmFja2dyb3VuZCBjb2xvciBwaWNrZXIgLS0+XG4gICAgICA8bmd4LWNvbG9yLXBpY2tlciBbY2xhc3NdPVwiaWNvbkNvbnRhaW5lckNsYXNzXCIgKm5nSWY9XCJpdGVtID09PSAnYmFja2dyb3VuZF9jb2xvcidcIiB0eXBlPVwiYmFja2dyb3VuZF9jb2xvclwiXG4gICAgICAgIFtwcmVzZXRzXT1cInByZXNldHNcIj5cbiAgICAgIDwvbmd4LWNvbG9yLXBpY2tlcj5cblxuICAgICAgPCEtLSBzZXBlcmF0b3IgLS0+XG4gICAgICA8ZGl2IFtjbGFzc109XCJzZXBlcmF0b3JDbGFzc1wiICpuZ0lmPVwibGFzdEl0ZW0gJiYgIWxhc3RUb29sYmFySXRlbVwiPjwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8IS0tIGN1c3RvbSBtZW51IC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VzdG9tTWVudVJlZlwiPlxuICAgIDxuZy1jb250YWluZXIgW25nVGVtcGxhdGVPdXRsZXRdPVwiY3VzdG9tTWVudVJlZlwiPjwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cblxuPC9kaXY+XG4iXX0=