@workflow/next 5.0.0-beta.20 → 5.0.0-beta.21

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
@@ -1,80 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.shouldNotifySocketForDiscoveredPattern = shouldNotifySocketForDiscoveredPattern;
4
3
  exports.default = workflowLoader;
5
4
  const node_fs_1 = require("node:fs");
6
- const promises_1 = require("node:fs/promises");
7
- const node_net_1 = require("node:net");
8
5
  const node_path_1 = require("node:path");
9
6
  const core_1 = require("@swc/core");
10
- const socket_server_js_1 = require("./socket-server.js");
11
7
  // Cache decorator options per working directory to avoid reading tsconfig for every file
12
8
  const decoratorOptionsCache = new Map();
13
9
  // Cache for shared utilities from @workflow/builders (ESM module loaded dynamically in CommonJS context)
14
10
  let cachedBuildersModule = null;
15
11
  let cachedLoaderStaticDependencies = null;
16
- const discoveredPatternStateByFilePath = new Map();
17
- function shouldNotifySocketForDiscoveredPattern(patternStateChanged, patternState) {
18
- return (patternStateChanged ||
19
- patternState.hasWorkflow ||
20
- patternState.hasStep ||
21
- patternState.hasSerde);
22
- }
23
- // Cache socket connection to avoid reconnecting on every file.
24
- let socketClientPromise = null;
25
- let socketClient = null;
26
- let socketClientKey = null;
27
- /**
28
- * Wrap a TCP connect failure with context about where the connection was
29
- * attempted, where the credentials came from, and which source file was
30
- * being processed when it failed. ECONNREFUSED is the common case here, and
31
- * the message points the user at the most likely root cause (stale
32
- * socket-info file).
33
- */
34
- function annotateConnectionError(originalError, credentials) {
35
- const errorCode = originalError instanceof Error &&
36
- 'code' in originalError &&
37
- typeof originalError.code === 'string'
38
- ? originalError.code
39
- : undefined;
40
- const errorMessage = originalError instanceof Error
41
- ? originalError.message
42
- : String(originalError);
43
- const lines = [
44
- `Workflow discovery socket connect failed: ${errorCode ?? errorMessage} (127.0.0.1:${credentials.port})`,
45
- ];
46
- const annotated = new Error(lines.join('\n'));
47
- if (originalError instanceof Error) {
48
- annotated.cause = originalError;
49
- }
50
- return annotated;
51
- }
52
- const ROUTE_STUB_FILE_MARKER = 'WORKFLOW_ROUTE_STUB_FILE';
53
- const ROUTE_STUB_BUILD_WAIT_TIMEOUT_MS = 120_000;
54
- let pendingDeferredRouteStubBuildPromise = null;
55
12
  function registerFileDependency(loaderContext, dependencyPath) {
56
13
  loaderContext.addDependency?.(dependencyPath);
57
14
  loaderContext.addBuildDependency?.(dependencyPath);
58
15
  }
59
- function updateDiscoveredPatternState(filePath, nextState) {
60
- const previousState = discoveredPatternStateByFilePath.get(filePath);
61
- const hasAnyPattern = nextState.hasWorkflow || nextState.hasStep || nextState.hasSerde;
62
- if (!hasAnyPattern) {
63
- if (!previousState) {
64
- return { shouldNotify: false };
65
- }
66
- discoveredPatternStateByFilePath.delete(filePath);
67
- return { shouldNotify: true, previousState };
68
- }
69
- if (previousState &&
70
- previousState.hasWorkflow === nextState.hasWorkflow &&
71
- previousState.hasStep === nextState.hasStep &&
72
- previousState.hasSerde === nextState.hasSerde) {
73
- return { shouldNotify: false, previousState };
74
- }
75
- discoveredPatternStateByFilePath.set(filePath, nextState);
76
- return { shouldNotify: true, previousState };
77
- }
78
16
  function addIfExists(files, dependencyPath) {
79
17
  if ((0, node_fs_1.existsSync)(dependencyPath)) {
80
18
  files.add(dependencyPath);
@@ -93,7 +31,6 @@ function resolveLoaderStaticDependencies() {
93
31
  const workflowBuildersPackageJsonPath = (0, node_path_1.join)((0, node_path_1.dirname)(workflowBuildersPath), '../package.json');
94
32
  const files = new Set([
95
33
  __filename,
96
- require.resolve('./socket-server'),
97
34
  swcPluginPath,
98
35
  swcPluginBuildHashPath,
99
36
  workflowBuildersPath,
@@ -113,286 +50,6 @@ function registerTransformDependencies(loaderContext) {
113
50
  }
114
51
  return staticDependencies.swcPluginPath;
115
52
  }
116
- function resetSocketClient(cachedSocket) {
117
- if (cachedSocket && socketClient && socketClient !== cachedSocket) {
118
- return;
119
- }
120
- socketClientPromise = null;
121
- socketClient = null;
122
- socketClientKey = null;
123
- }
124
- async function writeSocketMessage(socket, message) {
125
- await new Promise((resolve, reject) => {
126
- socket.write(message, (error) => {
127
- if (error) {
128
- reject(error);
129
- return;
130
- }
131
- resolve();
132
- });
133
- });
134
- }
135
- function getSocketInfoFilePath() {
136
- const configuredPath = process.env.WORKFLOW_SOCKET_INFO_PATH;
137
- if (configuredPath) {
138
- return configuredPath;
139
- }
140
- // Fallback for worker processes that don't inherit dynamic env updates
141
- // from the process that created the socket server.
142
- const distDir = process.env.WORKFLOW_NEXT_DIST_DIR || '.next';
143
- const cwdFallbackPath = (0, node_path_1.join)(process.cwd(), distDir, socket_server_js_1.SOCKET_INFO_FILENAME);
144
- const projectRoot = process.env.WORKFLOW_PROJECT_ROOT;
145
- if (projectRoot) {
146
- const projectRootFallbackPath = (0, node_path_1.join)(projectRoot, distDir, socket_server_js_1.SOCKET_INFO_FILENAME);
147
- if ((0, node_fs_1.existsSync)(projectRootFallbackPath)) {
148
- return projectRootFallbackPath;
149
- }
150
- }
151
- return cwdFallbackPath;
152
- }
153
- function getSocketCredentialsFromEnv() {
154
- const socketPort = process.env.WORKFLOW_SOCKET_PORT;
155
- const authToken = process.env.WORKFLOW_SOCKET_AUTH;
156
- if (!socketPort || !authToken) {
157
- return null;
158
- }
159
- const port = Number.parseInt(socketPort, 10);
160
- if (Number.isNaN(port)) {
161
- return null;
162
- }
163
- return { port, authToken };
164
- }
165
- async function getSocketCredentialsFromFile() {
166
- const socketInfoFilePath = getSocketInfoFilePath();
167
- if (!socketInfoFilePath) {
168
- return null;
169
- }
170
- if (!(0, node_fs_1.existsSync)(socketInfoFilePath)) {
171
- return null;
172
- }
173
- try {
174
- const raw = await (0, promises_1.readFile)(socketInfoFilePath, 'utf8');
175
- const parsed = JSON.parse(raw);
176
- const authToken = typeof parsed.authToken === 'string' ? parsed.authToken : null;
177
- const numericPort = typeof parsed.port === 'number'
178
- ? parsed.port
179
- : Number.parseInt(String(parsed.port), 10);
180
- if (!authToken || Number.isNaN(numericPort)) {
181
- return null;
182
- }
183
- return {
184
- port: numericPort,
185
- authToken,
186
- };
187
- }
188
- catch {
189
- return null;
190
- }
191
- }
192
- async function getSocketCredentials() {
193
- const envCredentials = getSocketCredentialsFromEnv();
194
- if (envCredentials) {
195
- return envCredentials;
196
- }
197
- return await getSocketCredentialsFromFile();
198
- }
199
- async function getSocketClient() {
200
- const socketCredentials = await getSocketCredentials();
201
- if (!socketCredentials) {
202
- return null;
203
- }
204
- if (socketClient?.destroyed) {
205
- resetSocketClient(socketClient);
206
- }
207
- const currentSocketKey = `${socketCredentials.port}:${socketCredentials.authToken}`;
208
- if (socketClientKey && socketClientKey !== currentSocketKey) {
209
- if (socketClient) {
210
- resetSocketClient(socketClient);
211
- }
212
- else {
213
- resetSocketClient();
214
- }
215
- }
216
- if (!socketClientPromise) {
217
- socketClientPromise = (async () => {
218
- try {
219
- const socket = (0, node_net_1.connect)({
220
- port: socketCredentials.port,
221
- host: '127.0.0.1',
222
- });
223
- // Wait for connection
224
- await new Promise((resolve, reject) => {
225
- const onConnect = () => {
226
- socket.setNoDelay(true);
227
- cleanup();
228
- resolve();
229
- };
230
- const onError = (error) => {
231
- cleanup();
232
- reject(annotateConnectionError(error, socketCredentials));
233
- };
234
- const timeout = setTimeout(() => {
235
- cleanup();
236
- socket.destroy();
237
- reject(annotateConnectionError(new Error('Socket connection timeout'), socketCredentials));
238
- }, 1000);
239
- const cleanup = () => {
240
- clearTimeout(timeout);
241
- socket.off('connect', onConnect);
242
- socket.off('error', onError);
243
- };
244
- socket.on('connect', onConnect);
245
- socket.on('error', onError);
246
- });
247
- socket.on('close', () => {
248
- resetSocketClient(socket);
249
- });
250
- socket.on('error', () => {
251
- resetSocketClient(socket);
252
- });
253
- socketClient = socket;
254
- socketClientKey = currentSocketKey;
255
- return socket;
256
- }
257
- catch (error) {
258
- resetSocketClient();
259
- throw error;
260
- }
261
- })();
262
- }
263
- return socketClientPromise;
264
- }
265
- async function notifySocketServer(filename, hasWorkflow, hasStep, hasSerde) {
266
- const socketCredentials = await getSocketCredentials();
267
- if (!socketCredentials) {
268
- return;
269
- }
270
- const socket = await getSocketClient();
271
- if (!socket) {
272
- throw new Error('Invariant: missing workflow socket connection');
273
- }
274
- const message = {
275
- type: 'file-discovered',
276
- filePath: filename,
277
- hasWorkflow,
278
- hasStep,
279
- hasSerde,
280
- };
281
- const serializedMessage = (0, socket_server_js_1.serializeMessage)(message, socketCredentials.authToken);
282
- try {
283
- await writeSocketMessage(socket, serializedMessage);
284
- }
285
- catch (error) {
286
- resetSocketClient(socket);
287
- const reconnectedSocket = await getSocketClient();
288
- if (!reconnectedSocket) {
289
- throw error;
290
- }
291
- await writeSocketMessage(reconnectedSocket, serializedMessage);
292
- }
293
- }
294
- function isWorkflowRouteStubSource(source) {
295
- return source.includes(ROUTE_STUB_FILE_MARKER);
296
- }
297
- async function createSocketConnection(socketCredentials, timeoutMs = 1_000) {
298
- return await new Promise((resolve, reject) => {
299
- const socket = (0, node_net_1.connect)({
300
- port: socketCredentials.port,
301
- host: '127.0.0.1',
302
- });
303
- const timeout = setTimeout(() => {
304
- cleanup();
305
- socket.destroy();
306
- reject(annotateConnectionError(new Error('Socket connection timeout'), socketCredentials));
307
- }, timeoutMs);
308
- const cleanup = () => {
309
- clearTimeout(timeout);
310
- socket.off('connect', onConnect);
311
- socket.off('error', onError);
312
- };
313
- const onConnect = () => {
314
- socket.setNoDelay(true);
315
- cleanup();
316
- resolve(socket);
317
- };
318
- const onError = (error) => {
319
- cleanup();
320
- socket.destroy();
321
- reject(annotateConnectionError(error, socketCredentials));
322
- };
323
- socket.on('connect', onConnect);
324
- socket.on('error', onError);
325
- });
326
- }
327
- async function waitForDeferredBuildComplete(socket, authToken, timeoutMs = ROUTE_STUB_BUILD_WAIT_TIMEOUT_MS) {
328
- await new Promise((resolve, reject) => {
329
- let buffer = '';
330
- const timeout = setTimeout(() => {
331
- cleanup();
332
- reject(new Error('Timed out waiting for deferred route build completion'));
333
- }, timeoutMs);
334
- const cleanup = () => {
335
- clearTimeout(timeout);
336
- socket.off('data', onData);
337
- socket.off('error', onError);
338
- socket.off('close', onClose);
339
- socket.off('end', onClose);
340
- };
341
- const onError = (error) => {
342
- cleanup();
343
- reject(error);
344
- };
345
- const onClose = () => {
346
- cleanup();
347
- reject(new Error('Socket closed before deferred route build completed'));
348
- };
349
- const onData = (chunk) => {
350
- buffer += chunk.toString();
351
- let newlineIndex = buffer.indexOf('\n');
352
- while (newlineIndex !== -1) {
353
- const line = buffer.slice(0, newlineIndex);
354
- buffer = buffer.slice(newlineIndex + 1);
355
- newlineIndex = buffer.indexOf('\n');
356
- const message = (0, socket_server_js_1.parseMessage)(line, authToken);
357
- if (message?.type === 'build-complete') {
358
- cleanup();
359
- resolve();
360
- return;
361
- }
362
- }
363
- };
364
- socket.on('data', onData);
365
- socket.on('error', onError);
366
- socket.on('close', onClose);
367
- socket.on('end', onClose);
368
- });
369
- }
370
- async function triggerDeferredRouteStubBuildAndWait() {
371
- const socketCredentials = await getSocketCredentials();
372
- if (!socketCredentials) {
373
- return;
374
- }
375
- const socket = await createSocketConnection(socketCredentials);
376
- try {
377
- await writeSocketMessage(socket, (0, socket_server_js_1.serializeMessage)({ type: 'trigger-build' }, socketCredentials.authToken));
378
- await waitForDeferredBuildComplete(socket, socketCredentials.authToken);
379
- }
380
- finally {
381
- socket.destroy();
382
- }
383
- }
384
- async function ensureDeferredRouteStubBuildAndWait() {
385
- if (pendingDeferredRouteStubBuildPromise) {
386
- return pendingDeferredRouteStubBuildPromise;
387
- }
388
- const pendingPromise = triggerDeferredRouteStubBuildAndWait();
389
- pendingDeferredRouteStubBuildPromise = pendingPromise.finally(() => {
390
- if (pendingDeferredRouteStubBuildPromise === pendingPromise) {
391
- pendingDeferredRouteStubBuildPromise = null;
392
- }
393
- });
394
- return pendingDeferredRouteStubBuildPromise;
395
- }
396
53
  async function getBuildersModule() {
397
54
  if (cachedBuildersModule) {
398
55
  return cachedBuildersModule;
@@ -484,37 +141,11 @@ function workflowLoader(source, sourceMap) {
484
141
  const sourceForTransform = normalizedSource;
485
142
  const isGeneratedWorkflowFile = await checkGeneratedFile(filename);
486
143
  // Skip generated workflow route files to avoid re-processing them.
487
- // Deferred route stubs are a special case: wait for the generated route
488
- // output to become available before returning.
489
144
  if (isGeneratedWorkflowFile) {
490
- if (process.env.WORKFLOW_NEXT_LAZY_DISCOVERY === '1' &&
491
- isWorkflowRouteStubSource(normalizedSource)) {
492
- try {
493
- await ensureDeferredRouteStubBuildAndWait();
494
- const refreshedSource = await (0, promises_1.readFile)(filename, 'utf8');
495
- if (!isWorkflowRouteStubSource(refreshedSource)) {
496
- return { code: refreshedSource, map: sourceMap };
497
- }
498
- }
499
- catch (error) {
500
- console.warn(`[workflow] Failed waiting for deferred route build for ${filename}, using stub output`, error);
501
- }
502
- }
503
145
  return { code: normalizedSource, map: sourceMap };
504
146
  }
505
147
  // Detect workflow patterns in the source code.
506
148
  const patterns = await detectPatterns(sourceForTransform);
507
- // Always notify discovery tracking, even for `false/false`, so files that
508
- // previously had workflow/step usage are removed from the tracked sets.
509
- const nextPatternState = {
510
- hasWorkflow: patterns.hasUseWorkflow,
511
- hasStep: patterns.hasUseStep,
512
- hasSerde: patterns.hasSerde,
513
- };
514
- const { shouldNotify } = updateDiscoveredPatternState(filename, nextPatternState);
515
- if (shouldNotifySocketForDiscoveredPattern(shouldNotify, nextPatternState)) {
516
- await notifySocketServer(filename, nextPatternState.hasWorkflow, nextPatternState.hasStep, nextPatternState.hasSerde);
517
- }
518
149
  // Check if file needs transformation based on patterns and path
519
150
  if (!(await checkShouldTransform(filename, patterns))) {
520
151
  return { code: normalizedSource, map: sourceMap };
@@ -591,4 +222,4 @@ function workflowLoader(source, sourceMap) {
591
222
  callback(error instanceof Error ? error : new Error(String(error)));
592
223
  });
593
224
  }
594
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXVDQSx3RkFVQztBQTBtQkQsaUNBcUpDO0FBaHpCRCxxQ0FBcUM7QUFDckMsK0NBQTRDO0FBQzVDLHVDQUFnRDtBQUNoRCx5Q0FBb0Q7QUFDcEQsb0NBQXNDO0FBQ3RDLHlEQUs0QjtBQU01Qix5RkFBeUY7QUFDekYsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsRUFHbEMsQ0FBQztBQUNKLHlHQUF5RztBQUN6RyxJQUFJLG9CQUFvQixHQUErQyxJQUFJLENBQUM7QUFLNUUsSUFBSSw4QkFBOEIsR0FBb0MsSUFBSSxDQUFDO0FBTzNFLE1BQU0sZ0NBQWdDLEdBQUcsSUFBSSxHQUFHLEVBRzdDLENBQUM7QUFFSixTQUFnQixzQ0FBc0MsQ0FDcEQsbUJBQTRCLEVBQzVCLFlBQW9DO0lBRXBDLE9BQU8sQ0FDTCxtQkFBbUI7UUFDbkIsWUFBWSxDQUFDLFdBQVc7UUFDeEIsWUFBWSxDQUFDLE9BQU87UUFDcEIsWUFBWSxDQUFDLFFBQVEsQ0FDdEIsQ0FBQztBQUNKLENBQUM7QUFFRCwrREFBK0Q7QUFDL0QsSUFBSSxtQkFBbUIsR0FBa0MsSUFBSSxDQUFDO0FBQzlELElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7QUFDdkMsSUFBSSxlQUFlLEdBQWtCLElBQUksQ0FBQztBQU8xQzs7Ozs7O0dBTUc7QUFDSCxTQUFTLHVCQUF1QixDQUM5QixhQUFzQixFQUN0QixXQUE4QjtJQUU5QixNQUFNLFNBQVMsR0FDYixhQUFhLFlBQVksS0FBSztRQUM5QixNQUFNLElBQUksYUFBYTtRQUN2QixPQUFRLGFBQW9DLENBQUMsSUFBSSxLQUFLLFFBQVE7UUFDNUQsQ0FBQyxDQUFHLGFBQWtDLENBQUMsSUFBZTtRQUN0RCxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLE1BQU0sWUFBWSxHQUNoQixhQUFhLFlBQVksS0FBSztRQUM1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RSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLENBQUM7SUFDcEQsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2QsT0FBTyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsS0FBSyxHQUFHLEVBQUU7U0FDUCxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDekQsS0FBSyxDQUFDLENBQUMsS0FBYyxFQUFFLEVBQUU7UUFDeEIsUUFBUSxDQUFDLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jIH0gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgeyByZWFkRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgY29ubmVjdCwgdHlwZSBTb2NrZXQgfSBmcm9tICdub2RlOm5ldCc7XG5pbXBvcnQgeyBkaXJuYW1lLCBqb2luLCByZWxhdGl2ZSB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0gfSBmcm9tICdAc3djL2NvcmUnO1xuaW1wb3J0IHtcbiAgcGFyc2VNZXNzYWdlLFxuICBTT0NLRVRfSU5GT19GSUxFTkFNRSxcbiAgdHlwZSBTb2NrZXRNZXNzYWdlLFxuICBzZXJpYWxpemVNZXNzYWdlLFxufSBmcm9tICcuL3NvY2tldC1zZXJ2ZXIuanMnO1xuXG50eXBlIERlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aCA9XG4gIGltcG9ydCgnQHdvcmtmbG93L2J1aWxkZXJzJykuRGVjb3JhdG9yT3B0aW9uc1dpdGhDb25maWdQYXRoO1xudHlwZSBXb3JrZmxvd1BhdHRlcm5NYXRjaCA9IGltcG9ydCgnQHdvcmtmbG93L2J1aWxkZXJzJykuV29ya2Zsb3dQYXR0ZXJuTWF0Y2g7XG5cbi8vIENhY2hlIGRlY29yYXRvciBvcHRpb25zIHBlciB3b3JraW5nIGRpcmVjdG9yeSB0byBhdm9pZCByZWFkaW5nIHRzY29uZmlnIGZvciBldmVyeSBmaWxlXG5jb25zdCBkZWNvcmF0b3JPcHRpb25zQ2FjaGUgPSBuZXcgTWFwPFxuICBzdHJpbmcsXG4gIFByb21pc2U8RGVjb3JhdG9yT3B0aW9uc1dpdGhDb25maWdQYXRoPlxuPigpO1xuLy8gQ2FjaGUgZm9yIHNoYXJlZCB1dGlsaXRpZXMgZnJvbSBAd29ya2Zsb3cvYnVpbGRlcnMgKEVTTSBtb2R1bGUgbG9hZGVkIGR5bmFtaWNhbGx5IGluIENvbW1vbkpTIGNvbnRleHQpXG5sZXQgY2FjaGVkQnVpbGRlcnNNb2R1bGU6IHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpIHwgbnVsbCA9IG51bGw7XG50eXBlIExvYWRlclN0YXRpY0RlcGVuZGVuY2llcyA9IHtcbiAgc3djUGx1Z2luUGF0aDogc3RyaW5nO1xuICBmaWxlczogc3RyaW5nW107XG59O1xubGV0IGNhY2hlZExvYWRlclN0YXRpY0RlcGVuZGVuY2llczogTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzIHwgbnVsbCA9IG51bGw7XG5cbnR5cGUgRGlzY292ZXJlZFBhdHRlcm5TdGF0ZSA9IHtcbiAgaGFzV29ya2Zsb3c6IGJvb2xlYW47XG4gIGhhc1N0ZXA6IGJvb2xlYW47XG4gIGhhc1NlcmRlOiBib29sZWFuO1xufTtcbmNvbnN0IGRpc2NvdmVyZWRQYXR0ZXJuU3RhdGVCeUZpbGVQYXRoID0gbmV3IE1hcDxcbiAgc3RyaW5nLFxuICBEaXNjb3ZlcmVkUGF0dGVyblN0YXRlXG4+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBzaG91bGROb3RpZnlTb2NrZXRGb3JEaXNjb3ZlcmVkUGF0dGVybihcbiAgcGF0dGVyblN0YXRlQ2hhbmdlZDogYm9vbGVhbixcbiAgcGF0dGVyblN0YXRlOiBEaXNjb3ZlcmVkUGF0dGVyblN0YXRlXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICBwYXR0ZXJuU3RhdGVDaGFuZ2VkIHx8XG4gICAgcGF0dGVyblN0YXRlLmhhc1dvcmtmbG93IHx8XG4gICAgcGF0dGVyblN0YXRlLmhhc1N0ZXAgfHxcbiAgICBwYXR0ZXJuU3RhdGUuaGFzU2VyZGVcbiAgKTtcbn1cblxuLy8gQ2FjaGUgc29ja2V0IGNvbm5lY3Rpb24gdG8gYXZvaWQgcmVjb25uZWN0aW5nIG9uIGV2ZXJ5IGZpbGUuXG5sZXQgc29ja2V0Q2xpZW50UHJvbWlzZTogUHJvbWlzZTxTb2NrZXQgfCBudWxsPiB8IG51bGwgPSBudWxsO1xubGV0IHNvY2tldENsaWVudDogU29ja2V0IHwgbnVsbCA9IG51bGw7XG5sZXQgc29ja2V0Q2xpZW50S2V5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxudHlwZSBTb2NrZXRDcmVkZW50aWFscyA9IHtcbiAgcG9ydDogbnVtYmVyO1xuICBhdXRoVG9rZW46IHN0cmluZztcbn07XG5cbi8qKlxuICogV3JhcCBhIFRDUCBjb25uZWN0IGZhaWx1cmUgd2l0aCBjb250ZXh0IGFib3V0IHdoZXJlIHRoZSBjb25uZWN0aW9uIHdhc1xuICogYXR0ZW1wdGVkLCB3aGVyZSB0aGUgY3JlZGVudGlhbHMgY2FtZSBmcm9tLCBhbmQgd2hpY2ggc291cmNlIGZpbGUgd2FzXG4gKiBiZWluZyBwcm9jZXNzZWQgd2hlbiBpdCBmYWlsZWQuIEVDT05OUkVGVVNFRCBpcyB0aGUgY29tbW9uIGNhc2UgaGVyZSwgYW5kXG4gKiB0aGUgbWVzc2FnZSBwb2ludHMgdGhlIHVzZXIgYXQgdGhlIG1vc3QgbGlrZWx5IHJvb3QgY2F1c2UgKHN0YWxlXG4gKiBzb2NrZXQtaW5mbyBmaWxlKS5cbiAqL1xuZnVuY3Rpb24gYW5ub3RhdGVDb25uZWN0aW9uRXJyb3IoXG4gIG9yaWdpbmFsRXJyb3I6IHVua25vd24sXG4gIGNyZWRlbnRpYWxzOiBTb2NrZXRDcmVkZW50aWFsc1xuKTogRXJyb3Ige1xuICBjb25zdCBlcnJvckNvZGUgPVxuICAgIG9yaWdpbmFsRXJyb3IgaW5zdGFuY2VvZiBFcnJvciAmJlxuICAgICdjb2RlJyBpbiBvcmlnaW5hbEVycm9yICYmXG4gICAgdHlwZW9mIChvcmlnaW5hbEVycm9yIGFzIHsgY29kZT86IHVua25vd24gfSkuY29kZSA9PT0gJ3N0cmluZydcbiAgICAgID8gKChvcmlnaW5hbEVycm9yIGFzIHsgY29kZTogc3RyaW5nIH0pLmNvZGUgYXMgc3RyaW5nKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgb3JpZ2luYWxFcnJvciBpbnN0YW5jZW9mIEVycm9yXG4gICAgICA/IG9yaWdpbmFsRXJyb3IubWVzc2FnZVxuICAgICAgOiBTdHJpbmcob3JpZ2luYWxFcnJvcik7XG5cbiAgY29uc3QgbGluZXMgPSBbXG4gICAgYFdvcmtmbG93IGRpc2NvdmVyeSBzb2NrZXQgY29ubmVjdCBmYWlsZWQ6ICR7ZXJyb3JDb2RlID8/IGVycm9yTWVzc2FnZX0gKDEyNy4wLjAuMToke2NyZWRlbnRpYWxzLnBvcnR9KWAsXG4gIF07XG5cbiAgY29uc3QgYW5ub3RhdGVkID0gbmV3IEVycm9yKGxpbmVzLmpvaW4oJ1xcbicpKTtcbiAgaWYgKG9yaWdpbmFsRXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIChhbm5vdGF0ZWQgYXMgeyBjYXVzZT86IHVua25vd24gfSkuY2F1c2UgPSBvcmlnaW5hbEVycm9yO1xuICB9XG4gIHJldHVybiBhbm5vdGF0ZWQ7XG59XG5cbmNvbnN0IFJPVVRFX1NUVUJfRklMRV9NQVJLRVIgPSAnV09SS0ZMT1dfUk9VVEVfU1RVQl9GSUxFJztcbmNvbnN0IFJPVVRFX1NUVUJfQlVJTERfV0FJVF9USU1FT1VUX01TID0gMTIwXzAwMDtcbmxldCBwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcblxuZnVuY3Rpb24gcmVnaXN0ZXJGaWxlRGVwZW5kZW5jeShcbiAgbG9hZGVyQ29udGV4dDogV29ya2Zsb3dMb2FkZXJDb250ZXh0LFxuICBkZXBlbmRlbmN5UGF0aDogc3RyaW5nXG4pOiB2b2lkIHtcbiAgbG9hZGVyQ29udGV4dC5hZGREZXBlbmRlbmN5Py4oZGVwZW5kZW5jeVBhdGgpO1xuICBsb2FkZXJDb250ZXh0LmFkZEJ1aWxkRGVwZW5kZW5jeT8uKGRlcGVuZGVuY3lQYXRoKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRGlzY292ZXJlZFBhdHRlcm5TdGF0ZShcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgbmV4dFN0YXRlOiBEaXNjb3ZlcmVkUGF0dGVyblN0YXRlXG4pOiB7IHNob3VsZE5vdGlmeTogYm9vbGVhbjsgcHJldmlvdXNTdGF0ZT86IERpc2NvdmVyZWRQYXR0ZXJuU3RhdGUgfSB7XG4gIGNvbnN0IHByZXZpb3VzU3RhdGUgPSBkaXNjb3ZlcmVkUGF0dGVyblN0YXRlQnlGaWxlUGF0aC5nZXQoZmlsZVBhdGgpO1xuICBjb25zdCBoYXNBbnlQYXR0ZXJuID1cbiAgICBuZXh0U3RhdGUuaGFzV29ya2Zsb3cgfHwgbmV4dFN0YXRlLmhhc1N0ZXAgfHwgbmV4dFN0YXRlLmhhc1NlcmRlO1xuXG4gIGlmICghaGFzQW55UGF0dGVybikge1xuICAgIGlmICghcHJldmlvdXNTdGF0ZSkge1xuICAgICAgcmV0dXJuIHsgc2hvdWxkTm90aWZ5OiBmYWxzZSB9O1xuICAgIH1cbiAgICBkaXNjb3ZlcmVkUGF0dGVyblN0YXRlQnlGaWxlUGF0aC5kZWxldGUoZmlsZVBhdGgpO1xuICAgIHJldHVybiB7IHNob3VsZE5vdGlmeTogdHJ1ZSwgcHJldmlvdXNTdGF0ZSB9O1xuICB9XG5cbiAgaWYgKFxuICAgIHByZXZpb3VzU3RhdGUgJiZcbiAgICBwcmV2aW91c1N0YXRlLmhhc1dvcmtmbG93ID09PSBuZXh0U3RhdGUuaGFzV29ya2Zsb3cgJiZcbiAgICBwcmV2aW91c1N0YXRlLmhhc1N0ZXAgPT09IG5leHRTdGF0ZS5oYXNTdGVwICYmXG4gICAgcHJldmlvdXNTdGF0ZS5oYXNTZXJkZSA9PT0gbmV4dFN0YXRlLmhhc1NlcmRlXG4gICkge1xuICAgIHJldHVybiB7IHNob3VsZE5vdGlmeTogZmFsc2UsIHByZXZpb3VzU3RhdGUgfTtcbiAgfVxuXG4gIGRpc2NvdmVyZWRQYXR0ZXJuU3RhdGVCeUZpbGVQYXRoLnNldChmaWxlUGF0aCwgbmV4dFN0YXRlKTtcbiAgcmV0dXJuIHsgc2hvdWxkTm90aWZ5OiB0cnVlLCBwcmV2aW91c1N0YXRlIH07XG59XG5cbmZ1bmN0aW9uIGFkZElmRXhpc3RzKGZpbGVzOiBTZXQ8c3RyaW5nPiwgZGVwZW5kZW5jeVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoZXhpc3RzU3luYyhkZXBlbmRlbmN5UGF0aCkpIHtcbiAgICBmaWxlcy5hZGQoZGVwZW5kZW5jeVBhdGgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXMoKTogTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzIHtcbiAgaWYgKGNhY2hlZExvYWRlclN0YXRpY0RlcGVuZGVuY2llcykge1xuICAgIHJldHVybiBjYWNoZWRMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXM7XG4gIH1cblxuICBjb25zdCBzd2NQbHVnaW5QYXRoID0gcmVxdWlyZS5yZXNvbHZlKCdAd29ya2Zsb3cvc3djLXBsdWdpbicpO1xuICBjb25zdCBzd2NQbHVnaW5CdWlsZEhhc2hQYXRoID0gcmVxdWlyZS5yZXNvbHZlKFxuICAgICdAd29ya2Zsb3cvc3djLXBsdWdpbi9idWlsZC1oYXNoLmpzb24nXG4gICk7XG4gIGNvbnN0IHdvcmtmbG93QnVpbGRlcnNQYXRoID0gcmVxdWlyZS5yZXNvbHZlKCdAd29ya2Zsb3cvYnVpbGRlcnMnKTtcblxuICAvLyBEZXJpdmUgcGFja2FnZS5qc29uIHBhdGhzIGZyb20gcmVzb2x2ZWQgZW50cnlwb2ludHMgdG8gYXZvaWRcbiAgLy8gVHVyYm9wYWNrIGxvYWRlci1ldmFsIGZhaWx1cmVzIGFyb3VuZCAuLi9wYWNrYWdlLmpzb24gcmVzb2x1dGlvbi5cbiAgY29uc3Qgc3djUGx1Z2luUGFja2FnZUpzb25QYXRoID0gam9pbihkaXJuYW1lKHN3Y1BsdWdpblBhdGgpLCAncGFja2FnZS5qc29uJyk7XG4gIGNvbnN0IHdvcmtmbG93QnVpbGRlcnNQYWNrYWdlSnNvblBhdGggPSBqb2luKFxuICAgIGRpcm5hbWUod29ya2Zsb3dCdWlsZGVyc1BhdGgpLFxuICAgICcuLi9wYWNrYWdlLmpzb24nXG4gICk7XG5cbiAgY29uc3QgZmlsZXMgPSBuZXcgU2V0PHN0cmluZz4oW1xuICAgIF9fZmlsZW5hbWUsXG4gICAgcmVxdWlyZS5yZXNvbHZlKCcuL3NvY2tldC1zZXJ2ZXInKSxcbiAgICBzd2NQbHVnaW5QYXRoLFxuICAgIHN3Y1BsdWdpbkJ1aWxkSGFzaFBhdGgsXG4gICAgd29ya2Zsb3dCdWlsZGVyc1BhdGgsXG4gIF0pO1xuICBhZGRJZkV4aXN0cyhmaWxlcywgc3djUGx1Z2luUGFja2FnZUpzb25QYXRoKTtcbiAgYWRkSWZFeGlzdHMoZmlsZXMsIHdvcmtmbG93QnVpbGRlcnNQYWNrYWdlSnNvblBhdGgpO1xuXG4gIGNhY2hlZExvYWRlclN0YXRpY0RlcGVuZGVuY2llcyA9IHtcbiAgICBzd2NQbHVnaW5QYXRoLFxuICAgIGZpbGVzOiBBcnJheS5mcm9tKGZpbGVzKSxcbiAgfTtcbiAgcmV0dXJuIGNhY2hlZExvYWRlclN0YXRpY0RlcGVuZGVuY2llcztcbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJUcmFuc2Zvcm1EZXBlbmRlbmNpZXMoXG4gIGxvYWRlckNvbnRleHQ6IFdvcmtmbG93TG9hZGVyQ29udGV4dFxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RhdGljRGVwZW5kZW5jaWVzID0gcmVzb2x2ZUxvYWRlclN0YXRpY0RlcGVuZGVuY2llcygpO1xuICBmb3IgKGNvbnN0IGRlcGVuZGVuY3lQYXRoIG9mIHN0YXRpY0RlcGVuZGVuY2llcy5maWxlcykge1xuICAgIHJlZ2lzdGVyRmlsZURlcGVuZGVuY3kobG9hZGVyQ29udGV4dCwgZGVwZW5kZW5jeVBhdGgpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRpY0RlcGVuZGVuY2llcy5zd2NQbHVnaW5QYXRoO1xufVxuXG5mdW5jdGlvbiByZXNldFNvY2tldENsaWVudChjYWNoZWRTb2NrZXQ/OiBTb2NrZXQpOiB2b2lkIHtcbiAgaWYgKGNhY2hlZFNvY2tldCAmJiBzb2NrZXRDbGllbnQgJiYgc29ja2V0Q2xpZW50ICE9PSBjYWNoZWRTb2NrZXQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBzb2NrZXRDbGllbnRQcm9taXNlID0gbnVsbDtcbiAgc29ja2V0Q2xpZW50ID0gbnVsbDtcbiAgc29ja2V0Q2xpZW50S2V5ID0gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd3JpdGVTb2NrZXRNZXNzYWdlKFxuICBzb2NrZXQ6IFNvY2tldCxcbiAgbWVzc2FnZTogc3RyaW5nXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNvY2tldC53cml0ZShtZXNzYWdlLCAoZXJyb3I/OiBFcnJvciB8IG51bGwpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRTb2NrZXRJbmZvRmlsZVBhdGgoKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGNvbmZpZ3VyZWRQYXRoID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfU09DS0VUX0lORk9fUEFUSDtcbiAgaWYgKGNvbmZpZ3VyZWRQYXRoKSB7XG4gICAgcmV0dXJuIGNvbmZpZ3VyZWRQYXRoO1xuICB9XG5cbiAgLy8gRmFsbGJhY2sgZm9yIHdvcmtlciBwcm9jZXNzZXMgdGhhdCBkb24ndCBpbmhlcml0IGR5bmFtaWMgZW52IHVwZGF0ZXNcbiAgLy8gZnJvbSB0aGUgcHJvY2VzcyB0aGF0IGNyZWF0ZWQgdGhlIHNvY2tldCBzZXJ2ZXIuXG4gIGNvbnN0IGRpc3REaXIgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19ORVhUX0RJU1RfRElSIHx8ICcubmV4dCc7XG4gIGNvbnN0IGN3ZEZhbGxiYWNrUGF0aCA9IGpvaW4ocHJvY2Vzcy5jd2QoKSwgZGlzdERpciwgU09DS0VUX0lORk9fRklMRU5BTUUpO1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IHByb2Nlc3MuZW52LldPUktGTE9XX1BST0pFQ1RfUk9PVDtcbiAgaWYgKHByb2plY3RSb290KSB7XG4gICAgY29uc3QgcHJvamVjdFJvb3RGYWxsYmFja1BhdGggPSBqb2luKFxuICAgICAgcHJvamVjdFJvb3QsXG4gICAgICBkaXN0RGlyLFxuICAgICAgU09DS0VUX0lORk9fRklMRU5BTUVcbiAgICApO1xuICAgIGlmIChleGlzdHNTeW5jKHByb2plY3RSb290RmFsbGJhY2tQYXRoKSkge1xuICAgICAgcmV0dXJuIHByb2plY3RSb290RmFsbGJhY2tQYXRoO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3dkRmFsbGJhY2tQYXRoO1xufVxuXG5mdW5jdGlvbiBnZXRTb2NrZXRDcmVkZW50aWFsc0Zyb21FbnYoKTogU29ja2V0Q3JlZGVudGlhbHMgfCBudWxsIHtcbiAgY29uc3Qgc29ja2V0UG9ydCA9IHByb2Nlc3MuZW52LldPUktGTE9XX1NPQ0tFVF9QT1JUO1xuICBjb25zdCBhdXRoVG9rZW4gPSBwcm9jZXNzLmVudi5XT1JLRkxPV19TT0NLRVRfQVVUSDtcbiAgaWYgKCFzb2NrZXRQb3J0IHx8ICFhdXRoVG9rZW4pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHBvcnQgPSBOdW1iZXIucGFyc2VJbnQoc29ja2V0UG9ydCwgMTApO1xuICBpZiAoTnVtYmVyLmlzTmFOKHBvcnQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHsgcG9ydCwgYXV0aFRva2VuIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFNvY2tldENyZWRlbnRpYWxzRnJvbUZpbGUoKTogUHJvbWlzZTxTb2NrZXRDcmVkZW50aWFscyB8IG51bGw+IHtcbiAgY29uc3Qgc29ja2V0SW5mb0ZpbGVQYXRoID0gZ2V0U29ja2V0SW5mb0ZpbGVQYXRoKCk7XG4gIGlmICghc29ja2V0SW5mb0ZpbGVQYXRoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKCFleGlzdHNTeW5jKHNvY2tldEluZm9GaWxlUGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmF3ID0gYXdhaXQgcmVhZEZpbGUoc29ja2V0SW5mb0ZpbGVQYXRoLCAndXRmOCcpO1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KSBhcyB7XG4gICAgICBwb3J0PzogdW5rbm93bjtcbiAgICAgIGF1dGhUb2tlbj86IHVua25vd247XG4gICAgfTtcbiAgICBjb25zdCBhdXRoVG9rZW4gPVxuICAgICAgdHlwZW9mIHBhcnNlZC5hdXRoVG9rZW4gPT09ICdzdHJpbmcnID8gcGFyc2VkLmF1dGhUb2tlbiA6IG51bGw7XG4gICAgY29uc3QgbnVtZXJpY1BvcnQgPVxuICAgICAgdHlwZW9mIHBhcnNlZC5wb3J0ID09PSAnbnVtYmVyJ1xuICAgICAgICA/IHBhcnNlZC5wb3J0XG4gICAgICAgIDogTnVtYmVyLnBhcnNlSW50KFN0cmluZyhwYXJzZWQucG9ydCksIDEwKTtcblxuICAgIGlmICghYXV0aFRva2VuIHx8IE51bWJlci5pc05hTihudW1lcmljUG9ydCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcG9ydDogbnVtZXJpY1BvcnQsXG4gICAgICBhdXRoVG9rZW4sXG4gICAgfTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0U29ja2V0Q3JlZGVudGlhbHMoKTogUHJvbWlzZTxTb2NrZXRDcmVkZW50aWFscyB8IG51bGw+IHtcbiAgY29uc3QgZW52Q3JlZGVudGlhbHMgPSBnZXRTb2NrZXRDcmVkZW50aWFsc0Zyb21FbnYoKTtcbiAgaWYgKGVudkNyZWRlbnRpYWxzKSB7XG4gICAgcmV0dXJuIGVudkNyZWRlbnRpYWxzO1xuICB9XG4gIHJldHVybiBhd2FpdCBnZXRTb2NrZXRDcmVkZW50aWFsc0Zyb21GaWxlKCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFNvY2tldENsaWVudCgpOiBQcm9taXNlPFNvY2tldCB8IG51bGw+IHtcbiAgY29uc3Qgc29ja2V0Q3JlZGVudGlhbHMgPSBhd2FpdCBnZXRTb2NrZXRDcmVkZW50aWFscygpO1xuICBpZiAoIXNvY2tldENyZWRlbnRpYWxzKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoc29ja2V0Q2xpZW50Py5kZXN0cm95ZWQpIHtcbiAgICByZXNldFNvY2tldENsaWVudChzb2NrZXRDbGllbnQpO1xuICB9XG5cbiAgY29uc3QgY3VycmVudFNvY2tldEtleSA9IGAke3NvY2tldENyZWRlbnRpYWxzLnBvcnR9OiR7c29ja2V0Q3JlZGVudGlhbHMuYXV0aFRva2VufWA7XG4gIGlmIChzb2NrZXRDbGllbnRLZXkgJiYgc29ja2V0Q2xpZW50S2V5ICE9PSBjdXJyZW50U29ja2V0S2V5KSB7XG4gICAgaWYgKHNvY2tldENsaWVudCkge1xuICAgICAgcmVzZXRTb2NrZXRDbGllbnQoc29ja2V0Q2xpZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzZXRTb2NrZXRDbGllbnQoKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNvY2tldENsaWVudFByb21pc2UpIHtcbiAgICBzb2NrZXRDbGllbnRQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Qoe1xuICAgICAgICAgIHBvcnQ6IHNvY2tldENyZWRlbnRpYWxzLnBvcnQsXG4gICAgICAgICAgaG9zdDogJzEyNy4wLjAuMScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIGNvbm5lY3Rpb25cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgIGNvbnN0IG9uQ29ubmVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgIHNvY2tldC5zZXROb0RlbGF5KHRydWUpO1xuICAgICAgICAgICAgY2xlYW51cCgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICAgIHJlamVjdChhbm5vdGF0ZUNvbm5lY3Rpb25FcnJvcihlcnJvciwgc29ja2V0Q3JlZGVudGlhbHMpKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgIGFubm90YXRlQ29ubmVjdGlvbkVycm9yKFxuICAgICAgICAgICAgICAgIG5ldyBFcnJvcignU29ja2V0IGNvbm5lY3Rpb24gdGltZW91dCcpLFxuICAgICAgICAgICAgICAgIHNvY2tldENyZWRlbnRpYWxzXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSwgMTAwMCk7XG4gICAgICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgIHNvY2tldC5vZmYoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuICAgICAgICAgICAgc29ja2V0Lm9mZignZXJyb3InLCBvbkVycm9yKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgc29ja2V0Lm9uKCdjb25uZWN0Jywgb25Db25uZWN0KTtcbiAgICAgICAgICBzb2NrZXQub24oJ2Vycm9yJywgb25FcnJvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNvY2tldC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICAgICAgcmVzZXRTb2NrZXRDbGllbnQoc29ja2V0KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNvY2tldC5vbignZXJyb3InLCAoKSA9PiB7XG4gICAgICAgICAgcmVzZXRTb2NrZXRDbGllbnQoc29ja2V0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc29ja2V0Q2xpZW50ID0gc29ja2V0O1xuICAgICAgICBzb2NrZXRDbGllbnRLZXkgPSBjdXJyZW50U29ja2V0S2V5O1xuICAgICAgICByZXR1cm4gc29ja2V0O1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgcmVzZXRTb2NrZXRDbGllbnQoKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSkoKTtcbiAgfVxuICByZXR1cm4gc29ja2V0Q2xpZW50UHJvbWlzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gbm90aWZ5U29ja2V0U2VydmVyKFxuICBmaWxlbmFtZTogc3RyaW5nLFxuICBoYXNXb3JrZmxvdzogYm9vbGVhbixcbiAgaGFzU3RlcDogYm9vbGVhbixcbiAgaGFzU2VyZGU6IGJvb2xlYW5cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBzb2NrZXRDcmVkZW50aWFscyA9IGF3YWl0IGdldFNvY2tldENyZWRlbnRpYWxzKCk7XG4gIGlmICghc29ja2V0Q3JlZGVudGlhbHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzb2NrZXQgPSBhd2FpdCBnZXRTb2NrZXRDbGllbnQoKTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFyaWFudDogbWlzc2luZyB3b3JrZmxvdyBzb2NrZXQgY29ubmVjdGlvbicpO1xuICB9XG5cbiAgY29uc3QgbWVzc2FnZTogU29ja2V0TWVzc2FnZSA9IHtcbiAgICB0eXBlOiAnZmlsZS1kaXNjb3ZlcmVkJyxcbiAgICBmaWxlUGF0aDogZmlsZW5hbWUsXG4gICAgaGFzV29ya2Zsb3csXG4gICAgaGFzU3RlcCxcbiAgICBoYXNTZXJkZSxcbiAgfTtcbiAgY29uc3Qgc2VyaWFsaXplZE1lc3NhZ2UgPSBzZXJpYWxpemVNZXNzYWdlKFxuICAgIG1lc3NhZ2UsXG4gICAgc29ja2V0Q3JlZGVudGlhbHMuYXV0aFRva2VuXG4gICk7XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCB3cml0ZVNvY2tldE1lc3NhZ2Uoc29ja2V0LCBzZXJpYWxpemVkTWVzc2FnZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmVzZXRTb2NrZXRDbGllbnQoc29ja2V0KTtcbiAgICBjb25zdCByZWNvbm5lY3RlZFNvY2tldCA9IGF3YWl0IGdldFNvY2tldENsaWVudCgpO1xuICAgIGlmICghcmVjb25uZWN0ZWRTb2NrZXQpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICBhd2FpdCB3cml0ZVNvY2tldE1lc3NhZ2UocmVjb25uZWN0ZWRTb2NrZXQsIHNlcmlhbGl6ZWRNZXNzYWdlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1dvcmtmbG93Um91dGVTdHViU291cmNlKHNvdXJjZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzb3VyY2UuaW5jbHVkZXMoUk9VVEVfU1RVQl9GSUxFX01BUktFUik7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNvY2tldENvbm5lY3Rpb24oXG4gIHNvY2tldENyZWRlbnRpYWxzOiBTb2NrZXRDcmVkZW50aWFscyxcbiAgdGltZW91dE1zID0gMV8wMDBcbik6IFByb21pc2U8U29ja2V0PiB7XG4gIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZTxTb2NrZXQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzb2NrZXQgPSBjb25uZWN0KHtcbiAgICAgIHBvcnQ6IHNvY2tldENyZWRlbnRpYWxzLnBvcnQsXG4gICAgICBob3N0OiAnMTI3LjAuMC4xJyxcbiAgICB9KTtcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgcmVqZWN0KFxuICAgICAgICBhbm5vdGF0ZUNvbm5lY3Rpb25FcnJvcihcbiAgICAgICAgICBuZXcgRXJyb3IoJ1NvY2tldCBjb25uZWN0aW9uIHRpbWVvdXQnKSxcbiAgICAgICAgICBzb2NrZXRDcmVkZW50aWFsc1xuICAgICAgICApXG4gICAgICApO1xuICAgIH0sIHRpbWVvdXRNcyk7XG4gICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHNvY2tldC5vZmYoJ2Nvbm5lY3QnLCBvbkNvbm5lY3QpO1xuICAgICAgc29ja2V0Lm9mZignZXJyb3InLCBvbkVycm9yKTtcbiAgICB9O1xuICAgIGNvbnN0IG9uQ29ubmVjdCA9ICgpID0+IHtcbiAgICAgIHNvY2tldC5zZXROb0RlbGF5KHRydWUpO1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVzb2x2ZShzb2NrZXQpO1xuICAgIH07XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHNvY2tldC5kZXN0cm95KCk7XG4gICAgICByZWplY3QoYW5ub3RhdGVDb25uZWN0aW9uRXJyb3IoZXJyb3IsIHNvY2tldENyZWRlbnRpYWxzKSk7XG4gICAgfTtcblxuICAgIHNvY2tldC5vbignY29ubmVjdCcsIG9uQ29ubmVjdCk7XG4gICAgc29ja2V0Lm9uKCdlcnJvcicsIG9uRXJyb3IpO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckRlZmVycmVkQnVpbGRDb21wbGV0ZShcbiAgc29ja2V0OiBTb2NrZXQsXG4gIGF1dGhUb2tlbjogc3RyaW5nLFxuICB0aW1lb3V0TXMgPSBST1VURV9TVFVCX0JVSUxEX1dBSVRfVElNRU9VVF9NU1xuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgYnVmZmVyID0gJyc7XG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVqZWN0KFxuICAgICAgICBuZXcgRXJyb3IoJ1RpbWVkIG91dCB3YWl0aW5nIGZvciBkZWZlcnJlZCByb3V0ZSBidWlsZCBjb21wbGV0aW9uJylcbiAgICAgICk7XG4gICAgfSwgdGltZW91dE1zKTtcbiAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgc29ja2V0Lm9mZignZGF0YScsIG9uRGF0YSk7XG4gICAgICBzb2NrZXQub2ZmKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgICAgc29ja2V0Lm9mZignY2xvc2UnLCBvbkNsb3NlKTtcbiAgICAgIHNvY2tldC5vZmYoJ2VuZCcsIG9uQ2xvc2UpO1xuICAgIH07XG4gICAgY29uc3Qgb25FcnJvciA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGNsZWFudXAoKTtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfTtcbiAgICBjb25zdCBvbkNsb3NlID0gKCkgPT4ge1xuICAgICAgY2xlYW51cCgpO1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcignU29ja2V0IGNsb3NlZCBiZWZvcmUgZGVmZXJyZWQgcm91dGUgYnVpbGQgY29tcGxldGVkJykpO1xuICAgIH07XG4gICAgY29uc3Qgb25EYXRhID0gKGNodW5rOiBCdWZmZXIpID0+IHtcbiAgICAgIGJ1ZmZlciArPSBjaHVuay50b1N0cmluZygpO1xuICAgICAgbGV0IG5ld2xpbmVJbmRleCA9IGJ1ZmZlci5pbmRleE9mKCdcXG4nKTtcbiAgICAgIHdoaWxlIChuZXdsaW5lSW5kZXggIT09IC0xKSB7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBidWZmZXIuc2xpY2UoMCwgbmV3bGluZUluZGV4KTtcbiAgICAgICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKG5ld2xpbmVJbmRleCArIDEpO1xuICAgICAgICBuZXdsaW5lSW5kZXggPSBidWZmZXIuaW5kZXhPZignXFxuJyk7XG5cbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHBhcnNlTWVzc2FnZShsaW5lLCBhdXRoVG9rZW4pO1xuICAgICAgICBpZiAobWVzc2FnZT8udHlwZSA9PT0gJ2J1aWxkLWNvbXBsZXRlJykge1xuICAgICAgICAgIGNsZWFudXAoKTtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNvY2tldC5vbignZGF0YScsIG9uRGF0YSk7XG4gICAgc29ja2V0Lm9uKCdlcnJvcicsIG9uRXJyb3IpO1xuICAgIHNvY2tldC5vbignY2xvc2UnLCBvbkNsb3NlKTtcbiAgICBzb2NrZXQub24oJ2VuZCcsIG9uQ2xvc2UpO1xuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdHJpZ2dlckRlZmVycmVkUm91dGVTdHViQnVpbGRBbmRXYWl0KCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBzb2NrZXRDcmVkZW50aWFscyA9IGF3YWl0IGdldFNvY2tldENyZWRlbnRpYWxzKCk7XG4gIGlmICghc29ja2V0Q3JlZGVudGlhbHMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3Qgc29ja2V0ID0gYXdhaXQgY3JlYXRlU29ja2V0Q29ubmVjdGlvbihzb2NrZXRDcmVkZW50aWFscyk7XG4gIHRyeSB7XG4gICAgYXdhaXQgd3JpdGVTb2NrZXRNZXNzYWdlKFxuICAgICAgc29ja2V0LFxuICAgICAgc2VyaWFsaXplTWVzc2FnZSh7IHR5cGU6ICd0cmlnZ2VyLWJ1aWxkJyB9LCBzb2NrZXRDcmVkZW50aWFscy5hdXRoVG9rZW4pXG4gICAgKTtcbiAgICBhd2FpdCB3YWl0Rm9yRGVmZXJyZWRCdWlsZENvbXBsZXRlKHNvY2tldCwgc29ja2V0Q3JlZGVudGlhbHMuYXV0aFRva2VuKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBzb2NrZXQuZGVzdHJveSgpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZURlZmVycmVkUm91dGVTdHViQnVpbGRBbmRXYWl0KCk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAocGVuZGluZ0RlZmVycmVkUm91dGVTdHViQnVpbGRQcm9taXNlKSB7XG4gICAgcmV0dXJuIHBlbmRpbmdEZWZlcnJlZFJvdXRlU3R1YkJ1aWxkUHJvbWlzZTtcbiAgfVxuICBjb25zdCBwZW5kaW5nUHJvbWlzZSA9IHRyaWdnZXJEZWZlcnJlZFJvdXRlU3R1YkJ1aWxkQW5kV2FpdCgpO1xuICBwZW5kaW5nRGVmZXJyZWRSb3V0ZVN0dWJCdWlsZFByb21pc2UgPSBwZW5kaW5nUHJvbWlzZS5maW5hbGx5KCgpID0+IHtcbiAgICBpZiAocGVuZGluZ0RlZmVycmVkUm91dGVTdHViQnVpbGRQcm9taXNlID09PSBwZW5kaW5nUHJvbWlzZSkge1xuICAgICAgcGVuZGluZ0RlZmVycmVkUm91dGVTdHViQnVpbGRQcm9taXNlID0gbnVsbDtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcGVuZGluZ0RlZmVycmVkUm91dGVTdHViQnVpbGRQcm9taXNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRCdWlsZGVyc01vZHVsZSgpOiBQcm9taXNlPFxuICB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKVxuPiB7XG4gIGlmIChjYWNoZWRCdWlsZGVyc01vZHVsZSkge1xuICAgIHJldHVybiBjYWNoZWRCdWlsZGVyc01vZHVsZTtcbiAgfVxuICAvLyBEeW5hbWljIGltcG9ydCB0byBoYW5kbGUgRVNNIG1vZHVsZSBmcm9tIENvbW1vbkpTIGNvbnRleHRcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc2VjdXJpdHkvbm9HbG9iYWxFdmFsOiBOZWVkIHRvIHVzZSBldmFsIGhlcmUgdG8gYXZvaWQgVHlwZVNjcmlwdCBmcm9tIHRyYW5zcGlsaW5nIHRoZSBpbXBvcnQgc3RhdGVtZW50IGludG8gYHJlcXVpcmUoKWBcbiAgY2FjaGVkQnVpbGRlcnNNb2R1bGUgPSAoYXdhaXQgZXZhbChcbiAgICAnaW1wb3J0KFwiQHdvcmtmbG93L2J1aWxkZXJzXCIpJ1xuICApKSBhcyB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKTtcbiAgcmV0dXJuIGNhY2hlZEJ1aWxkZXJzTW9kdWxlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXREZWNvcmF0b3JPcHRpb25zKFxuICB3b3JraW5nRGlyOiBzdHJpbmdcbik6IFByb21pc2U8RGVjb3JhdG9yT3B0aW9uc1dpdGhDb25maWdQYXRoPiB7XG4gIGNvbnN0IGNhY2hlZCA9IGRlY29yYXRvck9wdGlvbnNDYWNoZS5nZXQod29ya2luZ0Rpcik7XG4gIGlmIChjYWNoZWQpIHtcbiAgICByZXR1cm4gY2FjaGVkO1xuICB9XG5cbiAgY29uc3QgcHJvbWlzZSA9IChhc3luYyAoKTogUHJvbWlzZTxEZWNvcmF0b3JPcHRpb25zV2l0aENvbmZpZ1BhdGg+ID0+IHtcbiAgICBjb25zdCB7IGdldERlY29yYXRvck9wdGlvbnNGb3JEaXJlY3RvcnlXaXRoQ29uZmlnUGF0aCB9ID1cbiAgICAgIGF3YWl0IGdldEJ1aWxkZXJzTW9kdWxlKCk7XG4gICAgcmV0dXJuIGdldERlY29yYXRvck9wdGlvbnNGb3JEaXJlY3RvcnlXaXRoQ29uZmlnUGF0aCh3b3JraW5nRGlyKTtcbiAgfSkoKTtcblxuICBkZWNvcmF0b3JPcHRpb25zQ2FjaGUuc2V0KHdvcmtpbmdEaXIsIHByb21pc2UpO1xuICByZXR1cm4gcHJvbWlzZTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZGV0ZWN0UGF0dGVybnMoc291cmNlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtmbG93UGF0dGVybk1hdGNoPiB7XG4gIGNvbnN0IHsgZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIGRldGVjdFdvcmtmbG93UGF0dGVybnMoc291cmNlKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY2hlY2tHZW5lcmF0ZWRGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgeyBpc0dlbmVyYXRlZFdvcmtmbG93RmlsZSB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlKGZpbGVQYXRoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY2hlY2tTaG91bGRUcmFuc2Zvcm0oXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIHBhdHRlcm5zOiBXb3JrZmxvd1BhdHRlcm5NYXRjaFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHsgc2hvdWxkVHJhbnNmb3JtRmlsZSB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIHNob3VsZFRyYW5zZm9ybUZpbGUoZmlsZVBhdGgsIHBhdHRlcm5zKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0TW9kdWxlU3BlY2lmaWVyKFxuICBmaWxlUGF0aDogc3RyaW5nLFxuICBwcm9qZWN0Um9vdDogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB7IHJlc29sdmVNb2R1bGVTcGVjaWZpZXIgfSA9IGF3YWl0IGdldEJ1aWxkZXJzTW9kdWxlKCk7XG4gIHJldHVybiByZXNvbHZlTW9kdWxlU3BlY2lmaWVyKGZpbGVQYXRoLCBwcm9qZWN0Um9vdCkubW9kdWxlU3BlY2lmaWVyO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlV29ya2Zsb3dBbGlhc1BhdGgoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIHdvcmtpbmdEaXI6IHN0cmluZ1xuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgeyByZXNvbHZlV29ya2Zsb3dBbGlhc1JlbGF0aXZlUGF0aCB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoKGZpbGVQYXRoLCB3b3JraW5nRGlyKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UmVsYXRpdmVGaWxlbmFtZUZvclN3YyhcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgd29ya2luZ0Rpcjogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBub3JtYWxpemVkV29ya2luZ0RpciA9IHdvcmtpbmdEaXJcbiAgICAucmVwbGFjZSgvXFxcXC9nLCAnLycpXG4gICAgLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG4gIGNvbnN0IG5vcm1hbGl6ZWRGaWxlcGF0aCA9IGZpbGVuYW1lLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAvLyBXaW5kb3dzIGZpeDogVXNlIGNhc2UtaW5zZW5zaXRpdmUgY29tcGFyaXNvbiB0byB3b3JrIGFyb3VuZCBkcml2ZSBsZXR0ZXIgY2FzaW5nIGlzc3Vlc1xuICBjb25zdCBsb3dlcldkID0gbm9ybWFsaXplZFdvcmtpbmdEaXIudG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgbG93ZXJQYXRoID0gbm9ybWFsaXplZEZpbGVwYXRoLnRvTG93ZXJDYXNlKCk7XG5cbiAgbGV0IHJlbGF0aXZlRmlsZW5hbWU6IHN0cmluZztcbiAgaWYgKGxvd2VyUGF0aC5zdGFydHNXaXRoKGAke2xvd2VyV2R9L2ApKSB7XG4gICAgLy8gRmlsZSBpcyB1bmRlciB3b3JraW5nIGRpcmVjdG9yeSAtIG1hbnVhbGx5IGNhbGN1bGF0ZSByZWxhdGl2ZSBwYXRoXG4gICAgcmVsYXRpdmVGaWxlbmFtZSA9IG5vcm1hbGl6ZWRGaWxlcGF0aC5zdWJzdHJpbmcoXG4gICAgICBub3JtYWxpemVkV29ya2luZ0Rpci5sZW5ndGggKyAxXG4gICAgKTtcbiAgfSBlbHNlIGlmIChsb3dlclBhdGggPT09IGxvd2VyV2QpIHtcbiAgICAvLyBGaWxlIElTIHRoZSB3b3JraW5nIGRpcmVjdG9yeSAoc2hvdWxkbid0IGhhcHBlbilcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gJy4nO1xuICB9IGVsc2Uge1xuICAgIC8vIFVzZSByZWxhdGl2ZSgpIGZvciBmaWxlcyBvdXRzaWRlIHdvcmtpbmcgZGlyZWN0b3J5XG4gICAgcmVsYXRpdmVGaWxlbmFtZSA9IHJlbGF0aXZlKHdvcmtpbmdEaXIsIGZpbGVuYW1lKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICBpZiAocmVsYXRpdmVGaWxlbmFtZS5zdGFydHNXaXRoKCcuLi8nKSkge1xuICAgICAgY29uc3QgYWxpYXNlZFJlbGF0aXZlUGF0aCA9IGF3YWl0IHJlc29sdmVXb3JrZmxvd0FsaWFzUGF0aChcbiAgICAgICAgZmlsZW5hbWUsXG4gICAgICAgIHdvcmtpbmdEaXJcbiAgICAgICk7XG4gICAgICBpZiAoYWxpYXNlZFJlbGF0aXZlUGF0aCkge1xuICAgICAgICByZWxhdGl2ZUZpbGVuYW1lID0gYWxpYXNlZFJlbGF0aXZlUGF0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbGF0aXZlRmlsZW5hbWUgPSByZWxhdGl2ZUZpbGVuYW1lXG4gICAgICAgICAgLnNwbGl0KCcvJylcbiAgICAgICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0ICE9PSAnLi4nKVxuICAgICAgICAgIC5qb2luKCcvJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRmluYWwgc2FmZXR5IGNoZWNrIC0gZW5zdXJlIHdlIG5ldmVyIHBhc3MgYW4gYWJzb2x1dGUgcGF0aCB0byBTV0NcbiAgaWYgKHJlbGF0aXZlRmlsZW5hbWUuaW5jbHVkZXMoJzonKSB8fCByZWxhdGl2ZUZpbGVuYW1lLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgIC8vIFRoaXMgc2hvdWxkIHJhcmVseSBoYXBwZW4sIGJ1dCB1c2UgZmlsZW5hbWUgc3BsaXQgYXMgbGFzdCByZXNvcnRcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gbm9ybWFsaXplZEZpbGVwYXRoLnNwbGl0KCcvJykucG9wKCkgfHwgJ3Vua25vd24udHMnO1xuICB9XG5cbiAgcmV0dXJuIHJlbGF0aXZlRmlsZW5hbWU7XG59XG5cbi8vIFRoaXMgbG9hZGVyIGFwcGxpZXMgdGhlIFwidXNlIHdvcmtmbG93XCIvXCJ1c2Ugc3RlcFwiIHRyYW5zZm9ybS5cbi8vIEFsbCBmaWxlcyB1c2Ugc3RlcCBtb2RlOyB0aGUgU1dDIHBsdWdpbiBkZWNpZGVzIHBlci1mdW5jdGlvbiB3aGV0aGVyXG4vLyB0byBlbWl0IHdvcmtmbG93IG9yIHN0ZXAgYmluZGluZ3MgYmFzZWQgb24gdGhlIHNvdXJjZSdzIGRpcmVjdGl2ZXMuXG50eXBlIFdvcmtmbG93TG9hZGVyQ29udGV4dCA9IHtcbiAgcmVzb3VyY2VQYXRoOiBzdHJpbmc7XG4gIGFzeW5jPzogKCkgPT4gKFxuICAgIGVycm9yOiBFcnJvciB8IG51bGwsXG4gICAgY29udGVudD86IHN0cmluZyxcbiAgICBzb3VyY2VNYXA/OiBhbnlcbiAgKSA9PiB2b2lkO1xuICBhZGREZXBlbmRlbmN5PzogKGRlcGVuZGVuY3k6IHN0cmluZykgPT4gdm9pZDtcbiAgYWRkQnVpbGREZXBlbmRlbmN5PzogKGRlcGVuZGVuY3k6IHN0cmluZykgPT4gdm9pZDtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHdvcmtmbG93TG9hZGVyKFxuICB0aGlzOiBXb3JrZmxvd0xvYWRlckNvbnRleHQsXG4gIHNvdXJjZTogc3RyaW5nIHwgQnVmZmVyLFxuICBzb3VyY2VNYXA6IGFueVxuKTogc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+IHwgdm9pZCB7XG4gIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5hc3luYz8uKCk7XG4gIGNvbnN0IHJ1biA9IGFzeW5jICgpOiBQcm9taXNlPHsgY29kZTogc3RyaW5nOyBtYXA6IGFueSB9PiA9PiB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSB0aGlzLnJlc291cmNlUGF0aDtcbiAgICBjb25zdCBub3JtYWxpemVkU291cmNlID0gc291cmNlLnRvU3RyaW5nKCk7XG4gICAgY29uc3Qgd29ya2luZ0RpciA9IHByb2Nlc3MuY3dkKCk7XG4gICAgY29uc3Qgc3djUGx1Z2luUGF0aCA9IHJlZ2lzdGVyVHJhbnNmb3JtRGVwZW5kZW5jaWVzKHRoaXMpO1xuICAgIGNvbnN0IHNvdXJjZUZvclRyYW5zZm9ybSA9IG5vcm1hbGl6ZWRTb3VyY2U7XG5cbiAgICBjb25zdCBpc0dlbmVyYXRlZFdvcmtmbG93RmlsZSA9IGF3YWl0IGNoZWNrR2VuZXJhdGVkRmlsZShmaWxlbmFtZSk7XG4gICAgLy8gU2tpcCBnZW5lcmF0ZWQgd29ya2Zsb3cgcm91dGUgZmlsZXMgdG8gYXZvaWQgcmUtcHJvY2Vzc2luZyB0aGVtLlxuICAgIC8vIERlZmVycmVkIHJvdXRlIHN0dWJzIGFyZSBhIHNwZWNpYWwgY2FzZTogd2FpdCBmb3IgdGhlIGdlbmVyYXRlZCByb3V0ZVxuICAgIC8vIG91dHB1dCB0byBiZWNvbWUgYXZhaWxhYmxlIGJlZm9yZSByZXR1cm5pbmcuXG4gICAgaWYgKGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHByb2Nlc3MuZW52LldPUktGTE9XX05FWFRfTEFaWV9ESVNDT1ZFUlkgPT09ICcxJyAmJlxuICAgICAgICBpc1dvcmtmbG93Um91dGVTdHViU291cmNlKG5vcm1hbGl6ZWRTb3VyY2UpXG4gICAgICApIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBlbnN1cmVEZWZlcnJlZFJvdXRlU3R1YkJ1aWxkQW5kV2FpdCgpO1xuICAgICAgICAgIGNvbnN0IHJlZnJlc2hlZFNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGZpbGVuYW1lLCAndXRmOCcpO1xuICAgICAgICAgIGlmICghaXNXb3JrZmxvd1JvdXRlU3R1YlNvdXJjZShyZWZyZXNoZWRTb3VyY2UpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBjb2RlOiByZWZyZXNoZWRTb3VyY2UsIG1hcDogc291cmNlTWFwIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIGBbd29ya2Zsb3ddIEZhaWxlZCB3YWl0aW5nIGZvciBkZWZlcnJlZCByb3V0ZSBidWlsZCBmb3IgJHtmaWxlbmFtZX0sIHVzaW5nIHN0dWIgb3V0cHV0YCxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHsgY29kZTogbm9ybWFsaXplZFNvdXJjZSwgbWFwOiBzb3VyY2VNYXAgfTtcbiAgICB9XG5cbiAgICAvLyBEZXRlY3Qgd29ya2Zsb3cgcGF0dGVybnMgaW4gdGhlIHNvdXJjZSBjb2RlLlxuICAgIGNvbnN0IHBhdHRlcm5zID0gYXdhaXQgZGV0ZWN0UGF0dGVybnMoc291cmNlRm9yVHJhbnNmb3JtKTtcbiAgICAvLyBBbHdheXMgbm90aWZ5IGRpc2NvdmVyeSB0cmFja2luZywgZXZlbiBmb3IgYGZhbHNlL2ZhbHNlYCwgc28gZmlsZXMgdGhhdFxuICAgIC8vIHByZXZpb3VzbHkgaGFkIHdvcmtmbG93L3N0ZXAgdXNhZ2UgYXJlIHJlbW92ZWQgZnJvbSB0aGUgdHJhY2tlZCBzZXRzLlxuICAgIGNvbnN0IG5leHRQYXR0ZXJuU3RhdGU6IERpc2NvdmVyZWRQYXR0ZXJuU3RhdGUgPSB7XG4gICAgICBoYXNXb3JrZmxvdzogcGF0dGVybnMuaGFzVXNlV29ya2Zsb3csXG4gICAgICBoYXNTdGVwOiBwYXR0ZXJucy5oYXNVc2VTdGVwLFxuICAgICAgaGFzU2VyZGU6IHBhdHRlcm5zLmhhc1NlcmRlLFxuICAgIH07XG4gICAgY29uc3QgeyBzaG91bGROb3RpZnkgfSA9IHVwZGF0ZURpc2NvdmVyZWRQYXR0ZXJuU3RhdGUoXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIG5leHRQYXR0ZXJuU3RhdGVcbiAgICApO1xuICAgIGlmIChcbiAgICAgIHNob3VsZE5vdGlmeVNvY2tldEZvckRpc2NvdmVyZWRQYXR0ZXJuKHNob3VsZE5vdGlmeSwgbmV4dFBhdHRlcm5TdGF0ZSlcbiAgICApIHtcbiAgICAgIGF3YWl0IG5vdGlmeVNvY2tldFNlcnZlcihcbiAgICAgICAgZmlsZW5hbWUsXG4gICAgICAgIG5leHRQYXR0ZXJuU3RhdGUuaGFzV29ya2Zsb3csXG4gICAgICAgIG5leHRQYXR0ZXJuU3RhdGUuaGFzU3RlcCxcbiAgICAgICAgbmV4dFBhdHRlcm5TdGF0ZS5oYXNTZXJkZVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBmaWxlIG5lZWRzIHRyYW5zZm9ybWF0aW9uIGJhc2VkIG9uIHBhdHRlcm5zIGFuZCBwYXRoXG4gICAgaWYgKCEoYXdhaXQgY2hlY2tTaG91bGRUcmFuc2Zvcm0oZmlsZW5hbWUsIHBhdHRlcm5zKSkpIHtcbiAgICAgIHJldHVybiB7IGNvZGU6IG5vcm1hbGl6ZWRTb3VyY2UsIG1hcDogc291cmNlTWFwIH07XG4gICAgfVxuXG4gICAgY29uc3QgaXNUeXBlU2NyaXB0ID1cbiAgICAgIGZpbGVuYW1lLmVuZHNXaXRoKCcudHMnKSB8fFxuICAgICAgZmlsZW5hbWUuZW5kc1dpdGgoJy50c3gnKSB8fFxuICAgICAgZmlsZW5hbWUuZW5kc1dpdGgoJy5tdHMnKSB8fFxuICAgICAgZmlsZW5hbWUuZW5kc1dpdGgoJy5jdHMnKTtcblxuICAgIC8vIENhbGN1bGF0ZSByZWxhdGl2ZSBmaWxlbmFtZSBmb3IgU1dDIHBsdWdpblxuICAgIC8vIFRoZSBTV0MgcGx1Z2luIHVzZXMgZmlsZW5hbWUgdG8gZ2VuZXJhdGUgd29ya2Zsb3dJZCwgc28gaXQgbXVzdCBiZSByZWxhdGl2ZVxuICAgIGNvbnN0IHJlbGF0aXZlRmlsZW5hbWUgPSBhd2FpdCBnZXRSZWxhdGl2ZUZpbGVuYW1lRm9yU3djKFxuICAgICAgZmlsZW5hbWUsXG4gICAgICB3b3JraW5nRGlyXG4gICAgKTtcblxuICAgIC8vIEdldCBkZWNvcmF0b3Igb3B0aW9ucyBmcm9tIHRzY29uZmlnIChjYWNoZWQgcGVyIHdvcmtpbmcgZGlyZWN0b3J5KVxuICAgIGNvbnN0IHsgb3B0aW9uczogZGVjb3JhdG9yT3B0aW9ucywgY29uZmlnUGF0aCB9ID1cbiAgICAgIGF3YWl0IGdldERlY29yYXRvck9wdGlvbnMod29ya2luZ0Rpcik7XG4gICAgaWYgKGNvbmZpZ1BhdGgpIHtcbiAgICAgIHJlZ2lzdGVyRmlsZURlcGVuZGVuY3kodGhpcywgY29uZmlnUGF0aCk7XG4gICAgfVxuXG4gICAgLy8gUmVzb2x2ZSBtb2R1bGUgc3BlY2lmaWVyIGZvciBwYWNrYWdlcyAobm9kZV9tb2R1bGVzIG9yIHdvcmtzcGFjZSBwYWNrYWdlcylcbiAgICBjb25zdCBtb2R1bGVTcGVjaWZpZXIgPSBhd2FpdCBnZXRNb2R1bGVTcGVjaWZpZXIoZmlsZW5hbWUsIHdvcmtpbmdEaXIpO1xuICAgIGNvbnN0IG1vZGUgPSAnc3RlcCc7XG5cbiAgICAvLyBUcmFuc2Zvcm0gd2l0aCBTV0NcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0cmFuc2Zvcm0oc291cmNlRm9yVHJhbnNmb3JtLCB7XG4gICAgICBmaWxlbmFtZTogcmVsYXRpdmVGaWxlbmFtZSxcbiAgICAgIGpzYzoge1xuICAgICAgICBwYXJzZXI6IHtcbiAgICAgICAgICAuLi4oaXNUeXBlU2NyaXB0XG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBzeW50YXg6ICd0eXBlc2NyaXB0JyxcbiAgICAgICAgICAgICAgICB0c3g6IGZpbGVuYW1lLmVuZHNXaXRoKCcudHN4JyksXG4gICAgICAgICAgICAgICAgZGVjb3JhdG9yczogZGVjb3JhdG9yT3B0aW9ucy5kZWNvcmF0b3JzLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICBzeW50YXg6ICdlY21hc2NyaXB0JyxcbiAgICAgICAgICAgICAgICBqc3g6IGZpbGVuYW1lLmVuZHNXaXRoKCcuanN4JyksXG4gICAgICAgICAgICAgICAgZGVjb3JhdG9yczogZGVjb3JhdG9yT3B0aW9ucy5kZWNvcmF0b3JzLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgICAgdGFyZ2V0OiAnZXMyMDIyJyxcbiAgICAgICAgZXhwZXJpbWVudGFsOiB7XG4gICAgICAgICAgcGx1Z2luczogW1tzd2NQbHVnaW5QYXRoLCB7IG1vZGUsIG1vZHVsZVNwZWNpZmllciB9XV0sXG4gICAgICAgIH0sXG4gICAgICAgIHRyYW5zZm9ybToge1xuICAgICAgICAgIHJlYWN0OiB7XG4gICAgICAgICAgICBydW50aW1lOiAncHJlc2VydmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbGVnYWN5RGVjb3JhdG9yOiBkZWNvcmF0b3JPcHRpb25zLmxlZ2FjeURlY29yYXRvcixcbiAgICAgICAgICBkZWNvcmF0b3JNZXRhZGF0YTogZGVjb3JhdG9yT3B0aW9ucy5kZWNvcmF0b3JNZXRhZGF0YSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBtaW5pZnk6IGZhbHNlLFxuICAgICAgaW5wdXRTb3VyY2VNYXA6IHNvdXJjZU1hcCxcbiAgICAgIHNvdXJjZU1hcHM6IHRydWUsXG4gICAgICBpbmxpbmVTb3VyY2VzQ29udGVudDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGxldCB0cmFuc2Zvcm1lZE1hcCA9IHNvdXJjZU1hcDtcbiAgICBpZiAodHlwZW9mIHJlc3VsdC5tYXAgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0cmFuc2Zvcm1lZE1hcCA9IEpTT04ucGFyc2UocmVzdWx0Lm1hcCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgdHJhbnNmb3JtZWRNYXAgPSByZXN1bHQubWFwO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVzdWx0Lm1hcCkge1xuICAgICAgdHJhbnNmb3JtZWRNYXAgPSByZXN1bHQubWFwO1xuICAgIH1cblxuICAgIHJldHVybiB7IGNvZGU6IHJlc3VsdC5jb2RlLCBtYXA6IHRyYW5zZm9ybWVkTWFwIH07XG4gIH07XG5cbiAgaWYgKCFjYWxsYmFjaykge1xuICAgIHJldHVybiBydW4oKS50aGVuKChyZXN1bHQpID0+IHJlc3VsdC5jb2RlKTtcbiAgfVxuXG4gIHZvaWQgcnVuKClcbiAgICAudGhlbigocmVzdWx0KSA9PiBjYWxsYmFjayhudWxsLCByZXN1bHQuY29kZSwgcmVzdWx0Lm1hcCkpXG4gICAgLmNhdGNoKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgY2FsbGJhY2soZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpKTtcbiAgICB9KTtcbn1cbiJdfQ==
225
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW9OQSxpQ0E2R0M7QUFqVUQscUNBQXFDO0FBQ3JDLHlDQUFvRDtBQUNwRCxvQ0FBc0M7QUFNdEMseUZBQXlGO0FBQ3pGLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBR2xDLENBQUM7QUFDSix5R0FBeUc7QUFDekcsSUFBSSxvQkFBb0IsR0FBK0MsSUFBSSxDQUFDO0FBSzVFLElBQUksOEJBQThCLEdBQW9DLElBQUksQ0FBQztBQUUzRSxTQUFTLHNCQUFzQixDQUM3QixhQUFvQyxFQUNwQyxjQUFzQjtJQUV0QixhQUFhLENBQUMsYUFBYSxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDOUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVELFNBQVMsV0FBVyxDQUFDLEtBQWtCLEVBQUUsY0FBc0I7SUFDN0QsSUFBSSxJQUFBLG9CQUFVLEVBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUMvQixLQUFLLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUywrQkFBK0I7SUFDdEMsSUFBSSw4QkFBOEIsRUFBRSxDQUFDO1FBQ25DLE9BQU8sOEJBQThCLENBQUM7SUFDeEMsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUM5RCxNQUFNLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQzVDLHNDQUFzQyxDQUN2QyxDQUFDO0lBQ0YsTUFBTSxvQkFBb0IsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFFbkUsK0RBQStEO0lBQy9ELG9FQUFvRTtJQUNwRSxNQUFNLHdCQUF3QixHQUFHLElBQUEsZ0JB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aW1wb3J0IHsgZGlybmFtZSwgam9pbiwgcmVsYXRpdmUgfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgdHJhbnNmb3JtIH0gZnJvbSAnQHN3Yy9jb3JlJztcblxudHlwZSBEZWNvcmF0b3JPcHRpb25zV2l0aENvbmZpZ1BhdGggPVxuICBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpLkRlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aDtcbnR5cGUgV29ya2Zsb3dQYXR0ZXJuTWF0Y2ggPSBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpLldvcmtmbG93UGF0dGVybk1hdGNoO1xuXG4vLyBDYWNoZSBkZWNvcmF0b3Igb3B0aW9ucyBwZXIgd29ya2luZyBkaXJlY3RvcnkgdG8gYXZvaWQgcmVhZGluZyB0c2NvbmZpZyBmb3IgZXZlcnkgZmlsZVxuY29uc3QgZGVjb3JhdG9yT3B0aW9uc0NhY2hlID0gbmV3IE1hcDxcbiAgc3RyaW5nLFxuICBQcm9taXNlPERlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aD5cbj4oKTtcbi8vIENhY2hlIGZvciBzaGFyZWQgdXRpbGl0aWVzIGZyb20gQHdvcmtmbG93L2J1aWxkZXJzIChFU00gbW9kdWxlIGxvYWRlZCBkeW5hbWljYWxseSBpbiBDb21tb25KUyBjb250ZXh0KVxubGV0IGNhY2hlZEJ1aWxkZXJzTW9kdWxlOiB0eXBlb2YgaW1wb3J0KCdAd29ya2Zsb3cvYnVpbGRlcnMnKSB8IG51bGwgPSBudWxsO1xudHlwZSBMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXMgPSB7XG4gIHN3Y1BsdWdpblBhdGg6IHN0cmluZztcbiAgZmlsZXM6IHN0cmluZ1tdO1xufTtcbmxldCBjYWNoZWRMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXM6IExvYWRlclN0YXRpY0RlcGVuZGVuY2llcyB8IG51bGwgPSBudWxsO1xuXG5mdW5jdGlvbiByZWdpc3RlckZpbGVEZXBlbmRlbmN5KFxuICBsb2FkZXJDb250ZXh0OiBXb3JrZmxvd0xvYWRlckNvbnRleHQsXG4gIGRlcGVuZGVuY3lQYXRoOiBzdHJpbmdcbik6IHZvaWQge1xuICBsb2FkZXJDb250ZXh0LmFkZERlcGVuZGVuY3k/LihkZXBlbmRlbmN5UGF0aCk7XG4gIGxvYWRlckNvbnRleHQuYWRkQnVpbGREZXBlbmRlbmN5Py4oZGVwZW5kZW5jeVBhdGgpO1xufVxuXG5mdW5jdGlvbiBhZGRJZkV4aXN0cyhmaWxlczogU2V0PHN0cmluZz4sIGRlcGVuZGVuY3lQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKGV4aXN0c1N5bmMoZGVwZW5kZW5jeVBhdGgpKSB7XG4gICAgZmlsZXMuYWRkKGRlcGVuZGVuY3lQYXRoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXNvbHZlTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzKCk6IExvYWRlclN0YXRpY0RlcGVuZGVuY2llcyB7XG4gIGlmIChjYWNoZWRMb2FkZXJTdGF0aWNEZXBlbmRlbmNpZXMpIHtcbiAgICByZXR1cm4gY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzO1xuICB9XG5cbiAgY29uc3Qgc3djUGx1Z2luUGF0aCA9IHJlcXVpcmUucmVzb2x2ZSgnQHdvcmtmbG93L3N3Yy1wbHVnaW4nKTtcbiAgY29uc3Qgc3djUGx1Z2luQnVpbGRIYXNoUGF0aCA9IHJlcXVpcmUucmVzb2x2ZShcbiAgICAnQHdvcmtmbG93L3N3Yy1wbHVnaW4vYnVpbGQtaGFzaC5qc29uJ1xuICApO1xuICBjb25zdCB3b3JrZmxvd0J1aWxkZXJzUGF0aCA9IHJlcXVpcmUucmVzb2x2ZSgnQHdvcmtmbG93L2J1aWxkZXJzJyk7XG5cbiAgLy8gRGVyaXZlIHBhY2thZ2UuanNvbiBwYXRocyBmcm9tIHJlc29sdmVkIGVudHJ5cG9pbnRzIHRvIGF2b2lkXG4gIC8vIFR1cmJvcGFjayBsb2FkZXItZXZhbCBmYWlsdXJlcyBhcm91bmQgLi4vcGFja2FnZS5qc29uIHJlc29sdXRpb24uXG4gIGNvbnN0IHN3Y1BsdWdpblBhY2thZ2VKc29uUGF0aCA9IGpvaW4oZGlybmFtZShzd2NQbHVnaW5QYXRoKSwgJ3BhY2thZ2UuanNvbicpO1xuICBjb25zdCB3b3JrZmxvd0J1aWxkZXJzUGFja2FnZUpzb25QYXRoID0gam9pbihcbiAgICBkaXJuYW1lKHdvcmtmbG93QnVpbGRlcnNQYXRoKSxcbiAgICAnLi4vcGFja2FnZS5qc29uJ1xuICApO1xuXG4gIGNvbnN0IGZpbGVzID0gbmV3IFNldDxzdHJpbmc+KFtcbiAgICBfX2ZpbGVuYW1lLFxuICAgIHN3Y1BsdWdpblBhdGgsXG4gICAgc3djUGx1Z2luQnVpbGRIYXNoUGF0aCxcbiAgICB3b3JrZmxvd0J1aWxkZXJzUGF0aCxcbiAgXSk7XG4gIGFkZElmRXhpc3RzKGZpbGVzLCBzd2NQbHVnaW5QYWNrYWdlSnNvblBhdGgpO1xuICBhZGRJZkV4aXN0cyhmaWxlcywgd29ya2Zsb3dCdWlsZGVyc1BhY2thZ2VKc29uUGF0aCk7XG5cbiAgY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzID0ge1xuICAgIHN3Y1BsdWdpblBhdGgsXG4gICAgZmlsZXM6IEFycmF5LmZyb20oZmlsZXMpLFxuICB9O1xuICByZXR1cm4gY2FjaGVkTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzO1xufVxuXG5mdW5jdGlvbiByZWdpc3RlclRyYW5zZm9ybURlcGVuZGVuY2llcyhcbiAgbG9hZGVyQ29udGV4dDogV29ya2Zsb3dMb2FkZXJDb250ZXh0XG4pOiBzdHJpbmcge1xuICBjb25zdCBzdGF0aWNEZXBlbmRlbmNpZXMgPSByZXNvbHZlTG9hZGVyU3RhdGljRGVwZW5kZW5jaWVzKCk7XG4gIGZvciAoY29uc3QgZGVwZW5kZW5jeVBhdGggb2Ygc3RhdGljRGVwZW5kZW5jaWVzLmZpbGVzKSB7XG4gICAgcmVnaXN0ZXJGaWxlRGVwZW5kZW5jeShsb2FkZXJDb250ZXh0LCBkZXBlbmRlbmN5UGF0aCk7XG4gIH1cblxuICByZXR1cm4gc3RhdGljRGVwZW5kZW5jaWVzLnN3Y1BsdWdpblBhdGg7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEJ1aWxkZXJzTW9kdWxlKCk6IFByb21pc2U8XG4gIHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpXG4+IHtcbiAgaWYgKGNhY2hlZEJ1aWxkZXJzTW9kdWxlKSB7XG4gICAgcmV0dXJuIGNhY2hlZEJ1aWxkZXJzTW9kdWxlO1xuICB9XG4gIC8vIER5bmFtaWMgaW1wb3J0IHRvIGhhbmRsZSBFU00gbW9kdWxlIGZyb20gQ29tbW9uSlMgY29udGV4dFxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9zZWN1cml0eS9ub0dsb2JhbEV2YWw6IE5lZWQgdG8gdXNlIGV2YWwgaGVyZSB0byBhdm9pZCBUeXBlU2NyaXB0IGZyb20gdHJhbnNwaWxpbmcgdGhlIGltcG9ydCBzdGF0ZW1lbnQgaW50byBgcmVxdWlyZSgpYFxuICBjYWNoZWRCdWlsZGVyc01vZHVsZSA9IChhd2FpdCBldmFsKFxuICAgICdpbXBvcnQoXCJAd29ya2Zsb3cvYnVpbGRlcnNcIiknXG4gICkpIGFzIHR5cGVvZiBpbXBvcnQoJ0B3b3JrZmxvdy9idWlsZGVycycpO1xuICByZXR1cm4gY2FjaGVkQnVpbGRlcnNNb2R1bGU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldERlY29yYXRvck9wdGlvbnMoXG4gIHdvcmtpbmdEaXI6IHN0cmluZ1xuKTogUHJvbWlzZTxEZWNvcmF0b3JPcHRpb25zV2l0aENvbmZpZ1BhdGg+IHtcbiAgY29uc3QgY2FjaGVkID0gZGVjb3JhdG9yT3B0aW9uc0NhY2hlLmdldCh3b3JraW5nRGlyKTtcbiAgaWYgKGNhY2hlZCkge1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cblxuICBjb25zdCBwcm9taXNlID0gKGFzeW5jICgpOiBQcm9taXNlPERlY29yYXRvck9wdGlvbnNXaXRoQ29uZmlnUGF0aD4gPT4ge1xuICAgIGNvbnN0IHsgZ2V0RGVjb3JhdG9yT3B0aW9uc0ZvckRpcmVjdG9yeVdpdGhDb25maWdQYXRoIH0gPVxuICAgICAgYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgICByZXR1cm4gZ2V0RGVjb3JhdG9yT3B0aW9uc0ZvckRpcmVjdG9yeVdpdGhDb25maWdQYXRoKHdvcmtpbmdEaXIpO1xuICB9KSgpO1xuXG4gIGRlY29yYXRvck9wdGlvbnNDYWNoZS5zZXQod29ya2luZ0RpciwgcHJvbWlzZSk7XG4gIHJldHVybiBwcm9taXNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZXRlY3RQYXR0ZXJucyhzb3VyY2U6IHN0cmluZyk6IFByb21pc2U8V29ya2Zsb3dQYXR0ZXJuTWF0Y2g+IHtcbiAgY29uc3QgeyBkZXRlY3RXb3JrZmxvd1BhdHRlcm5zIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gZGV0ZWN0V29ya2Zsb3dQYXR0ZXJucyhzb3VyY2UpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjaGVja0dlbmVyYXRlZEZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCB7IGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gaXNHZW5lcmF0ZWRXb3JrZmxvd0ZpbGUoZmlsZVBhdGgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjaGVja1Nob3VsZFRyYW5zZm9ybShcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgcGF0dGVybnM6IFdvcmtmbG93UGF0dGVybk1hdGNoXG4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgeyBzaG91bGRUcmFuc2Zvcm1GaWxlIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gc2hvdWxkVHJhbnNmb3JtRmlsZShmaWxlUGF0aCwgcGF0dGVybnMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRNb2R1bGVTcGVjaWZpZXIoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4gIHByb2plY3RSb290OiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IHsgcmVzb2x2ZU1vZHVsZVNwZWNpZmllciB9ID0gYXdhaXQgZ2V0QnVpbGRlcnNNb2R1bGUoKTtcbiAgcmV0dXJuIHJlc29sdmVNb2R1bGVTcGVjaWZpZXIoZmlsZVBhdGgsIHByb2plY3RSb290KS5tb2R1bGVTcGVjaWZpZXI7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVXb3JrZmxvd0FsaWFzUGF0aChcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgd29ya2luZ0Rpcjogc3RyaW5nXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB7IHJlc29sdmVXb3JrZmxvd0FsaWFzUmVsYXRpdmVQYXRoIH0gPSBhd2FpdCBnZXRCdWlsZGVyc01vZHVsZSgpO1xuICByZXR1cm4gcmVzb2x2ZVdvcmtmbG93QWxpYXNSZWxhdGl2ZVBhdGgoZmlsZVBhdGgsIHdvcmtpbmdEaXIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRSZWxhdGl2ZUZpbGVuYW1lRm9yU3djKFxuICBmaWxlbmFtZTogc3RyaW5nLFxuICB3b3JraW5nRGlyOiBzdHJpbmdcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRXb3JraW5nRGlyID0gd29ya2luZ0RpclxuICAgIC5yZXBsYWNlKC9cXFxcL2csICcvJylcbiAgICAucmVwbGFjZSgvXFwvJC8sICcnKTtcbiAgY29uc3Qgbm9ybWFsaXplZEZpbGVwYXRoID0gZmlsZW5hbWUucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuXG4gIC8vIFdpbmRvd3MgZml4OiBVc2UgY2FzZS1pbnNlbnNpdGl2ZSBjb21wYXJpc29uIHRvIHdvcmsgYXJvdW5kIGRyaXZlIGxldHRlciBjYXNpbmcgaXNzdWVzXG4gIGNvbnN0IGxvd2VyV2QgPSBub3JtYWxpemVkV29ya2luZ0Rpci50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBsb3dlclBhdGggPSBub3JtYWxpemVkRmlsZXBhdGgudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcmVsYXRpdmVGaWxlbmFtZTogc3RyaW5nO1xuICBpZiAobG93ZXJQYXRoLnN0YXJ0c1dpdGgoYCR7bG93ZXJXZH0vYCkpIHtcbiAgICAvLyBGaWxlIGlzIHVuZGVyIHdvcmtpbmcgZGlyZWN0b3J5IC0gbWFudWFsbHkgY2FsY3VsYXRlIHJlbGF0aXZlIHBhdGhcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gbm9ybWFsaXplZEZpbGVwYXRoLnN1YnN0cmluZyhcbiAgICAgIG5vcm1hbGl6ZWRXb3JraW5nRGlyLmxlbmd0aCArIDFcbiAgICApO1xuICB9IGVsc2UgaWYgKGxvd2VyUGF0aCA9PT0gbG93ZXJXZCkge1xuICAgIC8vIEZpbGUgSVMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IChzaG91bGRuJ3QgaGFwcGVuKVxuICAgIHJlbGF0aXZlRmlsZW5hbWUgPSAnLic7XG4gIH0gZWxzZSB7XG4gICAgLy8gVXNlIHJlbGF0aXZlKCkgZm9yIGZpbGVzIG91dHNpZGUgd29ya2luZyBkaXJlY3RvcnlcbiAgICByZWxhdGl2ZUZpbGVuYW1lID0gcmVsYXRpdmUod29ya2luZ0RpciwgZmlsZW5hbWUpLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgIGlmIChyZWxhdGl2ZUZpbGVuYW1lLnN0YXJ0c1dpdGgoJy4uLycpKSB7XG4gICAgICBjb25zdCBhbGlhc2VkUmVsYXRpdmVQYXRoID0gYXdhaXQgcmVzb2x2ZVdvcmtmbG93QWxpYXNQYXRoKFxuICAgICAgICBmaWxlbmFtZSxcbiAgICAgICAgd29ya2luZ0RpclxuICAgICAgKTtcbiAgICAgIGlmIChhbGlhc2VkUmVsYXRpdmVQYXRoKSB7XG4gICAgICAgIHJlbGF0aXZlRmlsZW5hbWUgPSBhbGlhc2VkUmVsYXRpdmVQYXRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVsYXRpdmVGaWxlbmFtZSA9IHJlbGF0aXZlRmlsZW5hbWVcbiAgICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAgIC5maWx0ZXIoKHBhcnQpID0+IHBhcnQgIT09ICcuLicpXG4gICAgICAgICAgLmpvaW4oJy8nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBGaW5hbCBzYWZldHkgY2hlY2sgLSBlbnN1cmUgd2UgbmV2ZXIgcGFzcyBhbiBhYnNvbHV0ZSBwYXRoIHRvIFNXQ1xuICBpZiAocmVsYXRpdmVGaWxlbmFtZS5pbmNsdWRlcygnOicpIHx8IHJlbGF0aXZlRmlsZW5hbWUuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgLy8gVGhpcyBzaG91bGQgcmFyZWx5IGhhcHBlbiwgYnV0IHVzZSBmaWxlbmFtZSBzcGxpdCBhcyBsYXN0IHJlc29ydFxuICAgIHJlbGF0aXZlRmlsZW5hbWUgPSBub3JtYWxpemVkRmlsZXBhdGguc3BsaXQoJy8nKS5wb3AoKSB8fCAndW5rbm93bi50cyc7XG4gIH1cblxuICByZXR1cm4gcmVsYXRpdmVGaWxlbmFtZTtcbn1cblxuLy8gVGhpcyBsb2FkZXIgYXBwbGllcyB0aGUgXCJ1c2Ugd29ya2Zsb3dcIi9cInVzZSBzdGVwXCIgdHJhbnNmb3JtLlxuLy8gQWxsIGZpbGVzIHVzZSBzdGVwIG1vZGU7IHRoZSBTV0MgcGx1Z2luIGRlY2lkZXMgcGVyLWZ1bmN0aW9uIHdoZXRoZXJcbi8vIHRvIGVtaXQgd29ya2Zsb3cgb3Igc3RlcCBiaW5kaW5ncyBiYXNlZCBvbiB0aGUgc291cmNlJ3MgZGlyZWN0aXZlcy5cbnR5cGUgV29ya2Zsb3dMb2FkZXJDb250ZXh0ID0ge1xuICByZXNvdXJjZVBhdGg6IHN0cmluZztcbiAgYXN5bmM/OiAoKSA9PiAoXG4gICAgZXJyb3I6IEVycm9yIHwgbnVsbCxcbiAgICBjb250ZW50Pzogc3RyaW5nLFxuICAgIHNvdXJjZU1hcD86IGFueVxuICApID0+IHZvaWQ7XG4gIGFkZERlcGVuZGVuY3k/OiAoZGVwZW5kZW5jeTogc3RyaW5nKSA9PiB2b2lkO1xuICBhZGRCdWlsZERlcGVuZGVuY3k/OiAoZGVwZW5kZW5jeTogc3RyaW5nKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd29ya2Zsb3dMb2FkZXIoXG4gIHRoaXM6IFdvcmtmbG93TG9hZGVyQ29udGV4dCxcbiAgc291cmNlOiBzdHJpbmcgfCBCdWZmZXIsXG4gIHNvdXJjZU1hcDogYW55XG4pOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gfCB2b2lkIHtcbiAgY29uc3QgY2FsbGJhY2sgPSB0aGlzLmFzeW5jPy4oKTtcbiAgY29uc3QgcnVuID0gYXN5bmMgKCk6IFByb21pc2U8eyBjb2RlOiBzdHJpbmc7IG1hcDogYW55IH0+ID0+IHtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHRoaXMucmVzb3VyY2VQYXRoO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRTb3VyY2UgPSBzb3VyY2UudG9TdHJpbmcoKTtcbiAgICBjb25zdCB3b3JraW5nRGlyID0gcHJvY2Vzcy5jd2QoKTtcbiAgICBjb25zdCBzd2NQbHVnaW5QYXRoID0gcmVnaXN0ZXJUcmFuc2Zvcm1EZXBlbmRlbmNpZXModGhpcyk7XG4gICAgY29uc3Qgc291cmNlRm9yVHJhbnNmb3JtID0gbm9ybWFsaXplZFNvdXJjZTtcblxuICAgIGNvbnN0IGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlID0gYXdhaXQgY2hlY2tHZW5lcmF0ZWRGaWxlKGZpbGVuYW1lKTtcbiAgICAvLyBTa2lwIGdlbmVyYXRlZCB3b3JrZmxvdyByb3V0ZSBmaWxlcyB0byBhdm9pZCByZS1wcm9jZXNzaW5nIHRoZW0uXG4gICAgaWYgKGlzR2VuZXJhdGVkV29ya2Zsb3dGaWxlKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBub3JtYWxpemVkU291cmNlLCBtYXA6IHNvdXJjZU1hcCB9O1xuICAgIH1cblxuICAgIC8vIERldGVjdCB3b3JrZmxvdyBwYXR0ZXJucyBpbiB0aGUgc291cmNlIGNvZGUuXG4gICAgY29uc3QgcGF0dGVybnMgPSBhd2FpdCBkZXRlY3RQYXR0ZXJucyhzb3VyY2VGb3JUcmFuc2Zvcm0pO1xuXG4gICAgLy8gQ2hlY2sgaWYgZmlsZSBuZWVkcyB0cmFuc2Zvcm1hdGlvbiBiYXNlZCBvbiBwYXR0ZXJucyBhbmQgcGF0aFxuICAgIGlmICghKGF3YWl0IGNoZWNrU2hvdWxkVHJhbnNmb3JtKGZpbGVuYW1lLCBwYXR0ZXJucykpKSB7XG4gICAgICByZXR1cm4geyBjb2RlOiBub3JtYWxpemVkU291cmNlLCBtYXA6IHNvdXJjZU1hcCB9O1xuICAgIH1cblxuICAgIGNvbnN0IGlzVHlwZVNjcmlwdCA9XG4gICAgICBmaWxlbmFtZS5lbmRzV2l0aCgnLnRzJykgfHxcbiAgICAgIGZpbGVuYW1lLmVuZHNXaXRoKCcudHN4JykgfHxcbiAgICAgIGZpbGVuYW1lLmVuZHNXaXRoKCcubXRzJykgfHxcbiAgICAgIGZpbGVuYW1lLmVuZHNXaXRoKCcuY3RzJyk7XG5cbiAgICAvLyBDYWxjdWxhdGUgcmVsYXRpdmUgZmlsZW5hbWUgZm9yIFNXQyBwbHVnaW5cbiAgICAvLyBUaGUgU1dDIHBsdWdpbiB1c2VzIGZpbGVuYW1lIHRvIGdlbmVyYXRlIHdvcmtmbG93SWQsIHNvIGl0IG11c3QgYmUgcmVsYXRpdmVcbiAgICBjb25zdCByZWxhdGl2ZUZpbGVuYW1lID0gYXdhaXQgZ2V0UmVsYXRpdmVGaWxlbmFtZUZvclN3YyhcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgd29ya2luZ0RpclxuICAgICk7XG5cbiAgICAvLyBHZXQgZGVjb3JhdG9yIG9wdGlvbnMgZnJvbSB0c2NvbmZpZyAoY2FjaGVkIHBlciB3b3JraW5nIGRpcmVjdG9yeSlcbiAgICBjb25zdCB7IG9wdGlvbnM6IGRlY29yYXRvck9wdGlvbnMsIGNvbmZpZ1BhdGggfSA9XG4gICAgICBhd2FpdCBnZXREZWNvcmF0b3JPcHRpb25zKHdvcmtpbmdEaXIpO1xuICAgIGlmIChjb25maWdQYXRoKSB7XG4gICAgICByZWdpc3RlckZpbGVEZXBlbmRlbmN5KHRoaXMsIGNvbmZpZ1BhdGgpO1xuICAgIH1cblxuICAgIC8vIFJlc29sdmUgbW9kdWxlIHNwZWNpZmllciBmb3IgcGFja2FnZXMgKG5vZGVfbW9kdWxlcyBvciB3b3Jrc3BhY2UgcGFja2FnZXMpXG4gICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyID0gYXdhaXQgZ2V0TW9kdWxlU3BlY2lmaWVyKGZpbGVuYW1lLCB3b3JraW5nRGlyKTtcbiAgICBjb25zdCBtb2RlID0gJ3N0ZXAnO1xuXG4gICAgLy8gVHJhbnNmb3JtIHdpdGggU1dDXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdHJhbnNmb3JtKHNvdXJjZUZvclRyYW5zZm9ybSwge1xuICAgICAgZmlsZW5hbWU6IHJlbGF0aXZlRmlsZW5hbWUsXG4gICAgICBqc2M6IHtcbiAgICAgICAgcGFyc2VyOiB7XG4gICAgICAgICAgLi4uKGlzVHlwZVNjcmlwdFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgc3ludGF4OiAndHlwZXNjcmlwdCcsXG4gICAgICAgICAgICAgICAgdHN4OiBmaWxlbmFtZS5lbmRzV2l0aCgnLnRzeCcpLFxuICAgICAgICAgICAgICAgIGRlY29yYXRvcnM6IGRlY29yYXRvck9wdGlvbnMuZGVjb3JhdG9ycyxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgc3ludGF4OiAnZWNtYXNjcmlwdCcsXG4gICAgICAgICAgICAgICAganN4OiBmaWxlbmFtZS5lbmRzV2l0aCgnLmpzeCcpLFxuICAgICAgICAgICAgICAgIGRlY29yYXRvcnM6IGRlY29yYXRvck9wdGlvbnMuZGVjb3JhdG9ycyxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICAgIHRhcmdldDogJ2VzMjAyMicsXG4gICAgICAgIGV4cGVyaW1lbnRhbDoge1xuICAgICAgICAgIHBsdWdpbnM6IFtbc3djUGx1Z2luUGF0aCwgeyBtb2RlLCBtb2R1bGVTcGVjaWZpZXIgfV1dLFxuICAgICAgICB9LFxuICAgICAgICB0cmFuc2Zvcm06IHtcbiAgICAgICAgICByZWFjdDoge1xuICAgICAgICAgICAgcnVudGltZTogJ3ByZXNlcnZlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxlZ2FjeURlY29yYXRvcjogZGVjb3JhdG9yT3B0aW9ucy5sZWdhY3lEZWNvcmF0b3IsXG4gICAgICAgICAgZGVjb3JhdG9yTWV0YWRhdGE6IGRlY29yYXRvck9wdGlvbnMuZGVjb3JhdG9yTWV0YWRhdGEsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbWluaWZ5OiBmYWxzZSxcbiAgICAgIGlucHV0U291cmNlTWFwOiBzb3VyY2VNYXAsXG4gICAgICBzb3VyY2VNYXBzOiB0cnVlLFxuICAgICAgaW5saW5lU291cmNlc0NvbnRlbnQ6IHRydWUsXG4gICAgfSk7XG5cbiAgICBsZXQgdHJhbnNmb3JtZWRNYXAgPSBzb3VyY2VNYXA7XG4gICAgaWYgKHR5cGVvZiByZXN1bHQubWFwID09PSAnc3RyaW5nJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdHJhbnNmb3JtZWRNYXAgPSBKU09OLnBhcnNlKHJlc3VsdC5tYXApO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHRyYW5zZm9ybWVkTWFwID0gcmVzdWx0Lm1hcDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlc3VsdC5tYXApIHtcbiAgICAgIHRyYW5zZm9ybWVkTWFwID0gcmVzdWx0Lm1hcDtcbiAgICB9XG5cbiAgICByZXR1cm4geyBjb2RlOiByZXN1bHQuY29kZSwgbWFwOiB0cmFuc2Zvcm1lZE1hcCB9O1xuICB9O1xuXG4gIGlmICghY2FsbGJhY2spIHtcbiAgICByZXR1cm4gcnVuKCkudGhlbigocmVzdWx0KSA9PiByZXN1bHQuY29kZSk7XG4gIH1cblxuICB2b2lkIHJ1bigpXG4gICAgLnRoZW4oKHJlc3VsdCkgPT4gY2FsbGJhY2sobnVsbCwgcmVzdWx0LmNvZGUsIHJlc3VsdC5tYXApKVxuICAgIC5jYXRjaCgoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgIGNhbGxiYWNrKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSk7XG4gICAgfSk7XG59XG4iXX0=
@@ -36,6 +36,30 @@ Remove that package from `serverExternalPackages` in your
36
36
  `next.config` to silence the warning.
37
37
  </Callout>
38
38
 
39
+ ### Workflow Discovery in Next.js
40
+
41
+ `withWorkflow()` discovers workflows by scanning your Next.js entrypoints — App
42
+ Router `route`, `page`, and `layout` files (under `app/` or `src/app/`) and any
43
+ file under `pages/` or `src/pages/` — for `start()` calls imported from
44
+ `workflow/api`. The workflow and step files themselves can live anywhere (for
45
+ example `src/workflows/`); they are discovered transitively through imports, as
46
+ long as a `start()` call in an entrypoint statically reaches them.
47
+
48
+ <Callout type="info">
49
+ Call `start()` from server-side entrypoints, including Route Handlers and Server
50
+ Actions. Don't call workflow functions directly — that bypasses the workflow
51
+ runtime.
52
+ </Callout>
53
+
54
+ ### Next.js Server Actions and `"use server"`
55
+
56
+ Don't put a top-level `"use server"` directive in modules imported by workflow
57
+ or step functions. Workflow transformation wraps imported modules in synchronous
58
+ initializers, and Next.js rejects a `"use server"` directive inside that wrapper
59
+ with errors like `Server Actions must be async functions`. Keep `"use server"`
60
+ on the files that define your Server Actions, and move shared logic into
61
+ separate modules that don't carry the directive.
62
+
39
63
  ### Monorepos and Workspace Imports
40
64
 
41
65
  By default, Next.js detects the correct workspace root automatically. If your Next.js app lives in a subdirectory such as `apps/web` and workspace resolution is not working correctly, you can set `outputFileTracingRoot` as a workaround:
@@ -68,7 +92,6 @@ const nextConfig: NextConfig = {};
68
92
 
69
93
  export default withWorkflow(nextConfig, {
70
94
  workflows: {
71
- lazyDiscovery: false,
72
95
  local: {
73
96
  port: 4000,
74
97
  },
@@ -79,7 +102,6 @@ export default withWorkflow(nextConfig, {
79
102
 
80
103
  | Option | Type | Default | Description |
81
104
  | --- | --- | --- | --- |
82
- | `workflows.lazyDiscovery` | `boolean` | `true` | Defers workflow discovery until files are requested instead of scanning eagerly at startup. Set to `false` to force eager discovery (scanning the project up front). Requires a Next.js version that supports deferred entries; older versions fall back to eager discovery automatically. |
83
105
  | `workflows.local.port` | `number` | — | Overrides the `PORT` environment variable for local development. Has no effect when deployed to Vercel. |
84
106
  | `workflows.sourcemap` | `boolean \| 'inline' \| 'linked' \| 'external' \| 'both'` | `'inline'` (dev) / `false` (prod) | Controls source maps on generated workflow bundles. See [Source maps](#source-maps) below. |
85
107