UNPKG

@rnm/pm

Version:

Unified Package Manager for Node.js

111 lines 18.8 kB
import childProcess from "node:child_process"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import process from "node:process"; import { fileURLToPath } from "node:url"; import { styleText } from "node:util"; import corepackPkgJson from "corepack/package.json" with { type: "json" }; import semver from "semver"; import { getPackageJson } from "./common.js"; import { defaultVersions, executorMap } from "./constants.js"; import { fetchPmVersions } from "./utils/fetch-pm-versions.js"; import { getCorepackHome } from "./utils/get-corepack-home.js"; import { registryUrl } from "./utils/registry-url.js"; /** * @returns Absolute path to corepack binary. */ function getCorepackPath() { const corepackPkgJsonPath = fileURLToPath(import.meta.resolve("corepack/package.json")); return path.resolve(path.dirname(corepackPkgJsonPath), corepackPkgJson.bin.corepack); } async function getCommand(detectResult, args, execute) { const { name, version } = await getExecutingPmAndVersion(detectResult); const executor = execute ? executorMap[name] : name; return [`${executor}@${version}`, ...args]; } export async function run(detectResult, args, execute) { const command = await getCommand(detectResult, args, execute); const cp = childProcess.spawn(process.execPath, [getCorepackPath(), ...command], { stdio: "inherit", env: { COREPACK_DEFAULT_TO_LATEST: "0", COREPACK_ENV_FILE: "0", COREPACK_NPM_REGISTRY: registryUrl(), // TODO: Remove this env when https://github.com/nodejs/corepack/issues/540 is resolved. ...Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith("COREPACK_"))), }, }); const listener = (signal) => !cp.killed && cp.kill(signal); process.on("SIGINT", listener); process.on("SIGTERM", listener); return await new Promise((resolve, reject) => { cp.on("error", (err) => { reject(err); }); cp.on("close", (code, signal) => { resolve(code ?? (signal !== null ? 128 + os.constants.signals[signal] : 1)); }); }); } export async function getMsg(detectResult, args, execute) { const command = await getCommand(detectResult, args, execute); const [name, version] = command[0].split("@"); // name and version must be string. If statement below is not needed, but it's for type safety. if (!name || !version) { throw new Error("Internal error: `name` or `version` not found."); } const pmName = name in executorMap ? name : Object.fromEntries(Object.entries(executorMap).map(([k, v]) => [v, k]))[name]; if (!pmName) { throw new Error("Internal error: `pmName` not found."); } const nameVer = `[${pmName}@${version}]`; const packageJson = await getPackageJson(); const info = `(pm@${packageJson.version})`; return [ "📦", `${styleText("bold", nameVer)}${styleText("dim", info)}`, "➜", styleText("blue", [name, ...command.slice(1)].join(" ")), ].join(" "); } async function getDownloadedVersions(pm) { const pmFolder = path.join(getCorepackHome(), pm); return (await fs.readdir(pmFolder).catch(() => [])) .filter((file) => semver.valid(file)) .sort((x, y) => semver.compare(y, x)); // desc } async function getRemoteVersions(pm) { return (await fetchPmVersions(pm)) .filter((version) => semver.valid(version)) .sort((x, y) => semver.compare(y, x)); // desc } async function getExecutingPmAndVersion(detectResult) { const { name = "npm" } = detectResult ?? {}; const { version = defaultVersions[name] } = detectResult ?? {}; // 1. If version is valid, return it. if (semver.valid(version)) { return { name, version }; } if (semver.validRange(version)) { // 2. Try to find the version in the downloaded versions. const downloadedVersions = await getDownloadedVersions(name); for (const downloadedVersion of downloadedVersions) { if (semver.satisfies(downloadedVersion, version)) { return { name, version: downloadedVersion }; } } // 3. Try to find the version in the remote versions. const remoteVersions = await getRemoteVersions(name); for (const remoteVersion of remoteVersions) { if (semver.satisfies(remoteVersion, version)) { return { name, version: remoteVersion }; } } throw new Error(`No package manager version found that satisfies '${version}'. The specified version range may not exist or is unavailable from ${registryUrl()}.`); } // 4. Return the default version. return { name, version }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sWUFBWSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN0QyxPQUFPLGVBQWUsTUFBTSx1QkFBdUIsQ0FBQyxPQUFPLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUMxRSxPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLFdBQVcsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUV0RDs7R0FFRztBQUNILFNBQVMsZUFBZTtJQUN0QixNQUFNLG1CQUFtQixHQUFHLGFBQWEsQ0FDdkMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FDN0MsQ0FBQztJQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FDakIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxFQUNqQyxlQUFlLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FDN0IsQ0FBQztBQUNKLENBQUM7QUFFRCxLQUFLLFVBQVUs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QUFDLENBQUM7UUFDN0QsS0FBSyxNQUFNLGlCQUFpQixJQUFJLGtCQUFrQixFQUFFLENBQUM7WUFDbkQsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ2pELE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLENBQUM7WUFDOUMsQ0FBQztRQUNILENBQUM7UUFDRCxxREFBcUQ7UUFDckQsTUFBTSxjQUFjLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyRCxLQUFLLE1BQU0sYUFBYSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQzNDLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDN0MsT0FBTyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLENBQUM7WUFDMUMsQ0FBQztRQUNILENBQUM7UUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLG9EQUFvRCxPQUFPLHVFQUF1RSxXQUFXLEVBQUUsR0FBRyxDQUNuSixDQUFDO0lBQ0osQ0FBQztJQUNELGlDQUFpQztJQUNqQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2hpbGRQcm9jZXNzIGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IG9zIGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgcHJvY2VzcyBmcm9tIFwibm9kZTpwcm9jZXNzXCI7XG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcIm5vZGU6dXJsXCI7XG5pbXBvcnQgeyBzdHlsZVRleHQgfSBmcm9tIFwibm9kZTp1dGlsXCI7XG5pbXBvcnQgY29yZXBhY2tQa2dKc29uIGZyb20gXCJjb3JlcGFjay9wYWNrYWdlLmpzb25cIiB3aXRoIHsgdHlwZTogXCJqc29uXCIgfTtcbmltcG9ydCBzZW12ZXIgZnJvbSBcInNlbXZlclwiO1xuaW1wb3J0IHsgZ2V0UGFja2FnZUpzb24gfSBmcm9tIFwiLi9jb21tb24udHNcIjtcbmltcG9ydCB7IGRlZmF1bHRWZXJzaW9ucywgZXhlY3V0b3JNYXAsIHR5cGUgU3VwcG9ydGVkUG0gfSBmcm9tIFwiLi9jb25zdGFudHMudHNcIjtcbmltcG9ydCB0eXBlIHsgRGV0ZWN0UmVzdWx0IH0gZnJvbSBcIi4vdXRpbHMvZGV0ZWN0b3IudHNcIjtcbmltcG9ydCB7IGZldGNoUG1WZXJzaW9ucyB9IGZyb20gXCIuL3V0aWxzL2ZldGNoLXBtLXZlcnNpb25zLnRzXCI7XG5pbXBvcnQgeyBnZXRDb3JlcGFja0hvbWUgfSBmcm9tIFwiLi91dGlscy9nZXQtY29yZXBhY2staG9tZS50c1wiO1xuaW1wb3J0IHsgcmVnaXN0cnlVcmwgfSBmcm9tIFwiLi91dGlscy9yZWdpc3RyeS11cmwudHNcIjtcblxuLyoqXG4gKiBAcmV0dXJucyBBYnNvbHV0ZSBwYXRoIHRvIGNvcmVwYWNrIGJpbmFyeS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q29yZXBhY2tQYXRoKCk6IHN0cmluZyB7XG4gIGNvbnN0IGNvcmVwYWNrUGtnSnNvblBhdGggPSBmaWxlVVJMVG9QYXRoKFxuICAgIGltcG9ydC5tZXRhLnJlc29sdmUoXCJjb3JlcGFjay9wYWNrYWdlLmpzb25cIiksXG4gICk7XG4gIHJldHVybiBwYXRoLnJlc29sdmUoXG4gICAgcGF0aC5kaXJuYW1lKGNvcmVwYWNrUGtnSnNvblBhdGgpLFxuICAgIGNvcmVwYWNrUGtnSnNvbi5iaW4uY29yZXBhY2ssXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldENvbW1hbmQoXG4gIGRldGVjdFJlc3VsdDogRGV0ZWN0UmVzdWx0IHwgdW5kZWZpbmVkLFxuICBhcmdzOiBzdHJpbmdbXSxcbiAgZXhlY3V0ZT86IGJvb2xlYW4sXG4pIHtcbiAgY29uc3QgeyBuYW1lLCB2ZXJzaW9uIH0gPSBhd2FpdCBnZXRFeGVjdXRpbmdQbUFuZFZlcnNpb24oZGV0ZWN0UmVzdWx0KTtcbiAgY29uc3QgZXhlY3V0b3IgPSBleGVjdXRlID8gZXhlY3V0b3JNYXBbbmFtZV0gOiBuYW1lO1xuICByZXR1cm4gW2Ake2V4ZWN1dG9yfUAke3ZlcnNpb259YCwgLi4uYXJnc10gYXMgY29uc3Q7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW4oXG4gIGRldGVjdFJlc3VsdDogRGV0ZWN0UmVzdWx0IHwgdW5kZWZpbmVkLFxuICBhcmdzOiBzdHJpbmdbXSxcbiAgZXhlY3V0ZT86IGJvb2xlYW4sXG4pOiBQcm9taXNlPG51bWJlcj4ge1xuICBjb25zdCBjb21tYW5kID0gYXdhaXQgZ2V0Q29tbWFuZChkZXRlY3RSZXN1bHQsIGFyZ3MsIGV4ZWN1dGUpO1xuICBjb25zdCBjcCA9IGNoaWxkUHJvY2Vzcy5zcGF3bihcbiAgICBwcm9jZXNzLmV4ZWNQYXRoLFxuICAgIFtnZXRDb3JlcGFja1BhdGgoKSwgLi4uY29tbWFuZF0sXG4gICAge1xuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgICAgZW52OiB7XG4gICAgICAgIENPUkVQQUNLX0RFRkFVTFRfVE9fTEFURVNUOiBcIjBcIixcbiAgICAgICAgQ09SRVBBQ0tfRU5WX0ZJTEU6IFwiMFwiLFxuICAgICAgICBDT1JFUEFDS19OUE1fUkVHSVNUUlk6IHJlZ2lzdHJ5VXJsKCksIC8vIFRPRE86IFJlbW92ZSB0aGlzIGVudiB3aGVuIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvY29yZXBhY2svaXNzdWVzLzU0MCBpcyByZXNvbHZlZC5cbiAgICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHByb2Nlc3MuZW52KS5maWx0ZXIoXG4gICAgICAgICAgICAoW2tdKSA9PiAhay5zdGFydHNXaXRoKFwiQ09SRVBBQ0tfXCIpLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICB9LFxuICAgIH0sXG4gICk7XG5cbiAgY29uc3QgbGlzdGVuZXIgPSAoc2lnbmFsOiBOb2RlSlMuU2lnbmFscykgPT4gIWNwLmtpbGxlZCAmJiBjcC5raWxsKHNpZ25hbCk7XG4gIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgbGlzdGVuZXIpO1xuICBwcm9jZXNzLm9uKFwiU0lHVEVSTVwiLCBsaXN0ZW5lcik7XG5cbiAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjcC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICAgIGNwLm9uKFwiY2xvc2VcIiwgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgICAgcmVzb2x2ZShcbiAgICAgICAgY29kZSA/PyAoc2lnbmFsICE9PSBudWxsID8gMTI4ICsgb3MuY29uc3RhbnRzLnNpZ25hbHNbc2lnbmFsXSA6IDEpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRNc2coXG4gIGRldGVjdFJlc3VsdDogRGV0ZWN0UmVzdWx0IHwgdW5kZWZpbmVkLFxuICBhcmdzOiBzdHJpbmdbXSxcbiAgZXhlY3V0ZT86IGJvb2xlYW4sXG4pIHtcbiAgY29uc3QgY29tbWFuZCA9IGF3YWl0IGdldENvbW1hbmQoZGV0ZWN0UmVzdWx0LCBhcmdzLCBleGVjdXRlKTtcbiAgY29uc3QgW25hbWUsIHZlcnNpb25dID0gY29tbWFuZFswXS5zcGxpdChcIkBcIik7XG4gIC8vIG5hbWUgYW5kIHZlcnNpb24gbXVzdCBiZSBzdHJpbmcuIElmIHN0YXRlbWVudCBiZWxvdyBpcyBub3QgbmVlZGVkLCBidXQgaXQncyBmb3IgdHlwZSBzYWZldHkuXG4gIGlmICghbmFtZSB8fCAhdmVyc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludGVybmFsIGVycm9yOiBgbmFtZWAgb3IgYHZlcnNpb25gIG5vdCBmb3VuZC5cIik7XG4gIH1cbiAgY29uc3QgcG1OYW1lID1cbiAgICBuYW1lIGluIGV4ZWN1dG9yTWFwXG4gICAgICA/IG5hbWVcbiAgICAgIDogT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKGV4ZWN1dG9yTWFwKS5tYXAoKFtrLCB2XSkgPT4gW3YsIGtdKSlbXG4gICAgICAgICAgbmFtZVxuICAgICAgICBdO1xuICBpZiAoIXBtTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkludGVybmFsIGVycm9yOiBgcG1OYW1lYCBub3QgZm91bmQuXCIpO1xuICB9XG4gIGNvbnN0IG5hbWVWZXIgPSBgWyR7cG1OYW1lfUAke3ZlcnNpb259XWA7XG4gIGNvbnN0IHBhY2thZ2VKc29uID0gYXdhaXQgZ2V0UGFja2FnZUpzb24oKTtcbiAgY29uc3QgaW5mbyA9IGAocG1AJHtwYWNrYWdlSnNvbi52ZXJzaW9ufSlgO1xuICByZXR1cm4gW1xuICAgIFwi8J+TplwiLFxuICAgIGAke3N0eWxlVGV4dChcImJvbGRcIiwgbmFtZVZlcil9JHtzdHlsZVRleHQoXCJkaW1cIiwgaW5mbyl9YCxcbiAgICBcIuKenFwiLFxuICAgIHN0eWxlVGV4dChcImJsdWVcIiwgW25hbWUsIC4uLmNvbW1hbmQuc2xpY2UoMSldLmpvaW4oXCIgXCIpKSxcbiAgXS5qb2luKFwiIFwiKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0RG93bmxvYWRlZFZlcnNpb25zKHBtOiBTdXBwb3J0ZWRQbSkge1xuICBjb25zdCBwbUZvbGRlciA9IHBhdGguam9pbihnZXRDb3JlcGFja0hvbWUoKSwgcG0pO1xuICByZXR1cm4gKGF3YWl0IGZzLnJlYWRkaXIocG1Gb2xkZXIpLmNhdGNoKCgpID0+IFtdKSlcbiAgICAuZmlsdGVyKChmaWxlKSA9PiBzZW12ZXIudmFsaWQoZmlsZSkpXG4gICAgLnNvcnQoKHgsIHkpID0+IHNlbXZlci5jb21wYXJlKHksIHgpKTsgLy8gZGVzY1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRSZW1vdGVWZXJzaW9ucyhwbTogU3VwcG9ydGVkUG0pIHtcbiAgcmV0dXJuIChhd2FpdCBmZXRjaFBtVmVyc2lvbnMocG0pKVxuICAgIC5maWx0ZXIoKHZlcnNpb24pID0+IHNlbXZlci52YWxpZCh2ZXJzaW9uKSlcbiAgICAuc29ydCgoeCwgeSkgPT4gc2VtdmVyLmNvbXBhcmUoeSwgeCkpOyAvLyBkZXNjXG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEV4ZWN1dGluZ1BtQW5kVmVyc2lvbihcbiAgZGV0ZWN0UmVzdWx0OiBEZXRlY3RSZXN1bHQgfCB1bmRlZmluZWQsXG4pOiBQcm9taXNlPFJlcXVpcmVkPERldGVjdFJlc3VsdD4+IHtcbiAgY29uc3QgeyBuYW1lID0gXCJucG1cIiB9ID0gZGV0ZWN0UmVzdWx0ID8/IHt9O1xuICBjb25zdCB7IHZlcnNpb24gPSBkZWZhdWx0VmVyc2lvbnNbbmFtZV0gfSA9IGRldGVjdFJlc3VsdCA/PyB7fTtcbiAgLy8gMS4gSWYgdmVyc2lvbiBpcyB2YWxpZCwgcmV0dXJuIGl0LlxuICBpZiAoc2VtdmVyLnZhbGlkKHZlcnNpb24pKSB7XG4gICAgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbiB9O1xuICB9XG4gIGlmIChzZW12ZXIudmFsaWRSYW5nZSh2ZXJzaW9uKSkge1xuICAgIC8vIDIuIFRyeSB0byBmaW5kIHRoZSB2ZXJzaW9uIGluIHRoZSBkb3dubG9hZGVkIHZlcnNpb25zLlxuICAgIGNvbnN0IGRvd25sb2FkZWRWZXJzaW9ucyA9IGF3YWl0IGdldERvd25sb2FkZWRWZXJzaW9ucyhuYW1lKTtcbiAgICBmb3IgKGNvbnN0IGRvd25sb2FkZWRWZXJzaW9uIG9mIGRvd25sb2FkZWRWZXJzaW9ucykge1xuICAgICAgaWYgKHNlbXZlci5zYXRpc2ZpZXMoZG93bmxvYWRlZFZlcnNpb24sIHZlcnNpb24pKSB7XG4gICAgICAgIHJldHVybiB7IG5hbWUsIHZlcnNpb246IGRvd25sb2FkZWRWZXJzaW9uIH07XG4gICAgICB9XG4gICAgfVxuICAgIC8vIDMuIFRyeSB0byBmaW5kIHRoZSB2ZXJzaW9uIGluIHRoZSByZW1vdGUgdmVyc2lvbnMuXG4gICAgY29uc3QgcmVtb3RlVmVyc2lvbnMgPSBhd2FpdCBnZXRSZW1vdGVWZXJzaW9ucyhuYW1lKTtcbiAgICBmb3IgKGNvbnN0IHJlbW90ZVZlcnNpb24gb2YgcmVtb3RlVmVyc2lvbnMpIHtcbiAgICAgIGlmIChzZW12ZXIuc2F0aXNmaWVzKHJlbW90ZVZlcnNpb24sIHZlcnNpb24pKSB7XG4gICAgICAgIHJldHVybiB7IG5hbWUsIHZlcnNpb246IHJlbW90ZVZlcnNpb24gfTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYE5vIHBhY2thZ2UgbWFuYWdlciB2ZXJzaW9uIGZvdW5kIHRoYXQgc2F0aXNmaWVzICcke3ZlcnNpb259Jy4gVGhlIHNwZWNpZmllZCB2ZXJzaW9uIHJhbmdlIG1heSBub3QgZXhpc3Qgb3IgaXMgdW5hdmFpbGFibGUgZnJvbSAke3JlZ2lzdHJ5VXJsKCl9LmAsXG4gICAgKTtcbiAgfVxuICAvLyA0LiBSZXR1cm4gdGhlIGRlZmF1bHQgdmVyc2lvbi5cbiAgcmV0dXJuIHsgbmFtZSwgdmVyc2lvbiB9O1xufVxuIl19