UNPKG

ngx-markdown

Version:

Angular library that uses marked to parse markdown to html combined with Prism.js for synthax highlights

468 lines (456 loc) 36.8 kB
import { Pipe, Inject, Injectable, Optional, PLATFORM_ID, SecurityContext, Component, ElementRef, EventEmitter, Input, Output, NgZone, NgModule } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { DomSanitizer } from '@angular/platform-browser'; import { parse, Renderer } from 'marked'; import { map, first } from 'rxjs/operators'; import { __spread, __extends } from 'tslib'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var LanguagePipe = /** @class */ (function () { function LanguagePipe() { } /** * @param {?} value * @param {?} language * @return {?} */ LanguagePipe.prototype.transform = /** * @param {?} value * @param {?} language * @return {?} */ function (value, language) { if (typeof value !== 'string') { console.error("LanguagePipe has been invoked with an invalid value type [" + value + "]"); return value; } if (typeof language !== 'string') { console.error("LanguagePipe has been invoked with an invalid parameter [" + language + "]"); return value; } return '```' + language + '\n' + value + '\n```'; }; LanguagePipe.decorators = [ { type: Pipe, args: [{ name: 'language', },] }, ]; return LanguagePipe; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var MarkedOptions = /** @class */ (function () { function MarkedOptions() { } return MarkedOptions; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ var errorSrcWithoutHttpClient = '[ngx-markdown] When using the [src] attribute you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information'; var MarkdownService = /** @class */ (function () { function MarkdownService(platform, http, domSanitizer, options) { this.platform = platform; this.http = http; this.domSanitizer = domSanitizer; this.options = options; if (!this.renderer) { this.renderer = new Renderer(); } } Object.defineProperty(MarkdownService.prototype, "renderer", { get: /** * @return {?} */ function () { return this.options.renderer; }, set: /** * @param {?} value * @return {?} */ function (value) { this.options.renderer = value; }, enumerable: true, configurable: true }); /** * @param {?} markdown * @param {?=} decodeHtml * @param {?=} markedOptions * @return {?} */ MarkdownService.prototype.compile = /** * @param {?} markdown * @param {?=} decodeHtml * @param {?=} markedOptions * @return {?} */ function (markdown, decodeHtml, markedOptions) { if (decodeHtml === void 0) { decodeHtml = false; } if (markedOptions === void 0) { markedOptions = this.options; } /** @type {?} */ var precompiled = this.precompile(markdown); /** @type {?} */ var compiled = parse(decodeHtml ? this.decodeHtml(precompiled) : precompiled, markedOptions); return markedOptions.sanitize && !markedOptions.sanitizer ? this.domSanitizer.sanitize(SecurityContext.HTML, compiled) : compiled; }; /** * @param {?} src * @return {?} */ MarkdownService.prototype.getSource = /** * @param {?} src * @return {?} */ function (src) { var _this = this; if (!this.http) { throw new Error(errorSrcWithoutHttpClient); } return this.http .get(src, { responseType: 'text' }) .pipe(map(function (markdown) { return _this.handleExtension(src, markdown); })); }; /** * @return {?} */ MarkdownService.prototype.highlight = /** * @return {?} */ function () { if (isPlatformBrowser(this.platform) && typeof Prism !== 'undefined') { Prism.highlightAll(false); } }; /** * @param {?} html * @return {?} */ MarkdownService.prototype.decodeHtml = /** * @param {?} html * @return {?} */ function (html) { if (isPlatformBrowser(this.platform)) { /** @type {?} */ var textarea = document.createElement('textarea'); textarea.innerHTML = html; return textarea.value; } return html; }; /** * @param {?} src * @param {?} markdown * @return {?} */ MarkdownService.prototype.handleExtension = /** * @param {?} src * @param {?} markdown * @return {?} */ function (src, markdown) { /** @type {?} */ var extension = src ? src.split('.').splice(-1).join() : null; return extension !== 'md' ? '```' + extension + '\n' + markdown + '\n```' : markdown; }; /** * @param {?} markdown * @return {?} */ MarkdownService.prototype.precompile = /** * @param {?} markdown * @return {?} */ function (markdown) { if (!markdown) { return ''; } /** @type {?} */ var indentStart; return markdown .split('\n') .map(function (line) { /** @type {?} */ var lineIdentStart = indentStart; // find position of 1st non-whitespace character // to determine the current line indentation start if (line.length > 0) { lineIdentStart = isNaN(lineIdentStart) ? line.search(/\S|$/) : Math.min(line.search(/\S|$/), lineIdentStart); } // keep 1st non-whitespace line indentation // as base reference for other lines if (isNaN(indentStart)) { indentStart = lineIdentStart; } // remove whitespaces before current line indentation return !!lineIdentStart ? line.substring(lineIdentStart) : line; }).join('\n'); }; MarkdownService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ MarkdownService.ctorParameters = function () { return [ { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }, { type: HttpClient, decorators: [{ type: Optional }] }, { type: DomSanitizer }, { type: MarkedOptions } ]; }; return MarkdownService; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var MarkdownComponent = /** @class */ (function () { function MarkdownComponent(element, markdownService) { this.element = element; this.markdownService = markdownService; this.error = new EventEmitter(); this.load = new EventEmitter(); } Object.defineProperty(MarkdownComponent.prototype, "_isTranscluded", { get: /** * @return {?} */ function () { return !this._data && !this._src; }, enumerable: true, configurable: true }); Object.defineProperty(MarkdownComponent.prototype, "data", { get: /** * @return {?} */ function () { return this._data; }, set: /** * @param {?} value * @return {?} */ function (value) { this._data = value; this.render(value); }, enumerable: true, configurable: true }); Object.defineProperty(MarkdownComponent.prototype, "src", { get: /** * @return {?} */ function () { return this._src; }, set: /** * @param {?} value * @return {?} */ function (value) { var _this = this; this._src = value; this.markdownService .getSource(value) .subscribe(function (markdown) { _this.render(markdown); _this.load.emit(markdown); }, function (error) { return _this.error.emit(error); }); }, enumerable: true, configurable: true }); /** * @return {?} */ MarkdownComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { if (this._isTranscluded) { this.render(this.element.nativeElement.innerHTML, true); } }; /** * @param {?} markdown * @param {?=} decodeHtml * @return {?} */ MarkdownComponent.prototype.render = /** * @param {?} markdown * @param {?=} decodeHtml * @return {?} */ function (markdown, decodeHtml) { if (decodeHtml === void 0) { decodeHtml = false; } this.element.nativeElement.innerHTML = this.markdownService.compile(markdown, decodeHtml); this.markdownService.highlight(); }; MarkdownComponent.decorators = [ { type: Component, args: [{ // tslint:disable-next-line:component-selector selector: 'markdown, [markdown]', template: '<ng-content></ng-content>', },] }, ]; /** @nocollapse */ MarkdownComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: MarkdownService } ]; }; MarkdownComponent.propDecorators = { data: [{ type: Input }], src: [{ type: Input }], error: [{ type: Output }], load: [{ type: Output }] }; return MarkdownComponent; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var MarkdownPipe = /** @class */ (function () { function MarkdownPipe(markdownService, zone) { this.markdownService = markdownService; this.zone = zone; } /** * @param {?} value * @return {?} */ MarkdownPipe.prototype.transform = /** * @param {?} value * @return {?} */ function (value) { var _this = this; if (typeof value !== 'string') { console.error("MarkdownPipe has been invoked with an invalid value type [" + value + "]"); return value; } /** @type {?} */ var markdown = this.markdownService.compile(value); this.zone.onStable .pipe(first()) .subscribe(function () { return _this.markdownService.highlight(); }); return markdown; }; MarkdownPipe.decorators = [ { type: Pipe, args: [{ name: 'markdown', },] }, ]; /** @nocollapse */ MarkdownPipe.ctorParameters = function () { return [ { type: MarkdownService }, { type: NgZone } ]; }; return MarkdownPipe; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ var initialMarkedOptions = { provide: MarkedOptions, useValue: { gfm: true, tables: true, breaks: false, pedantic: false, sanitize: false, smartLists: true, smartypants: false, }, }; /** @type {?} */ var sharedDeclarations = [ LanguagePipe, MarkdownComponent, MarkdownPipe, ]; var MarkdownModule = /** @class */ (function () { function MarkdownModule() { } /** * @param {?=} markdownModuleConfig * @return {?} */ MarkdownModule.forRoot = /** * @param {?=} markdownModuleConfig * @return {?} */ function (markdownModuleConfig) { return { ngModule: MarkdownModule, providers: __spread([ MarkdownService ], (markdownModuleConfig ? [ markdownModuleConfig.loader || [], markdownModuleConfig.markedOptions || initialMarkedOptions, ] : [initialMarkedOptions])), }; }; /** * @return {?} */ MarkdownModule.forChild = /** * @return {?} */ function () { return { ngModule: MarkdownModule, }; }; MarkdownModule.decorators = [ { type: NgModule, args: [{ exports: __spread(sharedDeclarations), declarations: __spread(sharedDeclarations), },] }, ]; return MarkdownModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var MarkedRenderer = /** @class */ (function (_super) { __extends(MarkedRenderer, _super); function MarkedRenderer() { return _super !== null && _super.apply(this, arguments) || this; } return MarkedRenderer; }(Renderer)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ export { LanguagePipe, MarkdownComponent, initialMarkedOptions, MarkdownModule, MarkdownPipe, errorSrcWithoutHttpClient, MarkdownService, MarkedOptions, MarkedRenderer }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1hcmtkb3duLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9uZ3gtbWFya2Rvd24vc3JjL2xhbmd1YWdlLnBpcGUudHMiLCJuZzovL25neC1tYXJrZG93bi9zcmMvbWFya2VkLW9wdGlvbnMudHMiLCJuZzovL25neC1tYXJrZG93bi9zcmMvbWFya2Rvd24uc2VydmljZS50cyIsIm5nOi8vbmd4LW1hcmtkb3duL3NyYy9tYXJrZG93bi5jb21wb25lbnQudHMiLCJuZzovL25neC1tYXJrZG93bi9zcmMvbWFya2Rvd24ucGlwZS50cyIsIm5nOi8vbmd4LW1hcmtkb3duL3NyYy9tYXJrZG93bi5tb2R1bGUudHMiLCJuZzovL25neC1tYXJrZG93bi9zcmMvbWFya2VkLXJlbmRlcmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbkBQaXBlKHtcclxuICBuYW1lOiAnbGFuZ3VhZ2UnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTGFuZ3VhZ2VQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XHJcblxyXG4gIHRyYW5zZm9ybSh2YWx1ZTogc3RyaW5nLCBsYW5ndWFnZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYExhbmd1YWdlUGlwZSBoYXMgYmVlbiBpbnZva2VkIHdpdGggYW4gaW52YWxpZCB2YWx1ZSB0eXBlIFske3ZhbHVlfV1gKTtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiBsYW5ndWFnZSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgTGFuZ3VhZ2VQaXBlIGhhcyBiZWVuIGludm9rZWQgd2l0aCBhbiBpbnZhbGlkIHBhcmFtZXRlciBbJHtsYW5ndWFnZX1dYCk7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiAnYGBgJyArIGxhbmd1YWdlICsgJ1xcbicgKyAgdmFsdWUgKyAnXFxuYGBgJztcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgUmVuZGVyZXIgfSBmcm9tICdtYXJrZWQnO1xyXG5cclxuZXhwb3J0IGNsYXNzIE1hcmtlZE9wdGlvbnMgaW1wbGVtZW50cyBtYXJrZWQuTWFya2VkT3B0aW9ucyB7XHJcbiAgLyoqXHJcbiAgICogQSBwcmVmaXggVVJMIGZvciBhbnkgcmVsYXRpdmUgbGluay5cclxuICAgKi9cclxuICBiYXNlVXJsPzogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBFbmFibGUgR0ZNIGxpbmUgYnJlYWtzLiBUaGlzIG9wdGlvbiByZXF1aXJlcyB0aGUgZ2ZtIG9wdGlvbiB0byBiZSB0cnVlLlxyXG4gICAqL1xyXG4gIGJyZWFrcz86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIEVuYWJsZSBHaXRIdWIgZmxhdm9yZWQgbWFya2Rvd24uXHJcbiAgICovXHJcbiAgZ2ZtPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogSW5jbHVkZSBhbiBpZCBhdHRyaWJ1dGUgd2hlbiBlbWl0dGluZyBoZWFkaW5ncy5cclxuICAgKi9cclxuICBoZWFkZXJJZHM/OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBTZXQgdGhlIHByZWZpeCBmb3IgaGVhZGVyIHRhZyBpZHMuXHJcbiAgICovXHJcbiAgaGVhZGVyUHJlZml4Pzogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBTZXQgdGhlIHByZWZpeCBmb3IgY29kZSBibG9jayBjbGFzc2VzLlxyXG4gICAqL1xyXG4gIGxhbmdQcmVmaXg/OiBzdHJpbmc7XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hbmdsZSBhdXRvbGlua3MgKDxlbWFpbEBkb21haW4uY29tPikuXHJcbiAgICovXHJcbiAgbWFuZ2xlPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogQ29uZm9ybSB0byBvYnNjdXJlIHBhcnRzIG9mIG1hcmtkb3duLnBsIGFzIG11Y2ggYXMgcG9zc2libGUuIERvbid0IGZpeCBhbnkgb2YgdGhlIG9yaWdpbmFsIG1hcmtkb3duIGJ1Z3Mgb3IgcG9vciBiZWhhdmlvci5cclxuICAgKi9cclxuICBwZWRhbnRpYz86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFR5cGU6IG9iamVjdCBEZWZhdWx0OiBuZXcgUmVuZGVyZXIoKVxyXG4gICAqXHJcbiAgICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgZnVuY3Rpb25zIHRvIHJlbmRlciB0b2tlbnMgdG8gSFRNTC5cclxuICAgKi9cclxuICByZW5kZXJlcj86IFJlbmRlcmVyO1xyXG5cclxuICAvKipcclxuICAgKiBTYW5pdGl6ZSB0aGUgb3V0cHV0LiBJZ25vcmUgYW55IEhUTUwgdGhhdCBoYXMgYmVlbiBpbnB1dC5cclxuICAgKi9cclxuICBzYW5pdGl6ZT86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIFNob3dzIGFuIEhUTUwgZXJyb3IgbWVzc2FnZSB3aGVuIHJlbmRlcmluZyBmYWlscy5cclxuICAgKi9cclxuICBzaWxlbnQ/OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBVc2Ugc21hcnRlciBsaXN0IGJlaGF2aW9yIHRoYW4gdGhlIG9yaWdpbmFsIG1hcmtkb3duLiBNYXkgZXZlbnR1YWxseSBiZSBkZWZhdWx0IHdpdGggdGhlIG9sZCBiZWhhdmlvciBtb3ZlZCBpbnRvIHBlZGFudGljLlxyXG4gICAqL1xyXG4gIHNtYXJ0TGlzdHM/OiBib29sZWFuO1xyXG5cclxuICAvKipcclxuICAgKiBVc2UgXCJzbWFydFwiIHR5cG9ncmFoaWMgcHVuY3R1YXRpb24gZm9yIHRoaW5ncyBsaWtlIHF1b3RlcyBhbmQgZGFzaGVzLlxyXG4gICAqL1xyXG4gIHNtYXJ0eXBhbnRzPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogRW5hYmxlIEdGTSB0YWJsZXMuIFRoaXMgb3B0aW9uIHJlcXVpcmVzIHRoZSBnZm0gb3B0aW9uIHRvIGJlIHRydWUuXHJcbiAgICovXHJcbiAgdGFibGVzPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqXHJcbiAgICogR2VuZXJhdGUgY2xvc2luZyBzbGFzaCBmb3Igc2VsZi1jbG9zaW5nIHRhZ3MgKDxici8+IGluc3RlYWQgb2YgPGJyPilcclxuICAgKi9cclxuICB4aHRtbD86IGJvb2xlYW47XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgZnVuY3Rpb24gdG8gaGlnaGxpZ2h0IGNvZGUgYmxvY2tzLiBUaGUgZnVuY3Rpb24gdGFrZXMgdGhyZWUgYXJndW1lbnRzOiBjb2RlLCBsYW5nLCBhbmQgY2FsbGJhY2suXHJcbiAgICovXHJcbiAgaGlnaGxpZ2h0Pyhjb2RlOiBzdHJpbmcsIGxhbmc6IHN0cmluZywgY2FsbGJhY2s/OiAoZXJyb3I6IGFueSB8IHVuZGVmaW5lZCwgY29kZTogc3RyaW5nKSA9PiB2b2lkKTogc3RyaW5nO1xyXG5cclxuICAvKipcclxuICAgKiBPcHRpb25hbGx5IHNhbml0aXplIGZvdW5kIEhUTUwgd2l0aCBhIHNhbml0aXplciBmdW5jdGlvbi5cclxuICAgKi9cclxuICBzYW5pdGl6ZXI/KGh0bWw6IHN0cmluZyk6IHN0cmluZztcclxufVxyXG4iLCJpbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgT3B0aW9uYWwsIFBMQVRGT1JNX0lELCBTZWN1cml0eUNvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcbmltcG9ydCB7IHBhcnNlLCBSZW5kZXJlciB9IGZyb20gJ21hcmtlZCc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgTWFya2VkT3B0aW9ucyB9IGZyb20gJy4vbWFya2VkLW9wdGlvbnMnO1xyXG5cclxuZGVjbGFyZSB2YXIgUHJpc206IHtcclxuICBoaWdobGlnaHRBbGw6IChhc3luYzogYm9vbGVhbikgPT4gdm9pZDtcclxufTtcclxuXHJcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcclxuZXhwb3J0IGNvbnN0IGVycm9yU3JjV2l0aG91dEh0dHBDbGllbnQgPSAnW25neC1tYXJrZG93bl0gV2hlbiB1c2luZyB0aGUgW3NyY10gYXR0cmlidXRlIHlvdSAqaGF2ZSB0byogcGFzcyB0aGUgYEh0dHBDbGllbnRgIGFzIGEgcGFyYW1ldGVyIG9mIHRoZSBgZm9yUm9vdGAgbWV0aG9kLiBTZWUgUkVBRE1FIGZvciBtb3JlIGluZm9ybWF0aW9uJztcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE1hcmtkb3duU2VydmljZSB7XHJcbiAgZ2V0IHJlbmRlcmVyKCk6IFJlbmRlcmVyIHsgcmV0dXJuIHRoaXMub3B0aW9ucy5yZW5kZXJlcjsgfVxyXG4gIHNldCByZW5kZXJlcih2YWx1ZTogbWFya2VkLlJlbmRlcmVyKSB7XHJcbiAgICB0aGlzLm9wdGlvbnMucmVuZGVyZXIgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybTogT2JqZWN0LFxyXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxyXG4gICAgcHJpdmF0ZSBkb21TYW5pdGl6ZXI6IERvbVNhbml0aXplcixcclxuICAgIHB1YmxpYyBvcHRpb25zOiBNYXJrZWRPcHRpb25zLFxyXG4gICkge1xyXG4gICAgaWYgKCF0aGlzLnJlbmRlcmVyKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIgPSBuZXcgUmVuZGVyZXIoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNvbXBpbGUobWFya2Rvd246IHN0cmluZywgZGVjb2RlSHRtbCA9IGZhbHNlLCBtYXJrZWRPcHRpb25zID0gdGhpcy5vcHRpb25zKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHByZWNvbXBpbGVkID0gdGhpcy5wcmVjb21waWxlKG1hcmtkb3duKTtcclxuICAgIGNvbnN0IGNvbXBpbGVkID0gcGFyc2UoXHJcbiAgICAgIGRlY29kZUh0bWwgPyB0aGlzLmRlY29kZUh0bWwocHJlY29tcGlsZWQpIDogcHJlY29tcGlsZWQsXHJcbiAgICAgIG1hcmtlZE9wdGlvbnMpO1xyXG4gICAgcmV0dXJuIG1hcmtlZE9wdGlvbnMuc2FuaXRpemUgJiYgIW1hcmtlZE9wdGlvbnMuc2FuaXRpemVyXHJcbiAgICAgID8gdGhpcy5kb21TYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LkhUTUwsIGNvbXBpbGVkKVxyXG4gICAgICA6IGNvbXBpbGVkO1xyXG4gIH1cclxuXHJcbiAgZ2V0U291cmNlKHNyYzogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcclxuICAgIGlmICghdGhpcy5odHRwKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvclNyY1dpdGhvdXRIdHRwQ2xpZW50KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLmh0dHBcclxuICAgICAgLmdldChzcmMsIHsgcmVzcG9uc2VUeXBlOiAndGV4dCcgfSlcclxuICAgICAgLnBpcGUobWFwKG1hcmtkb3duID0+IHRoaXMuaGFuZGxlRXh0ZW5zaW9uKHNyYywgbWFya2Rvd24pKSk7XHJcbiAgfVxyXG5cclxuICBoaWdobGlnaHQoKSB7XHJcbiAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybSkgJiYgdHlwZW9mIFByaXNtICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBQcmlzbS5oaWdobGlnaHRBbGwoZmFsc2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkZWNvZGVIdG1sKGh0bWw6IHN0cmluZykge1xyXG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm0pKSB7XHJcbiAgICAgIGNvbnN0IHRleHRhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcclxuICAgICAgdGV4dGFyZWEuaW5uZXJIVE1MID0gaHRtbDtcclxuICAgICAgcmV0dXJuIHRleHRhcmVhLnZhbHVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGh0bWw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhbmRsZUV4dGVuc2lvbihzcmM6IHN0cmluZywgbWFya2Rvd246IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBleHRlbnNpb24gPSBzcmNcclxuICAgICAgPyBzcmMuc3BsaXQoJy4nKS5zcGxpY2UoLTEpLmpvaW4oKVxyXG4gICAgICA6IG51bGw7XHJcbiAgICByZXR1cm4gZXh0ZW5zaW9uICE9PSAnbWQnXHJcbiAgICAgID8gJ2BgYCcgKyBleHRlbnNpb24gKyAnXFxuJyArIG1hcmtkb3duICsgJ1xcbmBgYCdcclxuICAgICAgOiBtYXJrZG93bjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcHJlY29tcGlsZShtYXJrZG93bjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmICghbWFya2Rvd24pIHtcclxuICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gICAgbGV0IGluZGVudFN0YXJ0OiBudW1iZXI7XHJcbiAgICByZXR1cm4gbWFya2Rvd25cclxuICAgICAgLnNwbGl0KCdcXG4nKVxyXG4gICAgICAubWFwKGxpbmUgPT4ge1xyXG4gICAgICAgIC8vIHNldCBjdXJyZW50IGxpbmUgaWRlbnQgc3RhcnQgdG8gYmFzZSByZWZlcmVuY2UgaW5kZW50YXRpb25cclxuICAgICAgICBsZXQgbGluZUlkZW50U3RhcnQgPSBpbmRlbnRTdGFydDtcclxuICAgICAgICAvLyBmaW5kIHBvc2l0aW9uIG9mIDFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJcclxuICAgICAgICAvLyB0byBkZXRlcm1pbmUgdGhlIGN1cnJlbnQgbGluZSBpbmRlbnRhdGlvbiBzdGFydFxyXG4gICAgICAgIGlmIChsaW5lLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGxpbmVJZGVudFN0YXJ0ID0gaXNOYU4obGluZUlkZW50U3RhcnQpXHJcbiAgICAgICAgICAgID8gbGluZS5zZWFyY2goL1xcU3wkLylcclxuICAgICAgICAgICAgOiBNYXRoLm1pbihsaW5lLnNlYXJjaCgvXFxTfCQvKSwgbGluZUlkZW50U3RhcnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBrZWVwIDFzdCBub24td2hpdGVzcGFjZSBsaW5lIGluZGVudGF0aW9uXHJcbiAgICAgICAgLy8gYXMgYmFzZSByZWZlcmVuY2UgZm9yIG90aGVyIGxpbmVzXHJcbiAgICAgICAgaWYgKGlzTmFOKGluZGVudFN0YXJ0KSkge1xyXG4gICAgICAgICAgaW5kZW50U3RhcnQgPSBsaW5lSWRlbnRTdGFydDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gcmVtb3ZlIHdoaXRlc3BhY2VzIGJlZm9yZSBjdXJyZW50IGxpbmUgaW5kZW50YXRpb25cclxuICAgICAgICByZXR1cm4gISFsaW5lSWRlbnRTdGFydFxyXG4gICAgICAgICAgPyBsaW5lLnN1YnN0cmluZyhsaW5lSWRlbnRTdGFydClcclxuICAgICAgICAgIDogbGluZTtcclxuICAgICAgfSkuam9pbignXFxuJyk7XHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBNYXJrZG93blNlcnZpY2UgfSBmcm9tICcuL21hcmtkb3duLnNlcnZpY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmNvbXBvbmVudC1zZWxlY3RvclxyXG4gIHNlbGVjdG9yOiAnbWFya2Rvd24sIFttYXJrZG93bl0nLFxyXG4gIHRlbXBsYXRlOiAnPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PicsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXJrZG93bkNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xyXG4gIHByaXZhdGUgX2RhdGE6IHN0cmluZztcclxuICBwcml2YXRlIF9zcmM6IHN0cmluZztcclxuXHJcbiAgcHJpdmF0ZSBnZXQgX2lzVHJhbnNjbHVkZWQoKSB7XHJcbiAgICByZXR1cm4gIXRoaXMuX2RhdGEgJiYgIXRoaXMuX3NyYztcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpXHJcbiAgZ2V0IGRhdGEoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX2RhdGE7IH1cclxuICBzZXQgZGF0YSh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICB0aGlzLl9kYXRhID0gdmFsdWU7XHJcbiAgICB0aGlzLnJlbmRlcih2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKVxyXG4gIGdldCBzcmMoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX3NyYzsgfVxyXG4gIHNldCBzcmModmFsdWU6IHN0cmluZykge1xyXG4gICAgdGhpcy5fc3JjID0gdmFsdWU7XHJcbiAgICB0aGlzLm1hcmtkb3duU2VydmljZVxyXG4gICAgICAuZ2V0U291cmNlKHZhbHVlKVxyXG4gICAgICAuc3Vic2NyaWJlKFxyXG4gICAgICAgIG1hcmtkb3duID0+IHtcclxuICAgICAgICAgIHRoaXMucmVuZGVyKG1hcmtkb3duKTtcclxuICAgICAgICAgIHRoaXMubG9hZC5lbWl0KG1hcmtkb3duKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVycm9yID0+IHRoaXMuZXJyb3IuZW1pdChlcnJvciksXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KCkgZXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBAT3V0cHV0KCkgbG9hZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHB1YmxpYyBlbGVtZW50OiBFbGVtZW50UmVmLFxyXG4gICAgcHVibGljIG1hcmtkb3duU2VydmljZTogTWFya2Rvd25TZXJ2aWNlLFxyXG4gICkgeyB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGlmICh0aGlzLl9pc1RyYW5zY2x1ZGVkKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyKHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVySFRNTCwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZW5kZXIobWFya2Rvd246IHN0cmluZywgZGVjb2RlSHRtbCA9IGZhbHNlKSB7XHJcbiAgICB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLm1hcmtkb3duU2VydmljZS5jb21waWxlKG1hcmtkb3duLCBkZWNvZGVIdG1sKTtcclxuICAgIHRoaXMubWFya2Rvd25TZXJ2aWNlLmhpZ2hsaWdodCgpO1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgeyBOZ1pvbmUsIFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZmlyc3QgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBNYXJrZG93blNlcnZpY2UgfSBmcm9tICcuL21hcmtkb3duLnNlcnZpY2UnO1xyXG5cclxuQFBpcGUoe1xyXG4gIG5hbWU6ICdtYXJrZG93bicsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXJrZG93blBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIG1hcmtkb3duU2VydmljZTogTWFya2Rvd25TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsXHJcbiAgKSB7IH1cclxuXHJcbiAgdHJhbnNmb3JtKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgY29uc29sZS5lcnJvcihgTWFya2Rvd25QaXBlIGhhcyBiZWVuIGludm9rZWQgd2l0aCBhbiBpbnZhbGlkIHZhbHVlIHR5cGUgWyR7dmFsdWV9XWApO1xyXG4gICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgbWFya2Rvd24gPSB0aGlzLm1hcmtkb3duU2VydmljZS5jb21waWxlKHZhbHVlKTtcclxuXHJcbiAgICB0aGlzLnpvbmUub25TdGFibGVcclxuICAgICAgLnBpcGUoZmlyc3QoKSlcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLm1hcmtkb3duU2VydmljZS5oaWdobGlnaHQoKSk7XHJcblxyXG4gICAgcmV0dXJuIG1hcmtkb3duO1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgeyBNb2R1bGVXaXRoUHJvdmlkZXJzLCBOZ01vZHVsZSwgUHJvdmlkZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IExhbmd1YWdlUGlwZSB9IGZyb20gJy4vbGFuZ3VhZ2UucGlwZSc7XHJcbmltcG9ydCB7IE1hcmtkb3duQ29tcG9uZW50IH0gZnJvbSAnLi9tYXJrZG93bi5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBNYXJrZG93blBpcGUgfSBmcm9tICcuL21hcmtkb3duLnBpcGUnO1xyXG5pbXBvcnQgeyBNYXJrZG93blNlcnZpY2UgfSBmcm9tICcuL21hcmtkb3duLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBNYXJrZWRPcHRpb25zIH0gZnJvbSAnLi9tYXJrZWQtb3B0aW9ucyc7XHJcblxyXG4vLyBoYXZpbmcgYSBkZXBlbmRlbmN5IG9uIGBIdHRwQ2xpZW50TW9kdWxlYCB3aXRoaW4gYSBsaWJyYXJ5XHJcbi8vIGJyZWFrcyBhbGwgdGhlIGludGVyY2VwdG9ycyBmcm9tIHRoZSBhcHAgY29uc3VtaW5nIHRoZSBsaWJyYXJ5XHJcbi8vIGhlcmUsIHdlIGV4cGxpY2l0ZWx5IGFzayB0aGUgdXNlciB0byBwYXNzIGEgcHJvdmlkZXIgd2l0aFxyXG4vLyB0aGVpciBvd24gaW5zdGFuY2Ugb2YgYEh0dHBDbGllbnRNb2R1bGVgXHJcbmV4cG9ydCBpbnRlcmZhY2UgTWFya2Rvd25Nb2R1bGVDb25maWcge1xyXG4gIGxvYWRlcj86IFByb3ZpZGVyO1xyXG4gIG1hcmtlZE9wdGlvbnM/OiBQcm92aWRlcjtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGluaXRpYWxNYXJrZWRPcHRpb25zOiBQcm92aWRlciA9IHtcclxuICBwcm92aWRlOiBNYXJrZWRPcHRpb25zLFxyXG4gIHVzZVZhbHVlOiB7XHJcbiAgICBnZm06IHRydWUsXHJcbiAgICB0YWJsZXM6IHRydWUsXHJcbiAgICBicmVha3M6IGZhbHNlLFxyXG4gICAgcGVkYW50aWM6IGZhbHNlLFxyXG4gICAgc2FuaXRpemU6IGZhbHNlLFxyXG4gICAgc21hcnRMaXN0czogdHJ1ZSxcclxuICAgIHNtYXJ0eXBhbnRzOiBmYWxzZSxcclxuICB9LFxyXG59O1xyXG5cclxuY29uc3Qgc2hhcmVkRGVjbGFyYXRpb25zID0gW1xyXG4gIExhbmd1YWdlUGlwZSxcclxuICBNYXJrZG93bkNvbXBvbmVudCxcclxuICBNYXJrZG93blBpcGUsXHJcbl07XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gIGV4cG9ydHM6IFtcclxuICAgIC4uLnNoYXJlZERlY2xhcmF0aW9ucyxcclxuICBdLFxyXG4gIGRlY2xhcmF0aW9uczogW1xyXG4gICAgLi4uc2hhcmVkRGVjbGFyYXRpb25zLFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXJrZG93bk1vZHVsZSB7XHJcbiAgc3RhdGljIGZvclJvb3QobWFya2Rvd25Nb2R1bGVDb25maWc/OiBNYXJrZG93bk1vZHVsZUNvbmZpZyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbmdNb2R1bGU6IE1hcmtkb3duTW9kdWxlLFxyXG4gICAgICBwcm92aWRlcnM6IFtcclxuICAgICAgICBNYXJrZG93blNlcnZpY2UsXHJcbiAgICAgICAgLi4uKG1hcmtkb3duTW9kdWxlQ29uZmlnXHJcbiAgICAgICAgICA/IFtcclxuICAgICAgICAgICAgICBtYXJrZG93bk1vZHVsZUNvbmZpZy5sb2FkZXIgfHwgW10sXHJcbiAgICAgICAgICAgICAgbWFya2Rvd25Nb2R1bGVDb25maWcubWFya2VkT3B0aW9ucyB8fCBpbml0aWFsTWFya2VkT3B0aW9ucyxcclxuICAgICAgICAgICAgXVxyXG4gICAgICAgICAgOiBbaW5pdGlhbE1hcmtlZE9wdGlvbnNdKSxcclxuICAgICAgXSxcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZm9yQ2hpbGQoKTogTW9kdWxlV2l0aFByb3ZpZGVycyB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBuZ01vZHVsZTogTWFya2Rvd25Nb2R1bGUsXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgeyBSZW5kZXJlciB9IGZyb20gJ21hcmtlZCc7XHJcblxyXG5leHBvcnQgY2xhc3MgTWFya2VkUmVuZGVyZXIgZXh0ZW5kcyBSZW5kZXJlciB7IH1cclxuIl0sIm5hbWVzIjpbInRzbGliXzEuX19leHRlbmRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7SUFPRSxnQ0FBUzs7Ozs7SUFBVCxVQUFVLEtBQWEsRUFBRSxRQUFnQjtRQUN2QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixPQUFPLENBQUMsS0FBSyxDQUFDLCtEQUE2RCxLQUFLLE1BQUcsQ0FBQyxDQUFDO1lBQ3JGLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsRUFBRTtZQUNoQyxPQUFPLENBQUMsS0FBSyxDQUFDLDhEQUE0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