cdk-local-lambda 0.0.2

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.
Files changed (53) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +94 -0
  3. package/lib/aspect/docker-function-hook.d.ts +18 -0
  4. package/lib/aspect/docker-function-hook.js +31 -0
  5. package/lib/aspect/live-lambda-aspect.d.ts +85 -0
  6. package/lib/aspect/live-lambda-aspect.js +277 -0
  7. package/lib/aspect/live-lambda-bootstrap.d.ts +17 -0
  8. package/lib/aspect/live-lambda-bootstrap.js +260 -0
  9. package/lib/aspect/nodejs-function-hook.d.ts +20 -0
  10. package/lib/aspect/nodejs-function-hook.js +27 -0
  11. package/lib/bootstrap-stack/bootstrap-stack.d.ts +60 -0
  12. package/lib/bootstrap-stack/bootstrap-stack.js +338 -0
  13. package/lib/cli/appsync/client.d.ts +30 -0
  14. package/lib/cli/appsync/client.js +227 -0
  15. package/lib/cli/cdk-app.d.ts +7 -0
  16. package/lib/cli/cdk-app.js +25 -0
  17. package/lib/cli/commands/bootstrap.d.ts +9 -0
  18. package/lib/cli/commands/bootstrap.js +50 -0
  19. package/lib/cli/commands/local.d.ts +40 -0
  20. package/lib/cli/commands/local.js +1172 -0
  21. package/lib/cli/daemon.d.ts +22 -0
  22. package/lib/cli/daemon.js +18 -0
  23. package/lib/cli/docker/container.d.ts +116 -0
  24. package/lib/cli/docker/container.js +414 -0
  25. package/lib/cli/docker/types.d.ts +71 -0
  26. package/lib/cli/docker/types.js +5 -0
  27. package/lib/cli/docker/watcher.d.ts +44 -0
  28. package/lib/cli/docker/watcher.js +115 -0
  29. package/lib/cli/index.d.ts +9 -0
  30. package/lib/cli/index.js +26 -0
  31. package/lib/cli/runtime-api/server.d.ts +102 -0
  32. package/lib/cli/runtime-api/server.js +396 -0
  33. package/lib/cli/runtime-api/types.d.ts +149 -0
  34. package/lib/cli/runtime-api/types.js +10 -0
  35. package/lib/cli/runtime-wrapper/nodejs-runtime.d.ts +16 -0
  36. package/lib/cli/runtime-wrapper/nodejs-runtime.js +248 -0
  37. package/lib/cli/watcher/file-watcher.d.ts +32 -0
  38. package/lib/cli/watcher/file-watcher.js +57 -0
  39. package/lib/functions/bridge/appsync-client.d.ts +73 -0
  40. package/lib/functions/bridge/appsync-client.js +345 -0
  41. package/lib/functions/bridge/handler.d.ts +17 -0
  42. package/lib/functions/bridge/handler.js +79 -0
  43. package/lib/functions/bridge/ssm-config.d.ts +19 -0
  44. package/lib/functions/bridge/ssm-config.js +45 -0
  45. package/lib/functions/bridge-builder/handler.d.ts +12 -0
  46. package/lib/functions/bridge-builder/handler.js +181 -0
  47. package/lib/functions/bridge-docker/runtime.d.ts +9 -0
  48. package/lib/functions/bridge-docker/runtime.js +127 -0
  49. package/lib/index.d.ts +24 -0
  50. package/lib/index.js +28 -0
  51. package/lib/shared/types.d.ts +102 -0
  52. package/lib/shared/types.js +125 -0
  53. package/package.json +111 -0
@@ -0,0 +1,414 @@
1
+ /**
2
+ * Docker container management utilities.
3
+ *
4
+ * Handles running Docker containers with the Lambda Runtime API
5
+ * environment configured. Uses @effect/platform Command for
6
+ * proper Effect-based process management.
7
+ */
8
+ import * as os from "node:os";
9
+ import { CommandExecutor, Command as PlatformCommand } from "@effect/platform";
10
+ import { Context, Effect, Layer, Stream } from "effect";
11
+ /**
12
+ * Detect the Docker runtime environment.
13
+ */
14
+ export const detectDockerRuntime = () => Effect.try({
15
+ try: () => {
16
+ const platform = os.platform();
17
+ const isLinux = platform === "linux";
18
+ const isWsl = isLinux &&
19
+ (process.env.WSL_DISTRO_NAME !== undefined ||
20
+ process.env.WSL_INTEROP !== undefined);
21
+ // On Mac/Windows Docker Desktop, use host.docker.internal
22
+ // On Linux, we need to use the host's IP or --network=host
23
+ const isDockerDesktop = !isLinux || isWsl;
24
+ const hostAddress = isDockerDesktop
25
+ ? "host.docker.internal"
26
+ : "172.17.0.1"; // Default Docker bridge gateway
27
+ return {
28
+ dockerPath: "docker",
29
+ isLinux,
30
+ isWsl,
31
+ isDockerDesktop,
32
+ hostAddress,
33
+ };
34
+ },
35
+ catch: (error) => new Error(`Failed to detect Docker runtime: ${String(error)}`),
36
+ });
37
+ /**
38
+ * Build Docker run arguments from config.
39
+ */
40
+ const buildDockerRunArgs = (config, runtime) => {
41
+ const args = ["run", "--rm"];
42
+ // Container name (add timestamp for uniqueness)
43
+ if (config.containerName) {
44
+ args.push("--name", `${config.containerName}-${Date.now()}`);
45
+ }
46
+ // Platform - allow running ARM64 images on x86_64 via QEMU
47
+ if (config.platform) {
48
+ args.push("--platform", config.platform);
49
+ }
50
+ // Memory limit
51
+ args.push("--memory", `${config.memoryMB}m`);
52
+ // Network mode
53
+ if (config.networkMode === "host") {
54
+ args.push("--network", "host");
55
+ }
56
+ else if (config.networkMode !== "none") {
57
+ // For bridge mode, add host mapping for non-Linux
58
+ if (runtime.isDockerDesktop) {
59
+ // host.docker.internal is automatically available on Docker Desktop
60
+ }
61
+ else {
62
+ // On Linux, add explicit host mapping and helper address
63
+ args.push("--add-host", `host.docker.internal:${runtime.hostAddress}`);
64
+ args.push("--add-host", `host.containers.internal:${runtime.hostAddress}`);
65
+ args.push("--add-host", `runtime.api:${runtime.hostAddress}`);
66
+ }
67
+ }
68
+ // Extra hosts
69
+ if (config.extraHosts) {
70
+ for (const host of config.extraHosts) {
71
+ args.push("--add-host", host);
72
+ }
73
+ }
74
+ // Environment variables
75
+ for (const [key, value] of Object.entries(config.environment)) {
76
+ args.push("-e", `${key}=${value}`);
77
+ }
78
+ // Working directory
79
+ if (config.workdir) {
80
+ args.push("-w", config.workdir);
81
+ }
82
+ // Additional arguments
83
+ if (config.additionalArgs) {
84
+ args.push(...config.additionalArgs);
85
+ }
86
+ // Entrypoint override
87
+ if (config.entrypoint && config.entrypoint.length > 0) {
88
+ args.push("--entrypoint", config.entrypoint[0]);
89
+ }
90
+ // Image
91
+ args.push(config.imageUri);
92
+ // Entrypoint additional args (after image)
93
+ if (config.entrypoint && config.entrypoint.length > 1) {
94
+ args.push(...config.entrypoint.slice(1));
95
+ }
96
+ // Command override (after image and entrypoint args)
97
+ if (config.command) {
98
+ args.push(...config.command);
99
+ }
100
+ return args;
101
+ };
102
+ /**
103
+ * Docker Service tag for dependency injection.
104
+ */
105
+ export class Docker extends Context.Tag("Docker")() {
106
+ }
107
+ /**
108
+ * Create the live Docker service implementation.
109
+ */
110
+ const makeDockerService = Effect.gen(function* () {
111
+ const runtime = yield* detectDockerRuntime();
112
+ const getRuntimeInfo = () => Effect.succeed(runtime);
113
+ const run = (config) => Effect.gen(function* () {
114
+ const args = buildDockerRunArgs(config, runtime);
115
+ yield* Effect.logDebug(`Running: docker ${args.join(" ")}`);
116
+ const command = PlatformCommand.make(runtime.dockerPath, ...args);
117
+ const stdout = [];
118
+ const stderr = [];
119
+ // Run the command and collect output
120
+ const proc = yield* PlatformCommand.start(command);
121
+ // Lambda RIC error/output patterns that are expected during poll timeout
122
+ // These are suppressed from output to avoid scary error messages
123
+ const isExpectedRicOutput = (line) => line.includes("LAMBDA_RUNTIME Failed to get next invocation") ||
124
+ line.includes("Failed to get next invocation, error 503") ||
125
+ // Filter out the Node.js stack trace from Lambda RIC exit
126
+ line.includes("triggerUncaughtException") ||
127
+ line.includes("[Error: Failed to get next invocation") ||
128
+ // "Node.js v" version line after error
129
+ line.startsWith("Node.js v") ||
130
+ line.includes("node:internal/process/promises") ||
131
+ // Stack trace caret line (just whitespace and ^)
132
+ /^\s*\^?\s*$/.test(line);
133
+ // Pattern to parse Lambda log format: TIMESTAMP\tREQUEST_ID\tLEVEL\tMESSAGE
134
+ // Lambda uses tabs between fields. Captures: [1] = request ID, [2] = level + message
135
+ const lambdaLogPattern = /^(\d{4}-\d{2}-\d{2}T[\d:.]+Z)[\t\s]+([0-9a-f-]{36})[\t\s]+(.*)$/i;
136
+ // Helper to format log line with invocation prefix
137
+ const formatLine = (rawLine) => {
138
+ // Strip carriage returns that can cause terminal corruption
139
+ const line = rawLine.replace(/\r/g, "");
140
+ const match = lambdaLogPattern.exec(line);
141
+ if (match && config.invocationContexts) {
142
+ const requestId = match[2];
143
+ const ctx = config.invocationContexts.get(requestId);
144
+ if (ctx) {
145
+ // Strip timestamp and request ID, keep just LEVEL MESSAGE
146
+ return { prefix: `[${ctx.num}]`, content: match[3] };
147
+ }
148
+ }
149
+ return { prefix: "[Container]", content: line };
150
+ };
151
+ // Process stdout - filter expected errors, forward the rest
152
+ const stdoutFiber = yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((rawLine) => Effect.sync(() => {
153
+ stdout.push(rawLine);
154
+ // Suppress expected RIC output (poll timeout errors)
155
+ if (!isExpectedRicOutput(rawLine)) {
156
+ const { prefix, content } = formatLine(rawLine);
157
+ process.stdout.write(`${prefix} ${content}\n`);
158
+ }
159
+ })), Effect.fork);
160
+ // Process stderr - filter expected errors, forward the rest
161
+ const stderrFiber = yield* proc.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((rawLine) => Effect.sync(() => {
162
+ stderr.push(rawLine);
163
+ // Suppress expected RIC output (poll timeout errors)
164
+ if (!isExpectedRicOutput(rawLine)) {
165
+ const { prefix, content } = formatLine(rawLine);
166
+ process.stderr.write(`${prefix} ${content}\n`);
167
+ }
168
+ })), Effect.fork);
169
+ // Wait for both streams and exit code
170
+ yield* Effect.all([
171
+ Effect.fromFiber(stdoutFiber),
172
+ Effect.fromFiber(stderrFiber),
173
+ ]);
174
+ const exitCode = yield* proc.exitCode;
175
+ // Only suppress warnings for expected exit codes:
176
+ // - 0: Clean exit
177
+ // - 1: Lambda RIC exit after 503 poll timeout (expected)
178
+ // - 143 (128+15): SIGTERM from docker stop
179
+ // - 137 (128+9): SIGKILL from docker stop timeout
180
+ const expectedExitCodes = [0, 1, 143, 137];
181
+ if (!expectedExitCodes.includes(exitCode)) {
182
+ yield* Effect.logWarning(`Container exited with code ${exitCode}`);
183
+ }
184
+ else if (exitCode !== 0) {
185
+ yield* Effect.logDebug(`Container exited with code ${exitCode}`);
186
+ }
187
+ return {
188
+ exitCode,
189
+ stdout: stdout.join("\n"),
190
+ stderr: stderr.join("\n"),
191
+ };
192
+ });
193
+ const runScoped = (config) => Effect.gen(function* () {
194
+ const args = buildDockerRunArgs(config, runtime);
195
+ yield* Effect.logInfo(`Running (scoped): docker ${args.join(" ")}`);
196
+ const command = PlatformCommand.make(runtime.dockerPath, ...args);
197
+ const proc = yield* PlatformCommand.start(command);
198
+ // Fork output processing in background (will be interrupted when scope closes)
199
+ yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.sync(() => {
200
+ process.stdout.write(`[Container] ${line}\n`);
201
+ })), Effect.fork);
202
+ yield* proc.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.sync(() => {
203
+ process.stderr.write(`[Container] ${line}\n`);
204
+ })), Effect.fork);
205
+ return proc;
206
+ });
207
+ const build = (options) => Effect.gen(function* () {
208
+ const args = [
209
+ "build",
210
+ "-t",
211
+ options.imageName,
212
+ "--platform",
213
+ options.platform ?? "linux/arm64",
214
+ options.contextPath,
215
+ ];
216
+ yield* Effect.logInfo(`Building image: ${options.imageName}`);
217
+ yield* Effect.logDebug(`Context: ${options.contextPath}`);
218
+ const command = PlatformCommand.make(runtime.dockerPath, ...args);
219
+ const proc = yield* PlatformCommand.start(command);
220
+ // Process stdout (debug only)
221
+ const stdoutFiber = yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.logDebug(`[Docker] ${line}`)), Effect.fork);
222
+ // Process stderr (debug only)
223
+ const stderrFiber = yield* proc.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.logDebug(`[Docker] ${line}`)), Effect.fork);
224
+ // Wait for streams and exit code
225
+ yield* Effect.all([
226
+ Effect.fromFiber(stdoutFiber),
227
+ Effect.fromFiber(stderrFiber),
228
+ ]);
229
+ const exitCode = yield* proc.exitCode;
230
+ if (exitCode !== 0) {
231
+ return yield* Effect.fail(new Error(`Docker build failed with code ${exitCode}`));
232
+ }
233
+ yield* Effect.logInfo(`Built image: ${options.imageName}`);
234
+ });
235
+ const pull = (imageUri) => Effect.gen(function* () {
236
+ yield* Effect.logInfo(`Pulling image: ${imageUri}`);
237
+ const command = PlatformCommand.make(runtime.dockerPath, "pull", imageUri);
238
+ const proc = yield* PlatformCommand.start(command);
239
+ // Process stdout (debug only)
240
+ const stdoutFiber = yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.logDebug(`[Docker] ${line}`)), Effect.fork);
241
+ // Process stderr (debug only)
242
+ const stderrFiber = yield* proc.stderr.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.logDebug(`[Docker] ${line}`)), Effect.fork);
243
+ // Wait for streams and exit code
244
+ yield* Effect.all([
245
+ Effect.fromFiber(stdoutFiber),
246
+ Effect.fromFiber(stderrFiber),
247
+ ]);
248
+ const exitCode = yield* proc.exitCode;
249
+ if (exitCode !== 0) {
250
+ return yield* Effect.fail(new Error(`Docker pull failed with code ${exitCode}`));
251
+ }
252
+ yield* Effect.logInfo(`Pulled image: ${imageUri}`);
253
+ });
254
+ const list = (containerNameFilter) => Effect.gen(function* () {
255
+ const command = PlatformCommand.make(runtime.dockerPath, "ps", "-q", "--filter", `name=${containerNameFilter}`);
256
+ const proc = yield* PlatformCommand.start(command);
257
+ // Collect stdout
258
+ const containerIds = [];
259
+ yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.sync(() => {
260
+ const trimmed = line.trim();
261
+ if (trimmed) {
262
+ containerIds.push(trimmed);
263
+ }
264
+ })));
265
+ const exitCode = yield* proc.exitCode;
266
+ if (exitCode !== 0) {
267
+ return yield* Effect.fail(new Error(`Docker ps failed with code ${exitCode}`));
268
+ }
269
+ return containerIds;
270
+ });
271
+ const stop = (containerNameFilter, timeoutSeconds) => Effect.gen(function* () {
272
+ // First list matching containers
273
+ const containerIds = yield* list(containerNameFilter);
274
+ if (containerIds.length === 0) {
275
+ yield* Effect.logDebug(`No containers found matching: ${containerNameFilter}`);
276
+ return 0;
277
+ }
278
+ yield* Effect.logInfo(`Stopping containers: ${containerIds.join(", ")}`);
279
+ // Build stop command with optional timeout
280
+ // -t 0 sends SIGKILL immediately, useful for fast restarts
281
+ const timeoutArg = timeoutSeconds !== undefined ? ["-t", String(timeoutSeconds)] : [];
282
+ const command = PlatformCommand.make(runtime.dockerPath, "stop", ...timeoutArg, ...containerIds);
283
+ const proc = yield* PlatformCommand.start(command);
284
+ // Process output for logging
285
+ yield* proc.stdout.pipe(Stream.decodeText(), Stream.splitLines, Stream.runForEach((line) => Effect.logDebug(`[Docker stop] ${line.trim()}`)));
286
+ const exitCode = yield* proc.exitCode;
287
+ if (exitCode !== 0) {
288
+ yield* Effect.logWarning(`Docker stop exited with code ${exitCode} (some containers may have already stopped)`);
289
+ }
290
+ return containerIds.length;
291
+ });
292
+ const inspect = (imageUri) => Effect.gen(function* () {
293
+ const executor = yield* CommandExecutor.CommandExecutor;
294
+ // Get entrypoint
295
+ const entrypointCmd = PlatformCommand.make(runtime.dockerPath, "inspect", "--format", "{{json .Config.Entrypoint}}", imageUri);
296
+ const entrypointProc = yield* executor.start(entrypointCmd);
297
+ const entrypointOutput = yield* Stream.runCollect(Stream.decodeText(entrypointProc.stdout));
298
+ const entrypointExitCode = yield* entrypointProc.exitCode;
299
+ if (entrypointExitCode !== 0) {
300
+ yield* Effect.fail(new Error(`Failed to inspect image entrypoint: ${imageUri}`));
301
+ }
302
+ const entrypointJson = Array.from(entrypointOutput).join("").trim();
303
+ // Get cmd
304
+ const cmdCmd = PlatformCommand.make(runtime.dockerPath, "inspect", "--format", "{{json .Config.Cmd}}", imageUri);
305
+ const cmdProc = yield* executor.start(cmdCmd);
306
+ const cmdOutput = yield* Stream.runCollect(Stream.decodeText(cmdProc.stdout));
307
+ const cmdExitCode = yield* cmdProc.exitCode;
308
+ if (cmdExitCode !== 0) {
309
+ yield* Effect.fail(new Error(`Failed to inspect image cmd: ${imageUri}`));
310
+ }
311
+ const cmdJson = Array.from(cmdOutput).join("").trim();
312
+ // Parse JSON - null is valid, so handle that
313
+ const parseJsonArray = (json) => {
314
+ if (json === "null" || json === "")
315
+ return null;
316
+ try {
317
+ const parsed = JSON.parse(json);
318
+ return Array.isArray(parsed) ? parsed : null;
319
+ }
320
+ catch {
321
+ return null;
322
+ }
323
+ };
324
+ return {
325
+ entrypoint: parseJsonArray(entrypointJson),
326
+ cmd: parseJsonArray(cmdJson),
327
+ };
328
+ });
329
+ return {
330
+ run,
331
+ runScoped,
332
+ build,
333
+ pull,
334
+ stop,
335
+ list,
336
+ getRuntimeInfo,
337
+ inspect,
338
+ };
339
+ });
340
+ /**
341
+ * Live Docker service layer.
342
+ * Note: Does not require CommandExecutor in the layer - it's required
343
+ * when the service methods are called.
344
+ */
345
+ export const DockerLive = Layer.effect(Docker, makeDockerService);
346
+ /**
347
+ * Create a container config for running a Lambda container.
348
+ */
349
+ export const makeLambdaContainerConfig = (options) => ({
350
+ imageUri: options.imageUri,
351
+ containerName: `lambda-${options.functionName.replace(/[^a-zA-Z0-9]/g, "-")}`,
352
+ platform: options.platform,
353
+ environment: {
354
+ AWS_LAMBDA_RUNTIME_API: `${options.runtimeApiHost}:${options.runtimeApiPort}`,
355
+ AWS_LAMBDA_FUNCTION_NAME: options.functionName,
356
+ AWS_LAMBDA_FUNCTION_VERSION: options.functionVersion,
357
+ AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(options.memoryMB),
358
+ AWS_REGION: options.awsRegion ?? "us-east-1",
359
+ AWS_DEFAULT_REGION: options.awsRegion ?? "us-east-1",
360
+ AWS_LAMBDA_LOG_GROUP_NAME: `/aws/lambda/${options.functionName}`,
361
+ AWS_LAMBDA_LOG_STREAM_NAME: "local",
362
+ _HANDLER: options.handler ?? "index.handler",
363
+ ...options.additionalEnv,
364
+ },
365
+ memoryMB: options.memoryMB,
366
+ timeoutSeconds: options.timeoutSeconds,
367
+ networkMode: "bridge",
368
+ invocationContexts: options.invocationContexts,
369
+ });
370
+ /**
371
+ * Shell-quote a string for safe inclusion in a shell command.
372
+ * Uses single quotes and escapes any embedded single quotes.
373
+ */
374
+ const shellQuote = (s) => {
375
+ // Single quotes are safest - escape any embedded single quotes
376
+ return `'${s.replace(/'/g, "'\\''")}'`;
377
+ };
378
+ /**
379
+ * Build a wrapper command that starts Lambda extensions before the main app.
380
+ *
381
+ * This mimics AWS Lambda's behavior of automatically starting all executables
382
+ * in /opt/extensions/ as background processes before running the main command.
383
+ *
384
+ * @param originalEntrypoint - The image's original ENTRYPOINT
385
+ * @param originalCmd - The image's original CMD
386
+ * @returns Entrypoint and command arrays to pass to Docker
387
+ */
388
+ export const buildExtensionWrapperCommand = (originalEntrypoint, originalCmd) => {
389
+ // Combine original entrypoint + cmd into the full command
390
+ // Docker behavior: ENTRYPOINT + CMD are concatenated
391
+ const originalCommand = [
392
+ ...(originalEntrypoint ?? []),
393
+ ...(originalCmd ?? []),
394
+ ];
395
+ // Script to start all executable files in /opt/extensions/ as background processes
396
+ const extensionStarter = 'for ext in /opt/extensions/*; do [ -x "$ext" ] && "$ext" & done';
397
+ // Build the full wrapper command
398
+ let fullCommand;
399
+ if (originalCommand.length > 0) {
400
+ // Quote each argument and join with spaces
401
+ const quotedOriginal = originalCommand.map(shellQuote).join(" ");
402
+ // Start extensions, then exec the original command
403
+ fullCommand = `${extensionStarter}; exec ${quotedOriginal}`;
404
+ }
405
+ else {
406
+ // No original command - just start extensions (unusual but handle it)
407
+ fullCommand = extensionStarter;
408
+ }
409
+ return {
410
+ entrypoint: ["/bin/sh"],
411
+ command: ["-c", fullCommand],
412
+ };
413
+ };
414
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGFpbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NsaS9kb2NrZXIvY29udGFpbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQzdCLE9BQU8sRUFBRSxlQUFlLEVBQUUsT0FBTyxJQUFJLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBRTlFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBYyxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFRbkU7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxHQUdqQyxFQUFFLENBQ0YsTUFBTSxDQUFDLEdBQUcsQ0FBQztJQUNULEdBQUcsRUFBRSxHQUFHLEVBQUU7UUFDUixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUE7UUFDOUIsTUFBTSxPQUFPLEdBQUcsUUFBUSxLQUFLLE9BQU8sQ0FBQTtRQUNwQyxNQUFNLEtBQUssR0FDVCxPQUFPO1lBQ1AsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsS0FBSyxTQUFTO2dCQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQTtRQUUxQywwREFBMEQ7UUFDMUQsMkRBQTJEO1FBQzNELE1BQU0sZUFBZSxHQUFHLENBQUMsT0FBTyxJQUFJLEtBQUssQ0FBQTtRQUV6QyxNQUFNLFdBQVcsR0FBRyxlQUFlO1lBQ2pDLENBQUMsQ0FBQyxzQkFBc0I7WUFDeEIsQ0FBQyxDQUFDLFlBQVksQ0FBQSxDQUFDLGdDQUFnQztRQUVqRCxPQUFPO1lBQ0wsVUFBVSxFQUFFLFFBQVE7WUFDcEIsT0FBTztZQUNQLEtBQUs7WUFDTCxlQUFlO1lBQ2YsV0FBVztTQUNaLENBQUE7SUFDSCxDQUFDO0lBQ0QsS0FBSyxFQUFFLENBQUMsS0FBSyxF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QyxXQUE0QixFQUNpQixFQUFFO0lBQy9DLDBEQUEwRDtJQUMxRCxxREFBcUQ7SUFDckQsTUFBTSxlQUFlLEdBQUc7UUFDdEIsR0FBRyxDQUFDLGtCQUFrQixJQUFJLEVBQUUsQ0FBQztRQUM3QixHQUFHLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztLQUN2QixDQUFBO0lBRUQsbUZBQW1GO0lBQ25GLE1BQU0sZ0JBQWdCLEdBQ3BCLGlFQUFpRSxDQUFBO0lBRW5FLGlDQUFpQztJQUNqQyxJQUFJLFdBQW1CLENBQUE7SUFDdkIsSUFBSSxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQy9CLDJDQUEyQztRQUMzQyxNQUFNLGNBQWMsR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNoRSxtREFBbUQ7UUFDbkQsV0FBVyxHQUFHLEdBQUcsZ0JBQWdCLFVBQVUsY0FBYyxFQUFFLENBQUE7SUFDN0QsQ0FBQztTQUFNLENBQUM7UUFDTixzRUFBc0U7UUFDdEUsV0FBVyxHQUFHLGdCQUFnQixDQUFBO0lBQ2hDLENBQUM7SUFFRCxPQUFPO1FBQ0wsVUFBVSxFQUFFLENBQUMsU0FBUyxDQUFDO1FBQ3ZCLE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUM7S0FDN0IsQ0FBQTtBQUNILENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRG9ja2VyIGNvbnRhaW5lciBtYW5hZ2VtZW50IHV0aWxpdGllcy5cbiAqXG4gKiBIYW5kbGVzIHJ1bm5pbmcgRG9ja2VyIGNvbnRhaW5lcnMgd2l0aCB0aGUgTGFtYmRhIFJ1bnRpbWUgQVBJXG4gKiBlbnZpcm9ubWVudCBjb25maWd1cmVkLiBVc2VzIEBlZmZlY3QvcGxhdGZvcm0gQ29tbWFuZCBmb3JcbiAqIHByb3BlciBFZmZlY3QtYmFzZWQgcHJvY2VzcyBtYW5hZ2VtZW50LlxuICovXG5cbmltcG9ydCAqIGFzIG9zIGZyb20gXCJub2RlOm9zXCJcbmltcG9ydCB7IENvbW1hbmRFeGVjdXRvciwgQ29tbWFuZCBhcyBQbGF0Zm9ybUNvbW1hbmQgfSBmcm9tIFwiQGVmZmVjdC9wbGF0Zm9ybVwiXG5pbXBvcnQgdHlwZSB7IFByb2Nlc3MgYXMgRWZmZWN0UHJvY2VzcyB9IGZyb20gXCJAZWZmZWN0L3BsYXRmb3JtL0NvbW1hbmRFeGVjdXRvclwiXG5pbXBvcnQgeyBDb250ZXh0LCBFZmZlY3QsIExheWVyLCB0eXBlIFNjb3BlLCBTdHJlYW0gfSBmcm9tIFwiZWZmZWN0XCJcbmltcG9ydCB0eXBlIHtcbiAgRG9ja2VySW1hZ2VDb25maWcsXG4gIERvY2tlclJ1bkNvbmZpZyxcbiAgRG9ja2VyUnVuUmVzdWx0LFxuICBEb2NrZXJSdW50aW1lSW5mbyxcbn0gZnJvbSBcIi4vdHlwZXMuanNcIlxuXG4vKipcbiAqIERldGVjdCB0aGUgRG9ja2VyIHJ1bnRpbWUgZW52aXJvbm1lbnQuXG4gKi9cbmV4cG9ydCBjb25zdCBkZXRlY3REb2NrZXJSdW50aW1lID0gKCk6IEVmZmVjdC5FZmZlY3Q8XG4gIERvY2tlclJ1bnRpbWVJbmZvLFxuICBFcnJvclxuPiA9PlxuICBFZmZlY3QudHJ5KHtcbiAgICB0cnk6ICgpID0+IHtcbiAgICAgIGNvbnN0IHBsYXRmb3JtID0gb3MucGxhdGZvcm0oKVxuICAgICAgY29uc3QgaXNMaW51eCA9IHBsYXRmb3JtID09PSBcImxpbnV4XCJcbiAgICAgIGNvbnN0IGlzV3NsID1cbiAgICAgICAgaXNMaW51eCAmJlxuICAgICAgICAocHJvY2Vzcy5lbnYuV1NMX0RJU1RST19OQU1FICE9PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICBwcm9jZXNzLmVudi5XU0xfSU5URVJPUCAhPT0gdW5kZWZpbmVkKVxuXG4gICAgICAvLyBPbiBNYWMvV2luZG93cyBEb2NrZXIgRGVza3RvcCwgdXNlIGhvc3QuZG9ja2VyLmludGVybmFsXG4gICAgICAvLyBPbiBMaW51eCwgd2UgbmVlZCB0byB1c2UgdGhlIGhvc3QncyBJUCBvciAtLW5ldHdvcms9aG9zdFxuICAgICAgY29uc3QgaXNEb2NrZXJEZXNrdG9wID0gIWlzTGludXggfHwgaXNXc2xcblxuICAgICAgY29uc3QgaG9zdEFkZHJlc3MgPSBpc0RvY2tlckRlc2t0b3BcbiAgICAgICAgPyBcImhvc3QuZG9ja2VyLmludGVybmFsXCJcbiAgICAgICAgOiBcIjE3Mi4xNy4wLjFcIiAvLyBEZWZhdWx0IERvY2tlciBicmlkZ2UgZ2F0ZXdheVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb2NrZXJQYXRoOiBcImRvY2tlclwiLFxuICAgICAgICBpc0xpbnV4LFxuICAgICAgICBpc1dzbCxcbiAgICAgICAgaXNEb2NrZXJEZXNrdG9wLFxuICAgICAgICBob3N0QWRkcmVzcyxcbiAgICAgIH1cbiAgICB9LFxuICAgIGNhdGNoOiAoZXJyb3IpID0+XG4gICAgICBuZXcgRXJyb3IoYEZhaWxlZCB0byBkZXRlY3QgRG9ja2VyIHJ1bnRpbWU6ICR7U3RyaW5nKGVycm9yKX1gKSxcbiAgfSlcblxuLyoqXG4gKiBCdWlsZCBEb2NrZXIgcnVuIGFyZ3VtZW50cyBmcm9tIGNvbmZpZy5cbiAqL1xuY29uc3QgYnVpbGREb2NrZXJSdW5BcmdzID0gKFxuICBjb25maWc6IERvY2tlclJ1bkNvbmZpZyxcbiAgcnVudGltZTogRG9ja2VyUnVudGltZUluZm8sXG4pOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IGFyZ3M6IHN0cmluZ1tdID0gW1wicnVuXCIsIFwiLS1ybVwiXVxuXG4gIC8vIENvbnRhaW5lciBuYW1lIChhZGQgdGltZXN0YW1wIGZvciB1bmlxdWVuZXNzKVxuICBpZiAoY29uZmlnLmNvbnRhaW5lck5hbWUpIHtcbiAgICBhcmdzLnB1c2goXCItLW5hbWVcIiwgYCR7Y29uZmlnLmNvbnRhaW5lck5hbWV9LSR7RGF0ZS5ub3coKX1gKVxuICB9XG5cbiAgLy8gUGxhdGZvcm0gLSBhbGxvdyBydW5uaW5nIEFSTTY0IGltYWdlcyBvbiB4ODZfNjQgdmlhIFFFTVVcbiAgaWYgKGNvbmZpZy5wbGF0Zm9ybSkge1xuICAgIGFyZ3MucHVzaChcIi0tcGxhdGZvcm1cIiwgY29uZmlnLnBsYXRmb3JtKVxuICB9XG5cbiAgLy8gTWVtb3J5IGxpbWl0XG4gIGFyZ3MucHVzaChcIi0tbWVtb3J5XCIsIGAke2NvbmZpZy5tZW1vcnlNQn1tYClcblxuICAvLyBOZXR3b3JrIG1vZGVcbiAgaWYgKGNvbmZpZy5uZXR3b3JrTW9kZSA9PT0gXCJob3N0XCIpIHtcbiAgICBhcmdzLnB1c2goXCItLW5ldHdvcmtcIiwgXCJob3N0XCIpXG4gIH0gZWxzZSBpZiAoY29uZmlnLm5ldHdvcmtNb2RlICE9PSBcIm5vbmVcIikge1xuICAgIC8vIEZvciBicmlkZ2UgbW9kZSwgYWRkIGhvc3QgbWFwcGluZyBmb3Igbm9uLUxpbnV4XG4gICAgaWYgKHJ1bnRpbWUuaXNEb2NrZXJEZXNrdG9wKSB7XG4gICAgICAvLyBob3N0LmRvY2tlci5pbnRlcm5hbCBpcyBhdXRvbWF0aWNhbGx5IGF2YWlsYWJsZSBvbiBEb2NrZXIgRGVza3RvcFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPbiBMaW51eCwgYWRkIGV4cGxpY2l0IGhvc3QgbWFwcGluZyBhbmQgaGVscGVyIGFkZHJlc3NcbiAgICAgIGFyZ3MucHVzaChcIi0tYWRkLWhvc3RcIiwgYGhvc3QuZG9ja2VyLmludGVybmFsOiR7cnVudGltZS5ob3N0QWRkcmVzc31gKVxuICAgICAgYXJncy5wdXNoKFwiLS1hZGQtaG9zdFwiLCBgaG9zdC5jb250YWluZXJzLmludGVybmFsOiR7cnVudGltZS5ob3N0QWRkcmVzc31gKVxuICAgICAgYXJncy5wdXNoKFwiLS1hZGQtaG9zdFwiLCBgcnVudGltZS5hcGk6JHtydW50aW1lLmhvc3RBZGRyZXNzfWApXG4gICAgfVxuICB9XG5cbiAgLy8gRXh0cmEgaG9zdHNcbiAgaWYgKGNvbmZpZy5leHRyYUhvc3RzKSB7XG4gICAgZm9yIChjb25zdCBob3N0IG9mIGNvbmZpZy5leHRyYUhvc3RzKSB7XG4gICAgICBhcmdzLnB1c2goXCItLWFkZC1ob3N0XCIsIGhvc3QpXG4gICAgfVxuICB9XG5cbiAgLy8gRW52aXJvbm1lbnQgdmFyaWFibGVzXG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZy5lbnZpcm9ubWVudCkpIHtcbiAgICBhcmdzLnB1c2goXCItZVwiLCBgJHtrZXl9PSR7dmFsdWV9YClcbiAgfVxuXG4gIC8vIFdvcmtpbmcgZGlyZWN0b3J5XG4gIGlmIChjb25maWcud29ya2Rpcikge1xuICAgIGFyZ3MucHVzaChcIi13XCIsIGNvbmZpZy53b3JrZGlyKVxuICB9XG5cbiAgLy8gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgaWYgKGNvbmZpZy5hZGRpdGlvbmFsQXJncykge1xuICAgIGFyZ3MucHVzaCguLi5jb25maWcuYWRkaXRpb25hbEFyZ3MpXG4gIH1cblxuICAvLyBFbnRyeXBvaW50IG92ZXJyaWRlXG4gIGlmIChjb25maWcuZW50cnlwb2ludCAmJiBjb25maWcuZW50cnlwb2ludC5sZW5ndGggPiAwKSB7XG4gICAgYXJncy5wdXNoKFwiLS1lbnRyeXBvaW50XCIsIGNvbmZpZy5lbnRyeXBvaW50WzBdKVxuICB9XG5cbiAgLy8gSW1hZ2VcbiAgYXJncy5wdXNoKGNvbmZpZy5pbWFnZVVyaSlcblxuICAvLyBFbnRyeXBvaW50IGFkZGl0aW9uYWwgYXJncyAoYWZ0ZXIgaW1hZ2UpXG4gIGlmIChjb25maWcuZW50cnlwb2ludCAmJiBjb25maWcuZW50cnlwb2ludC5sZW5ndGggPiAxKSB7XG4gICAgYXJncy5wdXNoKC4uLmNvbmZpZy5lbnRyeXBvaW50LnNsaWNlKDEpKVxuICB9XG5cbiAgLy8gQ29tbWFuZCBvdmVycmlkZSAoYWZ0ZXIgaW1hZ2UgYW5kIGVudHJ5cG9pbnQgYXJncylcbiAgaWYgKGNvbmZpZy5jb21tYW5kKSB7XG4gICAgYXJncy5wdXNoKC4uLmNvbmZpZy5jb21tYW5kKVxuICB9XG5cbiAgcmV0dXJuIGFyZ3Ncbn1cblxuLyoqXG4gKiBEb2NrZXIgU2VydmljZSBpbnRlcmZhY2UgZm9yIEVmZmVjdC1iYXNlZCBEb2NrZXIgb3BlcmF0aW9ucy5cbiAqIEFsbCBzY29wZWQgb3BlcmF0aW9ucyByZXF1aXJlIGJvdGggU2NvcGUgYW5kIENvbW1hbmRFeGVjdXRvci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb2NrZXJTZXJ2aWNlIHtcbiAgLyoqXG4gICAqIFJ1biBhIERvY2tlciBjb250YWluZXIgYW5kIHdhaXQgZm9yIGl0IHRvIGNvbXBsZXRlLlxuICAgKiBPdXRwdXQgaXMgc3RyZWFtZWQgdG8gc3Rkb3V0L3N0ZGVyci5cbiAgICovXG4gIHJlYWRvbmx5IHJ1bjogKFxuICAgIGNvbmZpZzogRG9ja2VyUnVuQ29uZmlnLFxuICApID0+IEVmZmVjdC5FZmZlY3Q8XG4gICAgRG9ja2VyUnVuUmVzdWx0LFxuICAgIEVycm9yLFxuICAgIFNjb3BlLlNjb3BlIHwgQ29tbWFuZEV4ZWN1dG9yLkNvbW1hbmRFeGVjdXRvclxuICA+XG5cbiAgLyoqXG4gICAqIFJ1biBhIERvY2tlciBjb250YWluZXIgd2l0aCBzY29wZWQgbGlmZWN5Y2xlIG1hbmFnZW1lbnQuXG4gICAqIFJldHVybnMgdGhlIHJ1bm5pbmcgcHJvY2VzcyB3aGljaCBjYW4gYmUgaW50ZXJydXB0ZWQgdmlhIHNjb3BlLlxuICAgKi9cbiAgcmVhZG9ubHkgcnVuU2NvcGVkOiAoXG4gICAgY29uZmlnOiBEb2NrZXJSdW5Db25maWcsXG4gICkgPT4gRWZmZWN0LkVmZmVjdDxcbiAgICBFZmZlY3RQcm9jZXNzLFxuICAgIEVycm9yLFxuICAgIFNjb3BlLlNjb3BlIHwgQ29tbWFuZEV4ZWN1dG9yLkNvbW1hbmRFeGVjdXRvclxuICA+XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgRG9ja2VyIGltYWdlIGZyb20gYSBsb2NhbCBjb250ZXh0IGRpcmVjdG9yeS5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkOiAob3B0aW9uczoge1xuICAgIGNvbnRleHRQYXRoOiBzdHJpbmdcbiAgICBpbWFnZU5hbWU6IHN0cmluZ1xuICAgIHBsYXRmb3JtPzogc3RyaW5nXG4gIH0pID0+IEVmZmVjdC5FZmZlY3Q8XG4gICAgdm9pZCxcbiAgICBFcnJvcixcbiAgICBTY29wZS5TY29wZSB8IENvbW1hbmRFeGVjdXRvci5Db21tYW5kRXhlY3V0b3JcbiAgPlxuXG4gIC8qKlxuICAgKiBQdWxsIGEgRG9ja2VyIGltYWdlIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQuXG4gICAqL1xuICByZWFkb25seSBwdWxsOiAoXG4gICAgaW1hZ2VVcmk6IHN0cmluZyxcbiAgKSA9PiBFZmZlY3QuRWZmZWN0PHZvaWQsIEVycm9yLCBTY29wZS5TY29wZSB8IENvbW1hbmRFeGVjdXRvci5Db21tYW5kRXhlY3V0b3I+XG5cbiAgLyoqXG4gICAqIFN0b3AgRG9ja2VyIGNvbnRhaW5lcnMgbWF0Y2hpbmcgYSBuYW1lIGZpbHRlci5cbiAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGNvbnRhaW5lcnMgc3RvcHBlZC5cbiAgICogQHBhcmFtIGNvbnRhaW5lck5hbWVGaWx0ZXIgLSBGaWx0ZXIgdG8gbWF0Y2ggY29udGFpbmVyIG5hbWVzXG4gICAqIEBwYXJhbSB0aW1lb3V0U2Vjb25kcyAtIFNlY29uZHMgdG8gd2FpdCBiZWZvcmUgU0lHS0lMTCAoZGVmYXVsdDogMTApXG4gICAqL1xuICByZWFkb25seSBzdG9wOiAoXG4gICAgY29udGFpbmVyTmFtZUZpbHRlcjogc3RyaW5nLFxuICAgIHRpbWVvdXRTZWNvbmRzPzogbnVtYmVyLFxuICApID0+IEVmZmVjdC5FZmZlY3Q8XG4gICAgbnVtYmVyLFxuICAgIEVycm9yLFxuICAgIFNjb3BlLlNjb3BlIHwgQ29tbWFuZEV4ZWN1dG9yLkNvbW1hbmRFeGVjdXRvclxuICA+XG5cbiAgLyoqXG4gICAqIExpc3QgRG9ja2VyIGNvbnRhaW5lciBJRHMgbWF0Y2hpbmcgYSBuYW1lIGZpbHRlci5cbiAgICovXG4gIHJlYWRvbmx5IGxpc3Q6IChcbiAgICBjb250YWluZXJOYW1lRmlsdGVyOiBzdHJpbmcsXG4gICkgPT4gRWZmZWN0LkVmZmVjdDxcbiAgICBzdHJpbmdbXSxcbiAgICBFcnJvcixcbiAgICBTY29wZS5TY29wZSB8IENvbW1hbmRFeGVjdXRvci5Db21tYW5kRXhlY3V0b3JcbiAgPlxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRldGVjdGVkIERvY2tlciBydW50aW1lIGluZm8uXG4gICAqL1xuICByZWFkb25seSBnZXRSdW50aW1lSW5mbzogKCkgPT4gRWZmZWN0LkVmZmVjdDxEb2NrZXJSdW50aW1lSW5mbywgRXJyb3I+XG5cbiAgLyoqXG4gICAqIEluc3BlY3QgYSBEb2NrZXIgaW1hZ2UgdG8gZ2V0IGl0cyBjb25maWd1cmF0aW9uLlxuICAgKiBSZXR1cm5zIHRoZSBFTlRSWVBPSU5UIGFuZCBDTUQgZnJvbSB0aGUgaW1hZ2UuXG4gICAqL1xuICByZWFkb25seSBpbnNwZWN0OiAoXG4gICAgaW1hZ2VVcmk6IHN0cmluZyxcbiAgKSA9PiBFZmZlY3QuRWZmZWN0PFxuICAgIERvY2tlckltYWdlQ29uZmlnLFxuICAgIEVycm9yLFxuICAgIFNjb3BlLlNjb3BlIHwgQ29tbWFuZEV4ZWN1dG9yLkNvbW1hbmRFeGVjdXRvclxuICA+XG59XG5cbi8qKlxuICogRG9ja2VyIFNlcnZpY2UgdGFnIGZvciBkZXBlbmRlbmN5IGluamVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIERvY2tlciBleHRlbmRzIENvbnRleHQuVGFnKFwiRG9ja2VyXCIpPERvY2tlciwgRG9ja2VyU2VydmljZT4oKSB7fVxuXG4vKipcbiAqIENyZWF0ZSB0aGUgbGl2ZSBEb2NrZXIgc2VydmljZSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuY29uc3QgbWFrZURvY2tlclNlcnZpY2U6IEVmZmVjdC5FZmZlY3Q8RG9ja2VyU2VydmljZSwgRXJyb3I+ID0gRWZmZWN0LmdlbihcbiAgZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBydW50aW1lID0geWllbGQqIGRldGVjdERvY2tlclJ1bnRpbWUoKVxuXG4gICAgY29uc3QgZ2V0UnVudGltZUluZm86IERvY2tlclNlcnZpY2VbXCJnZXRSdW50aW1lSW5mb1wiXSA9ICgpID0+XG4gICAgICBFZmZlY3Quc3VjY2VlZChydW50aW1lKVxuXG4gICAgY29uc3QgcnVuOiBEb2NrZXJTZXJ2aWNlW1wicnVuXCJdID0gKGNvbmZpZykgPT5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgYXJncyA9IGJ1aWxkRG9ja2VyUnVuQXJncyhjb25maWcsIHJ1bnRpbWUpXG5cbiAgICAgICAgeWllbGQqIEVmZmVjdC5sb2dEZWJ1ZyhgUnVubmluZzogZG9ja2VyICR7YXJncy5qb2luKFwiIFwiKX1gKVxuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBQbGF0Zm9ybUNvbW1hbmQubWFrZShydW50aW1lLmRvY2tlclBhdGgsIC4uLmFyZ3MpXG5cbiAgICAgICAgY29uc3Qgc3Rkb3V0OiBzdHJpbmdbXSA9IFtdXG4gICAgICAgIGNvbnN0IHN0ZGVycjogc3RyaW5nW10gPSBbXVxuXG4gICAgICAgIC8vIFJ1biB0aGUgY29tbWFuZCBhbmQgY29sbGVjdCBvdXRwdXRcbiAgICAgICAgY29uc3QgcHJvYyA9IHlpZWxkKiBQbGF0Zm9ybUNvbW1hbmQuc3RhcnQoY29tbWFuZClcblxuICAgICAgICAvLyBMYW1iZGEgUklDIGVycm9yL291dHB1dCBwYXR0ZXJucyB0aGF0IGFyZSBleHBlY3RlZCBkdXJpbmcgcG9sbCB0aW1lb3V0XG4gICAgICAgIC8vIFRoZXNlIGFyZSBzdXBwcmVzc2VkIGZyb20gb3V0cHV0IHRvIGF2b2lkIHNjYXJ5IGVycm9yIG1lc3NhZ2VzXG4gICAgICAgIGNvbnN0IGlzRXhwZWN0ZWRSaWNPdXRwdXQgPSAobGluZTogc3RyaW5nKTogYm9vbGVhbiA9PlxuICAgICAgICAgIGxpbmUuaW5jbHVkZXMoXCJMQU1CREFfUlVOVElNRSBGYWlsZWQgdG8gZ2V0IG5leHQgaW52b2NhdGlvblwiKSB8fFxuICAgICAgICAgIGxpbmUuaW5jbHVkZXMoXCJGYWlsZWQgdG8gZ2V0IG5leHQgaW52b2NhdGlvbiwgZXJyb3IgNTAzXCIpIHx8XG4gICAgICAgICAgLy8gRmlsdGVyIG91dCB0aGUgTm9kZS5qcyBzdGFjayB0cmFjZSBmcm9tIExhbWJkYSBSSUMgZXhpdFxuICAgICAgICAgIGxpbmUuaW5jbHVkZXMoXCJ0cmlnZ2VyVW5jYXVnaHRFeGNlcHRpb25cIikgfHxcbiAgICAgICAgICBsaW5lLmluY2x1ZGVzKFwiW0Vycm9yOiBGYWlsZWQgdG8gZ2V0IG5leHQgaW52b2NhdGlvblwiKSB8fFxuICAgICAgICAgIC8vIFwiTm9kZS5qcyB2XCIgdmVyc2lvbiBsaW5lIGFmdGVyIGVycm9yXG4gICAgICAgICAgbGluZS5zdGFydHNXaXRoKFwiTm9kZS5qcyB2XCIpIHx8XG4gICAgICAgICAgbGluZS5pbmNsdWRlcyhcIm5vZGU6aW50ZXJuYWwvcHJvY2Vzcy9wcm9taXNlc1wiKSB8fFxuICAgICAgICAgIC8vIFN0YWNrIHRyYWNlIGNhcmV0IGxpbmUgKGp1c3Qgd2hpdGVzcGFjZSBhbmQgXilcbiAgICAgICAgICAvXlxccypcXF4/XFxzKiQvLnRlc3QobGluZSlcblxuICAgICAgICAvLyBQYXR0ZXJuIHRvIHBhcnNlIExhbWJkYSBsb2cgZm9ybWF0OiBUSU1FU1RBTVBcXHRSRVFVRVNUX0lEXFx0TEVWRUxcXHRNRVNTQUdFXG4gICAgICAgIC8vIExhbWJkYSB1c2VzIHRhYnMgYmV0d2VlbiBmaWVsZHMuIENhcHR1cmVzOiBbMV0gPSByZXF1ZXN0IElELCBbMl0gPSBsZXZlbCArIG1lc3NhZ2VcbiAgICAgICAgY29uc3QgbGFtYmRhTG9nUGF0dGVybiA9XG4gICAgICAgICAgL14oXFxkezR9LVxcZHsyfS1cXGR7Mn1UW1xcZDouXStaKVtcXHRcXHNdKyhbMC05YS1mLV17MzZ9KVtcXHRcXHNdKyguKikkL2lcblxuICAgICAgICAvLyBIZWxwZXIgdG8gZm9ybWF0IGxvZyBsaW5lIHdpdGggaW52b2NhdGlvbiBwcmVmaXhcbiAgICAgICAgY29uc3QgZm9ybWF0TGluZSA9IChcbiAgICAgICAgICByYXdMaW5lOiBzdHJpbmcsXG4gICAgICAgICk6IHsgcHJlZml4OiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9ID0+IHtcbiAgICAgICAgICAvLyBTdHJpcCBjYXJyaWFnZSByZXR1cm5zIHRoYXQgY2FuIGNhdXNlIHRlcm1pbmFsIGNvcnJ1cHRpb25cbiAgICAgICAgICBjb25zdCBsaW5lID0gcmF3TGluZS5yZXBsYWNlKC9cXHIvZywgXCJcIilcbiAgICAgICAgICBjb25zdCBtYXRjaCA9IGxhbWJkYUxvZ1BhdHRlcm4uZXhlYyhsaW5lKVxuICAgICAgICAgIGlmIChtYXRjaCAmJiBjb25maWcuaW52b2NhdGlvbkNvbnRleHRzKSB7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0SWQgPSBtYXRjaFsyXVxuICAgICAgICAgICAgY29uc3QgY3R4ID0gY29uZmlnLmludm9jYXRpb25Db250ZXh0cy5nZXQocmVxdWVzdElkKVxuICAgICAgICAgICAgaWYgKGN0eCkge1xuICAgICAgICAgICAgICAvLyBTdHJpcCB0aW1lc3RhbXAgYW5kIHJlcXVlc3QgSUQsIGtlZXAganVzdCBMRVZFTCBNRVNTQUdFXG4gICAgICAgICAgICAgIHJldHVybiB7IHByZWZpeDogYFske2N0eC5udW19XWAsIGNvbnRlbnQ6IG1hdGNoWzNdIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHsgcHJlZml4OiBcIltDb250YWluZXJdXCIsIGNvbnRlbnQ6IGxpbmUgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyBzdGRvdXQgLSBmaWx0ZXIgZXhwZWN0ZWQgZXJyb3JzLCBmb3J3YXJkIHRoZSByZXN0XG4gICAgICAgIGNvbnN0IHN0ZG91dEZpYmVyID0geWllbGQqIHByb2Muc3Rkb3V0LnBpcGUoXG4gICAgICAgICAgU3RyZWFtLmRlY29kZVRleHQoKSxcbiAgICAgICAgICBTdHJlYW0uc3BsaXRMaW5lcyxcbiAgICAgICAgICBTdHJlYW0ucnVuRm9yRWFjaCgocmF3TGluZSkgPT5cbiAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgc3Rkb3V0LnB1c2gocmF3TGluZSlcbiAgICAgICAgICAgICAgLy8gU3VwcHJlc3MgZXhwZWN0ZWQgUklDIG91dHB1dCAocG9sbCB0aW1lb3V0IGVycm9ycylcbiAgICAgICAgICAgICAgaWYgKCFpc0V4cGVjdGVkUmljT3V0cHV0KHJhd0xpbmUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwcmVmaXgsIGNvbnRlbnQgfSA9IGZvcm1hdExpbmUocmF3TGluZSlcbiAgICAgICAgICAgICAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtwcmVmaXh9ICR7Y29udGVudH1cXG5gKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIEVmZmVjdC5mb3JrLFxuICAgICAgICApXG5cbiAgICAgICAgLy8gUHJvY2VzcyBzdGRlcnIgLSBmaWx0ZXIgZXhwZWN0ZWQgZXJyb3JzLCBmb3J3YXJkIHRoZSByZXN0XG4gICAgICAgIGNvbnN0IHN0ZGVyckZpYmVyID0geWllbGQqIHByb2Muc3RkZXJyLnBpcGUoXG4gICAgICAgICAgU3RyZWFtLmRlY29kZVRleHQoKSxcbiAgICAgICAgICBTdHJlYW0uc3BsaXRMaW5lcyxcbiAgICAgICAgICBTdHJlYW0ucnVuRm9yRWFjaCgocmF3TGluZSkgPT5cbiAgICAgICAgICAgIEVmZmVjdC5zeW5jKCgpID0+IHtcbiAgICAgICAgICAgICAgc3RkZXJyLnB1c2gocmF3TGluZSlcbiAgICAgICAgICAgICAgLy8gU3VwcHJlc3MgZXhwZWN0ZWQgUklDIG91dHB1dCAocG9sbCB0aW1lb3V0IGVycm9ycylcbiAgICAgICAgICAgICAgaWYgKCFpc0V4cGVjdGVkUmljT3V0cHV0KHJhd0xpbmUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwcmVmaXgsIGNvbnRlbnQgfSA9IGZvcm1hdExpbmUocmF3TGluZSlcbiAgICAgICAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgJHtwcmVmaXh9ICR7Y29udGVudH1cXG5gKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIEVmZmVjdC5mb3JrLFxuICAgICAgICApXG5cbiAgICAgICAgLy8gV2FpdCBmb3IgYm90aCBzdHJlYW1zIGFuZCBleGl0IGNvZGVcbiAgICAgICAgeWllbGQqIEVmZmVjdC5hbGwoW1xuICAgICAgICAgIEVmZmVjdC5mcm9tRmliZXIoc3Rkb3V0RmliZXIpLFxuICAgICAgICAgIEVmZmVjdC5mcm9tRmliZXIoc3RkZXJyRmliZXIpLFxuICAgICAgICBdKVxuXG4gICAgICAgIGNvbnN0IGV4aXRDb2RlID0geWllbGQqIHByb2MuZXhpdENvZGVcblxuICAgICAgICAvLyBPbmx5IHN1cHByZXNzIHdhcm5pbmdzIGZvciBleHBlY3RlZCBleGl0IGNvZGVzOlxuICAgICAgICAvLyAtIDA6IENsZWFuIGV4aXRcbiAgICAgICAgLy8gLSAxOiBMYW1iZGEgUklDIGV4aXQgYWZ0ZXIgNTAzIHBvbGwgdGltZW91dCAoZXhwZWN0ZWQpXG4gICAgICAgIC8vIC0gMTQzICgxMjgrMTUpOiBTSUdURVJNIGZyb20gZG9ja2VyIHN0b3BcbiAgICAgICAgLy8gLSAxMzcgKDEyOCs5KTogU0lHS0lMTCBmcm9tIGRvY2tlciBzdG9wIHRpbWVvdXRcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRFeGl0Q29kZXMgPSBbMCwgMSwgMTQzLCAxMzddXG4gICAgICAgIGlmICghZXhwZWN0ZWRFeGl0Q29kZXMuaW5jbHVkZXMoZXhpdENvZGUpKSB7XG4gICAgICAgICAgeWllbGQqIEVmZmVjdC5sb2dXYXJuaW5nKGBDb250YWluZXIgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWApXG4gICAgICAgIH0gZWxzZSBpZiAoZXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgICB5aWVsZCogRWZmZWN0LmxvZ0RlYnVnKGBDb250YWluZXIgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWApXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGV4aXRDb2RlLFxuICAgICAgICAgIHN0ZG91dDogc3Rkb3V0LmpvaW4oXCJcXG5cIiksXG4gICAgICAgICAgc3RkZXJyOiBzdGRlcnIuam9pbihcIlxcblwiKSxcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgIGNvbnN0IHJ1blNjb3BlZDogRG9ja2VyU2VydmljZVtcInJ1blNjb3BlZFwiXSA9IChjb25maWcpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBidWlsZERvY2tlclJ1bkFyZ3MoY29uZmlnLCBydW50aW1lKVxuXG4gICAgICAgIHlpZWxkKiBFZmZlY3QubG9nSW5mbyhgUnVubmluZyAoc2NvcGVkKTogZG9ja2VyICR7YXJncy5qb2luKFwiIFwiKX1gKVxuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBQbGF0Zm9ybUNvbW1hbmQubWFrZShydW50aW1lLmRvY2tlclBhdGgsIC4uLmFyZ3MpXG5cbiAgICAgICAgY29uc3QgcHJvYyA9IHlpZWxkKiBQbGF0Zm9ybUNvbW1hbmQuc3RhcnQoY29tbWFuZClcblxuICAgICAgICAvLyBGb3JrIG91dHB1dCBwcm9jZXNzaW5nIGluIGJhY2tncm91bmQgKHdpbGwgYmUgaW50ZXJydXB0ZWQgd2hlbiBzY29wZSBjbG9zZXMpXG4gICAgICAgIHlpZWxkKiBwcm9jLnN0ZG91dC5waXBlKFxuICAgICAgICAgIFN0cmVhbS5kZWNvZGVUZXh0KCksXG4gICAgICAgICAgU3RyZWFtLnNwbGl0TGluZXMsXG4gICAgICAgICAgU3RyZWFtLnJ1bkZvckVhY2goKGxpbmUpID0+XG4gICAgICAgICAgICBFZmZlY3Quc3luYygoKSA9PiB7XG4gICAgICAgICAgICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGBbQ29udGFpbmVyXSAke2xpbmV9XFxuYClcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICAgRWZmZWN0LmZvcmssXG4gICAgICAgIClcblxuICAgICAgICB5aWVsZCogcHJvYy5zdGRlcnIucGlwZShcbiAgICAgICAgICBTdHJlYW0uZGVjb2RlVGV4dCgpLFxuICAgICAgICAgIFN0cmVhbS5zcGxpdExpbmVzLFxuICAgICAgICAgIFN0cmVhbS5ydW5Gb3JFYWNoKChsaW5lKSA9PlxuICAgICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICBwcm9jZXNzLnN0ZGVyci53cml0ZShgW0NvbnRhaW5lcl0gJHtsaW5lfVxcbmApXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIEVmZmVjdC5mb3JrLFxuICAgICAgICApXG5cbiAgICAgICAgcmV0dXJuIHByb2NcbiAgICAgIH0pXG5cbiAgICBjb25zdCBidWlsZDogRG9ja2VyU2VydmljZVtcImJ1aWxkXCJdID0gKG9wdGlvbnMpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBbXG4gICAgICAgICAgXCJidWlsZFwiLFxuICAgICAgICAgIFwiLXRcIixcbiAgICAgICAgICBvcHRpb25zLmltYWdlTmFtZSxcbiAgICAgICAgICBcIi0tcGxhdGZvcm1cIixcbiAgICAgICAgICBvcHRpb25zLnBsYXRmb3JtID8/IFwibGludXgvYXJtNjRcIixcbiAgICAgICAgICBvcHRpb25zLmNvbnRleHRQYXRoLFxuICAgICAgICBdXG5cbiAgICAgICAgeWllbGQqIEVmZmVjdC5sb2dJbmZvKGBCdWlsZGluZyBpbWFnZTogJHtvcHRpb25zLmltYWdlTmFtZX1gKVxuICAgICAgICB5aWVsZCogRWZmZWN0LmxvZ0RlYnVnKGBDb250ZXh0OiAke29wdGlvbnMuY29udGV4dFBhdGh9YClcblxuICAgICAgICBjb25zdCBjb21tYW5kID0gUGxhdGZvcm1Db21tYW5kLm1ha2UocnVudGltZS5kb2NrZXJQYXRoLCAuLi5hcmdzKVxuXG4gICAgICAgIGNvbnN0IHByb2MgPSB5aWVsZCogUGxhdGZvcm1Db21tYW5kLnN0YXJ0KGNvbW1hbmQpXG5cbiAgICAgICAgLy8gUHJvY2VzcyBzdGRvdXQgKGRlYnVnIG9ubHkpXG4gICAgICAgIGNvbnN0IHN0ZG91dEZpYmVyID0geWllbGQqIHByb2Muc3Rkb3V0LnBpcGUoXG4gICAgICAgICAgU3RyZWFtLmRlY29kZVRleHQoKSxcbiAgICAgICAgICBTdHJlYW0uc3BsaXRMaW5lcyxcbiAgICAgICAgICBTdHJlYW0ucnVuRm9yRWFjaCgobGluZSkgPT4gRWZmZWN0LmxvZ0RlYnVnKGBbRG9ja2VyXSAke2xpbmV9YCkpLFxuICAgICAgICAgIEVmZmVjdC5mb3JrLFxuICAgICAgICApXG5cbiAgICAgICAgLy8gUHJvY2VzcyBzdGRlcnIgKGRlYnVnIG9ubHkpXG4gICAgICAgIGNvbnN0IHN0ZGVyckZpYmVyID0geWllbGQqIHByb2Muc3RkZXJyLnBpcGUoXG4gICAgICAgICAgU3RyZWFtLmRlY29kZVRleHQoKSxcbiAgICAgICAgICBTdHJlYW0uc3BsaXRMaW5lcyxcbiAgICAgICAgICBTdHJlYW0ucnVuRm9yRWFjaCgobGluZSkgPT4gRWZmZWN0LmxvZ0RlYnVnKGBbRG9ja2VyXSAke2xpbmV9YCkpLFxuICAgICAgICAgIEVmZmVjdC5mb3JrLFxuICAgICAgICApXG5cbiAgICAgICAgLy8gV2FpdCBmb3Igc3RyZWFtcyBhbmQgZXhpdCBjb2RlXG4gICAgICAgIHlpZWxkKiBFZmZlY3QuYWxsKFtcbiAgICAgICAgICBFZmZlY3QuZnJvbUZpYmVyKHN0ZG91dEZpYmVyKSxcbiAgICAgICAgICBFZmZlY3QuZnJvbUZpYmVyKHN0ZGVyckZpYmVyKSxcbiAgICAgICAgXSlcblxuICAgICAgICBjb25zdCBleGl0Q29kZSA9IHlpZWxkKiBwcm9jLmV4aXRDb2RlXG5cbiAgICAgICAgaWYgKGV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChcbiAgICAgICAgICAgIG5ldyBFcnJvcihgRG9ja2VyIGJ1aWxkIGZhaWxlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX1gKSxcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICB5aWVsZCogRWZmZWN0LmxvZ0luZm8oYEJ1aWx0IGltYWdlOiAke29wdGlvbnMuaW1hZ2VOYW1lfWApXG4gICAgICB9KVxuXG4gICAgY29uc3QgcHVsbDogRG9ja2VyU2VydmljZVtcInB1bGxcIl0gPSAoaW1hZ2VVcmkpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIHlpZWxkKiBFZmZlY3QubG9nSW5mbyhgUHVsbGluZyBpbWFnZTogJHtpbWFnZVVyaX1gKVxuXG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBQbGF0Zm9ybUNvbW1hbmQubWFrZShcbiAgICAgICAgICBydW50aW1lLmRvY2tlclBhdGgsXG4gICAgICAgICAgXCJwdWxsXCIsXG4gICAgICAgICAgaW1hZ2VVcmksXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBwcm9jID0geWllbGQqIFBsYXRmb3JtQ29tbWFuZC5zdGFydChjb21tYW5kKVxuXG4gICAgICAgIC8vIFByb2Nlc3Mgc3Rkb3V0IChkZWJ1ZyBvbmx5KVxuICAgICAgICBjb25zdCBzdGRvdXRGaWJlciA9IHlpZWxkKiBwcm9jLnN0ZG91dC5waXBlKFxuICAgICAgICAgIFN0cmVhbS5kZWNvZGVUZXh0KCksXG4gICAgICAgICAgU3RyZWFtLnNwbGl0TGluZXMsXG4gICAgICAgICAgU3RyZWFtLnJ1bkZvckVhY2goKGxpbmUpID0+IEVmZmVjdC5sb2dEZWJ1ZyhgW0RvY2tlcl0gJHtsaW5lfWApKSxcbiAgICAgICAgICBFZmZlY3QuZm9yayxcbiAgICAgICAgKVxuXG4gICAgICAgIC8vIFByb2Nlc3Mgc3RkZXJyIChkZWJ1ZyBvbmx5KVxuICAgICAgICBjb25zdCBzdGRlcnJGaWJlciA9IHlpZWxkKiBwcm9jLnN0ZGVyci5waXBlKFxuICAgICAgICAgIFN0cmVhbS5kZWNvZGVUZXh0KCksXG4gICAgICAgICAgU3RyZWFtLnNwbGl0TGluZXMsXG4gICAgICAgICAgU3RyZWFtLnJ1bkZvckVhY2goKGxpbmUpID0+IEVmZmVjdC5sb2dEZWJ1ZyhgW0RvY2tlcl0gJHtsaW5lfWApKSxcbiAgICAgICAgICBFZmZlY3QuZm9yayxcbiAgICAgICAgKVxuXG4gICAgICAgIC8vIFdhaXQgZm9yIHN0cmVhbXMgYW5kIGV4aXQgY29kZVxuICAgICAgICB5aWVsZCogRWZmZWN0LmFsbChbXG4gICAgICAgICAgRWZmZWN0LmZyb21GaWJlcihzdGRvdXRGaWJlciksXG4gICAgICAgICAgRWZmZWN0LmZyb21GaWJlcihzdGRlcnJGaWJlciksXG4gICAgICAgIF0pXG5cbiAgICAgICAgY29uc3QgZXhpdENvZGUgPSB5aWVsZCogcHJvYy5leGl0Q29kZVxuXG4gICAgICAgIGlmIChleGl0Q29kZSAhPT0gMCkge1xuICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoXG4gICAgICAgICAgICBuZXcgRXJyb3IoYERvY2tlciBwdWxsIGZhaWxlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX1gKSxcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICB5aWVsZCogRWZmZWN0LmxvZ0luZm8oYFB1bGxlZCBpbWFnZTogJHtpbWFnZVVyaX1gKVxuICAgICAgfSlcblxuICAgIGNvbnN0IGxpc3Q6IERvY2tlclNlcnZpY2VbXCJsaXN0XCJdID0gKGNvbnRhaW5lck5hbWVGaWx0ZXIpID0+XG4gICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBQbGF0Zm9ybUNvbW1hbmQubWFrZShcbiAgICAgICAgICBydW50aW1lLmRvY2tlclBhdGgsXG4gICAgICAgICAgXCJwc1wiLFxuICAgICAgICAgIFwiLXFcIixcbiAgICAgICAgICBcIi0tZmlsdGVyXCIsXG4gICAgICAgICAgYG5hbWU9JHtjb250YWluZXJOYW1lRmlsdGVyfWAsXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBwcm9jID0geWllbGQqIFBsYXRmb3JtQ29tbWFuZC5zdGFydChjb21tYW5kKVxuXG4gICAgICAgIC8vIENvbGxlY3Qgc3Rkb3V0XG4gICAgICAgIGNvbnN0IGNvbnRhaW5lcklkczogc3RyaW5nW10gPSBbXVxuICAgICAgICB5aWVsZCogcHJvYy5zdGRvdXQucGlwZShcbiAgICAgICAgICBTdHJlYW0uZGVjb2RlVGV4dCgpLFxuICAgICAgICAgIFN0cmVhbS5zcGxpdExpbmVzLFxuICAgICAgICAgIFN0cmVhbS5ydW5Gb3JFYWNoKChsaW5lKSA9PlxuICAgICAgICAgICAgRWZmZWN0LnN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0cmltbWVkID0gbGluZS50cmltKClcbiAgICAgICAgICAgICAgaWYgKHRyaW1tZWQpIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXJJZHMucHVzaCh0cmltbWVkKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICApXG5cbiAgICAgICAgY29uc3QgZXhpdENvZGUgPSB5aWVsZCogcHJvYy5leGl0Q29kZVxuXG4gICAgICAgIGlmIChleGl0Q29kZSAhPT0gMCkge1xuICAgICAgICAgIHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoXG4gICAgICAgICAgICBuZXcgRXJyb3IoYERvY2tlciBwcyBmYWlsZWQgd2l0aCBjb2RlICR7ZXhpdENvZGV9YCksXG4gICAgICAgICAgKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lcklkc1xuICAgICAgfSlcblxuICAgIGNvbnN0IHN0b3A6IERvY2tlclNlcnZpY2VbXCJzdG9wXCJdID0gKGNvbnRhaW5lck5hbWVGaWx0ZXIsIHRpbWVvdXRTZWNvbmRzKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAvLyBGaXJzdCBsaXN0IG1hdGNoaW5nIGNvbnRhaW5lcnNcbiAgICAgICAgY29uc3QgY29udGFpbmVySWRzID0geWllbGQqIGxpc3QoY29udGFpbmVyTmFtZUZpbHRlcilcblxuICAgICAgICBpZiAoY29udGFpbmVySWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHlpZWxkKiBFZmZlY3QubG9nRGVidWcoXG4gICAgICAgICAgICBgTm8gY29udGFpbmVycyBmb3VuZCBtYXRjaGluZzogJHtjb250YWluZXJOYW1lRmlsdGVyfWAsXG4gICAgICAgICAgKVxuICAgICAgICAgIHJldHVybiAwXG4gICAgICAgIH1cblxuICAgICAgICB5aWVsZCogRWZmZWN0LmxvZ0luZm8oYFN0b3BwaW5nIGNvbnRhaW5lcnM6ICR7Y29udGFpbmVySWRzLmpvaW4oXCIsIFwiKX1gKVxuXG4gICAgICAgIC8vIEJ1aWxkIHN0b3AgY29tbWFuZCB3aXRoIG9wdGlvbmFsIHRpbWVvdXRcbiAgICAgICAgLy8gLXQgMCBzZW5kcyBTSUdLSUxMIGltbWVkaWF0ZWx5LCB1c2VmdWwgZm9yIGZhc3QgcmVzdGFydHNcbiAgICAgICAgY29uc3QgdGltZW91dEFyZyA9XG4gICAgICAgICAgdGltZW91dFNlY29uZHMgIT09IHVuZGVmaW5lZCA/IFtcIi10XCIsIFN0cmluZyh0aW1lb3V0U2Vjb25kcyldIDogW11cbiAgICAgICAgY29uc3QgY29tbWFuZCA9IFBsYXRmb3JtQ29tbWFuZC5tYWtlKFxuICAgICAgICAgIHJ1bnRpbWUuZG9ja2VyUGF0aCxcbiAgICAgICAgICBcInN0b3BcIixcbiAgICAgICAgICAuLi50aW1lb3V0QXJnLFxuICAgICAgICAgIC4uLmNvbnRhaW5lcklkcyxcbiAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IHByb2MgPSB5aWVsZCogUGxhdGZvcm1Db21tYW5kLnN0YXJ0KGNvbW1hbmQpXG5cbiAgICAgICAgLy8gUHJvY2VzcyBvdXRwdXQgZm9yIGxvZ2dpbmdcbiAgICAgICAgeWllbGQqIHByb2Muc3Rkb3V0LnBpcGUoXG4gICAgICAgICAgU3RyZWFtLmRlY29kZVRleHQoKSxcbiAgICAgICAgICBTdHJlYW0uc3BsaXRMaW5lcyxcbiAgICAgICAgICBTdHJlYW0ucnVuRm9yRWFjaCgobGluZSkgPT5cbiAgICAgICAgICAgIEVmZmVjdC5sb2dEZWJ1ZyhgW0RvY2tlciBzdG9wXSAke2xpbmUudHJpbSgpfWApLFxuICAgICAgICAgICksXG4gICAgICAgIClcblxuICAgICAgICBjb25zdCBleGl0Q29kZSA9IHlpZWxkKiBwcm9jLmV4aXRDb2RlXG5cbiAgICAgICAgaWYgKGV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgICAgeWllbGQqIEVmZmVjdC5sb2dXYXJuaW5nKFxuICAgICAgICAgICAgYERvY2tlciBzdG9wIGV4aXRlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX0gKHNvbWUgY29udGFpbmVycyBtYXkgaGF2ZSBhbHJlYWR5IHN0b3BwZWQpYCxcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29udGFpbmVySWRzLmxlbmd0aFxuICAgICAgfSlcblxuICAgIGNvbnN0IGluc3BlY3Q6IERvY2tlclNlcnZpY2VbXCJpbnNwZWN0XCJdID0gKGltYWdlVXJpKSA9PlxuICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBleGVjdXRvciA9IHlpZWxkKiBDb21tYW5kRXhlY3V0b3IuQ29tbWFuZEV4ZWN1dG9yXG5cbiAgICAgICAgLy8gR2V0IGVudHJ5cG9pbnRcbiAgICAgICAgY29uc3QgZW50cnlwb2ludENtZCA9IFBsYXRmb3JtQ29tbWFuZC5tYWtlKFxuICAgICAgICAgIHJ1bnRpbWUuZG9ja2VyUGF0aCxcbiAgICAgICAgICBcImluc3BlY3RcIixcbiAgICAgICAgICBcIi0tZm9ybWF0XCIsXG4gICAgICAgICAgXCJ7e2pzb24gLkNvbmZpZy5FbnRyeXBvaW50fX1cIixcbiAgICAgICAgICBpbWFnZVVyaSxcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBlbnRyeXBvaW50UHJvYyA9IHlpZWxkKiBleGVjdXRvci5zdGFydChlbnRyeXBvaW50Q21kKVxuICAgICAgICBjb25zdCBlbnRyeXBvaW50T3V0cHV0ID0geWllbGQqIFN0cmVhbS5ydW5Db2xsZWN0KFxuICAgICAgICAgIFN0cmVhbS5kZWNvZGVUZXh0KGVudHJ5cG9pbnRQcm9jLnN0ZG91dCksXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgZW50cnlwb2ludEV4aXRDb2RlID0geWllbGQqIGVudHJ5cG9pbnRQcm9jLmV4aXRDb2RlXG4gICAgICAgIGlmIChlbnRyeXBvaW50RXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgICB5aWVsZCogRWZmZWN0LmZhaWwoXG4gICAgICAgICAgICBuZXcgRXJyb3IoYEZhaWxlZCB0byBpbnNwZWN0IGltYWdlIGVudHJ5cG9pbnQ6ICR7aW1hZ2VVcml9YCksXG4gICAgICAgICAgKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVudHJ5cG9pbnRKc29uID0gQXJyYXkuZnJvbShlbnRyeXBvaW50T3V0cHV0KS5qb2luKFwiXCIpLnRyaW0oKVxuXG4gICAgICAgIC8vIEdldCBjbWRcbiAgICAgICAgY29uc3QgY21kQ21kID0gUGxhdGZvcm1Db21tYW5kLm1ha2UoXG4gICAgICAgICAgcnVudGltZS5kb2NrZXJQYXRoLFxuICAgICAgICAgIFwiaW5zcGVjdFwiLFxuICAgICAgICAgIFwiLS1mb3JtYXRcIixcbiAgICAgICAgICBcInt7anNvbiAuQ29uZmlnLkNtZH19XCIsXG4gICAgICAgICAgaW1hZ2VVcmksXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgY21kUHJvYyA9IHlpZWxkKiBleGVjdXRvci5zdGFydChjbWRDbWQpXG4gICAgICAgIGNvbnN0IGNtZE91dHB1dCA9IHlpZWxkKiBTdHJlYW0ucnVuQ29sbGVjdChcbiAgICAgICAgICBTdHJlYW0uZGVjb2RlVGV4dChjbWRQcm9jLnN0ZG91dCksXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgY21kRXhpdENvZGUgPSB5aWVsZCogY21kUHJvYy5leGl0Q29kZVxuICAgICAgICBpZiAoY21kRXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgICB5aWVsZCogRWZmZWN0LmZhaWwoXG4gICAgICAgICAgICBuZXcgRXJyb3IoYEZhaWxlZCB0byBpbnNwZWN0IGltYWdlIGNtZDogJHtpbWFnZVVyaX1gKSxcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY21kSnNvbiA9IEFycmF5LmZyb20oY21kT3V0cHV0KS5qb2luKFwiXCIpLnRyaW0oKVxuXG4gICAgICAgIC8vIFBhcnNlIEpTT04gLSBudWxsIGlzIHZhbGlkLCBzbyBoYW5kbGUgdGhhdFxuICAgICAgICBjb25zdCBwYXJzZUpzb25BcnJheSA9IChqc29uOiBzdHJpbmcpOiBzdHJpbmdbXSB8IG51bGwgPT4ge1xuICAgICAgICAgIGlmIChqc29uID09PSBcIm51bGxcIiB8fCBqc29uID09PSBcIlwiKSByZXR1cm4gbnVsbFxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGpzb24pXG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheShwYXJzZWQpID8gcGFyc2VkIDogbnVsbFxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVudHJ5cG9pbnQ6IHBhcnNlSnNvbkFycmF5KGVudHJ5cG9pbnRKc29uKSxcbiAgICAgICAgICBjbWQ6IHBhcnNlSnNvbkFycmF5KGNtZEpzb24pLFxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJ1bixcbiAgICAgIHJ1blNjb3BlZCxcbiAgICAgIGJ1aWxkLFxuICAgICAgcHVsbCxcbiAgICAgIHN0b3AsXG4gICAgICBsaXN0LFxuICAgICAgZ2V0UnVudGltZUluZm8sXG4gICAgICBpbnNwZWN0LFxuICAgIH0gc2F0aXNmaWVzIERvY2tlclNlcnZpY2VcbiAgfSxcbilcblxuLyoqXG4gKiBMaXZlIERvY2tlciBzZXJ2aWNlIGxheWVyLlxuICogTm90ZTogRG9lcyBub3QgcmVxdWlyZSBDb21tYW5kRXhlY3V0b3IgaW4gdGhlIGxheWVyIC0gaXQncyByZXF1aXJlZFxuICogd2hlbiB0aGUgc2VydmljZSBtZXRob2RzIGFyZSBjYWxsZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBEb2NrZXJMaXZlOiBMYXllci5MYXllcjxEb2NrZXIsIEVycm9yPiA9IExheWVyLmVmZmVjdChcbiAgRG9ja2VyLFxuICBtYWtlRG9ja2VyU2VydmljZSxcbilcblxuLyoqXG4gKiBDcmVhdGUgYSBjb250YWluZXIgY29uZmlnIGZvciBydW5uaW5nIGEgTGFtYmRhIGNvbnRhaW5lci5cbiAqL1xuZXhwb3J0IGNvbnN0IG1ha2VMYW1iZGFDb250YWluZXJDb25maWcgPSAob3B0aW9uczoge1xuICBpbWFnZVVyaTogc3RyaW5nXG4gIHJ1bnRpbWVBcGlIb3N0OiBzdHJpbmdcbiAgcnVudGltZUFwaVBvcnQ6IG51bWJlclxuICBmdW5jdGlvbk5hbWU6IHN0cmluZ1xuICBmdW5jdGlvblZlcnNpb246IHN0cmluZ1xuICBtZW1vcnlNQjogbnVtYmVyXG4gIHRpbWVvdXRTZWNvbmRzOiBudW1iZXJcbiAgaGFuZGxlcj86IHN0cmluZ1xuICBhd3NSZWdpb24/OiBzdHJpbmdcbiAgcGxhdGZvcm0/OiBzdHJpbmdcbiAgYWRkaXRpb25hbEVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cbiAgaW52b2NhdGlvbkNvbnRleHRzPzogTWFwPHN0cmluZywgeyBudW06IG51bWJlciB9PlxufSk6IERvY2tlclJ1bkNvbmZpZyA9PiAoe1xuICBpbWFnZVVyaTogb3B0aW9ucy5pbWFnZVVyaSxcbiAgY29udGFpbmVyTmFtZTogYGxhbWJkYS0ke29wdGlvbnMuZnVuY3Rpb25OYW1lLnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCBcIi1cIil9YCxcbiAgcGxhdGZvcm06IG9wdGlvbnMucGxhdGZvcm0sXG4gIGVudmlyb25tZW50OiB7XG4gICAgQVdTX0xBTUJEQV9SVU5USU1FX0FQSTogYCR7b3B0aW9ucy5ydW50aW1lQXBpSG9zdH06JHtvcHRpb25zLnJ1bnRpbWVBcGlQb3J0fWAsXG4gICAgQVdTX0xBTUJEQV9GVU5DVElPTl9OQU1FOiBvcHRpb25zLmZ1bmN0aW9uTmFtZSxcbiAgICBBV1NfTEFNQkRBX0ZVTkNUSU9OX1ZFUlNJT046IG9wdGlvbnMuZnVuY3Rpb25WZXJzaW9uLFxuICAgIEFXU19MQU1CREFfRlVOQ1RJT05fTUVNT1JZX1NJWkU6IFN0cmluZyhvcHRpb25zLm1lbW9yeU1CKSxcbiAgICBBV1NfUkVHSU9OOiBvcHRpb25zLmF3c1JlZ2lvbiA/PyBcInVzLWVhc3QtMVwiLFxuICAgIEFXU19ERUZBVUxUX1JFR0lPTjogb3B0aW9ucy5hd3NSZWdpb24gPz8gXCJ1cy1lYXN0LTFcIixcbiAgICBBV1NfTEFNQkRBX0xPR19HUk9VUF9OQU1FOiBgL2F3cy9sYW1iZGEvJHtvcHRpb25zLmZ1bmN0aW9uTmFtZX1gLFxuICAgIEFXU19MQU1CREFfTE9HX1NUUkVBTV9OQU1FOiBcImxvY2FsXCIsXG4gICAgX0hBTkRMRVI6IG9wdGlvbnMuaGFuZGxlciA/PyBcImluZGV4LmhhbmRsZXJcIixcbiAgICAuLi5vcHRpb25zLmFkZGl0aW9uYWxFbnYsXG4gIH0sXG4gIG1lbW9yeU1COiBvcHRpb25zLm1lbW9yeU1CLFxuICB0aW1lb3V0U2Vjb25kczogb3B0aW9ucy50aW1lb3V0U2Vjb25kcyxcbiAgbmV0d29ya01vZGU6IFwiYnJpZGdlXCIsXG4gIGludm9jYXRpb25Db250ZXh0czogb3B0aW9ucy5pbnZvY2F0aW9uQ29udGV4dHMsXG59KVxuXG4vKipcbiAqIFN0cmVhbSBvdXRwdXQgZnJvbSBhIERvY2tlciBjb250YWluZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29udGFpbmVyT3V0cHV0IHtcbiAgdHlwZTogXCJzdGRvdXRcIiB8IFwic3RkZXJyXCJcbiAgZGF0YTogc3RyaW5nXG59XG5cbi8qKlxuICogU2hlbGwtcXVvdGUgYSBzdHJpbmcgZm9yIHNhZmUgaW5jbHVzaW9uIGluIGEgc2hlbGwgY29tbWFuZC5cbiAqIFVzZXMgc2luZ2xlIHF1b3RlcyBhbmQgZXNjYXBlcyBhbnkgZW1iZWRkZWQgc2luZ2xlIHF1b3Rlcy5cbiAqL1xuY29uc3Qgc2hlbGxRdW90ZSA9IChzOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAvLyBTaW5nbGUgcXVvdGVzIGFyZSBzYWZlc3QgLSBlc2NhcGUgYW55IGVtYmVkZGVkIHNpbmdsZSBxdW90ZXNcbiAgcmV0dXJuIGAnJHtzLnJlcGxhY2UoLycvZywgXCInXFxcXCcnXCIpfSdgXG59XG5cbi8qKlxuICogQnVpbGQgYSB3cmFwcGVyIGNvbW1hbmQgdGhhdCBzdGFydHMgTGFtYmRhIGV4dGVuc2lvbnMgYmVmb3JlIHRoZSBtYWluIGFwcC5cbiAqXG4gKiBUaGlzIG1pbWljcyBBV1MgTGFtYmRhJ3MgYmVoYXZpb3Igb2YgYXV0b21hdGljYWxseSBzdGFydGluZyBhbGwgZXhlY3V0YWJsZXNcbiAqIGluIC9vcHQvZXh0ZW5zaW9ucy8gYXMgYmFja2dyb3VuZCBwcm9jZXNzZXMgYmVmb3JlIHJ1bm5pbmcgdGhlIG1haW4gY29tbWFuZC5cbiAqXG4gKiBAcGFyYW0gb3JpZ2luYWxFbnRyeXBvaW50IC0gVGhlIGltYWdlJ3Mgb3JpZ2luYWwgRU5UUllQT0lOVFxuICogQHBhcmFtIG9yaWdpbmFsQ21kIC0gVGhlIGltYWdlJ3Mgb3JpZ2luYWwgQ01EXG4gKiBAcmV0dXJucyBFbnRyeXBvaW50IGFuZCBjb21tYW5kIGFycmF5cyB0byBwYXNzIHRvIERvY2tlclxuICovXG5leHBvcnQgY29uc3QgYnVpbGRFeHRlbnNpb25XcmFwcGVyQ29tbWFuZCA9IChcbiAgb3JpZ2luYWxFbnRyeXBvaW50OiBzdHJpbmdbXSB8IG51bGwsXG4gIG9yaWdpbmFsQ21kOiBzdHJpbmdbXSB8IG51bGwsXG4pOiB7IGVudHJ5cG9pbnQ6IHN0cmluZ1tdOyBjb21tYW5kOiBzdHJpbmdbXSB9ID0+IHtcbiAgLy8gQ29tYmluZSBvcmlnaW5hbCBlbnRyeXBvaW50ICsgY21kIGludG8gdGhlIGZ1bGwgY29tbWFuZFxuICAvLyBEb2NrZXIgYmVoYXZpb3I6IEVOVFJZUE9JTlQgKyBDTUQgYXJlIGNvbmNhdGVuYXRlZFxuICBjb25zdCBvcmlnaW5hbENvbW1hbmQgPSBbXG4gICAgLi4uKG9yaWdpbmFsRW50cnlwb2ludCA/PyBbXSksXG4gICAgLi4uKG9yaWdpbmFsQ21kID8/IFtdKSxcbiAgXVxuXG4gIC8vIFNjcmlwdCB0byBzdGFydCBhbGwgZXhlY3V0YWJsZSBmaWxlcyBpbiAvb3B0L2V4dGVuc2lvbnMvIGFzIGJhY2tncm91bmQgcHJvY2Vzc2VzXG4gIGNvbnN0IGV4dGVuc2lvblN0YXJ0ZXIgPVxuICAgICdmb3IgZXh0IGluIC9vcHQvZXh0ZW5zaW9ucy8qOyBkbyBbIC14IFwiJGV4dFwiIF0gJiYgXCIkZXh0XCIgJiBkb25lJ1xuXG4gIC8vIEJ1aWxkIHRoZSBmdWxsIHdyYXBwZXIgY29tbWFuZFxuICBsZXQgZnVsbENvbW1hbmQ6IHN0cmluZ1xuICBpZiAob3JpZ2luYWxDb21tYW5kLmxlbmd0aCA+IDApIHtcbiAgICAvLyBRdW90ZSBlYWNoIGFyZ3VtZW50IGFuZCBqb2luIHdpdGggc3BhY2VzXG4gICAgY29uc3QgcXVvdGVkT3JpZ2luYWwgPSBvcmlnaW5hbENvbW1hbmQubWFwKHNoZWxsUXVvdGUpLmpvaW4oXCIgXCIpXG4gICAgLy8gU3RhcnQgZXh0ZW5zaW9ucywgdGhlbiBleGVjIHRoZSBvcmlnaW5hbCBjb21tYW5kXG4gICAgZnVsbENvbW1hbmQgPSBgJHtleHRlbnNpb25TdGFydGVyfTsgZXhlYyAke3F1b3RlZE9yaWdpbmFsfWBcbiAgfSBlbHNlIHtcbiAgICAvLyBObyBvcmlnaW5hbCBjb21tYW5kIC0ganVzdCBzdGFydCBleHRlbnNpb25zICh1bnVzdWFsIGJ1dCBoYW5kbGUgaXQpXG4gICAgZnVsbENvbW1hbmQgPSBleHRlbnNpb25TdGFydGVyXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVudHJ5cG9pbnQ6IFtcIi9iaW4vc2hcIl0sXG4gICAgY29tbWFuZDogW1wiLWNcIiwgZnVsbENvbW1hbmRdLFxuICB9XG59XG4iXX0=
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Types for Docker container management.
3
+ */
4
+ /**
5
+ * Configuration for running a Docker container.
6
+ */
7
+ export interface DockerRunConfig {
8
+ /** The Docker image URI to run */
9
+ imageUri: string;
10
+ /** Container name (optional) */
11
+ containerName?: string;
12
+ /** Platform (e.g., linux/arm64, linux/amd64) for cross-platform execution */
13
+ platform?: string;
14
+ /** Environment variables to pass to the container */
15
+ environment: Record<string, string>;
16
+ /** Memory limit in MB */
17
+ memoryMB: number;
18
+ /** Timeout in seconds */
19
+ timeoutSeconds: number;
20
+ /** Network mode (bridge, host, none) */
21
+ networkMode: "bridge" | "host" | "none";
22
+ /** Extra host entries (--add-host) */
23
+ extraHosts?: string[];
24
+ /** Working directory inside the container */
25
+ workdir?: string;
26
+ /** Additional Docker run arguments */
27
+ additionalArgs?: string[];
28
+ /** Optional invocation context map for log prefixing (requestId -> { num }) */
29
+ invocationContexts?: Map<string, {
30
+ num: number;
31
+ }>;
32
+ /** Override the container's entrypoint */
33
+ entrypoint?: string[];
34
+ /** Override the container's command (arguments after the image) */
35
+ command?: string[];
36
+ }
37
+ /**
38
+ * Docker image configuration from inspection.
39
+ */
40
+ export interface DockerImageConfig {
41
+ /** The image's ENTRYPOINT */
42
+ entrypoint: string[] | null;
43
+ /** The image's CMD */
44
+ cmd: string[] | null;
45
+ }
46
+ /**
47
+ * Result of running a Docker container.
48
+ */
49
+ export interface DockerRunResult {
50
+ /** Exit code of the container */
51
+ exitCode: number;
52
+ /** Stdout from the container */
53
+ stdout: string;
54
+ /** Stderr from the container */
55
+ stderr: string;
56
+ }
57
+ /**
58
+ * Docker runtime detection result.
59
+ */
60
+ export interface DockerRuntimeInfo {
61
+ /** Path to Docker executable */
62
+ dockerPath: string;
63
+ /** Whether running on Linux */
64
+ isLinux: boolean;
65
+ /** Whether running in WSL */
66
+ isWsl: boolean;
67
+ /** Whether Docker Desktop is detected */
68
+ isDockerDesktop: boolean;
69
+ /** Host address to use for container-to-host communication */
70
+ hostAddress: string;
71
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for Docker container management.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2RvY2tlci90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVHlwZXMgZm9yIERvY2tlciBjb250YWluZXIgbWFuYWdlbWVudC5cbiAqL1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIHJ1bm5pbmcgYSBEb2NrZXIgY29udGFpbmVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERvY2tlclJ1bkNvbmZpZyB7XG4gIC8qKiBUaGUgRG9ja2VyIGltYWdlIFVSSSB0byBydW4gKi9cbiAgaW1hZ2VVcmk6IHN0cmluZ1xuICAvKiogQ29udGFpbmVyIG5hbWUgKG9wdGlvbmFsKSAqL1xuICBjb250YWluZXJOYW1lPzogc3RyaW5nXG4gIC8qKiBQbGF0Zm9ybSAoZS5nLiwgbGludXgvYXJtNjQsIGxpbnV4L2FtZDY0KSBmb3IgY3Jvc3MtcGxhdGZvcm0gZXhlY3V0aW9uICovXG4gIHBsYXRmb3JtPzogc3RyaW5nXG4gIC8qKiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgdG8gcGFzcyB0byB0aGUgY29udGFpbmVyICovXG4gIGVudmlyb25tZW50OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+XG4gIC8qKiBNZW1vcnkgbGltaXQgaW4gTUIgKi9cbiAgbWVtb3J5TUI6IG51bWJlclxuICAvKiogVGltZW91dCBpbiBzZWNvbmRzICovXG4gIHRpbWVvdXRTZWNvbmRzOiBudW1iZXJcbiAgLyoqIE5ldHdvcmsgbW9kZSAoYnJpZGdlLCBob3N0LCBub25lKSAqL1xuICBuZXR3b3JrTW9kZTogXCJicmlkZ2VcIiB8IFwiaG9zdFwiIHwgXCJub25lXCJcbiAgLyoqIEV4dHJhIGhvc3QgZW50cmllcyAoLS1hZGQtaG9zdCkgKi9cbiAgZXh0cmFIb3N0cz86IHN0cmluZ1tdXG4gIC8qKiBXb3JraW5nIGRpcmVjdG9yeSBpbnNpZGUgdGhlIGNvbnRhaW5lciAqL1xuICB3b3JrZGlyPzogc3RyaW5nXG4gIC8qKiBBZGRpdGlvbmFsIERvY2tlciBydW4gYXJndW1lbnRzICovXG4gIGFkZGl0aW9uYWxBcmdzPzogc3RyaW5nW11cbiAgLyoqIE9wdGlvbmFsIGludm9jYXRpb24gY29udGV4dCBtYXAgZm9yIGxvZyBwcmVmaXhpbmcgKHJlcXVlc3RJZCAtPiB7IG51bSB9KSAqL1xuICBpbnZvY2F0aW9uQ29udGV4dHM/OiBNYXA8c3RyaW5nLCB7IG51bTogbnVtYmVyIH0+XG4gIC8qKiBPdmVycmlkZSB0aGUgY29udGFpbmVyJ3MgZW50cnlwb2ludCAqL1xuICBlbnRyeXBvaW50Pzogc3RyaW5nW11cbiAgLyoqIE92ZXJyaWRlIHRoZSBjb250YWluZXIncyBjb21tYW5kIChhcmd1bWVudHMgYWZ0ZXIgdGhlIGltYWdlKSAqL1xuICBjb21tYW5kPzogc3RyaW5nW11cbn1cblxuLyoqXG4gKiBEb2NrZXIgaW1hZ2UgY29uZmlndXJhdGlvbiBmcm9tIGluc3BlY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRG9ja2VySW1hZ2VDb25maWcge1xuICAvKiogVGhlIGltYWdlJ3MgRU5UUllQT0lOVCAqL1xuICBlbnRyeXBvaW50OiBzdHJpbmdbXSB8IG51bGxcbiAgLyoqIFRoZSBpbWFnZSdzIENNRCAqL1xuICBjbWQ6IHN0cmluZ1tdIHwgbnVsbFxufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBydW5uaW5nIGEgRG9ja2VyIGNvbnRhaW5lci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb2NrZXJSdW5SZXN1bHQge1xuICAvKiogRXhpdCBjb2RlIG9mIHRoZSBjb250YWluZXIgKi9cbiAgZXhpdENvZGU6IG51bWJlclxuICAvKiogU3Rkb3V0IGZyb20gdGhlIGNvbnRhaW5lciAqL1xuICBzdGRvdXQ6IHN0cmluZ1xuICAvKiogU3RkZXJyIGZyb20gdGhlIGNvbnRhaW5lciAqL1xuICBzdGRlcnI6IHN0cmluZ1xufVxuXG4vKipcbiAqIERvY2tlciBydW50aW1lIGRldGVjdGlvbiByZXN1bHQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRG9ja2VyUnVudGltZUluZm8ge1xuICAvKiogUGF0aCB0byBEb2NrZXIgZXhlY3V0YWJsZSAqL1xuICBkb2NrZXJQYXRoOiBzdHJpbmdcbiAgLyoqIFdoZXRoZXIgcnVubmluZyBvbiBMaW51eCAqL1xuICBpc0xpbnV4OiBib29sZWFuXG4gIC8qKiBXaGV0aGVyIHJ1bm5pbmcgaW4gV1NMICovXG4gIGlzV3NsOiBib29sZWFuXG4gIC8qKiBXaGV0aGVyIERvY2tlciBEZXNrdG9wIGlzIGRldGVjdGVkICovXG4gIGlzRG9ja2VyRGVza3RvcDogYm9vbGVhblxuICAvKiogSG9zdCBhZGRyZXNzIHRvIHVzZSBmb3IgY29udGFpbmVyLXRvLWhvc3QgY29tbXVuaWNhdGlvbiAqL1xuICBob3N0QWRkcmVzczogc3RyaW5nXG59XG4iXX0=
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Docker context file watching for automatic container rebuilds.
3
+ *
4
+ * Watches Docker context directories and emits events when files change,
5
+ * triggering container rebuilds for Docker-based Lambda functions.
6
+ */
7
+ import { Stream } from "effect";
8
+ /**
9
+ * Event emitted when a file changes in a Docker context.
10
+ */
11
+ export interface DockerContextChangeEvent {
12
+ /** The function ID that owns this Docker context */
13
+ functionId: string;
14
+ /** The absolute path to the file that changed */
15
+ filePath: string;
16
+ /** Type of change */
17
+ type: "add" | "change" | "unlink";
18
+ }
19
+ /**
20
+ * Configuration for a Docker function to watch.
21
+ */
22
+ export interface WatchedDockerFunction {
23
+ /** Unique function identifier (Lambda function name) */
24
+ functionId: string;
25
+ /** Absolute path to the Docker context directory */
26
+ dockerContextPath: string;
27
+ }
28
+ /**
29
+ * Watch multiple Docker context directories for file changes.
30
+ *
31
+ * Creates a single chokidar watcher that monitors all registered Docker
32
+ * contexts and emits events when files change. The events are debounced
33
+ * to prevent rapid successive rebuilds during batch operations.
34
+ *
35
+ * @param functions - Array of Docker functions to watch
36
+ * @param debounceMs - Debounce delay in milliseconds (default: 500)
37
+ * @returns Stream of change events with function ownership resolved
38
+ */
39
+ export declare const watchDockerContexts: (functions: WatchedDockerFunction[], debounceMs?: number) => Stream.Stream<DockerContextChangeEvent, Error>;
40
+ /**
41
+ * Create a watcher for a single Docker function.
42
+ * Convenience wrapper around watchDockerContexts for single-function use.
43
+ */
44
+ export declare const watchSingleDockerContext: (functionId: string, dockerContextPath: string, debounceMs?: number) => Stream.Stream<DockerContextChangeEvent, Error>;