@workflow/next 5.0.0-beta.4 → 5.0.0-beta.40
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.
- package/dist/builder-eager.d.ts +1 -1
- package/dist/builder-eager.d.ts.map +1 -1
- package/dist/builder-eager.js +377 -220
- package/dist/builder.d.ts +1 -4
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -28
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +311 -55
- package/dist/loader.d.ts +5 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +15 -341
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +2 -2
- package/dist/swc-plugin-cache.d.ts +7 -0
- package/dist/swc-plugin-cache.d.ts.map +1 -0
- package/dist/swc-plugin-cache.js +23 -0
- package/dist/watch-ignore.d.ts +51 -0
- package/dist/watch-ignore.d.ts.map +1 -0
- package/dist/watch-ignore.js +264 -0
- package/dist/watch-rebuild.d.ts +63 -0
- package/dist/watch-rebuild.d.ts.map +1 -0
- package/dist/watch-rebuild.js +399 -0
- package/docs/api-reference/with-workflow.mdx +56 -2
- package/docs/next.mdx +12 -6
- package/package.json +10 -7
- package/dist/builder-deferred.d.ts +0 -2
- package/dist/builder-deferred.d.ts.map +0 -1
- package/dist/builder-deferred.js +0 -1401
- package/dist/builder-deferred.js.map +0 -1
- package/dist/builder-eager.js.map +0 -1
- package/dist/builder.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/runtime.js.map +0 -1
- package/dist/socket-server.d.ts +0 -48
- package/dist/socket-server.d.ts.map +0 -1
- package/dist/socket-server.js +0 -154
- package/dist/socket-server.js.map +0 -1
package/dist/builder-eager.js
CHANGED
|
@@ -7,25 +7,33 @@ exports.getNextBuilderEager = getNextBuilderEager;
|
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const promises_1 = require("node:fs/promises");
|
|
9
9
|
const node_path_1 = require("node:path");
|
|
10
|
-
const
|
|
10
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
11
|
+
const watch_ignore_js_1 = require("./watch-ignore.js");
|
|
12
|
+
const watch_rebuild_js_1 = require("./watch-rebuild.js");
|
|
11
13
|
let CachedNextBuilderEager;
|
|
14
|
+
const importEsm = new Function('specifier', 'return import(specifier)');
|
|
12
15
|
// Create the eager Next builder dynamically by extending the ESM BaseBuilder.
|
|
13
16
|
// Exported as getNextBuilderEager() to allow CommonJS modules to import from
|
|
14
17
|
// the ESM @workflow/builders package via dynamic import at runtime.
|
|
15
|
-
async function getNextBuilderEager() {
|
|
18
|
+
async function getNextBuilderEager(buildersModule) {
|
|
16
19
|
if (CachedNextBuilderEager) {
|
|
17
20
|
return CachedNextBuilderEager;
|
|
18
21
|
}
|
|
19
|
-
const { BaseBuilder: BaseBuilderClass,
|
|
20
|
-
|
|
21
|
-
} = (await eval('import("@workflow/builders")'));
|
|
22
|
+
const { BaseBuilder: BaseBuilderClass, getWorkflowQueueTrigger, detectWorkflowPatterns, parentHasChild, } = buildersModule ??
|
|
23
|
+
(await importEsm('@workflow/builders'));
|
|
22
24
|
class NextBuilder extends BaseBuilderClass {
|
|
23
25
|
async build() {
|
|
24
26
|
const outputDir = await this.findAppDirectory();
|
|
25
27
|
const workflowGeneratedDir = (0, node_path_1.join)(outputDir, '.well-known/workflow/v1');
|
|
26
28
|
// Ensure output directories exist
|
|
27
29
|
await (0, promises_1.mkdir)(workflowGeneratedDir, { recursive: true });
|
|
28
|
-
|
|
30
|
+
if (!this.config.watch) {
|
|
31
|
+
// Production build caches may still contain the retired step route.
|
|
32
|
+
await (0, promises_1.rm)((0, node_path_1.join)(workflowGeneratedDir, 'step'), {
|
|
33
|
+
recursive: true,
|
|
34
|
+
force: true,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
29
37
|
await (0, promises_1.writeFile)((0, node_path_1.join)(workflowGeneratedDir, '.gitignore'), '*');
|
|
30
38
|
const inputFiles = await this.getInputFiles();
|
|
31
39
|
const tsconfigPath = await this.findTsConfigPath();
|
|
@@ -34,53 +42,55 @@ async function getNextBuilderEager() {
|
|
|
34
42
|
workflowGeneratedDir,
|
|
35
43
|
tsconfigPath,
|
|
36
44
|
};
|
|
37
|
-
|
|
38
|
-
const
|
|
45
|
+
// V2: Build combined route (replaces separate step + flow routes)
|
|
46
|
+
const combinedResult = await this.buildCombinedFunction(options);
|
|
39
47
|
await this.buildWebhookRoute({ workflowGeneratedDir });
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
...
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const writeManifest = async (sourceManifest) => {
|
|
49
|
+
const manifest = {
|
|
50
|
+
steps: { ...sourceManifest?.steps },
|
|
51
|
+
workflows: { ...sourceManifest?.workflows },
|
|
52
|
+
classes: { ...sourceManifest?.classes },
|
|
53
|
+
};
|
|
54
|
+
// Write manifest
|
|
55
|
+
const workflowBundlePath = (0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js');
|
|
56
|
+
const manifestJson = await this.createManifest({
|
|
57
|
+
workflowBundlePath,
|
|
58
|
+
manifestDir: workflowGeneratedDir,
|
|
59
|
+
manifest,
|
|
60
|
+
});
|
|
61
|
+
// Expose manifest as a static file when WORKFLOW_PUBLIC_MANIFEST=1.
|
|
62
|
+
if (this.shouldExposePublicManifest && manifestJson) {
|
|
63
|
+
const publicManifestDir = (0, node_path_1.join)(this.config.workingDir, 'public/.well-known/workflow/v1');
|
|
64
|
+
await (0, promises_1.mkdir)(publicManifestDir, { recursive: true });
|
|
65
|
+
if (process.env.VERCEL_DEPLOYMENT_ID === undefined) {
|
|
66
|
+
await (0, promises_1.writeFile)((0, node_path_1.join)(publicManifestDir, '.gitignore'), '*');
|
|
67
|
+
}
|
|
68
|
+
await (0, promises_1.copyFile)((0, node_path_1.join)(workflowGeneratedDir, 'manifest.json'), (0, node_path_1.join)(publicManifestDir, 'manifest.json'));
|
|
69
|
+
}
|
|
51
70
|
};
|
|
52
|
-
|
|
53
|
-
const workflowBundlePath = (0, node_path_1.join)(workflowGeneratedDir, 'flow/route.js');
|
|
54
|
-
const manifestJson = await this.createManifest({
|
|
55
|
-
workflowBundlePath,
|
|
56
|
-
manifestDir: workflowGeneratedDir,
|
|
57
|
-
manifest,
|
|
58
|
-
});
|
|
59
|
-
// Expose manifest as a static file when WORKFLOW_PUBLIC_MANIFEST=1.
|
|
60
|
-
// Next.js serves files from public/ at the root URL.
|
|
61
|
-
if (this.shouldExposePublicManifest && manifestJson) {
|
|
62
|
-
const publicManifestDir = (0, node_path_1.join)(this.config.workingDir, 'public/.well-known/workflow/v1');
|
|
63
|
-
await (0, promises_1.mkdir)(publicManifestDir, { recursive: true });
|
|
64
|
-
await (0, promises_1.copyFile)((0, node_path_1.join)(workflowGeneratedDir, 'manifest.json'), (0, node_path_1.join)(publicManifestDir, 'manifest.json'));
|
|
65
|
-
}
|
|
71
|
+
await writeManifest(combinedResult?.manifest);
|
|
66
72
|
await this.writeFunctionsConfig(outputDir);
|
|
67
73
|
if (this.config.watch) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
!workflowsBundle?.bundleFinal) {
|
|
73
|
-
throw new Error('Invariant: expected workflows bundle in watch mode');
|
|
74
|
+
// TODO: implement watch mode for combined bundle
|
|
75
|
+
// For now, fall back to full rebuild on file changes
|
|
76
|
+
if (!combinedResult?.interimBundleCtx || !combinedResult.bundleFinal) {
|
|
77
|
+
throw new Error('Invariant: expected workflow build context in watch mode');
|
|
74
78
|
}
|
|
75
|
-
|
|
76
|
-
//
|
|
79
|
+
// Step registrations may be emitted as source imports without an
|
|
80
|
+
// esbuild context when externalizeNonSteps is enabled.
|
|
81
|
+
let stepsCtx = combinedResult.stepsContext;
|
|
77
82
|
let workflowsCtx = {
|
|
78
|
-
interimBundleCtx:
|
|
79
|
-
bundleFinal:
|
|
83
|
+
interimBundleCtx: combinedResult.interimBundleCtx,
|
|
84
|
+
bundleFinal: combinedResult.bundleFinal,
|
|
80
85
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
let
|
|
86
|
+
let discoveredEntries = combinedResult.discoveredEntries;
|
|
87
|
+
let stepsManifest = combinedResult.stepsManifest;
|
|
88
|
+
let workflowsManifest = combinedResult.workflowsManifest;
|
|
89
|
+
const stepsOutfile = (0, node_path_1.join)(workflowGeneratedDir, 'flow', '__step_registrations.js');
|
|
90
|
+
const normalizePath = (pathname) => ((0, node_path_1.isAbsolute)(pathname)
|
|
91
|
+
? pathname
|
|
92
|
+
: (0, node_path_1.resolve)(this.config.workingDir, pathname)).replace(/\\/g, '/');
|
|
93
|
+
const sourceSnapshots = new Map();
|
|
84
94
|
const watchableExtensions = new Set([
|
|
85
95
|
'.js',
|
|
86
96
|
'.jsx',
|
|
@@ -91,55 +101,26 @@ async function getNextBuilderEager() {
|
|
|
91
101
|
'.cjs',
|
|
92
102
|
'.mjs',
|
|
93
103
|
]);
|
|
94
|
-
const ignoredPathFragments = [
|
|
95
|
-
'/.git/',
|
|
96
|
-
'/node_modules/',
|
|
97
|
-
'/.next/',
|
|
98
|
-
'/.turbo/',
|
|
99
|
-
'/.vercel/',
|
|
100
|
-
'/dist/',
|
|
101
|
-
'/build/',
|
|
102
|
-
'/out/',
|
|
103
|
-
'/.cache/',
|
|
104
|
-
'/.yarn/',
|
|
105
|
-
'/.pnpm-store/',
|
|
106
|
-
'/.parcel-cache/',
|
|
107
|
-
'/.well-known/workflow/',
|
|
108
|
-
];
|
|
109
104
|
const normalizedGeneratedDir = workflowGeneratedDir.replace(/\\/g, '/');
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
if (extension && !watchableExtensions.has(extension)) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
if (normalizedPath.startsWith(normalizedGeneratedDir)) {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
for (const fragment of ignoredPathFragments) {
|
|
129
|
-
if (normalizedPath.includes(fragment)) {
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return false;
|
|
134
|
-
},
|
|
105
|
+
const normalizedDistDir = normalizePath(this.config.distDir);
|
|
106
|
+
// Prune the dev watch set to keep chokidar from registering an
|
|
107
|
+
// fs.watch per directory across the whole project tree (chokidar 4
|
|
108
|
+
// dropped fsevents, so on macOS that exhausts the fd limit -> EMFILE
|
|
109
|
+
// on large monorepos). This honors `.gitignore` and the
|
|
110
|
+
// WORKFLOW_DEV_WATCH_IGNORED_PATHS env var in addition to the
|
|
111
|
+
// built-in fragments. The generated workflow dir is passed as an
|
|
112
|
+
// extra fragment so it is pruned regardless of `.gitignore`.
|
|
113
|
+
const isIgnoredWatchPath = (0, watch_ignore_js_1.createWatchIgnorePredicate)({
|
|
114
|
+
workingDir: this.config.workingDir,
|
|
115
|
+
projectRoot: this.transformProjectRoot,
|
|
116
|
+
extraFragments: [normalizedGeneratedDir],
|
|
135
117
|
});
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
normalizedEntries.set(normalizePath(path), info);
|
|
118
|
+
const hasIgnoredPathFragment = (normalizedPath) => {
|
|
119
|
+
if (normalizedPath === normalizedDistDir ||
|
|
120
|
+
normalizedPath.startsWith(`${normalizedDistDir}/`)) {
|
|
121
|
+
return true;
|
|
141
122
|
}
|
|
142
|
-
return
|
|
123
|
+
return isIgnoredWatchPath(normalizedPath);
|
|
143
124
|
};
|
|
144
125
|
let rebuildQueue = Promise.resolve();
|
|
145
126
|
const enqueue = (task) => {
|
|
@@ -148,143 +129,333 @@ async function getNextBuilderEager() {
|
|
|
148
129
|
});
|
|
149
130
|
return rebuildQueue;
|
|
150
131
|
};
|
|
132
|
+
const readSourceSnapshot = (file) => (0, watch_rebuild_js_1.createSourceSnapshot)({ file, detectWorkflowPatterns });
|
|
133
|
+
const refreshSourceSnapshots = () => (0, watch_rebuild_js_1.replaceSourceSnapshots)({
|
|
134
|
+
discoveredEntries,
|
|
135
|
+
inputFiles: options.inputFiles,
|
|
136
|
+
normalizePath,
|
|
137
|
+
readSnapshot: readSourceSnapshot,
|
|
138
|
+
sourceSnapshots,
|
|
139
|
+
});
|
|
140
|
+
const mergeCombinedManifest = (nextStepsManifest) => ({
|
|
141
|
+
...nextStepsManifest,
|
|
142
|
+
workflows: {
|
|
143
|
+
...nextStepsManifest.workflows,
|
|
144
|
+
...workflowsManifest.workflows,
|
|
145
|
+
},
|
|
146
|
+
classes: {
|
|
147
|
+
...nextStepsManifest.classes,
|
|
148
|
+
...workflowsManifest.classes,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
const hotRebuild = async (refreshStepRegistrations) => {
|
|
152
|
+
if (refreshStepRegistrations) {
|
|
153
|
+
if (stepsCtx) {
|
|
154
|
+
await stepsCtx.rebuild();
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
stepsManifest = await this.createStepSourceRegistrationFile({
|
|
158
|
+
inputFiles: options.inputFiles,
|
|
159
|
+
outfile: stepsOutfile,
|
|
160
|
+
tsconfigPath,
|
|
161
|
+
discoveredEntries,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const workflowResult = await workflowsCtx.interimBundleCtx.rebuild();
|
|
166
|
+
const workflowOutput = workflowResult.outputFiles?.[0]?.text;
|
|
167
|
+
if (!workflowOutput) {
|
|
168
|
+
throw new Error('Invariant: expected workflow output from hot rebuild');
|
|
169
|
+
}
|
|
170
|
+
await workflowsCtx.bundleFinal(workflowOutput);
|
|
171
|
+
await writeManifest(mergeCombinedManifest(stepsManifest));
|
|
172
|
+
};
|
|
151
173
|
const fullRebuild = async () => {
|
|
174
|
+
this.clearDiscoveredEntriesCache();
|
|
152
175
|
const newInputFiles = await this.getInputFiles();
|
|
153
176
|
options.inputFiles = newInputFiles;
|
|
154
|
-
await stepsCtx
|
|
155
|
-
const { context: newStepsCtx } = await this.buildStepsFunction(options);
|
|
156
|
-
if (!newStepsCtx) {
|
|
157
|
-
throw new Error('Invariant: expected steps build context after rebuild');
|
|
158
|
-
}
|
|
159
|
-
stepsCtx = newStepsCtx;
|
|
177
|
+
await stepsCtx?.dispose();
|
|
160
178
|
await workflowsCtx.interimBundleCtx.dispose();
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
179
|
+
const newCombined = await this.buildCombinedFunction(options);
|
|
180
|
+
stepsCtx = newCombined.stepsContext;
|
|
181
|
+
discoveredEntries = newCombined.discoveredEntries;
|
|
182
|
+
stepsManifest = newCombined.stepsManifest;
|
|
183
|
+
workflowsManifest = newCombined.workflowsManifest;
|
|
184
|
+
if (!newCombined?.interimBundleCtx || !newCombined?.bundleFinal) {
|
|
164
185
|
throw new Error('Invariant: expected workflows bundle context after rebuild');
|
|
165
186
|
}
|
|
166
187
|
workflowsCtx = {
|
|
167
|
-
interimBundleCtx:
|
|
168
|
-
bundleFinal:
|
|
188
|
+
interimBundleCtx: newCombined.interimBundleCtx,
|
|
189
|
+
bundleFinal: newCombined.bundleFinal,
|
|
169
190
|
};
|
|
191
|
+
await writeManifest(newCombined.manifest);
|
|
192
|
+
await refreshSourceSnapshots();
|
|
170
193
|
};
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
194
|
+
const isWatchableFile = (path) => watchableExtensions.has((0, node_path_1.extname)(path));
|
|
195
|
+
const readKnownFiles = async () => {
|
|
196
|
+
const files = new Set();
|
|
197
|
+
const aliases = new Map();
|
|
198
|
+
const relevantFiles = (0, watch_rebuild_js_1.getRelevantFiles)({
|
|
199
|
+
discoveredEntries,
|
|
200
|
+
inputFiles: options.inputFiles,
|
|
201
|
+
normalizePath,
|
|
202
|
+
});
|
|
203
|
+
const addKnownFile = async (filePath) => {
|
|
204
|
+
let realFilePath = filePath;
|
|
205
|
+
try {
|
|
206
|
+
realFilePath = normalizePath(await (0, promises_1.realpath)(filePath));
|
|
207
|
+
}
|
|
208
|
+
catch { }
|
|
209
|
+
const canonicalPath = relevantFiles.has(realFilePath)
|
|
210
|
+
? realFilePath
|
|
211
|
+
: filePath;
|
|
212
|
+
files.add(canonicalPath);
|
|
213
|
+
aliases.set(filePath, canonicalPath);
|
|
214
|
+
aliases.set(realFilePath, canonicalPath);
|
|
215
|
+
return canonicalPath;
|
|
216
|
+
};
|
|
217
|
+
const visit = async (directory) => {
|
|
218
|
+
let dirents;
|
|
219
|
+
try {
|
|
220
|
+
dirents = await (0, promises_1.readdir)(directory, { withFileTypes: true });
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
174
223
|
return;
|
|
175
224
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
225
|
+
await Promise.all(dirents.map(async (dirent) => {
|
|
226
|
+
const filePath = normalizePath((0, node_path_1.join)(directory, dirent.name));
|
|
227
|
+
if (hasIgnoredPathFragment(filePath)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (dirent.isDirectory()) {
|
|
231
|
+
await visit(filePath);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let stats;
|
|
235
|
+
try {
|
|
236
|
+
stats = await (0, promises_1.stat)(filePath);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (stats.isDirectory()) {
|
|
242
|
+
await visit(filePath);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!stats.isFile() || !isWatchableFile(filePath)) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
await addKnownFile(filePath);
|
|
249
|
+
}));
|
|
250
|
+
};
|
|
251
|
+
await visit(this.config.workingDir);
|
|
252
|
+
return { files, aliases, addKnownFile };
|
|
253
|
+
};
|
|
254
|
+
const mergeFileChanges = (left, right) => ({
|
|
255
|
+
addedFiles: unique([...left.addedFiles, ...right.addedFiles]),
|
|
256
|
+
modifiedFiles: unique([
|
|
257
|
+
...left.modifiedFiles,
|
|
258
|
+
...right.modifiedFiles,
|
|
259
|
+
]),
|
|
260
|
+
removedFiles: unique([...left.removedFiles, ...right.removedFiles]),
|
|
261
|
+
});
|
|
262
|
+
const unique = (paths) => [...new Set(paths)];
|
|
263
|
+
const classifyFileChanges = ({ changedFiles, knownFiles, removedFiles, }) => {
|
|
264
|
+
const addedFiles = [];
|
|
265
|
+
const modifiedFiles = [];
|
|
266
|
+
for (const file of unique(changedFiles)) {
|
|
267
|
+
if (knownFiles.has(file)) {
|
|
268
|
+
modifiedFiles.push(file);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
addedFiles.push(file);
|
|
272
|
+
knownFiles.add(file);
|
|
180
273
|
}
|
|
274
|
+
}
|
|
275
|
+
for (const file of removedFiles) {
|
|
276
|
+
knownFiles.delete(file);
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
addedFiles,
|
|
280
|
+
modifiedFiles,
|
|
281
|
+
removedFiles: unique(removedFiles),
|
|
181
282
|
};
|
|
182
|
-
logByType(result.errors, 'error');
|
|
183
|
-
logByType(result.warnings, 'warn');
|
|
184
283
|
};
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const workflowResult = await workflowsCtx.interimBundleCtx.rebuild();
|
|
192
|
-
logBuildMessages(workflowResult, 'workflows bundle');
|
|
193
|
-
if (!workflowResult.outputFiles ||
|
|
194
|
-
workflowResult.outputFiles.length === 0) {
|
|
195
|
-
console.error('No output generated while rebuilding workflows bundle');
|
|
196
|
-
return;
|
|
284
|
+
const hasFileChanges = ({ addedFiles, modifiedFiles, removedFiles, }) => addedFiles.length > 0 ||
|
|
285
|
+
modifiedFiles.length > 0 ||
|
|
286
|
+
removedFiles.length > 0;
|
|
287
|
+
const logDevHmr = (...args) => {
|
|
288
|
+
if (process.env.WORKFLOW_DEV_HMR_LOGS === '1') {
|
|
289
|
+
console.log(...args);
|
|
197
290
|
}
|
|
198
|
-
await workflowsCtx.bundleFinal(workflowResult.outputFiles[0].text);
|
|
199
|
-
console.log('Rebuilt workflow bundle', `${Date.now() - rebuiltWorkflowStart}ms`);
|
|
200
291
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
292
|
+
await refreshSourceSnapshots();
|
|
293
|
+
let { files: knownFiles, aliases: knownFileAliases, addKnownFile: rememberKnownFile, } = await readKnownFiles();
|
|
294
|
+
const refreshKnownFiles = async () => {
|
|
295
|
+
const nextKnown = await readKnownFiles();
|
|
296
|
+
knownFiles = nextKnown.files;
|
|
297
|
+
knownFileAliases = nextKnown.aliases;
|
|
298
|
+
rememberKnownFile = nextKnown.addKnownFile;
|
|
299
|
+
};
|
|
300
|
+
const processFileChanges = async (fileChanges) => {
|
|
301
|
+
if (!hasFileChanges(fileChanges)) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const decision = await (0, watch_rebuild_js_1.classifyRebuild)({
|
|
305
|
+
discoveredEntries,
|
|
306
|
+
fileChanges,
|
|
307
|
+
inputFiles: options.inputFiles,
|
|
308
|
+
normalizePath,
|
|
309
|
+
parentHasChild,
|
|
310
|
+
readSnapshot: readSourceSnapshot,
|
|
311
|
+
sourceSnapshots,
|
|
312
|
+
});
|
|
313
|
+
if (decision.kind === 'none') {
|
|
314
|
+
logDevHmr('workflow dev hmr: skip');
|
|
315
|
+
for (const [file, snapshot] of decision.snapshots || []) {
|
|
316
|
+
sourceSnapshots.set(file, snapshot);
|
|
208
317
|
}
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (decision.kind === 'full') {
|
|
321
|
+
logDevHmr('workflow dev hmr: full rediscovery');
|
|
322
|
+
await fullRebuild();
|
|
323
|
+
await refreshKnownFiles();
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
logDevHmr(`workflow dev hmr: hot rebuild${decision.refreshStepRegistrations ? ' with step registration refresh' : ''}`);
|
|
327
|
+
await hotRebuild(decision.refreshStepRegistrations);
|
|
328
|
+
for (const [file, snapshot] of decision.snapshots) {
|
|
329
|
+
sourceSnapshots.set(file, snapshot);
|
|
209
330
|
}
|
|
210
|
-
return removed;
|
|
211
331
|
};
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
if (getComparableTimestamp(info) !== getComparableTimestamp(previous)) {
|
|
225
|
-
modified.push(path);
|
|
226
|
-
}
|
|
332
|
+
let pendingFileChanges = {
|
|
333
|
+
addedFiles: [],
|
|
334
|
+
modifiedFiles: [],
|
|
335
|
+
removedFiles: [],
|
|
336
|
+
};
|
|
337
|
+
let flushTimer;
|
|
338
|
+
const scheduleFileChanges = (fileChanges) => {
|
|
339
|
+
pendingFileChanges = mergeFileChanges(pendingFileChanges, fileChanges);
|
|
340
|
+
if (flushTimer) {
|
|
341
|
+
return;
|
|
227
342
|
}
|
|
228
|
-
|
|
343
|
+
flushTimer = setTimeout(() => {
|
|
344
|
+
const fileChanges = pendingFileChanges;
|
|
345
|
+
pendingFileChanges = {
|
|
346
|
+
addedFiles: [],
|
|
347
|
+
modifiedFiles: [],
|
|
348
|
+
removedFiles: [],
|
|
349
|
+
};
|
|
350
|
+
flushTimer = undefined;
|
|
351
|
+
enqueue(() => processFileChanges(fileChanges));
|
|
352
|
+
}, 10);
|
|
229
353
|
};
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
354
|
+
const resolveExistingEventPath = async (pathname) => {
|
|
355
|
+
const normalizedPath = normalizePath(pathname);
|
|
356
|
+
if (!isWatchableFile(normalizedPath)) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const knownPath = knownFileAliases.get(normalizedPath);
|
|
360
|
+
if (knownPath) {
|
|
361
|
+
return knownPath;
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
const realFilePath = normalizePath(await (0, promises_1.realpath)(normalizedPath));
|
|
365
|
+
return knownFileAliases.get(realFilePath) ?? normalizedPath;
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
return normalizedPath;
|
|
369
|
+
}
|
|
238
370
|
};
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
const { addedFiles, modifiedFiles, removedFiles } = determineFileChanges(currentEntries, previousTimeInfo);
|
|
243
|
-
previousTimeInfo = currentEntries;
|
|
244
|
-
if (isInitial) {
|
|
245
|
-
isInitial = false;
|
|
371
|
+
const handleFileAdded = async (pathname) => {
|
|
372
|
+
const normalizedPath = normalizePath(pathname);
|
|
373
|
+
if (!isWatchableFile(normalizedPath)) {
|
|
246
374
|
return;
|
|
247
375
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
376
|
+
const existingPath = await resolveExistingEventPath(normalizedPath);
|
|
377
|
+
const wasKnown = existingPath ? knownFiles.has(existingPath) : false;
|
|
378
|
+
const canonicalPath = await rememberKnownFile(normalizedPath);
|
|
379
|
+
knownFiles.add(canonicalPath);
|
|
380
|
+
scheduleFileChanges({
|
|
381
|
+
addedFiles: wasKnown ? [] : [canonicalPath],
|
|
382
|
+
modifiedFiles: wasKnown ? [canonicalPath] : [],
|
|
383
|
+
removedFiles: [],
|
|
384
|
+
});
|
|
385
|
+
};
|
|
386
|
+
const handleFileChanged = async (pathname) => {
|
|
387
|
+
const canonicalPath = await resolveExistingEventPath(pathname);
|
|
388
|
+
if (!canonicalPath) {
|
|
251
389
|
return;
|
|
252
390
|
}
|
|
253
|
-
|
|
254
|
-
|
|
391
|
+
const fileChanges = classifyFileChanges({
|
|
392
|
+
changedFiles: [canonicalPath],
|
|
393
|
+
knownFiles,
|
|
394
|
+
removedFiles: [],
|
|
395
|
+
});
|
|
396
|
+
if (!knownFileAliases.has(canonicalPath)) {
|
|
397
|
+
await rememberKnownFile(canonicalPath);
|
|
255
398
|
}
|
|
256
|
-
|
|
257
|
-
|
|
399
|
+
scheduleFileChanges(fileChanges);
|
|
400
|
+
};
|
|
401
|
+
const handleFileRemoved = (pathname) => {
|
|
402
|
+
const normalizedPath = normalizePath(pathname);
|
|
403
|
+
if (!isWatchableFile(normalizedPath)) {
|
|
404
|
+
return;
|
|
258
405
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (modifiedFiles.length > 0) {
|
|
265
|
-
await rebuildExistingFiles();
|
|
266
|
-
}
|
|
406
|
+
const canonicalPath = knownFileAliases.get(normalizedPath) ?? normalizedPath;
|
|
407
|
+
const fileChanges = classifyFileChanges({
|
|
408
|
+
changedFiles: [],
|
|
409
|
+
knownFiles,
|
|
410
|
+
removedFiles: [canonicalPath],
|
|
267
411
|
});
|
|
412
|
+
knownFileAliases.delete(normalizedPath);
|
|
413
|
+
scheduleFileChanges(fileChanges);
|
|
414
|
+
};
|
|
415
|
+
const watcher = chokidar_1.default.watch(this.config.workingDir, {
|
|
416
|
+
ignoreInitial: true,
|
|
417
|
+
followSymlinks: true,
|
|
418
|
+
ignored: (pathname) => {
|
|
419
|
+
const normalizedPath = normalizePath(String(pathname));
|
|
420
|
+
const extension = (0, node_path_1.extname)(normalizedPath);
|
|
421
|
+
if (extension && !watchableExtensions.has(extension)) {
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
return hasIgnoredPathFragment(normalizedPath);
|
|
425
|
+
},
|
|
426
|
+
});
|
|
427
|
+
watcher.on('add', (pathname) => {
|
|
428
|
+
void handleFileAdded(pathname);
|
|
268
429
|
});
|
|
269
|
-
watcher.
|
|
270
|
-
|
|
271
|
-
|
|
430
|
+
watcher.on('change', (pathname) => {
|
|
431
|
+
void handleFileChanged(pathname);
|
|
432
|
+
});
|
|
433
|
+
watcher.on('unlink', (pathname) => {
|
|
434
|
+
handleFileRemoved(pathname);
|
|
435
|
+
});
|
|
436
|
+
watcher.on('error', (error) => {
|
|
437
|
+
console.error('Workflow dev watcher error', error);
|
|
438
|
+
});
|
|
439
|
+
watcher.on('ready', () => {
|
|
440
|
+
logDevHmr('workflow dev hmr: ready');
|
|
272
441
|
});
|
|
273
442
|
}
|
|
274
443
|
}
|
|
275
444
|
async getInputFiles() {
|
|
276
445
|
const inputFiles = await super.getInputFiles();
|
|
277
|
-
return inputFiles.filter((
|
|
278
|
-
|
|
279
|
-
//
|
|
280
|
-
if (
|
|
446
|
+
return inputFiles.filter((file) => {
|
|
447
|
+
const entry = (0, node_path_1.relative)(this.config.workingDir, file).replaceAll('\\', '/');
|
|
448
|
+
// Match App Router route, page, and layout entrypoints in app/ or src/app/.
|
|
449
|
+
if (/^(?:app|src\/app)\/(?:.*\/)?(?:route|page|layout)\./.test(entry)) {
|
|
281
450
|
return true;
|
|
282
451
|
}
|
|
283
|
-
// Match Pages Router
|
|
284
|
-
if (
|
|
452
|
+
// Match every Pages Router entrypoint in pages/ or src/pages/.
|
|
453
|
+
if (/^(?:pages|src\/pages)\//.test(entry)) {
|
|
285
454
|
return true;
|
|
286
455
|
}
|
|
287
|
-
|
|
456
|
+
// Match Next.js root entrypoints at the project root or under src/.
|
|
457
|
+
return ['instrumentation', 'middleware', 'proxy'].some((name) => this.config.pageExtensions.some((extension) => entry === `${name}.${extension}` ||
|
|
458
|
+
entry === `src/${name}.${extension}`));
|
|
288
459
|
});
|
|
289
460
|
}
|
|
290
461
|
async writeFunctionsConfig(outputDir) {
|
|
@@ -292,46 +463,32 @@ async function getNextBuilderEager() {
|
|
|
292
463
|
if (process.env.NODE_ENV === 'development') {
|
|
293
464
|
return;
|
|
294
465
|
}
|
|
466
|
+
// V2 combined config: single trigger handles both workflow and step execution.
|
|
467
|
+
// The step route no longer needs its own trigger since steps are executed
|
|
468
|
+
// inline by the combined handler or queued back to __wkf_workflow_* with stepId.
|
|
295
469
|
const generatedConfig = {
|
|
296
470
|
version: '0',
|
|
297
|
-
steps: {
|
|
298
|
-
maxDuration: 'max',
|
|
299
|
-
experimentalTriggers: [STEP_QUEUE_TRIGGER],
|
|
300
|
-
},
|
|
301
471
|
workflows: {
|
|
302
472
|
maxDuration: 'max',
|
|
303
|
-
experimentalTriggers: [
|
|
473
|
+
experimentalTriggers: [getWorkflowQueueTrigger()],
|
|
304
474
|
},
|
|
305
475
|
};
|
|
306
|
-
// We write this file to the generated directory for
|
|
307
|
-
// the Next.js builder to consume
|
|
308
476
|
await (0, promises_1.writeFile)((0, node_path_1.join)(outputDir, '.well-known/workflow/v1/config.json'), JSON.stringify(generatedConfig, null, 2));
|
|
309
477
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
// which turbopack/webpack fail to analyze. If we externalize
|
|
318
|
-
// correctly this shouldn't be an issue although we might want
|
|
319
|
-
// to use cjs as alternative to avoid
|
|
478
|
+
/**
|
|
479
|
+
* V2: Build combined route that handles both workflow and step execution.
|
|
480
|
+
*/
|
|
481
|
+
async buildCombinedFunction({ inputFiles, workflowGeneratedDir, tsconfigPath, }) {
|
|
482
|
+
const flowRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
483
|
+
await (0, promises_1.mkdir)(flowRouteDir, { recursive: true });
|
|
484
|
+
return await this.createCombinedBundle({
|
|
320
485
|
format: 'esm',
|
|
321
486
|
inputFiles,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
tsconfigPath,
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
async buildWorkflowsFunction({ inputFiles, workflowGeneratedDir, tsconfigPath, }) {
|
|
328
|
-
const workflowsRouteDir = (0, node_path_1.join)(workflowGeneratedDir, 'flow');
|
|
329
|
-
await (0, promises_1.mkdir)(workflowsRouteDir, { recursive: true });
|
|
330
|
-
return await this.createWorkflowsBundle({
|
|
331
|
-
format: 'esm',
|
|
332
|
-
outfile: (0, node_path_1.join)(workflowsRouteDir, 'route.js'),
|
|
487
|
+
stepsOutfile: (0, node_path_1.join)(flowRouteDir, '__step_registrations.js'),
|
|
488
|
+
flowOutfile: (0, node_path_1.join)(flowRouteDir, 'route.js'),
|
|
333
489
|
bundleFinalOutput: false,
|
|
334
|
-
|
|
490
|
+
externalizeNonSteps: true,
|
|
491
|
+
sourceStepRegistrationImports: true,
|
|
335
492
|
tsconfigPath,
|
|
336
493
|
});
|
|
337
494
|
}
|
|
@@ -389,4 +546,4 @@ async function getNextBuilderEager() {
|
|
|
389
546
|
CachedNextBuilderEager = NextBuilder;
|
|
390
547
|
return NextBuilder;
|
|
391
548
|
}
|
|
392
|
-
//# sourceMappingURL=builder-eager.js.map
|
|
549
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci1lYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9idWlsZGVyLWVhZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBb0NBLGtEQStyQkM7QUFudUJELHFDQUFpRDtBQUNqRCwrQ0FTMEI7QUFDMUIseUNBQXlFO0FBS3pFLHdEQUFnQztBQUVoQyx1REFBK0Q7QUFDL0QseURBTzRCO0FBRTVCLElBQUksc0JBQTJCLENBQUM7QUFDaEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxRQUFRLENBQUMsV0FBVyxFQUFFLDBCQUEwQixDQUV2RCxDQUFDO0FBRWhCLDhFQUE4RTtBQUM5RSw2RUFBNkU7QUFDN0Usb0VBQW9FO0FBQzdELEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsY0FBb0Q7SUFFcEQsSUFBSSxzQkFBc0IsRUFBRSxDQUFDO1FBQzNCLE9BQU8sc0JBQXNCLENBQUM7SUFDaEMsQ0FBQztJQUVELE1BQU0sRUFDSixXQUFXLEVBQUUsZ0JBQWdCLEVBQzdCLHVCQUF1QixFQUN2QixzQkFBc0IsRUFDdEIsY0FBYyxHQUNmLEdBQUcsY0FBYztRQUNsQixDQUFDLE1BQU0sU0FBUyxDQUFzQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7SUFFN0UsTUFBTSxXQUFZLFNBQVEsZ0JBQWdCO1FBTXhDLEtBQUssQ0FBQyxLQUFLO1lBQ1QsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNoRCxNQUFNLG9CQUFvQixHQUFHLElBQUEsZ0JBQUksRUFBQyxTQUFTLEVBQUUseUJBQXlCLENBQUMsQ0FBQztZQUV4RSxrQ0FBa0M7WUFDbEMsTUFBTSxJQUFBLGdCQUFLLEVBQUMsb0JBQW9CLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdkIsb0VBQW9FO2dCQUNwRSxNQUFN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QUFXLENBQUM7SUFDckMsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbnN0YW50cywgdHlwZSBEaXJlbnQgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7XG4gIGFjY2VzcyxcbiAgY29weUZpbGUsXG4gIG1rZGlyLFxuICByZWFkZGlyLFxuICByZWFscGF0aCxcbiAgcm0sXG4gIHN0YXQsXG4gIHdyaXRlRmlsZSxcbn0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBleHRuYW1lLCBpc0Fic29sdXRlLCBqb2luLCByZWxhdGl2ZSwgcmVzb2x2ZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgdHlwZSB7XG4gIE5leHRDb25maWcgYXMgQnVpbGRlck5leHRDb25maWcsXG4gIFdvcmtmbG93TWFuaWZlc3QsXG59IGZyb20gJ0B3b3JrZmxvdy9idWlsZGVycyc7XG5pbXBvcnQgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInO1xuaW1wb3J0IHR5cGUgeyBOZXh0Q29uZmlnIGFzIFByb2plY3ROZXh0Q29uZmlnIH0gZnJvbSAnbmV4dCc7XG5pbXBvcnQgeyBjcmVhdGVXYXRjaElnbm9yZVByZWRpY2F0ZSB9IGZyb20gJy4vd2F0Y2gtaWdub3JlLmpzJztcbmltcG9ydCB7XG4gIGNsYXNzaWZ5UmVidWlsZCxcbiAgY3JlYXRlU291cmNlU25hcHNob3QsXG4gIHR5cGUgRmlsZUNoYW5nZXMsXG4gIGdldFJlbGV2YW50RmlsZXMsXG4gIHJlcGxhY2VTb3VyY2VTbmFwc2hvdHMsXG4gIHR5cGUgU291cmNlU25hcHNob3QsXG59IGZyb20gJy4vd2F0Y2gtcmVidWlsZC5qcyc7XG5cbmxldCBDYWNoZWROZXh0QnVpbGRlckVhZ2VyOiBhbnk7XG5jb25zdCBpbXBvcnRFc20gPSBuZXcgRnVuY3Rpb24oJ3NwZWNpZmllcicsICdyZXR1cm4gaW1wb3J0KHNwZWNpZmllciknKSBhcyA8VD4oXG4gIHNwZWNpZmllcjogc3RyaW5nXG4pID0+IFByb21pc2U8VD47XG5cbi8vIENyZWF0ZSB0aGUgZWFnZXIgTmV4dCBidWlsZGVyIGR5bmFtaWNhbGx5IGJ5IGV4dGVuZGluZyB0aGUgRVNNIEJhc2VCdWlsZGVyLlxuLy8gRXhwb3J0ZWQgYXMgZ2V0TmV4dEJ1aWxkZXJFYWdlcigpIHRvIGFsbG93IENvbW1vbkpTIG1vZHVsZXMgdG8gaW1wb3J0IGZyb21cbi8vIHRoZSBFU00gQHdvcmtmbG93L2J1aWxkZXJzIHBhY2thZ2UgdmlhIGR5bmFtaWMgaW1wb3J0IGF0IHJ1bnRpbWUuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0TmV4dEJ1aWxkZXJFYWdlcihcbiAgYnVpbGRlcnNNb2R1bGU/OiB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKVxuKSB7XG4gIGlmIChDYWNoZWROZXh0QnVpbGRlckVhZ2VyKSB7XG4gICAgcmV0dXJuIENhY2hlZE5leHRCdWlsZGVyRWFnZXI7XG4gIH1cblxuICBjb25zdCB7XG4gICAgQmFzZUJ1aWxkZXI6IEJhc2VCdWlsZGVyQ2xhc3MsXG4gICAgZ2V0V29ya2Zsb3dRdWV1ZVRyaWdnZXIsXG4gICAgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyxcbiAgICBwYXJlbnRIYXNDaGlsZCxcbiAgfSA9IGJ1aWxkZXJzTW9kdWxlID8/XG4gIChhd2FpdCBpbXBvcnRFc208dHlwZW9mIGltcG9ydCgnQHdvcmtmbG93L2J1aWxkZXJzJyk+KCdAd29ya2Zsb3cvYnVpbGRlcnMnKSk7XG5cbiAgY2xhc3MgTmV4dEJ1aWxkZXIgZXh0ZW5kcyBCYXNlQnVpbGRlckNsYXNzIHtcbiAgICBwcm90ZWN0ZWQgZGVjbGFyZSBjb25maWc6IEJ1aWxkZXJOZXh0Q29uZmlnICYge1xuICAgICAgcGFnZUV4dGVuc2lvbnM6IE5vbk51bGxhYmxlPFByb2plY3ROZXh0Q29uZmlnWydwYWdlRXh0ZW5zaW9ucyddPjtcbiAgICAgIGRpc3REaXI6IHN0cmluZztcbiAgICB9O1xuXG4gICAgYXN5bmMgYnVpbGQoKSB7XG4gICAgICBjb25zdCBvdXRwdXREaXIgPSBhd2FpdCB0aGlzLmZpbmRBcHBEaXJlY3RvcnkoKTtcbiAgICAgIGNvbnN0IHdvcmtmbG93R2VuZXJhdGVkRGlyID0gam9pbihvdXRwdXREaXIsICcud2VsbC1rbm93bi93b3JrZmxvdy92MScpO1xuXG4gICAgICAvLyBFbnN1cmUgb3V0cHV0IGRpcmVjdG9yaWVzIGV4aXN0XG4gICAgICBhd2FpdCBta2Rpcih3b3JrZmxvd0dlbmVyYXRlZERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBpZiAoIXRoaXMuY29uZmlnLndhdGNoKSB7XG4gICAgICAgIC8vIFByb2R1Y3Rpb24gYnVpbGQgY2FjaGVzIG1heSBzdGlsbCBjb250YWluIHRoZSByZXRpcmVkIHN0ZXAgcm91dGUuXG4gICAgICAgIGF3YWl0IHJtKGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdzdGVwJyksIHtcbiAgICAgICAgICByZWN1cnNpdmU6IHRydWUsXG4gICAgICAgICAgZm9yY2U6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgd3JpdGVGaWxlKGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICcuZ2l0aWdub3JlJyksICcqJyk7XG5cbiAgICAgIGNvbnN0IGlucHV0RmlsZXMgPSBhd2FpdCB0aGlzLmdldElucHV0RmlsZXMoKTtcbiAgICAgIGNvbnN0IHRzY29uZmlnUGF0aCA9IGF3YWl0IHRoaXMuZmluZFRzQ29uZmlnUGF0aCgpO1xuXG4gICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICBpbnB1dEZpbGVzLFxuICAgICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgICAgdHNjb25maWdQYXRoLFxuICAgICAgfTtcblxuICAgICAgLy8gVjI6IEJ1aWxkIGNvbWJpbmVkIHJvdXRlIChyZXBsYWNlcyBzZXBhcmF0ZSBzdGVwICsgZmxvdyByb3V0ZXMpXG4gICAgICBjb25zdCBjb21iaW5lZFJlc3VsdCA9IGF3YWl0IHRoaXMuYnVpbGRDb21iaW5lZEZ1bmN0aW9uKG9wdGlvbnMpO1xuICAgICAgYXdhaXQgdGhpcy5idWlsZFdlYmhvb2tSb3V0ZSh7IHdvcmtmbG93R2VuZXJhdGVkRGlyIH0pO1xuXG4gICAgICBjb25zdCB3cml0ZU1hbmlmZXN0ID0gYXN5bmMgKFxuICAgICAgICBzb3VyY2VNYW5pZmVzdDogV29ya2Zsb3dNYW5pZmVzdCB8IHVuZGVmaW5lZFxuICAgICAgKSA9PiB7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0ID0ge1xuICAgICAgICAgIHN0ZXBzOiB7IC4uLnNvdXJjZU1hbmlmZXN0Py5zdGVwcyB9LFxuICAgICAgICAgIHdvcmtmbG93czogeyAuLi5zb3VyY2VNYW5pZmVzdD8ud29ya2Zsb3dzIH0sXG4gICAgICAgICAgY2xhc3NlczogeyAuLi5zb3VyY2VNYW5pZmVzdD8uY2xhc3NlcyB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFdyaXRlIG1hbmlmZXN0XG4gICAgICAgIGNvbnN0IHdvcmtmbG93QnVuZGxlUGF0aCA9IGpvaW4od29ya2Zsb3dHZW5lcmF0ZWREaXIsICdmbG93L3JvdXRlLmpzJyk7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0SnNvbiA9IGF3YWl0IHRoaXMuY3JlYXRlTWFuaWZlc3Qoe1xuICAgICAgICAgIHdvcmtmbG93QnVuZGxlUGF0aCxcbiAgICAgICAgICBtYW5pZmVzdERpcjogd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICAgICAgbWFuaWZlc3QsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4cG9zZSBtYW5pZmVzdCBhcyBhIHN0YXRpYyBmaWxlIHdoZW4gV09SS0ZMT1dfUFVCTElDX01BTklGRVNUPTEuXG4gICAgICAgIGlmICh0aGlzLnNob3VsZEV4cG9zZVB1YmxpY01hbmlmZXN0ICYmIG1hbmlmZXN0SnNvbikge1xuICAgICAgICAgIGNvbnN0IHB1YmxpY01hbmlmZXN0RGlyID0gam9pbihcbiAgICAgICAgICAgIHRoaXMuY29uZmlnLndvcmtpbmdEaXIsXG4gICAgICAgICAgICAncHVibGljLy53ZWxsLWtub3duL3dvcmtmbG93L3YxJ1xuICAgICAgICAgICk7XG4gICAgICAgICAgYXdhaXQgbWtkaXIocHVibGljTWFuaWZlc3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5WRVJDRUxfREVQTE9ZTUVOVF9JRCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUoam9pbihwdWJsaWNNYW5pZmVzdERpciwgJy5naXRpZ25vcmUnKSwgJyonKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgY29weUZpbGUoXG4gICAgICAgICAgICBqb2luKHdvcmtmbG93R2VuZXJhdGVkRGlyLCAnbWFuaWZlc3QuanNvbicpLFxuICAgICAgICAgICAgam9pbihwdWJsaWNNYW5pZmVzdERpciwgJ21hbmlmZXN0Lmpzb24nKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdyaXRlTWFuaWZlc3QoY29tYmluZWRSZXN1bHQ/Lm1hbmlmZXN0KTtcblxuICAgICAgYXdhaXQgdGhpcy53cml0ZUZ1bmN0aW9uc0NvbmZpZyhvdXRwdXREaXIpO1xuXG4gICAgICBpZiAodGhpcy5jb25maWcud2F0Y2gpIHtcbiAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IHdhdGNoIG1vZGUgZm9yIGNvbWJpbmVkIGJ1bmRsZVxuICAgICAgICAvLyBGb3Igbm93LCBmYWxsIGJhY2sgdG8gZnVsbCByZWJ1aWxkIG9uIGZpbGUgY2hhbmdlc1xuICAgICAgICBpZiAoIWNvbWJpbmVkUmVzdWx0Py5pbnRlcmltQnVuZGxlQ3R4IHx8ICFjb21iaW5lZFJlc3VsdC5idW5kbGVGaW5hbCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdJbnZhcmlhbnQ6IGV4cGVjdGVkIHdvcmtmbG93IGJ1aWxkIGNvbnRleHQgaW4gd2F0Y2ggbW9kZSdcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RlcCByZWdpc3RyYXRpb25zIG1heSBiZSBlbWl0dGVkIGFzIHNvdXJjZSBpbXBvcnRzIHdpdGhvdXQgYW5cbiAgICAgICAgLy8gZXNidWlsZCBjb250ZXh0IHdoZW4gZXh0ZXJuYWxpemVOb25TdGVwcyBpcyBlbmFibGVkLlxuICAgICAgICBsZXQgc3RlcHNDdHggPSBjb21iaW5lZFJlc3VsdC5zdGVwc0NvbnRleHQ7XG4gICAgICAgIGxldCB3b3JrZmxvd3NDdHggPSB7XG4gICAgICAgICAgaW50ZXJpbUJ1bmRsZUN0eDogY29tYmluZWRSZXN1bHQuaW50ZXJpbUJ1bmRsZUN0eCxcbiAgICAgICAgICBidW5kbGVGaW5hbDogY29tYmluZWRSZXN1bHQuYnVuZGxlRmluYWwsXG4gICAgICAgIH07XG4gICAgICAgIGxldCBkaXNjb3ZlcmVkRW50cmllcyA9IGNvbWJpbmVkUmVzdWx0LmRpc2NvdmVyZWRFbnRyaWVzO1xuICAgICAgICBsZXQgc3RlcHNNYW5pZmVzdCA9IGNvbWJpbmVkUmVzdWx0LnN0ZXBzTWFuaWZlc3Q7XG4gICAgICAgIGxldCB3b3JrZmxvd3NNYW5pZmVzdCA9IGNvbWJpbmVkUmVzdWx0LndvcmtmbG93c01hbmlmZXN0O1xuICAgICAgICBjb25zdCBzdGVwc091dGZpbGUgPSBqb2luKFxuICAgICAgICAgIHdvcmtmbG93R2VuZXJhdGVkRGlyLFxuICAgICAgICAgICdmbG93JyxcbiAgICAgICAgICAnX19zdGVwX3JlZ2lzdHJhdGlvbnMuanMnXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3Qgbm9ybWFsaXplUGF0aCA9IChwYXRobmFtZTogc3RyaW5nKSA9PlxuICAgICAgICAgIChpc0Fic29sdXRlKHBhdGhuYW1lKVxuICAgICAgICAgICAgPyBwYXRobmFtZVxuICAgICAgICAgICAgOiByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsIHBhdGhuYW1lKVxuICAgICAgICAgICkucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuICAgICAgICBjb25zdCBzb3VyY2VTbmFwc2hvdHMgPSBuZXcgTWFwPHN0cmluZywgU291cmNlU25hcHNob3Q+KCk7XG5cbiAgICAgICAgY29uc3Qgd2F0Y2hhYmxlRXh0ZW5zaW9ucyA9IG5ldyBTZXQoW1xuICAgICAgICAgICcuanMnLFxuICAgICAgICAgICcuanN4JyxcbiAgICAgICAgICAnLnRzJyxcbiAgICAgICAgICAnLnRzeCcsXG4gICAgICAgICAgJy5tdHMnLFxuICAgICAgICAgICcuY3RzJyxcbiAgICAgICAgICAnLmNqcycsXG4gICAgICAgICAgJy5tanMnLFxuICAgICAgICBdKTtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZEdlbmVyYXRlZERpciA9IHdvcmtmbG93R2VuZXJhdGVkRGlyLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAgICAgY29uc3Qgbm9ybWFsaXplZERpc3REaXIgPSBub3JtYWxpemVQYXRoKHRoaXMuY29uZmlnLmRpc3REaXIpO1xuXG4gICAgICAgIC8vIFBydW5lIHRoZSBkZXYgd2F0Y2ggc2V0IHRvIGtlZXAgY2hva2lkYXIgZnJvbSByZWdpc3RlcmluZyBhblxuICAgICAgICAvLyBmcy53YXRjaCBwZXIgZGlyZWN0b3J5IGFjcm9zcyB0aGUgd2hvbGUgcHJvamVjdCB0cmVlIChjaG9raWRhciA0XG4gICAgICAgIC8vIGRyb3BwZWQgZnNldmVudHMsIHNvIG9uIG1hY09TIHRoYXQgZXhoYXVzdHMgdGhlIGZkIGxpbWl0IC0+IEVNRklMRVxuICAgICAgICAvLyBvbiBsYXJnZSBtb25vcmVwb3MpLiBUaGlzIGhvbm9ycyBgLmdpdGlnbm9yZWAgYW5kIHRoZVxuICAgICAgICAvLyBXT1JLRkxPV19ERVZfV0FUQ0hfSUdOT1JFRF9QQVRIUyBlbnYgdmFyIGluIGFkZGl0aW9uIHRvIHRoZVxuICAgICAgICAvLyBidWlsdC1pbiBmcmFnbWVudHMuIFRoZSBnZW5lcmF0ZWQgd29ya2Zsb3cgZGlyIGlzIHBhc3NlZCBhcyBhblxuICAgICAgICAvLyBleHRyYSBmcmFnbWVudCBzbyBpdCBpcyBwcnVuZWQgcmVnYXJkbGVzcyBvZiBgLmdpdGlnbm9yZWAuXG4gICAgICAgIGNvbnN0IGlzSWdub3JlZFdhdGNoUGF0aCA9IGNyZWF0ZVdhdGNoSWdub3JlUHJlZGljYXRlKHtcbiAgICAgICAgICB3b3JraW5nRGlyOiB0aGlzLmNvbmZpZy53b3JraW5nRGlyLFxuICAgICAgICAgIHByb2plY3RSb290OiB0aGlzLnRyYW5zZm9ybVByb2plY3RSb290LFxuICAgICAgICAgIGV4dHJhRnJhZ21lbnRzOiBbbm9ybWFsaXplZEdlbmVyYXRlZERpcl0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGhhc0lnbm9yZWRQYXRoRnJhZ21lbnQgPSAobm9ybWFsaXplZFBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRQYXRoID09PSBub3JtYWxpemVkRGlzdERpciB8fFxuICAgICAgICAgICAgbm9ybWFsaXplZFBhdGguc3RhcnRzV2l0aChgJHtub3JtYWxpemVkRGlzdERpcn0vYClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaXNJZ25vcmVkV2F0Y2hQYXRoKG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgfTtcblxuICAgICAgICBsZXQgcmVidWlsZFF1ZXVlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICAgICAgY29uc3QgZW5xdWV1ZSA9ICh0YXNrOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgICAgICAgcmVidWlsZFF1ZXVlID0gcmVidWlsZFF1ZXVlLnRoZW4odGFzaykuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gcHJvY2VzcyBmaWxlIGNoYW5nZScsIGVycm9yKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gcmVidWlsZFF1ZXVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlYWRTb3VyY2VTbmFwc2hvdCA9IChmaWxlOiBzdHJpbmcpID0+XG4gICAgICAgICAgY3JlYXRlU291cmNlU25hcHNob3QoeyBmaWxlLCBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlZnJlc2hTb3VyY2VTbmFwc2hvdHMgPSAoKSA9PlxuICAgICAgICAgIHJlcGxhY2VTb3VyY2VTbmFwc2hvdHMoe1xuICAgICAgICAgICAgZGlzY292ZXJlZEVudHJpZXMsXG4gICAgICAgICAgICBpbnB1dEZpbGVzOiBvcHRpb25zLmlucHV0RmlsZXMsXG4gICAgICAgICAgICBub3JtYWxpemVQYXRoLFxuICAgICAgICAgICAgcmVhZFNuYXBzaG90OiByZWFkU291cmNlU25hcHNob3QsXG4gICAgICAgICAgICBzb3VyY2VTbmFwc2hvdHMsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbWVyZ2VDb21iaW5lZE1hbmlmZXN0ID0gKFxuICAgICAgICAgIG5leHRTdGVwc01hbmlmZXN0OiBXb3JrZmxvd01hbmlmZXN0XG4gICAgICAgICk6IFdvcmtmbG93TWFuaWZlc3QgPT4gKHtcbiAgICAgICAgICAuLi5uZXh0U3RlcHNNYW5pZmVzdCxcbiAgICAgICAgICB3b3JrZmxvd3M6IHtcbiAgICAgICAgICAgIC4uLm5leHRTdGVwc01hbmlmZXN0LndvcmtmbG93cyxcbiAgICAgICAgICAgIC4uLndvcmtmbG93c01hbmlmZXN0LndvcmtmbG93cyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNsYXNzZXM6IHtcbiAgICAgICAgICAgIC4uLm5leHRTdGVwc01hbmlmZXN0LmNsYXNzZXMsXG4gICAgICAgICAgICAuLi53b3JrZmxvd3NNYW5pZmVzdC5jbGFzc2VzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGhvdFJlYnVpbGQgPSBhc3luYyAocmVmcmVzaFN0ZXBSZWdpc3RyYXRpb25zOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgaWYgKHJlZnJlc2hTdGVwUmVnaXN0cmF0aW9ucykge1xuICAgICAgICAgICAgaWYgKHN0ZXBzQ3R4KSB7XG4gICAgICAgICAgICAgIGF3YWl0IHN0ZXBzQ3R4LnJlYnVpbGQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHN0ZXBzTWFuaWZlc3QgPSBhd2FpdCB0aGlzLmNyZWF0ZVN0ZXBTb3VyY2VSZWdpc3RyYXRpb25GaWxlKHtcbiAgICAgICAgICAgICAgICBpbnB1dEZpbGVzOiBvcHRpb25zLmlucHV0RmlsZXMsXG4gICAgICAgICAgICAgICAgb3V0ZmlsZTogc3RlcHNPdXRmaWxlLFxuICAgICAgICAgICAgICAgIHRzY29uZmlnUGF0aCxcbiAgICAgICAgICAgICAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgd29ya2Zsb3dSZXN1bHQgPSBhd2FpdCB3b3JrZmxvd3NDdHguaW50ZXJpbUJ1bmRsZUN0eC5yZWJ1aWxkKCk7XG4gICAgICAgICAgY29uc3Qgd29ya2Zsb3dPdXRwdXQgPSB3b3JrZmxvd1Jlc3VsdC5vdXRwdXRGaWxlcz8uWzBdPy50ZXh0O1xuICAgICAgICAgIGlmICghd29ya2Zsb3dPdXRwdXQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgJ0ludmFyaWFudDogZXhwZWN0ZWQgd29ya2Zsb3cgb3V0cHV0IGZyb20gaG90IHJlYnVpbGQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IHdvcmtmbG93c0N0eC5idW5kbGVGaW5hbCh3b3JrZmxvd091dHB1dCk7XG4gICAgICAgICAgYXdhaXQgd3JpdGVNYW5pZmVzdChtZXJnZUNvbWJpbmVkTWFuaWZlc3Qoc3RlcHNNYW5pZmVzdCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGZ1bGxSZWJ1aWxkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuY2xlYXJEaXNjb3ZlcmVkRW50cmllc0NhY2hlKCk7XG4gICAgICAgICAgY29uc3QgbmV3SW5wdXRGaWxlcyA9IGF3YWl0IHRoaXMuZ2V0SW5wdXRGaWxlcygpO1xuICAgICAgICAgIG9wdGlvbnMuaW5wdXRGaWxlcyA9IG5ld0lucHV0RmlsZXM7XG5cbiAgICAgICAgICBhd2FpdCBzdGVwc0N0eD8uZGlzcG9zZSgpO1xuICAgICAgICAgIGF3YWl0IHdvcmtmbG93c0N0eC5pbnRlcmltQnVuZGxlQ3R4LmRpc3Bvc2UoKTtcblxuICAgICAgICAgIGNvbnN0IG5ld0NvbWJpbmVkID0gYXdhaXQgdGhpcy5idWlsZENvbWJpbmVkRnVuY3Rpb24ob3B0aW9ucyk7XG4gICAgICAgICAgc3RlcHNDdHggPSBuZXdDb21iaW5lZC5zdGVwc0NvbnRleHQ7XG4gICAgICAgICAgZGlzY292ZXJlZEVudHJpZXMgPSBuZXdDb21iaW5lZC5kaXNjb3ZlcmVkRW50cmllcztcbiAgICAgICAgICBzdGVwc01hbmlmZXN0ID0gbmV3Q29tYmluZWQuc3RlcHNNYW5pZmVzdDtcbiAgICAgICAgICB3b3JrZmxvd3NNYW5pZmVzdCA9IG5ld0NvbWJpbmVkLndvcmtmbG93c01hbmlmZXN0O1xuXG4gICAgICAgICAgaWYgKCFuZXdDb21iaW5lZD8uaW50ZXJpbUJ1bmRsZUN0eCB8fCAhbmV3Q29tYmluZWQ/LmJ1bmRsZUZpbmFsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICdJbnZhcmlhbnQ6IGV4cGVjdGVkIHdvcmtmbG93cyBidW5kbGUgY29udGV4dCBhZnRlciByZWJ1aWxkJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgd29ya2Zsb3dzQ3R4ID0ge1xuICAgICAgICAgICAgaW50ZXJpbUJ1bmRsZUN0eDogbmV3Q29tYmluZWQuaW50ZXJpbUJ1bmRsZUN0eCxcbiAgICAgICAgICAgIGJ1bmRsZUZpbmFsOiBuZXdDb21iaW5lZC5idW5kbGVGaW5hbCxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgYXdhaXQgd3JpdGVNYW5pZmVzdChuZXdDb21iaW5lZC5tYW5pZmVzdCk7XG4gICAgICAgICAgYXdhaXQgcmVmcmVzaFNvdXJjZVNuYXBzaG90cygpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGlzV2F0Y2hhYmxlRmlsZSA9IChwYXRoOiBzdHJpbmcpID0+XG4gICAgICAgICAgd2F0Y2hhYmxlRXh0ZW5zaW9ucy5oYXMoZXh0bmFtZShwYXRoKSk7XG5cbiAgICAgICAgY29uc3QgcmVhZEtub3duRmlsZXMgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICAgICAgICBjb25zdCBhbGlhc2VzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICAgICAgICBjb25zdCByZWxldmFudEZpbGVzID0gZ2V0UmVsZXZhbnRGaWxlcyh7XG4gICAgICAgICAgICBkaXNjb3ZlcmVkRW50cmllcyxcbiAgICAgICAgICAgIGlucHV0RmlsZXM6IG9wdGlvbnMuaW5wdXRGaWxlcyxcbiAgICAgICAgICAgIG5vcm1hbGl6ZVBhdGgsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBhZGRLbm93bkZpbGUgPSBhc3luYyAoZmlsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgbGV0IHJlYWxGaWxlUGF0aCA9IGZpbGVQYXRoO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgcmVhbEZpbGVQYXRoID0gbm9ybWFsaXplUGF0aChhd2FpdCByZWFscGF0aChmaWxlUGF0aCkpO1xuICAgICAgICAgICAgfSBjYXRjaCB7fVxuXG4gICAgICAgICAgICBjb25zdCBjYW5vbmljYWxQYXRoID0gcmVsZXZhbnRGaWxlcy5oYXMocmVhbEZpbGVQYXRoKVxuICAgICAgICAgICAgICA/IHJlYWxGaWxlUGF0aFxuICAgICAgICAgICAgICA6IGZpbGVQYXRoO1xuICAgICAgICAgICAgZmlsZXMuYWRkKGNhbm9uaWNhbFBhdGgpO1xuICAgICAgICAgICAgYWxpYXNlcy5zZXQoZmlsZVBhdGgsIGNhbm9uaWNhbFBhdGgpO1xuICAgICAgICAgICAgYWxpYXNlcy5zZXQocmVhbEZpbGVQYXRoLCBjYW5vbmljYWxQYXRoKTtcbiAgICAgICAgICAgIHJldHVybiBjYW5vbmljYWxQYXRoO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCB2aXNpdCA9IGFzeW5jIChkaXJlY3Rvcnk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAgICAgbGV0IGRpcmVudHM6IERpcmVudDxzdHJpbmc+W107XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBkaXJlbnRzID0gYXdhaXQgcmVhZGRpcihkaXJlY3RvcnksIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgICBkaXJlbnRzLm1hcChhc3luYyAoZGlyZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBub3JtYWxpemVQYXRoKGpvaW4oZGlyZWN0b3J5LCBkaXJlbnQubmFtZSkpO1xuICAgICAgICAgICAgICAgIGlmIChoYXNJZ25vcmVkUGF0aEZyYWdtZW50KGZpbGVQYXRoKSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChkaXJlbnQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgICAgICAgYXdhaXQgdmlzaXQoZmlsZVBhdGgpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBzdGF0czogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBzdGF0Pj47XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIHN0YXRzID0gYXdhaXQgc3RhdChmaWxlUGF0aCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRzLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHZpc2l0KGZpbGVQYXRoKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIXN0YXRzLmlzRmlsZSgpIHx8ICFpc1dhdGNoYWJsZUZpbGUoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgYXdhaXQgYWRkS25vd25GaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGF3YWl0IHZpc2l0KHRoaXMuY29uZmlnLndvcmtpbmdEaXIpO1xuICAgICAgICAgIHJldHVybiB7IGZpbGVzLCBhbGlhc2VzLCBhZGRLbm93bkZpbGUgfTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBtZXJnZUZpbGVDaGFuZ2VzID0gKFxuICAgICAgICAgIGxlZnQ6IEZpbGVDaGFuZ2VzLFxuICAgICAgICAgIHJpZ2h0OiBGaWxlQ2hhbmdlc1xuICAgICAgICApOiBGaWxlQ2hhbmdlcyA9PiAoe1xuICAgICAgICAgIGFkZGVkRmlsZXM6IHVuaXF1ZShbLi4ubGVmdC5hZGRlZEZpbGVzLCAuLi5yaWdodC5hZGRlZEZpbGVzXSksXG4gICAgICAgICAgbW9kaWZpZWRGaWxlczogdW5pcXVlKFtcbiAgICAgICAgICAgIC4uLmxlZnQubW9kaWZpZWRGaWxlcyxcbiAgICAgICAgICAgIC4uLnJpZ2h0Lm1vZGlmaWVkRmlsZXMsXG4gICAgICAgICAgXSksXG4gICAgICAgICAgcmVtb3ZlZEZpbGVzOiB1bmlxdWUoWy4uLmxlZnQucmVtb3ZlZEZpbGVzLCAuLi5yaWdodC5yZW1vdmVkRmlsZXNdKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdW5pcXVlID0gKHBhdGhzOiBzdHJpbmdbXSkgPT4gWy4uLm5ldyBTZXQocGF0aHMpXTtcblxuICAgICAgICBjb25zdCBjbGFzc2lmeUZpbGVDaGFuZ2VzID0gKHtcbiAgICAgICAgICBjaGFuZ2VkRmlsZXMsXG4gICAgICAgICAga25vd25GaWxlcyxcbiAgICAgICAgICByZW1vdmVkRmlsZXMsXG4gICAgICAgIH06IHtcbiAgICAgICAgICBjaGFuZ2VkRmlsZXM6IHN0cmluZ1tdO1xuICAgICAgICAgIGtub3duRmlsZXM6IFNldDxzdHJpbmc+O1xuICAgICAgICAgIHJlbW92ZWRGaWxlczogc3RyaW5nW107XG4gICAgICAgIH0pOiBGaWxlQ2hhbmdlcyA9PiB7XG4gICAgICAgICAgY29uc3QgYWRkZWRGaWxlczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICBjb25zdCBtb2RpZmllZEZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIHVuaXF1ZShjaGFuZ2VkRmlsZXMpKSB7XG4gICAgICAgICAgICBpZiAoa25vd25GaWxlcy5oYXMoZmlsZSkpIHtcbiAgICAgICAgICAgICAgbW9kaWZpZWRGaWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYWRkZWRGaWxlcy5wdXNoKGZpbGUpO1xuICAgICAgICAgICAgICBrbm93bkZpbGVzLmFkZChmaWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcmVtb3ZlZEZpbGVzKSB7XG4gICAgICAgICAgICBrbm93bkZpbGVzLmRlbGV0ZShmaWxlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWRkZWRGaWxlcyxcbiAgICAgICAgICAgIG1vZGlmaWVkRmlsZXMsXG4gICAgICAgICAgICByZW1vdmVkRmlsZXM6IHVuaXF1ZShyZW1vdmVkRmlsZXMpLFxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgaGFzRmlsZUNoYW5nZXMgPSAoe1xuICAgICAgICAgIGFkZGVkRmlsZXMsXG4gICAgICAgICAgbW9kaWZpZWRGaWxlcyxcbiAgICAgICAgICByZW1vdmVkRmlsZXMsXG4gICAgICAgIH06IEZpbGVDaGFuZ2VzKSA9PlxuICAgICAgICAgIGFkZGVkRmlsZXMubGVuZ3RoID4gMCB8fFxuICAgICAgICAgIG1vZGlmaWVkRmlsZXMubGVuZ3RoID4gMCB8fFxuICAgICAgICAgIHJlbW92ZWRGaWxlcy5sZW5ndGggPiAwO1xuICAgICAgICBjb25zdCBsb2dEZXZIbXIgPSAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgaWYgKHByb2Nlc3MuZW52LldPUktGTE9XX0RFVl9ITVJfTE9HUyA9PT0gJzEnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyguLi5hcmdzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgcmVmcmVzaFNvdXJjZVNuYXBzaG90cygpO1xuICAgICAgICBsZXQge1xuICAgICAgICAgIGZpbGVzOiBrbm93bkZpbGVzLFxuICAgICAgICAgIGFsaWFzZXM6IGtub3duRmlsZUFsaWFzZXMsXG4gICAgICAgICAgYWRkS25vd25GaWxlOiByZW1lbWJlcktub3duRmlsZSxcbiAgICAgICAgfSA9IGF3YWl0IHJlYWRLbm93bkZpbGVzKCk7XG5cbiAgICAgICAgY29uc3QgcmVmcmVzaEtub3duRmlsZXMgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgbmV4dEtub3duID0gYXdhaXQgcmVhZEtub3duRmlsZXMoKTtcbiAgICAgICAgICBrbm93bkZpbGVzID0gbmV4dEtub3duLmZpbGVzO1xuICAgICAgICAgIGtub3duRmlsZUFsaWFzZXMgPSBuZXh0S25vd24uYWxpYXNlcztcbiAgICAgICAgICByZW1lbWJlcktub3duRmlsZSA9IG5leHRLbm93bi5hZGRLbm93bkZpbGU7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcHJvY2Vzc0ZpbGVDaGFuZ2VzID0gYXN5bmMgKGZpbGVDaGFuZ2VzOiBGaWxlQ2hhbmdlcykgPT4ge1xuICAgICAgICAgIGlmICghaGFzRmlsZUNoYW5nZXMoZmlsZUNoYW5nZXMpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZGVjaXNpb24gPSBhd2FpdCBjbGFzc2lmeVJlYnVpbGQoe1xuICAgICAgICAgICAgZGlzY292ZXJlZEVudHJpZXMsXG4gICAgICAgICAgICBmaWxlQ2hhbmdlcyxcbiAgICAgICAgICAgIGlucHV0RmlsZXM6IG9wdGlvbnMuaW5wdXRGaWxlcyxcbiAgICAgICAgICAgIG5vcm1hbGl6ZVBhdGgsXG4gICAgICAgICAgICBwYXJlbnRIYXNDaGlsZCxcbiAgICAgICAgICAgIHJlYWRTbmFwc2hvdDogcmVhZFNvdXJjZVNuYXBzaG90LFxuICAgICAgICAgICAgc291cmNlU25hcHNob3RzLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChkZWNpc2lvbi5raW5kID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgIGxvZ0Rldkhtcignd29ya2Zsb3cgZGV2IGhtcjogc2tpcCcpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBbZmlsZSwgc25hcHNob3RdIG9mIGRlY2lzaW9uLnNuYXBzaG90cyB8fCBbXSkge1xuICAgICAgICAgICAgICBzb3VyY2VTbmFwc2hvdHMuc2V0KGZpbGUsIHNuYXBzaG90KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRlY2lzaW9uLmtpbmQgPT09ICdmdWxsJykge1xuICAgICAgICAgICAgbG9nRGV2SG1yKCd3b3JrZmxvdyBkZXYgaG1yOiBmdWxsIHJlZGlzY292ZXJ5Jyk7XG4gICAgICAgICAgICBhd2FpdCBmdWxsUmVidWlsZCgpO1xuICAgICAgICAgICAgYXdhaXQgcmVmcmVzaEtub3duRmlsZXMoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsb2dEZXZIbXIoXG4gICAgICAgICAgICBgd29ya2Zsb3cgZGV2IGhtcjogaG90IHJlYnVpbGQke2RlY2lzaW9uLnJlZnJlc2hTdGVwUmVnaXN0cmF0aW9ucyA/ICcgd2l0aCBzdGVwIHJlZ2lzdHJhdGlvbiByZWZyZXNoJyA6ICcnfWBcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IGhvdFJlYnVpbGQoZGVjaXNpb24ucmVmcmVzaFN0ZXBSZWdpc3RyYXRpb25zKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IFtmaWxlLCBzbmFwc2hvdF0gb2YgZGVjaXNpb24uc25hcHNob3RzKSB7XG4gICAgICAgICAgICBzb3VyY2VTbmFwc2hvdHMuc2V0KGZpbGUsIHNuYXBzaG90KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgbGV0IHBlbmRpbmdGaWxlQ2hhbmdlczogRmlsZUNoYW5nZXMgPSB7XG4gICAgICAgICAgYWRkZWRGaWxlczogW10sXG4gICAgICAgICAgbW9kaWZpZWRGaWxlczogW10sXG4gICAgICAgICAgcmVtb3ZlZEZpbGVzOiBbXSxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGZsdXNoVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIGNvbnN0IHNjaGVkdWxlRmlsZUNoYW5nZXMgPSAoZmlsZUNoYW5nZXM6IEZpbGVDaGFuZ2VzKSA9PiB7XG4gICAgICAgICAgcGVuZGluZ0ZpbGVDaGFuZ2VzID0gbWVyZ2VGaWxlQ2hhbmdlcyhcbiAgICAgICAgICAgIHBlbmRpbmdGaWxlQ2hhbmdlcyxcbiAgICAgICAgICAgIGZpbGVDaGFuZ2VzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZmx1c2hUaW1lcikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWxlQ2hhbmdlcyA9IHBlbmRpbmdGaWxlQ2hhbmdlcztcbiAgICAgICAgICAgIHBlbmRpbmdGaWxlQ2hhbmdlcyA9IHtcbiAgICAgICAgICAgICAgYWRkZWRGaWxlczogW10sXG4gICAgICAgICAgICAgIG1vZGlmaWVkRmlsZXM6IFtdLFxuICAgICAgICAgICAgICByZW1vdmVkRmlsZXM6IFtdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZsdXNoVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBlbnF1ZXVlKCgpID0+IHByb2Nlc3NGaWxlQ2hhbmdlcyhmaWxlQ2hhbmdlcykpO1xuICAgICAgICAgIH0sIDEwKTtcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXNvbHZlRXhpc3RpbmdFdmVudFBhdGggPSBhc3luYyAocGF0aG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gbm9ybWFsaXplUGF0aChwYXRobmFtZSk7XG4gICAgICAgICAgaWYgKCFpc1dhdGNoYWJsZUZpbGUobm9ybWFsaXplZFBhdGgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qga25vd25QYXRoID0ga25vd25GaWxlQWxpYXNlcy5nZXQobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICAgIGlmIChrbm93blBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiBrbm93blBhdGg7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlYWxGaWxlUGF0aCA9IG5vcm1hbGl6ZVBhdGgoYXdhaXQgcmVhbHBhdGgobm9ybWFsaXplZFBhdGgpKTtcbiAgICAgICAgICAgIHJldHVybiBrbm93bkZpbGVBbGlhc2VzLmdldChyZWFsRmlsZVBhdGgpID8/IG5vcm1hbGl6ZWRQYXRoO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRQYXRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBoYW5kbGVGaWxlQWRkZWQgPSBhc3luYyAocGF0aG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gbm9ybWFsaXplUGF0aChwYXRobmFtZSk7XG4gICAgICAgICAgaWYgKCFpc1dhdGNoYWJsZUZpbGUobm9ybWFsaXplZFBhdGgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZXhpc3RpbmdQYXRoID0gYXdhaXQgcmVzb2x2ZUV4aXN0aW5nRXZlbnRQYXRoKG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgICBjb25zdCB3YXNLbm93biA9IGV4aXN0aW5nUGF0aCA/IGtub3duRmlsZXMuaGFzKGV4aXN0aW5nUGF0aCkgOiBmYWxzZTtcbiAgICAgICAgICBjb25zdCBjYW5vbmljYWxQYXRoID0gYXdhaXQgcmVtZW1iZXJLbm93bkZpbGUobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICAgIGtub3duRmlsZXMuYWRkKGNhbm9uaWNhbFBhdGgpO1xuICAgICAgICAgIHNjaGVkdWxlRmlsZUNoYW5nZXMoe1xuICAgICAgICAgICAgYWRkZWRGaWxlczogd2FzS25vd24gPyBbXSA6IFtjYW5vbmljYWxQYXRoXSxcbiAgICAgICAgICAgIG1vZGlmaWVkRmlsZXM6IHdhc0tub3duID8gW2Nhbm9uaWNhbFBhdGhdIDogW10sXG4gICAgICAgICAgICByZW1vdmVkRmlsZXM6IFtdLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGhhbmRsZUZpbGVDaGFuZ2VkID0gYXN5bmMgKHBhdGhuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBjb25zdCBjYW5vbmljYWxQYXRoID0gYXdhaXQgcmVzb2x2ZUV4aXN0aW5nRXZlbnRQYXRoKHBhdGhuYW1lKTtcbiAgICAgICAgICBpZiAoIWNhbm9uaWNhbFBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBmaWxlQ2hhbmdlcyA9IGNsYXNzaWZ5RmlsZUNoYW5nZXMoe1xuICAgICAgICAgICAgY2hhbmdlZEZpbGVzOiBbY2Fub25pY2FsUGF0aF0sXG4gICAgICAgICAgICBrbm93bkZpbGVzLFxuICAgICAgICAgICAgcmVtb3ZlZEZpbGVzOiBbXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoIWtub3duRmlsZUFsaWFzZXMuaGFzKGNhbm9uaWNhbFBhdGgpKSB7XG4gICAgICAgICAgICBhd2FpdCByZW1lbWJlcktub3duRmlsZShjYW5vbmljYWxQYXRoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2NoZWR1bGVGaWxlQ2hhbmdlcyhmaWxlQ2hhbmdlcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgaGFuZGxlRmlsZVJlbW92ZWQgPSAocGF0aG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gbm9ybWFsaXplUGF0aChwYXRobmFtZSk7XG4gICAgICAgICAgaWYgKCFpc1dhdGNoYWJsZUZpbGUobm9ybWFsaXplZFBhdGgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY2Fub25pY2FsUGF0aCA9XG4gICAgICAgICAgICBrbm93bkZpbGVBbGlhc2VzLmdldChub3JtYWxpemVkUGF0aCkgPz8gbm9ybWFsaXplZFBhdGg7XG4gICAgICAgICAgY29uc3QgZmlsZUNoYW5nZXMgPSBjbGFzc2lmeUZpbGVDaGFuZ2VzKHtcbiAgICAgICAgICAgIGNoYW5nZWRGaWxlczogW10sXG4gICAgICAgICAgICBrbm93bkZpbGVzLFxuICAgICAgICAgICAgcmVtb3ZlZEZpbGVzOiBbY2Fub25pY2FsUGF0aF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAga25vd25GaWxlQWxpYXNlcy5kZWxldGUobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICAgIHNjaGVkdWxlRmlsZUNoYW5nZXMoZmlsZUNoYW5nZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHdhdGNoZXIgPSBjaG9raWRhci53YXRjaCh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCB7XG4gICAgICAgICAgaWdub3JlSW5pdGlhbDogdHJ1ZSxcbiAgICAgICAgICBmb2xsb3dTeW1saW5rczogdHJ1ZSxcbiAgICAgICAgICBpZ25vcmVkOiAocGF0aG5hbWUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRQYXRoID0gbm9ybWFsaXplUGF0aChTdHJpbmcocGF0aG5hbWUpKTtcbiAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dG5hbWUobm9ybWFsaXplZFBhdGgpO1xuICAgICAgICAgICAgaWYgKGV4dGVuc2lvbiAmJiAhd2F0Y2hhYmxlRXh0ZW5zaW9ucy5oYXMoZXh0ZW5zaW9uKSkge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBoYXNJZ25vcmVkUGF0aEZyYWdtZW50KG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICB3YXRjaGVyLm9uKCdhZGQnLCAocGF0aG5hbWUpID0+IHtcbiAgICAgICAgICB2b2lkIGhhbmRsZUZpbGVBZGRlZChwYXRobmFtZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB3YXRjaGVyLm9uKCdjaGFuZ2UnLCAocGF0aG5hbWUpID0+IHtcbiAgICAgICAgICB2b2lkIGhhbmRsZUZpbGVDaGFuZ2VkKHBhdGhuYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHdhdGNoZXIub24oJ3VubGluaycsIChwYXRobmFtZSkgPT4ge1xuICAgICAgICAgIGhhbmRsZUZpbGVSZW1vdmVkKHBhdGhuYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHdhdGNoZXIub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignV29ya2Zsb3cgZGV2IHdhdGNoZXIgZXJyb3InLCBlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgICB3YXRjaGVyLm9uKCdyZWFkeScsICgpID0+IHtcbiAgICAgICAgICBsb2dEZXZIbXIoJ3dvcmtmbG93IGRldiBobXI6IHJlYWR5Jyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBhc3luYyBnZXRJbnB1dEZpbGVzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICAgIGNvbnN0IGlucHV0RmlsZXMgPSBhd2FpdCBzdXBlci5nZXRJbnB1dEZpbGVzKCk7XG4gICAgICByZXR1cm4gaW5wdXRGaWxlcy5maWx0ZXIoKGZpbGUpID0+IHtcbiAgICAgICAgY29uc3QgZW50cnkgPSByZWxhdGl2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCBmaWxlKS5yZXBsYWNlQWxsKFxuICAgICAgICAgICdcXFxcJyxcbiAgICAgICAgICAnLydcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBNYXRjaCBBcHAgUm91dGVyIHJvdXRlLCBwYWdlLCBhbmQgbGF5b3V0IGVudHJ5cG9pbnRzIGluIGFwcC8gb3Igc3JjL2FwcC8uXG4gICAgICAgIGlmICgvXig/OmFwcHxzcmNcXC9hcHApXFwvKD86LipcXC8pPyg/OnJvdXRlfHBhZ2V8bGF5b3V0KVxcLi8udGVzdChlbnRyeSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE1hdGNoIGV2ZXJ5IFBhZ2VzIFJvdXRlciBlbnRyeXBvaW50IGluIHBhZ2VzLyBvciBzcmMvcGFnZXMvLlxuICAgICAgICBpZiAoL14oPzpwYWdlc3xzcmNcXC9wYWdlcylcXC8vLnRlc3QoZW50cnkpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNYXRjaCBOZXh0LmpzIHJvb3QgZW50cnlwb2ludHMgYXQgdGhlIHByb2plY3Qgcm9vdCBvciB1bmRlciBzcmMvLlxuICAgICAgICByZXR1cm4gWydpbnN0cnVtZW50YXRpb24nLCAnbWlkZGxld2FyZScsICdwcm94eSddLnNvbWUoKG5hbWUpID0+XG4gICAgICAgICAgdGhpcy5jb25maWcucGFnZUV4dGVuc2lvbnMuc29tZShcbiAgICAgICAgICAgIChleHRlbnNpb24pID0+XG4gICAgICAgICAgICAgIGVudHJ5ID09PSBgJHtuYW1lfS4ke2V4dGVuc2lvbn1gIHx8XG4gICAgICAgICAgICAgIGVudHJ5ID09PSBgc3JjLyR7bmFtZX0uJHtleHRlbnNpb259YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgd3JpdGVGdW5jdGlvbnNDb25maWcob3V0cHV0RGlyOiBzdHJpbmcpIHtcbiAgICAgIC8vIHdlIGRvbid0IHJ1biB0aGlzIGluIGRldmVsb3BtZW50IG1vZGUgYXMgaXQncyBub3QgbmVlZGVkXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdkZXZlbG9wbWVudCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBWMiBjb21iaW5lZCBjb25maWc6IHNpbmdsZSB0cmlnZ2VyIGhhbmRsZXMgYm90aCB3b3JrZmxvdyBhbmQgc3RlcCBleGVjdXRpb24uXG4gICAgICAvLyBUaGUgc3RlcCByb3V0ZSBubyBsb25nZXIgbmVlZHMgaXRzIG93biB0cmlnZ2VyIHNpbmNlIHN0ZXBzIGFyZSBleGVjdXRlZFxuICAgICAgLy8gaW5saW5lIGJ5IHRoZSBjb21iaW5lZCBoYW5kbGVyIG9yIHF1ZXVlZCBiYWNrIHRvIF9fd2tmX3dvcmtmbG93Xyogd2l0aCBzdGVwSWQuXG4gICAgICBjb25zdCBnZW5lcmF0ZWRDb25maWcgPSB7XG4gICAgICAgIHZlcnNpb246ICcwJyxcbiAgICAgICAgd29ya2Zsb3dzOiB7XG4gICAgICAgICAgbWF4RHVyYXRpb246ICdtYXgnLFxuICAgICAgICAgIGV4cGVyaW1lbnRhbFRyaWdnZXJzOiBbZ2V0V29ya2Zsb3dRdWV1ZVRyaWdnZXIoKV0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICAgIGpvaW4ob3V0cHV0RGlyLCAnLndlbGwta25vd24vd29ya2Zsb3cvdjEvY29uZmlnLmpzb24nKSxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoZ2VuZXJhdGVkQ29uZmlnLCBudWxsLCAyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBWMjogQnVpbGQgY29tYmluZWQgcm91dGUgdGhhdCBoYW5kbGVzIGJvdGggd29ya2Zsb3cgYW5kIHN0ZXAgZXhlY3V0aW9uLlxuICAgICAqL1xuICAgIHByaXZhdGUgYXN5bmMgYnVpbGRDb21iaW5lZEZ1bmN0aW9uKHtcbiAgICAgIGlucHV0RmlsZXMsXG4gICAgICB3b3JrZmxvd0dlbmVyYXRlZERpcixcbiAgICAgIHRzY29uZmlnUGF0aCxcbiAgICB9OiB7XG4gICAgICBpbnB1dEZpbGVzOiBzdHJpbmdbXTtcbiAgICAgIHdvcmtmbG93R2VuZXJhdGVkRGlyOiBzdHJpbmc7XG4gICAgICB0c2NvbmZpZ1BhdGg/OiBzdHJpbmc7XG4gICAgfSkge1xuICAgICAgY29uc3QgZmxvd1JvdXRlRGlyID0gam9pbih3b3JrZmxvd0dlbmVyYXRlZERpciwgJ2Zsb3cnKTtcbiAgICAgIGF3YWl0IG1rZGlyKGZsb3dSb3V0ZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZUNvbWJpbmVkQnVuZGxlKHtcbiAgICAgICAgZm9ybWF0OiAnZXNtJyxcbiAgICAgICAgaW5wdXRGaWxlcyxcbiAgICAgICAgc3RlcHNPdXRmaWxlOiBqb2luKGZsb3dSb3V0ZURpciwgJ19fc3RlcF9yZWdpc3RyYXRpb25zLmpzJyksXG4gICAgICAgIGZsb3dPdXRmaWxlOiBqb2luKGZsb3dSb3V0ZURpciwgJ3JvdXRlLmpzJyksXG4gICAgICAgIGJ1bmRsZUZpbmFsT3V0cHV0OiBmYWxzZSxcbiAgICAgICAgZXh0ZXJuYWxpemVOb25TdGVwczogdHJ1ZSxcbiAgICAgICAgc291cmNlU3RlcFJlZ2lzdHJhdGlvbkltcG9ydHM6IHRydWUsXG4gICAgICAgIHRzY29uZmlnUGF0aCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYnVpbGRXZWJob29rUm91dGUoe1xuICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgfToge1xuICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXI6IHN0cmluZztcbiAgICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICBjb25zdCB3ZWJob29rUm91dGVGaWxlID0gam9pbihcbiAgICAgICAgd29ya2Zsb3dHZW5lcmF0ZWREaXIsXG4gICAgICAgICd3ZWJob29rL1t0b2tlbl0vcm91dGUuanMnXG4gICAgICApO1xuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVXZWJob29rQnVuZGxlKHtcbiAgICAgICAgb3V0ZmlsZTogd2ViaG9va1JvdXRlRmlsZSxcbiAgICAgICAgYnVuZGxlOiBmYWxzZSwgLy8gTmV4dC5qcyBkb2Vzbid0IG5lZWQgYnVuZGxpbmdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZmluZEFwcERpcmVjdG9yeSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgICAgY29uc3QgYXBwRGlyID0gcmVzb2x2ZSh0aGlzLmNvbmZpZy53b3JraW5nRGlyLCAnYXBwJyk7XG4gICAgICBjb25zdCBzcmNBcHBEaXIgPSByZXNvbHZlKHRoaXMuY29uZmlnLndvcmtpbmdEaXIsICdzcmMvYXBwJyk7XG4gICAgICBjb25zdCBwYWdlc0RpciA9IHJlc29sdmUodGhpcy5jb25maWcud29ya2luZ0RpciwgJ3BhZ2VzJyk7XG4gICAgICBjb25zdCBzcmNQYWdlc0RpciA9IHJlc29sdmUodGhpcy5jb25maWcud29ya2luZ0RpciwgJ3NyYy9wYWdlcycpO1xuXG4gICAgICAvLyBIZWxwZXIgdG8gY2hlY2sgaWYgYSBwYXRoIGV4aXN0cyBhbmQgaXMgYSBkaXJlY3RvcnlcbiAgICAgIGNvbnN0IGlzRGlyZWN0b3J5ID0gYXN5bmMgKHBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGFjY2VzcyhwYXRoLCBjb25zdGFudHMuRl9PSyk7XG4gICAgICAgICAgY29uc3Qgc3RhdHMgPSBhd2FpdCBzdGF0KHBhdGgpO1xuICAgICAgICAgIGlmICghc3RhdHMuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYXRoIGV4aXN0cyBidXQgaXMgbm90IGEgZGlyZWN0b3J5OiAke3BhdGh9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLm1lc3NhZ2UuaW5jbHVkZXMoJ25vdCBhIGRpcmVjdG9yeScpKSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIC8vIENoZWNrIGlmIGFwcCBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICBpZiAoYXdhaXQgaXNEaXJlY3RvcnkoYXBwRGlyKSkge1xuICAgICAgICByZXR1cm4gYXBwRGlyO1xuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBpZiBzcmMvYXBwIGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGlmIChhd2FpdCBpc0RpcmVjdG9yeShzcmNBcHBEaXIpKSB7XG4gICAgICAgIHJldHVybiBzcmNBcHBEaXI7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIG5vIGFwcCBkaXJlY3RvcnkgZXhpc3RzLCBjaGVjayBmb3IgcGFnZXMgZGlyZWN0b3J5IGFuZCBjcmVhdGUgYXBwIG5leHQgdG8gaXRcbiAgICAgIGlmIChhd2FpdCBpc0RpcmVjdG9yeShwYWdlc0RpcikpIHtcbiAgICAgICAgLy8gQ3JlYXRlIGFwcCBkaXJlY3RvcnkgbmV4dCB0byBwYWdlcyBkaXJlY3RvcnlcbiAgICAgICAgYXdhaXQgbWtkaXIoYXBwRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgcmV0dXJuIGFwcERpcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGF3YWl0IGlzRGlyZWN0b3J5KHNyY1BhZ2VzRGlyKSkge1xuICAgICAgICAvLyBDcmVhdGUgc3JjL2FwcCBkaXJlY3RvcnkgbmV4dCB0byBzcmMvcGFnZXMgZGlyZWN0b3J5XG4gICAgICAgIGF3YWl0IG1rZGlyKHNyY0FwcERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgIHJldHVybiBzcmNBcHBEaXI7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0NvdWxkIG5vdCBmaW5kIE5leHQuanMgYXBwIG9yIHBhZ2VzIGRpcmVjdG9yeS4gRXhwZWN0ZWQgb25lIG9mOiBcImFwcFwiLCBcInNyYy9hcHBcIiwgXCJwYWdlc1wiLCBvciBcInNyYy9wYWdlc1wiIHRvIGV4aXN0LidcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQ2FjaGVkTmV4dEJ1aWxkZXJFYWdlciA9IE5leHRCdWlsZGVyO1xuICByZXR1cm4gTmV4dEJ1aWxkZXI7XG59XG4iXX0=
|