UNPKG

ngx-router-meta

Version:

Configure HTML meta tags in route configuration of Angular

134 lines 19.2 kB
import { Inject, Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { combineLatest, filter, isObservable, map, merge, of, shareReplay, startWith, Subject, } from 'rxjs'; import { ROUTE_META_CONFIG, unfoldContext, } from './router-meta'; import { escapeRegExp, isNavigationEndEvent } from './util'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; /** * Service to provide context for meta tags */ export class RouterMetaContextService { constructor(config, router) { this.config = config; this.router = router; this.ctxNameCache = {}; this.interpolation = this.config.interpolation || RouterMetaContextService.interpolation; this.interpolationStart = escapeRegExp(this.interpolation.start); this.interpolationEnd = escapeRegExp(this.interpolation.end); this.navigationEnd$ = this.router.events.pipe(filter(isNavigationEndEvent)); this.metaDefaultContext$$ = new Subject(); this.metaContext$$ = new Subject(); this.clearDefaultContext$ = new Subject(); this.clearContext$ = new Subject(); this.metaDefaultContext$ = this.clearDefaultContext$.pipe(startWith(null), unfoldContext(this.metaDefaultContext$$, (ctx) => this._processContext(ctx))); this.metaContext$ = merge(this.clearContext$, this.navigationEnd$).pipe(startWith(null), unfoldContext(this.metaContext$$, (ctx) => this._processContext(ctx))); this.context$ = combineLatest(this.metaDefaultContext$, this.metaContext$).pipe(map(([defaultCtx, ctx]) => ({ ...defaultCtx, ...ctx })), shareReplay()); } /** * Provided context will be available between router navigations * * Multiple contexts will be merged together */ provideDefaultContext(ctx) { this.metaDefaultContext$$.next(isObservable(ctx) ? ctx : of(ctx)); } /** * Provided context will be available ONLY until next router navigation * * Multiple contexts will be merged together * * If you want to persist context between navigations - * use {@link RouterMetaContextService#provideDefaultContext()} */ provideContext(ctx) { this.metaContext$$.next(isObservable(ctx) ? ctx : of(ctx)); } /** * Clear default context provided by * {@link RouterMetaContextService#provideDefaultContext()} */ clearDefaultContext() { this.clearDefaultContext$.next(); } /** * Clear context provided by * {@link RouterMetaContextService#provideContext()} */ clearContext() { this.clearContext$.next(); } /** * Observable of computed context for meta tags */ getContext() { return this.context$; } /** @internal */ _templateStr(str, data, extras) { if (!str || !data) { return str || ''; } let template = str; let ctx = data; if (extras) { template = extras.templates && extras.name ? extras.templates[extras.name] || template : template; ctx = { ...this.prepareContext(extras.meta, ctx), ...ctx }; // Recover lost `str` value under provided `extras.name` key in context if (extras.name && extras.name in ctx === false) { const nameCtx = this._processContext({ [extras.name]: str }); ctx = { ...ctx, ...this.prepareContext(nameCtx, ctx) }; } } return this.templateReplace(template, ctx); } /** @internal */ _processContext(ctx) { return Object.keys(ctx).reduce((acc, key) => ({ ...acc, [key]: { replace: this.getContextReplace(key), value: ctx[key], }, }), {}); } prepareContext(ctx, data) { if (!ctx || !data) { return ctx; } return Object.keys(ctx).reduce((c, key) => { c[key] = { ...ctx[key], value: this.templateReplace(ctx[key].value, data), }; return c; }, {}); } templateReplace(tpl, ctx) { return Object.keys(ctx).reduce((s, key) => s.replace(ctx[key].replace, ctx[key].value), tpl); } getContextReplace(name) { return name in this.ctxNameCache ? this.ctxNameCache[name] : (this.ctxNameCache[name] = new RegExp(`${this.interpolationStart}${escapeRegExp(name)}${this.interpolationEnd}`, 'g')); } } RouterMetaContextService.interpolation = { start: '{', end: '}', }; RouterMetaContextService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: RouterMetaContextService, deps: [{ token: ROUTE_META_CONFIG }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); RouterMetaContextService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: RouterMetaContextService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: RouterMetaContextService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [ROUTE_META_CONFIG] }] }, { type: i1.Router }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLW1ldGEtY29udGV4dC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXJvdXRlci1tZXRhL3NyYy9saWIvcm91dGVyLW1ldGEtY29udGV4dC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQ0wsYUFBYSxFQUNiLE1BQU0sRUFDTixZQUFZLEVBQ1osR0FBRyxFQUNILEtBQUssRUFFTCxFQUFFLEVBQ0YsV0FBVyxFQUNYLFNBQVMsRUFDVCxPQUFPLEdBQ1IsTUFBTSxNQUFNLENBQUM7QUFFZCxPQUFPLEVBS0wsaUJBQWlCLEVBQ2pCLGFBQWEsR0FDZCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sUUFBUSxDQUFDOzs7QUFXNUQ7O0dBRUc7QUFJSCxNQUFNLE9BQU8sd0JBQXdCO0lBOENuQyxZQUNxQyxNQUF3QixFQUNuRCxNQUFjO1FBRGEsV0FBTSxHQUFOLE1BQU0sQ0FBa0I7UUFDbkQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQTFDaEIsaUJBQVksR0FBc0IsRUFBRSxDQUFDO1FBRXJDLGtCQUFhLEdBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxJQUFJLHdCQUF3QixDQUFDLGFBQWEsQ0FBQztRQUM5RCx1QkFBa0IsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RCxxQkFBZ0IsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV4RCxtQkFBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FD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QyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBjb21iaW5lTGF0ZXN0LFxuICBmaWx0ZXIsXG4gIGlzT2JzZXJ2YWJsZSxcbiAgbWFwLFxuICBtZXJnZSxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YsXG4gIHNoYXJlUmVwbGF5LFxuICBzdGFydFdpdGgsXG4gIFN1YmplY3QsXG59IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1xuICBNZXRhQ29udGV4dCxcbiAgUm91dGVNZXRhVGVtcGxhdGVzLFxuICBSb3V0ZXJNZXRhQ29uZmlnLFxuICBSb3V0ZXJNZXRhSW50ZXJwb2xhdGlvbixcbiAgUk9VVEVfTUVUQV9DT05GSUcsXG4gIHVuZm9sZENvbnRleHQsXG59IGZyb20gJy4vcm91dGVyLW1ldGEnO1xuaW1wb3J0IHsgSW5kZXhhYmxlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBlc2NhcGVSZWdFeHAsIGlzTmF2aWdhdGlvbkVuZEV2ZW50IH0gZnJvbSAnLi91dGlsJztcblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXRhSW5mbyB7XG4gIHJlcGxhY2U6IFJlZ0V4cDtcbiAgdmFsdWU6IGFueTtcbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9jZXNzZWRNZXRhQ29udGV4dCBleHRlbmRzIEluZGV4YWJsZTxNZXRhSW5mbz4ge31cblxuLyoqXG4gKiBTZXJ2aWNlIHRvIHByb3ZpZGUgY29udGV4dCBmb3IgbWV0YSB0YWdzXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBSb3V0ZXJNZXRhQ29udGV4dFNlcnZpY2Uge1xuICBwcml2YXRlIHN0YXRpYyBpbnRlcnBvbGF0aW9uOiBSb3V0ZXJNZXRhSW50ZXJwb2xhdGlvbiA9IHtcbiAgICBzdGFydDogJ3snLFxuICAgIGVuZDogJ30nLFxuICB9O1xuXG4gIHByaXZhdGUgY3R4TmFtZUNhY2hlOiBJbmRleGFibGU8UmVnRXhwPiA9IHt9O1xuXG4gIHByaXZhdGUgaW50ZXJwb2xhdGlvbiA9XG4gICAgdGhpcy5jb25maWcuaW50ZXJwb2xhdGlvbiB8fCBSb3V0ZXJNZXRhQ29udGV4dFNlcnZpY2UuaW50ZXJwb2xhdGlvbjtcbiAgcHJpdmF0ZSBpbnRlcnBvbGF0aW9uU3RhcnQgPSBlc2NhcGVSZWdFeHAodGhpcy5pbnRlcnBvbGF0aW9uLnN0YXJ0KTtcbiAgcHJpdmF0ZSBpbnRlcnBvbGF0aW9uRW5kID0gZXNjYXBlUmVnRXhwKHRoaXMuaW50ZXJwb2xhdGlvbi5lbmQpO1xuXG4gIHByaXZhdGUgbmF2aWdhdGlvbkVuZCQgPSB0aGlzLnJvdXRlci5ldmVudHMucGlwZShcbiAgICBmaWx0ZXIoaXNOYXZpZ2F0aW9uRW5kRXZlbnQpLFxuICApO1xuXG4gIHByaXZhdGUgbWV0YURlZmF1bHRDb250ZXh0JCQgPSBuZXcgU3ViamVjdDxPYnNlcnZhYmxlPE1ldGFDb250ZXh0Pj4oKTtcbiAgcHJpdmF0ZSBtZXRhQ29udGV4dCQkID0gbmV3IFN1YmplY3Q8T2JzZXJ2YWJsZTxNZXRhQ29udGV4dD4+KCk7XG4gIHByaXZhdGUgY2xlYXJEZWZhdWx0Q29udGV4dCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIGNsZWFyQ29udGV4dCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHByaXZhdGUgbWV0YURlZmF1bHRDb250ZXh0JDogT2JzZXJ2YWJsZTxQcm9jZXNzZWRNZXRhQ29udGV4dD4gPVxuICAgIHRoaXMuY2xlYXJEZWZhdWx0Q29udGV4dCQucGlwZShcbiAgICAgIHN0YXJ0V2l0aChudWxsKSxcbiAgICAgIHVuZm9sZENvbnRleHQodGhpcy5tZXRhRGVmYXVsdENvbnRleHQkJCwgKGN0eCkgPT5cbiAgICAgICAgdGhpcy5fcHJvY2Vzc0NvbnRleHQoY3R4KSxcbiAgICAgICksXG4gICAgKTtcblxuICBwcml2YXRlIG1ldGFDb250ZXh0JDogT2JzZXJ2YWJsZTxQcm9jZXNzZWRNZXRhQ29udGV4dD4gPSBtZXJnZShcbiAgICB0aGlzLmNsZWFyQ29udGV4dCQsXG4gICAgdGhpcy5uYXZpZ2F0aW9uRW5kJCwgLy8gU3RhcnQgZnJlc2ggYWZ0ZXIgZXZlcnkgbmF2aWdhdGlvblxuICApLnBpcGUoXG4gICAgc3RhcnRXaXRoKG51bGwpLFxuICAgIHVuZm9sZENvbnRleHQodGhpcy5tZXRhQ29udGV4dCQkLCAoY3R4KSA9PiB0aGlzLl9wcm9jZXNzQ29udGV4dChjdHgpKSxcbiAgKTtcblxuICBwcml2YXRlIGNvbnRleHQkID0gY29tYmluZUxhdGVzdChcbiAgICB0aGlzLm1ldGFEZWZhdWx0Q29udGV4dCQsXG4gICAgdGhpcy5tZXRhQ29udGV4dCQsXG4gICkucGlwZShcbiAgICBtYXAoKFtkZWZhdWx0Q3R4LCBjdHhdKSA9PiAoeyAuLi5kZWZhdWx0Q3R4LCAuLi5jdHggfSkpLFxuICAgIHNoYXJlUmVwbGF5KCksXG4gICk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChST1VURV9NRVRBX0NPTkZJRykgcHJpdmF0ZSBjb25maWc6IFJvdXRlck1ldGFDb25maWcsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBQcm92aWRlZCBjb250ZXh0IHdpbGwgYmUgYXZhaWxhYmxlIGJldHdlZW4gcm91dGVyIG5hdmlnYXRpb25zXG4gICAqXG4gICAqIE11bHRpcGxlIGNvbnRleHRzIHdpbGwgYmUgbWVyZ2VkIHRvZ2V0aGVyXG4gICAqL1xuICBwcm92aWRlRGVmYXVsdENvbnRleHQoY3R4OiBNZXRhQ29udGV4dCB8IE9ic2VydmFibGU8TWV0YUNvbnRleHQ+KSB7XG4gICAgdGhpcy5tZXRhRGVmYXVsdENvbnRleHQkJC5uZXh0KGlzT2JzZXJ2YWJsZShjdHgpID8gY3R4IDogb2YoY3R4KSk7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZWQgY29udGV4dCB3aWxsIGJlIGF2YWlsYWJsZSBPTkxZIHVudGlsIG5leHQgcm91dGVyIG5hdmlnYXRpb25cbiAgICpcbiAgICogTXVsdGlwbGUgY29udGV4dHMgd2lsbCBiZSBtZXJnZWQgdG9nZXRoZXJcbiAgICpcbiAgICogSWYgeW91IHdhbnQgdG8gcGVyc2lzdCBjb250ZXh0IGJldHdlZW4gbmF2aWdhdGlvbnMgLVxuICAgKiB1c2Uge0BsaW5rIFJvdXRlck1ldGFDb250ZXh0U2VydmljZSNwcm92aWRlRGVmYXVsdENvbnRleHQoKX1cbiAgICovXG4gIHByb3ZpZGVDb250ZXh0KGN0eDogTWV0YUNvbnRleHQgfCBPYnNlcnZhYmxlPE1ldGFDb250ZXh0Pikge1xuICAgIHRoaXMubWV0YUNvbnRleHQkJC5uZXh0KGlzT2JzZXJ2YWJsZShjdHgpID8gY3R4IDogb2YoY3R4KSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgZGVmYXVsdCBjb250ZXh0IHByb3ZpZGVkIGJ5XG4gICAqIHtAbGluayBSb3V0ZXJNZXRhQ29udGV4dFNlcnZpY2UjcHJvdmlkZURlZmF1bHRDb250ZXh0KCl9XG4gICAqL1xuICBjbGVhckRlZmF1bHRDb250ZXh0KCkge1xuICAgIHRoaXMuY2xlYXJEZWZhdWx0Q29udGV4dCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGNvbnRleHQgcHJvdmlkZWQgYnlcbiAgICoge0BsaW5rIFJvdXRlck1ldGFDb250ZXh0U2VydmljZSNwcm92aWRlQ29udGV4dCgpfVxuICAgKi9cbiAgY2xlYXJDb250ZXh0KCkge1xuICAgIHRoaXMuY2xlYXJDb250ZXh0JC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogT2JzZXJ2YWJsZSBvZiBjb21wdXRlZCBjb250ZXh0IGZvciBtZXRhIHRhZ3NcbiAgICovXG4gIGdldENvbnRleHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGV4dCQ7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF90ZW1wbGF0ZVN0cihcbiAgICBzdHI/OiBzdHJpbmcsXG4gICAgZGF0YT86IFByb2Nlc3NlZE1ldGFDb250ZXh0LFxuICAgIGV4dHJhcz86IHtcbiAgICAgIG5hbWU/OiBzdHJpbmc7XG4gICAgICB0ZW1wbGF0ZXM/OiBSb3V0ZU1ldGFUZW1wbGF0ZXM7XG4gICAgICBtZXRhPzogUHJvY2Vzc2VkTWV0YUNvbnRleHQ7XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKCFzdHIgfHwgIWRhdGEpIHtcbiAgICAgIHJldHVybiBzdHIgfHwgJyc7XG4gICAgfVxuXG4gICAgbGV0IHRlbXBsYXRlID0gc3RyO1xuICAgIGxldCBjdHggPSBkYXRhO1xuXG4gICAgaWYgKGV4dHJhcykge1xuICAgICAgdGVtcGxhdGUgPVxuICAgICAgICBleHRyYXMudGVtcGxhdGVzICYmIGV4dHJhcy5uYW1lXG4gICAgICAgICAgPyBleHRyYXMudGVtcGxhdGVzW2V4dHJhcy5uYW1lXSB8fCB0ZW1wbGF0ZVxuICAgICAgICAgIDogdGVtcGxhdGU7XG4gICAgICBjdHggPSB7IC4uLnRoaXMucHJlcGFyZUNvbnRleHQoZXh0cmFzLm1ldGEsIGN0eCksIC4uLmN0eCB9O1xuXG4gICAgICAvLyBSZWNvdmVyIGxvc3QgYHN0cmAgdmFsdWUgdW5kZXIgcHJvdmlkZWQgYGV4dHJhcy5uYW1lYCBrZXkgaW4gY29udGV4dFxuICAgICAgaWYgKGV4dHJhcy5uYW1lICYmIGV4dHJhcy5uYW1lIGluIGN0eCA9PT0gZmFsc2UpIHtcbiAgICAgICAgY29uc3QgbmFtZUN0eCA9IHRoaXMuX3Byb2Nlc3NDb250ZXh0KHsgW2V4dHJhcy5uYW1lXTogc3RyIH0pO1xuICAgICAgICBjdHggPSB7IC4uLmN0eCwgLi4udGhpcy5wcmVwYXJlQ29udGV4dChuYW1lQ3R4LCBjdHgpIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudGVtcGxhdGVSZXBsYWNlKHRlbXBsYXRlLCBjdHgpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfcHJvY2Vzc0NvbnRleHQoY3R4OiBNZXRhQ29udGV4dCk6IFByb2Nlc3NlZE1ldGFDb250ZXh0IHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoY3R4KS5yZWR1Y2UoXG4gICAgICAoYWNjLCBrZXkpID0+ICh7XG4gICAgICAgIC4uLmFjYyxcbiAgICAgICAgW2tleV06IHtcbiAgICAgICAgICByZXBsYWNlOiB0aGlzLmdldENvbnRleHRSZXBsYWNlKGtleSksXG4gICAgICAgICAgdmFsdWU6IGN0eFtrZXldLFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgICB7fSBhcyBQcm9jZXNzZWRNZXRhQ29udGV4dCxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlQ29udGV4dChcbiAgICBjdHg/OiBQcm9jZXNzZWRNZXRhQ29udGV4dCxcbiAgICBkYXRhPzogUHJvY2Vzc2VkTWV0YUNvbnRleHQsXG4gICk6IFByb2Nlc3NlZE1ldGFDb250ZXh0IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWN0eCB8fCAhZGF0YSkge1xuICAgICAgcmV0dXJuIGN0eDtcbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoY3R4KS5yZWR1Y2UoKGMsIGtleSkgPT4ge1xuICAgICAgY1trZXldID0ge1xuICAgICAgICAuLi5jdHhba2V5XSxcbiAgICAgICAgdmFsdWU6IHRoaXMudGVtcGxhdGVSZXBsYWNlKGN0eFtrZXldLnZhbHVlLCBkYXRhKSxcbiAgICAgIH07XG4gICAgICByZXR1cm4gYztcbiAgICB9LCB7fSBhcyBQcm9jZXNzZWRNZXRhQ29udGV4dCk7XG4gIH1cblxuICBwcml2YXRlIHRlbXBsYXRlUmVwbGFjZSh0cGw6IHN0cmluZywgY3R4OiBQcm9jZXNzZWRNZXRhQ29udGV4dCkge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhjdHgpLnJlZHVjZShcbiAgICAgIChzLCBrZXkpID0+IHMucmVwbGFjZShjdHhba2V5XS5yZXBsYWNlLCBjdHhba2V5XS52YWx1ZSksXG4gICAgICB0cGwsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29udGV4dFJlcGxhY2UobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5hbWUgaW4gdGhpcy5jdHhOYW1lQ2FjaGVcbiAgICAgID8gdGhpcy5jdHhOYW1lQ2FjaGVbbmFtZV1cbiAgICAgIDogKHRoaXMuY3R4TmFtZUNhY2hlW25hbWVdID0gbmV3IFJlZ0V4cChcbiAgICAgICAgICBgJHt0aGlzLmludGVycG9sYXRpb25TdGFydH0ke2VzY2FwZVJlZ0V4cChuYW1lKX0ke1xuICAgICAgICAgICAgdGhpcy5pbnRlcnBvbGF0aW9uRW5kXG4gICAgICAgICAgfWAsXG4gICAgICAgICAgJ2cnLFxuICAgICAgICApKTtcbiAgfVxufVxuIl19