UNPKG

patch-package

Version:

When forking just won't work, patch it.

126 lines 22.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var chalk_1 = require("chalk"); var patchFs_1 = require("./patchFs"); var apply_1 = require("./patch/apply"); var fs_extra_1 = require("fs-extra"); var path_1 = require("./path"); var path_2 = require("path"); var PackageDetails_1 = require("./PackageDetails"); var parse_1 = require("./patch/parse"); var reverse_1 = require("./patch/reverse"); var is_ci_1 = __importDefault(require("is-ci")); // don't want to exit(1) on postinsall locally. // see https://github.com/ds300/patch-package/issues/86 var shouldExitPostinstallWithError = is_ci_1.default || process.env.NODE_ENV === "test"; function findPatchFiles(patchesDirectory) { if (!fs_extra_1.existsSync(patchesDirectory)) { return []; } return patchFs_1.getPatchFiles(patchesDirectory); } function getInstalledPackageVersion(_a) { var appPath = _a.appPath, path = _a.path, pathSpecifier = _a.pathSpecifier; var packageDir = path_1.join(appPath, path); if (!fs_extra_1.existsSync(packageDir)) { console.log(chalk_1.yellow("Warning:") + " Patch file found for package " + path_2.posix.basename(pathSpecifier) + (" which is not present at " + packageDir)); return null; } return require(path_1.join(packageDir, "package.json")).version; } exports.applyPatchesForApp = function (appPath, reverse, patchDir) { if (patchDir === void 0) { patchDir = "patches"; } var patchesDirectory = path_1.join(appPath, patchDir); var files = findPatchFiles(patchesDirectory); if (files.length === 0) { console.error(chalk_1.red("No patch files found")); process.exit(shouldExitPostinstallWithError ? 1 : 0); } files.forEach(function (filename) { var details = PackageDetails_1.getPackageDetailsFromPatchFilename(filename); if (!details) { console.warn("Unrecognized patch file in patches directory " + filename); return; } var name = details.name, version = details.version, path = details.path, pathSpecifier = details.pathSpecifier; var installedPackageVersion = getInstalledPackageVersion({ appPath: appPath, path: path, pathSpecifier: pathSpecifier, }); if (!installedPackageVersion) { return; } if (exports.applyPatch(path_1.resolve(patchesDirectory, filename), reverse)) { // yay patch was applied successfully // print warning if version mismatch if (installedPackageVersion !== version) { printVersionMismatchWarning({ packageName: name, actualVersion: installedPackageVersion, originalVersion: version, pathSpecifier: pathSpecifier, path: path, }); } else { console.log(chalk_1.bold(pathSpecifier) + "@" + version + " " + chalk_1.green("✔")); } } else { // completely failed to apply patch // TODO: propagate useful error messages from patch application if (installedPackageVersion === version) { printBrokenPatchFileError({ packageName: name, patchFileName: filename, pathSpecifier: pathSpecifier, path: path, }); } else { printPatchApplictionFailureError({ packageName: name, actualVersion: installedPackageVersion, originalVersion: version, patchFileName: filename, path: path, pathSpecifier: pathSpecifier, }); } process.exit(shouldExitPostinstallWithError ? 1 : 0); } }); }; exports.applyPatch = function (patchFilePath, reverse) { var patchFileContents = fs_extra_1.readFileSync(patchFilePath).toString(); var patch = parse_1.parsePatchFile(patchFileContents); try { apply_1.executeEffects(reverse ? reverse_1.reversePatch(patch) : patch, { dryRun: false }); } catch (e) { try { apply_1.executeEffects(reverse ? patch : reverse_1.reversePatch(patch), { dryRun: true }); } catch (e) { return false; } } return true; }; function printVersionMismatchWarning(_a) { var packageName = _a.packageName, actualVersion = _a.actualVersion, originalVersion = _a.originalVersion, pathSpecifier = _a.pathSpecifier, path = _a.path; console.warn("\n" + chalk_1.red("Warning:") + " patch-package detected a patch file version mismatch\n\n Don't worry! This is probably fine. The patch was still applied\n successfully. Here's the deets:\n\n Patch file created for\n\n " + packageName + "@" + chalk_1.bold(originalVersion) + "\n\n applied to\n\n " + packageName + "@" + chalk_1.bold(actualVersion) + "\n \n At path\n \n " + path + "\n\n This warning is just to give you a heads-up. There is a small chance of\n breakage even though the patch was applied successfully. Make sure the package\n still behaves like you expect (you wrote tests, right?) and then run\n\n " + chalk_1.bold("patch-package " + pathSpecifier) + "\n\n to update the version in the patch file name and make this warning go away.\n"); } function printBrokenPatchFileError(_a) { var packageName = _a.packageName, patchFileName = _a.patchFileName, path = _a.path, pathSpecifier = _a.pathSpecifier; console.error("\n" + chalk_1.red.bold("**ERROR**") + " " + chalk_1.red("Failed to apply patch for package " + chalk_1.bold(packageName) + " at path") + "\n \n " + path + "\n\n This error was caused because patch-package cannot apply the following patch file:\n\n patches/" + patchFileName + "\n\n Try removing node_modules and trying again. If that doesn't work, maybe there was\n an accidental change made to the patch file? Try recreating it by manually\n editing the appropriate files and running:\n \n patch-package " + pathSpecifier + "\n \n If that doesn't work, then it's a bug in patch-package, so please submit a bug\n report. Thanks!\n\n https://github.com/ds300/patch-package/issues\n \n"); } function printPatchApplictionFailureError(_a) { var packageName = _a.packageName, actualVersion = _a.actualVersion, originalVersion = _a.originalVersion, patchFileName = _a.patchFileName, path = _a.path, pathSpecifier = _a.pathSpecifier; console.error("\n" + chalk_1.red.bold("**ERROR**") + " " + chalk_1.red("Failed to apply patch for package " + chalk_1.bold(packageName) + " at path") + "\n \n " + path + "\n\n This error was caused because " + chalk_1.bold(packageName) + " has changed since you\n made the patch file for it. This introduced conflicts with your patch,\n just like a merge conflict in Git when separate incompatible changes are\n made to the same piece of code.\n\n Maybe this means your patch file is no longer necessary, in which case\n hooray! Just delete it!\n\n Otherwise, you need generate a new patch file.\n\n To generate a new one, just repeat the steps you made to generate the first\n one.\n\n i.e. manually make the appropriate file changes, then run \n\n patch-package " + pathSpecifier + "\n\n Info:\n Patch file: patches/" + patchFileName + "\n Patch was made for version: " + chalk_1.green.bold(originalVersion) + "\n Installed version: " + chalk_1.red.bold(actualVersion) + "\n"); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbHlQYXRjaGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwcGx5UGF0Y2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtCQUFnRDtBQUNoRCxxQ0FBeUM7QUFDekMsdUNBQThDO0FBQzlDLHFDQUFtRDtBQUNuRCwrQkFBc0M7QUFDdEMsNkJBQTRCO0FBQzVCLG1EQUFxRTtBQUNyRSx1Q0FBOEM7QUFDOUMsMkNBQThDO0FBQzlDLGdEQUF3QjtBQUV4QiwrQ0FBK0M7QUFDL0MsdURBQXVEO0FBQ3ZELElBQU0sOEJBQThCLEdBQUcsZUFBSSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLE1BQU0sQ0FBQTtBQUU5RSxTQUFTLGNBQWMsQ0FBQyxnQkFBd0I7SUFDOUMsSUFBSSxDQUFDLHFCQUFVLENBQUMsZ0JBQWdCLENBQUMsRUFBRTtRQUNqQyxPQUFPLEVBQUUsQ0FBQTtLQUNWO0lBRUQsT0FBTyx1QkFBYSxDQUFDLGdCQUFnQixDQUFhLENBQUE7QUFDcEQsQ0FBQztBQUVELFNBQVMsMEJBQTBCLENBQUMsRUFRbkM7UUFQQyxvQkFBTyxFQUNQLGNBQUksRUFDSixnQ0FBYTtJQU1iLElBQU0sVUFBVSxHQUFHLFdBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDdEMsSUFBSSxDQUFDLHFCQUFVLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FDTixjQUFNLENBQUMsVUFBVSxDQUFDLHNDQUFpQyxZQUFLLENBQUMsUUFBUSxDQUNsRSxhQUFhLENBQ1osSUFBRyw4QkFBNEIsVUFBWSxDQUFBLENBQy9DLENBQUE7UUFFRCxPQUFPLElBQUksQ0FBQTtLQUNaO0lBRUQsT0FBTyxPQUFPLENBQUMsV0FBSSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQTtBQUMxRCxDQUFDO0FBRVksUUFBQSxrQkFBa0IsR0FBRyxVQUNoQyxPQUFlLEVBQ2YsT0FBZ0IsRUFDaEIsUUFBNEI7SUFBNUIseUJBQUEsRUFBQSxvQkFBNEI7SUFFNUIsSUFBTSxnQkFBZ0IsR0FBRyxXQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQ2hELElBQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBRTlDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDdEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFBO1FBQzFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7S0FDckQ7SUFFRCxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQUEsUUFBUTtRQUNwQixJQUFNLE9BQU8sR0FBRyxtREFBa0MsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUU1RCxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osT0FBTyxDQUFDLElBQUksQ0FBQyxrREFBZ0QsUUFBVSxDQUFDLENBQUE7WUFDeEUsT0FBTTtTQUNQO1FBRU8sSUFBQSxtQkFBSSxFQUFFLHlCQUFPLEVBQUUsbUJBQUksRUFBRSxxQ0FBYSxDQUFZO1FBRXRELElBQU0sdUJBQXVCLEdBQUcsMEJBQTBCLENBQUM7WUFDekQsT0FBTyxTQUFBO1lBQ1AsSUFBSSxNQUFBO1lBQ0osYUFBYSxlQUFBO1NBQ2QsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLHVCQUF1QixFQUFFO1lBQzVCLE9BQU07U0FDUDtRQUVELElBQUksa0JBQVUsQ0FBQyxjQUFPLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFXLEVBQUUsT0FBTyxDQUFDLEVBQUU7WUFDdEUscUNBQXFDO1lBQ3JDLG9DQUFvQztZQUNwQyxJQUFJLHVCQUF1QixLQUFLLE9BQU8sRUFBRTtnQkFDdkMsMkJBQTJCLENBQUM7b0JBQzFCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixhQUFhLEVBQUUsdUJBQXVCO29CQUN0QyxlQUFlLEVBQUUsT0FBTztvQkFDeEIsYUFBYSxlQUFBO29CQUNiLElBQUksTUFBQTtpQkFDTCxDQUFDLENBQUE7YUFDSDtpQkFBTTtnQkFDTCxPQUFPLENBQUMsR0FBRyxDQUFJLFlBQUksQ0FBQyxhQUFhLENBQUMsU0FBSSxPQUFPLFNBQUksYUFBSyxDQUFDLEdBQUcsQ0FBRyxDQUFDLENBQUE7YUFDL0Q7U0FDRjthQUFNO1lBQ0wsbUNBQW1DO1lBQ25DLCtEQUErRDtZQUMvRCxJQUFJLHVCQUF1QixLQUFLLE9BQU8sRUFBRTtnQkFDdkMseUJBQXlCLENBQUM7b0JBQ3hCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixhQUFhLEVBQUUsUUFBUTtvQkFDdkIsYUFBYSxlQUFBO29CQUNiLElBQUksTUFBQTtpQkFDTCxDQUFDLENBQUE7YUFDSDtpQkFBTTtnQkFDTCxnQ0FBZ0MsQ0FBQztvQkFDL0IsV0FBVyxFQUFFLElBQUk7b0JBQ2pCLGFBQWEsRUFBRSx1QkFBdUI7b0JBQ3RDLGVBQWUsRUFBRSxPQUFPO29CQUN4QixhQUFhLEVBQUUsUUFBUTtvQkFDdkIsSUFBSSxNQUFBO29CQUNKLGFBQWEsZUFBQTtpQkFDZCxDQUFDLENBQUE7YUFDSDtZQUNELE9BQU8sQ0FBQyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7U0FDckQ7SUFDSCxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQTtBQUVZLFFBQUEsVUFBVSxHQUFHLFVBQ3hCLGFBQXFCLEVBQ3JCLE9BQWdCO0lBRWhCLElBQU0saUJBQWlCLEdBQUcsdUJBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtJQUNoRSxJQUFNLEtBQUssR0FBRyxzQkFBYyxDQUFDLGlCQUFpQixDQUFDLENBQUE7SUFDL0MsSUFBSTtRQUNGLHNCQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxzQkFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQTtLQUN6RTtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1YsSUFBSTtZQUNGLHNCQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHNCQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtTQUN4RTtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxLQUFLLENBQUE7U0FDYjtLQUNGO0lBRUQsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDLENBQUE7QUFFRCxTQUFTLDJCQUEyQixDQUFDLEVBWXBDO1FBWEMsNEJBQVcsRUFDWCxnQ0FBYSxFQUNiLG9DQUFlLEVBQ2YsZ0NBQWEsRUFDYixjQUFJO0lBUUosT0FBTyxDQUFDLElBQUksQ0FBQyxPQUNiLFdBQUcsQ0FBQyxVQUFVLENBQUMseU1BT1gsV0FBVyxTQUFJLFlBQUksQ0FBQyxlQUFlLENBQUMsZ0NBSXBDLFdBQVcsU0FBSSxZQUFJLENBQUMsYUFBYSxDQUFDLGlDQUlsQyxJQUFJLHVQQU1KLFlBQUksQ0FBQyxtQkFBaUIsYUFBZSxDQUFDLHdGQUczQyxDQUFDLENBQUE7QUFDRixDQUFDO0FBRUQsU0FBUyx5QkFBeUIsQ0FBQyxFQVVsQztRQVRDLDRCQUFXLEVBQ1gsZ0NBQWEsRUFDYixjQUFJLEVBQ0osZ0NBQWE7SUFPYixPQUFPLENBQUMsS0FBSyxDQUFDLE9BQ2QsV0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBSSxXQUFHLENBQzFCLHVDQUFxQyxZQUFJLENBQUMsV0FBVyxDQUFDLGFBQVUsQ0FDakUsa0JBRUcsSUFBSSxnSEFJSSxhQUFhLG1QQU1QLGFBQWEsMktBT2hDLENBQUMsQ0FBQTtBQUNGLENBQUM7QUFFRCxTQUFTLGdDQUFnQyxDQUFDLEVBY3pDO1FBYkMsNEJBQVcsRUFDWCxnQ0FBYSxFQUNiLG9DQUFlLEVBQ2YsZ0NBQWEsRUFDYixjQUFJLEVBQ0osZ0NBQWE7SUFTYixPQUFPLENBQUMsS0FBSyxDQUFDLE9BQ2QsV0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBSSxXQUFHLENBQzFCLHVDQUFxQyxZQUFJLENBQUMsV0FBVyxDQUFDLGFBQVUsQ0FDakUsa0JBRUcsSUFBSSw0Q0FFd0IsWUFBSSxDQUFDLFdBQVcsQ0FBQyxpaUJBZS9CLGFBQWEsNkNBR1AsYUFBYSwwQ0FDTCxhQUFLLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQ0FDcEMsV0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FDL0MsQ0FBQyxDQUFBO0FBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJvbGQsIGdyZWVuLCByZWQsIHllbGxvdyB9IGZyb20gXCJjaGFsa1wiXG5pbXBvcnQgeyBnZXRQYXRjaEZpbGVzIH0gZnJvbSBcIi4vcGF0Y2hGc1wiXG5pbXBvcnQgeyBleGVjdXRlRWZmZWN0cyB9IGZyb20gXCIuL3BhdGNoL2FwcGx5XCJcbmltcG9ydCB7IGV4aXN0c1N5bmMsIHJlYWRGaWxlU3luYyB9IGZyb20gXCJmcy1leHRyYVwiXG5pbXBvcnQgeyBqb2luLCByZXNvbHZlIH0gZnJvbSBcIi4vcGF0aFwiXG5pbXBvcnQgeyBwb3NpeCB9IGZyb20gXCJwYXRoXCJcbmltcG9ydCB7IGdldFBhY2thZ2VEZXRhaWxzRnJvbVBhdGNoRmlsZW5hbWUgfSBmcm9tIFwiLi9QYWNrYWdlRGV0YWlsc1wiXG5pbXBvcnQgeyBwYXJzZVBhdGNoRmlsZSB9IGZyb20gXCIuL3BhdGNoL3BhcnNlXCJcbmltcG9ydCB7IHJldmVyc2VQYXRjaCB9IGZyb20gXCIuL3BhdGNoL3JldmVyc2VcIlxuaW1wb3J0IGlzQ2kgZnJvbSBcImlzLWNpXCJcblxuLy8gZG9uJ3Qgd2FudCB0byBleGl0KDEpIG9uIHBvc3RpbnNhbGwgbG9jYWxseS5cbi8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZHMzMDAvcGF0Y2gtcGFja2FnZS9pc3N1ZXMvODZcbmNvbnN0IHNob3VsZEV4aXRQb3N0aW5zdGFsbFdpdGhFcnJvciA9IGlzQ2kgfHwgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiXG5cbmZ1bmN0aW9uIGZpbmRQYXRjaEZpbGVzKHBhdGNoZXNEaXJlY3Rvcnk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgaWYgKCFleGlzdHNTeW5jKHBhdGNoZXNEaXJlY3RvcnkpKSB7XG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICByZXR1cm4gZ2V0UGF0Y2hGaWxlcyhwYXRjaGVzRGlyZWN0b3J5KSBhcyBzdHJpbmdbXVxufVxuXG5mdW5jdGlvbiBnZXRJbnN0YWxsZWRQYWNrYWdlVmVyc2lvbih7XG4gIGFwcFBhdGgsXG4gIHBhdGgsXG4gIHBhdGhTcGVjaWZpZXIsXG59OiB7XG4gIGFwcFBhdGg6IHN0cmluZ1xuICBwYXRoOiBzdHJpbmdcbiAgcGF0aFNwZWNpZmllcjogc3RyaW5nXG59KTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHBhY2thZ2VEaXIgPSBqb2luKGFwcFBhdGgsIHBhdGgpXG4gIGlmICghZXhpc3RzU3luYyhwYWNrYWdlRGlyKSkge1xuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYCR7eWVsbG93KFwiV2FybmluZzpcIil9IFBhdGNoIGZpbGUgZm91bmQgZm9yIHBhY2thZ2UgJHtwb3NpeC5iYXNlbmFtZShcbiAgICAgICAgcGF0aFNwZWNpZmllcixcbiAgICAgICl9YCArIGAgd2hpY2ggaXMgbm90IHByZXNlbnQgYXQgJHtwYWNrYWdlRGlyfWAsXG4gICAgKVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHJldHVybiByZXF1aXJlKGpvaW4ocGFja2FnZURpciwgXCJwYWNrYWdlLmpzb25cIikpLnZlcnNpb25cbn1cblxuZXhwb3J0IGNvbnN0IGFwcGx5UGF0Y2hlc0ZvckFwcCA9IChcbiAgYXBwUGF0aDogc3RyaW5nLFxuICByZXZlcnNlOiBib29sZWFuLFxuICBwYXRjaERpcjogc3RyaW5nID0gXCJwYXRjaGVzXCIsXG4pOiB2b2lkID0+IHtcbiAgY29uc3QgcGF0Y2hlc0RpcmVjdG9yeSA9IGpvaW4oYXBwUGF0aCwgcGF0Y2hEaXIpXG4gIGNvbnN0IGZpbGVzID0gZmluZFBhdGNoRmlsZXMocGF0Y2hlc0RpcmVjdG9yeSlcblxuICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5lcnJvcihyZWQoXCJObyBwYXRjaCBmaWxlcyBmb3VuZFwiKSlcbiAgICBwcm9jZXNzLmV4aXQoc2hvdWxkRXhpdFBvc3RpbnN0YWxsV2l0aEVycm9yID8gMSA6IDApXG4gIH1cblxuICBmaWxlcy5mb3JFYWNoKGZpbGVuYW1lID0+IHtcbiAgICBjb25zdCBkZXRhaWxzID0gZ2V0UGFja2FnZURldGFpbHNGcm9tUGF0Y2hGaWxlbmFtZShmaWxlbmFtZSlcblxuICAgIGlmICghZGV0YWlscykge1xuICAgICAgY29uc29sZS53YXJuKGBVbnJlY29nbml6ZWQgcGF0Y2ggZmlsZSBpbiBwYXRjaGVzIGRpcmVjdG9yeSAke2ZpbGVuYW1lfWApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB7IG5hbWUsIHZlcnNpb24sIHBhdGgsIHBhdGhTcGVjaWZpZXIgfSA9IGRldGFpbHNcblxuICAgIGNvbnN0IGluc3RhbGxlZFBhY2thZ2VWZXJzaW9uID0gZ2V0SW5zdGFsbGVkUGFja2FnZVZlcnNpb24oe1xuICAgICAgYXBwUGF0aCxcbiAgICAgIHBhdGgsXG4gICAgICBwYXRoU3BlY2lmaWVyLFxuICAgIH0pXG5cbiAgICBpZiAoIWluc3RhbGxlZFBhY2thZ2VWZXJzaW9uKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoYXBwbHlQYXRjaChyZXNvbHZlKHBhdGNoZXNEaXJlY3RvcnksIGZpbGVuYW1lKSBhcyBzdHJpbmcsIHJldmVyc2UpKSB7XG4gICAgICAvLyB5YXkgcGF0Y2ggd2FzIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICAvLyBwcmludCB3YXJuaW5nIGlmIHZlcnNpb24gbWlzbWF0Y2hcbiAgICAgIGlmIChpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbiAhPT0gdmVyc2lvbikge1xuICAgICAgICBwcmludFZlcnNpb25NaXNtYXRjaFdhcm5pbmcoe1xuICAgICAgICAgIHBhY2thZ2VOYW1lOiBuYW1lLFxuICAgICAgICAgIGFjdHVhbFZlcnNpb246IGluc3RhbGxlZFBhY2thZ2VWZXJzaW9uLFxuICAgICAgICAgIG9yaWdpbmFsVmVyc2lvbjogdmVyc2lvbixcbiAgICAgICAgICBwYXRoU3BlY2lmaWVyLFxuICAgICAgICAgIHBhdGgsXG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhgJHtib2xkKHBhdGhTcGVjaWZpZXIpfUAke3ZlcnNpb259ICR7Z3JlZW4oXCLinJRcIil9YClcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gY29tcGxldGVseSBmYWlsZWQgdG8gYXBwbHkgcGF0Y2hcbiAgICAgIC8vIFRPRE86IHByb3BhZ2F0ZSB1c2VmdWwgZXJyb3IgbWVzc2FnZXMgZnJvbSBwYXRjaCBhcHBsaWNhdGlvblxuICAgICAgaWYgKGluc3RhbGxlZFBhY2thZ2VWZXJzaW9uID09PSB2ZXJzaW9uKSB7XG4gICAgICAgIHByaW50QnJva2VuUGF0Y2hGaWxlRXJyb3Ioe1xuICAgICAgICAgIHBhY2thZ2VOYW1lOiBuYW1lLFxuICAgICAgICAgIHBhdGNoRmlsZU5hbWU6IGZpbGVuYW1lLFxuICAgICAgICAgIHBhdGhTcGVjaWZpZXIsXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByaW50UGF0Y2hBcHBsaWN0aW9uRmFpbHVyZUVycm9yKHtcbiAgICAgICAgICBwYWNrYWdlTmFtZTogbmFtZSxcbiAgICAgICAgICBhY3R1YWxWZXJzaW9uOiBpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbixcbiAgICAgICAgICBvcmlnaW5hbFZlcnNpb246IHZlcnNpb24sXG4gICAgICAgICAgcGF0Y2hGaWxlTmFtZTogZmlsZW5hbWUsXG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICBwYXRoU3BlY2lmaWVyLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgcHJvY2Vzcy5leGl0KHNob3VsZEV4aXRQb3N0aW5zdGFsbFdpdGhFcnJvciA/IDEgOiAwKVxuICAgIH1cbiAgfSlcbn1cblxuZXhwb3J0IGNvbnN0IGFwcGx5UGF0Y2ggPSAoXG4gIHBhdGNoRmlsZVBhdGg6IHN0cmluZyxcbiAgcmV2ZXJzZTogYm9vbGVhbixcbik6IGJvb2xlYW4gPT4ge1xuICBjb25zdCBwYXRjaEZpbGVDb250ZW50cyA9IHJlYWRGaWxlU3luYyhwYXRjaEZpbGVQYXRoKS50b1N0cmluZygpXG4gIGNvbnN0IHBhdGNoID0gcGFyc2VQYXRjaEZpbGUocGF0Y2hGaWxlQ29udGVudHMpXG4gIHRyeSB7XG4gICAgZXhlY3V0ZUVmZmVjdHMocmV2ZXJzZSA/IHJldmVyc2VQYXRjaChwYXRjaCkgOiBwYXRjaCwgeyBkcnlSdW46IGZhbHNlIH0pXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0cnkge1xuICAgICAgZXhlY3V0ZUVmZmVjdHMocmV2ZXJzZSA/IHBhdGNoIDogcmV2ZXJzZVBhdGNoKHBhdGNoKSwgeyBkcnlSdW46IHRydWUgfSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBwcmludFZlcnNpb25NaXNtYXRjaFdhcm5pbmcoe1xuICBwYWNrYWdlTmFtZSxcbiAgYWN0dWFsVmVyc2lvbixcbiAgb3JpZ2luYWxWZXJzaW9uLFxuICBwYXRoU3BlY2lmaWVyLFxuICBwYXRoLFxufToge1xuICBwYWNrYWdlTmFtZTogc3RyaW5nXG4gIGFjdHVhbFZlcnNpb246IHN0cmluZ1xuICBvcmlnaW5hbFZlcnNpb246IHN0cmluZ1xuICBwYXRoU3BlY2lmaWVyOiBzdHJpbmdcbiAgcGF0aDogc3RyaW5nXG59KSB7XG4gIGNvbnNvbGUud2FybihgXG4ke3JlZChcIldhcm5pbmc6XCIpfSBwYXRjaC1wYWNrYWdlIGRldGVjdGVkIGEgcGF0Y2ggZmlsZSB2ZXJzaW9uIG1pc21hdGNoXG5cbiAgRG9uJ3Qgd29ycnkhIFRoaXMgaXMgcHJvYmFibHkgZmluZS4gVGhlIHBhdGNoIHdhcyBzdGlsbCBhcHBsaWVkXG4gIHN1Y2Nlc3NmdWxseS4gSGVyZSdzIHRoZSBkZWV0czpcblxuICBQYXRjaCBmaWxlIGNyZWF0ZWQgZm9yXG5cbiAgICAke3BhY2thZ2VOYW1lfUAke2JvbGQob3JpZ2luYWxWZXJzaW9uKX1cblxuICBhcHBsaWVkIHRvXG5cbiAgICAke3BhY2thZ2VOYW1lfUAke2JvbGQoYWN0dWFsVmVyc2lvbil9XG4gIFxuICBBdCBwYXRoXG4gIFxuICAgICR7cGF0aH1cblxuICBUaGlzIHdhcm5pbmcgaXMganVzdCB0byBnaXZlIHlvdSBhIGhlYWRzLXVwLiBUaGVyZSBpcyBhIHNtYWxsIGNoYW5jZSBvZlxuICBicmVha2FnZSBldmVuIHRob3VnaCB0aGUgcGF0Y2ggd2FzIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5LiBNYWtlIHN1cmUgdGhlIHBhY2thZ2VcbiAgc3RpbGwgYmVoYXZlcyBsaWtlIHlvdSBleHBlY3QgKHlvdSB3cm90ZSB0ZXN0cywgcmlnaHQ/KSBhbmQgdGhlbiBydW5cblxuICAgICR7Ym9sZChgcGF0Y2gtcGFja2FnZSAke3BhdGhTcGVjaWZpZXJ9YCl9XG5cbiAgdG8gdXBkYXRlIHRoZSB2ZXJzaW9uIGluIHRoZSBwYXRjaCBmaWxlIG5hbWUgYW5kIG1ha2UgdGhpcyB3YXJuaW5nIGdvIGF3YXkuXG5gKVxufVxuXG5mdW5jdGlvbiBwcmludEJyb2tlblBhdGNoRmlsZUVycm9yKHtcbiAgcGFja2FnZU5hbWUsXG4gIHBhdGNoRmlsZU5hbWUsXG4gIHBhdGgsXG4gIHBhdGhTcGVjaWZpZXIsXG59OiB7XG4gIHBhY2thZ2VOYW1lOiBzdHJpbmdcbiAgcGF0Y2hGaWxlTmFtZTogc3RyaW5nXG4gIHBhdGg6IHN0cmluZ1xuICBwYXRoU3BlY2lmaWVyOiBzdHJpbmdcbn0pIHtcbiAgY29uc29sZS5lcnJvcihgXG4ke3JlZC5ib2xkKFwiKipFUlJPUioqXCIpfSAke3JlZChcbiAgICBgRmFpbGVkIHRvIGFwcGx5IHBhdGNoIGZvciBwYWNrYWdlICR7Ym9sZChwYWNrYWdlTmFtZSl9IGF0IHBhdGhgLFxuICApfVxuICBcbiAgICAke3BhdGh9XG5cbiAgVGhpcyBlcnJvciB3YXMgY2F1c2VkIGJlY2F1c2UgcGF0Y2gtcGFja2FnZSBjYW5ub3QgYXBwbHkgdGhlIGZvbGxvd2luZyBwYXRjaCBmaWxlOlxuXG4gICAgcGF0Y2hlcy8ke3BhdGNoRmlsZU5hbWV9XG5cbiAgVHJ5IHJlbW92aW5nIG5vZGVfbW9kdWxlcyBhbmQgdHJ5aW5nIGFnYWluLiBJZiB0aGF0IGRvZXNuJ3Qgd29yaywgbWF5YmUgdGhlcmUgd2FzXG4gIGFuIGFjY2lkZW50YWwgY2hhbmdlIG1hZGUgdG8gdGhlIHBhdGNoIGZpbGU/IFRyeSByZWNyZWF0aW5nIGl0IGJ5IG1hbnVhbGx5XG4gIGVkaXRpbmcgdGhlIGFwcHJvcHJpYXRlIGZpbGVzIGFuZCBydW5uaW5nOlxuICBcbiAgICBwYXRjaC1wYWNrYWdlICR7cGF0aFNwZWNpZmllcn1cbiAgXG4gIElmIHRoYXQgZG9lc24ndCB3b3JrLCB0aGVuIGl0J3MgYSBidWcgaW4gcGF0Y2gtcGFja2FnZSwgc28gcGxlYXNlIHN1Ym1pdCBhIGJ1Z1xuICByZXBvcnQuIFRoYW5rcyFcblxuICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9kczMwMC9wYXRjaC1wYWNrYWdlL2lzc3Vlc1xuICAgIFxuYClcbn1cblxuZnVuY3Rpb24gcHJpbnRQYXRjaEFwcGxpY3Rpb25GYWlsdXJlRXJyb3Ioe1xuICBwYWNrYWdlTmFtZSxcbiAgYWN0dWFsVmVyc2lvbixcbiAgb3JpZ2luYWxWZXJzaW9uLFxuICBwYXRjaEZpbGVOYW1lLFxuICBwYXRoLFxuICBwYXRoU3BlY2lmaWVyLFxufToge1xuICBwYWNrYWdlTmFtZTogc3RyaW5nXG4gIGFjdHVhbFZlcnNpb246IHN0cmluZ1xuICBvcmlnaW5hbFZlcnNpb246IHN0cmluZ1xuICBwYXRjaEZpbGVOYW1lOiBzdHJpbmdcbiAgcGF0aDogc3RyaW5nXG4gIHBhdGhTcGVjaWZpZXI6IHN0cmluZ1xufSkge1xuICBjb25zb2xlLmVycm9yKGBcbiR7cmVkLmJvbGQoXCIqKkVSUk9SKipcIil9ICR7cmVkKFxuICAgIGBGYWlsZWQgdG8gYXBwbHkgcGF0Y2ggZm9yIHBhY2thZ2UgJHtib2xkKHBhY2thZ2VOYW1lKX0gYXQgcGF0aGAsXG4gICl9XG4gIFxuICAgICR7cGF0aH1cblxuICBUaGlzIGVycm9yIHdhcyBjYXVzZWQgYmVjYXVzZSAke2JvbGQocGFja2FnZU5hbWUpfSBoYXMgY2hhbmdlZCBzaW5jZSB5b3VcbiAgbWFkZSB0aGUgcGF0Y2ggZmlsZSBmb3IgaXQuIFRoaXMgaW50cm9kdWNlZCBjb25mbGljdHMgd2l0aCB5b3VyIHBhdGNoLFxuICBqdXN0IGxpa2UgYSBtZXJnZSBjb25mbGljdCBpbiBHaXQgd2hlbiBzZXBhcmF0ZSBpbmNvbXBhdGlibGUgY2hhbmdlcyBhcmVcbiAgbWFkZSB0byB0aGUgc2FtZSBwaWVjZSBvZiBjb2RlLlxuXG4gIE1heWJlIHRoaXMgbWVhbnMgeW91ciBwYXRjaCBmaWxlIGlzIG5vIGxvbmdlciBuZWNlc3NhcnksIGluIHdoaWNoIGNhc2VcbiAgaG9vcmF5ISBKdXN0IGRlbGV0ZSBpdCFcblxuICBPdGhlcndpc2UsIHlvdSBuZWVkIGdlbmVyYXRlIGEgbmV3IHBhdGNoIGZpbGUuXG5cbiAgVG8gZ2VuZXJhdGUgYSBuZXcgb25lLCBqdXN0IHJlcGVhdCB0aGUgc3RlcHMgeW91IG1hZGUgdG8gZ2VuZXJhdGUgdGhlIGZpcnN0XG4gIG9uZS5cblxuICBpLmUuIG1hbnVhbGx5IG1ha2UgdGhlIGFwcHJvcHJpYXRlIGZpbGUgY2hhbmdlcywgdGhlbiBydW4gXG5cbiAgICBwYXRjaC1wYWNrYWdlICR7cGF0aFNwZWNpZmllcn1cblxuICBJbmZvOlxuICAgIFBhdGNoIGZpbGU6IHBhdGNoZXMvJHtwYXRjaEZpbGVOYW1lfVxuICAgIFBhdGNoIHdhcyBtYWRlIGZvciB2ZXJzaW9uOiAke2dyZWVuLmJvbGQob3JpZ2luYWxWZXJzaW9uKX1cbiAgICBJbnN0YWxsZWQgdmVyc2lvbjogJHtyZWQuYm9sZChhY3R1YWxWZXJzaW9uKX1cbmApXG59XG4iXX0=