UNPKG

@jsverse/transloco

Version:

The internationalization (i18n) library for Angular

148 lines 18.8 kB
import { inject, Injectable, InjectionToken, Injector } from '@angular/core'; import { getValue, isDefined, isObject, isString, setValue } from './helpers'; import { defaultConfig, TRANSLOCO_CONFIG, } from './transloco.config'; import * as i0 from "@angular/core"; export const TRANSLOCO_TRANSPILER = 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLnRyYW5zcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3RyYW5zbG9jby9zcmMvbGliL3RyYW5zbG9jby50cmFuc3BpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHN0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDOUUsT0FBTyxFQUNMLGFBQWEsRUFDYixnQkFBZ0IsR0FFakIsTUFBTSxvQkFBb0IsQ0FBQzs7QUFFNUIsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxjQUFjLENBQ3BELFNBQVMsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDeEMsQ0FBQztBQWdCRixNQUFNLE9BQU8saUJBQWlCO0lBQ2xCLE1BQU0sR0FDZCxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsSUFBSSxhQUFhLENBQUM7SUFFaEUsSUFBYyxvQkFBb0I7UUFDaEMsT0FBTyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUUsR0FBRyxFQUFtQjtRQUNqRSxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BCLElBQUksVUFBa0MsQ0FBQztZQUN2QyxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFFeEIsT0FDRSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEtBQUss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Q0FDeEIsNkJBQTZCLEVBQzdCLENBQUMsS0FBYSxFQUFFLFlBQW9CLEVBQUUsSUFBWSxFQUFFLEVBQUU7Z0JBQ3BELElBQUksQ0FBQztvQkFDSCxNQUFNLElBQUksR0FDUixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFFbEMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ2xELENBQUM7Z0JBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztvQkFDcEIsSUFBSSxPQUFPLEdBQUcsMEJBQTBCLEtBQUs7d0hBQytELFlBQVksY0FBYyxDQUFDO29CQUN2SSxJQUFLLENBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQzt3QkFDdkQsT0FBTyxHQUFHLHNCQUFzQixZQUFZLDJEQUEyRCxDQUFDO29CQUMxRyxDQUFDO29CQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzNCLENBQUM7WUFDSCxDQUFDLENBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO3VHQTlCVSxvQkFBb0I7MkdBQXBCLG9CQUFvQjs7MkZBQXBCLG9CQUFvQjtrQkFEaEMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIEluamVjdG9yIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEhhc2hNYXAsIFRyYW5zbGF0aW9uIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBnZXRWYWx1ZSwgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNTdHJpbmcsIHNldFZhbHVlIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7XG4gIGRlZmF1bHRDb25maWcsXG4gIFRSQU5TTE9DT19DT05GSUcsXG4gIFRyYW5zbG9jb0NvbmZpZyxcbn0gZnJvbSAnLi90cmFuc2xvY28uY29uZmlnJztcblxuZXhwb3J0IGNvbnN0IFRSQU5TTE9DT19UUkFOU1BJTEVSID0gbmV3IEluamVjdGlvblRva2VuPFRyYW5zbG9jb1RyYW5zcGlsZXI+KFxuICBuZ0Rldk1vZGUgPyAnVFJBTlNMT0NPX1RSQU5TUElMRVInIDogJycsXG4pO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbG9jb1RyYW5zcGlsZXIge1xuICB0cmFuc3BpbGUocGFyYW1zOiBUcmFuc3BpbGVQYXJhbXMpOiBhbnk7XG5cbiAgb25MYW5nQ2hhbmdlZD8obGFuZzogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc3BpbGVQYXJhbXM8ViA9IHVua25vd24+IHtcbiAgdmFsdWU6IFY7XG4gIHBhcmFtcz86IEhhc2hNYXA7XG4gIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbjtcbiAga2V5OiBzdHJpbmc7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZWZhdWx0VHJhbnNwaWxlciBpbXBsZW1lbnRzIFRyYW5zbG9jb1RyYW5zcGlsZXIge1xuICBwcm90ZWN0ZWQgY29uZmlnID1cbiAgICBpbmplY3QoVFJBTlNMT0NPX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KSA/PyBkZWZhdWx0Q29uZmlnO1xuXG4gIHByb3RlY3RlZCBnZXQgaW50ZXJwb2xhdGlvbk1hdGNoZXIoKSB7XG4gICAgcmV0dXJuIHJlc29sdmVNYXRjaGVyKHRoaXMuY29uZmlnKTtcbiAgfVxuXG4gIHRyYW5zcGlsZSh7IHZhbHVlLCBwYXJhbXMgPSB7fSwgdHJhbnNsYXRpb24sIGtleSB9OiBUcmFuc3BpbGVQYXJhbXMpOiBhbnkge1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIGxldCBwYXJhbU1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsO1xuICAgICAgbGV0IHBhcnNlZFZhbHVlID0gdmFsdWU7XG5cbiAgICAgIHdoaWxlIChcbiAgICAgICAgKHBhcmFtTWF0Y2ggPSB0aGlzLmludGVycG9sYXRpb25NYXRjaGVyLmV4ZWMocGFyc2VkVmFsdWUpKSAhPT0gbnVsbFxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IFttYXRjaCwgcGFyYW1WYWx1ZV0gPSBwYXJhbU1hdGNoO1xuICAgICAgICBwYXJzZWRWYWx1ZSA9IHBhcnNlZFZhbHVlLnJlcGxhY2UobWF0Y2gsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBtYXRjaCA9IHBhcmFtVmFsdWUudHJpbSgpO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW0gPSBnZXRWYWx1ZShwYXJhbXMsIG1hdGNoKTtcbiAgICAgICAgICBpZiAoaXNEZWZpbmVkKHBhcmFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcmFtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpc0RlZmluZWQodHJhbnNsYXRpb25bbWF0Y2hdKVxuICAgICAgICAgICAgPyB0aGlzLnRyYW5zcGlsZSh7XG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uLFxuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogdHJhbnNsYXRpb25bbWF0Y2hdLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgOiAnJztcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJzZWRWYWx1ZTtcbiAgICB9IGVsc2UgaWYgKHBhcmFtcykge1xuICAgICAgaWYgKGlzT2JqZWN0KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHRoaXMuaGFuZGxlT2JqZWN0KHtcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgdHJhbnNsYXRpb24sXG4gICAgICAgICAga2V5LFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZUFycmF5KHsgdmFsdWUsIHBhcmFtcywgdHJhbnNsYXRpb24sIGtleSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogY29uc3QgZW4gPSB7XG4gICAqICBhOiB7XG4gICAqICAgIGI6IHtcbiAgICogICAgICBjOiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICogICAgfVxuICAgKiAgfVxuICAgKiB9XG4gICAqXG4gICAqIGNvbnN0IHBhcmFtcyA9ICB7XG4gICAqICBcImIuY1wiOiB7IHZhbHVlOiBcIlRyYW5zbG9jbyBcIn1cbiAgICogfVxuICAgKlxuICAgKiBzZXJ2aWNlLnNlbGVjdFRyYW5zbGF0ZSgnYScsIHBhcmFtcyk7XG4gICAqXG4gICAqIC8vIHRoZSBmaXJzdCBwYXJhbSB3aWxsIGJlIHRoZSByZXN1bHQgb2YgYGVuLmFgLlxuICAgKiAvLyB0aGUgc2Vjb25kIHBhcmFtIHdpbGwgYmUgYHBhcmFtc2AuXG4gICAqIHBhcnNlci50cmFuc3BpbGUodmFsdWUsIHBhcmFtcywge30pO1xuICAgKlxuICAgKlxuICAgKi9cbiAgcHJvdGVjdGVkIGhhbmRsZU9iamVjdCh7XG4gICAgdmFsdWUsXG4gICAgcGFyYW1zID0ge30sXG4gICAgdHJhbnNsYXRpb24sXG4gICAga2V5LFxuICB9OiBUcmFuc3BpbGVQYXJhbXM8UmVjb3JkPGFueSwgYW55Pj4pIHtcbiAgICBsZXQgcmVzdWx0ID0gdmFsdWU7XG5cbiAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goKHApID0+IHtcbiAgICAgIC8vIHRyYW5zcGlsZSB0aGUgdmFsdWUgPT4gXCJIZWxsbyBUcmFuc2xvY29cIlxuICAgICAgY29uc3QgdHJhbnNwaWxlZCA9IHRoaXMudHJhbnNwaWxlKHtcbiAgICAgICAgLy8gZ2V0IHRoZSB2YWx1ZSBvZiBcImIuY1wiIGluc2lkZSBcImFcIiA9PiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICAgICAgdmFsdWU6IGdldFZhbHVlKHJlc3VsdCwgcCksXG4gICAgICAgIC8vIGdldCB0aGUgcGFyYW1zIG9mIFwiYi5jXCIgPT4geyB2YWx1ZTogXCJUcmFuc2xvY29cIiB9XG4gICAgICAgIHBhcmFtczogZ2V0VmFsdWUocGFyYW1zLCBwKSxcbiAgICAgICAgdHJhbnNsYXRpb24sXG4gICAgICAgIGtleSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBzZXQgXCJiLmNcIiB0byBgdHJhbnNwaWxlZGBcbiAgICAgIHJlc3VsdCA9IHNldFZhbHVlKHJlc3VsdCwgcCwgdHJhbnNwaWxlZCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZUFycmF5KHsgdmFsdWUsIC4uLnJlc3QgfTogVHJhbnNwaWxlUGFyYW1zPHVua25vd25bXT4pIHtcbiAgICByZXR1cm4gdmFsdWUubWFwKCh2KSA9PlxuICAgICAgdGhpcy50cmFuc3BpbGUoe1xuICAgICAgICB2YWx1ZTogdixcbiAgICAgICAgLi4ucmVzdCxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZU1hdGNoZXIoY29uZmlnOiBUcmFuc2xvY29Db25maWcpOiBSZWdFeHAge1xuICBjb25zdCBbc3RhcnQsIGVuZF0gPSBjb25maWcuaW50ZXJwb2xhdGlvbjtcblxuICByZXR1cm4gbmV3IFJlZ0V4cChgJHtzdGFydH0oW14ke3N0YXJ0fSR7ZW5kfV0qPykke2VuZH1gLCAnZycpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbG9jb1RyYW5zcGlsZXJGdW5jdGlvbiB7XG4gIHRyYW5zcGlsZSguLi5hcmdzOiBzdHJpbmdbXSk6IGFueTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uQXJncyhhcmdzU3RyaW5nOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHNwbGl0dGVkID0gYXJnc1N0cmluZyA/IGFyZ3NTdHJpbmcuc3BsaXQoJywnKSA6IFtdO1xuICBjb25zdCBhcmdzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc3BsaXR0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgdmFsdWUgPSBzcGxpdHRlZFtpXS50cmltKCk7XG4gICAgd2hpbGUgKHZhbHVlW3ZhbHVlLmxlbmd0aCAtIDFdID09PSAnXFxcXCcpIHtcbiAgICAgIGkrKztcbiAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgnXFxcXCcsICcsJykgKyBzcGxpdHRlZFtpXTtcbiAgICB9XG4gICAgYXJncy5wdXNoKHZhbHVlKTtcbiAgfVxuXG4gIHJldHVybiBhcmdzO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25hbFRyYW5zcGlsZXJcbiAgZXh0ZW5kcyBEZWZhdWx0VHJhbnNwaWxlclxuICBpbXBsZW1lbnRzIFRyYW5zbG9jb1RyYW5zcGlsZXJcbntcbiAgcHJvdGVjdGVkIGluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcblxuICB0cmFuc3BpbGUoeyB2YWx1ZSwgLi4ucmVzdCB9OiBUcmFuc3BpbGVQYXJhbXMpIHtcbiAgICBsZXQgdHJhbnNwaWxlZCA9IHZhbHVlO1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIHRyYW5zcGlsZWQgPSB2YWx1ZS5yZXBsYWNlKFxuICAgICAgICAvXFxbXFxbXFxzKihcXHcrKVxcKCguKj8pXFwpXFxzKl1dL2csXG4gICAgICAgIChtYXRjaDogc3RyaW5nLCBmdW5jdGlvbk5hbWU6IHN0cmluZywgYXJnczogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bmM6IFRyYW5zbG9jb1RyYW5zcGlsZXJGdW5jdGlvbiA9XG4gICAgICAgICAgICAgIHRoaXMuaW5qZWN0b3IuZ2V0KGZ1bmN0aW9uTmFtZSk7XG5cbiAgICAgICAgICAgIHJldHVybiBmdW5jLnRyYW5zcGlsZSguLi5nZXRGdW5jdGlvbkFyZ3MoYXJncykpO1xuICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYFRoZXJlIGlzIGFuIGVycm9yIGluOiAnJHt2YWx1ZX0nLiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQ2hlY2sgdGhhdCB0aGUgeW91IHVzZWQgdGhlIHJpZ2h0IHN5bnRheCBpbiB5b3VyIHRyYW5zbGF0aW9uIGFuZCB0aGF0IHRoZSBpbXBsZW1lbnRhdGlvbiBvZiAke2Z1bmN0aW9uTmFtZX0gaXMgY29ycmVjdC5gO1xuICAgICAgICAgICAgaWYgKChlIGFzIEVycm9yKS5tZXNzYWdlLmluY2x1ZGVzKCdOdWxsSW5qZWN0b3JFcnJvcicpKSB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UgPSBgWW91IGFyZSB1c2luZyB0aGUgJyR7ZnVuY3Rpb25OYW1lfScgZnVuY3Rpb24gaW4geW91ciB0cmFuc2xhdGlvbiBidXQgbm8gcHJvdmlkZXIgd2FzIGZvdW5kIWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwZXIudHJhbnNwaWxlKHsgdmFsdWU6IHRyYW5zcGlsZWQsIC4uLnJlc3QgfSk7XG4gIH1cbn1cbiJdfQ==