UNPKG

@jsverse/transloco

Version:

The internationalization (i18n) library for Angular

150 lines 19.1 kB
import { inject, Injectable, InjectionToken, Injector } from '@angular/core'; import { isDefined, isObject, isString } from '@jsverse/utils'; import { defaultConfig, TRANSLOCO_CONFIG, } from './transloco.config'; import { getValue, setValue } from './utils/object.utils'; import * as i0 from "@angular/core"; export const TRANSLOCO_TRANSPILER = /* @__PURE__ */ new InjectionToken(ngDevMode ? 'TRANSLOCO_TRANSPILER' : ''); export class DefaultTranspiler { config = inject(TRANSLOCO_CONFIG, { optional: true }) ?? defaultConfig; get interpolationMatcher() { return resolveMatcher(this.config); } transpile({ value, params = {}, translation, key }) { if (isString(value)) { let paramMatch; let parsedValue = value; while ((paramMatch = this.interpolationMatcher.exec(parsedValue)) !== null) { const [match, paramValue] = paramMatch; parsedValue = parsedValue.replace(match, () => { const match = paramValue.trim(); const param = getValue(params, match); if (isDefined(param)) { return param; } return isDefined(translation[match]) ? this.transpile({ params, translation, key, value: translation[match], }) : ''; }); } return parsedValue; } else if (params) { if (isObject(value)) { value = this.handleObject({ value, params, translation, key, }); } else if (Array.isArray(value)) { value = this.handleArray({ value, params, translation, key }); } } return value; } /** * * @example * * const en = { * a: { * b: { * c: "Hello {{ value }}" * } * } * } * * const params = { * "b.c": { value: "Transloco "} * } * * service.selectTranslate('a', params); * * // the first param will be the result of `en.a`. * // the second param will be `params`. * parser.transpile(value, params, {}); * * */ handleObject({ value, params = {}, translation, key, }) { let result = value; Object.keys(params).forEach((p) => { // transpile the value => "Hello Transloco" const transpiled = this.transpile({ // get the value of "b.c" inside "a" => "Hello {{ value }}" value: getValue(result, p), // get the params of "b.c" => { value: "Transloco" } params: getValue(params, p), translation, key, }); // set "b.c" to `transpiled` result = setValue(result, p, transpiled); }); return result; } handleArray({ value, ...rest }) { return value.map((v) => this.transpile({ value: v, ...rest, })); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DefaultTranspiler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DefaultTranspiler }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: DefaultTranspiler, decorators: [{ type: Injectable }] }); function resolveMatcher(config) { const [start, end] = config.interpolation; return new RegExp(`${start}([^${start}${end}]*?)${end}`, 'g'); } export function getFunctionArgs(argsString) { const splitted = argsString ? argsString.split(',') : []; const args = []; for (let i = 0; i < splitted.length; i++) { let value = splitted[i].trim(); while (value[value.length - 1] === '\\') { i++; value = value.replace('\\', ',') + splitted[i]; } args.push(value); } return args; } export class FunctionalTranspiler extends DefaultTranspiler { injector = inject(Injector); transpile({ value, ...rest }) { let transpiled = value; if (isString(value)) { transpiled = value.replace(/\[\[\s*(\w+)\((.*?)\)\s*]]/g, (match, functionName, args) => { try { const func = this.injector.get(functionName); return func.transpile(...getFunctionArgs(args)); } catch (e) { let message = `There is an error in: '${value}'. Check that the you used the right syntax in your translation and that the implementation of ${functionName} is correct.`; if (e.message.includes('NullInjectorError')) { message = `You are using the '${functionName}' function in your translation but no provider was found!`; } throw new Error(message); } }); } return super.transpile({ value: transpiled, ...rest }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FunctionalTranspiler, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FunctionalTranspiler }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: FunctionalTranspiler, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLnRyYW5zcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3RyYW5zbG9jby9zcmMvbGliL3RyYW5zbG9jby50cmFuc3BpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHL0QsT0FBTyxFQUNMLGFBQWEsRUFDYixnQkFBZ0IsR0FFakIsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLHNCQUFzQixDQUFDOztBQUUxRCxNQUFNLENBQUMsTUFBTSxvQkFBb0I7QUFDL0IsZUFBZSxDQUFDLElBQUksY0FBYyxDQUNoQyxTQUFTLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ3hDLENBQUM7QUFnQkosTUFBTSxPQUFPLGlCQUFpQjtJQUNsQixNQUFNLEdBQ2QsTUFBTSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLElBQUksYUFBYSxDQUFDO0lBRWhFLElBQWMsb0JBQW9CO1FBQ2hDLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sR0FBRyxFQUFFLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBbUI7UUFDakUsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNwQixJQUFJLFVBQWtDLENBQUM7WUFDdkMsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDO1lBRXhCLE9BQ0UsQ0FBQyxVQUFVLEdBQUcsSUFBSSxD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Q0FBQyxFQUFFLENBQUM7WUFDcEIsVUFBVSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQ3hCLDZCQUE2QixFQUM3QixDQUFDLEtBQWEsRUFBRSxZQUFvQixFQUFFLElBQVksRUFBRSxFQUFFO2dCQUNwRCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxJQUFJLEdBQ1IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBRWxDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUNsRCxDQUFDO2dCQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7b0JBQ3BCLElBQUksT0FBTyxHQUFHLDBCQUEwQixLQUFLO3dIQUMrRCxZQUFZLGNBQWMsQ0FBQztvQkFDdkksSUFBSyxDQUFXLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUM7d0JBQ3ZELE9BQU8sR0FBRyxzQkFBc0IsWUFBWSwyREFBMkQsQ0FBQztvQkFDMUcsQ0FBQztvQkFDRCxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMzQixDQUFDO1lBQ0gsQ0FBQyxDQUNGLENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUM7SUFDekQsQ0FBQzt1R0E5QlUsb0JBQW9COzJHQUFwQixvQkFBb0I7OzJGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tICdAanN2ZXJzZS91dGlscyc7XG5cbmltcG9ydCB7IFRyYW5zbGF0aW9uIH0gZnJvbSAnLi90cmFuc2xvY28udHlwZXMnO1xuaW1wb3J0IHtcbiAgZGVmYXVsdENvbmZpZyxcbiAgVFJBTlNMT0NPX0NPTkZJRyxcbiAgVHJhbnNsb2NvQ29uZmlnLFxufSBmcm9tICcuL3RyYW5zbG9jby5jb25maWcnO1xuaW1wb3J0IHsgSGFzaE1hcCB9IGZyb20gJy4vdXRpbHMvdHlwZS51dGlscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZSwgc2V0VmFsdWUgfSBmcm9tICcuL3V0aWxzL29iamVjdC51dGlscyc7XG5cbmV4cG9ydCBjb25zdCBUUkFOU0xPQ09fVFJBTlNQSUxFUiA9XG4gIC8qIEBfX1BVUkVfXyAqLyBuZXcgSW5qZWN0aW9uVG9rZW48VHJhbnNsb2NvVHJhbnNwaWxlcj4oXG4gICAgbmdEZXZNb2RlID8gJ1RSQU5TTE9DT19UUkFOU1BJTEVSJyA6ICcnLFxuICApO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbG9jb1RyYW5zcGlsZXIge1xuICB0cmFuc3BpbGUocGFyYW1zOiBUcmFuc3BpbGVQYXJhbXMpOiBhbnk7XG5cbiAgb25MYW5nQ2hhbmdlZD8obGFuZzogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc3BpbGVQYXJhbXM8ViA9IHVua25vd24+IHtcbiAgdmFsdWU6IFY7XG4gIHBhcmFtcz86IEhhc2hNYXA7XG4gIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbjtcbiAga2V5OiBzdHJpbmc7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZWZhdWx0VHJhbnNwaWxlciBpbXBsZW1lbnRzIFRyYW5zbG9jb1RyYW5zcGlsZXIge1xuICBwcm90ZWN0ZWQgY29uZmlnID1cbiAgICBpbmplY3QoVFJBTlNMT0NPX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KSA/PyBkZWZhdWx0Q29uZmlnO1xuXG4gIHByb3RlY3RlZCBnZXQgaW50ZXJwb2xhdGlvbk1hdGNoZXIoKSB7XG4gICAgcmV0dXJuIHJlc29sdmVNYXRjaGVyKHRoaXMuY29uZmlnKTtcbiAgfVxuXG4gIHRyYW5zcGlsZSh7IHZhbHVlLCBwYXJhbXMgPSB7fSwgdHJhbnNsYXRpb24sIGtleSB9OiBUcmFuc3BpbGVQYXJhbXMpOiBhbnkge1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIGxldCBwYXJhbU1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICAgICAgbGV0IHBhcnNlZFZhbHVlID0gdmFsdWU7XG5cbiAgICAgIHdoaWxlIChcbiAgICAgICAgKHBhcmFtTWF0Y2ggPSB0aGlzLmludGVycG9sYXRpb25NYXRjaGVyLmV4ZWMocGFyc2VkVmFsdWUpKSAhPT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IFttYXRjaCwgcGFyYW1WYWx1ZV0gPSBwYXJhbU1hdGNoO1xuICAgICAgICBwYXJzZWRWYWx1ZSA9IHBhcnNlZFZhbHVlLnJlcGxhY2UobWF0Y2gsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBtYXRjaCA9IHBhcmFtVmFsdWUudHJpbSgpO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW0gPSBnZXRWYWx1ZShwYXJhbXMsIG1hdGNoKTtcbiAgICAgICAgICBpZiAoaXNEZWZpbmVkKHBhcmFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcmFtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpc0RlZmluZWQodHJhbnNsYXRpb25bbWF0Y2hdKVxuICAgICAgICAgICAgPyB0aGlzLnRyYW5zcGlsZSh7XG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uLFxuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdHJhbnNsYXRpb25bbWF0Y2hdLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgOiAnJztcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZWRWYWx1ZTtcbiAgICB9IGVsc2UgaWYgKHBhcmFtcykge1xuICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHRoaXMuaGFuZGxlT2JqZWN0KHtcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgdHJhbnNsYXRpb24sXG4gICAgICAgICAga2V5LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZUFycmF5KHsgdmFsdWUsIHBhcmFtcywgdHJhbnNsYXRpb24sIGtleSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogY29uc3QgZW4gPSB7XG4gICAqICBhOiB7XG4gICAqICAgIGI6IHtcbiAgICogICAgICBjOiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICogICAgfVxuICAgKiAgfVxuICAgKiB9XG4gICAqXG4gICAqIGNvbnN0IHBhcmFtcyA9ICB7XG4gICAqICBcImIuY1wiOiB7IHZhbHVlOiBcIlRyYW5zbG9jbyBcIn1cbiAgICogfVxuICAgKlxuICAgKiBzZXJ2aWNlLnNlbGVjdFRyYW5zbGF0ZSgnYScsIHBhcmFtcyk7XG4gICAqXG4gICAqIC8vIHRoZSBmaXJzdCBwYXJhbSB3aWxsIGJlIHRoZSByZXN1bHQgb2YgYGVuLmFgLlxuICAgKiAvLyB0aGUgc2Vjb25kIHBhcmFtIHdpbGwgYmUgYHBhcmFtc2AuXG4gICAqIHBhcnNlci50cmFuc3BpbGUodmFsdWUsIHBhcmFtcywge30pO1xuICAgKlxuICAgKlxuICAgKi9cbiAgcHJvdGVjdGVkIGhhbmRsZU9iamVjdCh7XG4gICAgdmFsdWUsXG4gICAgcGFyYW1zID0ge30sXG4gICAgdHJhbnNsYXRpb24sXG4gICAga2V5LFxuICB9OiBUcmFuc3BpbGVQYXJhbXM8UmVjb3JkPGFueSwgYW55Pj4pIHtcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWU7XG5cbiAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goKHApID0+IHtcbiAgICAgIC8vIHRyYW5zcGlsZSB0aGUgdmFsdWUgPT4gXCJIZWxsbyBUcmFuc2xvY29cIlxuICAgICAgY29uc3QgdHJhbnNwaWxlZCA9IHRoaXMudHJhbnNwaWxlKHtcbiAgICAgICAgLy8gZ2V0IHRoZSB2YWx1ZSBvZiBcImIuY1wiIGluc2lkZSBcImFcIiA9PiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICAgICAgdmFsdWU6IGdldFZhbHVlKHJlc3VsdCwgcCksXG4gICAgICAgIC8vIGdldCB0aGUgcGFyYW1zIG9mIFwiYi5jXCIgPT4geyB2YWx1ZTogXCJUcmFuc2xvY29cIiB9XG4gICAgICAgIHBhcmFtczogZ2V0VmFsdWUocGFyYW1zLCBwKSxcbiAgICAgICAgdHJhbnNsYXRpb24sXG4gICAgICAgIGtleSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBzZXQgXCJiLmNcIiB0byBgdHJhbnNwaWxlZGBcbiAgICAgIHJlc3VsdCA9IHNldFZhbHVlKHJlc3VsdCwgcCwgdHJhbnNwaWxlZCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZUFycmF5KHsgdmFsdWUsIC4uLnJlc3QgfTogVHJhbnNwaWxlUGFyYW1zPHVua25vd25bXT4pIHtcbiAgICByZXR1cm4gdmFsdWUubWFwKCh2KSA9PlxuICAgICAgdGhpcy50cmFuc3BpbGUoe1xuICAgICAgICB2YWx1ZTogdixcbiAgICAgICAgLi4ucmVzdCxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZU1hdGNoZXIoY29uZmlnOiBUcmFuc2xvY29Db25maWcpOiBSZWdFeHAge1xuICBjb25zdCBbc3RhcnQsIGVuZF0gPSBjb25maWcuaW50ZXJwb2xhdGlvbjtcblxuICByZXR1cm4gbmV3IFJlZ0V4cChgJHtzdGFydH0oW14ke3N0YXJ0fSR7ZW5kfV0qPykke2VuZH1gLCAnZycpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbG9jb1RyYW5zcGlsZXJGdW5jdGlvbiB7XG4gIHRyYW5zcGlsZSguLi5hcmdzOiBzdHJpbmdbXSk6IGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uQXJncyhhcmdzU3RyaW5nOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHNwbGl0dGVkID0gYXJnc1N0cmluZyA/IGFyZ3NTdHJpbmcuc3BsaXQoJywnKSA6IFtdO1xuICBjb25zdCBhcmdzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3BsaXR0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgdmFsdWUgPSBzcGxpdHRlZFtpXS50cmltKCk7XG4gICAgd2hpbGUgKHZhbHVlW3ZhbHVlLmxlbmd0aCAtIDFdID09PSAnXFxcXCcpIHtcbiAgICAgIGkrKztcbiAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgnXFxcXCcsICcsJykgKyBzcGxpdHRlZFtpXTtcbiAgICB9XG4gICAgYXJncy5wdXNoKHZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiBhcmdzO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25hbFRyYW5zcGlsZXJcbiAgZXh0ZW5kcyBEZWZhdWx0VHJhbnNwaWxlclxuICBpbXBsZW1lbnRzIFRyYW5zbG9jb1RyYW5zcGlsZXJcbntcbiAgcHJvdGVjdGVkIGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuICB0cmFuc3BpbGUoeyB2YWx1ZSwgLi4ucmVzdCB9OiBUcmFuc3BpbGVQYXJhbXMpIHtcbiAgICBsZXQgdHJhbnNwaWxlZCA9IHZhbHVlO1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIHRyYW5zcGlsZWQgPSB2YWx1ZS5yZXBsYWNlKFxuICAgICAgICAvXFxbXFxbXFxzKihcXHcrKVxcKCguKj8pXFwpXFxzKl1dL2csXG4gICAgICAgIChtYXRjaDogc3RyaW5nLCBmdW5jdGlvbk5hbWU6IHN0cmluZywgYXJnczogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bmM6IFRyYW5zbG9jb1RyYW5zcGlsZXJGdW5jdGlvbiA9XG4gICAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IuZ2V0KGZ1bmN0aW9uTmFtZSk7XG5cbiAgICAgICAgICAgIHJldHVybiBmdW5jLnRyYW5zcGlsZSguLi5nZXRGdW5jdGlvbkFyZ3MoYXJncykpO1xuICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYFRoZXJlIGlzIGFuIGVycm9yIGluOiAnJHt2YWx1ZX0nLiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2sgdGhhdCB0aGUgeW91IHVzZWQgdGhlIHJpZ2h0IHN5bnRheCBpbiB5b3VyIHRyYW5zbGF0aW9uIGFuZCB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiAke2Z1bmN0aW9uTmFtZX0gaXMgY29ycmVjdC5gO1xuICAgICAgICAgICAgaWYgKChlIGFzIEVycm9yKS5tZXNzYWdlLmluY2x1ZGVzKCdOdWxsSW5qZWN0b3JFcnJvcicpKSB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UgPSBgWW91IGFyZSB1c2luZyB0aGUgJyR7ZnVuY3Rpb25OYW1lfScgZnVuY3Rpb24gaW4geW91ciB0cmFuc2xhdGlvbiBidXQgbm8gcHJvdmlkZXIgd2FzIGZvdW5kIWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwZXIudHJhbnNwaWxlKHsgdmFsdWU6IHRyYW5zcGlsZWQsIC4uLnJlc3QgfSk7XG4gIH1cbn1cbiJdfQ==