@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
@@ -8,6 +8,7 @@ const aws_stepfunctions_tasks_1 = require("aws-cdk-lib/aws-stepfunctions-tasks")
8
8
  const cdk_nag_1 = require("cdk-nag");
9
9
  const framework_1 = require("../../framework");
10
10
  const eventbridge_broker_1 = require("../../framework/foundation/eventbridge-broker");
11
+ const test_utils_1 = require("../../utilities/test-utils");
11
12
  const adapter_1 = require("../adapter");
12
13
  const base_document_processing_1 = require("../base-document-processing");
13
14
  // Concrete test implementation of BaseDocumentProcessing for CDK Nag testing
@@ -43,12 +44,18 @@ class TestDocumentProcessing extends base_document_processing_1.BaseDocumentProc
43
44
  postProcessingStep() {
44
45
  return undefined;
45
46
  }
47
+ preprocessingStep() {
48
+ return undefined;
49
+ }
50
+ createProcessingWorkflow() {
51
+ return this.createStandardProcessingWorkflow();
52
+ }
46
53
  createStateMachine() {
47
54
  return this.handleStateMachineCreation('test-state-machine');
48
55
  }
49
56
  }
50
57
  // Create app and stack
51
- const app = new aws_cdk_lib_1.App();
58
+ const app = (0, test_utils_1.createTestApp)();
52
59
  const stack = new aws_cdk_lib_1.Stack(app, 'TestStack', {
53
60
  env: {
54
61
  account: '123456789012',
@@ -158,4 +165,4 @@ test('No unsuppressed errors', () => {
158
165
  }
159
166
  expect(errors).toHaveLength(0);
160
167
  });
161
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLW5hZy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL2RvY3VtZW50LXByb2Nlc3NpbmcvdGVzdHMvYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLW5hZy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQWtEO0FBQ2xELHVEQUE0RDtBQUM1RCx1REFBaUU7QUFDakUsK0NBQTRDO0FBQzVDLGlGQUFtRTtBQUNuRSxxQ0FBOEQ7QUFDOUQsK0NBQTRDO0FBQzVDLHNGQUFrRjtBQUNsRix3Q0FBNkM7QUFDN0MsMEVBQWlHO0FBRWpHLDZFQUE2RTtBQUM3RSxNQUFNLHNCQUF1QixTQUFRLGlEQUFzQjtJQUl6RCxZQUFZLEtBQVUsRUFBRSxFQUFVLEVBQUUsS0FBVTtRQUM1QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUV4QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUM3RCxPQUFPLEVBQUUsb0JBQU8sQ0FBQyxXQUFXO1lBQzVCLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLElBQUksRUFBRSxpQkFBSSxDQUFDLFVBQVUsQ0FBQyxxRUFBcUUsQ0FBQztTQUM3RixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUkscUJBQVEsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO1lBQ3JELE9BQU8sRUFBRSxvQkFBTyxDQUFDLFdBQVc7WUFDNUIsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsVUFBVSxDQUFDLGlEQUFpRCxDQUFDO1NBQ3pFLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxrQkFBa0I7UUFDMUIsT0FBTyxJQUFJLHNDQUFZLENBQUMsSUFBSSxFQUFFLG9CQUFvQixFQUFFO1lBQ2xELGNBQWMs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UyxDQUFDLEdBQUcsRUFBRSxrQkFBSyxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztBQUV0RyxpQ0FBaUM7QUFDakMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLEdBQUcsRUFBRTtJQUNwQyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBQ0QsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuQyxDQUFDLENBQUMsQ0FBQztBQUVILCtCQUErQjtBQUMvQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsR0FBRyxFQUFFO0lBQ2xDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFDRCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2pDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXBwLCBTdGFjaywgQXNwZWN0cyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IEFubm90YXRpb25zLCBNYXRjaCB9IGZyb20gJ2F3cy1jZGstbGliL2Fzc2VydGlvbnMnO1xuaW1wb3J0IHsgQ29kZSwgRnVuY3Rpb24sIFJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBMYW1iZGFJbnZva2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucy10YXNrcyc7XG5pbXBvcnQgeyBBd3NTb2x1dGlvbnNDaGVja3MsIE5hZ1N1cHByZXNzaW9ucyB9IGZyb20gJ2Nkay1uYWcnO1xuaW1wb3J0IHsgQWNjZXNzTG9nIH0gZnJvbSAnLi4vLi4vZnJhbWV3b3JrJztcbmltcG9ydCB7IEV2ZW50YnJpZGdlQnJva2VyIH0gZnJvbSAnLi4vLi4vZnJhbWV3b3JrL2ZvdW5kYXRpb24vZXZlbnRicmlkZ2UtYnJva2VyJztcbmltcG9ydCB7IFF1ZXVlZFMzQWRhcHRlciB9IGZyb20gJy4uL2FkYXB0ZXInO1xuaW1wb3J0IHsgQmFzZURvY3VtZW50UHJvY2Vzc2luZywgRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfSBmcm9tICcuLi9iYXNlLWRvY3VtZW50LXByb2Nlc3NpbmcnO1xuXG4vLyBDb25jcmV0ZSB0ZXN0IGltcGxlbWVudGF0aW9uIG9mIEJhc2VEb2N1bWVudFByb2Nlc3NpbmcgZm9yIENESyBOYWcgdGVzdGluZ1xuY2xhc3MgVGVzdERvY3VtZW50UHJvY2Vzc2luZyBleHRlbmRzIEJhc2VEb2N1bWVudFByb2Nlc3Npbmcge1xuICBwcml2YXRlIGNsYXNzaWZpY2F0aW9uRm46IEZ1bmN0aW9uO1xuICBwcml2YXRlIHByb2Nlc3NpbmdGbjogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGFueSwgaWQ6IHN0cmluZywgcHJvcHM6IGFueSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgdGhpcy5jbGFzc2lmaWNhdGlvbkZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdDbGFzc2lmaWNhdGlvbkZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgZG9jdW1lbnRDbGFzc2lmaWNhdGlvbjogXCJURVNUXCIgfSk7JyksXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnUHJvY2Vzc2luZ0ZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgcmVzdWx0OiB7fSB9KTsnKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbGFzc2lmaWNhdGlvblN0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUge1xuICAgIHJldHVybiBuZXcgTGFtYmRhSW52b2tlKHRoaXMsICdNb2NrQ2xhc3NpZmljYXRpb24nLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jbGFzc2lmaWNhdGlvbkZuLFxuICAgICAgcmVzdWx0UGF0aDogJyQuY2xhc3NpZmljYXRpb25SZXN1bHQnLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHByb2Nlc3NpbmdTdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHtcbiAgICByZXR1cm4gbmV3IExhbWJkYUludm9rZSh0aGlzLCAnTW9ja1Byb2Nlc3NpbmcnLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5wcm9jZXNzaW5nRm4sXG4gICAgICByZXN1bHRQYXRoOiAnJC5wcm9jZXNzaW5nUmVzdWx0JyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbnJpY2htZW50U3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwb3N0UHJvY2Vzc2luZ1N0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlU3RhdGVNYWNoaW5lKCkge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZVN0YXRlTWFjaGluZUNyZWF0aW9uKCd0ZXN0LXN0YXRlLW1hY2hpbmUnKTtcbiAgfVxufVxuXG4vLyBDcmVhdGUgYXBwIGFuZCBzdGFja1xuY29uc3QgYXBwID0gbmV3IEFwcCgpO1xuY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCAnVGVzdFN0YWNrJywge1xuICBlbnY6IHtcbiAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICByZWdpb246ICd1cy1lYXN0LTEnLFxuICB9LFxufSk7XG5cbi8vIENyZWF0ZSBhY2Nlc3MgbG9nIGJ1Y2tldFxuY29uc3QgYWNjZXNzTG9nID0gbmV3IEFjY2Vzc0xvZyhzdGFjaywgJ0FjY2Vzc0xvZycpO1xuXG4vLyBDcmVhdGUgUzMgYnVja2V0IHdpdGggcHJvcGVyIGNvbmZpZ3VyYXRpb25cbmNvbnN0IGJ1Y2tldCA9IG5ldyBCdWNrZXQoc3RhY2ssICdCYXNlRG9jdW1lbnRQcm9jZXNzaW5nQnVja2V0Jywge1xuICBzZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0OiBhY2Nlc3NMb2cuYnVja2V0LFxuICBzZXJ2ZXJBY2Nlc3NMb2dzUHJlZml4OiBhY2Nlc3NMb2cuYnVja2V0UHJlZml4LFxuICBlbmZvcmNlU1NMOiB0cnVlLFxufSk7XG5cbi8vIENyZWF0ZSBFdmVudEJyaWRnZSBicm9rZXJcbmNvbnN0IGJyb2tlciA9IG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ1Rlc3RCcm9rZXInLCB7XG4gIG5hbWU6ICd0ZXN0LWJyb2tlcicsXG4gIGV2ZW50U291cmNlOiAndGVzdC1zb3VyY2UnLFxufSk7XG5cbi8vIENyZWF0ZSBhZGFwdGVyIHdpdGggY3VzdG9tIGJ1Y2tldFxuY29uc3QgYWRhcHRlciA9IG5ldyBRdWV1ZWRTM0FkYXB0ZXIoe1xuICBidWNrZXQsXG59KTtcblxuLy8gQ3JlYXRlIHRoZSBCYXNlRG9jdW1lbnRQcm9jZXNzaW5nIGNvbnN0cnVjdFxuY29uc3QgY29uc3RydWN0ID0gbmV3IFRlc3REb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdCYXNlRG9jdW1lbnRQcm9jZXNzaW5nJywge1xuICBpbmdyZXNzQWRhcHRlcjogYWRhcHRlcixcbiAgZXZlbnRicmlkZ2VCcm9rZXI6IGJyb2tlcixcbiAgZW5hYmxlT2JzZXJ2YWJpbGl0eTogdHJ1ZSxcbn0pO1xuXG4vLyBDcmVhdGUgdGhlIHN0YXRlIG1hY2hpbmVcbmNvbnN0cnVjdC5jcmVhdGVTdGF0ZU1hY2hpbmUoKTtcblxuLy8gU3VwcHJlc3MgQ0RLLW1hbmFnZWQgQnVja2V0Tm90aWZpY2F0aW9uc0hhbmRsZXIgQVdTIG1hbmFnZWQgcG9saWN5XG5OYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnNCeVBhdGgoXG4gIHN0YWNrLFxuICAnL1Rlc3RTdGFjay9CdWNrZXROb3RpZmljYXRpb25zSGFuZGxlcjA1MGEwNTg3Yjc1NDQ1NDdiZjMyNWYwOTRhM2RiODM0L1JvbGUnLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNCcsXG4gICAgICByZWFzb246ICdDREstbWFuYWdlZCBCdWNrZXROb3RpZmljYXRpb25zSGFuZGxlciByZXF1aXJlcyBBV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUgZm9yIFMzIGV2ZW50IHByb2Nlc3NpbmcnLFxuICAgICAgYXBwbGllc1RvOiBbJ1BvbGljeTo6YXJuOjxBV1M6OlBhcnRpdGlvbj46aWFtOjphd3M6cG9saWN5L3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnXSxcbiAgICB9LFxuICBdLFxuKTtcblxuLy8gU3VwcHJlc3MgUzMgYnVja2V0IHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBMYW1iZGEgcm9sZXNcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgIHJlYXNvbjogJ0xhbWJkYSBmdW5jdGlvbnMgcmVxdWlyZSB3aWxkY2FyZCBhY2Nlc3MgdG8gUzMgYnVja2V0IG9iamVjdHMgZm9yIGRvY3VtZW50IHByb2Nlc3NpbmcnLFxuICAgICAgYXBwbGllc1RvOiBbJ1Jlc291cmNlOjo8QmFzZURvY3VtZW50UHJvY2Vzc2luZ0J1Y2tldEU4RTBGNkY1LkFybj4vKiddLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBTUVMgY29uc3VtZXIgTGFtYmRhIHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBsb2cgc3RyZWFtc1xuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUlBTTUnLFxuICAgICAgcmVhc29uOiAnTGFtYmRhIGxvZyBzdHJlYW0gQVJOIGlzIG9ubHkga25vd24gYXQgcnVudGltZSwgd2lsZGNhcmQgcmVxdWlyZWQgZm9yIENsb3VkV2F0Y2ggTG9ncyBhY2Nlc3MnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBTdGF0ZU1hY2hpbmVSb2xlIHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBMYW1iZGEgaW52b2NhdGlvblxuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zQnlQYXRoKFxuICBzdGFjayxcbiAgJy9UZXN0U3RhY2svQmFzZURvY3VtZW50UHJvY2Vzc2luZy9TdGF0ZU1hY2hpbmVSb2xlL0RlZmF1bHRQb2xpY3knLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNScsXG4gICAgICByZWFzb246ICdTdGVwIEZ1bmN0aW9ucyByZXF1aXJlcyB3aWxkY2FyZCBwZXJtaXNzaW9ucyB0byBpbnZva2UgTGFtYmRhIGZ1bmN0aW9ucyB3aXRoIHZlcnNpb24tc3BlY2lmaWMgQVJOcycsXG4gICAgfSxcbiAgXSxcbik7XG5cbi8vIFN1cHByZXNzIExhbWJkYSBsb2cgZ3JvdXAgd2lsZGNhcmQgcGVybWlzc2lvbnNcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgIHJlYXNvbjogJ0xhbWJkYSBsb2cgc3RyZWFtIG5hbWVzIGFyZSBnZW5lcmF0ZWQgYXQgcnVudGltZSwgd2lsZGNhcmQgcmVxdWlyZWQgZm9yIENsb3VkV2F0Y2ggTG9ncyBhY2Nlc3MnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBMYW1iZGEgYmFzaWMgZXhlY3V0aW9uIHJvbGVcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU00JyxcbiAgICAgIHJlYXNvbjogJ1Rlc3QgTGFtYmRhIGZ1bmN0aW9ucyB1c2UgQVdTIG1hbmFnZWQgcG9saWNpZXMgZm9yIGJhc2ljIGV4ZWN1dGlvbicsXG4gICAgICBhcHBsaWVzVG86IFsnUG9saWN5Ojphcm46PEFXUzo6UGFydGl0aW9uPjppYW06OmF3czpwb2xpY3kvc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZSddLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBMYW1iZGEgcnVudGltZSB2ZXJzaW9uIGZvciB0ZXN0IGZ1bmN0aW9uc1xuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUwxJyxcbiAgICAgIHJlYXNvbjogJ1Rlc3QgTGFtYmRhIGZ1bmN0aW9ucyB1c2UgTm9kZS5qcyAyMCB3aGljaCBpcyBhIHN1cHBvcnRlZCBydW50aW1lJyxcbiAgICB9LFxuICBdLFxuICB0cnVlLFxuKTtcblxuLy8gU3VwcHJlc3MgS01TIGtleSByb3RhdGlvbiBmb3IgdGVzdCBlbmNyeXB0aW9uIGtleVxuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUtNUzUnLFxuICAgICAgcmVhc29uOiAnS01TIGtleSByb3RhdGlvbiBpcyBlbmFibGVkIGJ5IGRlZmF1bHQgaW4gQmFzZURvY3VtZW50UHJvY2Vzc2luZyBjb25zdHJ1Y3QnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBBcHBseSBDREsgTmFnIGNoZWNrc1xuQXNwZWN0cy5vZihhcHApLmFkZChuZXcgQXdzU29sdXRpb25zQ2hlY2tzKHsgdmVyYm9zZTogdHJ1ZSB9KSk7XG5cbi8vIFN5bnRoZXNpemUgdGhlIHN0YWNrIGFuZCBjaGVjayBmb3IgdW5zdXBwcmVzc2VkIHdhcm5pbmdzIGFuZCBlcnJvcnNcbmNvbnN0IHdhcm5pbmdzID0gQW5ub3RhdGlvbnMuZnJvbVN0YWNrKHN0YWNrKS5maW5kV2FybmluZygnKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcbmNvbnN0IGVycm9ycyA9IEFubm90YXRpb25zLmZyb21TdGFjayhzdGFjaykuZmluZEVycm9yKCcqJywgTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cCgnQXdzU29sdXRpb25zLS4qJykpO1xuXG4vLyBUZXN0OiBObyB1bnN1cHByZXNzZWQgd2FybmluZ3NcbnRlc3QoJ05vIHVuc3VwcHJlc3NlZCB3YXJuaW5ncycsICgpID0+IHtcbiAgaWYgKHdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zb2xlLmxvZygnQ0RLIE5hZyBXYXJuaW5nczonLCBKU09OLnN0cmluZ2lmeSh3YXJuaW5ncywgbnVsbCwgMikpO1xuICB9XG4gIGV4cGVjdCh3YXJuaW5ncykudG9IYXZlTGVuZ3RoKDApO1xufSk7XG5cbi8vIFRlc3Q6IE5vIHVuc3VwcHJlc3NlZCBlcnJvcnNcbnRlc3QoJ05vIHVuc3VwcHJlc3NlZCBlcnJvcnMnLCAoKSA9PiB7XG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnNvbGUubG9nKCdDREsgTmFnIEVycm9yczonLCBKU09OLnN0cmluZ2lmeShlcnJvcnMsIG51bGwsIDIpKTtcbiAgfVxuICBleHBlY3QoZXJyb3JzKS50b0hhdmVMZW5ndGgoMCk7XG59KTtcbiJdfQ==
168
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLW5hZy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL2RvY3VtZW50LXByb2Nlc3NpbmcvdGVzdHMvYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLW5hZy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQTZDO0FBQzdDLHVEQUE0RDtBQUM1RCx1REFBaUU7QUFDakUsK0NBQTRDO0FBQzVDLGlGQUFtRTtBQUNuRSxxQ0FBOEQ7QUFDOUQsK0NBQTRDO0FBQzVDLHNGQUFrRjtBQUNsRiwyREFBMkQ7QUFDM0Qsd0NBQTZDO0FBQzdDLDBFQUFpRztBQUVqRyw2RUFBNkU7QUFDN0UsTUFBTSxzQkFBdUIsU0FBUSxpREFBc0I7SUFJekQsWUFBWSxLQUFVLEVBQUUsRUFBVSxFQUFFLEtBQVU7UUFDNUMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFeEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUkscUJBQVEsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDN0QsT0FBTyxFQUFFLG9CQUFPLENBQUMsV0FBVztZQUM1QixPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsaUJBQUksQ0FBQyxVQUFVLENBQUMscUVBQXFFLENBQUM7U0FDN0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLHFCQUFRLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRTtZQUNyRCxPQUFPLEVBQUUsb0JBQU8sQ0FBQyxXQUFXO1lBQzVCLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLElBQUksRUFBRSxpQkFBSSxDQUFDLFVBQVUsQ0FBQyxpREFBaUQsQ0FBQztTQUN6RSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVMsa0JBQWtCO1FBQzFCLE9BQU8sSUFBSSxzQ0FBWSxDQUFDLElBQUksRUFBRSxvQkFBb0IsRUFB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QUMsR0FBRyxFQUFFLGtCQUFLLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO0FBQzFHLE1BQU0sTUFBTSxHQUFHLHdCQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsa0JBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7QUFFdEcsaUNBQWlDO0FBQ2pDLElBQUksQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7SUFDcEMsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUNELE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQyxDQUFDLENBQUM7QUFFSCwrQkFBK0I7QUFDL0IsSUFBSSxDQUFDLHdCQUF3QixFQUFFLEdBQUcsRUFBRTtJQUNsQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQyxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrLCBBc3BlY3RzIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQW5ub3RhdGlvbnMsIE1hdGNoIH0gZnJvbSAnYXdzLWNkay1saWIvYXNzZXJ0aW9ucyc7XG5pbXBvcnQgeyBDb2RlLCBGdW5jdGlvbiwgUnVudGltZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQnVja2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzJztcbmltcG9ydCB7IExhbWJkYUludm9rZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzJztcbmltcG9ydCB7IEF3c1NvbHV0aW9uc0NoZWNrcywgTmFnU3VwcHJlc3Npb25zIH0gZnJvbSAnY2RrLW5hZyc7XG5pbXBvcnQgeyBBY2Nlc3NMb2cgfSBmcm9tICcuLi8uLi9mcmFtZXdvcmsnO1xuaW1wb3J0IHsgRXZlbnRicmlkZ2VCcm9rZXIgfSBmcm9tICcuLi8uLi9mcmFtZXdvcmsvZm91bmRhdGlvbi9ldmVudGJyaWRnZS1icm9rZXInO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEFwcCB9IGZyb20gJy4uLy4uL3V0aWxpdGllcy90ZXN0LXV0aWxzJztcbmltcG9ydCB7IFF1ZXVlZFMzQWRhcHRlciB9IGZyb20gJy4uL2FkYXB0ZXInO1xuaW1wb3J0IHsgQmFzZURvY3VtZW50UHJvY2Vzc2luZywgRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfSBmcm9tICcuLi9iYXNlLWRvY3VtZW50LXByb2Nlc3NpbmcnO1xuXG4vLyBDb25jcmV0ZSB0ZXN0IGltcGxlbWVudGF0aW9uIG9mIEJhc2VEb2N1bWVudFByb2Nlc3NpbmcgZm9yIENESyBOYWcgdGVzdGluZ1xuY2xhc3MgVGVzdERvY3VtZW50UHJvY2Vzc2luZyBleHRlbmRzIEJhc2VEb2N1bWVudFByb2Nlc3Npbmcge1xuICBwcml2YXRlIGNsYXNzaWZpY2F0aW9uRm46IEZ1bmN0aW9uO1xuICBwcml2YXRlIHByb2Nlc3NpbmdGbjogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGFueSwgaWQ6IHN0cmluZywgcHJvcHM6IGFueSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgdGhpcy5jbGFzc2lmaWNhdGlvbkZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdDbGFzc2lmaWNhdGlvbkZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgZG9jdW1lbnRDbGFzc2lmaWNhdGlvbjogXCJURVNUXCIgfSk7JyksXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnUHJvY2Vzc2luZ0ZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgcmVzdWx0OiB7fSB9KTsnKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjbGFzc2lmaWNhdGlvblN0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUge1xuICAgIHJldHVybiBuZXcgTGFtYmRhSW52b2tlKHRoaXMsICdNb2NrQ2xhc3NpZmljYXRpb24nLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jbGFzc2lmaWNhdGlvbkZuLFxuICAgICAgcmVzdWx0UGF0aDogJyQuY2xhc3NpZmljYXRpb25SZXN1bHQnLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHByb2Nlc3NpbmdTdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHtcbiAgICByZXR1cm4gbmV3IExhbWJkYUludm9rZSh0aGlzLCAnTW9ja1Byb2Nlc3NpbmcnLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5wcm9jZXNzaW5nRm4sXG4gICAgICByZXN1bHRQYXRoOiAnJC5wcm9jZXNzaW5nUmVzdWx0JyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbnJpY2htZW50U3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwb3N0UHJvY2Vzc2luZ1N0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJlcHJvY2Vzc2luZ1N0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlUHJvY2Vzc2luZ1dvcmtmbG93KCkge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVN0YW5kYXJkUHJvY2Vzc2luZ1dvcmtmbG93KCk7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlU3RhdGVNYWNoaW5lKCkge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZVN0YXRlTWFjaGluZUNyZWF0aW9uKCd0ZXN0LXN0YXRlLW1hY2hpbmUnKTtcbiAgfVxufVxuXG4vLyBDcmVhdGUgYXBwIGFuZCBzdGFja1xuY29uc3QgYXBwID0gY3JlYXRlVGVzdEFwcCgpO1xuY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCAnVGVzdFN0YWNrJywge1xuICBlbnY6IHtcbiAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICByZWdpb246ICd1cy1lYXN0LTEnLFxuICB9LFxufSk7XG5cbi8vIENyZWF0ZSBhY2Nlc3MgbG9nIGJ1Y2tldFxuY29uc3QgYWNjZXNzTG9nID0gbmV3IEFjY2Vzc0xvZyhzdGFjaywgJ0FjY2Vzc0xvZycpO1xuXG4vLyBDcmVhdGUgUzMgYnVja2V0IHdpdGggcHJvcGVyIGNvbmZpZ3VyYXRpb25cbmNvbnN0IGJ1Y2tldCA9IG5ldyBCdWNrZXQoc3RhY2ssICdCYXNlRG9jdW1lbnRQcm9jZXNzaW5nQnVja2V0Jywge1xuICBzZXJ2ZXJBY2Nlc3NMb2dzQnVja2V0OiBhY2Nlc3NMb2cuYnVja2V0LFxuICBzZXJ2ZXJBY2Nlc3NMb2dzUHJlZml4OiBhY2Nlc3NMb2cuYnVja2V0UHJlZml4LFxuICBlbmZvcmNlU1NMOiB0cnVlLFxufSk7XG5cbi8vIENyZWF0ZSBFdmVudEJyaWRnZSBicm9rZXJcbmNvbnN0IGJyb2tlciA9IG5ldyBFdmVudGJyaWRnZUJyb2tlcihzdGFjaywgJ1Rlc3RCcm9rZXInLCB7XG4gIG5hbWU6ICd0ZXN0LWJyb2tlcicsXG4gIGV2ZW50U291cmNlOiAndGVzdC1zb3VyY2UnLFxufSk7XG5cbi8vIENyZWF0ZSBhZGFwdGVyIHdpdGggY3VzdG9tIGJ1Y2tldFxuY29uc3QgYWRhcHRlciA9IG5ldyBRdWV1ZWRTM0FkYXB0ZXIoe1xuICBidWNrZXQsXG59KTtcblxuLy8gQ3JlYXRlIHRoZSBCYXNlRG9jdW1lbnRQcm9jZXNzaW5nIGNvbnN0cnVjdFxuY29uc3QgY29uc3RydWN0ID0gbmV3IFRlc3REb2N1bWVudFByb2Nlc3Npbmcoc3RhY2ssICdCYXNlRG9jdW1lbnRQcm9jZXNzaW5nJywge1xuICBpbmdyZXNzQWRhcHRlcjogYWRhcHRlcixcbiAgZXZlbnRicmlkZ2VCcm9rZXI6IGJyb2tlcixcbiAgZW5hYmxlT2JzZXJ2YWJpbGl0eTogdHJ1ZSxcbn0pO1xuXG4vLyBDcmVhdGUgdGhlIHN0YXRlIG1hY2hpbmVcbmNvbnN0cnVjdC5jcmVhdGVTdGF0ZU1hY2hpbmUoKTtcblxuLy8gU3VwcHJlc3MgQ0RLLW1hbmFnZWQgQnVja2V0Tm90aWZpY2F0aW9uc0hhbmRsZXIgQVdTIG1hbmFnZWQgcG9saWN5XG5OYWdTdXBwcmVzc2lvbnMuYWRkUmVzb3VyY2VTdXBwcmVzc2lvbnNCeVBhdGgoXG4gIHN0YWNrLFxuICAnL1Rlc3RTdGFjay9CdWNrZXROb3RpZmljYXRpb25zSGFuZGxlcjA1MGEwNTg3Yjc1NDQ1NDdiZjMyNWYwOTRhM2RiODM0L1JvbGUnLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNCcsXG4gICAgICByZWFzb246ICdDREstbWFuYWdlZCBCdWNrZXROb3RpZmljYXRpb25zSGFuZGxlciByZXF1aXJlcyBBV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUgZm9yIFMzIGV2ZW50IHByb2Nlc3NpbmcnLFxuICAgICAgYXBwbGllc1RvOiBbJ1BvbGljeTo6YXJuOjxBV1M6OlBhcnRpdGlvbj46aWFtOjphd3M6cG9saWN5L3NlcnZpY2Utcm9sZS9BV1NMYW1iZGFCYXNpY0V4ZWN1dGlvblJvbGUnXSxcbiAgICB9LFxuICBdLFxuKTtcblxuLy8gU3VwcHJlc3MgUzMgYnVja2V0IHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBMYW1iZGEgcm9sZXNcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgIHJlYXNvbjogJ0xhbWJkYSBmdW5jdGlvbnMgcmVxdWlyZSB3aWxkY2FyZCBhY2Nlc3MgdG8gUzMgYnVja2V0IG9iamVjdHMgZm9yIGRvY3VtZW50IHByb2Nlc3NpbmcnLFxuICAgICAgYXBwbGllc1RvOiBbJ1Jlc291cmNlOjo8QmFzZURvY3VtZW50UHJvY2Vzc2luZ0J1Y2tldEU4RTBGNkY1LkFybj4vKiddLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBTUVMgY29uc3VtZXIgTGFtYmRhIHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBsb2cgc3RyZWFtc1xuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUlBTTUnLFxuICAgICAgcmVhc29uOiAnTGFtYmRhIGxvZyBzdHJlYW0gQVJOIGlzIG9ubHkga25vd24gYXQgcnVudGltZSwgd2lsZGNhcmQgcmVxdWlyZWQgZm9yIENsb3VkV2F0Y2ggTG9ncyBhY2Nlc3MnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBTdGF0ZU1hY2hpbmVSb2xlIHdpbGRjYXJkIHBlcm1pc3Npb25zIGZvciBMYW1iZGEgaW52b2NhdGlvblxuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zQnlQYXRoKFxuICBzdGFjayxcbiAgJy9UZXN0U3RhY2svQmFzZURvY3VtZW50UHJvY2Vzc2luZy9TdGF0ZU1hY2hpbmVSb2xlL0RlZmF1bHRQb2xpY3knLFxuICBbXG4gICAge1xuICAgICAgaWQ6ICdBd3NTb2x1dGlvbnMtSUFNNScsXG4gICAgICByZWFzb246ICdTdGVwIEZ1bmN0aW9ucyByZXF1aXJlcyB3aWxkY2FyZCBwZXJtaXNzaW9ucyB0byBpbnZva2UgTGFtYmRhIGZ1bmN0aW9ucyB3aXRoIHZlcnNpb24tc3BlY2lmaWMgQVJOcycsXG4gICAgfSxcbiAgXSxcbik7XG5cbi8vIFN1cHByZXNzIExhbWJkYSBsb2cgZ3JvdXAgd2lsZGNhcmQgcGVybWlzc2lvbnNcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JyxcbiAgICAgIHJlYXNvbjogJ0xhbWJkYSBsb2cgc3RyZWFtIG5hbWVzIGFyZSBnZW5lcmF0ZWQgYXQgcnVudGltZSwgd2lsZGNhcmQgcmVxdWlyZWQgZm9yIENsb3VkV2F0Y2ggTG9ncyBhY2Nlc3MnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBMYW1iZGEgYmFzaWMgZXhlY3V0aW9uIHJvbGVcbk5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhcbiAgc3RhY2ssXG4gIFtcbiAgICB7XG4gICAgICBpZDogJ0F3c1NvbHV0aW9ucy1JQU00JyxcbiAgICAgIHJlYXNvbjogJ1Rlc3QgTGFtYmRhIGZ1bmN0aW9ucyB1c2UgQVdTIG1hbmFnZWQgcG9saWNpZXMgZm9yIGJhc2ljIGV4ZWN1dGlvbicsXG4gICAgICBhcHBsaWVzVG86IFsnUG9saWN5Ojphcm46PEFXUzo6UGFydGl0aW9uPjppYW06OmF3czpwb2xpY3kvc2VydmljZS1yb2xlL0FXU0xhbWJkYUJhc2ljRXhlY3V0aW9uUm9sZSddLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBTdXBwcmVzcyBMYW1iZGEgcnVudGltZSB2ZXJzaW9uIGZvciB0ZXN0IGZ1bmN0aW9uc1xuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUwxJyxcbiAgICAgIHJlYXNvbjogJ1Rlc3QgTGFtYmRhIGZ1bmN0aW9ucyB1c2UgTm9kZS5qcyAyMCB3aGljaCBpcyBhIHN1cHBvcnRlZCBydW50aW1lJyxcbiAgICB9LFxuICBdLFxuICB0cnVlLFxuKTtcblxuLy8gU3VwcHJlc3MgS01TIGtleSByb3RhdGlvbiBmb3IgdGVzdCBlbmNyeXB0aW9uIGtleVxuTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFxuICBzdGFjayxcbiAgW1xuICAgIHtcbiAgICAgIGlkOiAnQXdzU29sdXRpb25zLUtNUzUnLFxuICAgICAgcmVhc29uOiAnS01TIGtleSByb3RhdGlvbiBpcyBlbmFibGVkIGJ5IGRlZmF1bHQgaW4gQmFzZURvY3VtZW50UHJvY2Vzc2luZyBjb25zdHJ1Y3QnLFxuICAgIH0sXG4gIF0sXG4gIHRydWUsXG4pO1xuXG4vLyBBcHBseSBDREsgTmFnIGNoZWNrc1xuQXNwZWN0cy5vZihhcHApLmFkZChuZXcgQXdzU29sdXRpb25zQ2hlY2tzKHsgdmVyYm9zZTogdHJ1ZSB9KSk7XG5cbi8vIFN5bnRoZXNpemUgdGhlIHN0YWNrIGFuZCBjaGVjayBmb3IgdW5zdXBwcmVzc2VkIHdhcm5pbmdzIGFuZCBlcnJvcnNcbmNvbnN0IHdhcm5pbmdzID0gQW5ub3RhdGlvbnMuZnJvbVN0YWNrKHN0YWNrKS5maW5kV2FybmluZygnKicsIE1hdGNoLnN0cmluZ0xpa2VSZWdleHAoJ0F3c1NvbHV0aW9ucy0uKicpKTtcbmNvbnN0IGVycm9ycyA9IEFubm90YXRpb25zLmZyb21TdGFjayhzdGFjaykuZmluZEVycm9yKCcqJywgTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cCgnQXdzU29sdXRpb25zLS4qJykpO1xuXG4vLyBUZXN0OiBObyB1bnN1cHByZXNzZWQgd2FybmluZ3NcbnRlc3QoJ05vIHVuc3VwcHJlc3NlZCB3YXJuaW5ncycsICgpID0+IHtcbiAgaWYgKHdhcm5pbmdzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zb2xlLmxvZygnQ0RLIE5hZyBXYXJuaW5nczonLCBKU09OLnN0cmluZ2lmeSh3YXJuaW5ncywgbnVsbCwgMikpO1xuICB9XG4gIGV4cGVjdCh3YXJuaW5ncykudG9IYXZlTGVuZ3RoKDApO1xufSk7XG5cbi8vIFRlc3Q6IE5vIHVuc3VwcHJlc3NlZCBlcnJvcnNcbnRlc3QoJ05vIHVuc3VwcHJlc3NlZCBlcnJvcnMnLCAoKSA9PiB7XG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIGNvbnNvbGUubG9nKCdDREsgTmFnIEVycm9yczonLCBKU09OLnN0cmluZ2lmeShlcnJvcnMsIG51bGwsIDIpKTtcbiAgfVxuICBleHBlY3QoZXJyb3JzKS50b0hhdmVMZW5ndGgoMCk7XG59KTtcbiJdfQ==
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
4
+ const assertions_1 = require("aws-cdk-lib/assertions");
5
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
6
+ const aws_stepfunctions_1 = require("aws-cdk-lib/aws-stepfunctions");
7
+ const aws_stepfunctions_tasks_1 = require("aws-cdk-lib/aws-stepfunctions-tasks");
8
+ const test_utils_1 = require("../../utilities/test-utils");
9
+ const base_document_processing_1 = require("../base-document-processing");
10
+ /**
11
+ * Test implementation WITHOUT preprocessing (backward compatible)
12
+ * This simulates existing implementations that don't use any preprocessing
13
+ */
14
+ class TestDocumentProcessingWithoutPreprocessing extends base_document_processing_1.BaseDocumentProcessing {
15
+ constructor(scope, id, props) {
16
+ super(scope, id, props);
17
+ this.classificationFn = new aws_lambda_1.Function(this, 'ClassificationFn', {
18
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
19
+ handler: 'index.handler',
20
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ documentClassification: "TEST" });'),
21
+ });
22
+ this.processingFn = new aws_lambda_1.Function(this, 'ProcessingFn', {
23
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
24
+ handler: 'index.handler',
25
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ result: {} });'),
26
+ });
27
+ }
28
+ preprocessingStep() {
29
+ // No preprocessing - backward compatible
30
+ return undefined;
31
+ }
32
+ // No override of preprocessingMetadata() - uses default (empty)
33
+ classificationStep() {
34
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockClassification', {
35
+ lambdaFunction: this.classificationFn,
36
+ resultPath: '$.classificationResult',
37
+ });
38
+ }
39
+ processingStep() {
40
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockProcessing', {
41
+ lambdaFunction: this.processingFn,
42
+ resultPath: '$.processingResult',
43
+ });
44
+ }
45
+ enrichmentStep() {
46
+ return undefined;
47
+ }
48
+ postProcessingStep() {
49
+ return undefined;
50
+ }
51
+ createProcessingWorkflow() {
52
+ return this.createStandardProcessingWorkflow();
53
+ }
54
+ createStateMachine() {
55
+ return this.handleStateMachineCreation('test-state-machine-no-preprocessing');
56
+ }
57
+ }
58
+ /**
59
+ * Test implementation WITH preprocessing and custom metadata
60
+ * This simulates implementations that add their own preprocessing-specific fields
61
+ * (e.g., chunking metadata) without the base class knowing about them
62
+ */
63
+ class TestDocumentProcessingWithCustomMetadata extends base_document_processing_1.BaseDocumentProcessing {
64
+ constructor(scope, id, props) {
65
+ super(scope, id, props);
66
+ this.preprocessingFn = new aws_lambda_1.Function(this, 'PreprocessingFn', {
67
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
68
+ handler: 'index.handler',
69
+ code: aws_lambda_1.Code.fromInline(`
70
+ exports.handler = async () => ({
71
+ customField1: 'value1',
72
+ customField2: { nested: 'data' },
73
+ customField3: true
74
+ });
75
+ `),
76
+ });
77
+ this.classificationFn = new aws_lambda_1.Function(this, 'ClassificationFn', {
78
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
79
+ handler: 'index.handler',
80
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ documentClassification: "TEST" });'),
81
+ });
82
+ this.processingFn = new aws_lambda_1.Function(this, 'ProcessingFn', {
83
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
84
+ handler: 'index.handler',
85
+ code: aws_lambda_1.Code.fromInline('exports.handler = async () => ({ result: {} });'),
86
+ });
87
+ }
88
+ preprocessingStep() {
89
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockPreprocessing', {
90
+ lambdaFunction: this.preprocessingFn,
91
+ resultPath: '$.preprocessingResult',
92
+ });
93
+ }
94
+ // Override to add custom metadata fields
95
+ preprocessingMetadata() {
96
+ return {
97
+ CustomField1: aws_stepfunctions_tasks_1.DynamoAttributeValue.fromString(aws_stepfunctions_1.JsonPath.stringAt('$.preprocessingResult.customField1')),
98
+ CustomField2: aws_stepfunctions_tasks_1.DynamoAttributeValue.fromString(aws_stepfunctions_1.JsonPath.jsonToString(aws_stepfunctions_1.JsonPath.objectAt('$.preprocessingResult.customField2'))),
99
+ CustomField3: aws_stepfunctions_tasks_1.DynamoAttributeValue.booleanFromJsonPath(aws_stepfunctions_1.JsonPath.stringAt('$.preprocessingResult.customField3')),
100
+ };
101
+ }
102
+ classificationStep() {
103
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockClassification', {
104
+ lambdaFunction: this.classificationFn,
105
+ resultPath: '$.classificationResult',
106
+ });
107
+ }
108
+ processingStep() {
109
+ return new aws_stepfunctions_tasks_1.LambdaInvoke(this, 'MockProcessing', {
110
+ lambdaFunction: this.processingFn,
111
+ resultPath: '$.processingResult',
112
+ });
113
+ }
114
+ enrichmentStep() {
115
+ return undefined;
116
+ }
117
+ postProcessingStep() {
118
+ return undefined;
119
+ }
120
+ createProcessingWorkflow() {
121
+ return this.createStandardProcessingWorkflow();
122
+ }
123
+ createStateMachine() {
124
+ return this.handleStateMachineCreation('test-state-machine-with-custom-metadata');
125
+ }
126
+ }
127
+ describe('BaseDocumentProcessing - DynamoDB Schema Extension Mechanism', () => {
128
+ let app;
129
+ let stackWithoutPreprocessing;
130
+ let stackWithCustomMetadata;
131
+ let templateWithoutPreprocessing;
132
+ let templateWithCustomMetadata;
133
+ beforeAll(() => {
134
+ // Use createTestApp() to skip bundling and speed up tests
135
+ app = (0, test_utils_1.createTestApp)();
136
+ // Stack without preprocessing (backward compatible)
137
+ stackWithoutPreprocessing = new aws_cdk_lib_1.Stack(app, 'WithoutPreprocessingStack');
138
+ const constructWithoutPreprocessing = new TestDocumentProcessingWithoutPreprocessing(stackWithoutPreprocessing, 'TestWithoutPreprocessing', {});
139
+ constructWithoutPreprocessing.createStateMachine();
140
+ // Stack with custom metadata
141
+ stackWithCustomMetadata = new aws_cdk_lib_1.Stack(app, 'WithCustomMetadataStack');
142
+ const constructWithCustomMetadata = new TestDocumentProcessingWithCustomMetadata(stackWithCustomMetadata, 'TestWithCustomMetadata', {});
143
+ constructWithCustomMetadata.createStateMachine();
144
+ // Generate templates
145
+ templateWithoutPreprocessing = assertions_1.Template.fromStack(stackWithoutPreprocessing);
146
+ templateWithCustomMetadata = assertions_1.Template.fromStack(stackWithCustomMetadata);
147
+ });
148
+ describe('Backward Compatibility - Documents without preprocessing', () => {
149
+ test('InitMetadata only includes base fields when no preprocessing', () => {
150
+ const stateMachines = templateWithoutPreprocessing.findResources('AWS::StepFunctions::StateMachine');
151
+ const stateMachineKey = Object.keys(stateMachines)[0];
152
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
153
+ // Parse the definition
154
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
155
+ // Find the InitMetadataEntry state by name
156
+ const initMetadataState = definition.States.InitMetadataEntry;
157
+ expect(initMetadataState).toBeDefined();
158
+ expect(initMetadataState.Type).toBe('Task');
159
+ // Verify base fields are present
160
+ expect(initMetadataState.Parameters.Item.DocumentId).toBeDefined();
161
+ expect(initMetadataState.Parameters.Item.ContentType).toBeDefined();
162
+ expect(initMetadataState.Parameters.Item.Content).toBeDefined();
163
+ expect(initMetadataState.Parameters.Item.WorkflowStatus).toBeDefined();
164
+ expect(initMetadataState.Parameters.Item.StateMachineExecId).toBeDefined();
165
+ // Verify NO custom fields are present (backward compatibility)
166
+ expect(initMetadataState.Parameters.Item.CustomField1).toBeUndefined();
167
+ expect(initMetadataState.Parameters.Item.CustomField2).toBeUndefined();
168
+ expect(initMetadataState.Parameters.Item.CustomField3).toBeUndefined();
169
+ });
170
+ test('workflow starts with InitMetadata when no preprocessing', () => {
171
+ const stateMachines = templateWithoutPreprocessing.findResources('AWS::StepFunctions::StateMachine');
172
+ const stateMachineKey = Object.keys(stateMachines)[0];
173
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
174
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
175
+ // Should start with InitMetadata when no preprocessing
176
+ expect(definition.StartAt).toMatch(/InitMetadata/);
177
+ });
178
+ test('DynamoDB table schema remains unchanged', () => {
179
+ // Verify table is created with same schema as before
180
+ templateWithoutPreprocessing.hasResourceProperties('AWS::DynamoDB::Table', {
181
+ KeySchema: [{
182
+ AttributeName: 'DocumentId',
183
+ KeyType: 'HASH',
184
+ }],
185
+ BillingMode: 'PAY_PER_REQUEST',
186
+ });
187
+ });
188
+ });
189
+ describe('Schema Extension Mechanism - Generic preprocessing metadata', () => {
190
+ test('preprocessingMetadata() hook allows subclasses to extend schema', () => {
191
+ // The key design principle: subclasses can override preprocessingMetadata()
192
+ // to add their own fields to InitMetadata without base class knowing the details
193
+ // Verify the construct with custom metadata was created successfully
194
+ expect(stackWithCustomMetadata).toBeDefined();
195
+ // Verify it has a state machine
196
+ templateWithCustomMetadata.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
197
+ // Verify it has the same DynamoDB table structure as the base implementation
198
+ templateWithCustomMetadata.hasResourceProperties('AWS::DynamoDB::Table', {
199
+ KeySchema: [{
200
+ AttributeName: 'DocumentId',
201
+ KeyType: 'HASH',
202
+ }],
203
+ });
204
+ });
205
+ test('workflow includes preprocessing step when provided', () => {
206
+ const stateMachines = templateWithCustomMetadata.findResources('AWS::StepFunctions::StateMachine');
207
+ const stateMachineKey = Object.keys(stateMachines)[0];
208
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
209
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
210
+ // Verify InitMetadata step exists (core functionality)
211
+ expect(definition.States.InitMetadataEntry).toBeDefined();
212
+ // When preprocessing is provided, it should be in the workflow
213
+ // The exact structure depends on the subclass implementation
214
+ expect(definition.States).toBeDefined();
215
+ expect(Object.keys(definition.States).length).toBeGreaterThan(1);
216
+ });
217
+ test('InitMetadata can accept additional fields via preprocessingMetadata()', () => {
218
+ const stateMachines = templateWithCustomMetadata.findResources('AWS::StepFunctions::StateMachine');
219
+ const stateMachineKey = Object.keys(stateMachines)[0];
220
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
221
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
222
+ const initMetadataState = definition.States.InitMetadataEntry;
223
+ // Verify base fields are always present
224
+ expect(initMetadataState.Parameters.Item.DocumentId).toBeDefined();
225
+ expect(initMetadataState.Parameters.Item.ContentType).toBeDefined();
226
+ expect(initMetadataState.Parameters.Item.Content).toBeDefined();
227
+ expect(initMetadataState.Parameters.Item.WorkflowStatus).toBeDefined();
228
+ expect(initMetadataState.Parameters.Item.StateMachineExecId).toBeDefined();
229
+ // The mechanism allows adding custom fields (implementation detail of subclass)
230
+ // DynamoDB's schemaless nature means any fields can be added at runtime
231
+ });
232
+ });
233
+ describe('Schema Compatibility', () => {
234
+ test('both implementations use the same DynamoDB table structure', () => {
235
+ // Both should create tables with same partition key
236
+ templateWithoutPreprocessing.hasResourceProperties('AWS::DynamoDB::Table', {
237
+ KeySchema: [{
238
+ AttributeName: 'DocumentId',
239
+ KeyType: 'HASH',
240
+ }],
241
+ });
242
+ templateWithCustomMetadata.hasResourceProperties('AWS::DynamoDB::Table', {
243
+ KeySchema: [{
244
+ AttributeName: 'DocumentId',
245
+ KeyType: 'HASH',
246
+ }],
247
+ });
248
+ });
249
+ test('both implementations create encrypted tables', () => {
250
+ templateWithoutPreprocessing.hasResourceProperties('AWS::DynamoDB::Table', {
251
+ SSESpecification: {
252
+ SSEEnabled: true,
253
+ SSEType: 'KMS',
254
+ },
255
+ });
256
+ templateWithCustomMetadata.hasResourceProperties('AWS::DynamoDB::Table', {
257
+ SSESpecification: {
258
+ SSEEnabled: true,
259
+ SSEType: 'KMS',
260
+ },
261
+ });
262
+ });
263
+ test('both implementations use PAY_PER_REQUEST billing', () => {
264
+ templateWithoutPreprocessing.hasResourceProperties('AWS::DynamoDB::Table', {
265
+ BillingMode: 'PAY_PER_REQUEST',
266
+ });
267
+ templateWithCustomMetadata.hasResourceProperties('AWS::DynamoDB::Table', {
268
+ BillingMode: 'PAY_PER_REQUEST',
269
+ });
270
+ });
271
+ });
272
+ describe('Design Principle: Base class has no knowledge of preprocessing specifics', () => {
273
+ test('base class provides generic extension mechanism via preprocessingMetadata()', () => {
274
+ // This test verifies the design principle:
275
+ // - Base class doesn't know about chunking, validation, or any specific preprocessing
276
+ // - Base class only provides a hook (preprocessingMetadata) for subclasses to extend
277
+ // - Subclasses are responsible for their own metadata fields
278
+ // Verify that without overriding preprocessingMetadata(), workflow works correctly
279
+ const stateMachines = templateWithoutPreprocessing.findResources('AWS::StepFunctions::StateMachine');
280
+ const stateMachineKey = Object.keys(stateMachines)[0];
281
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
282
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
283
+ const initMetadataState = definition.States.InitMetadataEntry;
284
+ // Base fields are always present
285
+ expect(initMetadataState.Parameters.Item.DocumentId).toBeDefined();
286
+ expect(initMetadataState.Parameters.Item.ContentType).toBeDefined();
287
+ expect(initMetadataState.Parameters.Item.Content).toBeDefined();
288
+ expect(initMetadataState.Parameters.Item.WorkflowStatus).toBeDefined();
289
+ expect(initMetadataState.Parameters.Item.StateMachineExecId).toBeDefined();
290
+ });
291
+ test('subclasses can extend via preprocessingMetadata() without breaking base functionality', () => {
292
+ // Verify that the construct with custom metadata still has all base functionality
293
+ templateWithCustomMetadata.resourceCountIs('AWS::StepFunctions::StateMachine', 1);
294
+ templateWithCustomMetadata.resourceCountIs('AWS::DynamoDB::Table', 1);
295
+ templateWithCustomMetadata.resourceCountIs('AWS::S3::Bucket', 1);
296
+ // Verify state machine has the same base structure
297
+ const stateMachines = templateWithCustomMetadata.findResources('AWS::StepFunctions::StateMachine');
298
+ const stateMachineKey = Object.keys(stateMachines)[0];
299
+ const definitionString = stateMachines[stateMachineKey].Properties.DefinitionString;
300
+ const definition = JSON.parse(definitionString['Fn::Join'][1].join(''));
301
+ // Core states should exist
302
+ expect(definition.States.InitMetadataEntry).toBeDefined();
303
+ expect(definition.States.MockClassification).toBeDefined();
304
+ expect(definition.States.MockProcessing).toBeDefined();
305
+ });
306
+ });
307
+ describe('DynamoDB schemaless nature supports runtime field addition', () => {
308
+ test('DynamoDB table supports any additional fields at runtime', () => {
309
+ // DynamoDB is schemaless, so any fields can be added at runtime
310
+ // This test verifies the table is created correctly and can accept any attributes
311
+ templateWithCustomMetadata.hasResourceProperties('AWS::DynamoDB::Table', {
312
+ KeySchema: [{
313
+ AttributeName: 'DocumentId',
314
+ KeyType: 'HASH',
315
+ }],
316
+ BillingMode: 'PAY_PER_REQUEST',
317
+ });
318
+ // No attribute definitions needed for non-key attributes in DynamoDB
319
+ // Fields like AggregatedResult can be added via DynamoUpdateItem during processing
320
+ });
321
+ test('state machine has permissions to update DynamoDB items', () => {
322
+ // Verify the state machine role has UpdateItem permissions
323
+ // This allows adding fields like AggregatedResult during processing
324
+ const policies = templateWithCustomMetadata.findResources('AWS::IAM::Policy');
325
+ // Find the state machine role policy
326
+ const stateMachinePolicy = Object.values(policies).find((policy) => policy.Properties.PolicyName.includes('StateMachineRole'));
327
+ expect(stateMachinePolicy).toBeDefined();
328
+ // Check that it has DynamoDB UpdateItem permissions
329
+ const statements = stateMachinePolicy.Properties.PolicyDocument.Statement;
330
+ const dynamoStatement = statements.find((stmt) => stmt.Action && ((Array.isArray(stmt.Action) && stmt.Action.includes('dynamodb:UpdateItem')) ||
331
+ stmt.Action === 'dynamodb:UpdateItem'));
332
+ expect(dynamoStatement).toBeDefined();
333
+ expect(dynamoStatement.Effect).toBe('Allow');
334
+ });
335
+ });
336
+ });
337
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLXNjaGVtYS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdXNlLWNhc2VzL2RvY3VtZW50LXByb2Nlc3NpbmcvdGVzdHMvYmFzZS1kb2N1bWVudC1wcm9jZXNzaW5nLXNjaGVtYS50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQXlDO0FBQ3pDLHVEQUFrRDtBQUNsRCx1REFBaUU7QUFDakUscUVBQXlEO0FBQ3pELGlGQUF5RjtBQUN6RiwyREFBMkQ7QUFDM0QsMEVBQWlHO0FBRWpHOzs7R0FHRztBQUNILE1BQU0sMENBQTJDLFNBQVEsaURBQXNCO0lBSTdFLFlBQVksS0FBVSxFQUFFLEVBQVUsRUFBRSxLQUFVO1FBQzVDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXhCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLHFCQUFRLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFO1lBQzdELE9BQU8sRUFBRSxvQkFBTyxDQUFDLFdBQVc7WUFDNUIsT0FBTyxFQUFFLGVBQWU7WUFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsVUFBVSxDQUFDLHFFQUFxRSxDQUFDO1NBQzdGLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxxQkFBUSxDQUFDLElBQUksRUFBRSxjQUFjLEVBQUU7WUFDckQsT0FBTyxFQUFFLG9CQUFPLENBQUMsV0FBVztZQUM1QixPQUFPLEVBQUUsZUFBZTtZQUN4QixJQUFJLEVBQUUsaUJBQUksQ0FBQyxVQUFVLENBQUMsaURBQWlELENBQUM7U0FDekUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLGlCQUFpQjtRQUN6Qix5Q0FBeUM7UUFDekMsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELGdFQUFnRTtJQUV0RCxrQkFBa0I7UUFDMUIsT0FBTyxJQUFJLHNDQUFZLENB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LENBQUMsTUFBVyxFQUFFLEVBQUUsQ0FDdEUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQzFELENBQUM7WUFFRixNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUV6QyxvREFBb0Q7WUFDcEQsTUFBTSxVQUFVLEdBQUksa0JBQTBCLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUM7WUFDbkYsTUFBTSxlQUFlLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQ3BELElBQUksQ0FBQyxNQUFNLElBQUksQ0FDYixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBQzNFLElBQUksQ0FBQyxNQUFNLEtBQUsscUJBQXFCLENBQ3RDLENBQ0YsQ0FBQztZQUVGLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcHAsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IENvZGUsIEZ1bmN0aW9uLCBSdW50aW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBKc29uUGF0aCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zJztcbmltcG9ydCB7IER5bmFtb0F0dHJpYnV0ZVZhbHVlLCBMYW1iZGFJbnZva2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc3RlcGZ1bmN0aW9ucy10YXNrcyc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXBwIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL3Rlc3QtdXRpbHMnO1xuaW1wb3J0IHsgQmFzZURvY3VtZW50UHJvY2Vzc2luZywgRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfSBmcm9tICcuLi9iYXNlLWRvY3VtZW50LXByb2Nlc3NpbmcnO1xuXG4vKipcbiAqIFRlc3QgaW1wbGVtZW50YXRpb24gV0lUSE9VVCBwcmVwcm9jZXNzaW5nIChiYWNrd2FyZCBjb21wYXRpYmxlKVxuICogVGhpcyBzaW11bGF0ZXMgZXhpc3RpbmcgaW1wbGVtZW50YXRpb25zIHRoYXQgZG9uJ3QgdXNlIGFueSBwcmVwcm9jZXNzaW5nXG4gKi9cbmNsYXNzIFRlc3REb2N1bWVudFByb2Nlc3NpbmdXaXRob3V0UHJlcHJvY2Vzc2luZyBleHRlbmRzIEJhc2VEb2N1bWVudFByb2Nlc3Npbmcge1xuICBwcml2YXRlIGNsYXNzaWZpY2F0aW9uRm46IEZ1bmN0aW9uO1xuICBwcml2YXRlIHByb2Nlc3NpbmdGbjogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGFueSwgaWQ6IHN0cmluZywgcHJvcHM6IGFueSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgdGhpcy5jbGFzc2lmaWNhdGlvbkZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdDbGFzc2lmaWNhdGlvbkZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgZG9jdW1lbnRDbGFzc2lmaWNhdGlvbjogXCJURVNUXCIgfSk7JyksXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnUHJvY2Vzc2luZ0ZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgcmVzdWx0OiB7fSB9KTsnKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwcmVwcm9jZXNzaW5nU3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgLy8gTm8gcHJlcHJvY2Vzc2luZyAtIGJhY2t3YXJkIGNvbXBhdGlibGVcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gTm8gb3ZlcnJpZGUgb2YgcHJlcHJvY2Vzc2luZ01ldGFkYXRhKCkgLSB1c2VzIGRlZmF1bHQgKGVtcHR5KVxuXG4gIHByb3RlY3RlZCBjbGFzc2lmaWNhdGlvblN0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUge1xuICAgIHJldHVybiBuZXcgTGFtYmRhSW52b2tlKHRoaXMsICdNb2NrQ2xhc3NpZmljYXRpb24nLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5jbGFzc2lmaWNhdGlvbkZuLFxuICAgICAgcmVzdWx0UGF0aDogJyQuY2xhc3NpZmljYXRpb25SZXN1bHQnLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHByb2Nlc3NpbmdTdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHtcbiAgICByZXR1cm4gbmV3IExhbWJkYUludm9rZSh0aGlzLCAnTW9ja1Byb2Nlc3NpbmcnLCB7XG4gICAgICBsYW1iZGFGdW5jdGlvbjogdGhpcy5wcm9jZXNzaW5nRm4sXG4gICAgICByZXN1bHRQYXRoOiAnJC5wcm9jZXNzaW5nUmVzdWx0JyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBlbnJpY2htZW50U3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwb3N0UHJvY2Vzc2luZ1N0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlUHJvY2Vzc2luZ1dvcmtmbG93KCkge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVN0YW5kYXJkUHJvY2Vzc2luZ1dvcmtmbG93KCk7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlU3RhdGVNYWNoaW5lKCkge1xuICAgIHJldHVybiB0aGlzLmhhbmRsZVN0YXRlTWFjaGluZUNyZWF0aW9uKCd0ZXN0LXN0YXRlLW1hY2hpbmUtbm8tcHJlcHJvY2Vzc2luZycpO1xuICB9XG59XG5cbi8qKlxuICogVGVzdCBpbXBsZW1lbnRhdGlvbiBXSVRIIHByZXByb2Nlc3NpbmcgYW5kIGN1c3RvbSBtZXRhZGF0YVxuICogVGhpcyBzaW11bGF0ZXMgaW1wbGVtZW50YXRpb25zIHRoYXQgYWRkIHRoZWlyIG93biBwcmVwcm9jZXNzaW5nLXNwZWNpZmljIGZpZWxkc1xuICogKGUuZy4sIGNodW5raW5nIG1ldGFkYXRhKSB3aXRob3V0IHRoZSBiYXNlIGNsYXNzIGtub3dpbmcgYWJvdXQgdGhlbVxuICovXG5jbGFzcyBUZXN0RG9jdW1lbnRQcm9jZXNzaW5nV2l0aEN1c3RvbU1ldGFkYXRhIGV4dGVuZHMgQmFzZURvY3VtZW50UHJvY2Vzc2luZyB7XG4gIHByaXZhdGUgcHJlcHJvY2Vzc2luZ0ZuOiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSBjbGFzc2lmaWNhdGlvbkZuOiBGdW5jdGlvbjtcbiAgcHJpdmF0ZSBwcm9jZXNzaW5nRm46IEZ1bmN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBhbnksIGlkOiBzdHJpbmcsIHByb3BzOiBhbnkpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMucHJlcHJvY2Vzc2luZ0ZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdQcmVwcm9jZXNzaW5nRm4nLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKGBcbiAgICAgICAgZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHtcbiAgICAgICAgICBjdXN0b21GaWVsZDE6ICd2YWx1ZTEnLFxuICAgICAgICAgIGN1c3RvbUZpZWxkMjogeyBuZXN0ZWQ6ICdkYXRhJyB9LFxuICAgICAgICAgIGN1c3RvbUZpZWxkMzogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIGApLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jbGFzc2lmaWNhdGlvbkZuID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdDbGFzc2lmaWNhdGlvbkZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgZG9jdW1lbnRDbGFzc2lmaWNhdGlvbjogXCJURVNUXCIgfSk7JyksXG4gICAgfSk7XG5cbiAgICB0aGlzLnByb2Nlc3NpbmdGbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnUHJvY2Vzc2luZ0ZuJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjBfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZSgnZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4gKHsgcmVzdWx0OiB7fSB9KTsnKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwcmVwcm9jZXNzaW5nU3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIG5ldyBMYW1iZGFJbnZva2UodGhpcywgJ01vY2tQcmVwcm9jZXNzaW5nJywge1xuICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMucHJlcHJvY2Vzc2luZ0ZuLFxuICAgICAgcmVzdWx0UGF0aDogJyQucHJlcHJvY2Vzc2luZ1Jlc3VsdCcsXG4gICAgfSk7XG4gIH1cblxuICAvLyBPdmVycmlkZSB0byBhZGQgY3VzdG9tIG1ldGFkYXRhIGZpZWxkc1xuICBwcm90ZWN0ZWQgcHJlcHJvY2Vzc2luZ01ldGFkYXRhKCk6IFJlY29yZDxzdHJpbmcsIER5bmFtb0F0dHJpYnV0ZVZhbHVlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEN1c3RvbUZpZWxkMTogRHluYW1vQXR0cmlidXRlVmFsdWUuZnJvbVN0cmluZyhKc29uUGF0aC5zdHJpbmdBdCgnJC5wcmVwcm9jZXNzaW5nUmVzdWx0LmN1c3RvbUZpZWxkMScpKSxcbiAgICAgIEN1c3RvbUZpZWxkMjogRHluYW1vQXR0cmlidXRlVmFsdWUuZnJvbVN0cmluZyhKc29uUGF0aC5qc29uVG9TdHJpbmcoSnNvblBhdGgub2JqZWN0QXQoJyQucHJlcHJvY2Vzc2luZ1Jlc3VsdC5jdXN0b21GaWVsZDInKSkpLFxuICAgICAgQ3VzdG9tRmllbGQzOiBEeW5hbW9BdHRyaWJ1dGVWYWx1ZS5ib29sZWFuRnJvbUpzb25QYXRoKEpzb25QYXRoLnN0cmluZ0F0KCckLnByZXByb2Nlc3NpbmdSZXN1bHQuY3VzdG9tRmllbGQzJykpLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xhc3NpZmljYXRpb25TdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHtcbiAgICByZXR1cm4gbmV3IExhbWJkYUludm9rZSh0aGlzLCAnTW9ja0NsYXNzaWZpY2F0aW9uJywge1xuICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMuY2xhc3NpZmljYXRpb25GbixcbiAgICAgIHJlc3VsdFBhdGg6ICckLmNsYXNzaWZpY2F0aW9uUmVzdWx0JyxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwcm9jZXNzaW5nU3RlcCgpOiBEb2N1bWVudFByb2Nlc3NpbmdTdGVwVHlwZSB7XG4gICAgcmV0dXJuIG5ldyBMYW1iZGFJbnZva2UodGhpcywgJ01vY2tQcm9jZXNzaW5nJywge1xuICAgICAgbGFtYmRhRnVuY3Rpb246IHRoaXMucHJvY2Vzc2luZ0ZuLFxuICAgICAgcmVzdWx0UGF0aDogJyQucHJvY2Vzc2luZ1Jlc3VsdCcsXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZW5yaWNobWVudFN0ZXAoKTogRG9jdW1lbnRQcm9jZXNzaW5nU3RlcFR5cGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgcG9zdFByb2Nlc3NpbmdTdGVwKCk6IERvY3VtZW50UHJvY2Vzc2luZ1N0ZXBUeXBlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVByb2Nlc3NpbmdXb3JrZmxvdygpIHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVTdGFuZGFyZFByb2Nlc3NpbmdXb3JrZmxvdygpO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZVN0YXRlTWFjaGluZSgpIHtcbiAgICByZXR1cm4gdGhpcy5oYW5kbGVTdGF0ZU1hY2hpbmVDcmVhdGlvbigndGVzdC1zdGF0ZS1tYWNoaW5lLXdpdGgtY3VzdG9tLW1ldGFkYXRhJyk7XG4gIH1cbn1cblxuZGVzY3JpYmUoJ0Jhc2VEb2N1bWVudFByb2Nlc3NpbmcgLSBEeW5hbW9EQiBTY2hlbWEgRXh0ZW5zaW9uIE1lY2hhbmlzbScsICgpID0+IHtcbiAgbGV0IGFwcDogQXBwO1xuICBsZXQgc3RhY2tXaXRob3V0UHJlcHJvY2Vzc2luZzogU3RhY2s7XG4gIGxldCBzdGFja1dpdGhDdXN0b21NZXRhZGF0YTogU3RhY2s7XG4gIGxldCB0ZW1wbGF0ZVdpdGhvdXRQcmVwcm9jZXNzaW5nOiBUZW1wbGF0ZTtcbiAgbGV0IHRlbXBsYXRlV2l0aEN1c3RvbU1ldGFkYXRhOiBUZW1wbGF0ZTtcblxuICBiZWZvcmVBbGwoKCkgPT4ge1xuICAgIC8vIFVzZSBjcmVhdGVUZXN0QXBwKCkgdG8gc2tpcCBidW5kbGluZyBhbmQgc3BlZWQgdXAgdGVzdHNcbiAgICBhcHAgPSBjcmVhdGVUZXN0QXBwKCk7XG5cbiAgICAvLyBTdGFjayB3aXRob3V0IHByZXByb2Nlc3NpbmcgKGJhY2t3YXJkIGNvbXBhdGlibGUpXG4gICAgc3RhY2tXaXRob3V0UHJlcHJvY2Vzc2luZyA9IG5ldyBTdGFjayhhcHAsICdXaXRob3V0UHJlcHJvY2Vzc2luZ1N0YWNrJyk7XG4gICAgY29uc3QgY29uc3RydWN0V2l0aG91dFByZXByb2Nlc3NpbmcgPSBuZXcgVGVzdERvY3VtZW50UHJvY2Vzc2luZ1dpdGhvdXRQcmVwcm9jZXNzaW5nKFxuICAgICAgc3RhY2tXaXRob3V0UHJlcHJvY2Vzc2luZyxcbiAgICAgICdUZXN0V2l0aG91dFByZXByb2Nlc3NpbmcnLFxuICAgICAge30sXG4gICAgKTtcbiAgICBjb25zdHJ1Y3RXaXRob3V0UHJlcHJvY2Vzc2luZy5jcmVhdGVTdGF0ZU1hY2hpbmUoKTtcblxuICAgIC8vIFN0YWNrIHdpdGggY3VzdG9tIG1ldGFkYXRhXG4gICAgc3RhY2tXaXRoQ3VzdG9tTWV0YWRhdGEgPSBuZXcgU3RhY2soYXBwLCAnV2l0aEN1c3RvbU1ldGFkYXRhU3RhY2snKTtcbiAgICBjb25zdCBjb25zdHJ1Y3RXaXRoQ3VzdG9tTWV0YWRhdGEgPSBuZXcgVGVzdERvY3VtZW50UHJvY2Vzc2luZ1dpdGhDdXN0b21NZXRhZGF0YShcbiAgICAgIHN0YWNrV2l0aEN1c3RvbU1ldGFkYXRhLFxuICAgICAgJ1Rlc3RXaXRoQ3VzdG9tTWV0YWRhdGEnLFxuICAgICAge30sXG4gICAgKTtcbiAgICBjb25zdHJ1Y3RXaXRoQ3VzdG9tTWV0YWRhdGEuY3JlYXRlU3RhdGVNYWNoaW5lKCk7XG5cbiAgICAvLyBHZW5lcmF0ZSB0ZW1wbGF0ZXNcbiAgICB0ZW1wbGF0ZVdpdGhvdXRQcmVwcm9jZXNzaW5nID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrV2l0aG91dFByZXByb2Nlc3NpbmcpO1xuICAgIHRlbXBsYXRlV2l0aEN1c3RvbU1ldGFkYXRhID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrV2l0aEN1c3RvbU1ldGFkYXRhKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0JhY2t3YXJkIENvbXBhdGliaWxpdHkgLSBEb2N1bWVudHMgd2l0aG91dCBwcmVwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgIHRlc3QoJ0luaXRNZXRhZGF0YSBvbmx5IGluY2x1ZGVzIGJhc2UgZmllbGRzIHdoZW4gbm8gcHJlcHJvY2Vzc2luZycsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZXMgPSB0ZW1wbGF0ZVdpdGhvdXRQcmVwcm9jZXNzaW5nLmZpbmRSZXNvdXJjZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJyk7XG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVLZXkgPSBPYmplY3Qua2V5cyhzdGF0ZU1hY2hpbmVzKVswXTtcbiAgICAgIGNvbnN0IGRlZmluaXRpb25TdHJpbmcgPSBzdGF0ZU1hY2hpbmVzW3N0YXRlTWFjaGluZUtleV0uUHJvcGVydGllcy5EZWZpbml0aW9uU3RyaW5nO1xuXG4gICAgICAvLyBQYXJzZSB0aGUgZGVmaW5pdGlvblxuICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IEpTT04ucGFyc2UoZGVmaW5pdGlvblN0cmluZ1snRm46OkpvaW4nXVsxXS5qb2luKCcnKSk7XG5cbiAgICAgIC8vIEZpbmQgdGhlIEluaXRNZXRhZGF0YUVudHJ5IHN0YXRlIGJ5IG5hbWVcbiAgICAgIGNvbnN0IGluaXRNZXRhZGF0YVN0YXRlID0gZGVmaW5pdGlvbi5TdGF0ZXMuSW5pdE1ldGFkYXRhRW50cnk7XG5cbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5UeXBlKS50b0JlKCdUYXNrJyk7XG5cbiAgICAgIC8vIFZlcmlmeSBiYXNlIGZpZWxkcyBhcmUgcHJlc2VudFxuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5Eb2N1bWVudElkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5Db250ZW50VHlwZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uQ29udGVudCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uV29ya2Zsb3dTdGF0dXMpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLlN0YXRlTWFjaGluZUV4ZWNJZCkudG9CZURlZmluZWQoKTtcblxuICAgICAgLy8gVmVyaWZ5IE5PIGN1c3RvbSBmaWVsZHMgYXJlIHByZXNlbnQgKGJhY2t3YXJkIGNvbXBhdGliaWxpdHkpXG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLkN1c3RvbUZpZWxkMSkudG9CZVVuZGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5DdXN0b21GaWVsZDIpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uQ3VzdG9tRmllbGQzKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCd3b3JrZmxvdyBzdGFydHMgd2l0aCBJbml0TWV0YWRhdGEgd2hlbiBubyBwcmVwcm9jZXNzaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGVNYWNoaW5lcyA9IHRlbXBsYXRlV2l0aG91dFByZXByb2Nlc3NpbmcuZmluZFJlc291cmNlcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnKTtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZUtleSA9IE9iamVjdC5rZXlzKHN0YXRlTWFjaGluZXMpWzBdO1xuICAgICAgY29uc3QgZGVmaW5pdGlvblN0cmluZyA9IHN0YXRlTWFjaGluZXNbc3RhdGVNYWNoaW5lS2V5XS5Qcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmc7XG5cbiAgICAgIGNvbnN0IGRlZmluaXRpb24gPSBKU09OLnBhcnNlKGRlZmluaXRpb25TdHJpbmdbJ0ZuOjpKb2luJ11bMV0uam9pbignJykpO1xuXG4gICAgICAvLyBTaG91bGQgc3RhcnQgd2l0aCBJbml0TWV0YWRhdGEgd2hlbiBubyBwcmVwcm9jZXNzaW5nXG4gICAgICBleHBlY3QoZGVmaW5pdGlvbi5TdGFydEF0KS50b01hdGNoKC9Jbml0TWV0YWRhdGEvKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ0R5bmFtb0RCIHRhYmxlIHNjaGVtYSByZW1haW5zIHVuY2hhbmdlZCcsICgpID0+IHtcbiAgICAgIC8vIFZlcmlmeSB0YWJsZSBpcyBjcmVhdGVkIHdpdGggc2FtZSBzY2hlbWEgYXMgYmVmb3JlXG4gICAgICB0ZW1wbGF0ZVdpdGhvdXRQcmVwcm9jZXNzaW5nLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpEeW5hbW9EQjo6VGFibGUnLCB7XG4gICAgICAgIEtleVNjaGVtYTogW3tcbiAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiAnRG9jdW1lbnRJZCcsXG4gICAgICAgICAgS2V5VHlwZTogJ0hBU0gnLFxuICAgICAgICB9XSxcbiAgICAgICAgQmlsbGluZ01vZGU6ICdQQVlfUEVSX1JFUVVFU1QnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTY2hlbWEgRXh0ZW5zaW9uIE1lY2hhbmlzbSAtIEdlbmVyaWMgcHJlcHJvY2Vzc2luZyBtZXRhZGF0YScsICgpID0+IHtcbiAgICB0ZXN0KCdwcmVwcm9jZXNzaW5nTWV0YWRhdGEoKSBob29rIGFsbG93cyBzdWJjbGFzc2VzIHRvIGV4dGVuZCBzY2hlbWEnLCAoKSA9PiB7XG4gICAgICAvLyBUaGUga2V5IGRlc2lnbiBwcmluY2lwbGU6IHN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHByZXByb2Nlc3NpbmdNZXRhZGF0YSgpXG4gICAgICAvLyB0byBhZGQgdGhlaXIgb3duIGZpZWxkcyB0byBJbml0TWV0YWRhdGEgd2l0aG91dCBiYXNlIGNsYXNzIGtub3dpbmcgdGhlIGRldGFpbHNcblxuICAgICAgLy8gVmVyaWZ5IHRoZSBjb25zdHJ1Y3Qgd2l0aCBjdXN0b20gbWV0YWRhdGEgd2FzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5XG4gICAgICBleHBlY3Qoc3RhY2tXaXRoQ3VzdG9tTWV0YWRhdGEpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICAgIC8vIFZlcmlmeSBpdCBoYXMgYSBzdGF0ZSBtYWNoaW5lXG4gICAgICB0ZW1wbGF0ZVdpdGhDdXN0b21NZXRhZGF0YS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJywgMSk7XG5cbiAgICAgIC8vIFZlcmlmeSBpdCBoYXMgdGhlIHNhbWUgRHluYW1vREIgdGFibGUgc3RydWN0dXJlIGFzIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uXG4gICAgICB0ZW1wbGF0ZVdpdGhDdXN0b21NZXRhZGF0YS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RHluYW1vREI6OlRhYmxlJywge1xuICAgICAgICBLZXlTY2hlbWE6IFt7XG4gICAgICAgICAgQXR0cmlidXRlTmFtZTogJ0RvY3VtZW50SWQnLFxuICAgICAgICAgIEtleVR5cGU6ICdIQVNIJyxcbiAgICAgICAgfV0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3dvcmtmbG93IGluY2x1ZGVzIHByZXByb2Nlc3Npbmcgc3RlcCB3aGVuIHByb3ZpZGVkJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RhdGVNYWNoaW5lcyA9IHRlbXBsYXRlV2l0aEN1c3RvbU1ldGFkYXRhLmZpbmRSZXNvdXJjZXMoJ0FXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lJyk7XG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVLZXkgPSBPYmplY3Qua2V5cyhzdGF0ZU1hY2hpbmVzKVswXTtcbiAgICAgIGNvbnN0IGRlZmluaXRpb25TdHJpbmcgPSBzdGF0ZU1hY2hpbmVzW3N0YXRlTWFjaGluZUtleV0uUHJvcGVydGllcy5EZWZpbml0aW9uU3RyaW5nO1xuXG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gSlNPTi5wYXJzZShkZWZpbml0aW9uU3RyaW5nWydGbjo6Sm9pbiddWzFdLmpvaW4oJycpKTtcblxuICAgICAgLy8gVmVyaWZ5IEluaXRNZXRhZGF0YSBzdGVwIGV4aXN0cyAoY29yZSBmdW5jdGlvbmFsaXR5KVxuICAgICAgZXhwZWN0KGRlZmluaXRpb24uU3RhdGVzLkluaXRNZXRhZGF0YUVudHJ5KS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICAvLyBXaGVuIHByZXByb2Nlc3NpbmcgaXMgcHJvdmlkZWQsIGl0IHNob3VsZCBiZSBpbiB0aGUgd29ya2Zsb3dcbiAgICAgIC8vIFRoZSBleGFjdCBzdHJ1Y3R1cmUgZGVwZW5kcyBvbiB0aGUgc3ViY2xhc3MgaW1wbGVtZW50YXRpb25cbiAgICAgIGV4cGVjdChkZWZpbml0aW9uLlN0YXRlcykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhkZWZpbml0aW9uLlN0YXRlcykubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdJbml0TWV0YWRhdGEgY2FuIGFjY2VwdCBhZGRpdGlvbmFsIGZpZWxkcyB2aWEgcHJlcHJvY2Vzc2luZ01ldGFkYXRhKCknLCAoKSA9PiB7XG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVzID0gdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEuZmluZFJlc291cmNlcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnKTtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZUtleSA9IE9iamVjdC5rZXlzKHN0YXRlTWFjaGluZXMpWzBdO1xuICAgICAgY29uc3QgZGVmaW5pdGlvblN0cmluZyA9IHN0YXRlTWFjaGluZXNbc3RhdGVNYWNoaW5lS2V5XS5Qcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmc7XG5cbiAgICAgIGNvbnN0IGRlZmluaXRpb24gPSBKU09OLnBhcnNlKGRlZmluaXRpb25TdHJpbmdbJ0ZuOjpKb2luJ11bMV0uam9pbignJykpO1xuXG4gICAgICBjb25zdCBpbml0TWV0YWRhdGFTdGF0ZSA9IGRlZmluaXRpb24uU3RhdGVzLkluaXRNZXRhZGF0YUVudHJ5O1xuXG4gICAgICAvLyBWZXJpZnkgYmFzZSBmaWVsZHMgYXJlIGFsd2F5cyBwcmVzZW50XG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLkRvY3VtZW50SWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLkNvbnRlbnRUeXBlKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5Db250ZW50KS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5Xb3JrZmxvd1N0YXR1cykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uU3RhdGVNYWNoaW5lRXhlY0lkKS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICAvLyBUaGUgbWVjaGFuaXNtIGFsbG93cyBhZGRpbmcgY3VzdG9tIGZpZWxkcyAoaW1wbGVtZW50YXRpb24gZGV0YWlsIG9mIHN1YmNsYXNzKVxuICAgICAgLy8gRHluYW1vREIncyBzY2hlbWFsZXNzIG5hdHVyZSBtZWFucyBhbnkgZmllbGRzIGNhbiBiZSBhZGRlZCBhdCBydW50aW1lXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTY2hlbWEgQ29tcGF0aWJpbGl0eScsICgpID0+IHtcbiAgICB0ZXN0KCdib3RoIGltcGxlbWVudGF0aW9ucyB1c2UgdGhlIHNhbWUgRHluYW1vREIgdGFibGUgc3RydWN0dXJlJywgKCkgPT4ge1xuICAgICAgLy8gQm90aCBzaG91bGQgY3JlYXRlIHRhYmxlcyB3aXRoIHNhbWUgcGFydGl0aW9uIGtleVxuICAgICAgdGVtcGxhdGVXaXRob3V0UHJlcHJvY2Vzc2luZy5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RHluYW1vREI6OlRhYmxlJywge1xuICAgICAgICBLZXlTY2hlbWE6IFt7XG4gICAgICAgICAgQXR0cmlidXRlTmFtZTogJ0RvY3VtZW50SWQnLFxuICAgICAgICAgIEtleVR5cGU6ICdIQVNIJyxcbiAgICAgICAgfV0sXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbe1xuICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6ICdEb2N1bWVudElkJyxcbiAgICAgICAgICBLZXlUeXBlOiAnSEFTSCcsXG4gICAgICAgIH1dLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdib3RoIGltcGxlbWVudGF0aW9ucyBjcmVhdGUgZW5jcnlwdGVkIHRhYmxlcycsICgpID0+IHtcbiAgICAgIHRlbXBsYXRlV2l0aG91dFByZXByb2Nlc3NpbmcuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHtcbiAgICAgICAgU1NFU3BlY2lmaWNhdGlvbjoge1xuICAgICAgICAgIFNTRUVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgU1NFVHlwZTogJ0tNUycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHtcbiAgICAgICAgU1NFU3BlY2lmaWNhdGlvbjoge1xuICAgICAgICAgIFNTRUVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgU1NFVHlwZTogJ0tNUycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2JvdGggaW1wbGVtZW50YXRpb25zIHVzZSBQQVlfUEVSX1JFUVVFU1QgYmlsbGluZycsICgpID0+IHtcbiAgICAgIHRlbXBsYXRlV2l0aG91dFByZXByb2Nlc3NpbmcuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHtcbiAgICAgICAgQmlsbGluZ01vZGU6ICdQQVlfUEVSX1JFUVVFU1QnLFxuICAgICAgfSk7XG5cbiAgICAgIHRlbXBsYXRlV2l0aEN1c3RvbU1ldGFkYXRhLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpEeW5hbW9EQjo6VGFibGUnLCB7XG4gICAgICAgIEJpbGxpbmdNb2RlOiAnUEFZX1BFUl9SRVFVRVNUJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRGVzaWduIFByaW5jaXBsZTogQmFzZSBjbGFzcyBoYXMgbm8ga25vd2xlZGdlIG9mIHByZXByb2Nlc3Npbmcgc3BlY2lmaWNzJywgKCkgPT4ge1xuICAgIHRlc3QoJ2Jhc2UgY2xhc3MgcHJvdmlkZXMgZ2VuZXJpYyBleHRlbnNpb24gbWVjaGFuaXNtIHZpYSBwcmVwcm9jZXNzaW5nTWV0YWRhdGEoKScsICgpID0+IHtcbiAgICAgIC8vIFRoaXMgdGVzdCB2ZXJpZmllcyB0aGUgZGVzaWduIHByaW5jaXBsZTpcbiAgICAgIC8vIC0gQmFzZSBjbGFzcyBkb2Vzbid0IGtub3cgYWJvdXQgY2h1bmtpbmcsIHZhbGlkYXRpb24sIG9yIGFueSBzcGVjaWZpYyBwcmVwcm9jZXNzaW5nXG4gICAgICAvLyAtIEJhc2UgY2xhc3Mgb25seSBwcm92aWRlcyBhIGhvb2sgKHByZXByb2Nlc3NpbmdNZXRhZGF0YSkgZm9yIHN1YmNsYXNzZXMgdG8gZXh0ZW5kXG4gICAgICAvLyAtIFN1YmNsYXNzZXMgYXJlIHJlc3BvbnNpYmxlIGZvciB0aGVpciBvd24gbWV0YWRhdGEgZmllbGRzXG5cbiAgICAgIC8vIFZlcmlmeSB0aGF0IHdpdGhvdXQgb3ZlcnJpZGluZyBwcmVwcm9jZXNzaW5nTWV0YWRhdGEoKSwgd29ya2Zsb3cgd29ya3MgY29ycmVjdGx5XG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVzID0gdGVtcGxhdGVXaXRob3V0UHJlcHJvY2Vzc2luZy5maW5kUmVzb3VyY2VzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScpO1xuICAgICAgY29uc3Qgc3RhdGVNYWNoaW5lS2V5ID0gT2JqZWN0LmtleXMoc3RhdGVNYWNoaW5lcylbMF07XG4gICAgICBjb25zdCBkZWZpbml0aW9uU3RyaW5nID0gc3RhdGVNYWNoaW5lc1tzdGF0ZU1hY2hpbmVLZXldLlByb3BlcnRpZXMuRGVmaW5pdGlvblN0cmluZztcbiAgICAgIGNvbnN0IGRlZmluaXRpb24gPSBKU09OLnBhcnNlKGRlZmluaXRpb25TdHJpbmdbJ0ZuOjpKb2luJ11bMV0uam9pbignJykpO1xuXG4gICAgICBjb25zdCBpbml0TWV0YWRhdGFTdGF0ZSA9IGRlZmluaXRpb24uU3RhdGVzLkluaXRNZXRhZGF0YUVudHJ5O1xuXG4gICAgICAvLyBCYXNlIGZpZWxkcyBhcmUgYWx3YXlzIHByZXNlbnRcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uRG9jdW1lbnRJZCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChpbml0TWV0YWRhdGFTdGF0ZS5QYXJhbWV0ZXJzLkl0ZW0uQ29udGVudFR5cGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLkNvbnRlbnQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoaW5pdE1ldGFkYXRhU3RhdGUuUGFyYW1ldGVycy5JdGVtLldvcmtmbG93U3RhdHVzKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGluaXRNZXRhZGF0YVN0YXRlLlBhcmFtZXRlcnMuSXRlbS5TdGF0ZU1hY2hpbmVFeGVjSWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdWJjbGFzc2VzIGNhbiBleHRlbmQgdmlhIHByZXByb2Nlc3NpbmdNZXRhZGF0YSgpIHdpdGhvdXQgYnJlYWtpbmcgYmFzZSBmdW5jdGlvbmFsaXR5JywgKCkgPT4ge1xuICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGNvbnN0cnVjdCB3aXRoIGN1c3RvbSBtZXRhZGF0YSBzdGlsbCBoYXMgYWxsIGJhc2UgZnVuY3Rpb25hbGl0eVxuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEucmVzb3VyY2VDb3VudElzKCdBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZScsIDEpO1xuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEucmVzb3VyY2VDb3VudElzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIDEpO1xuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEucmVzb3VyY2VDb3VudElzKCdBV1M6OlMzOjpCdWNrZXQnLCAxKTtcblxuICAgICAgLy8gVmVyaWZ5IHN0YXRlIG1hY2hpbmUgaGFzIHRoZSBzYW1lIGJhc2Ugc3RydWN0dXJlXG4gICAgICBjb25zdCBzdGF0ZU1hY2hpbmVzID0gdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEuZmluZFJlc291cmNlcygnQVdTOjpTdGVwRnVuY3Rpb25zOjpTdGF0ZU1hY2hpbmUnKTtcbiAgICAgIGNvbnN0IHN0YXRlTWFjaGluZUtleSA9IE9iamVjdC5rZXlzKHN0YXRlTWFjaGluZXMpWzBdO1xuICAgICAgY29uc3QgZGVmaW5pdGlvblN0cmluZyA9IHN0YXRlTWFjaGluZXNbc3RhdGVNYWNoaW5lS2V5XS5Qcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmc7XG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gSlNPTi5wYXJzZShkZWZpbml0aW9uU3RyaW5nWydGbjo6Sm9pbiddWzFdLmpvaW4oJycpKTtcblxuICAgICAgLy8gQ29yZSBzdGF0ZXMgc2hvdWxkIGV4aXN0XG4gICAgICBleHBlY3QoZGVmaW5pdGlvbi5TdGF0ZXMuSW5pdE1ldGFkYXRhRW50cnkpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoZGVmaW5pdGlvbi5TdGF0ZXMuTW9ja0NsYXNzaWZpY2F0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGRlZmluaXRpb24uU3RhdGVzLk1vY2tQcm9jZXNzaW5nKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRHluYW1vREIgc2NoZW1hbGVzcyBuYXR1cmUgc3VwcG9ydHMgcnVudGltZSBmaWVsZCBhZGRpdGlvbicsICgpID0+IHtcbiAgICB0ZXN0KCdEeW5hbW9EQiB0YWJsZSBzdXBwb3J0cyBhbnkgYWRkaXRpb25hbCBmaWVsZHMgYXQgcnVudGltZScsICgpID0+IHtcbiAgICAgIC8vIER5bmFtb0RCIGlzIHNjaGVtYWxlc3MsIHNvIGFueSBmaWVsZHMgY2FuIGJlIGFkZGVkIGF0IHJ1bnRpbWVcbiAgICAgIC8vIFRoaXMgdGVzdCB2ZXJpZmllcyB0aGUgdGFibGUgaXMgY3JlYXRlZCBjb3JyZWN0bHkgYW5kIGNhbiBhY2NlcHQgYW55IGF0dHJpYnV0ZXNcblxuICAgICAgdGVtcGxhdGVXaXRoQ3VzdG9tTWV0YWRhdGEuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkR5bmFtb0RCOjpUYWJsZScsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbe1xuICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6ICdEb2N1bWVudElkJyxcbiAgICAgICAgICBLZXlUeXBlOiAnSEFTSCcsXG4gICAgICAgIH1dLFxuICAgICAgICBCaWxsaW5nTW9kZTogJ1BBWV9QRVJfUkVRVUVTVCcsXG4gICAgICB9KTtcblxuICAgICAgLy8gTm8gYXR0cmlidXRlIGRlZmluaXRpb25zIG5lZWRlZCBmb3Igbm9uLWtleSBhdHRyaWJ1dGVzIGluIER5bmFtb0RCXG4gICAgICAvLyBGaWVsZHMgbGlrZSBBZ2dyZWdhdGVkUmVzdWx0IGNhbiBiZSBhZGRlZCB2aWEgRHluYW1vVXBkYXRlSXRlbSBkdXJpbmcgcHJvY2Vzc2luZ1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc3RhdGUgbWFjaGluZSBoYXMgcGVybWlzc2lvbnMgdG8gdXBkYXRlIER5bmFtb0RCIGl0ZW1zJywgKCkgPT4ge1xuICAgICAgLy8gVmVyaWZ5IHRoZSBzdGF0ZSBtYWNoaW5lIHJvbGUgaGFzIFVwZGF0ZUl0ZW0gcGVybWlzc2lvbnNcbiAgICAgIC8vIFRoaXMgYWxsb3dzIGFkZGluZyBmaWVsZHMgbGlrZSBBZ2dyZWdhdGVkUmVzdWx0IGR1cmluZyBwcm9jZXNzaW5nXG4gICAgICBjb25zdCBwb2xpY2llcyA9IHRlbXBsYXRlV2l0aEN1c3RvbU1ldGFkYXRhLmZpbmRSZXNvdXJjZXMoJ0FXUzo6SUFNOjpQb2xpY3knKTtcblxuICAgICAgLy8gRmluZCB0aGUgc3RhdGUgbWFjaGluZSByb2xlIHBvbGljeVxuICAgICAgY29uc3Qgc3RhdGVNYWNoaW5lUG9saWN5ID0gT2JqZWN0LnZhbHVlcyhwb2xpY2llcykuZmluZCgocG9saWN5OiBhbnkpID0+XG4gICAgICAgIHBvbGljeS5Qcm9wZXJ0aWVzLlBvbGljeU5hbWUuaW5jbHVkZXMoJ1N0YXRlTWFjaGluZVJvbGUnKSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChzdGF0ZU1hY2hpbmVQb2xpY3kpLnRvQmVEZWZpbmVkKCk7XG5cbiAgICAgIC8vIENoZWNrIHRoYXQgaXQgaGFzIER5bmFtb0RCIFVwZGF0ZUl0ZW0gcGVybWlzc2lvbnNcbiAgICAgIGNvbnN0IHN0YXRlbWVudHMgPSAoc3RhdGVNYWNoaW5lUG9saWN5IGFzIGFueSkuUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudC5TdGF0ZW1lbnQ7XG4gICAgICBjb25zdCBkeW5hbW9TdGF0ZW1lbnQgPSBzdGF0ZW1lbnRzLmZpbmQoKHN0bXQ6IGFueSkgPT5cbiAgICAgICAgc3RtdC5BY3Rpb24gJiYgKFxuICAgICAgICAgIChBcnJheS5pc0FycmF5KHN0bXQuQWN0aW9uKSAmJiBzdG10LkFjdGlvbi5pbmNsdWRlcygnZHluYW1vZGI6VXBkYXRlSXRlbScpKSB8fFxuICAgICAgICAgIHN0bXQuQWN0aW9uID09PSAnZHluYW1vZGI6VXBkYXRlSXRlbSdcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChkeW5hbW9TdGF0ZW1lbnQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoZHluYW1vU3RhdGVtZW50LkVmZmVjdCkudG9CZSgnQWxsb3cnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==