UNPKG

primeng

Version:

[![npm version](https://badge.fury.io/js/primeng.svg)](https://badge.fury.io/js/primeng) [![npm downloads](https://img.shields.io/npm/dm/primeng.svg)](https://www.npmjs.com/package/primeng) [![Actions CI](https://github.com/primefaces/primeng/workflows/No

392 lines 43.3 kB
import { CommonModule, isPlatformServer } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, EventEmitter, Inject, Input, NgModule, Output, PLATFORM_ID, ViewEncapsulation, afterNextRender, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { Header, PrimeTemplate, SharedModule } from 'primeng/api'; import { DomHandler } from 'primeng/dom'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export const EDITOR_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Editor), multi: true }; /** * Editor groups a collection of contents in tabs. * @group Components */ export class Editor { el; platformId; /** * Inline style of the container. * @group Props */ style; /** * Style class of the container. * @group Props */ styleClass; /** * Placeholder text to show when editor is empty. * @group Props */ placeholder; /** * Whitelist of formats to display, see here for available options. * @group Props */ formats; /** * Modules configuration of Editor, see here for available options. * @group Props */ modules; /** * DOM Element or a CSS selector for a DOM Element, within which the editor’s p elements (i.e. tooltips, etc.) should be confined. Currently, it only considers left and right boundaries. * @group Props */ bounds; /** * DOM Element or a CSS selector for a DOM Element, specifying which container has the scrollbars (i.e. overflow-y: auto), if is has been changed from the default ql-editor with custom CSS. Necessary to fix scroll jumping bugs when Quill is set to auto grow its height, and another ancestor container is responsible from the scrolling.. * @group Props */ scrollingContainer; /** * Shortcut for debug. Note debug is a static method and will affect other instances of Quill editors on the page. Only warning and error messages are enabled by default. * @group Props */ debug; /** * Whether to instantiate the editor to read-only mode. * @group Props */ get readonly() { return this._readonly; } set readonly(val) { this._readonly = val; if (this.quill) { if (this._readonly) this.quill.disable(); else this.quill.enable(); } } /** * Callback to invoke when the quill modules are loaded. * @param {EditorInitEvent} event - custom event. * @group Emits */ onInit = new EventEmitter(); /** * Callback to invoke when text of editor changes. * @param {EditorTextChangeEvent} event - custom event. * @group Emits */ onTextChange = new EventEmitter(); /** * Callback to invoke when selection of the text changes. * @param {EditorSelectionChangeEvent} event - custom event. * @group Emits */ onSelectionChange = new EventEmitter(); templates; toolbar; value; delayedCommand = null; _readonly = false; onModelChange = () => { }; onModelTouched = () => { }; quill; dynamicQuill; headerTemplate; get isAttachedQuillEditorToDOM() { return this.quillElements?.editorElement?.isConnected; } quillElements; constructor(el, platformId) { this.el = el; this.platformId = platformId; /** * Read or write the DOM once, when initializing non-Angular (Quill) library. */ afterNextRender(() => { this.initQuillElements(); this.initQuillEditor(); }); } ngAfterContentInit() { this.templates.forEach((item) => { switch (item.getType()) { case 'header': this.headerTemplate = item.template; break; } }); } writeValue(value) { this.value = value; if (this.quill) { if (value) { const command = () => { this.quill.setContents(this.quill.clipboard.convert(this.dynamicQuill.version.startsWith('2') ? { html: this.value } : this.value)); }; if (this.isAttachedQuillEditorToDOM) { command(); } else { this.delayedCommand = command; } } else { const command = () => { this.quill.setText(''); }; if (this.isAttachedQuillEditorToDOM) { command(); } else { this.delayedCommand = command; } } } } registerOnChange(fn) { this.onModelChange = fn; } registerOnTouched(fn) { this.onModelTouched = fn; } getQuill() { return this.quill; } initQuillEditor() { if (isPlatformServer(this.platformId)) { return; } /** * Importing Quill at top level, throws `document is undefined` error during when * building for SSR, so this dynamically loads quill when it's in browser module. */ if (!this.dynamicQuill) { import('quill') .then((quillModule) => { this.dynamicQuill = quillModule.default; this.createQuillEditor(); }) .catch((e) => console.error(e.message)); } else { this.createQuillEditor(); } } createQuillEditor() { this.initQuillElements(); const { toolbarElement, editorElement } = this.quillElements; let defaultModule = { toolbar: toolbarElement }; let modules = this.modules ? { ...defaultModule, ...this.modules } : defaultModule; this.quill = new this.dynamicQuill(editorElement, { modules: modules, placeholder: this.placeholder, readOnly: this.readonly, theme: 'snow', formats: this.formats, bounds: this.bounds, debug: this.debug, scrollingContainer: this.scrollingContainer }); const isQuill2 = this.dynamicQuill.version.startsWith('2'); if (this.value) { this.quill.setContents(this.quill.clipboard.convert(isQuill2 ? { html: this.value } : this.value)); } this.quill.on('text-change', (delta, oldContents, source) => { if (source === 'user') { let html = isQuill2 ? this.quill.getSemanticHTML() : DomHandler.findSingle(editorElement, '.ql-editor').innerHTML; let text = this.quill.getText().trim(); if (html === '<p><br></p>') { html = null; } this.onTextChange.emit({ htmlValue: html, textValue: text, delta: delta, source: source }); this.onModelChange(html); this.onModelTouched(); } }); this.quill.on('selection-change', (range, oldRange, source) => { this.onSelectionChange.emit({ range: range, oldRange: oldRange, source: source }); }); this.onInit.emit({ editor: this.quill }); } initQuillElements() { if (!this.quillElements) { this.quillElements = { editorElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-content'), toolbarElement: DomHandler.findSingle(this.el.nativeElement, 'div.p-editor-toolbar') }; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: Editor, deps: [{ token: i0.ElementRef }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.7", type: Editor, selector: "p-editor", inputs: { style: "style", styleClass: "styleClass", placeholder: "placeholder", formats: "formats", modules: "modules", bounds: "bounds", scrollingContainer: "scrollingContainer", debug: "debug", readonly: "readonly" }, outputs: { onInit: "onInit", onTextChange: "onTextChange", onSelectionChange: "onSelectionChange" }, host: { classAttribute: "p-element" }, providers: [EDITOR_VALUE_ACCESSOR], queries: [{ propertyName: "toolbar", first: true, predicate: Header, descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], ngImport: i0, template: ` <div [ngClass]="'p-editor-container'" [class]="styleClass"> <div class="p-editor-toolbar" *ngIf="toolbar || headerTemplate"> <ng-content select="p-header"></ng-content> <ng-container *ngTemplateOutlet="headerTemplate"></ng-container> </div> <div class="p-editor-toolbar" *ngIf="!toolbar && !headerTemplate"> <span class="ql-formats"> <select class="ql-header"> <option value="1">Heading</option> <option value="2">Subheading</option> <option selected>Normal</option> </select> <select class="ql-font"> <option selected>Sans Serif</option> <option value="serif">Serif</option> <option value="monospace">Monospace</option> </select> </span> <span class="ql-formats"> <button class="ql-bold" aria-label="Bold" type="button"></button> <button class="ql-italic" aria-label="Italic" type="button"></button> <button class="ql-underline" aria-label="Underline" type="button"></button> </span> <span class="ql-formats"> <select class="ql-color"></select> <select class="ql-background"></select> </span> <span class="ql-formats"> <button class="ql-list" value="ordered" aria-label="Ordered List" type="button"></button> <button class="ql-list" value="bullet" aria-label="Unordered List" type="button"></button> <select class="ql-align"> <option selected></option> <option value="center">center</option> <option value="right">right</option> <option value="justify">justify</option> </select> </span> <span class="ql-formats"> <button class="ql-link" aria-label="Insert Link" type="button"></button> <button class="ql-image" aria-label="Insert Image" type="button"></button> <button class="ql-code-block" aria-label="Insert Code Block" type="button"></button> </span> <span class="ql-formats"> <button class="ql-clean" aria-label="Remove Styles" type="button"></button> </span> </div> <div class="p-editor-content" [ngStyle]="style"></div> </div> `, isInline: true, styles: [".p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options .ql-picker-item{width:auto;height:auto}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: Editor, decorators: [{ type: Component, args: [{ selector: 'p-editor', template: ` <div [ngClass]="'p-editor-container'" [class]="styleClass"> <div class="p-editor-toolbar" *ngIf="toolbar || headerTemplate"> <ng-content select="p-header"></ng-content> <ng-container *ngTemplateOutlet="headerTemplate"></ng-container> </div> <div class="p-editor-toolbar" *ngIf="!toolbar && !headerTemplate"> <span class="ql-formats"> <select class="ql-header"> <option value="1">Heading</option> <option value="2">Subheading</option> <option selected>Normal</option> </select> <select class="ql-font"> <option selected>Sans Serif</option> <option value="serif">Serif</option> <option value="monospace">Monospace</option> </select> </span> <span class="ql-formats"> <button class="ql-bold" aria-label="Bold" type="button"></button> <button class="ql-italic" aria-label="Italic" type="button"></button> <button class="ql-underline" aria-label="Underline" type="button"></button> </span> <span class="ql-formats"> <select class="ql-color"></select> <select class="ql-background"></select> </span> <span class="ql-formats"> <button class="ql-list" value="ordered" aria-label="Ordered List" type="button"></button> <button class="ql-list" value="bullet" aria-label="Unordered List" type="button"></button> <select class="ql-align"> <option selected></option> <option value="center">center</option> <option value="right">right</option> <option value="justify">justify</option> </select> </span> <span class="ql-formats"> <button class="ql-link" aria-label="Insert Link" type="button"></button> <button class="ql-image" aria-label="Insert Image" type="button"></button> <button class="ql-code-block" aria-label="Insert Code Block" type="button"></button> </span> <span class="ql-formats"> <button class="ql-clean" aria-label="Remove Styles" type="button"></button> </span> </div> <div class="p-editor-content" [ngStyle]="style"></div> </div> `, providers: [EDITOR_VALUE_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'p-element' }, styles: [".p-editor-container .p-editor-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options .ql-picker-item{width:auto;height:auto}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }], propDecorators: { style: [{ type: Input }], styleClass: [{ type: Input }], placeholder: [{ type: Input }], formats: [{ type: Input }], modules: [{ type: Input }], bounds: [{ type: Input }], scrollingContainer: [{ type: Input }], debug: [{ type: Input }], readonly: [{ type: Input }], onInit: [{ type: Output }], onTextChange: [{ type: Output }], onSelectionChange: [{ type: Output }], templates: [{ type: ContentChildren, args: [PrimeTemplate] }], toolbar: [{ type: ContentChild, args: [Header] }] } }); export class EditorModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: EditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.7", ngImport: i0, type: EditorModule, declarations: [Editor], imports: [CommonModule], exports: [Editor, SharedModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: EditorModule, imports: [CommonModule, SharedModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: EditorModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule], exports: [Editor, SharedModule], declarations: [Editor] }] }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnRzL2VkaXRvci9lZGl0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pFLE9BQU8sRUFFSCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBRWYsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixXQUFXLEVBR1gsaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixVQUFVLEVBQ2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDOzs7QUFJekMsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQVE7SUFDdEMsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNyQyxLQUFLLEVBQUUsSUFBSTtDQUNkLENBQUM7QUFDRjs7O0dBR0c7QUE2REgsTUFBTSxPQUFPLE1BQU07SUFxR0k7SUFBNkM7SUFwR2hFOzs7T0FHRztJQUNNLEtBQUssQ0FBOEM7SUFDNUQ7OztPQUdHO0lBQ00sVUFBVSxDQUFxQjtJQUN4Qzs7O09BR0c7SUFDTSxXQUFXLENBQXFCO0lBQ3pDOzs7T0FHRztJQUNNLE9BQU8sQ0FBdUI7SUFDdkM7OztPQUdHO0lBQ00sT0FBTyxDQUFxQjtJQUNyQzs7O09BR0c7SUFDTSxNQUFNLENBQW1DO0lBQ2xEOzs7T0FHRztJQUNNLGtCQUFrQixDQUFtQztJQUM5RDs7O09B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WixZQUFZLGlCQTdQWixNQUFNLGFBeVBMLFlBQVksYUF6UGIsTUFBTSxFQTBQRyxZQUFZO3dHQUdyQixZQUFZLFlBSlgsWUFBWSxFQUNKLFlBQVk7OzJGQUdyQixZQUFZO2tCQUx4QixRQUFRO21CQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQztvQkFDL0IsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDO2lCQUN6QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSwgaXNQbGF0Zm9ybVNlcnZlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICAgIEFmdGVyQ29udGVudEluaXQsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSW5qZWN0LFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE91dHB1dCxcbiAgICBQTEFURk9STV9JRCxcbiAgICBRdWVyeUxpc3QsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXG4gICAgYWZ0ZXJOZXh0UmVuZGVyLFxuICAgIGZvcndhcmRSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBIZWFkZXIsIFByaW1lVGVtcGxhdGUsIFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IERvbUhhbmRsZXIgfSBmcm9tICdwcmltZW5nL2RvbSc7XG5pbXBvcnQgeyBOdWxsYWJsZSB9IGZyb20gJ3ByaW1lbmcvdHMtaGVscGVycyc7XG5pbXBvcnQgeyBFZGl0b3JJbml0RXZlbnQsIEVkaXRvclNlbGVjdGlvbkNoYW5nZUV2ZW50LCBFZGl0b3JUZXh0Q2hhbmdlRXZlbnQgfSBmcm9tICcuL2VkaXRvci5pbnRlcmZhY2UnO1xuXG5leHBvcnQgY29uc3QgRURJVE9SX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XG4gICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRWRpdG9yKSxcbiAgICBtdWx0aTogdHJ1ZVxufTtcbi8qKlxuICogRWRpdG9yIGdyb3VwcyBhIGNvbGxlY3Rpb24gb2YgY29udGVudHMgaW4gdGFicy5cbiAqIEBncm91cCBDb21wb25lbnRzXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncC1lZGl0b3InLFxuICAgIHRlbXBsYXRlOiBgXG4gICAgICAgIDxkaXYgW25nQ2xhc3NdPVwiJ3AtZWRpdG9yLWNvbnRhaW5lcidcIiBbY2xhc3NdPVwic3R5bGVDbGFzc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtZWRpdG9yLXRvb2xiYXJcIiAqbmdJZj1cInRvb2xiYXIgfHwgaGVhZGVyVGVtcGxhdGVcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJwLWhlYWRlclwiPjwvbmctY29udGVudD5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaGVhZGVyVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtZWRpdG9yLXRvb2xiYXJcIiAqbmdJZj1cIiF0b29sYmFyICYmICFoZWFkZXJUZW1wbGF0ZVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicWwtZm9ybWF0c1wiPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwicWwtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiMVwiPkhlYWRpbmc8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCIyXCI+U3ViaGVhZGluZzwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBzZWxlY3RlZD5Ob3JtYWw8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJxbC1mb250XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHNlbGVjdGVkPlNhbnMgU2VyaWY8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJzZXJpZlwiPlNlcmlmPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwibW9ub3NwYWNlXCI+TW9ub3NwYWNlPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInFsLWZvcm1hdHNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInFsLWJvbGRcIiBhcmlhLWxhYmVsPVwiQm9sZFwiIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInFsLWl0YWxpY1wiIGFyaWEtbGFiZWw9XCJJdGFsaWNcIiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJxbC11bmRlcmxpbmVcIiBhcmlhLWxhYmVsPVwiVW5kZXJsaW5lXCIgdHlwZT1cImJ1dHRvblwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInFsLWZvcm1hdHNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cInFsLWNvbG9yXCI+PC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJxbC1iYWNrZ3JvdW5kXCI+PC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicWwtZm9ybWF0c1wiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicWwtbGlzdFwiIHZhbHVlPVwib3JkZXJlZFwiIGFyaWEtbGFiZWw9XCJPcmRlcmVkIExpc3RcIiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJxbC1saXN0XCIgdmFsdWU9XCJidWxsZXRcIiBhcmlhLWxhYmVsPVwiVW5vcmRlcmVkIExpc3RcIiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJxbC1hbGlnblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBzZWxlY3RlZD48L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJjZW50ZXJcIj5jZW50ZXI8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJyaWdodFwiPnJpZ2h0PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwianVzdGlmeVwiPmp1c3RpZnk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicWwtZm9ybWF0c1wiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicWwtbGlua1wiIGFyaWEtbGFiZWw9XCJJbnNlcnQgTGlua1wiIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInFsLWltYWdlXCIgYXJpYS1sYWJlbD1cIkluc2VydCBJbWFnZVwiIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInFsLWNvZGUtYmxvY2tcIiBhcmlhLWxhYmVsPVwiSW5zZXJ0IENvZGUgQmxvY2tcIiB0eXBlPVwiYnV0dG9uXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicWwtZm9ybWF0c1wiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicWwtY2xlYW5cIiBhcmlhLWxhYmVsPVwiUmVtb3ZlIFN0eWxlc1wiIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwLWVkaXRvci1jb250ZW50XCIgW25nU3R5bGVdPVwic3R5bGVcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgYCxcbiAgICBwcm92aWRlcnM6IFtFRElUT1JfVkFMVUVfQUNDRVNTT1JdLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHN0eWxlVXJsczogWycuL2VkaXRvci5jc3MnXSxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgY2xhc3M6ICdwLWVsZW1lbnQnXG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBFZGl0b3IgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG4gICAgLyoqXG4gICAgICogSW5saW5lIHN0eWxlIG9mIHRoZSBjb250YWluZXIuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgc3R5bGU6IHsgW2tsYXNzOiBzdHJpbmddOiBhbnkgfSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogU3R5bGUgY2xhc3Mgb2YgdGhlIGNvbnRhaW5lci5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBzdHlsZUNsYXNzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogUGxhY2Vob2xkZXIgdGV4dCB0byBzaG93IHdoZW4gZWRpdG9yIGlzIGVtcHR5LlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogV2hpdGVsaXN0IG9mIGZvcm1hdHMgdG8gZGlzcGxheSwgc2VlIGhlcmUgZm9yIGF2YWlsYWJsZSBvcHRpb25zLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGZvcm1hdHM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIE1vZHVsZXMgY29uZmlndXJhdGlvbiBvZiBFZGl0b3IsIHNlZSBoZXJlIGZvciBhdmFpbGFibGUgb3B0aW9ucy5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBtb2R1bGVzOiBvYmplY3QgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogRE9NIEVsZW1lbnQgb3IgYSBDU1Mgc2VsZWN0b3IgZm9yIGEgRE9NIEVsZW1lbnQsIHdpdGhpbiB3aGljaCB0aGUgZWRpdG9y4oCZcyBwIGVsZW1lbnRzIChpLmUuIHRvb2x0aXBzLCBldGMuKSBzaG91bGQgYmUgY29uZmluZWQuIEN1cnJlbnRseSwgaXQgb25seSBjb25zaWRlcnMgbGVmdCBhbmQgcmlnaHQgYm91bmRhcmllcy5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBib3VuZHM6IEhUTUxFbGVtZW50IHwgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIERPTSBFbGVtZW50IG9yIGEgQ1NTIHNlbGVjdG9yIGZvciBhIERPTSBFbGVtZW50LCBzcGVjaWZ5aW5nIHdoaWNoIGNvbnRhaW5lciBoYXMgdGhlIHNjcm9sbGJhcnMgKGkuZS4gb3ZlcmZsb3cteTogYXV0byksIGlmIGlzIGhhcyBiZWVuIGNoYW5nZWQgZnJvbSB0aGUgZGVmYXVsdCBxbC1lZGl0b3Igd2l0aCBjdXN0b20gQ1NTLiBOZWNlc3NhcnkgdG8gZml4IHNjcm9sbCBqdW1waW5nIGJ1Z3Mgd2hlbiBRdWlsbCBpcyBzZXQgdG8gYXV0byBncm93IGl0cyBoZWlnaHQsIGFuZCBhbm90aGVyIGFuY2VzdG9yIGNvbnRhaW5lciBpcyByZXNwb25zaWJsZSBmcm9tIHRoZSBzY3JvbGxpbmcuLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHNjcm9sbGluZ0NvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogU2hvcnRjdXQgZm9yIGRlYnVnLiBOb3RlIGRlYnVnIGlzIGEgc3RhdGljIG1ldGhvZCBhbmQgd2lsbCBhZmZlY3Qgb3RoZXIgaW5zdGFuY2VzIG9mIFF1aWxsIGVkaXRvcnMgb24gdGhlIHBhZ2UuIE9ubHkgd2FybmluZyBhbmQgZXJyb3IgbWVzc2FnZXMgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBkZWJ1Zzogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gaW5zdGFudGlhdGUgdGhlIGVkaXRvciB0byByZWFkLW9ubHkgbW9kZS5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBnZXQgcmVhZG9ubHkoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWFkb25seTtcbiAgICB9XG4gICAgc2V0IHJlYWRvbmx5KHZhbDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9yZWFkb25seSA9IHZhbDtcblxuICAgICAgICBpZiAodGhpcy5xdWlsbCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3JlYWRvbmx5KSB0aGlzLnF1aWxsLmRpc2FibGUoKTtcbiAgICAgICAgICAgIGVsc2UgdGhpcy5xdWlsbC5lbmFibGUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgcXVpbGwgbW9kdWxlcyBhcmUgbG9hZGVkLlxuICAgICAqIEBwYXJhbSB7RWRpdG9ySW5pdEV2ZW50fSBldmVudCAtIGN1c3RvbSBldmVudC5cbiAgICAgKiBAZ3JvdXAgRW1pdHNcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgb25Jbml0OiBFdmVudEVtaXR0ZXI8RWRpdG9ySW5pdEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8RWRpdG9ySW5pdEV2ZW50PigpO1xuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRleHQgb2YgZWRpdG9yIGNoYW5nZXMuXG4gICAgICogQHBhcmFtIHtFZGl0b3JUZXh0Q2hhbmdlRXZlbnR9IGV2ZW50IC0gY3VzdG9tIGV2ZW50LlxuICAgICAqIEBncm91cCBFbWl0c1xuICAgICAqL1xuICAgIEBPdXRwdXQoKSBvblRleHRDaGFuZ2U6IEV2ZW50RW1pdHRlcjxFZGl0b3JUZXh0Q2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxFZGl0b3JUZXh0Q2hhbmdlRXZlbnQ+KCk7XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gc2VsZWN0aW9uIG9mIHRoZSB0ZXh0IGNoYW5nZXMuXG4gICAgICogQHBhcmFtIHtFZGl0b3JTZWxlY3Rpb25DaGFuZ2VFdmVudH0gZXZlbnQgLSBjdXN0b20gZXZlbnQuXG4gICAgICogQGdyb3VwIEVtaXRzXG4gICAgICovXG4gICAgQE91dHB1dCgpIG9uU2VsZWN0aW9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RWRpdG9yU2VsZWN0aW9uQ2hhbmdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxFZGl0b3JTZWxlY3Rpb25DaGFuZ2VFdmVudD4oKTtcblxuICAgIEBDb250ZW50Q2hpbGRyZW4oUHJpbWVUZW1wbGF0ZSkgdGVtcGxhdGVzITogUXVlcnlMaXN0PFByaW1lVGVtcGxhdGU+O1xuXG4gICAgQENvbnRlbnRDaGlsZChIZWFkZXIpIHRvb2xiYXI6IGFueTtcblxuICAgIHZhbHVlOiBOdWxsYWJsZTxzdHJpbmc+O1xuXG4gICAgZGVsYXllZENvbW1hbmQ6IEZ1bmN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgICBfcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIG9uTW9kZWxDaGFuZ2U6IEZ1bmN0aW9uID0gKCkgPT4ge307XG5cbiAgICBvbk1vZGVsVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7fTtcblxuICAgIHF1aWxsOiBhbnk7XG5cbiAgICBkeW5hbWljUXVpbGw6IGFueTtcblxuICAgIGhlYWRlclRlbXBsYXRlOiBOdWxsYWJsZTxUZW1wbGF0ZVJlZjxhbnk+PjtcblxuICAgIHByaXZhdGUgZ2V0IGlzQXR0YWNoZWRRdWlsbEVkaXRvclRvRE9NKCk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5xdWlsbEVsZW1lbnRzPy5lZGl0b3JFbGVtZW50Py5pc0Nvbm5lY3RlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHF1aWxsRWxlbWVudHMhOiB7IGVkaXRvckVsZW1lbnQ6IEhUTUxFbGVtZW50OyB0b29sYmFyRWxlbWVudDogSFRNTEVsZW1lbnQgfTtcblxuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBlbDogRWxlbWVudFJlZiwgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBvYmplY3QpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlYWQgb3Igd3JpdGUgdGhlIERPTSBvbmNlLCB3aGVuIGluaXRpYWxpemluZyBub24tQW5ndWxhciAoUXVpbGwpIGxpYnJhcnkuXG4gICAgICAgICAqL1xuICAgICAgICBhZnRlck5leHRSZW5kZXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbml0UXVpbGxFbGVtZW50cygpO1xuICAgICAgICAgICAgdGhpcy5pbml0UXVpbGxFZGl0b3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLnRlbXBsYXRlcy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGl0ZW0uZ2V0VHlwZSgpKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWFkZXJUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgIGlmICh0aGlzLnF1aWxsKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21tYW5kID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnF1aWxsLnNldENvbnRlbnRzKHRoaXMucXVpbGwuY2xpcGJvYXJkLmNvbnZlcnQodGhpcy5keW5hbWljUXVpbGwudmVyc2lvbi5zdGFydHNXaXRoKCcyJykgPyB7IGh0bWw6IHRoaXMudmFsdWUgfSA6IHRoaXMudmFsdWUpKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNBdHRhY2hlZFF1aWxsRWRpdG9yVG9ET00pIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVsYXllZENvbW1hbmQgPSBjb21tYW5kO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tbWFuZCA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWlsbC5zZXRUZXh0KCcnKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNBdHRhY2hlZFF1aWxsRWRpdG9yVG9ET00pIHtcbiAgICAgICAgICAgICAgICAgICAgY29tbWFuZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVsYXllZENvbW1hbmQgPSBjb21tYW5kO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IEZ1bmN0aW9uKTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Nb2RlbENoYW5nZSA9IGZuO1xuICAgIH1cblxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBGdW5jdGlvbik6IHZvaWQge1xuICAgICAgICB0aGlzLm9uTW9kZWxUb3VjaGVkID0gZm47XG4gICAgfVxuXG4gICAgZ2V0UXVpbGwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnF1aWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFF1aWxsRWRpdG9yKCk6IHZvaWQge1xuICAgICAgICBpZiAoaXNQbGF0Zm9ybVNlcnZlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogSW1wb3J0aW5nIFF1aWxsIGF0IHRvcCBsZXZlbCwgdGhyb3dzIGBkb2N1bWVudCBpcyB1bmRlZmluZWRgIGVycm9yIGR1cmluZyB3aGVuXG4gICAgICAgICAqIGJ1aWxkaW5nIGZvciBTU1IsIHNvIHRoaXMgZHluYW1pY2FsbHkgbG9hZHMgcXVpbGwgd2hlbiBpdCdzIGluIGJyb3dzZXIgbW9kdWxlLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKCF0aGlzLmR5bmFtaWNRdWlsbCkge1xuICAgICAgICAgICAgaW1wb3J0KCdxdWlsbCcpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHF1aWxsTW9kdWxlOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5keW5hbWljUXVpbGwgPSBxdWlsbE1vZHVsZS5kZWZhdWx0O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0ZVF1aWxsRWRpdG9yKCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGUpID0+IGNvbnNvbGUuZXJyb3IoZS5tZXNzYWdlKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVF1aWxsRWRpdG9yKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVF1aWxsRWRpdG9yKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluaXRRdWlsbEVsZW1lbnRzKCk7XG5cbiAgICAgICAgY29uc3QgeyB0b29sYmFyRWxlbWVudCwgZWRpdG9yRWxlbWVudCB9ID0gdGhpcy5xdWlsbEVsZW1lbnRzO1xuICAgICAgICBsZXQgZGVmYXVsdE1vZHVsZSA9IHsgdG9vbGJhcjogdG9vbGJhckVsZW1lbnQgfTtcbiAgICAgICAgbGV0IG1vZHVsZXMgPSB0aGlzLm1vZHVsZXMgPyB7IC4uLmRlZmF1bHRNb2R1bGUsIC4uLnRoaXMubW9kdWxlcyB9IDogZGVmYXVsdE1vZHVsZTtcbiAgICAgICAgdGhpcy5xdWlsbCA9IG5ldyB0aGlzLmR5bmFtaWNRdWlsbChlZGl0b3JFbGVtZW50LCB7XG4gICAgICAgICAgICBtb2R1bGVzOiBtb2R1bGVzLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMucGxhY2Vob2xkZXIsXG4gICAgICAgICAgICByZWFkT25seTogdGhpcy5yZWFkb25seSxcbiAgICAgICAgICAgIHRoZW1lOiAnc25vdycsXG4gICAgICAgICAgICBmb3JtYXRzOiB0aGlzLmZvcm1hdHMsXG4gICAgICAgICAgICBib3VuZHM6IHRoaXMuYm91bmRzLFxuICAgICAgICAgICAgZGVidWc6IHRoaXMuZGVidWcsXG4gICAgICAgICAgICBzY3JvbGxpbmdDb250YWluZXI6IHRoaXMuc2Nyb2xsaW5nQ29udGFpbmVyXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGlzUXVpbGwyID0gdGhpcy5keW5hbWljUXVpbGwudmVyc2lvbi5zdGFydHNXaXRoKCcyJyk7XG5cbiAgICAgICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMucXVpbGwuc2V0Q29udGVudHModGhpcy5xdWlsbC5jbGlwYm9hcmQuY29udmVydChpc1F1aWxsMiA/IHsgaHRtbDogdGhpcy52YWx1ZSB9IDogdGhpcy52YWx1ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5xdWlsbC5vbigndGV4dC1jaGFuZ2UnLCAoZGVsdGE6IGFueSwgb2xkQ29udGVudHM6IGFueSwgc291cmNlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChzb3VyY2UgPT09ICd1c2VyJykge1xuICAgICAgICAgICAgICAgIGxldCBodG1sID0gaXNRdWlsbDIgPyB0aGlzLnF1aWxsLmdldFNlbWFudGljSFRNTCgpIDogRG9tSGFuZGxlci5maW5kU2luZ2xlKGVkaXRvckVsZW1lbnQsICcucWwtZWRpdG9yJykuaW5uZXJIVE1MO1xuICAgICAgICAgICAgICAgIGxldCB0ZXh0ID0gdGhpcy5xdWlsbC5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgICAgIGlmIChodG1sID09PSAnPHA+PGJyPjwvcD4nKSB7XG4gICAgICAgICAgICAgICAgICAgIGh0bWwgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMub25UZXh0Q2hhbmdlLmVtaXQoe1xuICAgICAgICAgICAgICAgICAgICBodG1sVmFsdWU6IGh0bWwsXG4gICAgICAgICAgICAgICAgICAgIHRleHRWYWx1ZTogdGV4dCxcbiAgICAgICAgICAgICAgICAgICAgZGVsdGE6IGRlbHRhLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHNvdXJjZVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5vbk1vZGVsQ2hhbmdlKGh0bWwpO1xuICAgICAgICAgICAgICAgIHRoaXMub25Nb2RlbFRvdWNoZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5xdWlsbC5vbignc2VsZWN0aW9uLWNoYW5nZScsIChyYW5nZTogc3RyaW5nLCBvbGRSYW5nZTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZS5lbWl0KHtcbiAgICAgICAgICAgICAgICByYW5nZTogcmFuZ2UsXG4gICAgICAgICAgICAgICAgb2xkUmFuZ2U6IG9sZFJhbmdlLFxuICAgICAgICAgICAgICAgIHNvdXJjZTogc291cmNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vbkluaXQuZW1pdCh7XG4gICAgICAgICAgICBlZGl0b3I6IHRoaXMucXVpbGxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0UXVpbGxFbGVtZW50cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnF1aWxsRWxlbWVudHMpIHtcbiAgICAgICAgICAgIHRoaXMucXVpbGxFbGVtZW50cyA9IHtcbiAgICAgICAgICAgICAgICBlZGl0b3JFbGVtZW50OiBEb21IYW5kbGVyLmZpbmRTaW5nbGUodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnZGl2LnAtZWRpdG9yLWNvbnRlbnQnKSxcbiAgICAgICAgICAgICAgICB0b29sYmFyRWxlbWVudDogRG9tSGFuZGxlci5maW5kU2luZ2xlKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ2Rpdi5wLWVkaXRvci10b29sYmFyJylcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbkBOZ01vZHVsZSh7XG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gICAgZXhwb3J0czogW0VkaXRvciwgU2hhcmVkTW9kdWxlXSxcbiAgICBkZWNsYXJhdGlvbnM6IFtFZGl0b3JdXG59KVxuZXhwb3J0IGNsYXNzIEVkaXRvck1vZHVsZSB7fVxuIl19