@aws-cdk-testing/cli-integ 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/.eslintrc.js +9 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +16 -0
  4. package/README.md +205 -0
  5. package/bin/apply-patches +22 -0
  6. package/bin/download-and-run-old-tests +52 -0
  7. package/bin/query-github +2 -0
  8. package/bin/query-github.d.ts +1 -0
  9. package/bin/query-github.js +54 -0
  10. package/bin/query-github.ts +56 -0
  11. package/bin/run-suite +2 -0
  12. package/bin/run-suite.d.ts +1 -0
  13. package/bin/run-suite.js +131 -0
  14. package/bin/run-suite.ts +140 -0
  15. package/bin/stage-distribution +2 -0
  16. package/bin/stage-distribution.d.ts +1 -0
  17. package/bin/stage-distribution.js +217 -0
  18. package/bin/stage-distribution.ts +267 -0
  19. package/bin/test-root +2 -0
  20. package/bin/test-root.d.ts +1 -0
  21. package/bin/test-root.js +6 -0
  22. package/bin/test-root.ts +3 -0
  23. package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
  24. package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
  25. package/entrypoints/test-cli-regression.bash +83 -0
  26. package/entrypoints/test.sh +12 -0
  27. package/lib/aws.d.ts +51 -0
  28. package/lib/aws.js +206 -0
  29. package/lib/aws.ts +263 -0
  30. package/lib/corking.d.ts +12 -0
  31. package/lib/corking.js +35 -0
  32. package/lib/corking.ts +33 -0
  33. package/lib/eventually.d.ts +20 -0
  34. package/lib/eventually.js +34 -0
  35. package/lib/eventually.ts +42 -0
  36. package/lib/files.d.ts +15 -0
  37. package/lib/files.js +80 -0
  38. package/lib/files.ts +80 -0
  39. package/lib/github.d.ts +4 -0
  40. package/lib/github.js +43 -0
  41. package/lib/github.ts +43 -0
  42. package/lib/index.d.ts +13 -0
  43. package/lib/index.js +30 -0
  44. package/lib/index.ts +13 -0
  45. package/lib/integ-test.d.ts +10 -0
  46. package/lib/integ-test.js +70 -0
  47. package/lib/integ-test.ts +81 -0
  48. package/lib/lists.d.ts +1 -0
  49. package/lib/lists.js +11 -0
  50. package/lib/lists.ts +9 -0
  51. package/lib/memoize.d.ts +6 -0
  52. package/lib/memoize.js +18 -0
  53. package/lib/memoize.ts +14 -0
  54. package/lib/npm.d.ts +8 -0
  55. package/lib/npm.js +38 -0
  56. package/lib/npm.ts +41 -0
  57. package/lib/package-sources/release-source.d.ts +23 -0
  58. package/lib/package-sources/release-source.js +71 -0
  59. package/lib/package-sources/release-source.ts +81 -0
  60. package/lib/package-sources/repo-source.d.ts +30 -0
  61. package/lib/package-sources/repo-source.js +97 -0
  62. package/lib/package-sources/repo-source.ts +111 -0
  63. package/lib/package-sources/repo-tools/npm +2 -0
  64. package/lib/package-sources/repo-tools/npm.d.ts +1 -0
  65. package/lib/package-sources/repo-tools/npm.js +43 -0
  66. package/lib/package-sources/repo-tools/npm.ts +48 -0
  67. package/lib/package-sources/source.d.ts +28 -0
  68. package/lib/package-sources/source.js +3 -0
  69. package/lib/package-sources/source.ts +35 -0
  70. package/lib/package-sources/subprocess.d.ts +3 -0
  71. package/lib/package-sources/subprocess.js +17 -0
  72. package/lib/package-sources/subprocess.ts +15 -0
  73. package/lib/resource-pool.d.ts +50 -0
  74. package/lib/resource-pool.js +117 -0
  75. package/lib/resource-pool.ts +140 -0
  76. package/lib/resources.d.ts +1 -0
  77. package/lib/resources.js +6 -0
  78. package/lib/resources.ts +4 -0
  79. package/lib/shell.d.ts +56 -0
  80. package/lib/shell.js +123 -0
  81. package/lib/shell.ts +168 -0
  82. package/lib/staging/codeartifact.d.ts +44 -0
  83. package/lib/staging/codeartifact.js +281 -0
  84. package/lib/staging/codeartifact.ts +387 -0
  85. package/lib/staging/maven.d.ts +5 -0
  86. package/lib/staging/maven.js +91 -0
  87. package/lib/staging/maven.ts +95 -0
  88. package/lib/staging/npm.d.ts +4 -0
  89. package/lib/staging/npm.js +55 -0
  90. package/lib/staging/npm.ts +62 -0
  91. package/lib/staging/nuget.d.ts +4 -0
  92. package/lib/staging/nuget.js +69 -0
  93. package/lib/staging/nuget.ts +75 -0
  94. package/lib/staging/parallel-shell.d.ts +5 -0
  95. package/lib/staging/parallel-shell.js +45 -0
  96. package/lib/staging/parallel-shell.ts +51 -0
  97. package/lib/staging/pypi.d.ts +4 -0
  98. package/lib/staging/pypi.js +48 -0
  99. package/lib/staging/pypi.ts +50 -0
  100. package/lib/staging/usage-dir.d.ts +31 -0
  101. package/lib/staging/usage-dir.js +87 -0
  102. package/lib/staging/usage-dir.ts +99 -0
  103. package/lib/with-aws.d.ts +14 -0
  104. package/lib/with-aws.js +60 -0
  105. package/lib/with-aws.ts +67 -0
  106. package/lib/with-cdk-app.d.ts +210 -0
  107. package/lib/with-cdk-app.js +539 -0
  108. package/lib/with-cdk-app.ts +742 -0
  109. package/lib/with-cli-lib.d.ts +17 -0
  110. package/lib/with-cli-lib.js +123 -0
  111. package/lib/with-cli-lib.ts +134 -0
  112. package/lib/with-packages.d.ts +5 -0
  113. package/lib/with-packages.js +13 -0
  114. package/lib/with-packages.ts +15 -0
  115. package/lib/with-sam.d.ts +33 -0
  116. package/lib/with-sam.js +258 -0
  117. package/lib/with-sam.ts +288 -0
  118. package/lib/with-temporary-directory.d.ts +5 -0
  119. package/lib/with-temporary-directory.js +31 -0
  120. package/lib/with-temporary-directory.ts +35 -0
  121. package/lib/with-timeout.d.ts +19 -0
  122. package/lib/with-timeout.js +34 -0
  123. package/lib/with-timeout.ts +33 -0
  124. package/lib/xpmutex.d.ts +43 -0
  125. package/lib/xpmutex.js +207 -0
  126. package/lib/xpmutex.ts +218 -0
  127. package/package.json +111 -0
  128. package/resources/bootstrap-templates/session-tags.all-roles-deny-all.yaml +703 -0
  129. package/resources/bootstrap-templates/session-tags.deploy-role-deny-sqs.yaml +700 -0
  130. package/resources/cdk-apps/app/app.js +926 -0
  131. package/resources/cdk-apps/app/appsync.hotswap.graphql +3 -0
  132. package/resources/cdk-apps/app/cdk.json +7 -0
  133. package/resources/cdk-apps/app/docker/Dockerfile +2 -0
  134. package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
  135. package/resources/cdk-apps/app/lambda/index.js +4 -0
  136. package/resources/cdk-apps/app/lambda/response.json +3 -0
  137. package/resources/cdk-apps/app/nested-stack.js +65 -0
  138. package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
  139. package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
  140. package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
  141. package/resources/cdk-apps/rollback-test-app/app.js +110 -0
  142. package/resources/cdk-apps/rollback-test-app/cdk.json +7 -0
  143. package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
  144. package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
  145. package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  146. package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  147. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
  148. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
  149. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
  150. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
  151. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
  152. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
  153. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
  154. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
  155. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
  156. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
  157. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
  158. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
  159. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
  160. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
  161. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
  162. package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
  163. package/resources/cdk-apps/simple-app/app.js +26 -0
  164. package/resources/cdk-apps/simple-app/cdk.json +7 -0
  165. package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
  166. package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
  167. package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
  168. package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
  169. package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
  170. package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
  171. package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
  172. package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
  173. package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
  174. package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
  175. package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
  176. package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
  177. package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
  178. package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
  179. package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
  180. package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
  181. package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
  182. package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
  183. package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
  184. package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
  185. package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
  186. package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
  187. package/resources/cli-regression-patches/v2.130.0/NOTES.md +1 -0
  188. package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  189. package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  190. package/resources/cli-regression-patches/v2.130.0/skip-tests.txt +5 -0
  191. package/resources/cli-regression-patches/v2.132.0/NOTES.md +1 -0
  192. package/resources/cli-regression-patches/v2.132.0/skip-tests.txt +4 -0
  193. package/resources/cli-regression-patches/v2.142.0/NOTES.md +1 -0
  194. package/resources/cli-regression-patches/v2.142.0/skip-tests.txt +4 -0
  195. package/resources/cli-regression-patches/v2.160.0/skip-tests.txt +2 -0
  196. package/resources/cli-regression-patches/v2.161.0/NOTES.md +1 -0
  197. package/resources/cli-regression-patches/v2.161.0/skip-tests.txt +5 -0
  198. package/resources/cli-regression-patches/v2.166.0/NOTES.md +1 -0
  199. package/resources/cli-regression-patches/v2.166.0/skip-tests.txt +2 -0
  200. package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
  201. package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
  202. package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
  203. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
  204. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
  205. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
  206. package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
  207. package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
  208. package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
  209. package/resources/integ.jest.config.js +25 -0
  210. package/resources/templates/sqs-template.json +36 -0
  211. package/skip-tests.txt +8 -0
  212. package/tests/cli-integ-tests/README.md +47 -0
  213. package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
  214. package/tests/cli-integ-tests/bootstrapping.integtest.js +412 -0
  215. package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
  216. package/tests/cli-integ-tests/cli-lib.integtest.d.ts +1 -0
  217. package/tests/cli-integ-tests/cli-lib.integtest.js +62 -0
  218. package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
  219. package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
  220. package/tests/cli-integ-tests/cli.integtest.js +2104 -0
  221. package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
  222. package/tests/cli-integ-tests/garbage-collection.integtest.d.ts +1 -0
  223. package/tests/cli-integ-tests/garbage-collection.integtest.js +314 -0
  224. package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
  225. package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
  226. package/tests/init-csharp/init-csharp.integtest.js +14 -0
  227. package/tests/init-csharp/init-csharp.integtest.ts +15 -0
  228. package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
  229. package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
  230. package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
  231. package/tests/init-go/init-go.integtest.d.ts +1 -0
  232. package/tests/init-go/init-go.integtest.js +21 -0
  233. package/tests/init-go/init-go.integtest.ts +23 -0
  234. package/tests/init-java/init-java.integtest.d.ts +1 -0
  235. package/tests/init-java/init-java.integtest.js +14 -0
  236. package/tests/init-java/init-java.integtest.ts +14 -0
  237. package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
  238. package/tests/init-javascript/init-javascript.integtest.js +53 -0
  239. package/tests/init-javascript/init-javascript.integtest.ts +59 -0
  240. package/tests/init-python/init-python.integtest.d.ts +1 -0
  241. package/tests/init-python/init-python.integtest.js +19 -0
  242. package/tests/init-python/init-python.integtest.ts +20 -0
  243. package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
  244. package/tests/init-typescript-app/init-typescript-app.integtest.js +54 -0
  245. package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
  246. package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
  247. package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
  248. package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
  249. package/tests/tool-integrations/amplify.integtest.d.ts +1 -0
  250. package/tests/tool-integrations/amplify.integtest.js +39 -0
  251. package/tests/tool-integrations/amplify.integtest.ts +43 -0
  252. package/tests/tool-integrations/with-tool-context.d.ts +9 -0
  253. package/tests/tool-integrations/with-tool-context.js +13 -0
  254. package/tests/tool-integrations/with-tool-context.ts +14 -0
  255. package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
  256. package/tests/uberpackage/uberpackage.integtest.js +11 -0
  257. package/tests/uberpackage/uberpackage.integtest.ts +11 -0
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /* eslint-disable @cdklabs/no-literal-partition */
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
7
+ const client_ecr_1 = require("@aws-sdk/client-ecr");
8
+ const client_iam_1 = require("@aws-sdk/client-iam");
9
+ const yaml = require("yaml");
10
+ const lib_1 = require("../../lib");
11
+ const eventually_1 = require("../../lib/eventually");
12
+ jest.setTimeout(2 * 60 * 60000); // Includes the time to acquire locks, worst-case single-threaded runtime
13
+ (0, lib_1.integTest)('can bootstrap without execution', (0, lib_1.withoutBootstrap)(async (fixture) => {
14
+ var _a;
15
+ const bootstrapStackName = fixture.bootstrapStackName;
16
+ await fixture.cdkBootstrapLegacy({
17
+ toolkitStackName: bootstrapStackName,
18
+ noExecute: true,
19
+ });
20
+ const resp = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({
21
+ StackName: bootstrapStackName,
22
+ }));
23
+ expect((_a = resp.Stacks) === null || _a === void 0 ? void 0 : _a[0].StackStatus).toEqual('REVIEW_IN_PROGRESS');
24
+ }));
25
+ (0, lib_1.integTest)('upgrade legacy bootstrap stack to new bootstrap stack while in use', (0, lib_1.withoutBootstrap)(async (fixture) => {
26
+ const bootstrapStackName = fixture.bootstrapStackName;
27
+ const legacyBootstrapBucketName = `aws-cdk-bootstrap-integ-test-legacy-bckt-${(0, lib_1.randomString)()}`;
28
+ const newBootstrapBucketName = `aws-cdk-bootstrap-integ-test-v2-bckt-${(0, lib_1.randomString)()}`;
29
+ fixture.rememberToDeleteBucket(legacyBootstrapBucketName); // This one will leak
30
+ fixture.rememberToDeleteBucket(newBootstrapBucketName); // This one shouldn't leak if the test succeeds, but let's be safe in case it doesn't
31
+ // Legacy bootstrap
32
+ await fixture.cdkBootstrapLegacy({
33
+ toolkitStackName: bootstrapStackName,
34
+ bootstrapBucketName: legacyBootstrapBucketName,
35
+ });
36
+ // Deploy stack that uses file assets
37
+ await fixture.cdkDeploy('lambda', {
38
+ options: [
39
+ '--context', `bootstrapBucket=${legacyBootstrapBucketName}`,
40
+ '--context', 'legacySynth=true',
41
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
42
+ '--toolkit-stack-name', bootstrapStackName,
43
+ ],
44
+ });
45
+ // Upgrade bootstrap stack to "new" style
46
+ await fixture.cdkBootstrapModern({
47
+ toolkitStackName: bootstrapStackName,
48
+ bootstrapBucketName: newBootstrapBucketName,
49
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
50
+ });
51
+ // (Force) deploy stack again
52
+ // --force to bypass the check which says that the template hasn't changed.
53
+ await fixture.cdkDeploy('lambda', {
54
+ options: [
55
+ '--context', `bootstrapBucket=${newBootstrapBucketName}`,
56
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
57
+ '--toolkit-stack-name', bootstrapStackName,
58
+ '--force',
59
+ ],
60
+ });
61
+ }));
62
+ (0, lib_1.integTest)('can and deploy if omitting execution policies', (0, lib_1.withoutBootstrap)(async (fixture) => {
63
+ const bootstrapStackName = fixture.bootstrapStackName;
64
+ await fixture.cdkBootstrapModern({
65
+ toolkitStackName: bootstrapStackName,
66
+ });
67
+ // Deploy stack that uses file assets
68
+ await fixture.cdkDeploy('lambda', {
69
+ options: [
70
+ '--toolkit-stack-name', bootstrapStackName,
71
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
72
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
73
+ ],
74
+ });
75
+ }));
76
+ (0, lib_1.integTest)('can deploy with session tags on the deploy, lookup, file asset, and image asset publishing roles', (0, lib_1.withoutBootstrap)(async (fixture) => {
77
+ const bootstrapStackName = fixture.bootstrapStackName;
78
+ await fixture.cdkBootstrapModern({
79
+ toolkitStackName: bootstrapStackName,
80
+ bootstrapTemplate: path.join(__dirname, '..', '..', 'resources', 'bootstrap-templates', 'session-tags.all-roles-deny-all.yaml'),
81
+ });
82
+ await fixture.cdkDeploy('session-tags', {
83
+ options: [
84
+ '--toolkit-stack-name', bootstrapStackName,
85
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
86
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
87
+ ],
88
+ modEnv: {
89
+ ENABLE_VPC_TESTING: 'IMPORT',
90
+ },
91
+ });
92
+ }));
93
+ (0, lib_1.integTest)('can deploy without execution role and with session tags on deploy role', (0, lib_1.withoutBootstrap)(async (fixture) => {
94
+ const bootstrapStackName = fixture.bootstrapStackName;
95
+ await fixture.cdkBootstrapModern({
96
+ toolkitStackName: bootstrapStackName,
97
+ bootstrapTemplate: path.join(__dirname, '..', '..', 'resources', 'bootstrap-templates', 'session-tags.deploy-role-deny-sqs.yaml'),
98
+ });
99
+ await fixture.cdkDeploy('session-tags-with-custom-synthesizer', {
100
+ options: [
101
+ '--toolkit-stack-name', bootstrapStackName,
102
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
103
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
104
+ ],
105
+ });
106
+ }));
107
+ (0, lib_1.integTest)('deploy new style synthesis to new style bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
108
+ const bootstrapStackName = fixture.bootstrapStackName;
109
+ await fixture.cdkBootstrapModern({
110
+ toolkitStackName: bootstrapStackName,
111
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
112
+ });
113
+ // Deploy stack that uses file assets
114
+ await fixture.cdkDeploy('lambda', {
115
+ options: [
116
+ '--toolkit-stack-name', bootstrapStackName,
117
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
118
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
119
+ ],
120
+ });
121
+ }));
122
+ (0, lib_1.integTest)('deploy new style synthesis to new style bootstrap (with docker image)', (0, lib_1.withoutBootstrap)(async (fixture) => {
123
+ const bootstrapStackName = fixture.bootstrapStackName;
124
+ await fixture.cdkBootstrapModern({
125
+ toolkitStackName: bootstrapStackName,
126
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
127
+ });
128
+ // Deploy stack that uses file assets
129
+ await fixture.cdkDeploy('docker', {
130
+ options: [
131
+ '--toolkit-stack-name', bootstrapStackName,
132
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
133
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
134
+ ],
135
+ });
136
+ }));
137
+ (0, lib_1.integTest)('deploy old style synthesis to new style bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
138
+ const bootstrapStackName = fixture.bootstrapStackName;
139
+ await fixture.cdkBootstrapModern({
140
+ toolkitStackName: bootstrapStackName,
141
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
142
+ });
143
+ // Deploy stack that uses file assets
144
+ await fixture.cdkDeploy('lambda', {
145
+ options: [
146
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
147
+ '--toolkit-stack-name', bootstrapStackName,
148
+ ],
149
+ });
150
+ }));
151
+ (0, lib_1.integTest)('can create a legacy bootstrap stack with --public-access-block-configuration=false', (0, lib_1.withoutBootstrap)(async (fixture) => {
152
+ var _a;
153
+ const bootstrapStackName = fixture.bootstrapStackName;
154
+ await fixture.cdkBootstrapLegacy({
155
+ verbose: true,
156
+ toolkitStackName: bootstrapStackName,
157
+ publicAccessBlockConfiguration: false,
158
+ tags: 'Foo=Bar',
159
+ });
160
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
161
+ expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([
162
+ { Key: 'Foo', Value: 'Bar' },
163
+ ]);
164
+ }));
165
+ (0, lib_1.integTest)('can create multiple legacy bootstrap stacks', (0, lib_1.withoutBootstrap)(async (fixture) => {
166
+ var _a;
167
+ const bootstrapStackName1 = `${fixture.bootstrapStackName}-1`;
168
+ const bootstrapStackName2 = `${fixture.bootstrapStackName}-2`;
169
+ // deploy two toolkit stacks into the same environment (see #1416)
170
+ // one with tags
171
+ await fixture.cdkBootstrapLegacy({
172
+ verbose: true,
173
+ toolkitStackName: bootstrapStackName1,
174
+ tags: 'Foo=Bar',
175
+ });
176
+ await fixture.cdkBootstrapLegacy({
177
+ verbose: true,
178
+ toolkitStackName: bootstrapStackName2,
179
+ });
180
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName1 }));
181
+ expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([
182
+ { Key: 'Foo', Value: 'Bar' },
183
+ ]);
184
+ }));
185
+ (0, lib_1.integTest)('can dump the template, modify and use it to deploy a custom bootstrap stack', (0, lib_1.withoutBootstrap)(async (fixture) => {
186
+ let template = await fixture.cdkBootstrapModern({
187
+ // toolkitStackName doesn't matter for this particular invocation
188
+ toolkitStackName: fixture.bootstrapStackName,
189
+ showTemplate: true,
190
+ cliOptions: {
191
+ captureStderr: false,
192
+ },
193
+ });
194
+ expect(template).toContain('BootstrapVersion:');
195
+ template += '\n' + [
196
+ ' TwiddleDee:',
197
+ ' Value: Template got twiddled',
198
+ ].join('\n');
199
+ const filename = path.join(fixture.integTestDir, `${fixture.qualifier}-template.yaml`);
200
+ fs.writeFileSync(filename, template, { encoding: 'utf-8' });
201
+ await fixture.cdkBootstrapModern({
202
+ toolkitStackName: fixture.bootstrapStackName,
203
+ template: filename,
204
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
205
+ });
206
+ }));
207
+ (0, lib_1.integTest)('a customized template vendor will not overwrite the default template', (0, lib_1.withoutBootstrap)(async (fixture) => {
208
+ // Initial bootstrap
209
+ const toolkitStackName = fixture.bootstrapStackName;
210
+ await fixture.cdkBootstrapModern({
211
+ toolkitStackName,
212
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
213
+ });
214
+ // Customize template
215
+ const templateStr = await fixture.cdkBootstrapModern({
216
+ // toolkitStackName doesn't matter for this particular invocation
217
+ toolkitStackName,
218
+ showTemplate: true,
219
+ cliOptions: {
220
+ captureStderr: false,
221
+ },
222
+ });
223
+ const template = yaml.parse(templateStr, { schema: 'core' });
224
+ template.Parameters.BootstrapVariant.Default = 'CustomizedVendor';
225
+ const filename = path.join(fixture.integTestDir, `${fixture.qualifier}-template.yaml`);
226
+ fs.writeFileSync(filename, yaml.stringify(template, { schema: 'yaml-1.1' }), { encoding: 'utf-8' });
227
+ // Rebootstrap. For some reason, this doesn't cause a failure, it's a successful no-op.
228
+ const output = await fixture.cdkBootstrapModern({
229
+ toolkitStackName,
230
+ template: filename,
231
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
232
+ cliOptions: {
233
+ captureStderr: true,
234
+ },
235
+ });
236
+ expect(output).toContain('Not overwriting it with a template containing');
237
+ }));
238
+ (0, lib_1.integTest)('can use the default permissions boundary to bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
239
+ let template = await fixture.cdkBootstrapModern({
240
+ // toolkitStackName doesn't matter for this particular invocation
241
+ toolkitStackName: fixture.bootstrapStackName,
242
+ showTemplate: true,
243
+ examplePermissionsBoundary: true,
244
+ });
245
+ expect(template).toContain('PermissionsBoundary');
246
+ }));
247
+ (0, lib_1.integTest)('can use the custom permissions boundary to bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
248
+ let template = await fixture.cdkBootstrapModern({
249
+ // toolkitStackName doesn't matter for this particular invocation
250
+ toolkitStackName: fixture.bootstrapStackName,
251
+ showTemplate: true,
252
+ customPermissionsBoundary: 'permission-boundary-name',
253
+ });
254
+ expect(template).toContain('permission-boundary-name');
255
+ }));
256
+ (0, lib_1.integTest)('can use the custom permissions boundary (with slashes) to bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
257
+ let template = await fixture.cdkBootstrapModern({
258
+ // toolkitStackName doesn't matter for this particular invocation
259
+ toolkitStackName: fixture.bootstrapStackName,
260
+ showTemplate: true,
261
+ customPermissionsBoundary: 'permission-boundary-name/with/path',
262
+ });
263
+ expect(template).toContain('permission-boundary-name/with/path');
264
+ }));
265
+ (0, lib_1.integTest)('can remove customPermissionsBoundary', (0, lib_1.withoutBootstrap)(async (fixture) => {
266
+ var _a, _b, _c;
267
+ const bootstrapStackName = fixture.bootstrapStackName;
268
+ const policyName = `${bootstrapStackName}-pb`;
269
+ let policyArn;
270
+ try {
271
+ const policy = await fixture.aws.iam.send(new client_iam_1.CreatePolicyCommand({
272
+ PolicyName: policyName,
273
+ PolicyDocument: JSON.stringify({
274
+ Version: '2012-10-17',
275
+ Statement: {
276
+ Action: ['*'],
277
+ Resource: ['*'],
278
+ Effect: 'Allow',
279
+ },
280
+ }),
281
+ }));
282
+ policyArn = (_a = policy.Policy) === null || _a === void 0 ? void 0 : _a.Arn;
283
+ // Policy creation and consistency across regions is "almost immediate"
284
+ // See: https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency
285
+ // We will put this in an `eventually` block to retry stack creation with a reasonable timeout
286
+ const createStackWithPermissionBoundary = async () => {
287
+ var _a, _b;
288
+ await fixture.cdkBootstrapModern({
289
+ // toolkitStackName doesn't matter for this particular invocation
290
+ toolkitStackName: bootstrapStackName,
291
+ customPermissionsBoundary: policyName,
292
+ });
293
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
294
+ expect((_b = (_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Parameters) === null || _b === void 0 ? void 0 : _b.some(param => (param.ParameterKey === 'InputPermissionsBoundary' && param.ParameterValue === policyName))).toEqual(true);
295
+ };
296
+ await (0, eventually_1.default)(createStackWithPermissionBoundary, { maxAttempts: 3 });
297
+ await fixture.cdkBootstrapModern({
298
+ // toolkitStackName doesn't matter for this particular invocation
299
+ toolkitStackName: bootstrapStackName,
300
+ usePreviousParameters: false,
301
+ });
302
+ const response2 = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
303
+ expect((_c = (_b = response2.Stacks) === null || _b === void 0 ? void 0 : _b[0].Parameters) === null || _c === void 0 ? void 0 : _c.some(param => (param.ParameterKey === 'InputPermissionsBoundary' && !param.ParameterValue))).toEqual(true);
304
+ const region = fixture.aws.region;
305
+ const account = await fixture.aws.account();
306
+ const role = await fixture.aws.iam.send(new client_iam_1.GetRoleCommand({ RoleName: `cdk-${fixture.qualifier}-cfn-exec-role-${account}-${region}` }));
307
+ if (!role.Role) {
308
+ throw new Error('Role not found');
309
+ }
310
+ expect(role.Role.PermissionsBoundary).toBeUndefined();
311
+ }
312
+ finally {
313
+ if (policyArn) {
314
+ await fixture.aws.iam.send(new client_iam_1.DeletePolicyCommand({ PolicyArn: policyArn }));
315
+ }
316
+ }
317
+ }));
318
+ (0, lib_1.integTest)('switch on termination protection, switch is left alone on re-bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
319
+ var _a;
320
+ const bootstrapStackName = fixture.bootstrapStackName;
321
+ await fixture.cdkBootstrapModern({
322
+ verbose: true,
323
+ toolkitStackName: bootstrapStackName,
324
+ terminationProtection: true,
325
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
326
+ });
327
+ await fixture.cdkBootstrapModern({
328
+ verbose: true,
329
+ toolkitStackName: bootstrapStackName,
330
+ force: true,
331
+ });
332
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
333
+ expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].EnableTerminationProtection).toEqual(true);
334
+ }));
335
+ (0, lib_1.integTest)('add tags, left alone on re-bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
336
+ var _a;
337
+ const bootstrapStackName = fixture.bootstrapStackName;
338
+ await fixture.cdkBootstrapModern({
339
+ verbose: true,
340
+ toolkitStackName: bootstrapStackName,
341
+ tags: 'Foo=Bar',
342
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
343
+ });
344
+ await fixture.cdkBootstrapModern({
345
+ verbose: true,
346
+ toolkitStackName: bootstrapStackName,
347
+ force: true,
348
+ });
349
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
350
+ expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([
351
+ { Key: 'Foo', Value: 'Bar' },
352
+ ]);
353
+ }));
354
+ (0, lib_1.integTest)('can add tags then update tags during re-bootstrap', (0, lib_1.withoutBootstrap)(async (fixture) => {
355
+ var _a;
356
+ const bootstrapStackName = fixture.bootstrapStackName;
357
+ await fixture.cdkBootstrapModern({
358
+ verbose: true,
359
+ toolkitStackName: bootstrapStackName,
360
+ tags: 'Foo=Bar',
361
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
362
+ });
363
+ await fixture.cdkBootstrapModern({
364
+ verbose: true,
365
+ toolkitStackName: bootstrapStackName,
366
+ tags: 'Foo=BarBaz',
367
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
368
+ force: true,
369
+ });
370
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: bootstrapStackName }));
371
+ expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([
372
+ { Key: 'Foo', Value: 'BarBaz' },
373
+ ]);
374
+ }));
375
+ (0, lib_1.integTest)('can deploy modern-synthesized stack even if bootstrap stack name is unknown', (0, lib_1.withoutBootstrap)(async (fixture) => {
376
+ const bootstrapStackName = fixture.bootstrapStackName;
377
+ await fixture.cdkBootstrapModern({
378
+ toolkitStackName: bootstrapStackName,
379
+ cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess',
380
+ });
381
+ // Deploy stack that uses file assets
382
+ await fixture.cdkDeploy('lambda', {
383
+ options: [
384
+ // Explicity pass a name that's sure to not exist, otherwise the CLI might accidentally find a
385
+ // default bootstracp stack if that happens to be in the account already.
386
+ '--toolkit-stack-name', 'DefinitelyDoesNotExist',
387
+ '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`,
388
+ '--context', '@aws-cdk/core:newStyleStackSynthesis=1',
389
+ ],
390
+ });
391
+ }));
392
+ (0, lib_1.integTest)('create ECR with tag IMMUTABILITY to set on', (0, lib_1.withoutBootstrap)(async (fixture) => {
393
+ var _a, _b, _c;
394
+ const bootstrapStackName = fixture.bootstrapStackName;
395
+ await fixture.cdkBootstrapModern({
396
+ verbose: true,
397
+ toolkitStackName: bootstrapStackName,
398
+ });
399
+ const response = await fixture.aws.cloudFormation.send(new client_cloudformation_1.DescribeStackResourcesCommand({
400
+ StackName: bootstrapStackName,
401
+ }));
402
+ const ecrResource = (_a = response.StackResources) === null || _a === void 0 ? void 0 : _a.find(resource => resource.LogicalResourceId === 'ContainerAssetsRepository');
403
+ expect(ecrResource).toBeDefined();
404
+ const ecrResponse = await fixture.aws.ecr.send(new client_ecr_1.DescribeRepositoriesCommand({
405
+ repositoryNames: [
406
+ // This is set, as otherwise we don't end up here
407
+ (_b = ecrResource === null || ecrResource === void 0 ? void 0 : ecrResource.PhysicalResourceId) !== null && _b !== void 0 ? _b : '',
408
+ ],
409
+ }));
410
+ expect((_c = ecrResponse.repositories) === null || _c === void 0 ? void 0 : _c[0].imageTagMutability).toEqual('IMMUTABLE');
411
+ }));
412
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwcGluZy5pbnRlZ3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJib290c3RyYXBwaW5nLmludGVndGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGtEQUFrRDtBQUNsRCx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLDBFQUFzRztBQUN0RyxvREFBa0U7QUFDbEUsb0RBQStGO0FBQy9GLDZCQUE2QjtBQUM3QixtQ0FBc0U7QUFDdEUscURBQThDO0FBRTlDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFNLENBQUMsQ0FBQyxDQUFDLHlFQUF5RTtBQUUzRyxJQUFBLGVBQVMsRUFBQyxpQ0FBaUMsRUFBRSxJQUFBLHNCQUFnQixFQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTs7SUFDOUUsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVILE1BQU0sSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUNoRCxJQUFJLDZDQUFxQixDQUFDO1FBQ3hCLFNBQVMsRUFBRSxrQkFBa0I7S0FDOUIsQ0FBQyxDQUNILENBQUM7SUFFRixNQUFNLENBQUMsTUFBQSxJQUFJLENBQUMsTUFBTSwwQ0FBRyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFDckUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVKLElBQUEsZUFBUyxFQUFDLG9FQUFvRSxFQUFFLElBQUEsc0JBQWdCLEVBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO0lBQ2pILE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFD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Y0FBYywwQ0FBRSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLEtBQUssMkJBQTJCLENBQUMsQ0FBQztJQUMxSCxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFbEMsTUFBTSxXQUFXLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQzVDLElBQUksd0NBQTJCLENBQUM7UUFDOUIsZUFBZSxFQUFFO1lBQ2YsaURBQWlEO1lBQ2pELE1BQUEsV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLGtCQUFrQixtQ0FBSSxFQUFFO1NBQ3RDO0tBQ0YsQ0FBQyxDQUNILENBQUM7SUFFRixNQUFNLENBQUMsTUFBQSxXQUFXLENBQUMsWUFBWSwwQ0FBRyxDQUFDLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDaEYsQ0FBQyxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEBjZGtsYWJzL25vLWxpdGVyYWwtcGFydGl0aW9uICovXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgRGVzY3JpYmVTdGFja1Jlc291cmNlc0NvbW1hbmQsIERlc2NyaWJlU3RhY2tzQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgeyBEZXNjcmliZVJlcG9zaXRvcmllc0NvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtZWNyJztcbmltcG9ydCB7IENyZWF0ZVBvbGljeUNvbW1hbmQsIERlbGV0ZVBvbGljeUNvbW1hbmQsIEdldFJvbGVDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWlhbSc7XG5pbXBvcnQgKiBhcyB5YW1sIGZyb20gJ3lhbWwnO1xuaW1wb3J0IHsgaW50ZWdUZXN0LCByYW5kb21TdHJpbmcsIHdpdGhvdXRCb290c3RyYXAgfSBmcm9tICcuLi8uLi9saWInO1xuaW1wb3J0IGV2ZW50dWFsbHkgZnJvbSAnLi4vLi4vbGliL2V2ZW50dWFsbHknO1xuXG5qZXN0LnNldFRpbWVvdXQoMiAqIDYwICogNjBfMDAwKTsgLy8gSW5jbHVkZXMgdGhlIHRpbWUgdG8gYWNxdWlyZSBsb2Nrcywgd29yc3QtY2FzZSBzaW5nbGUtdGhyZWFkZWQgcnVudGltZVxuXG5pbnRlZ1Rlc3QoJ2NhbiBib290c3RyYXAgd2l0aG91dCBleGVjdXRpb24nLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTGVnYWN5KHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgbm9FeGVjdXRlOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXNwID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24uc2VuZChcbiAgICBuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHtcbiAgICAgIFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIH0pLFxuICApO1xuXG4gIGV4cGVjdChyZXNwLlN0YWNrcz8uWzBdLlN0YWNrU3RhdHVzKS50b0VxdWFsKCdSRVZJRVdfSU5fUFJPR1JFU1MnKTtcbn0pKTtcblxuaW50ZWdUZXN0KCd1cGdyYWRlIGxlZ2FjeSBib290c3RyYXAgc3RhY2sgdG8gbmV3IGJvb3RzdHJhcCBzdGFjayB3aGlsZSBpbiB1c2UnLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGNvbnN0IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC1sZWdhY3ktYmNrdC0ke3JhbmRvbVN0cmluZygpfWA7XG4gIGNvbnN0IG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC12Mi1iY2t0LSR7cmFuZG9tU3RyaW5nKCl9YDtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSB3aWxsIGxlYWtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSBzaG91bGRuJ3QgbGVhayBpZiB0aGUgdGVzdCBzdWNjZWVkcywgYnV0IGxldCdzIGJlIHNhZmUgaW4gY2FzZSBpdCBkb2Vzbid0XG5cbiAgLy8gTGVnYWN5IGJvb3RzdHJhcFxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGJvb3RzdHJhcEJ1Y2tldE5hbWU6IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS1jb250ZXh0JywgYGJvb3RzdHJhcEJ1Y2tldD0ke2xlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWV9YCxcbiAgICAgICctLWNvbnRleHQnLCAnbGVnYWN5U3ludGg9dHJ1ZScsXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBdLFxuICB9KTtcblxuICAvLyBVcGdyYWRlIGJvb3RzdHJhcCBzdGFjayB0byBcIm5ld1wiIHN0eWxlXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgYm9vdHN0cmFwQnVja2V0TmFtZTogbmV3Qm9vdHN0cmFwQnVja2V0TmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG5cbiAgLy8gKEZvcmNlKSBkZXBsb3kgc3RhY2sgYWdhaW5cbiAgLy8gLS1mb3JjZSB0byBieXBhc3MgdGhlIGNoZWNrIHdoaWNoIHNheXMgdGhhdCB0aGUgdGVtcGxhdGUgaGFzbid0IGNoYW5nZWQuXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tY29udGV4dCcsIGBib290c3RyYXBCdWNrZXQ9JHtuZXdCb290c3RyYXBCdWNrZXROYW1lfWAsXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWZvcmNlJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gYW5kIGRlcGxveSBpZiBvbWl0dGluZyBleGVjdXRpb24gcG9saWNpZXMnLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS10b29sa2l0LXN0YWNrLW5hbWUnLCBib290c3RyYXBTdGFja05hbWUsXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLWNvbnRleHQnLCAnQGF3cy1jZGsvY29yZTpuZXdTdHlsZVN0YWNrU3ludGhlc2lzPTEnLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NhbiBkZXBsb3kgd2l0aCBzZXNzaW9uIHRhZ3Mgb24gdGhlIGRlcGxveSwgbG9va3VwLCBmaWxlIGFzc2V0LCBhbmQgaW1hZ2UgYXNzZXQgcHVibGlzaGluZyByb2xlcycsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBib290c3RyYXBUZW1wbGF0ZTogcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJ3Jlc291cmNlcycsICdib290c3RyYXAtdGVtcGxhdGVzJywgJ3Nlc3Npb24tdGFncy5hbGwtcm9sZXMtZGVueS1hbGwueWFtbCcpLFxuICB9KTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnc2Vzc2lvbi10YWdzJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgICBtb2RFbnY6IHtcbiAgICAgIEVOQUJMRV9WUENfVEVTVElORzogJ0lNUE9SVCcsXG4gICAgfSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIGRlcGxveSB3aXRob3V0IGV4ZWN1dGlvbiByb2xlIGFuZCB3aXRoIHNlc3Npb24gdGFncyBvbiBkZXBsb3kgcm9sZScsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBib290c3RyYXBUZW1wbGF0ZTogcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJ3Jlc291cmNlcycsICdib290c3RyYXAtdGVtcGxhdGVzJywgJ3Nlc3Npb24tdGFncy5kZXBsb3ktcm9sZS1kZW55LXNxcy55YW1sJyksXG4gIH0pO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdzZXNzaW9uLXRhZ3Mtd2l0aC1jdXN0b20tc3ludGhlc2l6ZXInLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgJy0tY29udGV4dCcsIGBAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcj0ke2ZpeHR1cmUucXVhbGlmaWVyfWAsXG4gICAgICAnLS1jb250ZXh0JywgJ0Bhd3MtY2RrL2NvcmU6bmV3U3R5bGVTdGFja1N5bnRoZXNpcz0xJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgbmV3IHN0eWxlIHN5bnRoZXNpcyB0byBuZXcgc3R5bGUgYm9vdHN0cmFwJywgd2l0aG91dEJvb3RzdHJhcChhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcblxuICAvLyBEZXBsb3kgc3RhY2sgdGhhdCB1c2VzIGZpbGUgYXNzZXRzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgJy0tY29udGV4dCcsIGBAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcj0ke2ZpeHR1cmUucXVhbGlmaWVyfWAsXG4gICAgICAnLS1jb250ZXh0JywgJ0Bhd3MtY2RrL2NvcmU6bmV3U3R5bGVTdGFja1N5bnRoZXNpcz0xJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgbmV3IHN0eWxlIHN5bnRoZXNpcyB0byBuZXcgc3R5bGUgYm9vdHN0cmFwICh3aXRoIGRvY2tlciBpbWFnZSknLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2RvY2tlcicsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS10b29sa2l0LXN0YWNrLW5hbWUnLCBib290c3RyYXBTdGFja05hbWUsXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLWNvbnRleHQnLCAnQGF3cy1jZGsvY29yZTpuZXdTdHlsZVN0YWNrU3ludGhlc2lzPTEnLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2RlcGxveSBvbGQgc3R5bGUgc3ludGhlc2lzIHRvIG5ldyBzdHlsZSBib290c3RyYXAnLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gY3JlYXRlIGEgbGVnYWN5IGJvb3RzdHJhcCBzdGFjayB3aXRoIC0tcHVibGljLWFjY2Vzcy1ibG9jay1jb25maWd1cmF0aW9uPWZhbHNlJywgd2l0aG91dEJvb3RzdHJhcChhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgcHVibGljQWNjZXNzQmxvY2tDb25maWd1cmF0aW9uOiBmYWxzZSxcbiAgICB0YWdzOiAnRm9vPUJhcicsXG4gIH0pO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24uc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSkpO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uVGFncykudG9FcXVhbChbXG4gICAgeyBLZXk6ICdGb28nLCBWYWx1ZTogJ0JhcicgfSxcbiAgXSk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIGNyZWF0ZSBtdWx0aXBsZSBsZWdhY3kgYm9vdHN0cmFwIHN0YWNrcycsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lMSA9IGAke2ZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lfS0xYDtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lMiA9IGAke2ZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lfS0yYDtcblxuICAvLyBkZXBsb3kgdHdvIHRvb2xraXQgc3RhY2tzIGludG8gdGhlIHNhbWUgZW52aXJvbm1lbnQgKHNlZSAjMTQxNilcbiAgLy8gb25lIHdpdGggdGFnc1xuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUxLFxuICAgIHRhZ3M6ICdGb289QmFyJyxcbiAgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTGVnYWN5KHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZTIsXG4gIH0pO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24uc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUxIH0pKTtcbiAgZXhwZWN0KHJlc3BvbnNlLlN0YWNrcz8uWzBdLlRhZ3MpLnRvRXF1YWwoW1xuICAgIHsgS2V5OiAnRm9vJywgVmFsdWU6ICdCYXInIH0sXG4gIF0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NhbiBkdW1wIHRoZSB0ZW1wbGF0ZSwgbW9kaWZ5IGFuZCB1c2UgaXQgdG8gZGVwbG95IGEgY3VzdG9tIGJvb3RzdHJhcCBzdGFjaycsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgbGV0IHRlbXBsYXRlID0gYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIC8vIHRvb2xraXRTdGFja05hbWUgZG9lc24ndCBtYXR0ZXIgZm9yIHRoaXMgcGFydGljdWxhciBpbnZvY2F0aW9uXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogZml4dHVyZS5ib290c3RyYXBTdGFja05hbWUsXG4gICAgc2hvd1RlbXBsYXRlOiB0cnVlLFxuICAgIGNsaU9wdGlvbnM6IHtcbiAgICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICAgIH0sXG4gIH0pO1xuXG4gIGV4cGVjdCh0ZW1wbGF0ZSkudG9Db250YWluKCdCb290c3RyYXBWZXJzaW9uOicpO1xuXG4gIHRlbXBsYXRlICs9ICdcXG4nICsgW1xuICAgICcgIFR3aWRkbGVEZWU6JyxcbiAgICAnICAgIFZhbHVlOiBUZW1wbGF0ZSBnb3QgdHdpZGRsZWQnLFxuICBdLmpvaW4oJ1xcbicpO1xuXG4gIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCBgJHtmaXh0dXJlLnF1YWxpZmllcn0tdGVtcGxhdGUueWFtbGApO1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVuYW1lLCB0ZW1wbGF0ZSwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KTtcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHRlbXBsYXRlOiBmaWxlbmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnYSBjdXN0b21pemVkIHRlbXBsYXRlIHZlbmRvciB3aWxsIG5vdCBvdmVyd3JpdGUgdGhlIGRlZmF1bHQgdGVtcGxhdGUnLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIC8vIEluaXRpYWwgYm9vdHN0cmFwXG4gIGNvbnN0IHRvb2xraXRTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIEN1c3RvbWl6ZSB0ZW1wbGF0ZVxuICBjb25zdCB0ZW1wbGF0ZVN0ciA9IGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICAvLyB0b29sa2l0U3RhY2tOYW1lIGRvZXNuJ3QgbWF0dGVyIGZvciB0aGlzIHBhcnRpY3VsYXIgaW52b2NhdGlvblxuICAgIHRvb2xraXRTdGFja05hbWUsXG4gICAgc2hvd1RlbXBsYXRlOiB0cnVlLFxuICAgIGNsaU9wdGlvbnM6IHtcbiAgICAgIGNhcHR1cmVTdGRlcnI6IGZhbHNlLFxuICAgIH0sXG4gIH0pO1xuXG4gIGNvbnN0IHRlbXBsYXRlID0geWFtbC5wYXJzZSh0ZW1wbGF0ZVN0ciwgeyBzY2hlbWE6ICdjb3JlJyB9KTtcbiAgdGVtcGxhdGUuUGFyYW1ldGVycy5Cb290c3RyYXBWYXJpYW50LkRlZmF1bHQgPSAnQ3VzdG9taXplZFZlbmRvcic7XG4gIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5qb2luKGZpeHR1cmUuaW50ZWdUZXN0RGlyLCBgJHtmaXh0dXJlLnF1YWxpZmllcn0tdGVtcGxhdGUueWFtbGApO1xuICBmcy53cml0ZUZpbGVTeW5jKGZpbGVuYW1lLCB5YW1sLnN0cmluZ2lmeSh0ZW1wbGF0ZSwgeyBzY2hlbWE6ICd5YW1sLTEuMScgfSksIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG5cbiAgLy8gUmVib290c3RyYXAuIEZvciBzb21lIHJlYXNvbiwgdGhpcyBkb2Vzbid0IGNhdXNlIGEgZmFpbHVyZSwgaXQncyBhIHN1Y2Nlc3NmdWwgbm8tb3AuXG4gIGNvbnN0IG91dHB1dCA9IGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lLFxuICAgIHRlbXBsYXRlOiBmaWxlbmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgICBjbGlPcHRpb25zOiB7XG4gICAgICBjYXB0dXJlU3RkZXJyOiB0cnVlLFxuICAgIH0sXG4gIH0pO1xuICBleHBlY3Qob3V0cHV0KS50b0NvbnRhaW4oJ05vdCBvdmVyd3JpdGluZyBpdCB3aXRoIGEgdGVtcGxhdGUgY29udGFpbmluZycpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NhbiB1c2UgdGhlIGRlZmF1bHQgcGVybWlzc2lvbnMgYm91bmRhcnkgdG8gYm9vdHN0cmFwJywgd2l0aG91dEJvb3RzdHJhcChhc3luYyAoZml4dHVyZSkgPT4ge1xuICBsZXQgdGVtcGxhdGUgPSBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgLy8gdG9vbGtpdFN0YWNrTmFtZSBkb2Vzbid0IG1hdHRlciBmb3IgdGhpcyBwYXJ0aWN1bGFyIGludm9jYXRpb25cbiAgICB0b29sa2l0U3RhY2tOYW1lOiBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBzaG93VGVtcGxhdGU6IHRydWUsXG4gICAgZXhhbXBsZVBlcm1pc3Npb25zQm91bmRhcnk6IHRydWUsXG4gIH0pO1xuXG4gIGV4cGVjdCh0ZW1wbGF0ZSkudG9Db250YWluKCdQZXJtaXNzaW9uc0JvdW5kYXJ5Jyk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIHVzZSB0aGUgY3VzdG9tIHBlcm1pc3Npb25zIGJvdW5kYXJ5IHRvIGJvb3RzdHJhcCcsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgbGV0IHRlbXBsYXRlID0gYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIC8vIHRvb2xraXRTdGFja05hbWUgZG9lc24ndCBtYXR0ZXIgZm9yIHRoaXMgcGFydGljdWxhciBpbnZvY2F0aW9uXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogZml4dHVyZS5ib290c3RyYXBTdGFja05hbWUsXG4gICAgc2hvd1RlbXBsYXRlOiB0cnVlLFxuICAgIGN1c3RvbVBlcm1pc3Npb25zQm91bmRhcnk6ICdwZXJtaXNzaW9uLWJvdW5kYXJ5LW5hbWUnLFxuICB9KTtcblxuICBleHBlY3QodGVtcGxhdGUpLnRvQ29udGFpbigncGVybWlzc2lvbi1ib3VuZGFyeS1uYW1lJyk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIHVzZSB0aGUgY3VzdG9tIHBlcm1pc3Npb25zIGJvdW5kYXJ5ICh3aXRoIHNsYXNoZXMpIHRvIGJvb3RzdHJhcCcsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgbGV0IHRlbXBsYXRlID0gYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIC8vIHRvb2xraXRTdGFja05hbWUgZG9lc24ndCBtYXR0ZXIgZm9yIHRoaXMgcGFydGljdWxhciBpbnZvY2F0aW9uXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogZml4dHVyZS5ib290c3RyYXBTdGFja05hbWUsXG4gICAgc2hvd1RlbXBsYXRlOiB0cnVlLFxuICAgIGN1c3RvbVBlcm1pc3Npb25zQm91bmRhcnk6ICdwZXJtaXNzaW9uLWJvdW5kYXJ5LW5hbWUvd2l0aC9wYXRoJyxcbiAgfSk7XG5cbiAgZXhwZWN0KHRlbXBsYXRlKS50b0NvbnRhaW4oJ3Blcm1pc3Npb24tYm91bmRhcnktbmFtZS93aXRoL3BhdGgnKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gcmVtb3ZlIGN1c3RvbVBlcm1pc3Npb25zQm91bmRhcnknLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuICBjb25zdCBwb2xpY3lOYW1lID0gYCR7Ym9vdHN0cmFwU3RhY2tOYW1lfS1wYmA7XG4gIGxldCBwb2xpY3lBcm47XG4gIHRyeSB7XG4gICAgY29uc3QgcG9saWN5ID0gYXdhaXQgZml4dHVyZS5hd3MuaWFtLnNlbmQoXG4gICAgICBuZXcgQ3JlYXRlUG9saWN5Q29tbWFuZCh7XG4gICAgICAgIFBvbGljeU5hbWU6IHBvbGljeU5hbWUsXG4gICAgICAgIFBvbGljeURvY3VtZW50OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgVmVyc2lvbjogJzIwMTItMTAtMTcnLFxuICAgICAgICAgIFN0YXRlbWVudDoge1xuICAgICAgICAgICAgQWN0aW9uOiBbJyonXSxcbiAgICAgICAgICAgIFJlc291cmNlOiBbJyonXSxcbiAgICAgICAgICAgIEVmZmVjdDogJ0FsbG93JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcG9saWN5QXJuID0gcG9saWN5LlBvbGljeT8uQXJuO1xuXG4gICAgLy8gUG9saWN5IGNyZWF0aW9uIGFuZCBjb25zaXN0ZW5jeSBhY3Jvc3MgcmVnaW9ucyBpcyBcImFsbW9zdCBpbW1lZGlhdGVcIlxuICAgIC8vIFNlZTogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3Ryb3VibGVzaG9vdF9nZW5lcmFsLmh0bWwjdHJvdWJsZXNob290X2dlbmVyYWxfZXZlbnR1YWwtY29uc2lzdGVuY3lcbiAgICAvLyBXZSB3aWxsIHB1dCB0aGlzIGluIGFuIGBldmVudHVhbGx5YCBibG9jayB0byByZXRyeSBzdGFjayBjcmVhdGlvbiB3aXRoIGEgcmVhc29uYWJsZSB0aW1lb3V0XG4gICAgY29uc3QgY3JlYXRlU3RhY2tXaXRoUGVybWlzc2lvbkJvdW5kYXJ5ID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgICAgICAvLyB0b29sa2l0U3RhY2tOYW1lIGRvZXNuJ3QgbWF0dGVyIGZvciB0aGlzIHBhcnRpY3VsYXIgaW52b2NhdGlvblxuICAgICAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgICAgIGN1c3RvbVBlcm1pc3Npb25zQm91bmRhcnk6IHBvbGljeU5hbWUsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbi5zZW5kKFxuICAgICAgICBuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSksXG4gICAgICApO1xuICAgICAgZXhwZWN0KFxuICAgICAgICByZXNwb25zZS5TdGFja3M/LlswXS5QYXJhbWV0ZXJzPy5zb21lKFxuICAgICAgICAgIHBhcmFtID0+IChwYXJhbS5QYXJhbWV0ZXJLZXkgPT09ICdJbnB1dFBlcm1pc3Npb25zQm91bmRhcnknICYmIHBhcmFtLlBhcmFtZXRlclZhbHVlID09PSBwb2xpY3lOYW1lKSxcbiAgICAgICAgKSkudG9FcXVhbCh0cnVlKTtcbiAgICB9O1xuXG4gICAgYXdhaXQgZXZlbnR1YWxseShjcmVhdGVTdGFja1dpdGhQZXJtaXNzaW9uQm91bmRhcnksIHsgbWF4QXR0ZW1wdHM6IDMgfSk7XG5cbiAgICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgICAvLyB0b29sa2l0U3RhY2tOYW1lIGRvZXNuJ3QgbWF0dGVyIGZvciB0aGlzIHBhcnRpY3VsYXIgaW52b2NhdGlvblxuICAgICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgdXNlUHJldmlvdXNQYXJhbWV0ZXJzOiBmYWxzZSxcbiAgICB9KTtcbiAgICBjb25zdCByZXNwb25zZTIgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbi5zZW5kKFxuICAgICAgbmV3IERlc2NyaWJlU3RhY2tzQ29tbWFuZCh7IFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lIH0pLFxuICAgICk7XG4gICAgZXhwZWN0KFxuICAgICAgcmVzcG9uc2UyLlN0YWNrcz8uWzBdLlBhcmFtZXRlcnM/LnNvbWUoXG4gICAgICAgIHBhcmFtID0+IChwYXJhbS5QYXJhbWV0ZXJLZXkgPT09ICdJbnB1dFBlcm1pc3Npb25zQm91bmRhcnknICYmICFwYXJhbS5QYXJhbWV0ZXJWYWx1ZSksXG4gICAgICApKS50b0VxdWFsKHRydWUpO1xuXG4gICAgY29uc3QgcmVnaW9uID0gZml4dHVyZS5hd3MucmVnaW9uO1xuICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBmaXh0dXJlLmF3cy5hY2NvdW50KCk7XG4gICAgY29uc3Qgcm9sZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmlhbS5zZW5kKFxuICAgICAgbmV3IEdldFJvbGVDb21tYW5kKHsgUm9sZU5hbWU6IGBjZGstJHtmaXh0dXJlLnF1YWxpZmllcn0tY2ZuLWV4ZWMtcm9sZS0ke2FjY291bnR9LSR7cmVnaW9ufWAgfSksXG4gICAgKTtcbiAgICBpZiAoIXJvbGUuUm9sZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdSb2xlIG5vdCBmb3VuZCcpO1xuICAgIH1cbiAgICBleHBlY3Qocm9sZS5Sb2xlLlBlcm1pc3Npb25zQm91bmRhcnkpLnRvQmVVbmRlZmluZWQoKTtcblxuICB9IGZpbmFsbHkge1xuICAgIGlmIChwb2xpY3lBcm4pIHtcbiAgICAgIGF3YWl0IGZpeHR1cmUuYXdzLmlhbS5zZW5kKG5ldyBEZWxldGVQb2xpY3lDb21tYW5kKHsgUG9saWN5QXJuOiBwb2xpY3lBcm4gfSkpO1xuICAgIH1cbiAgfVxufSkpO1xuXG5pbnRlZ1Rlc3QoJ3N3aXRjaCBvbiB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uLCBzd2l0Y2ggaXMgbGVmdCBhbG9uZSBvbiByZS1ib290c3RyYXAnLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICB0ZXJtaW5hdGlvblByb3RlY3Rpb246IHRydWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgZm9yY2U6IHRydWUsXG4gIH0pO1xuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24uc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSkpO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uRW5hYmxlVGVybWluYXRpb25Qcm90ZWN0aW9uKS50b0VxdWFsKHRydWUpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2FkZCB0YWdzLCBsZWZ0IGFsb25lIG9uIHJlLWJvb3RzdHJhcCcsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHRhZ3M6ICdGb289QmFyJyxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBmb3JjZTogdHJ1ZSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbi5zZW5kKG5ldyBEZXNjcmliZVN0YWNrc0NvbW1hbmQoeyBTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSB9KSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyJyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gYWRkIHRhZ3MgdGhlbiB1cGRhdGUgdGFncyBkdXJpbmcgcmUtYm9vdHN0cmFwJywgd2l0aG91dEJvb3RzdHJhcChhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgdGFnczogJ0Zvbz1CYXInLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHRhZ3M6ICdGb289QmFyQmF6JyxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgICBmb3JjZTogdHJ1ZSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbi5zZW5kKG5ldyBEZXNjcmliZVN0YWNrc0NvbW1hbmQoeyBTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSB9KSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyQmF6JyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gZGVwbG95IG1vZGVybi1zeW50aGVzaXplZCBzdGFjayBldmVuIGlmIGJvb3RzdHJhcCBzdGFjayBuYW1lIGlzIHVua25vd24nLCB3aXRob3V0Qm9vdHN0cmFwKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbXG4gICAgICAvLyBFeHBsaWNpdHkgcGFzcyBhIG5hbWUgdGhhdCdzIHN1cmUgdG8gbm90IGV4aXN0LCBvdGhlcndpc2UgdGhlIENMSSBtaWdodCBhY2NpZGVudGFsbHkgZmluZCBhXG4gICAgICAvLyBkZWZhdWx0IGJvb3RzdHJhY3Agc3RhY2sgaWYgdGhhdCBoYXBwZW5zIHRvIGJlIGluIHRoZSBhY2NvdW50IGFscmVhZHkuXG4gICAgICAnLS10b29sa2l0LXN0YWNrLW5hbWUnLCAnRGVmaW5pdGVseURvZXNOb3RFeGlzdCcsXG4gICAgICAnLS1jb250ZXh0JywgYEBhd3MtY2RrL2NvcmU6Ym9vdHN0cmFwUXVhbGlmaWVyPSR7Zml4dHVyZS5xdWFsaWZpZXJ9YCxcbiAgICAgICctLWNvbnRleHQnLCAnQGF3cy1jZGsvY29yZTpuZXdTdHlsZVN0YWNrU3ludGhlc2lzPTEnLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NyZWF0ZSBFQ1Igd2l0aCB0YWcgSU1NVVRBQklMSVRZIHRvIHNldCBvbicsIHdpdGhvdXRCb290c3RyYXAoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uLnNlbmQoXG4gICAgbmV3IERlc2NyaWJlU3RhY2tSZXNvdXJjZXNDb21tYW5kKHtcbiAgICAgIFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIH0pLFxuICApO1xuICBjb25zdCBlY3JSZXNvdXJjZSA9IHJlc3BvbnNlLlN0YWNrUmVzb3VyY2VzPy5maW5kKHJlc291cmNlID0+IHJlc291cmNlLkxvZ2ljYWxSZXNvdXJjZUlkID09PSAnQ29udGFpbmVyQXNzZXRzUmVwb3NpdG9yeScpO1xuICBleHBlY3QoZWNyUmVzb3VyY2UpLnRvQmVEZWZpbmVkKCk7XG5cbiAgY29uc3QgZWNyUmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5lY3Iuc2VuZChcbiAgICBuZXcgRGVzY3JpYmVSZXBvc2l0b3JpZXNDb21tYW5kKHtcbiAgICAgIHJlcG9zaXRvcnlOYW1lczogW1xuICAgICAgICAvLyBUaGlzIGlzIHNldCwgYXMgb3RoZXJ3aXNlIHdlIGRvbid0IGVuZCB1cCBoZXJlXG4gICAgICAgIGVjclJlc291cmNlPy5QaHlzaWNhbFJlc291cmNlSWQgPz8gJycsXG4gICAgICBdLFxuICAgIH0pLFxuICApO1xuXG4gIGV4cGVjdChlY3JSZXNwb25zZS5yZXBvc2l0b3JpZXM/LlswXS5pbWFnZVRhZ011dGFiaWxpdHkpLnRvRXF1YWwoJ0lNTVVUQUJMRScpO1xufSkpO1xuXG4iXX0=