UNPKG

projen

Version:

CDK for software projects

171 lines • 20 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.FILE_MANIFEST = void 0; exports.cleanup = cleanup; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const glob = __importStar(require("fast-glob")); const common_1 = require("./common"); const logging = __importStar(require("./logging")); const path_1 = require("./util/path"); exports.FILE_MANIFEST = `${common_1.PROJEN_DIR}/files.json`; function cleanup(dir, newFiles, exclude) { try { const manifestFiles = getFilesFromManifest(dir); if (manifestFiles.length > 0) { // Use `FILE_MANIFEST` to remove files that are no longer managed by projen removeFiles(findOrphanedFiles(dir, manifestFiles, newFiles)); } else { // Remove all files managed by projen with legacy logic removeFiles(findGeneratedFiles(dir, exclude)); } } catch (e) { logging.warn(`Could not clean up previously generated files, so outdated files may be left behind in your project. ` + `Synthesis continues, but you may need to delete them yourself. Error: ${e.stack}`); } } function removeFiles(files) { for (const file of files) { fs.rmSync(file, { force: true, recursive: true }); } } function findGeneratedFiles(dir, exclude) { const ignore = [ ...readGitIgnore(dir), "node_modules/**", ...exclude, ".git/**", ]; const files = glob.sync("**", { ignore, cwd: dir, dot: true, onlyFiles: true, followSymbolicLinks: false, absolute: true, }); const generated = new Array(); for (const file of files) { const contents = fs.readFileSync(file, "utf-8"); if (contents.includes(common_1.PROJEN_MARKER)) { generated.push(file); } } return generated; } function findOrphanedFiles(dir, oldFiles, newFiles) { return oldFiles .filter((old) => !newFiles.includes(old)) .map((f) => resolveWithinDir(dir, f)) .filter((f) => f !== undefined); } /** * Resolves a file path taken from the file manifest against the project * directory, making sure the result stays inside of it. * * The file manifest is checked into the repository and is therefore untrusted * input: without this check, a manifest containing `../` or absolute path * entries would make cleanup delete files outside of the project directory. * * @returns the absolute path to delete, or `undefined` if the entry does not * resolve to a location inside `dir`. */ function resolveWithinDir(dir, file) { const skip = (reason) => { logging.warn(`Not deleting ${JSON.stringify(file)} during cleanup because ${reason}. ` + `projen only removes generated files inside your project directory. ` + `This entry in ${exports.FILE_MANIFEST} should not be there - review it (and who changed it) in version control, ` + `and delete the file yourself if you really no longer need it.`); return undefined; }; if (typeof file !== "string" || file.trim() === "") { return skip("it is not a file path"); } if (path.isAbsolute(file)) { return skip("it is an absolute path instead of a path in your project"); } const baseDir = (0, path_1.realpathOfClosestExisting)(dir); const resolved = path.resolve(baseDir, file); if (!(0, path_1.isPathInside)(baseDir, resolved)) { return skip("it points outside of your project directory"); } // the entry might traverse outside of the project through a symlinked // directory, which `path.resolve` cannot detect. The last path segment is // intentionally kept as-is: removing a symlink inside the project only // deletes the link itself, not its target. const realParent = (0, path_1.realpathOfClosestExisting)(path.dirname(resolved)); if (!(0, path_1.isPathInside)(baseDir, path.join(realParent, path.basename(resolved)))) { return skip("it points outside of your project directory through a symlink"); } return resolved; } function getFilesFromManifest(dir) { try { const fileManifestPath = path.resolve(dir, exports.FILE_MANIFEST); if (fs.existsSync(fileManifestPath)) { const fileManifest = JSON.parse(fs.readFileSync(fileManifestPath, "utf-8")); if (Array.isArray(fileManifest.files)) { return fileManifest.files; } if (fileManifest.files) { logging.debug(`"files" in ${exports.FILE_MANIFEST} is not a list of files, so it cannot be used to find files to clean up. Falling back to scanning your project for projen-generated files.`); } } } catch (e) { logging.warn(`Could not read the list of generated files from ${exports.FILE_MANIFEST}, so projen will scan your project for generated files instead. ` + `Check that the file exists in version control and contains valid JSON. Error: ${e.stack}`); } return []; } function readGitIgnore(dir) { const filepath = path.join(dir, ".gitignore"); if (!fs.existsSync(filepath)) { return []; } return fs .readFileSync(filepath, "utf-8") .split("\n") .filter((x) => x?.trim() !== "") .filter((x) => !x.startsWith("#") && !x.startsWith("!")) .map((x) => x.replace(/^\//, "")) // remove "/" prefix .map((x) => `${x}\n${x}/**`) .join("\n") .split("\n"); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xlYW51cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jbGVhbnVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNBLDBCQWdCQztBQXpCRCx1Q0FBeUI7QUFDekIsMkNBQTZCO0FBQzdCLGdEQUFrQztBQUNsQyxxQ0FBcUQ7QUFDckQsbURBQXFDO0FBQ3JDLHNDQUFzRTtBQUV6RCxRQUFBLGFBQWEsR0FBRyxHQUFHLG1CQUFVLGFBQWEsQ0FBQztBQUV4RCxTQUFnQixPQUFPLENBQUMsR0FBVyxFQUFFLFFBQWtCLEVBQUUsT0FBaUI7SUFDeEUsSUFBSSxDQUFDO1FBQ0gsTUFBTSxhQUFhLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEQsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzdCLDJFQUEyRTtZQUMzRSxXQUFXLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7YUFBTSxDQUFDO1lBQ04sdURBQXVEO1lBQ3ZELFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNoRCxDQUFDO0lBQ0gsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIsT0FBTyxDQUFDLElBQUksQ0FDVix1R0FBdUc7WUFDckcseUVBQXlFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FDckYsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsS0FBZTtJQUNsQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pCLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FB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RyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzlDLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDN0IsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsT0FBTyxFQUFFO1NBQ04sWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7U0FDL0IsS0FBSyxDQUFDLElBQUksQ0FBQztTQUNYLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztTQUMvQixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDdkQsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtTQUNyRCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO1NBQzNCLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDVixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDakIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0ICogYXMgZ2xvYiBmcm9tIFwiZmFzdC1nbG9iXCI7XG5pbXBvcnQgeyBQUk9KRU5fRElSLCBQUk9KRU5fTUFSS0VSIH0gZnJvbSBcIi4vY29tbW9uXCI7XG5pbXBvcnQgKiBhcyBsb2dnaW5nIGZyb20gXCIuL2xvZ2dpbmdcIjtcbmltcG9ydCB7IGlzUGF0aEluc2lkZSwgcmVhbHBhdGhPZkNsb3Nlc3RFeGlzdGluZyB9IGZyb20gXCIuL3V0aWwvcGF0aFwiO1xuXG5leHBvcnQgY29uc3QgRklMRV9NQU5JRkVTVCA9IGAke1BST0pFTl9ESVJ9L2ZpbGVzLmpzb25gO1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYW51cChkaXI6IHN0cmluZywgbmV3RmlsZXM6IHN0cmluZ1tdLCBleGNsdWRlOiBzdHJpbmdbXSkge1xuICB0cnkge1xuICAgIGNvbnN0IG1hbmlmZXN0RmlsZXMgPSBnZXRGaWxlc0Zyb21NYW5pZmVzdChkaXIpO1xuICAgIGlmIChtYW5pZmVzdEZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFVzZSBgRklMRV9NQU5JRkVTVGAgdG8gcmVtb3ZlIGZpbGVzIHRoYXQgYXJlIG5vIGxvbmdlciBtYW5hZ2VkIGJ5IHByb2plblxuICAgICAgcmVtb3ZlRmlsZXMoZmluZE9ycGhhbmVkRmlsZXMoZGlyLCBtYW5pZmVzdEZpbGVzLCBuZXdGaWxlcykpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1vdmUgYWxsIGZpbGVzIG1hbmFnZWQgYnkgcHJvamVuIHdpdGggbGVnYWN5IGxvZ2ljXG4gICAgICByZW1vdmVGaWxlcyhmaW5kR2VuZXJhdGVkRmlsZXMoZGlyLCBleGNsdWRlKSk7XG4gICAgfVxuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBsb2dnaW5nLndhcm4oXG4gICAgICBgQ291bGQgbm90IGNsZWFuIHVwIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGZpbGVzLCBzbyBvdXRkYXRlZCBmaWxlcyBtYXkgYmUgbGVmdCBiZWhpbmQgaW4geW91ciBwcm9qZWN0LiBgICtcbiAgICAgICAgYFN5bnRoZXNpcyBjb250aW51ZXMsIGJ1dCB5b3UgbWF5IG5lZWQgdG8gZGVsZXRlIHRoZW0geW91cnNlbGYuIEVycm9yOiAke2Uuc3RhY2t9YCxcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUZpbGVzKGZpbGVzOiBzdHJpbmdbXSkge1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICBmcy5ybVN5bmMoZmlsZSwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRHZW5lcmF0ZWRGaWxlcyhkaXI6IHN0cmluZywgZXhjbHVkZTogc3RyaW5nW10pIHtcbiAgY29uc3QgaWdub3JlID0gW1xuICAgIC4uLnJlYWRHaXRJZ25vcmUoZGlyKSxcbiAgICBcIm5vZGVfbW9kdWxlcy8qKlwiLFxuICAgIC4uLmV4Y2x1ZGUsXG4gICAgXCIuZ2l0LyoqXCIsXG4gIF07XG5cbiAgY29uc3QgZmlsZXMgPSBnbG9iLnN5bmMoXCIqKlwiLCB7XG4gICAgaWdub3JlLFxuICAgIGN3ZDogZGlyLFxuICAgIGRvdDogdHJ1ZSxcbiAgICBvbmx5RmlsZXM6IHRydWUsXG4gICAgZm9sbG93U3ltYm9saWNMaW5rczogZmFsc2UsXG4gICAgYWJzb2x1dGU6IHRydWUsXG4gIH0pO1xuXG4gIGNvbnN0IGdlbmVyYXRlZCA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG5cbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgY29udGVudHMgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZSwgXCJ1dGYtOFwiKTtcblxuICAgIGlmIChjb250ZW50cy5pbmNsdWRlcyhQUk9KRU5fTUFSS0VSKSkge1xuICAgICAgZ2VuZXJhdGVkLnB1c2goZmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGdlbmVyYXRlZDtcbn1cblxuZnVuY3Rpb24gZmluZE9ycGhhbmVkRmlsZXMoXG4gIGRpcjogc3RyaW5nLFxuICBvbGRGaWxlczogc3RyaW5nW10sXG4gIG5ld0ZpbGVzOiBzdHJpbmdbXSxcbikge1xuICByZXR1cm4gb2xkRmlsZXNcbiAgICAuZmlsdGVyKChvbGQpID0+ICFuZXdGaWxlcy5pbmNsdWRlcyhvbGQpKVxuICAgIC5tYXAoKGY6IHN0cmluZykgPT4gcmVzb2x2ZVdpdGhpbkRpcihkaXIsIGYpKVxuICAgIC5maWx0ZXIoKGYpOiBmIGlzIHN0cmluZyA9PiBmICE9PSB1bmRlZmluZWQpO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIGEgZmlsZSBwYXRoIHRha2VuIGZyb20gdGhlIGZpbGUgbWFuaWZlc3QgYWdhaW5zdCB0aGUgcHJvamVjdFxuICogZGlyZWN0b3J5LCBtYWtpbmcgc3VyZSB0aGUgcmVzdWx0IHN0YXlzIGluc2lkZSBvZiBpdC5cbiAqXG4gKiBUaGUgZmlsZSBtYW5pZmVzdCBpcyBjaGVja2VkIGludG8gdGhlIHJlcG9zaXRvcnkgYW5kIGlzIHRoZXJlZm9yZSB1bnRydXN0ZWRcbiAqIGlucHV0OiB3aXRob3V0IHRoaXMgY2hlY2ssIGEgbWFuaWZlc3QgY29udGFpbmluZyBgLi4vYCBvciBhYnNvbHV0ZSBwYXRoXG4gKiBlbnRyaWVzIHdvdWxkIG1ha2UgY2xlYW51cCBkZWxldGUgZmlsZXMgb3V0c2lkZSBvZiB0aGUgcHJvamVjdCBkaXJlY3RvcnkuXG4gKlxuICogQHJldHVybnMgdGhlIGFic29sdXRlIHBhdGggdG8gZGVsZXRlLCBvciBgdW5kZWZpbmVkYCBpZiB0aGUgZW50cnkgZG9lcyBub3RcbiAqIHJlc29sdmUgdG8gYSBsb2NhdGlvbiBpbnNpZGUgYGRpcmAuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVXaXRoaW5EaXIoZGlyOiBzdHJpbmcsIGZpbGU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHNraXAgPSAocmVhc29uOiBzdHJpbmcpID0+IHtcbiAgICBsb2dnaW5nLndhcm4oXG4gICAgICBgTm90IGRlbGV0aW5nICR7SlNPTi5zdHJpbmdpZnkoZmlsZSl9IGR1cmluZyBjbGVhbnVwIGJlY2F1c2UgJHtyZWFzb259LiBgICtcbiAgICAgICAgYHByb2plbiBvbmx5IHJlbW92ZXMgZ2VuZXJhdGVkIGZpbGVzIGluc2lkZSB5b3VyIHByb2plY3QgZGlyZWN0b3J5LiBgICtcbiAgICAgICAgYFRoaXMgZW50cnkgaW4gJHtGSUxFX01BTklGRVNUfSBzaG91bGQgbm90IGJlIHRoZXJlIC0gcmV2aWV3IGl0IChhbmQgd2hvIGNoYW5nZWQgaXQpIGluIHZlcnNpb24gY29udHJvbCwgYCArXG4gICAgICAgIGBhbmQgZGVsZXRlIHRoZSBmaWxlIHlvdXJzZWxmIGlmIHlvdSByZWFsbHkgbm8gbG9uZ2VyIG5lZWQgaXQuYCxcbiAgICApO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG5cbiAgaWYgKHR5cGVvZiBmaWxlICE9PSBcInN0cmluZ1wiIHx8IGZpbGUudHJpbSgpID09PSBcIlwiKSB7XG4gICAgcmV0dXJuIHNraXAoXCJpdCBpcyBub3QgYSBmaWxlIHBhdGhcIik7XG4gIH1cblxuICBpZiAocGF0aC5pc0Fic29sdXRlKGZpbGUpKSB7XG4gICAgcmV0dXJuIHNraXAoXCJpdCBpcyBhbiBhYnNvbHV0ZSBwYXRoIGluc3RlYWQgb2YgYSBwYXRoIGluIHlvdXIgcHJvamVjdFwiKTtcbiAgfVxuXG4gIGNvbnN0IGJhc2VEaXIgPSByZWFscGF0aE9mQ2xvc2VzdEV4aXN0aW5nKGRpcik7XG4gIGNvbnN0IHJlc29sdmVkID0gcGF0aC5yZXNvbHZlKGJhc2VEaXIsIGZpbGUpO1xuXG4gIGlmICghaXNQYXRoSW5zaWRlKGJhc2VEaXIsIHJlc29sdmVkKSkge1xuICAgIHJldHVybiBza2lwKFwiaXQgcG9pbnRzIG91dHNpZGUgb2YgeW91ciBwcm9qZWN0IGRpcmVjdG9yeVwiKTtcbiAgfVxuXG4gIC8vIHRoZSBlbnRyeSBtaWdodCB0cmF2ZXJzZSBvdXRzaWRlIG9mIHRoZSBwcm9qZWN0IHRocm91Z2ggYSBzeW1saW5rZWRcbiAgLy8gZGlyZWN0b3J5LCB3aGljaCBgcGF0aC5yZXNvbHZlYCBjYW5ub3QgZGV0ZWN0LiBUaGUgbGFzdCBwYXRoIHNlZ21lbnQgaXNcbiAgLy8gaW50ZW50aW9uYWxseSBrZXB0IGFzLWlzOiByZW1vdmluZyBhIHN5bWxpbmsgaW5zaWRlIHRoZSBwcm9qZWN0IG9ubHlcbiAgLy8gZGVsZXRlcyB0aGUgbGluayBpdHNlbGYsIG5vdCBpdHMgdGFyZ2V0LlxuICBjb25zdCByZWFsUGFyZW50ID0gcmVhbHBhdGhPZkNsb3Nlc3RFeGlzdGluZyhwYXRoLmRpcm5hbWUocmVzb2x2ZWQpKTtcbiAgaWYgKCFpc1BhdGhJbnNpZGUoYmFzZURpciwgcGF0aC5qb2luKHJlYWxQYXJlbnQsIHBhdGguYmFzZW5hbWUocmVzb2x2ZWQpKSkpIHtcbiAgICByZXR1cm4gc2tpcChcbiAgICAgIFwiaXQgcG9pbnRzIG91dHNpZGUgb2YgeW91ciBwcm9qZWN0IGRpcmVjdG9yeSB0aHJvdWdoIGEgc3ltbGlua1wiLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVzRnJvbU1hbmlmZXN0KGRpcjogc3RyaW5nKTogc3RyaW5nW10ge1xuICB0cnkge1xuICAgIGNvbnN0IGZpbGVNYW5pZmVzdFBhdGggPSBwYXRoLnJlc29sdmUoZGlyLCBGSUxFX01BTklGRVNUKTtcbiAgICBpZiAoZnMuZXhpc3RzU3luYyhmaWxlTWFuaWZlc3RQYXRoKSkge1xuICAgICAgY29uc3QgZmlsZU1hbmlmZXN0ID0gSlNPTi5wYXJzZShcbiAgICAgICAgZnMucmVhZEZpbGVTeW5jKGZpbGVNYW5pZmVzdFBhdGgsIFwidXRmLThcIiksXG4gICAgICApO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmlsZU1hbmlmZXN0LmZpbGVzKSkge1xuICAgICAgICByZXR1cm4gZmlsZU1hbmlmZXN0LmZpbGVzO1xuICAgICAgfVxuICAgICAgaWYgKGZpbGVNYW5pZmVzdC5maWxlcykge1xuICAgICAgICBsb2dnaW5nLmRlYnVnKFxuICAgICAgICAgIGBcImZpbGVzXCIgaW4gJHtGSUxFX01BTklGRVNUfSBpcyBub3QgYSBsaXN0IG9mIGZpbGVzLCBzbyBpdCBjYW5ub3QgYmUgdXNlZCB0byBmaW5kIGZpbGVzIHRvIGNsZWFuIHVwLiBGYWxsaW5nIGJhY2sgdG8gc2Nhbm5pbmcgeW91ciBwcm9qZWN0IGZvciBwcm9qZW4tZ2VuZXJhdGVkIGZpbGVzLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICBsb2dnaW5nLndhcm4oXG4gICAgICBgQ291bGQgbm90IHJlYWQgdGhlIGxpc3Qgb2YgZ2VuZXJhdGVkIGZpbGVzIGZyb20gJHtGSUxFX01BTklGRVNUfSwgc28gcHJvamVuIHdpbGwgc2NhbiB5b3VyIHByb2plY3QgZm9yIGdlbmVyYXRlZCBmaWxlcyBpbnN0ZWFkLiBgICtcbiAgICAgICAgYENoZWNrIHRoYXQgdGhlIGZpbGUgZXhpc3RzIGluIHZlcnNpb24gY29udHJvbCBhbmQgY29udGFpbnMgdmFsaWQgSlNPTi4gRXJyb3I6ICR7ZS5zdGFja31gLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gW107XG59XG5cbmZ1bmN0aW9uIHJlYWRHaXRJZ25vcmUoZGlyOiBzdHJpbmcpIHtcbiAgY29uc3QgZmlsZXBhdGggPSBwYXRoLmpvaW4oZGlyLCBcIi5naXRpZ25vcmVcIik7XG4gIGlmICghZnMuZXhpc3RzU3luYyhmaWxlcGF0aCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gZnNcbiAgICAucmVhZEZpbGVTeW5jKGZpbGVwYXRoLCBcInV0Zi04XCIpXG4gICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgLmZpbHRlcigoeCkgPT4geD8udHJpbSgpICE9PSBcIlwiKVxuICAgIC5maWx0ZXIoKHgpID0+ICF4LnN0YXJ0c1dpdGgoXCIjXCIpICYmICF4LnN0YXJ0c1dpdGgoXCIhXCIpKVxuICAgIC5tYXAoKHgpID0+IHgucmVwbGFjZSgvXlxcLy8sIFwiXCIpKSAvLyByZW1vdmUgXCIvXCIgcHJlZml4XG4gICAgLm1hcCgoeCkgPT4gYCR7eH1cXG4ke3h9LyoqYClcbiAgICAuam9pbihcIlxcblwiKVxuICAgIC5zcGxpdChcIlxcblwiKTtcbn1cbiJdfQ==