gitlab-ci-local
Version:
Tired of pushing to test your .gitlab-ci.yml?
347 lines • 44.1 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.63.0")
.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("validate-dependency-chain", {
type: "boolean",
description: "Validate that jobs needed or dependent by active jobs under specified conditions are also active without actually running the jobs. Uses fail-fast approach - stops at first validation error for both 'needs' and 'dependencies' keywords. If validation fails, use --list flag to see which jobs will run under specified conditions",
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("wait-image", {
type: "string",
description: "Which image to be used for the wait container. Defaults to docker.io/sumina46/wait-for-it:latest 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("device", {
type: "array",
description: "Add devices to docker executor",
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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QUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFDLElBQUksRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQ3RHLElBQUksQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLFdBQVcsRUFBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLGdCQUFnQixFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUMzRixJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtvQkFDYixNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDL0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNuQixDQUFDLENBQUMsQ0FBQztZQUNYLENBQUM7UUFDTCxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ0wsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDOUIsQ0FBQztJQUVMLENBQUMsQ0FBQztTQUNELEtBQUssRUFBRSxDQUFDO0FBQ2pCLENBQUMsQ0FBQyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgeWFyZ3MgZnJvbSBcInlhcmdzXCI7XG5pbXBvcnQge1BhcnNlcn0gZnJvbSBcIi4vcGFyc2VyLmpzXCI7XG5pbXBvcnQgKiBhcyBzdGF0ZSBmcm9tIFwiLi9zdGF0ZS5qc1wiO1xuaW1wb3J0IHtXcml0ZVN0cmVhbXNQcm9jZXNzLCBXcml0ZVN0cmVhbXNNb2NrfSBmcm9tIFwiLi93cml0ZS1zdHJlYW1zLmpzXCI7XG5pbXBvcnQge2hhbmRsZXJ9IGZyb20gXCIuL2hhbmRsZXIuanNcIjtcbmltcG9ydCB7RXhlY3V0b3J9IGZyb20gXCIuL2V4ZWN1dG9yLmpzXCI7XG5pbXBvcnQge0FyZ3Z9IGZyb20gXCIuL2FyZ3YuanNcIjtcbmltcG9ydCB7QXNzZXJ0aW9uRXJyb3J9IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCB7Sm9iLCBjbGVhbnVwSm9iUmVzb3VyY2VzfSBmcm9tIFwiLi9qb2IuanNcIjtcbmltcG9ydCB7R2l0bGFiUnVubmVyUHJlc2V0VmFsdWVzfSBmcm9tIFwiLi9naXRsYWItcHJlc2V0LmpzXCI7XG5cbmNvbnN0IGpvYnM6IEpvYltdID0gW107XG5cbnByb2Nlc3Mub24oXCJTSUdJTlRcIiwgYXN5bmMgKF86IHN0cmluZywgY29kZTogbnVtYmVyKSA9PiB7XG4gICAgYXdhaXQgY2xlYW51cEpvYlJlc291cmNlcyhqb2JzKTtcbiAgICBwcm9jZXNzLmV4aXQoY29kZSk7XG59KTtcblxuLy8gR3JhY2VmdWwgc2h1dGRvd24gZm9yIG5vZGVtb25cbnByb2Nlc3Mub24oXCJTSUdVU1IyXCIsIGFzeW5jICgpID0+IGF3YWl0IGNsZWFudXBKb2JSZXNvdXJjZXMoam9icykpO1xuXG4oKCkgPT4ge1xuICAgIGNvbnN0IHlwYXJzZXIgPSB5YXJncyhwcm9jZXNzLmFyZ3Yuc2xpY2UoMikpO1xuICAgIHlwYXJzZXIucGFyc2VyQ29uZmlndXJhdGlvbih7XCJncmVlZHktYXJyYXlzXCI6IGZhbHNlfSlcbiAgICAgICAgLnNob3dIZWxwT25GYWlsKGZhbHNlKVxuICAgICAgICAudmVyc2lvbihcIjQuNjMuMFwiKVxuICAgICAgICAud3JhcCh5cGFyc2VyLnRlcm1pbmFsV2lkdGg/LigpKVxuICAgICAgICAuY29tbWFuZCh7XG4gICAgICAgICAgICBoYW5kbGVyOiBhc3luYyAoYXJndikgPT4ge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGhhbmRsZXIoYXJndiwgbmV3IFdyaXRlU3RyZWFtc1Byb2Nlc3MoKSwgam9icyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZhaWxlZEpvYnMgPSBFeGVjdXRvci5nZXRGYWlsZWQoam9icyk7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdChmYWlsZWRKb2JzLmxlbmd0aCA+IDAgPyAxIDogMCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgQXNzZXJ0aW9uRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGNoYWxrYHtyZWQgJHtlLm1lc3NhZ2UudHJpbSgpfX1cXG5gKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlIGluc3RhbmNlb2YgQWdncmVnYXRlRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGUuZXJyb3JzLmZvckVhY2goKGFnZ0UpID0+IHByb2Nlc3Muc3RkZXJyLndyaXRlKGNoYWxrYHtyZWQgJHthZ2dFLnN0YWNrID8/IGFnZ0V9fVxcbmApKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGNoYWxrYHtyZWQgJHtlLnN0YWNrID8/IGV9fVxcbmApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNsZWFudXBKb2JSZXNvdXJjZXMoam9icyk7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnVpbGRlcjogKHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB5XG4gICAgICAgICAgICAgICAgICAgIC5wb3NpdGlvbmFsKFwiam9iXCIsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaWJlOiBcIkpvYm5hbWUncyB0byBleGVjdXRlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLCAvLyBUeXBlIGhlcmUgaXMgcmVmZXJyaW5nIHRvIGVhY2ggZWxlbWVudCBvZiB0aGUgcG9zaXRpb25hbCBhcmdzXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC8vIGJ5IGRlZmF1bHQgeWFyZ3MncyBwb3NpdGlvbmFsIG9wdGlvbnMgKGFyZ3MpIGNhbiBiZSB1c2VkIGFzIG9wdGlvbnMgKGZsYWdzKSBzbyB0aGlzIGNvZXJjZSBpcyBzb2xlbHkgZm9yXG4gICAgICAgICAgICAgICAgICAgIC8vIGhhbmRsaW5nIHNjZW5hcmlvIHdoZW4gYSBzaW5nbGUgLS1qb2Igb3B0aW9uIGZsYWcgaXMgcGFzc2VkXG4gICAgICAgICAgICAgICAgICAgIC8vIE9uY2UgaHR0cHM6Ly9naXRodWIuY29tL3lhcmdzL3lhcmdzL2lzc3Vlcy8yMTk2IGlzIGltcGxlbWVudGVkLCB3ZSBjYW4gcHJvYmFibHkgcmVtb3ZlIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgLmNvZXJjZShcImpvYlwiLCAoYXJnczogc3RyaW5nW10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcmdzKSkgcmV0dXJuIFthcmdzXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcmdzO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21tYW5kOiBcIiQwIFtqb2IuLl1cIixcbiAgICAgICAgICAgIGRlc2NyaWJlOiBcIlJ1bnMgdGhlIGVudGlyZSBwaXBlbGluZSBvciBqb2Inc1wiLFxuICAgICAgICB9KVxuICAgICAgICAudXNhZ2UoXCJGaW5kIG1vcmUgaW5mb3JtYXRpb24gYXQgaHR0cHM6Ly9naXRodWIuY29tL2ZpcmVjb3cvZ2l0bGFiLWNpLWxvY2FsLlxcbk5vdGU6IFRvIG5lZ2F0ZSBhbiBvcHRpb24gdXNlICctLW5vLShvcHRpb24pJy5cIilcbiAgICAgICAgLnN0cmljdE9wdGlvbnMoKVxuICAgICAgICAuZW52KFwiR0NMXCIpXG4gICAgICAgIC5vcHRpb24oXCJtYW51YWxcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiT25lIG9yIG1vcmUgbWFudWFsIGpvYnMgdG8gcnVuIGR1cmluZyBhIHBpcGVsaW5lXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogdHJ1ZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImxpc3RcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaXN0IGpvYiBpbmZvcm1hdGlvbiwgd2hlbjpuZXZlciBleGNsdWRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibGlzdC1hbGxcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaXN0IGpvYiBpbmZvcm1hdGlvbiwgd2hlbjpuZXZlciBpbmNsdWRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibGlzdC1qc29uXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTGlzdCBqb2IgaW5mb3JtYXRpb24gaW4ganNvbiBmb3JtYXQsIHdoZW46bmV2ZXIgaW5jbHVkZWRcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImxpc3QtY3N2XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTGlzdCBqb2IgaW5mb3JtYXRpb24gaW4gY3N2IGZvcm1hdCwgd2hlbjpuZXZlciBleGNsdWRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwibGlzdC1jc3YtYWxsXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTGlzdCBqb2IgaW5mb3JtYXRpb24gaW4gY3N2IGZvcm1hdCwgd2hlbjpuZXZlciBpbmNsdWRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwidmFsaWRhdGUtZGVwZW5kZW5jeS1jaGFpblwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlZhbGlkYXRlIHRoYXQgam9icyBuZWVkZWQgb3IgZGVwZW5kZW50IGJ5IGFjdGl2ZSBqb2JzIHVuZGVyIHNwZWNpZmllZCBjb25kaXRpb25zIGFyZSBhbHNvIGFjdGl2ZSB3aXRob3V0IGFjdHVhbGx5IHJ1bm5pbmcgdGhlIGpvYnMuIFVzZXMgZmFpbC1mYXN0IGFwcHJvYWNoIC0gc3RvcHMgYXQgZmlyc3QgdmFsaWRhdGlvbiBlcnJvciBmb3IgYm90aCAnbmVlZHMnIGFuZCAnZGVwZW5kZW5jaWVzJyBrZXl3b3Jkcy4gSWYgdmFsaWRhdGlvbiBmYWlscywgdXNlIC0tbGlzdCBmbGFnIHRvIHNlZSB3aGljaCBqb2JzIHdpbGwgcnVuIHVuZGVyIHNwZWNpZmllZCBjb25kaXRpb25zXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJwcmV2aWV3XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUHJpbnQgWU1MIHdpdGggZGVmYXVsdHMsIGluY2x1ZGVzLCBleHRlbmRzIGFuZCByZWZlcmVuY2UncyBleHBhbmRlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiY3dkXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJQYXRoIHRvIGEgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ2YXJpYWJsZXMtZmlsZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUGF0aCB0byB0aGUgcHJvamVjdCBmaWxlIHZhcmlhYmxlc1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgICAgICBkZWZhdWx0OiBBcmd2LmRlZmF1bHQudmFyaWFibGVzRmlsZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbXBsZXRpb25cIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJHZW5lcmF0ZSB0YWIgY29tcGxldGlvbiBzY3JpcHRcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImV2YWx1YXRlLXJ1bGUtY2hhbmdlc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZXRoZXIgdG8gZXZhbHVhdGUgcnVsZTpjaGFuZ2VzLiBJZiBzZXQgdG8gZmFsc2UsIHJ1bGVzOmNoYW5nZXMgd2lsbCBhbHdheXMgZXZhbHVhdGUgdG8gdHJ1ZVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICAgICAgZGVmYXVsdDogQXJndi5kZWZhdWx0LmV2YWx1YXRlUnVsZUNoYW5nZXMsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJuZWVkc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1biBuZWVkZWQgam9icywgd2hlbiBleGVjdXRpbmcgc3BlY2lmaWMgam9ic1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwib25seS1uZWVkc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1biBuZWVkZWQgam9icywgZXhjZXB0IHRoZSBzcGVjaWZpZWQgam9icyB0aGVtc2VsdmVzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzdGFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiUnVuIGFsbCBqb2JzIGluIGEgc3BlY2lmaWMgc3RhZ2VcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInZhcmlhYmxlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkFkZCB2YXJpYWJsZSB0byBhbGwgZXhlY3V0ZWQgam9icyAoLS12YXJpYWJsZSBIRUxMTz13b3JsZClcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInVuc2V0LXZhcmlhYmxlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlVuc2V0cyBhIHZhcmlhYmxlICgtLXVuc2V0LXZhcmlhYmxlIEhFTExPKVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwicmVtb3RlLXZhcmlhYmxlc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiRmV0Y2ggdmFyaWFibGVzIGZpbGUgZnJvbSByZW1vdGUgbG9jYXRpb25cIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInN0YXRlLWRpclwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTG9jYXRpb24gb2YgdGhlIC5naXRsYWItY2ktbG9jYWwgc3RhdGUgZGlyLCByZWxhdGl2ZSB0byBjd2QsIGVnLiAoc3ltZm9ueS8uZ2l0bGFiLWNpLWxvY2FsLylcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImZpbGVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxvY2F0aW9uIG9mIHRoZSAuZ2l0bGFiLWNpLnltbCwgcmVsYXRpdmUgdG8gY3dkLCBlZy4gKGdpdGxhYi8uZ2l0bGFiLWNpLnltbClcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImhvbWVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkxvY2F0aW9uIG9mIHRoZSBIT01FIC5naXRsYWItY2ktbG9jYWwgZm9sZGVyICgkSE9NRS8uZ2l0bGFiLWNpLWxvY2FsL3ZhcmlhYmxlcy55bWwpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzaGVsbC1pc29sYXRpb25cIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJFbmFibGUgYXJ0aWZhY3QgaXNvbGF0aW9uIGZvciBzaGVsbC1leGVjdXRvciBqb2JzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJmb3JjZS1zaGVsbC1leGVjdXRvclwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkZvcmNlcyBhbGwgam9icyB0byBiZSBleGVjdXRlZCB1c2luZyB0aGUgc2hlbGwgZXhlY3V0b3IuIChPbmx5IHVzZSB0aGlzIG9wdGlvbiBmb3IgdHJ1c3RlZCBqb2IpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJzaGVsbC1leGVjdXRvci1uby1pbWFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZXRoZXIgdG8gdXNlIHNoZWxsIGV4ZWN1dG9yIHdoZW4gbm8gaW1hZ2UgaXMgc3BlY2lmaWVkLlwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiZGVmYXVsdC1pbWFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiV2hlbiB1c2luZyAtLXNoZWxsLWV4ZWN1dG9yLW5vLWltYWdlPWZhbHNlIHdoaWNoIGltYWdlIHRvIGJlIHVzZWQgZm9yIHRoZSBjb250YWluZXIuIERlZmF1bHRzIHRvIGRvY2tlci5pby9ydWJ5OjMuMSBpZiBub3Qgc2V0LlwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwid2FpdC1pbWFnZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiV2hpY2ggaW1hZ2UgdG8gYmUgdXNlZCBmb3IgdGhlIHdhaXQgY29udGFpbmVyLiBEZWZhdWx0cyB0byBkb2NrZXIuaW8vc3VtaW5hNDYvd2FpdC1mb3ItaXQ6bGF0ZXN0IGlmIG5vdCBzZXQuXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJoZWxwZXItaW1hZ2VcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIldoZW4gdXNpbmcgLS1zaGVsbC1leGVjdXRvci1uby1pbWFnZT1mYWxzZSB3aGljaCBpbWFnZSB0byBiZSB1c2VkIGZvciB0aGUgdXRpbHMgY29udGFpbmVyLiBEZWZhdWx0cyB0byBkb2NrZXIuaW8vZmlyZWNvdy9naXRsYWItY2ktbG9jYWwtdXRpbDpsYXRlc3QgaWYgbm90IHNldC5cIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcIm1vdW50LWNhY2hlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiRW5hYmxlIGRvY2tlciBtb3VudCBiYXNlZCBjYWNoaW5nXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ1bWFza1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlNldHMgZG9ja2VyIHVzZXIgdG8gMDowXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ1c2VybnNcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlNldCBkb2NrZXIgZXhlY3V0b3IgdXNlcm5zIG9wdGlvblwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwicHJpdmlsZWdlZFwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlNldCBkb2NrZXIgZXhlY3V0b3IgdG8gcHJpdmlsZWdlZCBtb2RlXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJkZXZpY2VcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQWRkIGRldmljZXMgdG8gZG9ja2VyIGV4ZWN1dG9yXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJ1bGltaXRcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlNldCBkb2NrZXIgZXhlY3V0b3IgdWxpbWl0XCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJuZXR3b3JrXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkFkZCBuZXR3b3JrcyB0byBkb2NrZXIgZXhlY3V0b3JcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInZvbHVtZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJBZGQgdm9sdW1lcyB0byBkb2NrZXIgZXhlY3V0b3JcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImV4dHJhLWhvc3RcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQWRkIGV4dHJhIGRvY2tlciBob3N0IGVudHJpZXNcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcInB1bGwtcG9saWN5XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTZXQgaW1hZ2UgcHVsbC1wb2xpY3kgKGFsd2F5cyBvciBpZi1ub3QtcHJlc2VudClcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImZldGNoLWluY2x1ZGVzXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiRmV0Y2ggYWxsIGV4dGVybmFsIGluY2x1ZGVzIG9uZSBtb3JlIHRpbWVcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcIm1heGltdW0taW5jbHVkZXNcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJudW1iZXJcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZSBtYXhpbXVtIG51bWJlciBvZiBpbmNsdWRlc1wiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiYXJ0aWZhY3RzLXRvLXNvdXJjZVwiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvcHkgdGhlIGdlbmVyYXRlZCBhcnRpZmFjdHMgaW50byBjd2RcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNsZWFudXBcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJSZW1vdmUgZG9ja2VyIHJlc291cmNlcyBhZnRlciB0aGV5J3ZlIGJlZW4gdXNlZFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwicXVpZXRcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJTdXBwcmVzcyBhbGwgam9iIG91dHB1dFwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwidGltZXN0YW1wc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlNob3cgdGltZXN0YW1wcyBhbmQgam9iIGR1cmF0aW9uIGluIHRoZSBsb2dzXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJtYXgtam9iLW5hbWUtcGFkZGluZ1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiTWF4aW11bSBwYWRkaW5nIGZvciBqb2IgbmFtZSAodXNlIDw9IDAgZm9yIG5vIHBhZGRpbmcpXCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIH0pXG4gICAgICAgIC5vcHRpb24oXCJqc29uLXNjaGVtYS12YWxpZGF0aW9uXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwiYm9vbGVhblwiLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiV2hldGhlciB0byBlbmFibGUganNvbiBzY2hlbWEgdmFsaWRhdGlvblwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiaWdub3JlLXNjaGVtYS1wYXRoc1wiLCB7XG4gICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgICAgICBkZWZhdWx0OiBBcmd2LmRlZmF1bHQuaWdub3JlU2NoZW1hUGF0aHMsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGUganNvbiBzY2hlbWEgcGF0aHMgdGhhdCB3aWxsIGJlIGlnbm9yZWRcIixcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbmN1cnJlbmN5XCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJMaW1pdCB0aGUgbnVtYmVyIG9mIGpvYnMgdGhhdCBydW4gc2ltdWx0YW5lb3VzbHlcIixcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbnRhaW5lci1leGVjdXRhYmxlXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJDb21tYW5kIHRvIHN0YXJ0IHRoZSBjb250YWluZXIgZW5naW5lIChkb2NrZXIgb3IgcG9kbWFuKVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiY29udGFpbmVyLW1hYy1hZGRyZXNzXCIsIHtcbiAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJDb250YWluZXIgTUFDIGFkZHJlc3MgKGUuZy4sIGFhOmJiOmNjOmRkOmVlOmZmKVwiLFxuICAgICAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAub3B0aW9uKFwiY29udGFpbmVyLWVtdWxhdGVcIiwge1xuICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZSBuYW1lLCB3aXRob3V0IHRoZSBhcmNoaXRlY3R1cmUsIG9mIGEgZ2l0bGFiIGhvc3RlZCBydW5uZXIgdG8gZW11bGF0ZS4gU2VlIGhlcmU6IGh0dHBzOi8vZG9jcy5naXRsYWIuY29tL2VlL2NpL3J1bm5lcnMvaG9zdGVkX3J1bm5lcnMvbGludXguaHRtbCNtYWNoaW5lLXR5cGVzLWF2YWlsYWJsZS1mb3ItbGludXgtLS14ODYtNjRcIixcbiAgICAgICAgICAgIGNob2ljZXM6IEdpdGxhYlJ1bm5lclByZXNldFZhbHVlcyxcbiAgICAgICAgfSlcbiAgICAgICAgLm9wdGlvbihcImNvbG9yXCIsIHtcbiAgICAgICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJFbmFibGVzIGNvbG9yXCIsXG4gICAgICAgIH0pXG4gICAgICAgIC5jb21wbGV0aW9uKFwiY29tcGxldGlvblwiLCBmYWxzZSwgKGN1cnJlbnQ6IHN0cmluZywgeWFyZ3NBcmd2OiBhbnksIGNvbXBsZXRpb25GaWx0ZXI6IGFueSwgZG9uZTogKGNvbXBsZXRpb25zOiBzdHJpbmdbXSkgPT4gYW55KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25GaWx0ZXIoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBBcmd2LmJ1aWxkKHsuLi55YXJnc0FyZ3YsIGF1dG9Db21wbGV0aW5nOiB0cnVlfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKGFyZ3YgPT4gc3RhdGUuZ2V0UGlwZWxpbmVJaWQoYXJndi5jd2QsIGFyZ3Yuc3RhdGVEaXIpLnRoZW4ocGlwZWxpbmVJaWQgPT4gKHthcmd2LCBwaXBlbGluZUlpZH0pKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCh7YXJndiwgcGlwZWxpbmVJaWR9KSA9PiBQYXJzZXIuY3JlYXRlKGFyZ3YsIG5ldyBXcml0ZVN0cmVhbXNNb2NrKCksIHBpcGVsaW5lSWlkLCBbXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigocGFyc2VyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgam9iTmFtZXMgPSBbLi4ucGFyc2VyLmpvYnMudmFsdWVzKCldLmZpbHRlcigoaikgPT4gai53aGVuICE9IFwibmV2ZXJcIikubWFwKChqKSA9PiBqLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoam9iTmFtZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcIlBhcnNlci1GYWlsZWQhXCJdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pXG4gICAgICAgIC5wYXJzZSgpO1xufSkoKTtcbiJdfQ==