@ngneat/transloco
Version:
The internationalization (i18n) library for Angular
134 lines • 17.6 kB
JavaScript
import { Inject, Injectable, InjectionToken, Injector, Optional, } 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('TRANSLOCO_TRANSPILER');
export class DefaultTranspiler {
interpolationMatcher;
constructor(config) {
this.interpolationMatcher = resolveMatcher(config ?? defaultConfig);
}
transpile(value, params = {}, translation, key) {
if (isString(value)) {
return value.replace(this.interpolationMatcher, (_, match) => {
match = match.trim();
if (isDefined(params[match])) {
return params[match];
}
return isDefined(translation[match])
? this.transpile(translation[match], params, translation, key)
: '';
});
}
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) => {
// get the value of "b.c" inside "a" => "Hello {{ value }}"
const v = getValue(result, p);
// get the params of "b.c" => { value: "Transloco" }
const getParams = getValue(params, p);
// transpile the value => "Hello Transloco"
const transpiled = this.transpile(v, getParams, translation, key);
// set "b.c" to `transpiled`
result = setValue(result, p, transpiled);
});
return result;
}
handleArray(value, params = {}, translation, key) {
return value.map((v) => this.transpile(v, params, translation, key));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler, deps: [{ token: TRANSLOCO_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: DefaultTranspiler, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [TRANSLOCO_CONFIG]
}] }]; } });
function resolveMatcher(config) {
const [start, end] = config.interpolation;
return new RegExp(`${start}(.*?)${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;
constructor(injector) {
super();
this.injector = injector;
}
transpile(value, params = {}, translation, key) {
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(transpiled, params, translation, key);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: FunctionalTranspiler, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: i0.Injector }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLnRyYW5zcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL3RyYW5zbG9jby9zcmMvbGliL3RyYW5zbG9jby50cmFuc3BpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxNQUFNLEVBQ04sVUFBVSxFQUNWLGNBQWMsRUFDZCxRQUFRLEVBQ1IsUUFBUSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzlFLE9BQU8sRUFDTCxhQUFhLEVBQ2IsZ0JBQWdCLEdBRWpCLE1BQU0sb0JBQW9CLENBQUM7O0FBRTVCLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLElBQUksY0FBYyxDQUNwRCxzQkFBc0IsQ0FDdkIsQ0FBQztBQWVGLE1BQU0sT0FBTyxpQkFBaUI7SUFDbEIsb0JBQW9CLENBQVM7SUFFdkMsWUFBa0QsTUFBd0I7UUFDeEUsSUFBSSxDQUFDLG9CQUFvQixHQUFHLGNBQWMsQ0FBQyxNQUFNLElBQUksYUFBYSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELFNBQVMsQ0FDUCxLQUFVLEVBQ1YsU0FBa0IsRUFBRSxFQUNwQixXQUF3QixFQUN4QixHQUFXO1FBRVgsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDbkIsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDM0QsS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDckIsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7b0JBQzVCLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUN0QjtnQkFFRCxPQUFPLFNBQVMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ2xDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLEdBQUcsQ0FBQztvQkFDOUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNULENBQUMsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLE1BQU0sRUFBRTtZQUNqQixJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDbkIsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7YUFDNUQ7aUJBQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUMvQixLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQzthQUMzRDtTQUNGO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BdUJHO0lBQ08sWUFBWSxDQUNwQixLQUFVLEVBQ1YsU0FBa0IsRUFBRSxFQUNwQixXQUF3QixFQUN4QixHQUFXO1FBRVgsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBRW5CLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDaEMsMkRBQTJEO1lBQzNELE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUIsb0RBQW9EO1lBQ3BELE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFFdEMsMkNBQTJDO1lBQzNDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFbEUsNEJBQTRCO1lBQzVCLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFUyxXQUFXLENBQ25CLEtBQWUsRUFDZixTQUFrQixFQUFFLEVBQ3BCLFdBQXdCLEVBQ3hCLEdBQVc7UUFFWCxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2RSxDQUFDO3VHQTFGVSxpQkFBaUIsa0JBR0ksZ0JBQWdCOzJHQUhyQyxpQkFBaUI7OzJGQUFqQixpQkFBaUI7a0JBRDdCLFVBQVU7OzBCQUlJLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsZ0JBQWdCOztBQTBGbEQsU0FBUyxjQUFjLENBQUMsTUFBdUI7SUFDN0MsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDO0lBRTFDLE9BQU8sSUFBSSxNQUFNLENBQUMsR0FBRyxLQUFLLFFBQVEsR0FBRyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQU1ELE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBa0I7SUFDaEQsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDekQsTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ3hDLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvQixPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUN2QyxDQUFDLEVBQUUsQ0FBQztZQUNKLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDaEQ7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ2xCO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBR0QsTUFBTSxPQUFPLG9CQUNYLFNBQVEsaUJBQWlCO0lBR0w7SUFBcEIsWUFBb0IsUUFBa0I7UUFDcEMsS0FBSyxFQUFFLENBQUM7UUFEVSxhQUFRLEdBQVIsUUFBUSxDQUFVO0lBRXRDLENBQUM7SUFFRCxTQUFTLENBQ1AsS0FBVSxFQUNWLFNBQWtCLEVBQUUsRUFDcEIsV0FBd0IsRUFDeEIsR0FBVztRQUVYLElBQUksVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNuQixVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FDeEIsNkJBQTZCLEVBQzdCLENBQUMsS0FBYSxFQUFFLFlBQW9CLEVBQUUsSUFBWSxFQUFFLEVBQUU7Z0JBQ3BELElBQUk7b0JBQ0YsTUFBTSxJQUFJLEdBQ1IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBRWxDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2lCQUNqRDtnQkFBQyxPQUFPLENBQU0sRUFBRTtvQkFDZixJQUFJLE9BQU8sR0FBRywwQkFBMEIsS0FBSzt3SEFDK0QsWUFBWSxjQUFjLENBQUM7b0JBQ3ZJLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsRUFBRTt3QkFDM0MsT0FBTyxHQUFHLHNCQUFzQixZQUFZLDJEQUEyRCxDQUFDO3FCQUN6RztvQkFDRCxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUMxQjtZQUNILENBQUMsQ0FDRixDQUFDO1NBQ0g7UUFFRCxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDL0QsQ0FBQzt1R0FyQ1Usb0JBQW9COzJHQUFwQixvQkFBb0I7OzJGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBJbmplY3QsXG4gIEluamVjdGFibGUsXG4gIEluamVjdGlvblRva2VuLFxuICBJbmplY3RvcixcbiAgT3B0aW9uYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBIYXNoTWFwLCBUcmFuc2xhdGlvbiB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0VmFsdWUsIGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzU3RyaW5nLCBzZXRWYWx1ZSB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQge1xuICBkZWZhdWx0Q29uZmlnLFxuICBUUkFOU0xPQ09fQ09ORklHLFxuICBUcmFuc2xvY29Db25maWcsXG59IGZyb20gJy4vdHJhbnNsb2NvLmNvbmZpZyc7XG5cbmV4cG9ydCBjb25zdCBUUkFOU0xPQ09fVFJBTlNQSUxFUiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxUcmFuc2xvY29UcmFuc3BpbGVyPihcbiAgJ1RSQU5TTE9DT19UUkFOU1BJTEVSJ1xuKTtcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xvY29UcmFuc3BpbGVyIHtcbiAgLy8gVE9ETzogQ2hhbmdlIHBhcmFtZXRlcnMgdG8gb2JqZWN0IGluIHRoZSBuZXh0IG1ham9yIHJlbGVhc2VcbiAgdHJhbnNwaWxlKFxuICAgIHZhbHVlOiBhbnksXG4gICAgcGFyYW1zOiBIYXNoTWFwLFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApOiBhbnk7XG5cbiAgb25MYW5nQ2hhbmdlZD8obGFuZzogc3RyaW5nKTogdm9pZDtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIERlZmF1bHRUcmFuc3BpbGVyIGltcGxlbWVudHMgVHJhbnNsb2NvVHJhbnNwaWxlciB7XG4gIHByb3RlY3RlZCBpbnRlcnBvbGF0aW9uTWF0Y2hlcjogUmVnRXhwO1xuXG4gIGNvbnN0cnVjdG9yKEBPcHRpb25hbCgpIEBJbmplY3QoVFJBTlNMT0NPX0NPTkZJRykgY29uZmlnPzogVHJhbnNsb2NvQ29uZmlnKSB7XG4gICAgdGhpcy5pbnRlcnBvbGF0aW9uTWF0Y2hlciA9IHJlc29sdmVNYXRjaGVyKGNvbmZpZyA/PyBkZWZhdWx0Q29uZmlnKTtcbiAgfVxuXG4gIHRyYW5zcGlsZShcbiAgICB2YWx1ZTogYW55LFxuICAgIHBhcmFtczogSGFzaE1hcCA9IHt9LFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApOiBhbnkge1xuICAgIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKHRoaXMuaW50ZXJwb2xhdGlvbk1hdGNoZXIsIChfLCBtYXRjaCkgPT4ge1xuICAgICAgICBtYXRjaCA9IG1hdGNoLnRyaW0oKTtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChwYXJhbXNbbWF0Y2hdKSkge1xuICAgICAgICAgIHJldHVybiBwYXJhbXNbbWF0Y2hdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZCh0cmFuc2xhdGlvblttYXRjaF0pXG4gICAgICAgICAgPyB0aGlzLnRyYW5zcGlsZSh0cmFuc2xhdGlvblttYXRjaF0sIHBhcmFtcywgdHJhbnNsYXRpb24sIGtleSlcbiAgICAgICAgICA6ICcnO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwYXJhbXMpIHtcbiAgICAgIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZU9iamVjdCh2YWx1ZSwgcGFyYW1zLCB0cmFuc2xhdGlvbiwga2V5KTtcbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmhhbmRsZUFycmF5KHZhbHVlLCBwYXJhbXMsIHRyYW5zbGF0aW9uLCBrZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBjb25zdCBlbiA9IHtcbiAgICogIGE6IHtcbiAgICogICAgYjoge1xuICAgKiAgICAgIGM6IFwiSGVsbG8ge3sgdmFsdWUgfX1cIlxuICAgKiAgICB9XG4gICAqICB9XG4gICAqIH1cbiAgICpcbiAgICogY29uc3QgcGFyYW1zID0gIHtcbiAgICogIFwiYi5jXCI6IHsgdmFsdWU6IFwiVHJhbnNsb2NvIFwifVxuICAgKiB9XG4gICAqXG4gICAqIHNlcnZpY2Uuc2VsZWN0VHJhbnNsYXRlKCdhJywgcGFyYW1zKTtcbiAgICpcbiAgICogLy8gdGhlIGZpcnN0IHBhcmFtIHdpbGwgYmUgdGhlIHJlc3VsdCBvZiBgZW4uYWAuXG4gICAqIC8vIHRoZSBzZWNvbmQgcGFyYW0gd2lsbCBiZSBgcGFyYW1zYC5cbiAgICogcGFyc2VyLnRyYW5zcGlsZSh2YWx1ZSwgcGFyYW1zLCB7fSk7XG4gICAqXG4gICAqXG4gICAqL1xuICBwcm90ZWN0ZWQgaGFuZGxlT2JqZWN0KFxuICAgIHZhbHVlOiBhbnksXG4gICAgcGFyYW1zOiBIYXNoTWFwID0ge30sXG4gICAgdHJhbnNsYXRpb246IFRyYW5zbGF0aW9uLFxuICAgIGtleTogc3RyaW5nXG4gICkge1xuICAgIGxldCByZXN1bHQgPSB2YWx1ZTtcblxuICAgIE9iamVjdC5rZXlzKHBhcmFtcykuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgLy8gZ2V0IHRoZSB2YWx1ZSBvZiBcImIuY1wiIGluc2lkZSBcImFcIiA9PiBcIkhlbGxvIHt7IHZhbHVlIH19XCJcbiAgICAgIGNvbnN0IHYgPSBnZXRWYWx1ZShyZXN1bHQsIHApO1xuICAgICAgLy8gZ2V0IHRoZSBwYXJhbXMgb2YgXCJiLmNcIiA9PiB7IHZhbHVlOiBcIlRyYW5zbG9jb1wiIH1cbiAgICAgIGNvbnN0IGdldFBhcmFtcyA9IGdldFZhbHVlKHBhcmFtcywgcCk7XG5cbiAgICAgIC8vIHRyYW5zcGlsZSB0aGUgdmFsdWUgPT4gXCJIZWxsbyBUcmFuc2xvY29cIlxuICAgICAgY29uc3QgdHJhbnNwaWxlZCA9IHRoaXMudHJhbnNwaWxlKHYsIGdldFBhcmFtcywgdHJhbnNsYXRpb24sIGtleSk7XG5cbiAgICAgIC8vIHNldCBcImIuY1wiIHRvIGB0cmFuc3BpbGVkYFxuICAgICAgcmVzdWx0ID0gc2V0VmFsdWUocmVzdWx0LCBwLCB0cmFuc3BpbGVkKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlQXJyYXkoXG4gICAgdmFsdWU6IHN0cmluZ1tdLFxuICAgIHBhcmFtczogSGFzaE1hcCA9IHt9LFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApIHtcbiAgICByZXR1cm4gdmFsdWUubWFwKCh2KSA9PiB0aGlzLnRyYW5zcGlsZSh2LCBwYXJhbXMsIHRyYW5zbGF0aW9uLCBrZXkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlTWF0Y2hlcihjb25maWc6IFRyYW5zbG9jb0NvbmZpZyk6IFJlZ0V4cCB7XG4gIGNvbnN0IFtzdGFydCwgZW5kXSA9IGNvbmZpZy5pbnRlcnBvbGF0aW9uO1xuXG4gIHJldHVybiBuZXcgUmVnRXhwKGAke3N0YXJ0fSguKj8pJHtlbmR9YCwgJ2cnKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xvY29UcmFuc3BpbGVyRnVuY3Rpb24ge1xuICB0cmFuc3BpbGUoLi4uYXJnczogc3RyaW5nW10pOiBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGdW5jdGlvbkFyZ3MoYXJnc1N0cmluZzogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCBzcGxpdHRlZCA9IGFyZ3NTdHJpbmcgPyBhcmdzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3QgYXJncyA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHNwbGl0dGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IHZhbHVlID0gc3BsaXR0ZWRbaV0udHJpbSgpO1xuICAgIHdoaWxlICh2YWx1ZVt2YWx1ZS5sZW5ndGggLSAxXSA9PT0gJ1xcXFwnKSB7XG4gICAgICBpKys7XG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoJ1xcXFwnLCAnLCcpICsgc3BsaXR0ZWRbaV07XG4gICAgfVxuICAgIGFyZ3MucHVzaCh2YWx1ZSk7XG4gIH1cblxuICByZXR1cm4gYXJncztcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uYWxUcmFuc3BpbGVyXG4gIGV4dGVuZHMgRGVmYXVsdFRyYW5zcGlsZXJcbiAgaW1wbGVtZW50cyBUcmFuc2xvY29UcmFuc3BpbGVyXG57XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIHRyYW5zcGlsZShcbiAgICB2YWx1ZTogYW55LFxuICAgIHBhcmFtczogSGFzaE1hcCA9IHt9LFxuICAgIHRyYW5zbGF0aW9uOiBUcmFuc2xhdGlvbixcbiAgICBrZXk6IHN0cmluZ1xuICApOiBhbnkge1xuICAgIGxldCB0cmFuc3BpbGVkID0gdmFsdWU7XG4gICAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgdHJhbnNwaWxlZCA9IHZhbHVlLnJlcGxhY2UoXG4gICAgICAgIC9cXFtcXFtcXHMqKFxcdyspXFwoKC4qPylcXClcXHMqXV0vZyxcbiAgICAgICAgKG1hdGNoOiBzdHJpbmcsIGZ1bmN0aW9uTmFtZTogc3RyaW5nLCBhcmdzOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZnVuYzogVHJhbnNsb2NvVHJhbnNwaWxlckZ1bmN0aW9uID1cbiAgICAgICAgICAgICAgdGhpcy5pbmplY3Rvci5nZXQoZnVuY3Rpb25OYW1lKTtcblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmMudHJhbnNwaWxlKC4uLmdldEZ1bmN0aW9uQXJncyhhcmdzKSk7XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGBUaGVyZSBpcyBhbiBlcnJvciBpbjogJyR7dmFsdWV9Jy4gXG4gICAgICAgICAgICAgICAgICAgICAgICAgIENoZWNrIHRoYXQgdGhlIHlvdSB1c2VkIHRoZSByaWdodCBzeW50YXggaW4geW91ciB0cmFuc2xhdGlvbiBhbmQgdGhhdCB0aGUgaW1wbGVtZW50YXRpb24gb2YgJHtmdW5jdGlvbk5hbWV9IGlzIGNvcnJlY3QuYDtcbiAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UuaW5jbHVkZXMoJ051bGxJbmplY3RvckVycm9yJykpIHtcbiAgICAgICAgICAgICAgbWVzc2FnZSA9IGBZb3UgYXJlIHVzaW5nIHRoZSAnJHtmdW5jdGlvbk5hbWV9JyBmdW5jdGlvbiBpbiB5b3VyIHRyYW5zbGF0aW9uIGJ1dCBubyBwcm92aWRlciB3YXMgZm91bmQhYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1cGVyLnRyYW5zcGlsZSh0cmFuc3BpbGVkLCBwYXJhbXMsIHRyYW5zbGF0aW9uLCBrZXkpO1xuICB9XG59XG4iXX0=