UNPKG

gitlab-ci-local

Version:

Tired of pushing to test your .gitlab-ci.yml?

161 lines 28.6 kB
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0LWRhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJnaXQtZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ2pDLE9BQU8sTUFBTSxFQUFFLEVBQUMsY0FBYyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBRTlDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUkxQixNQUFNLE9BQU8sT0FBTztJQUVBLElBQUksR0FBRztRQUNuQixpQkFBaUIsRUFBRSxPQUFPO1FBQzFCLGlCQUFpQixFQUFFLGtCQUFrQjtRQUNyQyxnQkFBZ0IsRUFBRSxXQUFXO1FBQzdCLGNBQWMsRUFBRSxNQUFNO0tBQ3pCLENBQUM7SUFFYyxRQUFRLEdBQUc7UUFDdkIsT0FBTyxFQUFFLE1BQU07S0FDbEIsQ0FBQztJQUVjLE1BQU0sR0FBRztRQUNyQixNQUFNLEVBQUUsS0FBa0I7UUFDMUIsSUFBSSxFQUFFLElBQUk7UUFDVixJQUFJLEVBQUUsWUFBWTtRQUNsQixLQUFLLEVBQUUsZ0JBQWdCO1FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0I7S0FDOUIsQ0FBQztJQUVjLE1BQU0sR0FBRztRQUNyQixRQUFRLEVBQUUsTUFBTTtRQUNoQixHQUFHLEVBQUUsMENBQTBDO1FBQy9DLFNBQVMsRUFBRSxVQUFVO1FBQ3JCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHO0tBQzFELENBQUM7SUFFRixNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBRSxHQUFXLEVBQUUsWUFBMEI7UUFDdEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM5QixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDcEIsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEdB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c3NlcnQsIHtBc3NlcnRpb25FcnJvcn0gZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHtXcml0ZVN0cmVhbXN9IGZyb20gXCIuL3dyaXRlLXN0cmVhbXMuanNcIjtcbmltcG9ydCBjaGFsayBmcm9tIFwiY2hhbGtcIjtcblxuZXhwb3J0IHR5cGUgR2l0U2NoZW1hID0gXCJnaXRcIiB8IFwiaHR0cFwiIHwgXCJodHRwc1wiIHwgXCJzc2hcIjtcblxuZXhwb3J0IGNsYXNzIEdpdERhdGEge1xuXG4gICAgcHVibGljIHJlYWRvbmx5IHVzZXIgPSB7XG4gICAgICAgIEdJVExBQl9VU0VSX0xPR0lOOiBcImxvY2FsXCIsXG4gICAgICAgIEdJVExBQl9VU0VSX0VNQUlMOiBcImxvY2FsQGdpdGxhYi5jb21cIixcbiAgICAgICAgR0lUTEFCX1VTRVJfTkFNRTogXCJCb2IgTG9jYWxcIixcbiAgICAgICAgR0lUTEFCX1VTRVJfSUQ6IFwiMTAwMFwiLFxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgYnJhbmNoZXMgPSB7XG4gICAgICAgIGRlZmF1bHQ6IFwibWFpblwiLFxuICAgIH07XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgcmVtb3RlID0ge1xuICAgICAgICBzY2hlbWE6IFwiZ2l0XCIgYXMgR2l0U2NoZW1hLFxuICAgICAgICBwb3J0OiBcIjIyXCIsXG4gICAgICAgIGhvc3Q6IFwiZ2l0bGFiLmNvbVwiLFxuICAgICAgICBncm91cDogXCJmYWxsYmFjay5ncm91cFwiLFxuICAgICAgICBwcm9qZWN0OiBcImZhbGxiYWNrLnByb2plY3RcIixcbiAgICB9O1xuXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbW1pdCA9IHtcbiAgICAgICAgUkVGX05BTUU6IFwibWFpblwiLFxuICAgICAgICBTSEE6IFwiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMFwiLFxuICAgICAgICBTSE9SVF9TSEE6IFwiMDAwMDAwMDBcIixcbiAgICAgICAgVElNRVNUQU1QOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzBdICsgXCJaXCIsXG4gICAgfTtcblxuICAgIHN0YXRpYyBhc3luYyBpbml0IChjd2Q6IHN0cmluZywgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMpOiBQcm9taXNlPEdpdERhdGE+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=