projen
Version:
CDK for software projects
124 lines • 14.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjenTaskRunner = void 0;
const path = __importStar(require("node:path"));
const _resolve_1 = require("./_resolve");
const common_1 = require("./common");
const component_1 = require("./component");
const json_1 = require("./json");
const exec_1 = require("./util/exec");
class ProjenTaskRunner extends component_1.Component {
/**
* The project-relative path of the tasks manifest file.
*/
static MANIFEST_FILE = path.posix.join(common_1.PROJEN_DIR, "tasks.json");
constructor(scope, id) {
super(scope, id);
// The runner owns the projen tasks manifest (`.projen/tasks.json`).
//
// The file is created here, in the constructor, with *lazy* content so
// that tasks added to the project later are still included. It cannot be
// created in `synthesize()` because components created during the synthesis
// loop are not themselves synthesized (the file would never be written).
new json_1.JsonFile(this.project, ProjenTaskRunner.MANIFEST_FILE, {
omitEmpty: true,
obj: (() => this.tasksManifest),
});
}
/**
* Runs a task by shelling out to the projen CLI. The CLI owns the task
* runtime, which keeps `src/` decoupled from `src/cli/`.
*/
runTask(task, args) {
// Resolve the compiled CLI entrypoint relative to the package root (the
// same approach used by TaskRuntime for builtin tasks). This works both
// from the compiled `lib/` output and when running from `src/` under
// ts-jest, where a module-relative `./cli/index.js` would not exist.
const moduleRoot = path.dirname(require.resolve("../package.json"));
const cli = path.join(moduleRoot, "lib", "cli", "index.js");
// When projen runs inside a jsii language runtime (Python, Java, Go, ...)
// the kernel loads it through a symlinked module closure and runs node
// with `--preserve-symlinks`: the symlink target - the jsii package
// cache - is a bare tarball extraction where non-bundled dependencies
// (`constructs`) are not resolvable. A spawned child does not inherit
// execArgv, so without the flag it would realpath the CLI back into the
// bare extraction and crash with `Cannot find module 'constructs'`.
// Forward the flag, plus `--preserve-symlinks-main` so the CLI entrypoint
// path itself (which lives inside the symlinked closure) is not
// realpathed either. See https://github.com/projen/projen/issues/4840.
const execArgv = process.execArgv.includes("--preserve-symlinks")
? ["--preserve-symlinks", "--preserve-symlinks-main"]
: [];
const argv = [
...execArgv,
cli,
task.name,
...(args ?? []).map((a) => a.toString()),
];
try {
exec_1.node.run(argv, {
cwd: this.project.outdir,
inheritStdio: true,
});
}
catch (e) {
// `node.run` (execFileSync) throws on a non-zero exit (with a numeric
// `.status`) or on a spawn failure. Translate a non-zero exit into a
// task-friendly error; re-throw spawn errors as-is. The child's stderr
// was already streamed live (inheritStdio), so it need not be re-surfaced.
if (typeof e?.status === "number") {
throw new Error(`Task "${task.name}" failed (exit code ${e.status}).`);
}
throw e;
}
}
get tasksManifest() {
const resolver = {
resolve: (obj, options) => (0, _resolve_1.resolve)(obj, options),
};
// The runner owns the on-disk manifest, so it stamps the schema version
// onto the logical tasks/env produced by `Tasks`. The version lets the task
// runtime detect manifests produced by a newer (potentially incompatible)
// version of projen.
const resolved = this.project.tasks.resolveTasksManifest(resolver) ?? {};
return {
manifestVersion: common_1.TASKS_MANIFEST_VERSION,
...resolved,
};
}
}
exports.ProjenTaskRunner = ProjenTaskRunner;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdGFzay1ydW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWtDO0FBRWxDLHlDQUFxQztBQUNyQyxxQ0FBOEQ7QUFDOUQsMkNBQXdDO0FBRXhDLGlDQUFrQztBQUdsQyxzQ0FBbUM7QUFXbkMsTUFBYSxnQkFBaUIsU0FBUSxxQkFBUztJQUM3Qzs7T0FFRztJQUNJLE1BQU0sQ0FBVSxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ3BELG1CQUFVLEVBQ1YsWUFBWSxDQUNiLENBQUM7SUFFRixZQUFZLEtBQWlCLEVBQUUsRUFBVztRQUN4QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLG9FQUFvRTtRQUNwRSxFQUFFO1FBQ0YsdUVBQXVFO1FBQ3ZFLHlFQUF5RTtRQUN6RSw0RUFBNEU7UUFDNUUseUVBQXlFO1FBQ3pFLElBQUksZUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsYUFBYSxFQUFFO1lBQ3pELFNBQVMsRUFBRSxJQUFJO1lBQ2YsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBUTtTQUN2QyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksT0FBTyxDQUFDLElBQVUsRUFBRSxJQUE2QjtRQUN0RCx3RUFBd0U7UUFDeEUsd0VBQXdFO1FBQ3hFLHFFQUFxRTtRQUNyRSxxRUFBcUU7UUFDckUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztRQUNwRSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRTVELDBFQUEwRTtRQUMxRSx1RUFBdUU7UUFDdkUsb0VBQW9FO1FBQ3BFLHNFQUFzRTtRQUN0RSxzRUFBc0U7UUFDdEUsd0VBQXdFO1FBQ3hFLG9FQUFvRTtRQUNwRSwwRUFBMEU7UUFDMUUsZ0VBQWdFO1FBQ2hFLHVFQUF1RTtRQUN2RSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQztZQUMvRCxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsRUFBRSwwQkFBMEIsQ0FBQztZQUNyRCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRVAsTUFBTSxJQUFJLEdBQUc7WUFDWCxHQUFHLFFBQVE7WUFDWCxHQUFHO1lBQ0gsSUFBSSxDQUFDLElBQUk7WUFDVCxHQUFHLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3pDLENBQUM7UUFDRixJQUFJLENBQUM7WUFDSCxXQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRTtnQkFDYixHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNO2dCQUN4QixZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixzRUFBc0U7WUFDdEUscUVBQXFFO1lBQ3JFLHVFQUF1RTtZQUN2RSwyRUFBMkU7WUFDM0UsSUFBSSxPQUFPLENBQUMsRUFBRSxNQUFNLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7WUFDekUsQ0FBQztZQUNELE1BQU0sQ0FBQyxDQUFDO1FBQ1YsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFjLGFBQWE7UUFDekIsTUFBTSxRQUFRLEdBQWM7WUFDMUIsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBQSxrQkFBTyxFQUFDLEdBQUcsRUFBRSxPQUFPLENBQUM7U0FDakQsQ0FBQztRQUVGLHdFQUF3RTtRQUN4RSw0RUFBNEU7UUFDNUUsMEVBQTBFO1FBQzFFLHFCQUFxQjtRQUNyQixNQUFNLFFBQVEsR0FDWixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFMUQsT0FBTztZQUNMLGVBQWUsRUFBRSwrQkFBc0I7WUFDdkMsR0FBRyxRQUFRO1NBQ1osQ0FBQztJQUNKLENBQUM7O0FBekZILDRDQTBGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwiLi9fcmVzb2x2ZVwiO1xuaW1wb3J0IHsgUFJPSkVOX0RJUiwgVEFTS1NfTUFOSUZFU1RfVkVSU0lPTiB9IGZyb20gXCIuL2NvbW1vblwiO1xuaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSBcIi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IElSZXNvbHZlciB9IGZyb20gXCIuL2ZpbGVcIjtcbmltcG9ydCB7IEpzb25GaWxlIH0gZnJvbSBcIi4vanNvblwiO1xuaW1wb3J0IHR5cGUgeyBUYXNrIH0gZnJvbSBcIi4vdGFza1wiO1xuaW1wb3J0IHR5cGUgeyBUYXNrc01hbmlmZXN0IH0gZnJvbSBcIi4vdGFzay1tb2RlbFwiO1xuaW1wb3J0IHsgbm9kZSB9IGZyb20gXCIuL3V0aWwvZXhlY1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIElUYXNrUnVubmVyIHtcbiAgLyoqXG4gICAqIFJ1bnMgYSB0YXNrLlxuICAgKiBAcGFyYW0gdGFzayBUaGUgdGFzayB0byBydW4uXG4gICAqIEBwYXJhbSBhcmdzIExpc3Qgb2YgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGFzaywgaWYgc3VwcG9ydGVkLlxuICAgKi9cbiAgcnVuVGFzayh0YXNrOiBUYXNrLCBhcmdzPzogQXJyYXk8c3RyaW5nIHwgbnVtYmVyPik6IHZvaWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9qZW5UYXNrUnVubmVyIGV4dGVuZHMgQ29tcG9uZW50IGltcGxlbWVudHMgSVRhc2tSdW5uZXIge1xuICAvKipcbiAgICogVGhlIHByb2plY3QtcmVsYXRpdmUgcGF0aCBvZiB0aGUgdGFza3MgbWFuaWZlc3QgZmlsZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTUFOSUZFU1RfRklMRSA9IHBhdGgucG9zaXguam9pbihcbiAgICBQUk9KRU5fRElSLFxuICAgIFwidGFza3MuanNvblwiLFxuICApO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBpZD86IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvLyBUaGUgcnVubmVyIG93bnMgdGhlIHByb2plbiB0YXNrcyBtYW5pZmVzdCAoYC5wcm9qZW4vdGFza3MuanNvbmApLlxuICAgIC8vXG4gICAgLy8gVGhlIGZpbGUgaXMgY3JlYXRlZCBoZXJlLCBpbiB0aGUgY29uc3RydWN0b3IsIHdpdGggKmxhenkqIGNvbnRlbnQgc29cbiAgICAvLyB0aGF0IHRhc2tzIGFkZGVkIHRvIHRoZSBwcm9qZWN0IGxhdGVyIGFyZSBzdGlsbCBpbmNsdWRlZC4gSXQgY2Fubm90IGJlXG4gICAgLy8gY3JlYXRlZCBpbiBgc3ludGhlc2l6ZSgpYCBiZWNhdXNlIGNvbXBvbmVudHMgY3JlYXRlZCBkdXJpbmcgdGhlIHN5bnRoZXNpc1xuICAgIC8vIGxvb3AgYXJlIG5vdCB0aGVtc2VsdmVzIHN5bnRoZXNpemVkICh0aGUgZmlsZSB3b3VsZCBuZXZlciBiZSB3cml0dGVuKS5cbiAgICBuZXcgSnNvbkZpbGUodGhpcy5wcm9qZWN0LCBQcm9qZW5UYXNrUnVubmVyLk1BTklGRVNUX0ZJTEUsIHtcbiAgICAgIG9taXRFbXB0eTogdHJ1ZSxcbiAgICAgIG9iajogKCgpID0+IHRoaXMudGFza3NNYW5pZmVzdCkgYXMgYW55LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSB0YXNrIGJ5IHNoZWxsaW5nIG91dCB0byB0aGUgcHJvamVuIENMSS4gVGhlIENMSSBvd25zIHRoZSB0YXNrXG4gICAqIHJ1bnRpbWUsIHdoaWNoIGtlZXBzIGBzcmMvYCBkZWNvdXBsZWQgZnJvbSBgc3JjL2NsaS9gLlxuICAgKi9cbiAgcHVibGljIHJ1blRhc2sodGFzazogVGFzaywgYXJncz86IEFycmF5PHN0cmluZyB8IG51bWJlcj4pOiB2b2lkIHtcbiAgICAvLyBSZXNvbHZlIHRoZSBjb21waWxlZCBDTEkgZW50cnlwb2ludCByZWxhdGl2ZSB0byB0aGUgcGFja2FnZSByb290ICh0aGVcbiAgICAvLyBzYW1lIGFwcHJvYWNoIHVzZWQgYnkgVGFza1J1bnRpbWUgZm9yIGJ1aWx0aW4gdGFza3MpLiBUaGlzIHdvcmtzIGJvdGhcbiAgICAvLyBmcm9tIHRoZSBjb21waWxlZCBgbGliL2Agb3V0cHV0IGFuZCB3aGVuIHJ1bm5pbmcgZnJvbSBgc3JjL2AgdW5kZXJcbiAgICAvLyB0cy1qZXN0LCB3aGVyZSBhIG1vZHVsZS1yZWxhdGl2ZSBgLi9jbGkvaW5kZXguanNgIHdvdWxkIG5vdCBleGlzdC5cbiAgICBjb25zdCBtb2R1bGVSb290ID0gcGF0aC5kaXJuYW1lKHJlcXVpcmUucmVzb2x2ZShcIi4uL3BhY2thZ2UuanNvblwiKSk7XG4gICAgY29uc3QgY2xpID0gcGF0aC5qb2luKG1vZHVsZVJvb3QsIFwibGliXCIsIFwiY2xpXCIsIFwiaW5kZXguanNcIik7XG5cbiAgICAvLyBXaGVuIHByb2plbiBydW5zIGluc2lkZSBhIGpzaWkgbGFuZ3VhZ2UgcnVudGltZSAoUHl0aG9uLCBKYXZhLCBHbywgLi4uKVxuICAgIC8vIHRoZSBrZXJuZWwgbG9hZHMgaXQgdGhyb3VnaCBhIHN5bWxpbmtlZCBtb2R1bGUgY2xvc3VyZSBhbmQgcnVucyBub2RlXG4gICAgLy8gd2l0aCBgLS1wcmVzZXJ2ZS1zeW1saW5rc2A6IHRoZSBzeW1saW5rIHRhcmdldCAtIHRoZSBqc2lpIHBhY2thZ2VcbiAgICAvLyBjYWNoZSAtIGlzIGEgYmFyZSB0YXJiYWxsIGV4dHJhY3Rpb24gd2hlcmUgbm9uLWJ1bmRsZWQgZGVwZW5kZW5jaWVzXG4gICAgLy8gKGBjb25zdHJ1Y3RzYCkgYXJlIG5vdCByZXNvbHZhYmxlLiBBIHNwYXduZWQgY2hpbGQgZG9lcyBub3QgaW5oZXJpdFxuICAgIC8vIGV4ZWNBcmd2LCBzbyB3aXRob3V0IHRoZSBmbGFnIGl0IHdvdWxkIHJlYWxwYXRoIHRoZSBDTEkgYmFjayBpbnRvIHRoZVxuICAgIC8vIGJhcmUgZXh0cmFjdGlvbiBhbmQgY3Jhc2ggd2l0aCBgQ2Fubm90IGZpbmQgbW9kdWxlICdjb25zdHJ1Y3RzJ2AuXG4gICAgLy8gRm9yd2FyZCB0aGUgZmxhZywgcGx1cyBgLS1wcmVzZXJ2ZS1zeW1saW5rcy1tYWluYCBzbyB0aGUgQ0xJIGVudHJ5cG9pbnRcbiAgICAvLyBwYXRoIGl0c2VsZiAod2hpY2ggbGl2ZXMgaW5zaWRlIHRoZSBzeW1saW5rZWQgY2xvc3VyZSkgaXMgbm90XG4gICAgLy8gcmVhbHBhdGhlZCBlaXRoZXIuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vcHJvamVuL3Byb2plbi9pc3N1ZXMvNDg0MC5cbiAgICBjb25zdCBleGVjQXJndiA9IHByb2Nlc3MuZXhlY0FyZ3YuaW5jbHVkZXMoXCItLXByZXNlcnZlLXN5bWxpbmtzXCIpXG4gICAgICA/IFtcIi0tcHJlc2VydmUtc3ltbGlua3NcIiwgXCItLXByZXNlcnZlLXN5bWxpbmtzLW1haW5cIl1cbiAgICAgIDogW107XG5cbiAgICBjb25zdCBhcmd2ID0gW1xuICAgICAgLi4uZXhlY0FyZ3YsXG4gICAgICBjbGksXG4gICAgICB0YXNrLm5hbWUsXG4gICAgICAuLi4oYXJncyA/PyBbXSkubWFwKChhKSA9PiBhLnRvU3RyaW5nKCkpLFxuICAgIF07XG4gICAgdHJ5IHtcbiAgICAgIG5vZGUucnVuKGFyZ3YsIHtcbiAgICAgICAgY3dkOiB0aGlzLnByb2plY3Qub3V0ZGlyLFxuICAgICAgICBpbmhlcml0U3RkaW86IHRydWUsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIC8vIGBub2RlLnJ1bmAgKGV4ZWNGaWxlU3luYykgdGhyb3dzIG9uIGEgbm9uLXplcm8gZXhpdCAod2l0aCBhIG51bWVyaWNcbiAgICAgIC8vIGAuc3RhdHVzYCkgb3Igb24gYSBzcGF3biBmYWlsdXJlLiBUcmFuc2xhdGUgYSBub24temVybyBleGl0IGludG8gYVxuICAgICAgLy8gdGFzay1mcmllbmRseSBlcnJvcjsgcmUtdGhyb3cgc3Bhd24gZXJyb3JzIGFzLWlzLiBUaGUgY2hpbGQncyBzdGRlcnJcbiAgICAgIC8vIHdhcyBhbHJlYWR5IHN0cmVhbWVkIGxpdmUgKGluaGVyaXRTdGRpbyksIHNvIGl0IG5lZWQgbm90IGJlIHJlLXN1cmZhY2VkLlxuICAgICAgaWYgKHR5cGVvZiBlPy5zdGF0dXMgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUYXNrIFwiJHt0YXNrLm5hbWV9XCIgZmFpbGVkIChleGl0IGNvZGUgJHtlLnN0YXR1c30pLmApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHRhc2tzTWFuaWZlc3QoKTogVGFza3NNYW5pZmVzdCB7XG4gICAgY29uc3QgcmVzb2x2ZXI6IElSZXNvbHZlciA9IHtcbiAgICAgIHJlc29sdmU6IChvYmosIG9wdGlvbnMpID0+IHJlc29sdmUob2JqLCBvcHRpb25zKSxcbiAgICB9O1xuXG4gICAgLy8gVGhlIHJ1bm5lciBvd25zIHRoZSBvbi1kaXNrIG1hbmlmZXN0LCBzbyBpdCBzdGFtcHMgdGhlIHNjaGVtYSB2ZXJzaW9uXG4gICAgLy8gb250byB0aGUgbG9naWNhbCB0YXNrcy9lbnYgcHJvZHVjZWQgYnkgYFRhc2tzYC4gVGhlIHZlcnNpb24gbGV0cyB0aGUgdGFza1xuICAgIC8vIHJ1bnRpbWUgZGV0ZWN0IG1hbmlmZXN0cyBwcm9kdWNlZCBieSBhIG5ld2VyIChwb3RlbnRpYWxseSBpbmNvbXBhdGlibGUpXG4gICAgLy8gdmVyc2lvbiBvZiBwcm9qZW4uXG4gICAgY29uc3QgcmVzb2x2ZWQ6IFRhc2tzTWFuaWZlc3QgPVxuICAgICAgdGhpcy5wcm9qZWN0LnRhc2tzLnJlc29sdmVUYXNrc01hbmlmZXN0KHJlc29sdmVyKSA/PyB7fTtcblxuICAgIHJldHVybiB7XG4gICAgICBtYW5pZmVzdFZlcnNpb246IFRBU0tTX01BTklGRVNUX1ZFUlNJT04sXG4gICAgICAuLi5yZXNvbHZlZCxcbiAgICB9O1xuICB9XG59XG4iXX0=