gitlab-ci-local
Version:
Tired of pushing to test your .gitlab-ci.yml?
161 lines • 28.6 kB
JavaScript
import { Utils } from "./utils.js";
import assert, { AssertionError } from "assert";
import chalk from "chalk";
export class GitData {
user = {
GITLAB_USER_LOGIN: "local",
GITLAB_USER_EMAIL: "local@gitlab.com",
GITLAB_USER_NAME: "Bob Local",
GITLAB_USER_ID: "1000",
};
branches = {
default: "main",
};
remote = {
schema: "git",
port: "22",
host: "gitlab.com",
group: "fallback.group",
project: "fallback.project",
};
commit = {
REF_NAME: "main",
SHA: "0000000000000000000000000000000000000000",
SHORT_SHA: "00000000",
TIMESTAMP: new Date().toISOString().split(".")[0] + "Z",
};
static async init(cwd, writeStreams) {
const gitData = new GitData();
const promises = [];
promises.push(gitData.initCommitData(cwd, writeStreams));
promises.push(gitData.initRemoteData(cwd, writeStreams));
promises.push(gitData.initUserData(cwd, writeStreams));
promises.push(gitData.initBranchData(cwd, writeStreams));
await Promise.all(promises);
return gitData;
}
async initCommitData(cwd, writeStreams) {
const promises = [];
const refNamePromise = Utils.spawn(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd);
promises.push(refNamePromise.then(({ stdout }) => {
this.commit.REF_NAME = stdout.trimEnd();
}));
const shaPromise = Utils.spawn(["git", "rev-parse", "HEAD"], cwd);
promises.push(shaPromise.then(({ stdout }) => {
this.commit.SHA = stdout.trimEnd();
}));
try {
await Promise.all(promises);
}
catch (e) {
if (e instanceof AssertionError) {
return writeStreams.stderr(chalk `{yellow ${e.message}}\n`);
}
writeStreams.stderr(chalk `{yellow Using fallback git commit data}\n`);
}
}
async initBranchData(cwd, writeStreams) {
try {
const { stdout: gitRemoteDefaultBranch } = await Utils.spawn(["git", "symbolic-ref", "--short", "refs/remotes/origin/HEAD"], cwd);
this.branches.default = gitRemoteDefaultBranch.replace("origin/", "");
}
catch (e) {
if (e.stderr === "fatal: ref refs/remotes/origin/HEAD is not a symbolic ref") {
writeStreams.stderr(chalk `{yellow Unable to retrieve default remote branch, falling back to \`${this.branches.default}\`. The default remote branch can be set via \`git remote set-head origin <default_branch>\`}`);
}
else {
writeStreams.stderr(chalk `{yellow Unable to retrieve default remote branch, falling back to \`${this.branches.default}\`.\n}`);
}
}
}
static changedFiles(defaultBranch, cwd) {
return Utils.syncSpawn(["git", "diff", "--name-only", defaultBranch], cwd).stdout.split("\n");
}
async initRemoteData(cwd, writeStreams) {
try {
let gitRemoteMatch;
let gitRemote;
try {
// NOTE: For power user that wishes to customize the remote url
const res = await Utils.spawn(["git", "remote", "get-url", "gcl-origin"], cwd);
gitRemote = res.stdout;
}
catch {
const res = await Utils.spawn(["git", "remote", "get-url", "origin"], cwd);
gitRemote = res.stdout;
}
// To simplify the regex. Stripping the trailing `/` or `.git` since they're both optional.
const normalizedGitRemote = gitRemote
.replace(/\/$/, "")
.replace(/\.git$/, "");
if (normalizedGitRemote.startsWith("http")) {
gitRemoteMatch = /(?<schema>https?):\/\/(?:([^:]+):([^@]+)@)?(?<host>[^/:]+):?(?<port>\d+)?\/(?<group>\S+)\/(?<project>\S+)/.exec(normalizedGitRemote); // regexr.com/7ve8l
assert(gitRemoteMatch?.groups != null, "git remote get-url origin didn't provide valid matches");
let port = "443";
if (gitRemoteMatch.groups.schema === "https") {
port = gitRemoteMatch.groups.port ?? "443";
}
else if (gitRemoteMatch.groups.schema === "http") {
port = gitRemoteMatch.groups.port ?? "80";
}
this.remote.host = gitRemoteMatch.groups.host;
this.remote.group = gitRemoteMatch.groups.group;
this.remote.project = gitRemoteMatch.groups.project;
this.remote.schema = gitRemoteMatch.groups.schema;
this.remote.port = port;
}
else if (normalizedGitRemote.startsWith("ssh://")) {
gitRemoteMatch = /(?<schema>ssh):\/\/(\w+)@(?<host>[^/:]+):?(?<port>\d+)?\/(?<group>\S+)\/(?<project>\S+)/.exec(normalizedGitRemote); // regexr.com/7vjq4
assert(gitRemoteMatch?.groups != null, "git remote get-url origin didn't provide valid matches");
this.remote.host = gitRemoteMatch.groups.host;
this.remote.group = gitRemoteMatch.groups.group;
this.remote.project = gitRemoteMatch.groups.project;
this.remote.schema = gitRemoteMatch.groups.schema;
this.remote.port = gitRemoteMatch.groups.port ?? "22";
}
else {
gitRemoteMatch = /(?<username>\S+)@(?<host>[^:]+):(?<group>\S+)\/(?<project>\S+)/.exec(normalizedGitRemote); // regexr.com/7vjoq
assert(gitRemoteMatch?.groups != null, "git remote get-url origin didn't provide valid matches");
const { stdout } = await Utils.spawn(["ssh", "-G", `${gitRemoteMatch.groups.username}@${gitRemoteMatch.groups.host}`]);
const port = stdout.split("\n").filter((line) => line.startsWith("port "))[0].split(" ")[1];
this.remote.host = gitRemoteMatch.groups.host;
this.remote.group = gitRemoteMatch.groups.group;
this.remote.project = gitRemoteMatch.groups.project;
this.remote.schema = "git";
this.remote.port = port;
}
}
catch (e) {
if (e instanceof AssertionError) {
writeStreams.stderr(chalk `{yellow ${e.message}}\n`);
return;
}
writeStreams.stderr(chalk `{yellow Using fallback git remote data}\n`);
}
}
async initUserData(cwd, writeStreams) {
const promises = [];
const gitUsernamePromise = Utils.spawn(["git", "config", "user.name"], cwd).then(({ stdout }) => {
this.user.GITLAB_USER_NAME = stdout.trimEnd();
}).catch(() => {
writeStreams.stderr(chalk `{yellow Using fallback git user.name}\n`);
});
promises.push(gitUsernamePromise);
const gitEmailPromise = Utils.spawn(["git", "config", "user.email"], cwd).then(({ stdout }) => {
const email = stdout.trimEnd();
this.user.GITLAB_USER_EMAIL = email;
this.user.GITLAB_USER_LOGIN = email.replace(/@.*/, "");
}).catch(() => {
writeStreams.stderr(chalk `{yellow Using fallback git user.email}\n`);
});
promises.push(gitEmailPromise);
const osUidPromise = Utils.spawn(["id", "-u"], cwd).then(({ stdout }) => {
this.user.GITLAB_USER_ID = stdout.trimEnd();
}).catch(() => {
writeStreams.stderr(chalk `{yellow Using fallback linux user id}\n`);
});
promises.push(osUidPromise);
await Promise.all(promises);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0LWRhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJnaXQtZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ2pDLE9BQU8sTUFBTSxFQUFFLEVBQUMsY0FBYyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBRTlDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUkxQixNQUFNLE9BQU8sT0FBTztJQUVBLElBQUksR0FBRztRQUNuQixpQkFBaUIsRUFBRSxPQUFPO1FBQzFCLGlCQUFpQixFQUFFLGtCQUFrQjtRQUNyQyxnQkFBZ0IsRUFBRSxXQUFXO1FBQzdCLGNBQWMsRUFBRSxNQUFNO0tBQ3pCLENBQUM7SUFFYyxRQUFRLEdBQUc7UUFDdkIsT0FBTyxFQUFFLE1BQU07S0FDbEIsQ0FBQztJQUVjLE1BQU0sR0FBRztRQUNyQixNQUFNLEVBQUUsS0FBa0I7UUFDMUIsSUFBSSxFQUFFLElBQUk7UUFDVixJQUFJLEVBQUUsWUFBWTtRQUNsQixLQUFLLEVBQUUsZ0JBQWdCO1FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0I7S0FDOUIsQ0FBQztJQUVjLE1BQU0sR0FBRztRQUNyQixRQUFRLEVBQUUsTUFBTTtRQUNoQixHQUFHLEVBQUUsMENBQTBDO1FBQy9DLFNBQVMsRUFBRSxVQUFVO1FBQ3JCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO0tBQzFELENBQUM7SUFFRixNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDdEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM5QixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDcEIsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ3pELFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUN6RCxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDdkQsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1QixPQUFPLE9BQU8sQ0FBQztJQUNuQixDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWMsQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDakUsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBRXBCLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0RixRQUFRLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBQyxFQUFFLEVBQUU7WUFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFSixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNsRSxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBQyxFQUFFLEVBQUU7WUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFSixJQUFJLENBQUM7WUFDRCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsWUFBWSxjQUFjLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSxXQUFXLENBQUMsQ0FBQyxPQUFPLEtBQUssQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFDRCxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSwyQ0FBMkMsQ0FBQyxDQUFDO1FBQzFFLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWMsQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDakUsSUFBSSxDQUFDO1lBQ0QsTUFBTSxFQUFDLE1BQU0sRUFBRSxzQkFBc0IsRUFBQyxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsU0FBUyxFQUFFLDBCQUEwQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEdBQUcsc0JBQXNCLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSywyREFBMkQsRUFBRSxDQUFDO2dCQUMzRSxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSx1RUFBdUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLCtGQUErRixDQUFDLENBQUM7WUFDMU4sQ0FBQztpQkFBTSxDQUFDO2dCQUNKLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFBLHVFQUF1RSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sUUFBUSxDQUFDLENBQUM7WUFDbkksQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxDQUFDLFlBQVksQ0FBRSxhQUFxQixFQUFFLEdBQVc7UUFDbkQsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsRyxDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWMsQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDakUsSUFBSSxDQUFDO1lBQ0QsSUFBSSxjQUFjLENBQUM7WUFDbkIsSUFBSSxTQUFTLENBQUM7WUFDZCxJQUFJLENBQUM7Z0JBQ0QsK0RBQStEO2dCQUMvRCxNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxZQUFZLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDL0UsU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDM0IsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDTCxNQUFNLEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDM0UsU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDM0IsQ0FBQztZQUVELDJGQUEyRjtZQUMzRixNQUFNLG1CQUFtQixHQUFHLFNBQVM7aUJBQ2hDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO2lCQUNsQixPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRTNCLElBQUksbUJBQW1CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLGNBQWMsR0FBRywyR0FBMkcsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLG1CQUFtQjtnQkFDM0ssTUFBTSxDQUFDLGNBQWMsRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLHdEQUF3RCxDQUFDLENBQUM7Z0JBRWpHLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztnQkFDakIsSUFBSSxjQUFjLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxPQUFPLEVBQUUsQ0FBQztvQkFDM0MsSUFBSSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQztnQkFDL0MsQ0FBQztxQkFBTSxJQUFJLGNBQWMsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUNqRCxJQUFJLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDO2dCQUM5QyxDQUFDO2dCQUNELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztnQkFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsTUFBbUIsQ0FBQztnQkFDL0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQzVCLENBQUM7aUJBQU0sSUFBSSxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDbEQsY0FBYyxHQUFHLHlGQUF5RixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsbUJBQW1CO2dCQUN6SixNQUFNLENBQUMsY0FBYyxFQUFFLE1BQU0sSUFBSSxJQUFJLEVBQUUsd0RBQXdELENBQUMsQ0FBQztnQkFFakcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztnQkFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxNQUFtQixDQUFDO2dCQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUM7WUFDMUQsQ0FBQztpQkFBTSxDQUFDO2dCQUNKLGNBQWMsR0FBRyxnRUFBZ0UsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLG1CQUFtQjtnQkFDaEksTUFBTSxDQUFDLGNBQWMsRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLHdEQUF3RCxDQUFDLENBQUM7Z0JBRWpHLE1BQU0sRUFBQyxNQUFNLEVBQUMsR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JILE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM1RixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO2dCQUNwRCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztZQUM1QixDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDVCxJQUFJLENBQUMsWUFBWSxjQUFjLEVBQUUsQ0FBQztnQkFDOUIsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUEsV0FBVyxDQUFDLENBQUMsT0FBTyxLQUFLLENBQUMsQ0FBQztnQkFDcEQsT0FBTztZQUNYLENBQUM7WUFDRCxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSwyQ0FBMkMsQ0FBQyxDQUFDO1FBQzFFLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDdkQsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBRXBCLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsV0FBVyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBQyxNQUFNLEVBQUMsRUFBRSxFQUFFO1lBQzFGLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xELENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDVixZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSx5Q0FBeUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRWxDLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUMsTUFBTSxFQUFDLEVBQUUsRUFBRTtZQUN4RixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7WUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO1lBQ1YsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUEsMENBQTBDLENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FBQztRQUNILFFBQVEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFL0IsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLE1BQU0sRUFBQyxFQUFFLEVBQUU7WUFDbEUsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDVixZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQSx5Q0FBeUMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUU1QixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDaEMsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtVdGlsc30gZnJvbSBcIi4vdXRpbHMuanNcIjtcbmltcG9ydCBhc3NlcnQsIHtBc3NlcnRpb25FcnJvcn0gZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHtXcml0ZVN0cmVhbXN9IGZyb20gXCIuL3dyaXRlLXN0cmVhbXMuanNcIjtcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcblxuZXhwb3J0IHR5cGUgR2l0U2NoZW1hID0gXCJnaXRcIiB8IFwiaHR0cFwiIHwgXCJodHRwc1wiIHwgXCJzc2hcIjtcblxuZXhwb3J0IGNsYXNzIEdpdERhdGEge1xuXG4gICAgcHVibGljIHJlYWRvbmx5IHVzZXIgPSB7XG4gICAgICAgIEdJVExBQl9VU0VSX0xPR0lOOiBcImxvY2FsXCIsXG4gICAgICAgIEdJVExBQl9VU0VSX0VNQUlMOiBcImxvY2FsQGdpdGxhYi5jb21cIixcbiAgICAgICAgR0lUTEFCX1VTRVJfTkFNRTogXCJCb2IgTG9jYWxcIixcbiAgICAgICAgR0lUTEFCX1VTRVJfSUQ6IFwiMTAwMFwiLFxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgYnJhbmNoZXMgPSB7XG4gICAgICAgIGRlZmF1bHQ6IFwibWFpblwiLFxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgcmVtb3RlID0ge1xuICAgICAgICBzY2hlbWE6IFwiZ2l0XCIgYXMgR2l0U2NoZW1hLFxuICAgICAgICBwb3J0OiBcIjIyXCIsXG4gICAgICAgIGhvc3Q6IFwiZ2l0bGFiLmNvbVwiLFxuICAgICAgICBncm91cDogXCJmYWxsYmFjay5ncm91cFwiLFxuICAgICAgICBwcm9qZWN0OiBcImZhbGxiYWNrLnByb2plY3RcIixcbiAgICB9O1xuXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbW1pdCA9IHtcbiAgICAgICAgUkVGX05BTUU6IFwibWFpblwiLFxuICAgICAgICBTSEE6IFwiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMFwiLFxuICAgICAgICBTSE9SVF9TSEE6IFwiMDAwMDAwMDBcIixcbiAgICAgICAgVElNRVNUQU1QOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzBdICsgXCJaXCIsXG4gICAgfTtcblxuICAgIHN0YXRpYyBhc3luYyBpbml0IChjd2Q6IHN0cmluZywgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMpOiBQcm9taXNlPEdpdERhdGE+IHtcbiAgICAgICAgY29uc3QgZ2l0RGF0YSA9IG5ldyBHaXREYXRhKCk7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgIHByb21pc2VzLnB1c2goZ2l0RGF0YS5pbml0Q29tbWl0RGF0YShjd2QsIHdyaXRlU3RyZWFtcykpO1xuICAgICAgICBwcm9taXNlcy5wdXNoKGdpdERhdGEuaW5pdFJlbW90ZURhdGEoY3dkLCB3cml0ZVN0cmVhbXMpKTtcbiAgICAgICAgcHJvbWlzZXMucHVzaChnaXREYXRhLmluaXRVc2VyRGF0YShjd2QsIHdyaXRlU3RyZWFtcykpO1xuICAgICAgICBwcm9taXNlcy5wdXNoKGdpdERhdGEuaW5pdEJyYW5jaERhdGEoY3dkLCB3cml0ZVN0cmVhbXMpKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICByZXR1cm4gZ2l0RGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGluaXRDb21taXREYXRhIChjd2Q6IHN0cmluZywgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblxuICAgICAgICBjb25zdCByZWZOYW1lUHJvbWlzZSA9IFV0aWxzLnNwYXduKFtcImdpdFwiLCBcInJldi1wYXJzZVwiLCBcIi0tYWJicmV2LXJlZlwiLCBcIkhFQURcIl0sIGN3ZCk7XG4gICAgICAgIHByb21pc2VzLnB1c2gocmVmTmFtZVByb21pc2UudGhlbigoe3N0ZG91dH0pID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29tbWl0LlJFRl9OQU1FID0gc3Rkb3V0LnRyaW1FbmQoKTtcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IHNoYVByb21pc2UgPSBVdGlscy5zcGF3bihbXCJnaXRcIiwgXCJyZXYtcGFyc2VcIiwgXCJIRUFEXCJdLCBjd2QpO1xuICAgICAgICBwcm9taXNlcy5wdXNoKHNoYVByb21pc2UudGhlbigoe3N0ZG91dH0pID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29tbWl0LlNIQSA9IHN0ZG91dC50cmltRW5kKCk7XG4gICAgICAgIH0pKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEFzc2VydGlvbkVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlU3RyZWFtcy5zdGRlcnIoY2hhbGtge3llbGxvdyAke2UubWVzc2FnZX19XFxuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3cml0ZVN0cmVhbXMuc3RkZXJyKGNoYWxrYHt5ZWxsb3cgVXNpbmcgZmFsbGJhY2sgZ2l0IGNvbW1pdCBkYXRhfVxcbmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBpbml0QnJhbmNoRGF0YSAoY3dkOiBzdHJpbmcsIHdyaXRlU3RyZWFtczogV3JpdGVTdHJlYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7c3Rkb3V0OiBnaXRSZW1vdGVEZWZhdWx0QnJhbmNofSA9IGF3YWl0IFV0aWxzLnNwYXduKFtcImdpdFwiLCBcInN5bWJvbGljLXJlZlwiLCBcIi0tc2hvcnRcIiwgXCJyZWZzL3JlbW90ZXMvb3JpZ2luL0hFQURcIl0sIGN3ZCk7XG4gICAgICAgICAgICB0aGlzLmJyYW5jaGVzLmRlZmF1bHQgPSBnaXRSZW1vdGVEZWZhdWx0QnJhbmNoLnJlcGxhY2UoXCJvcmlnaW4vXCIsIFwiXCIpO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGlmIChlLnN0ZGVyciA9PT0gXCJmYXRhbDogcmVmIHJlZnMvcmVtb3Rlcy9vcmlnaW4vSEVBRCBpcyBub3QgYSBzeW1ib2xpYyByZWZcIikge1xuICAgICAgICAgICAgICAgIHdyaXRlU3RyZWFtcy5zdGRlcnIoY2hhbGtge3llbGxvdyBVbmFibGUgdG8gcmV0cmlldmUgZGVmYXVsdCByZW1vdGUgYnJhbmNoLCBmYWxsaW5nIGJhY2sgdG8gXFxgJHt0aGlzLmJyYW5jaGVzLmRlZmF1bHR9XFxgLiBUaGUgZGVmYXVsdCByZW1vdGUgYnJhbmNoIGNhbiBiZSBzZXQgdmlhIFxcYGdpdCByZW1vdGUgc2V0LWhlYWQgb3JpZ2luIDxkZWZhdWx0X2JyYW5jaD5cXGB9YCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdyaXRlU3RyZWFtcy5zdGRlcnIoY2hhbGtge3llbGxvdyBVbmFibGUgdG8gcmV0cmlldmUgZGVmYXVsdCByZW1vdGUgYnJhbmNoLCBmYWxsaW5nIGJhY2sgdG8gXFxgJHt0aGlzLmJyYW5jaGVzLmRlZmF1bHR9XFxgLlxcbn1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBjaGFuZ2VkRmlsZXMgKGRlZmF1bHRCcmFuY2g6IHN0cmluZywgY3dkOiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIFV0aWxzLnN5bmNTcGF3bihbXCJnaXRcIiwgXCJkaWZmXCIsIFwiLS1uYW1lLW9ubHlcIiwgZGVmYXVsdEJyYW5jaF0sIGN3ZCkuc3Rkb3V0LnNwbGl0KFwiXFxuXCIpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgaW5pdFJlbW90ZURhdGEgKGN3ZDogc3RyaW5nLCB3cml0ZVN0cmVhbXM6IFdyaXRlU3RyZWFtcyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGdpdFJlbW90ZU1hdGNoO1xuICAgICAgICAgICAgbGV0IGdpdFJlbW90ZTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gTk9URTogRm9yIHBvd2VyIHVzZXIgdGhhdCB3aXNoZXMgdG8gY3VzdG9taXplIHRoZSByZW1vdGUgdXJsXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgVXRpbHMuc3Bhd24oW1wiZ2l0XCIsIFwicmVtb3RlXCIsIFwiZ2V0LXVybFwiLCBcImdjbC1vcmlnaW5cIl0sIGN3ZCk7XG4gICAgICAgICAgICAgICAgZ2l0UmVtb3RlID0gcmVzLnN0ZG91dDtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IFV0aWxzLnNwYXduKFtcImdpdFwiLCBcInJlbW90ZVwiLCBcImdldC11cmxcIiwgXCJvcmlnaW5cIl0sIGN3ZCk7XG4gICAgICAgICAgICAgICAgZ2l0UmVtb3RlID0gcmVzLnN0ZG91dDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVG8gc2ltcGxpZnkgdGhlIHJlZ2V4LiBTdHJpcHBpbmcgdGhlIHRyYWlsaW5nIGAvYCBvciBgLmdpdGAgc2luY2UgdGhleSdyZSBib3RoIG9wdGlvbmFsLlxuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZEdpdFJlbW90ZSA9IGdpdFJlbW90ZVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXC8kLywgXCJcIilcbiAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFwuZ2l0JC8sIFwiXCIpO1xuXG4gICAgICAgICAgICBpZiAobm9ybWFsaXplZEdpdFJlbW90ZS5zdGFydHNXaXRoKFwiaHR0cFwiKSkge1xuICAgICAgICAgICAgICAgIGdpdFJlbW90ZU1hdGNoID0gLyg/PHNjaGVtYT5odHRwcz8pOlxcL1xcLyg/OihbXjpdKyk6KFteQF0rKUApPyg/PGhvc3Q+W14vOl0rKTo/KD88cG9ydD5cXGQrKT9cXC8oPzxncm91cD5cXFMrKVxcLyg/PHByb2plY3Q+XFxTKykvLmV4ZWMobm9ybWFsaXplZEdpdFJlbW90ZSk7IC8vIHJlZ2V4ci5jb20vN3ZlOGxcbiAgICAgICAgICAgICAgICBhc3NlcnQoZ2l0UmVtb3RlTWF0Y2g/Lmdyb3VwcyAhPSBudWxsLCBcImdpdCByZW1vdGUgZ2V0LXVybCBvcmlnaW4gZGlkbid0IHByb3ZpZGUgdmFsaWQgbWF0Y2hlc1wiKTtcblxuICAgICAgICAgICAgICAgIGxldCBwb3J0ID0gXCI0NDNcIjtcbiAgICAgICAgICAgICAgICBpZiAoZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLnNjaGVtYSA9PT0gXCJodHRwc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHBvcnQgPSBnaXRSZW1vdGVNYXRjaC5ncm91cHMucG9ydCA/PyBcIjQ0M1wiO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLnNjaGVtYSA9PT0gXCJodHRwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9ydCA9IGdpdFJlbW90ZU1hdGNoLmdyb3Vwcy5wb3J0ID8/IFwiODBcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGUuaG9zdCA9IGdpdFJlbW90ZU1hdGNoLmdyb3Vwcy5ob3N0O1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLmdyb3VwID0gZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLmdyb3VwO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLnByb2plY3QgPSBnaXRSZW1vdGVNYXRjaC5ncm91cHMucHJvamVjdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZS5zY2hlbWEgPSBnaXRSZW1vdGVNYXRjaC5ncm91cHMuc2NoZW1hIGFzIEdpdFNjaGVtYTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZS5wb3J0ID0gcG9ydDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm9ybWFsaXplZEdpdFJlbW90ZS5zdGFydHNXaXRoKFwic3NoOi8vXCIpKSB7XG4gICAgICAgICAgICAgICAgZ2l0UmVtb3RlTWF0Y2ggPSAvKD88c2NoZW1hPnNzaCk6XFwvXFwvKFxcdyspQCg/PGhvc3Q+W14vOl0rKTo/KD88cG9ydD5cXGQrKT9cXC8oPzxncm91cD5cXFMrKVxcLyg/PHByb2plY3Q+XFxTKykvLmV4ZWMobm9ybWFsaXplZEdpdFJlbW90ZSk7IC8vIHJlZ2V4ci5jb20vN3ZqcTRcbiAgICAgICAgICAgICAgICBhc3NlcnQoZ2l0UmVtb3RlTWF0Y2g/Lmdyb3VwcyAhPSBudWxsLCBcImdpdCByZW1vdGUgZ2V0LXVybCBvcmlnaW4gZGlkbid0IHByb3ZpZGUgdmFsaWQgbWF0Y2hlc1wiKTtcblxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLmhvc3QgPSBnaXRSZW1vdGVNYXRjaC5ncm91cHMuaG9zdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZS5ncm91cCA9IGdpdFJlbW90ZU1hdGNoLmdyb3Vwcy5ncm91cDtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZS5wcm9qZWN0ID0gZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLnByb2plY3Q7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGUuc2NoZW1hID0gZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLnNjaGVtYSBhcyBHaXRTY2hlbWE7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGUucG9ydCA9IGdpdFJlbW90ZU1hdGNoLmdyb3Vwcy5wb3J0ID8/IFwiMjJcIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZ2l0UmVtb3RlTWF0Y2ggPSAvKD88dXNlcm5hbWU+XFxTKylAKD88aG9zdD5bXjpdKyk6KD88Z3JvdXA+XFxTKylcXC8oPzxwcm9qZWN0PlxcUyspLy5leGVjKG5vcm1hbGl6ZWRHaXRSZW1vdGUpOyAvLyByZWdleHIuY29tLzd2am9xXG4gICAgICAgICAgICAgICAgYXNzZXJ0KGdpdFJlbW90ZU1hdGNoPy5ncm91cHMgIT0gbnVsbCwgXCJnaXQgcmVtb3RlIGdldC11cmwgb3JpZ2luIGRpZG4ndCBwcm92aWRlIHZhbGlkIG1hdGNoZXNcIik7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB7c3Rkb3V0fSA9IGF3YWl0IFV0aWxzLnNwYXduKFtcInNzaFwiLCBcIi1HXCIsIGAke2dpdFJlbW90ZU1hdGNoLmdyb3Vwcy51c2VybmFtZX1AJHtnaXRSZW1vdGVNYXRjaC5ncm91cHMuaG9zdH1gXSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcG9ydCA9IHN0ZG91dC5zcGxpdChcIlxcblwiKS5maWx0ZXIoKGxpbmUpID0+IGxpbmUuc3RhcnRzV2l0aChcInBvcnQgXCIpKVswXS5zcGxpdChcIiBcIilbMV07XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGUuaG9zdCA9IGdpdFJlbW90ZU1hdGNoLmdyb3Vwcy5ob3N0O1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLmdyb3VwID0gZ2l0UmVtb3RlTWF0Y2guZ3JvdXBzLmdyb3VwO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLnByb2plY3QgPSBnaXRSZW1vdGVNYXRjaC5ncm91cHMucHJvamVjdDtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZS5zY2hlbWEgPSBcImdpdFwiO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlLnBvcnQgPSBwb3J0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIEFzc2VydGlvbkVycm9yKSB7XG4gICAgICAgICAgICAgICAgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7eWVsbG93ICR7ZS5tZXNzYWdlfX1cXG5gKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3cml0ZVN0cmVhbXMuc3RkZXJyKGNoYWxrYHt5ZWxsb3cgVXNpbmcgZmFsbGJhY2sgZ2l0IHJlbW90ZSBkYXRhfVxcbmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgaW5pdFVzZXJEYXRhIChjd2Q6IHN0cmluZywgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblxuICAgICAgICBjb25zdCBnaXRVc2VybmFtZVByb21pc2UgPSBVdGlscy5zcGF3bihbXCJnaXRcIiwgXCJjb25maWdcIiwgXCJ1c2VyLm5hbWVcIl0sIGN3ZCkudGhlbigoe3N0ZG91dH0pID0+IHtcbiAgICAgICAgICAgIHRoaXMudXNlci5HSVRMQUJfVVNFUl9OQU1FID0gc3Rkb3V0LnRyaW1FbmQoKTtcbiAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7eWVsbG93IFVzaW5nIGZhbGxiYWNrIGdpdCB1c2VyLm5hbWV9XFxuYCk7XG4gICAgICAgIH0pO1xuICAgICAgICBwcm9taXNlcy5wdXNoKGdpdFVzZXJuYW1lUHJvbWlzZSk7XG5cbiAgICAgICAgY29uc3QgZ2l0RW1haWxQcm9taXNlID0gVXRpbHMuc3Bhd24oW1wiZ2l0XCIsIFwiY29uZmlnXCIsIFwidXNlci5lbWFpbFwiXSwgY3dkKS50aGVuKCh7c3Rkb3V0fSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW1haWwgPSBzdGRvdXQudHJpbUVuZCgpO1xuICAgICAgICAgICAgdGhpcy51c2VyLkdJVExBQl9VU0VSX0VNQUlMID0gZW1haWw7XG4gICAgICAgICAgICB0aGlzLnVzZXIuR0lUTEFCX1VTRVJfTE9HSU4gPSBlbWFpbC5yZXBsYWNlKC9ALiovLCBcIlwiKTtcbiAgICAgICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7eWVsbG93IFVzaW5nIGZhbGxiYWNrIGdpdCB1c2VyLmVtYWlsfVxcbmApO1xuICAgICAgICB9KTtcbiAgICAgICAgcHJvbWlzZXMucHVzaChnaXRFbWFpbFByb21pc2UpO1xuXG4gICAgICAgIGNvbnN0IG9zVWlkUHJvbWlzZSA9IFV0aWxzLnNwYXduKFtcImlkXCIsIFwiLXVcIl0sIGN3ZCkudGhlbigoe3N0ZG91dH0pID0+IHtcbiAgICAgICAgICAgIHRoaXMudXNlci5HSVRMQUJfVVNFUl9JRCA9IHN0ZG91dC50cmltRW5kKCk7XG4gICAgICAgIH0pLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIHdyaXRlU3RyZWFtcy5zdGRlcnIoY2hhbGtge3llbGxvdyBVc2luZyBmYWxsYmFjayBsaW51eCB1c2VyIGlkfVxcbmApO1xuICAgICAgICB9KTtcbiAgICAgICAgcHJvbWlzZXMucHVzaChvc1VpZFByb21pc2UpO1xuXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICB9XG59XG4iXX0=