projen
Version:
CDK for software projects
224 lines • 32.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModuleImports = void 0;
exports.renderProjenInitOptions = renderProjenInitOptions;
exports.resolveInitProject = resolveInitProject;
exports.renderJavaScriptOptions = renderJavaScriptOptions;
const inventory = require("../inventory");
const option_hints_1 = require("../option-hints");
const PROJEN_NEW = "__new__";
const TAB = makePadding(2);
/**
* Renders options as if the project was created via `projen new` (embeds the __new__ field).
*/
function renderProjenInitOptions(fqn, args, comments = option_hints_1.InitProjectOptionHints.NONE) {
return {
...args,
[PROJEN_NEW]: { fqn, args, comments },
};
}
function resolveInitProject(opts) {
const f = opts[PROJEN_NEW];
if (!f) {
return undefined;
}
const type = inventory.resolveProjectType(f.fqn);
if (!type) {
throw new Error(`unable to resolve project type for ${f.fqn}`);
}
return {
args: f.args,
fqn: f.fqn,
type: type,
comments: f.comments,
};
}
class ModuleImports {
constructor() {
this.imports = new Map();
}
/**
* Add a named import from a module
*/
add(moduleName, importName) {
const moduleImports = this.imports.get(moduleName) ?? new Set();
moduleImports.add(importName);
this.imports.set(moduleName, moduleImports);
}
/**
* Get all named imports for a module
*/
get(moduleName) {
const moduleImports = this.imports.get(moduleName) ?? new Set();
return Array.from(moduleImports);
}
/**
* Get a list of all used modules
*/
get modules() {
return Array.from(this.imports.keys());
}
/**
* Return all imports as ESM import statements
*/
asEsmImports() {
return this.all().map(([moduleName, namedImports]) => `import { ${[...namedImports].join(", ")} } from "${moduleName}";`);
}
/**
* Return all imports as CJS require statements
*/
asCjsRequire() {
return this.all().map(([moduleName, namedImports]) => `const { ${[...namedImports].join(", ")} } = require("${moduleName}");`);
}
all() {
const allImports = Object.fromEntries(this.imports);
return Object.entries(allImports).map(([key, value]) => [
key,
Array.from(value).sort(),
]);
}
}
exports.ModuleImports = ModuleImports;
/**
* Prints all parameters that can be used in a project type, alongside their descriptions.
*
* Parameters in `params` that aren't undefined are rendered as defaults,
* while all other parameters are rendered as commented out.
*
* Returns the printed output and a set of required imports as an object
* in the form { options, imports }.
*/
function renderJavaScriptOptions(opts) {
const renders = {};
const optionsWithDefaults = [];
const allImports = new ModuleImports();
for (const option of opts.type.options) {
if (option.deprecated) {
continue;
}
const optionName = option.name;
if (opts.args[optionName] !== undefined) {
const arg = opts.args[optionName];
const { js, moduleName, importName } = renderArgAsJavaScript(arg, option);
renders[optionName] = `${optionName}: ${js},`;
optionsWithDefaults.push(optionName);
if (moduleName && importName) {
allImports.add(moduleName, importName);
if (opts.prefixImports) {
const prefix = `${opts.prefixImports}["${moduleName}"].`;
renders[optionName] = `${optionName}: ${prefix}${js},`;
}
}
}
else {
const defaultValue = option.default?.startsWith("-")
? undefined
: option.default ?? undefined;
renders[optionName] = `// ${optionName}: ${defaultValue},`;
}
}
const bootstrap = opts.bootstrap ?? false;
if (bootstrap) {
for (const arg of opts.omitFromBootstrap ?? []) {
delete opts.args[arg];
}
renders[PROJEN_NEW] = `${PROJEN_NEW}: ${JSON.stringify({
args: opts.args,
fqn: opts.type.fqn,
comments: opts.comments,
})},`;
optionsWithDefaults.push(PROJEN_NEW);
}
// generate rendering
const result = [];
result.push("{");
// render options with defaults
optionsWithDefaults.sort();
for (const optionName of optionsWithDefaults) {
result.push(`${TAB}${renders[optionName]}`);
}
if (result.length > 1) {
result.push("");
}
// render options without defaults as comments
if (opts.comments === option_hints_1.InitProjectOptionHints.ALL) {
const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined);
result.push(...renderCommentedOptionsByModule(renders, options));
}
else if (opts.comments === option_hints_1.InitProjectOptionHints.FEATURED) {
const options = opts.type.options.filter((opt) => !opt.deprecated && opts.args[opt.name] === undefined && opt.featured);
result.push(...renderCommentedOptionsInOrder(renders, options));
}
else if (opts.comments === option_hints_1.InitProjectOptionHints.NONE) {
// don't render any extra options
}
if (result[result.length - 1] === "") {
result.pop();
}
result.push("}");
return { renderedOptions: result.join("\n"), imports: allImports };
}
function renderCommentedOptionsByModule(renders, options) {
const optionsByModule = {};
for (const option of options) {
const parentModule = option.parent;
optionsByModule[parentModule] = optionsByModule[parentModule] ?? [];
optionsByModule[parentModule].push(option);
}
for (const parentModule in optionsByModule) {
optionsByModule[parentModule].sort((o1, o2) => o1.name.localeCompare(o2.name));
}
const result = [];
const marginSize = Math.max(...options.map((opt) => renders[opt.name].length));
for (const [moduleName, optionGroup] of Object.entries(optionsByModule).sort()) {
result.push(`${TAB}/* ${moduleName} */`);
for (const option of optionGroup) {
const paramRender = renders[option.name];
const docstring = option.docs || "No documentation found.";
result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`);
}
result.push("");
}
return result;
}
function renderCommentedOptionsInOrder(renders, options) {
const result = [];
const marginSize = Math.max(...options.map((opt) => renders[opt.name].length));
for (const option of options) {
const paramRender = renders[option.name];
const docstring = option.docs || "No documentation found.";
result.push(`${TAB}${paramRender}${makePadding(marginSize - paramRender.length + 2)}/* ${docstring} */`);
}
return result;
}
/**
* Renders a value as a JavaScript value, converting strings to enums where
* appropriate. The type must be JSON-like (string, number, boolean, array,
* enum, or JSON object).
*
* Returns a JavaScript expression as a string, and the names of any
* necessary imports.
*/
function renderArgAsJavaScript(arg, option) {
if (option.kind === "enum") {
if (!option.fqn) {
throw new Error(`fqn field is missing from enum option ${option.name}`);
}
const parts = option.fqn.split("."); // -> ['projen', 'web', 'MyEnum']
const enumChoice = String(arg).toUpperCase().replace(/-/g, "_"); // custom-value -> CUSTOM_VALUE
const js = `${parts.slice(1).join(".")}.${enumChoice}`; // -> web.MyEnum.CUSTOM_VALUE
const moduleName = parts[0]; // -> projen
const importName = parts[1]; // -> web
return { js, moduleName, importName };
}
else if (option.jsonLike) {
return { js: JSON.stringify(arg) };
}
else {
throw new Error(`Unexpected option ${option.name} - cannot render a value for this option because it does not have a JSON-like type.`);
}
}
function makePadding(paddingLength) {
return " ".repeat(paddingLength);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLW9wdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvamF2YXNjcmlwdC9yZW5kZXItb3B0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUEyRUEsMERBU0M7QUFFRCxnREFnQkM7QUFtRUQsMERBb0ZDO0FBN1BELDBDQUEwQztBQUMxQyxrREFBeUQ7QUFFekQsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDO0FBQzdCLE1BQU0sR0FBRyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQW9FM0I7O0dBRUc7QUFDSCxTQUFnQix1QkFBdUIsQ0FDckMsR0FBVyxFQUNYLElBQXlCLEVBQ3pCLFdBQW1DLHFDQUFzQixDQUFDLElBQUk7SUFFOUQsT0FBTztRQUNMLEdBQUcsSUFBSTtRQUNQLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBZ0I7S0FDcEQsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUFTO0lBQzFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQWUsQ0FBQztJQUN6QyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBQ0QsT0FBTztRQUNMLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSTtRQUNaLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRztRQUNWLElBQUksRUFBRSxJQUFJO1FBQ1YsUUFBUSxFQUFFLENBQUMsQ0FBQyxRQUFRO0tBQ3JCLENB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LEdBQUcsQ0FBQyxDQUFDLENBQUMsK0JBQStCO1FBQ2hHLE1BQU0sRUFBRSxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQyw2QkFBNkI7UUFDckYsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWTtRQUN6QyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3RDLE9BQU8sRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxDQUFDO0lBQ3hDLENBQUM7U0FBTSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMzQixPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUNyQyxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sSUFBSSxLQUFLLENBQ2IscUJBQXFCLE1BQU0sQ0FBQyxJQUFJLHFGQUFxRixDQUN0SCxDQUFDO0lBQ0osQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLFdBQVcsQ0FBQyxhQUFxQjtJQUN4QyxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDbkMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGludmVudG9yeSBmcm9tIFwiLi4vaW52ZW50b3J5XCI7XG5pbXBvcnQgeyBJbml0UHJvamVjdE9wdGlvbkhpbnRzIH0gZnJvbSBcIi4uL29wdGlvbi1oaW50c1wiO1xuXG5jb25zdCBQUk9KRU5fTkVXID0gXCJfX25ld19fXCI7XG5jb25zdCBUQUIgPSBtYWtlUGFkZGluZygyKTtcblxuLyoqXG4gKiBPcHRpb25zIGZvciBgcmVuZGVyUHJvamVjdE9wdGlvbnNgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbmRlclByb2plY3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBwcm9qZWN0IHR5cGUgdG8gcmVuZGVyLlxuICAgKi9cbiAgcmVhZG9ubHkgdHlwZTogaW52ZW50b3J5LlByb2plY3RUeXBlO1xuXG4gIC8qKlxuICAgKiBQcm9qZWN0IGFyZ3VtZW50cyBhcyBwYXNzZWQgdG8gYHByb2plbiBuZXdgLlxuICAgKi9cbiAgcmVhZG9ubHkgYXJnczogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAvKipcbiAgICogSW5jbHVkZSBjb21tZW50ZWQgb3V0IG9wdGlvbnMuXG4gICAqIEBkZWZhdWx0IEluaXRQcm9qZWN0T3B0aW9uSGludHMuRkVBVFVSRURcbiAgICovXG4gIHJlYWRvbmx5IGNvbW1lbnRzPzogSW5pdFByb2plY3RPcHRpb25IaW50cztcblxuICAvKipcbiAgICogSW5qZWN0IGEgYF9fbmV3X19gIGF0dHJpYnV0ZSB0byB0aGUgcHJvamVjdCBjb25zdHJ1Y3RvciB3aXRoIGEgc3RyaW5naWZpZWRcbiAgICogdmVyc2lvbiBvZiB0aGUgcHJvamVjdCBwYXJhbWV0ZXJzIGFuZCBhIGBqc2lpRnFuYCBhdHRyaWJ1dGUgdGhhdCBpbmNsdWRlc1xuICAgKiB0aGUgRlFOIG9mIHRoZSBwcm9qZWN0IHR5cGUuIFRoaXMgaXMgbmVlZGVkIGluIG9yZGVyIHRvIGdlbmVyYXRlIGluaXRpYWxcbiAgICogcHJvamVucmMgZmlsZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBib290c3RyYXA/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgZmllbGRzIHRvIG9taXQgZnJvbSB0aGUgaW5pdGlhbCBwcm9qZW5yYyBmaWxlLlxuICAgKiBAZGVmYXVsdCAtIG5vbmVcbiAgICovXG4gIHJlYWRvbmx5IG9taXRGcm9tQm9vdHN0cmFwPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFByZWZpeCBhbGwgaW1wb3J0cyB3aXRoIHRoaXMgc3RyaW5nIGFuZCB0aGUgZnVsbCBtb2R1bGUgbmFtZVxuICAgKiBUaGlzIGlzIHJlcXVpcmVkIHdoZW4gZXhlY3V0aW5nIG9wdGlvbnMgY29kZSBpbiBhIHZtXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gb25seSB1c2Ugc3VibW9kdWxlIGFzIHByZWZpeFxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4SW1wb3J0cz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBwYXNzZWQgZnJvbSBgcHJvamVuIG5ld2AgdG8gdGhlIHByb2plY3Qgb2JqZWN0IHdoZW4gdGhlIHByb2plY3RcbiAqIGlzIGZpcnN0IGNyZWF0ZWQuIEl0IGlzIHVzZWQgdG8gZ2VuZXJhdGUgcHJvamVucmMgZmlsZXMgaW4gdmFyaW91cyBsYW5ndWFnZXMuXG4gKi9cbmludGVyZmFjZSBQcm9qZW5Jbml0IHtcbiAgLyoqXG4gICAqIFRoZSBKU0lJIEZRTiBvZiB0aGUgcHJvamVjdCB0eXBlLlxuICAgKi9cbiAgcmVhZG9ubHkgZnFuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluaXRpYWwgYXJndW1lbnRzIHBhc3NlZCB0byBgcHJvamVuIG5ld2AuXG4gICAqL1xuICByZWFkb25seSBhcmdzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG4gIC8qKlxuICAgKiBJbmNsdWRlIGNvbW1lbnRlZCBvdXQgb3B0aW9ucy4gRG9lcyBub3QgYXBwbHkgdG8gcHJvamVucmMuanNvbiBmaWxlcy5cbiAgICovXG4gIHJlYWRvbmx5IGNvbW1lbnRzOiBJbml0UHJvamVjdE9wdGlvbkhpbnRzO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgb3B0aW9ucyBhcyBpZiB0aGUgcHJvamVjdCB3YXMgY3JlYXRlZCB2aWEgYHByb2plbiBuZXdgIChlbWJlZHMgdGhlIF9fbmV3X18gZmllbGQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyUHJvamVuSW5pdE9wdGlvbnMoXG4gIGZxbjogc3RyaW5nLFxuICBhcmdzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBjb21tZW50czogSW5pdFByb2plY3RPcHRpb25IaW50cyA9IEluaXRQcm9qZWN0T3B0aW9uSGludHMuTk9ORVxuKTogYW55IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5hcmdzLFxuICAgIFtQUk9KRU5fTkVXXTogeyBmcW4sIGFyZ3MsIGNvbW1lbnRzIH0gYXMgUHJvamVuSW5pdCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVJbml0UHJvamVjdChvcHRzOiBhbnkpIHtcbiAgY29uc3QgZiA9IG9wdHNbUFJPSkVOX05FV10gYXMgUHJvamVuSW5pdDtcbiAgaWYgKCFmKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHR5cGUgPSBpbnZlbnRvcnkucmVzb2x2ZVByb2plY3RUeXBlKGYuZnFuKTtcbiAgaWYgKCF0eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bmFibGUgdG8gcmVzb2x2ZSBwcm9qZWN0IHR5cGUgZm9yICR7Zi5mcW59YCk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBhcmdzOiBmLmFyZ3MsXG4gICAgZnFuOiBmLmZxbixcbiAgICB0eXBlOiB0eXBlLFxuICAgIGNvbW1lbnRzOiBmLmNvbW1lbnRzLFxuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgTW9kdWxlSW1wb3J0cyB7XG4gIHByaXZhdGUgaW1wb3J0czogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+ID0gbmV3IE1hcCgpO1xuXG4gIC8qKlxuICAgKiBBZGQgYSBuYW1lZCBpbXBvcnQgZnJvbSBhIG1vZHVsZVxuICAgKi9cbiAgcHVibGljIGFkZChtb2R1bGVOYW1lOiBzdHJpbmcsIGltcG9ydE5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IG1vZHVsZUltcG9ydHMgPSB0aGlzLmltcG9ydHMuZ2V0KG1vZHVsZU5hbWUpID8/IG5ldyBTZXQoKTtcbiAgICBtb2R1bGVJbXBvcnRzLmFkZChpbXBvcnROYW1lKTtcbiAgICB0aGlzLmltcG9ydHMuc2V0KG1vZHVsZU5hbWUsIG1vZHVsZUltcG9ydHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgbmFtZWQgaW1wb3J0cyBmb3IgYSBtb2R1bGVcbiAgICovXG4gIHB1YmxpYyBnZXQobW9kdWxlTmFtZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IG1vZHVsZUltcG9ydHMgPSB0aGlzLmltcG9ydHMuZ2V0KG1vZHVsZU5hbWUpID8/IG5ldyBTZXQoKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShtb2R1bGVJbXBvcnRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBsaXN0IG9mIGFsbCB1c2VkIG1vZHVsZXNcbiAgICovXG4gIHB1YmxpYyBnZXQgbW9kdWxlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5pbXBvcnRzLmtleXMoKSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFsbCBpbXBvcnRzIGFzIEVTTSBpbXBvcnQgc3RhdGVtZW50c1xuICAgKi9cbiAgcHVibGljIGFzRXNtSW1wb3J0cygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkubWFwKFxuICAgICAgKFttb2R1bGVOYW1lLCBuYW1lZEltcG9ydHNdKSA9PlxuICAgICAgICBgaW1wb3J0IHsgJHtbLi4ubmFtZWRJbXBvcnRzXS5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7bW9kdWxlTmFtZX1cIjtgXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYWxsIGltcG9ydHMgYXMgQ0pTIHJlcXVpcmUgc3RhdGVtZW50c1xuICAgKi9cbiAgcHVibGljIGFzQ2pzUmVxdWlyZSgpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkubWFwKFxuICAgICAgKFttb2R1bGVOYW1lLCBuYW1lZEltcG9ydHNdKSA9PlxuICAgICAgICBgY29uc3QgeyAke1suLi5uYW1lZEltcG9ydHNdLmpvaW4oXCIsIFwiKX0gfSA9IHJlcXVpcmUoXCIke21vZHVsZU5hbWV9XCIpO2BcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhbGwoKTogQXJyYXk8W3N0cmluZywgc3RyaW5nW11dPiB7XG4gICAgY29uc3QgYWxsSW1wb3J0cyA9IE9iamVjdC5mcm9tRW50cmllcyh0aGlzLmltcG9ydHMpO1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhhbGxJbXBvcnRzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gW1xuICAgICAga2V5LFxuICAgICAgQXJyYXkuZnJvbSh2YWx1ZSkuc29ydCgpLFxuICAgIF0pO1xuICB9XG59XG5cbi8qKlxuICogUHJpbnRzIGFsbCBwYXJhbWV0ZXJzIHRoYXQgY2FuIGJlIHVzZWQgaW4gYSBwcm9qZWN0IHR5cGUsIGFsb25nc2lkZSB0aGVpciBkZXNjcmlwdGlvbnMuXG4gKlxuICogUGFyYW1ldGVycyBpbiBgcGFyYW1zYCB0aGF0IGFyZW4ndCB1bmRlZmluZWQgYXJlIHJlbmRlcmVkIGFzIGRlZmF1bHRzLFxuICogd2hpbGUgYWxsIG90aGVyIHBhcmFtZXRlcnMgYXJlIHJlbmRlcmVkIGFzIGNvbW1lbnRlZCBvdXQuXG4gKlxuICogUmV0dXJucyB0aGUgcHJpbnRlZCBvdXRwdXQgYW5kIGEgc2V0IG9mIHJlcXVpcmVkIGltcG9ydHMgYXMgYW4gb2JqZWN0XG4gKiBpbiB0aGUgZm9ybSB7IG9wdGlvbnMsIGltcG9ydHMgfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckphdmFTY3JpcHRPcHRpb25zKG9wdHM6IFJlbmRlclByb2plY3RPcHRpb25zKToge1xuICByZW5kZXJlZE9wdGlvbnM6IHN0cmluZztcbiAgaW1wb3J0czogTW9kdWxlSW1wb3J0cztcbn0ge1xuICBjb25zdCByZW5kZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIGNvbnN0IG9wdGlvbnNXaXRoRGVmYXVsdHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGFsbEltcG9ydHMgPSBuZXcgTW9kdWxlSW1wb3J0cygpO1xuXG4gIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdHMudHlwZS5vcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbi5kZXByZWNhdGVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25OYW1lID0gb3B0aW9uLm5hbWU7XG5cbiAgICBpZiAob3B0cy5hcmdzW29wdGlvbk5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGFyZyA9IG9wdHMuYXJnc1tvcHRpb25OYW1lXTtcbiAgICAgIGNvbnN0IHsganMsIG1vZHVsZU5hbWUsIGltcG9ydE5hbWUgfSA9IHJlbmRlckFyZ0FzSmF2YVNjcmlwdChhcmcsIG9wdGlvbik7XG5cbiAgICAgIHJlbmRlcnNbb3B0aW9uTmFtZV0gPSBgJHtvcHRpb25OYW1lfTogJHtqc30sYDtcbiAgICAgIG9wdGlvbnNXaXRoRGVmYXVsdHMucHVzaChvcHRpb25OYW1lKTtcblxuICAgICAgaWYgKG1vZHVsZU5hbWUgJiYgaW1wb3J0TmFtZSkge1xuICAgICAgICBhbGxJbXBvcnRzLmFkZChtb2R1bGVOYW1lLCBpbXBvcnROYW1lKTtcbiAgICAgICAgaWYgKG9wdHMucHJlZml4SW1wb3J0cykge1xuICAgICAgICAgIGNvbnN0IHByZWZpeCA9IGAke29wdHMucHJlZml4SW1wb3J0c31bXCIke21vZHVsZU5hbWV9XCJdLmA7XG4gICAgICAgICAgcmVuZGVyc1tvcHRpb25OYW1lXSA9IGAke29wdGlvbk5hbWV9OiAke3ByZWZpeH0ke2pzfSxgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IG9wdGlvbi5kZWZhdWx0Py5zdGFydHNXaXRoKFwiLVwiKVxuICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICA6IG9wdGlvbi5kZWZhdWx0ID8/IHVuZGVmaW5lZDtcbiAgICAgIHJlbmRlcnNbb3B0aW9uTmFtZV0gPSBgLy8gJHtvcHRpb25OYW1lfTogJHtkZWZhdWx0VmFsdWV9LGA7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgYm9vdHN0cmFwID0gb3B0cy5ib290c3RyYXAgPz8gZmFsc2U7XG4gIGlmIChib290c3RyYXApIHtcbiAgICBmb3IgKGNvbnN0IGFyZyBvZiBvcHRzLm9taXRGcm9tQm9vdHN0cmFwID8/IFtdKSB7XG4gICAgICBkZWxldGUgb3B0cy5hcmdzW2FyZ107XG4gICAgfVxuICAgIHJlbmRlcnNbUFJPSkVOX05FV10gPSBgJHtQUk9KRU5fTkVXfTogJHtKU09OLnN0cmluZ2lmeSh7XG4gICAgICBhcmdzOiBvcHRzLmFyZ3MsXG4gICAgICBmcW46IG9wdHMudHlwZS5mcW4sXG4gICAgICBjb21tZW50czogb3B0cy5jb21tZW50cyxcbiAgICB9IGFzIFByb2plbkluaXQpfSxgO1xuICAgIG9wdGlvbnNXaXRoRGVmYXVsdHMucHVzaChQUk9KRU5fTkVXKTtcbiAgfVxuXG4gIC8vIGdlbmVyYXRlIHJlbmRlcmluZ1xuICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG4gIHJlc3VsdC5wdXNoKFwie1wiKTtcblxuICAvLyByZW5kZXIgb3B0aW9ucyB3aXRoIGRlZmF1bHRzXG4gIG9wdGlvbnNXaXRoRGVmYXVsdHMuc29ydCgpO1xuICBmb3IgKGNvbnN0IG9wdGlvbk5hbWUgb2Ygb3B0aW9uc1dpdGhEZWZhdWx0cykge1xuICAgIHJlc3VsdC5wdXNoKGAke1RBQn0ke3JlbmRlcnNbb3B0aW9uTmFtZV19YCk7XG4gIH1cbiAgaWYgKHJlc3VsdC5sZW5ndGggPiAxKSB7XG4gICAgcmVzdWx0LnB1c2goXCJcIik7XG4gIH1cblxuICAvLyByZW5kZXIgb3B0aW9ucyB3aXRob3V0IGRlZmF1bHRzIGFzIGNvbW1lbnRzXG4gIGlmIChvcHRzLmNvbW1lbnRzID09PSBJbml0UHJvamVjdE9wdGlvbkhpbnRzLkFMTCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRzLnR5cGUub3B0aW9ucy5maWx0ZXIoXG4gICAgICAob3B0KSA9PiAhb3B0LmRlcHJlY2F0ZWQgJiYgb3B0cy5hcmdzW29wdC5uYW1lXSA9PT0gdW5kZWZpbmVkXG4gICAgKTtcbiAgICByZXN1bHQucHVzaCguLi5yZW5kZXJDb21tZW50ZWRPcHRpb25zQnlNb2R1bGUocmVuZGVycywgb3B0aW9ucykpO1xuICB9IGVsc2UgaWYgKG9wdHMuY29tbWVudHMgPT09IEluaXRQcm9qZWN0T3B0aW9uSGludHMuRkVBVFVSRUQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gb3B0cy50eXBlLm9wdGlvbnMuZmlsdGVyKFxuICAgICAgKG9wdCkgPT5cbiAgICAgICAgIW9wdC5kZXByZWNhdGVkICYmIG9wdHMuYXJnc1tvcHQubmFtZV0gPT09IHVuZGVmaW5lZCAmJiBvcHQuZmVhdHVyZWRcbiAgICApO1xuICAgIHJlc3VsdC5wdXNoKC4uLnJlbmRlckNvbW1lbnRlZE9wdGlvbnNJbk9yZGVyKHJlbmRlcnMsIG9wdGlvbnMpKTtcbiAgfSBlbHNlIGlmIChvcHRzLmNvbW1lbnRzID09PSBJbml0UHJvamVjdE9wdGlvbkhpbnRzLk5PTkUpIHtcbiAgICAvLyBkb24ndCByZW5kZXIgYW55IGV4dHJhIG9wdGlvbnNcbiAgfVxuXG4gIGlmIChyZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdID09PSBcIlwiKSB7XG4gICAgcmVzdWx0LnBvcCgpO1xuICB9XG4gIHJlc3VsdC5wdXNoKFwifVwiKTtcbiAgcmV0dXJuIHsgcmVuZGVyZWRPcHRpb25zOiByZXN1bHQuam9pbihcIlxcblwiKSwgaW1wb3J0czogYWxsSW1wb3J0cyB9O1xufVxuXG5mdW5jdGlvbiByZW5kZXJDb21tZW50ZWRPcHRpb25zQnlNb2R1bGUoXG4gIHJlbmRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gIG9wdGlvbnM6IGludmVudG9yeS5Qcm9qZWN0T3B0aW9uW11cbikge1xuICBjb25zdCBvcHRpb25zQnlNb2R1bGU6IFJlY29yZDxzdHJpbmcsIGludmVudG9yeS5Qcm9qZWN0T3B0aW9uW10+ID0ge307XG5cbiAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykge1xuICAgIGNvbnN0IHBhcmVudE1vZHVsZSA9IG9wdGlvbi5wYXJlbnQ7XG4gICAgb3B0aW9uc0J5TW9kdWxlW3BhcmVudE1vZHVsZV0gPSBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXSA/PyBbXTtcbiAgICBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXS5wdXNoKG9wdGlvbik7XG4gIH1cblxuICBmb3IgKGNvbnN0IHBhcmVudE1vZHVsZSBpbiBvcHRpb25zQnlNb2R1bGUpIHtcbiAgICBvcHRpb25zQnlNb2R1bGVbcGFyZW50TW9kdWxlXS5zb3J0KChvMSwgbzIpID0+XG4gICAgICBvMS5uYW1lLmxvY2FsZUNvbXBhcmUobzIubmFtZSlcbiAgICApO1xuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGNvbnN0IG1hcmdpblNpemUgPSBNYXRoLm1heChcbiAgICAuLi5vcHRpb25zLm1hcCgob3B0KSA9PiByZW5kZXJzW29wdC5uYW1lXS5sZW5ndGgpXG4gICk7XG4gIGZvciAoY29uc3QgW21vZHVsZU5hbWUsIG9wdGlvbkdyb3VwXSBvZiBPYmplY3QuZW50cmllcyhcbiAgICBvcHRpb25zQnlNb2R1bGVcbiAgKS5zb3J0KCkpIHtcbiAgICByZXN1bHQucHVzaChgJHtUQUJ9LyogJHttb2R1bGVOYW1lfSAqL2ApO1xuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbkdyb3VwKSB7XG4gICAgICBjb25zdCBwYXJhbVJlbmRlciA9IHJlbmRlcnNbb3B0aW9uLm5hbWVdO1xuICAgICAgY29uc3QgZG9jc3RyaW5nID0gb3B0aW9uLmRvY3MgfHwgXCJObyBkb2N1bWVudGF0aW9uIGZvdW5kLlwiO1xuICAgICAgcmVzdWx0LnB1c2goXG4gICAgICAgIGAke1RBQn0ke3BhcmFtUmVuZGVyfSR7bWFrZVBhZGRpbmcoXG4gICAgICAgICAgbWFyZ2luU2l6ZSAtIHBhcmFtUmVuZGVyLmxlbmd0aCArIDJcbiAgICAgICAgKX0vKiAke2RvY3N0cmluZ30gKi9gXG4gICAgICApO1xuICAgIH1cbiAgICByZXN1bHQucHVzaChcIlwiKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZW5kZXJDb21tZW50ZWRPcHRpb25zSW5PcmRlcihcbiAgcmVuZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgb3B0aW9uczogaW52ZW50b3J5LlByb2plY3RPcHRpb25bXVxuKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBtYXJnaW5TaXplID0gTWF0aC5tYXgoXG4gICAgLi4ub3B0aW9ucy5tYXAoKG9wdCkgPT4gcmVuZGVyc1tvcHQubmFtZV0ubGVuZ3RoKVxuICApO1xuICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25zKSB7XG4gICAgY29uc3QgcGFyYW1SZW5kZXIgPSByZW5kZXJzW29wdGlvbi5uYW1lXTtcbiAgICBjb25zdCBkb2NzdHJpbmcgPSBvcHRpb24uZG9jcyB8fCBcIk5vIGRvY3VtZW50YXRpb24gZm91bmQuXCI7XG4gICAgcmVzdWx0LnB1c2goXG4gICAgICBgJHtUQUJ9JHtwYXJhbVJlbmRlcn0ke21ha2VQYWRkaW5nKFxuICAgICAgICBtYXJnaW5TaXplIC0gcGFyYW1SZW5kZXIubGVuZ3RoICsgMlxuICAgICAgKX0vKiAke2RvY3N0cmluZ30gKi9gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJlbmRlcnMgYSB2YWx1ZSBhcyBhIEphdmFTY3JpcHQgdmFsdWUsIGNvbnZlcnRpbmcgc3RyaW5ncyB0byBlbnVtcyB3aGVyZVxuICogYXBwcm9wcmlhdGUuIFRoZSB0eXBlIG11c3QgYmUgSlNPTi1saWtlIChzdHJpbmcsIG51bWJlciwgYm9vbGVhbiwgYXJyYXksXG4gKiBlbnVtLCBvciBKU09OIG9iamVjdCkuXG4gKlxuICogUmV0dXJucyBhIEphdmFTY3JpcHQgZXhwcmVzc2lvbiBhcyBhIHN0cmluZywgYW5kIHRoZSBuYW1lcyBvZiBhbnlcbiAqIG5lY2Vzc2FyeSBpbXBvcnRzLlxuICovXG5mdW5jdGlvbiByZW5kZXJBcmdBc0phdmFTY3JpcHQoYXJnOiBhbnksIG9wdGlvbjogaW52ZW50b3J5LlByb2plY3RPcHRpb24pIHtcbiAgaWYgKG9wdGlvbi5raW5kID09PSBcImVudW1cIikge1xuICAgIGlmICghb3B0aW9uLmZxbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBmcW4gZmllbGQgaXMgbWlzc2luZyBmcm9tIGVudW0gb3B0aW9uICR7b3B0aW9uLm5hbWV9YCk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gb3B0aW9uLmZxbi5zcGxpdChcIi5cIik7IC8vIC0+IFsncHJvamVuJywgJ3dlYicsICdNeUVudW0nXVxuICAgIGNvbnN0IGVudW1DaG9pY2UgPSBTdHJpbmcoYXJnKS50b1VwcGVyQ2FzZSgpLnJlcGxhY2UoLy0vZywgXCJfXCIpOyAvLyBjdXN0b20tdmFsdWUgLT4gQ1VTVE9NX1ZBTFVFXG4gICAgY29uc3QganMgPSBgJHtwYXJ0cy5zbGljZSgxKS5qb2luKFwiLlwiKX0uJHtlbnVtQ2hvaWNlfWA7IC8vIC0+IHdlYi5NeUVudW0uQ1VTVE9NX1ZBTFVFXG4gICAgY29uc3QgbW9kdWxlTmFtZSA9IHBhcnRzWzBdOyAvLyAtPiBwcm9qZW5cbiAgICBjb25zdCBpbXBvcnROYW1lID0gcGFydHNbMV07IC8vIC0+IHdlYlxuICAgIHJldHVybiB7IGpzLCBtb2R1bGVOYW1lLCBpbXBvcnROYW1lIH07XG4gIH0gZWxzZSBpZiAob3B0aW9uLmpzb25MaWtlKSB7XG4gICAgcmV0dXJuIHsganM6IEpTT04uc3RyaW5naWZ5KGFyZykgfTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVW5leHBlY3RlZCBvcHRpb24gJHtvcHRpb24ubmFtZX0gLSBjYW5ub3QgcmVuZGVyIGEgdmFsdWUgZm9yIHRoaXMgb3B0aW9uIGJlY2F1c2UgaXQgZG9lcyBub3QgaGF2ZSBhIEpTT04tbGlrZSB0eXBlLmBcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VQYWRkaW5nKHBhZGRpbmdMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBcIiBcIi5yZXBlYXQocGFkZGluZ0xlbmd0aCk7XG59XG4iXX0=