UNPKG

ngx-showdown

Version:

A Angular (>=2) integration for Showdown

280 lines 22.1 kB
import { Component, ElementRef, Input, Optional, SecurityContext } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { ShowdownConfig } from './showdown-config.provider'; import { ShowdownConverter } from './showdown-converter.provider'; /** * @internal */ const MAP_OPTION = { '': true, true: true, false: false }; /** * @internal */ let _toOption = (value) => MAP_OPTION.hasOwnProperty(value) ? MAP_OPTION[value] : value; const ɵ0 = _toOption; /** * The options keys for the dynamic properties set. * @internal */ const OPTIONS_PROPERTIES_KEYS = [ 'backslashEscapesHTMLTags', 'completeHTMLDocument', 'disableForced4SpacesIndentedSublists', 'emoji', 'encodeEmails', 'ghCodeBlocks', 'ghCompatibleHeaderId', 'ghMentions', 'ghMentionsLink', 'headerLevelStart', 'literalMidWordAsterisks', 'literalMidWordUnderscores', 'metadata', 'noHeaderId', 'omitExtraWLInCodeBlocks', 'openLinksInNewWindow', 'parseImgDimensions', 'prefixHeaderId', 'rawHeaderId', 'rawPrefixHeaderId', 'requireSpaceBeforeHeadingText', 'simpleLineBreaks', 'simplifiedAutoLink', 'smartIndentationFix', 'smoothLivePreview', 'splitAdjacentBlockquotes', 'strikethrough', 'tables', 'tablesHeaderId', 'tasklists', 'underline' ]; /** * A angular component for render `Markdown` to `HTML`. * * ### Example * * Setup as standalone * ```typescript * import { NgModule } from '@angular/core'; * import { ShowdownComponent } from 'ngx-showdown'; * * @NgModule({ * declarations: [ ShowdownComponent ]; * }) * export class AppModule {} * ``` * * Bind markdown value and options object * ```typescript * import { Component } from '@angular/core'; * import * as Showdown from 'showdown'; * * @Component({ * selector: 'some', * template: '<showdown [value]="text" [options]="options"></showdown>' * }) * export class SomeComponent { * text: string = ` * # Some header * --- * **Some bold** * `; * options: Showdown.ShowdownOptions = { smartIndentationFix: true }; * // ... * } * ``` * Bind single option (it have properties for all showdown options). * ```html * <showdown emoji="true" noHeaderId># Some text :+1:</showdown> * ``` * * Set static markdown value. * ```html * <showdown value="___Some static value___" underline></showdown> * ``` * * Use as directive on anther element. * ```html * <div showdown="# Div Element" headerLevelStart="2"></div> * ``` * * Static markdown value in the element content. * ```html * <div> * <showdown smartIndentationFix> * # List: * * a * * A * * b * </showdown> * </div> * ``` * * Set template reference variable. * ```html * <showdown #sd></showdown> * ``` * Or * ```html * <div showdown #sd="showdown"></div> * ``` */ export class ShowdownComponent extends ShowdownConverter { constructor(_elementRef, _domSanitizer, config) { super(config); this._elementRef = _elementRef; this._domSanitizer = _domSanitizer; } /** * Input alias to `value`. * * __Example :__ * * ```html * <div [showdown]="# Some Header"></div> * ``` * * Equivalent to * ```html * <showdown [value]="# Some Header"></showdown> * ``` */ set showdown(value) { this.value = value; } /** * The showdown options of the converter. * * __Example :__ * * Bind options * ```typescript * import { Component } from '@angular/core'; * import * as Showdown from 'showdown'; * * @Component({ * selector: `some`, * template: `<showdown [options]="options"># Some Header<showdown>` * }) * export class SomeComponent { * options: Showdown.ShowdownOptions = {headerLevelStart: 3}; * // ... * } * ``` * Or * ```html * <showdown [options]="{smartIndentationFix: true}"> # Indentation Fix<showdown> * ``` */ get options() { return this.getOptions(); } set options(options) { this.setOptions(options); } /** * Enables html sanitize, it will sanitize the converter html output by [`DomSanitizer`](https://angular.io/api/platform-browser/DomSanitizer#sanitize). * * __Example :__ * * ```typescript * import { Component } from '@angular/core'; * * @Component({ * selector: 'some', * styles: [`.box { width: 95%; padding: 5px; border: 1px solid black;}`], * template: ` * <h3>Input</h3> * <textarea class="box" [(ngModel)]="text"></textarea> * <input type="checkbox" [(ngModel)]="sanitize"/> <b>Sanitize</b> * <h3>Markdown</h3> * <pre class="box"><code>{{ text }}</code></pre> * <h3>Preview</h3> * <div class="box"> * <showdown #sd [value]="text" [sanitize]="sanitize"></showdown> * </div> * `; * }) * export class SomeComponent { * text: string = `# A cool link * <a href="javascript:alert('Hello!')">click me</a>`; * } * ``` */ set sanitize(sanitize) { this._sanitize = _toOption(sanitize); } /** * A angular lifecycle method, Use on init to check if it `content` type and load the element `content` to `value`. * @internal */ ngOnInit() { if (this.value === undefined && this._elementRef.nativeElement.innerHTML.trim() !== '') { this.render(this._elementRef.nativeElement.innerHTML); } } /** * A angular lifecycle method, Use to call to render method after changes. * @internal */ ngOnChanges() { this.render(); } /** * Convert the markdown value of {@link ShowdownComponent#value} to html and set the html result to the element content. * * __Example :__ * * ```html * <textarea #textarea (change)="showdown.render(textarea.value)"/># Some Header</textarea> * <showdown #showdown></showdown> * ``` * @param value - A markdown value to render (it will override the current value of `ShowdownComponent#value`) */ render(value) { if (typeof value === 'string') { this.value = value; } if (typeof this.value === 'string') { let result = this.makeHtml(this.value); if (this._sanitize) { result = this._domSanitizer.sanitize(SecurityContext.HTML, result); } this._elementRef.nativeElement.innerHTML = result; } } } ShowdownComponent.decorators = [ { type: Component, args: [{ selector: 'showdown,[showdown]', template: '<ng-content></ng-content>', exportAs: 'showdown', inputs: OPTIONS_PROPERTIES_KEYS },] } ]; ShowdownComponent.ctorParameters = () => [ { type: ElementRef }, { type: DomSanitizer, decorators: [{ type: Optional }] }, { type: ShowdownConfig, decorators: [{ type: Optional }] } ]; ShowdownComponent.propDecorators = { value: [{ type: Input }], showdown: [{ type: Input }], options: [{ type: Input }], sanitize: [{ type: Input }] }; // Define options properties setter for angular directive and direct access for (let key of OPTIONS_PROPERTIES_KEYS) { Object.defineProperty(ShowdownComponent.prototype, key, { set(value) { this.setOption(key, _toOption(value)); }, configurable: true }); } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hvd2Rvd24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Nob3dkb3duLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQXFCLFFBQVEsRUFBRSxlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0csT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXpELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUVsRTs7R0FFRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLEVBQUUsRUFBRSxJQUFJO0lBQ1IsSUFBSSxFQUFFLElBQUk7SUFDVixLQUFLLEVBQUUsS0FBSztDQUNiLENBQUM7QUFFRjs7R0FFRztBQUNILElBQUksU0FBUyxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQzs7QUFFN0Y7OztHQUdHO0FBQ0gsTUFBTSx1QkFBdUIsR0FBYTtJQUN4QywwQkFBMEI7SUFDMUIsc0JBQXNCO0lBQ3RCLHNDQUFzQztJQUN0QyxPQUFPO0lBQ1AsY0FBYztJQUNkLGNBQWM7SUFDZCxzQkFBc0I7SUFDdEIsWUFBWTtJQUNaLGdCQUFnQjtJQUNoQixrQkFBa0I7SUFDbEIseUJBQXlCO0lBQ3pCLDJCQUEyQjtJQUMzQixVQUFVO0lBQ1YsWUFBWTtJQUNaLHlCQUF5QjtJQUN6QixzQkFBc0I7SUFDdEIsb0JBQW9CO0lBQ3BCLGdCQUFnQjtJQUNoQixhQUFhO0lBQ2IsbUJBQW1CO0lBQ25CLCtCQUErQjtJQUMvQixrQkFBa0I7SUFDbEIs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LENBQUMsS0FBVTtZQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFDRCxZQUFZLEVBQUUsSUFBSTtLQUNuQixDQUFDLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBPcHRpb25hbCwgU2VjdXJpdHlDb250ZXh0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCAqIGFzIFNob3dkb3duIGZyb20gJ3Nob3dkb3duJztcbmltcG9ydCB7IFNob3dkb3duQ29uZmlnIH0gZnJvbSAnLi9zaG93ZG93bi1jb25maWcucHJvdmlkZXInO1xuaW1wb3J0IHsgU2hvd2Rvd25Db252ZXJ0ZXIgfSBmcm9tICcuL3Nob3dkb3duLWNvbnZlcnRlci5wcm92aWRlcic7XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmNvbnN0IE1BUF9PUFRJT04gPSB7XG4gICcnOiB0cnVlLFxuICB0cnVlOiB0cnVlLFxuICBmYWxzZTogZmFsc2Vcbn07XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmxldCBfdG9PcHRpb24gPSAodmFsdWU6IGFueSkgPT4gTUFQX09QVElPTi5oYXNPd25Qcm9wZXJ0eSh2YWx1ZSkgPyBNQVBfT1BUSU9OW3ZhbHVlXSA6IHZhbHVlO1xuXG4vKipcbiAqIFRoZSBvcHRpb25zIGtleXMgZm9yIHRoZSBkeW5hbWljIHByb3BlcnRpZXMgc2V0LlxuICogQGludGVybmFsXG4gKi9cbmNvbnN0IE9QVElPTlNfUFJPUEVSVElFU19LRVlTOiBzdHJpbmdbXSA9IFtcbiAgJ2JhY2tzbGFzaEVzY2FwZXNIVE1MVGFncycsXG4gICdjb21wbGV0ZUhUTUxEb2N1bWVudCcsXG4gICdkaXNhYmxlRm9yY2VkNFNwYWNlc0luZGVudGVkU3VibGlzdHMnLFxuICAnZW1vamknLFxuICAnZW5jb2RlRW1haWxzJyxcbiAgJ2doQ29kZUJsb2NrcycsXG4gICdnaENvbXBhdGlibGVIZWFkZXJJZCcsXG4gICdnaE1lbnRpb25zJyxcbiAgJ2doTWVudGlvbnNMaW5rJyxcbiAgJ2hlYWRlckxldmVsU3RhcnQnLFxuICAnbGl0ZXJhbE1pZFdvcmRBc3Rlcmlza3MnLFxuICAnbGl0ZXJhbE1pZFdvcmRVbmRlcnNjb3JlcycsXG4gICdtZXRhZGF0YScsXG4gICdub0hlYWRlcklkJyxcbiAgJ29taXRFeHRyYVdMSW5Db2RlQmxvY2tzJyxcbiAgJ29wZW5MaW5rc0luTmV3V2luZG93JyxcbiAgJ3BhcnNlSW1nRGltZW5zaW9ucycsXG4gICdwcmVmaXhIZWFkZXJJZCcsXG4gICdyYXdIZWFkZXJJZCcsXG4gICdyYXdQcmVmaXhIZWFkZXJJZCcsXG4gICdyZXF1aXJlU3BhY2VCZWZvcmVIZWFkaW5nVGV4dCcsXG4gICdzaW1wbGVMaW5lQnJlYWtzJyxcbiAgJ3NpbXBsaWZpZWRBdXRvTGluaycsXG4gICdzbWFydEluZGVudGF0aW9uRml4JyxcbiAgJ3Ntb290aExpdmVQcmV2aWV3JyxcbiAgJ3NwbGl0QWRqYWNlbnRCbG9ja3F1b3RlcycsXG4gICdzdHJpa2V0aHJvdWdoJyxcbiAgJ3RhYmxlcycsXG4gICd0YWJsZXNIZWFkZXJJZCcsXG4gICd0YXNrbGlzdHMnLFxuICAndW5kZXJsaW5lJ1xuXTtcblxuLy8gRm9yIHRoZSBvcHRpb25zIHNldHRlciBwcm9wZXJ0aWVzIHRoYXQgZHluYW1pYyBkZWZpbml0aW9uICh0aGUgY29kZSBhZnRlciB0aGUgY2xhc3MpXG5leHBvcnQgaW50ZXJmYWNlIFNob3dkb3duQ29tcG9uZW50IGV4dGVuZHMgU2hvd2Rvd24uU2hvd2Rvd25PcHRpb25zIHtcbn1cblxuLyoqXG4gKiBBIGFuZ3VsYXIgY29tcG9uZW50IGZvciByZW5kZXIgYE1hcmtkb3duYCB0byBgSFRNTGAuXG4gKlxuICogIyMjIEV4YW1wbGVcbiAqXG4gKiBTZXR1cCBhcyBzdGFuZGFsb25lXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuICogaW1wb3J0IHsgU2hvd2Rvd25Db21wb25lbnQgfSBmcm9tICduZ3gtc2hvd2Rvd24nO1xuICpcbiAqIEBOZ01vZHVsZSh7XG4gKiAgIGRlY2xhcmF0aW9uczogWyBTaG93ZG93bkNvbXBvbmVudCBdO1xuICogfSlcbiAqIGV4cG9ydCBjbGFzcyBBcHBNb2R1bGUge31cbiAqIGBgYFxuICpcbiAqIEJpbmQgbWFya2Rvd24gdmFsdWUgYW5kIG9wdGlvbnMgb2JqZWN0XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbiAqIGltcG9ydCAqIGFzIFNob3dkb3duIGZyb20gJ3Nob3dkb3duJztcbiAqXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdzb21lJyxcbiAqICAgdGVtcGxhdGU6ICc8c2hvd2Rvd24gW3ZhbHVlXT1cInRleHRcIiBbb3B0aW9uc109XCJvcHRpb25zXCI+PC9zaG93ZG93bj4nXG4gKiB9KVxuICogZXhwb3J0IGNsYXNzIFNvbWVDb21wb25lbnQge1xuICogICB0ZXh0OiBzdHJpbmcgPSBgXG4gKiAgICAgIyBTb21lIGhlYWRlclxuICogICAgIC0tLVxuICogICAgICoqU29tZSBib2xkKipcbiAqICAgYDtcbiAqICAgb3B0aW9uczogU2hvd2Rvd24uU2hvd2Rvd25PcHRpb25zID0geyBzbWFydEluZGVudGF0aW9uRml4OiB0cnVlIH07XG4gKiAgIC8vIC4uLlxuICogfVxuICogYGBgXG4gKiBCaW5kIHNpbmdsZSBvcHRpb24gKGl0IGhhdmUgcHJvcGVydGllcyBmb3IgYWxsIHNob3dkb3duIG9wdGlvbnMpLlxuICogYGBgaHRtbFxuICogPHNob3dkb3duIGVtb2ppPVwidHJ1ZVwiICBub0hlYWRlcklkPiMgU29tZSB0ZXh0IDorMTo8L3Nob3dkb3duPlxuICogYGBgXG4gKlxuICogU2V0IHN0YXRpYyBtYXJrZG93biB2YWx1ZS5cbiAqIGBgYGh0bWxcbiAqIDxzaG93ZG93biB2YWx1ZT1cIl9fX1NvbWUgc3RhdGljIHZhbHVlX19fXCIgdW5kZXJsaW5lPjwvc2hvd2Rvd24+XG4gKiBgYGBcbiAqXG4gKiBVc2UgYXMgZGlyZWN0aXZlIG9uIGFudGhlciBlbGVtZW50LlxuICogYGBgaHRtbFxuICogPGRpdiBzaG93ZG93bj1cIiMgRGl2IEVsZW1lbnRcIiBoZWFkZXJMZXZlbFN0YXJ0PVwiMlwiPjwvZGl2PlxuICogYGBgXG4gKlxuICogU3RhdGljIG1hcmtkb3duIHZhbHVlIGluIHRoZSBlbGVtZW50IGNvbnRlbnQuXG4gKiBgYGBodG1sXG4gKiA8ZGl2PlxuICogICAgPHNob3dkb3duIHNtYXJ0SW5kZW50YXRpb25GaXg+XG4gKiAgICAgICAjIExpc3Q6XG4gKiAgICAgICAqIGFcbiAqICAgICAgICAgICAgKiBBXG4gKiAgICAgICAqIGJcbiAqICAgIDwvc2hvd2Rvd24+XG4gKiA8L2Rpdj5cbiAqIGBgYFxuICpcbiAqIFNldCB0ZW1wbGF0ZSByZWZlcmVuY2UgdmFyaWFibGUuXG4gKiBgYGBodG1sXG4gKiA8c2hvd2Rvd24gI3NkPjwvc2hvd2Rvd24+XG4gKiBgYGBcbiAqIE9yXG4gKiBgYGBodG1sXG4gKiA8ZGl2IHNob3dkb3duICNzZD1cInNob3dkb3duXCI+PC9kaXY+XG4gKiBgYGBcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc2hvd2Rvd24sW3Nob3dkb3duXScsXG4gIHRlbXBsYXRlOiAnPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PicsXG4gIGV4cG9ydEFzOiAnc2hvd2Rvd24nLFxuICBpbnB1dHM6IE9QVElPTlNfUFJPUEVSVElFU19LRVlTXG59KVxuZXhwb3J0IGNsYXNzIFNob3dkb3duQ29tcG9uZW50IGV4dGVuZHMgU2hvd2Rvd25Db252ZXJ0ZXIgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgU2hvd2Rvd24uU2hvd2Rvd25PcHRpb25zIHtcblxuICAvKipcbiAgICogVGhlIGlucHV0IG1hcmtkb3duIHZhbHVlLlxuICAgKlxuICAgKiBfX0V4YW1wbGUgOl9fXG4gICAqXG4gICAqIFNldCBzb21lIHN0YXRpYyBtYXJrZG93biB2YWx1ZS5cbiAgICogYGBgaHRtbFxuICAgKiA8c2hvd2Rvd24gdmFsdWU9XCIqKlNvbWUgYm9sZCB2YWx1ZSoqXCI+PC9zaG93ZG93bj5cbiAgICogYGBgXG4gICAqXG4gICAqIEJpbmQgcHJvcGVydHkgd2l0aCBtYXJrZG93biB2YWx1ZS5cbiAgICogYGBgaHRtbFxuICAgKiA8dGV4dGFyZWEgWyhuZ01vZGVsKV09XCJ0ZXh0XCI+PC90ZXh0YXJlYT5cbiAgICogPHNob3dkb3duIFt2YWx1ZV09XCJ0ZXh0XCI+PC9zaG93ZG93bj5cbiAgICogYGBgXG4gICAqL1xuICBASW5wdXQoKSB2YWx1ZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJbnB1dCBhbGlhcyB0byBgdmFsdWVgLlxuICAgKlxuICAgKiBfX0V4YW1wbGUgOl9fXG4gICAqXG4gICAqIGBgYGh0bWxcbiAgICogPGRpdiBbc2hvd2Rvd25dPVwiIyBTb21lIEhlYWRlclwiPjwvZGl2PlxuICAgKiBgYGBcbiAgICpcbiAgICogRXF1aXZhbGVudCB0b1xuICAgKiBgYGBodG1sXG4gICAqIDxzaG93ZG93biBbdmFsdWVdPVwiIyBTb21lIEhlYWRlclwiPjwvc2hvd2Rvd24+XG4gICAqIGBgYFxuICAgKi9cbiAgQElucHV0KCkgc2V0IHNob3dkb3duKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHNob3dkb3duIG9wdGlvbnMgb2YgdGhlIGNvbnZlcnRlci5cbiAgICpcbiAgICogX19FeGFtcGxlIDpfX1xuICAgKlxuICAgKiBCaW5kIG9wdGlvbnNcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbiAgICogaW1wb3J0ICogYXMgU2hvd2Rvd24gZnJvbSAnc2hvd2Rvd24nO1xuICAgKlxuICAgKiBAQ29tcG9uZW50KHtcbiAgICogICBzZWxlY3RvcjogYHNvbWVgLFxuICAgKiAgIHRlbXBsYXRlOiBgPHNob3dkb3duIFtvcHRpb25zXT1cIm9wdGlvbnNcIj4jIFNvbWUgSGVhZGVyPHNob3dkb3duPmBcbiAgICogfSlcbiAgICogZXhwb3J0IGNsYXNzIFNvbWVDb21wb25lbnQge1xuICAgKiAgIG9wdGlvbnM6IFNob3dkb3duLlNob3dkb3duT3B0aW9ucyA9IHtoZWFkZXJMZXZlbFN0YXJ0OiAzfTtcbiAgICogICAvLyAuLi5cbiAgICogfVxuICAgKiBgYGBcbiAgICogT3JcbiAgICogYGBgaHRtbFxuICAgKiA8c2hvd2Rvd24gW29wdGlvbnNdPVwie3NtYXJ0SW5kZW50YXRpb25GaXg6IHRydWV9XCI+ICMgSW5kZW50YXRpb24gRml4PHNob3dkb3duPlxuICAgKiBgYGBcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBvcHRpb25zKCk6IFNob3dkb3duLlNob3dkb3duT3B0aW9ucyB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T3B0aW9ucygpO1xuICB9XG5cbiAgc2V0IG9wdGlvbnMob3B0aW9uczogU2hvd2Rvd24uU2hvd2Rvd25PcHRpb25zKSB7XG4gICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2FuaXRpemU6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgaHRtbCBzYW5pdGl6ZSwgaXQgd2lsbCBzYW5pdGl6ZSB0aGUgY29udmVydGVyIGh0bWwgb3V0cHV0IGJ5IFtgRG9tU2FuaXRpemVyYF0oaHR0cHM6Ly9hbmd1bGFyLmlvL2FwaS9wbGF0Zm9ybS1icm93c2VyL0RvbVNhbml0aXplciNzYW5pdGl6ZSkuXG4gICAqXG4gICAqIF9fRXhhbXBsZSA6X19cbiAgICpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiBpbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbiAgICpcbiAgICogQENvbXBvbmVudCh7XG4gICAqICAgc2VsZWN0b3I6ICdzb21lJyxcbiAgICogICBzdHlsZXM6IFtgLmJveCB7IHdpZHRoOiA5NSU7IHBhZGRpbmc6IDVweDsgYm9yZGVyOiAxcHggc29saWQgYmxhY2s7fWBdLFxuICAgKiAgIHRlbXBsYXRlOiBgXG4gICAqICAgICA8aDM+SW5wdXQ8L2gzPlxuICAgKiAgICAgPHRleHRhcmVhIGNsYXNzPVwiYm94XCIgWyhuZ01vZGVsKV09XCJ0ZXh0XCI+PC90ZXh0YXJlYT5cbiAgICogICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInNhbml0aXplXCIvPiA8Yj5TYW5pdGl6ZTwvYj5cbiAgICogICAgIDxoMz5NYXJrZG93bjwvaDM+XG4gICAqICAgICA8cHJlIGNsYXNzPVwiYm94XCI+PGNvZGU+e3sgdGV4dCB9fTwvY29kZT48L3ByZT5cbiAgICogICAgIDxoMz5QcmV2aWV3PC9oMz5cbiAgICogICAgIDxkaXYgY2xhc3M9XCJib3hcIj5cbiAgICogICAgICAgPHNob3dkb3duICNzZCBbdmFsdWVdPVwidGV4dFwiIFtzYW5pdGl6ZV09XCJzYW5pdGl6ZVwiPjwvc2hvd2Rvd24+XG4gICAqICAgICA8L2Rpdj5cbiAgICogICBgO1xuICAgKiB9KVxuICAgKiBleHBvcnQgY2xhc3MgU29tZUNvbXBvbmVudCB7XG4gICAqICAgIHRleHQ6IHN0cmluZyA9IGAjIEEgY29vbCBsaW5rXG4gICAqIDxhIGhyZWY9XCJqYXZhc2NyaXB0OmFsZXJ0KCdIZWxsbyEnKVwiPmNsaWNrIG1lPC9hPmA7XG4gICAqIH1cbiAgICogYGBgXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgc2FuaXRpemUoc2FuaXRpemU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9zYW5pdGl6ZSA9IF90b09wdGlvbihzYW5pdGl6ZSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLCBAT3B0aW9uYWwoKSBwcml2YXRlIF9kb21TYW5pdGl6ZXI/OiBEb21TYW5pdGl6ZXIsIEBPcHRpb25hbCgpIGNvbmZpZz86IFNob3dkb3duQ29uZmlnKSB7XG4gICAgc3VwZXIoY29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIGFuZ3VsYXIgbGlmZWN5Y2xlIG1ldGhvZCwgVXNlIG9uIGluaXQgdG8gY2hlY2sgaWYgaXQgYGNvbnRlbnRgIHR5cGUgYW5kIGxvYWQgdGhlIGVsZW1lbnQgYGNvbnRlbnRgIHRvIGB2YWx1ZWAuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmFsdWUgPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MLnRyaW0oKSAhPT0gJycpIHtcbiAgICAgIHRoaXMucmVuZGVyKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5pbm5lckhUTUwpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBIGFuZ3VsYXIgbGlmZWN5Y2xlIG1ldGhvZCwgVXNlIHRvIGNhbGwgdG8gcmVuZGVyIG1ldGhvZCBhZnRlciBjaGFuZ2VzLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCB0aGUgbWFya2Rvd24gdmFsdWUgb2Yge0BsaW5rIFNob3dkb3duQ29tcG9uZW50I3ZhbHVlfSB0byBodG1sIGFuZCBzZXQgdGhlIGh0bWwgcmVzdWx0IHRvIHRoZSBlbGVtZW50IGNvbnRlbnQuXG4gICAqXG4gICAqIF9fRXhhbXBsZSA6X19cbiAgICpcbiAgICogYGBgaHRtbFxuICAgKiA8dGV4dGFyZWEgI3RleHRhcmVhIChjaGFuZ2UpPVwic2hvd2Rvd24ucmVuZGVyKHRleHRhcmVhLnZhbHVlKVwiLz4jIFNvbWUgSGVhZGVyPC90ZXh0YXJlYT5cbiAgICogPHNob3dkb3duICNzaG93ZG93bj48L3Nob3dkb3duPlxuICAgKiBgYGBcbiAgICogQHBhcmFtIHZhbHVlIC0gQSBtYXJrZG93biB2YWx1ZSB0byByZW5kZXIgKGl0IHdpbGwgb3ZlcnJpZGUgdGhlIGN1cnJlbnQgdmFsdWUgb2YgYFNob3dkb3duQ29tcG9uZW50I3ZhbHVlYClcbiAgICovXG4gIHB1YmxpYyByZW5kZXIodmFsdWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGxldCByZXN1bHQgPSB0aGlzLm1ha2VIdG1sKHRoaXMudmFsdWUpO1xuXG4gICAgICBpZiAodGhpcy5fc2FuaXRpemUpIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5fZG9tU2FuaXRpemVyLnNhbml0aXplKFNlY3VyaXR5Q29udGV4dC5IVE1MLCByZXN1bHQpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MID0gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG59XG5cbi8vIERlZmluZSBvcHRpb25zIHByb3BlcnRpZXMgc2V0dGVyIGZvciBhbmd1bGFyIGRpcmVjdGl2ZSBhbmQgZGlyZWN0IGFjY2Vzc1xuZm9yIChsZXQga2V5IG9mIE9QVElPTlNfUFJPUEVSVElFU19LRVlTKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTaG93ZG93bkNvbXBvbmVudC5wcm90b3R5cGUsIGtleSwge1xuICAgIHNldCh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgICB0aGlzLnNldE9wdGlvbihrZXksIF90b09wdGlvbih2YWx1ZSkpO1xuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufVxuIl19