@cdklabs/cdk-appmod-catalog-blueprints 1.4.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/.jsii +2579 -194
  2. package/lib/document-processing/adapter/adapter.d.ts +4 -2
  3. package/lib/document-processing/adapter/adapter.js +1 -1
  4. package/lib/document-processing/adapter/queued-s3-adapter.d.ts +9 -2
  5. package/lib/document-processing/adapter/queued-s3-adapter.js +29 -15
  6. package/lib/document-processing/agentic-document-processing.d.ts +4 -0
  7. package/lib/document-processing/agentic-document-processing.js +20 -10
  8. package/lib/document-processing/base-document-processing.d.ts +54 -2
  9. package/lib/document-processing/base-document-processing.js +136 -82
  10. package/lib/document-processing/bedrock-document-processing.d.ts +202 -2
  11. package/lib/document-processing/bedrock-document-processing.js +717 -77
  12. package/lib/document-processing/chunking-config.d.ts +614 -0
  13. package/lib/document-processing/chunking-config.js +5 -0
  14. package/lib/document-processing/default-document-processing-config.js +1 -1
  15. package/lib/document-processing/index.d.ts +1 -0
  16. package/lib/document-processing/index.js +2 -1
  17. package/lib/document-processing/resources/aggregation/handler.py +567 -0
  18. package/lib/document-processing/resources/aggregation/requirements.txt +7 -0
  19. package/lib/document-processing/resources/aggregation/test_handler.py +362 -0
  20. package/lib/document-processing/resources/cleanup/handler.py +276 -0
  21. package/lib/document-processing/resources/cleanup/requirements.txt +5 -0
  22. package/lib/document-processing/resources/cleanup/test_handler.py +436 -0
  23. package/lib/document-processing/resources/default-bedrock-invoke/index.py +85 -3
  24. package/lib/document-processing/resources/default-bedrock-invoke/test_index.py +622 -0
  25. package/lib/document-processing/resources/pdf-chunking/README.md +313 -0
  26. package/lib/document-processing/resources/pdf-chunking/chunking_strategies.py +460 -0
  27. package/lib/document-processing/resources/pdf-chunking/error_handling.py +491 -0
  28. package/lib/document-processing/resources/pdf-chunking/handler.py +958 -0
  29. package/lib/document-processing/resources/pdf-chunking/metrics.py +435 -0
  30. package/lib/document-processing/resources/pdf-chunking/requirements.txt +3 -0
  31. package/lib/document-processing/resources/pdf-chunking/strategy_selection.py +420 -0
  32. package/lib/document-processing/resources/pdf-chunking/structured_logging.py +457 -0
  33. package/lib/document-processing/resources/pdf-chunking/test_chunking_strategies.py +353 -0
  34. package/lib/document-processing/resources/pdf-chunking/test_error_handling.py +487 -0
  35. package/lib/document-processing/resources/pdf-chunking/test_handler.py +609 -0
  36. package/lib/document-processing/resources/pdf-chunking/test_integration.py +694 -0
  37. package/lib/document-processing/resources/pdf-chunking/test_metrics.py +532 -0
  38. package/lib/document-processing/resources/pdf-chunking/test_strategy_selection.py +471 -0
  39. package/lib/document-processing/resources/pdf-chunking/test_structured_logging.py +449 -0
  40. package/lib/document-processing/resources/pdf-chunking/test_token_estimation.py +374 -0
  41. package/lib/document-processing/resources/pdf-chunking/token_estimation.py +189 -0
  42. package/lib/document-processing/tests/agentic-document-processing-nag.test.js +4 -3
  43. package/lib/document-processing/tests/agentic-document-processing.test.js +488 -4
  44. package/lib/document-processing/tests/base-document-processing-nag.test.js +9 -2
  45. package/lib/document-processing/tests/base-document-processing-schema.test.d.ts +1 -0
  46. package/lib/document-processing/tests/base-document-processing-schema.test.js +337 -0
  47. package/lib/document-processing/tests/base-document-processing.test.js +114 -8
  48. package/lib/document-processing/tests/bedrock-document-processing-chunking-nag.test.d.ts +1 -0
  49. package/lib/document-processing/tests/bedrock-document-processing-chunking-nag.test.js +382 -0
  50. package/lib/document-processing/tests/bedrock-document-processing-nag.test.js +4 -3
  51. package/lib/document-processing/tests/bedrock-document-processing-security.test.d.ts +1 -0
  52. package/lib/document-processing/tests/bedrock-document-processing-security.test.js +389 -0
  53. package/lib/document-processing/tests/bedrock-document-processing.test.js +808 -8
  54. package/lib/document-processing/tests/chunking-config.test.d.ts +1 -0
  55. package/lib/document-processing/tests/chunking-config.test.js +238 -0
  56. package/lib/document-processing/tests/queued-s3-adapter-nag.test.js +9 -2
  57. package/lib/document-processing/tests/queued-s3-adapter.test.js +17 -6
  58. package/lib/framework/agents/base-agent.js +1 -1
  59. package/lib/framework/agents/batch-agent.js +1 -1
  60. package/lib/framework/agents/default-agent-config.js +1 -1
  61. package/lib/framework/bedrock/bedrock.js +1 -1
  62. package/lib/framework/custom-resource/default-runtimes.js +1 -1
  63. package/lib/framework/foundation/access-log.js +1 -1
  64. package/lib/framework/foundation/eventbridge-broker.js +1 -1
  65. package/lib/framework/foundation/network.d.ts +4 -2
  66. package/lib/framework/foundation/network.js +52 -41
  67. package/lib/framework/tests/access-log.test.js +5 -2
  68. package/lib/framework/tests/batch-agent.test.js +5 -2
  69. package/lib/framework/tests/bedrock.test.js +5 -2
  70. package/lib/framework/tests/eventbridge-broker.test.js +5 -2
  71. package/lib/framework/tests/framework-nag.test.js +26 -7
  72. package/lib/framework/tests/network.test.js +30 -2
  73. package/lib/tsconfig.tsbuildinfo +1 -1
  74. package/lib/utilities/data-loader.js +1 -1
  75. package/lib/utilities/lambda-iam-utils.js +1 -1
  76. package/lib/utilities/observability/cloudfront-distribution-observability-property-injector.js +1 -1
  77. package/lib/utilities/observability/default-observability-config.js +1 -1
  78. package/lib/utilities/observability/lambda-observability-property-injector.js +1 -1
  79. package/lib/utilities/observability/log-group-data-protection-utils.js +1 -1
  80. package/lib/utilities/observability/powertools-config.d.ts +10 -1
  81. package/lib/utilities/observability/powertools-config.js +19 -3
  82. package/lib/utilities/observability/state-machine-observability-property-injector.js +1 -1
  83. package/lib/utilities/test-utils.d.ts +43 -0
  84. package/lib/utilities/test-utils.js +56 -0
  85. package/lib/utilities/tests/data-loader-nag.test.js +3 -2
  86. package/lib/utilities/tests/data-loader.test.js +3 -2
  87. package/lib/webapp/frontend-construct.js +1 -1
  88. package/lib/webapp/tests/frontend-construct-nag.test.js +3 -2
  89. package/lib/webapp/tests/frontend-construct.test.js +3 -2
  90. package/package.json +6 -5
  91. package/lib/document-processing/resources/default-error-handler/index.js +0 -46
  92. package/lib/document-processing/resources/default-pdf-processor/index.js +0 -46
  93. package/lib/document-processing/resources/default-pdf-validator/index.js +0 -36
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const aws_cdk_lib_1 = require("aws-cdk-lib");
4
4
  const assertions_1 = require("aws-cdk-lib/assertions");
5
5
  const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets");
6
+ const test_utils_1 = require("../../utilities/test-utils");
6
7
  const agentic_document_processing_1 = require("../agentic-document-processing");
8
+ const bedrock_document_processing_1 = require("../bedrock-document-processing");
7
9
  describe('AgenticDocumentProcessing', () => {
10
+ let app;
8
11
  let basicStack;
9
12
  let crossRegionStack;
10
13
  let defaultModelStack;
@@ -12,7 +15,9 @@ describe('AgenticDocumentProcessing', () => {
12
15
  let crossRegionTemplate;
13
16
  let defaultModelTemplate;
14
17
  beforeAll(() => {
15
- basicStack = new aws_cdk_lib_1.Stack();
18
+ // Use createTestApp() to skip bundling and speed up tests
19
+ app = (0, test_utils_1.createTestApp)();
20
+ basicStack = new aws_cdk_lib_1.Stack(app, 'BasicStack');
16
21
  const systemPrompt = new aws_s3_assets_1.Asset(basicStack, 'SystemPrompt', {
17
22
  path: __dirname + '/../resources/default-strands-agent',
18
23
  });
@@ -26,7 +31,7 @@ describe('AgenticDocumentProcessing', () => {
26
31
  prompt: 'Custom processing prompt',
27
32
  },
28
33
  });
29
- crossRegionStack = new aws_cdk_lib_1.Stack();
34
+ crossRegionStack = new aws_cdk_lib_1.Stack(app, 'CrossRegionStack');
30
35
  const crossRegionPrompt = new aws_s3_assets_1.Asset(crossRegionStack, 'SystemPrompt', {
31
36
  path: __dirname + '/../resources/default-strands-agent',
32
37
  });
@@ -40,7 +45,7 @@ describe('AgenticDocumentProcessing', () => {
40
45
  prompt: 'Test prompt',
41
46
  },
42
47
  });
43
- defaultModelStack = new aws_cdk_lib_1.Stack();
48
+ defaultModelStack = new aws_cdk_lib_1.Stack(app, 'DefaultModelStack');
44
49
  const defaultPrompt = new aws_s3_assets_1.Asset(defaultModelStack, 'SystemPrompt', {
45
50
  path: __dirname + '/../resources/default-strands-agent',
46
51
  });
@@ -176,5 +181,484 @@ describe('AgenticDocumentProcessing', () => {
176
181
  basicTemplate.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
177
182
  });
178
183
  });
184
+ describe('Chunking inheritance from BedrockDocumentProcessing', () => {
185
+ describe('preprocessingStep() inheritance', () => {
186
+ test('inherits preprocessingStep() from BedrockDocumentProcessing', () => {
187
+ // Verify that AgenticDocumentProcessing extends BedrockDocumentProcessing
188
+ // and inherits the preprocessingStep() method
189
+ const testApp = (0, test_utils_1.createTestApp)();
190
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticChunkingStack');
191
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
192
+ path: __dirname + '/../resources/default-strands-agent',
193
+ });
194
+ const agenticProcessor = new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticChunkingTest', {
195
+ enableChunking: true,
196
+ chunkingConfig: {
197
+ strategy: 'hybrid',
198
+ maxPagesPerChunk: 100,
199
+ targetTokensPerChunk: 80000,
200
+ pageThreshold: 100,
201
+ tokenThreshold: 150000,
202
+ },
203
+ processingAgentParameters: {
204
+ agentName: 'ChunkingTestAgent',
205
+ agentDefinition: {
206
+ bedrockModel: {},
207
+ systemPrompt,
208
+ },
209
+ prompt: 'Test prompt',
210
+ },
211
+ });
212
+ // Verify the construct is created successfully
213
+ expect(agenticProcessor).toBeDefined();
214
+ const template = assertions_1.Template.fromStack(chunkingStack);
215
+ // Verify PDF chunking Lambda is created (inherited from BedrockDocumentProcessing)
216
+ const lambdas = template.findResources('AWS::Lambda::Function');
217
+ const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
218
+ lambda.Properties.MemorySize === 2048 &&
219
+ lambda.Properties.Timeout === 600);
220
+ expect(chunkingLambda).toBeDefined();
221
+ expect(chunkingLambda).toHaveProperty('Properties.Handler', 'handler.handler');
222
+ });
223
+ test('preprocessingStep() returns undefined when chunking is disabled', () => {
224
+ // Verify that when enableChunking is false, no chunking Lambda is created
225
+ const testApp = (0, test_utils_1.createTestApp)();
226
+ const noChunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticNoChunkingStack');
227
+ const systemPrompt = new aws_s3_assets_1.Asset(noChunkingStack, 'SystemPrompt', {
228
+ path: __dirname + '/../resources/default-strands-agent',
229
+ });
230
+ new agentic_document_processing_1.AgenticDocumentProcessing(noChunkingStack, 'AgenticNoChunkingTest', {
231
+ enableChunking: false,
232
+ processingAgentParameters: {
233
+ agentName: 'NoChunkingAgent',
234
+ agentDefinition: {
235
+ bedrockModel: {},
236
+ systemPrompt,
237
+ },
238
+ prompt: 'Test prompt',
239
+ },
240
+ });
241
+ const template = assertions_1.Template.fromStack(noChunkingStack);
242
+ // Verify NO PDF chunking Lambda is created
243
+ const lambdas = template.findResources('AWS::Lambda::Function');
244
+ const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
245
+ lambda.Properties.MemorySize === 2048 &&
246
+ lambda.Properties.Timeout === 600);
247
+ expect(chunkingLambda).toBeUndefined();
248
+ });
249
+ test('chunking Lambda has correct environment variables', () => {
250
+ const testApp = (0, test_utils_1.createTestApp)();
251
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticChunkingEnvStack');
252
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
253
+ path: __dirname + '/../resources/default-strands-agent',
254
+ });
255
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticChunkingEnvTest', {
256
+ enableChunking: true,
257
+ chunkingConfig: {
258
+ strategy: 'token-based',
259
+ tokenThreshold: 200000,
260
+ maxTokensPerChunk: 120000,
261
+ },
262
+ processingAgentParameters: {
263
+ agentName: 'EnvTestAgent',
264
+ agentDefinition: {
265
+ bedrockModel: {},
266
+ systemPrompt,
267
+ },
268
+ prompt: 'Test prompt',
269
+ },
270
+ });
271
+ const template = assertions_1.Template.fromStack(chunkingStack);
272
+ // Find the chunking Lambda
273
+ const lambdas = template.findResources('AWS::Lambda::Function');
274
+ const chunkingLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
275
+ lambda.Properties.MemorySize === 2048);
276
+ expect(chunkingLambda).toBeDefined();
277
+ expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'token-based');
278
+ expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.TOKEN_THRESHOLD', '200000');
279
+ expect(chunkingLambda).toHaveProperty('Properties.Environment.Variables.MAX_TOKENS_PER_CHUNK', '120000');
280
+ });
281
+ });
282
+ describe('createProcessingWorkflow() inheritance', () => {
283
+ test('inherits createProcessingWorkflow() from BedrockDocumentProcessing', () => {
284
+ // Verify that the state machine includes the Choice state for chunking
285
+ const testApp = (0, test_utils_1.createTestApp)();
286
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticWorkflowStack');
287
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
288
+ path: __dirname + '/../resources/default-strands-agent',
289
+ });
290
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticWorkflowTest', {
291
+ enableChunking: true,
292
+ chunkingConfig: {
293
+ strategy: 'hybrid',
294
+ processingMode: 'parallel',
295
+ maxConcurrency: 5,
296
+ },
297
+ processingAgentParameters: {
298
+ agentName: 'WorkflowTestAgent',
299
+ agentDefinition: {
300
+ bedrockModel: {},
301
+ systemPrompt,
302
+ },
303
+ prompt: 'Test prompt',
304
+ },
305
+ });
306
+ const template = assertions_1.Template.fromStack(chunkingStack);
307
+ // Verify state machine is created
308
+ template.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
309
+ // Verify state machine has encryption (inherited behavior)
310
+ template.hasResourceProperties('AWS::StepFunctions::StateMachine', {
311
+ EncryptionConfiguration: assertions_1.Match.objectLike({
312
+ Type: 'CUSTOMER_MANAGED_KMS_KEY',
313
+ }),
314
+ });
315
+ });
316
+ test('creates aggregation Lambda when chunking is enabled', () => {
317
+ const testApp = (0, test_utils_1.createTestApp)();
318
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticAggregationStack');
319
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
320
+ path: __dirname + '/../resources/default-strands-agent',
321
+ });
322
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticAggregationTest', {
323
+ enableChunking: true,
324
+ processingAgentParameters: {
325
+ agentName: 'AggregationTestAgent',
326
+ agentDefinition: {
327
+ bedrockModel: {},
328
+ systemPrompt,
329
+ },
330
+ prompt: 'Test prompt',
331
+ },
332
+ });
333
+ const template = assertions_1.Template.fromStack(chunkingStack);
334
+ // Verify aggregation Lambda is created (inherited from BedrockDocumentProcessing)
335
+ const lambdas = template.findResources('AWS::Lambda::Function');
336
+ const aggregationLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
337
+ lambda.Properties.MemorySize === 1024 &&
338
+ lambda.Properties.Timeout === 300);
339
+ expect(aggregationLambda).toBeDefined();
340
+ });
341
+ test('creates cleanup Lambda when chunking is enabled', () => {
342
+ const testApp = (0, test_utils_1.createTestApp)();
343
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticCleanupStack');
344
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
345
+ path: __dirname + '/../resources/default-strands-agent',
346
+ });
347
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticCleanupTest', {
348
+ enableChunking: true,
349
+ processingAgentParameters: {
350
+ agentName: 'CleanupTestAgent',
351
+ agentDefinition: {
352
+ bedrockModel: {},
353
+ systemPrompt,
354
+ },
355
+ prompt: 'Test prompt',
356
+ },
357
+ });
358
+ const template = assertions_1.Template.fromStack(chunkingStack);
359
+ // Verify cleanup Lambda is created (inherited from BedrockDocumentProcessing)
360
+ const lambdas = template.findResources('AWS::Lambda::Function');
361
+ const cleanupLambda = Object.values(lambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
362
+ lambda.Properties.MemorySize === 512 &&
363
+ lambda.Properties.Timeout === 300);
364
+ expect(cleanupLambda).toBeDefined();
365
+ });
366
+ });
367
+ describe('Agent-based processing with chunking', () => {
368
+ test('uses BatchAgent for processing step in chunked workflow', () => {
369
+ const testApp = (0, test_utils_1.createTestApp)();
370
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticBatchAgentStack');
371
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
372
+ path: __dirname + '/../resources/default-strands-agent',
373
+ });
374
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticBatchAgentTest', {
375
+ enableChunking: true,
376
+ chunkingConfig: {
377
+ strategy: 'hybrid',
378
+ maxConcurrency: 10,
379
+ },
380
+ processingAgentParameters: {
381
+ agentName: 'BatchAgentTest',
382
+ agentDefinition: {
383
+ bedrockModel: {},
384
+ systemPrompt,
385
+ },
386
+ prompt: 'Process this document chunk',
387
+ },
388
+ });
389
+ const template = assertions_1.Template.fromStack(chunkingStack);
390
+ // Verify BatchAgent Lambda is created with correct configuration
391
+ template.hasResourceProperties('AWS::Lambda::Function', {
392
+ Environment: {
393
+ Variables: {
394
+ PROMPT: 'Process this document chunk',
395
+ },
396
+ },
397
+ });
398
+ });
399
+ test('BatchAgent has S3 access for chunk processing', () => {
400
+ const testApp = (0, test_utils_1.createTestApp)();
401
+ const chunkingStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticS3AccessStack');
402
+ const systemPrompt = new aws_s3_assets_1.Asset(chunkingStack, 'SystemPrompt', {
403
+ path: __dirname + '/../resources/default-strands-agent',
404
+ });
405
+ new agentic_document_processing_1.AgenticDocumentProcessing(chunkingStack, 'AgenticS3AccessTest', {
406
+ enableChunking: true,
407
+ processingAgentParameters: {
408
+ agentName: 'S3AccessAgent',
409
+ agentDefinition: {
410
+ bedrockModel: {},
411
+ systemPrompt,
412
+ },
413
+ prompt: 'Test prompt',
414
+ },
415
+ });
416
+ const template = assertions_1.Template.fromStack(chunkingStack);
417
+ // Verify S3 access permissions are granted
418
+ template.hasResourceProperties('AWS::IAM::Role', {
419
+ Policies: assertions_1.Match.arrayWith([
420
+ assertions_1.Match.objectLike({
421
+ PolicyDocument: assertions_1.Match.objectLike({
422
+ Statement: assertions_1.Match.arrayWith([
423
+ assertions_1.Match.objectLike({
424
+ Action: assertions_1.Match.arrayWith(['s3:GetObject']),
425
+ Effect: 'Allow',
426
+ }),
427
+ ]),
428
+ }),
429
+ }),
430
+ ]),
431
+ });
432
+ });
433
+ });
434
+ describe('Chunking configuration validation', () => {
435
+ test('validates chunking configuration (inherited from BedrockDocumentProcessing)', () => {
436
+ const testApp = (0, test_utils_1.createTestApp)();
437
+ const stack = new aws_cdk_lib_1.Stack(testApp, 'AgenticValidationStack');
438
+ const systemPrompt = new aws_s3_assets_1.Asset(stack, 'SystemPrompt', {
439
+ path: __dirname + '/../resources/default-strands-agent',
440
+ });
441
+ // Should throw error for invalid chunkSize
442
+ expect(() => {
443
+ new agentic_document_processing_1.AgenticDocumentProcessing(stack, 'AgenticValidationTest', {
444
+ enableChunking: true,
445
+ chunkingConfig: {
446
+ strategy: 'fixed-pages',
447
+ chunkSize: 0,
448
+ },
449
+ processingAgentParameters: {
450
+ agentName: 'ValidationAgent',
451
+ agentDefinition: {
452
+ bedrockModel: {},
453
+ systemPrompt,
454
+ },
455
+ prompt: 'Test prompt',
456
+ },
457
+ });
458
+ }).toThrow('ChunkingConfig validation error: chunkSize must be greater than 0');
459
+ });
460
+ test('validates overlap configuration (inherited from BedrockDocumentProcessing)', () => {
461
+ const testApp = (0, test_utils_1.createTestApp)();
462
+ const stack = new aws_cdk_lib_1.Stack(testApp, 'AgenticOverlapValidationStack');
463
+ const systemPrompt = new aws_s3_assets_1.Asset(stack, 'SystemPrompt', {
464
+ path: __dirname + '/../resources/default-strands-agent',
465
+ });
466
+ // Should throw error for overlapPages >= chunkSize
467
+ expect(() => {
468
+ new agentic_document_processing_1.AgenticDocumentProcessing(stack, 'AgenticOverlapValidationTest', {
469
+ enableChunking: true,
470
+ chunkingConfig: {
471
+ strategy: 'fixed-pages',
472
+ chunkSize: 50,
473
+ overlapPages: 60,
474
+ },
475
+ processingAgentParameters: {
476
+ agentName: 'OverlapValidationAgent',
477
+ agentDefinition: {
478
+ bedrockModel: {},
479
+ systemPrompt,
480
+ },
481
+ prompt: 'Test prompt',
482
+ },
483
+ });
484
+ }).toThrow('ChunkingConfig validation error: overlapPages must be less than chunkSize');
485
+ });
486
+ });
487
+ describe('Comparison with BedrockDocumentProcessing', () => {
488
+ test('AgenticDocumentProcessing creates same chunking infrastructure as BedrockDocumentProcessing', () => {
489
+ const testApp = (0, test_utils_1.createTestApp)();
490
+ // Create BedrockDocumentProcessing with chunking
491
+ const bedrockStack = new aws_cdk_lib_1.Stack(testApp, 'BedrockCompareStack');
492
+ new bedrock_document_processing_1.BedrockDocumentProcessing(bedrockStack, 'BedrockCompareTest', {
493
+ enableChunking: true,
494
+ chunkingConfig: {
495
+ strategy: 'hybrid',
496
+ maxPagesPerChunk: 100,
497
+ targetTokensPerChunk: 80000,
498
+ },
499
+ });
500
+ // Create AgenticDocumentProcessing with same chunking config
501
+ const agenticStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticCompareStack');
502
+ const systemPrompt = new aws_s3_assets_1.Asset(agenticStack, 'SystemPrompt', {
503
+ path: __dirname + '/../resources/default-strands-agent',
504
+ });
505
+ new agentic_document_processing_1.AgenticDocumentProcessing(agenticStack, 'AgenticCompareTest', {
506
+ enableChunking: true,
507
+ chunkingConfig: {
508
+ strategy: 'hybrid',
509
+ maxPagesPerChunk: 100,
510
+ targetTokensPerChunk: 80000,
511
+ },
512
+ processingAgentParameters: {
513
+ agentName: 'CompareAgent',
514
+ agentDefinition: {
515
+ bedrockModel: {},
516
+ systemPrompt,
517
+ },
518
+ prompt: 'Test prompt',
519
+ },
520
+ });
521
+ const bedrockTemplate = assertions_1.Template.fromStack(bedrockStack);
522
+ const agenticTemplate = assertions_1.Template.fromStack(agenticStack);
523
+ // Both should have PDF chunking Lambda
524
+ const bedrockLambdas = bedrockTemplate.findResources('AWS::Lambda::Function');
525
+ const agenticLambdas = agenticTemplate.findResources('AWS::Lambda::Function');
526
+ const bedrockChunkingLambda = Object.values(bedrockLambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
527
+ lambda.Properties.MemorySize === 2048);
528
+ const agenticChunkingLambda = Object.values(agenticLambdas).find((lambda) => lambda.Properties.Runtime === 'python3.13' &&
529
+ lambda.Properties.MemorySize === 2048);
530
+ expect(bedrockChunkingLambda).toBeDefined();
531
+ expect(agenticChunkingLambda).toBeDefined();
532
+ // Both should have same chunking strategy
533
+ expect(bedrockChunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'hybrid');
534
+ expect(agenticChunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', 'hybrid');
535
+ });
536
+ test('both implementations create same number of chunking-related Lambdas', () => {
537
+ const testApp = (0, test_utils_1.createTestApp)();
538
+ // Create BedrockDocumentProcessing with chunking
539
+ const bedrockStack = new aws_cdk_lib_1.Stack(testApp, 'BedrockLambdaCountStack');
540
+ new bedrock_document_processing_1.BedrockDocumentProcessing(bedrockStack, 'BedrockLambdaCountTest', {
541
+ enableChunking: true,
542
+ });
543
+ // Create AgenticDocumentProcessing with chunking
544
+ const agenticStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticLambdaCountStack');
545
+ const systemPrompt = new aws_s3_assets_1.Asset(agenticStack, 'SystemPrompt', {
546
+ path: __dirname + '/../resources/default-strands-agent',
547
+ });
548
+ new agentic_document_processing_1.AgenticDocumentProcessing(agenticStack, 'AgenticLambdaCountTest', {
549
+ enableChunking: true,
550
+ processingAgentParameters: {
551
+ agentName: 'LambdaCountAgent',
552
+ agentDefinition: {
553
+ bedrockModel: {},
554
+ systemPrompt,
555
+ },
556
+ prompt: 'Test prompt',
557
+ },
558
+ });
559
+ const bedrockTemplate = assertions_1.Template.fromStack(bedrockStack);
560
+ const agenticTemplate = assertions_1.Template.fromStack(agenticStack);
561
+ // Count chunking-related Lambdas (chunking, aggregation, cleanup)
562
+ const bedrockLambdas = bedrockTemplate.findResources('AWS::Lambda::Function');
563
+ const agenticLambdas = agenticTemplate.findResources('AWS::Lambda::Function');
564
+ // Find chunking Lambda (2048 MB)
565
+ const bedrockChunking = Object.values(bedrockLambdas).filter((l) => l.Properties.MemorySize === 2048);
566
+ const agenticChunking = Object.values(agenticLambdas).filter((l) => l.Properties.MemorySize === 2048);
567
+ // Find aggregation Lambda (1024 MB, 300s timeout)
568
+ const bedrockAggregation = Object.values(bedrockLambdas).filter((l) => l.Properties.MemorySize === 1024 && l.Properties.Timeout === 300);
569
+ const agenticAggregation = Object.values(agenticLambdas).filter((l) => l.Properties.MemorySize === 1024 && l.Properties.Timeout === 300);
570
+ // Both should have same number of chunking and aggregation Lambdas
571
+ // (chunking infrastructure is inherited)
572
+ expect(bedrockChunking.length).toBe(agenticChunking.length);
573
+ expect(bedrockAggregation.length).toBe(agenticAggregation.length);
574
+ // Both should have at least one cleanup Lambda
575
+ // Note: AgenticDocumentProcessing may have additional Lambdas due to BatchAgent
576
+ const bedrockCleanup = Object.values(bedrockLambdas).filter((l) => l.Properties.MemorySize === 512 && l.Properties.Timeout === 300);
577
+ const agenticCleanup = Object.values(agenticLambdas).filter((l) => l.Properties.MemorySize === 512 && l.Properties.Timeout === 300);
578
+ expect(bedrockCleanup.length).toBeGreaterThanOrEqual(1);
579
+ expect(agenticCleanup.length).toBeGreaterThanOrEqual(1);
580
+ });
581
+ test('AgenticDocumentProcessing uses agent for processing while BedrockDocumentProcessing uses Bedrock Lambda', () => {
582
+ const testApp = (0, test_utils_1.createTestApp)();
583
+ // Create BedrockDocumentProcessing with chunking
584
+ const bedrockStack = new aws_cdk_lib_1.Stack(testApp, 'BedrockProcessingStack');
585
+ new bedrock_document_processing_1.BedrockDocumentProcessing(bedrockStack, 'BedrockProcessingTest', {
586
+ enableChunking: true,
587
+ });
588
+ // Create AgenticDocumentProcessing with chunking
589
+ const agenticStack = new aws_cdk_lib_1.Stack(testApp, 'AgenticProcessingStack');
590
+ const systemPrompt = new aws_s3_assets_1.Asset(agenticStack, 'SystemPrompt', {
591
+ path: __dirname + '/../resources/default-strands-agent',
592
+ });
593
+ new agentic_document_processing_1.AgenticDocumentProcessing(agenticStack, 'AgenticProcessingTest', {
594
+ enableChunking: true,
595
+ processingAgentParameters: {
596
+ agentName: 'ProcessingAgent',
597
+ agentDefinition: {
598
+ bedrockModel: {},
599
+ systemPrompt,
600
+ },
601
+ prompt: 'Agent processing prompt',
602
+ },
603
+ });
604
+ const bedrockTemplate = assertions_1.Template.fromStack(bedrockStack);
605
+ const agenticTemplate = assertions_1.Template.fromStack(agenticStack);
606
+ // BedrockDocumentProcessing should have processing Lambda with INVOKE_TYPE=processing
607
+ bedrockTemplate.hasResourceProperties('AWS::Lambda::Function', {
608
+ Environment: {
609
+ Variables: {
610
+ INVOKE_TYPE: 'processing',
611
+ },
612
+ },
613
+ });
614
+ // AgenticDocumentProcessing should have agent Lambda with PROMPT
615
+ agenticTemplate.hasResourceProperties('AWS::Lambda::Function', {
616
+ Environment: {
617
+ Variables: {
618
+ PROMPT: 'Agent processing prompt',
619
+ },
620
+ },
621
+ });
622
+ });
623
+ test('both implementations support all three chunking strategies', () => {
624
+ const strategies = ['fixed-pages', 'token-based', 'hybrid'];
625
+ for (const strategy of strategies) {
626
+ const testApp = (0, test_utils_1.createTestApp)();
627
+ // Create BedrockDocumentProcessing
628
+ const bedrockStack = new aws_cdk_lib_1.Stack(testApp, `Bedrock${strategy}Stack`);
629
+ new bedrock_document_processing_1.BedrockDocumentProcessing(bedrockStack, `Bedrock${strategy}Test`, {
630
+ enableChunking: true,
631
+ chunkingConfig: { strategy },
632
+ });
633
+ // Create AgenticDocumentProcessing
634
+ const agenticStack = new aws_cdk_lib_1.Stack(testApp, `Agentic${strategy}Stack`);
635
+ const systemPrompt = new aws_s3_assets_1.Asset(agenticStack, 'SystemPrompt', {
636
+ path: __dirname + '/../resources/default-strands-agent',
637
+ });
638
+ new agentic_document_processing_1.AgenticDocumentProcessing(agenticStack, `Agentic${strategy}Test`, {
639
+ enableChunking: true,
640
+ chunkingConfig: { strategy },
641
+ processingAgentParameters: {
642
+ agentName: `${strategy}Agent`,
643
+ agentDefinition: {
644
+ bedrockModel: {},
645
+ systemPrompt,
646
+ },
647
+ prompt: 'Test prompt',
648
+ },
649
+ });
650
+ const bedrockTemplate = assertions_1.Template.fromStack(bedrockStack);
651
+ const agenticTemplate = assertions_1.Template.fromStack(agenticStack);
652
+ // Both should have chunking Lambda with correct strategy
653
+ const bedrockLambdas = bedrockTemplate.findResources('AWS::Lambda::Function');
654
+ const agenticLambdas = agenticTemplate.findResources('AWS::Lambda::Function');
655
+ const bedrockChunkingLambda = Object.values(bedrockLambdas).find((l) => l.Properties.MemorySize === 2048);
656
+ const agenticChunkingLambda = Object.values(agenticLambdas).find((l) => l.Properties.MemorySize === 2048);
657
+ expect(bedrockChunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', strategy);
658
+ expect(agenticChunkingLambda).toHaveProperty('Properties.Environment.Variables.CHUNKING_STRATEGY', strategy);
659
+ }
660
+ });
661
+ });
662
+ });
179
663
  });
180
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnRpYy1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9hZ2VudGljLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUFvQztBQUNwQyx1REFBeUQ7QUFDekQsNkRBQWtEO0FBQ2xELGdGQUEyRTtBQUUzRSxRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBQ3pDLElBQUksVUFBaUIsQ0FBQztJQUN0QixJQUFJLGdCQUF1QixDQUFDO0lBQzVCLElBQUksaUJBQXdCLENBQUM7SUFDN0IsSUFBSSxhQUF1QixDQUFDO0lBQzVCLElBQUksbUJBQTZCLENBQUM7SUFDbEMsSUFBSSxvQkFBOEIsQ0FBQztJQUVuQyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsVUFBVSxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO1FBQ3pCLE1BQU0sWUFBWSxHQUFHLElBQUkscUJBQUssQ0FBQyxVQUFVLEVBQUUsY0FBYyxFQUFFO1lBQ3pELElBQUksRUFBRSxTQUFTLEdBQUcscUNBQXFDO1NBQ3hELENBQUMsQ0FBQztRQUNILElBQUksdURBQXlCLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRTtZQUNyRCx5QkFBeUIsRUFBRTtnQkFDekIsU0FBUyxFQUFFLFdBQVc7Z0JBQ3RCLGVBQWUsRUFBRTtvQkFDZixZQUFZLEVBQUUsRUFBRTtvQkFDaEIsWUFBWTtpQkFDYjtnQkFDRCxNQUFNLEVBQUUsMEJBQTBCO2FBQ25DO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsZ0JBQWdCLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7UUFDL0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLHFCQUFLLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFO1lBQ3BFLElBQUksRUFBRSxTQUFTLEdBQUcscUNBQXFD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QUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLElBQUksQ0FBQyw2Q0FBNkMsRUFBRSxHQUFHLEVBQUU7WUFDdkQsYUFBYSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyw4QkFBOEIsRUFBRSxHQUFHLEVBQUU7WUFDeEMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IE1hdGNoLCBUZW1wbGF0ZSB9IGZyb20gJ2F3cy1jZGstbGliL2Fzc2VydGlvbnMnO1xuaW1wb3J0IHsgQXNzZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtczMtYXNzZXRzJztcbmltcG9ydCB7IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcgfSBmcm9tICcuLi9hZ2VudGljLWRvY3VtZW50LXByb2Nlc3NpbmcnO1xuXG5kZXNjcmliZSgnQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZycsICgpID0+IHtcbiAgbGV0IGJhc2ljU3RhY2s6IFN0YWNrO1xuICBsZXQgY3Jvc3NSZWdpb25TdGFjazogU3RhY2s7XG4gIGxldCBkZWZhdWx0TW9kZWxTdGFjazogU3RhY2s7XG4gIGxldCBiYXNpY1RlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgbGV0IGNyb3NzUmVnaW9uVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgZGVmYXVsdE1vZGVsVGVtcGxhdGU6IFRlbXBsYXRlO1xuXG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgYmFzaWNTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChiYXNpY1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICB9KTtcbiAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhiYXNpY1N0YWNrLCAnQmFzaWNUZXN0Jywge1xuICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvbXB0OiAnQ3VzdG9tIHByb2Nlc3NpbmcgcHJvbXB0JyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjcm9zc1JlZ2lvblN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgY3Jvc3NSZWdpb25Qcm9tcHQgPSBuZXcgQXNzZXQoY3Jvc3NSZWdpb25TdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgfSk7XG4gICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoY3Jvc3NSZWdpb25TdGFjaywgJ0Nyb3NzUmVnaW9uVGVzdCcsIHtcbiAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgYWdlbnROYW1lOiAnQ3Jvc3NSZWdpb25BZ2VudCcsXG4gICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgIGJlZHJvY2tNb2RlbDogeyB1c2VDcm9zc1JlZ2lvbkluZmVyZW5jZTogdHJ1ZSB9LFxuICAgICAgICAgIHN5c3RlbVByb21wdDogY3Jvc3NSZWdpb25Qcm9tcHQsXG4gICAgICAgIH0sXG4gICAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBkZWZhdWx0TW9kZWxTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IGRlZmF1bHRQcm9tcHQgPSBuZXcgQXNzZXQoZGVmYXVsdE1vZGVsU3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgIH0pO1xuICAgIG5ldyBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nKGRlZmF1bHRNb2RlbFN0YWNrLCAnRGVmYXVsdE1vZGVsVGVzdCcsIHtcbiAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgYWdlbnROYW1lOiAnRGVmYXVsdEFnZW50JyxcbiAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgYmVkcm9ja01vZGVsOiB7IHVzZUNyb3NzUmVnaW9uSW5mZXJlbmNlOiBmYWxzZSB9LFxuICAgICAgICAgIHN5c3RlbVByb21wdDogZGVmYXVsdFByb21wdCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGJhc2ljVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soYmFzaWNTdGFjayk7XG4gICAgY3Jvc3NSZWdpb25UZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhjcm9zc1JlZ2lvblN0YWNrKTtcbiAgICBkZWZhdWx0TW9kZWxUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhkZWZhdWx0TW9kZWxTdGFjayk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCYXNpYyBpbmZyYXN0cnVjdHVyZScsICgpID0+IHtcbiAgICB0ZXN0KCdjcmVhdGVzIGJhc2ljIGluZnJhc3RydWN0dXJlJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6UzM6OkJ1Y2tldCcsIHt9KTtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIFJ1bnRpbWU6ICdweXRob24zLjEzJyxcbiAgICAgIH0pO1xuICAgICAgYmFzaWNUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIDUpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnaW5oZXJpdHMgYmVkcm9jayBkb2N1bWVudCBwcm9jZXNzaW5nIGZ1bmN0aW9uYWxpdHknLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTMzo6QnVja2V0Jywge30pO1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RHluYW1vREI6OlRhYmxlJywge30pO1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U1FTOjpRdWV1ZScsIHt9KTtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHt9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FnZW50IGNvbmZpZ3VyYXRpb24nLCAoKSA9PiB7XG4gICAgdGVzdCgnY29uZmlndXJlcyBhbGwgYWdlbnQgcGFyYW1ldGVycycsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBQUk9NUFQ6ICdDdXN0b20gcHJvY2Vzc2luZyBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NvbmZpZ3VyZXMgdGltZW91dCBhbmQgbWVtb3J5IGZvciBwcm9jZXNzaW5nIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgVGltZW91dDogNjAwLFxuICAgICAgICBNZW1vcnlTaXplOiAxMDI0LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd1c2VzIGNyb3NzLXJlZ2lvbiBpbmZlcmVuY2Ugd2hlbiBlbmFibGVkJywgKCkgPT4ge1xuICAgICAgY3Jvc3NSZWdpb25UZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiAndXMuYW50aHJvcGljLmNsYXVkZS1zb25uZXQtNC0yMDI1MDUxNC12MTowJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd1c2VzIGRlZmF1bHQgbW9kZWwgd2hlbiBjcm9zcy1yZWdpb24gaW5mZXJlbmNlIGlzIGRpc2FibGVkJywgKCkgPT4ge1xuICAgICAgZGVmYXVsdE1vZGVsVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgVmFyaWFibGVzOiB7XG4gICAgICAgICAgICBNT0RFTF9JRDogJ2FudGhyb3BpYy5jbGF1ZGUtc29ubmV0LTQtMjAyNTA1MTQtdjE6MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnSUFNIHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NyZWF0ZXMgSUFNIHJvbGUgd2l0aCBjb3JyZWN0IHBlcm1pc3Npb25zJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBBc3N1bWVSb2xlUG9saWN5RG9jdW1lbnQ6IHtcbiAgICAgICAgICBTdGF0ZW1lbnQ6IFt7XG4gICAgICAgICAgICBBY3Rpb246ICdzdHM6QXNzdW1lUm9sZScsXG4gICAgICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgICAgICBQcmluY2lwYWw6IHtcbiAgICAgICAgICAgICAgU2VydmljZTogJ2xhbWJkYS5hbWF6b25hd3MuY29tJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfV0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogW3tcbiAgICAgICAgICBQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgICAgICAgICAgQWN0aW9uOiBbJ2JlZHJvY2s6SW52b2tlTW9kZWwnLCAnYmVkcm9jazpJbnZva2VNb2RlbFdpdGhSZXNwb25zZVN0cmVhbSddLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgUG9saWN5TmFtZTogJ0JlZHJvY2tJbnZva2VQb2xpY3knLFxuICAgICAgICB9XSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnZ3JhbnRzIFMzIGFjY2VzcyB0byBhZ2VudCBmdW5jdGlvbicsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6Um9sZScsIHtcbiAgICAgICAgUG9saWNpZXM6IE1hdGNoLmFycmF5V2l0aChbXG4gICAgICAgICAgTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICBQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgICAgICBTdGF0ZW1lbnQ6IE1hdGNoLmFycmF5V2l0aChbXG4gICAgICAgICAgICAgICAgTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICAgICAgICBBY3Rpb246IE1hdGNoLmFycmF5V2l0aChbJ3MzOkdldE9iamVjdCddKSxcbiAgICAgICAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICBdKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU3RhdGUgbWFjaGluZSBpbnRlZ3JhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCdpbnRlZ3JhdGVzIGFnZW50IGFzIHByb2Nlc3Npbmcgc3RlcCBpbiB3b3JrZmxvdycsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHtcbiAgICAgICAgRGVmaW5pdGlvblN0cmluZzogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgJ0ZuOjpKb2luJzogTWF0Y2guYXJyYXlXaXRoKFsnJ10pLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY3JlYXRlcyBzdGF0ZSBtYWNoaW5lIHdpdGggZW5jcnlwdGlvbicsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIHtcbiAgICAgICAgRW5jcnlwdGlvbkNvbmZpZ3VyYXRpb246IE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgIFR5cGU6ICdDVVNUT01FUl9NQU5BR0VEX0tNU19LRVknLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVzb3VyY2UgY291bnRzJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NyZWF0ZXMgZXhwZWN0ZWQgbnVtYmVyIG9mIExhbWJkYSBmdW5jdGlvbnMnLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywgNSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjcmVhdGVzIHNpbmdsZSBzdGF0ZSBtYWNoaW5lJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywgMSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
664
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnRpYy1kb2N1bWVudC1wcm9jZXNzaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi91c2UtY2FzZXMvZG9jdW1lbnQtcHJvY2Vzc2luZy90ZXN0cy9hZ2VudGljLWRvY3VtZW50LXByb2Nlc3NpbmcudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDZDQUF5QztBQUN6Qyx1REFBeUQ7QUFDekQsNkRBQWtEO0FBQ2xELDJEQUEyRDtBQUMzRCxnRkFBMkU7QUFDM0UsZ0ZBQTJFO0FBRTNFLFFBQVEsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7SUFDekMsSUFBSSxHQUFRLENBQUM7SUFDYixJQUFJLFVBQWlCLENBQUM7SUFDdEIsSUFBSSxnQkFBdUIsQ0FBQztJQUM1QixJQUFJLGlCQUF3QixDQUFDO0lBQzdCLElBQUksYUFBdUIsQ0FBQztJQUM1QixJQUFJLG1CQUE2QixDQUFDO0lBQ2xDLElBQUksb0JBQThCLENBQUM7SUFFbkMsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNiLDBEQUEwRDtRQUMxRCxHQUFHLEdBQUcsSUFBQSwwQkFBYSxHQUFFLENBQUM7UUFFdEIsVUFBVSxHQUFHLElBQUksbUJBQUssQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDMUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxxQkFBSyxDQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUU7WUFDekQsSUFBSSxFQUFFLFNBQVMsR0FBRyxxQ0FBcUM7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsSUFBSSx1REFBeUIsQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFO1lBQ3JELHlCQUF5QixFQUFFO2dCQUN6QixTQUFTLEVBQUUsV0FBVztnQkFDdEIsZUFBZSxFQUFFO29CQUNmLFlBQVksRUFBRSxFQUFFO29CQUNoQixZQUFZO2lCQUNiO2dCQUNELE1BQU0sRUFBRSwwQkFBMEI7YUFDbkM7U0FDRixDQUFDLENBQUM7UUFFSCxnQkFBZ0IsR0FB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TCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFwcCwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBNYXRjaCwgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IEFzc2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWFzc2V0cyc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXBwIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL3Rlc3QtdXRpbHMnO1xuaW1wb3J0IHsgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyB9IGZyb20gJy4uL2FnZW50aWMtZG9jdW1lbnQtcHJvY2Vzc2luZyc7XG5pbXBvcnQgeyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nIH0gZnJvbSAnLi4vYmVkcm9jay1kb2N1bWVudC1wcm9jZXNzaW5nJztcblxuZGVzY3JpYmUoJ0FnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcnLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IGJhc2ljU3RhY2s6IFN0YWNrO1xuICBsZXQgY3Jvc3NSZWdpb25TdGFjazogU3RhY2s7XG4gIGxldCBkZWZhdWx0TW9kZWxTdGFjazogU3RhY2s7XG4gIGxldCBiYXNpY1RlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgbGV0IGNyb3NzUmVnaW9uVGVtcGxhdGU6IFRlbXBsYXRlO1xuICBsZXQgZGVmYXVsdE1vZGVsVGVtcGxhdGU6IFRlbXBsYXRlO1xuXG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgLy8gVXNlIGNyZWF0ZVRlc3RBcHAoKSB0byBza2lwIGJ1bmRsaW5nIGFuZCBzcGVlZCB1cCB0ZXN0c1xuICAgIGFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcblxuICAgIGJhc2ljU3RhY2sgPSBuZXcgU3RhY2soYXBwLCAnQmFzaWNTdGFjaycpO1xuICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChiYXNpY1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICB9KTtcbiAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhiYXNpY1N0YWNrLCAnQmFzaWNUZXN0Jywge1xuICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICBhZ2VudE5hbWU6ICdUZXN0QWdlbnQnLFxuICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvbXB0OiAnQ3VzdG9tIHByb2Nlc3NpbmcgcHJvbXB0JyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjcm9zc1JlZ2lvblN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0Nyb3NzUmVnaW9uU3RhY2snKTtcbiAgICBjb25zdCBjcm9zc1JlZ2lvblByb21wdCA9IG5ldyBBc3NldChjcm9zc1JlZ2lvblN0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICB9KTtcbiAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhjcm9zc1JlZ2lvblN0YWNrLCAnQ3Jvc3NSZWdpb25UZXN0Jywge1xuICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICBhZ2VudE5hbWU6ICdDcm9zc1JlZ2lvbkFnZW50JyxcbiAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgYmVkcm9ja01vZGVsOiB7IHVzZUNyb3NzUmVnaW9uSW5mZXJlbmNlOiB0cnVlIH0sXG4gICAgICAgICAgc3lzdGVtUHJvbXB0OiBjcm9zc1JlZ2lvblByb21wdCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGRlZmF1bHRNb2RlbFN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ0RlZmF1bHRNb2RlbFN0YWNrJyk7XG4gICAgY29uc3QgZGVmYXVsdFByb21wdCA9IG5ldyBBc3NldChkZWZhdWx0TW9kZWxTdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgfSk7XG4gICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoZGVmYXVsdE1vZGVsU3RhY2ssICdEZWZhdWx0TW9kZWxUZXN0Jywge1xuICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICBhZ2VudE5hbWU6ICdEZWZhdWx0QWdlbnQnLFxuICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICBiZWRyb2NrTW9kZWw6IHsgdXNlQ3Jvc3NSZWdpb25JbmZlcmVuY2U6IGZhbHNlIH0sXG4gICAgICAgICAgc3lzdGVtUHJvbXB0OiBkZWZhdWx0UHJvbXB0LFxuICAgICAgICB9LFxuICAgICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgYmFzaWNUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhiYXNpY1N0YWNrKTtcbiAgICBjcm9zc1JlZ2lvblRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNyb3NzUmVnaW9uU3RhY2spO1xuICAgIGRlZmF1bHRNb2RlbFRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGRlZmF1bHRNb2RlbFN0YWNrKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Jhc2ljIGluZnJhc3RydWN0dXJlJywgKCkgPT4ge1xuICAgIHRlc3QoJ2NyZWF0ZXMgYmFzaWMgaW5mcmFzdHJ1Y3R1cmUnLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTMzo6QnVja2V0Jywge30pO1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgUnVudGltZTogJ3B5dGhvbjMuMTMnLFxuICAgICAgfSk7XG4gICAgICBiYXNpY1RlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywgNSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdpbmhlcml0cyBiZWRyb2NrIGRvY3VtZW50IHByb2Nlc3NpbmcgZnVuY3Rpb25hbGl0eScsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OlMzOjpCdWNrZXQnLCB7fSk7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpEeW5hbW9EQjo6VGFibGUnLCB7fSk7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpTUVM6OlF1ZXVlJywge30pO1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge30pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWdlbnQgY29uZmlndXJhdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCdjb25maWd1cmVzIGFsbCBhZ2VudCBwYXJhbWV0ZXJzJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIFBST01QVDogJ0N1c3RvbSBwcm9jZXNzaW5nIHByb21wdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY29uZmlndXJlcyB0aW1lb3V0IGFuZCBtZW1vcnkgZm9yIHByb2Nlc3NpbmcgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBUaW1lb3V0OiA2MDAsXG4gICAgICAgIE1lbW9yeVNpemU6IDEwMjQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgY3Jvc3MtcmVnaW9uIGluZmVyZW5jZSB3aGVuIGVuYWJsZWQnLCAoKSA9PiB7XG4gICAgICBjcm9zc1JlZ2lvblRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgTU9ERUxfSUQ6ICd1cy5hbnRocm9waWMuY2xhdWRlLXNvbm5ldC00LTIwMjUwNTE0LXYxOjAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3VzZXMgZGVmYXVsdCBtb2RlbCB3aGVuIGNyb3NzLXJlZ2lvbiBpbmZlcmVuY2UgaXMgZGlzYWJsZWQnLCAoKSA9PiB7XG4gICAgICBkZWZhdWx0TW9kZWxUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicsIHtcbiAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiAnYW50aHJvcGljLmNsYXVkZS1zb25uZXQtNC0yMDI1MDUxNC12MTowJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdJQU0gcGVybWlzc2lvbnMnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBJQU0gcm9sZSB3aXRoIGNvcnJlY3QgcGVybWlzc2lvbnMnLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIEFzc3VtZVJvbGVQb2xpY3lEb2N1bWVudDoge1xuICAgICAgICAgIFN0YXRlbWVudDogW3tcbiAgICAgICAgICAgIEFjdGlvbjogJ3N0czpBc3N1bWVSb2xlJyxcbiAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgIFByaW5jaXBhbDoge1xuICAgICAgICAgICAgICBTZXJ2aWNlOiAnbGFtYmRhLmFtYXpvbmF3cy5jb20nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9XSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBiYXNpY1RlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpJQU06OlJvbGUnLCB7XG4gICAgICAgIFBvbGljaWVzOiBbe1xuICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICBTdGF0ZW1lbnQ6IE1hdGNoLmFycmF5V2l0aChbXG4gICAgICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICAgICAgICBBY3Rpb246IFsnYmVkcm9jazpJbnZva2VNb2RlbCcsICdiZWRyb2NrOkludm9rZU1vZGVsV2l0aFJlc3BvbnNlU3RyZWFtJ10sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBQb2xpY3lOYW1lOiAnQmVkcm9ja0ludm9rZVBvbGljeScsXG4gICAgICAgIH1dLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdncmFudHMgUzMgYWNjZXNzIHRvIGFnZW50IGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6SUFNOjpSb2xlJywge1xuICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFBvbGljeURvY3VtZW50OiB7XG4gICAgICAgICAgICAgIFN0YXRlbWVudDogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgICAgICAgIEFjdGlvbjogTWF0Y2guYXJyYXlXaXRoKFsnczM6R2V0T2JqZWN0J10pLFxuICAgICAgICAgICAgICAgICAgRWZmZWN0OiAnQWxsb3cnLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTdGF0ZSBtYWNoaW5lIGludGVncmF0aW9uJywgKCkgPT4ge1xuICAgIHRlc3QoJ2ludGVncmF0ZXMgYWdlbnQgYXMgcHJvY2Vzc2luZyBzdGVwIGluIHdvcmtmbG93JywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICBEZWZpbml0aW9uU3RyaW5nOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAnRm46OkpvaW4nOiBNYXRjaC5hcnJheVdpdGgoWycnXSksXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdjcmVhdGVzIHN0YXRlIG1hY2hpbmUgd2l0aCBlbmNyeXB0aW9uJywgKCkgPT4ge1xuICAgICAgYmFzaWNUZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICBFbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgVHlwZTogJ0NVU1RPTUVSX01BTkFHRURfS01TX0tFWScsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZXNvdXJjZSBjb3VudHMnLCAoKSA9PiB7XG4gICAgdGVzdCgnY3JlYXRlcyBleHBlY3RlZCBudW1iZXIgb2YgTGFtYmRhIGZ1bmN0aW9ucycsICgpID0+IHtcbiAgICAgIGJhc2ljVGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCA1KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NyZWF0ZXMgc2luZ2xlIHN0YXRlIG1hY2hpbmUnLCAoKSA9PiB7XG4gICAgICBiYXNpY1RlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCAxKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NodW5raW5nIGluaGVyaXRhbmNlIGZyb20gQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZycsICgpID0+IHtcbiAgICBkZXNjcmliZSgncHJlcHJvY2Vzc2luZ1N0ZXAoKSBpbmhlcml0YW5jZScsICgpID0+IHtcbiAgICAgIHRlc3QoJ2luaGVyaXRzIHByZXByb2Nlc3NpbmdTdGVwKCkgZnJvbSBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgICAvLyBWZXJpZnkgdGhhdCBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nIGV4dGVuZHMgQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZ1xuICAgICAgICAvLyBhbmQgaW5oZXJpdHMgdGhlIHByZXByb2Nlc3NpbmdTdGVwKCkgbWV0aG9kXG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNDaHVua2luZ1N0YWNrJyk7XG4gICAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChjaHVua2luZ1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFnZW50aWNQcm9jZXNzb3IgPSBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhjaHVua2luZ1N0YWNrLCAnQWdlbnRpY0NodW5raW5nVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICdoeWJyaWQnLFxuICAgICAgICAgICAgbWF4UGFnZXNQZXJDaHVuazogMTAwLFxuICAgICAgICAgICAgdGFyZ2V0VG9rZW5zUGVyQ2h1bms6IDgwMDAwLFxuICAgICAgICAgICAgcGFnZVRocmVzaG9sZDogMTAwLFxuICAgICAgICAgICAgdG9rZW5UaHJlc2hvbGQ6IDE1MDAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFnZW50TmFtZTogJ0NodW5raW5nVGVzdEFnZW50JyxcbiAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgY29uc3RydWN0IGlzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICAgIGV4cGVjdChhZ2VudGljUHJvY2Vzc29yKS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBQREYgY2h1bmtpbmcgTGFtYmRhIGlzIGNyZWF0ZWQgKGluaGVyaXRlZCBmcm9tIEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcpXG4gICAgICAgIGNvbnN0IGxhbWJkYXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgICAgY29uc3QgY2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlJ1bnRpbWUgPT09ICdweXRob24zLjEzJyAmJlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDggJiZcbiAgICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5UaW1lb3V0ID09PSA2MDAsXG4gICAgICAgICk7XG5cbiAgICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0JlRGVmaW5lZCgpO1xuICAgICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkhhbmRsZXInLCAnaGFuZGxlci5oYW5kbGVyJyk7XG4gICAgICB9KTtcblxuICAgICAgdGVzdCgncHJlcHJvY2Vzc2luZ1N0ZXAoKSByZXR1cm5zIHVuZGVmaW5lZCB3aGVuIGNodW5raW5nIGlzIGRpc2FibGVkJywgKCkgPT4ge1xuICAgICAgICAvLyBWZXJpZnkgdGhhdCB3aGVuIGVuYWJsZUNodW5raW5nIGlzIGZhbHNlLCBubyBjaHVua2luZyBMYW1iZGEgaXMgY3JlYXRlZFxuICAgICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgICBjb25zdCBub0NodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNOb0NodW5raW5nU3RhY2snKTtcbiAgICAgICAgY29uc3Qgc3lzdGVtUHJvbXB0ID0gbmV3IEFzc2V0KG5vQ2h1bmtpbmdTdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhub0NodW5raW5nU3RhY2ssICdBZ2VudGljTm9DaHVua2luZ1Rlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IGZhbHNlLFxuICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFnZW50TmFtZTogJ05vQ2h1bmtpbmdBZ2VudCcsXG4gICAgICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICAgICAgYmVkcm9ja01vZGVsOiB7fSxcbiAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhub0NodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBOTyBQREYgY2h1bmtpbmcgTGFtYmRhIGlzIGNyZWF0ZWRcbiAgICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgICBjb25zdCBjaHVua2luZ0xhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCAmJlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlRpbWVvdXQgPT09IDYwMCxcbiAgICAgICAgKTtcblxuICAgICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgICB0ZXN0KCdjaHVua2luZyBMYW1iZGEgaGFzIGNvcnJlY3QgZW52aXJvbm1lbnQgdmFyaWFibGVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgICBjb25zdCBjaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdBZ2VudGljQ2h1bmtpbmdFbnZTdGFjaycpO1xuICAgICAgICBjb25zdCBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoY2h1bmtpbmdTdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhjaHVua2luZ1N0YWNrLCAnQWdlbnRpY0NodW5raW5nRW52VGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICd0b2tlbi1iYXNlZCcsXG4gICAgICAgICAgICB0b2tlblRocmVzaG9sZDogMjAwMDAwLFxuICAgICAgICAgICAgbWF4VG9rZW5zUGVyQ2h1bms6IDEyMDAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFnZW50TmFtZTogJ0VudlRlc3RBZ2VudCcsXG4gICAgICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICAgICAgYmVkcm9ja01vZGVsOiB7fSxcbiAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhjaHVua2luZ1N0YWNrKTtcblxuICAgICAgICAvLyBGaW5kIHRoZSBjaHVua2luZyBMYW1iZGFcbiAgICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgICBjb25zdCBjaHVua2luZ0xhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICAgKTtcblxuICAgICAgICBleHBlY3QoY2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LSU5HX1NUUkFURUdZJywgJ3Rva2VuLWJhc2VkJyk7XG4gICAgICAgIGV4cGVjdChjaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLlRPS0VOX1RIUkVTSE9MRCcsICcyMDAwMDAnKTtcbiAgICAgICAgZXhwZWN0KGNodW5raW5nTGFtYmRhKS50b0hhdmVQcm9wZXJ0eSgnUHJvcGVydGllcy5FbnZpcm9ubWVudC5WYXJpYWJsZXMuTUFYX1RPS0VOU19QRVJfQ0hVTksnLCAnMTIwMDAwJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGVQcm9jZXNzaW5nV29ya2Zsb3coKSBpbmhlcml0YW5jZScsICgpID0+IHtcbiAgICAgIHRlc3QoJ2luaGVyaXRzIGNyZWF0ZVByb2Nlc3NpbmdXb3JrZmxvdygpIGZyb20gQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZycsICgpID0+IHtcbiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIHN0YXRlIG1hY2hpbmUgaW5jbHVkZXMgdGhlIENob2ljZSBzdGF0ZSBmb3IgY2h1bmtpbmdcbiAgICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgICAgY29uc3QgY2h1bmtpbmdTdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQWdlbnRpY1dvcmtmbG93U3RhY2snKTtcbiAgICAgICAgY29uc3Qgc3lzdGVtUHJvbXB0ID0gbmV3IEFzc2V0KGNodW5raW5nU3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ0FnZW50aWNXb3JrZmxvd1Rlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgY2h1bmtpbmdDb25maWc6IHtcbiAgICAgICAgICAgIHN0cmF0ZWd5OiAnaHlicmlkJyxcbiAgICAgICAgICAgIHByb2Nlc3NpbmdNb2RlOiAncGFyYWxsZWwnLFxuICAgICAgICAgICAgbWF4Q29uY3VycmVuY3k6IDUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9jZXNzaW5nQWdlbnRQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBhZ2VudE5hbWU6ICdXb3JrZmxvd1Rlc3RBZ2VudCcsXG4gICAgICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICAgICAgYmVkcm9ja01vZGVsOiB7fSxcbiAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb21wdDogJ1Rlc3QgcHJvbXB0JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhjaHVua2luZ1N0YWNrKTtcblxuICAgICAgICAvLyBWZXJpZnkgc3RhdGUgbWFjaGluZSBpcyBjcmVhdGVkXG4gICAgICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnLCAxKTtcblxuICAgICAgICAvLyBWZXJpZnkgc3RhdGUgbWFjaGluZSBoYXMgZW5jcnlwdGlvbiAoaW5oZXJpdGVkIGJlaGF2aW9yKVxuICAgICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywge1xuICAgICAgICAgIEVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICAgIFR5cGU6ICdDVVNUT01FUl9NQU5BR0VEX0tNU19LRVknLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICB0ZXN0KCdjcmVhdGVzIGFnZ3JlZ2F0aW9uIExhbWJkYSB3aGVuIGNodW5raW5nIGlzIGVuYWJsZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNBZ2dyZWdhdGlvblN0YWNrJyk7XG4gICAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChjaHVua2luZ1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5ldyBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nKGNodW5raW5nU3RhY2ssICdBZ2VudGljQWdncmVnYXRpb25UZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFnZW50TmFtZTogJ0FnZ3JlZ2F0aW9uVGVzdEFnZW50JyxcbiAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBhZ2dyZWdhdGlvbiBMYW1iZGEgaXMgY3JlYXRlZCAoaW5oZXJpdGVkIGZyb20gQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZylcbiAgICAgICAgY29uc3QgbGFtYmRhcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoJ0FXUzo6TGFtYmRhOjpGdW5jdGlvbicpO1xuICAgICAgICBjb25zdCBhZ2dyZWdhdGlvbkxhbWJkYSA9IE9iamVjdC52YWx1ZXMobGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMTAyNCAmJlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlRpbWVvdXQgPT09IDMwMCxcbiAgICAgICAgKTtcblxuICAgICAgICBleHBlY3QoYWdncmVnYXRpb25MYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICB9KTtcblxuICAgICAgdGVzdCgnY3JlYXRlcyBjbGVhbnVwIExhbWJkYSB3aGVuIGNodW5raW5nIGlzIGVuYWJsZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNDbGVhbnVwU3RhY2snKTtcbiAgICAgICAgY29uc3Qgc3lzdGVtUHJvbXB0ID0gbmV3IEFzc2V0KGNodW5raW5nU3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ0FnZW50aWNDbGVhbnVwVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBwcm9jZXNzaW5nQWdlbnRQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBhZ2VudE5hbWU6ICdDbGVhbnVwVGVzdEFnZW50JyxcbiAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBjbGVhbnVwIExhbWJkYSBpcyBjcmVhdGVkIChpbmhlcml0ZWQgZnJvbSBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKVxuICAgICAgICBjb25zdCBsYW1iZGFzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICAgIGNvbnN0IGNsZWFudXBMYW1iZGEgPSBPYmplY3QudmFsdWVzKGxhbWJkYXMpLmZpbmQoKGxhbWJkYTogYW55KSA9PlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlJ1bnRpbWUgPT09ICdweXRob24zLjEzJyAmJlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDUxMiAmJlxuICAgICAgICAgIGxhbWJkYS5Qcm9wZXJ0aWVzLlRpbWVvdXQgPT09IDMwMCxcbiAgICAgICAgKTtcblxuICAgICAgICBleHBlY3QoY2xlYW51cExhbWJkYSkudG9CZURlZmluZWQoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0FnZW50LWJhc2VkIHByb2Nlc3Npbmcgd2l0aCBjaHVua2luZycsICgpID0+IHtcbiAgICAgIHRlc3QoJ3VzZXMgQmF0Y2hBZ2VudCBmb3IgcHJvY2Vzc2luZyBzdGVwIGluIGNodW5rZWQgd29ya2Zsb3cnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICAgIGNvbnN0IGNodW5raW5nU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNCYXRjaEFnZW50U3RhY2snKTtcbiAgICAgICAgY29uc3Qgc3lzdGVtUHJvbXB0ID0gbmV3IEFzc2V0KGNodW5raW5nU3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICAgICAgcGF0aDogX19kaXJuYW1lICsgJy8uLi9yZXNvdXJjZXMvZGVmYXVsdC1zdHJhbmRzLWFnZW50JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoY2h1bmtpbmdTdGFjaywgJ0FnZW50aWNCYXRjaEFnZW50VGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBjaHVua2luZ0NvbmZpZzoge1xuICAgICAgICAgICAgc3RyYXRlZ3k6ICdoeWJyaWQnLFxuICAgICAgICAgICAgbWF4Q29uY3VycmVuY3k6IDEwLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgYWdlbnROYW1lOiAnQmF0Y2hBZ2VudFRlc3QnLFxuICAgICAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgICAgIGJlZHJvY2tNb2RlbDoge30sXG4gICAgICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9tcHQ6ICdQcm9jZXNzIHRoaXMgZG9jdW1lbnQgY2h1bmsnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBCYXRjaEFnZW50IExhbWJkYSBpcyBjcmVhdGVkIHdpdGggY29ycmVjdCBjb25maWd1cmF0aW9uXG4gICAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJywge1xuICAgICAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgICAgICBWYXJpYWJsZXM6IHtcbiAgICAgICAgICAgICAgUFJPTVBUOiAnUHJvY2VzcyB0aGlzIGRvY3VtZW50IGNodW5rJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgdGVzdCgnQmF0Y2hBZ2VudCBoYXMgUzMgYWNjZXNzIGZvciBjaHVuayBwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuICAgICAgICBjb25zdCBjaHVua2luZ1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdBZ2VudGljUzNBY2Nlc3NTdGFjaycpO1xuICAgICAgICBjb25zdCBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoY2h1bmtpbmdTdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhjaHVua2luZ1N0YWNrLCAnQWdlbnRpY1MzQWNjZXNzVGVzdCcsIHtcbiAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICBwcm9jZXNzaW5nQWdlbnRQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBhZ2VudE5hbWU6ICdTM0FjY2Vzc0FnZW50JyxcbiAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGNodW5raW5nU3RhY2spO1xuXG4gICAgICAgIC8vIFZlcmlmeSBTMyBhY2Nlc3MgcGVybWlzc2lvbnMgYXJlIGdyYW50ZWRcbiAgICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OklBTTo6Um9sZScsIHtcbiAgICAgICAgICBQb2xpY2llczogTWF0Y2guYXJyYXlXaXRoKFtcbiAgICAgICAgICAgIE1hdGNoLm9iamVjdExpa2Uoe1xuICAgICAgICAgICAgICBQb2xpY3lEb2N1bWVudDogTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICAgICAgU3RhdGVtZW50OiBNYXRjaC5hcnJheVdpdGgoW1xuICAgICAgICAgICAgICAgICAgTWF0Y2gub2JqZWN0TGlrZSh7XG4gICAgICAgICAgICAgICAgICAgIEFjdGlvbjogTWF0Y2guYXJyYXlXaXRoKFsnczM6R2V0T2JqZWN0J10pLFxuICAgICAgICAgICAgICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdDaHVua2luZyBjb25maWd1cmF0aW9uIHZhbGlkYXRpb24nLCAoKSA9PiB7XG4gICAgICB0ZXN0KCd2YWxpZGF0ZXMgY2h1bmtpbmcgY29uZmlndXJhdGlvbiAoaW5oZXJpdGVkIGZyb20gQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZyknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG4gICAgICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdBZ2VudGljVmFsaWRhdGlvblN0YWNrJyk7XG4gICAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChzdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgY2h1bmtTaXplXG4gICAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdBZ2VudGljVmFsaWRhdGlvblRlc3QnLCB7XG4gICAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgICAgICBjaHVua1NpemU6IDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICBhZ2VudE5hbWU6ICdWYWxpZGF0aW9uQWdlbnQnLFxuICAgICAgICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSkudG9UaHJvdygnQ2h1bmtpbmdDb25maWcgdmFsaWRhdGlvbiBlcnJvcjogY2h1bmtTaXplIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICAgIH0pO1xuXG4gICAgICB0ZXN0KCd2YWxpZGF0ZXMgb3ZlcmxhcCBjb25maWd1cmF0aW9uIChpbmhlcml0ZWQgZnJvbSBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgdGVzdEFwcCA9IGNyZWF0ZVRlc3RBcHAoKTtcbiAgICAgICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNPdmVybGFwVmFsaWRhdGlvblN0YWNrJyk7XG4gICAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChzdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTaG91bGQgdGhyb3cgZXJyb3IgZm9yIG92ZXJsYXBQYWdlcyA+PSBjaHVua1NpemVcbiAgICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhzdGFjaywgJ0FnZW50aWNPdmVybGFwVmFsaWRhdGlvblRlc3QnLCB7XG4gICAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICAgIHN0cmF0ZWd5OiAnZml4ZWQtcGFnZXMnLFxuICAgICAgICAgICAgICBjaHVua1NpemU6IDUwLFxuICAgICAgICAgICAgICBvdmVybGFwUGFnZXM6IDYwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgYWdlbnROYW1lOiAnT3ZlcmxhcFZhbGlkYXRpb25BZ2VudCcsXG4gICAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICAgIGJlZHJvY2tNb2RlbDoge30sXG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KS50b1Rocm93KCdDaHVua2luZ0NvbmZpZyB2YWxpZGF0aW9uIGVycm9yOiBvdmVybGFwUGFnZXMgbXVzdCBiZSBsZXNzIHRoYW4gY2h1bmtTaXplJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdDb21wYXJpc29uIHdpdGggQmVkcm9ja0RvY3VtZW50UHJvY2Vzc2luZycsICgpID0+IHtcbiAgICAgIHRlc3QoJ0FnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcgY3JlYXRlcyBzYW1lIGNodW5raW5nIGluZnJhc3RydWN0dXJlIGFzIEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcgd2l0aCBjaHVua2luZ1xuICAgICAgICBjb25zdCBiZWRyb2NrU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0JlZHJvY2tDb21wYXJlU3RhY2snKTtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoYmVkcm9ja1N0YWNrLCAnQmVkcm9ja0NvbXBhcmVUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgICBtYXhQYWdlc1BlckNodW5rOiAxMDAsXG4gICAgICAgICAgICB0YXJnZXRUb2tlbnNQZXJDaHVuazogODAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIEFnZW50aWNEb2N1bWVudFByb2Nlc3Npbmcgd2l0aCBzYW1lIGNodW5raW5nIGNvbmZpZ1xuICAgICAgICBjb25zdCBhZ2VudGljU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0FnZW50aWNDb21wYXJlU3RhY2snKTtcbiAgICAgICAgY29uc3Qgc3lzdGVtUHJvbXB0ID0gbmV3IEFzc2V0KGFnZW50aWNTdGFjaywgJ1N5c3RlbVByb21wdCcsIHtcbiAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICB9KTtcbiAgICAgICAgbmV3IEFnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcoYWdlbnRpY1N0YWNrLCAnQWdlbnRpY0NvbXBhcmVUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7XG4gICAgICAgICAgICBzdHJhdGVneTogJ2h5YnJpZCcsXG4gICAgICAgICAgICBtYXhQYWdlc1BlckNodW5rOiAxMDAsXG4gICAgICAgICAgICB0YXJnZXRUb2tlbnNQZXJDaHVuazogODAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9jZXNzaW5nQWdlbnRQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICBhZ2VudE5hbWU6ICdDb21wYXJlQWdlbnQnLFxuICAgICAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgICAgIGJlZHJvY2tNb2RlbDoge30sXG4gICAgICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYmVkcm9ja1RlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGJlZHJvY2tTdGFjayk7XG4gICAgICAgIGNvbnN0IGFnZW50aWNUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhhZ2VudGljU3RhY2spO1xuXG4gICAgICAgIC8vIEJvdGggc2hvdWxkIGhhdmUgUERGIGNodW5raW5nIExhbWJkYVxuICAgICAgICBjb25zdCBiZWRyb2NrTGFtYmRhcyA9IGJlZHJvY2tUZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgICAgY29uc3QgYWdlbnRpY0xhbWJkYXMgPSBhZ2VudGljVGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG5cbiAgICAgICAgY29uc3QgYmVkcm9ja0NodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhiZWRyb2NrTGFtYmRhcykuZmluZCgobGFtYmRhOiBhbnkpID0+XG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuUnVudGltZSA9PT0gJ3B5dGhvbjMuMTMnICYmXG4gICAgICAgICAgbGFtYmRhLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBhZ2VudGljQ2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGFnZW50aWNMYW1iZGFzKS5maW5kKChsYW1iZGE6IGFueSkgPT5cbiAgICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5SdW50aW1lID09PSAncHl0aG9uMy4xMycgJiZcbiAgICAgICAgICBsYW1iZGEuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAyMDQ4LFxuICAgICAgICApO1xuXG4gICAgICAgIGV4cGVjdChiZWRyb2NrQ2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgICAgIGV4cGVjdChhZ2VudGljQ2h1bmtpbmdMYW1iZGEpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICAgICAgLy8gQm90aCBzaG91bGQgaGF2ZSBzYW1lIGNodW5raW5nIHN0cmF0ZWd5XG4gICAgICAgIGV4cGVjdChiZWRyb2NrQ2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5DSFVOS0lOR19TVFJBVEVHWScsICdoeWJyaWQnKTtcbiAgICAgICAgZXhwZWN0KGFnZW50aWNDaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LSU5HX1NUUkFURUdZJywgJ2h5YnJpZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIHRlc3QoJ2JvdGggaW1wbGVtZW50YXRpb25zIGNyZWF0ZSBzYW1lIG51bWJlciBvZiBjaHVua2luZy1yZWxhdGVkIExhbWJkYXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcgd2l0aCBjaHVua2luZ1xuICAgICAgICBjb25zdCBiZWRyb2NrU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0JlZHJvY2tMYW1iZGFDb3VudFN0YWNrJyk7XG4gICAgICAgIG5ldyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nKGJlZHJvY2tTdGFjaywgJ0JlZHJvY2tMYW1iZGFDb3VudFRlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENyZWF0ZSBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nIHdpdGggY2h1bmtpbmdcbiAgICAgICAgY29uc3QgYWdlbnRpY1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsICdBZ2VudGljTGFtYmRhQ291bnRTdGFjaycpO1xuICAgICAgICBjb25zdCBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoYWdlbnRpY1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgICAgIH0pO1xuICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhhZ2VudGljU3RhY2ssICdBZ2VudGljTGFtYmRhQ291bnRUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgIHByb2Nlc3NpbmdBZ2VudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFnZW50TmFtZTogJ0xhbWJkYUNvdW50QWdlbnQnLFxuICAgICAgICAgICAgYWdlbnREZWZpbml0aW9uOiB7XG4gICAgICAgICAgICAgIGJlZHJvY2tNb2RlbDoge30sXG4gICAgICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9tcHQ6ICdUZXN0IHByb21wdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYmVkcm9ja1RlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKGJlZHJvY2tTdGFjayk7XG4gICAgICAgIGNvbnN0IGFnZW50aWNUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhhZ2VudGljU3RhY2spO1xuXG4gICAgICAgIC8vIENvdW50IGNodW5raW5nLXJlbGF0ZWQgTGFtYmRhcyAoY2h1bmtpbmcsIGFnZ3JlZ2F0aW9uLCBjbGVhbnVwKVxuICAgICAgICBjb25zdCBiZWRyb2NrTGFtYmRhcyA9IGJlZHJvY2tUZW1wbGF0ZS5maW5kUmVzb3VyY2VzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKTtcbiAgICAgICAgY29uc3QgYWdlbnRpY0xhbWJkYXMgPSBhZ2VudGljVGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG5cbiAgICAgICAgLy8gRmluZCBjaHVua2luZyBMYW1iZGEgKDIwNDggTUIpXG4gICAgICAgIGNvbnN0IGJlZHJvY2tDaHVua2luZyA9IE9iamVjdC52YWx1ZXMoYmVkcm9ja0xhbWJkYXMpLmZpbHRlcigobDogYW55KSA9PlxuICAgICAgICAgIGwuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAyMDQ4KTtcbiAgICAgICAgY29uc3QgYWdlbnRpY0NodW5raW5nID0gT2JqZWN0LnZhbHVlcyhhZ2VudGljTGFtYmRhcykuZmlsdGVyKChsOiBhbnkpID0+XG4gICAgICAgICAgbC5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgpO1xuXG4gICAgICAgIC8vIEZpbmQgYWdncmVnYXRpb24gTGFtYmRhICgxMDI0IE1CLCAzMDBzIHRpbWVvdXQpXG4gICAgICAgIGNvbnN0IGJlZHJvY2tBZ2dyZWdhdGlvbiA9IE9iamVjdC52YWx1ZXMoYmVkcm9ja0xhbWJkYXMpLmZpbHRlcigobDogYW55KSA9PlxuICAgICAgICAgIGwuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSAxMDI0ICYmIGwuUHJvcGVydGllcy5UaW1lb3V0ID09PSAzMDApO1xuICAgICAgICBjb25zdCBhZ2VudGljQWdncmVnYXRpb24gPSBPYmplY3QudmFsdWVzKGFnZW50aWNMYW1iZGFzKS5maWx0ZXIoKGw6IGFueSkgPT5cbiAgICAgICAgICBsLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMTAyNCAmJiBsLlByb3BlcnRpZXMuVGltZW91dCA9PT0gMzAwKTtcblxuICAgICAgICAvLyBCb3RoIHNob3VsZCBoYXZlIHNhbWUgbnVtYmVyIG9mIGNodW5raW5nIGFuZCBhZ2dyZWdhdGlvbiBMYW1iZGFzXG4gICAgICAgIC8vIChjaHVua2luZyBpbmZyYXN0cnVjdHVyZSBpcyBpbmhlcml0ZWQpXG4gICAgICAgIGV4cGVjdChiZWRyb2NrQ2h1bmtpbmcubGVuZ3RoKS50b0JlKGFnZW50aWNDaHVua2luZy5sZW5ndGgpO1xuICAgICAgICBleHBlY3QoYmVkcm9ja0FnZ3JlZ2F0aW9uLmxlbmd0aCkudG9CZShhZ2VudGljQWdncmVnYXRpb24ubGVuZ3RoKTtcblxuICAgICAgICAvLyBCb3RoIHNob3VsZCBoYXZlIGF0IGxlYXN0IG9uZSBjbGVhbnVwIExhbWJkYVxuICAgICAgICAvLyBOb3RlOiBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nIG1heSBoYXZlIGFkZGl0aW9uYWwgTGFtYmRhcyBkdWUgdG8gQmF0Y2hBZ2VudFxuICAgICAgICBjb25zdCBiZWRyb2NrQ2xlYW51cCA9IE9iamVjdC52YWx1ZXMoYmVkcm9ja0xhbWJkYXMpLmZpbHRlcigobDogYW55KSA9PlxuICAgICAgICAgIGwuUHJvcGVydGllcy5NZW1vcnlTaXplID09PSA1MTIgJiYgbC5Qcm9wZXJ0aWVzLlRpbWVvdXQgPT09IDMwMCk7XG4gICAgICAgIGNvbnN0IGFnZW50aWNDbGVhbnVwID0gT2JqZWN0LnZhbHVlcyhhZ2VudGljTGFtYmRhcykuZmlsdGVyKChsOiBhbnkpID0+XG4gICAgICAgICAgbC5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDUxMiAmJiBsLlByb3BlcnRpZXMuVGltZW91dCA9PT0gMzAwKTtcblxuICAgICAgICBleHBlY3QoYmVkcm9ja0NsZWFudXAubGVuZ3RoKS50b0JlR3JlYXRlclRoYW5PckVxdWFsKDEpO1xuICAgICAgICBleHBlY3QoYWdlbnRpY0NsZWFudXAubGVuZ3RoKS50b0JlR3JlYXRlclRoYW5PckVxdWFsKDEpO1xuICAgICAgfSk7XG5cbiAgICAgIHRlc3QoJ0FnZW50aWNEb2N1bWVudFByb2Nlc3NpbmcgdXNlcyBhZ2VudCBmb3IgcHJvY2Vzc2luZyB3aGlsZSBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nIHVzZXMgQmVkcm9jayBMYW1iZGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlc3RBcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIEJlZHJvY2tEb2N1bWVudFByb2Nlc3Npbmcgd2l0aCBjaHVua2luZ1xuICAgICAgICBjb25zdCBiZWRyb2NrU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgJ0JlZHJvY2tQcm9jZXNzaW5nU3RhY2snKTtcbiAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoYmVkcm9ja1N0YWNrLCAnQmVkcm9ja1Byb2Nlc3NpbmdUZXN0Jywge1xuICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDcmVhdGUgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyB3aXRoIGNodW5raW5nXG4gICAgICAgIGNvbnN0IGFnZW50aWNTdGFjayA9IG5ldyBTdGFjayh0ZXN0QXBwLCAnQWdlbnRpY1Byb2Nlc3NpbmdTdGFjaycpO1xuICAgICAgICBjb25zdCBzeXN0ZW1Qcm9tcHQgPSBuZXcgQXNzZXQoYWdlbnRpY1N0YWNrLCAnU3lzdGVtUHJvbXB0Jywge1xuICAgICAgICAgIHBhdGg6IF9fZGlybmFtZSArICcvLi4vcmVzb3VyY2VzL2RlZmF1bHQtc3RyYW5kcy1hZ2VudCcsXG4gICAgICAgIH0pO1xuICAgICAgICBuZXcgQWdlbnRpY0RvY3VtZW50UHJvY2Vzc2luZyhhZ2VudGljU3RhY2ssICdBZ2VudGljUHJvY2Vzc2luZ1Rlc3QnLCB7XG4gICAgICAgICAgZW5hYmxlQ2h1bmtpbmc6IHRydWUsXG4gICAgICAgICAgcHJvY2Vzc2luZ0FnZW50UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgYWdlbnROYW1lOiAnUHJvY2Vzc2luZ0FnZW50JyxcbiAgICAgICAgICAgIGFnZW50RGVmaW5pdGlvbjoge1xuICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJvbXB0OiAnQWdlbnQgcHJvY2Vzc2luZyBwcm9tcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJlZHJvY2tUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhiZWRyb2NrU3RhY2spO1xuICAgICAgICBjb25zdCBhZ2VudGljVGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soYWdlbnRpY1N0YWNrKTtcblxuICAgICAgICAvLyBCZWRyb2NrRG9jdW1lbnRQcm9jZXNzaW5nIHNob3VsZCBoYXZlIHByb2Nlc3NpbmcgTGFtYmRhIHdpdGggSU5WT0tFX1RZUEU9cHJvY2Vzc2luZ1xuICAgICAgICBiZWRyb2NrVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgICBJTlZPS0VfVFlQRTogJ3Byb2Nlc3NpbmcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nIHNob3VsZCBoYXZlIGFnZW50IExhbWJkYSB3aXRoIFBST01QVFxuICAgICAgICBhZ2VudGljVGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nLCB7XG4gICAgICAgICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgICAgICBQUk9NUFQ6ICdBZ2VudCBwcm9jZXNzaW5nIHByb21wdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHRlc3QoJ2JvdGggaW1wbGVtZW50YXRpb25zIHN1cHBvcnQgYWxsIHRocmVlIGNodW5raW5nIHN0cmF0ZWdpZXMnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmF0ZWdpZXM6IEFycmF5PCdmaXhlZC1wYWdlcycgfCAndG9rZW4tYmFzZWQnIHwgJ2h5YnJpZCc+ID0gWydmaXhlZC1wYWdlcycsICd0b2tlbi1iYXNlZCcsICdoeWJyaWQnXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0cmF0ZWd5IG9mIHN0cmF0ZWdpZXMpIHtcbiAgICAgICAgICBjb25zdCB0ZXN0QXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuXG4gICAgICAgICAgLy8gQ3JlYXRlIEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmdcbiAgICAgICAgICBjb25zdCBiZWRyb2NrU3RhY2sgPSBuZXcgU3RhY2sodGVzdEFwcCwgYEJlZHJvY2ske3N0cmF0ZWd5fVN0YWNrYCk7XG4gICAgICAgICAgbmV3IEJlZHJvY2tEb2N1bWVudFByb2Nlc3NpbmcoYmVkcm9ja1N0YWNrLCBgQmVkcm9jayR7c3RyYXRlZ3l9VGVzdGAsIHtcbiAgICAgICAgICAgIGVuYWJsZUNodW5raW5nOiB0cnVlLFxuICAgICAgICAgICAgY2h1bmtpbmdDb25maWc6IHsgc3RyYXRlZ3kgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIENyZWF0ZSBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nXG4gICAgICAgICAgY29uc3QgYWdlbnRpY1N0YWNrID0gbmV3IFN0YWNrKHRlc3RBcHAsIGBBZ2VudGljJHtzdHJhdGVneX1TdGFja2ApO1xuICAgICAgICAgIGNvbnN0IHN5c3RlbVByb21wdCA9IG5ldyBBc3NldChhZ2VudGljU3RhY2ssICdTeXN0ZW1Qcm9tcHQnLCB7XG4gICAgICAgICAgICBwYXRoOiBfX2Rpcm5hbWUgKyAnLy4uL3Jlc291cmNlcy9kZWZhdWx0LXN0cmFuZHMtYWdlbnQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIG5ldyBBZ2VudGljRG9jdW1lbnRQcm9jZXNzaW5nKGFnZW50aWNTdGFjaywgYEFnZW50aWMke3N0cmF0ZWd5fVRlc3RgLCB7XG4gICAgICAgICAgICBlbmFibGVDaHVua2luZzogdHJ1ZSxcbiAgICAgICAgICAgIGNodW5raW5nQ29uZmlnOiB7IHN0cmF0ZWd5IH0sXG4gICAgICAgICAgICBwcm9jZXNzaW5nQWdlbnRQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIGFnZW50TmFtZTogYCR7c3RyYXRlZ3l9QWdlbnRgLFxuICAgICAgICAgICAgICBhZ2VudERlZmluaXRpb246IHtcbiAgICAgICAgICAgICAgICBiZWRyb2NrTW9kZWw6IHt9LFxuICAgICAgICAgICAgICAgIHN5c3RlbVByb21wdCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcHJvbXB0OiAnVGVzdCBwcm9tcHQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGJlZHJvY2tUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhiZWRyb2NrU3RhY2spO1xuICAgICAgICAgIGNvbnN0IGFnZW50aWNUZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhhZ2VudGljU3RhY2spO1xuXG4gICAgICAgICAgLy8gQm90aCBzaG91bGQgaGF2ZSBjaHVua2luZyBMYW1iZGEgd2l0aCBjb3JyZWN0IHN0cmF0ZWd5XG4gICAgICAgICAgY29uc3QgYmVkcm9ja0xhbWJkYXMgPSBiZWRyb2NrVGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG4gICAgICAgICAgY29uc3QgYWdlbnRpY0xhbWJkYXMgPSBhZ2VudGljVGVtcGxhdGUuZmluZFJlc291cmNlcygnQVdTOjpMYW1iZGE6OkZ1bmN0aW9uJyk7XG5cbiAgICAgICAgICBjb25zdCBiZWRyb2NrQ2h1bmtpbmdMYW1iZGEgPSBPYmplY3QudmFsdWVzKGJlZHJvY2tMYW1iZGFzKS5maW5kKChsOiBhbnkpID0+XG4gICAgICAgICAgICBsLlByb3BlcnRpZXMuTWVtb3J5U2l6ZSA9PT0gMjA0OCk7XG4gICAgICAgICAgY29uc3QgYWdlbnRpY0NodW5raW5nTGFtYmRhID0gT2JqZWN0LnZhbHVlcyhhZ2VudGljTGFtYmRhcykuZmluZCgobDogYW55KSA9PlxuICAgICAgICAgICAgbC5Qcm9wZXJ0aWVzLk1lbW9yeVNpemUgPT09IDIwNDgpO1xuXG4gICAgICAgICAgZXhwZWN0KGJlZHJvY2tDaHVua2luZ0xhbWJkYSkudG9IYXZlUHJvcGVydHkoJ1Byb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzLkNIVU5LSU5HX1NUUkFURUdZJywgc3RyYXRlZ3kpO1xuICAgICAgICAgIGV4cGVjdChhZ2VudGljQ2h1bmtpbmdMYW1iZGEpLnRvSGF2ZVByb3BlcnR5KCdQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlcy5DSFVOS0lOR19TVFJBVEVHWScsIHN0cmF0ZWd5KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=