cdk-nextjs 0.6.2 → 0.7.1

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 (263) hide show
  1. package/.jsii +2404 -2723
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +1681 -1930
  4. package/CLAUDE.md +2 -1
  5. package/README.md +429 -130
  6. package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
  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 +667 -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 +1551 -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 +857 -0
  28. package/lib/adapter/build-outputs.test.d.ts +1 -0
  29. package/lib/adapter/build-outputs.test.js +863 -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 +8 -0
  79. package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
  80. package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
  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/prune-cache-bucket.d.ts +7 -3
  85. package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
  86. package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
  87. package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
  88. package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
  89. package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
  90. package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
  91. package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
  92. package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
  93. package/lib/lambdas/post-deploy/prune-s3.js +41 -12
  94. package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
  95. package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
  96. package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
  97. package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
  98. package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
  99. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
  100. package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
  101. package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
  102. package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
  103. package/lib/nextjs-api.d.ts +102 -18
  104. package/lib/nextjs-api.js +338 -38
  105. package/lib/nextjs-api.test.js +537 -1
  106. package/lib/nextjs-build/global-containers.Dockerfile +15 -10
  107. package/lib/nextjs-build/nextjs-build.d.ts +339 -63
  108. package/lib/nextjs-build/nextjs-build.js +684 -327
  109. package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
  110. package/lib/nextjs-build/nextjs-build.test.js +412 -0
  111. package/lib/nextjs-build/patch-fetch.js +1 -1
  112. package/lib/nextjs-build/patch-fetch.test.js +166 -11
  113. package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
  114. package/lib/nextjs-cache.d.ts +82 -4
  115. package/lib/nextjs-cache.js +186 -10
  116. package/lib/nextjs-cache.test.js +176 -1
  117. package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
  118. package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
  119. package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
  120. package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
  121. package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
  122. package/lib/nextjs-compute/nextjs-containers.js +57 -20
  123. package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
  124. package/lib/nextjs-compute/nextjs-functions.js +113 -67
  125. package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
  126. package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
  127. package/lib/nextjs-distribution.d.ts +194 -23
  128. package/lib/nextjs-distribution.js +535 -62
  129. package/lib/nextjs-distribution.test.d.ts +1 -0
  130. package/lib/nextjs-distribution.test.js +697 -0
  131. package/lib/nextjs-post-deploy.d.ts +13 -5
  132. package/lib/nextjs-post-deploy.js +13 -10
  133. package/lib/nextjs-post-deploy.test.d.ts +1 -0
  134. package/lib/nextjs-post-deploy.test.js +34 -0
  135. package/lib/nextjs-static-assets.d.ts +17 -4
  136. package/lib/nextjs-static-assets.js +22 -5
  137. package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
  138. package/lib/root-constructs/nextjs-base-construct.js +139 -47
  139. package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
  140. package/lib/root-constructs/nextjs-global-containers.js +20 -71
  141. package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
  142. package/lib/root-constructs/nextjs-global-functions.js +52 -70
  143. package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
  144. package/lib/root-constructs/nextjs-regional-containers.js +8 -15
  145. package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
  146. package/lib/root-constructs/nextjs-regional-functions.js +8 -26
  147. package/lib/runtime/api-gateway-path.d.ts +34 -0
  148. package/lib/runtime/api-gateway-path.js +71 -0
  149. package/lib/runtime/api-gateway-path.test.d.ts +1 -0
  150. package/lib/runtime/api-gateway-path.test.js +65 -0
  151. package/lib/runtime/case-redirect.d.ts +22 -0
  152. package/lib/runtime/case-redirect.js +63 -0
  153. package/lib/runtime/case-redirect.test.d.ts +1 -0
  154. package/lib/runtime/case-redirect.test.js +32 -0
  155. package/lib/runtime/core.d.ts +234 -0
  156. package/lib/runtime/core.js +1216 -0
  157. package/lib/runtime/core.test.d.ts +1 -0
  158. package/lib/runtime/core.test.js +1686 -0
  159. package/lib/runtime/deployment-root.d.ts +13 -0
  160. package/lib/runtime/deployment-root.js +29 -0
  161. package/lib/runtime/dispatch.d.ts +331 -0
  162. package/lib/runtime/dispatch.js +751 -0
  163. package/lib/runtime/dispatch.test.d.ts +1 -0
  164. package/lib/runtime/dispatch.test.js +853 -0
  165. package/lib/runtime/entrypoints.d.ts +57 -0
  166. package/lib/runtime/entrypoints.js +115 -0
  167. package/lib/runtime/http/abort-signal.d.ts +6 -0
  168. package/lib/runtime/http/abort-signal.js +19 -0
  169. package/lib/runtime/http/abort-signal.test.d.ts +1 -0
  170. package/lib/runtime/http/abort-signal.test.js +49 -0
  171. package/lib/runtime/http/node-server.d.ts +38 -0
  172. package/lib/runtime/http/node-server.js +99 -0
  173. package/lib/runtime/http/node-server.test.d.ts +1 -0
  174. package/lib/runtime/http/node-server.test.js +96 -0
  175. package/lib/runtime/http/node-sink.d.ts +16 -0
  176. package/lib/runtime/http/node-sink.js +48 -0
  177. package/lib/runtime/http/node-sink.test.d.ts +1 -0
  178. package/lib/runtime/http/node-sink.test.js +66 -0
  179. package/lib/runtime/http/request.d.ts +62 -0
  180. package/lib/runtime/http/request.js +134 -0
  181. package/lib/runtime/http/request.test.d.ts +1 -0
  182. package/lib/runtime/http/request.test.js +103 -0
  183. package/lib/runtime/http/response.d.ts +77 -0
  184. package/lib/runtime/http/response.js +229 -0
  185. package/lib/runtime/http/response.test.d.ts +1 -0
  186. package/lib/runtime/http/response.test.js +178 -0
  187. package/lib/runtime/http/sink.d.ts +73 -0
  188. package/lib/runtime/http/sink.js +188 -0
  189. package/lib/runtime/http/sink.test.d.ts +1 -0
  190. package/lib/runtime/http/sink.test.js +257 -0
  191. package/lib/runtime/image-utils.d.ts +78 -0
  192. package/lib/runtime/image-utils.js +129 -0
  193. package/lib/runtime/image-utils.test.d.ts +1 -0
  194. package/lib/runtime/image-utils.test.js +237 -0
  195. package/lib/runtime/image.d.ts +76 -0
  196. package/lib/runtime/image.js +296 -0
  197. package/lib/runtime/image.test.d.ts +1 -0
  198. package/lib/runtime/image.test.js +405 -0
  199. package/lib/runtime/lambda-event.d.ts +4 -0
  200. package/lib/runtime/lambda-event.js +113 -0
  201. package/lib/runtime/lambda-event.test.d.ts +1 -0
  202. package/lib/runtime/lambda-event.test.js +119 -0
  203. package/lib/runtime/lambda.mjs +41600 -0
  204. package/lib/runtime/load-module.d.ts +8 -0
  205. package/lib/runtime/load-module.js +35 -0
  206. package/lib/runtime/manifest.d.ts +215 -0
  207. package/lib/runtime/manifest.js +118 -0
  208. package/lib/runtime/middleware.d.ts +43 -0
  209. package/lib/runtime/middleware.js +113 -0
  210. package/lib/runtime/middleware.test.d.ts +1 -0
  211. package/lib/runtime/middleware.test.js +259 -0
  212. package/lib/runtime/next-modules.d.ts +71 -0
  213. package/lib/runtime/next-modules.js +144 -0
  214. package/lib/runtime/next-modules.test.d.ts +1 -0
  215. package/lib/runtime/next-modules.test.js +34 -0
  216. package/lib/runtime/public-files.d.ts +32 -0
  217. package/lib/runtime/public-files.js +117 -0
  218. package/lib/runtime/public-files.test.d.ts +1 -0
  219. package/lib/runtime/public-files.test.js +97 -0
  220. package/lib/runtime/server.mjs +41593 -0
  221. package/lib/runtime/static-files.d.ts +50 -0
  222. package/lib/runtime/static-files.js +266 -0
  223. package/lib/runtime/static-files.test.d.ts +1 -0
  224. package/lib/runtime/static-files.test.js +118 -0
  225. package/lib/runtime/util.d.ts +28 -0
  226. package/lib/runtime/util.js +79 -0
  227. package/lib/utils/base-path.d.ts +106 -13
  228. package/lib/utils/base-path.js +254 -41
  229. package/lib/utils/base-path.test.js +219 -51
  230. package/lib/utils/get-architecture.d.ts +7 -8
  231. package/lib/utils/get-architecture.js +12 -13
  232. package/lib/utils/zip-directory.d.ts +14 -0
  233. package/lib/utils/zip-directory.js +121 -0
  234. package/lib/utils/zip-directory.test.d.ts +1 -0
  235. package/lib/utils/zip-directory.test.js +99 -0
  236. package/package.json +22 -3
  237. package/scripts/capture-adapter-fixture.mjs +325 -0
  238. package/scripts/e2e-deploy.sh +398 -0
  239. package/scripts/e2e-harness/README.md +707 -0
  240. package/scripts/e2e-harness/app.js +370 -0
  241. package/scripts/e2e-harness/common.sh +249 -0
  242. package/scripts/e2e-harness/screen.mjs +302 -0
  243. package/scripts/e2e-harness/stage-proxy.mjs +145 -0
  244. package/scripts/e2e-harness/type-filters.mjs +47 -0
  245. package/scripts/e2e-logs.sh +75 -0
  246. package/scripts/e2e-offline.sh +91 -0
  247. package/scripts/e2e-sweep.sh +370 -0
  248. package/scripts/e2e-warm.sh +114 -0
  249. package/scripts/zero-config-build.mjs +418 -0
  250. package/docs/1k-concurrent-users-executions.png +0 -0
  251. package/docs/plans/adapter-runtime-release.md +0 -362
  252. package/docs/plans/phase-0-image-function-opt-in.md +0 -295
  253. package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
  254. package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
  255. package/lib/image-optimization/handler-utils.d.ts +0 -34
  256. package/lib/image-optimization/handler-utils.js +0 -83
  257. package/lib/image-optimization/handler-utils.test.js +0 -178
  258. package/lib/nextjs-build/functions.Dockerfile +0 -31
  259. package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
  260. package/lib/nextjs-compute/nextjs-image-function.js +0 -59
  261. package/lib/utils/experimental-flags.d.ts +0 -24
  262. package/lib/utils/experimental-flags.js +0 -30
  263. /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
@@ -6,7 +6,26 @@ const assertions_1 = require("aws-cdk-lib/assertions");
6
6
  const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
7
7
  const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
8
8
  const aws_s3_1 = require("aws-cdk-lib/aws-s3");
9
+ const function_groups_1 = require("./adapter/function-groups");
9
10
  const nextjs_api_1 = require("./nextjs-api");
11
+ /**
12
+ * `functionGroups` and the `functionGroupBehaviors` the build would record for
13
+ * them: `routes` as routed (an optional catch-all's parent listed by hand),
14
+ * with data-URL behaviors for a group that owns a Pages Router page.
15
+ */
16
+ function grouped(groups) {
17
+ return {
18
+ functionGroups: groups.map(({ name, function: fn }) => ({
19
+ name,
20
+ function: fn,
21
+ })),
22
+ functionGroupBehaviors: groups.flatMap((group) => group.routes.flatMap((route) => (0, function_groups_1.pathPatternsFor)(route, {
23
+ hasDataRoutes: group.hasDataRoutes ?? false,
24
+ trailingSlash: group.trailingSlash,
25
+ buildId: "abc123",
26
+ }).map((pattern) => ({ group: group.name, route, pattern })))),
27
+ };
28
+ }
10
29
  describe("NextjsApi", () => {
11
30
  let stack;
12
31
  beforeEach(() => {
@@ -61,6 +80,46 @@ describe("NextjsApi", () => {
61
80
  createApi("/branch-x/");
62
81
  expect(s3IntegrationKeys()).toContain("branch-x/_next/static/{key}");
63
82
  });
83
+ /** The statements of the API Gateway → S3 integration role's policy. */
84
+ function staticIntegrationStatements() {
85
+ const policies = assertions_1.Template.fromStack(stack).findResources("AWS::IAM::Policy", {
86
+ Properties: {
87
+ Roles: [{ Ref: assertions_1.Match.stringLikeRegexp("StaticIntegrationRole") }],
88
+ },
89
+ });
90
+ return Object.values(policies).flatMap((policy) => policy.Properties.PolicyDocument.Statement);
91
+ }
92
+ it("scopes the S3 integration role to the static assets key prefix", () => {
93
+ // A shared bucket holds other apps' assets under their own prefixes.
94
+ createApi("/branch-x/");
95
+ const bucketArn = {
96
+ "Fn::Join": ["", ["arn:", { Ref: "AWS::Partition" }, ":s3:::my-bucket"]],
97
+ };
98
+ expect(staticIntegrationStatements()).toEqual([
99
+ {
100
+ Action: "s3:GetObject",
101
+ Effect: "Allow",
102
+ Resource: {
103
+ "Fn::Join": [
104
+ "",
105
+ ["arn:", { Ref: "AWS::Partition" }, ":s3:::my-bucket/branch-x/*"],
106
+ ],
107
+ },
108
+ },
109
+ {
110
+ // Unconditioned: S3 checks it during a GetObject, with no `s3:prefix`.
111
+ Action: "s3:ListBucket",
112
+ Effect: "Allow",
113
+ Resource: bucketArn,
114
+ },
115
+ ]);
116
+ });
117
+ it("lets the S3 integration role read the whole bucket without a key prefix", () => {
118
+ createApi();
119
+ const statements = staticIntegrationStatements();
120
+ expect(statements).toHaveLength(2);
121
+ expect(statements[0].Resource["Fn::Join"][1]).toContain(":s3:::my-bucket/*");
122
+ });
64
123
  it("keeps the key prefix independent of basePath, which is the URL prefix", () => {
65
124
  // A NextjsRegionalFunctions app whose `basePath` matches the API Gateway
66
125
  // stage still has its assets at the bucket root.
@@ -185,5 +244,482 @@ describe("NextjsApi", () => {
185
244
  }))).toBe("https://{NextjsApiRestApiCustomDomain}/team-a");
186
245
  });
187
246
  });
247
+ describe("functionGroups resource tree", () => {
248
+ /** Lambda functions that `ANY` on the resource at `pathPart` invokes. */
249
+ function anyTargets(pathPart) {
250
+ const template = assertions_1.Template.fromStack(stack);
251
+ const resources = template.findResources("AWS::ApiGateway::Resource", {
252
+ Properties: { PathPart: pathPart },
253
+ });
254
+ const ids = Object.keys(resources);
255
+ expect(ids).toHaveLength(1);
256
+ const methods = template.findResources("AWS::ApiGateway::Method", {
257
+ Properties: { HttpMethod: "ANY", ResourceId: { Ref: ids[0] } },
258
+ });
259
+ return Object.values(methods).map((method) => JSON.stringify(method.Properties.Integration.Uri).match(/(ServerFn|GroupFn|ReportsFn)[A-F0-9]+/)[1]);
260
+ }
261
+ it("sends a group's parent paths to the default function", () => {
262
+ // API Gateway answers a methodless resource with 403 rather than falling
263
+ // back to the root `{proxy+}`, so `/api` and `/api/reports` need one.
264
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
265
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
266
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
267
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
268
+ handler: "index.handler",
269
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
270
+ }),
271
+ publicDirEntries: [],
272
+ ...grouped([
273
+ {
274
+ name: "reports",
275
+ routes: ["/api/reports/**", "/api/export"],
276
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
277
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
278
+ handler: "index.handler",
279
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
280
+ }),
281
+ },
282
+ ]),
283
+ });
284
+ expect(anyTargets("api")).toEqual(["ServerFn"]);
285
+ expect(anyTargets("reports")).toEqual(["ServerFn"]);
286
+ expect(anyTargets("export")).toEqual(["GroupFn"]);
287
+ });
288
+ it("sends a parent under another group's subtree to that group", () => {
289
+ // `assignRoutesToGroups` packages `/api/reports` into `api`, and
290
+ // CloudFront's `api/*` sends it there; so must API Gateway.
291
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
292
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
293
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
294
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
295
+ handler: "index.handler",
296
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
297
+ }),
298
+ publicDirEntries: [],
299
+ ...grouped([
300
+ {
301
+ name: "api",
302
+ routes: ["/api/**"],
303
+ hasDataRoutes: true,
304
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
305
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
306
+ handler: "index.handler",
307
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
308
+ }),
309
+ },
310
+ {
311
+ name: "reports",
312
+ routes: ["/api/reports/q1/**"],
313
+ hasDataRoutes: true,
314
+ function: new aws_lambda_1.Function(stack, "ReportsFn", {
315
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
316
+ handler: "index.handler",
317
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
318
+ }),
319
+ },
320
+ ]),
321
+ });
322
+ // Each path part below appears twice, under `/` and under the data
323
+ // prefix, so check the tree by path.
324
+ const targets = anyTargetsByPath();
325
+ expect(targets["/api"]).toEqual(["ServerFn"]);
326
+ expect(targets["/api/reports"]).toEqual(["GroupFn"]);
327
+ expect(targets["/api/reports/q1"]).toEqual(["GroupFn"]);
328
+ expect(targets["/api/reports/q1/{proxy+}"]).toEqual(["ReportsFn"]);
329
+ expect(targets["/_next/data/{buildId}/api/reports"]).toEqual(["GroupFn"]);
330
+ expect(targets["/_next/data/{buildId}"]).toEqual(["ServerFn"]);
331
+ });
332
+ function createGroupedApi(hasDataRoutes) {
333
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
334
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
335
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
336
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
337
+ handler: "index.handler",
338
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
339
+ }),
340
+ publicDirEntries: [],
341
+ ...grouped([
342
+ {
343
+ name: "reports",
344
+ routes: ["/reports/**", "/docs/intro"],
345
+ hasDataRoutes,
346
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
347
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
348
+ handler: "index.handler",
349
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
350
+ }),
351
+ },
352
+ ]),
353
+ });
354
+ }
355
+ /** Every resource path in the API, e.g. `/_next/data/{buildId}/x.json`. */
356
+ function resourcePaths() {
357
+ const resources = assertions_1.Template.fromStack(stack).findResources("AWS::ApiGateway::Resource");
358
+ const pathOf = (id) => {
359
+ const { ParentId, PathPart } = resources[id].Properties;
360
+ const parent = ParentId.Ref;
361
+ return parent && resources[parent]
362
+ ? `${pathOf(parent)}/${PathPart}`
363
+ : `/${PathPart}`;
364
+ };
365
+ return Object.keys(resources).map(pathOf).sort();
366
+ }
367
+ /** Resource path → the Lambda functions `ANY` on it invokes. */
368
+ function anyTargetsByPath() {
369
+ const template = assertions_1.Template.fromStack(stack);
370
+ const resources = template.findResources("AWS::ApiGateway::Resource");
371
+ const pathOf = (id) => {
372
+ const { ParentId, PathPart } = resources[id].Properties;
373
+ const parent = ParentId.Ref;
374
+ return parent && resources[parent]
375
+ ? `${pathOf(parent)}/${PathPart}`
376
+ : `/${PathPart}`;
377
+ };
378
+ const methods = template.findResources("AWS::ApiGateway::Method", {
379
+ Properties: { HttpMethod: "ANY" },
380
+ });
381
+ const targets = {};
382
+ for (const method of Object.values(methods)) {
383
+ const id = method.Properties.ResourceId?.Ref;
384
+ if (!id || !resources[id])
385
+ continue;
386
+ (targets[pathOf(id)] ??= []).push(JSON.stringify(method.Properties.Integration.Uri).match(/(ServerFn|GroupFn|ReportsFn)[A-F0-9]+/)[1]);
387
+ }
388
+ return targets;
389
+ }
390
+ it("routes a group's Pages Router data URLs to it too", () => {
391
+ createGroupedApi(true);
392
+ const paths = resourcePaths();
393
+ expect(paths).toContain("/_next/data/{buildId}/reports/{proxy+}");
394
+ expect(paths).toContain("/_next/data/{buildId}/docs/intro.json");
395
+ expect(anyTargets("intro.json")).toEqual(["GroupFn"]);
396
+ // A methodless parent answers 403, so the data prefix needs the default.
397
+ expect(anyTargets("{buildId}")).toEqual(["ServerFn"]);
398
+ });
399
+ it("keeps each group's data URLs to its own subtree (A)", () => {
400
+ // `{buildId}` is one path segment, where CloudFront's `*` crossed `/`:
401
+ // `/_next/data/<id>/docs/blog/x.json` has no way into blog's resource.
402
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
403
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
404
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
405
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
406
+ handler: "index.handler",
407
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
408
+ }),
409
+ publicDirEntries: [],
410
+ ...grouped([
411
+ {
412
+ name: "blog",
413
+ routes: ["/blog/**"],
414
+ hasDataRoutes: true,
415
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
416
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
417
+ handler: "index.handler",
418
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
419
+ }),
420
+ },
421
+ ]),
422
+ });
423
+ expect(resourcePaths().filter((path) => path.startsWith("/_next/data"))).toEqual([
424
+ "/_next/data",
425
+ "/_next/data/{buildId}",
426
+ "/_next/data/{buildId}/blog",
427
+ "/_next/data/{buildId}/blog/{proxy+}",
428
+ ]);
429
+ });
430
+ it("routes an optional catch-all's parent to the group when it is listed (B)", () => {
431
+ // The build routes `/shop` alongside `/shop/**` when the group owns
432
+ // `shop/[[...slug]]` (see `routedPatterns`): `{proxy+}` does not match
433
+ // the parent, which would otherwise reach the default function.
434
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
435
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
436
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
437
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
438
+ handler: "index.handler",
439
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
440
+ }),
441
+ publicDirEntries: [],
442
+ ...grouped([
443
+ {
444
+ name: "shop",
445
+ routes: ["/shop/**", "/shop"],
446
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
447
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
448
+ handler: "index.handler",
449
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
450
+ }),
451
+ },
452
+ ]),
453
+ });
454
+ expect(anyTargets("shop")).toEqual(["GroupFn"]);
455
+ });
456
+ it.each([
457
+ [{ name: "docs", isDirectory: true }, "/docs/**", "directory"],
458
+ [{ name: "docs", isDirectory: true }, "/docs/guide/**", "directory"],
459
+ [{ name: "robots.txt", isDirectory: false }, "/robots.txt", "file"],
460
+ ])("rejects a group route on a public/ entry's resource: %p with %p (E)", (entry, route, kind) => {
461
+ expect(() => new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
462
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
463
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
464
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
465
+ handler: "index.handler",
466
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
467
+ }),
468
+ publicDirEntries: [entry],
469
+ ...grouped([
470
+ {
471
+ name: "g",
472
+ routes: [route],
473
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
474
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
475
+ handler: "index.handler",
476
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
477
+ }),
478
+ },
479
+ ]),
480
+ })).toThrow(`overlaps the top-level public/ ${kind} "${entry.name}"`);
481
+ });
482
+ it("allows an exact route named like a public/ directory, which is not under it", () => {
483
+ expect(() => new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
484
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
485
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
486
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
487
+ handler: "index.handler",
488
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
489
+ }),
490
+ publicDirEntries: [{ name: "docs", isDirectory: true }],
491
+ ...grouped([
492
+ {
493
+ name: "g",
494
+ routes: ["/docs"],
495
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
496
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
497
+ handler: "index.handler",
498
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
499
+ }),
500
+ },
501
+ ]),
502
+ })).not.toThrow();
503
+ });
504
+ it("routes an exact route's trailingSlash form through its one resource", () => {
505
+ // CloudFront needs `pricing/` as a behavior of its own; API Gateway
506
+ // matches `/pricing/` on the `pricing` resource, so the variant adds
507
+ // nothing here and must not add the resource twice.
508
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
509
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
510
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
511
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
512
+ handler: "index.handler",
513
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
514
+ }),
515
+ publicDirEntries: [],
516
+ ...grouped([
517
+ {
518
+ name: "pricing",
519
+ routes: ["/pricing"],
520
+ trailingSlash: true,
521
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
522
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
523
+ handler: "index.handler",
524
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
525
+ }),
526
+ },
527
+ ]),
528
+ });
529
+ expect(resourcePaths().filter((path) => !path.startsWith("/_next/static"))).toEqual(["/_next", "/pricing", "/{proxy+}"]);
530
+ expect(anyTargetsByPath()).toEqual({
531
+ "/pricing": ["GroupFn"],
532
+ "/{proxy+}": ["ServerFn"],
533
+ });
534
+ });
535
+ it("rejects a behavior for a group it was not given", () => {
536
+ const { functionGroupBehaviors } = grouped([
537
+ {
538
+ name: "api",
539
+ routes: ["/api/**"],
540
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
541
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
542
+ handler: "index.handler",
543
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
544
+ }),
545
+ },
546
+ ]);
547
+ expect(() => new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
548
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
549
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
550
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
551
+ handler: "index.handler",
552
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
553
+ }),
554
+ publicDirEntries: [],
555
+ functionGroupBehaviors,
556
+ })).toThrow(/routes to function group "api", which is not in/);
557
+ });
558
+ it("adds no data routes for an app without Pages Router routes", () => {
559
+ createGroupedApi(false);
560
+ expect(resourcePaths().filter((path) => path.startsWith("/_next/data"))).toEqual([]);
561
+ });
562
+ it("grants each function one API-scoped permission, not two per method", () => {
563
+ // Per-method permissions put two statements in the function's resource
564
+ // policy for every `ANY`, which outgrows Lambda's 20 KB cap.
565
+ createGroupedApi(true);
566
+ const permissions = Object.values(assertions_1.Template.fromStack(stack).findResources("AWS::Lambda::Permission", {
567
+ Properties: { Principal: "apigateway.amazonaws.com" },
568
+ }));
569
+ expect(permissions).toHaveLength(2);
570
+ for (const permission of permissions) {
571
+ const sourceArn = JSON.stringify(permission.Properties.SourceArn);
572
+ expect(sourceArn).toContain(":execute-api:");
573
+ expect(sourceArn).toContain("/*/*/*");
574
+ }
575
+ });
576
+ });
577
+ it("names the group and pattern API Gateway cannot route", () => {
578
+ expect(() => new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
579
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
580
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
581
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
582
+ handler: "index.handler",
583
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
584
+ }),
585
+ publicDirEntries: [],
586
+ ...grouped([
587
+ {
588
+ name: "about",
589
+ routes: ["/about~us"],
590
+ function: new aws_lambda_1.Function(stack, "GroupFn", {
591
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
592
+ handler: "index.handler",
593
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
594
+ }),
595
+ },
596
+ ]),
597
+ })).toThrow(/pattern "\/about~us" \(group "about"\) has a segment/);
598
+ });
599
+ describe("a public/ entry API Gateway cannot address", () => {
600
+ it("warns and skips it instead of failing the synth", () => {
601
+ // `public/hello world.jpg` is a valid Next.js asset that `addResource`
602
+ // rejects outright, taking the whole app's synth with it. The Global types
603
+ // serve it with a wildcard path pattern; here the honest outcome is one
604
+ // 404ing asset and a warning that names it.
605
+ const api = new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
606
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
607
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
608
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
609
+ handler: "index.handler",
610
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
611
+ }),
612
+ publicDirEntries: [
613
+ { name: "hello world.jpg", isDirectory: false },
614
+ { name: "äöüščří.png", isDirectory: false },
615
+ { name: "favicon.ico", isDirectory: false },
616
+ ],
617
+ });
618
+ const message = assertions_1.Annotations.fromStack(stack)
619
+ .findWarning(`/${api.node.path}`, assertions_1.Match.anyValue())
620
+ .map((warning) => warning.entry.data)
621
+ .join("\n");
622
+ expect(message).toContain('"hello world.jpg"');
623
+ expect(message).toContain('"äöüščří.png"');
624
+ expect(message).not.toContain('"favicon.ico"');
625
+ // The expressible one is still served.
626
+ expect(s3IntegrationKeys()).toContain("favicon.ico");
627
+ });
628
+ });
629
+ });
630
+ describe("NextjsApi redeploy after update", () => {
631
+ function synth(props = {}) {
632
+ const stack = new aws_cdk_lib_1.Stack(new aws_cdk_lib_1.App(), "TestStack", {
633
+ env: { account: "123456789012", region: "us-east-1" },
634
+ });
635
+ new nextjs_api_1.NextjsApi(stack, "NextjsApi", {
636
+ staticAssetsBucket: aws_s3_1.Bucket.fromBucketName(stack, "Bucket", "my-bucket"),
637
+ serverFunction: new aws_lambda_1.Function(stack, "ServerFn", {
638
+ runtime: aws_lambda_1.Runtime.NODEJS_22_X,
639
+ handler: "index.handler",
640
+ code: aws_lambda_1.Code.fromInline("exports.handler = async () => {};"),
641
+ }),
642
+ publicDirEntries: [],
643
+ ...props,
644
+ });
645
+ return assertions_1.Template.fromStack(stack);
646
+ }
647
+ /** The `Fn::Join` parts of every resource the redeploy role is granted. */
648
+ function grantedResources(template) {
649
+ const [policy] = Object.values(template.findResources("AWS::IAM::Policy", {
650
+ Properties: {
651
+ PolicyName: assertions_1.Match.stringLikeRegexp("RedeployFn"),
652
+ },
653
+ }));
654
+ return policy.Properties.PolicyDocument.Statement.map((statement) => ({
655
+ action: statement.Action,
656
+ resources: JSON.stringify(statement.Resource),
657
+ }));
658
+ }
659
+ it("redeploys the stage on this stack's UPDATE_COMPLETE", () => {
660
+ const template = synth();
661
+ template.hasResourceProperties("AWS::Events::Rule", {
662
+ EventPattern: {
663
+ source: ["aws.cloudformation"],
664
+ "detail-type": ["CloudFormation Stack Status Change"],
665
+ detail: {
666
+ "stack-id": [{ Ref: "AWS::StackId" }],
667
+ "status-details": {
668
+ status: ["UPDATE_COMPLETE", "UPDATE_ROLLBACK_COMPLETE"],
669
+ },
670
+ },
671
+ },
672
+ Targets: [
673
+ assertions_1.Match.objectLike({
674
+ Arn: { "Fn::GetAtt": [assertions_1.Match.stringLikeRegexp("RedeployFn"), "Arn"] },
675
+ }),
676
+ ],
677
+ });
678
+ template.hasResourceProperties("AWS::Lambda::Function", {
679
+ Handler: "index.handler",
680
+ Environment: {
681
+ Variables: {
682
+ REST_API_ID: { Ref: assertions_1.Match.stringLikeRegexp("RestApi") },
683
+ STAGE_NAME: { Ref: assertions_1.Match.stringLikeRegexp("DeploymentStage") },
684
+ },
685
+ },
686
+ });
687
+ });
688
+ it("scopes its API Gateway access to this REST API", () => {
689
+ const statements = grantedResources(synth());
690
+ expect(statements.map((s) => s.action)).toEqual([
691
+ "apigateway:POST",
692
+ "apigateway:GET",
693
+ "apigateway:DELETE",
694
+ ]);
695
+ for (const { resources } of statements) {
696
+ expect(resources).toContain("/restapis/");
697
+ expect(resources).toMatch(/"Ref":"NextjsApiRestApi[0-9A-F]+"/);
698
+ expect(resources).not.toMatch(/restapis\/\*/);
699
+ }
700
+ expect(statements[0].resources).toContain("/deployments");
701
+ expect(statements[2].resources).toContain("/deployments/*");
702
+ });
703
+ it("is off when redeployAfterUpdate is false", () => {
704
+ const template = synth({ redeployAfterUpdate: false });
705
+ template.resourceCountIs("AWS::Events::Rule", 0);
706
+ });
707
+ it("is off when the API deploys no stage", () => {
708
+ const template = synth({
709
+ overrides: { restApiProps: { deploy: false } },
710
+ });
711
+ template.resourceCountIs("AWS::Events::Rule", 0);
712
+ });
713
+ it("takes function overrides", () => {
714
+ const template = synth({
715
+ overrides: { redeployFunctionProps: { memorySize: 512 } },
716
+ });
717
+ template.hasResourceProperties("AWS::Lambda::Function", {
718
+ MemorySize: 512,
719
+ Environment: {
720
+ Variables: { REST_API_ID: assertions_1.Match.anyValue() },
721
+ },
722
+ });
723
+ });
188
724
  });
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWFwaS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1hcGkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCw2Q0FBeUM7QUFDekMsdURBQWtEO0FBQ2xELCtFQUFpRTtBQUNqRSx1REFJZ0M7QUFDaEMsK0NBQTRDO0FBQzVDLDZDQUF5RDtBQUV6RCxRQUFRLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRTtJQUN6QixJQUFJLEtBQVksQ0FBQztJQUVqQixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsS0FBSyxHQUFHLElBQUksbUJBQUssQ0FBQyxJQUFJLGlCQUFHLEVBQUUsRUFBRSxXQUFXLEVBQUU7WUFDeEMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO1NBQ3RELENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxTQUFTLENBQUMscUJBQThCO1FBQy9DLE9BQU8sSUFBSSxzQkFBUyxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUU7WUFDdkMsa0JBQWtCLEVBQUUsZUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFdBQVcsQ0FBQztZQUN2RSxxQkFBcUI7WUFDckIsY0FBYyxFQUFFLElBQUkscUJBQWMsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFO2dCQUNwRCxPQUFPLEVBQUUsb0JBQU8sQ0FBQyxXQUFXO2dCQUM1QixPQUFPLEVBQUUsZUFBZTtnQkFDeEIsSUFBSSxFQUFFLGlCQUFJLENBQUMsVUFBVSxDQUFDLG1DQUFtQyxDQUFDO2FBQzNELENBQUM7WUFDRixnQkFBZ0IsRUFBRTtnQkFDaEIsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUU7Z0JBQzNDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFO2FB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QUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBcHAsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgeyBDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBDb2RlLFxuICBGdW5jdGlvbiBhcyBMYW1iZGFGdW5jdGlvbixcbiAgUnVudGltZSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIjtcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IE5leHRqc0FwaSwgTmV4dGpzQXBpUHJvcHMgfSBmcm9tIFwiLi9uZXh0anMtYXBpXCI7XG5cbmRlc2NyaWJlKFwiTmV4dGpzQXBpXCIsICgpID0+IHtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBzdGFjayA9IG5ldyBTdGFjayhuZXcgQXBwKCksIFwiVGVzdFN0YWNrXCIsIHtcbiAgICAgIGVudjogeyBhY2NvdW50OiBcIjEyMzQ1Njc4OTAxMlwiLCByZWdpb246IFwidXMtZWFzdC0xXCIgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlQXBpKHN0YXRpY0Fzc2V0c0tleVByZWZpeD86IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgTmV4dGpzQXBpKHN0YWNrLCBcIk5leHRqc0FwaVwiLCB7XG4gICAgICBzdGF0aWNBc3NldHNCdWNrZXQ6IEJ1Y2tldC5mcm9tQnVja2V0TmFtZShzdGFjaywgXCJCdWNrZXRcIiwgXCJteS1idWNrZXRcIiksXG4gICAgICBzdGF0aWNBc3NldHNLZXlQcmVmaXgsXG4gICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgIH0pLFxuICAgICAgcHVibGljRGlyRW50cmllczogW1xuICAgICAgICB7IG5hbWU6IFwiZmF2aWNvbi5pY29cIiwgaXNEaXJlY3Rvcnk6IGZhbHNlIH0sXG4gICAgICAgIHsgbmFtZTogXCJpbWFnZXNcIiwgaXNEaXJlY3Rvcnk6IHRydWUgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIFMzIGludGVncmF0aW9ucyBhZGRyZXNzIG9iamVjdHMgYnkga2V5LCBzbyB0aGUgdXBsb2FkZWQga2V5IHByZWZpeCBoYXNcbiAgICogdG8gYXBwZWFyIGluIHRoZSBpbnRlZ3JhdGlvbiBVUkkgb3IgZXZlcnkgc3RhdGljIHJlcXVlc3QgNDA0cy5cbiAgICovXG4gIGZ1bmN0aW9uIHMzSW50ZWdyYXRpb25LZXlzKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBtZXRob2RzID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5maW5kUmVzb3VyY2VzKFxuICAgICAgXCJBV1M6OkFwaUdhdGV3YXk6Ok1ldGhvZFwiLFxuICAgICk7XG4gICAgY29uc3QgbWFya2VyID0gXCJzMzpwYXRoL215LWJ1Y2tldC9cIjtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhtZXRob2RzKVxuICAgICAgLmZsYXRNYXAoKG1ldGhvZCkgPT4gbWV0aG9kLlByb3BlcnRpZXMuSW50ZWdyYXRpb24uVXJpW1wiRm46OkpvaW5cIl1bMV0pXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAocGFydDogdW5rbm93bik6IHBhcnQgaXMgc3RyaW5nID0+XG4gICAgICAgICAgdHlwZW9mIHBhcnQgPT09IFwic3RyaW5nXCIgJiYgcGFydC5pbmNsdWRlcyhtYXJrZXIpLFxuICAgICAgKVxuICAgICAgLm1hcCgocGFydCkgPT4gcGFydC5zcGxpdChtYXJrZXIpWzFdKTtcbiAgfVxuXG4gIGl0KFwiYWRkcmVzc2VzIG9iamVjdHMgYXQgdGhlIGJ1Y2tldCByb290IHdoZW4gbm8ga2V5IHByZWZpeCBpcyBzZXRcIiwgKCkgPT4ge1xuICAgIGNyZWF0ZUFwaSgpO1xuXG4gICAgZXhwZWN0KHMzSW50ZWdyYXRpb25LZXlzKCkuc29ydCgpKS50b0VxdWFsKFtcbiAgICAgIFwiX25leHQvc3RhdGljL3trZXl9XCIsXG4gICAgICBcImZhdmljb24uaWNvXCIsXG4gICAgICBcImltYWdlcy97a2V5fVwiLFxuICAgIF0pO1xuICB9KTtcblxuICBpdChcInByZWZpeGVzIGV2ZXJ5IFMzIGludGVncmF0aW9uIGtleSB3aXRoIHRoZSBzdGF0aWMgYXNzZXRzIGtleSBwcmVmaXhcIiwgKCkgPT4ge1xuICAgIGNyZWF0ZUFwaShcImJyYW5jaC14XCIpO1xuXG4gICAgZXhwZWN0KHMzSW50ZWdyYXRpb25LZXlzKCkuc29ydCgpKS50b0VxdWFsKFtcbiAgICAgIFwiYnJhbmNoLXgvX25leHQvc3RhdGljL3trZXl9XCIsXG4gICAgICBcImJyYW5jaC14L2Zhdmljb24uaWNvXCIsXG4gICAgICBcImJyYW5jaC14L2ltYWdlcy97a2V5fVwiLFxuICAgIF0pO1xuICB9KTtcblxuICBpdChcIm5vcm1hbGl6ZXMgc3Vycm91bmRpbmcgc2xhc2hlcyBvbiB0aGUga2V5IHByZWZpeFwiLCAoKSA9PiB7XG4gICAgY3JlYXRlQXBpKFwiL2JyYW5jaC14L1wiKTtcblxuICAgIGV4cGVjdChzM0ludGVncmF0aW9uS2V5cygpKS50b0NvbnRhaW4oXCJicmFuY2gteC9fbmV4dC9zdGF0aWMve2tleX1cIik7XG4gIH0pO1xuXG4gIGl0KFwia2VlcHMgdGhlIGtleSBwcmVmaXggaW5kZXBlbmRlbnQgb2YgYmFzZVBhdGgsIHdoaWNoIGlzIHRoZSBVUkwgcHJlZml4XCIsICgpID0+IHtcbiAgICAvLyBBIE5leHRqc1JlZ2lvbmFsRnVuY3Rpb25zIGFwcCB3aG9zZSBgYmFzZVBhdGhgIG1hdGNoZXMgdGhlIEFQSSBHYXRld2F5XG4gICAgLy8gc3RhZ2Ugc3RpbGwgaGFzIGl0cyBhc3NldHMgYXQgdGhlIGJ1Y2tldCByb290LlxuICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgIGJhc2VQYXRoOiBcIi9wcm9kXCIsXG4gICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgIH0pLFxuICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgfSk7XG5cbiAgICBleHBlY3QoczNJbnRlZ3JhdGlvbktleXMoKSkudG9FcXVhbChbXCJfbmV4dC9zdGF0aWMve2tleX1cIl0pO1xuICAgIC8vIC4uLnNlcnZlZCB1bmRlciB0aGUgc3RhZ2UtbWF0Y2hpbmcgVVJMIHByZWZpeC5cbiAgICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcyhcbiAgICAgIFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiLFxuICAgICAgeyBQYXRoUGFydDogXCJwcm9kXCIgfSxcbiAgICApO1xuICB9KTtcblxuICAvLyBBUEkgR2F0ZXdheSBwYXRoIHBhcnRzIGNhbid0IGNvbnRhaW4gXCIvXCIsIHNvIGEgbmVzdGVkIGJhc2VQYXRoIHBhc3NlZCB3aG9sZVxuICAvLyB0byBgYWRkUmVzb3VyY2VgIGZhaWxzIENESydzIGB2YWxpZGF0ZVJlc291cmNlUGF0aFBhcnRgIGF0IHN5bnRoLiBJdCdzXG4gIC8vIHJlYWNoYWJsZTogYHJlc29sdmVCYXNlUGF0aGAgYWNjZXB0cyBhIG5lc3RlZCBwcm9wIGZvciBSRUdJT05BTF9GVU5DVElPTlMgYXNcbiAgLy8gbG9uZyBhcyB0aGUgYXBwJ3MgYmFzZVBhdGggZW5kcyB3aXRoIGl0LlxuICBkZXNjcmliZShcIm5lc3RlZCBiYXNlUGF0aFwiLCAoKSA9PiB7XG4gICAgZnVuY3Rpb24gcGF0aFBhcnRzKCk6IHN0cmluZ1tdIHtcbiAgICAgIGNvbnN0IHJlc291cmNlcyA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuZmluZFJlc291cmNlcyhcbiAgICAgICAgXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuIE9iamVjdC52YWx1ZXMocmVzb3VyY2VzKS5tYXAoXG4gICAgICAgIChyZXNvdXJjZSkgPT4gcmVzb3VyY2UuUHJvcGVydGllcy5QYXRoUGFydCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3JlYXRlQXBpV2l0aEJhc2VQYXRoKGJhc2VQYXRoOiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBuZXcgTmV4dGpzQXBpKHN0YWNrLCBcIk5leHRqc0FwaVwiLCB7XG4gICAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgICAgYmFzZVBhdGgsXG4gICAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICB9KSxcbiAgICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpdChcImNyZWF0ZXMgb25lIHJlc291cmNlIHBlciBzZWdtZW50XCIsICgpID0+IHtcbiAgICAgIGV4cGVjdCgoKSA9PiBjcmVhdGVBcGlXaXRoQmFzZVBhdGgoXCIvdGVhbS9hcHBcIikpLm5vdC50b1Rocm93KCk7XG5cbiAgICAgIGV4cGVjdChwYXRoUGFydHMoKSkudG9FcXVhbChcbiAgICAgICAgZXhwZWN0LmFycmF5Q29udGFpbmluZyhbXCJ0ZWFtXCIsIFwiYXBwXCIsIFwiX25leHRcIiwgXCJ7cHJveHkrfVwiXSksXG4gICAgICApO1xuICAgICAgLy8gTm90IHRoZSB1bnNwbGl0IHZhbHVlLCB3aGljaCBBUEkgR2F0ZXdheSB3b3VsZCByZWplY3QuXG4gICAgICBleHBlY3QocGF0aFBhcnRzKCkpLm5vdC50b0NvbnRhaW4oXCJ0ZWFtL2FwcFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwibmVzdHMgdGhlIHNlZ21lbnRzIHNvIHRoZSBhcHAgaXMgcmVhY2hhYmxlIHVuZGVyIHRoZSBmdWxsIHBhdGhcIiwgKCkgPT4ge1xuICAgICAgY3JlYXRlQXBpV2l0aEJhc2VQYXRoKFwiL3RlYW0vYXBwXCIpO1xuXG4gICAgICBjb25zdCByZXNvdXJjZXMgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmZpbmRSZXNvdXJjZXMoXG4gICAgICAgIFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGJ5UGF0aFBhcnQgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHJlc291cmNlcykubWFwKChbbG9naWNhbElkLCByZXNvdXJjZV0pID0+IFtcbiAgICAgICAgICByZXNvdXJjZS5Qcm9wZXJ0aWVzLlBhdGhQYXJ0LFxuICAgICAgICAgIHsgbG9naWNhbElkLCBwYXJlbnRJZDogcmVzb3VyY2UuUHJvcGVydGllcy5QYXJlbnRJZCB9LFxuICAgICAgICBdKSxcbiAgICAgICk7XG4gICAgICAvLyBcImFwcFwiIGhhbmdzIG9mZiBcInRlYW1cIiwgbm90IG9mZiB0aGUgQVBJIHJvb3QuXG4gICAgICBleHBlY3QoYnlQYXRoUGFydC5hcHAucGFyZW50SWQpLnRvRXF1YWwoe1xuICAgICAgICBSZWY6IGJ5UGF0aFBhcnQudGVhbS5sb2dpY2FsSWQsXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChieVBhdGhQYXJ0LnRlYW0ucGFyZW50SWQpLnRvSGF2ZVByb3BlcnR5KFwiRm46OkdldEF0dFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic3RpbGwgY3JlYXRlcyBhIHNpbmdsZSByZXNvdXJjZSBmb3IgYSBmbGF0IGJhc2VQYXRoXCIsICgpID0+IHtcbiAgICAgIGNyZWF0ZUFwaVdpdGhCYXNlUGF0aChcIi9iYXNlXCIpO1xuXG4gICAgICBleHBlY3QocGF0aFBhcnRzKCkpLnRvQ29udGFpbihcImJhc2VcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwidXJsXCIsICgpID0+IHtcbiAgICBmdW5jdGlvbiBjcmVhdGVBcGlXaXRoT3ZlcnJpZGVzKFxuICAgICAgcHJvcHM6IFBhcnRpYWw8TmV4dGpzQXBpUHJvcHM+ID0ge30sXG4gICAgKTogTmV4dGpzQXBpIHtcbiAgICAgIHJldHVybiBuZXcgTmV4dGpzQXBpKHN0YWNrLCBcIk5leHRqc0FwaVwiLCB7XG4gICAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgICAgc2VydmVyRnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJTZXJ2ZXJGblwiLCB7XG4gICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgIH0pLFxuICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICAgICAgLi4ucHJvcHMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkb21haW5OYW1lKGJhc2VQYXRoPzogc3RyaW5nKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkb21haW5OYW1lOiBcImFwcC5leGFtcGxlLmNvbVwiLFxuICAgICAgICBjZXJ0aWZpY2F0ZTogQ2VydGlmaWNhdGUuZnJvbUNlcnRpZmljYXRlQXJuKFxuICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgIFwiQ2VydFwiLFxuICAgICAgICAgIFwiYXJuOmF3czphY206dXMtZWFzdC0xOjEyMzQ1Njc4OTAxMjpjZXJ0aWZpY2F0ZS9hYmNcIixcbiAgICAgICAgKSxcbiAgICAgICAgYmFzZVBhdGgsXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBSRVNUIEFQSSBpZCwgdGhlIHN0YWdlIG5hbWUgYW5kIHRoZSBkb21haW4gbmFtZSBhcmUgYWxsIHRva2VucyB0aGF0XG4gICAgICogb25seSByZXNvbHZlIGF0IGRlcGxveSB0aW1lLCBzbyBmbGF0dGVuIHRoZSByZXNvbHZlZCBgRm46OkpvaW5gIGFuZCBzdGFuZFxuICAgICAqIGVhY2ggcmVmZXJlbmNlIGluIGZvciB0aGUgcmVzb3VyY2UgaXQgcG9pbnRzIGF0IChtaW51cyBDREsncyBsb2dpY2FsIGlkXG4gICAgICogaGFzaCBzdWZmaXgpLiBUaGF0IGtlZXBzIHRoZSBhc3NlcnRpb25zIGFib3V0ICp3aGljaCogcmVzb3VyY2Ugc3VwcGxpZXNcbiAgICAgKiBlYWNoIHBhcnQgb2YgdGhlIFVSTCwgd2hpY2ggaXMgdGhlIHdob2xlIHF1ZXN0aW9uIGhlcmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVVybChhcGk6IE5leHRqc0FwaSk6IHN0cmluZyB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHN0YWNrLnJlc29sdmUoYXBpLnVybCk7XG4gICAgICBpZiAodHlwZW9mIHJlc29sdmVkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlZFtcIkZuOjpKb2luXCJdWzFdXG4gICAgICAgIC5tYXAoKHBhcnQ6IHVua25vd24pID0+XG4gICAgICAgICAgdHlwZW9mIHBhcnQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgID8gcGFydFxuICAgICAgICAgICAgOiBgeyR7KHBhcnQgYXMgeyBSZWY6IHN0cmluZyB9KS5SZWYucmVwbGFjZSgvWzAtOUEtRl17OH0kLywgXCJcIil9fWAsXG4gICAgICAgIClcbiAgICAgICAgLmpvaW4oXCJcIik7XG4gICAgfVxuXG4gICAgaXQoXCJyZXBvcnRzIHRoZSBleGVjdXRlLWFwaSBlbmRwb2ludCB3aXRoIHRoZSBzdGFnZSBhcHBlbmRlZCB3aGVuIHRoZXJlJ3Mgbm8gY3VzdG9tIGRvbWFpblwiLCAoKSA9PiB7XG4gICAgICAvLyBUaGUgc3RhZ2UgaXMgaW4gdGhlIHBhdGggb25seSBoZXJlLCB3aGljaCBpcyB0aGUgd2hvbGUgcmVhc29uIHRoZVxuICAgICAgLy8gcmVnaW9uYWwtZnVuY3Rpb25zIGV4YW1wbGUgc2V0cyBhbiBhcHAgYmFzZVBhdGggb2YgXCIvcHJvZFwiLlxuICAgICAgZXhwZWN0KHJlc29sdmVVcmwoY3JlYXRlQXBpV2l0aE92ZXJyaWRlcygpKSkudG9CZShcbiAgICAgICAgXCJodHRwczovL3tOZXh0anNBcGlSZXN0QXBpfS5leGVjdXRlLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbS97TmV4dGpzQXBpUmVzdEFwaURlcGxveW1lbnRTdGFnZXByb2R9XCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJhcHBlbmRzIGJhc2VQYXRoLCB3aGljaCBuZXN0cyBldmVyeSByZXNvdXJjZSBhIGxldmVsIGRvd25cIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KFxuICAgICAgICByZXNvbHZlVXJsKGNyZWF0ZUFwaVdpdGhPdmVycmlkZXMoeyBiYXNlUGF0aDogXCIvbXktYmFzZS1wYXRoXCIgfSkpLFxuICAgICAgKS50b0JlKFxuICAgICAgICBcImh0dHBzOi8ve05leHRqc0FwaVJlc3RBcGl9LmV4ZWN1dGUtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3tOZXh0anNBcGlSZXN0QXBpRGVwbG95bWVudFN0YWdlcHJvZH0vbXktYmFzZS1wYXRoXCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJwcmVmZXJzIGEgY3VzdG9tIGRvbWFpbiBhbmQgZHJvcHMgdGhlIHN0YWdlIGZyb20gdGhlIHBhdGhcIiwgKCkgPT4ge1xuICAgICAgLy8gQSBkb21haW4gbWFwcGVkIGF0IHRoZSByb290IGlzIHRoZSBjbGVhbmVzdCBSZWdpb25hbCBzZXR1cDogbm8gc3RhZ2UgaW5cbiAgICAgIC8vIHRoZSBVUkwgbWVhbnMgbm8gYmFzZVBhdGggYW5kIG5vIHN0YWdlIHdvcmthcm91bmRzIGFueXdoZXJlLiBUaGUgc3RhZ2UgaXNcbiAgICAgIC8vIHJlYWNoZWQgdGhyb3VnaCB0aGUgZG9tYWluJ3MgYmFzZSBwYXRoIG1hcHBpbmcgaW5zdGVhZC5cbiAgICAgIGV4cGVjdChcbiAgICAgICAgcmVzb2x2ZVVybChcbiAgICAgICAgICBjcmVhdGVBcGlXaXRoT3ZlcnJpZGVzKHtcbiAgICAgICAgICAgIG92ZXJyaWRlczogeyByZXN0QXBpUHJvcHM6IHsgZG9tYWluTmFtZTogZG9tYWluTmFtZSgpIH0gfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICkudG9CZShcImh0dHBzOi8ve05leHRqc0FwaVJlc3RBcGlDdXN0b21Eb21haW59XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJpbmNsdWRlcyBhIGN1c3RvbSBkb21haW4ncyBiYXNlIHBhdGggbWFwcGluZ1wiLCAoKSA9PiB7XG4gICAgICAvLyBDREsgcmVqZWN0cyBzdXJyb3VuZGluZyBzbGFzaGVzIG9uIGEgbWFwcGluZywgc28gaXQncyBhbHdheXMgYSBiYXJlXG4gICAgICAvLyBzZWdtZW50IGJ5IHRoZSB0aW1lIGl0IGdldHMgaGVyZS5cbiAgICAgIGV4cGVjdChcbiAgICAgICAgcmVzb2x2ZVVybChcbiAgICAgICAgICBjcmVhdGVBcGlXaXRoT3ZlcnJpZGVzKHtcbiAgICAgICAgICAgIG92ZXJyaWRlczogeyByZXN0QXBpUHJvcHM6IHsgZG9tYWluTmFtZTogZG9tYWluTmFtZShcInRlYW0tYVwiKSB9IH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApLnRvQmUoXCJodHRwczovL3tOZXh0anNBcGlSZXN0QXBpQ3VzdG9tRG9tYWlufS90ZWFtLWFcIik7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
725
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWFwaS50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1hcGkudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHNEQUFzRDtBQUN0RCw2Q0FBeUM7QUFDekMsdURBQXNFO0FBQ3RFLCtFQUFpRTtBQUNqRSx1REFLZ0M7QUFDaEMsK0NBQTRDO0FBQzVDLCtEQUE0RDtBQUM1RCw2Q0FBeUQ7QUFFekQ7Ozs7R0FJRztBQUNILFNBQVMsT0FBTyxDQUNkLE1BTUc7SUFFSCxPQUFPO1FBQ0wsY0FBYyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEQsSUFBSTtZQUNKLFFBQVEsRUFBRSxFQUFFO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsc0JBQXNCLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQy9DLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDN0IsSUFBQSxpQ0FBZSxFQUFDLEtBQUssRUFBRTtZQUNyQixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWEsSUFBSSxLQUFLO1lBQzNDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxPQUFPLEVBQUUsUUFBUTtTQUNsQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FDN0QsQ0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsUUFBUSxDQUFDLFdBQVcsRUFBRSxHQUFHLEVBQUU7SUFDekIsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEtBQUssR0FB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UUFDbEQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV2RCxRQUFRLENBQUMsZUFBZSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRTtRQUM5QyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7WUFDckIsU0FBUyxFQUFFLEVBQUUsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFO1NBQy9DLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyxlQUFlLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztZQUNyQixTQUFTLEVBQUUsRUFBRSxxQkFBcUIsRUFBRSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsRUFBRTtTQUMxRCxDQUFDLENBQUM7UUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLEVBQUU7WUFDdEQsVUFBVSxFQUFFLEdBQUc7WUFDZixXQUFXLEVBQUU7Z0JBQ1gsU0FBUyxFQUFFLEVBQUUsV0FBVyxFQUFFLGtCQUFLLENBQUMsUUFBUSxFQUFFLEVBQUU7YUFDN0M7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBcHAsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBBbm5vdGF0aW9ucywgTWF0Y2gsIFRlbXBsYXRlIH0gZnJvbSBcImF3cy1jZGstbGliL2Fzc2VydGlvbnNcIjtcbmltcG9ydCB7IENlcnRpZmljYXRlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jZXJ0aWZpY2F0ZW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIENvZGUsXG4gIEZ1bmN0aW9uIGFzIExhbWJkYUZ1bmN0aW9uLFxuICBJRnVuY3Rpb24sXG4gIFJ1bnRpbWUsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCI7XG5pbXBvcnQgeyBCdWNrZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQgeyBwYXRoUGF0dGVybnNGb3IgfSBmcm9tIFwiLi9hZGFwdGVyL2Z1bmN0aW9uLWdyb3Vwc1wiO1xuaW1wb3J0IHsgTmV4dGpzQXBpLCBOZXh0anNBcGlQcm9wcyB9IGZyb20gXCIuL25leHRqcy1hcGlcIjtcblxuLyoqXG4gKiBgZnVuY3Rpb25Hcm91cHNgIGFuZCB0aGUgYGZ1bmN0aW9uR3JvdXBCZWhhdmlvcnNgIHRoZSBidWlsZCB3b3VsZCByZWNvcmQgZm9yXG4gKiB0aGVtOiBgcm91dGVzYCBhcyByb3V0ZWQgKGFuIG9wdGlvbmFsIGNhdGNoLWFsbCdzIHBhcmVudCBsaXN0ZWQgYnkgaGFuZCksXG4gKiB3aXRoIGRhdGEtVVJMIGJlaGF2aW9ycyBmb3IgYSBncm91cCB0aGF0IG93bnMgYSBQYWdlcyBSb3V0ZXIgcGFnZS5cbiAqL1xuZnVuY3Rpb24gZ3JvdXBlZChcbiAgZ3JvdXBzOiB7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHJvdXRlczogc3RyaW5nW107XG4gICAgaGFzRGF0YVJvdXRlcz86IGJvb2xlYW47XG4gICAgdHJhaWxpbmdTbGFzaD86IGJvb2xlYW47XG4gICAgZnVuY3Rpb246IElGdW5jdGlvbjtcbiAgfVtdLFxuKTogUGljazxOZXh0anNBcGlQcm9wcywgXCJmdW5jdGlvbkdyb3Vwc1wiIHwgXCJmdW5jdGlvbkdyb3VwQmVoYXZpb3JzXCI+IHtcbiAgcmV0dXJuIHtcbiAgICBmdW5jdGlvbkdyb3VwczogZ3JvdXBzLm1hcCgoeyBuYW1lLCBmdW5jdGlvbjogZm4gfSkgPT4gKHtcbiAgICAgIG5hbWUsXG4gICAgICBmdW5jdGlvbjogZm4sXG4gICAgfSkpLFxuICAgIGZ1bmN0aW9uR3JvdXBCZWhhdmlvcnM6IGdyb3Vwcy5mbGF0TWFwKChncm91cCkgPT5cbiAgICAgIGdyb3VwLnJvdXRlcy5mbGF0TWFwKChyb3V0ZSkgPT5cbiAgICAgICAgcGF0aFBhdHRlcm5zRm9yKHJvdXRlLCB7XG4gICAgICAgICAgaGFzRGF0YVJvdXRlczogZ3JvdXAuaGFzRGF0YVJvdXRlcyA/PyBmYWxzZSxcbiAgICAgICAgICB0cmFpbGluZ1NsYXNoOiBncm91cC50cmFpbGluZ1NsYXNoLFxuICAgICAgICAgIGJ1aWxkSWQ6IFwiYWJjMTIzXCIsXG4gICAgICAgIH0pLm1hcCgocGF0dGVybikgPT4gKHsgZ3JvdXA6IGdyb3VwLm5hbWUsIHJvdXRlLCBwYXR0ZXJuIH0pKSxcbiAgICAgICksXG4gICAgKSxcbiAgfTtcbn1cblxuZGVzY3JpYmUoXCJOZXh0anNBcGlcIiwgKCkgPT4ge1xuICBsZXQgc3RhY2s6IFN0YWNrO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIHN0YWNrID0gbmV3IFN0YWNrKG5ldyBBcHAoKSwgXCJUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICB9KTtcblxuICBmdW5jdGlvbiBjcmVhdGVBcGkoc3RhdGljQXNzZXRzS2V5UHJlZml4Pzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgIHN0YXRpY0Fzc2V0c0tleVByZWZpeCxcbiAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgfSksXG4gICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXG4gICAgICAgIHsgbmFtZTogXCJmYXZpY29uLmljb1wiLCBpc0RpcmVjdG9yeTogZmFsc2UgfSxcbiAgICAgICAgeyBuYW1lOiBcImltYWdlc1wiLCBpc0RpcmVjdG9yeTogdHJ1ZSB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgUzMgaW50ZWdyYXRpb25zIGFkZHJlc3Mgb2JqZWN0cyBieSBrZXksIHNvIHRoZSB1cGxvYWRlZCBrZXkgcHJlZml4IGhhc1xuICAgKiB0byBhcHBlYXIgaW4gdGhlIGludGVncmF0aW9uIFVSSSBvciBldmVyeSBzdGF0aWMgcmVxdWVzdCA0MDRzLlxuICAgKi9cbiAgZnVuY3Rpb24gczNJbnRlZ3JhdGlvbktleXMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IG1ldGhvZHMgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmZpbmRSZXNvdXJjZXMoXG4gICAgICBcIkFXUzo6QXBpR2F0ZXdheTo6TWV0aG9kXCIsXG4gICAgKTtcbiAgICBjb25zdCBtYXJrZXIgPSBcInMzOnBhdGgvbXktYnVja2V0L1wiO1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKG1ldGhvZHMpXG4gICAgICAuZmxhdE1hcCgobWV0aG9kKSA9PiBtZXRob2QuUHJvcGVydGllcy5JbnRlZ3JhdGlvbi5VcmlbXCJGbjo6Sm9pblwiXVsxXSlcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChwYXJ0OiB1bmtub3duKTogcGFydCBpcyBzdHJpbmcgPT5cbiAgICAgICAgICB0eXBlb2YgcGFydCA9PT0gXCJzdHJpbmdcIiAmJiBwYXJ0LmluY2x1ZGVzKG1hcmtlciksXG4gICAgICApXG4gICAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LnNwbGl0KG1hcmtlcilbMV0pO1xuICB9XG5cbiAgaXQoXCJhZGRyZXNzZXMgb2JqZWN0cyBhdCB0aGUgYnVja2V0IHJvb3Qgd2hlbiBubyBrZXkgcHJlZml4IGlzIHNldFwiLCAoKSA9PiB7XG4gICAgY3JlYXRlQXBpKCk7XG5cbiAgICBleHBlY3QoczNJbnRlZ3JhdGlvbktleXMoKS5zb3J0KCkpLnRvRXF1YWwoW1xuICAgICAgXCJfbmV4dC9zdGF0aWMve2tleX1cIixcbiAgICAgIFwiZmF2aWNvbi5pY29cIixcbiAgICAgIFwiaW1hZ2VzL3trZXl9XCIsXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KFwicHJlZml4ZXMgZXZlcnkgUzMgaW50ZWdyYXRpb24ga2V5IHdpdGggdGhlIHN0YXRpYyBhc3NldHMga2V5IHByZWZpeFwiLCAoKSA9PiB7XG4gICAgY3JlYXRlQXBpKFwiYnJhbmNoLXhcIik7XG5cbiAgICBleHBlY3QoczNJbnRlZ3JhdGlvbktleXMoKS5zb3J0KCkpLnRvRXF1YWwoW1xuICAgICAgXCJicmFuY2gteC9fbmV4dC9zdGF0aWMve2tleX1cIixcbiAgICAgIFwiYnJhbmNoLXgvZmF2aWNvbi5pY29cIixcbiAgICAgIFwiYnJhbmNoLXgvaW1hZ2VzL3trZXl9XCIsXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KFwibm9ybWFsaXplcyBzdXJyb3VuZGluZyBzbGFzaGVzIG9uIHRoZSBrZXkgcHJlZml4XCIsICgpID0+IHtcbiAgICBjcmVhdGVBcGkoXCIvYnJhbmNoLXgvXCIpO1xuXG4gICAgZXhwZWN0KHMzSW50ZWdyYXRpb25LZXlzKCkpLnRvQ29udGFpbihcImJyYW5jaC14L19uZXh0L3N0YXRpYy97a2V5fVwiKTtcbiAgfSk7XG5cbiAgLyoqIFRoZSBzdGF0ZW1lbnRzIG9mIHRoZSBBUEkgR2F0ZXdheSDihpIgUzMgaW50ZWdyYXRpb24gcm9sZSdzIHBvbGljeS4gKi9cbiAgZnVuY3Rpb24gc3RhdGljSW50ZWdyYXRpb25TdGF0ZW1lbnRzKCkge1xuICAgIGNvbnN0IHBvbGljaWVzID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5maW5kUmVzb3VyY2VzKFxuICAgICAgXCJBV1M6OklBTTo6UG9saWN5XCIsXG4gICAgICB7XG4gICAgICAgIFByb3BlcnRpZXM6IHtcbiAgICAgICAgICBSb2xlczogW3sgUmVmOiBNYXRjaC5zdHJpbmdMaWtlUmVnZXhwKFwiU3RhdGljSW50ZWdyYXRpb25Sb2xlXCIpIH1dLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICApO1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHBvbGljaWVzKS5mbGF0TWFwKFxuICAgICAgKHBvbGljeSkgPT4gcG9saWN5LlByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnQuU3RhdGVtZW50LFxuICAgICk7XG4gIH1cblxuICBpdChcInNjb3BlcyB0aGUgUzMgaW50ZWdyYXRpb24gcm9sZSB0byB0aGUgc3RhdGljIGFzc2V0cyBrZXkgcHJlZml4XCIsICgpID0+IHtcbiAgICAvLyBBIHNoYXJlZCBidWNrZXQgaG9sZHMgb3RoZXIgYXBwcycgYXNzZXRzIHVuZGVyIHRoZWlyIG93biBwcmVmaXhlcy5cbiAgICBjcmVhdGVBcGkoXCIvYnJhbmNoLXgvXCIpO1xuXG4gICAgY29uc3QgYnVja2V0QXJuID0ge1xuICAgICAgXCJGbjo6Sm9pblwiOiBbXCJcIiwgW1wiYXJuOlwiLCB7IFJlZjogXCJBV1M6OlBhcnRpdGlvblwiIH0sIFwiOnMzOjo6bXktYnVja2V0XCJdXSxcbiAgICB9O1xuICAgIGV4cGVjdChzdGF0aWNJbnRlZ3JhdGlvblN0YXRlbWVudHMoKSkudG9FcXVhbChbXG4gICAgICB7XG4gICAgICAgIEFjdGlvbjogXCJzMzpHZXRPYmplY3RcIixcbiAgICAgICAgRWZmZWN0OiBcIkFsbG93XCIsXG4gICAgICAgIFJlc291cmNlOiB7XG4gICAgICAgICAgXCJGbjo6Sm9pblwiOiBbXG4gICAgICAgICAgICBcIlwiLFxuICAgICAgICAgICAgW1wiYXJuOlwiLCB7IFJlZjogXCJBV1M6OlBhcnRpdGlvblwiIH0sIFwiOnMzOjo6bXktYnVja2V0L2JyYW5jaC14LypcIl0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIC8vIFVuY29uZGl0aW9uZWQ6IFMzIGNoZWNrcyBpdCBkdXJpbmcgYSBHZXRPYmplY3QsIHdpdGggbm8gYHMzOnByZWZpeGAuXG4gICAgICAgIEFjdGlvbjogXCJzMzpMaXN0QnVja2V0XCIsXG4gICAgICAgIEVmZmVjdDogXCJBbGxvd1wiLFxuICAgICAgICBSZXNvdXJjZTogYnVja2V0QXJuLFxuICAgICAgfSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoXCJsZXRzIHRoZSBTMyBpbnRlZ3JhdGlvbiByb2xlIHJlYWQgdGhlIHdob2xlIGJ1Y2tldCB3aXRob3V0IGEga2V5IHByZWZpeFwiLCAoKSA9PiB7XG4gICAgY3JlYXRlQXBpKCk7XG5cbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gc3RhdGljSW50ZWdyYXRpb25TdGF0ZW1lbnRzKCk7XG4gICAgZXhwZWN0KHN0YXRlbWVudHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICBleHBlY3Qoc3RhdGVtZW50c1swXS5SZXNvdXJjZVtcIkZuOjpKb2luXCJdWzFdKS50b0NvbnRhaW4oXG4gICAgICBcIjpzMzo6Om15LWJ1Y2tldC8qXCIsXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoXCJrZWVwcyB0aGUga2V5IHByZWZpeCBpbmRlcGVuZGVudCBvZiBiYXNlUGF0aCwgd2hpY2ggaXMgdGhlIFVSTCBwcmVmaXhcIiwgKCkgPT4ge1xuICAgIC8vIEEgTmV4dGpzUmVnaW9uYWxGdW5jdGlvbnMgYXBwIHdob3NlIGBiYXNlUGF0aGAgbWF0Y2hlcyB0aGUgQVBJIEdhdGV3YXlcbiAgICAvLyBzdGFnZSBzdGlsbCBoYXMgaXRzIGFzc2V0cyBhdCB0aGUgYnVja2V0IHJvb3QuXG4gICAgbmV3IE5leHRqc0FwaShzdGFjaywgXCJOZXh0anNBcGlcIiwge1xuICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgYmFzZVBhdGg6IFwiL3Byb2RcIixcbiAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgfSksXG4gICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICB9KTtcblxuICAgIGV4cGVjdChzM0ludGVncmF0aW9uS2V5cygpKS50b0VxdWFsKFtcIl9uZXh0L3N0YXRpYy97a2V5fVwiXSk7XG4gICAgLy8gLi4uc2VydmVkIHVuZGVyIHRoZSBzdGFnZS1tYXRjaGluZyBVUkwgcHJlZml4LlxuICAgIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFxuICAgICAgXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsXG4gICAgICB7IFBhdGhQYXJ0OiBcInByb2RcIiB9LFxuICAgICk7XG4gIH0pO1xuXG4gIC8vIEFQSSBHYXRld2F5IHBhdGggcGFydHMgY2FuJ3QgY29udGFpbiBcIi9cIiwgc28gYSBuZXN0ZWQgYmFzZVBhdGggcGFzc2VkIHdob2xlXG4gIC8vIHRvIGBhZGRSZXNvdXJjZWAgZmFpbHMgQ0RLJ3MgYHZhbGlkYXRlUmVzb3VyY2VQYXRoUGFydGAgYXQgc3ludGguIEl0J3NcbiAgLy8gcmVhY2hhYmxlOiBgcmVzb2x2ZUJhc2VQYXRoYCBhY2NlcHRzIGEgbmVzdGVkIHByb3AgZm9yIFJFR0lPTkFMX0ZVTkNUSU9OUyBhc1xuICAvLyBsb25nIGFzIHRoZSBhcHAncyBiYXNlUGF0aCBlbmRzIHdpdGggaXQuXG4gIGRlc2NyaWJlKFwibmVzdGVkIGJhc2VQYXRoXCIsICgpID0+IHtcbiAgICBmdW5jdGlvbiBwYXRoUGFydHMoKTogc3RyaW5nW10ge1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5maW5kUmVzb3VyY2VzKFxuICAgICAgICBcIkFXUzo6QXBpR2F0ZXdheTo6UmVzb3VyY2VcIixcbiAgICAgICk7XG4gICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhyZXNvdXJjZXMpLm1hcChcbiAgICAgICAgKHJlc291cmNlKSA9PiByZXNvdXJjZS5Qcm9wZXJ0aWVzLlBhdGhQYXJ0LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVBcGlXaXRoQmFzZVBhdGgoYmFzZVBhdGg6IHN0cmluZykge1xuICAgICAgcmV0dXJuIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgICBiYXNlUGF0aCxcbiAgICAgICAgc2VydmVyRnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJTZXJ2ZXJGblwiLCB7XG4gICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgIH0pLFxuICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGl0KFwiY3JlYXRlcyBvbmUgcmVzb3VyY2UgcGVyIHNlZ21lbnRcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IGNyZWF0ZUFwaVdpdGhCYXNlUGF0aChcIi90ZWFtL2FwcFwiKSkubm90LnRvVGhyb3coKTtcblxuICAgICAgZXhwZWN0KHBhdGhQYXJ0cygpKS50b0VxdWFsKFxuICAgICAgICBleHBlY3QuYXJyYXlDb250YWluaW5nKFtcInRlYW1cIiwgXCJhcHBcIiwgXCJfbmV4dFwiLCBcIntwcm94eSt9XCJdKSxcbiAgICAgICk7XG4gICAgICAvLyBOb3QgdGhlIHVuc3BsaXQgdmFsdWUsIHdoaWNoIEFQSSBHYXRld2F5IHdvdWxkIHJlamVjdC5cbiAgICAgIGV4cGVjdChwYXRoUGFydHMoKSkubm90LnRvQ29udGFpbihcInRlYW0vYXBwXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJuZXN0cyB0aGUgc2VnbWVudHMgc28gdGhlIGFwcCBpcyByZWFjaGFibGUgdW5kZXIgdGhlIGZ1bGwgcGF0aFwiLCAoKSA9PiB7XG4gICAgICBjcmVhdGVBcGlXaXRoQmFzZVBhdGgoXCIvdGVhbS9hcHBcIik7XG5cbiAgICAgIGNvbnN0IHJlc291cmNlcyA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuZmluZFJlc291cmNlcyhcbiAgICAgICAgXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsXG4gICAgICApO1xuICAgICAgY29uc3QgYnlQYXRoUGFydCA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgT2JqZWN0LmVudHJpZXMocmVzb3VyY2VzKS5tYXAoKFtsb2dpY2FsSWQsIHJlc291cmNlXSkgPT4gW1xuICAgICAgICAgIHJlc291cmNlLlByb3BlcnRpZXMuUGF0aFBhcnQsXG4gICAgICAgICAgeyBsb2dpY2FsSWQsIHBhcmVudElkOiByZXNvdXJjZS5Qcm9wZXJ0aWVzLlBhcmVudElkIH0sXG4gICAgICAgIF0pLFxuICAgICAgKTtcbiAgICAgIC8vIFwiYXBwXCIgaGFuZ3Mgb2ZmIFwidGVhbVwiLCBub3Qgb2ZmIHRoZSBBUEkgcm9vdC5cbiAgICAgIGV4cGVjdChieVBhdGhQYXJ0LmFwcC5wYXJlbnRJZCkudG9FcXVhbCh7XG4gICAgICAgIFJlZjogYnlQYXRoUGFydC50ZWFtLmxvZ2ljYWxJZCxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGJ5UGF0aFBhcnQudGVhbS5wYXJlbnRJZCkudG9IYXZlUHJvcGVydHkoXCJGbjo6R2V0QXR0XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzdGlsbCBjcmVhdGVzIGEgc2luZ2xlIHJlc291cmNlIGZvciBhIGZsYXQgYmFzZVBhdGhcIiwgKCkgPT4ge1xuICAgICAgY3JlYXRlQXBpV2l0aEJhc2VQYXRoKFwiL2Jhc2VcIik7XG5cbiAgICAgIGV4cGVjdChwYXRoUGFydHMoKSkudG9Db250YWluKFwiYmFzZVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJ1cmxcIiwgKCkgPT4ge1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFwaVdpdGhPdmVycmlkZXMoXG4gICAgICBwcm9wczogUGFydGlhbDxOZXh0anNBcGlQcm9wcz4gPSB7fSxcbiAgICApOiBOZXh0anNBcGkge1xuICAgICAgcmV0dXJuIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgfSksXG4gICAgICAgIHB1YmxpY0RpckVudHJpZXM6IFtdLFxuICAgICAgICAuLi5wcm9wcyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRvbWFpbk5hbWUoYmFzZVBhdGg/OiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRvbWFpbk5hbWU6IFwiYXBwLmV4YW1wbGUuY29tXCIsXG4gICAgICAgIGNlcnRpZmljYXRlOiBDZXJ0aWZpY2F0ZS5mcm9tQ2VydGlmaWNhdGVBcm4oXG4gICAgICAgICAgc3RhY2ssXG4gICAgICAgICAgXCJDZXJ0XCIsXG4gICAgICAgICAgXCJhcm46YXdzOmFjbTp1cy1lYXN0LTE6MTIzNDU2Nzg5MDEyOmNlcnRpZmljYXRlL2FiY1wiLFxuICAgICAgICApLFxuICAgICAgICBiYXNlUGF0aCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIFJFU1QgQVBJIGlkLCB0aGUgc3RhZ2UgbmFtZSBhbmQgdGhlIGRvbWFpbiBuYW1lIGFyZSBhbGwgdG9rZW5zIHRoYXRcbiAgICAgKiBvbmx5IHJlc29sdmUgYXQgZGVwbG95IHRpbWUsIHNvIGZsYXR0ZW4gdGhlIHJlc29sdmVkIGBGbjo6Sm9pbmAgYW5kIHN0YW5kXG4gICAgICogZWFjaCByZWZlcmVuY2UgaW4gZm9yIHRoZSByZXNvdXJjZSBpdCBwb2ludHMgYXQgKG1pbnVzIENESydzIGxvZ2ljYWwgaWRcbiAgICAgKiBoYXNoIHN1ZmZpeCkuIFRoYXQga2VlcHMgdGhlIGFzc2VydGlvbnMgYWJvdXQgKndoaWNoKiByZXNvdXJjZSBzdXBwbGllc1xuICAgICAqIGVhY2ggcGFydCBvZiB0aGUgVVJMLCB3aGljaCBpcyB0aGUgd2hvbGUgcXVlc3Rpb24gaGVyZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXNvbHZlVXJsKGFwaTogTmV4dGpzQXBpKTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gc3RhY2sucmVzb2x2ZShhcGkudXJsKTtcbiAgICAgIGlmICh0eXBlb2YgcmVzb2x2ZWQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc29sdmVkW1wiRm46OkpvaW5cIl1bMV1cbiAgICAgICAgLm1hcCgocGFydDogdW5rbm93bikgPT5cbiAgICAgICAgICB0eXBlb2YgcGFydCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgPyBwYXJ0XG4gICAgICAgICAgICA6IGB7JHsocGFydCBhcyB7IFJlZjogc3RyaW5nIH0pLlJlZi5yZXBsYWNlKC9bMC05QS1GXXs4fSQvLCBcIlwiKX19YCxcbiAgICAgICAgKVxuICAgICAgICAuam9pbihcIlwiKTtcbiAgICB9XG5cbiAgICBpdChcInJlcG9ydHMgdGhlIGV4ZWN1dGUtYXBpIGVuZHBvaW50IHdpdGggdGhlIHN0YWdlIGFwcGVuZGVkIHdoZW4gdGhlcmUncyBubyBjdXN0b20gZG9tYWluXCIsICgpID0+IHtcbiAgICAgIC8vIFRoZSBzdGFnZSBpcyBpbiB0aGUgcGF0aCBvbmx5IGhlcmUsIHdoaWNoIGlzIHRoZSB3aG9sZSByZWFzb24gdGhlXG4gICAgICAvLyByZWdpb25hbC1mdW5jdGlvbnMgZXhhbXBsZSBzZXRzIGFuIGFwcCBiYXNlUGF0aCBvZiBcIi9wcm9kXCIuXG4gICAgICBleHBlY3QocmVzb2x2ZVVybChjcmVhdGVBcGlXaXRoT3ZlcnJpZGVzKCkpKS50b0JlKFxuICAgICAgICBcImh0dHBzOi8ve05leHRqc0FwaVJlc3RBcGl9LmV4ZWN1dGUtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3tOZXh0anNBcGlSZXN0QXBpRGVwbG95bWVudFN0YWdlcHJvZH1cIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcImFwcGVuZHMgYmFzZVBhdGgsIHdoaWNoIG5lc3RzIGV2ZXJ5IHJlc291cmNlIGEgbGV2ZWwgZG93blwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoXG4gICAgICAgIHJlc29sdmVVcmwoY3JlYXRlQXBpV2l0aE92ZXJyaWRlcyh7IGJhc2VQYXRoOiBcIi9teS1iYXNlLXBhdGhcIiB9KSksXG4gICAgICApLnRvQmUoXG4gICAgICAgIFwiaHR0cHM6Ly97TmV4dGpzQXBpUmVzdEFwaX0uZXhlY3V0ZS1hcGkudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20ve05leHRqc0FwaVJlc3RBcGlEZXBsb3ltZW50U3RhZ2Vwcm9kfS9teS1iYXNlLXBhdGhcIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInByZWZlcnMgYSBjdXN0b20gZG9tYWluIGFuZCBkcm9wcyB0aGUgc3RhZ2UgZnJvbSB0aGUgcGF0aFwiLCAoKSA9PiB7XG4gICAgICAvLyBBIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3QgaXMgdGhlIGNsZWFuZXN0IFJlZ2lvbmFsIHNldHVwOiBubyBzdGFnZSBpblxuICAgICAgLy8gdGhlIFVSTCBtZWFucyBubyBiYXNlUGF0aCBhbmQgbm8gc3RhZ2Ugd29ya2Fyb3VuZHMgYW55d2hlcmUuIFRoZSBzdGFnZSBpc1xuICAgICAgLy8gcmVhY2hlZCB0aHJvdWdoIHRoZSBkb21haW4ncyBiYXNlIHBhdGggbWFwcGluZyBpbnN0ZWFkLlxuICAgICAgZXhwZWN0KFxuICAgICAgICByZXNvbHZlVXJsKFxuICAgICAgICAgIGNyZWF0ZUFwaVdpdGhPdmVycmlkZXMoe1xuICAgICAgICAgICAgb3ZlcnJpZGVzOiB7IHJlc3RBcGlQcm9wczogeyBkb21haW5OYW1lOiBkb21haW5OYW1lKCkgfSB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKS50b0JlKFwiaHR0cHM6Ly97TmV4dGpzQXBpUmVzdEFwaUN1c3RvbURvbWFpbn1cIik7XG4gICAgfSk7XG5cbiAgICBpdChcImluY2x1ZGVzIGEgY3VzdG9tIGRvbWFpbidzIGJhc2UgcGF0aCBtYXBwaW5nXCIsICgpID0+IHtcbiAgICAgIC8vIENESyByZWplY3RzIHN1cnJvdW5kaW5nIHNsYXNoZXMgb24gYSBtYXBwaW5nLCBzbyBpdCdzIGFsd2F5cyBhIGJhcmVcbiAgICAgIC8vIHNlZ21lbnQgYnkgdGhlIHRpbWUgaXQgZ2V0cyBoZXJlLlxuICAgICAgZXhwZWN0KFxuICAgICAgICByZXNvbHZlVXJsKFxuICAgICAgICAgIGNyZWF0ZUFwaVdpdGhPdmVycmlkZXMoe1xuICAgICAgICAgICAgb3ZlcnJpZGVzOiB7IHJlc3RBcGlQcm9wczogeyBkb21haW5OYW1lOiBkb21haW5OYW1lKFwidGVhbS1hXCIpIH0gfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICkudG9CZShcImh0dHBzOi8ve05leHRqc0FwaVJlc3RBcGlDdXN0b21Eb21haW59L3RlYW0tYVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJmdW5jdGlvbkdyb3VwcyByZXNvdXJjZSB0cmVlXCIsICgpID0+IHtcbiAgICAvKiogTGFtYmRhIGZ1bmN0aW9ucyB0aGF0IGBBTllgIG9uIHRoZSByZXNvdXJjZSBhdCBgcGF0aFBhcnRgIGludm9rZXMuICovXG4gICAgZnVuY3Rpb24gYW55VGFyZ2V0cyhwYXRoUGFydDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6QXBpR2F0ZXdheTo6UmVzb3VyY2VcIiwge1xuICAgICAgICBQcm9wZXJ0aWVzOiB7IFBhdGhQYXJ0OiBwYXRoUGFydCB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBpZHMgPSBPYmplY3Qua2V5cyhyZXNvdXJjZXMpO1xuICAgICAgZXhwZWN0KGlkcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgY29uc3QgbWV0aG9kcyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoXCJBV1M6OkFwaUdhdGV3YXk6Ok1ldGhvZFwiLCB7XG4gICAgICAgIFByb3BlcnRpZXM6IHsgSHR0cE1ldGhvZDogXCJBTllcIiwgUmVzb3VyY2VJZDogeyBSZWY6IGlkc1swXSB9IH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKG1ldGhvZHMpLm1hcChcbiAgICAgICAgKG1ldGhvZCkgPT5cbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShtZXRob2QuUHJvcGVydGllcy5JbnRlZ3JhdGlvbi5VcmkpLm1hdGNoKFxuICAgICAgICAgICAgLyhTZXJ2ZXJGbnxHcm91cEZufFJlcG9ydHNGbilbQS1GMC05XSsvLFxuICAgICAgICAgICkhWzFdLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpdChcInNlbmRzIGEgZ3JvdXAncyBwYXJlbnQgcGF0aHMgdG8gdGhlIGRlZmF1bHQgZnVuY3Rpb25cIiwgKCkgPT4ge1xuICAgICAgLy8gQVBJIEdhdGV3YXkgYW5zd2VycyBhIG1ldGhvZGxlc3MgcmVzb3VyY2Ugd2l0aCA0MDMgcmF0aGVyIHRoYW4gZmFsbGluZ1xuICAgICAgLy8gYmFjayB0byB0aGUgcm9vdCBge3Byb3h5K31gLCBzbyBgL2FwaWAgYW5kIGAvYXBpL3JlcG9ydHNgIG5lZWQgb25lLlxuICAgICAgbmV3IE5leHRqc0FwaShzdGFjaywgXCJOZXh0anNBcGlcIiwge1xuICAgICAgICBzdGF0aWNBc3NldHNCdWNrZXQ6IEJ1Y2tldC5mcm9tQnVja2V0TmFtZShzdGFjaywgXCJCdWNrZXRcIiwgXCJteS1idWNrZXRcIiksXG4gICAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICB9KSxcbiAgICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgICAgIC4uLmdyb3VwZWQoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IFwicmVwb3J0c1wiLFxuICAgICAgICAgICAgcm91dGVzOiBbXCIvYXBpL3JlcG9ydHMvKipcIiwgXCIvYXBpL2V4cG9ydFwiXSxcbiAgICAgICAgICAgIGZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiR3JvdXBGblwiLCB7XG4gICAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICBdKSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoYW55VGFyZ2V0cyhcImFwaVwiKSkudG9FcXVhbChbXCJTZXJ2ZXJGblwiXSk7XG4gICAgICBleHBlY3QoYW55VGFyZ2V0cyhcInJlcG9ydHNcIikpLnRvRXF1YWwoW1wiU2VydmVyRm5cIl0pO1xuICAgICAgZXhwZWN0KGFueVRhcmdldHMoXCJleHBvcnRcIikpLnRvRXF1YWwoW1wiR3JvdXBGblwiXSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNlbmRzIGEgcGFyZW50IHVuZGVyIGFub3RoZXIgZ3JvdXAncyBzdWJ0cmVlIHRvIHRoYXQgZ3JvdXBcIiwgKCkgPT4ge1xuICAgICAgLy8gYGFzc2lnblJvdXRlc1RvR3JvdXBzYCBwYWNrYWdlcyBgL2FwaS9yZXBvcnRzYCBpbnRvIGBhcGlgLCBhbmRcbiAgICAgIC8vIENsb3VkRnJvbnQncyBgYXBpLypgIHNlbmRzIGl0IHRoZXJlOyBzbyBtdXN0IEFQSSBHYXRld2F5LlxuICAgICAgbmV3IE5leHRqc0FwaShzdGFjaywgXCJOZXh0anNBcGlcIiwge1xuICAgICAgICBzdGF0aWNBc3NldHNCdWNrZXQ6IEJ1Y2tldC5mcm9tQnVja2V0TmFtZShzdGFjaywgXCJCdWNrZXRcIiwgXCJteS1idWNrZXRcIiksXG4gICAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICB9KSxcbiAgICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgICAgIC4uLmdyb3VwZWQoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IFwiYXBpXCIsXG4gICAgICAgICAgICByb3V0ZXM6IFtcIi9hcGkvKipcIl0sXG4gICAgICAgICAgICBoYXNEYXRhUm91dGVzOiB0cnVlLFxuICAgICAgICAgICAgZnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJHcm91cEZuXCIsIHtcbiAgICAgICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogXCJyZXBvcnRzXCIsXG4gICAgICAgICAgICByb3V0ZXM6IFtcIi9hcGkvcmVwb3J0cy9xMS8qKlwiXSxcbiAgICAgICAgICAgIGhhc0RhdGFSb3V0ZXM6IHRydWUsXG4gICAgICAgICAgICBmdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlJlcG9ydHNGblwiLCB7XG4gICAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICBdKSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBFYWNoIHBhdGggcGFydCBiZWxvdyBhcHBlYXJzIHR3aWNlLCB1bmRlciBgL2AgYW5kIHVuZGVyIHRoZSBkYXRhXG4gICAgICAvLyBwcmVmaXgsIHNvIGNoZWNrIHRoZSB0cmVlIGJ5IHBhdGguXG4gICAgICBjb25zdCB0YXJnZXRzID0gYW55VGFyZ2V0c0J5UGF0aCgpO1xuICAgICAgZXhwZWN0KHRhcmdldHNbXCIvYXBpXCJdKS50b0VxdWFsKFtcIlNlcnZlckZuXCJdKTtcbiAgICAgIGV4cGVjdCh0YXJnZXRzW1wiL2FwaS9yZXBvcnRzXCJdKS50b0VxdWFsKFtcIkdyb3VwRm5cIl0pO1xuICAgICAgZXhwZWN0KHRhcmdldHNbXCIvYXBpL3JlcG9ydHMvcTFcIl0pLnRvRXF1YWwoW1wiR3JvdXBGblwiXSk7XG4gICAgICBleHBlY3QodGFyZ2V0c1tcIi9hcGkvcmVwb3J0cy9xMS97cHJveHkrfVwiXSkudG9FcXVhbChbXCJSZXBvcnRzRm5cIl0pO1xuICAgICAgZXhwZWN0KHRhcmdldHNbXCIvX25leHQvZGF0YS97YnVpbGRJZH0vYXBpL3JlcG9ydHNcIl0pLnRvRXF1YWwoW1wiR3JvdXBGblwiXSk7XG4gICAgICBleHBlY3QodGFyZ2V0c1tcIi9fbmV4dC9kYXRhL3tidWlsZElkfVwiXSkudG9FcXVhbChbXCJTZXJ2ZXJGblwiXSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVHcm91cGVkQXBpKGhhc0RhdGFSb3V0ZXM6IGJvb2xlYW4pIHtcbiAgICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgfSksXG4gICAgICAgIHB1YmxpY0RpckVudHJpZXM6IFtdLFxuICAgICAgICAuLi5ncm91cGVkKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiBcInJlcG9ydHNcIixcbiAgICAgICAgICAgIHJvdXRlczogW1wiL3JlcG9ydHMvKipcIiwgXCIvZG9jcy9pbnRyb1wiXSxcbiAgICAgICAgICAgIGhhc0RhdGFSb3V0ZXMsXG4gICAgICAgICAgICBmdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIkdyb3VwRm5cIiwge1xuICAgICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKiogRXZlcnkgcmVzb3VyY2UgcGF0aCBpbiB0aGUgQVBJLCBlLmcuIGAvX25leHQvZGF0YS97YnVpbGRJZH0veC5qc29uYC4gKi9cbiAgICBmdW5jdGlvbiByZXNvdXJjZVBhdGhzKCk6IHN0cmluZ1tdIHtcbiAgICAgIGNvbnN0IHJlc291cmNlcyA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuZmluZFJlc291cmNlcyhcbiAgICAgICAgXCJBV1M6OkFwaUdhdGV3YXk6OlJlc291cmNlXCIsXG4gICAgICApO1xuICAgICAgY29uc3QgcGF0aE9mID0gKGlkOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgICBjb25zdCB7IFBhcmVudElkLCBQYXRoUGFydCB9ID0gcmVzb3VyY2VzW2lkXS5Qcm9wZXJ0aWVzO1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBQYXJlbnRJZC5SZWY7XG4gICAgICAgIHJldHVybiBwYXJlbnQgJiYgcmVzb3VyY2VzW3BhcmVudF1cbiAgICAgICAgICA/IGAke3BhdGhPZihwYXJlbnQpfS8ke1BhdGhQYXJ0fWBcbiAgICAgICAgICA6IGAvJHtQYXRoUGFydH1gO1xuICAgICAgfTtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhyZXNvdXJjZXMpLm1hcChwYXRoT2YpLnNvcnQoKTtcbiAgICB9XG5cbiAgICAvKiogUmVzb3VyY2UgcGF0aCDihpIgdGhlIExhbWJkYSBmdW5jdGlvbnMgYEFOWWAgb24gaXQgaW52b2tlcy4gKi9cbiAgICBmdW5jdGlvbiBhbnlUYXJnZXRzQnlQYXRoKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gICAgICBjb25zdCByZXNvdXJjZXMgPSB0ZW1wbGF0ZS5maW5kUmVzb3VyY2VzKFwiQVdTOjpBcGlHYXRld2F5OjpSZXNvdXJjZVwiKTtcbiAgICAgIGNvbnN0IHBhdGhPZiA9IChpZDogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgICAgY29uc3QgeyBQYXJlbnRJZCwgUGF0aFBhcnQgfSA9IHJlc291cmNlc1tpZF0uUHJvcGVydGllcztcbiAgICAgICAgY29uc3QgcGFyZW50ID0gUGFyZW50SWQuUmVmO1xuICAgICAgICByZXR1cm4gcGFyZW50ICYmIHJlc291cmNlc1twYXJlbnRdXG4gICAgICAgICAgPyBgJHtwYXRoT2YocGFyZW50KX0vJHtQYXRoUGFydH1gXG4gICAgICAgICAgOiBgLyR7UGF0aFBhcnR9YDtcbiAgICAgIH07XG4gICAgICBjb25zdCBtZXRob2RzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6QXBpR2F0ZXdheTo6TWV0aG9kXCIsIHtcbiAgICAgICAgUHJvcGVydGllczogeyBIdHRwTWV0aG9kOiBcIkFOWVwiIH0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHRhcmdldHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xuICAgICAgZm9yIChjb25zdCBtZXRob2Qgb2YgT2JqZWN0LnZhbHVlcyhtZXRob2RzKSkge1xuICAgICAgICBjb25zdCBpZCA9IG1ldGhvZC5Qcm9wZXJ0aWVzLlJlc291cmNlSWQ/LlJlZjtcbiAgICAgICAgaWYgKCFpZCB8fCAhcmVzb3VyY2VzW2lkXSkgY29udGludWU7XG4gICAgICAgICh0YXJnZXRzW3BhdGhPZihpZCldID8/PSBbXSkucHVzaChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShtZXRob2QuUHJvcGVydGllcy5JbnRlZ3JhdGlvbi5VcmkpLm1hdGNoKFxuICAgICAgICAgICAgLyhTZXJ2ZXJGbnxHcm91cEZufFJlcG9ydHNGbilbQS1GMC05XSsvLFxuICAgICAgICAgICkhWzFdLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRhcmdldHM7XG4gICAgfVxuXG4gICAgaXQoXCJyb3V0ZXMgYSBncm91cCdzIFBhZ2VzIFJvdXRlciBkYXRhIFVSTHMgdG8gaXQgdG9vXCIsICgpID0+IHtcbiAgICAgIGNyZWF0ZUdyb3VwZWRBcGkodHJ1ZSk7XG5cbiAgICAgIGNvbnN0IHBhdGhzID0gcmVzb3VyY2VQYXRocygpO1xuICAgICAgZXhwZWN0KHBhdGhzKS50b0NvbnRhaW4oXCIvX25leHQvZGF0YS97YnVpbGRJZH0vcmVwb3J0cy97cHJveHkrfVwiKTtcbiAgICAgIGV4cGVjdChwYXRocykudG9Db250YWluKFwiL19uZXh0L2RhdGEve2J1aWxkSWR9L2RvY3MvaW50cm8uanNvblwiKTtcbiAgICAgIGV4cGVjdChhbnlUYXJnZXRzKFwiaW50cm8uanNvblwiKSkudG9FcXVhbChbXCJHcm91cEZuXCJdKTtcbiAgICAgIC8vIEEgbWV0aG9kbGVzcyBwYXJlbnQgYW5zd2VycyA0MDMsIHNvIHRoZSBkYXRhIHByZWZpeCBuZWVkcyB0aGUgZGVmYXVsdC5cbiAgICAgIGV4cGVjdChhbnlUYXJnZXRzKFwie2J1aWxkSWR9XCIpKS50b0VxdWFsKFtcIlNlcnZlckZuXCJdKTtcbiAgICB9KTtcblxuICAgIGl0KFwia2VlcHMgZWFjaCBncm91cCdzIGRhdGEgVVJMcyB0byBpdHMgb3duIHN1YnRyZWUgKEEpXCIsICgpID0+IHtcbiAgICAgIC8vIGB7YnVpbGRJZH1gIGlzIG9uZSBwYXRoIHNlZ21lbnQsIHdoZXJlIENsb3VkRnJvbnQncyBgKmAgY3Jvc3NlZCBgL2A6XG4gICAgICAvLyBgL19uZXh0L2RhdGEvPGlkPi9kb2NzL2Jsb2cveC5qc29uYCBoYXMgbm8gd2F5IGludG8gYmxvZydzIHJlc291cmNlLlxuICAgICAgbmV3IE5leHRqc0FwaShzdGFjaywgXCJOZXh0anNBcGlcIiwge1xuICAgICAgICBzdGF0aWNBc3NldHNCdWNrZXQ6IEJ1Y2tldC5mcm9tQnVja2V0TmFtZShzdGFjaywgXCJCdWNrZXRcIiwgXCJteS1idWNrZXRcIiksXG4gICAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICB9KSxcbiAgICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgICAgIC4uLmdyb3VwZWQoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IFwiYmxvZ1wiLFxuICAgICAgICAgICAgcm91dGVzOiBbXCIvYmxvZy8qKlwiXSxcbiAgICAgICAgICAgIGhhc0RhdGFSb3V0ZXM6IHRydWUsXG4gICAgICAgICAgICBmdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIkdyb3VwRm5cIiwge1xuICAgICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSksXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChcbiAgICAgICAgcmVzb3VyY2VQYXRocygpLmZpbHRlcigocGF0aCkgPT4gcGF0aC5zdGFydHNXaXRoKFwiL19uZXh0L2RhdGFcIikpLFxuICAgICAgKS50b0VxdWFsKFtcbiAgICAgICAgXCIvX25leHQvZGF0YVwiLFxuICAgICAgICBcIi9fbmV4dC9kYXRhL3tidWlsZElkfVwiLFxuICAgICAgICBcIi9fbmV4dC9kYXRhL3tidWlsZElkfS9ibG9nXCIsXG4gICAgICAgIFwiL19uZXh0L2RhdGEve2J1aWxkSWR9L2Jsb2cve3Byb3h5K31cIixcbiAgICAgIF0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJyb3V0ZXMgYW4gb3B0aW9uYWwgY2F0Y2gtYWxsJ3MgcGFyZW50IHRvIHRoZSBncm91cCB3aGVuIGl0IGlzIGxpc3RlZCAoQilcIiwgKCkgPT4ge1xuICAgICAgLy8gVGhlIGJ1aWxkIHJvdXRlcyBgL3Nob3BgIGFsb25nc2lkZSBgL3Nob3AvKipgIHdoZW4gdGhlIGdyb3VwIG93bnNcbiAgICAgIC8vIGBzaG9wL1tbLi4uc2x1Z11dYCAoc2VlIGByb3V0ZWRQYXR0ZXJuc2ApOiBge3Byb3h5K31gIGRvZXMgbm90IG1hdGNoXG4gICAgICAvLyB0aGUgcGFyZW50LCB3aGljaCB3b3VsZCBvdGhlcndpc2UgcmVhY2ggdGhlIGRlZmF1bHQgZnVuY3Rpb24uXG4gICAgICBuZXcgTmV4dGpzQXBpKHN0YWNrLCBcIk5leHRqc0FwaVwiLCB7XG4gICAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgICAgc2VydmVyRnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJTZXJ2ZXJGblwiLCB7XG4gICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgIH0pLFxuICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICAgICAgLi4uZ3JvdXBlZChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogXCJzaG9wXCIsXG4gICAgICAgICAgICByb3V0ZXM6IFtcIi9zaG9wLyoqXCIsIFwiL3Nob3BcIl0sXG4gICAgICAgICAgICBmdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIkdyb3VwRm5cIiwge1xuICAgICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSksXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChhbnlUYXJnZXRzKFwic2hvcFwiKSkudG9FcXVhbChbXCJHcm91cEZuXCJdKTtcbiAgICB9KTtcblxuICAgIGl0LmVhY2goW1xuICAgICAgW3sgbmFtZTogXCJkb2NzXCIsIGlzRGlyZWN0b3J5OiB0cnVlIH0sIFwiL2RvY3MvKipcIiwgXCJkaXJlY3RvcnlcIl0sXG4gICAgICBbeyBuYW1lOiBcImRvY3NcIiwgaXNEaXJlY3Rvcnk6IHRydWUgfSwgXCIvZG9jcy9ndWlkZS8qKlwiLCBcImRpcmVjdG9yeVwiXSxcbiAgICAgIFt7IG5hbWU6IFwicm9ib3RzLnR4dFwiLCBpc0RpcmVjdG9yeTogZmFsc2UgfSwgXCIvcm9ib3RzLnR4dFwiLCBcImZpbGVcIl0sXG4gICAgXSkoXG4gICAgICBcInJlamVjdHMgYSBncm91cCByb3V0ZSBvbiBhIHB1YmxpYy8gZW50cnkncyByZXNvdXJjZTogJXAgd2l0aCAlcCAoRSlcIixcbiAgICAgIChlbnRyeSwgcm91dGUsIGtpbmQpID0+IHtcbiAgICAgICAgZXhwZWN0KFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBuZXcgTmV4dGpzQXBpKHN0YWNrLCBcIk5leHRqc0FwaVwiLCB7XG4gICAgICAgICAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKFxuICAgICAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgICAgIFwiQnVja2V0XCIsXG4gICAgICAgICAgICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgc2VydmVyRnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJTZXJ2ZXJGblwiLCB7XG4gICAgICAgICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbZW50cnldLFxuICAgICAgICAgICAgICAuLi5ncm91cGVkKFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBuYW1lOiBcImdcIixcbiAgICAgICAgICAgICAgICAgIHJvdXRlczogW3JvdXRlXSxcbiAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiR3JvdXBGblwiLCB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgICAgICAgICAgICBjb2RlOiBDb2RlLmZyb21JbmxpbmUoXCJleHBvcnRzLmhhbmRsZXIgPSBhc3luYyAoKSA9PiB7fTtcIiksXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApLnRvVGhyb3coYG92ZXJsYXBzIHRoZSB0b3AtbGV2ZWwgcHVibGljLyAke2tpbmR9IFwiJHtlbnRyeS5uYW1lfVwiYCk7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICBpdChcImFsbG93cyBhbiBleGFjdCByb3V0ZSBuYW1lZCBsaWtlIGEgcHVibGljLyBkaXJlY3RvcnksIHdoaWNoIGlzIG5vdCB1bmRlciBpdFwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoXG4gICAgICAgICgpID0+XG4gICAgICAgICAgbmV3IE5leHRqc0FwaShzdGFjaywgXCJOZXh0anNBcGlcIiwge1xuICAgICAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoXG4gICAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgICBcIkJ1Y2tldFwiLFxuICAgICAgICAgICAgICBcIm15LWJ1Y2tldFwiLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbeyBuYW1lOiBcImRvY3NcIiwgaXNEaXJlY3Rvcnk6IHRydWUgfV0sXG4gICAgICAgICAgICAuLi5ncm91cGVkKFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwiZ1wiLFxuICAgICAgICAgICAgICAgIHJvdXRlczogW1wiL2RvY3NcIl0sXG4gICAgICAgICAgICAgICAgZnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJHcm91cEZuXCIsIHtcbiAgICAgICAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgIH0pLFxuICAgICAgKS5ub3QudG9UaHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJyb3V0ZXMgYW4gZXhhY3Qgcm91dGUncyB0cmFpbGluZ1NsYXNoIGZvcm0gdGhyb3VnaCBpdHMgb25lIHJlc291cmNlXCIsICgpID0+IHtcbiAgICAgIC8vIENsb3VkRnJvbnQgbmVlZHMgYHByaWNpbmcvYCBhcyBhIGJlaGF2aW9yIG9mIGl0cyBvd247IEFQSSBHYXRld2F5XG4gICAgICAvLyBtYXRjaGVzIGAvcHJpY2luZy9gIG9uIHRoZSBgcHJpY2luZ2AgcmVzb3VyY2UsIHNvIHRoZSB2YXJpYW50IGFkZHNcbiAgICAgIC8vIG5vdGhpbmcgaGVyZSBhbmQgbXVzdCBub3QgYWRkIHRoZSByZXNvdXJjZSB0d2ljZS5cbiAgICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgfSksXG4gICAgICAgIHB1YmxpY0RpckVudHJpZXM6IFtdLFxuICAgICAgICAuLi5ncm91cGVkKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiBcInByaWNpbmdcIixcbiAgICAgICAgICAgIHJvdXRlczogW1wiL3ByaWNpbmdcIl0sXG4gICAgICAgICAgICB0cmFpbGluZ1NsYXNoOiB0cnVlLFxuICAgICAgICAgICAgZnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJHcm91cEZuXCIsIHtcbiAgICAgICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgICBleHBlY3QoXG4gICAgICAgIHJlc291cmNlUGF0aHMoKS5maWx0ZXIoKHBhdGgpID0+ICFwYXRoLnN0YXJ0c1dpdGgoXCIvX25leHQvc3RhdGljXCIpKSxcbiAgICAgICkudG9FcXVhbChbXCIvX25leHRcIiwgXCIvcHJpY2luZ1wiLCBcIi97cHJveHkrfVwiXSk7XG4gICAgICBleHBlY3QoYW55VGFyZ2V0c0J5UGF0aCgpKS50b0VxdWFsKHtcbiAgICAgICAgXCIvcHJpY2luZ1wiOiBbXCJHcm91cEZuXCJdLFxuICAgICAgICBcIi97cHJveHkrfVwiOiBbXCJTZXJ2ZXJGblwiXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJyZWplY3RzIGEgYmVoYXZpb3IgZm9yIGEgZ3JvdXAgaXQgd2FzIG5vdCBnaXZlblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGZ1bmN0aW9uR3JvdXBCZWhhdmlvcnMgfSA9IGdyb3VwZWQoW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJhcGlcIixcbiAgICAgICAgICByb3V0ZXM6IFtcIi9hcGkvKipcIl0sXG4gICAgICAgICAgZnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJHcm91cEZuXCIsIHtcbiAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKFxuICAgICAgICAgICAgICBzdGFjayxcbiAgICAgICAgICAgICAgXCJCdWNrZXRcIixcbiAgICAgICAgICAgICAgXCJteS1idWNrZXRcIixcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjJfWCxcbiAgICAgICAgICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcHVibGljRGlyRW50cmllczogW10sXG4gICAgICAgICAgICBmdW5jdGlvbkdyb3VwQmVoYXZpb3JzLFxuICAgICAgICAgIH0pLFxuICAgICAgKS50b1Rocm93KC9yb3V0ZXMgdG8gZnVuY3Rpb24gZ3JvdXAgXCJhcGlcIiwgd2hpY2ggaXMgbm90IGluLyk7XG4gICAgfSk7XG5cbiAgICBpdChcImFkZHMgbm8gZGF0YSByb3V0ZXMgZm9yIGFuIGFwcCB3aXRob3V0IFBhZ2VzIFJvdXRlciByb3V0ZXNcIiwgKCkgPT4ge1xuICAgICAgY3JlYXRlR3JvdXBlZEFwaShmYWxzZSk7XG5cbiAgICAgIGV4cGVjdChcbiAgICAgICAgcmVzb3VyY2VQYXRocygpLmZpbHRlcigocGF0aCkgPT4gcGF0aC5zdGFydHNXaXRoKFwiL19uZXh0L2RhdGFcIikpLFxuICAgICAgKS50b0VxdWFsKFtdKTtcbiAgICB9KTtcblxuICAgIGl0KFwiZ3JhbnRzIGVhY2ggZnVuY3Rpb24gb25lIEFQSS1zY29wZWQgcGVybWlzc2lvbiwgbm90IHR3byBwZXIgbWV0aG9kXCIsICgpID0+IHtcbiAgICAgIC8vIFBlci1tZXRob2QgcGVybWlzc2lvbnMgcHV0IHR3byBzdGF0ZW1lbnRzIGluIHRoZSBmdW5jdGlvbidzIHJlc291cmNlXG4gICAgICAvLyBwb2xpY3kgZm9yIGV2ZXJ5IGBBTllgLCB3aGljaCBvdXRncm93cyBMYW1iZGEncyAyMCBLQiBjYXAuXG4gICAgICBjcmVhdGVHcm91cGVkQXBpKHRydWUpO1xuXG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IE9iamVjdC52YWx1ZXMoXG4gICAgICAgIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuZmluZFJlc291cmNlcyhcIkFXUzo6TGFtYmRhOjpQZXJtaXNzaW9uXCIsIHtcbiAgICAgICAgICBQcm9wZXJ0aWVzOiB7IFByaW5jaXBhbDogXCJhcGlnYXRld2F5LmFtYXpvbmF3cy5jb21cIiB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBleHBlY3QocGVybWlzc2lvbnMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGZvciAoY29uc3QgcGVybWlzc2lvbiBvZiBwZXJtaXNzaW9ucykge1xuICAgICAgICBjb25zdCBzb3VyY2VBcm4gPSBKU09OLnN0cmluZ2lmeShwZXJtaXNzaW9uLlByb3BlcnRpZXMuU291cmNlQXJuKTtcbiAgICAgICAgZXhwZWN0KHNvdXJjZUFybikudG9Db250YWluKFwiOmV4ZWN1dGUtYXBpOlwiKTtcbiAgICAgICAgZXhwZWN0KHNvdXJjZUFybikudG9Db250YWluKFwiLyovKi8qXCIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBpdChcIm5hbWVzIHRoZSBncm91cCBhbmQgcGF0dGVybiBBUEkgR2F0ZXdheSBjYW5ub3Qgcm91dGVcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgICBzdGF0aWNBc3NldHNCdWNrZXQ6IEJ1Y2tldC5mcm9tQnVja2V0TmFtZShcbiAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgXCJCdWNrZXRcIixcbiAgICAgICAgICAgIFwibXktYnVja2V0XCIsXG4gICAgICAgICAgKSxcbiAgICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIyX1gsXG4gICAgICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICAgICAgICAuLi5ncm91cGVkKFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmFtZTogXCJhYm91dFwiLFxuICAgICAgICAgICAgICByb3V0ZXM6IFtcIi9hYm91dH51c1wiXSxcbiAgICAgICAgICAgICAgZnVuY3Rpb246IG5ldyBMYW1iZGFGdW5jdGlvbihzdGFjaywgXCJHcm91cEZuXCIsIHtcbiAgICAgICAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0pLFxuICAgICAgICB9KSxcbiAgICApLnRvVGhyb3coL3BhdHRlcm4gXCJcXC9hYm91dH51c1wiIFxcKGdyb3VwIFwiYWJvdXRcIlxcKSBoYXMgYSBzZWdtZW50Lyk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiYSBwdWJsaWMvIGVudHJ5IEFQSSBHYXRld2F5IGNhbm5vdCBhZGRyZXNzXCIsICgpID0+IHtcbiAgICBpdChcIndhcm5zIGFuZCBza2lwcyBpdCBpbnN0ZWFkIG9mIGZhaWxpbmcgdGhlIHN5bnRoXCIsICgpID0+IHtcbiAgICAgIC8vIGBwdWJsaWMvaGVsbG8gd29ybGQuanBnYCBpcyBhIHZhbGlkIE5leHQuanMgYXNzZXQgdGhhdCBgYWRkUmVzb3VyY2VgXG4gICAgICAvLyByZWplY3RzIG91dHJpZ2h0LCB0YWtpbmcgdGhlIHdob2xlIGFwcCdzIHN5bnRoIHdpdGggaXQuIFRoZSBHbG9iYWwgdHlwZXNcbiAgICAgIC8vIHNlcnZlIGl0IHdpdGggYSB3aWxkY2FyZCBwYXRoIHBhdHRlcm47IGhlcmUgdGhlIGhvbmVzdCBvdXRjb21lIGlzIG9uZVxuICAgICAgLy8gNDA0aW5nIGFzc2V0IGFuZCBhIHdhcm5pbmcgdGhhdCBuYW1lcyBpdC5cbiAgICAgIGNvbnN0IGFwaSA9IG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgICAgc3RhdGljQXNzZXRzQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoc3RhY2ssIFwiQnVja2V0XCIsIFwibXktYnVja2V0XCIpLFxuICAgICAgICBzZXJ2ZXJGdW5jdGlvbjogbmV3IExhbWJkYUZ1bmN0aW9uKHN0YWNrLCBcIlNlcnZlckZuXCIsIHtcbiAgICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaGFuZGxlclwiLFxuICAgICAgICAgIGNvZGU6IENvZGUuZnJvbUlubGluZShcImV4cG9ydHMuaGFuZGxlciA9IGFzeW5jICgpID0+IHt9O1wiKSxcbiAgICAgICAgfSksXG4gICAgICAgIHB1YmxpY0RpckVudHJpZXM6IFtcbiAgICAgICAgICB7IG5hbWU6IFwiaGVsbG8gd29ybGQuanBnXCIsIGlzRGlyZWN0b3J5OiBmYWxzZSB9LFxuICAgICAgICAgIHsgbmFtZTogXCLDpMO2w7zFocSNxZnDrS5wbmdcIiwgaXNEaXJlY3Rvcnk6IGZhbHNlIH0sXG4gICAgICAgICAgeyBuYW1lOiBcImZhdmljb24uaWNvXCIsIGlzRGlyZWN0b3J5OiBmYWxzZSB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBBbm5vdGF0aW9ucy5mcm9tU3RhY2soc3RhY2spXG4gICAgICAgIC5maW5kV2FybmluZyhgLyR7YXBpLm5vZGUucGF0aH1gLCBNYXRjaC5hbnlWYWx1ZSgpKVxuICAgICAgICAubWFwKCh3YXJuaW5nKSA9PiB3YXJuaW5nLmVudHJ5LmRhdGEgYXMgc3RyaW5nKVxuICAgICAgICAuam9pbihcIlxcblwiKTtcbiAgICAgIGV4cGVjdChtZXNzYWdlKS50b0NvbnRhaW4oJ1wiaGVsbG8gd29ybGQuanBnXCInKTtcbiAgICAgIGV4cGVjdChtZXNzYWdlKS50b0NvbnRhaW4oJ1wiw6TDtsO8xaHEjcWZw60ucG5nXCInKTtcbiAgICAgIGV4cGVjdChtZXNzYWdlKS5ub3QudG9Db250YWluKCdcImZhdmljb24uaWNvXCInKTtcbiAgICAgIC8vIFRoZSBleHByZXNzaWJsZSBvbmUgaXMgc3RpbGwgc2VydmVkLlxuICAgICAgZXhwZWN0KHMzSW50ZWdyYXRpb25LZXlzKCkpLnRvQ29udGFpbihcImZhdmljb24uaWNvXCIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIk5leHRqc0FwaSByZWRlcGxveSBhZnRlciB1cGRhdGVcIiwgKCkgPT4ge1xuICBmdW5jdGlvbiBzeW50aChwcm9wczogUGFydGlhbDxOZXh0anNBcGlQcm9wcz4gPSB7fSkge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKG5ldyBBcHAoKSwgXCJUZXN0U3RhY2tcIiwge1xuICAgICAgZW52OiB7IGFjY291bnQ6IFwiMTIzNDU2Nzg5MDEyXCIsIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIiB9LFxuICAgIH0pO1xuICAgIG5ldyBOZXh0anNBcGkoc3RhY2ssIFwiTmV4dGpzQXBpXCIsIHtcbiAgICAgIHN0YXRpY0Fzc2V0c0J1Y2tldDogQnVja2V0LmZyb21CdWNrZXROYW1lKHN0YWNrLCBcIkJ1Y2tldFwiLCBcIm15LWJ1Y2tldFwiKSxcbiAgICAgIHNlcnZlckZ1bmN0aW9uOiBuZXcgTGFtYmRhRnVuY3Rpb24oc3RhY2ssIFwiU2VydmVyRm5cIiwge1xuICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMl9YLFxuICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKFwiZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKCkgPT4ge307XCIpLFxuICAgICAgfSksXG4gICAgICBwdWJsaWNEaXJFbnRyaWVzOiBbXSxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICAgIHJldHVybiBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICB9XG5cbiAgLyoqIFRoZSBgRm46OkpvaW5gIHBhcnRzIG9mIGV2ZXJ5IHJlc291cmNlIHRoZSByZWRlcGxveSByb2xlIGlzIGdyYW50ZWQuICovXG4gIGZ1bmN0aW9uIGdyYW50ZWRSZXNvdXJjZXModGVtcGxhdGU6IFRlbXBsYXRlKSB7XG4gICAgY29uc3QgW3BvbGljeV0gPSBPYmplY3QudmFsdWVzKFxuICAgICAgdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6SUFNOjpQb2xpY3lcIiwge1xuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgUG9saWN5TmFtZTogTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cChcIlJlZGVwbG95Rm5cIiksXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiBwb2xpY3kuUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudC5TdGF0ZW1lbnQubWFwKFxuICAgICAgKHN0YXRlbWVudDogeyBBY3Rpb246IHN0cmluZzsgUmVzb3VyY2U6IHVua25vd24gfSkgPT4gKHtcbiAgICAgICAgYWN0aW9uOiBzdGF0ZW1lbnQuQWN0aW9uLFxuICAgICAgICByZXNvdXJjZXM6IEpTT04uc3RyaW5naWZ5KHN0YXRlbWVudC5SZXNvdXJjZSksXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgaXQoXCJyZWRlcGxveXMgdGhlIHN0YWdlIG9uIHRoaXMgc3RhY2sncyBVUERBVEVfQ09NUExFVEVcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gc3ludGgoKTtcblxuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RXZlbnRzOjpSdWxlXCIsIHtcbiAgICAgIEV2ZW50UGF0dGVybjoge1xuICAgICAgICBzb3VyY2U6IFtcImF3cy5jbG91ZGZvcm1hdGlvblwiXSxcbiAgICAgICAgXCJkZXRhaWwtdHlwZVwiOiBbXCJDbG91ZEZvcm1hdGlvbiBTdGFjayBTdGF0dXMgQ2hhbmdlXCJdLFxuICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICBcInN0YWNrLWlkXCI6IFt7IFJlZjogXCJBV1M6OlN0YWNrSWRcIiB9XSxcbiAgICAgICAgICBcInN0YXR1cy1kZXRhaWxzXCI6IHtcbiAgICAgICAgICAgIHN0YXR1czogW1wiVVBEQVRFX0NPTVBMRVRFXCIsIFwiVVBEQVRFX1JPTExCQUNLX0NPTVBMRVRFXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgVGFyZ2V0czogW1xuICAgICAgICBNYXRjaC5vYmplY3RMaWtlKHtcbiAgICAgICAgICBBcm46IHsgXCJGbjo6R2V0QXR0XCI6IFtNYXRjaC5zdHJpbmdMaWtlUmVnZXhwKFwiUmVkZXBsb3lGblwiKSwgXCJBcm5cIl0gfSxcbiAgICAgICAgfSksXG4gICAgICBdLFxuICAgIH0pO1xuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6TGFtYmRhOjpGdW5jdGlvblwiLCB7XG4gICAgICBIYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgIEVudmlyb25tZW50OiB7XG4gICAgICAgIFZhcmlhYmxlczoge1xuICAgICAgICAgIFJFU1RfQVBJX0lEOiB7IFJlZjogTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cChcIlJlc3RBcGlcIikgfSxcbiAgICAgICAgICBTVEFHRV9OQU1FOiB7IFJlZjogTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cChcIkRlcGxveW1lbnRTdGFnZVwiKSB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoXCJzY29wZXMgaXRzIEFQSSBHYXRld2F5IGFjY2VzcyB0byB0aGlzIFJFU1QgQVBJXCIsICgpID0+IHtcbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gZ3JhbnRlZFJlc291cmNlcyhzeW50aCgpKTtcblxuICAgIGV4cGVjdChzdGF0ZW1lbnRzLm1hcCgoczogeyBhY3Rpb246IHN0cmluZyB9KSA9PiBzLmFjdGlvbikpLnRvRXF1YWwoW1xuICAgICAgXCJhcGlnYXRld2F5OlBPU1RcIixcbiAgICAgIFwiYXBpZ2F0ZXdheTpHRVRcIixcbiAgICAgIFwiYXBpZ2F0ZXdheTpERUxFVEVcIixcbiAgICBdKTtcbiAgICBmb3IgKGNvbnN0IHsgcmVzb3VyY2VzIH0gb2Ygc3RhdGVtZW50cykge1xuICAgICAgZXhwZWN0KHJlc291cmNlcykudG9Db250YWluKFwiL3Jlc3RhcGlzL1wiKTtcbiAgICAgIGV4cGVjdChyZXNvdXJjZXMpLnRvTWF0Y2goL1wiUmVmXCI6XCJOZXh0anNBcGlSZXN0QXBpWzAtOUEtRl0rXCIvKTtcbiAgICAgIGV4cGVjdChyZXNvdXJjZXMpLm5vdC50b01hdGNoKC9yZXN0YXBpc1xcL1xcKi8pO1xuICAgIH1cbiAgICBleHBlY3Qoc3RhdGVtZW50c1swXS5yZXNvdXJjZXMpLnRvQ29udGFpbihcIi9kZXBsb3ltZW50c1wiKTtcbiAgICBleHBlY3Qoc3RhdGVtZW50c1syXS5yZXNvdXJjZXMpLnRvQ29udGFpbihcIi9kZXBsb3ltZW50cy8qXCIpO1xuICB9KTtcblxuICBpdChcImlzIG9mZiB3aGVuIHJlZGVwbG95QWZ0ZXJVcGRhdGUgaXMgZmFsc2VcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHRlbXBsYXRlID0gc3ludGgoeyByZWRlcGxveUFmdGVyVXBkYXRlOiBmYWxzZSB9KTtcblxuICAgIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcyhcIkFXUzo6RXZlbnRzOjpSdWxlXCIsIDApO1xuICB9KTtcblxuICBpdChcImlzIG9mZiB3aGVuIHRoZSBBUEkgZGVwbG95cyBubyBzdGFnZVwiLCAoKSA9PiB7XG4gICAgY29uc3QgdGVtcGxhdGUgPSBzeW50aCh7XG4gICAgICBvdmVycmlkZXM6IHsgcmVzdEFwaVByb3BzOiB7IGRlcGxveTogZmFsc2UgfSB9LFxuICAgIH0pO1xuXG4gICAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKFwiQVdTOjpFdmVudHM6OlJ1bGVcIiwgMCk7XG4gIH0pO1xuXG4gIGl0KFwidGFrZXMgZnVuY3Rpb24gb3ZlcnJpZGVzXCIsICgpID0+IHtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHN5bnRoKHtcbiAgICAgIG92ZXJyaWRlczogeyByZWRlcGxveUZ1bmN0aW9uUHJvcHM6IHsgbWVtb3J5U2l6ZTogNTEyIH0gfSxcbiAgICB9KTtcblxuICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6TGFtYmRhOjpGdW5jdGlvblwiLCB7XG4gICAgICBNZW1vcnlTaXplOiA1MTIsXG4gICAgICBFbnZpcm9ubWVudDoge1xuICAgICAgICBWYXJpYWJsZXM6IHsgUkVTVF9BUElfSUQ6IE1hdGNoLmFueVZhbHVlKCkgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=