@psync/patch-package 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,414 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.applyPatchesForApp = applyPatchesForApp;
7
+ exports.applyPatchesForPackage = applyPatchesForPackage;
8
+ exports.applyPatch = applyPatch;
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const fs_1 = require("fs");
11
+ const fs_extra_1 = require("fs-extra");
12
+ const path_1 = require("path");
13
+ const semver_1 = __importDefault(require("semver"));
14
+ const hash_1 = require("./hash");
15
+ const makePatch_1 = require("./makePatch");
16
+ const packageIsDevDependency_1 = require("./packageIsDevDependency");
17
+ const apply_1 = require("./patch/apply");
18
+ const read_1 = require("./patch/read");
19
+ const reverse_1 = require("./patch/reverse");
20
+ const patchFs_1 = require("./patchFs");
21
+ const path_2 = require("./path");
22
+ const stateFile_1 = require("./stateFile");
23
+ class PatchApplicationError extends Error {
24
+ constructor(msg) {
25
+ super(msg);
26
+ }
27
+ }
28
+ function getInstalledPackageVersion({ appPath, path, pathSpecifier, isDevOnly, patchFilename, }) {
29
+ const packageDir = (0, path_2.join)(appPath, path);
30
+ if (!(0, fs_extra_1.existsSync)(packageDir)) {
31
+ if (process.env.NODE_ENV === "production" && isDevOnly) {
32
+ return null;
33
+ }
34
+ let err = `${chalk_1.default.red("Error:")} Patch file found for package ${path_1.posix.basename(pathSpecifier)}` + ` which is not present at ${(0, path_2.relative)(".", packageDir)}`;
35
+ if (!isDevOnly && process.env.NODE_ENV === "production") {
36
+ err += `
37
+
38
+ If this package is a dev dependency, rename the patch file to
39
+
40
+ ${chalk_1.default.bold(patchFilename.replace(".patch", ".dev.patch"))}
41
+ `;
42
+ }
43
+ throw new PatchApplicationError(err);
44
+ }
45
+ const { version } = require((0, path_2.join)(packageDir, "package.json"));
46
+ // normalize version for `npm ci`
47
+ const result = semver_1.default.valid(version);
48
+ if (result === null) {
49
+ throw new PatchApplicationError(`${chalk_1.default.red("Error:")} Version string '${version}' cannot be parsed from ${(0, path_2.join)(packageDir, "package.json")}`);
50
+ }
51
+ return result;
52
+ }
53
+ function logPatchApplication(patchDetails) {
54
+ const sequenceString = patchDetails.sequenceNumber != null
55
+ ? ` (${patchDetails.sequenceNumber}${patchDetails.sequenceName ? " " + patchDetails.sequenceName : ""})`
56
+ : "";
57
+ console.log(`${chalk_1.default.bold(patchDetails.pathSpecifier)}@${patchDetails.version}${sequenceString} ${chalk_1.default.green("✔")}`);
58
+ }
59
+ function applyPatchesForApp({ appPath, reverse, patchDir, shouldExitWithError, shouldExitWithWarning, bestEffort, }) {
60
+ const patchesDirectory = (0, path_2.join)(appPath, patchDir);
61
+ const groupedPatches = (0, patchFs_1.getGroupedPatches)(patchesDirectory);
62
+ if (groupedPatches.numPatchFiles === 0) {
63
+ console.log(chalk_1.default.blueBright("No patch files found"));
64
+ return;
65
+ }
66
+ const errors = [];
67
+ const warnings = [...groupedPatches.warnings];
68
+ for (const patches of Object.values(groupedPatches.pathSpecifierToPatchFiles)) {
69
+ applyPatchesForPackage({
70
+ patches,
71
+ appPath,
72
+ patchDir,
73
+ reverse,
74
+ warnings,
75
+ errors,
76
+ bestEffort,
77
+ });
78
+ }
79
+ for (const warning of warnings) {
80
+ console.log(warning);
81
+ }
82
+ for (const error of errors) {
83
+ console.log(error);
84
+ }
85
+ const problemsSummary = [];
86
+ if (warnings.length) {
87
+ problemsSummary.push(chalk_1.default.yellow(`${warnings.length} warning(s)`));
88
+ }
89
+ if (errors.length) {
90
+ problemsSummary.push(chalk_1.default.red(`${errors.length} error(s)`));
91
+ }
92
+ if (problemsSummary.length) {
93
+ console.log("---");
94
+ console.log("patch-package finished with", problemsSummary.join(", ") + ".");
95
+ }
96
+ if (errors.length && shouldExitWithError) {
97
+ process.exit(1);
98
+ }
99
+ if (warnings.length && shouldExitWithWarning) {
100
+ process.exit(1);
101
+ }
102
+ process.exit(0);
103
+ }
104
+ function applyPatchesForPackage({ patches, appPath, patchDir, reverse, warnings, errors, bestEffort, }) {
105
+ const pathSpecifier = patches[0].pathSpecifier;
106
+ const state = patches.length > 1 ? (0, stateFile_1.getPatchApplicationState)(patches[0]) : null;
107
+ const unappliedPatches = patches.slice(0);
108
+ const appliedPatches = [];
109
+ // if there are multiple patches to apply, we can't rely on the reverse-patch-dry-run behavior to make this operation
110
+ // idempotent, so instead we need to check the state file to see whether we have already applied any of the patches
111
+ // todo: once this is battle tested we might want to use the same approach for single patches as well, but it's not biggie since the dry run thing is fast
112
+ if (unappliedPatches && state) {
113
+ for (let i = 0; i < state.patches.length; i++) {
114
+ const patchThatWasApplied = state.patches[i];
115
+ if (!patchThatWasApplied.didApply) {
116
+ break;
117
+ }
118
+ const patchToApply = unappliedPatches[0];
119
+ const currentPatchHash = (0, hash_1.hashFile)((0, path_2.join)(appPath, patchDir, patchToApply.patchFilename));
120
+ if (patchThatWasApplied.patchContentHash === currentPatchHash) {
121
+ // this patch was applied we can skip it
122
+ appliedPatches.push(unappliedPatches.shift());
123
+ }
124
+ else {
125
+ console.log(chalk_1.default.red("Error:"), `The patches for ${chalk_1.default.bold(pathSpecifier)} have changed.`, `You should reinstall your node_modules folder to make sure the package is up to date`);
126
+ process.exit(1);
127
+ }
128
+ }
129
+ }
130
+ if (reverse && state) {
131
+ // if we are reversing the patches we need to make the unappliedPatches array
132
+ // be the reversed version of the appliedPatches array.
133
+ // The applied patches array should then be empty because it is used differently
134
+ // when outputting the state file.
135
+ unappliedPatches.length = 0;
136
+ unappliedPatches.push(...appliedPatches);
137
+ unappliedPatches.reverse();
138
+ appliedPatches.length = 0;
139
+ }
140
+ if (appliedPatches.length) {
141
+ // some patches have already been applied
142
+ appliedPatches.forEach(logPatchApplication);
143
+ }
144
+ if (!unappliedPatches.length) {
145
+ return;
146
+ }
147
+ let failedPatch = null;
148
+ packageLoop: for (const patchDetails of unappliedPatches) {
149
+ try {
150
+ const { name, version, path, isDevOnly, patchFilename } = patchDetails;
151
+ const installedPackageVersion = getInstalledPackageVersion({
152
+ appPath,
153
+ path,
154
+ pathSpecifier,
155
+ isDevOnly: isDevOnly ||
156
+ // check for direct-dependents in prod
157
+ (process.env.NODE_ENV === "production" &&
158
+ (0, packageIsDevDependency_1.packageIsDevDependency)({
159
+ appPath,
160
+ patchDetails,
161
+ })),
162
+ patchFilename,
163
+ });
164
+ if (!installedPackageVersion) {
165
+ // it's ok we're in production mode and this is a dev only package
166
+ console.log(`Skipping dev-only ${chalk_1.default.bold(pathSpecifier)}@${version} ${chalk_1.default.blue("✔")}`);
167
+ continue;
168
+ }
169
+ if (applyPatch({
170
+ patchFilePath: (0, path_2.join)(appPath, patchDir, patchFilename),
171
+ reverse,
172
+ patchDetails,
173
+ patchDir,
174
+ cwd: process.cwd(),
175
+ bestEffort,
176
+ })) {
177
+ appliedPatches.push(patchDetails);
178
+ // yay patch was applied successfully
179
+ // print warning if version mismatch
180
+ if (installedPackageVersion !== version) {
181
+ warnings.push(createVersionMismatchWarning({
182
+ packageName: name,
183
+ actualVersion: installedPackageVersion,
184
+ originalVersion: version,
185
+ pathSpecifier,
186
+ path,
187
+ }));
188
+ }
189
+ logPatchApplication(patchDetails);
190
+ }
191
+ else if (patches.length > 1) {
192
+ (0, makePatch_1.logPatchSequenceError)({ patchDetails });
193
+ // in case the package has multiple patches, we need to break out of this inner loop
194
+ // because we don't want to apply more patches on top of the broken state
195
+ failedPatch = patchDetails;
196
+ break packageLoop;
197
+ }
198
+ else if (installedPackageVersion === version) {
199
+ // completely failed to apply patch
200
+ // TODO: propagate useful error messages from patch application
201
+ errors.push(createBrokenPatchFileError({
202
+ packageName: name,
203
+ patchFilename,
204
+ pathSpecifier,
205
+ path,
206
+ }));
207
+ break packageLoop;
208
+ }
209
+ else {
210
+ errors.push(createPatchApplicationFailureError({
211
+ packageName: name,
212
+ actualVersion: installedPackageVersion,
213
+ originalVersion: version,
214
+ patchFilename,
215
+ path,
216
+ pathSpecifier,
217
+ }));
218
+ // in case the package has multiple patches, we need to break out of this inner loop
219
+ // because we don't want to apply more patches on top of the broken state
220
+ break packageLoop;
221
+ }
222
+ }
223
+ catch (error) {
224
+ if (error instanceof PatchApplicationError) {
225
+ errors.push(error.message);
226
+ }
227
+ else {
228
+ errors.push(createUnexpectedError({
229
+ filename: patchDetails.patchFilename,
230
+ error: error,
231
+ }));
232
+ }
233
+ // in case the package has multiple patches, we need to break out of this inner loop
234
+ // because we don't want to apply more patches on top of the broken state
235
+ break packageLoop;
236
+ }
237
+ }
238
+ if (patches.length > 1) {
239
+ if (reverse) {
240
+ if (!state) {
241
+ throw new Error("unexpected state: no state file found while reversing");
242
+ }
243
+ // if we removed all the patches that were previously applied we can delete the state file
244
+ if (appliedPatches.length === patches.length) {
245
+ (0, stateFile_1.clearPatchApplicationState)(patches[0]);
246
+ }
247
+ else {
248
+ // We failed while reversing patches and some are still in the applied state.
249
+ // We need to update the state file to reflect that.
250
+ // appliedPatches is currently the patches that were successfully reversed, in the order they were reversed
251
+ // So we need to find the index of the last reversed patch in the original patches array
252
+ // and then remove all the patches after that. Sorry for the confusing code.
253
+ const lastReversedPatchIndex = patches.indexOf(appliedPatches[appliedPatches.length - 1]);
254
+ if (lastReversedPatchIndex === -1) {
255
+ throw new Error("unexpected state: failed to find last reversed patch in original patches array");
256
+ }
257
+ (0, stateFile_1.savePatchApplicationState)({
258
+ packageDetails: patches[0],
259
+ patches: patches.slice(0, lastReversedPatchIndex).map((patch) => ({
260
+ didApply: true,
261
+ patchContentHash: (0, hash_1.hashFile)((0, path_2.join)(appPath, patchDir, patch.patchFilename)),
262
+ patchFilename: patch.patchFilename,
263
+ })),
264
+ isRebasing: false,
265
+ });
266
+ }
267
+ }
268
+ else {
269
+ const nextState = appliedPatches.map((patch) => ({
270
+ didApply: true,
271
+ patchContentHash: (0, hash_1.hashFile)((0, path_2.join)(appPath, patchDir, patch.patchFilename)),
272
+ patchFilename: patch.patchFilename,
273
+ }));
274
+ if (failedPatch) {
275
+ nextState.push({
276
+ didApply: false,
277
+ patchContentHash: (0, hash_1.hashFile)((0, path_2.join)(appPath, patchDir, failedPatch.patchFilename)),
278
+ patchFilename: failedPatch.patchFilename,
279
+ });
280
+ }
281
+ (0, stateFile_1.savePatchApplicationState)({
282
+ packageDetails: patches[0],
283
+ patches: nextState,
284
+ isRebasing: !!failedPatch,
285
+ });
286
+ }
287
+ if (failedPatch) {
288
+ process.exit(1);
289
+ }
290
+ }
291
+ }
292
+ function applyPatch({ patchFilePath, reverse, patchDetails, patchDir, cwd, bestEffort, }) {
293
+ const patch = (0, read_1.readPatch)({
294
+ patchFilePath,
295
+ patchDetails,
296
+ patchDir,
297
+ });
298
+ const forward = reverse ? (0, reverse_1.reversePatch)(patch) : patch;
299
+ try {
300
+ if (!bestEffort) {
301
+ (0, apply_1.executeEffects)(forward, { dryRun: true, cwd, bestEffort: false });
302
+ }
303
+ const errors = bestEffort ? [] : undefined;
304
+ (0, apply_1.executeEffects)(forward, { dryRun: false, cwd, bestEffort, errors });
305
+ if (errors?.length) {
306
+ console.log("Saving errors to", chalk_1.default.cyan.bold("./patch-package-errors.log"));
307
+ (0, fs_1.writeFileSync)("patch-package-errors.log", errors.join("\n\n"));
308
+ process.exit(0);
309
+ }
310
+ }
311
+ catch (e) {
312
+ try {
313
+ const backward = reverse ? patch : (0, reverse_1.reversePatch)(patch);
314
+ (0, apply_1.executeEffects)(backward, {
315
+ dryRun: true,
316
+ cwd,
317
+ bestEffort: false,
318
+ });
319
+ }
320
+ catch (e) {
321
+ return false;
322
+ }
323
+ }
324
+ return true;
325
+ }
326
+ function createVersionMismatchWarning({ packageName, actualVersion, originalVersion, pathSpecifier, path, }) {
327
+ return `
328
+ ${chalk_1.default.yellow("Warning:")} patch-package detected a patch file version mismatch
329
+
330
+ Don't worry! This is probably fine. The patch was still applied
331
+ successfully. Here's the deets:
332
+
333
+ Patch file created for
334
+
335
+ ${packageName}@${chalk_1.default.bold(originalVersion)}
336
+
337
+ applied to
338
+
339
+ ${packageName}@${chalk_1.default.bold(actualVersion)}
340
+
341
+ At path
342
+
343
+ ${path}
344
+
345
+ This warning is just to give you a heads-up. There is a small chance of
346
+ breakage even though the patch was applied successfully. Make sure the package
347
+ still behaves like you expect (you wrote tests, right?) and then run
348
+
349
+ ${chalk_1.default.bold(`patch-package ${pathSpecifier}`)}
350
+
351
+ to update the version in the patch file name and make this warning go away.
352
+ `;
353
+ }
354
+ function createBrokenPatchFileError({ packageName, patchFilename, path, pathSpecifier, }) {
355
+ return `
356
+ ${chalk_1.default.red.bold("**ERROR**")} ${chalk_1.default.red(`Failed to apply patch for package ${chalk_1.default.bold(packageName)} at path`)}
357
+
358
+ ${path}
359
+
360
+ This error was caused because patch-package cannot apply the following patch file:
361
+
362
+ patches/${patchFilename}
363
+
364
+ Try removing node_modules and trying again. If that doesn't work, maybe there was
365
+ an accidental change made to the patch file? Try recreating it by manually
366
+ editing the appropriate files and running:
367
+
368
+ patch-package ${pathSpecifier}
369
+
370
+ If that doesn't work, then it's a bug in patch-package, so please submit a bug
371
+ report. Thanks!
372
+
373
+ https://github.com/ds300/patch-package/issues
374
+
375
+ `;
376
+ }
377
+ function createPatchApplicationFailureError({ packageName, actualVersion, originalVersion, patchFilename, path, pathSpecifier, }) {
378
+ return `
379
+ ${chalk_1.default.red.bold("**ERROR**")} ${chalk_1.default.red(`Failed to apply patch for package ${chalk_1.default.bold(packageName)} at path`)}
380
+
381
+ ${path}
382
+
383
+ This error was caused because ${chalk_1.default.bold(packageName)} has changed since you
384
+ made the patch file for it. This introduced conflicts with your patch,
385
+ just like a merge conflict in Git when separate incompatible changes are
386
+ made to the same piece of code.
387
+
388
+ Maybe this means your patch file is no longer necessary, in which case
389
+ hooray! Just delete it!
390
+
391
+ Otherwise, you need to generate a new patch file.
392
+
393
+ To generate a new one, just repeat the steps you made to generate the first
394
+ one.
395
+
396
+ i.e. manually make the appropriate file changes, then run
397
+
398
+ patch-package ${pathSpecifier}
399
+
400
+ Info:
401
+ Patch file: patches/${patchFilename}
402
+ Patch was made for version: ${chalk_1.default.green.bold(originalVersion)}
403
+ Installed version: ${chalk_1.default.red.bold(actualVersion)}
404
+ `;
405
+ }
406
+ function createUnexpectedError({ filename, error, }) {
407
+ return `
408
+ ${chalk_1.default.red.bold("**ERROR**")} ${chalk_1.default.red(`Failed to apply patch file ${chalk_1.default.bold(filename)}`)}
409
+
410
+ ${error.stack}
411
+
412
+ `;
413
+ }
414
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbHlQYXRjaGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwcGx5UGF0Y2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQTZGQSxnREFxRUM7QUFFRCx3REEwT0M7QUFFRCxnQ0FrREM7QUFsY0Qsa0RBQXlCO0FBQ3pCLDJCQUFrQztBQUNsQyx1Q0FBcUM7QUFDckMsK0JBQTRCO0FBQzVCLG9EQUEyQjtBQUMzQixpQ0FBaUM7QUFDakMsMkNBQW1EO0FBRW5ELHFFQUFpRTtBQUNqRSx5Q0FBOEM7QUFDOUMsdUNBQXdDO0FBQ3hDLDZDQUE4QztBQUM5Qyx1Q0FBNkM7QUFDN0MsaUNBQXVDO0FBQ3ZDLDJDQUtvQjtBQUVwQixNQUFNLHFCQUFzQixTQUFRLEtBQUs7SUFDdkMsWUFBWSxHQUFXO1FBQ3JCLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNaLENBQUM7Q0FDRjtBQUVELFNBQVMsMEJBQTBCLENBQUMsRUFDbEMsT0FBTyxFQUNQLElBQUksRUFDSixhQUFhLEVBQ2IsU0FBUyxFQUNULGFBQWEsR0FPZDtJQUNDLE1BQU0sVUFBVSxHQUFHLElBQUEsV0FBSSxFQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUN0QyxJQUFJLENBQUMsSUFBQSxxQkFBVSxFQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxZQUFZLElBQUksU0FBUyxFQUFFLENBQUM7WUFDdkQsT0FBTyxJQUFJLENBQUE7UUFDYixDQUFDO1FBRUQsSUFBSSxHQUFHLEdBQ0wsR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxpQ0FBaUMsWUFBSyxDQUFDLFFBQVEsQ0FDbkUsYUFBYSxDQUNkLEVBQUUsR0FBRyw0QkFBNEIsSUFBQSxlQUFRLEVBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUE7UUFFL0QsSUFBSSxDQUFDLFNBQVMsSUFBSSxPQUFP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QUFJLENBQUMsZUFBZSxDQUFDO3lCQUMxQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7Q0FDckQsQ0FBQTtBQUNELENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLEVBQzdCLFFBQVEsRUFDUixLQUFLLEdBSU47SUFDQyxPQUFPO0VBQ1AsZUFBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksZUFBSyxDQUFDLEdBQUcsQ0FDdEMsOEJBQThCLGVBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FDckQ7O0VBRUQsS0FBSyxDQUFDLEtBQUs7O0dBRVYsQ0FBQTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCJcclxuaW1wb3J0IHsgd3JpdGVGaWxlU3luYyB9IGZyb20gXCJmc1wiXHJcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwiZnMtZXh0cmFcIlxyXG5pbXBvcnQgeyBwb3NpeCB9IGZyb20gXCJwYXRoXCJcclxuaW1wb3J0IHNlbXZlciBmcm9tIFwic2VtdmVyXCJcclxuaW1wb3J0IHsgaGFzaEZpbGUgfSBmcm9tIFwiLi9oYXNoXCJcclxuaW1wb3J0IHsgbG9nUGF0Y2hTZXF1ZW5jZUVycm9yIH0gZnJvbSBcIi4vbWFrZVBhdGNoXCJcclxuaW1wb3J0IHsgUGFja2FnZURldGFpbHMsIFBhdGNoZWRQYWNrYWdlRGV0YWlscyB9IGZyb20gXCIuL1BhY2thZ2VEZXRhaWxzXCJcclxuaW1wb3J0IHsgcGFja2FnZUlzRGV2RGVwZW5kZW5jeSB9IGZyb20gXCIuL3BhY2thZ2VJc0RldkRlcGVuZGVuY3lcIlxyXG5pbXBvcnQgeyBleGVjdXRlRWZmZWN0cyB9IGZyb20gXCIuL3BhdGNoL2FwcGx5XCJcclxuaW1wb3J0IHsgcmVhZFBhdGNoIH0gZnJvbSBcIi4vcGF0Y2gvcmVhZFwiXHJcbmltcG9ydCB7IHJldmVyc2VQYXRjaCB9IGZyb20gXCIuL3BhdGNoL3JldmVyc2VcIlxyXG5pbXBvcnQgeyBnZXRHcm91cGVkUGF0Y2hlcyB9IGZyb20gXCIuL3BhdGNoRnNcIlxyXG5pbXBvcnQgeyBqb2luLCByZWxhdGl2ZSB9IGZyb20gXCIuL3BhdGhcIlxyXG5pbXBvcnQge1xyXG4gIGNsZWFyUGF0Y2hBcHBsaWNhdGlvblN0YXRlLFxyXG4gIGdldFBhdGNoQXBwbGljYXRpb25TdGF0ZSxcclxuICBQYXRjaFN0YXRlLFxyXG4gIHNhdmVQYXRjaEFwcGxpY2F0aW9uU3RhdGUsXHJcbn0gZnJvbSBcIi4vc3RhdGVGaWxlXCJcclxuXHJcbmNsYXNzIFBhdGNoQXBwbGljYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcclxuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZykge1xyXG4gICAgc3VwZXIobXNnKVxyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0SW5zdGFsbGVkUGFja2FnZVZlcnNpb24oe1xyXG4gIGFwcFBhdGgsXHJcbiAgcGF0aCxcclxuICBwYXRoU3BlY2lmaWVyLFxyXG4gIGlzRGV2T25seSxcclxuICBwYXRjaEZpbGVuYW1lLFxyXG59OiB7XHJcbiAgYXBwUGF0aDogc3RyaW5nXHJcbiAgcGF0aDogc3RyaW5nXHJcbiAgcGF0aFNwZWNpZmllcjogc3RyaW5nXHJcbiAgaXNEZXZPbmx5OiBib29sZWFuXHJcbiAgcGF0Y2hGaWxlbmFtZTogc3RyaW5nXHJcbn0pOiBudWxsIHwgc3RyaW5nIHtcclxuICBjb25zdCBwYWNrYWdlRGlyID0gam9pbihhcHBQYXRoLCBwYXRoKVxyXG4gIGlmICghZXhpc3RzU3luYyhwYWNrYWdlRGlyKSkge1xyXG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInByb2R1Y3Rpb25cIiAmJiBpc0Rldk9ubHkpIHtcclxuICAgICAgcmV0dXJuIG51bGxcclxuICAgIH1cclxuXHJcbiAgICBsZXQgZXJyID1cclxuICAgICAgYCR7Y2hhbGsucmVkKFwiRXJyb3I6XCIpfSBQYXRjaCBmaWxlIGZvdW5kIGZvciBwYWNrYWdlICR7cG9zaXguYmFzZW5hbWUoXHJcbiAgICAgICAgcGF0aFNwZWNpZmllcixcclxuICAgICAgKX1gICsgYCB3aGljaCBpcyBub3QgcHJlc2VudCBhdCAke3JlbGF0aXZlKFwiLlwiLCBwYWNrYWdlRGlyKX1gXHJcblxyXG4gICAgaWYgKCFpc0Rldk9ubHkgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwicHJvZHVjdGlvblwiKSB7XHJcbiAgICAgIGVyciArPSBgXHJcblxyXG4gIElmIHRoaXMgcGFja2FnZSBpcyBhIGRldiBkZXBlbmRlbmN5LCByZW5hbWUgdGhlIHBhdGNoIGZpbGUgdG9cclxuICBcclxuICAgICR7Y2hhbGsuYm9sZChwYXRjaEZpbGVuYW1lLnJlcGxhY2UoXCIucGF0Y2hcIiwgXCIuZGV2LnBhdGNoXCIpKX1cclxuYFxyXG4gICAgfVxyXG4gICAgdGhyb3cgbmV3IFBhdGNoQXBwbGljYXRpb25FcnJvcihlcnIpXHJcbiAgfVxyXG5cclxuICBjb25zdCB7IHZlcnNpb24gfSA9IHJlcXVpcmUoam9pbihwYWNrYWdlRGlyLCBcInBhY2thZ2UuanNvblwiKSlcclxuICAvLyBub3JtYWxpemUgdmVyc2lvbiBmb3IgYG5wbSBjaWBcclxuICBjb25zdCByZXN1bHQgPSBzZW12ZXIudmFsaWQodmVyc2lvbilcclxuICBpZiAocmVzdWx0ID09PSBudWxsKSB7XHJcbiAgICB0aHJvdyBuZXcgUGF0Y2hBcHBsaWNhdGlvbkVycm9yKFxyXG4gICAgICBgJHtjaGFsay5yZWQoXHJcbiAgICAgICAgXCJFcnJvcjpcIixcclxuICAgICAgKX0gVmVyc2lvbiBzdHJpbmcgJyR7dmVyc2lvbn0nIGNhbm5vdCBiZSBwYXJzZWQgZnJvbSAke2pvaW4oXHJcbiAgICAgICAgcGFja2FnZURpcixcclxuICAgICAgICBcInBhY2thZ2UuanNvblwiLFxyXG4gICAgICApfWAsXHJcbiAgICApXHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzdWx0IGFzIHN0cmluZ1xyXG59XHJcblxyXG5mdW5jdGlvbiBsb2dQYXRjaEFwcGxpY2F0aW9uKHBhdGNoRGV0YWlsczogUGF0Y2hlZFBhY2thZ2VEZXRhaWxzKSB7XHJcbiAgY29uc3Qgc2VxdWVuY2VTdHJpbmcgPVxyXG4gICAgcGF0Y2hEZXRhaWxzLnNlcXVlbmNlTnVtYmVyICE9IG51bGxcclxuICAgICAgPyBgICgke3BhdGNoRGV0YWlscy5zZXF1ZW5jZU51bWJlcn0ke1xyXG4gICAgICAgICAgcGF0Y2hEZXRhaWxzLnNlcXVlbmNlTmFtZSA/IFwiIFwiICsgcGF0Y2hEZXRhaWxzLnNlcXVlbmNlTmFtZSA6IFwiXCJcclxuICAgICAgICB9KWBcclxuICAgICAgOiBcIlwiXHJcbiAgY29uc29sZS5sb2coXHJcbiAgICBgJHtjaGFsay5ib2xkKHBhdGNoRGV0YWlscy5wYXRoU3BlY2lmaWVyKX1AJHtcclxuICAgICAgcGF0Y2hEZXRhaWxzLnZlcnNpb25cclxuICAgIH0ke3NlcXVlbmNlU3RyaW5nfSAke2NoYWxrLmdyZWVuKFwi4pyUXCIpfWAsXHJcbiAgKVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQYXRjaGVzRm9yQXBwKHtcclxuICBhcHBQYXRoLFxyXG4gIHJldmVyc2UsXHJcbiAgcGF0Y2hEaXIsXHJcbiAgc2hvdWxkRXhpdFdpdGhFcnJvcixcclxuICBzaG91bGRFeGl0V2l0aFdhcm5pbmcsXHJcbiAgYmVzdEVmZm9ydCxcclxufToge1xyXG4gIGFwcFBhdGg6IHN0cmluZ1xyXG4gIHJldmVyc2U6IGJvb2xlYW5cclxuICBwYXRjaERpcjogc3RyaW5nXHJcbiAgc2hvdWxkRXhpdFdpdGhFcnJvcjogYm9vbGVhblxyXG4gIHNob3VsZEV4aXRXaXRoV2FybmluZzogYm9vbGVhblxyXG4gIGJlc3RFZmZvcnQ6IGJvb2xlYW5cclxufSk6IHZvaWQge1xyXG4gIGNvbnN0IHBhdGNoZXNEaXJlY3RvcnkgPSBqb2luKGFwcFBhdGgsIHBhdGNoRGlyKVxyXG4gIGNvbnN0IGdyb3VwZWRQYXRjaGVzID0gZ2V0R3JvdXBlZFBhdGNoZXMocGF0Y2hlc0RpcmVjdG9yeSlcclxuXHJcbiAgaWYgKGdyb3VwZWRQYXRjaGVzLm51bVBhdGNoRmlsZXMgPT09IDApIHtcclxuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsdWVCcmlnaHQoXCJObyBwYXRjaCBmaWxlcyBmb3VuZFwiKSlcclxuICAgIHJldHVyblxyXG4gIH1cclxuXHJcbiAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdXHJcbiAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gWy4uLmdyb3VwZWRQYXRjaGVzLndhcm5pbmdzXVxyXG5cclxuICBmb3IgKGNvbnN0IHBhdGNoZXMgb2YgT2JqZWN0LnZhbHVlcyhcclxuICAgIGdyb3VwZWRQYXRjaGVzLnBhdGhTcGVjaWZpZXJUb1BhdGNoRmlsZXMsXHJcbiAgKSkge1xyXG4gICAgYXBwbHlQYXRjaGVzRm9yUGFja2FnZSh7XHJcbiAgICAgIHBhdGNoZXMsXHJcbiAgICAgIGFwcFBhdGgsXHJcbiAgICAgIHBhdGNoRGlyLFxyXG4gICAgICByZXZlcnNlLFxyXG4gICAgICB3YXJuaW5ncyxcclxuICAgICAgZXJyb3JzLFxyXG4gICAgICBiZXN0RWZmb3J0LFxyXG4gICAgfSlcclxuICB9XHJcblxyXG4gIGZvciAoY29uc3Qgd2FybmluZyBvZiB3YXJuaW5ncykge1xyXG4gICAgY29uc29sZS5sb2cod2FybmluZylcclxuICB9XHJcbiAgZm9yIChjb25zdCBlcnJvciBvZiBlcnJvcnMpIHtcclxuICAgIGNvbnNvbGUubG9nKGVycm9yKVxyXG4gIH1cclxuXHJcbiAgY29uc3QgcHJvYmxlbXNTdW1tYXJ5ID0gW11cclxuICBpZiAod2FybmluZ3MubGVuZ3RoKSB7XHJcbiAgICBwcm9ibGVtc1N1bW1hcnkucHVzaChjaGFsay55ZWxsb3coYCR7d2FybmluZ3MubGVuZ3RofSB3YXJuaW5nKHMpYCkpXHJcbiAgfVxyXG4gIGlmIChlcnJvcnMubGVuZ3RoKSB7XHJcbiAgICBwcm9ibGVtc1N1bW1hcnkucHVzaChjaGFsay5yZWQoYCR7ZXJyb3JzLmxlbmd0aH0gZXJyb3IocylgKSlcclxuICB9XHJcblxyXG4gIGlmIChwcm9ibGVtc1N1bW1hcnkubGVuZ3RoKSB7XHJcbiAgICBjb25zb2xlLmxvZyhcIi0tLVwiKVxyXG4gICAgY29uc29sZS5sb2coXCJwYXRjaC1wYWNrYWdlIGZpbmlzaGVkIHdpdGhcIiwgcHJvYmxlbXNTdW1tYXJ5LmpvaW4oXCIsIFwiKSArIFwiLlwiKVxyXG4gIH1cclxuXHJcbiAgaWYgKGVycm9ycy5sZW5ndGggJiYgc2hvdWxkRXhpdFdpdGhFcnJvcikge1xyXG4gICAgcHJvY2Vzcy5leGl0KDEpXHJcbiAgfVxyXG5cclxuICBpZiAod2FybmluZ3MubGVuZ3RoICYmIHNob3VsZEV4aXRXaXRoV2FybmluZykge1xyXG4gICAgcHJvY2Vzcy5leGl0KDEpXHJcbiAgfVxyXG5cclxuICBwcm9jZXNzLmV4aXQoMClcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2hlc0ZvclBhY2thZ2Uoe1xyXG4gIHBhdGNoZXMsXHJcbiAgYXBwUGF0aCxcclxuICBwYXRjaERpcixcclxuICByZXZlcnNlLFxyXG4gIHdhcm5pbmdzLFxyXG4gIGVycm9ycyxcclxuICBiZXN0RWZmb3J0LFxyXG59OiB7XHJcbiAgcGF0Y2hlczogUGF0Y2hlZFBhY2thZ2VEZXRhaWxzW11cclxuICBhcHBQYXRoOiBzdHJpbmdcclxuICBwYXRjaERpcjogc3RyaW5nXHJcbiAgcmV2ZXJzZTogYm9vbGVhblxyXG4gIHdhcm5pbmdzOiBzdHJpbmdbXVxyXG4gIGVycm9yczogc3RyaW5nW11cclxuICBiZXN0RWZmb3J0OiBib29sZWFuXHJcbn0pIHtcclxuICBjb25zdCBwYXRoU3BlY2lmaWVyID0gcGF0Y2hlc1swXS5wYXRoU3BlY2lmaWVyXHJcbiAgY29uc3Qgc3RhdGUgPSBwYXRjaGVzLmxlbmd0aCA+IDEgPyBnZXRQYXRjaEFwcGxpY2F0aW9uU3RhdGUocGF0Y2hlc1swXSkgOiBudWxsXHJcbiAgY29uc3QgdW5hcHBsaWVkUGF0Y2hlcyA9IHBhdGNoZXMuc2xpY2UoMClcclxuICBjb25zdCBhcHBsaWVkUGF0Y2hlczogUGF0Y2hlZFBhY2thZ2VEZXRhaWxzW10gPSBbXVxyXG4gIC8vIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBwYXRjaGVzIHRvIGFwcGx5LCB3ZSBjYW4ndCByZWx5IG9uIHRoZSByZXZlcnNlLXBhdGNoLWRyeS1ydW4gYmVoYXZpb3IgdG8gbWFrZSB0aGlzIG9wZXJhdGlvblxyXG4gIC8vIGlkZW1wb3RlbnQsIHNvIGluc3RlYWQgd2UgbmVlZCB0byBjaGVjayB0aGUgc3RhdGUgZmlsZSB0byBzZWUgd2hldGhlciB3ZSBoYXZlIGFscmVhZHkgYXBwbGllZCBhbnkgb2YgdGhlIHBhdGNoZXNcclxuICAvLyB0b2RvOiBvbmNlIHRoaXMgaXMgYmF0dGxlIHRlc3RlZCB3ZSBtaWdodCB3YW50IHRvIHVzZSB0aGUgc2FtZSBhcHByb2FjaCBmb3Igc2luZ2xlIHBhdGNoZXMgYXMgd2VsbCwgYnV0IGl0J3Mgbm90IGJpZ2dpZSBzaW5jZSB0aGUgZHJ5IHJ1biB0aGluZyBpcyBmYXN0XHJcbiAgaWYgKHVuYXBwbGllZFBhdGNoZXMgJiYgc3RhdGUpIHtcclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhdGUucGF0Y2hlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICBjb25zdCBwYXRjaFRoYXRXYXNBcHBsaWVkID0gc3RhdGUucGF0Y2hlc1tpXVxyXG4gICAgICBpZiAoIXBhdGNoVGhhdFdhc0FwcGxpZWQuZGlkQXBwbHkpIHtcclxuICAgICAgICBicmVha1xyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IHBhdGNoVG9BcHBseSA9IHVuYXBwbGllZFBhdGNoZXNbMF1cclxuICAgICAgY29uc3QgY3VycmVudFBhdGNoSGFzaCA9IGhhc2hGaWxlKFxyXG4gICAgICAgIGpvaW4oYXBwUGF0aCwgcGF0Y2hEaXIsIHBhdGNoVG9BcHBseS5wYXRjaEZpbGVuYW1lKSxcclxuICAgICAgKVxyXG4gICAgICBpZiAocGF0Y2hUaGF0V2FzQXBwbGllZC5wYXRjaENvbnRlbnRIYXNoID09PSBjdXJyZW50UGF0Y2hIYXNoKSB7XHJcbiAgICAgICAgLy8gdGhpcyBwYXRjaCB3YXMgYXBwbGllZCB3ZSBjYW4gc2tpcCBpdFxyXG4gICAgICAgIGFwcGxpZWRQYXRjaGVzLnB1c2godW5hcHBsaWVkUGF0Y2hlcy5zaGlmdCgpISlcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zb2xlLmxvZyhcclxuICAgICAgICAgIGNoYWxrLnJlZChcIkVycm9yOlwiKSxcclxuICAgICAgICAgIGBUaGUgcGF0Y2hlcyBmb3IgJHtjaGFsay5ib2xkKHBhdGhTcGVjaWZpZXIpfSBoYXZlIGNoYW5nZWQuYCxcclxuICAgICAgICAgIGBZb3Ugc2hvdWxkIHJlaW5zdGFsbCB5b3VyIG5vZGVfbW9kdWxlcyBmb2xkZXIgdG8gbWFrZSBzdXJlIHRoZSBwYWNrYWdlIGlzIHVwIHRvIGRhdGVgLFxyXG4gICAgICAgIClcclxuICAgICAgICBwcm9jZXNzLmV4aXQoMSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKHJldmVyc2UgJiYgc3RhdGUpIHtcclxuICAgIC8vIGlmIHdlIGFyZSByZXZlcnNpbmcgdGhlIHBhdGNoZXMgd2UgbmVlZCB0byBtYWtlIHRoZSB1bmFwcGxpZWRQYXRjaGVzIGFycmF5XHJcbiAgICAvLyBiZSB0aGUgcmV2ZXJzZWQgdmVyc2lvbiBvZiB0aGUgYXBwbGllZFBhdGNoZXMgYXJyYXkuXHJcbiAgICAvLyBUaGUgYXBwbGllZCBwYXRjaGVzIGFycmF5IHNob3VsZCB0aGVuIGJlIGVtcHR5IGJlY2F1c2UgaXQgaXMgdXNlZCBkaWZmZXJlbnRseVxyXG4gICAgLy8gd2hlbiBvdXRwdXR0aW5nIHRoZSBzdGF0ZSBmaWxlLlxyXG4gICAgdW5hcHBsaWVkUGF0Y2hlcy5sZW5ndGggPSAwXHJcbiAgICB1bmFwcGxpZWRQYXRjaGVzLnB1c2goLi4uYXBwbGllZFBhdGNoZXMpXHJcbiAgICB1bmFwcGxpZWRQYXRjaGVzLnJldmVyc2UoKVxyXG4gICAgYXBwbGllZFBhdGNoZXMubGVuZ3RoID0gMFxyXG4gIH1cclxuICBpZiAoYXBwbGllZFBhdGNoZXMubGVuZ3RoKSB7XHJcbiAgICAvLyBzb21lIHBhdGNoZXMgaGF2ZSBhbHJlYWR5IGJlZW4gYXBwbGllZFxyXG4gICAgYXBwbGllZFBhdGNoZXMuZm9yRWFjaChsb2dQYXRjaEFwcGxpY2F0aW9uKVxyXG4gIH1cclxuICBpZiAoIXVuYXBwbGllZFBhdGNoZXMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm5cclxuICB9XHJcbiAgbGV0IGZhaWxlZFBhdGNoOiBQYXRjaGVkUGFja2FnZURldGFpbHMgfCBudWxsID0gbnVsbFxyXG4gIHBhY2thZ2VMb29wOiBmb3IgKGNvbnN0IHBhdGNoRGV0YWlscyBvZiB1bmFwcGxpZWRQYXRjaGVzKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCB7IG5hbWUsIHZlcnNpb24sIHBhdGgsIGlzRGV2T25seSwgcGF0Y2hGaWxlbmFtZSB9ID0gcGF0Y2hEZXRhaWxzXHJcblxyXG4gICAgICBjb25zdCBpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbiA9IGdldEluc3RhbGxlZFBhY2thZ2VWZXJzaW9uKHtcclxuICAgICAgICBhcHBQYXRoLFxyXG4gICAgICAgIHBhdGgsXHJcbiAgICAgICAgcGF0aFNwZWNpZmllcixcclxuICAgICAgICBpc0Rldk9ubHk6XHJcbiAgICAgICAgICBpc0Rldk9ubHkgfHxcclxuICAgICAgICAgIC8vIGNoZWNrIGZvciBkaXJlY3QtZGVwZW5kZW50cyBpbiBwcm9kXHJcbiAgICAgICAgICAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwicHJvZHVjdGlvblwiICYmXHJcbiAgICAgICAgICAgIHBhY2thZ2VJc0RldkRlcGVuZGVuY3koe1xyXG4gICAgICAgICAgICAgIGFwcFBhdGgsXHJcbiAgICAgICAgICAgICAgcGF0Y2hEZXRhaWxzLFxyXG4gICAgICAgICAgICB9KSksXHJcbiAgICAgICAgcGF0Y2hGaWxlbmFtZSxcclxuICAgICAgfSlcclxuICAgICAgaWYgKCFpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbikge1xyXG4gICAgICAgIC8vIGl0J3Mgb2sgd2UncmUgaW4gcHJvZHVjdGlvbiBtb2RlIGFuZCB0aGlzIGlzIGEgZGV2IG9ubHkgcGFja2FnZVxyXG4gICAgICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICAgICAgYFNraXBwaW5nIGRldi1vbmx5ICR7Y2hhbGsuYm9sZChcclxuICAgICAgICAgICAgcGF0aFNwZWNpZmllcixcclxuICAgICAgICAgICl9QCR7dmVyc2lvbn0gJHtjaGFsay5ibHVlKFwi4pyUXCIpfWAsXHJcbiAgICAgICAgKVxyXG4gICAgICAgIGNvbnRpbnVlXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChcclxuICAgICAgICBhcHBseVBhdGNoKHtcclxuICAgICAgICAgIHBhdGNoRmlsZVBhdGg6IGpvaW4oYXBwUGF0aCwgcGF0Y2hEaXIsIHBhdGNoRmlsZW5hbWUpIGFzIHN0cmluZyxcclxuICAgICAgICAgIHJldmVyc2UsXHJcbiAgICAgICAgICBwYXRjaERldGFpbHMsXHJcbiAgICAgICAgICBwYXRjaERpcixcclxuICAgICAgICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcclxuICAgICAgICAgIGJlc3RFZmZvcnQsXHJcbiAgICAgICAgfSlcclxuICAgICAgKSB7XHJcbiAgICAgICAgYXBwbGllZFBhdGNoZXMucHVzaChwYXRjaERldGFpbHMpXHJcbiAgICAgICAgLy8geWF5IHBhdGNoIHdhcyBhcHBsaWVkIHN1Y2Nlc3NmdWxseVxyXG4gICAgICAgIC8vIHByaW50IHdhcm5pbmcgaWYgdmVyc2lvbiBtaXNtYXRjaFxyXG4gICAgICAgIGlmIChpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbiAhPT0gdmVyc2lvbikge1xyXG4gICAgICAgICAgd2FybmluZ3MucHVzaChcclxuICAgICAgICAgICAgY3JlYXRlVmVyc2lvbk1pc21hdGNoV2FybmluZyh7XHJcbiAgICAgICAgICAgICAgcGFja2FnZU5hbWU6IG5hbWUsXHJcbiAgICAgICAgICAgICAgYWN0dWFsVmVyc2lvbjogaW5zdGFsbGVkUGFja2FnZVZlcnNpb24sXHJcbiAgICAgICAgICAgICAgb3JpZ2luYWxWZXJzaW9uOiB2ZXJzaW9uLFxyXG4gICAgICAgICAgICAgIHBhdGhTcGVjaWZpZXIsXHJcbiAgICAgICAgICAgICAgcGF0aCxcclxuICAgICAgICAgICAgfSksXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGxvZ1BhdGNoQXBwbGljYXRpb24ocGF0Y2hEZXRhaWxzKVxyXG4gICAgICB9IGVsc2UgaWYgKHBhdGNoZXMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgIGxvZ1BhdGNoU2VxdWVuY2VFcnJvcih7IHBhdGNoRGV0YWlscyB9KVxyXG4gICAgICAgIC8vIGluIGNhc2UgdGhlIHBhY2thZ2UgaGFzIG11bHRpcGxlIHBhdGNoZXMsIHdlIG5lZWQgdG8gYnJlYWsgb3V0IG9mIHRoaXMgaW5uZXIgbG9vcFxyXG4gICAgICAgIC8vIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBhcHBseSBtb3JlIHBhdGNoZXMgb24gdG9wIG9mIHRoZSBicm9rZW4gc3RhdGVcclxuICAgICAgICBmYWlsZWRQYXRjaCA9IHBhdGNoRGV0YWlsc1xyXG4gICAgICAgIGJyZWFrIHBhY2thZ2VMb29wXHJcbiAgICAgIH0gZWxzZSBpZiAoaW5zdGFsbGVkUGFja2FnZVZlcnNpb24gPT09IHZlcnNpb24pIHtcclxuICAgICAgICAvLyBjb21wbGV0ZWx5IGZhaWxlZCB0byBhcHBseSBwYXRjaFxyXG4gICAgICAgIC8vIFRPRE86IHByb3BhZ2F0ZSB1c2VmdWwgZXJyb3IgbWVzc2FnZXMgZnJvbSBwYXRjaCBhcHBsaWNhdGlvblxyXG4gICAgICAgIGVycm9ycy5wdXNoKFxyXG4gICAgICAgICAgY3JlYXRlQnJva2VuUGF0Y2hGaWxlRXJyb3Ioe1xyXG4gICAgICAgICAgICBwYWNrYWdlTmFtZTogbmFtZSxcclxuICAgICAgICAgICAgcGF0Y2hGaWxlbmFtZSxcclxuICAgICAgICAgICAgcGF0aFNwZWNpZmllcixcclxuICAgICAgICAgICAgcGF0aCxcclxuICAgICAgICAgIH0pLFxyXG4gICAgICAgIClcclxuICAgICAgICBicmVhayBwYWNrYWdlTG9vcFxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVycm9ycy5wdXNoKFxyXG4gICAgICAgICAgY3JlYXRlUGF0Y2hBcHBsaWNhdGlvbkZhaWx1cmVFcnJvcih7XHJcbiAgICAgICAgICAgIHBhY2thZ2VOYW1lOiBuYW1lLFxyXG4gICAgICAgICAgICBhY3R1YWxWZXJzaW9uOiBpbnN0YWxsZWRQYWNrYWdlVmVyc2lvbixcclxuICAgICAgICAgICAgb3JpZ2luYWxWZXJzaW9uOiB2ZXJzaW9uLFxyXG4gICAgICAgICAgICBwYXRjaEZpbGVuYW1lLFxyXG4gICAgICAgICAgICBwYXRoLFxyXG4gICAgICAgICAgICBwYXRoU3BlY2lmaWVyLFxyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC8vIGluIGNhc2UgdGhlIHBhY2thZ2UgaGFzIG11bHRpcGxlIHBhdGNoZXMsIHdlIG5lZWQgdG8gYnJlYWsgb3V0IG9mIHRoaXMgaW5uZXIgbG9vcFxyXG4gICAgICAgIC8vIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBhcHBseSBtb3JlIHBhdGNoZXMgb24gdG9wIG9mIHRoZSBicm9rZW4gc3RhdGVcclxuICAgICAgICBicmVhayBwYWNrYWdlTG9vcFxyXG4gICAgICB9XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXRjaEFwcGxpY2F0aW9uRXJyb3IpIHtcclxuICAgICAgICBlcnJvcnMucHVzaChlcnJvci5tZXNzYWdlKVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGVycm9ycy5wdXNoKFxyXG4gICAgICAgICAgY3JlYXRlVW5leHBlY3RlZEVycm9yKHtcclxuICAgICAgICAgICAgZmlsZW5hbWU6IHBhdGNoRGV0YWlscy5wYXRjaEZpbGVuYW1lLFxyXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgYXMgRXJyb3IsXHJcbiAgICAgICAgICB9KSxcclxuICAgICAgICApXHJcbiAgICAgIH1cclxuICAgICAgLy8gaW4gY2FzZSB0aGUgcGFja2FnZSBoYXMgbXVsdGlwbGUgcGF0Y2hlcywgd2UgbmVlZCB0byBicmVhayBvdXQgb2YgdGhpcyBpbm5lciBsb29wXHJcbiAgICAgIC8vIGJlY2F1c2Ugd2UgZG9uJ3Qgd2FudCB0byBhcHBseSBtb3JlIHBhdGNoZXMgb24gdG9wIG9mIHRoZSBicm9rZW4gc3RhdGVcclxuICAgICAgYnJlYWsgcGFja2FnZUxvb3BcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChwYXRjaGVzLmxlbmd0aCA+IDEpIHtcclxuICAgIGlmIChyZXZlcnNlKSB7XHJcbiAgICAgIGlmICghc3RhdGUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmV4cGVjdGVkIHN0YXRlOiBubyBzdGF0ZSBmaWxlIGZvdW5kIHdoaWxlIHJldmVyc2luZ1wiKVxyXG4gICAgICB9XHJcbiAgICAgIC8vIGlmIHdlIHJlbW92ZWQgYWxsIHRoZSBwYXRjaGVzIHRoYXQgd2VyZSBwcmV2aW91c2x5IGFwcGxpZWQgd2UgY2FuIGRlbGV0ZSB0aGUgc3RhdGUgZmlsZVxyXG4gICAgICBpZiAoYXBwbGllZFBhdGNoZXMubGVuZ3RoID09PSBwYXRjaGVzLmxlbmd0aCkge1xyXG4gICAgICAgIGNsZWFyUGF0Y2hBcHBsaWNhdGlvblN0YXRlKHBhdGNoZXNbMF0pXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gV2UgZmFpbGVkIHdoaWxlIHJldmVyc2luZyBwYXRjaGVzIGFuZCBzb21lIGFyZSBzdGlsbCBpbiB0aGUgYXBwbGllZCBzdGF0ZS5cclxuICAgICAgICAvLyBXZSBuZWVkIHRvIHVwZGF0ZSB0aGUgc3RhdGUgZmlsZSB0byByZWZsZWN0IHRoYXQuXHJcbiAgICAgICAgLy8gYXBwbGllZFBhdGNoZXMgaXMgY3VycmVudGx5IHRoZSBwYXRjaGVzIHRoYXQgd2VyZSBzdWNjZXNzZnVsbHkgcmV2ZXJzZWQsIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgcmV2ZXJzZWRcclxuICAgICAgICAvLyBTbyB3ZSBuZWVkIHRvIGZpbmQgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHJldmVyc2VkIHBhdGNoIGluIHRoZSBvcmlnaW5hbCBwYXRjaGVzIGFycmF5XHJcbiAgICAgICAgLy8gYW5kIHRoZW4gcmVtb3ZlIGFsbCB0aGUgcGF0Y2hlcyBhZnRlciB0aGF0LiBTb3JyeSBmb3IgdGhlIGNvbmZ1c2luZyBjb2RlLlxyXG4gICAgICAgIGNvbnN0IGxhc3RSZXZlcnNlZFBhdGNoSW5kZXggPSBwYXRjaGVzLmluZGV4T2YoXHJcbiAgICAgICAgICBhcHBsaWVkUGF0Y2hlc1thcHBsaWVkUGF0Y2hlcy5sZW5ndGggLSAxXSxcclxuICAgICAgICApXHJcbiAgICAgICAgaWYgKGxhc3RSZXZlcnNlZFBhdGNoSW5kZXggPT09IC0xKSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXHJcbiAgICAgICAgICAgIFwidW5leHBlY3RlZCBzdGF0ZTogZmFpbGVkIHRvIGZpbmQgbGFzdCByZXZlcnNlZCBwYXRjaCBpbiBvcmlnaW5hbCBwYXRjaGVzIGFycmF5XCIsXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzYXZlUGF0Y2hBcHBsaWNhdGlvblN0YXRlKHtcclxuICAgICAgICAgIHBhY2thZ2VEZXRhaWxzOiBwYXRjaGVzWzBdLFxyXG4gICAgICAgICAgcGF0Y2hlczogcGF0Y2hlcy5zbGljZSgwLCBsYXN0UmV2ZXJzZWRQYXRjaEluZGV4KS5tYXAoKHBhdGNoKSA9PiAoe1xyXG4gICAgICAgICAgICBkaWRBcHBseTogdHJ1ZSxcclxuICAgICAgICAgICAgcGF0Y2hDb250ZW50SGFzaDogaGFzaEZpbGUoXHJcbiAgICAgICAgICAgICAgam9pbihhcHBQYXRoLCBwYXRjaERpciwgcGF0Y2gucGF0Y2hGaWxlbmFtZSksXHJcbiAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgIHBhdGNoRmlsZW5hbWU6IHBhdGNoLnBhdGNoRmlsZW5hbWUsXHJcbiAgICAgICAgICB9KSksXHJcbiAgICAgICAgICBpc1JlYmFzaW5nOiBmYWxzZSxcclxuICAgICAgICB9KVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb25zdCBuZXh0U3RhdGUgPSBhcHBsaWVkUGF0Y2hlcy5tYXAoXHJcbiAgICAgICAgKHBhdGNoKTogUGF0Y2hTdGF0ZSA9PiAoe1xyXG4gICAgICAgICAgZGlkQXBwbHk6IHRydWUsXHJcbiAgICAgICAgICBwYXRjaENvbnRlbnRIYXNoOiBoYXNoRmlsZShcclxuICAgICAgICAgICAgam9pbihhcHBQYXRoLCBwYXRjaERpciwgcGF0Y2gucGF0Y2hGaWxlbmFtZSksXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgcGF0Y2hGaWxlbmFtZTogcGF0Y2gucGF0Y2hGaWxlbmFtZSxcclxuICAgICAgICB9KSxcclxuICAgICAgKVxyXG5cclxuICAgICAgaWYgKGZhaWxlZFBhdGNoKSB7XHJcbiAgICAgICAgbmV4dFN0YXRlLnB1c2goe1xyXG4gICAgICAgICAgZGlkQXBwbHk6IGZhbHNlLFxyXG4gICAgICAgICAgcGF0Y2hDb250ZW50SGFzaDogaGFzaEZpbGUoXHJcbiAgICAgICAgICAgIGpvaW4oYXBwUGF0aCwgcGF0Y2hEaXIsIGZhaWxlZFBhdGNoLnBhdGNoRmlsZW5hbWUpLFxyXG4gICAgICAgICAgKSxcclxuICAgICAgICAgIHBhdGNoRmlsZW5hbWU6IGZhaWxlZFBhdGNoLnBhdGNoRmlsZW5hbWUsXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gICAgICBzYXZlUGF0Y2hBcHBsaWNhdGlvblN0YXRlKHtcclxuICAgICAgICBwYWNrYWdlRGV0YWlsczogcGF0Y2hlc1swXSxcclxuICAgICAgICBwYXRjaGVzOiBuZXh0U3RhdGUsXHJcbiAgICAgICAgaXNSZWJhc2luZzogISFmYWlsZWRQYXRjaCxcclxuICAgICAgfSlcclxuICAgIH1cclxuICAgIGlmIChmYWlsZWRQYXRjaCkge1xyXG4gICAgICBwcm9jZXNzLmV4aXQoMSlcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhcHBseVBhdGNoKHtcclxuICBwYXRjaEZpbGVQYXRoLFxyXG4gIHJldmVyc2UsXHJcbiAgcGF0Y2hEZXRhaWxzLFxyXG4gIHBhdGNoRGlyLFxyXG4gIGN3ZCxcclxuICBiZXN0RWZmb3J0LFxyXG59OiB7XHJcbiAgcGF0Y2hGaWxlUGF0aDogc3RyaW5nXHJcbiAgcmV2ZXJzZTogYm9vbGVhblxyXG4gIHBhdGNoRGV0YWlsczogUGFja2FnZURldGFpbHNcclxuICBwYXRjaERpcjogc3RyaW5nXHJcbiAgY3dkOiBzdHJpbmdcclxuICBiZXN0RWZmb3J0OiBib29sZWFuXHJcbn0pOiBib29sZWFuIHtcclxuICBjb25zdCBwYXRjaCA9IHJlYWRQYXRjaCh7XHJcbiAgICBwYXRjaEZpbGVQYXRoLFxyXG4gICAgcGF0Y2hEZXRhaWxzLFxyXG4gICAgcGF0Y2hEaXIsXHJcbiAgfSlcclxuXHJcbiAgY29uc3QgZm9yd2FyZCA9IHJldmVyc2UgPyByZXZlcnNlUGF0Y2gocGF0Y2gpIDogcGF0Y2hcclxuICB0cnkge1xyXG4gICAgaWYgKCFiZXN0RWZmb3J0KSB7XHJcbiAgICAgIGV4ZWN1dGVFZmZlY3RzKGZvcndhcmQsIHsgZHJ5UnVuOiB0cnVlLCBjd2QsIGJlc3RFZmZvcnQ6IGZhbHNlIH0pXHJcbiAgICB9XHJcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkID0gYmVzdEVmZm9ydCA/IFtdIDogdW5kZWZpbmVkXHJcbiAgICBleGVjdXRlRWZmZWN0cyhmb3J3YXJkLCB7IGRyeVJ1bjogZmFsc2UsIGN3ZCwgYmVzdEVmZm9ydCwgZXJyb3JzIH0pXHJcbiAgICBpZiAoZXJyb3JzPy5sZW5ndGgpIHtcclxuICAgICAgY29uc29sZS5sb2coXHJcbiAgICAgICAgXCJTYXZpbmcgZXJyb3JzIHRvXCIsXHJcbiAgICAgICAgY2hhbGsuY3lhbi5ib2xkKFwiLi9wYXRjaC1wYWNrYWdlLWVycm9ycy5sb2dcIiksXHJcbiAgICAgIClcclxuICAgICAgd3JpdGVGaWxlU3luYyhcInBhdGNoLXBhY2thZ2UtZXJyb3JzLmxvZ1wiLCBlcnJvcnMuam9pbihcIlxcblxcblwiKSlcclxuICAgICAgcHJvY2Vzcy5leGl0KDApXHJcbiAgICB9XHJcbiAgfSBjYXRjaCAoZSkge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgYmFja3dhcmQgPSByZXZlcnNlID8gcGF0Y2ggOiByZXZlcnNlUGF0Y2gocGF0Y2gpXHJcbiAgICAgIGV4ZWN1dGVFZmZlY3RzKGJhY2t3YXJkLCB7XHJcbiAgICAgICAgZHJ5UnVuOiB0cnVlLFxyXG4gICAgICAgIGN3ZCxcclxuICAgICAgICBiZXN0RWZmb3J0OiBmYWxzZSxcclxuICAgICAgfSlcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdHJ1ZVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVWZXJzaW9uTWlzbWF0Y2hXYXJuaW5nKHtcclxuICBwYWNrYWdlTmFtZSxcclxuICBhY3R1YWxWZXJzaW9uLFxyXG4gIG9yaWdpbmFsVmVyc2lvbixcclxuICBwYXRoU3BlY2lmaWVyLFxyXG4gIHBhdGgsXHJcbn06IHtcclxuICBwYWNrYWdlTmFtZTogc3RyaW5nXHJcbiAgYWN0dWFsVmVyc2lvbjogc3RyaW5nXHJcbiAgb3JpZ2luYWxWZXJzaW9uOiBzdHJpbmdcclxuICBwYXRoU3BlY2lmaWVyOiBzdHJpbmdcclxuICBwYXRoOiBzdHJpbmdcclxufSkge1xyXG4gIHJldHVybiBgXHJcbiR7Y2hhbGsueWVsbG93KFwiV2FybmluZzpcIil9IHBhdGNoLXBhY2thZ2UgZGV0ZWN0ZWQgYSBwYXRjaCBmaWxlIHZlcnNpb24gbWlzbWF0Y2hcclxuXHJcbiAgRG9uJ3Qgd29ycnkhIFRoaXMgaXMgcHJvYmFibHkgZmluZS4gVGhlIHBhdGNoIHdhcyBzdGlsbCBhcHBsaWVkXHJcbiAgc3VjY2Vzc2Z1bGx5LiBIZXJlJ3MgdGhlIGRlZXRzOlxyXG5cclxuICBQYXRjaCBmaWxlIGNyZWF0ZWQgZm9yXHJcblxyXG4gICAgJHtwYWNrYWdlTmFtZX1AJHtjaGFsay5ib2xkKG9yaWdpbmFsVmVyc2lvbil9XHJcblxyXG4gIGFwcGxpZWQgdG9cclxuXHJcbiAgICAke3BhY2thZ2VOYW1lfUAke2NoYWxrLmJvbGQoYWN0dWFsVmVyc2lvbil9XHJcbiAgXHJcbiAgQXQgcGF0aFxyXG4gIFxyXG4gICAgJHtwYXRofVxyXG5cclxuICBUaGlzIHdhcm5pbmcgaXMganVzdCB0byBnaXZlIHlvdSBhIGhlYWRzLXVwLiBUaGVyZSBpcyBhIHNtYWxsIGNoYW5jZSBvZlxyXG4gIGJyZWFrYWdlIGV2ZW4gdGhvdWdoIHRoZSBwYXRjaCB3YXMgYXBwbGllZCBzdWNjZXNzZnVsbHkuIE1ha2Ugc3VyZSB0aGUgcGFja2FnZVxyXG4gIHN0aWxsIGJlaGF2ZXMgbGlrZSB5b3UgZXhwZWN0ICh5b3Ugd3JvdGUgdGVzdHMsIHJpZ2h0PykgYW5kIHRoZW4gcnVuXHJcblxyXG4gICAgJHtjaGFsay5ib2xkKGBwYXRjaC1wYWNrYWdlICR7cGF0aFNwZWNpZmllcn1gKX1cclxuXHJcbiAgdG8gdXBkYXRlIHRoZSB2ZXJzaW9uIGluIHRoZSBwYXRjaCBmaWxlIG5hbWUgYW5kIG1ha2UgdGhpcyB3YXJuaW5nIGdvIGF3YXkuXHJcbmBcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlQnJva2VuUGF0Y2hGaWxlRXJyb3Ioe1xyXG4gIHBhY2thZ2VOYW1lLFxyXG4gIHBhdGNoRmlsZW5hbWUsXHJcbiAgcGF0aCxcclxuICBwYXRoU3BlY2lmaWVyLFxyXG59OiB7XHJcbiAgcGFja2FnZU5hbWU6IHN0cmluZ1xyXG4gIHBhdGNoRmlsZW5hbWU6IHN0cmluZ1xyXG4gIHBhdGg6IHN0cmluZ1xyXG4gIHBhdGhTcGVjaWZpZXI6IHN0cmluZ1xyXG59KSB7XHJcbiAgcmV0dXJuIGBcclxuJHtjaGFsay5yZWQuYm9sZChcIioqRVJST1IqKlwiKX0gJHtjaGFsay5yZWQoXHJcbiAgICBgRmFpbGVkIHRvIGFwcGx5IHBhdGNoIGZvciBwYWNrYWdlICR7Y2hhbGsuYm9sZChwYWNrYWdlTmFtZSl9IGF0IHBhdGhgLFxyXG4gICl9XHJcbiAgXHJcbiAgICAke3BhdGh9XHJcblxyXG4gIFRoaXMgZXJyb3Igd2FzIGNhdXNlZCBiZWNhdXNlIHBhdGNoLXBhY2thZ2UgY2Fubm90IGFwcGx5IHRoZSBmb2xsb3dpbmcgcGF0Y2ggZmlsZTpcclxuXHJcbiAgICBwYXRjaGVzLyR7cGF0Y2hGaWxlbmFtZX1cclxuXHJcbiAgVHJ5IHJlbW92aW5nIG5vZGVfbW9kdWxlcyBhbmQgdHJ5aW5nIGFnYWluLiBJZiB0aGF0IGRvZXNuJ3Qgd29yaywgbWF5YmUgdGhlcmUgd2FzXHJcbiAgYW4gYWNjaWRlbnRhbCBjaGFuZ2UgbWFkZSB0byB0aGUgcGF0Y2ggZmlsZT8gVHJ5IHJlY3JlYXRpbmcgaXQgYnkgbWFudWFsbHlcclxuICBlZGl0aW5nIHRoZSBhcHByb3ByaWF0ZSBmaWxlcyBhbmQgcnVubmluZzpcclxuICBcclxuICAgIHBhdGNoLXBhY2thZ2UgJHtwYXRoU3BlY2lmaWVyfVxyXG4gIFxyXG4gIElmIHRoYXQgZG9lc24ndCB3b3JrLCB0aGVuIGl0J3MgYSBidWcgaW4gcGF0Y2gtcGFja2FnZSwgc28gcGxlYXNlIHN1Ym1pdCBhIGJ1Z1xyXG4gIHJlcG9ydC4gVGhhbmtzIVxyXG5cclxuICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9kczMwMC9wYXRjaC1wYWNrYWdlL2lzc3Vlc1xyXG4gICAgXHJcbmBcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlUGF0Y2hBcHBsaWNhdGlvbkZhaWx1cmVFcnJvcih7XHJcbiAgcGFja2FnZU5hbWUsXHJcbiAgYWN0dWFsVmVyc2lvbixcclxuICBvcmlnaW5hbFZlcnNpb24sXHJcbiAgcGF0Y2hGaWxlbmFtZSxcclxuICBwYXRoLFxyXG4gIHBhdGhTcGVjaWZpZXIsXHJcbn06IHtcclxuICBwYWNrYWdlTmFtZTogc3RyaW5nXHJcbiAgYWN0dWFsVmVyc2lvbjogc3RyaW5nXHJcbiAgb3JpZ2luYWxWZXJzaW9uOiBzdHJpbmdcclxuICBwYXRjaEZpbGVuYW1lOiBzdHJpbmdcclxuICBwYXRoOiBzdHJpbmdcclxuICBwYXRoU3BlY2lmaWVyOiBzdHJpbmdcclxufSkge1xyXG4gIHJldHVybiBgXHJcbiR7Y2hhbGsucmVkLmJvbGQoXCIqKkVSUk9SKipcIil9ICR7Y2hhbGsucmVkKFxyXG4gICAgYEZhaWxlZCB0byBhcHBseSBwYXRjaCBmb3IgcGFja2FnZSAke2NoYWxrLmJvbGQocGFja2FnZU5hbWUpfSBhdCBwYXRoYCxcclxuICApfVxyXG4gIFxyXG4gICAgJHtwYXRofVxyXG5cclxuICBUaGlzIGVycm9yIHdhcyBjYXVzZWQgYmVjYXVzZSAke2NoYWxrLmJvbGQocGFja2FnZU5hbWUpfSBoYXMgY2hhbmdlZCBzaW5jZSB5b3VcclxuICBtYWRlIHRoZSBwYXRjaCBmaWxlIGZvciBpdC4gVGhpcyBpbnRyb2R1Y2VkIGNvbmZsaWN0cyB3aXRoIHlvdXIgcGF0Y2gsXHJcbiAganVzdCBsaWtlIGEgbWVyZ2UgY29uZmxpY3QgaW4gR2l0IHdoZW4gc2VwYXJhdGUgaW5jb21wYXRpYmxlIGNoYW5nZXMgYXJlXHJcbiAgbWFkZSB0byB0aGUgc2FtZSBwaWVjZSBvZiBjb2RlLlxyXG5cclxuICBNYXliZSB0aGlzIG1lYW5zIHlvdXIgcGF0Y2ggZmlsZSBpcyBubyBsb25nZXIgbmVjZXNzYXJ5LCBpbiB3aGljaCBjYXNlXHJcbiAgaG9vcmF5ISBKdXN0IGRlbGV0ZSBpdCFcclxuXHJcbiAgT3RoZXJ3aXNlLCB5b3UgbmVlZCB0byBnZW5lcmF0ZSBhIG5ldyBwYXRjaCBmaWxlLlxyXG5cclxuICBUbyBnZW5lcmF0ZSBhIG5ldyBvbmUsIGp1c3QgcmVwZWF0IHRoZSBzdGVwcyB5b3UgbWFkZSB0byBnZW5lcmF0ZSB0aGUgZmlyc3RcclxuICBvbmUuXHJcblxyXG4gIGkuZS4gbWFudWFsbHkgbWFrZSB0aGUgYXBwcm9wcmlhdGUgZmlsZSBjaGFuZ2VzLCB0aGVuIHJ1biBcclxuXHJcbiAgICBwYXRjaC1wYWNrYWdlICR7cGF0aFNwZWNpZmllcn1cclxuXHJcbiAgSW5mbzpcclxuICAgIFBhdGNoIGZpbGU6IHBhdGNoZXMvJHtwYXRjaEZpbGVuYW1lfVxyXG4gICAgUGF0Y2ggd2FzIG1hZGUgZm9yIHZlcnNpb246ICR7Y2hhbGsuZ3JlZW4uYm9sZChvcmlnaW5hbFZlcnNpb24pfVxyXG4gICAgSW5zdGFsbGVkIHZlcnNpb246ICR7Y2hhbGsucmVkLmJvbGQoYWN0dWFsVmVyc2lvbil9XHJcbmBcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlVW5leHBlY3RlZEVycm9yKHtcclxuICBmaWxlbmFtZSxcclxuICBlcnJvcixcclxufToge1xyXG4gIGZpbGVuYW1lOiBzdHJpbmdcclxuICBlcnJvcjogRXJyb3JcclxufSkge1xyXG4gIHJldHVybiBgXHJcbiR7Y2hhbGsucmVkLmJvbGQoXCIqKkVSUk9SKipcIil9ICR7Y2hhbGsucmVkKFxyXG4gICAgYEZhaWxlZCB0byBhcHBseSBwYXRjaCBmaWxlICR7Y2hhbGsuYm9sZChmaWxlbmFtZSl9YCxcclxuICApfVxyXG4gIFxyXG4ke2Vycm9yLnN0YWNrfVxyXG5cclxuICBgXHJcbn1cclxuIl19
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertNever = assertNever;
4
+ function assertNever(x) {
5
+ throw new Error("Unexpected object: " + x);
6
+ }
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXJ0TmV2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYXNzZXJ0TmV2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxrQ0FFQztBQUZELFNBQWdCLFdBQVcsQ0FBQyxDQUFRO0lBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLEdBQUcsQ0FBQyxDQUFDLENBQUE7QUFDNUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBhc3NlcnROZXZlcih4OiBuZXZlcik6IG5ldmVyIHtcclxuICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIG9iamVjdDogXCIgKyB4KVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.coerceSemVer = coerceSemVer;
7
+ const semver_1 = __importDefault(require("semver"));
8
+ function coerceSemVer(version) {
9
+ return semver_1.default.coerce(version)?.version || null;
10
+ }
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29lcmNlU2VtVmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvZXJjZVNlbVZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLG9DQUVDO0FBSkQsb0RBQTJCO0FBRTNCLFNBQWdCLFlBQVksQ0FBQyxPQUFlO0lBQzFDLE9BQU8sZ0JBQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQTtBQUNoRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNlbXZlciBmcm9tIFwic2VtdmVyXCJcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjb2VyY2VTZW1WZXIodmVyc2lvbjogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XHJcbiAgcmV0dXJuIHNlbXZlci5jb2VyY2UodmVyc2lvbik/LnZlcnNpb24gfHwgbnVsbFxyXG59XHJcbiJdfQ==
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getPackageVCSDetails = getPackageVCSDetails;
7
+ exports.shouldRecommendIssue = shouldRecommendIssue;
8
+ exports.maybePrintIssueCreationPrompt = maybePrintIssueCreationPrompt;
9
+ exports.openIssueCreationLink = openIssueCreationLink;
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const open_1 = __importDefault(require("open"));
12
+ const querystring_1 = require("querystring");
13
+ const path_1 = require("./path");
14
+ const repoSpecifier = /^([\w.-]+)\/([\w.-]+)$/;
15
+ const githubURL = /github.com(:|\/)([\w.-]+\/[\w.-]+?)(.git|\/.*)?$/;
16
+ function parseRepoString(repository) {
17
+ if (repository.startsWith("github:")) {
18
+ repository = repository.replace(/^github:/, "");
19
+ }
20
+ const urlMatch = repository.match(githubURL);
21
+ if (urlMatch) {
22
+ repository = urlMatch[2];
23
+ }
24
+ const specMatch = repository.match(repoSpecifier);
25
+ if (!specMatch) {
26
+ return null;
27
+ }
28
+ const [, org, repo] = specMatch;
29
+ return { org, repo, provider: "GitHub" };
30
+ }
31
+ function getPackageVCSDetails(packageDetails) {
32
+ const repository = require((0, path_1.resolve)((0, path_1.join)(packageDetails.path, "package.json")))
33
+ .repository;
34
+ if (!repository) {
35
+ return null;
36
+ }
37
+ if (typeof repository === "string") {
38
+ return parseRepoString(repository);
39
+ }
40
+ else if (typeof repository === "object" &&
41
+ typeof repository.url === "string") {
42
+ return parseRepoString(repository.url);
43
+ }
44
+ }
45
+ function createIssueUrl({ vcs, packageDetails, packageVersion, diff, }) {
46
+ return `https://github.com/${vcs?.org}/${vcs?.repo}/issues/new?${(0, querystring_1.stringify)({
47
+ title: "",
48
+ body: `Hi! 👋
49
+
50
+ Firstly, thanks for your work on this project! 🙂
51
+
52
+ Today I used [patch-package](https://github.com/ds300/patch-package) to patch \`${packageDetails.name}@${packageVersion}\` for the project I'm working on.
53
+
54
+ <!-- 🔺️🔺️🔺️ PLEASE REPLACE THIS BLOCK with a description of your problem, and any other relevant context 🔺️🔺️🔺️ -->
55
+
56
+ Here is the diff that solved my problem:
57
+
58
+ \`\`\`diff
59
+ ${diff}
60
+ \`\`\`
61
+
62
+ <em>This issue body was [partially generated by patch-package](https://github.com/ds300/patch-package/issues/296).</em>
63
+ `,
64
+ })}`;
65
+ }
66
+ function shouldRecommendIssue(vcsDetails) {
67
+ if (!vcsDetails) {
68
+ return true;
69
+ }
70
+ const { repo, org } = vcsDetails;
71
+ if (repo === "DefinitelyTyped" && org === "DefinitelyTyped") {
72
+ return false;
73
+ }
74
+ return true;
75
+ }
76
+ function maybePrintIssueCreationPrompt(vcs, packageDetails, packageManager) {
77
+ if (vcs) {
78
+ console.log(`💡 ${chalk_1.default.bold(packageDetails.name)} is on ${vcs.provider}! To draft an issue based on your patch run
79
+
80
+ ${packageManager === "yarn" ? "yarn" : "npx"} patch-package ${packageDetails.pathSpecifier} --create-issue
81
+ `);
82
+ }
83
+ }
84
+ function openIssueCreationLink({ packageDetails, patchFileContents, packageVersion, patchPath, }) {
85
+ const vcs = getPackageVCSDetails(packageDetails);
86
+ if (!vcs) {
87
+ console.log(`Error: Couldn't find VCS details for ${packageDetails.pathSpecifier}`);
88
+ process.exit(1);
89
+ }
90
+ // trim off trailing newline since we add an extra one in the markdown block
91
+ if (patchFileContents.endsWith("\n")) {
92
+ patchFileContents = patchFileContents.slice(0, -1);
93
+ }
94
+ let issueUrl = createIssueUrl({
95
+ vcs,
96
+ packageDetails,
97
+ packageVersion,
98
+ diff: patchFileContents,
99
+ });
100
+ const urlExceedsLimit = patchFileContents.length > 1950;
101
+ if (urlExceedsLimit) {
102
+ const diffMessage = `<!-- 🔺️🔺️🔺️ PLEASE REPLACE THIS BLOCK with the diff contents of ${patchPath
103
+ .split("/")
104
+ .pop()}. 🔺️🔺️🔺️ -->`;
105
+ console.log(`📋 Copy the contents in [ ${patchPath} ] and paste it in the new issue's diff section.`);
106
+ issueUrl = createIssueUrl({
107
+ vcs,
108
+ packageDetails,
109
+ packageVersion,
110
+ diff: diffMessage,
111
+ });
112
+ }
113
+ (0, open_1.default)(issueUrl);
114
+ }
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlSXNzdWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY3JlYXRlSXNzdWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFzQ0Esb0RBZUM7QUFrQ0Qsb0RBWUM7QUFFRCxzRUFlQztBQUVELHNEQWlEQztBQXZLRCxrREFBeUI7QUFDekIsZ0RBQXVCO0FBQ3ZCLDZDQUF1QztBQUd2QyxpQ0FBc0M7QUFFdEMsTUFBTSxhQUFhLEdBQUcsd0JBQXdCLENBQUE7QUFDOUMsTUFBTSxTQUFTLEdBQUcsa0RBQWtELENBQUE7QUFXcEUsU0FBUyxlQUFlLENBQUMsVUFBa0I7SUFDekMsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDckMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ2pELENBQUM7SUFDRCxNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQzVDLElBQUksUUFBUSxFQUFFLENBQUM7UUFDYixVQUFVLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzFCLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBRWpELElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQztJQUNELE1BQU0sQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUE7SUFFL0IsT0FBTyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFBO0FBQzFDLENBQUM7QUFFRCxTQUFnQixvQkFBb0IsQ0FBQyxjQUE4QjtJQUNqRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBQSxjQUFPLEVBQUMsSUFBQSxXQUFJLEVBQUMsY0FB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R0FBRyxDQUFDO2FBQ1YsR0FBRyxFQUFFLGlCQUFpQixDQUFBO1FBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQ1QsNkJBQTZCLFNBQVMsa0RBQWtELENBQ3pGLENBQUE7UUFDRCxRQUFRLEdBQUcsY0FBYyxDQUFDO1lBQ3hCLEdBQUc7WUFDSCxjQUFjO1lBQ2QsY0FBYztZQUNkLElBQUksRUFBRSxXQUFXO1NBQ2xCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxJQUFBLGNBQUksRUFBQyxRQUFRLENBQUMsQ0FBQTtBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiXHJcbmltcG9ydCBvcGVuIGZyb20gXCJvcGVuXCJcclxuaW1wb3J0IHsgc3RyaW5naWZ5IH0gZnJvbSBcInF1ZXJ5c3RyaW5nXCJcclxuaW1wb3J0IHsgUGFja2FnZU1hbmFnZXIgfSBmcm9tIFwiLi9kZXRlY3RQYWNrYWdlTWFuYWdlclwiXHJcbmltcG9ydCB7IFBhY2thZ2VEZXRhaWxzIH0gZnJvbSBcIi4vUGFja2FnZURldGFpbHNcIlxyXG5pbXBvcnQgeyBqb2luLCByZXNvbHZlIH0gZnJvbSBcIi4vcGF0aFwiXHJcblxyXG5jb25zdCByZXBvU3BlY2lmaWVyID0gL14oW1xcdy4tXSspXFwvKFtcXHcuLV0rKSQvXHJcbmNvbnN0IGdpdGh1YlVSTCA9IC9naXRodWIuY29tKDp8XFwvKShbXFx3Li1dK1xcL1tcXHcuLV0rPykoLmdpdHxcXC8uKik/JC9cclxuXHJcbnR5cGUgVkNTID1cclxuICB8IHtcclxuICAgICAgcmVwbzogc3RyaW5nXHJcbiAgICAgIG9yZzogc3RyaW5nXHJcbiAgICAgIHByb3ZpZGVyOiBcIkdpdEh1YlwiXHJcbiAgICB9XHJcbiAgfCBudWxsXHJcbiAgfCB1bmRlZmluZWRcclxuXHJcbmZ1bmN0aW9uIHBhcnNlUmVwb1N0cmluZyhyZXBvc2l0b3J5OiBzdHJpbmcpOiBWQ1Mge1xyXG4gIGlmIChyZXBvc2l0b3J5LnN0YXJ0c1dpdGgoXCJnaXRodWI6XCIpKSB7XHJcbiAgICByZXBvc2l0b3J5ID0gcmVwb3NpdG9yeS5yZXBsYWNlKC9eZ2l0aHViOi8sIFwiXCIpXHJcbiAgfVxyXG4gIGNvbnN0IHVybE1hdGNoID0gcmVwb3NpdG9yeS5tYXRjaChnaXRodWJVUkwpXHJcbiAgaWYgKHVybE1hdGNoKSB7XHJcbiAgICByZXBvc2l0b3J5ID0gdXJsTWF0Y2hbMl1cclxuICB9XHJcblxyXG4gIGNvbnN0IHNwZWNNYXRjaCA9IHJlcG9zaXRvcnkubWF0Y2gocmVwb1NwZWNpZmllcilcclxuXHJcbiAgaWYgKCFzcGVjTWF0Y2gpIHtcclxuICAgIHJldHVybiBudWxsXHJcbiAgfVxyXG4gIGNvbnN0IFssIG9yZywgcmVwb10gPSBzcGVjTWF0Y2hcclxuXHJcbiAgcmV0dXJuIHsgb3JnLCByZXBvLCBwcm92aWRlcjogXCJHaXRIdWJcIiB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYWNrYWdlVkNTRGV0YWlscyhwYWNrYWdlRGV0YWlsczogUGFja2FnZURldGFpbHMpOiBWQ1Mge1xyXG4gIGNvbnN0IHJlcG9zaXRvcnkgPSByZXF1aXJlKHJlc29sdmUoam9pbihwYWNrYWdlRGV0YWlscy5wYXRoLCBcInBhY2thZ2UuanNvblwiKSkpXHJcbiAgICAucmVwb3NpdG9yeSBhcyB1bmRlZmluZWQgfCBzdHJpbmcgfCB7IHVybDogc3RyaW5nIH1cclxuXHJcbiAgaWYgKCFyZXBvc2l0b3J5KSB7XHJcbiAgICByZXR1cm4gbnVsbFxyXG4gIH1cclxuICBpZiAodHlwZW9mIHJlcG9zaXRvcnkgPT09IFwic3RyaW5nXCIpIHtcclxuICAgIHJldHVybiBwYXJzZVJlcG9TdHJpbmcocmVwb3NpdG9yeSlcclxuICB9IGVsc2UgaWYgKFxyXG4gICAgdHlwZW9mIHJlcG9zaXRvcnkgPT09IFwib2JqZWN0XCIgJiZcclxuICAgIHR5cGVvZiByZXBvc2l0b3J5LnVybCA9PT0gXCJzdHJpbmdcIlxyXG4gICkge1xyXG4gICAgcmV0dXJuIHBhcnNlUmVwb1N0cmluZyhyZXBvc2l0b3J5LnVybClcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUlzc3VlVXJsKHtcclxuICB2Y3MsXHJcbiAgcGFja2FnZURldGFpbHMsXHJcbiAgcGFja2FnZVZlcnNpb24sXHJcbiAgZGlmZixcclxufToge1xyXG4gIHZjczogVkNTXHJcbiAgcGFja2FnZURldGFpbHM6IFBhY2thZ2VEZXRhaWxzXHJcbiAgcGFja2FnZVZlcnNpb246IHN0cmluZ1xyXG4gIGRpZmY6IHN0cmluZ1xyXG59KTogc3RyaW5nIHtcclxuICByZXR1cm4gYGh0dHBzOi8vZ2l0aHViLmNvbS8ke3Zjcz8ub3JnfS8ke3Zjcz8ucmVwb30vaXNzdWVzL25ldz8ke3N0cmluZ2lmeSh7XHJcbiAgICB0aXRsZTogXCJcIixcclxuICAgIGJvZHk6IGBIaSEg8J+RiyBcclxuICAgICAgXHJcbkZpcnN0bHksIHRoYW5rcyBmb3IgeW91ciB3b3JrIG9uIHRoaXMgcHJvamVjdCEg8J+ZglxyXG5cclxuVG9kYXkgSSB1c2VkIFtwYXRjaC1wYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vZHMzMDAvcGF0Y2gtcGFja2FnZSkgdG8gcGF0Y2ggXFxgJHtwYWNrYWdlRGV0YWlscy5uYW1lfUAke3BhY2thZ2VWZXJzaW9ufVxcYCBmb3IgdGhlIHByb2plY3QgSSdtIHdvcmtpbmcgb24uXHJcblxyXG48IS0tIPCflLrvuI/wn5S677iP8J+Uuu+4jyBQTEVBU0UgUkVQTEFDRSBUSElTIEJMT0NLIHdpdGggYSBkZXNjcmlwdGlvbiBvZiB5b3VyIHByb2JsZW0sIGFuZCBhbnkgb3RoZXIgcmVsZXZhbnQgY29udGV4dCDwn5S677iP8J+Uuu+4j/CflLrvuI8gLS0+XHJcblxyXG5IZXJlIGlzIHRoZSBkaWZmIHRoYXQgc29sdmVkIG15IHByb2JsZW06XHJcblxyXG5cXGBcXGBcXGBkaWZmXHJcbiR7ZGlmZn1cclxuXFxgXFxgXFxgXHJcblxyXG48ZW0+VGhpcyBpc3N1ZSBib2R5IHdhcyBbcGFydGlhbGx5IGdlbmVyYXRlZCBieSBwYXRjaC1wYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vZHMzMDAvcGF0Y2gtcGFja2FnZS9pc3N1ZXMvMjk2KS48L2VtPlxyXG5gLFxyXG4gIH0pfWBcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZFJlY29tbWVuZElzc3VlKFxyXG4gIHZjc0RldGFpbHM6IFJldHVyblR5cGU8dHlwZW9mIGdldFBhY2thZ2VWQ1NEZXRhaWxzPixcclxuKSB7XHJcbiAgaWYgKCF2Y3NEZXRhaWxzKSB7XHJcbiAgICByZXR1cm4gdHJ1ZVxyXG4gIH1cclxuXHJcbiAgY29uc3QgeyByZXBvLCBvcmcgfSA9IHZjc0RldGFpbHNcclxuICBpZiAocmVwbyA9PT0gXCJEZWZpbml0ZWx5VHlwZWRcIiAmJiBvcmcgPT09IFwiRGVmaW5pdGVseVR5cGVkXCIpIHtcclxuICAgIHJldHVybiBmYWxzZVxyXG4gIH1cclxuICByZXR1cm4gdHJ1ZVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVQcmludElzc3VlQ3JlYXRpb25Qcm9tcHQoXHJcbiAgdmNzOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRQYWNrYWdlVkNTRGV0YWlscz4sXHJcbiAgcGFja2FnZURldGFpbHM6IFBhY2thZ2VEZXRhaWxzLFxyXG4gIHBhY2thZ2VNYW5hZ2VyOiBQYWNrYWdlTWFuYWdlcixcclxuKSB7XHJcbiAgaWYgKHZjcykge1xyXG4gICAgY29uc29sZS5sb2coYPCfkqEgJHtjaGFsay5ib2xkKHBhY2thZ2VEZXRhaWxzLm5hbWUpfSBpcyBvbiAke1xyXG4gICAgICB2Y3MucHJvdmlkZXJcclxuICAgIH0hIFRvIGRyYWZ0IGFuIGlzc3VlIGJhc2VkIG9uIHlvdXIgcGF0Y2ggcnVuXHJcblxyXG4gICAgJHtwYWNrYWdlTWFuYWdlciA9PT0gXCJ5YXJuXCIgPyBcInlhcm5cIiA6IFwibnB4XCJ9IHBhdGNoLXBhY2thZ2UgJHtcclxuICAgICAgcGFja2FnZURldGFpbHMucGF0aFNwZWNpZmllclxyXG4gICAgfSAtLWNyZWF0ZS1pc3N1ZVxyXG5gKVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG9wZW5Jc3N1ZUNyZWF0aW9uTGluayh7XHJcbiAgcGFja2FnZURldGFpbHMsXHJcbiAgcGF0Y2hGaWxlQ29udGVudHMsXHJcbiAgcGFja2FnZVZlcnNpb24sXHJcbiAgcGF0Y2hQYXRoLFxyXG59OiB7XHJcbiAgcGFja2FnZURldGFpbHM6IFBhY2thZ2VEZXRhaWxzXHJcbiAgcGF0Y2hGaWxlQ29udGVudHM6IHN0cmluZ1xyXG4gIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmdcclxuICBwYXRjaFBhdGg6IHN0cmluZ1xyXG59KSB7XHJcbiAgY29uc3QgdmNzID0gZ2V0UGFja2FnZVZDU0RldGFpbHMocGFja2FnZURldGFpbHMpXHJcblxyXG4gIGlmICghdmNzKSB7XHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgYEVycm9yOiBDb3VsZG4ndCBmaW5kIFZDUyBkZXRhaWxzIGZvciAke3BhY2thZ2VEZXRhaWxzLnBhdGhTcGVjaWZpZXJ9YCxcclxuICAgIClcclxuICAgIHByb2Nlc3MuZXhpdCgxKVxyXG4gIH1cclxuXHJcbiAgLy8gdHJpbSBvZmYgdHJhaWxpbmcgbmV3bGluZSBzaW5jZSB3ZSBhZGQgYW4gZXh0cmEgb25lIGluIHRoZSBtYXJrZG93biBibG9ja1xyXG4gIGlmIChwYXRjaEZpbGVDb250ZW50cy5lbmRzV2l0aChcIlxcblwiKSkge1xyXG4gICAgcGF0Y2hGaWxlQ29udGVudHMgPSBwYXRjaEZpbGVDb250ZW50cy5zbGljZSgwLCAtMSlcclxuICB9XHJcblxyXG4gIGxldCBpc3N1ZVVybCA9IGNyZWF0ZUlzc3VlVXJsKHtcclxuICAgIHZjcyxcclxuICAgIHBhY2thZ2VEZXRhaWxzLFxyXG4gICAgcGFja2FnZVZlcnNpb24sXHJcbiAgICBkaWZmOiBwYXRjaEZpbGVDb250ZW50cyxcclxuICB9KVxyXG5cclxuICBjb25zdCB1cmxFeGNlZWRzTGltaXQgPSBwYXRjaEZpbGVDb250ZW50cy5sZW5ndGggPiAxOTUwXHJcblxyXG4gIGlmICh1cmxFeGNlZWRzTGltaXQpIHtcclxuICAgIGNvbnN0IGRpZmZNZXNzYWdlID0gYDwhLS0g8J+Uuu+4j/CflLrvuI/wn5S677iPIFBMRUFTRSBSRVBMQUNFIFRISVMgQkxPQ0sgd2l0aCB0aGUgZGlmZiBjb250ZW50cyBvZiAke3BhdGNoUGF0aFxyXG4gICAgICAuc3BsaXQoXCIvXCIpXHJcbiAgICAgIC5wb3AoKX0uIPCflLrvuI/wn5S677iP8J+Uuu+4jyAtLT5gXHJcbiAgICBjb25zb2xlLmxvZyhcclxuICAgICAgYPCfk4sgQ29weSB0aGUgY29udGVudHMgaW4gWyAke3BhdGNoUGF0aH0gXSBhbmQgcGFzdGUgaXQgaW4gdGhlIG5ldyBpc3N1ZSdzIGRpZmYgc2VjdGlvbi5gLFxyXG4gICAgKVxyXG4gICAgaXNzdWVVcmwgPSBjcmVhdGVJc3N1ZVVybCh7XHJcbiAgICAgIHZjcyxcclxuICAgICAgcGFja2FnZURldGFpbHMsXHJcbiAgICAgIHBhY2thZ2VWZXJzaW9uLFxyXG4gICAgICBkaWZmOiBkaWZmTWVzc2FnZSxcclxuICAgIH0pXHJcbiAgfVxyXG4gIG9wZW4oaXNzdWVVcmwpXHJcbn1cclxuIl19