cdk-nextjs 0.6.1 → 0.7.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 (266) hide show
  1. package/.jsii +2467 -2714
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1725 -1909
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +152 -170
  7. package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
  8. package/docs/adapter-runtime.md +185 -0
  9. package/docs/breaking-changes.md +687 -4
  10. package/docs/caching-guide.md +156 -112
  11. package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
  12. package/docs/development-guide.md +1 -1
  13. package/docs/harness-coverage.md +598 -0
  14. package/docs/init-cache-deployment.md +32 -1
  15. package/docs/next-build-output-guide.md +30 -20
  16. package/examples/README.md +5 -1
  17. package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
  18. package/lib/adapter/__fixtures__/app-playground.json +4917 -0
  19. package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
  20. package/lib/adapter/adapter.mjs +1548 -185
  21. package/lib/adapter/adapter.test.js +106 -0
  22. package/lib/adapter/aws-cache-store.d.ts +489 -0
  23. package/lib/adapter/aws-cache-store.js +1004 -0
  24. package/lib/adapter/aws-cache-store.test.d.ts +1 -0
  25. package/lib/adapter/aws-cache-store.test.js +361 -0
  26. package/lib/adapter/build-outputs.d.ts +80 -0
  27. package/lib/adapter/build-outputs.js +852 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +861 -0
  30. package/lib/adapter/cache-handler.d.ts +9 -2
  31. package/lib/adapter/cache-handler.js +72 -96
  32. package/lib/adapter/cache-handler.mjs +18956 -17774
  33. package/lib/adapter/cache-handler.test.js +263 -31
  34. package/lib/adapter/cache-kinds.d.ts +32 -0
  35. package/lib/adapter/cache-kinds.js +35 -0
  36. package/lib/adapter/cache-kinds.test.d.ts +1 -0
  37. package/lib/adapter/cache-kinds.test.js +69 -0
  38. package/lib/adapter/cache-utils.d.ts +90 -0
  39. package/lib/adapter/cache-utils.js +199 -4
  40. package/lib/adapter/cache-utils.test.d.ts +1 -0
  41. package/lib/adapter/cache-utils.test.js +179 -0
  42. package/lib/adapter/function-groups.d.ts +215 -0
  43. package/lib/adapter/function-groups.js +1099 -0
  44. package/lib/adapter/function-groups.test.d.ts +1 -0
  45. package/lib/adapter/function-groups.test.js +743 -0
  46. package/lib/adapter/init-cache.d.ts +6 -0
  47. package/lib/adapter/init-cache.js +245 -0
  48. package/lib/adapter/init-cache.test.d.ts +1 -0
  49. package/lib/adapter/init-cache.test.js +137 -0
  50. package/lib/adapter/local-file-cache-handler.d.ts +23 -0
  51. package/lib/adapter/local-file-cache-handler.js +52 -1
  52. package/lib/adapter/memory-cache-handler.d.ts +26 -17
  53. package/lib/adapter/memory-cache-handler.js +32 -50
  54. package/lib/adapter/memory-cache-handler.test.js +105 -85
  55. package/lib/adapter/s3-cache-handler.d.ts +179 -40
  56. package/lib/adapter/s3-cache-handler.js +807 -277
  57. package/lib/adapter/s3-cache-handler.test.js +1186 -31
  58. package/lib/adapter/use-cache-common.d.ts +90 -0
  59. package/lib/adapter/use-cache-common.js +250 -0
  60. package/lib/adapter/use-cache-common.test.d.ts +1 -0
  61. package/lib/adapter/use-cache-common.test.js +646 -0
  62. package/lib/adapter/use-cache-default-handler.d.ts +24 -0
  63. package/lib/adapter/use-cache-default-handler.js +90 -0
  64. package/lib/adapter/use-cache-default-handler.mjs +38645 -0
  65. package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
  66. package/lib/adapter/use-cache-handlers.test.js +349 -0
  67. package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
  68. package/lib/adapter/use-cache-remote-handler.js +186 -0
  69. package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
  70. package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
  71. package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
  72. package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
  73. package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
  74. package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
  75. package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
  76. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
  77. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  78. package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +13 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +11 -2
  81. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
  82. package/lib/index.d.ts +6 -7
  83. package/lib/index.js +2 -4
  84. package/lib/lambdas/post-deploy/post-deploy.lambda.js +3 -2
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  88. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  92. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  93. package/lib/lambdas/post-deploy/prune-s3.d.ts +19 -3
  94. package/lib/lambdas/post-deploy/prune-s3.js +54 -15
  95. package/lib/lambdas/post-deploy/prune-s3.test.d.ts +1 -0
  96. package/lib/lambdas/post-deploy/prune-s3.test.js +255 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  103. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  104. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  105. package/lib/nextjs-api.d.ts +107 -18
  106. package/lib/nextjs-api.js +349 -39
  107. package/lib/nextjs-api.test.js +582 -1
  108. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  109. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  110. package/lib/nextjs-build/nextjs-build.js +684 -327
  111. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  112. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  113. package/lib/nextjs-build/patch-fetch.js +1 -1
  114. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  115. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  116. package/lib/nextjs-cache.d.ts +82 -4
  117. package/lib/nextjs-cache.js +186 -10
  118. package/lib/nextjs-cache.test.js +176 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  120. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  121. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  122. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  123. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  124. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  125. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  126. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  127. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  128. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  129. package/lib/nextjs-distribution.d.ts +194 -23
  130. package/lib/nextjs-distribution.js +535 -62
  131. package/lib/nextjs-distribution.test.d.ts +1 -0
  132. package/lib/nextjs-distribution.test.js +697 -0
  133. package/lib/nextjs-post-deploy.d.ts +23 -3
  134. package/lib/nextjs-post-deploy.js +14 -10
  135. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  136. package/lib/nextjs-post-deploy.test.js +34 -0
  137. package/lib/nextjs-static-assets.d.ts +23 -4
  138. package/lib/nextjs-static-assets.js +29 -6
  139. package/lib/nextjs-static-assets.test.js +20 -1
  140. package/lib/root-constructs/nextjs-base-construct.d.ts +105 -45
  141. package/lib/root-constructs/nextjs-base-construct.js +144 -34
  142. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  143. package/lib/root-constructs/nextjs-global-containers.js +20 -70
  144. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  145. package/lib/root-constructs/nextjs-global-functions.js +52 -69
  146. package/lib/root-constructs/nextjs-regional-containers.d.ts +25 -5
  147. package/lib/root-constructs/nextjs-regional-containers.js +17 -15
  148. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  149. package/lib/root-constructs/nextjs-regional-functions.js +8 -25
  150. package/lib/runtime/api-gateway-path.d.ts +34 -0
  151. package/lib/runtime/api-gateway-path.js +71 -0
  152. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  153. package/lib/runtime/api-gateway-path.test.js +65 -0
  154. package/lib/runtime/case-redirect.d.ts +22 -0
  155. package/lib/runtime/case-redirect.js +63 -0
  156. package/lib/runtime/case-redirect.test.d.ts +1 -0
  157. package/lib/runtime/case-redirect.test.js +32 -0
  158. package/lib/runtime/core.d.ts +234 -0
  159. package/lib/runtime/core.js +1213 -0
  160. package/lib/runtime/core.test.d.ts +1 -0
  161. package/lib/runtime/core.test.js +1678 -0
  162. package/lib/runtime/deployment-root.d.ts +13 -0
  163. package/lib/runtime/deployment-root.js +29 -0
  164. package/lib/runtime/dispatch.d.ts +331 -0
  165. package/lib/runtime/dispatch.js +751 -0
  166. package/lib/runtime/dispatch.test.d.ts +1 -0
  167. package/lib/runtime/dispatch.test.js +853 -0
  168. package/lib/runtime/entrypoints.d.ts +57 -0
  169. package/lib/runtime/entrypoints.js +115 -0
  170. package/lib/runtime/http/abort-signal.d.ts +6 -0
  171. package/lib/runtime/http/abort-signal.js +19 -0
  172. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  173. package/lib/runtime/http/abort-signal.test.js +49 -0
  174. package/lib/runtime/http/node-server.d.ts +38 -0
  175. package/lib/runtime/http/node-server.js +99 -0
  176. package/lib/runtime/http/node-server.test.d.ts +1 -0
  177. package/lib/runtime/http/node-server.test.js +96 -0
  178. package/lib/runtime/http/node-sink.d.ts +16 -0
  179. package/lib/runtime/http/node-sink.js +48 -0
  180. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  181. package/lib/runtime/http/node-sink.test.js +66 -0
  182. package/lib/runtime/http/request.d.ts +62 -0
  183. package/lib/runtime/http/request.js +134 -0
  184. package/lib/runtime/http/request.test.d.ts +1 -0
  185. package/lib/runtime/http/request.test.js +103 -0
  186. package/lib/runtime/http/response.d.ts +77 -0
  187. package/lib/runtime/http/response.js +229 -0
  188. package/lib/runtime/http/response.test.d.ts +1 -0
  189. package/lib/runtime/http/response.test.js +178 -0
  190. package/lib/runtime/http/sink.d.ts +73 -0
  191. package/lib/runtime/http/sink.js +188 -0
  192. package/lib/runtime/http/sink.test.d.ts +1 -0
  193. package/lib/runtime/http/sink.test.js +257 -0
  194. package/lib/runtime/image-utils.d.ts +78 -0
  195. package/lib/runtime/image-utils.js +129 -0
  196. package/lib/runtime/image-utils.test.d.ts +1 -0
  197. package/lib/runtime/image-utils.test.js +237 -0
  198. package/lib/runtime/image.d.ts +76 -0
  199. package/lib/runtime/image.js +296 -0
  200. package/lib/runtime/image.test.d.ts +1 -0
  201. package/lib/runtime/image.test.js +405 -0
  202. package/lib/runtime/lambda-event.d.ts +4 -0
  203. package/lib/runtime/lambda-event.js +113 -0
  204. package/lib/runtime/lambda-event.test.d.ts +1 -0
  205. package/lib/runtime/lambda-event.test.js +119 -0
  206. package/lib/runtime/lambda.mjs +41595 -0
  207. package/lib/runtime/load-module.d.ts +8 -0
  208. package/lib/runtime/load-module.js +35 -0
  209. package/lib/runtime/manifest.d.ts +215 -0
  210. package/lib/runtime/manifest.js +118 -0
  211. package/lib/runtime/middleware.d.ts +43 -0
  212. package/lib/runtime/middleware.js +113 -0
  213. package/lib/runtime/middleware.test.d.ts +1 -0
  214. package/lib/runtime/middleware.test.js +259 -0
  215. package/lib/runtime/next-modules.d.ts +55 -0
  216. package/lib/runtime/next-modules.js +124 -0
  217. package/lib/runtime/next-modules.test.d.ts +1 -0
  218. package/lib/runtime/next-modules.test.js +34 -0
  219. package/lib/runtime/public-files.d.ts +32 -0
  220. package/lib/runtime/public-files.js +117 -0
  221. package/lib/runtime/public-files.test.d.ts +1 -0
  222. package/lib/runtime/public-files.test.js +97 -0
  223. package/lib/runtime/server.mjs +41588 -0
  224. package/lib/runtime/static-files.d.ts +50 -0
  225. package/lib/runtime/static-files.js +266 -0
  226. package/lib/runtime/static-files.test.d.ts +1 -0
  227. package/lib/runtime/static-files.test.js +118 -0
  228. package/lib/runtime/util.d.ts +28 -0
  229. package/lib/runtime/util.js +79 -0
  230. package/lib/utils/base-path.d.ts +123 -11
  231. package/lib/utils/base-path.js +276 -39
  232. package/lib/utils/base-path.test.js +275 -50
  233. package/lib/utils/get-architecture.d.ts +7 -8
  234. package/lib/utils/get-architecture.js +12 -13
  235. package/lib/utils/zip-directory.d.ts +14 -0
  236. package/lib/utils/zip-directory.js +121 -0
  237. package/lib/utils/zip-directory.test.d.ts +1 -0
  238. package/lib/utils/zip-directory.test.js +99 -0
  239. package/package.json +22 -3
  240. package/scripts/capture-adapter-fixture.mjs +325 -0
  241. package/scripts/e2e-deploy.sh +398 -0
  242. package/scripts/e2e-harness/README.md +707 -0
  243. package/scripts/e2e-harness/app.js +370 -0
  244. package/scripts/e2e-harness/common.sh +249 -0
  245. package/scripts/e2e-harness/screen.mjs +302 -0
  246. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  247. package/scripts/e2e-harness/type-filters.mjs +47 -0
  248. package/scripts/e2e-logs.sh +75 -0
  249. package/scripts/e2e-offline.sh +91 -0
  250. package/scripts/e2e-sweep.sh +370 -0
  251. package/scripts/e2e-warm.sh +114 -0
  252. package/scripts/zero-config-build.mjs +418 -0
  253. package/docs/1k-concurrent-users-executions.png +0 -0
  254. package/docs/plans/adapter-runtime-release.md +0 -362
  255. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  256. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  257. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  258. package/lib/image-optimization/handler-utils.d.ts +0 -34
  259. package/lib/image-optimization/handler-utils.js +0 -83
  260. package/lib/image-optimization/handler-utils.test.js +0 -178
  261. package/lib/nextjs-build/functions.Dockerfile +0 -31
  262. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  263. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  264. package/lib/utils/experimental-flags.d.ts +0 -24
  265. package/lib/utils/experimental-flags.js +0 -30
  266. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -1,19 +1,92 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.NextjsCache = void 0;
4
37
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
38
  const fs_1 = require("fs");
39
+ const os_1 = require("os");
40
+ const path_1 = require("path");
6
41
  const aws_cdk_lib_1 = require("aws-cdk-lib");
7
42
  const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
8
43
  const aws_s3_1 = require("aws-cdk-lib/aws-s3");
9
44
  const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
45
+ const cxapi = __importStar(require("aws-cdk-lib/cx-api"));
10
46
  const constructs_1 = require("constructs");
11
47
  const constants_1 = require("./constants");
48
+ /** What a `BucketDeployment` Lambda gets without asking. */
49
+ const DEFAULT_EPHEMERAL_STORAGE_MIB = 512;
50
+ /** The most Lambda will give any function. */
51
+ const MAX_EPHEMERAL_STORAGE_MIB = 10240;
52
+ /**
53
+ * The smallest power-of-two MiB step at or above `mib`, capped at `max`.
54
+ *
55
+ * `BucketDeployment` folds `ephemeralStorageSize` into both its singleton
56
+ * handler's UUID and its custom resource's logical ID, so every distinct size is
57
+ * a new handler Lambda, a new `ServiceToken`, and a replaced custom resource.
58
+ * Sized to the MiB, that was every deploy whose init cache grew by one: a full
59
+ * CloudFormation deployment where a hotswap would have done. Doubling steps
60
+ * change only when the cache does by a large fraction.
61
+ */
62
+ function storageStep(mib, max) {
63
+ let step = DEFAULT_EPHEMERAL_STORAGE_MIB;
64
+ while (step < mib) {
65
+ step *= 2;
66
+ }
67
+ return Math.min(step, max);
68
+ }
69
+ /** Bytes on disk under `dir`, following the tree but not symlinks. */
70
+ function sizeOfDirectory(dir) {
71
+ let total = 0;
72
+ for (const entry of (0, fs_1.readdirSync)(dir, {
73
+ withFileTypes: true,
74
+ recursive: true,
75
+ })) {
76
+ if (entry.isFile()) {
77
+ // `parentPath` only exists from Node 20.12; `path` is its deprecated
78
+ // predecessor, and the only one on 20.9-20.11.
79
+ const parent = entry.parentPath ?? entry.path;
80
+ total += (0, fs_1.statSync)((0, path_1.join)(parent, entry.name)).size;
81
+ }
82
+ }
83
+ return total;
84
+ }
12
85
  /**
13
86
  * Next.js Cache construct providing unified S3 and DynamoDB cache management.
14
87
  */
15
88
  class NextjsCache extends constructs_1.Construct {
16
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsCache", version: "0.6.1" };
89
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsCache", version: "0.7.0" };
17
90
  cacheBucket;
18
91
  revalidationTable;
19
92
  buildId;
@@ -45,6 +118,9 @@ class NextjsCache extends constructs_1.Construct {
45
118
  /**
46
119
  * Creates DynamoDB table for revalidation metadata
47
120
  * Schema: pk (buildId or "METADATA"), sk (tag#cacheKey or "CURRENT_BUILD"), createdAt, revalidatedAt
121
+ *
122
+ * Also the `'use cache'` revalidation log (pk "<buildId>#log",
123
+ * sk "<epoch-ms>#<tag>"), whose rows expire through the `ttl` attribute.
48
124
  */
49
125
  createRevalidationTable() {
50
126
  const table = new aws_dynamodb_1.TableV2(this, "RevalidationTable", {
@@ -58,6 +134,7 @@ class NextjsCache extends constructs_1.Construct {
58
134
  },
59
135
  billing: aws_dynamodb_1.Billing.onDemand(),
60
136
  removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
137
+ timeToLiveAttribute: "ttl",
61
138
  ...this.props.overrides?.revalidationTableProps,
62
139
  });
63
140
  return table;
@@ -72,16 +149,115 @@ class NextjsCache extends constructs_1.Construct {
72
149
  return undefined;
73
150
  }
74
151
  console.log(`${constants_1.LOG_PREFIX} Deploying init cache from ${this.props.initCacheDir}`);
75
- // Use standard BucketDeployment for regular S3 buckets
76
- const bucketDeployment = new aws_s3_deployment_1.BucketDeployment(this, "InitCacheDeployment", {
77
- sources: [aws_s3_deployment_1.Source.asset(this.props.initCacheDir)],
78
- destinationBucket: this.cacheBucket,
79
- destinationKeyPrefix: this.props.buildId, // Add buildId prefix to all uploaded files
80
- prune: false, // Don't delete existing objects to prevent 404s during deployment, pruning will be handled by post-deploy
81
- ...this.props.overrides?.bucketDeploymentProps,
152
+ const stagingDir = this.createStagingDirectory();
153
+ try {
154
+ // Use standard BucketDeployment for regular S3 buckets
155
+ const bucketDeployment = new aws_s3_deployment_1.BucketDeployment(this, "InitCacheDeployment", {
156
+ sources: [aws_s3_deployment_1.Source.asset(stagingDir)],
157
+ destinationBucket: this.cacheBucket,
158
+ prune: false, // Don't delete existing objects to prevent 404s during deployment, pruning will be handled by post-deploy
159
+ ...this.sizeDeploymentLambda(),
160
+ ...this.props.overrides?.bucketDeploymentProps,
161
+ });
162
+ return bucketDeployment;
163
+ }
164
+ finally {
165
+ // `Source.asset` stages during `BucketDeployment`'s construction - CDK's
166
+ // `AssetStaging` zips into `cdk.out` from its own constructor - so the
167
+ // temporary copy is dead the moment that returns. Leaving it was a slow
168
+ // leak with a large unit: the init cache has been measured at 664 MiB, and
169
+ // every `cdk synth` left another full copy in the system temp directory,
170
+ // so a CI loop of ~22 deploys could put ~15 GB on the runner's disk.
171
+ //
172
+ // Unless staging is disabled (`cdk synth --no-staging`, and SAM, which
173
+ // sets the same context): then nothing is copied into `cdk.out`, the
174
+ // asset manifest points at this directory itself, and removing it fails
175
+ // the publish that follows the synth with ENOENT.
176
+ if (!this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT)) {
177
+ (0, fs_1.rmSync)(stagingDir, { recursive: true, force: true });
178
+ }
179
+ }
180
+ }
181
+ /**
182
+ * `/tmp` and memory for `BucketDeployment`'s unzip Lambda, scaled to the init
183
+ * cache it has to unpack.
184
+ *
185
+ * That Lambda downloads the asset zip into `/tmp` and then extracts it
186
+ * alongside, so it needs room for both at once. CDK defaults it to 512 MiB of
187
+ * ephemeral storage and 128 MB of memory — fine for a small app, and a hard
188
+ * failure for one whose prerendered payloads are large. A fixture with 60
189
+ * statically generated pages carrying ~1 MB of RSC each produced a 664 MiB
190
+ * seed directory and the handler died on
191
+ * `OSError: [Errno 28] No space left on device` inside `zip.extractall`.
192
+ * Worse, `cdk deploy --hotswap` invokes the custom resource directly with a
193
+ * placeholder response URL, so the `Status: FAILED` it sends goes nowhere: the
194
+ * CLI prints "Contents of AWS::S3::Bucket … hotswapped!", exits 0, and the app
195
+ * comes up serving a *partially* seeded cache. Every route whose entry did not
196
+ * make it is then a miss that re-renders — which, for a
197
+ * `cacheComponents: true` app, means a postponed shell where the prerender
198
+ * should have been.
199
+ *
200
+ * The zip's compressed size is not known at synth time (CDK archives the asset
201
+ * later), so the worst case — an incompressible payload — is what gets
202
+ * budgeted: twice the directory, plus headroom, rounded up to a
203
+ * {@link storageStep}. Memory is only raised past
204
+ * CDK's default for caches big enough that 128 MB's slice of a vCPU would make
205
+ * the unzip and upload race the custom resource's 15-minute timeout; small
206
+ * apps keep the cheaper default and their existing template.
207
+ *
208
+ * Above the 10 GiB ephemeral-storage ceiling there is nothing left to ask for,
209
+ * so this warns and lets the deployment fail loudly rather than pretend.
210
+ * `overrides.bucketDeploymentProps` wins over everything here, including
211
+ * `useEfs: true`, which is the supported way out.
212
+ */
213
+ sizeDeploymentLambda() {
214
+ const mib = Math.ceil(sizeOfDirectory(this.props.initCacheDir) / 1024 ** 2);
215
+ const wanted = mib * 2 + 128;
216
+ if (wanted > MAX_EPHEMERAL_STORAGE_MIB) {
217
+ console.warn(`${constants_1.LOG_PREFIX} The init cache at ${this.props.initCacheDir} is ${mib} MiB, which does not fit in the ${MAX_EPHEMERAL_STORAGE_MIB} MiB of ephemeral storage a BucketDeployment Lambda can be given. Pass overrides.bucketDeploymentProps with useEfs: true to seed a cache this large.`);
218
+ }
219
+ const ephemeral = storageStep(wanted, MAX_EPHEMERAL_STORAGE_MIB);
220
+ return {
221
+ ephemeralStorageSize: aws_cdk_lib_1.Size.mebibytes(ephemeral),
222
+ ...(mib > 256 ? { memoryLimit: 1024 } : {}),
223
+ };
224
+ }
225
+ /**
226
+ * Stage the init cache under a `buildId` directory, so that the objects land
227
+ * at `<buildId>/<key>` without a `destinationKeyPrefix`.
228
+ *
229
+ * The keys have to carry the build ID — that is how the runtime cache handler
230
+ * and the post-deploy pruner namespace one deployment's entries from the next
231
+ * (`src/adapter/s3-cache-handler.ts`). Asking `BucketDeployment` for it, as
232
+ * this used to, is what costs: it unconditionally tags the *destination
233
+ * bucket* with `aws-cdk:cr-owned:<destinationKeyPrefix>:<hash>`, so a prefix
234
+ * that changes per build makes the bucket's `Tags` change per build.
235
+ * `AWS::S3::Bucket` `Tags` are not hotswappable, so `cdk deploy
236
+ * --hotswap-fallback` rejected the diff and fell back to a full CloudFormation
237
+ * deployment every single time — measured at 19 of 22 deploys in one harness
238
+ * run, ~110s each against a ~52s hotswap.
239
+ *
240
+ * Putting the build ID in the asset's own paths instead leaves the S3 keys
241
+ * byte-identical and the tag key constant (`aws-cdk:cr-owned:<hash>`, derived
242
+ * from the construct path). Nothing else read the prefix: `prune` is already
243
+ * `false`, and the two handler branches that do scope work to it — emptying
244
+ * the prefix on delete, and deleting the old prefix when the destination
245
+ * changes — are both gated on `retainOnDelete`, which `BucketDeployment`
246
+ * defaults to `true`.
247
+ *
248
+ * A copy rather than the directory itself because the build ID is only known
249
+ * *after* `next build`, so the adapter cannot write into a nested directory in
250
+ * the first place, and because `.next/cdk-nextjs-init-cache` has to stay where
251
+ * it is for the local cache handler to read it (`CDK_NEXTJS_INIT_CACHE_DIR`).
252
+ * CDK is about to read every byte of this to zip it regardless.
253
+ */
254
+ createStagingDirectory() {
255
+ const stagingDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "nextjs-init-cache-"));
256
+ (0, fs_1.cpSync)(this.props.initCacheDir, (0, path_1.join)(stagingDir, this.props.buildId), {
257
+ recursive: true,
82
258
  });
83
- return bucketDeployment;
259
+ return stagingDir;
84
260
  }
85
261
  }
86
262
  exports.NextjsCache = NextjsCache;
87
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsMkJBQWdDO0FBQ2hDLDZDQUE0QztBQUM1QywyREFNa0M7QUFDbEMsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywyQ0FBdUM7QUFDdkMsMkNBQXlDO0FBK0J6Qzs7R0FFRztBQUNILE1BQWEsV0FBWSxTQUFRLHNCQUFTOztJQUMvQixXQUFXLENBQVU7SUFDckIsaUJBQWlCLENBQVc7SUFDNUIsT0FBTyxDQUFTO0lBQ2hCLGdCQUFnQixDQUFvQjtJQUNyQyxLQUFLLENBQW1CO0lBRWhDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUI7UUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxpQkFBaUI7WUFDcEIsS0FBSyxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDdkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUN4QyxVQUFVLEVBQUUseUJBQWdCLENBQUMsVUFBVTtZQUN2QyxpQkFBaUIsRUFBRSwwQkFBaUIsQ0FBQyxTQUFTO1lBQzlDLGFBQWEsRUFBRSwyQkFBYSxDQUFDLE9BQU87WUFDcEMsaUJBQWlCLEVBQUUsSUFBSTtZQUN2QixVQUFVLEVBQUUsSUFBSTtZQUNoQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGdCQUFnQjtTQUMxQyxDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssdUJBQXVCO1FBQzdCLE1BQU0sS0FBSyxHQUFHLElBQUksc0JBQU8sQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDbkQsWUFBWSxFQUFFO2dCQUNaLElBQUksRUFBRSxJQUFJO2dCQUNWLElBQUksRUFBRSw0QkFBYSxDQUFDLE1BQU07YUFDM0I7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTthQUMzQjtZQUNELE9BQU8sRUFBRSxzQkFBTyxDQUFDLFFBQVEsRUFBRTtZQUMzQixhQUFhLEVBQUUsMkJBQWEsQ0FBQyxPQUFPO1lBQ3BDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsc0JBQXNCO1NBQ2hELENBQUMsQ0FBQztRQUVILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCO1FBQ3RCLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsSUFBQSxlQUFVLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSxnQ0FBZ0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLGtDQUFrQyxDQUN2RyxDQUFDO1lBQ0YsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FDckUsQ0FBQztRQUVGLHVEQUF1RDtRQUN2RCxNQUFNLGdCQUFnQixHQUFHLElBQUksb0NBQWdCLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO1lBQ3pFLE9BQU8sRUFBRSxDQUFDLDBCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDaEQsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDbkMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsMkNBQTJDO1lBQ3JGLEtBQUssRUFBRSxLQUFLLEVBQUUsMEdBQTBHO1lBQ3hILEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUscUJBQXFCO1NBQy9DLENBQUMsQ0FBQztRQUNILE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQzs7QUFoRkgsa0NBaUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgUmVtb3ZhbFBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVHlwZSxcbiAgQmlsbGluZyxcbiAgVGFibGVWMixcbiAgVGFibGVQcm9wc1YyLFxuICBJVGFibGVWMixcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiO1xuaW1wb3J0IHtcbiAgQnVja2V0LFxuICBCdWNrZXRFbmNyeXB0aW9uLFxuICBCdWNrZXRQcm9wcyxcbiAgQmxvY2tQdWJsaWNBY2Nlc3MsXG4gIElCdWNrZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7XG4gIEJ1Y2tldERlcGxveW1lbnQsXG4gIEJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgU291cmNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBMT0dfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzQ2FjaGVPdmVycmlkZXMge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldFByb3BzPzogQnVja2V0UHJvcHM7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlUHJvcHM/OiBUYWJsZVByb3BzVjI7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnRQcm9wcz86IEJ1Y2tldERlcGxveW1lbnRQcm9wcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNDYWNoZVByb3BzIHtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQuIENhY2hlIG9iamVjdHMgYXJlIHByZWZpeGVkIHdpdGggYGJ1aWxkSWRgXG4gICAqIHNvIG11bHRpcGxlIGRlcGxveW1lbnRzIGNhbiBzYWZlbHkgc2hhcmUgb25lIGJ1Y2tldC5cbiAgICovXG4gIHJlYWRvbmx5IGNhY2hlQnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIEFic29sdXRlIHBhdGggdG8gdGhlIGluaXQgY2FjaGUgZGlyZWN0b3J5XG4gICAqIEBleGFtcGxlIFwiL1VzZXJzL2pvaG4vbXlhcHAvLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlXCJcbiAgICovXG4gIHJlYWRvbmx5IGluaXRDYWNoZURpcjogc3RyaW5nO1xuICByZWFkb25seSBvdmVycmlkZXM/OiBOZXh0anNDYWNoZU92ZXJyaWRlcztcbiAgLyoqXG4gICAqIEJyaW5nIHlvdXIgb3duIER5bmFtb0RCIHRhYmxlIGZvciByZXZhbGlkYXRpb24gbWV0YWRhdGEuIFdoZW4gcHJvdmlkZWQsXG4gICAqIGNkay1uZXh0anMgd2lsbCBza2lwIGNyZWF0aW5nIGEgbmV3IHRhYmxlLiBUaGUgdGFibGUgbXVzdCBoYXZlIGBwa2AgKFN0cmluZylcbiAgICogYXMgcGFydGl0aW9uIGtleSBhbmQgYHNrYCAoU3RyaW5nKSBhcyBzb3J0IGtleS4gRW50cmllcyBhcmUgcGFydGl0aW9uZWQgYnlcbiAgICogYGJ1aWxkSWRgIHNvIG11bHRpcGxlIGRlcGxveW1lbnRzIGNhbiBzYWZlbHkgc2hhcmUgb25lIHRhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcmV2YWxpZGF0aW9uVGFibGU/OiBJVGFibGVWMjtcbn1cblxuLyoqXG4gKiBOZXh0LmpzIENhY2hlIGNvbnN0cnVjdCBwcm92aWRpbmcgdW5pZmllZCBTMyBhbmQgRHluYW1vREIgY2FjaGUgbWFuYWdlbWVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5leHRqc0NhY2hlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcmVhZG9ubHkgY2FjaGVCdWNrZXQ6IElCdWNrZXQ7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlOiBJVGFibGVWMjtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50PzogQnVja2V0RGVwbG95bWVudDtcbiAgcHJpdmF0ZSBwcm9wczogTmV4dGpzQ2FjaGVQcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzQ2FjaGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgIHRoaXMuYnVpbGRJZCA9IHByb3BzLmJ1aWxkSWQ7XG4gICAgdGhpcy5jYWNoZUJ1Y2tldCA9IHByb3BzLmNhY2hlQnVja2V0ID8/IHRoaXMuY3JlYXRlQ2FjaGVCdWNrZXQoKTtcbiAgICB0aGlzLnJldmFsaWRhdGlvblRhYmxlID1cbiAgICAgIHByb3BzLnJldmFsaWRhdGlvblRhYmxlID8/IHRoaXMuY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTtcbiAgICB0aGlzLmJ1Y2tldERlcGxveW1lbnQgPSB0aGlzLmNyZWF0ZURlcGxveW1lbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIFMzIGJ1Y2tldCBmb3IgY2FjaGUgc3RvcmFnZSB3aXRoIEJVSUxEX0lEIHByZWZpeGluZy5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQ2FjaGVCdWNrZXQoKTogSUJ1Y2tldCB7XG4gICAgY29uc3QgYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBcIkJ1Y2tldFwiLCB7XG4gICAgICBlbmNyeXB0aW9uOiBCdWNrZXRFbmNyeXB0aW9uLlMzX01BTkFHRUQsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmNhY2hlQnVja2V0UHJvcHMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYnVja2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgRHluYW1vREIgdGFibGUgZm9yIHJldmFsaWRhdGlvbiBtZXRhZGF0YVxuICAgKiBTY2hlbWE6IHBrIChidWlsZElkIG9yIFwiTUVUQURBVEFcIiksIHNrICh0YWcjY2FjaGVLZXkgb3IgXCJDVVJSRU5UX0JVSUxEXCIpLCBjcmVhdGVkQXQsIHJldmFsaWRhdGVkQXRcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTogVGFibGVWMiB7XG4gICAgY29uc3QgdGFibGUgPSBuZXcgVGFibGVWMih0aGlzLCBcIlJldmFsaWRhdGlvblRhYmxlXCIsIHtcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiBcInBrXCIsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogXCJza1wiLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBiaWxsaW5nOiBCaWxsaW5nLm9uRGVtYW5kKCksXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8ucmV2YWxpZGF0aW9uVGFibGVQcm9wcyxcbiAgICB9KTtcblxuICAgIHJldHVybiB0YWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXBsb3kgcHJlLWJ1aWx0IGNhY2hlIGZpbGVzIGZyb20gLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlIHRvIFMzXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnQoKTogQnVja2V0RGVwbG95bWVudCB8IHVuZGVmaW5lZCB7XG4gICAgLy8gQ2hlY2sgaWYgY2FjaGUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGlmICghZXhpc3RzU3luYyh0aGlzLnByb3BzLmluaXRDYWNoZURpcikpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgJHtMT0dfUFJFRklYfSBObyBwcmUtYnVpbHQgY2FjaGUgZm91bmQgYXQgJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn0sIHNraXBwaW5nIGluaXQgY2FjaGUgZGVwbG95bWVudGAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGAke0xPR19QUkVGSVh9IERlcGxveWluZyBpbml0IGNhY2hlIGZyb20gJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn1gLFxuICAgICk7XG5cbiAgICAvLyBVc2Ugc3RhbmRhcmQgQnVja2V0RGVwbG95bWVudCBmb3IgcmVndWxhciBTMyBidWNrZXRzXG4gICAgY29uc3QgYnVja2V0RGVwbG95bWVudCA9IG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIFwiSW5pdENhY2hlRGVwbG95bWVudFwiLCB7XG4gICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KHRoaXMucHJvcHMuaW5pdENhY2hlRGlyKV0sXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5jYWNoZUJ1Y2tldCxcbiAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiB0aGlzLnByb3BzLmJ1aWxkSWQsIC8vIEFkZCBidWlsZElkIHByZWZpeCB0byBhbGwgdXBsb2FkZWQgZmlsZXNcbiAgICAgIHBydW5lOiBmYWxzZSwgLy8gRG9uJ3QgZGVsZXRlIGV4aXN0aW5nIG9iamVjdHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICB9KTtcbiAgICByZXR1cm4gYnVja2V0RGVwbG95bWVudDtcbiAgfVxufVxuIl19
263
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkJBT1k7QUFDWiwyQkFBNEI7QUFDNUIsK0JBQTRCO0FBQzVCLDZDQUFrRDtBQUNsRCwyREFNa0M7QUFDbEMsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywwREFBNEM7QUFDNUMsMkNBQXVDO0FBQ3ZDLDJDQUF5QztBQUV6Qyw0REFBNEQ7QUFDNUQsTUFBTSw2QkFBNkIsR0FBRyxHQUFHLENBQUM7QUFDMUMsOENBQThDO0FBQzlDLE1BQU0seUJBQXlCLEdBQUcsS0FBSyxDQUFDO0FBRXhDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsV0FBVyxDQUFDLEdBQVcsRUFBRSxHQUFXO0lBQzNDLElBQUksSUFBSSxHQUFHLDZCQUE2QixDQUFDO0lBQ3pDLE9BQU8sSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksSUFBSSxDQUFDLENBQUM7SUFDWixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUM3QixDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLFNBQVMsZUFBZSxDQUFDLEdBQVc7SUFDbEMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFBLGdCQUFXLEVBQUMsR0FBRyxFQUFFO1FBQ25DLGFBQWEsRUFBRSxJQUFJO1FBQ25CLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsRUFBRSxDQUFDO1FBQ0gsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNuQixxRUFBcUU7WUFDckUsK0NBQStDO1lBQy9DLE1BQU0sTUFBTSxHQUNWLEtBQUssQ0FBQyxVQUFVLElBQUssS0FBcUMsQ0FBQyxJQUFJ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Q3ZDLE9BQU8sQ0FBQyxJQUFJLENBQ1YsR0FBRyxzQkFBVSxzQkFBc0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLE9BQU8sR0FBRyxtQ0FBbUMseUJBQXlCLHNKQUFzSixDQUN2UixDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUVqRSxPQUFPO1lBQ0wsb0JBQW9CLEVBQUUsa0JBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQy9DLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzVDLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E0Qkc7SUFDSyxzQkFBc0I7UUFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBQSxnQkFBVyxFQUFDLElBQUEsV0FBSSxFQUFDLElBQUEsV0FBTSxHQUFFLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUEsV0FBTSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLElBQUEsV0FBSSxFQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3BFLFNBQVMsRUFBRSxJQUFJO1NBQ2hCLENBQUMsQ0FBQztRQUNILE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7O0FBaE1ILGtDQWlNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGNwU3luYyxcbiAgZXhpc3RzU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHJlYWRkaXJTeW5jLFxuICBybVN5bmMsXG4gIHN0YXRTeW5jLFxufSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBSZW1vdmFsUG9saWN5LCBTaXplIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVUeXBlLFxuICBCaWxsaW5nLFxuICBUYWJsZVYyLFxuICBUYWJsZVByb3BzVjIsXG4gIElUYWJsZVYyLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiXCI7XG5pbXBvcnQge1xuICBCdWNrZXQsXG4gIEJ1Y2tldEVuY3J5cHRpb24sXG4gIEJ1Y2tldFByb3BzLFxuICBCbG9ja1B1YmxpY0FjY2VzcyxcbiAgSUJ1Y2tldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHtcbiAgQnVja2V0RGVwbG95bWVudCxcbiAgQnVja2V0RGVwbG95bWVudFByb3BzLFxuICBTb3VyY2UsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSBcImF3cy1jZGstbGliL2N4LWFwaVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVggfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqIFdoYXQgYSBgQnVja2V0RGVwbG95bWVudGAgTGFtYmRhIGdldHMgd2l0aG91dCBhc2tpbmcuICovXG5jb25zdCBERUZBVUxUX0VQSEVNRVJBTF9TVE9SQUdFX01JQiA9IDUxMjtcbi8qKiBUaGUgbW9zdCBMYW1iZGEgd2lsbCBnaXZlIGFueSBmdW5jdGlvbi4gKi9cbmNvbnN0IE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIgPSAxMDI0MDtcblxuLyoqXG4gKiBUaGUgc21hbGxlc3QgcG93ZXItb2YtdHdvIE1pQiBzdGVwIGF0IG9yIGFib3ZlIGBtaWJgLCBjYXBwZWQgYXQgYG1heGAuXG4gKlxuICogYEJ1Y2tldERlcGxveW1lbnRgIGZvbGRzIGBlcGhlbWVyYWxTdG9yYWdlU2l6ZWAgaW50byBib3RoIGl0cyBzaW5nbGV0b25cbiAqIGhhbmRsZXIncyBVVUlEIGFuZCBpdHMgY3VzdG9tIHJlc291cmNlJ3MgbG9naWNhbCBJRCwgc28gZXZlcnkgZGlzdGluY3Qgc2l6ZSBpc1xuICogYSBuZXcgaGFuZGxlciBMYW1iZGEsIGEgbmV3IGBTZXJ2aWNlVG9rZW5gLCBhbmQgYSByZXBsYWNlZCBjdXN0b20gcmVzb3VyY2UuXG4gKiBTaXplZCB0byB0aGUgTWlCLCB0aGF0IHdhcyBldmVyeSBkZXBsb3kgd2hvc2UgaW5pdCBjYWNoZSBncmV3IGJ5IG9uZTogYSBmdWxsXG4gKiBDbG91ZEZvcm1hdGlvbiBkZXBsb3ltZW50IHdoZXJlIGEgaG90c3dhcCB3b3VsZCBoYXZlIGRvbmUuIERvdWJsaW5nIHN0ZXBzXG4gKiBjaGFuZ2Ugb25seSB3aGVuIHRoZSBjYWNoZSBkb2VzIGJ5IGEgbGFyZ2UgZnJhY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIHN0b3JhZ2VTdGVwKG1pYjogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciB7XG4gIGxldCBzdGVwID0gREVGQVVMVF9FUEhFTUVSQUxfU1RPUkFHRV9NSUI7XG4gIHdoaWxlIChzdGVwIDwgbWliKSB7XG4gICAgc3RlcCAqPSAyO1xuICB9XG4gIHJldHVybiBNYXRoLm1pbihzdGVwLCBtYXgpO1xufVxuXG4vKiogQnl0ZXMgb24gZGlzayB1bmRlciBgZGlyYCwgZm9sbG93aW5nIHRoZSB0cmVlIGJ1dCBub3Qgc3ltbGlua3MuICovXG5mdW5jdGlvbiBzaXplT2ZEaXJlY3RvcnkoZGlyOiBzdHJpbmcpOiBudW1iZXIge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKGRpciwge1xuICAgIHdpdGhGaWxlVHlwZXM6IHRydWUsXG4gICAgcmVjdXJzaXZlOiB0cnVlLFxuICB9KSkge1xuICAgIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuICAgICAgLy8gYHBhcmVudFBhdGhgIG9ubHkgZXhpc3RzIGZyb20gTm9kZSAyMC4xMjsgYHBhdGhgIGlzIGl0cyBkZXByZWNhdGVkXG4gICAgICAvLyBwcmVkZWNlc3NvciwgYW5kIHRoZSBvbmx5IG9uZSBvbiAyMC45LTIwLjExLlxuICAgICAgY29uc3QgcGFyZW50ID1cbiAgICAgICAgZW50cnkucGFyZW50UGF0aCA/PyAoZW50cnkgYXMgdW5rbm93biBhcyB7IHBhdGg6IHN0cmluZyB9KS5wYXRoO1xuICAgICAgdG90YWwgKz0gc3RhdFN5bmMoam9pbihwYXJlbnQsIGVudHJ5Lm5hbWUpKS5zaXplO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdG90YWw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzQ2FjaGVPdmVycmlkZXMge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldFByb3BzPzogQnVja2V0UHJvcHM7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlUHJvcHM/OiBUYWJsZVByb3BzVjI7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnRQcm9wcz86IEJ1Y2tldERlcGxveW1lbnRQcm9wcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNDYWNoZVByb3BzIHtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQuXG4gICAqXG4gICAqIFRoZSBidWNrZXQgbXVzdCBiZSBkZWRpY2F0ZWQgdG8gdGhpcyBvbmUgZGVwbG95bWVudC4gRG9uJ3Qgc2hhcmUgaXQgd2l0aFxuICAgKiBhbm90aGVyIGRlcGxveW1lbnQgKGFub3RoZXIgYnJhbmNoLCBzdGFnZSwgb3IgYXBwKTogZXZlcnkgZGVwbG95J3NcbiAgICogcG9zdC1kZXBsb3kgc3RlcCBkZWxldGVzIGV2ZXJ5IG9iamVjdCB1bmRlciBhIHRvcC1sZXZlbCBwcmVmaXggb3RoZXIgdGhhblxuICAgKiB0aGUgY3VycmVudCBgYnVpbGRJZC9gLCB3aGljaCBpbmNsdWRlcyBldmVyeSBvdGhlciBkZXBsb3ltZW50J3MgY2FjaGUuXG4gICAqL1xuICByZWFkb25seSBjYWNoZUJ1Y2tldD86IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBpbml0IGNhY2hlIGRpcmVjdG9yeVxuICAgKiBAZXhhbXBsZSBcIi9Vc2Vycy9qb2huL215YXBwLy5uZXh0L2Nkay1uZXh0anMtaW5pdC1jYWNoZVwiXG4gICAqL1xuICByZWFkb25seSBpbml0Q2FjaGVEaXI6IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzQ2FjaGVPdmVycmlkZXM7XG4gIC8qKlxuICAgKiBCcmluZyB5b3VyIG93biBEeW5hbW9EQiB0YWJsZSBmb3IgcmV2YWxpZGF0aW9uIG1ldGFkYXRhLiBXaGVuIHByb3ZpZGVkLFxuICAgKiBjZGstbmV4dGpzIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyB0YWJsZS4gVGhlIHRhYmxlIG11c3QgaGF2ZSBgcGtgIChTdHJpbmcpXG4gICAqIGFzIHBhcnRpdGlvbiBrZXkgYW5kIGBza2AgKFN0cmluZykgYXMgc29ydCBrZXkuXG4gICAqIEVuYWJsaW5nIFRUTCBvbiBpdHMgYHR0bGAgYXR0cmlidXRlIGlzIHJlY29tbWVuZGVkOiBlYWNoIHRhZyByZXZhbGlkYXRpb25cbiAgICogd3JpdGVzIGEgcmV2YWxpZGF0aW9uIGxvZyByb3cgdGhhdCBleHBpcmVzIHRocm91Z2ggaXQgYWZ0ZXIgMTUgbWludXRlcy5cbiAgICogV2l0aG91dCBUVEwgdGhvc2Ugcm93cyBhcmUga2VwdCB1bnRpbCBhIGRlcGxveSByZXBsYWNlcyB0aGVpciBidWlsZCwgd2hvc2VcbiAgICogcG9zdC1kZXBsb3kgc3RlcCBkZWxldGVzIHRoZW0uXG4gICAqXG4gICAqIFRoZSB0YWJsZSBtdXN0IGJlIGRlZGljYXRlZCB0byB0aGlzIG9uZSBkZXBsb3ltZW50LiBEb24ndCBzaGFyZSBpdCB3aXRoXG4gICAqIGFub3RoZXIgZGVwbG95bWVudCAoYW5vdGhlciBicmFuY2gsIHN0YWdlLCBvciBhcHApOiBldmVyeSBkZXBsb3knc1xuICAgKiBwb3N0LWRlcGxveSBzdGVwIGRlbGV0ZXMgdGhlIGVudHJpZXMgb2YgdGhlIGJ1aWxkIGl0IGxhc3QgcmVjb3JkZWQgaW4gdGhlXG4gICAqIHRhYmxlLCB3aGljaCB3aXRoIGEgc2hhcmVkIHRhYmxlIGlzIGFub3RoZXIgZGVwbG95bWVudCdzIGxpdmUgYnVpbGQuXG4gICAqL1xuICByZWFkb25seSByZXZhbGlkYXRpb25UYWJsZT86IElUYWJsZVYyO1xufVxuXG4vKipcbiAqIE5leHQuanMgQ2FjaGUgY29uc3RydWN0IHByb3ZpZGluZyB1bmlmaWVkIFMzIGFuZCBEeW5hbW9EQiBjYWNoZSBtYW5hZ2VtZW50LlxuICovXG5leHBvcnQgY2xhc3MgTmV4dGpzQ2FjaGUgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldDogSUJ1Y2tldDtcbiAgcmVhZG9ubHkgcmV2YWxpZGF0aW9uVGFibGU6IElUYWJsZVYyO1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICBwcml2YXRlIHByb3BzOiBOZXh0anNDYWNoZVByb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXh0anNDYWNoZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgdGhpcy5idWlsZElkID0gcHJvcHMuYnVpbGRJZDtcbiAgICB0aGlzLmNhY2hlQnVja2V0ID0gcHJvcHMuY2FjaGVCdWNrZXQgPz8gdGhpcy5jcmVhdGVDYWNoZUJ1Y2tldCgpO1xuICAgIHRoaXMucmV2YWxpZGF0aW9uVGFibGUgPVxuICAgICAgcHJvcHMucmV2YWxpZGF0aW9uVGFibGUgPz8gdGhpcy5jcmVhdGVSZXZhbGlkYXRpb25UYWJsZSgpO1xuICAgIHRoaXMuYnVja2V0RGVwbG95bWVudCA9IHRoaXMuY3JlYXRlRGVwbG95bWVudCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlIHdpdGggQlVJTERfSUQgcHJlZml4aW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVDYWNoZUJ1Y2tldCgpOiBJQnVja2V0IHtcbiAgICBjb25zdCBidWNrZXQgPSBuZXcgQnVja2V0KHRoaXMsIFwiQnVja2V0XCIsIHtcbiAgICAgIGVuY3J5cHRpb246IEJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCxcbiAgICAgIGJsb2NrUHVibGljQWNjZXNzOiBCbG9ja1B1YmxpY0FjY2Vzcy5CTE9DS19BTEwsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZSxcbiAgICAgIGVuZm9yY2VTU0w6IHRydWUsXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uY2FjaGVCdWNrZXRQcm9wcyxcbiAgICB9KTtcblxuICAgIHJldHVybiBidWNrZXQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBEeW5hbW9EQiB0YWJsZSBmb3IgcmV2YWxpZGF0aW9uIG1ldGFkYXRhXG4gICAqIFNjaGVtYTogcGsgKGJ1aWxkSWQgb3IgXCJNRVRBREFUQVwiKSwgc2sgKHRhZyNjYWNoZUtleSBvciBcIkNVUlJFTlRfQlVJTERcIiksIGNyZWF0ZWRBdCwgcmV2YWxpZGF0ZWRBdFxuICAgKlxuICAgKiBBbHNvIHRoZSBgJ3VzZSBjYWNoZSdgIHJldmFsaWRhdGlvbiBsb2cgKHBrIFwiPGJ1aWxkSWQ+I2xvZ1wiLFxuICAgKiBzayBcIjxlcG9jaC1tcz4jPHRhZz5cIiksIHdob3NlIHJvd3MgZXhwaXJlIHRocm91Z2ggdGhlIGB0dGxgIGF0dHJpYnV0ZS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTogVGFibGVWMiB7XG4gICAgY29uc3QgdGFibGUgPSBuZXcgVGFibGVWMih0aGlzLCBcIlJldmFsaWRhdGlvblRhYmxlXCIsIHtcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiBcInBrXCIsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogXCJza1wiLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBiaWxsaW5nOiBCaWxsaW5nLm9uRGVtYW5kKCksXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICB0aW1lVG9MaXZlQXR0cmlidXRlOiBcInR0bFwiLFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LnJldmFsaWRhdGlvblRhYmxlUHJvcHMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGFibGU7XG4gIH1cblxuICAvKipcbiAgICogRGVwbG95IHByZS1idWlsdCBjYWNoZSBmaWxlcyBmcm9tIC5uZXh0L2Nkay1uZXh0anMtaW5pdC1jYWNoZSB0byBTM1xuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEZXBsb3ltZW50KCk6IEJ1Y2tldERlcGxveW1lbnQgfCB1bmRlZmluZWQge1xuICAgIC8vIENoZWNrIGlmIGNhY2hlIGRpcmVjdG9yeSBleGlzdHNcbiAgICBpZiAoIWV4aXN0c1N5bmModGhpcy5wcm9wcy5pbml0Q2FjaGVEaXIpKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYCR7TE9HX1BSRUZJWH0gTm8gcHJlLWJ1aWx0IGNhY2hlIGZvdW5kIGF0ICR7dGhpcy5wcm9wcy5pbml0Q2FjaGVEaXJ9LCBza2lwcGluZyBpbml0IGNhY2hlIGRlcGxveW1lbnRgLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coXG4gICAgICBgJHtMT0dfUFJFRklYfSBEZXBsb3lpbmcgaW5pdCBjYWNoZSBmcm9tICR7dGhpcy5wcm9wcy5pbml0Q2FjaGVEaXJ9YCxcbiAgICApO1xuXG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IHRoaXMuY3JlYXRlU3RhZ2luZ0RpcmVjdG9yeSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBzdGFuZGFyZCBCdWNrZXREZXBsb3ltZW50IGZvciByZWd1bGFyIFMzIGJ1Y2tldHNcbiAgICAgIGNvbnN0IGJ1Y2tldERlcGxveW1lbnQgPSBuZXcgQnVja2V0RGVwbG95bWVudChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJJbml0Q2FjaGVEZXBsb3ltZW50XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KHN0YWdpbmdEaXIpXSxcbiAgICAgICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5jYWNoZUJ1Y2tldCxcbiAgICAgICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBvYmplY3RzIHRvIHByZXZlbnQgNDA0cyBkdXJpbmcgZGVwbG95bWVudCwgcHJ1bmluZyB3aWxsIGJlIGhhbmRsZWQgYnkgcG9zdC1kZXBsb3lcbiAgICAgICAgICAuLi50aGlzLnNpemVEZXBsb3ltZW50TGFtYmRhKCksXG4gICAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gYnVja2V0RGVwbG95bWVudDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gYFNvdXJjZS5hc3NldGAgc3RhZ2VzIGR1cmluZyBgQnVja2V0RGVwbG95bWVudGAncyBjb25zdHJ1Y3Rpb24gLSBDREsnc1xuICAgICAgLy8gYEFzc2V0U3RhZ2luZ2AgemlwcyBpbnRvIGBjZGsub3V0YCBmcm9tIGl0cyBvd24gY29uc3RydWN0b3IgLSBzbyB0aGVcbiAgICAgIC8vIHRlbXBvcmFyeSBjb3B5IGlzIGRlYWQgdGhlIG1vbWVudCB0aGF0IHJldHVybnMuIExlYXZpbmcgaXQgd2FzIGEgc2xvd1xuICAgICAgLy8gbGVhayB3aXRoIGEgbGFyZ2UgdW5pdDogdGhlIGluaXQgY2FjaGUgaGFzIGJlZW4gbWVhc3VyZWQgYXQgNjY0IE1pQiwgYW5kXG4gICAgICAvLyBldmVyeSBgY2RrIHN5bnRoYCBsZWZ0IGFub3RoZXIgZnVsbCBjb3B5IGluIHRoZSBzeXN0ZW0gdGVtcCBkaXJlY3RvcnksXG4gICAgICAvLyBzbyBhIENJIGxvb3Agb2YgfjIyIGRlcGxveXMgY291bGQgcHV0IH4xNSBHQiBvbiB0aGUgcnVubmVyJ3MgZGlzay5cbiAgICAgIC8vXG4gICAgICAvLyBVbmxlc3Mgc3RhZ2luZyBpcyBkaXNhYmxlZCAoYGNkayBzeW50aCAtLW5vLXN0YWdpbmdgLCBhbmQgU0FNLCB3aGljaFxuICAgICAgLy8gc2V0cyB0aGUgc2FtZSBjb250ZXh0KTogdGhlbiBub3RoaW5nIGlzIGNvcGllZCBpbnRvIGBjZGsub3V0YCwgdGhlXG4gICAgICAvLyBhc3NldCBtYW5pZmVzdCBwb2ludHMgYXQgdGhpcyBkaXJlY3RvcnkgaXRzZWxmLCBhbmQgcmVtb3ZpbmcgaXQgZmFpbHNcbiAgICAgIC8vIHRoZSBwdWJsaXNoIHRoYXQgZm9sbG93cyB0aGUgc3ludGggd2l0aCBFTk9FTlQuXG4gICAgICBpZiAoIXRoaXMubm9kZS50cnlHZXRDb250ZXh0KGN4YXBpLkRJU0FCTEVfQVNTRVRfU1RBR0lOR19DT05URVhUKSkge1xuICAgICAgICBybVN5bmMoc3RhZ2luZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBgL3RtcGAgYW5kIG1lbW9yeSBmb3IgYEJ1Y2tldERlcGxveW1lbnRgJ3MgdW56aXAgTGFtYmRhLCBzY2FsZWQgdG8gdGhlIGluaXRcbiAgICogY2FjaGUgaXQgaGFzIHRvIHVucGFjay5cbiAgICpcbiAgICogVGhhdCBMYW1iZGEgZG93bmxvYWRzIHRoZSBhc3NldCB6aXAgaW50byBgL3RtcGAgYW5kIHRoZW4gZXh0cmFjdHMgaXRcbiAgICogYWxvbmdzaWRlLCBzbyBpdCBuZWVkcyByb29tIGZvciBib3RoIGF0IG9uY2UuIENESyBkZWZhdWx0cyBpdCB0byA1MTIgTWlCIG9mXG4gICAqIGVwaGVtZXJhbCBzdG9yYWdlIGFuZCAxMjggTUIgb2YgbWVtb3J5IOKAlCBmaW5lIGZvciBhIHNtYWxsIGFwcCwgYW5kIGEgaGFyZFxuICAgKiBmYWlsdXJlIGZvciBvbmUgd2hvc2UgcHJlcmVuZGVyZWQgcGF5bG9hZHMgYXJlIGxhcmdlLiBBIGZpeHR1cmUgd2l0aCA2MFxuICAgKiBzdGF0aWNhbGx5IGdlbmVyYXRlZCBwYWdlcyBjYXJyeWluZyB+MSBNQiBvZiBSU0MgZWFjaCBwcm9kdWNlZCBhIDY2NCBNaUJcbiAgICogc2VlZCBkaXJlY3RvcnkgYW5kIHRoZSBoYW5kbGVyIGRpZWQgb25cbiAgICogYE9TRXJyb3I6IFtFcnJubyAyOF0gTm8gc3BhY2UgbGVmdCBvbiBkZXZpY2VgIGluc2lkZSBgemlwLmV4dHJhY3RhbGxgLlxuICAgKiBXb3JzZSwgYGNkayBkZXBsb3kgLS1ob3Rzd2FwYCBpbnZva2VzIHRoZSBjdXN0b20gcmVzb3VyY2UgZGlyZWN0bHkgd2l0aCBhXG4gICAqIHBsYWNlaG9sZGVyIHJlc3BvbnNlIFVSTCwgc28gdGhlIGBTdGF0dXM6IEZBSUxFRGAgaXQgc2VuZHMgZ29lcyBub3doZXJlOiB0aGVcbiAgICogQ0xJIHByaW50cyBcIkNvbnRlbnRzIG9mIEFXUzo6UzM6OkJ1Y2tldCDigKYgaG90c3dhcHBlZCFcIiwgZXhpdHMgMCwgYW5kIHRoZSBhcHBcbiAgICogY29tZXMgdXAgc2VydmluZyBhICpwYXJ0aWFsbHkqIHNlZWRlZCBjYWNoZS4gRXZlcnkgcm91dGUgd2hvc2UgZW50cnkgZGlkIG5vdFxuICAgKiBtYWtlIGl0IGlzIHRoZW4gYSBtaXNzIHRoYXQgcmUtcmVuZGVycyDigJQgd2hpY2gsIGZvciBhXG4gICAqIGBjYWNoZUNvbXBvbmVudHM6IHRydWVgIGFwcCwgbWVhbnMgYSBwb3N0cG9uZWQgc2hlbGwgd2hlcmUgdGhlIHByZXJlbmRlclxuICAgKiBzaG91bGQgaGF2ZSBiZWVuLlxuICAgKlxuICAgKiBUaGUgemlwJ3MgY29tcHJlc3NlZCBzaXplIGlzIG5vdCBrbm93biBhdCBzeW50aCB0aW1lIChDREsgYXJjaGl2ZXMgdGhlIGFzc2V0XG4gICAqIGxhdGVyKSwgc28gdGhlIHdvcnN0IGNhc2Ug4oCUIGFuIGluY29tcHJlc3NpYmxlIHBheWxvYWQg4oCUIGlzIHdoYXQgZ2V0c1xuICAgKiBidWRnZXRlZDogdHdpY2UgdGhlIGRpcmVjdG9yeSwgcGx1cyBoZWFkcm9vbSwgcm91bmRlZCB1cCB0byBhXG4gICAqIHtAbGluayBzdG9yYWdlU3RlcH0uIE1lbW9yeSBpcyBvbmx5IHJhaXNlZCBwYXN0XG4gICAqIENESydzIGRlZmF1bHQgZm9yIGNhY2hlcyBiaWcgZW5vdWdoIHRoYXQgMTI4IE1CJ3Mgc2xpY2Ugb2YgYSB2Q1BVIHdvdWxkIG1ha2VcbiAgICogdGhlIHVuemlwIGFuZCB1cGxvYWQgcmFjZSB0aGUgY3VzdG9tIHJlc291cmNlJ3MgMTUtbWludXRlIHRpbWVvdXQ7IHNtYWxsXG4gICAqIGFwcHMga2VlcCB0aGUgY2hlYXBlciBkZWZhdWx0IGFuZCB0aGVpciBleGlzdGluZyB0ZW1wbGF0ZS5cbiAgICpcbiAgICogQWJvdmUgdGhlIDEwIEdpQiBlcGhlbWVyYWwtc3RvcmFnZSBjZWlsaW5nIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCB0byBhc2sgZm9yLFxuICAgKiBzbyB0aGlzIHdhcm5zIGFuZCBsZXRzIHRoZSBkZXBsb3ltZW50IGZhaWwgbG91ZGx5IHJhdGhlciB0aGFuIHByZXRlbmQuXG4gICAqIGBvdmVycmlkZXMuYnVja2V0RGVwbG95bWVudFByb3BzYCB3aW5zIG92ZXIgZXZlcnl0aGluZyBoZXJlLCBpbmNsdWRpbmdcbiAgICogYHVzZUVmczogdHJ1ZWAsIHdoaWNoIGlzIHRoZSBzdXBwb3J0ZWQgd2F5IG91dC5cbiAgICovXG4gIHByaXZhdGUgc2l6ZURlcGxveW1lbnRMYW1iZGEoKSB7XG4gICAgY29uc3QgbWliID0gTWF0aC5jZWlsKHNpemVPZkRpcmVjdG9yeSh0aGlzLnByb3BzLmluaXRDYWNoZURpcikgLyAxMDI0ICoqIDIpO1xuICAgIGNvbnN0IHdhbnRlZCA9IG1pYiAqIDIgKyAxMjg7XG4gICAgaWYgKHdhbnRlZCA+IE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYCR7TE9HX1BSRUZJWH0gVGhlIGluaXQgY2FjaGUgYXQgJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn0gaXMgJHttaWJ9IE1pQiwgd2hpY2ggZG9lcyBub3QgZml0IGluIHRoZSAke01BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUJ9IE1pQiBvZiBlcGhlbWVyYWwgc3RvcmFnZSBhIEJ1Y2tldERlcGxveW1lbnQgTGFtYmRhIGNhbiBiZSBnaXZlbi4gUGFzcyBvdmVycmlkZXMuYnVja2V0RGVwbG95bWVudFByb3BzIHdpdGggdXNlRWZzOiB0cnVlIHRvIHNlZWQgYSBjYWNoZSB0aGlzIGxhcmdlLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBlcGhlbWVyYWwgPSBzdG9yYWdlU3RlcCh3YW50ZWQsIE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVwaGVtZXJhbFN0b3JhZ2VTaXplOiBTaXplLm1lYmlieXRlcyhlcGhlbWVyYWwpLFxuICAgICAgLi4uKG1pYiA+IDI1NiA/IHsgbWVtb3J5TGltaXQ6IDEwMjQgfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YWdlIHRoZSBpbml0IGNhY2hlIHVuZGVyIGEgYGJ1aWxkSWRgIGRpcmVjdG9yeSwgc28gdGhhdCB0aGUgb2JqZWN0cyBsYW5kXG4gICAqIGF0IGA8YnVpbGRJZD4vPGtleT5gIHdpdGhvdXQgYSBgZGVzdGluYXRpb25LZXlQcmVmaXhgLlxuICAgKlxuICAgKiBUaGUga2V5cyBoYXZlIHRvIGNhcnJ5IHRoZSBidWlsZCBJRCDigJQgdGhhdCBpcyBob3cgdGhlIHJ1bnRpbWUgY2FjaGUgaGFuZGxlclxuICAgKiBhbmQgdGhlIHBvc3QtZGVwbG95IHBydW5lciBuYW1lc3BhY2Ugb25lIGRlcGxveW1lbnQncyBlbnRyaWVzIGZyb20gdGhlIG5leHRcbiAgICogKGBzcmMvYWRhcHRlci9zMy1jYWNoZS1oYW5kbGVyLnRzYCkuIEFza2luZyBgQnVja2V0RGVwbG95bWVudGAgZm9yIGl0LCBhc1xuICAgKiB0aGlzIHVzZWQgdG8sIGlzIHdoYXQgY29zdHM6IGl0IHVuY29uZGl0aW9uYWxseSB0YWdzIHRoZSAqZGVzdGluYXRpb25cbiAgICogYnVja2V0KiB3aXRoIGBhd3MtY2RrOmNyLW93bmVkOjxkZXN0aW5hdGlvbktleVByZWZpeD46PGhhc2g+YCwgc28gYSBwcmVmaXhcbiAgICogdGhhdCBjaGFuZ2VzIHBlciBidWlsZCBtYWtlcyB0aGUgYnVja2V0J3MgYFRhZ3NgIGNoYW5nZSBwZXIgYnVpbGQuXG4gICAqIGBBV1M6OlMzOjpCdWNrZXRgIGBUYWdzYCBhcmUgbm90IGhvdHN3YXBwYWJsZSwgc28gYGNkayBkZXBsb3lcbiAgICogLS1ob3Rzd2FwLWZhbGxiYWNrYCByZWplY3RlZCB0aGUgZGlmZiBhbmQgZmVsbCBiYWNrIHRvIGEgZnVsbCBDbG91ZEZvcm1hdGlvblxuICAgKiBkZXBsb3ltZW50IGV2ZXJ5IHNpbmdsZSB0aW1lIOKAlCBtZWFzdXJlZCBhdCAxOSBvZiAyMiBkZXBsb3lzIGluIG9uZSBoYXJuZXNzXG4gICAqIHJ1biwgfjExMHMgZWFjaCBhZ2FpbnN0IGEgfjUycyBob3Rzd2FwLlxuICAgKlxuICAgKiBQdXR0aW5nIHRoZSBidWlsZCBJRCBpbiB0aGUgYXNzZXQncyBvd24gcGF0aHMgaW5zdGVhZCBsZWF2ZXMgdGhlIFMzIGtleXNcbiAgICogYnl0ZS1pZGVudGljYWwgYW5kIHRoZSB0YWcga2V5IGNvbnN0YW50IChgYXdzLWNkazpjci1vd25lZDo8aGFzaD5gLCBkZXJpdmVkXG4gICAqIGZyb20gdGhlIGNvbnN0cnVjdCBwYXRoKS4gTm90aGluZyBlbHNlIHJlYWQgdGhlIHByZWZpeDogYHBydW5lYCBpcyBhbHJlYWR5XG4gICAqIGBmYWxzZWAsIGFuZCB0aGUgdHdvIGhhbmRsZXIgYnJhbmNoZXMgdGhhdCBkbyBzY29wZSB3b3JrIHRvIGl0IOKAlCBlbXB0eWluZ1xuICAgKiB0aGUgcHJlZml4IG9uIGRlbGV0ZSwgYW5kIGRlbGV0aW5nIHRoZSBvbGQgcHJlZml4IHdoZW4gdGhlIGRlc3RpbmF0aW9uXG4gICAqIGNoYW5nZXMg4oCUIGFyZSBib3RoIGdhdGVkIG9uIGByZXRhaW5PbkRlbGV0ZWAsIHdoaWNoIGBCdWNrZXREZXBsb3ltZW50YFxuICAgKiBkZWZhdWx0cyB0byBgdHJ1ZWAuXG4gICAqXG4gICAqIEEgY29weSByYXRoZXIgdGhhbiB0aGUgZGlyZWN0b3J5IGl0c2VsZiBiZWNhdXNlIHRoZSBidWlsZCBJRCBpcyBvbmx5IGtub3duXG4gICAqICphZnRlciogYG5leHQgYnVpbGRgLCBzbyB0aGUgYWRhcHRlciBjYW5ub3Qgd3JpdGUgaW50byBhIG5lc3RlZCBkaXJlY3RvcnkgaW5cbiAgICogdGhlIGZpcnN0IHBsYWNlLCBhbmQgYmVjYXVzZSBgLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlYCBoYXMgdG8gc3RheSB3aGVyZVxuICAgKiBpdCBpcyBmb3IgdGhlIGxvY2FsIGNhY2hlIGhhbmRsZXIgdG8gcmVhZCBpdCAoYENES19ORVhUSlNfSU5JVF9DQUNIRV9ESVJgKS5cbiAgICogQ0RLIGlzIGFib3V0IHRvIHJlYWQgZXZlcnkgYnl0ZSBvZiB0aGlzIHRvIHppcCBpdCByZWdhcmRsZXNzLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVTdGFnaW5nRGlyZWN0b3J5KCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwibmV4dGpzLWluaXQtY2FjaGUtXCIpKTtcbiAgICBjcFN5bmModGhpcy5wcm9wcy5pbml0Q2FjaGVEaXIsIGpvaW4oc3RhZ2luZ0RpciwgdGhpcy5wcm9wcy5idWlsZElkKSwge1xuICAgICAgcmVjdXJzaXZlOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiBzdGFnaW5nRGlyO1xuICB9XG59XG4iXX0=
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /* eslint-disable import/no-extraneous-dependencies */
4
+ const fs_1 = require("fs");
5
+ const os_1 = require("os");
6
+ const path_1 = require("path");
4
7
  const aws_cdk_lib_1 = require("aws-cdk-lib");
5
8
  const assertions_1 = require("aws-cdk-lib/assertions");
6
9
  const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
10
+ const aws_s3_1 = require("aws-cdk-lib/aws-s3");
11
+ const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
7
12
  const nextjs_cache_1 = require("./nextjs-cache");
8
13
  describe("NextjsCache", () => {
9
14
  let app;
@@ -65,6 +70,16 @@ describe("NextjsCache", () => {
65
70
  BillingMode: "PAY_PER_REQUEST",
66
71
  });
67
72
  });
73
+ // The 'use cache' revalidation log's rows expire through `ttl`.
74
+ it("expires revalidation log rows through a TTL attribute", () => {
75
+ new nextjs_cache_1.NextjsCache(stack, "TestCache", {
76
+ buildId: "test-build-123",
77
+ initCacheDir: "/tmp/test-cache",
78
+ });
79
+ assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::DynamoDB::GlobalTable", {
80
+ TimeToLiveSpecification: { AttributeName: "ttl", Enabled: true },
81
+ });
82
+ });
68
83
  it("should apply custom overrides", () => {
69
84
  new nextjs_cache_1.NextjsCache(stack, "TestCache", {
70
85
  buildId: "test-build-123",
@@ -83,6 +98,7 @@ describe("NextjsCache", () => {
83
98
  name: "cacheKey",
84
99
  type: aws_dynamodb_1.AttributeType.STRING,
85
100
  },
101
+ timeToLiveAttribute: "expiresAt",
86
102
  },
87
103
  },
88
104
  });
@@ -92,8 +108,167 @@ describe("NextjsCache", () => {
92
108
  });
93
109
  template.hasResourceProperties("AWS::DynamoDB::GlobalTable", {
94
110
  TableName: "custom-revalidation-table",
111
+ TimeToLiveSpecification: { AttributeName: "expiresAt", Enabled: true },
112
+ });
113
+ });
114
+ });
115
+ describe("Init cache deployment", () => {
116
+ let initCacheDir;
117
+ let outdir;
118
+ beforeEach(() => {
119
+ initCacheDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "init-cache-src-"));
120
+ (0, fs_1.mkdirSync)((0, path_1.join)(initCacheDir, "server", "app"), { recursive: true });
121
+ (0, fs_1.writeFileSync)((0, path_1.join)(initCacheDir, "server", "app", "index.html"), "<p/>");
122
+ outdir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "init-cache-out-"));
123
+ });
124
+ afterEach(() => {
125
+ (0, fs_1.rmSync)(initCacheDir, { recursive: true, force: true });
126
+ (0, fs_1.rmSync)(outdir, { recursive: true, force: true });
127
+ });
128
+ /**
129
+ * The tag `BucketDeployment` stamps on its destination bucket, and the only
130
+ * one that can vary between two builds. `Tags` on an `AWS::S3::Bucket` are
131
+ * not hotswappable, so a tag key that carries the build ID costs a full
132
+ * CloudFormation deployment on every deploy.
133
+ */
134
+ function ownerTags(template) {
135
+ const buckets = template.findResources("AWS::S3::Bucket");
136
+ return Object.values(buckets)
137
+ .flatMap((bucket) => bucket.Properties?.Tags ?? [])
138
+ .map((tag) => tag.Key)
139
+ .filter((key) => key.startsWith("aws-cdk:cr-owned"));
140
+ }
141
+ function synth(buildId) {
142
+ const ownApp = new aws_cdk_lib_1.App({ outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")) });
143
+ const ownStack = new aws_cdk_lib_1.Stack(ownApp, "TestStack");
144
+ new nextjs_cache_1.NextjsCache(ownStack, "TestCache", { buildId, initCacheDir });
145
+ return { app: ownApp, template: assertions_1.Template.fromStack(ownStack) };
146
+ }
147
+ it("keys the objects under the build ID without a destinationKeyPrefix", () => {
148
+ const { app: ownApp, template } = synth("build-abc123");
149
+ // Not `DestinationBucketKeyPrefix: Match.absent()` on its own: that would
150
+ // also pass if the staged tree had lost the build ID, which is what keeps
151
+ // the S3 keys the same as before this moved.
152
+ const deployments = template.findResources("Custom::CDKBucketDeployment");
153
+ expect(Object.keys(deployments)).toHaveLength(1);
154
+ expect(Object.values(deployments)[0].Properties).not.toHaveProperty("DestinationBucketKeyPrefix");
155
+ const assembly = ownApp.synth();
156
+ const stagedUnderBuildId = (0, fs_1.readdirSync)(assembly.directory, {
157
+ withFileTypes: true,
158
+ }).some((entry) => entry.isDirectory() &&
159
+ entry.name.startsWith("asset.") &&
160
+ (0, fs_1.readdirSync)((0, path_1.join)(assembly.directory, entry.name)).includes("build-abc123"));
161
+ expect(stagedUnderBuildId).toBe(true);
162
+ });
163
+ it("removes its temporary staging copy once the asset is staged", () => {
164
+ // `Source.asset` stages during `BucketDeployment`'s construction, so the
165
+ // copy is dead as soon as that returns - and it is a whole init cache,
166
+ // measured at 664 MiB. Leaving one per synth put ~15 GB in the system temp
167
+ // directory over a CI loop of ~22 deploys.
168
+ const existing = new Set((0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-")));
169
+ synth("build-abc123").app.synth();
170
+ const leaked = (0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-") && !existing.has(name));
171
+ expect(leaked).toEqual([]);
172
+ });
173
+ it("tags the cache bucket the same way whatever the build ID", () => {
174
+ const first = ownerTags(synth("build-abc123").template);
175
+ const second = ownerTags(synth("build-def456").template);
176
+ expect(first).toHaveLength(1);
177
+ expect(first[0]).toMatch(/^aws-cdk:cr-owned:[0-9a-f]{8}$/);
178
+ expect(second).toEqual(first);
179
+ });
180
+ /**
181
+ * The unzip Lambda holds the asset zip and its extracted contents in `/tmp`
182
+ * at once, so a seed directory bigger than the 512 MiB CDK asks for by
183
+ * default kills it with `[Errno 28] No space left on device` — and under
184
+ * `cdk deploy --hotswap` that failure is invisible, because the CLI hands the
185
+ * custom resource a placeholder response URL and never reads its status.
186
+ */
187
+ function deploymentLambda(template) {
188
+ const functions = template.findResources("AWS::Lambda::Function", {
189
+ Properties: {
190
+ Handler: "index.handler",
191
+ Runtime: assertions_1.Match.stringLikeRegexp("^python"),
192
+ },
193
+ });
194
+ expect(Object.keys(functions)).toHaveLength(1);
195
+ return Object.values(functions)[0].Properties;
196
+ }
197
+ it("leaves a small init cache on the default Lambda sizing", () => {
198
+ const properties = deploymentLambda(synth("build-abc123").template);
199
+ // The floor, not a computed value: a handful of bytes still wants 512 MiB
200
+ // because that is the least Lambda will give.
201
+ expect(properties.EphemeralStorage).toEqual({ Size: 512 });
202
+ // Absent, not 128: leaving `memoryLimit` alone keeps the property out of
203
+ // the template, which is Lambda's own 128 MB default.
204
+ expect(properties.MemorySize).toBeUndefined();
205
+ });
206
+ it("scales /tmp and memory to a large init cache", () => {
207
+ // A sparse file: `statSync` reports 300 MiB, the filesystem stores almost
208
+ // nothing, and the zip of a 300 MiB hole costs no real work.
209
+ const big = (0, path_1.join)(initCacheDir, "server", "app", "big.rsc");
210
+ (0, fs_1.writeFileSync)(big, "");
211
+ (0, fs_1.truncateSync)(big, 300 * 1024 * 1024);
212
+ const properties = deploymentLambda(synth("build-abc123").template);
213
+ // 301 MiB of cache — the 300 MiB hole plus the fixture's own file, rounded
214
+ // up — doubled for the zip that sits beside it, plus headroom: 730 MiB,
215
+ // rounded up to the next step.
216
+ expect(properties.EphemeralStorage).toEqual({ Size: 1024 });
217
+ expect(properties.MemorySize).toBe(1024);
218
+ });
219
+ it("keeps the deployment's identity while the cache grows by a little", () => {
220
+ // `ephemeralStorageSize` is part of the singleton handler's UUID and the
221
+ // custom resource's logical ID. Sized to the MiB, a cache 5 MiB bigger
222
+ // than the last deploy's was a new handler Lambda, a new ServiceToken
223
+ // and a replaced custom resource - a full deployment, not a hotswap.
224
+ const big = (0, path_1.join)(initCacheDir, "server", "app", "big.rsc");
225
+ const logicalIds = (mib) => {
226
+ (0, fs_1.writeFileSync)(big, "");
227
+ (0, fs_1.truncateSync)(big, mib * 1024 * 1024);
228
+ const template = synth("build-abc123").template;
229
+ return [
230
+ ...Object.keys(template.findResources("Custom::CDKBucketDeployment")),
231
+ ...Object.keys(template.findResources("AWS::Lambda::Function")),
232
+ ].sort();
233
+ };
234
+ expect(logicalIds(305)).toEqual(logicalIds(300));
235
+ });
236
+ it("keeps the staging copy when asset staging is disabled", () => {
237
+ // `--no-staging` (and SAM) leaves the asset where it is rather than
238
+ // copying it into `cdk.out`, so the staging copy *is* the asset, and the
239
+ // publish after synth needs it.
240
+ const ownApp = new aws_cdk_lib_1.App({
241
+ outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")),
242
+ context: { "aws:cdk:disable-asset-staging": true },
243
+ });
244
+ const existing = new Set((0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-")));
245
+ new nextjs_cache_1.NextjsCache(new aws_cdk_lib_1.Stack(ownApp, "TestStack"), "TestCache", {
246
+ buildId: "build-abc123",
247
+ initCacheDir,
248
+ });
249
+ const kept = (0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-") && !existing.has(name));
250
+ expect(kept).toHaveLength(1);
251
+ (0, fs_1.rmSync)((0, path_1.join)((0, os_1.tmpdir)(), kept[0]), { recursive: true, force: true });
252
+ });
253
+ it("lets overrides win over the computed sizing", () => {
254
+ const ownApp = new aws_cdk_lib_1.App({ outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")) });
255
+ const ownStack = new aws_cdk_lib_1.Stack(ownApp, "TestStack");
256
+ new nextjs_cache_1.NextjsCache(ownStack, "TestCache", {
257
+ buildId: "build-abc123",
258
+ initCacheDir,
259
+ overrides: {
260
+ bucketDeploymentProps: {
261
+ destinationBucket: aws_s3_1.Bucket.fromBucketName(ownStack, "Existing", "someone-elses-bucket"),
262
+ sources: [aws_s3_deployment_1.Source.data("marker", "x")],
263
+ ephemeralStorageSize: aws_cdk_lib_1.Size.gibibytes(2),
264
+ memoryLimit: 2048,
265
+ },
266
+ },
95
267
  });
268
+ const properties = deploymentLambda(assertions_1.Template.fromStack(ownStack));
269
+ expect(properties.EphemeralStorage).toEqual({ Size: 2048 });
270
+ expect(properties.MemorySize).toBe(2048);
96
271
  });
97
272
  });
98
273
  });
99
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLWNhY2hlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzREFBc0Q7QUFDdEQsNkNBQXlDO0FBQ3pDLHVEQUFrRDtBQUNsRCwyREFBeUQ7QUFDekQsaURBQTZDO0FBRTdDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFO0lBQzNCLElBQUksR0FBUSxDQUFDO0lBQ2IsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLGlCQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDbEMsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtZQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLDBCQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDaEQsT0FBTyxFQUFFLGdCQUFnQjtnQkFDekIsWUFBWSxFQUFFLGlCQUFpQjthQUNoQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLDhCQUE4QjtZQUM5QixRQUFRLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ2hELGdCQUFnQixFQUFFO29CQUNoQixpQ0FBaUMsRUFBRTt3QkFDakM7NEJBQ0UsNkJBQTZCLEVBQUU7Z0NBQzdCLFlBQVksRUFBRSxRQUFROzZCQUN2Qjt5QkFDRjtxQkFDRjtpQkFDRjtnQkFDRCw4QkFBOEIsRUFBRTtvQkFDOUIsZUFBZSxFQUFFLElBQUk7b0JBQ3JCLGlCQUFpQixFQUFFLElBQUk7b0JBQ3ZCLGdCQUFnQixFQUFFLElBQUk7b0JBQ3RCLHFCQUFxQixFQUFFLElBQUk7aUJBQzVCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsMEVBQTBFO1lBQzFFLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyw0QkFBNEIsRUFBRTtnQkFDM0QsU0FBUyxFQUFFO29CQUNUO3dCQUNFLGFBQWEsRUFBRSxJQUFJO3dCQUNuQixPQUFPLEVBQUUsTUFBTTtxQkFDaEI7b0JBQ0Q7d0JBQ0UsYUFBYSxFQUFFLElBQUk7d0JBQ25CLE9BQU8sRUFBRSxPQUFPO3FCQUNqQjtpQkFDRjtnQkFDRCxvQkFBb0IsRUFBRTtvQkFDcEI7d0JBQ0UsYUFBYSxFQUFFLElBQUk7d0JBQ25CLGFBQWEsRUFBRSxHQUFHO3FCQUNuQjtvQkFDRDt3QkFDRSxhQUFhLEVBQUUsSUFBSTt3QkFDbkIsYUFBYSxFQUFFLEdBQUc7cUJBQ25CO2lCQUNGO2dCQUNELFdBQVcsRUFBRSxpQkFBaUI7YUFDL0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1lBQ3ZDLElBQUksMEJBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFO2dCQUNsQyxPQUFPLEVBQUUsZ0JBQWdCO2dCQUN6QixZQUFZLEVBQUUsaUJBQWlCO2dCQUMvQixTQUFTLEVBQUU7b0JBQ1QsZ0JBQWdCLEVBQUU7d0JBQ2hCLFVBQVUsRUFBRSxxQkFBcUI7cUJBQ2xDO29CQUNELHNCQUFzQixFQUFFO3dCQUN0QixTQUFTLEVBQUUsMkJBQTJCO3dCQUN0QyxZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLEtBQUs7NEJBQ1gsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTt5QkFDM0I7d0JBQ0QsT0FBTyxFQUFFOzRCQUNQLElBQUksRUFBRSxVQUFVOzRCQUNoQixJQUFJLEVBQUUsNEJBQWEsQ0FBQyxNQUFNO3lCQUMzQjtxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEQsVUFBVSxFQUFFLHFCQUFxQjthQUNsQyxDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMsNEJBQTRCLEVBQUU7Z0JBQzNELFNBQVMsRUFBRSwyQkFBMkI7YUFDdkMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBcHAsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgeyBBdHRyaWJ1dGVUeXBlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiO1xuaW1wb3J0IHsgTmV4dGpzQ2FjaGUgfSBmcm9tIFwiLi9uZXh0anMtY2FjaGVcIjtcblxuZGVzY3JpYmUoXCJOZXh0anNDYWNoZVwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBuZXcgQXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBDb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTMyBidWNrZXQgYW5kIER5bmFtb0RCIHRhYmxlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gbmV3IE5leHRqc0NhY2hlKHN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwidGVzdC1idWlsZC0xMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyOiBcIi90bXAvdGVzdC1jYWNoZVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjYWNoZS5jYWNoZUJ1Y2tldCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5yZXZhbGlkYXRpb25UYWJsZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5idWlsZElkKS50b0JlKFwidGVzdC1idWlsZC0xMjNcIik7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IFMzIGJ1Y2tldCBpcyBjcmVhdGVkXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgICAgICBCdWNrZXRFbmNyeXB0aW9uOiB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQnlEZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgU1NFQWxnb3JpdGhtOiBcIkFFUzI1NlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBQdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBCbG9ja1B1YmxpY0FjbHM6IHRydWUsXG4gICAgICAgICAgQmxvY2tQdWJsaWNQb2xpY3k6IHRydWUsXG4gICAgICAgICAgSWdub3JlUHVibGljQWNsczogdHJ1ZSxcbiAgICAgICAgICBSZXN0cmljdFB1YmxpY0J1Y2tldHM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gVmVyaWZ5IER5bmFtb0RCIHRhYmxlIGlzIGNyZWF0ZWQgKFRhYmxlVjIgY3JlYXRlcyBHbG9iYWxUYWJsZSByZXNvdXJjZSlcbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgQXR0cmlidXRlTmFtZTogXCJwa1wiLFxuICAgICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInNrXCIsXG4gICAgICAgICAgICBLZXlUeXBlOiBcIlJBTkdFXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgQXR0cmlidXRlRGVmaW5pdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInBrXCIsXG4gICAgICAgICAgICBBdHRyaWJ1dGVUeXBlOiBcIlNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2tcIixcbiAgICAgICAgICAgIEF0dHJpYnV0ZVR5cGU6IFwiU1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIEJpbGxpbmdNb2RlOiBcIlBBWV9QRVJfUkVRVUVTVFwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBhcHBseSBjdXN0b20gb3ZlcnJpZGVzXCIsICgpID0+IHtcbiAgICAgIG5ldyBOZXh0anNDYWNoZShzdGFjaywgXCJUZXN0Q2FjaGVcIiwge1xuICAgICAgICBidWlsZElkOiBcInRlc3QtYnVpbGQtMTIzXCIsXG4gICAgICAgIGluaXRDYWNoZURpcjogXCIvdG1wL3Rlc3QtY2FjaGVcIixcbiAgICAgICAgb3ZlcnJpZGVzOiB7XG4gICAgICAgICAgY2FjaGVCdWNrZXRQcm9wczoge1xuICAgICAgICAgICAgYnVja2V0TmFtZTogXCJjdXN0b20tY2FjaGUtYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXZhbGlkYXRpb25UYWJsZVByb3BzOiB7XG4gICAgICAgICAgICB0YWJsZU5hbWU6IFwiY3VzdG9tLXJldmFsaWRhdGlvbi10YWJsZVwiLFxuICAgICAgICAgICAgcGFydGl0aW9uS2V5OiB7XG4gICAgICAgICAgICAgIG5hbWU6IFwidGFnXCIsXG4gICAgICAgICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgICAgICAgbmFtZTogXCJjYWNoZUtleVwiLFxuICAgICAgICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICAgIEJ1Y2tldE5hbWU6IFwiY3VzdG9tLWNhY2hlLWJ1Y2tldFwiLFxuICAgICAgfSk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgVGFibGVOYW1lOiBcImN1c3RvbS1yZXZhbGlkYXRpb24tdGFibGVcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
274
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLWNhY2hlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzREFBc0Q7QUFDdEQsMkJBT1k7QUFDWiwyQkFBNEI7QUFDNUIsK0JBQTRCO0FBQzVCLDZDQUErQztBQUMvQyx1REFBeUQ7QUFDekQsMkRBQXlEO0FBQ3pELCtDQUE0QztBQUM1QyxxRUFBdUQ7QUFDdkQsaURBQTZDO0FBRTdDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFO0lBQzNCLElBQUksR0FBUSxDQUFDO0lBQ2IsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLGlCQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDbEMsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtZQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLDBCQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDaEQsT0FBTyxFQUFFLGdCQUFnQjtnQkFDekIsWUFBWSxFQUFFLGlCQUFpQjthQUNoQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxD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LEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDaEQsSUFBSSwwQkFBVyxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUU7Z0JBQ3JDLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixZQUFZO2dCQUNaLFNBQVMsRUFBRTtvQkFDVCxxQkFBcUIsRUFBRTt3QkFDckIsaUJBQWlCLEVBQUUsZUFBTSxDQUFDLGNBQWMsQ0FDdEMsUUFBUSxFQUNSLFVBQVUsRUFDVixzQkFBc0IsQ0FDdkI7d0JBQ0QsT0FBTyxFQUFFLENBQUMsMEJBQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUNyQyxvQkFBb0IsRUFBRSxrQkFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLFdBQVcsRUFBRSxJQUFJO3FCQUNsQjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLHFCQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDbEUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzVELE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBta2R0ZW1wU3luYyxcbiAgcmVhZGRpclN5bmMsXG4gIHJtU3luYyxcbiAgdHJ1bmNhdGVTeW5jLFxuICB3cml0ZUZpbGVTeW5jLFxufSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBBcHAsIFNpemUsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBNYXRjaCwgVGVtcGxhdGUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXNzZXJ0aW9uc1wiO1xuaW1wb3J0IHsgQXR0cmlidXRlVHlwZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZHluYW1vZGJcIjtcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHsgTmV4dGpzQ2FjaGUgfSBmcm9tIFwiLi9uZXh0anMtY2FjaGVcIjtcblxuZGVzY3JpYmUoXCJOZXh0anNDYWNoZVwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBuZXcgQXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBDb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTMyBidWNrZXQgYW5kIER5bmFtb0RCIHRhYmxlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gbmV3IE5leHRqc0NhY2hlKHN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwidGVzdC1idWlsZC0xMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyOiBcIi90bXAvdGVzdC1jYWNoZVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjYWNoZS5jYWNoZUJ1Y2tldCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5yZXZhbGlkYXRpb25UYWJsZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5idWlsZElkKS50b0JlKFwidGVzdC1idWlsZC0xMjNcIik7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IFMzIGJ1Y2tldCBpcyBjcmVhdGVkXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgICAgICBCdWNrZXRFbmNyeXB0aW9uOiB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQnlEZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgU1NFQWxnb3JpdGhtOiBcIkFFUzI1NlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBQdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBCbG9ja1B1YmxpY0FjbHM6IHRydWUsXG4gICAgICAgICAgQmxvY2tQdWJsaWNQb2xpY3k6IHRydWUsXG4gICAgICAgICAgSWdub3JlUHVibGljQWNsczogdHJ1ZSxcbiAgICAgICAgICBSZXN0cmljdFB1YmxpY0J1Y2tldHM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gVmVyaWZ5IER5bmFtb0RCIHRhYmxlIGlzIGNyZWF0ZWQgKFRhYmxlVjIgY3JlYXRlcyBHbG9iYWxUYWJsZSByZXNvdXJjZSlcbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgQXR0cmlidXRlTmFtZTogXCJwa1wiLFxuICAgICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInNrXCIsXG4gICAgICAgICAgICBLZXlUeXBlOiBcIlJBTkdFXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgQXR0cmlidXRlRGVmaW5pdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInBrXCIsXG4gICAgICAgICAgICBBdHRyaWJ1dGVUeXBlOiBcIlNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2tcIixcbiAgICAgICAgICAgIEF0dHJpYnV0ZVR5cGU6IFwiU1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIEJpbGxpbmdNb2RlOiBcIlBBWV9QRVJfUkVRVUVTVFwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBUaGUgJ3VzZSBjYWNoZScgcmV2YWxpZGF0aW9uIGxvZydzIHJvd3MgZXhwaXJlIHRocm91Z2ggYHR0bGAuXG4gICAgaXQoXCJleHBpcmVzIHJldmFsaWRhdGlvbiBsb2cgcm93cyB0aHJvdWdoIGEgVFRMIGF0dHJpYnV0ZVwiLCAoKSA9PiB7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUoc3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJ0ZXN0LWJ1aWxkLTEyM1wiLFxuICAgICAgICBpbml0Q2FjaGVEaXI6IFwiL3RtcC90ZXN0LWNhY2hlXCIsXG4gICAgICB9KTtcbiAgICAgIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFxuICAgICAgICBcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBUaW1lVG9MaXZlU3BlY2lmaWNhdGlvbjogeyBBdHRyaWJ1dGVOYW1lOiBcInR0bFwiLCBFbmFibGVkOiB0cnVlIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYXBwbHkgY3VzdG9tIG92ZXJyaWRlc1wiLCAoKSA9PiB7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUoc3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJ0ZXN0LWJ1aWxkLTEyM1wiLFxuICAgICAgICBpbml0Q2FjaGVEaXI6IFwiL3RtcC90ZXN0LWNhY2hlXCIsXG4gICAgICAgIG92ZXJyaWRlczoge1xuICAgICAgICAgIGNhY2hlQnVja2V0UHJvcHM6IHtcbiAgICAgICAgICAgIGJ1Y2tldE5hbWU6IFwiY3VzdG9tLWNhY2hlLWJ1Y2tldFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmV2YWxpZGF0aW9uVGFibGVQcm9wczoge1xuICAgICAgICAgICAgdGFibGVOYW1lOiBcImN1c3RvbS1yZXZhbGlkYXRpb24tdGFibGVcIixcbiAgICAgICAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICAgICAgICBuYW1lOiBcInRhZ1wiLFxuICAgICAgICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzb3J0S2V5OiB7XG4gICAgICAgICAgICAgIG5hbWU6IFwiY2FjaGVLZXlcIixcbiAgICAgICAgICAgICAgdHlwZTogQXR0cmlidXRlVHlwZS5TVFJJTkcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGltZVRvTGl2ZUF0dHJpYnV0ZTogXCJleHBpcmVzQXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICAgICAgQnVja2V0TmFtZTogXCJjdXN0b20tY2FjaGUtYnVja2V0XCIsXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpEeW5hbW9EQjo6R2xvYmFsVGFibGVcIiwge1xuICAgICAgICBUYWJsZU5hbWU6IFwiY3VzdG9tLXJldmFsaWRhdGlvbi10YWJsZVwiLFxuICAgICAgICBUaW1lVG9MaXZlU3BlY2lmaWNhdGlvbjogeyBBdHRyaWJ1dGVOYW1lOiBcImV4cGlyZXNBdFwiLCBFbmFibGVkOiB0cnVlIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJJbml0IGNhY2hlIGRlcGxveW1lbnRcIiwgKCkgPT4ge1xuICAgIGxldCBpbml0Q2FjaGVEaXI6IHN0cmluZztcbiAgICBsZXQgb3V0ZGlyOiBzdHJpbmc7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIGluaXRDYWNoZURpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwiaW5pdC1jYWNoZS1zcmMtXCIpKTtcbiAgICAgIG1rZGlyU3luYyhqb2luKGluaXRDYWNoZURpciwgXCJzZXJ2ZXJcIiwgXCJhcHBcIiksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgd3JpdGVGaWxlU3luYyhqb2luKGluaXRDYWNoZURpciwgXCJzZXJ2ZXJcIiwgXCJhcHBcIiwgXCJpbmRleC5odG1sXCIpLCBcIjxwLz5cIik7XG4gICAgICBvdXRkaXIgPSBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBcImluaXQtY2FjaGUtb3V0LVwiKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgcm1TeW5jKGluaXRDYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgcm1TeW5jKG91dGRpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRhZyBgQnVja2V0RGVwbG95bWVudGAgc3RhbXBzIG9uIGl0cyBkZXN0aW5hdGlvbiBidWNrZXQsIGFuZCB0aGUgb25seVxuICAgICAqIG9uZSB0aGF0IGNhbiB2YXJ5IGJldHdlZW4gdHdvIGJ1aWxkcy4gYFRhZ3NgIG9uIGFuIGBBV1M6OlMzOjpCdWNrZXRgIGFyZVxuICAgICAqIG5vdCBob3Rzd2FwcGFibGUsIHNvIGEgdGFnIGtleSB0aGF0IGNhcnJpZXMgdGhlIGJ1aWxkIElEIGNvc3RzIGEgZnVsbFxuICAgICAqIENsb3VkRm9ybWF0aW9uIGRlcGxveW1lbnQgb24gZXZlcnkgZGVwbG95LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG93bmVyVGFncyh0ZW1wbGF0ZTogVGVtcGxhdGUpOiBzdHJpbmdbXSB7XG4gICAgICBjb25zdCBidWNrZXRzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6UzM6OkJ1Y2tldFwiKTtcbiAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKGJ1Y2tldHMpXG4gICAgICAgIC5mbGF0TWFwKChidWNrZXQpID0+IGJ1Y2tldC5Qcm9wZXJ0aWVzPy5UYWdzID8/IFtdKVxuICAgICAgICAubWFwKCh0YWc6IHsgS2V5OiBzdHJpbmcgfSkgPT4gdGFnLktleSlcbiAgICAgICAgLmZpbHRlcigoa2V5KSA9PiBrZXkuc3RhcnRzV2l0aChcImF3cy1jZGs6Y3Itb3duZWRcIikpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN5bnRoKGJ1aWxkSWQ6IHN0cmluZykge1xuICAgICAgY29uc3Qgb3duQXBwID0gbmV3IEFwcCh7IG91dGRpcjogbWtkdGVtcFN5bmMoam9pbihvdXRkaXIsIFwiYXBwLVwiKSkgfSk7XG4gICAgICBjb25zdCBvd25TdGFjayA9IG5ldyBTdGFjayhvd25BcHAsIFwiVGVzdFN0YWNrXCIpO1xuICAgICAgbmV3IE5leHRqc0NhY2hlKG93blN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7IGJ1aWxkSWQsIGluaXRDYWNoZURpciB9KTtcbiAgICAgIHJldHVybiB7IGFwcDogb3duQXBwLCB0ZW1wbGF0ZTogVGVtcGxhdGUuZnJvbVN0YWNrKG93blN0YWNrKSB9O1xuICAgIH1cblxuICAgIGl0KFwia2V5cyB0aGUgb2JqZWN0cyB1bmRlciB0aGUgYnVpbGQgSUQgd2l0aG91dCBhIGRlc3RpbmF0aW9uS2V5UHJlZml4XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgYXBwOiBvd25BcHAsIHRlbXBsYXRlIH0gPSBzeW50aChcImJ1aWxkLWFiYzEyM1wiKTtcblxuICAgICAgLy8gTm90IGBEZXN0aW5hdGlvbkJ1Y2tldEtleVByZWZpeDogTWF0Y2guYWJzZW50KClgIG9uIGl0cyBvd246IHRoYXQgd291bGRcbiAgICAgIC8vIGFsc28gcGFzcyBpZiB0aGUgc3RhZ2VkIHRyZWUgaGFkIGxvc3QgdGhlIGJ1aWxkIElELCB3aGljaCBpcyB3aGF0IGtlZXBzXG4gICAgICAvLyB0aGUgUzMga2V5cyB0aGUgc2FtZSBhcyBiZWZvcmUgdGhpcyBtb3ZlZC5cbiAgICAgIGNvbnN0IGRlcGxveW1lbnRzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkN1c3RvbTo6Q0RLQnVja2V0RGVwbG95bWVudFwiKTtcbiAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhkZXBsb3ltZW50cykpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICAgIGV4cGVjdChPYmplY3QudmFsdWVzKGRlcGxveW1lbnRzKVswXS5Qcm9wZXJ0aWVzKS5ub3QudG9IYXZlUHJvcGVydHkoXG4gICAgICAgIFwiRGVzdGluYXRpb25CdWNrZXRLZXlQcmVmaXhcIixcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGFzc2VtYmx5ID0gb3duQXBwLnN5bnRoKCk7XG4gICAgICBjb25zdCBzdGFnZWRVbmRlckJ1aWxkSWQgPSByZWFkZGlyU3luYyhhc3NlbWJseS5kaXJlY3RvcnksIHtcbiAgICAgICAgd2l0aEZpbGVUeXBlczogdHJ1ZSxcbiAgICAgIH0pLnNvbWUoXG4gICAgICAgIChlbnRyeSkgPT5cbiAgICAgICAgICBlbnRyeS5pc0RpcmVjdG9yeSgpICYmXG4gICAgICAgICAgZW50cnkubmFtZS5zdGFydHNXaXRoKFwiYXNzZXQuXCIpICYmXG4gICAgICAgICAgcmVhZGRpclN5bmMoam9pbihhc3NlbWJseS5kaXJlY3RvcnksIGVudHJ5Lm5hbWUpKS5pbmNsdWRlcyhcbiAgICAgICAgICAgIFwiYnVpbGQtYWJjMTIzXCIsXG4gICAgICAgICAgKSxcbiAgICAgICk7XG4gICAgICBleHBlY3Qoc3RhZ2VkVW5kZXJCdWlsZElkKS50b0JlKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJyZW1vdmVzIGl0cyB0ZW1wb3Jhcnkgc3RhZ2luZyBjb3B5IG9uY2UgdGhlIGFzc2V0IGlzIHN0YWdlZFwiLCAoKSA9PiB7XG4gICAgICAvLyBgU291cmNlLmFzc2V0YCBzdGFnZXMgZHVyaW5nIGBCdWNrZXREZXBsb3ltZW50YCdzIGNvbnN0cnVjdGlvbiwgc28gdGhlXG4gICAgICAvLyBjb3B5IGlzIGRlYWQgYXMgc29vbiBhcyB0aGF0IHJldHVybnMgLSBhbmQgaXQgaXMgYSB3aG9sZSBpbml0IGNhY2hlLFxuICAgICAgLy8gbWVhc3VyZWQgYXQgNjY0IE1pQi4gTGVhdmluZyBvbmUgcGVyIHN5bnRoIHB1dCB+MTUgR0IgaW4gdGhlIHN5c3RlbSB0ZW1wXG4gICAgICAvLyBkaXJlY3Rvcnkgb3ZlciBhIENJIGxvb3Agb2YgfjIyIGRlcGxveXMuXG4gICAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQoXG4gICAgICAgIHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoKG5hbWUpID0+XG4gICAgICAgICAgbmFtZS5zdGFydHNXaXRoKFwibmV4dGpzLWluaXQtY2FjaGUtXCIpLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgc3ludGgoXCJidWlsZC1hYmMxMjNcIikuYXBwLnN5bnRoKCk7XG5cbiAgICAgIGNvbnN0IGxlYWtlZCA9IHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiBuYW1lLnN0YXJ0c1dpdGgoXCJuZXh0anMtaW5pdC1jYWNoZS1cIikgJiYgIWV4aXN0aW5nLmhhcyhuYW1lKSxcbiAgICAgICk7XG4gICAgICBleHBlY3QobGVha2VkKS50b0VxdWFsKFtdKTtcbiAgICB9KTtcblxuICAgIGl0KFwidGFncyB0aGUgY2FjaGUgYnVja2V0IHRoZSBzYW1lIHdheSB3aGF0ZXZlciB0aGUgYnVpbGQgSURcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZmlyc3QgPSBvd25lclRhZ3Moc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuICAgICAgY29uc3Qgc2Vjb25kID0gb3duZXJUYWdzKHN5bnRoKFwiYnVpbGQtZGVmNDU2XCIpLnRlbXBsYXRlKTtcblxuICAgICAgZXhwZWN0KGZpcnN0KS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICBleHBlY3QoZmlyc3RbMF0pLnRvTWF0Y2goL15hd3MtY2RrOmNyLW93bmVkOlswLTlhLWZdezh9JC8pO1xuICAgICAgZXhwZWN0KHNlY29uZCkudG9FcXVhbChmaXJzdCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW56aXAgTGFtYmRhIGhvbGRzIHRoZSBhc3NldCB6aXAgYW5kIGl0cyBleHRyYWN0ZWQgY29udGVudHMgaW4gYC90bXBgXG4gICAgICogYXQgb25jZSwgc28gYSBzZWVkIGRpcmVjdG9yeSBiaWdnZXIgdGhhbiB0aGUgNTEyIE1pQiBDREsgYXNrcyBmb3IgYnlcbiAgICAgKiBkZWZhdWx0IGtpbGxzIGl0IHdpdGggYFtFcnJubyAyOF0gTm8gc3BhY2UgbGVmdCBvbiBkZXZpY2VgIOKAlCBhbmQgdW5kZXJcbiAgICAgKiBgY2RrIGRlcGxveSAtLWhvdHN3YXBgIHRoYXQgZmFpbHVyZSBpcyBpbnZpc2libGUsIGJlY2F1c2UgdGhlIENMSSBoYW5kcyB0aGVcbiAgICAgKiBjdXN0b20gcmVzb3VyY2UgYSBwbGFjZWhvbGRlciByZXNwb25zZSBVUkwgYW5kIG5ldmVyIHJlYWRzIGl0cyBzdGF0dXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVwbG95bWVudExhbWJkYSh0ZW1wbGF0ZTogVGVtcGxhdGUpIHtcbiAgICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoXCJBV1M6OkxhbWJkYTo6RnVuY3Rpb25cIiwge1xuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgSGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgUnVudGltZTogTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cChcIl5weXRob25cIiksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhmdW5jdGlvbnMpKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhmdW5jdGlvbnMpWzBdLlByb3BlcnRpZXM7XG4gICAgfVxuXG4gICAgaXQoXCJsZWF2ZXMgYSBzbWFsbCBpbml0IGNhY2hlIG9uIHRoZSBkZWZhdWx0IExhbWJkYSBzaXppbmdcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuXG4gICAgICAvLyBUaGUgZmxvb3IsIG5vdCBhIGNvbXB1dGVkIHZhbHVlOiBhIGhhbmRmdWwgb2YgYnl0ZXMgc3RpbGwgd2FudHMgNTEyIE1pQlxuICAgICAgLy8gYmVjYXVzZSB0aGF0IGlzIHRoZSBsZWFzdCBMYW1iZGEgd2lsbCBnaXZlLlxuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuRXBoZW1lcmFsU3RvcmFnZSkudG9FcXVhbCh7IFNpemU6IDUxMiB9KTtcbiAgICAgIC8vIEFic2VudCwgbm90IDEyODogbGVhdmluZyBgbWVtb3J5TGltaXRgIGFsb25lIGtlZXBzIHRoZSBwcm9wZXJ0eSBvdXQgb2ZcbiAgICAgIC8vIHRoZSB0ZW1wbGF0ZSwgd2hpY2ggaXMgTGFtYmRhJ3Mgb3duIDEyOCBNQiBkZWZhdWx0LlxuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuTWVtb3J5U2l6ZSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzY2FsZXMgL3RtcCBhbmQgbWVtb3J5IHRvIGEgbGFyZ2UgaW5pdCBjYWNoZVwiLCAoKSA9PiB7XG4gICAgICAvLyBBIHNwYXJzZSBmaWxlOiBgc3RhdFN5bmNgIHJlcG9ydHMgMzAwIE1pQiwgdGhlIGZpbGVzeXN0ZW0gc3RvcmVzIGFsbW9zdFxuICAgICAgLy8gbm90aGluZywgYW5kIHRoZSB6aXAgb2YgYSAzMDAgTWlCIGhvbGUgY29zdHMgbm8gcmVhbCB3b3JrLlxuICAgICAgY29uc3QgYmlnID0gam9pbihpbml0Q2FjaGVEaXIsIFwic2VydmVyXCIsIFwiYXBwXCIsIFwiYmlnLnJzY1wiKTtcbiAgICAgIHdyaXRlRmlsZVN5bmMoYmlnLCBcIlwiKTtcbiAgICAgIHRydW5jYXRlU3luYyhiaWcsIDMwMCAqIDEwMjQgKiAxMDI0KTtcblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuXG4gICAgICAvLyAzMDEgTWlCIG9mIGNhY2hlIOKAlCB0aGUgMzAwIE1pQiBob2xlIHBsdXMgdGhlIGZpeHR1cmUncyBvd24gZmlsZSwgcm91bmRlZFxuICAgICAgLy8gdXAg4oCUIGRvdWJsZWQgZm9yIHRoZSB6aXAgdGhhdCBzaXRzIGJlc2lkZSBpdCwgcGx1cyBoZWFkcm9vbTogNzMwIE1pQixcbiAgICAgIC8vIHJvdW5kZWQgdXAgdG8gdGhlIG5leHQgc3RlcC5cbiAgICAgIGV4cGVjdChwcm9wZXJ0aWVzLkVwaGVtZXJhbFN0b3JhZ2UpLnRvRXF1YWwoeyBTaXplOiAxMDI0IH0pO1xuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuTWVtb3J5U2l6ZSkudG9CZSgxMDI0KTtcbiAgICB9KTtcblxuICAgIGl0KFwia2VlcHMgdGhlIGRlcGxveW1lbnQncyBpZGVudGl0eSB3aGlsZSB0aGUgY2FjaGUgZ3Jvd3MgYnkgYSBsaXR0bGVcIiwgKCkgPT4ge1xuICAgICAgLy8gYGVwaGVtZXJhbFN0b3JhZ2VTaXplYCBpcyBwYXJ0IG9mIHRoZSBzaW5nbGV0b24gaGFuZGxlcidzIFVVSUQgYW5kIHRoZVxuICAgICAgLy8gY3VzdG9tIHJlc291cmNlJ3MgbG9naWNhbCBJRC4gU2l6ZWQgdG8gdGhlIE1pQiwgYSBjYWNoZSA1IE1pQiBiaWdnZXJcbiAgICAgIC8vIHRoYW4gdGhlIGxhc3QgZGVwbG95J3Mgd2FzIGEgbmV3IGhhbmRsZXIgTGFtYmRhLCBhIG5ldyBTZXJ2aWNlVG9rZW5cbiAgICAgIC8vIGFuZCBhIHJlcGxhY2VkIGN1c3RvbSByZXNvdXJjZSAtIGEgZnVsbCBkZXBsb3ltZW50LCBub3QgYSBob3Rzd2FwLlxuICAgICAgY29uc3QgYmlnID0gam9pbihpbml0Q2FjaGVEaXIsIFwic2VydmVyXCIsIFwiYXBwXCIsIFwiYmlnLnJzY1wiKTtcbiAgICAgIGNvbnN0IGxvZ2ljYWxJZHMgPSAobWliOiBudW1iZXIpID0+IHtcbiAgICAgICAgd3JpdGVGaWxlU3luYyhiaWcsIFwiXCIpO1xuICAgICAgICB0cnVuY2F0ZVN5bmMoYmlnLCBtaWIgKiAxMDI0ICogMTAyNCk7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGU7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgLi4uT2JqZWN0LmtleXModGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkN1c3RvbTo6Q0RLQnVja2V0RGVwbG95bWVudFwiKSksXG4gICAgICAgICAgLi4uT2JqZWN0LmtleXModGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6TGFtYmRhOjpGdW5jdGlvblwiKSksXG4gICAgICAgIF0uc29ydCgpO1xuICAgICAgfTtcblxuICAgICAgZXhwZWN0KGxvZ2ljYWxJZHMoMzA1KSkudG9FcXVhbChsb2dpY2FsSWRzKDMwMCkpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJrZWVwcyB0aGUgc3RhZ2luZyBjb3B5IHdoZW4gYXNzZXQgc3RhZ2luZyBpcyBkaXNhYmxlZFwiLCAoKSA9PiB7XG4gICAgICAvLyBgLS1uby1zdGFnaW5nYCAoYW5kIFNBTSkgbGVhdmVzIHRoZSBhc3NldCB3aGVyZSBpdCBpcyByYXRoZXIgdGhhblxuICAgICAgLy8gY29weWluZyBpdCBpbnRvIGBjZGsub3V0YCwgc28gdGhlIHN0YWdpbmcgY29weSAqaXMqIHRoZSBhc3NldCwgYW5kIHRoZVxuICAgICAgLy8gcHVibGlzaCBhZnRlciBzeW50aCBuZWVkcyBpdC5cbiAgICAgIGNvbnN0IG93bkFwcCA9IG5ldyBBcHAoe1xuICAgICAgICBvdXRkaXI6IG1rZHRlbXBTeW5jKGpvaW4ob3V0ZGlyLCBcImFwcC1cIikpLFxuICAgICAgICBjb250ZXh0OiB7IFwiYXdzOmNkazpkaXNhYmxlLWFzc2V0LXN0YWdpbmdcIjogdHJ1ZSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQoXG4gICAgICAgIHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoKG5hbWUpID0+XG4gICAgICAgICAgbmFtZS5zdGFydHNXaXRoKFwibmV4dGpzLWluaXQtY2FjaGUtXCIpLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgbmV3IE5leHRqc0NhY2hlKG5ldyBTdGFjayhvd25BcHAsIFwiVGVzdFN0YWNrXCIpLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwiYnVpbGQtYWJjMTIzXCIsXG4gICAgICAgIGluaXRDYWNoZURpcixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBrZXB0ID0gcmVhZGRpclN5bmModG1wZGlyKCkpLmZpbHRlcihcbiAgICAgICAgKG5hbWUpID0+IG5hbWUuc3RhcnRzV2l0aChcIm5leHRqcy1pbml0LWNhY2hlLVwiKSAmJiAhZXhpc3RpbmcuaGFzKG5hbWUpLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChrZXB0KS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICBybVN5bmMoam9pbih0bXBkaXIoKSwga2VwdFswXSksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwibGV0cyBvdmVycmlkZXMgd2luIG92ZXIgdGhlIGNvbXB1dGVkIHNpemluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBvd25BcHAgPSBuZXcgQXBwKHsgb3V0ZGlyOiBta2R0ZW1wU3luYyhqb2luKG91dGRpciwgXCJhcHAtXCIpKSB9KTtcbiAgICAgIGNvbnN0IG93blN0YWNrID0gbmV3IFN0YWNrKG93bkFwcCwgXCJUZXN0U3RhY2tcIik7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUob3duU3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJidWlsZC1hYmMxMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyLFxuICAgICAgICBvdmVycmlkZXM6IHtcbiAgICAgICAgICBidWNrZXREZXBsb3ltZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoXG4gICAgICAgICAgICAgIG93blN0YWNrLFxuICAgICAgICAgICAgICBcIkV4aXN0aW5nXCIsXG4gICAgICAgICAgICAgIFwic29tZW9uZS1lbHNlcy1idWNrZXRcIixcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzb3VyY2VzOiBbU291cmNlLmRhdGEoXCJtYXJrZXJcIiwgXCJ4XCIpXSxcbiAgICAgICAgICAgIGVwaGVtZXJhbFN0b3JhZ2VTaXplOiBTaXplLmdpYmlieXRlcygyKSxcbiAgICAgICAgICAgIG1lbW9yeUxpbWl0OiAyMDQ4LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoVGVtcGxhdGUuZnJvbVN0YWNrKG93blN0YWNrKSk7XG4gICAgICBleHBlY3QocHJvcGVydGllcy5FcGhlbWVyYWxTdG9yYWdlKS50b0VxdWFsKHsgU2l6ZTogMjA0OCB9KTtcbiAgICAgIGV4cGVjdChwcm9wZXJ0aWVzLk1lbW9yeVNpemUpLnRvQmUoMjA0OCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=