gitlab-ci-local
Version:
Tired of pushing to test your .gitlab-ci.yml?
332 lines • 41.6 kB
JavaScript
#!/usr/bin/env node
import chalk from "chalk";
import yargs from "yargs";
import { Parser } from "./parser.js";
import * as state from "./state.js";
import { WriteStreamsProcess, WriteStreamsMock } from "./write-streams.js";
import { handler } from "./handler.js";
import { Executor } from "./executor.js";
import { Argv } from "./argv.js";
import { AssertionError } from "assert";
import { cleanupJobResources } from "./job.js";
import { GitlabRunnerPresetValues } from "./gitlab-preset.js";
const jobs = [];
process.on("SIGINT", async (_, code) => {
await cleanupJobResources(jobs);
process.exit(code);
});
// Graceful shutdown for nodemon
process.on("SIGUSR2", async () => await cleanupJobResources(jobs));
(() => {
const yparser = yargs(process.argv.slice(2));
yparser.parserConfiguration({ "greedy-arrays": false })
.showHelpOnFail(false)
.version("4.61.1")
.wrap(yparser.terminalWidth?.())
.command({
handler: async (argv) => {
try {
await handler(argv, new WriteStreamsProcess(), jobs);
const failedJobs = Executor.getFailed(jobs);
process.exit(failedJobs.length > 0 ? 1 : 0);
}
catch (e) {
if (e instanceof AssertionError) {
process.stderr.write(chalk `{red ${e.message.trim()}}\n`);
}
else if (e instanceof AggregateError) {
e.errors.forEach((aggE) => process.stderr.write(chalk `{red ${aggE.stack ?? aggE}}\n`));
}
else {
process.stderr.write(chalk `{red ${e.stack ?? e}}\n`);
}
await cleanupJobResources(jobs);
process.exit(1);
}
},
builder: (y) => {
return y
.positional("job", {
describe: "Jobname's to execute",
type: "string", // Type here is referring to each element of the positional args
})
// by default yargs's positional options (args) can be used as options (flags) so this coerce is solely for
// handling scenario when a single --job option flag is passed
// Once https://github.com/yargs/yargs/issues/2196 is implemented, we can probably remove this
.coerce("job", (args) => {
if (!Array.isArray(args))
return [args];
return args;
});
},
command: "$0 [job..]",
describe: "Runs the entire pipeline or job's",
})
.usage("Find more information at https://github.com/firecow/gitlab-ci-local.\nNote: To negate an option use '--no-(option)'.")
.strictOptions()
.env("GCL")
.option("manual", {
type: "array",
description: "One or more manual jobs to run during a pipeline",
requiresArg: true,
})
.option("list", {
type: "boolean",
description: "List job information, when:never excluded",
requiresArg: false,
})
.option("list-all", {
type: "boolean",
description: "List job information, when:never included",
requiresArg: false,
})
.option("list-json", {
type: "boolean",
description: "List job information in json format, when:never included",
requiresArg: false,
})
.option("list-csv", {
type: "boolean",
description: "List job information in csv format, when:never excluded",
requiresArg: false,
})
.option("list-csv-all", {
type: "boolean",
description: "List job information in csv format, when:never included",
requiresArg: false,
})
.option("preview", {
type: "boolean",
description: "Print YML with defaults, includes, extends and reference's expanded",
requiresArg: false,
})
.option("cwd", {
type: "string",
description: "Path to a current working directory",
requiresArg: true,
})
.option("variables-file", {
type: "string",
description: "Path to the project file variables",
requiresArg: true,
default: Argv.default.variablesFile,
})
.option("completion", {
type: "boolean",
description: "Generate tab completion script",
requiresArg: false,
})
.option("evaluate-rule-changes", {
type: "boolean",
description: "Whether to evaluate rule:changes. If set to false, rules:changes will always evaluate to true",
requiresArg: false,
default: Argv.default.evaluateRuleChanges,
})
.option("needs", {
type: "boolean",
description: "Run needed jobs, when executing specific jobs",
requiresArg: false,
})
.option("only-needs", {
type: "boolean",
description: "Run needed jobs, except the specified jobs themselves",
requiresArg: false,
})
.option("stage", {
type: "string",
description: "Run all jobs in a specific stage",
requiresArg: false,
})
.option("variable", {
type: "array",
description: "Add variable to all executed jobs (--variable HELLO=world)",
requiresArg: false,
})
.option("unset-variable", {
type: "array",
description: "Unsets a variable (--unset-variable HELLO)",
requiresArg: false,
})
.option("remote-variables", {
type: "string",
description: "Fetch variables file from remote location",
requiresArg: false,
})
.option("state-dir", {
type: "string",
description: "Location of the .gitlab-ci-local state dir, relative to cwd, eg. (symfony/.gitlab-ci-local/)",
requiresArg: false,
})
.option("file", {
type: "string",
description: "Location of the .gitlab-ci.yml, relative to cwd, eg. (gitlab/.gitlab-ci.yml)",
requiresArg: false,
})
.option("home", {
type: "string",
description: "Location of the HOME .gitlab-ci-local folder ($HOME/.gitlab-ci-local/variables.yml)",
requiresArg: false,
})
.option("shell-isolation", {
type: "boolean",
description: "Enable artifact isolation for shell-executor jobs",
requiresArg: false,
})
.option("force-shell-executor", {
type: "boolean",
description: "Forces all jobs to be executed using the shell executor. (Only use this option for trusted job)",
requiresArg: false,
})
.option("shell-executor-no-image", {
type: "boolean",
description: "Whether to use shell executor when no image is specified.",
requiresArg: false,
})
.option("default-image", {
type: "string",
description: "When using --shell-executor-no-image=false which image to be used for the container. Defaults to docker.io/ruby:3.1 if not set.",
requiresArg: false,
})
.option("helper-image", {
type: "string",
description: "When using --shell-executor-no-image=false which image to be used for the utils container. Defaults to docker.io/firecow/gitlab-ci-local-util:latest if not set.",
requiresArg: false,
})
.option("mount-cache", {
type: "boolean",
description: "Enable docker mount based caching",
requiresArg: false,
})
.option("umask", {
type: "boolean",
description: "Sets docker user to 0:0",
requiresArg: false,
})
.option("userns", {
type: "string",
description: "Set docker executor userns option",
requiresArg: false,
})
.option("privileged", {
type: "boolean",
description: "Set docker executor to privileged mode",
requiresArg: false,
})
.option("ulimit", {
type: "number",
description: "Set docker executor ulimit",
requiresArg: false,
})
.option("network", {
type: "array",
description: "Add networks to docker executor",
requiresArg: false,
})
.option("volume", {
type: "array",
description: "Add volumes to docker executor",
requiresArg: false,
})
.option("extra-host", {
type: "array",
description: "Add extra docker host entries",
requiresArg: false,
})
.option("pull-policy", {
type: "string",
description: "Set image pull-policy (always or if-not-present)",
requiresArg: false,
})
.option("fetch-includes", {
type: "boolean",
description: "Fetch all external includes one more time",
requiresArg: false,
})
.option("maximum-includes", {
type: "number",
description: "The maximum number of includes",
requiresArg: false,
})
.option("artifacts-to-source", {
type: "boolean",
description: "Copy the generated artifacts into cwd",
requiresArg: false,
})
.option("cleanup", {
type: "boolean",
description: "Remove docker resources after they've been used",
requiresArg: false,
})
.option("quiet", {
type: "boolean",
description: "Suppress all job output",
requiresArg: false,
})
.option("timestamps", {
type: "boolean",
description: "Show timestamps and job duration in the logs",
requiresArg: false,
})
.option("max-job-name-padding", {
type: "number",
description: "Maximum padding for job name (use <= 0 for no padding)",
requiresArg: false,
})
.option("json-schema-validation", {
type: "boolean",
description: "Whether to enable json schema validation",
requiresArg: false,
})
.option("ignore-schema-paths", {
type: "array",
requiresArg: false,
default: Argv.default.ignoreSchemaPaths,
description: "The json schema paths that will be ignored",
})
.option("concurrency", {
type: "number",
description: "Limit the number of jobs that run simultaneously",
requiresArg: false,
})
.option("container-executable", {
type: "string",
description: "Command to start the container engine (docker or podman)",
requiresArg: false,
})
.option("container-mac-address", {
type: "string",
description: "Container MAC address (e.g., aa:bb:cc:dd:ee:ff)",
requiresArg: false,
})
.option("container-emulate", {
type: "string",
description: "The name, without the architecture, of a gitlab hosted runner to emulate. See here: https://docs.gitlab.com/ee/ci/runners/hosted_runners/linux.html#machine-types-available-for-linux---x86-64",
choices: GitlabRunnerPresetValues,
})
.option("color", {
requiresArg: false,
default: true,
description: "Enables color",
})
.completion("completion", false, (current, yargsArgv, completionFilter, done) => {
try {
if (current.startsWith("-")) {
completionFilter();
}
else {
Argv.build({ ...yargsArgv, autoCompleting: true })
.then(argv => state.getPipelineIid(argv.cwd, argv.stateDir).then(pipelineIid => ({ argv, pipelineIid })))
.then(({ argv, pipelineIid }) => Parser.create(argv, new WriteStreamsMock(), pipelineIid, []))
.then((parser) => {
const jobNames = [...parser.jobs.values()].filter((j) => j.when != "never").map((j) => j.name);
done(jobNames);
});
}
}
catch {
return ["Parser-Failed!"];
}
})
.parse();
})();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxtQkFBbUIsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ3pFLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDckMsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN2QyxPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQy9CLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDdEMsT0FBTyxFQUFNLG1CQUFtQixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ2xELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRTVELE1BQU0sSUFBSSxHQUFVLEVBQUUsQ0FBQztBQUV2QixPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBUyxFQUFFLElBQVksRUFBRSxFQUFFO0lBQ25ELE1BQU0sbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN2QixDQUFDLENBQUMsQ0FBQztBQUVILGdDQUFnQztBQUNoQyxPQUFPLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUVuRSxDQUFDLEdBQUcsRUFBRTtJQUNGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxP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QUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUMvRixJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ25CLENBQUMsQ0FBQyxDQUFDO1lBQ1gsQ0FBQztRQUNMLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDTCxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM5QixDQUFDO0lBRUwsQ0FBQyxDQUFDO1NBQ0QsS0FBSyxFQUFFLENBQUM7QUFDakIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcbmltcG9ydCB5YXJncyBmcm9tIFwieWFyZ3NcIjtcbmltcG9ydCB7UGFyc2VyfSBmcm9tIFwiLi9wYXJzZXIuanNcIjtcbmltcG9ydCAqIGFzIHN0YXRlIGZyb20gXCIuL3N0YXRlLmpzXCI7XG5pbXBvcnQge1dyaXRlU3RyZWFtc1Byb2Nlc3MsIFdyaXRlU3RyZWFtc01vY2t9IGZyb20gXCIuL3dyaXRlLXN0cmVhbXMuanNcIjtcbmltcG9ydCB7aGFuZGxlcn0gZnJvbSBcIi4vaGFuZGxlci5qc1wiO1xuaW1wb3J0IHtFeGVjdXRvcn0gZnJvbSBcIi4vZXhlY3V0b3IuanNcIjtcbmltcG9ydCB7QXJndn0gZnJvbSBcIi4vYXJndi5qc1wiO1xuaW1wb3J0IHtBc3NlcnRpb25FcnJvcn0gZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHtKb2IsIGNsZWFudXBKb2JSZXNvdXJjZXN9IGZyb20gXCIuL2pvYi5qc1wiO1xuaW1wb3J0IHtHaXRsYWJSdW5uZXJQcmVzZXRWYWx1ZXN9IGZyb20gXCIuL2dpdGxhYi1wcmVzZXQuanNcIjtcblxuY29uc3Qgam9iczogSm9iW10gPSBbXTtcblxucHJvY2Vzcy5vbihcIlNJR0lOVFwiLCBhc3luYyAoXzogc3RyaW5nLCBjb2RlOiBudW1iZXIpID0+IHtcbiAgICBhd2FpdCBjbGVhbnVwSm9iUmVzb3VyY2VzKGpvYnMpO1xuICAgIHByb2Nlc3MuZXhpdChjb2RlKTtcbn0pO1xuXG4vLyBHcmFjZWZ1bCBzaHV0ZG93biBmb3Igbm9kZW1vblxucHJvY2Vzcy5vbihcIlNJR1VTUjJcIiwgYXN5bmMgKCkgPT4gYXdhaXQgY2xlYW51cEpvYlJlc291cmNlcyhqb2JzKSk7XG5cbigoKSA9PiB7XG4gICAgY29uc3QgeXBhcnNlciA9IHlhcmdzKHByb2Nlc3MuYXJndi5zbGljZSgyKSk7XG4gICAgeXBhcnNlci5wYXJzZXJDb25maWd1cmF0aW9uKHtcImdyZWVkeS1hcnJheXNcIjogZmFsc2V9KVxuICAgICAgICAuc2hvd0hlbHBPbkZhaWwoZmFsc2UpXG4gICAgICAgIC52ZXJzaW9uKFwiNC42MS4xXCIpXG4gICAgICAgIC53cmFwKHlwYXJzZXIudGVybWluYWxXaWR0aD8uKCkpXG4gICAgICAgIC5jb21tYW5kKHtcbiAgICAgICAgICAgIGhhbmRsZXI6IGFzeW5jIChhcmd2KSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgaGFuZGxlcihhcmd2LCBuZXcgV3JpdGVTdHJlYW1zUHJvY2VzcygpLCBqb2JzKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmFpbGVkSm9icyA9IEV4ZWN1dG9yLmdldEZhaWxlZChqb2JzKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KGZhaWxlZEpvYnMubGVuZ3RoID4gMCA/IDEgOiAwKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBBc3NlcnRpb25FcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoY2hhbGtge3JlZCAke2UubWVzc2FnZS50cmltKCl9fVxcbmApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGUgaW5zdGFuY2VvZiBBZ2dyZWdhdGVFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZS5lcnJvcnMuZm9yRWFjaCgoYWdnRSkgPT4gcHJvY2Vzcy5zdGRlcnIud3JpdGUoY2hhbGtge3JlZCAke2FnZ0Uuc3RhY2sgPz8gYWdnRX19XFxuYCkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5zdGRlcnIud3JpdGUoY2hhbGtge3JlZCAke2Uuc3RhY2sgPz8gZX19XFxuYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgY2xlYW51cEpvYlJlc291cmNlcyhqb2JzKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBidWlsZGVyOiAoeTogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHlcbiAgICAgICAgICAgICAgICAgICAgLnBvc2l0aW9uYWwoXCJqb2JcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpYmU6IFwiSm9ibmFtZSdzIHRvIGV4ZWN1dGVcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsIC8vIFR5cGUgaGVyZSBpcyByZWZlcnJpbmcgdG8gZWFjaCBlbGVtZW50IG9mIHRoZSBwb3NpdGlvbmFsIGFyZ3NcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLy8gYnkgZGVmYXVsdCB5YXJncydzIHBvc2l0aW9uYWwgb3B0aW9ucyAoYXJncykgY2FuIGJlIHVzZWQgYXMgb3B0aW9ucyAoZmxhZ3MpIHNvIHRoaXMgY29lcmNlIGlzIHNvbGVseSBmb3JcbiAgICAgICAgICAgICAgICAgICAgLy8gaGFuZGxpbmcgc2NlbmFyaW8gd2hlbiBhIHNpbmdsZSAtLWpvYiBvcHRpb24gZmxhZyBpcyBwYXNzZWRcbiAgICAgICAgICAgICAgICAgICAgLy8gT25jZSBodHRwczovL2dpdGh1Yi5jb20veWFyZ3MveWFyZ3MvaXNzdWVzLzIxOTYgaXMgaW1wbGVtZW50ZWQsIHdlIGNhbiBwcm9iYWJseSByZW1vdmUgdGhpc1xuICAgICAgICAgICAgICAgICAgICAuY29lcmNlKFwiam9iXCIsIChhcmdzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFyZ3MpKSByZXR1cm4gW2FyZ3NdO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbW1hbmQ6IFwiJDAgW2pvYi4uXVwiLFxuICAgICAgICAgICAgZGVzY3JpYmU6IFwiUnVucyB0aGUgZW50aXJlIHBpcGVsaW5lIG9yIGpvYidzXCIsXG4gICAgICAgIH0pXG4gICAgICAgIC51c2FnZShcIkZpbmQgbW9yZSBpbmZvcm1hdGlvbiBhdCBodHRwczovL2dpdGh1Yi5jb20vZmlyZWNvdy9naXRsYWItY2ktbG9jYWwuXFxuTm90ZTogVG8gbmVnYXRlIGFuIG9wdGlvbiB1c2UgJy0tbm8tKG9wdGlvbiknLlwiKVxuICAgICAgICAuc3RyaWN0T3B0aW9ucygpXG4gICAgICAgIC5lbnYoXCJHQ0xcIilcbiAgICAgICAgLm9wdGlvbihcIm1hbnVhbFwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJPbmUgb3IgbW9yZSBtYW51YWwgam9icyB0byBydW4gZHVyaW5nIGEgcGlwZWxpbmVcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiB0cnVlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibGlzdFwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxpc3Qgam9iIGluZm9ybWF0aW9uLCB3aGVuOm5ldmVyIGV4Y2x1ZGVkXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJsaXN0LWFsbFwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxpc3Qgam9iIGluZm9ybWF0aW9uLCB3aGVuOm5ldmVyIGluY2x1ZGVkXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJsaXN0LWpzb25cIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaXN0IGpvYiBpbmZvcm1hdGlvbiBpbiBqc29uIGZvcm1hdCwgd2hlbjpuZXZlciBpbmNsdWRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibGlzdC1jc3ZcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaXN0IGpvYiBpbmZvcm1hdGlvbiBpbiBjc3YgZm9ybWF0LCB3aGVuOm5ldmVyIGV4Y2x1ZGVkXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJsaXN0LWNzdi1hbGxcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaXN0IGpvYiBpbmZvcm1hdGlvbiBpbiBjc3YgZm9ybWF0LCB3aGVuOm5ldmVyIGluY2x1ZGVkXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJwcmV2aWV3XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUHJpbnQgWU1MIHdpdGggZGVmYXVsdHMsIGluY2x1ZGVzLCBleHRlbmRzIGFuZCByZWZlcmVuY2UncyBleHBhbmRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiY3dkXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJQYXRoIHRvIGEgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ2YXJpYWJsZXMtZmlsZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUGF0aCB0byB0aGUgcHJvamVjdCBmaWxlIHZhcmlhYmxlc1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgICAgICBkZWZhdWx0OiBBcmd2LmRlZmF1bHQudmFyaWFibGVzRmlsZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbXBsZXRpb25cIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJHZW5lcmF0ZSB0YWIgY29tcGxldGlvbiBzY3JpcHRcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImV2YWx1YXRlLXJ1bGUtY2hhbmdlc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZXRoZXIgdG8gZXZhbHVhdGUgcnVsZTpjaGFuZ2VzLiBJZiBzZXQgdG8gZmFsc2UsIHJ1bGVzOmNoYW5nZXMgd2lsbCBhbHdheXMgZXZhbHVhdGUgdG8gdHJ1ZVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICAgICAgZGVmYXVsdDogQXJndi5kZWZhdWx0LmV2YWx1YXRlUnVsZUNoYW5nZXMsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJuZWVkc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1biBuZWVkZWQgam9icywgd2hlbiBleGVjdXRpbmcgc3BlY2lmaWMgam9ic1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwib25seS1uZWVkc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1biBuZWVkZWQgam9icywgZXhjZXB0IHRoZSBzcGVjaWZpZWQgam9icyB0aGVtc2VsdmVzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzdGFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUnVuIGFsbCBqb2JzIGluIGEgc3BlY2lmaWMgc3RhZ2VcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInZhcmlhYmxlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkFkZCB2YXJpYWJsZSB0byBhbGwgZXhlY3V0ZWQgam9icyAoLS12YXJpYWJsZSBIRUxMTz13b3JsZClcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInVuc2V0LXZhcmlhYmxlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlVuc2V0cyBhIHZhcmlhYmxlICgtLXVuc2V0LXZhcmlhYmxlIEhFTExPKVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwicmVtb3RlLXZhcmlhYmxlc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiRmV0Y2ggdmFyaWFibGVzIGZpbGUgZnJvbSByZW1vdGUgbG9jYXRpb25cIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInN0YXRlLWRpclwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTG9jYXRpb24gb2YgdGhlIC5naXRsYWItY2ktbG9jYWwgc3RhdGUgZGlyLCByZWxhdGl2ZSB0byBjd2QsIGVnLiAoc3ltZm9ueS8uZ2l0bGFiLWNpLWxvY2FsLylcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImZpbGVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxvY2F0aW9uIG9mIHRoZSAuZ2l0bGFiLWNpLnltbCwgcmVsYXRpdmUgdG8gY3dkLCBlZy4gKGdpdGxhYi8uZ2l0bGFiLWNpLnltbClcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImhvbWVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxvY2F0aW9uIG9mIHRoZSBIT01FIC5naXRsYWItY2ktbG9jYWwgZm9sZGVyICgkSE9NRS8uZ2l0bGFiLWNpLWxvY2FsL3ZhcmlhYmxlcy55bWwpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzaGVsbC1pc29sYXRpb25cIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJFbmFibGUgYXJ0aWZhY3QgaXNvbGF0aW9uIGZvciBzaGVsbC1leGVjdXRvciBqb2JzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJmb3JjZS1zaGVsbC1leGVjdXRvclwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkZvcmNlcyBhbGwgam9icyB0byBiZSBleGVjdXRlZCB1c2luZyB0aGUgc2hlbGwgZXhlY3V0b3IuIChPbmx5IHVzZSB0aGlzIG9wdGlvbiBmb3IgdHJ1c3RlZCBqb2IpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzaGVsbC1leGVjdXRvci1uby1pbWFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZXRoZXIgdG8gdXNlIHNoZWxsIGV4ZWN1dG9yIHdoZW4gbm8gaW1hZ2UgaXMgc3BlY2lmaWVkLlwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiZGVmYXVsdC1pbWFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiV2hlbiB1c2luZyAtLXNoZWxsLWV4ZWN1dG9yLW5vLWltYWdlPWZhbHNlIHdoaWNoIGltYWdlIHRvIGJlIHVzZWQgZm9yIHRoZSBjb250YWluZXIuIERlZmF1bHRzIHRvIGRvY2tlci5pby9ydWJ5OjMuMSBpZiBub3Qgc2V0LlwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiaGVscGVyLWltYWdlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJXaGVuIHVzaW5nIC0tc2hlbGwtZXhlY3V0b3Itbm8taW1hZ2U9ZmFsc2Ugd2hpY2ggaW1hZ2UgdG8gYmUgdXNlZCBmb3IgdGhlIHV0aWxzIGNvbnRhaW5lci4gRGVmYXVsdHMgdG8gZG9ja2VyLmlvL2ZpcmVjb3cvZ2l0bGFiLWNpLWxvY2FsLXV0aWw6bGF0ZXN0IGlmIG5vdCBzZXQuXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJtb3VudC1jYWNoZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkVuYWJsZSBkb2NrZXIgbW91bnQgYmFzZWQgY2FjaGluZ1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwidW1hc2tcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTZXRzIGRvY2tlciB1c2VyIHRvIDA6MFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwidXNlcm5zXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTZXQgZG9ja2VyIGV4ZWN1dG9yIHVzZXJucyBvcHRpb25cIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInByaXZpbGVnZWRcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTZXQgZG9ja2VyIGV4ZWN1dG9yIHRvIHByaXZpbGVnZWQgbW9kZVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwidWxpbWl0XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTZXQgZG9ja2VyIGV4ZWN1dG9yIHVsaW1pdFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibmV0d29ya1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBZGQgbmV0d29ya3MgdG8gZG9ja2VyIGV4ZWN1dG9yXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ2b2x1bWVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQWRkIHZvbHVtZXMgdG8gZG9ja2VyIGV4ZWN1dG9yXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJleHRyYS1ob3N0XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkFkZCBleHRyYSBkb2NrZXIgaG9zdCBlbnRyaWVzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJwdWxsLXBvbGljeVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiU2V0IGltYWdlIHB1bGwtcG9saWN5IChhbHdheXMgb3IgaWYtbm90LXByZXNlbnQpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJmZXRjaC1pbmNsdWRlc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkZldGNoIGFsbCBleHRlcm5hbCBpbmNsdWRlcyBvbmUgbW9yZSB0aW1lXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJtYXhpbXVtLWluY2x1ZGVzXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGUgbWF4aW11bSBudW1iZXIgb2YgaW5jbHVkZXNcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImFydGlmYWN0cy10by1zb3VyY2VcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJDb3B5IHRoZSBnZW5lcmF0ZWQgYXJ0aWZhY3RzIGludG8gY3dkXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJjbGVhbnVwXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUmVtb3ZlIGRvY2tlciByZXNvdXJjZXMgYWZ0ZXIgdGhleSd2ZSBiZWVuIHVzZWRcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInF1aWV0XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiU3VwcHJlc3MgYWxsIGpvYiBvdXRwdXRcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInRpbWVzdGFtcHNcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTaG93IHRpbWVzdGFtcHMgYW5kIGpvYiBkdXJhdGlvbiBpbiB0aGUgbG9nc1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibWF4LWpvYi1uYW1lLXBhZGRpbmdcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIk1heGltdW0gcGFkZGluZyBmb3Igam9iIG5hbWUgKHVzZSA8PSAwIGZvciBubyBwYWRkaW5nKVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwianNvbi1zY2hlbWEtdmFsaWRhdGlvblwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZXRoZXIgdG8gZW5hYmxlIGpzb24gc2NoZW1hIHZhbGlkYXRpb25cIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImlnbm9yZS1zY2hlbWEtcGF0aHNcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICAgICAgZGVmYXVsdDogQXJndi5kZWZhdWx0Lmlnbm9yZVNjaGVtYVBhdGhzLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiVGhlIGpzb24gc2NoZW1hIHBhdGhzIHRoYXQgd2lsbCBiZSBpZ25vcmVkXCIsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJjb25jdXJyZW5jeVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTGltaXQgdGhlIG51bWJlciBvZiBqb2JzIHRoYXQgcnVuIHNpbXVsdGFuZW91c2x5XCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJjb250YWluZXItZXhlY3V0YWJsZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQ29tbWFuZCB0byBzdGFydCB0aGUgY29udGFpbmVyIGVuZ2luZSAoZG9ja2VyIG9yIHBvZG1hbilcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbnRhaW5lci1tYWMtYWRkcmVzc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQ29udGFpbmVyIE1BQyBhZGRyZXNzIChlLmcuLCBhYTpiYjpjYzpkZDplZTpmZilcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbnRhaW5lci1lbXVsYXRlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGUgbmFtZSwgd2l0aG91dCB0aGUgYXJjaGl0ZWN0dXJlLCBvZiBhIGdpdGxhYiBob3N0ZWQgcnVubmVyIHRvIGVtdWxhdGUuIFNlZSBoZXJlOiBodHRwczovL2RvY3MuZ2l0bGFiLmNvbS9lZS9jaS9ydW5uZXJzL2hvc3RlZF9ydW5uZXJzL2xpbnV4Lmh0bWwjbWFjaGluZS10eXBlcy1hdmFpbGFibGUtZm9yLWxpbnV4LS0teDg2LTY0XCIsXG4gICAgICAgICAgICBjaG9pY2VzOiBHaXRsYWJSdW5uZXJQcmVzZXRWYWx1ZXMsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJjb2xvclwiLCB7XG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiRW5hYmxlcyBjb2xvclwiLFxuICAgICAgICB9KVxuICAgICAgICAuY29tcGxldGlvbihcImNvbXBsZXRpb25cIiwgZmFsc2UsIChjdXJyZW50OiBzdHJpbmcsIHlhcmdzQXJndjogYW55LCBjb21wbGV0aW9uRmlsdGVyOiBhbnksIGRvbmU6IChjb21wbGV0aW9uczogc3RyaW5nW10pID0+IGFueSkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudC5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uRmlsdGVyKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgQXJndi5idWlsZCh7Li4ueWFyZ3NBcmd2LCBhdXRvQ29tcGxldGluZzogdHJ1ZX0pXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbihhcmd2ID0+IHN0YXRlLmdldFBpcGVsaW5lSWlkKGFyZ3YuY3dkLCBhcmd2LnN0YXRlRGlyKS50aGVuKHBpcGVsaW5lSWlkID0+ICh7YXJndiwgcGlwZWxpbmVJaWR9KSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoe2FyZ3YsIHBpcGVsaW5lSWlkfSkgPT4gUGFyc2VyLmNyZWF0ZShhcmd2LCBuZXcgV3JpdGVTdHJlYW1zTW9jaygpLCBwaXBlbGluZUlpZCwgW10pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHBhcnNlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvYk5hbWVzID0gWy4uLnBhcnNlci5qb2JzLnZhbHVlcygpXS5maWx0ZXIoKGopID0+IGoud2hlbiAhPSBcIm5ldmVyXCIpLm1hcCgoaikgPT4gai5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lKGpvYk5hbWVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXCJQYXJzZXItRmFpbGVkIVwiXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9KVxuICAgICAgICAucGFyc2UoKTtcbn0pKCk7XG4iXX0=