@workflow/next 5.0.0-beta.0 → 5.0.0-beta.10

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/loader.js CHANGED
@@ -7,20 +7,67 @@ const node_net_1 = require("node:net");
7
7
  const node_path_1 = require("node:path");
8
8
  const core_1 = require("@swc/core");
9
9
  const socket_server_js_1 = require("./socket-server.js");
10
- const step_copy_utils_js_1 = require("./step-copy-utils.js");
11
10
  // Cache decorator options per working directory to avoid reading tsconfig for every file
12
11
  const decoratorOptionsCache = new Map();
13
12
  // Cache for shared utilities from @workflow/builders (ESM module loaded dynamically in CommonJS context)
14
13
  let cachedBuildersModule = null;
15
14
  let cachedLoaderStaticDependencies = null;
15
+ const discoveredPatternStateByFilePath = new Map();
16
16
  // Cache socket connection to avoid reconnecting on every file.
17
17
  let socketClientPromise = null;
18
18
  let socketClient = null;
19
19
  let socketClientKey = null;
20
+ /**
21
+ * Wrap a TCP connect failure with context about where the connection was
22
+ * attempted, where the credentials came from, and which source file was
23
+ * being processed when it failed. ECONNREFUSED is the common case here, and
24
+ * the message points the user at the most likely root cause (stale
25
+ * socket-info file).
26
+ */
27
+ function annotateConnectionError(originalError, credentials) {
28
+ const errorCode = originalError instanceof Error &&
29
+ 'code' in originalError &&
30
+ typeof originalError.code === 'string'
31
+ ? originalError.code
32
+ : undefined;
33
+ const errorMessage = originalError instanceof Error
34
+ ? originalError.message
35
+ : String(originalError);
36
+ const lines = [
37
+ `Workflow discovery socket connect failed: ${errorCode ?? errorMessage} (127.0.0.1:${credentials.port})`,
38
+ ];
39
+ const annotated = new Error(lines.join('\n'));
40
+ if (originalError instanceof Error) {
41
+ annotated.cause = originalError;
42
+ }
43
+ return annotated;
44
+ }
45
+ const ROUTE_STUB_FILE_MARKER = 'WORKFLOW_ROUTE_STUB_FILE';
46
+ const ROUTE_STUB_BUILD_WAIT_TIMEOUT_MS = 120_000;
47
+ let pendingDeferredRouteStubBuildPromise = null;
20
48
  function registerFileDependency(loaderContext, dependencyPath) {
21
49
  loaderContext.addDependency?.(dependencyPath);
22
50
  loaderContext.addBuildDependency?.(dependencyPath);
23
51
  }
52
+ function updateDiscoveredPatternState(filePath, nextState) {
53
+ const previousState = discoveredPatternStateByFilePath.get(filePath);
54
+ const hasAnyPattern = nextState.hasWorkflow || nextState.hasStep || nextState.hasSerde;
55
+ if (!hasAnyPattern) {
56
+ if (!previousState) {
57
+ return { shouldNotify: false };
58
+ }
59
+ discoveredPatternStateByFilePath.delete(filePath);
60
+ return { shouldNotify: true, previousState };
61
+ }
62
+ if (previousState &&
63
+ previousState.hasWorkflow === nextState.hasWorkflow &&
64
+ previousState.hasStep === nextState.hasStep &&
65
+ previousState.hasSerde === nextState.hasSerde) {
66
+ return { shouldNotify: false, previousState };
67
+ }
68
+ discoveredPatternStateByFilePath.set(filePath, nextState);
69
+ return { shouldNotify: true, previousState };
70
+ }
24
71
  function addIfExists(files, dependencyPath) {
25
72
  if ((0, node_fs_1.existsSync)(dependencyPath)) {
26
73
  files.add(dependencyPath);
@@ -40,7 +87,6 @@ function resolveLoaderStaticDependencies() {
40
87
  const files = new Set([
41
88
  __filename,
42
89
  require.resolve('./socket-server'),
43
- require.resolve('./step-copy-utils'),
44
90
  swcPluginPath,
45
91
  swcPluginBuildHashPath,
46
92
  workflowBuildersPath,
@@ -81,10 +127,21 @@ async function writeSocketMessage(socket, message) {
81
127
  }
82
128
  function getSocketInfoFilePath() {
83
129
  const configuredPath = process.env.WORKFLOW_SOCKET_INFO_PATH;
84
- if (!configuredPath) {
85
- return null;
130
+ if (configuredPath) {
131
+ return configuredPath;
132
+ }
133
+ // Fallback for worker processes that don't inherit dynamic env updates
134
+ // from the process that created the socket server.
135
+ const distDir = process.env.WORKFLOW_NEXT_DIST_DIR || '.next';
136
+ const cwdFallbackPath = (0, node_path_1.join)(process.cwd(), distDir, socket_server_js_1.SOCKET_INFO_FILENAME);
137
+ const projectRoot = process.env.WORKFLOW_PROJECT_ROOT;
138
+ if (projectRoot) {
139
+ const projectRootFallbackPath = (0, node_path_1.join)(projectRoot, distDir, socket_server_js_1.SOCKET_INFO_FILENAME);
140
+ if ((0, node_fs_1.existsSync)(projectRootFallbackPath)) {
141
+ return projectRootFallbackPath;
142
+ }
86
143
  }
87
- return configuredPath;
144
+ return cwdFallbackPath;
88
145
  }
89
146
  function getSocketCredentialsFromEnv() {
90
147
  const socketPort = process.env.WORKFLOW_SOCKET_PORT;
@@ -126,7 +183,11 @@ async function getSocketCredentialsFromFile() {
126
183
  }
127
184
  }
128
185
  async function getSocketCredentials() {
129
- return (getSocketCredentialsFromEnv() ?? (await getSocketCredentialsFromFile()));
186
+ const envCredentials = getSocketCredentialsFromEnv();
187
+ if (envCredentials) {
188
+ return envCredentials;
189
+ }
190
+ return await getSocketCredentialsFromFile();
130
191
  }
131
192
  async function getSocketClient() {
132
193
  const socketCredentials = await getSocketCredentials();
@@ -161,12 +222,12 @@ async function getSocketClient() {
161
222
  };
162
223
  const onError = (error) => {
163
224
  cleanup();
164
- reject(error);
225
+ reject(annotateConnectionError(error, socketCredentials));
165
226
  };
166
227
  const timeout = setTimeout(() => {
167
228
  cleanup();
168
229
  socket.destroy();
169
- reject(new Error('Socket connection timeout'));
230
+ reject(annotateConnectionError(new Error('Socket connection timeout'), socketCredentials));
170
231
  }, 1000);
171
232
  const cleanup = () => {
172
233
  clearTimeout(timeout);
@@ -223,6 +284,108 @@ async function notifySocketServer(filename, hasWorkflow, hasStep, hasSerde) {
223
284
  await writeSocketMessage(reconnectedSocket, serializedMessage);
224
285
  }
225
286
  }
287
+ function isWorkflowRouteStubSource(source) {
288
+ return source.includes(ROUTE_STUB_FILE_MARKER);
289
+ }
290
+ async function createSocketConnection(socketCredentials, timeoutMs = 1_000) {
291
+ return await new Promise((resolve, reject) => {
292
+ const socket = (0, node_net_1.connect)({
293
+ port: socketCredentials.port,
294
+ host: '127.0.0.1',
295
+ });
296
+ const timeout = setTimeout(() => {
297
+ cleanup();
298
+ socket.destroy();
299
+ reject(annotateConnectionError(new Error('Socket connection timeout'), socketCredentials));
300
+ }, timeoutMs);
301
+ const cleanup = () => {
302
+ clearTimeout(timeout);
303
+ socket.off('connect', onConnect);
304
+ socket.off('error', onError);
305
+ };
306
+ const onConnect = () => {
307
+ socket.setNoDelay(true);
308
+ cleanup();
309
+ resolve(socket);
310
+ };
311
+ const onError = (error) => {
312
+ cleanup();
313
+ socket.destroy();
314
+ reject(annotateConnectionError(error, socketCredentials));
315
+ };
316
+ socket.on('connect', onConnect);
317
+ socket.on('error', onError);
318
+ });
319
+ }
320
+ async function waitForDeferredBuildComplete(socket, authToken, timeoutMs = ROUTE_STUB_BUILD_WAIT_TIMEOUT_MS) {
321
+ await new Promise((resolve, reject) => {
322
+ let buffer = '';
323
+ const timeout = setTimeout(() => {
324
+ cleanup();
325
+ reject(new Error('Timed out waiting for deferred route build completion'));
326
+ }, timeoutMs);
327
+ const cleanup = () => {
328
+ clearTimeout(timeout);
329
+ socket.off('data', onData);
330
+ socket.off('error', onError);
331
+ socket.off('close', onClose);
332
+ socket.off('end', onClose);
333
+ };
334
+ const onError = (error) => {
335
+ cleanup();
336
+ reject(error);
337
+ };
338
+ const onClose = () => {
339
+ cleanup();
340
+ reject(new Error('Socket closed before deferred route build completed'));
341
+ };
342
+ const onData = (chunk) => {
343
+ buffer += chunk.toString();
344
+ let newlineIndex = buffer.indexOf('\n');
345
+ while (newlineIndex !== -1) {
346
+ const line = buffer.slice(0, newlineIndex);
347
+ buffer = buffer.slice(newlineIndex + 1);
348
+ newlineIndex = buffer.indexOf('\n');
349
+ const message = (0, socket_server_js_1.parseMessage)(line, authToken);
350
+ if (message?.type === 'build-complete') {
351
+ cleanup();
352
+ resolve();
353
+ return;
354
+ }
355
+ }
356
+ };
357
+ socket.on('data', onData);
358
+ socket.on('error', onError);
359
+ socket.on('close', onClose);
360
+ socket.on('end', onClose);
361
+ });
362
+ }
363
+ async function triggerDeferredRouteStubBuildAndWait() {
364
+ const socketCredentials = await getSocketCredentials();
365
+ if (!socketCredentials) {
366
+ return;
367
+ }
368
+ const socket = await createSocketConnection(socketCredentials);
369
+ try {
370
+ await writeSocketMessage(socket, (0, socket_server_js_1.serializeMessage)({ type: 'trigger-build' }, socketCredentials.authToken));
371
+ await waitForDeferredBuildComplete(socket, socketCredentials.authToken);
372
+ }
373
+ finally {
374
+ socket.destroy();
375
+ }
376
+ }
377
+ async function ensureDeferredRouteStubBuildAndWait() {
378
+ if (pendingDeferredRouteStubBuildPromise) {
379
+ return pendingDeferredRouteStubBuildPromise;
380
+ }
381
+ const pendingPromise = triggerDeferredRouteStubBuildAndWait();
382
+ pendingDeferredRouteStubBuildPromise = pendingPromise.finally(() => {
383
+ if (pendingDeferredRouteStubBuildPromise === pendingPromise) {
384
+ pendingDeferredRouteStubBuildPromise = null;
385
+ }
386
+ });
387
+ return pendingDeferredRouteStubBuildPromise;
388
+ }
226
389
  async function getBuildersModule() {
227
390
  if (cachedBuildersModule) {
228
391
  return cachedBuildersModule;
@@ -252,10 +415,6 @@ async function checkGeneratedFile(filePath) {
252
415
  const { isGeneratedWorkflowFile } = await getBuildersModule();
253
416
  return isGeneratedWorkflowFile(filePath);
254
417
  }
255
- async function checkSdkFile(filePath) {
256
- const { isWorkflowSdkFile } = await getBuildersModule();
257
- return isWorkflowSdkFile(filePath);
258
- }
259
418
  async function checkShouldTransform(filePath, patterns) {
260
419
  const { shouldTransformFile } = await getBuildersModule();
261
420
  return shouldTransformFile(filePath, patterns);
@@ -308,10 +467,6 @@ async function getRelativeFilenameForSwc(filename, workingDir) {
308
467
  }
309
468
  return relativeFilename;
310
469
  }
311
- function stripDeferredStepSourceMetadataComment(source) {
312
- const metadataPattern = new RegExp(`^\\s*//\\s*${step_copy_utils_js_1.DEFERRED_STEP_SOURCE_METADATA_PREFIX}[A-Za-z0-9+/=]+\\s*\\r?\\n?`);
313
- return source.replace(metadataPattern, '');
314
- }
315
470
  function workflowLoader(source, sourceMap) {
316
471
  const callback = this.async?.();
317
472
  const run = async () => {
@@ -319,53 +474,43 @@ function workflowLoader(source, sourceMap) {
319
474
  const normalizedSource = source.toString();
320
475
  const workingDir = process.cwd();
321
476
  const swcPluginPath = registerTransformDependencies(this);
322
- const isDeferredStepCopyFile = (0, step_copy_utils_js_1.isDeferredStepCopyFilePath)(filename);
323
- const deferredStepSourceMetadata = isDeferredStepCopyFile
324
- ? (0, step_copy_utils_js_1.parseDeferredStepSourceMetadata)(normalizedSource)
325
- : null;
326
- const sourceWithoutDeferredMetadata = isDeferredStepCopyFile
327
- ? stripDeferredStepSourceMetadataComment(normalizedSource)
328
- : normalizedSource;
329
- const deferredSourceMapResult = isDeferredStepCopyFile
330
- ? (0, step_copy_utils_js_1.parseInlineSourceMapComment)(sourceWithoutDeferredMetadata)
331
- : {
332
- sourceWithoutMapComment: sourceWithoutDeferredMetadata,
333
- sourceMap: null,
334
- };
335
- const sourceForTransform = deferredSourceMapResult.sourceWithoutMapComment;
336
- const discoveryFilePath = deferredStepSourceMetadata?.absolutePath || filename;
337
- if (deferredStepSourceMetadata?.absolutePath) {
338
- // Ensure edits to the original source invalidate deferred step copies.
339
- registerFileDependency(this, deferredStepSourceMetadata.absolutePath);
340
- }
341
- // Skip generated workflow route files to avoid re-processing them
342
- if ((await checkGeneratedFile(filename)) && !isDeferredStepCopyFile) {
477
+ const sourceForTransform = normalizedSource;
478
+ const isGeneratedWorkflowFile = await checkGeneratedFile(filename);
479
+ // Skip generated workflow route files to avoid re-processing them.
480
+ // Deferred route stubs are a special case: wait for the generated route
481
+ // output to become available before returning.
482
+ if (isGeneratedWorkflowFile) {
483
+ if (process.env.WORKFLOW_NEXT_LAZY_DISCOVERY === '1' &&
484
+ isWorkflowRouteStubSource(normalizedSource)) {
485
+ try {
486
+ await ensureDeferredRouteStubBuildAndWait();
487
+ const refreshedSource = await (0, promises_1.readFile)(filename, 'utf8');
488
+ if (!isWorkflowRouteStubSource(refreshedSource)) {
489
+ return { code: refreshedSource, map: sourceMap };
490
+ }
491
+ }
492
+ catch (error) {
493
+ console.warn(`[workflow] Failed waiting for deferred route build for ${filename}, using stub output`, error);
494
+ }
495
+ }
343
496
  return { code: normalizedSource, map: sourceMap };
344
497
  }
345
498
  // Detect workflow patterns in the source code.
346
499
  const patterns = await detectPatterns(sourceForTransform);
347
500
  // Always notify discovery tracking, even for `false/false`, so files that
348
501
  // previously had workflow/step usage are removed from the tracked sets.
349
- // Deferred step copy files must report using their original source path so
350
- // deferred rebuilds can react to source edits outside generated artifacts.
351
- if (!isDeferredStepCopyFile || deferredStepSourceMetadata?.absolutePath) {
352
- // For @workflow SDK packages, do not report serde-only matches for
353
- // discovery, otherwise deferred mode can incorrectly treat SDK internals
354
- // as app serde entrypoints.
355
- const isSdkFile = await checkSdkFile(discoveryFilePath);
356
- await notifySocketServer(discoveryFilePath, patterns.hasUseWorkflow, patterns.hasUseStep, patterns.hasSerde && !isSdkFile);
502
+ const nextPatternState = {
503
+ hasWorkflow: patterns.hasUseWorkflow,
504
+ hasStep: patterns.hasUseStep,
505
+ hasSerde: patterns.hasSerde,
506
+ };
507
+ const { shouldNotify } = updateDiscoveredPatternState(filename, nextPatternState);
508
+ if (shouldNotify) {
509
+ await notifySocketServer(filename, nextPatternState.hasWorkflow, nextPatternState.hasStep, nextPatternState.hasSerde);
357
510
  }
358
- if (!isDeferredStepCopyFile) {
359
- // For @workflow SDK packages, only transform files with actual directives,
360
- // not files that just match serde patterns (which are internal SDK implementation files)
361
- const isSdkFile = await checkSdkFile(filename);
362
- if (isSdkFile && !patterns.hasDirective) {
363
- return { code: normalizedSource, map: sourceMap };
364
- }
365
- // Check if file needs transformation based on patterns and path
366
- if (!(await checkShouldTransform(filename, patterns))) {
367
- return { code: normalizedSource, map: sourceMap };
368
- }
511
+ // Check if file needs transformation based on patterns and path
512
+ if (!(await checkShouldTransform(filename, patterns))) {
513
+ return { code: normalizedSource, map: sourceMap };
369
514
  }
370
515
  const isTypeScript = filename.endsWith('.ts') ||
371
516
  filename.endsWith('.tsx') ||
@@ -373,16 +518,15 @@ function workflowLoader(source, sourceMap) {
373
518
  filename.endsWith('.cts');
374
519
  // Calculate relative filename for SWC plugin
375
520
  // The SWC plugin uses filename to generate workflowId, so it must be relative
376
- const relativeFilename = deferredStepSourceMetadata?.relativeFilename ||
377
- (await getRelativeFilenameForSwc(filename, workingDir));
521
+ const relativeFilename = await getRelativeFilenameForSwc(filename, workingDir);
378
522
  // Get decorator options from tsconfig (cached per working directory)
379
523
  const { options: decoratorOptions, configPath } = await getDecoratorOptions(workingDir);
380
524
  if (configPath) {
381
525
  registerFileDependency(this, configPath);
382
526
  }
383
527
  // Resolve module specifier for packages (node_modules or workspace packages)
384
- const moduleSpecifier = await getModuleSpecifier(deferredStepSourceMetadata?.absolutePath || filename, workingDir);
385
- const mode = isDeferredStepCopyFile ? 'step' : 'client';
528
+ const moduleSpecifier = await getModuleSpecifier(filename, workingDir);
529
+ const mode = 'step';
386
530
  // Transform with SWC
387
531
  const result = await (0, core_1.transform)(sourceForTransform, {
388
532
  filename: relativeFilename,
@@ -413,9 +557,7 @@ function workflowLoader(source, sourceMap) {
413
557
  },
414
558
  },
415
559
  minify: false,
416
- inputSourceMap: isDeferredStepCopyFile
417
- ? deferredSourceMapResult.sourceMap || sourceMap
418
- : sourceMap,
560
+ inputSourceMap: sourceMap,
419
561
  sourceMaps: true,
420
562
  inlineSourcesContent: true,
421
563
  });
@@ -442,4 +584,4 @@ function workflowLoader(source, sourceMap) {
442
584
  callback(error instanceof Error ? error : new Error(String(error)));
443
585
  });
444
586
  }
445
- //# sourceMappingURL=loader.js.map
587
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQStvQkEsaUNBbUpDO0FBbHlCRCxxQ0FBcUM7QUFDckMsK0NBQTRDO0FBQzVDLHVDQUFnRDtBQUNoRCx5Q0FBb0Q7QUFDcEQsb0NBQXNDO0FBQ3RDLHlEQUs0QjtBQU01Qix5RkFBeUY7QUFDekYsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFHbEMsQ0FBQztBQUNKLHlHQUF5RztBQUN6RyxJQUFJLG9CQUFvQixHQUErQyxJQUFJLENBQUM7QUFLNUUsSUFBSSw4QkFBOEIsR0FBb0MsSUFBSSxDQUFDO0FBTzNFLE1BQU0sZ0NBQWdDLEdBQUcsSUFBSSxHQUFHLEVBRzdDLENBQUM7QUFFSiwrREFBK0Q7QUFDL0QsSUFBSSxtQkFBbUIsR0FBa0MsSUFBSSxDQUFDO0FBQzlELElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7QUFDdkMsSUFBSSxlQUFlLEdBQWtCLElBQUksQ0FBQztBQU8xQzs7Ozs7O0dBTUc7QUFDSCxTQUFTLHVCQUF1QixDQUM5QixhQUFzQixFQUN0QixXQUE4QjtJQUU5QixNQUFNLFNBQVMsR0FDYixhQUFhLFlBQVksS0FBSztRQUM5QixNQUFNLElBQUksYUFBYTtRQUN2QixPQUFRLGFBQW9DLENBQUMsSUFBSSxLQUFLLFFBQVE7UUFDNUQsQ0FBQyxDQUFHLGFBQWtDLENBQUMsSUFBZTtRQUN0RCxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLE1BQU0sWUFBWSxHQUNoQixhQUFhLFlBQVksS0FBSztRQUM1QixDQUFDLENBQUMsYUFBYSxDQUFDLE9BQU87UUFDdkIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUU1QixNQUFNLEtBQUssR0FBRztRQUNaLDZDQUE2QyxTQUFTLElBQUksWUFBWSxlQUFlLFdBQVcsQ0FBQyxJQUFJLEdBQUc7S0FDekcsQ0FBQztJQUVGLE1BQU0s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N0MsQ0FBQztJQUVELEtBQUssR0FBRyxFQUFFO1NBQ1AsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3pELEtBQUssQ0FBQyxDQUFDLEtBQWMsRUFBRSxFQUFFO1FBQ3hCLFFBQVEsQ0FBQyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IGNvbm5lY3QsIHR5cGUgU29ja2V0IH0gZnJvbSAnbm9kZTpuZXQnO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiwgcmVsYXRpdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgdHJhbnNmb3JtIH0gZnJvbSAnQHN3Yy9jb3JlJztcbmltcG9ydCB7XG4gIHBhcnNlTWVzc2FnZSxcbiAgU09DS0VUX0lORk9fRklMRU5BTUUsXG4gIHR5cGUgU29ja2V0TWVzc2FnZSxcbiAgc2VyaWFsaXplTWVzc2FnZSxcbn0gZnJvbSAnLi9zb2NrZXQtc2VydmVyLmpzJztcblxudHlwZSBEZWNvcmF0b3JPcHRpb25zV2l0aENvbmZpZ1BhdGggPVxuICBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpLkRlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aDtcbnR5cGUgV29ya2Zsb3dQYXR0ZXJuTWF0Y2ggPSBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpLldvcmtmbG93UGF0dGVybk1hdGNoO1xuXG4vLyBDYWNoZSBkZWNvcmF0b3Igb3B0aW9ucyBwZXIgd29ya2luZyBkaXJlY3RvcnkgdG8gYXZvaWQgcmVhZGluZyB0c2NvbmZpZyBmb3IgZXZlcnkgZmlsZVxuY29uc3QgZGVjb3JhdG9yT3B0aW9uc0NhY2hlID0gbmV3IE1hcDxcbiAgc3RyaW5nLFxuICBQcm9taXNlPERlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aD5cbj4oKTtcbi8vIENhY2hlIGZvciBzaGFyZWQgdXRpbGl0aWVzIGZyb20gQHdvcmtmbG93L2J1aWxkZXJzIChFU00gbW9kdWxlIGxvYWRlZCBkeW5hbWljYWxseSBpbiBDb21tb25KUyBjb250ZXh0KVxubGV0IGNhY2hlZEJ1aWxkZXJzTW9kdWxlOiB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKSB8IG51bGwgPSBudWxsO1xudHlwZSBMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXMgPSB7XG4gIHN3Y1BsdWdpblBhdGg6IHN0cmluZztcbiAgZmlsZXM6IHN0cmluZ1tdO1xufTtcbmxldCBjYWNoZWRMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXM6IExvYWRlclN0YXRpY0RlcGVuZGVuY2llcyB8IG51bGwgPSBudWxsO1xuXG50eXBlIERpc2NvdmVyZWRQYXR0ZXJuU3RhdGUgPSB7XG4gIGhhc1dvcmtmbG93OiBib29sZWFuO1xuICBoYXNTdGVwOiBib29sZWFuO1xuICBoYXNTZXJkZTogYm9vbGVhbjtcbn07XG5jb25zdCBkaXNjb3ZlcmVkUGF0dGVyblN0YXRlQnlGaWxlUGF0aCA9IG5ldyBNYXA8XG4gIHN0cmluZyxcbiAgRGlzY292ZXJlZFBhdHRlcm5TdGF0ZVxuPigpO1xuXG4vLyBDYWNoZSBzb2NrZXQgY29ubmVjdGlvbiB0byBhdm9pZCByZWNvbm5lY3Rpbmcgb24gZXZlcnkgZmlsZS5cbmxldCBzb2NrZXRDbGllbnRQcm9taXNlOiBQcm9taXNlPFNvY2tldCB8IG51bGw+IHwgbnVsbCA9IG51bGw7XG5sZXQgc29ja2V0Q2xpZW50OiBTb2NrZXQgfCBudWxsID0gbnVsbDtcbmxldCBzb2NrZXRDbGllbnRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG50eXBlIFNvY2tldENyZWRlbnRpYWxzID0ge1xuICBwb3J0OiBudW1iZXI7XG4gIGF1dGhUb2tlbjogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBXcmFwIGEgVENQIGNvbm5lY3QgZmFpbHVyZSB3aXRoIGNvbnRleHQgYWJvdXQgd2hlcmUgdGhlIGNvbm5lY3Rpb24gd2FzXG4gKiBhdHRlbXB0ZWQsIHdoZXJlIHRoZSBjcmVkZW50aWFscyBjYW1lIGZyb20sIGFuZCB3aGljaCBzb3VyY2UgZmlsZSB3YXNcbiAqIGJlaW5nIHByb2Nlc3NlZCB3aGVuIGl0IGZhaWxlZC4gRUNPTk5SRUZVU0VEIGlzIHRoZSBjb21tb24gY2FzZSBoZXJlLCBhbmRcbiAqIHRoZSBtZXNzYWdlIHBvaW50cyB0aGUgdXNlciBhdCB0aGUgbW9zdCBsaWtlbHkgcm9vdCBjYXVzZSAoc3RhbGVcbiAqIHNvY2tldC1pbmZvIGZpbGUpLlxuICovXG5mdW5jdGlvbiBhbm5vdGF0ZUNvbm5lY3Rpb25FcnJvcihcbiAgb3JpZ2luYWxFcnJvcjogdW5rbm93bixcbiAgY3JlZGVudGlhbHM6IFNvY2tldENyZWRlbnRpYWxzXG4pOiBFcnJvciB7XG4gIGNvbnN0IGVycm9yQ29kZSA9XG4gICAgb3JpZ2luYWxFcnJvciBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgJ2NvZGUnIGluIG9yaWdpbmFsRXJyb3IgJiZcbiAgICB0eXBlb2YgKG9yaWdpbmFsRXJyb3IgYXMgeyBjb2RlPzogdW5rbm93biB9KS5jb2RlID09PSAnc3RyaW5nJ1xuICAgICAgPyAoKG9yaWdpbmFsRXJyb3IgYXMgeyBjb2RlOiBzdHJpbmcgfSkuY29kZSBhcyBzdHJpbmcpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgY29uc3QgZXJyb3JNZXNzYWdlID1cbiAgICBvcmlnaW5hbEVycm9yIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgID8gb3JpZ2luYWxFcnJvci5tZXNzYWdlXG4gICAgICA6IFN0cmluZyhvcmlnaW5hbEVycm9yKTtcblxuICBjb25zdCBsaW5lcyA9IFtcbiAgICBgV29ya2Zsb3cgZGlzY292ZXJ5IHNvY2tldCBjb25uZWN0IGZhaWxlZDogJHtlcnJvckNvZGUgPz8gZXJyb3JNZXNzYWdlfSAoMTI3LjAuMC4xOiR7Y3JlZGVudGlhbHMucG9ydH0pYCxcbiAgXTtcblxuICBjb25zdCBhbm5vdGF0ZWQgPSBuZXcgRXJyb3IobGluZXMuam9pbignXFxuJykpO1xuICBpZiAob3JpZ2luYWxFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgKGFubm90YXRlZCBhcyB7IGNhdXNlPzogdW5rbm93biB9KS5jYXVzZSA9IG9yaWdpbmFsRXJyb3I7XG4gIH1cbiAgcmV0dXJuIGFubm90YXRlZDtcbn1cblxuY29uc3QgUk9VVEVfU1RVQl9GSUxFX01BUktFUiA9ICdXT1JLRkxPV19ST1VURV9TVFVCX0ZJTEUnO1xuY29uc3QgUk9VVEVfU1RVQl9CVUlMRF9XQUlUX1RJTUVPVVRfTVMgPSAxMjBfMDAwO1xubGV0IHBlbmRpbmdEZWZlcnJlZFJvdXRlU3R1YkJ1aWxkUHJvbWlzZTogUHJvbWlzZTx2b2lkPiB8IG51bGwgPSBudWxsO1xuXG5mdW5jdGlvbiByZWdpc3RlckZpbGVEZXBlbmRlbmN5KFxuICBsb2FkZXJDb250ZXh0OiBXb3JrZmxvd0xvYWRlckNvbnRleHQsXG4gIGRlcGVuZGVuY3lQYXRoOiBzdHJpbmdcbik6IHZvaWQge1xuICBsb2FkZXJDb250ZXh0LmFkZERlcGVuZGVuY3k/LihkZXBlbmRlbmN5UGF0aCk7XG4gIGxvYWRlckNvbnRleHQuYWRkQnVpbGREZXBlbmRlbmN5Py4oZGVwZW5kZW5jeVBhdGgpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVEaXNjb3ZlcmVkUGF0dGVyblN0YXRlKFxuICBmaWxlUGF0aDogc3RyaW5nLFxuICBuZXh0U3RhdGU6IERpc2NvdmVyZWRQYXR0ZXJuU3RhdGVcbik6IHsgc2hvdWxkTm90aWZ5OiBib29sZWFuOyBwcmV2aW91c1N0YXRlPzogRGlzY292ZXJlZFBhdHRlcm5TdGF0ZSB9IHtcbiAgY29uc3QgcHJldmlvdXNTdGF0ZSA9IGRpc2NvdmVyZWRQYXR0ZXJuU3RhdGVCeUZpbGVQYXRoLmdldChmaWxlUGF0aCk7XG4gIGNvbnN0IGhhc0FueVBhdHRlcm4gPVxuICAgIG5leHRTdGF0ZS5oYXNXb3JrZmxvdyB8fCBuZXh0U3RhdGUuaGFzU3RlcCB8fCBuZXh0U3RhdGUuaGFzU2VyZGU7XG5cbiAgaWYgKCFoYXNBbnlQYXR0ZXJuKSB7XG4gICAgaWYgKCFwcmV2aW91c1N0YXRlKSB7XG4gICAgICByZXR1cm4geyBzaG91bGROb3RpZnk6IGZhbHNlIH07XG4gICAgfVxuICAgIGRpc2NvdmVyZWRQYXR0ZXJuU3RhdGVCeUZpbGVQYXRoLmRlbGV0ZShmaWxlUGF0aCk7XG4gICAgcmV0dXJuIHsgc2hvdWxkTm90aWZ5OiB0cnVlLCBwcmV2aW91c1N0YXRlIH07XG4gIH1cblxuICBpZiAoXG4gICAgcHJldmlvdXNTdGF0ZSAmJlxuICAgIHByZXZpb3VzU3RhdGUuaGFzV29ya2Zsb3cgPT09IG5leHRTdGF0ZS5oYXNXb3JrZmxvdyAmJlxuICAgIHByZXZpb3VzU3RhdGUuaGFzU3RlcCA9PT0gbmV4dFN0YXRlLmhhc1N0ZXAgJiZcbiAgICBwcmV2aW91c1N0YXRlLmhhc1NlcmRlID09PSBuZXh0U3RhdGUuaGFzU2VyZGVcbiAgKSB7XG4gICAgcmV0dXJuIHsgc2hvdWxkTm90aWZ5OiBmYWxzZSwgcHJldmlvdXNTdGF0ZSB9O1xuICB9XG5cbiAgZGlzY292ZXJlZFBhdHRlcm5TdGF0ZUJ5RmlsZVBhdGguc2V0KGZpbGVQYXRoLCBuZXh0U3RhdGUpO1xuICByZXR1cm4geyBzaG91bGROb3RpZnk6IHRydWUsIHByZXZpb3VzU3RhdGUgfTtcbn1cblxuZnVuY3Rpb24gYWRkSWZFeGlzdHMoZmlsZXM6IFNldDxzdHJpbmc+LCBkZXBlbmRlbmN5UGF0aDogc3RyaW5nKTogdm9pZCB7XG4gIGlmIChleGlzdHNTeW5jKGRlcGVuZGVuY3lQYXRoKSkge1xuICAgIGZpbGVzLmFkZChkZXBlbmRlbmN5UGF0aCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUxvYWRlclN0YXRpY0RlcGVuZGVuY2llcygpOiBMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXMge1xuICBpZiAoY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzKSB7XG4gICAgcmV0dXJuIGNhY2hlZExvYWRlclN0YXRpY0RlcGVuZGVuY2llcztcbiAgfVxuXG4gIGNvbnN0IHN3Y1BsdWdpblBhdGggPSByZXF1aXJlLnJlc29sdmUoJ0B3b3JrZmxvdy9zd2MtcGx1Z2luJyk7XG4gIGNvbnN0IHN3Y1BsdWdpbkJ1aWxkSGFzaFBhdGggPSByZXF1aXJlLnJlc29sdmUoXG4gICAgJ0B3b3JrZmxvdy9zd2MtcGx1Z2luL2J1aWxkLWhhc2guanNvbidcbiAgKTtcbiAgY29uc3Qgd29ya2Zsb3dCdWlsZGVyc1BhdGggPSByZXF1aXJlLnJlc29sdmUoJ0B3b3JrZmxvdy9idWlsZGVycycpO1xuXG4gIC8vIERlcml2ZSBwYWNrYWdlLmpzb24gcGF0aHMgZnJvbSByZXNvbHZlZCBlbnRyeXBvaW50cyB0byBhdm9pZFxuICAvLyBUdXJib3BhY2sgbG9hZGVyLWV2YWwgZmFpbHVyZXMgYXJvdW5kIC4uL3BhY2thZ2UuanNvbiByZXNvbHV0aW9uLlxuICBjb25zdCBzd2NQbHVnaW5QYWNrYWdlSnNvblBhdGggPSBqb2luKGRpcm5hbWUoc3djUGx1Z2luUGF0aCksICdwYWNrYWdlLmpzb24nKTtcbiAgY29uc3Qgd29ya2Zsb3dCdWlsZGVyc1BhY2thZ2VKc29uUGF0aCA9IGpvaW4oXG4gICAgZGlybmFtZSh3b3JrZmxvd0J1aWxkZXJzUGF0aCksXG4gICAgJy4uL3BhY2thZ2UuanNvbidcbiAgKTtcblxuICBjb25zdCBmaWxlcyA9IG5ldyBTZXQ8c3RyaW5nPihbXG4gICAgX19maWxlbmFtZSxcbiAgICByZXF1aXJlLnJlc29sdmUoJy4vc29ja2V0LXNlcnZlcicpLFxuICAgIHN3Y1BsdWdpblBhdGgsXG4gICAgc3djUGx1Z2luQnVpbGRIYXNoUGF0aCxcbiAgICB3b3JrZmxvd0J1aWxkZXJzUGF0aCxcbiAgXSk7XG4gIGFkZElmRXhpc3RzKGZpbGVzLCBzd2NQbHVnaW5QYWNrYWdlSnNvblBhdGgpO1xuICBhZGRJZkV4aXN0cyhmaWxlcywgd29ya2Zsb3dCdWlsZGVyc1BhY2thZ2VKc29uUGF0aCk7XG5cbiAgY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzID0ge1xuICAgIHN3Y1BsdWdpblBhdGgsXG4gICAgZmlsZXM6IEFycmF5LmZyb20oZmlsZXMpLFxuICB9O1xuICByZXR1cm4gY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzO1xufVxuXG5mdW5jdGlvbiByZWdpc3RlclRyYW5zZm9ybURlcGVuZGVuY2llcyhcbiAgbG9hZGVyQ29udGV4dDogV29ya2Zsb3dMb2FkZXJDb250ZXh0XG4pOiBzdHJpbmcge1xuICBjb25zdCBzdGF0aWNEZXBlbmRlbmNpZXMgPSByZXNvbHZlTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzKCk7XG4gIGZvciAoY29uc3QgZGVwZW5kZW5jeVBhdGggb2Ygc3RhdGljRGVwZW5kZW5jaWVzLmZpbGVzKSB7XG4gICAgcmVnaXN0ZXJGaWxlRGVwZW5kZW5jeShsb2FkZXJDb250ZXh0LCBkZXBlbmRlbmN5UGF0aCk7XG4gIH1cblxuICByZXR1cm4gc3RhdGljRGVwZW5kZW5jaWVzLnN3Y1BsdWdpblBhdGg7XG59XG5cbmZ1bmN0aW9uIHJlc2V0U29ja2V0Q2xpZW50KGNhY2hlZFNvY2tldD86IFNvY2tldCk6IHZvaWQge1xuICBpZiAoY2FjaGVkU29ja2V0ICYmIHNvY2tldENsaWVudCAmJiBzb2NrZXRDbGllbnQgIT09IGNhY2hlZFNvY2tldCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHNvY2tldENsaWVudFByb21pc2UgPSBudWxsO1xuICBzb2NrZXRDbGllbnQgPSBudWxsO1xuICBzb2NrZXRDbGllbnRLZXkgPSBudWxsO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3cml0ZVNvY2tldE1lc3NhZ2UoXG4gIHNvY2tldDogU29ja2V0LFxuICBtZXNzYWdlOiBzdHJpbmdcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgc29ja2V0LndyaXRlKG1lc3NhZ2UsIChlcnJvcj86IEVycm9yIHwgbnVsbCkgPT4ge1xuICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFNvY2tldEluZm9GaWxlUGF0aCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgY29uZmlndXJlZFBhdGggPSBwcm9jZXNzLmVudi5XT1JLRkxPV19TT0NLRVRfSU5GT19QQVRIO1xuICBpZiAoY29uZmlndXJlZFBhdGgpIHtcbiAgICByZXR1cm4gY29uZmlndXJlZFBhdGg7XG4gIH1cblxuICAvLyBGYWxsYmFjayBmb3Igd29ya2VyIHByb2Nlc3NlcyB0aGF0IGRvbid0IGluaGVyaXQgZHluYW1pYyBlbnYgdXBkYXRlc1xuICAvLyBmcm9tIHRoZSBwcm9jZXNzIHRoYXQgY3JlYXRlZCB0aGUgc29ja2V0IHNlcnZlci5cbiAgY29uc3QgZGlzdERpciA9IHByb2Nlc3MuZW52LldPUktGTE9XX05FWFRfRElTVF9ESVIgfHwgJy5uZXh0JztcbiAgY29uc3QgY3dkRmFsbGJhY2tQYXRoID0gam9pbihwcm9jZXNzLmN3ZCgpLCBkaXN0RGlyLCBTT0NLRVRfSU5GT19GSUxFTkFNRSk7XG4gIGNvbnN0IHByb2plY3RSb290ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUFJPSkVDVF9ST09UO1xuICBpZiAocHJvamVjdFJvb3QpIHtcbiAgICBjb25zdCBwcm9qZWN0Um9vdEZhbGxiYWNrUGF0aCA9IGpvaW4oXG4gICAgICBwcm9qZWN0Um9vdCxcbiAgICAgIGRpc3REaXIsXG4gICAgICBTT0NLRVRfSU5GT19GSUxFTkFNRVxuICAgICk7XG4gICAgaWYgKGV4aXN0c1N5bmMocHJvamVjdFJvb3RGYWxsYmFja1BhdGgpKSB7XG4gICAgICByZXR1cm4gcHJvamVjdFJvb3RGYWxsYmFja1BhdGg7XG4gICAgfVxuICB9XG4gIHJldHVybiBjd2RGYWxsYmFja1BhdGg7XG59XG5cbmZ1bmN0aW9uIGdldFNvY2tldENyZWRlbnRpYWxzRnJvbUVudigpOiBTb2NrZXRDcmVkZW50aWFscyB8IG51bGwge1xuICBjb25zdCBzb2NrZXRQb3J0ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfU09DS0VUX1BPUlQ7XG4gIGNvbnN0IGF1dGhUb2tlbiA9IHByb2Nlc3MuZW52LldPUktGTE9XX1NPQ0tFVF9BVVRIO1xuICBpZiAoIXNvY2tldFBvcnQgfHwgIWF1dGhUb2tlbikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgcG9ydCA9IE51bWJlci5wYXJzZUludChzb2NrZXRQb3J0LCAxMCk7XG4gIGlmIChOdW1iZXIuaXNOYU4ocG9ydCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4geyBwb3J0LCBhdXRoVG9rZW4gfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0U29ja2V0Q3JlZGVudGlhbHNGcm9tRmlsZSgpOiBQcm9taXNlPFNvY2tldENyZWRlbnRpYWxzIHwgbnVsbD4ge1xuICBjb25zdCBzb2NrZXRJbmZvRmlsZVBhdGggPSBnZXRTb2NrZXRJbmZvRmlsZVBhdGgoKTtcbiAgaWYgKCFzb2NrZXRJbmZvRmlsZVBhdGgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoIWV4aXN0c1N5bmMoc29ja2V0SW5mb0ZpbGVQYXRoKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCByYXcgPSBhd2FpdCByZWFkRmlsZShzb2NrZXRJbmZvRmlsZVBhdGgsICd1dGY4Jyk7XG4gICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShyYXcpIGFzIHtcbiAgICAgIHBvcnQ/OiB1bmtub3duO1xuICAgICAgYXV0aFRva2VuPzogdW5rbm93bjtcbiAgICB9O1xuICAgIGNvbnN0IGF1dGhUb2tlbiA9XG4gICAgICB0eXBlb2YgcGFyc2VkLmF1dGhUb2tlbiA9PT0gJ3N0cmluZycgPyBwYXJzZWQuYXV0aFRva2VuIDogbnVsbDtcbiAgICBjb25zdCBudW1lcmljUG9ydCA9XG4gICAgICB0eXBlb2YgcGFyc2VkLnBvcnQgPT09ICdudW1iZXInXG4gICAgICAgID8gcGFyc2VkLnBvcnRcbiAgICAgICAgOiBOdW1iZXIucGFyc2VJbnQoU3RyaW5nKHBhcnNlZC5wb3J0KSwgMTApO1xuXG4gICAgaWYgKCFhdXRoVG9rZW4gfHwgTnVtYmVyLmlzTmFOKG51bWVyaWNQb3J0KSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwb3J0OiBudW1lcmljUG9ydCxcbiAgICAgIGF1dGhUb2tlbixcbiAgICB9O1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRTb2NrZXRDcmVkZW50aWFscygpOiBQcm9taXNlPFNvY2tldENyZWRlbnRpYWxzIHwgbnVsbD4ge1xuICBjb25zdCBlbnZDcmVkZW50aWFscyA9IGdldFNvY2tldENyZWRlbnRpYWxzRnJvbUVudigpO1xuICBpZiAoZW52Q3JlZGVudGlhbHMpIHtcbiAgICByZXR1cm4gZW52Q3JlZGVudGlhbHM7XG4gIH1cbiAgcmV0dXJuIGF3YWl0IGdldFNvY2tldENyZWRlbnRpYWxzRnJvbUZpbGUoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0U29ja2V0Q2xpZW50KCk6IFByb21pc2U8U29ja2V0IHwgbnVsbD4ge1xuICBjb25zdCBzb2NrZXRDcmVkZW50aWFscyA9IGF3YWl0IGdldFNvY2tldENyZWRlbnRpYWxzKCk7XG4gIGlmICghc29ja2V0Q3JlZGVudGlhbHMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChzb2NrZXRDbGllbnQ/LmRlc3Ryb3llZCkge1xuICAgIHJlc2V0U29ja2V0Q2xpZW50KHNvY2tldENsaWVudCk7XG4gIH1cblxuICBjb25zdCBjdXJyZW50U29ja2V0S2V5ID0gYCR7c29ja2V0Q3JlZGVudGlhbHMucG9ydH06JHtzb2NrZXRDcmVkZW50aWFscy5hdXRoVG9rZW59YDtcbiAgaWYgKHNvY2tldENsaWVudEtleSAmJiBzb2NrZXRDbGllbnRLZXkgIT09IGN1cnJlbnRTb2NrZXRLZXkpIHtcbiAgICBpZiAoc29ja2V0Q2xpZW50KSB7XG4gICAgICByZXNldFNvY2tldENsaWVudChzb2NrZXRDbGllbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNldFNvY2tldENsaWVudCgpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghc29ja2V0Q2xpZW50UHJvbWlzZSkge1xuICAgIHNvY2tldENsaWVudFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3Qgc29ja2V0ID0gY29ubmVjdCh7XG4gICAgICAgICAgcG9ydDogc29ja2V0Q3JlZGVudGlhbHMucG9ydCxcbiAgICAgICAgICBob3N0OiAnMTI3LjAuMC4xJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgY29ubmVjdGlvblxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgY29uc3Qgb25Db25uZWN0ID0gKCkgPT4ge1xuICAgICAgICAgICAgc29ja2V0LnNldE5vRGVsYXkodHJ1ZSk7XG4gICAgICAgICAgICBjbGVhbnVwKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICAgICAgcmVqZWN0KGFubm90YXRlQ29ubmVjdGlvbkVycm9yKGVycm9yLCBzb2NrZXRDcmVkZW50aWFscykpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHJlamVjdChcbiAgICAgICAgICAgICAgYW5ub3RhdGVDb25uZWN0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgbmV3IEVycm9yKCdTb2NrZXQgY29ubmVjdGlvbiB0aW1lb3V0JyksXG4gICAgICAgICAgICAgICAgc29ja2V0Q3JlZGVudGlhbHNcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9LCAxMDAwKTtcbiAgICAgICAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgc29ja2V0Lm9mZignY29ubmVjdCcsIG9uQ29ubmVjdCk7XG4gICAgICAgICAgICBzb2NrZXQub2ZmKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBzb2NrZXQub24oJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuICAgICAgICAgIHNvY2tldC5vbignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc29ja2V0Lm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgICByZXNldFNvY2tldENsaWVudChzb2NrZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgc29ja2V0Lm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICByZXNldFNvY2tldENsaWVudChzb2NrZXQpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzb2NrZXRDbGllbnQgPSBzb2NrZXQ7XG4gICAgICAgIHNvY2tldENsaWVudEtleSA9IGN1cnJlbnRTb2NrZXRLZXk7XG4gICAgICAgIHJldHVybiBzb2NrZXQ7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXNldFNvY2tldENsaWVudCgpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9KSgpO1xuICB9XG4gIHJldHVybiBzb2NrZXRDbGllbnRQcm9taXNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBub3RpZnlTb2NrZXRTZXJ2ZXIoXG4gIGZpbGVuYW1lOiBzdHJpbmcsXG4gIGhhc1dvcmtmbG93OiBib29sZWFuLFxuICBoYXNTdGVwOiBib29sZWFuLFxuICBoYXNTZXJkZTogYm9vbGVhblxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHNvY2tldENyZWRlbnRpYWxzID0gYXdhaXQgZ2V0U29ja2V0Q3JlZGVudGlhbHMoKTtcbiAgaWYgKCFzb2NrZXRDcmVkZW50aWFscykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHNvY2tldCA9IGF3YWl0IGdldFNvY2tldENsaWVudCgpO1xuICBpZiAoIXNvY2tldCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YXJpYW50OiBtaXNzaW5nIHdvcmtmbG93IHNvY2tldCBjb25uZWN0aW9uJyk7XG4gIH1cblxuICBjb25zdCBtZXNzYWdlOiBTb2NrZXRNZXNzYWdlID0ge1xuICAgIHR5cGU6ICdmaWxlLWRpc2NvdmVyZWQnLFxuICAgIGZpbGVQYXRoOiBmaWxlbmFtZSxcbiAgICBoYXNXb3JrZmxvdyxcbiAgICBoYXNTdGVwLFxuICAgIGhhc1NlcmRlLFxuICB9O1xuICBjb25zdCBzZXJpYWxpemVkTWVzc2FnZSA9IHNlcmlhbGl6ZU1lc3NhZ2UoXG4gICAgbWVzc2FnZSxcbiAgICBzb2NrZXRDcmVkZW50aWFscy5hdXRoVG9rZW5cbiAgKTtcblxuICB0cnkge1xuICAgIGF3YWl0IHdyaXRlU29ja2V0TWVzc2FnZShzb2NrZXQsIHNlcmlhbGl6ZWRNZXNzYWdlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXNldFNvY2tldENsaWVudChzb2NrZXQpO1xuICAgIGNvbnN0IHJlY29ubmVjdGVkU29ja2V0ID0gYXdhaXQgZ2V0U29ja2V0Q2xpZW50KCk7XG4gICAgaWYgKCFyZWNvbm5lY3RlZFNvY2tldCkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIGF3YWl0IHdyaXRlU29ja2V0TWVzc2FnZShyZWNvbm5lY3RlZFNvY2tldCwgc2VyaWFsaXplZE1lc3NhZ2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzV29ya2Zsb3dSb3V0ZVN0dWJTb3VyY2Uoc291cmNlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHNvdXJjZS5pbmNsdWRlcyhST1VURV9TVFVCX0ZJTEVfTUFSS0VSKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlU29ja2V0Q29ubmVjdGlvbihcbiAgc29ja2V0Q3JlZGVudGlhbHM6IFNvY2tldENyZWRlbnRpYWxzLFxuICB0aW1lb3V0TXMgPSAxXzAwMFxuKTogUHJvbWlzZTxTb2NrZXQ+IHtcbiAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPFNvY2tldD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Qoe1xuICAgICAgcG9ydDogc29ja2V0Q3JlZGVudGlhbHMucG9ydCxcbiAgICAgIGhvc3Q6ICcxMjcuMC4wLjEnLFxuICAgIH0pO1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICByZWplY3QoXG4gICAgICAgIGFubm90YXRlQ29ubmVjdGlvbkVycm9yKFxuICAgICAgICAgIG5ldyBFcnJvcignU29ja2V0IGNvbm5lY3Rpb24gdGltZW91dCcpLFxuICAgICAgICAgIHNvY2tldENyZWRlbnRpYWxzXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSwgdGltZW91dE1zKTtcbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc29ja2V0Lm9mZignY29ubmVjdCcsIG9uQ29ubmVjdCk7XG4gICAgICBzb2NrZXQub2ZmKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgIH07XG4gICAgY29uc3Qgb25Db25uZWN0ID0gKCkgPT4ge1xuICAgICAgc29ja2V0LnNldE5vRGVsYXkodHJ1ZSk7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICByZXNvbHZlKHNvY2tldCk7XG4gICAgfTtcbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgIHJlamVjdChhbm5vdGF0ZUNvbm5lY3Rpb25FcnJvcihlcnJvciwgc29ja2V0Q3JlZGVudGlhbHMpKTtcbiAgICB9O1xuXG4gICAgc29ja2V0Lm9uKCdjb25uZWN0Jywgb25Db25uZWN0KTtcbiAgICBzb2NrZXQub24oJ2Vycm9yJywgb25FcnJvcik7XG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiB3YWl0Rm9yRGVmZXJyZWRCdWlsZENvbXBsZXRlKFxuICBzb2NrZXQ6IFNvY2tldCxcbiAgYXV0aFRva2VuOiBzdHJpbmcsXG4gIHRpbWVvdXRNcyA9IFJPVVRFX1NUVUJfQlVJTERfV0FJVF9USU1FT1VUX01TXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCBidWZmZXIgPSAnJztcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICByZWplY3QoXG4gICAgICAgIG5ldyBFcnJvcignVGltZWQgb3V0IHdhaXRpbmcgZm9yIGRlZmVycmVkIHJvdXRlIGJ1aWxkIGNvbXBsZXRpb24nKVxuICAgICAgKTtcbiAgICB9LCB0aW1lb3V0TXMpO1xuICAgIGNvbnN0IGNsZWFudXAgPSAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICBzb2NrZXQub2ZmKCdkYXRhJywgb25EYXRhKTtcbiAgICAgIHNvY2tldC5vZmYoJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICBzb2NrZXQub2ZmKCdjbG9zZScsIG9uQ2xvc2UpO1xuICAgICAgc29ja2V0Lm9mZignZW5kJywgb25DbG9zZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdTb2NrZXQgY2xvc2VkIGJlZm9yZSBkZWZlcnJlZCByb3V0ZSBidWlsZCBjb21wbGV0ZWQnKSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkRhdGEgPSAoY2h1bms6IEJ1ZmZlcikgPT4ge1xuICAgICAgYnVmZmVyICs9IGNodW5rLnRvU3RyaW5nKCk7XG4gICAgICBsZXQgbmV3bGluZUluZGV4ID0gYnVmZmVyLmluZGV4T2YoJ1xcbicpO1xuICAgICAgd2hpbGUgKG5ld2xpbmVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgY29uc3QgbGluZSA9IGJ1ZmZlci5zbGljZSgwLCBuZXdsaW5lSW5kZXgpO1xuICAgICAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UobmV3bGluZUluZGV4ICsgMSk7XG4gICAgICAgIG5ld2xpbmVJbmRleCA9IGJ1ZmZlci5pbmRleE9mKCdcXG4nKTtcblxuICAgICAgICBjb25zdCBtZXNzYWdlID0gcGFyc2VNZXNzYWdlKGxpbmUsIGF1dGhUb2tlbik7XG4gICAgICAgIGlmIChtZXNzYWdlPy50eXBlID09PSAnYnVpbGQtY29tcGxldGUnKSB7XG4gICAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgc29ja2V0Lm9uKCdkYXRhJywgb25EYXRhKTtcbiAgICBzb2NrZXQub24oJ2Vycm9yJywgb25FcnJvcik7XG4gICAgc29ja2V0Lm9uKCdjbG9zZScsIG9uQ2xvc2UpO1xuICAgIHNvY2tldC5vbignZW5kJywgb25DbG9zZSk7XG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiB0cmlnZ2VyRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZEFuZFdhaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHNvY2tldENyZWRlbnRpYWxzID0gYXdhaXQgZ2V0U29ja2V0Q3JlZGVudGlhbHMoKTtcbiAgaWYgKCFzb2NrZXRDcmVkZW50aWFscykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBzb2NrZXQgPSBhd2FpdCBjcmVhdGVTb2NrZXRDb25uZWN0aW9uKHNvY2tldENyZWRlbnRpYWxzKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCB3cml0ZVNvY2tldE1lc3NhZ2UoXG4gICAgICBzb2NrZXQsXG4gICAgICBzZXJpYWxpemVNZXNzYWdlKHsgdHlwZTogJ3RyaWdnZXItYnVpbGQnIH0sIHNvY2tldENyZWRlbnRpYWxzLmF1dGhUb2tlbilcbiAgICApO1xuICAgIGF3YWl0IHdhaXRGb3JEZWZlcnJlZEJ1aWxkQ29tcGxldGUoc29ja2V0LCBzb2NrZXRDcmVkZW50aWFscy5hdXRoVG9rZW4pO1xuICB9IGZpbmFsbHkge1xuICAgIHNvY2tldC5kZXN0cm95KCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZEFuZFdhaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2UpIHtcbiAgICByZXR1cm4gcGVuZGluZ0RlZmVycmVkUm91dGVTdHViQnVpbGRQcm9taXNlO1xuICB9XG4gIGNvbnN0IHBlbmRpbmdQcm9taXNlID0gdHJpZ2dlckRlZmVycmVkUm91dGVTdHViQnVpbGRBbmRXYWl0KCk7XG4gIHBlbmRpbmdEZWZlcnJlZFJvdXRlU3R1YkJ1aWxkUHJvbWlzZSA9IHBlbmRpbmdQcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgIGlmIChwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2UgPT09IHBlbmRpbmdQcm9taXNlKSB7XG4gICAgICBwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2UgPSBudWxsO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2U7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEJ1aWxkZXJzTW9kdWxlKCk6IFByb21pc2U8XG4gIHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpXG4+IHtcbiAgaWYgKGNhY2hlZEJ1aWxkZXJzTW9kdWxlKSB7XG4gICAgcmV0dXJuIGNhY2hlZEJ1aWxkZXJzTW9kdWxlO1xuICB9XG4gIC8vIER5bmFtaWMgaW1wb3J0IHRvIGhhbmRsZSBFU00gbW9kdWxlIGZyb20gQ29tbW9uSlMgY29udGV4dFxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9zZWN1cml0eS9ub0dsb2JhbEV2YWw6IE5lZWQgdG8gdXNlIGV2YWwgaGVyZSB0byBhdm9pZCBUeXBlU2NyaXB0IGZyb20gdHJhbnNwaWxpbmcgdGhlIGltcG9ydCBzdGF0ZW1lbnQgaW50byBgcmVxdWlyZSgpYFxuICBjYWNoZWRCdWlsZGVyc01vZHVsZSA9IChhd2FpdCBldmFsKFxuICAgICdpbXBvcnQoXCJAd29ya2Zsb3cvYnVpbGRlcnNcIiknXG4gICkpIGFzIHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpO1xuICByZXR1cm4gY2FjaGVkQnVpbGRlcnNNb2R1bGU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERlY29yYXRvck9wdGlvbnMoXG4gIHdvcmtpbmdEaXI6IHN0cmluZ1xuKTogUHJvbWlzZTxEZWNvcmF0b3JPcHRpb25zV2l0aENvbmZpZ1BhdGg+IHtcbiAgY29uc3QgY2FjaGVkID0gZGVjb3JhdG9yT3B0aW9uc0NhY2hlLmdldCh3b3JraW5nRGlyKTtcbiAgaWYgKGNhY2hlZCkge1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cblxuICBjb25zdCBwcm9taXNlID0gKGFzeW5jICgpOiBQcm9taXNlPERlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aD4gPT4ge1xuICAgIGNvbnN0IHsgZ2V0RGVjb3JhdG9yT3B0aW9uc0ZvckRpcmVjdG9yeVdpdGhDb25maWdQYXRoIH0gPVxuICAgICAgYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgICByZXR1cm4gZ2V0RGVjb3JhdG9yT3B0aW9uc0ZvckRpcmVjdG9yeVdpdGhDb25maWdQYXRoKHdvcmtpbmdEaXIpO1xuICB9KSgpO1xuXG4gIGRlY29yYXRvck9wdGlvbnNDYWNoZS5zZXQod29ya2luZ0RpciwgcHJvbWlzZSk7XG4gIHJldHVybiBwcm9taXNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZXRlY3RQYXR0ZXJucyhzb3VyY2U6IHN0cmluZyk6IFByb21pc2U8V29ya2Zsb3dQYXR0ZXJuTWF0Y2g+IHtcbiAgY29uc3QgeyBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjaGVja0dlbmVyYXRlZEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB7IGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gaXNHZW5lcmF0ZWRXb3JrZmxvd0ZpbGUoZmlsZVBhdGgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjaGVja1Nob3VsZFRyYW5zZm9ybShcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgcGF0dGVybnM6IFdvcmtmbG93UGF0dGVybk1hdGNoXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgeyBzaG91bGRUcmFuc2Zvcm1GaWxlIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gc2hvdWxkVHJhbnNmb3JtRmlsZShmaWxlUGF0aCwgcGF0dGVybnMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRNb2R1bGVTcGVjaWZpZXIoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIHByb2plY3RSb290OiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IHsgcmVzb2x2ZU1vZHVsZVNwZWNpZmllciB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIHJlc29sdmVNb2R1bGVTcGVjaWZpZXIoZmlsZVBhdGgsIHByb2plY3RSb290KS5tb2R1bGVTcGVjaWZpZXI7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3JrZmxvd0FsaWFzUGF0aChcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgd29ya2luZ0Rpcjogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB7IHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gcmVzb2x2ZVdvcmtmbG93QWxpYXNSZWxhdGl2ZVBhdGgoZmlsZVBhdGgsIHdvcmtpbmdEaXIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRSZWxhdGl2ZUZpbGVuYW1lRm9yU3djKFxuICBmaWxlbmFtZTogc3RyaW5nLFxuICB3b3JraW5nRGlyOiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRXb3JraW5nRGlyID0gd29ya2luZ0RpclxuICAgIC5yZXBsYWNlKC9cXFxcL2csICcvJylcbiAgICAucmVwbGFjZSgvXFwvJC8sICcnKTtcbiAgY29uc3Qgbm9ybWFsaXplZEZpbGVwYXRoID0gZmlsZW5hbWUucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuXG4gIC8vIFdpbmRvd3MgZml4OiBVc2UgY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIHRvIHdvcmsgYXJvdW5kIGRyaXZlIGxldHRlciBjYXNpbmcgaXNzdWVzXG4gIGNvbnN0IGxvd2VyV2QgPSBub3JtYWxpemVkV29ya2luZ0Rpci50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBsb3dlclBhdGggPSBub3JtYWxpemVkRmlsZXBhdGgudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcmVsYXRpdmVGaWxlbmFtZTogc3RyaW5nO1xuICBpZiAobG93ZXJQYXRoLnN0YXJ0c1dpdGgoYCR7bG93ZXJXZH0vYCkpIHtcbiAgICAvLyBGaWxlIGlzIHVuZGVyIHdvcmtpbmcgZGlyZWN0b3J5IC0gbWFudWFsbHkgY2FsY3VsYXRlIHJlbGF0aXZlIHBhdGhcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gbm9ybWFsaXplZEZpbGVwYXRoLnN1YnN0cmluZyhcbiAgICAgIG5vcm1hbGl6ZWRXb3JraW5nRGlyLmxlbmd0aCArIDFcbiAgICApO1xuICB9IGVsc2UgaWYgKGxvd2VyUGF0aCA9PT0gbG93ZXJXZCkge1xuICAgIC8vIEZpbGUgSVMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IChzaG91bGRuJ3QgaGFwcGVuKVxuICAgIHJlbGF0aXZlRmlsZW5hbWUgPSAnLic7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHJlbGF0aXZlKCkgZm9yIGZpbGVzIG91dHNpZGUgd29ya2luZyBkaXJlY3RvcnlcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gcmVsYXRpdmUod29ya2luZ0RpciwgZmlsZW5hbWUpLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICBjb25zdCBhbGlhc2VkUmVsYXRpdmVQYXRoID0gYXdhaXQgcmVzb2x2ZVdvcmtmbG93QWxpYXNQYXRoKFxuICAgICAgICBmaWxlbmFtZSxcbiAgICAgICAgd29ya2luZ0RpclxuICAgICAgKTtcbiAgICAgIGlmIChhbGlhc2VkUmVsYXRpdmVQYXRoKSB7XG4gICAgICAgIHJlbGF0aXZlRmlsZW5hbWUgPSBhbGlhc2VkUmVsYXRpdmVQYXRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IHJlbGF0aXZlRmlsZW5hbWVcbiAgICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+IHBhcnQgIT09ICcuLicpXG4gICAgICAgICAgLmpvaW4oJy8nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBGaW5hbCBzYWZldHkgY2hlY2sgLSBlbnN1cmUgd2UgbmV2ZXIgcGFzcyBhbiBhYnNvbHV0ZSBwYXRoIHRvIFNXQ1xuICBpZiAocmVsYXRpdmVGaWxlbmFtZS5pbmNsdWRlcygnOicpIHx8IHJlbGF0aXZlRmlsZW5hbWUuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgLy8gVGhpcyBzaG91bGQgcmFyZWx5IGhhcHBlbiwgYnV0IHVzZSBmaWxlbmFtZSBzcGxpdCBhcyBsYXN0IHJlc29ydFxuICAgIHJlbGF0aXZlRmlsZW5hbWUgPSBub3JtYWxpemVkRmlsZXBhdGguc3BsaXQoJy8nKS5wb3AoKSB8fCAndW5rbm93bi50cyc7XG4gIH1cblxuICByZXR1cm4gcmVsYXRpdmVGaWxlbmFtZTtcbn1cblxuLy8gVGhpcyBsb2FkZXIgYXBwbGllcyB0aGUgXCJ1c2Ugd29ya2Zsb3dcIi9cInVzZSBzdGVwXCIgdHJhbnNmb3JtLlxuLy8gQWxsIGZpbGVzIHVzZSBzdGVwIG1vZGU7IHRoZSBTV0MgcGx1Z2luIGRlY2lkZXMgcGVyLWZ1bmN0aW9uIHdoZXRoZXJcbi8vIHRvIGVtaXQgd29ya2Zsb3cgb3Igc3RlcCBiaW5kaW5ncyBiYXNlZCBvbiB0aGUgc291cmNlJ3MgZGlyZWN0aXZlcy5cbnR5cGUgV29ya2Zsb3dMb2FkZXJDb250ZXh0ID0ge1xuICByZXNvdXJjZVBhdGg6IHN0cmluZztcbiAgYXN5bmM/OiAoKSA9PiAoXG4gICAgZXJyb3I6IEVycm9yIHwgbnVsbCxcbiAgICBjb250ZW50Pzogc3RyaW5nLFxuICAgIHNvdXJjZU1hcD86IGFueVxuICApID0+IHZvaWQ7XG4gIGFkZERlcGVuZGVuY3k/OiAoZGVwZW5kZW5jeTogc3RyaW5nKSA9PiB2b2lkO1xuICBhZGRCdWlsZERlcGVuZGVuY3k/OiAoZGVwZW5kZW5jeTogc3RyaW5nKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd29ya2Zsb3dMb2FkZXIoXG4gIHRoaXM6IFdvcmtmbG93TG9hZGVyQ29udGV4dCxcbiAgc291cmNlOiBzdHJpbmcgfCBCdWZmZXIsXG4gIHNvdXJjZU1hcDogYW55XG4pOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gfCB2b2lkIHtcbiAgY29uc3QgY2FsbGJhY2sgPSB0aGlzLmFzeW5jPy4oKTtcbiAgY29uc3QgcnVuID0gYXN5bmMgKCk6IFByb21pc2U8eyBjb2RlOiBzdHJpbmc7IG1hcDogYW55IH0+ID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHRoaXMucmVzb3VyY2VQYXRoO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2UgPSBzb3VyY2UudG9TdHJpbmcoKTtcbiAgICBjb25zdCB3b3JraW5nRGlyID0gcHJvY2Vzcy5jd2QoKTtcbiAgICBjb25zdCBzd2NQbHVnaW5QYXRoID0gcmVnaXN0ZXJUcmFuc2Zvcm1EZXBlbmRlbmNpZXModGhpcyk7XG4gICAgY29uc3Qgc291cmNlRm9yVHJhbnNmb3JtID0gbm9ybWFsaXplZFNvdXJjZTtcblxuICAgIGNvbnN0IGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlID0gYXdhaXQgY2hlY2tHZW5lcmF0ZWRGaWxlKGZpbGVuYW1lKTtcbiAgICAvLyBTa2lwIGdlbmVyYXRlZCB3b3JrZmxvdyByb3V0ZSBmaWxlcyB0byBhdm9pZCByZS1wcm9jZXNzaW5nIHRoZW0uXG4gICAgLy8gRGVmZXJyZWQgcm91dGUgc3R1YnMgYXJlIGEgc3BlY2lhbCBjYXNlOiB3YWl0IGZvciB0aGUgZ2VuZXJhdGVkIHJvdXRlXG4gICAgLy8gb3V0cHV0IHRvIGJlY29tZSBhdmFpbGFibGUgYmVmb3JlIHJldHVybmluZy5cbiAgICBpZiAoaXNHZW5lcmF0ZWRXb3JrZmxvd0ZpbGUpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTkVYVF9MQVpZX0RJU0NPVkVSWSA9PT0gJzEnICYmXG4gICAgICAgIGlzV29ya2Zsb3dSb3V0ZVN0dWJTb3VyY2Uobm9ybWFsaXplZFNvdXJjZSlcbiAgICAgICkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGVuc3VyZURlZmVycmVkUm91dGVTdHViQnVpbGRBbmRXYWl0KCk7XG4gICAgICAgICAgY29uc3QgcmVmcmVzaGVkU291cmNlID0gYXdhaXQgcmVhZEZpbGUoZmlsZW5hbWUsICd1dGY4Jyk7XG4gICAgICAgICAgaWYgKCFpc1dvcmtmbG93Um91dGVTdHViU291cmNlKHJlZnJlc2hlZFNvdXJjZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGNvZGU6IHJlZnJlc2hlZFNvdXJjZSwgbWFwOiBzb3VyY2VNYXAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgYFt3b3JrZmxvd10gRmFpbGVkIHdhaXRpbmcgZm9yIGRlZmVycmVkIHJvdXRlIGJ1aWxkIGZvciAke2ZpbGVuYW1lfSwgdXNpbmcgc3R1YiBvdXRwdXRgLFxuICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4geyBjb2RlOiBub3JtYWxpemVkU291cmNlLCBtYXA6IHNvdXJjZU1hcCB9O1xuICAgIH1cblxuICAgIC8vIERldGVjdCB3b3JrZmxvdyBwYXR0ZXJucyBpbiB0aGUgc291cmNlIGNvZGUuXG4gICAgY29uc3QgcGF0dGVybnMgPSBhd2FpdCBkZXRlY3RQYXR0ZXJucyhzb3VyY2VGb3JUcmFuc2Zvcm0pO1xuICAgIC8vIEFsd2F5cyBub3RpZnkgZGlzY292ZXJ5IHRyYWNraW5nLCBldmVuIGZvciBgZmFsc2UvZmFsc2VgLCBzbyBmaWxlcyB0aGF0XG4gICAgLy8gcHJldmlvdXNseSBoYWQgd29ya2Zsb3cvc3RlcCB1c2FnZSBhcmUgcmVtb3ZlZCBmcm9tIHRoZSB0cmFja2VkIHNldHMuXG4gICAgY29uc3QgbmV4dFBhdHRlcm5TdGF0ZTogRGlzY292ZXJlZFBhdHRlcm5TdGF0ZSA9IHtcbiAgICAgIGhhc1dvcmtmbG93OiBwYXR0ZXJucy5oYXNVc2VXb3JrZmxvdyxcbiAgICAgIGhhc1N0ZXA6IHBhdHRlcm5zLmhhc1VzZVN0ZXAsXG4gICAgICBoYXNTZXJkZTogcGF0dGVybnMuaGFzU2VyZGUsXG4gICAgfTtcbiAgICBjb25zdCB7IHNob3VsZE5vdGlmeSB9ID0gdXBkYXRlRGlzY292ZXJlZFBhdHRlcm5TdGF0ZShcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgbmV4dFBhdHRlcm5TdGF0ZVxuICAgICk7XG4gICAgaWYgKHNob3VsZE5vdGlmeSkge1xuICAgICAgYXdhaXQgbm90aWZ5U29ja2V0U2VydmVyKFxuICAgICAgICBmaWxlbmFtZSxcbiAgICAgICAgbmV4dFBhdHRlcm5TdGF0ZS5oYXNXb3JrZmxvdyxcbiAgICAgICAgbmV4dFBhdHRlcm5TdGF0ZS5oYXNTdGVwLFxuICAgICAgICBuZXh0UGF0dGVyblN0YXRlLmhhc1NlcmRlXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIENoZWNrIGlmIGZpbGUgbmVlZHMgdHJhbnNmb3JtYXRpb24gYmFzZWQgb24gcGF0dGVybnMgYW5kIHBhdGhcbiAgICBpZiAoIShhd2FpdCBjaGVja1Nob3VsZFRyYW5zZm9ybShmaWxlbmFtZSwgcGF0dGVybnMpKSkge1xuICAgICAgcmV0dXJuIHsgY29kZTogbm9ybWFsaXplZFNvdXJjZSwgbWFwOiBzb3VyY2VNYXAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBpc1R5cGVTY3JpcHQgPVxuICAgICAgZmlsZW5hbWUuZW5kc1dpdGgoJy50cycpIHx8XG4gICAgICBmaWxlbmFtZS5lbmRzV2l0aCgnLnRzeCcpIHx8XG4gICAgICBmaWxlbmFtZS5lbmRzV2l0aCgnLm10cycpIHx8XG4gICAgICBmaWxlbmFtZS5lbmRzV2l0aCgnLmN0cycpO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHJlbGF0aXZlIGZpbGVuYW1lIGZvciBTV0MgcGx1Z2luXG4gICAgLy8gVGhlIFNXQyBwbHVnaW4gdXNlcyBmaWxlbmFtZSB0byBnZW5lcmF0ZSB3b3JrZmxvd0lkLCBzbyBpdCBtdXN0IGJlIHJlbGF0aXZlXG4gICAgY29uc3QgcmVsYXRpdmVGaWxlbmFtZSA9IGF3YWl0IGdldFJlbGF0aXZlRmlsZW5hbWVGb3JTd2MoXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIHdvcmtpbmdEaXJcbiAgICApO1xuXG4gICAgLy8gR2V0IGRlY29yYXRvciBvcHRpb25zIGZyb20gdHNjb25maWcgKGNhY2hlZCBwZXIgd29ya2luZyBkaXJlY3RvcnkpXG4gICAgY29uc3QgeyBvcHRpb25zOiBkZWNvcmF0b3JPcHRpb25zLCBjb25maWdQYXRoIH0gPVxuICAgICAgYXdhaXQgZ2V0RGVjb3JhdG9yT3B0aW9ucyh3b3JraW5nRGlyKTtcbiAgICBpZiAoY29uZmlnUGF0aCkge1xuICAgICAgcmVnaXN0ZXJGaWxlRGVwZW5kZW5jeSh0aGlzLCBjb25maWdQYXRoKTtcbiAgICB9XG5cbiAgICAvLyBSZXNvbHZlIG1vZHVsZSBzcGVjaWZpZXIgZm9yIHBhY2thZ2VzIChub2RlX21vZHVsZXMgb3Igd29ya3NwYWNlIHBhY2thZ2VzKVxuICAgIGNvbnN0IG1vZHVsZVNwZWNpZmllciA9IGF3YWl0IGdldE1vZHVsZVNwZWNpZmllcihmaWxlbmFtZSwgd29ya2luZ0Rpcik7XG4gICAgY29uc3QgbW9kZSA9ICdzdGVwJztcblxuICAgIC8vIFRyYW5zZm9ybSB3aXRoIFNXQ1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRyYW5zZm9ybShzb3VyY2VGb3JUcmFuc2Zvcm0sIHtcbiAgICAgIGZpbGVuYW1lOiByZWxhdGl2ZUZpbGVuYW1lLFxuICAgICAganNjOiB7XG4gICAgICAgIHBhcnNlcjoge1xuICAgICAgICAgIC4uLihpc1R5cGVTY3JpcHRcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIHN5bnRheDogJ3R5cGVzY3JpcHQnLFxuICAgICAgICAgICAgICAgIHRzeDogZmlsZW5hbWUuZW5kc1dpdGgoJy50c3gnKSxcbiAgICAgICAgICAgICAgICBkZWNvcmF0b3JzOiBkZWNvcmF0b3JPcHRpb25zLmRlY29yYXRvcnMsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIHN5bnRheDogJ2VjbWFzY3JpcHQnLFxuICAgICAgICAgICAgICAgIGpzeDogZmlsZW5hbWUuZW5kc1dpdGgoJy5qc3gnKSxcbiAgICAgICAgICAgICAgICBkZWNvcmF0b3JzOiBkZWNvcmF0b3JPcHRpb25zLmRlY29yYXRvcnMsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXQ6ICdlczIwMjInLFxuICAgICAgICBleHBlcmltZW50YWw6IHtcbiAgICAgICAgICBwbHVnaW5zOiBbW3N3Y1BsdWdpblBhdGgsIHsgbW9kZSwgbW9kdWxlU3BlY2lmaWVyIH1dXSxcbiAgICAgICAgfSxcbiAgICAgICAgdHJhbnNmb3JtOiB7XG4gICAgICAgICAgcmVhY3Q6IHtcbiAgICAgICAgICAgIHJ1bnRpbWU6ICdwcmVzZXJ2ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsZWdhY3lEZWNvcmF0b3I6IGRlY29yYXRvck9wdGlvbnMubGVnYWN5RGVjb3JhdG9yLFxuICAgICAgICAgIGRlY29yYXRvck1ldGFkYXRhOiBkZWNvcmF0b3JPcHRpb25zLmRlY29yYXRvck1ldGFkYXRhLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG1pbmlmeTogZmFsc2UsXG4gICAgICBpbnB1dFNvdXJjZU1hcDogc291cmNlTWFwLFxuICAgICAgc291cmNlTWFwczogdHJ1ZSxcbiAgICAgIGlubGluZVNvdXJjZXNDb250ZW50OiB0cnVlLFxuICAgIH0pO1xuXG4gICAgbGV0IHRyYW5zZm9ybWVkTWFwID0gc291cmNlTWFwO1xuICAgIGlmICh0eXBlb2YgcmVzdWx0Lm1hcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRyYW5zZm9ybWVkTWFwID0gSlNPTi5wYXJzZShyZXN1bHQubWFwKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICB0cmFuc2Zvcm1lZE1hcCA9IHJlc3VsdC5tYXA7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZXN1bHQubWFwKSB7XG4gICAgICB0cmFuc2Zvcm1lZE1hcCA9IHJlc3VsdC5tYXA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29kZTogcmVzdWx0LmNvZGUsIG1hcDogdHJhbnNmb3JtZWRNYXAgfTtcbiAgfTtcblxuICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHJ1bigpLnRoZW4oKHJlc3VsdCkgPT4gcmVzdWx0LmNvZGUpO1xuICB9XG5cbiAgdm9pZCBydW4oKVxuICAgIC50aGVuKChyZXN1bHQpID0+IGNhbGxiYWNrKG51bGwsIHJlc3VsdC5jb2RlLCByZXN1bHQubWFwKSlcbiAgICAuY2F0Y2goKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICBjYWxsYmFjayhlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSkpO1xuICAgIH0pO1xufVxuIl19
package/dist/runtime.js CHANGED
@@ -18,4 +18,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  // require @workflow/core be a dependency as well as
19
19
  // @workflow/next
20
20
  __exportStar(require("@workflow/core/dist/runtime"), exports);
21
- //# sourceMappingURL=runtime.js.map
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxpREFBaUQ7QUFDakQsb0RBQW9EO0FBQ3BELGlCQUFpQjtBQUNqQiw4REFBNEMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyByZS1leHBvcnQgcnVudGltZSBhcyBzdHViIGZvciByZXNvbHZpbmcgdG8gbm90XG4vLyByZXF1aXJlIEB3b3JrZmxvdy9jb3JlIGJlIGEgZGVwZW5kZW5jeSBhcyB3ZWxsIGFzXG4vLyBAd29ya2Zsb3cvbmV4dFxuZXhwb3J0ICogZnJvbSAnQHdvcmtmbG93L2NvcmUvZGlzdC9ydW50aW1lJztcbiJdfQ==
@@ -28,6 +28,26 @@ export interface SocketIO {
28
28
  emit(event: 'build-complete'): void;
29
29
  getAuthToken(): string;
30
30
  }
31
+ /**
32
+ * Filename for the socket-info file.
33
+ */
34
+ export declare const SOCKET_INFO_FILENAME = "workflow-socket.json";
35
+ /**
36
+ * Previous filesystem location for the socket-info file. This file lives
37
+ * inside `.next/cache/`, which Vercel and Turborepo preserve across builds —
38
+ * a stale file from a prior build would cause the loader to attempt to
39
+ * connect to a dead port (ECONNREFUSED). The current location is a sibling
40
+ * of `cache/` so it isn't preserved.
41
+ *
42
+ * Exported so the builders can unlink the legacy path at boot, cleaning up
43
+ * any leftover file written by older versions of the SDK.
44
+ */
45
+ export declare const LEGACY_SOCKET_INFO_RELATIVE_PATH: string;
46
+ /**
47
+ * Remove any stale socket-info files at boot.
48
+ * @param distDir absolute path to the project's `.next` directory.
49
+ */
50
+ export declare function cleanupStaleSocketInfoFiles(distDir: string): Promise<void>;
31
51
  /**
32
52
  * Serialize a message with authentication preamble
33
53
  */
@@ -1 +1 @@
1
- {"version":3,"file":"socket-server.d.ts","sourceRoot":"","sources":["../src/socket-server.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,KACd,IAAI,CAAC;IACV,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,YAAY,IAAI,MAAM,CAAC;CACxB;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,aAAa,GAAG,IAAI,CAoCtB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAoGnB"}
1
+ {"version":3,"file":"socket-server.d.ts","sourceRoot":"","sources":["../src/socket-server.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,OAAO,EACpB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,KACd,IAAI,CAAC;IACV,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,YAAY,IAAI,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,gCAAgC,QAG5C,CAAC;AAMF;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,aAAa,GAAG,IAAI,CAoCtB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAoGnB"}
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LEGACY_SOCKET_INFO_RELATIVE_PATH = exports.SOCKET_INFO_FILENAME = void 0;
4
+ exports.cleanupStaleSocketInfoFiles = cleanupStaleSocketInfoFiles;
3
5
  exports.serializeMessage = serializeMessage;
4
6
  exports.parseMessage = parseMessage;
5
7
  exports.createSocketServer = createSocketServer;
@@ -19,8 +21,33 @@ const MESSAGE_PREAMBLE = 'WF:';
19
21
  function generateAuthToken() {
20
22
  return (0, node_crypto_1.randomBytes)(16).toString('hex');
21
23
  }
24
+ /**
25
+ * Filename for the socket-info file.
26
+ */
27
+ exports.SOCKET_INFO_FILENAME = 'workflow-socket.json';
28
+ /**
29
+ * Previous filesystem location for the socket-info file. This file lives
30
+ * inside `.next/cache/`, which Vercel and Turborepo preserve across builds —
31
+ * a stale file from a prior build would cause the loader to attempt to
32
+ * connect to a dead port (ECONNREFUSED). The current location is a sibling
33
+ * of `cache/` so it isn't preserved.
34
+ *
35
+ * Exported so the builders can unlink the legacy path at boot, cleaning up
36
+ * any leftover file written by older versions of the SDK.
37
+ */
38
+ exports.LEGACY_SOCKET_INFO_RELATIVE_PATH = (0, node_path_1.join)('cache', exports.SOCKET_INFO_FILENAME);
22
39
  function getDefaultSocketInfoFilePath() {
23
- return (0, node_path_1.join)(process.cwd(), '.next', 'cache', 'workflow-socket.json');
40
+ return (0, node_path_1.join)(process.cwd(), '.next', exports.SOCKET_INFO_FILENAME);
41
+ }
42
+ /**
43
+ * Remove any stale socket-info files at boot.
44
+ * @param distDir absolute path to the project's `.next` directory.
45
+ */
46
+ async function cleanupStaleSocketInfoFiles(distDir) {
47
+ await Promise.all([
48
+ (0, promises_1.rm)((0, node_path_1.join)(distDir, exports.SOCKET_INFO_FILENAME), { force: true }),
49
+ (0, promises_1.rm)((0, node_path_1.join)(distDir, exports.LEGACY_SOCKET_INFO_RELATIVE_PATH), { force: true }),
50
+ ]);
24
51
  }
25
52
  /**
26
53
  * Serialize a message with authentication preamble
@@ -151,4 +178,4 @@ async function createSocketServer(config) {
151
178
  getAuthToken: () => authToken,
152
179
  };
153
180
  }
154
- //# sourceMappingURL=socket-server.js.map
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29ja2V0LXNlcnZlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zb2NrZXQtc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQW9GQSxrRUFPQztBQUtELDRDQUtDO0FBTUQsb0NBdUNDO0FBU0QsZ0RBc0dDO0FBalFELDZDQUEwQztBQUMxQywrQ0FBd0Q7QUFDeEQsdUNBQWtFO0FBQ2xFLHlDQUEwQztBQUUxQzs7O0dBR0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQztBQUUvQjs7O0dBR0c7QUFDSCxTQUFTLGlCQUFpQjtJQUN4QixPQUFPLElBQUEseUJBQVcsRUFBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDekMsQ0FBQztBQXVDRDs7R0FFRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsc0JBQXNCLENBQUM7QUFFM0Q7Ozs7Ozs7OztHQVNHO0FBQ1UsUUFBQSxnQ0FBZ0MsR0FBRyxJQUFBLGdCQUFJLEVBQ2xELE9BQU8sRUFDUCw0QkFBb0IsQ0FDckIsQ0FBQztBQUVGLFNBQVMsNEJBQTRCO0lBQ25DLE9BQU8sSUFBQSxnQkFBSSxFQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsNEJBQW9CLENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0ksS0FBSyxVQUFVLDJCQUEyQixDQUMvQyxPQUFlO0lBRWYsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ2hCLElBQUEsYUFBRSxFQUFDLElBQUEsZ0JBQUksRUFBQyxPQUFPLEVBQUUsNEJBQW9CLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUN4RCxJQUFBLGFBQUUsRUFBQyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLHdDQUFnQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7S0FDckUsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztB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LENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ2hCLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDTCxPQUFPO1lBQ1QsQ0FBQztZQUNELE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxJQUFJLEVBQUUsQ0FBQyxNQUF3QixFQUFFLEVBQUU7WUFDakMsY0FBYyxHQUFHLElBQUksQ0FBQztZQUN0QixNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3hFLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEIsQ0FBQztRQUNILENBQUM7UUFDRCxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUztLQUM5QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuaW1wb3J0IHsgbWtkaXIsIHJtLCB3cml0ZUZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciwgdHlwZSBTZXJ2ZXIsIHR5cGUgU29ja2V0IH0gZnJvbSAnbm9kZTpuZXQnO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbi8qKlxuICogTWFnaWMgcHJlYW1ibGUgdGhhdCBtdXN0IHByZWZpeCBhbGwgbWVzc2FnZXMgdG8gYXV0aGVudGljYXRlIHRoZW0gYXMgd29ya2Zsb3cgbWVzc2FnZXMuXG4gKiBUaGlzIHByZXZlbnRzIGFjY2lkZW50YWwgcHJvY2Vzc2luZyBvZiBtZXNzYWdlcyBmcm9tIHBvcnQgc2Nhbm5lcnMgb3Igb3RoZXIgbG9jYWwgcHJvY2Vzc2VzLlxuICovXG5jb25zdCBNRVNTQUdFX1BSRUFNQkxFID0gJ1dGOic7XG5cbi8qKlxuICogR2VuZXJhdGUgYSByYW5kb20gYXV0aGVudGljYXRpb24gdG9rZW4gZm9yIHRoaXMgc2VydmVyIHNlc3Npb24uXG4gKiBDbGllbnRzIG11c3QgaW5jbHVkZSB0aGlzIHRva2VuIGluIGFsbCBtZXNzYWdlcy5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVBdXRoVG9rZW4oKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJhbmRvbUJ5dGVzKDE2KS50b1N0cmluZygnaGV4Jyk7XG59XG5cbi8qKlxuICogTWVzc2FnZSB0eXBlcyB0aGF0IGNhbiBiZSBzZW50IGJldHdlZW4gbG9hZGVyIGFuZCBidWlsZGVyXG4gKi9cbmV4cG9ydCB0eXBlIFNvY2tldE1lc3NhZ2UgPVxuICB8IHtcbiAgICAgIHR5cGU6ICdmaWxlLWRpc2NvdmVyZWQnO1xuICAgICAgZmlsZVBhdGg6IHN0cmluZztcbiAgICAgIGhhc1dvcmtmbG93OiBib29sZWFuO1xuICAgICAgaGFzU3RlcDogYm9vbGVhbjtcbiAgICAgIGhhc1NlcmRlOiBib29sZWFuO1xuICAgIH1cbiAgfCB7IHR5cGU6ICd0cmlnZ2VyLWJ1aWxkJyB9XG4gIHwgeyB0eXBlOiAnYnVpbGQtY29tcGxldGUnIH07XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgdGhlIHNvY2tldCBzZXJ2ZXJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTb2NrZXRTZXJ2ZXJDb25maWcge1xuICBpc0RldlNlcnZlcjogYm9vbGVhbjtcbiAgb25GaWxlRGlzY292ZXJlZDogKFxuICAgIGZpbGVQYXRoOiBzdHJpbmcsXG4gICAgaGFzV29ya2Zsb3c6IGJvb2xlYW4sXG4gICAgaGFzU3RlcDogYm9vbGVhbixcbiAgICBoYXNTZXJkZTogYm9vbGVhblxuICApID0+IHZvaWQ7XG4gIG9uVHJpZ2dlckJ1aWxkOiAoKSA9PiB2b2lkO1xuICBzb2NrZXRJbmZvRmlsZVBhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciB0aGUgc29ja2V0IElPIGluc3RhbmNlIHJldHVybmVkIGJ5IGNyZWF0ZVNvY2tldFNlcnZlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNvY2tldElPIHtcbiAgZW1pdChldmVudDogJ2J1aWxkLWNvbXBsZXRlJyk6IHZvaWQ7XG4gIGdldEF1dGhUb2tlbigpOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRmlsZW5hbWUgZm9yIHRoZSBzb2NrZXQtaW5mbyBmaWxlLlxuICovXG5leHBvcnQgY29uc3QgU09DS0VUX0lORk9fRklMRU5BTUUgPSAnd29ya2Zsb3ctc29ja2V0Lmpzb24nO1xuXG4vKipcbiAqIFByZXZpb3VzIGZpbGVzeXN0ZW0gbG9jYXRpb24gZm9yIHRoZSBzb2NrZXQtaW5mbyBmaWxlLiBUaGlzIGZpbGUgbGl2ZXNcbiAqIGluc2lkZSBgLm5leHQvY2FjaGUvYCwgd2hpY2ggVmVyY2VsIGFuZCBUdXJib3JlcG8gcHJlc2VydmUgYWNyb3NzIGJ1aWxkcyDigJRcbiAqIGEgc3RhbGUgZmlsZSBmcm9tIGEgcHJpb3IgYnVpbGQgd291bGQgY2F1c2UgdGhlIGxvYWRlciB0byBhdHRlbXB0IHRvXG4gKiBjb25uZWN0IHRvIGEgZGVhZCBwb3J0IChFQ09OTlJFRlVTRUQpLiBUaGUgY3VycmVudCBsb2NhdGlvbiBpcyBhIHNpYmxpbmdcbiAqIG9mIGBjYWNoZS9gIHNvIGl0IGlzbid0IHByZXNlcnZlZC5cbiAqXG4gKiBFeHBvcnRlZCBzbyB0aGUgYnVpbGRlcnMgY2FuIHVubGluayB0aGUgbGVnYWN5IHBhdGggYXQgYm9vdCwgY2xlYW5pbmcgdXBcbiAqIGFueSBsZWZ0b3ZlciBmaWxlIHdyaXR0ZW4gYnkgb2xkZXIgdmVyc2lvbnMgb2YgdGhlIFNESy5cbiAqL1xuZXhwb3J0IGNvbnN0IExFR0FDWV9TT0NLRVRfSU5GT19SRUxBVElWRV9QQVRIID0gam9pbihcbiAgJ2NhY2hlJyxcbiAgU09DS0VUX0lORk9fRklMRU5BTUVcbik7XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRTb2NrZXRJbmZvRmlsZVBhdGgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4ocHJvY2Vzcy5jd2QoKSwgJy5uZXh0JywgU09DS0VUX0lORk9fRklMRU5BTUUpO1xufVxuXG4vKipcbiAqIFJlbW92ZSBhbnkgc3RhbGUgc29ja2V0LWluZm8gZmlsZXMgYXQgYm9vdC5cbiAqIEBwYXJhbSBkaXN0RGlyIGFic29sdXRlIHBhdGggdG8gdGhlIHByb2plY3QncyBgLm5leHRgIGRpcmVjdG9yeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFudXBTdGFsZVNvY2tldEluZm9GaWxlcyhcbiAgZGlzdERpcjogc3RyaW5nXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgIHJtKGpvaW4oZGlzdERpciwgU09DS0VUX0lORk9fRklMRU5BTUUpLCB7IGZvcmNlOiB0cnVlIH0pLFxuICAgIHJtKGpvaW4oZGlzdERpciwgTEVHQUNZX1NPQ0tFVF9JTkZPX1JFTEFUSVZFX1BBVEgpLCB7IGZvcmNlOiB0cnVlIH0pLFxuICBdKTtcbn1cblxuLyoqXG4gKiBTZXJpYWxpemUgYSBtZXNzYWdlIHdpdGggYXV0aGVudGljYXRpb24gcHJlYW1ibGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZU1lc3NhZ2UoXG4gIG1lc3NhZ2U6IFNvY2tldE1lc3NhZ2UsXG4gIGF1dGhUb2tlbjogc3RyaW5nXG4pOiBzdHJpbmcge1xuICByZXR1cm4gYCR7TUVTU0FHRV9QUkVBTUJMRX0ke2F1dGhUb2tlbn06JHtKU09OLnN0cmluZ2lmeShtZXNzYWdlKX1cXG5gO1xufVxuXG4vKipcbiAqIFBhcnNlIGFuZCBhdXRoZW50aWNhdGUgYSBtZXNzYWdlIGZyb20gdGhlIHNvY2tldFxuICogUmV0dXJucyB0aGUgcGFyc2VkIG1lc3NhZ2UgaWYgdmFsaWQsIG51bGwgb3RoZXJ3aXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU1lc3NhZ2UoXG4gIGxpbmU6IHN0cmluZyxcbiAgYXV0aFRva2VuOiBzdHJpbmdcbik6IFNvY2tldE1lc3NhZ2UgfCBudWxsIHtcbiAgY29uc3QgdHJpbW1lZCA9IGxpbmUudHJpbSgpO1xuICBpZiAoIXRyaW1tZWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENoZWNrIGZvciBwcmVhbWJsZVxuICBpZiAoIXRyaW1tZWQuc3RhcnRzV2l0aChNRVNTQUdFX1BSRUFNQkxFKSkge1xuICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgbWVzc2FnZSB3aXRob3V0IHZhbGlkIHByZWFtYmxlLCBpZ25vcmluZycpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gRXh0cmFjdCBhdXRoIHRva2VuIGFuZCBwYXlsb2FkXG4gIGNvbnN0IHdpdGhvdXRQcmVhbWJsZSA9IHRyaW1tZWQuc2xpY2UoTUVTU0FHRV9QUkVBTUJMRS5sZW5ndGgpO1xuICBjb25zdCBjb2xvbkluZGV4ID0gd2l0aG91dFByZWFtYmxlLmluZGV4T2YoJzonKTtcbiAgaWYgKGNvbG9uSW5kZXggPT09IC0xKSB7XG4gICAgY29uc29sZS53YXJuKCdSZWNlaXZlZCBtZXNzYWdlIHdpdGhvdXQgYXV0aCB0b2tlbiBzZXBhcmF0b3IsIGlnbm9yaW5nJyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBtZXNzYWdlVG9rZW4gPSB3aXRob3V0UHJlYW1ibGUuc2xpY2UoMCwgY29sb25JbmRleCk7XG4gIGNvbnN0IHBheWxvYWQgPSB3aXRob3V0UHJlYW1ibGUuc2xpY2UoY29sb25JbmRleCArIDEpO1xuXG4gIC8vIFZlcmlmeSBhdXRoIHRva2VuXG4gIGlmIChtZXNzYWdlVG9rZW4gIT09IGF1dGhUb2tlbikge1xuICAgIGNvbnNvbGUud2FybignUmVjZWl2ZWQgbWVzc2FnZSB3aXRoIGludmFsaWQgYXV0aCB0b2tlbiwgaWdub3JpbmcnKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIFBhcnNlIEpTT04gcGF5bG9hZFxuICB0cnkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHBheWxvYWQpIGFzIFNvY2tldE1lc3NhZ2U7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHBhcnNlIHNvY2tldCBtZXNzYWdlIEpTT046JywgZXJyb3IpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgVENQIHNvY2tldCBzZXJ2ZXIgZm9yIGxvYWRlcjwtPmJ1aWxkZXIgY29tbXVuaWNhdGlvbi5cbiAqIFJldHVybnMgYSBTb2NrZXRJTyBpbnRlcmZhY2UgZm9yIGJyb2FkY2FzdGluZyBtZXNzYWdlcyBhbmQgdGhlIGF1dGggdG9rZW4uXG4gKlxuICogU0VDVVJJVFk6IFNlcnZlciBsaXN0ZW5zIG9uIDEyNy4wLjAuMSAobG9jYWxob3N0IG9ubHkpIGFuZCB1c2VzXG4gKiBtZXNzYWdlIGF1dGhlbnRpY2F0aW9uIHRvIHByZXZlbnQgcHJvY2Vzc2luZyBvZiB1bmF1dGhvcml6ZWQgbWVzc2FnZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTb2NrZXRTZXJ2ZXIoXG4gIGNvbmZpZzogU29ja2V0U2VydmVyQ29uZmlnXG4pOiBQcm9taXNlPFNvY2tldElPPiB7XG4gIGNvbnN0IGF1dGhUb2tlbiA9IGdlbmVyYXRlQXV0aFRva2VuKCk7XG4gIGNvbnN0IGNsaWVudHMgPSBuZXcgU2V0PFNvY2tldD4oKTtcbiAgbGV0IGJ1aWxkVHJpZ2dlcmVkID0gZmFsc2U7XG5cbiAgY29uc3Qgc2VydmVyOiBTZXJ2ZXIgPSBjcmVhdGVTZXJ2ZXIoKHNvY2tldDogU29ja2V0KSA9PiB7XG4gICAgc29ja2V0LnNldE5vRGVsYXkodHJ1ZSk7XG4gICAgY2xpZW50cy5hZGQoc29ja2V0KTtcblxuICAgIC8vIFNlbmQgYnVpbGQtY29tcGxldGUgaWYgYnVpbGQgYWxyZWFkeSBmaW5pc2hlZCAocHJvZHVjdGlvbiBtb2RlKVxuICAgIGlmIChidWlsZFRyaWdnZXJlZCAmJiAhY29uZmlnLmlzRGV2U2VydmVyKSB7XG4gICAgICBzb2NrZXQud3JpdGUoc2VyaWFsaXplTWVzc2FnZSh7IHR5cGU6ICdidWlsZC1jb21wbGV0ZScgfSwgYXV0aFRva2VuKSk7XG4gICAgfVxuXG4gICAgbGV0IGJ1ZmZlciA9ICcnO1xuXG4gICAgc29ja2V0Lm9uKCdkYXRhJywgKGRhdGE6IEJ1ZmZlcikgPT4ge1xuICAgICAgYnVmZmVyICs9IGRhdGEudG9TdHJpbmcoKTtcblxuICAgICAgLy8gUHJvY2VzcyBjb21wbGV0ZSBtZXNzYWdlcyAobmV3bGluZS1kZWxpbWl0ZWQpXG4gICAgICBsZXQgbmV3bGluZUluZGV4ID0gYnVmZmVyLmluZGV4T2YoJ1xcbicpO1xuICAgICAgd2hpbGUgKG5ld2xpbmVJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgY29uc3QgbGluZSA9IGJ1ZmZlci5zbGljZSgwLCBuZXdsaW5lSW5kZXgpO1xuICAgICAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UobmV3bGluZUluZGV4ICsgMSk7XG4gICAgICAgIG5ld2xpbmVJbmRleCA9IGJ1ZmZlci5pbmRleE9mKCdcXG4nKTtcblxuICAgICAgICBjb25zdCBtZXNzYWdlID0gcGFyc2VNZXNzYWdlKGxpbmUsIGF1dGhUb2tlbik7XG4gICAgICAgIGlmICghbWVzc2FnZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gJ2ZpbGUtZGlzY292ZXJlZCcpIHtcbiAgICAgICAgICBjb25maWcub25GaWxlRGlzY292ZXJlZChcbiAgICAgICAgICAgIG1lc3NhZ2UuZmlsZVBhdGgsXG4gICAgICAgICAgICBtZXNzYWdlLmhhc1dvcmtmbG93LFxuICAgICAgICAgICAgbWVzc2FnZS5oYXNTdGVwLFxuICAgICAgICAgICAgbWVzc2FnZS5oYXNTZXJkZVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAobWVzc2FnZS50eXBlID09PSAndHJpZ2dlci1idWlsZCcpIHtcbiAgICAgICAgICBjb25maWcub25UcmlnZ2VyQnVpbGQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgc29ja2V0Lm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICBjbGllbnRzLmRlbGV0ZShzb2NrZXQpO1xuICAgIH0pO1xuXG4gICAgc29ja2V0Lm9uKCdlcnJvcicsIChlcnI6IEVycm9yKSA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKCdTb2NrZXQgZXJyb3I6JywgZXJyKTtcbiAgICAgIGNsaWVudHMuZGVsZXRlKHNvY2tldCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIExpc3RlbiBvbiByYW5kb20gYXZhaWxhYmxlIHBvcnQgKGxvY2FsaG9zdCBvbmx5KVxuICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgc2VydmVyLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcbiAgICBzZXJ2ZXIubGlzdGVuKDAsICcxMjcuMC4wLjEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgIGlmIChhZGRyZXNzICYmIHR5cGVvZiBhZGRyZXNzID09PSAnb2JqZWN0Jykge1xuICAgICAgICBjb25zdCBzb2NrZXRJbmZvRmlsZVBhdGggPVxuICAgICAgICAgIGNvbmZpZy5zb2NrZXRJbmZvRmlsZVBhdGggfHwgZ2V0RGVmYXVsdFNvY2tldEluZm9GaWxlUGF0aCgpO1xuICAgICAgICB2b2lkIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IG1rZGlyKGRpcm5hbWUoc29ja2V0SW5mb0ZpbGVQYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgICAgICBhd2FpdCB3cml0ZUZpbGUoXG4gICAgICAgICAgICAgIHNvY2tldEluZm9GaWxlUGF0aCxcbiAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgcG9ydDogYWRkcmVzcy5wb3J0LFxuICAgICAgICAgICAgICAgICAgYXV0aFRva2VuLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAyXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBwcm9jZXNzLmVudi5XT1JLRkxPV19TT0NLRVRfSU5GT19QQVRIID0gc29ja2V0SW5mb0ZpbGVQYXRoO1xuICAgICAgICAgICAgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfU09DS0VUX1BPUlQgPSBTdHJpbmcoYWRkcmVzcy5wb3J0KTtcbiAgICAgICAgICAgIHByb2Nlc3MuZW52LldPUktGTE9XX1NPQ0tFVF9BVVRIID0gYXV0aFRva2VuO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVqZWN0KG5ldyBFcnJvcignRmFpbGVkIHRvIG9idGFpbiB3b3JrZmxvdyBzb2NrZXQgc2VydmVyIGFkZHJlc3MnKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZW1pdDogKF9ldmVudDogJ2J1aWxkLWNvbXBsZXRlJykgPT4ge1xuICAgICAgYnVpbGRUcmlnZ2VyZWQgPSB0cnVlO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IHNlcmlhbGl6ZU1lc3NhZ2UoeyB0eXBlOiAnYnVpbGQtY29tcGxldGUnIH0sIGF1dGhUb2tlbik7XG4gICAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiBjbGllbnRzKSB7XG4gICAgICAgIGNsaWVudC53cml0ZShtZXNzYWdlKTtcbiAgICAgIH1cbiAgICB9LFxuICAgIGdldEF1dGhUb2tlbjogKCkgPT4gYXV0aFRva2VuLFxuICB9O1xufVxuIl19