ngx-showdown
Version:
A Angular (>=2) integration for Showdown
280 lines • 22.1 kB
JavaScript
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