UNPKG

@rnm/pm

Version:

Unified Package Manager for Node.js

127 lines 20 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 corepackPkgJson from "corepack/package.json" with { type: "json" }; import registryUrl from "registry-url"; import { importMetaResolve } from "./import-meta-resolve.js"; const exists = async (p) => await fs .access(p) .then(() => true) .catch(() => false); const importPkgJson = async (p) => await fs .readFile(p, "utf8") .then(JSON.parse) .catch(() => undefined); async function findUp(name, { cwd = process.cwd() } = {}) { const result = path.join(cwd, name); const existing = await exists(result); if (existing) return result; const parent = path.dirname(cwd); if (parent === cwd) return undefined; return await findUp(name, { cwd: parent }); } async function detectByPackageJson(directory = process.cwd()) { const pkgJsonContent = await importPkgJson(path.join(directory, "package.json")); // 1. detect pm by `packageManager` field const [packageManager, rest] = pkgJsonContent?.packageManager?.split("@") ?? []; if (packageManager === "npm" || packageManager === "yarn" || packageManager === "pnpm") { const version = rest?.split("+")[0]; return { name: packageManager, ...(version && { version }) }; } // 2. detect pm by `devEngines` filed const { name, version: devEnginesVer } = pkgJsonContent?.devEngines?.packageManager ?? {}; if (name === "npm" || name === "yarn" || name === "pnpm") { const version = devEnginesVer?.split("+")[0]; return { name, ...(version && { version }) }; } // 3. detect pm by `engines` filed // Note: Corepack does not support `engines` field. So the result doesn't include the version. See https://github.com/nodejs/corepack/issues/694. if (pkgJsonContent?.engines?.["npm"]) return { name: "npm" }; if (pkgJsonContent?.engines?.["yarn"]) return { name: "yarn" }; if (pkgJsonContent?.engines?.["pnpm"]) return { name: "pnpm" }; const parent = path.dirname(directory); if (directory === parent) return undefined; return await detectByPackageJson(parent); } /** * Detects the package manager used in the specified directory. * @param directory - The absolute path to the directory to check. */ async function detect(directory = process.cwd()) { const pkgJsonPath = await findUp("package.json", { cwd: directory }); if (!pkgJsonPath) throw new Error("No package.json found."); // 1. detect pm by package.json const pm = await detectByPackageJson(path.dirname(pkgJsonPath)); if (pm) return pm; // 2. detect pm by lock files const locks = (await Promise.all([ findUp("package-lock.json", { cwd: directory }), findUp("yarn.lock", { cwd: directory }), findUp("pnpm-lock.yaml", { cwd: directory }), ])).filter((p) => p !== undefined); if (locks.length > 1) { throw new Error("Multiple lock files found. Please remove one of them."); } if (locks[0]?.endsWith("package-lock.json")) return { name: "npm" }; if (locks[0]?.endsWith("yarn.lock")) return { name: "yarn" }; if (locks[0]?.endsWith("pnpm-lock.yaml")) return { name: "pnpm" }; return undefined; } /** * @returns Absolute path to corepack binary. */ function getCorepackPath() { const corepackPkgJsonPath = fileURLToPath(importMetaResolve("corepack/package.json")); return path.resolve(path.dirname(corepackPkgJsonPath), corepackPkgJson.bin.corepack); } function getRegistry() { const registry = registryUrl(); return registry.endsWith("/") ? registry.slice(0, -1) : registry; } export async function main({ forceTo, onDetected, }) { let packageManager = forceTo; let version = ""; if (!packageManager) { const detectResult = await detect(); onDetected?.(detectResult); packageManager = detectResult?.name ?? "npm"; if (detectResult?.version) version = `@${detectResult.version}`; } const cp = childProcess.spawn(getCorepackPath(), [`${packageManager}${version}`, ...process.argv.slice(2)], { stdio: "inherit", env: { COREPACK_ENV_FILE: "0", COREPACK_NPM_REGISTRY: getRegistry(), // 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)); }); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sWUFBWSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxlQUFlLE1BQU0sdUJBQXVCLENBQUMsT0FBTyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDMUUsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBUzdELE1BQU0sTUFBTSxHQUFHLEtBQUssRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUNqQyxNQUFNLEVBQUU7S0FDTCxNQUFNLENBQUMsQ0FBQyxDQUFDO0tBQ1QsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQztLQUNoQixLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEIsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLENBQVMsRUFBRSxFQUFFLENBQ3hDLE1BQU0sRUFBRTtLQUNMLFFBQVEsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDO0tBQ25CLElBQUksQ0FJRixJQUFJLENBQUMsS0FBSyxDQUFDO0tBQ2IsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRTVCLEtBQUssVUFBVSxNQUFNLENBQUMsSUFBWSxFQUFFLEVBQUUsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUU7SUFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxD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dXJjZXNDb250ZW50IjpbImltcG9ydCBjaGlsZFByb2Nlc3MgZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCBwcm9jZXNzIGZyb20gXCJub2RlOnByb2Nlc3NcIjtcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tIFwibm9kZTp1cmxcIjtcbmltcG9ydCBjb3JlcGFja1BrZ0pzb24gZnJvbSBcImNvcmVwYWNrL3BhY2thZ2UuanNvblwiIHdpdGggeyB0eXBlOiBcImpzb25cIiB9O1xuaW1wb3J0IHJlZ2lzdHJ5VXJsIGZyb20gXCJyZWdpc3RyeS11cmxcIjtcbmltcG9ydCB7IGltcG9ydE1ldGFSZXNvbHZlIH0gZnJvbSBcIi4vaW1wb3J0LW1ldGEtcmVzb2x2ZS50c1wiO1xuXG50eXBlIFN1cHBvcnRlZFBtID0gXCJucG1cIiB8IFwieWFyblwiIHwgXCJwbnBtXCI7XG5cbmludGVyZmFjZSBEZXRlY3RSZXN1bHQge1xuICBuYW1lOiBTdXBwb3J0ZWRQbTtcbiAgdmVyc2lvbj86IHN0cmluZztcbn1cblxuY29uc3QgZXhpc3RzID0gYXN5bmMgKHA6IHN0cmluZykgPT5cbiAgYXdhaXQgZnNcbiAgICAuYWNjZXNzKHApXG4gICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAuY2F0Y2goKCkgPT4gZmFsc2UpO1xuY29uc3QgaW1wb3J0UGtnSnNvbiA9IGFzeW5jIChwOiBzdHJpbmcpID0+XG4gIGF3YWl0IGZzXG4gICAgLnJlYWRGaWxlKHAsIFwidXRmOFwiKVxuICAgIC50aGVuPHtcbiAgICAgIHBhY2thZ2VNYW5hZ2VyPzogc3RyaW5nO1xuICAgICAgZW5naW5lcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICBkZXZFbmdpbmVzPzogeyBwYWNrYWdlTWFuYWdlcj86IHsgbmFtZT86IHN0cmluZzsgdmVyc2lvbj86IHN0cmluZyB9IH07XG4gICAgfT4oSlNPTi5wYXJzZSlcbiAgICAuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuYXN5bmMgZnVuY3Rpb24gZmluZFVwKG5hbWU6IHN0cmluZywgeyBjd2QgPSBwcm9jZXNzLmN3ZCgpIH0gPSB7fSkge1xuICBjb25zdCByZXN1bHQgPSBwYXRoLmpvaW4oY3dkLCBuYW1lKTtcbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBleGlzdHMocmVzdWx0KTtcbiAgaWYgKGV4aXN0aW5nKSByZXR1cm4gcmVzdWx0O1xuICBjb25zdCBwYXJlbnQgPSBwYXRoLmRpcm5hbWUoY3dkKTtcbiAgaWYgKHBhcmVudCA9PT0gY3dkKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4gYXdhaXQgZmluZFVwKG5hbWUsIHsgY3dkOiBwYXJlbnQgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRldGVjdEJ5UGFja2FnZUpzb24oXG4gIGRpcmVjdG9yeSA9IHByb2Nlc3MuY3dkKCksXG4pOiBQcm9taXNlPERldGVjdFJlc3VsdCB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBwa2dKc29uQ29udGVudCA9IGF3YWl0IGltcG9ydFBrZ0pzb24oXG4gICAgcGF0aC5qb2luKGRpcmVjdG9yeSwgXCJwYWNrYWdlLmpzb25cIiksXG4gICk7XG5cbiAgLy8gMS4gZGV0ZWN0IHBtIGJ5IGBwYWNrYWdlTWFuYWdlcmAgZmllbGRcbiAgY29uc3QgW3BhY2thZ2VNYW5hZ2VyLCByZXN0XSA9XG4gICAgcGtnSnNvbkNvbnRlbnQ/LnBhY2thZ2VNYW5hZ2VyPy5zcGxpdChcIkBcIikgPz8gW107XG4gIGlmIChcbiAgICBwYWNrYWdlTWFuYWdlciA9PT0gXCJucG1cIiB8fFxuICAgIHBhY2thZ2VNYW5hZ2VyID09PSBcInlhcm5cIiB8fFxuICAgIHBhY2thZ2VNYW5hZ2VyID09PSBcInBucG1cIlxuICApIHtcbiAgICBjb25zdCB2ZXJzaW9uID0gcmVzdD8uc3BsaXQoXCIrXCIpWzBdO1xuICAgIHJldHVybiB7IG5hbWU6IHBhY2thZ2VNYW5hZ2VyLCAuLi4odmVyc2lvbiAmJiB7IHZlcnNpb24gfSkgfTtcbiAgfVxuXG4gIC8vIDIuIGRldGVjdCBwbSBieSBgZGV2RW5naW5lc2AgZmlsZWRcbiAgY29uc3QgeyBuYW1lLCB2ZXJzaW9uOiBkZXZFbmdpbmVzVmVyIH0gPVxuICAgIHBrZ0pzb25Db250ZW50Py5kZXZFbmdpbmVzPy5wYWNrYWdlTWFuYWdlciA/PyB7fTtcbiAgaWYgKG5hbWUgPT09IFwibnBtXCIgfHwgbmFtZSA9PT0gXCJ5YXJuXCIgfHwgbmFtZSA9PT0gXCJwbnBtXCIpIHtcbiAgICBjb25zdCB2ZXJzaW9uID0gZGV2RW5naW5lc1Zlcj8uc3BsaXQoXCIrXCIpWzBdO1xuICAgIHJldHVybiB7IG5hbWUsIC4uLih2ZXJzaW9uICYmIHsgdmVyc2lvbiB9KSB9O1xuICB9XG5cbiAgLy8gMy4gZGV0ZWN0IHBtIGJ5IGBlbmdpbmVzYCBmaWxlZFxuICAvLyBOb3RlOiBDb3JlcGFjayBkb2VzIG5vdCBzdXBwb3J0IGBlbmdpbmVzYCBmaWVsZC4gU28gdGhlIHJlc3VsdCBkb2Vzbid0IGluY2x1ZGUgdGhlIHZlcnNpb24uIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL2NvcmVwYWNrL2lzc3Vlcy82OTQuXG4gIGlmIChwa2dKc29uQ29udGVudD8uZW5naW5lcz8uW1wibnBtXCJdKSByZXR1cm4geyBuYW1lOiBcIm5wbVwiIH07XG4gIGlmIChwa2dKc29uQ29udGVudD8uZW5naW5lcz8uW1wieWFyblwiXSkgcmV0dXJuIHsgbmFtZTogXCJ5YXJuXCIgfTtcbiAgaWYgKHBrZ0pzb25Db250ZW50Py5lbmdpbmVzPy5bXCJwbnBtXCJdKSByZXR1cm4geyBuYW1lOiBcInBucG1cIiB9O1xuXG4gIGNvbnN0IHBhcmVudCA9IHBhdGguZGlybmFtZShkaXJlY3RvcnkpO1xuICBpZiAoZGlyZWN0b3J5ID09PSBwYXJlbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBhd2FpdCBkZXRlY3RCeVBhY2thZ2VKc29uKHBhcmVudCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB0aGUgcGFja2FnZSBtYW5hZ2VyIHVzZWQgaW4gdGhlIHNwZWNpZmllZCBkaXJlY3RvcnkuXG4gKiBAcGFyYW0gZGlyZWN0b3J5IC0gVGhlIGFic29sdXRlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSB0byBjaGVjay5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0KFxuICBkaXJlY3RvcnkgPSBwcm9jZXNzLmN3ZCgpLFxuKTogUHJvbWlzZTxEZXRlY3RSZXN1bHQgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgcGtnSnNvblBhdGggPSBhd2FpdCBmaW5kVXAoXCJwYWNrYWdlLmpzb25cIiwgeyBjd2Q6IGRpcmVjdG9yeSB9KTtcbiAgaWYgKCFwa2dKc29uUGF0aCkgdGhyb3cgbmV3IEVycm9yKFwiTm8gcGFja2FnZS5qc29uIGZvdW5kLlwiKTtcblxuICAvLyAxLiBkZXRlY3QgcG0gYnkgcGFja2FnZS5qc29uXG4gIGNvbnN0IHBtID0gYXdhaXQgZGV0ZWN0QnlQYWNrYWdlSnNvbihwYXRoLmRpcm5hbWUocGtnSnNvblBhdGgpKTtcbiAgaWYgKHBtKSByZXR1cm4gcG07XG5cbiAgLy8gMi4gZGV0ZWN0IHBtIGJ5IGxvY2sgZmlsZXNcbiAgY29uc3QgbG9ja3MgPSAoXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgZmluZFVwKFwicGFja2FnZS1sb2NrLmpzb25cIiwgeyBjd2Q6IGRpcmVjdG9yeSB9KSxcbiAgICAgIGZpbmRVcChcInlhcm4ubG9ja1wiLCB7IGN3ZDogZGlyZWN0b3J5IH0pLFxuICAgICAgZmluZFVwKFwicG5wbS1sb2NrLnlhbWxcIiwgeyBjd2Q6IGRpcmVjdG9yeSB9KSxcbiAgICBdKVxuICApLmZpbHRlcigocCkgPT4gcCAhPT0gdW5kZWZpbmVkKTtcbiAgaWYgKGxvY2tzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJNdWx0aXBsZSBsb2NrIGZpbGVzIGZvdW5kLiBQbGVhc2UgcmVtb3ZlIG9uZSBvZiB0aGVtLlwiKTtcbiAgfVxuICBpZiAobG9ja3NbMF0/LmVuZHNXaXRoKFwicGFja2FnZS1sb2NrLmpzb25cIikpIHJldHVybiB7IG5hbWU6IFwibnBtXCIgfTtcbiAgaWYgKGxvY2tzWzBdPy5lbmRzV2l0aChcInlhcm4ubG9ja1wiKSkgcmV0dXJuIHsgbmFtZTogXCJ5YXJuXCIgfTtcbiAgaWYgKGxvY2tzWzBdPy5lbmRzV2l0aChcInBucG0tbG9jay55YW1sXCIpKSByZXR1cm4geyBuYW1lOiBcInBucG1cIiB9O1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIEFic29sdXRlIHBhdGggdG8gY29yZXBhY2sgYmluYXJ5LlxuICovXG5mdW5jdGlvbiBnZXRDb3JlcGFja1BhdGgoKTogc3RyaW5nIHtcbiAgY29uc3QgY29yZXBhY2tQa2dKc29uUGF0aCA9IGZpbGVVUkxUb1BhdGgoXG4gICAgaW1wb3J0TWV0YVJlc29sdmUoXCJjb3JlcGFjay9wYWNrYWdlLmpzb25cIiksXG4gICk7XG4gIHJldHVybiBwYXRoLnJlc29sdmUoXG4gICAgcGF0aC5kaXJuYW1lKGNvcmVwYWNrUGtnSnNvblBhdGgpLFxuICAgIGNvcmVwYWNrUGtnSnNvbi5iaW4uY29yZXBhY2ssXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldFJlZ2lzdHJ5KCkge1xuICBjb25zdCByZWdpc3RyeSA9IHJlZ2lzdHJ5VXJsKCk7XG4gIHJldHVybiByZWdpc3RyeS5lbmRzV2l0aChcIi9cIikgPyByZWdpc3RyeS5zbGljZSgwLCAtMSkgOiByZWdpc3RyeTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1haW4oe1xuICBmb3JjZVRvLFxuICBvbkRldGVjdGVkLFxufToge1xuICBmb3JjZVRvPzogU3VwcG9ydGVkUG07XG4gIG9uRGV0ZWN0ZWQ/OiAocG06IERldGVjdFJlc3VsdCB8IHVuZGVmaW5lZCkgPT4gdm9pZDtcbn0pOiBQcm9taXNlPG51bWJlcj4ge1xuICBsZXQgcGFja2FnZU1hbmFnZXIgPSBmb3JjZVRvO1xuICBsZXQgdmVyc2lvbiA9IFwiXCI7XG4gIGlmICghcGFja2FnZU1hbmFnZXIpIHtcbiAgICBjb25zdCBkZXRlY3RSZXN1bHQgPSBhd2FpdCBkZXRlY3QoKTtcbiAgICBvbkRldGVjdGVkPy4oZGV0ZWN0UmVzdWx0KTtcbiAgICBwYWNrYWdlTWFuYWdlciA9IGRldGVjdFJlc3VsdD8ubmFtZSA/PyBcIm5wbVwiO1xuICAgIGlmIChkZXRlY3RSZXN1bHQ/LnZlcnNpb24pIHZlcnNpb24gPSBgQCR7ZGV0ZWN0UmVzdWx0LnZlcnNpb259YDtcbiAgfVxuXG4gIGNvbnN0IGNwID0gY2hpbGRQcm9jZXNzLnNwYXduKFxuICAgIGdldENvcmVwYWNrUGF0aCgpLFxuICAgIFtgJHtwYWNrYWdlTWFuYWdlcn0ke3ZlcnNpb259YCwgLi4ucHJvY2Vzcy5hcmd2LnNsaWNlKDIpXSxcbiAgICB7XG4gICAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gICAgICBlbnY6IHtcbiAgICAgICAgQ09SRVBBQ0tfRU5WX0ZJTEU6IFwiMFwiLFxuICAgICAgICBDT1JFUEFDS19OUE1fUkVHSVNUUlk6IGdldFJlZ2lzdHJ5KCksIC8vIFRPRE86IFJlbW92ZSB0aGlzIGVudiB3aGVuIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvY29yZXBhY2svaXNzdWVzLzU0MCBpcyByZXNvbHZlZC5cbiAgICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHByb2Nlc3MuZW52KS5maWx0ZXIoXG4gICAgICAgICAgICAoW2tdKSA9PiAhay5zdGFydHNXaXRoKFwiQ09SRVBBQ0tfXCIpLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICB9LFxuICAgIH0sXG4gICk7XG5cbiAgY29uc3QgbGlzdGVuZXIgPSAoc2lnbmFsOiBOb2RlSlMuU2lnbmFscykgPT4gIWNwLmtpbGxlZCAmJiBjcC5raWxsKHNpZ25hbCk7XG4gIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgbGlzdGVuZXIpO1xuICBwcm9jZXNzLm9uKFwiU0lHVEVSTVwiLCBsaXN0ZW5lcik7XG5cbiAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjcC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICAgIGNwLm9uKFwiY2xvc2VcIiwgKGNvZGUsIHNpZ25hbCkgPT4ge1xuICAgICAgcmVzb2x2ZShcbiAgICAgICAgY29kZSA/PyAoc2lnbmFsICE9PSBudWxsID8gMTI4ICsgb3MuY29uc3RhbnRzLnNpZ25hbHNbc2lnbmFsXSA6IDEpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXX0=