aws-cdk 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 (402) hide show
  1. package/CONTRIBUTING.md +276 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +16 -0
  4. package/README.md +1274 -0
  5. package/THIRD_PARTY_LICENSES +26821 -0
  6. package/bin/cdk +6 -0
  7. package/build-info.json +4 -0
  8. package/db.json.gz +0 -0
  9. package/generate.sh +25 -0
  10. package/images/garbage-collection.png +0 -0
  11. package/lib/api/aws-auth/account-cache.d.ts +39 -0
  12. package/lib/api/aws-auth/account-cache.js +102 -0
  13. package/lib/api/aws-auth/awscli-compatible.d.ts +42 -0
  14. package/lib/api/aws-auth/awscli-compatible.js +264 -0
  15. package/lib/api/aws-auth/cached.d.ts +11 -0
  16. package/lib/api/aws-auth/cached.js +26 -0
  17. package/lib/api/aws-auth/credential-plugins.d.ts +36 -0
  18. package/lib/api/aws-auth/credential-plugins.js +153 -0
  19. package/lib/api/aws-auth/index.d.ts +3 -0
  20. package/lib/api/aws-auth/index.js +20 -0
  21. package/lib/api/aws-auth/provider-caching.d.ts +13 -0
  22. package/lib/api/aws-auth/provider-caching.js +24 -0
  23. package/lib/api/aws-auth/sdk-logger.d.ts +69 -0
  24. package/lib/api/aws-auth/sdk-logger.js +130 -0
  25. package/lib/api/aws-auth/sdk-provider.d.ts +207 -0
  26. package/lib/api/aws-auth/sdk-provider.js +359 -0
  27. package/lib/api/aws-auth/sdk.d.ts +223 -0
  28. package/lib/api/aws-auth/sdk.js +366 -0
  29. package/lib/api/aws-auth/tracing.d.ts +11 -0
  30. package/lib/api/aws-auth/tracing.js +61 -0
  31. package/lib/api/aws-auth/user-agent.d.ts +7 -0
  32. package/lib/api/aws-auth/user-agent.js +21 -0
  33. package/lib/api/aws-auth/util.d.ts +6 -0
  34. package/lib/api/aws-auth/util.js +23 -0
  35. package/lib/api/bootstrap/bootstrap-environment.d.ts +33 -0
  36. package/lib/api/bootstrap/bootstrap-environment.js +322 -0
  37. package/lib/api/bootstrap/bootstrap-props.d.ts +130 -0
  38. package/lib/api/bootstrap/bootstrap-props.js +14 -0
  39. package/lib/api/bootstrap/bootstrap-template.yaml +692 -0
  40. package/lib/api/bootstrap/deploy-bootstrap.d.ts +37 -0
  41. package/lib/api/bootstrap/deploy-bootstrap.js +143 -0
  42. package/lib/api/bootstrap/index.d.ts +2 -0
  43. package/lib/api/bootstrap/index.js +19 -0
  44. package/lib/api/bootstrap/legacy-template.d.ts +2 -0
  45. package/lib/api/bootstrap/legacy-template.js +82 -0
  46. package/lib/api/context.d.ts +40 -0
  47. package/lib/api/context.js +82 -0
  48. package/lib/api/cxapp/cloud-assembly.d.ts +150 -0
  49. package/lib/api/cxapp/cloud-assembly.js +305 -0
  50. package/lib/api/cxapp/cloud-executable.d.ts +44 -0
  51. package/lib/api/cxapp/cloud-executable.js +90 -0
  52. package/lib/api/cxapp/environments.d.ts +9 -0
  53. package/lib/api/cxapp/environments.js +66 -0
  54. package/lib/api/cxapp/exec.d.ts +56 -0
  55. package/lib/api/cxapp/exec.js +275 -0
  56. package/lib/api/deployments/asset-manifest-builder.d.ts +8 -0
  57. package/lib/api/deployments/asset-manifest-builder.js +35 -0
  58. package/lib/api/deployments/asset-publishing.d.ts +77 -0
  59. package/lib/api/deployments/asset-publishing.js +163 -0
  60. package/lib/api/deployments/assets.d.ts +10 -0
  61. package/lib/api/deployments/assets.js +111 -0
  62. package/lib/api/deployments/checks.d.ts +8 -0
  63. package/lib/api/deployments/checks.js +73 -0
  64. package/lib/api/deployments/cloudformation.d.ts +235 -0
  65. package/lib/api/deployments/cloudformation.js +598 -0
  66. package/lib/api/deployments/deploy-stack.d.ts +177 -0
  67. package/lib/api/deployments/deploy-stack.js +484 -0
  68. package/lib/api/deployments/deployment-method.d.ts +24 -0
  69. package/lib/api/deployments/deployment-method.js +3 -0
  70. package/lib/api/deployments/deployment-result.d.ts +21 -0
  71. package/lib/api/deployments/deployment-result.js +10 -0
  72. package/lib/api/deployments/deployments.d.ts +340 -0
  73. package/lib/api/deployments/deployments.js +369 -0
  74. package/lib/api/deployments/hotswap-deployments.d.ts +14 -0
  75. package/lib/api/deployments/hotswap-deployments.js +357 -0
  76. package/lib/api/deployments/index.d.ts +6 -0
  77. package/lib/api/deployments/index.js +23 -0
  78. package/lib/api/deployments/nested-stack-helpers.d.ts +25 -0
  79. package/lib/api/deployments/nested-stack-helpers.js +88 -0
  80. package/lib/api/environment-access.d.ts +138 -0
  81. package/lib/api/environment-access.js +203 -0
  82. package/lib/api/environment-resources.d.ts +73 -0
  83. package/lib/api/environment-resources.js +208 -0
  84. package/lib/api/evaluate-cloudformation-template.d.ts +84 -0
  85. package/lib/api/evaluate-cloudformation-template.js +443 -0
  86. package/lib/api/garbage-collection/garbage-collector.d.ts +152 -0
  87. package/lib/api/garbage-collection/garbage-collector.js +607 -0
  88. package/lib/api/garbage-collection/progress-printer.d.ts +21 -0
  89. package/lib/api/garbage-collection/progress-printer.js +69 -0
  90. package/lib/api/garbage-collection/stack-refresh.d.ts +44 -0
  91. package/lib/api/garbage-collection/stack-refresh.js +154 -0
  92. package/lib/api/hotswap/appsync-mapping-templates.d.ts +3 -0
  93. package/lib/api/hotswap/appsync-mapping-templates.js +157 -0
  94. package/lib/api/hotswap/code-build-projects.d.ts +3 -0
  95. package/lib/api/hotswap/code-build-projects.js +55 -0
  96. package/lib/api/hotswap/common.d.ts +126 -0
  97. package/lib/api/hotswap/common.js +170 -0
  98. package/lib/api/hotswap/ecs-services.d.ts +3 -0
  99. package/lib/api/hotswap/ecs-services.js +140 -0
  100. package/lib/api/hotswap/lambda-functions.d.ts +3 -0
  101. package/lib/api/hotswap/lambda-functions.js +309 -0
  102. package/lib/api/hotswap/s3-bucket-deployments.d.ts +9 -0
  103. package/lib/api/hotswap/s3-bucket-deployments.js +112 -0
  104. package/lib/api/hotswap/stepfunctions-state-machines.d.ts +3 -0
  105. package/lib/api/hotswap/stepfunctions-state-machines.js +42 -0
  106. package/lib/api/index.d.ts +5 -0
  107. package/lib/api/index.js +22 -0
  108. package/lib/api/logs/find-cloudwatch-logs.d.ts +24 -0
  109. package/lib/api/logs/find-cloudwatch-logs.js +97 -0
  110. package/lib/api/logs/logs-monitor.d.ts +53 -0
  111. package/lib/api/logs/logs-monitor.js +169 -0
  112. package/lib/api/plugin/context-provider-plugin.d.ts +6 -0
  113. package/lib/api/plugin/context-provider-plugin.js +7 -0
  114. package/lib/api/plugin/index.d.ts +3 -0
  115. package/lib/api/plugin/index.js +20 -0
  116. package/lib/api/plugin/mode.d.ts +4 -0
  117. package/lib/api/plugin/mode.js +9 -0
  118. package/lib/api/plugin/plugin.d.ts +63 -0
  119. package/lib/api/plugin/plugin.js +106 -0
  120. package/lib/api/settings.d.ts +29 -0
  121. package/lib/api/settings.js +141 -0
  122. package/lib/api/tags.d.ts +9 -0
  123. package/lib/api/tags.js +10 -0
  124. package/lib/api/toolkit-info.d.ts +51 -0
  125. package/lib/api/toolkit-info.js +156 -0
  126. package/lib/api/util/cloudformation/stack-activity-monitor.d.ts +237 -0
  127. package/lib/api/util/cloudformation/stack-activity-monitor.js +550 -0
  128. package/lib/api/util/cloudformation/stack-event-poller.d.ts +63 -0
  129. package/lib/api/util/cloudformation/stack-event-poller.js +129 -0
  130. package/lib/api/util/cloudformation/stack-status.d.ts +42 -0
  131. package/lib/api/util/cloudformation/stack-status.js +88 -0
  132. package/lib/api/util/display.d.ts +13 -0
  133. package/lib/api/util/display.js +80 -0
  134. package/lib/api/util/placeholders.d.ts +10 -0
  135. package/lib/api/util/placeholders.js +24 -0
  136. package/lib/api/util/rwlock.d.ts +65 -0
  137. package/lib/api/util/rwlock.js +179 -0
  138. package/lib/api/util/string-manipulation.d.ts +10 -0
  139. package/lib/api/util/string-manipulation.js +33 -0
  140. package/lib/api/util/template-body-parameter.d.ts +21 -0
  141. package/lib/api/util/template-body-parameter.js +104 -0
  142. package/lib/cli/cdk-toolkit.d.ts +594 -0
  143. package/lib/cli/cdk-toolkit.js +1019 -0
  144. package/lib/cli/cli-config.d.ts +10 -0
  145. package/lib/cli/cli-config.js +406 -0
  146. package/lib/cli/cli.d.ts +4 -0
  147. package/lib/cli/cli.js +538 -0
  148. package/lib/cli/convert-to-user-input.d.ts +3 -0
  149. package/lib/cli/convert-to-user-input.js +434 -0
  150. package/lib/cli/parse-command-line-arguments.d.ts +1 -0
  151. package/lib/cli/parse-command-line-arguments.js +806 -0
  152. package/lib/cli/platform-warnings.d.ts +2 -0
  153. package/lib/cli/platform-warnings.js +45 -0
  154. package/lib/cli/user-configuration.d.ts +90 -0
  155. package/lib/cli/user-configuration.js +272 -0
  156. package/lib/cli/user-input.d.ts +1163 -0
  157. package/lib/cli/user-input.js +3 -0
  158. package/lib/cli/util/console-formatters.d.ts +18 -0
  159. package/lib/cli/util/console-formatters.js +42 -0
  160. package/lib/cli/util/npm.d.ts +1 -0
  161. package/lib/cli/util/npm.js +22 -0
  162. package/lib/cli/util/yargs-helpers.d.ts +22 -0
  163. package/lib/cli/util/yargs-helpers.js +49 -0
  164. package/lib/cli/version.d.ts +13 -0
  165. package/lib/cli/version.js +120 -0
  166. package/lib/commands/context.d.ts +35 -0
  167. package/lib/commands/context.js +156 -0
  168. package/lib/commands/docs.d.ts +13 -0
  169. package/lib/commands/docs.js +32 -0
  170. package/lib/commands/doctor.d.ts +1 -0
  171. package/lib/commands/doctor.js +69 -0
  172. package/lib/commands/migrate.d.ts +327 -0
  173. package/lib/commands/migrate.js +804 -0
  174. package/lib/context-providers/ami.d.ts +11 -0
  175. package/lib/context-providers/ami.js +50 -0
  176. package/lib/context-providers/availability-zones.d.ts +11 -0
  177. package/lib/context-providers/availability-zones.js +27 -0
  178. package/lib/context-providers/endpoint-service-availability-zones.d.ts +11 -0
  179. package/lib/context-providers/endpoint-service-availability-zones.js +33 -0
  180. package/lib/context-providers/hosted-zones.d.ts +10 -0
  181. package/lib/context-providers/hosted-zones.js +67 -0
  182. package/lib/context-providers/index.d.ts +30 -0
  183. package/lib/context-providers/index.js +109 -0
  184. package/lib/context-providers/keys.d.ts +11 -0
  185. package/lib/context-providers/keys.js +52 -0
  186. package/lib/context-providers/load-balancers.d.ts +20 -0
  187. package/lib/context-providers/load-balancers.js +159 -0
  188. package/lib/context-providers/security-groups.d.ts +9 -0
  189. package/lib/context-providers/security-groups.js +70 -0
  190. package/lib/context-providers/ssm-parameters.d.ts +23 -0
  191. package/lib/context-providers/ssm-parameters.js +59 -0
  192. package/lib/context-providers/vpcs.d.ts +11 -0
  193. package/lib/context-providers/vpcs.js +288 -0
  194. package/lib/diff.d.ts +28 -0
  195. package/lib/diff.js +165 -0
  196. package/lib/import.d.ts +182 -0
  197. package/lib/import.js +335 -0
  198. package/lib/index.d.ts +3 -0
  199. package/lib/index.js +348304 -0
  200. package/lib/index_bg.wasm +0 -0
  201. package/lib/init-hooks.d.ts +40 -0
  202. package/lib/init-hooks.js +64 -0
  203. package/lib/init-templates/.init-version.json +1 -0
  204. package/lib/init-templates/.no-packagejson-validator +0 -0
  205. package/lib/init-templates/.recommended-feature-flags.json +68 -0
  206. package/lib/init-templates/LICENSE +16 -0
  207. package/lib/init-templates/app/csharp/.template.gitignore +342 -0
  208. package/lib/init-templates/app/csharp/README.md +14 -0
  209. package/lib/init-templates/app/csharp/cdk.template.json +15 -0
  210. package/lib/init-templates/app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +20 -0
  211. package/lib/init-templates/app/csharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.cs +13 -0
  212. package/lib/init-templates/app/csharp/src/%name.PascalCased%/GlobalSuppressions.cs +1 -0
  213. package/lib/init-templates/app/csharp/src/%name.PascalCased%/Program.template.cs +44 -0
  214. package/lib/init-templates/app/csharp/src/%name.PascalCased%.template.sln +18 -0
  215. package/lib/init-templates/app/fsharp/.template.gitignore +342 -0
  216. package/lib/init-templates/app/fsharp/README.md +18 -0
  217. package/lib/init-templates/app/fsharp/cdk.template.json +14 -0
  218. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +25 -0
  219. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.fs +8 -0
  220. package/lib/init-templates/app/fsharp/src/%name.PascalCased%/Program.template.fs +11 -0
  221. package/lib/init-templates/app/fsharp/src/%name.PascalCased%.template.sln +18 -0
  222. package/lib/init-templates/app/go/%name%.template.go +70 -0
  223. package/lib/init-templates/app/go/%name%_test.template.go +26 -0
  224. package/lib/init-templates/app/go/.template.gitignore +19 -0
  225. package/lib/init-templates/app/go/README.md +12 -0
  226. package/lib/init-templates/app/go/cdk.template.json +13 -0
  227. package/lib/init-templates/app/go/go.template.mod +9 -0
  228. package/lib/init-templates/app/info.json +4 -0
  229. package/lib/init-templates/app/java/.template.gitignore +13 -0
  230. package/lib/init-templates/app/java/README.md +18 -0
  231. package/lib/init-templates/app/java/cdk.json +13 -0
  232. package/lib/init-templates/app/java/pom.xml +60 -0
  233. package/lib/init-templates/app/java/src/main/java/com/myorg/%name.PascalCased%App.template.java +42 -0
  234. package/lib/init-templates/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +24 -0
  235. package/lib/init-templates/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +26 -0
  236. package/lib/init-templates/app/javascript/.template.gitignore +5 -0
  237. package/lib/init-templates/app/javascript/.template.npmignore +3 -0
  238. package/lib/init-templates/app/javascript/README.md +12 -0
  239. package/lib/init-templates/app/javascript/bin/%name%.template.js +21 -0
  240. package/lib/init-templates/app/javascript/cdk.template.json +15 -0
  241. package/lib/init-templates/app/javascript/jest.config.js +3 -0
  242. package/lib/init-templates/app/javascript/lib/%name%-stack.template.js +23 -0
  243. package/lib/init-templates/app/javascript/package.json +20 -0
  244. package/lib/init-templates/app/javascript/test/%name%.test.template.js +17 -0
  245. package/lib/init-templates/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +19 -0
  246. package/lib/init-templates/app/python/%name.PythonModule%/__init__.py +0 -0
  247. package/lib/init-templates/app/python/.template.gitignore +10 -0
  248. package/lib/init-templates/app/python/README.template.md +58 -0
  249. package/lib/init-templates/app/python/app.template.py +28 -0
  250. package/lib/init-templates/app/python/cdk.template.json +15 -0
  251. package/lib/init-templates/app/python/requirements-dev.txt +1 -0
  252. package/lib/init-templates/app/python/requirements.txt +2 -0
  253. package/lib/init-templates/app/python/source.bat +13 -0
  254. package/lib/init-templates/app/python/tests/__init__.py +0 -0
  255. package/lib/init-templates/app/python/tests/unit/__init__.py +0 -0
  256. package/lib/init-templates/app/python/tests/unit/test_%name.PythonModule%_stack.template.py +15 -0
  257. package/lib/init-templates/app/typescript/.template.gitignore +8 -0
  258. package/lib/init-templates/app/typescript/.template.npmignore +6 -0
  259. package/lib/init-templates/app/typescript/README.md +14 -0
  260. package/lib/init-templates/app/typescript/bin/%name%.template.ts +20 -0
  261. package/lib/init-templates/app/typescript/cdk.template.json +17 -0
  262. package/lib/init-templates/app/typescript/jest.config.js +8 -0
  263. package/lib/init-templates/app/typescript/lib/%name%-stack.template.ts +16 -0
  264. package/lib/init-templates/app/typescript/package.json +26 -0
  265. package/lib/init-templates/app/typescript/test/%name%.test.template.ts +17 -0
  266. package/lib/init-templates/app/typescript/tsconfig.json +31 -0
  267. package/lib/init-templates/lib/info.json +4 -0
  268. package/lib/init-templates/lib/typescript/.template.gitignore +8 -0
  269. package/lib/init-templates/lib/typescript/.template.npmignore +6 -0
  270. package/lib/init-templates/lib/typescript/README.template.md +12 -0
  271. package/lib/init-templates/lib/typescript/jest.config.js +8 -0
  272. package/lib/init-templates/lib/typescript/lib/index.template.ts +21 -0
  273. package/lib/init-templates/lib/typescript/package.json +24 -0
  274. package/lib/init-templates/lib/typescript/test/%name%.test.template.ts +18 -0
  275. package/lib/init-templates/lib/typescript/tsconfig.json +31 -0
  276. package/lib/init-templates/sample-app/csharp/.template.gitignore +342 -0
  277. package/lib/init-templates/sample-app/csharp/README.template.md +19 -0
  278. package/lib/init-templates/sample-app/csharp/cdk.template.json +15 -0
  279. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/%name.PascalCased%.template.csproj +20 -0
  280. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.cs +24 -0
  281. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/GlobalSuppressions.cs +1 -0
  282. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%/Program.template.cs +15 -0
  283. package/lib/init-templates/sample-app/csharp/src/%name.PascalCased%.template.sln +18 -0
  284. package/lib/init-templates/sample-app/fsharp/.template.gitignore +342 -0
  285. package/lib/init-templates/sample-app/fsharp/README.template.md +20 -0
  286. package/lib/init-templates/sample-app/fsharp/cdk.template.json +14 -0
  287. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/%name.PascalCased%.template.fsproj +25 -0
  288. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/%name.PascalCased%Stack.template.fs +14 -0
  289. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%/Program.template.fs +11 -0
  290. package/lib/init-templates/sample-app/fsharp/src/%name.PascalCased%.template.sln +18 -0
  291. package/lib/init-templates/sample-app/go/%name%.template.go +73 -0
  292. package/lib/init-templates/sample-app/go/%name%_test.template.go +25 -0
  293. package/lib/init-templates/sample-app/go/.template.gitignore +19 -0
  294. package/lib/init-templates/sample-app/go/README.md +12 -0
  295. package/lib/init-templates/sample-app/go/cdk.template.json +13 -0
  296. package/lib/init-templates/sample-app/go/go.template.mod +9 -0
  297. package/lib/init-templates/sample-app/info.json +4 -0
  298. package/lib/init-templates/sample-app/java/.template.gitignore +13 -0
  299. package/lib/init-templates/sample-app/java/README.template.md +19 -0
  300. package/lib/init-templates/sample-app/java/cdk.json +13 -0
  301. package/lib/init-templates/sample-app/java/pom.xml +55 -0
  302. package/lib/init-templates/sample-app/java/src/main/java/com/myorg/%name.PascalCased%App.template.java +13 -0
  303. package/lib/init-templates/sample-app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +29 -0
  304. package/lib/init-templates/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +27 -0
  305. package/lib/init-templates/sample-app/javascript/.template.gitignore +5 -0
  306. package/lib/init-templates/sample-app/javascript/.template.npmignore +3 -0
  307. package/lib/init-templates/sample-app/javascript/README.template.md +13 -0
  308. package/lib/init-templates/sample-app/javascript/bin/%name%.template.js +6 -0
  309. package/lib/init-templates/sample-app/javascript/cdk.template.json +15 -0
  310. package/lib/init-templates/sample-app/javascript/jest.config.js +3 -0
  311. package/lib/init-templates/sample-app/javascript/lib/%name%-stack.template.js +25 -0
  312. package/lib/init-templates/sample-app/javascript/package.json +20 -0
  313. package/lib/init-templates/sample-app/javascript/test/%name%.test.template.js +16 -0
  314. package/lib/init-templates/sample-app/javascript/tsconfig.json +34 -0
  315. package/lib/init-templates/sample-app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +26 -0
  316. package/lib/init-templates/sample-app/python/%name.PythonModule%/__init__.py +0 -0
  317. package/lib/init-templates/sample-app/python/.template.gitignore +22 -0
  318. package/lib/init-templates/sample-app/python/README.template.md +65 -0
  319. package/lib/init-templates/sample-app/python/app.template.py +11 -0
  320. package/lib/init-templates/sample-app/python/cdk.template.json +15 -0
  321. package/lib/init-templates/sample-app/python/requirements-dev.txt +1 -0
  322. package/lib/init-templates/sample-app/python/requirements.txt +2 -0
  323. package/lib/init-templates/sample-app/python/source.bat +13 -0
  324. package/lib/init-templates/sample-app/python/tests/__init__.py +0 -0
  325. package/lib/init-templates/sample-app/python/tests/unit/__init__.py +0 -0
  326. package/lib/init-templates/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py +21 -0
  327. package/lib/init-templates/sample-app/typescript/.template.gitignore +8 -0
  328. package/lib/init-templates/sample-app/typescript/.template.npmignore +6 -0
  329. package/lib/init-templates/sample-app/typescript/README.template.md +15 -0
  330. package/lib/init-templates/sample-app/typescript/bin/%name%.template.ts +6 -0
  331. package/lib/init-templates/sample-app/typescript/cdk.template.json +17 -0
  332. package/lib/init-templates/sample-app/typescript/jest.config.js +8 -0
  333. package/lib/init-templates/sample-app/typescript/lib/%name%-stack.template.ts +19 -0
  334. package/lib/init-templates/sample-app/typescript/package.json +26 -0
  335. package/lib/init-templates/sample-app/typescript/test/%name%.test.template.ts +17 -0
  336. package/lib/init-templates/sample-app/typescript/tsconfig.json +31 -0
  337. package/lib/init.d.ts +52 -0
  338. package/lib/init.js +430 -0
  339. package/lib/legacy-exports-source.d.ts +27 -0
  340. package/lib/legacy-exports-source.js +88 -0
  341. package/lib/legacy-exports.d.ts +10 -0
  342. package/lib/legacy-exports.js +28 -0
  343. package/lib/legacy-logging-source.d.ts +32 -0
  344. package/lib/legacy-logging-source.js +107 -0
  345. package/lib/list-stacks.d.ts +22 -0
  346. package/lib/list-stacks.js +23 -0
  347. package/lib/logging.d.ts +109 -0
  348. package/lib/logging.js +159 -0
  349. package/lib/migrator.d.ts +25 -0
  350. package/lib/migrator.js +67 -0
  351. package/lib/notices.d.ts +156 -0
  352. package/lib/notices.js +373 -0
  353. package/lib/os.d.ts +7 -0
  354. package/lib/os.js +92 -0
  355. package/lib/serialize.d.ts +27 -0
  356. package/lib/serialize.js +86 -0
  357. package/lib/toolkit/cli-io-host.d.ts +208 -0
  358. package/lib/toolkit/cli-io-host.js +282 -0
  359. package/lib/toolkit/error.d.ts +44 -0
  360. package/lib/toolkit/error.js +78 -0
  361. package/lib/tree.d.ts +31 -0
  362. package/lib/tree.js +40 -0
  363. package/lib/util/archive.d.ts +1 -0
  364. package/lib/util/archive.js +86 -0
  365. package/lib/util/arrays.d.ts +14 -0
  366. package/lib/util/arrays.js +36 -0
  367. package/lib/util/bool.d.ts +7 -0
  368. package/lib/util/bool.js +13 -0
  369. package/lib/util/bytes.d.ts +8 -0
  370. package/lib/util/bytes.js +21 -0
  371. package/lib/util/content-hash.d.ts +5 -0
  372. package/lib/util/content-hash.js +43 -0
  373. package/lib/util/directories.d.ts +23 -0
  374. package/lib/util/directories.js +57 -0
  375. package/lib/util/error.d.ts +9 -0
  376. package/lib/util/error.js +22 -0
  377. package/lib/util/index.d.ts +5 -0
  378. package/lib/util/index.js +22 -0
  379. package/lib/util/objects.d.ts +52 -0
  380. package/lib/util/objects.js +183 -0
  381. package/lib/util/parallel.d.ts +6 -0
  382. package/lib/util/parallel.js +44 -0
  383. package/lib/util/tables.d.ts +1 -0
  384. package/lib/util/tables.js +10 -0
  385. package/lib/util/type-brands.d.ts +39 -0
  386. package/lib/util/type-brands.js +38 -0
  387. package/lib/util/types.d.ts +27 -0
  388. package/lib/util/types.js +25 -0
  389. package/lib/util/validate-notification-arn.d.ts +4 -0
  390. package/lib/util/validate-notification-arn.js +10 -0
  391. package/lib/util/version-range.d.ts +2 -0
  392. package/lib/util/version-range.js +36 -0
  393. package/lib/util/work-graph-builder.d.ts +32 -0
  394. package/lib/util/work-graph-builder.js +167 -0
  395. package/lib/util/work-graph-types.d.ts +50 -0
  396. package/lib/util/work-graph-types.js +14 -0
  397. package/lib/util/work-graph.d.ts +70 -0
  398. package/lib/util/work-graph.js +344 -0
  399. package/lib/util/yaml-cfn.d.ts +15 -0
  400. package/lib/util/yaml-cfn.js +56 -0
  401. package/package.json +197 -0
  402. package/scripts/user-input-gen +2 -0
@@ -0,0 +1,607 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GarbageCollector = exports.ObjectAsset = exports.ImageAsset = exports.ECR_ISOLATED_TAG = exports.S3_ISOLATED_TAG = void 0;
4
+ const chalk = require("chalk");
5
+ const promptly = require("promptly");
6
+ const logging_1 = require("../../logging");
7
+ const toolkit_info_1 = require("../toolkit-info");
8
+ const progress_printer_1 = require("./progress-printer");
9
+ const stack_refresh_1 = require("./stack-refresh");
10
+ const error_1 = require("../../toolkit/error");
11
+ const mode_1 = require("../plugin/mode");
12
+ // Must use a require() otherwise esbuild complains
13
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
14
+ const pLimit = require('p-limit');
15
+ exports.S3_ISOLATED_TAG = 'aws-cdk:isolated';
16
+ exports.ECR_ISOLATED_TAG = 'aws-cdk.isolated'; // ':' is not valid in ECR tags
17
+ const P_LIMIT = 50;
18
+ const DAY = 24 * 60 * 60 * 1000; // Number of milliseconds in a day
19
+ /**
20
+ * An image asset that lives in the bootstrapped ECR Repository
21
+ */
22
+ class ImageAsset {
23
+ constructor(digest, size, tags, manifest) {
24
+ this.digest = digest;
25
+ this.size = size;
26
+ this.tags = tags;
27
+ this.manifest = manifest;
28
+ }
29
+ getTag(tag) {
30
+ return this.tags.find(t => t.includes(tag));
31
+ }
32
+ hasTag(tag) {
33
+ return this.tags.some(t => t.includes(tag));
34
+ }
35
+ hasIsolatedTag() {
36
+ return this.hasTag(exports.ECR_ISOLATED_TAG);
37
+ }
38
+ getIsolatedTag() {
39
+ return this.getTag(exports.ECR_ISOLATED_TAG);
40
+ }
41
+ isolatedTagBefore(date) {
42
+ const dateIsolated = this.dateIsolated();
43
+ if (!dateIsolated || dateIsolated == '') {
44
+ return false;
45
+ }
46
+ return new Date(dateIsolated) < date;
47
+ }
48
+ buildImageTag(inc) {
49
+ // isolatedTag will look like "X-aws-cdk.isolated-YYYYY"
50
+ return `${inc}-${exports.ECR_ISOLATED_TAG}-${String(Date.now())}`;
51
+ }
52
+ dateIsolated() {
53
+ var _a;
54
+ // isolatedTag will look like "X-aws-cdk.isolated-YYYYY"
55
+ return (_a = this.getIsolatedTag()) === null || _a === void 0 ? void 0 : _a.split('-')[3];
56
+ }
57
+ }
58
+ exports.ImageAsset = ImageAsset;
59
+ /**
60
+ * An object asset that lives in the bootstrapped S3 Bucket
61
+ */
62
+ class ObjectAsset {
63
+ constructor(bucket, key, size) {
64
+ this.bucket = bucket;
65
+ this.key = key;
66
+ this.size = size;
67
+ this.cached_tags = undefined;
68
+ }
69
+ fileName() {
70
+ return this.key.split('.')[0];
71
+ }
72
+ async allTags(s3) {
73
+ if (this.cached_tags) {
74
+ return this.cached_tags;
75
+ }
76
+ const response = await s3.getObjectTagging({ Bucket: this.bucket, Key: this.key });
77
+ this.cached_tags = response.TagSet;
78
+ return this.cached_tags;
79
+ }
80
+ getTag(tag) {
81
+ var _a;
82
+ if (!this.cached_tags) {
83
+ throw new error_1.ToolkitError('Cannot call getTag before allTags');
84
+ }
85
+ return (_a = this.cached_tags.find((t) => t.Key === tag)) === null || _a === void 0 ? void 0 : _a.Value;
86
+ }
87
+ hasTag(tag) {
88
+ if (!this.cached_tags) {
89
+ throw new error_1.ToolkitError('Cannot call hasTag before allTags');
90
+ }
91
+ return this.cached_tags.some((t) => t.Key === tag);
92
+ }
93
+ hasIsolatedTag() {
94
+ return this.hasTag(exports.S3_ISOLATED_TAG);
95
+ }
96
+ isolatedTagBefore(date) {
97
+ const tagValue = this.getTag(exports.S3_ISOLATED_TAG);
98
+ if (!tagValue || tagValue == '') {
99
+ return false;
100
+ }
101
+ return new Date(tagValue) < date;
102
+ }
103
+ }
104
+ exports.ObjectAsset = ObjectAsset;
105
+ /**
106
+ * A class to facilitate Garbage Collection of S3 and ECR assets
107
+ */
108
+ class GarbageCollector {
109
+ constructor(props) {
110
+ var _a, _b;
111
+ this.props = props;
112
+ this.garbageCollectS3Assets = ['s3', 'all'].includes(props.type);
113
+ this.garbageCollectEcrAssets = ['ecr', 'all'].includes(props.type);
114
+ (0, logging_1.debug)(`${this.garbageCollectS3Assets} ${this.garbageCollectEcrAssets}`);
115
+ this.permissionToDelete = ['delete-tagged', 'full'].includes(props.action);
116
+ this.permissionToTag = ['tag', 'full'].includes(props.action);
117
+ this.confirm = (_a = props.confirm) !== null && _a !== void 0 ? _a : true;
118
+ this.bootstrapStackName = (_b = props.bootstrapStackName) !== null && _b !== void 0 ? _b : toolkit_info_1.DEFAULT_TOOLKIT_STACK_NAME;
119
+ }
120
+ /**
121
+ * Perform garbage collection on the resolved environment.
122
+ */
123
+ async garbageCollect() {
124
+ // SDKs
125
+ const sdk = (await this.props.sdkProvider.forEnvironment(this.props.resolvedEnvironment, mode_1.Mode.ForWriting)).sdk;
126
+ const cfn = sdk.cloudFormation();
127
+ const qualifier = await this.bootstrapQualifier(sdk, this.bootstrapStackName);
128
+ const activeAssets = new stack_refresh_1.ActiveAssetCache();
129
+ // Grab stack templates first
130
+ await (0, stack_refresh_1.refreshStacks)(cfn, activeAssets, qualifier);
131
+ // Start the background refresh
132
+ const backgroundStackRefresh = new stack_refresh_1.BackgroundStackRefresh({
133
+ cfn,
134
+ activeAssets,
135
+ qualifier,
136
+ });
137
+ backgroundStackRefresh.start();
138
+ try {
139
+ if (this.garbageCollectS3Assets) {
140
+ await this.garbageCollectS3(sdk, activeAssets, backgroundStackRefresh);
141
+ }
142
+ if (this.garbageCollectEcrAssets) {
143
+ await this.garbageCollectEcr(sdk, activeAssets, backgroundStackRefresh);
144
+ }
145
+ }
146
+ catch (err) {
147
+ throw new error_1.ToolkitError(err);
148
+ }
149
+ finally {
150
+ backgroundStackRefresh.stop();
151
+ }
152
+ }
153
+ /**
154
+ * Perform garbage collection on ECR assets
155
+ */
156
+ async garbageCollectEcr(sdk, activeAssets, backgroundStackRefresh) {
157
+ const ecr = sdk.ecr();
158
+ const repo = await this.bootstrapRepositoryName(sdk, this.bootstrapStackName);
159
+ const numImages = await this.numImagesInRepo(ecr, repo);
160
+ const printer = new progress_printer_1.ProgressPrinter(numImages, 1000);
161
+ (0, logging_1.debug)(`Found bootstrap repo ${repo} with ${numImages} images`);
162
+ try {
163
+ // const batches = 1;
164
+ const batchSize = 1000;
165
+ const currentTime = Date.now();
166
+ const graceDays = this.props.rollbackBufferDays;
167
+ (0, logging_1.debug)(`Parsing through ${numImages} images in batches`);
168
+ printer.start();
169
+ for await (const batch of this.readRepoInBatches(ecr, repo, batchSize, currentTime)) {
170
+ await backgroundStackRefresh.noOlderThan(600000); // 10 mins
171
+ const { included: isolated, excluded: notIsolated } = partition(batch, asset => !asset.tags.some(t => activeAssets.contains(t)));
172
+ (0, logging_1.debug)(`${isolated.length} isolated images`);
173
+ (0, logging_1.debug)(`${notIsolated.length} not isolated images`);
174
+ (0, logging_1.debug)(`${batch.length} images total`);
175
+ let deletables = isolated;
176
+ let taggables = [];
177
+ let untaggables = [];
178
+ if (graceDays > 0) {
179
+ (0, logging_1.debug)('Filtering out images that are not old enough to delete');
180
+ // We delete images that are not referenced in ActiveAssets and have the Isolated Tag with a date
181
+ // earlier than the current time - grace period.
182
+ deletables = isolated.filter(img => img.isolatedTagBefore(new Date(currentTime - (graceDays * DAY))));
183
+ // We tag images that are not referenced in ActiveAssets and do not have the Isolated Tag.
184
+ taggables = isolated.filter(img => !img.hasIsolatedTag());
185
+ // We untag images that are referenced in ActiveAssets and currently have the Isolated Tag.
186
+ untaggables = notIsolated.filter(img => img.hasIsolatedTag());
187
+ }
188
+ (0, logging_1.debug)(`${deletables.length} deletable assets`);
189
+ (0, logging_1.debug)(`${taggables.length} taggable assets`);
190
+ (0, logging_1.debug)(`${untaggables.length} assets to untag`);
191
+ if (this.permissionToDelete && deletables.length > 0) {
192
+ await this.confirmationPrompt(printer, deletables, 'image');
193
+ await this.parallelDeleteEcr(ecr, repo, deletables, printer);
194
+ }
195
+ if (this.permissionToTag && taggables.length > 0) {
196
+ await this.parallelTagEcr(ecr, repo, taggables, printer);
197
+ }
198
+ if (this.permissionToTag && untaggables.length > 0) {
199
+ await this.parallelUntagEcr(ecr, repo, untaggables);
200
+ }
201
+ printer.reportScannedAsset(batch.length);
202
+ }
203
+ }
204
+ catch (err) {
205
+ throw new error_1.ToolkitError(err);
206
+ }
207
+ finally {
208
+ printer.stop();
209
+ }
210
+ }
211
+ /**
212
+ * Perform garbage collection on S3 assets
213
+ */
214
+ async garbageCollectS3(sdk, activeAssets, backgroundStackRefresh) {
215
+ const s3 = sdk.s3();
216
+ const bucket = await this.bootstrapBucketName(sdk, this.bootstrapStackName);
217
+ const numObjects = await this.numObjectsInBucket(s3, bucket);
218
+ const printer = new progress_printer_1.ProgressPrinter(numObjects, 1000);
219
+ (0, logging_1.debug)(`Found bootstrap bucket ${bucket} with ${numObjects} objects`);
220
+ try {
221
+ const batchSize = 1000;
222
+ const currentTime = Date.now();
223
+ const graceDays = this.props.rollbackBufferDays;
224
+ (0, logging_1.debug)(`Parsing through ${numObjects} objects in batches`);
225
+ printer.start();
226
+ // Process objects in batches of 1000
227
+ // This is the batch limit of s3.DeleteObject and we intend to optimize for the "worst case" scenario
228
+ // where gc is run for the first time on a long-standing bucket where ~100% of objects are isolated.
229
+ for await (const batch of this.readBucketInBatches(s3, bucket, batchSize, currentTime)) {
230
+ await backgroundStackRefresh.noOlderThan(600000); // 10 mins
231
+ const { included: isolated, excluded: notIsolated } = partition(batch, asset => !activeAssets.contains(asset.fileName()));
232
+ (0, logging_1.debug)(`${isolated.length} isolated assets`);
233
+ (0, logging_1.debug)(`${notIsolated.length} not isolated assets`);
234
+ (0, logging_1.debug)(`${batch.length} objects total`);
235
+ let deletables = isolated;
236
+ let taggables = [];
237
+ let untaggables = [];
238
+ if (graceDays > 0) {
239
+ (0, logging_1.debug)('Filtering out assets that are not old enough to delete');
240
+ await this.parallelReadAllTags(s3, batch);
241
+ // We delete objects that are not referenced in ActiveAssets and have the Isolated Tag with a date
242
+ // earlier than the current time - grace period.
243
+ deletables = isolated.filter(obj => obj.isolatedTagBefore(new Date(currentTime - (graceDays * DAY))));
244
+ // We tag objects that are not referenced in ActiveAssets and do not have the Isolated Tag.
245
+ taggables = isolated.filter(obj => !obj.hasIsolatedTag());
246
+ // We untag objects that are referenced in ActiveAssets and currently have the Isolated Tag.
247
+ untaggables = notIsolated.filter(obj => obj.hasIsolatedTag());
248
+ }
249
+ (0, logging_1.debug)(`${deletables.length} deletable assets`);
250
+ (0, logging_1.debug)(`${taggables.length} taggable assets`);
251
+ (0, logging_1.debug)(`${untaggables.length} assets to untag`);
252
+ if (this.permissionToDelete && deletables.length > 0) {
253
+ await this.confirmationPrompt(printer, deletables, 'object');
254
+ await this.parallelDeleteS3(s3, bucket, deletables, printer);
255
+ }
256
+ if (this.permissionToTag && taggables.length > 0) {
257
+ await this.parallelTagS3(s3, bucket, taggables, currentTime, printer);
258
+ }
259
+ if (this.permissionToTag && untaggables.length > 0) {
260
+ await this.parallelUntagS3(s3, bucket, untaggables);
261
+ }
262
+ printer.reportScannedAsset(batch.length);
263
+ }
264
+ }
265
+ catch (err) {
266
+ throw new error_1.ToolkitError(err);
267
+ }
268
+ finally {
269
+ printer.stop();
270
+ }
271
+ }
272
+ async parallelReadAllTags(s3, objects) {
273
+ const limit = pLimit(P_LIMIT);
274
+ for (const obj of objects) {
275
+ await limit(() => obj.allTags(s3));
276
+ }
277
+ }
278
+ /**
279
+ * Untag assets that were previously tagged, but now currently referenced.
280
+ * Since this is treated as an implementation detail, we do not print the results in the printer.
281
+ */
282
+ async parallelUntagEcr(ecr, repo, untaggables) {
283
+ const limit = pLimit(P_LIMIT);
284
+ for (const img of untaggables) {
285
+ const tag = img.getIsolatedTag();
286
+ await limit(() => ecr.batchDeleteImage({
287
+ repositoryName: repo,
288
+ imageIds: [{
289
+ imageTag: tag,
290
+ }],
291
+ }));
292
+ }
293
+ (0, logging_1.debug)(`Untagged ${untaggables.length} assets`);
294
+ }
295
+ /**
296
+ * Untag assets that were previously tagged, but now currently referenced.
297
+ * Since this is treated as an implementation detail, we do not print the results in the printer.
298
+ */
299
+ async parallelUntagS3(s3, bucket, untaggables) {
300
+ var _a;
301
+ const limit = pLimit(P_LIMIT);
302
+ for (const obj of untaggables) {
303
+ const tags = (_a = await obj.allTags(s3)) !== null && _a !== void 0 ? _a : [];
304
+ const updatedTags = tags.filter((tag) => tag.Key !== exports.S3_ISOLATED_TAG);
305
+ await limit(() => s3.deleteObjectTagging({
306
+ Bucket: bucket,
307
+ Key: obj.key,
308
+ }));
309
+ await limit(() => s3.putObjectTagging({
310
+ Bucket: bucket,
311
+ Key: obj.key,
312
+ Tagging: {
313
+ TagSet: updatedTags,
314
+ },
315
+ }));
316
+ }
317
+ (0, logging_1.debug)(`Untagged ${untaggables.length} assets`);
318
+ }
319
+ /**
320
+ * Tag images in parallel using p-limit
321
+ */
322
+ async parallelTagEcr(ecr, repo, taggables, printer) {
323
+ const limit = pLimit(P_LIMIT);
324
+ for (let i = 0; i < taggables.length; i++) {
325
+ const img = taggables[i];
326
+ const tagEcr = async () => {
327
+ try {
328
+ await ecr.putImage({
329
+ repositoryName: repo,
330
+ imageDigest: img.digest,
331
+ imageManifest: img.manifest,
332
+ imageTag: img.buildImageTag(i),
333
+ });
334
+ }
335
+ catch (error) {
336
+ // This is a false negative -- an isolated asset is untagged
337
+ // likely due to an imageTag collision. We can safely ignore,
338
+ // and the isolated asset will be tagged next time.
339
+ (0, logging_1.debug)(`Warning: unable to tag image ${JSON.stringify(img.tags)} with ${img.buildImageTag(i)} due to the following error: ${error}`);
340
+ }
341
+ };
342
+ await limit(() => tagEcr());
343
+ }
344
+ printer.reportTaggedAsset(taggables);
345
+ (0, logging_1.debug)(`Tagged ${taggables.length} assets`);
346
+ }
347
+ /**
348
+ * Tag objects in parallel using p-limit. The putObjectTagging API does not
349
+ * support batch tagging so we must handle the parallelism client-side.
350
+ */
351
+ async parallelTagS3(s3, bucket, taggables, date, printer) {
352
+ const limit = pLimit(P_LIMIT);
353
+ for (const obj of taggables) {
354
+ await limit(() => s3.putObjectTagging({
355
+ Bucket: bucket,
356
+ Key: obj.key,
357
+ Tagging: {
358
+ TagSet: [
359
+ {
360
+ Key: exports.S3_ISOLATED_TAG,
361
+ Value: String(date),
362
+ },
363
+ ],
364
+ },
365
+ }));
366
+ }
367
+ printer.reportTaggedAsset(taggables);
368
+ (0, logging_1.debug)(`Tagged ${taggables.length} assets`);
369
+ }
370
+ /**
371
+ * Delete images in parallel. The deleteImage API supports batches of 100.
372
+ */
373
+ async parallelDeleteEcr(ecr, repo, deletables, printer) {
374
+ const batchSize = 100;
375
+ const imagesToDelete = deletables.map(img => ({
376
+ imageDigest: img.digest,
377
+ }));
378
+ try {
379
+ const batches = [];
380
+ for (let i = 0; i < imagesToDelete.length; i += batchSize) {
381
+ batches.push(imagesToDelete.slice(i, i + batchSize));
382
+ }
383
+ // Delete images in batches
384
+ for (const batch of batches) {
385
+ await ecr.batchDeleteImage({
386
+ imageIds: batch,
387
+ repositoryName: repo,
388
+ });
389
+ const deletedCount = batch.length;
390
+ (0, logging_1.debug)(`Deleted ${deletedCount} assets`);
391
+ printer.reportDeletedAsset(deletables.slice(0, deletedCount));
392
+ }
393
+ }
394
+ catch (err) {
395
+ (0, logging_1.info)(chalk.red(`Error deleting images: ${err}`));
396
+ }
397
+ }
398
+ /**
399
+ * Delete objects in parallel. The deleteObjects API supports batches of 1000.
400
+ */
401
+ async parallelDeleteS3(s3, bucket, deletables, printer) {
402
+ const batchSize = 1000;
403
+ const objectsToDelete = deletables.map(asset => ({
404
+ Key: asset.key,
405
+ }));
406
+ try {
407
+ const batches = [];
408
+ for (let i = 0; i < objectsToDelete.length; i += batchSize) {
409
+ batches.push(objectsToDelete.slice(i, i + batchSize));
410
+ }
411
+ // Delete objects in batches
412
+ for (const batch of batches) {
413
+ await s3.deleteObjects({
414
+ Bucket: bucket,
415
+ Delete: {
416
+ Objects: batch,
417
+ Quiet: true,
418
+ },
419
+ });
420
+ const deletedCount = batch.length;
421
+ (0, logging_1.debug)(`Deleted ${deletedCount} assets`);
422
+ printer.reportDeletedAsset(deletables.slice(0, deletedCount));
423
+ }
424
+ }
425
+ catch (err) {
426
+ (0, logging_1.info)(chalk.red(`Error deleting objects: ${err}`));
427
+ }
428
+ }
429
+ async bootstrapBucketName(sdk, bootstrapStackName) {
430
+ const toolkitInfo = await toolkit_info_1.ToolkitInfo.lookup(this.props.resolvedEnvironment, sdk, bootstrapStackName);
431
+ return toolkitInfo.bucketName;
432
+ }
433
+ async bootstrapRepositoryName(sdk, bootstrapStackName) {
434
+ const toolkitInfo = await toolkit_info_1.ToolkitInfo.lookup(this.props.resolvedEnvironment, sdk, bootstrapStackName);
435
+ return toolkitInfo.repositoryName;
436
+ }
437
+ async bootstrapQualifier(sdk, bootstrapStackName) {
438
+ const toolkitInfo = await toolkit_info_1.ToolkitInfo.lookup(this.props.resolvedEnvironment, sdk, bootstrapStackName);
439
+ return toolkitInfo.bootstrapStack.parameters.Qualifier;
440
+ }
441
+ async numObjectsInBucket(s3, bucket) {
442
+ var _a;
443
+ let totalCount = 0;
444
+ let continuationToken;
445
+ do {
446
+ const response = await s3.listObjectsV2({
447
+ Bucket: bucket,
448
+ ContinuationToken: continuationToken,
449
+ });
450
+ totalCount += (_a = response.KeyCount) !== null && _a !== void 0 ? _a : 0;
451
+ continuationToken = response.NextContinuationToken;
452
+ } while (continuationToken);
453
+ return totalCount;
454
+ }
455
+ async numImagesInRepo(ecr, repo) {
456
+ var _a, _b;
457
+ let totalCount = 0;
458
+ let nextToken;
459
+ do {
460
+ const response = await ecr.listImages({
461
+ repositoryName: repo,
462
+ nextToken: nextToken,
463
+ });
464
+ totalCount += (_b = (_a = response.imageIds) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
465
+ nextToken = response.nextToken;
466
+ } while (nextToken);
467
+ return totalCount;
468
+ }
469
+ async *readRepoInBatches(ecr, repo, batchSize = 1000, currentTime) {
470
+ var _a, _b, _c, _d, _e, _f;
471
+ let continuationToken;
472
+ do {
473
+ const batch = [];
474
+ while (batch.length < batchSize) {
475
+ const response = await ecr.listImages({
476
+ repositoryName: repo,
477
+ nextToken: continuationToken,
478
+ });
479
+ // No images in the repository
480
+ if (!response.imageIds || response.imageIds.length === 0) {
481
+ break;
482
+ }
483
+ // map unique image digest to (possibly multiple) tags
484
+ const images = imageMap((_a = response.imageIds) !== null && _a !== void 0 ? _a : []);
485
+ const imageIds = Object.keys(images).map(key => ({
486
+ imageDigest: key,
487
+ }));
488
+ const describeImageInfo = await ecr.describeImages({
489
+ repositoryName: repo,
490
+ imageIds: imageIds,
491
+ });
492
+ const getImageInfo = await ecr.batchGetImage({
493
+ repositoryName: repo,
494
+ imageIds: imageIds,
495
+ });
496
+ const combinedImageInfo = (_b = describeImageInfo.imageDetails) === null || _b === void 0 ? void 0 : _b.map(imageDetail => {
497
+ var _a;
498
+ const matchingImage = (_a = getImageInfo.images) === null || _a === void 0 ? void 0 : _a.find(img => { var _a; return ((_a = img.imageId) === null || _a === void 0 ? void 0 : _a.imageDigest) === imageDetail.imageDigest; });
499
+ return {
500
+ ...imageDetail,
501
+ manifest: matchingImage === null || matchingImage === void 0 ? void 0 : matchingImage.imageManifest,
502
+ };
503
+ });
504
+ for (const image of combinedImageInfo !== null && combinedImageInfo !== void 0 ? combinedImageInfo : []) {
505
+ const lastModified = (_c = image.imagePushedAt) !== null && _c !== void 0 ? _c : new Date(currentTime);
506
+ // Store the image if it was pushed earlier than today - createdBufferDays
507
+ if (image.imageDigest && lastModified < new Date(currentTime - (this.props.createdBufferDays * DAY))) {
508
+ batch.push(new ImageAsset(image.imageDigest, (_d = image.imageSizeInBytes) !== null && _d !== void 0 ? _d : 0, (_e = image.imageTags) !== null && _e !== void 0 ? _e : [], (_f = image.manifest) !== null && _f !== void 0 ? _f : ''));
509
+ }
510
+ }
511
+ continuationToken = response.nextToken;
512
+ if (!continuationToken)
513
+ break; // No more images to fetch
514
+ }
515
+ if (batch.length > 0) {
516
+ yield batch;
517
+ }
518
+ } while (continuationToken);
519
+ }
520
+ /**
521
+ * Generator function that reads objects from the S3 Bucket in batches.
522
+ */
523
+ async *readBucketInBatches(s3, bucket, batchSize = 1000, currentTime) {
524
+ var _a;
525
+ let continuationToken;
526
+ do {
527
+ const batch = [];
528
+ while (batch.length < batchSize) {
529
+ const response = await s3.listObjectsV2({
530
+ Bucket: bucket,
531
+ ContinuationToken: continuationToken,
532
+ });
533
+ (_a = response.Contents) === null || _a === void 0 ? void 0 : _a.forEach((obj) => {
534
+ var _a, _b, _c;
535
+ const key = (_a = obj.Key) !== null && _a !== void 0 ? _a : '';
536
+ const size = (_b = obj.Size) !== null && _b !== void 0 ? _b : 0;
537
+ const lastModified = (_c = obj.LastModified) !== null && _c !== void 0 ? _c : new Date(currentTime);
538
+ // Store the object if it has a Key and
539
+ // if it has not been modified since today - createdBufferDays
540
+ if (key && lastModified < new Date(currentTime - (this.props.createdBufferDays * DAY))) {
541
+ batch.push(new ObjectAsset(bucket, key, size));
542
+ }
543
+ });
544
+ continuationToken = response.NextContinuationToken;
545
+ if (!continuationToken)
546
+ break; // No more objects to fetch
547
+ }
548
+ if (batch.length > 0) {
549
+ yield batch;
550
+ }
551
+ } while (continuationToken);
552
+ }
553
+ async confirmationPrompt(printer, deletables, type) {
554
+ const pluralize = (name, count) => {
555
+ return count === 1 ? name : `${name}s`;
556
+ };
557
+ if (this.confirm) {
558
+ const message = [
559
+ `Found ${deletables.length} ${pluralize(type, deletables.length)} to delete based off of the following criteria:`,
560
+ `- ${type}s have been isolated for > ${this.props.rollbackBufferDays} days`,
561
+ `- ${type}s were created > ${this.props.createdBufferDays} days ago`,
562
+ '',
563
+ 'Delete this batch (yes/no/delete-all)?',
564
+ ].join('\n');
565
+ printer.pause();
566
+ const response = await promptly.prompt(message, { trim: true });
567
+ // Anything other than yes/y/delete-all is treated as no
568
+ if (!response || !['yes', 'y', 'delete-all'].includes(response.toLowerCase())) {
569
+ throw new error_1.ToolkitError('Deletion aborted by user');
570
+ }
571
+ else if (response.toLowerCase() == 'delete-all') {
572
+ this.confirm = false;
573
+ }
574
+ }
575
+ printer.resume();
576
+ }
577
+ }
578
+ exports.GarbageCollector = GarbageCollector;
579
+ function partition(xs, pred) {
580
+ const result = {
581
+ included: [],
582
+ excluded: [],
583
+ };
584
+ for (const x of xs) {
585
+ if (pred(x)) {
586
+ result.included.push(x);
587
+ }
588
+ else {
589
+ result.excluded.push(x);
590
+ }
591
+ }
592
+ return result;
593
+ }
594
+ function imageMap(imageIds) {
595
+ const images = {};
596
+ for (const image of imageIds !== null && imageIds !== void 0 ? imageIds : []) {
597
+ if (!image.imageDigest || !image.imageTag) {
598
+ continue;
599
+ }
600
+ if (!images[image.imageDigest]) {
601
+ images[image.imageDigest] = [];
602
+ }
603
+ images[image.imageDigest].push(image.imageTag);
604
+ }
605
+ return images;
606
+ }
607
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FyYmFnZS1jb2xsZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJnYXJiYWdlLWNvbGxlY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFHQSwrQkFBK0I7QUFDL0IscUNBQXFDO0FBQ3JDLDJDQUE0QztBQUU1QyxrREFBMEU7QUFDMUUseURBQXFEO0FBQ3JELG1EQUEwRjtBQUMxRiwrQ0FBbUQ7QUFDbkQseUNBQXNDO0FBRXRDLG1EQUFtRDtBQUNuRCxpRUFBaUU7QUFDakUsTUFBTSxNQUFNLEdBQTZCLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUUvQyxRQUFBLGVBQWUsR0FBRyxrQkFBa0IsQ0FBQztBQUNyQyxRQUFBLGdCQUFnQixHQUFHLGtCQUFrQixDQUFDLENBQUMsK0JBQStCO0FBQ25GLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUNuQixNQUFNLEdBQUcsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxrQ0FBa0M7QUFJbkU7O0dBRUc7QUFDSCxNQUFhLFVBQVU7SUFDckIsWUFDa0IsTUFBYyxFQUNkLElBQVksRUFDWixJQUFjLEVBQ2QsUUFBZ0I7UUFIaEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixTQUFJLEdBQUosSUFBSSxDQUFVO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBUTtJQUMvQixDQUFDO0lBRUksTUFBTSxDQUFDLEdBQVc7UUFDeEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRU8sTUFBTSxDQUFDLEdBQVc7UUFDeEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMs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b3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjeGFwaSBmcm9tICdAYXdzLWNkay9jeC1hcGknO1xuaW1wb3J0IHsgSW1hZ2VJZGVudGlmaWVyIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVjcic7XG5pbXBvcnQgeyBUYWcgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtczMnO1xuaW1wb3J0ICogYXMgY2hhbGsgZnJvbSAnY2hhbGsnO1xuaW1wb3J0ICogYXMgcHJvbXB0bHkgZnJvbSAncHJvbXB0bHknO1xuaW1wb3J0IHsgZGVidWcsIGluZm8gfSBmcm9tICcuLi8uLi9sb2dnaW5nJztcbmltcG9ydCB7IElFQ1JDbGllbnQsIElTM0NsaWVudCwgU0RLLCBTZGtQcm92aWRlciB9IGZyb20gJy4uL2F3cy1hdXRoJztcbmltcG9ydCB7IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FLCBUb29sa2l0SW5mbyB9IGZyb20gJy4uL3Rvb2xraXQtaW5mbyc7XG5pbXBvcnQgeyBQcm9ncmVzc1ByaW50ZXIgfSBmcm9tICcuL3Byb2dyZXNzLXByaW50ZXInO1xuaW1wb3J0IHsgQWN0aXZlQXNzZXRDYWNoZSwgQmFja2dyb3VuZFN0YWNrUmVmcmVzaCwgcmVmcmVzaFN0YWNrcyB9IGZyb20gJy4vc3RhY2stcmVmcmVzaCc7XG5pbXBvcnQgeyBUb29sa2l0RXJyb3IgfSBmcm9tICcuLi8uLi90b29sa2l0L2Vycm9yJztcbmltcG9ydCB7IE1vZGUgfSBmcm9tICcuLi9wbHVnaW4vbW9kZSc7XG5cbi8vIE11c3QgdXNlIGEgcmVxdWlyZSgpIG90aGVyd2lzZSBlc2J1aWxkIGNvbXBsYWluc1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbmNvbnN0IHBMaW1pdDogdHlwZW9mIGltcG9ydCgncC1saW1pdCcpID0gcmVxdWlyZSgncC1saW1pdCcpO1xuXG5leHBvcnQgY29uc3QgUzNfSVNPTEFURURfVEFHID0gJ2F3cy1jZGs6aXNvbGF0ZWQnO1xuZXhwb3J0IGNvbnN0IEVDUl9JU09MQVRFRF9UQUcgPSAnYXdzLWNkay5pc29sYXRlZCc7IC8vICc6JyBpcyBub3QgdmFsaWQgaW4gRUNSIHRhZ3NcbmNvbnN0IFBfTElNSVQgPSA1MDtcbmNvbnN0IERBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7IC8vIE51bWJlciBvZiBtaWxsaXNlY29uZHMgaW4gYSBkYXlcblxuZXhwb3J0IHR5cGUgR2NBc3NldCA9IEltYWdlQXNzZXQgfCBPYmplY3RBc3NldDtcblxuLyoqXG4gKiBBbiBpbWFnZSBhc3NldCB0aGF0IGxpdmVzIGluIHRoZSBib290c3RyYXBwZWQgRUNSIFJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNsYXNzIEltYWdlQXNzZXQge1xuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGRpZ2VzdDogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzaXplOiBudW1iZXIsXG4gICAgcHVibGljIHJlYWRvbmx5IHRhZ3M6IHN0cmluZ1tdLFxuICAgIHB1YmxpYyByZWFkb25seSBtYW5pZmVzdDogc3RyaW5nLFxuICApIHt9XG5cbiAgcHJpdmF0ZSBnZXRUYWcodGFnOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50YWdzLmZpbmQodCA9PiB0LmluY2x1ZGVzKHRhZykpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNUYWcodGFnOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy50YWdzLnNvbWUodCA9PiB0LmluY2x1ZGVzKHRhZykpO1xuICB9XG5cbiAgcHVibGljIGhhc0lzb2xhdGVkVGFnKCkge1xuICAgIHJldHVybiB0aGlzLmhhc1RhZyhFQ1JfSVNPTEFURURfVEFHKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRJc29sYXRlZFRhZygpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRUYWcoRUNSX0lTT0xBVEVEX1RBRyk7XG4gIH1cblxuICBwdWJsaWMgaXNvbGF0ZWRUYWdCZWZvcmUoZGF0ZTogRGF0ZSkge1xuICAgIGNvbnN0IGRhdGVJc29sYXRlZCA9IHRoaXMuZGF0ZUlzb2xhdGVkKCk7XG4gICAgaWYgKCFkYXRlSXNvbGF0ZWQgfHwgZGF0ZUlzb2xhdGVkID09ICcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlSXNvbGF0ZWQpIDwgZGF0ZTtcbiAgfVxuXG4gIHB1YmxpYyBidWlsZEltYWdlVGFnKGluYzogbnVtYmVyKSB7XG4gICAgLy8gaXNvbGF0ZWRUYWcgd2lsbCBsb29rIGxpa2UgXCJYLWF3cy1jZGsuaXNvbGF0ZWQtWVlZWVlcIlxuICAgIHJldHVybiBgJHtpbmN9LSR7RUNSX0lTT0xBVEVEX1RBR30tJHtTdHJpbmcoRGF0ZS5ub3coKSl9YDtcbiAgfVxuXG4gIHB1YmxpYyBkYXRlSXNvbGF0ZWQoKSB7XG4gICAgLy8gaXNvbGF0ZWRUYWcgd2lsbCBsb29rIGxpa2UgXCJYLWF3cy1jZGsuaXNvbGF0ZWQtWVlZWVlcIlxuICAgIHJldHVybiB0aGlzLmdldElzb2xhdGVkVGFnKCk/LnNwbGl0KCctJylbM107XG4gIH1cbn1cblxuLyoqXG4gKiBBbiBvYmplY3QgYXNzZXQgdGhhdCBsaXZlcyBpbiB0aGUgYm9vdHN0cmFwcGVkIFMzIEJ1Y2tldFxuICovXG5leHBvcnQgY2xhc3MgT2JqZWN0QXNzZXQge1xuICBwcml2YXRlIGNhY2hlZF90YWdzOiBUYWdbXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBidWNrZXQ6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGtleTogc3RyaW5nLCBwdWJsaWMgcmVhZG9ubHkgc2l6ZTogbnVtYmVyKSB7fVxuXG4gIHB1YmxpYyBmaWxlTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmtleS5zcGxpdCgnLicpWzBdO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFsbFRhZ3MoczM6IElTM0NsaWVudCkge1xuICAgIGlmICh0aGlzLmNhY2hlZF90YWdzKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZWRfdGFncztcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHMzLmdldE9iamVjdFRhZ2dpbmcoeyBCdWNrZXQ6IHRoaXMuYnVja2V0LCBLZXk6IHRoaXMua2V5IH0pO1xuICAgIHRoaXMuY2FjaGVkX3RhZ3MgPSByZXNwb25zZS5UYWdTZXQ7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGVkX3RhZ3M7XG4gIH1cblxuICBwcml2YXRlIGdldFRhZyh0YWc6IHN0cmluZykge1xuICAgIGlmICghdGhpcy5jYWNoZWRfdGFncykge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcignQ2Fubm90IGNhbGwgZ2V0VGFnIGJlZm9yZSBhbGxUYWdzJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhY2hlZF90YWdzLmZpbmQoKHQ6IGFueSkgPT4gdC5LZXkgPT09IHRhZyk/LlZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNUYWcodGFnOiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuY2FjaGVkX3RhZ3MpIHtcbiAgICAgIHRocm93IG5ldyBUb29sa2l0RXJyb3IoJ0Nhbm5vdCBjYWxsIGhhc1RhZyBiZWZvcmUgYWxsVGFncycpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZWRfdGFncy5zb21lKCh0OiBhbnkpID0+IHQuS2V5ID09PSB0YWcpO1xuICB9XG5cbiAgcHVibGljIGhhc0lzb2xhdGVkVGFnKCkge1xuICAgIHJldHVybiB0aGlzLmhhc1RhZyhTM19JU09MQVRFRF9UQUcpO1xuICB9XG5cbiAgcHVibGljIGlzb2xhdGVkVGFnQmVmb3JlKGRhdGU6IERhdGUpIHtcbiAgICBjb25zdCB0YWdWYWx1ZSA9IHRoaXMuZ2V0VGFnKFMzX0lTT0xBVEVEX1RBRyk7XG4gICAgaWYgKCF0YWdWYWx1ZSB8fCB0YWdWYWx1ZSA9PSAnJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUodGFnVmFsdWUpIDwgZGF0ZTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BzIGZvciB0aGUgR2FyYmFnZSBDb2xsZWN0b3JcbiAqL1xuaW50ZXJmYWNlIEdhcmJhZ2VDb2xsZWN0b3JQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgYWN0aW9uIHRvIHBlcmZvcm0uIFNwZWNpZnkgdGhpcyBpZiB5b3Ugd2FudCB0byBwZXJmb3JtIGEgdHJ1bmNhdGVkIHNldFxuICAgKiBvZiBhY3Rpb25zIGF2YWlsYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IGFjdGlvbjogJ3ByaW50JyB8ICd0YWcnIHwgJ2RlbGV0ZS10YWdnZWQnIHwgJ2Z1bGwnO1xuXG4gIC8qKlxuICAgKiBUaGUgdHlwZSBvZiBhc3NldCB0byBnYXJiYWdlIGNvbGxlY3QuXG4gICAqL1xuICByZWFkb25seSB0eXBlOiAnczMnIHwgJ2VjcicgfCAnYWxsJztcblxuICAvKipcbiAgICogVGhlIGRheXMgYW4gYXNzZXQgbXVzdCBiZSBpbiBpc29sYXRpb24gYmVmb3JlIGJlaW5nIGFjdHVhbGx5IGRlbGV0ZWQuXG4gICAqL1xuICByZWFkb25seSByb2xsYmFja0J1ZmZlckRheXM6IG51bWJlcjtcblxuICAvKipcbiAgICogUmVmdXNlIGRlbGV0aW9uIG9mIGFueSBhc3NldHMgeW91bmdlciB0aGFuIHRoaXMgbnVtYmVyIG9mIGRheXMuXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVkQnVmZmVyRGF5czogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZW52aXJvbm1lbnQgdG8gZGVwbG95IHRoaXMgc3RhY2sgaW5cbiAgICpcbiAgICogVGhlIGVudmlyb25tZW50IG9uIHRoZSBzdGFjayBhcnRpZmFjdCBtYXkgYmUgdW5yZXNvbHZlZCwgdGhpcyBvbmVcbiAgICogbXVzdCBiZSByZXNvbHZlZC5cbiAgICovXG4gIHJlYWRvbmx5IHJlc29sdmVkRW52aXJvbm1lbnQ6IGN4YXBpLkVudmlyb25tZW50O1xuXG4gIC8qKlxuICAgKiBTREsgcHJvdmlkZXIgKHNlZWRlZCB3aXRoIGRlZmF1bHQgY3JlZGVudGlhbHMpXG4gICAqXG4gICAqIFdpbGwgYmUgdXNlZCB0byBtYWtlIFNESyBjYWxscyB0byBDbG91ZEZvcm1hdGlvbiwgUzMsIGFuZCBFQ1IuXG4gICAqL1xuICByZWFkb25seSBzZGtQcm92aWRlcjogU2RrUHJvdmlkZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBib290c3RyYXAgc3RhY2sgdG8gbG9vayBmb3IuXG4gICAqXG4gICAqIEBkZWZhdWx0IERFRkFVTFRfVE9PTEtJVF9TVEFDS19OQU1FXG4gICAqL1xuICByZWFkb25seSBib290c3RyYXBTdGFja05hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENvbmZpcm0gd2l0aCB0aGUgdXNlciBiZWZvcmUgYWN0dWFsIGRlbGV0aW9uIGhhcHBlbnNcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgY29uZmlybT86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBjbGFzcyB0byBmYWNpbGl0YXRlIEdhcmJhZ2UgQ29sbGVjdGlvbiBvZiBTMyBhbmQgRUNSIGFzc2V0c1xuICovXG5leHBvcnQgY2xhc3MgR2FyYmFnZUNvbGxlY3RvciB7XG4gIHByaXZhdGUgZ2FyYmFnZUNvbGxlY3RTM0Fzc2V0czogYm9vbGVhbjtcbiAgcHJpdmF0ZSBnYXJiYWdlQ29sbGVjdEVjckFzc2V0czogYm9vbGVhbjtcbiAgcHJpdmF0ZSBwZXJtaXNzaW9uVG9EZWxldGU6IGJvb2xlYW47XG4gIHByaXZhdGUgcGVybWlzc2lvblRvVGFnOiBib29sZWFuO1xuICBwcml2YXRlIGJvb3RzdHJhcFN0YWNrTmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGNvbmZpcm06IGJvb2xlYW47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHByb3BzOiBHYXJiYWdlQ29sbGVjdG9yUHJvcHMpIHtcbiAgICB0aGlzLmdhcmJhZ2VDb2xsZWN0UzNBc3NldHMgPSBbJ3MzJywgJ2FsbCddLmluY2x1ZGVzKHByb3BzLnR5cGUpO1xuICAgIHRoaXMuZ2FyYmFnZUNvbGxlY3RFY3JBc3NldHMgPSBbJ2VjcicsICdhbGwnXS5pbmNsdWRlcyhwcm9wcy50eXBlKTtcblxuICAgIGRlYnVnKGAke3RoaXMuZ2FyYmFnZUNvbGxlY3RTM0Fzc2V0c30gJHt0aGlzLmdhcmJhZ2VDb2xsZWN0RWNyQXNzZXRzfWApO1xuXG4gICAgdGhpcy5wZXJtaXNzaW9uVG9EZWxldGUgPSBbJ2RlbGV0ZS10YWdnZWQnLCAnZnVsbCddLmluY2x1ZGVzKHByb3BzLmFjdGlvbik7XG4gICAgdGhpcy5wZXJtaXNzaW9uVG9UYWcgPSBbJ3RhZycsICdmdWxsJ10uaW5jbHVkZXMocHJvcHMuYWN0aW9uKTtcbiAgICB0aGlzLmNvbmZpcm0gPSBwcm9wcy5jb25maXJtID8/IHRydWU7XG5cbiAgICB0aGlzLmJvb3RzdHJhcFN0YWNrTmFtZSA9IHByb3BzLmJvb3RzdHJhcFN0YWNrTmFtZSA/PyBERUZBVUxUX1RPT0xLSVRfU1RBQ0tfTkFNRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIGdhcmJhZ2UgY29sbGVjdGlvbiBvbiB0aGUgcmVzb2x2ZWQgZW52aXJvbm1lbnQuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2FyYmFnZUNvbGxlY3QoKSB7XG4gICAgLy8gU0RLc1xuICAgIGNvbnN0IHNkayA9IChhd2FpdCB0aGlzLnByb3BzLnNka1Byb3ZpZGVyLmZvckVudmlyb25tZW50KHRoaXMucHJvcHMucmVzb2x2ZWRFbnZpcm9ubWVudCwgTW9kZS5Gb3JXcml0aW5nKSkuc2RrO1xuICAgIGNvbnN0IGNmbiA9IHNkay5jbG91ZEZvcm1hdGlvbigpO1xuXG4gICAgY29uc3QgcXVhbGlmaWVyID0gYXdhaXQgdGhpcy5ib290c3RyYXBRdWFsaWZpZXIoc2RrLCB0aGlzLmJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgY29uc3QgYWN0aXZlQXNzZXRzID0gbmV3IEFjdGl2ZUFzc2V0Q2FjaGUoKTtcblxuICAgIC8vIEdyYWIgc3RhY2sgdGVtcGxhdGVzIGZpcnN0XG4gICAgYXdhaXQgcmVmcmVzaFN0YWNrcyhjZm4sIGFjdGl2ZUFzc2V0cywgcXVhbGlmaWVyKTtcbiAgICAvLyBTdGFydCB0aGUgYmFja2dyb3VuZCByZWZyZXNoXG4gICAgY29uc3QgYmFja2dyb3VuZFN0YWNrUmVmcmVzaCA9IG5ldyBCYWNrZ3JvdW5kU3RhY2tSZWZyZXNoKHtcbiAgICAgIGNmbixcbiAgICAgIGFjdGl2ZUFzc2V0cyxcbiAgICAgIHF1YWxpZmllcixcbiAgICB9KTtcbiAgICBiYWNrZ3JvdW5kU3RhY2tSZWZyZXNoLnN0YXJ0KCk7XG5cbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZ2FyYmFnZUNvbGxlY3RTM0Fzc2V0cykge1xuICAgICAgICBhd2FpdCB0aGlzLmdhcmJhZ2VDb2xsZWN0UzMoc2RrLCBhY3RpdmVBc3NldHMsIGJhY2tncm91bmRTdGFja1JlZnJlc2gpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5nYXJiYWdlQ29sbGVjdEVjckFzc2V0cykge1xuICAgICAgICBhd2FpdCB0aGlzLmdhcmJhZ2VDb2xsZWN0RWNyKHNkaywgYWN0aXZlQXNzZXRzLCBiYWNrZ3JvdW5kU3RhY2tSZWZyZXNoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihlcnIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBiYWNrZ3JvdW5kU3RhY2tSZWZyZXNoLnN0b3AoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSBnYXJiYWdlIGNvbGxlY3Rpb24gb24gRUNSIGFzc2V0c1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGdhcmJhZ2VDb2xsZWN0RWNyKHNkazogU0RLLCBhY3RpdmVBc3NldHM6IEFjdGl2ZUFzc2V0Q2FjaGUsIGJhY2tncm91bmRTdGFja1JlZnJlc2g6IEJhY2tncm91bmRTdGFja1JlZnJlc2gpIHtcbiAgICBjb25zdCBlY3IgPSBzZGsuZWNyKCk7XG4gICAgY29uc3QgcmVwbyA9IGF3YWl0IHRoaXMuYm9vdHN0cmFwUmVwb3NpdG9yeU5hbWUoc2RrLCB0aGlzLmJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgY29uc3QgbnVtSW1hZ2VzID0gYXdhaXQgdGhpcy5udW1JbWFnZXNJblJlcG8oZWNyLCByZXBvKTtcbiAgICBjb25zdCBwcmludGVyID0gbmV3IFByb2dyZXNzUHJpbnRlcihudW1JbWFnZXMsIDEwMDApO1xuXG4gICAgZGVidWcoYEZvdW5kIGJvb3RzdHJhcCByZXBvICR7cmVwb30gd2l0aCAke251bUltYWdlc30gaW1hZ2VzYCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gY29uc3QgYmF0Y2hlcyA9IDE7XG4gICAgICBjb25zdCBiYXRjaFNpemUgPSAxMDAwO1xuICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgZ3JhY2VEYXlzID0gdGhpcy5wcm9wcy5yb2xsYmFja0J1ZmZlckRheXM7XG5cbiAgICAgIGRlYnVnKGBQYXJzaW5nIHRocm91Z2ggJHtudW1JbWFnZXN9IGltYWdlcyBpbiBiYXRjaGVzYCk7XG5cbiAgICAgIHByaW50ZXIuc3RhcnQoKTtcblxuICAgICAgZm9yIGF3YWl0IChjb25zdCBiYXRjaCBvZiB0aGlzLnJlYWRSZXBvSW5CYXRjaGVzKGVjciwgcmVwbywgYmF0Y2hTaXplLCBjdXJyZW50VGltZSkpIHtcbiAgICAgICAgYXdhaXQgYmFja2dyb3VuZFN0YWNrUmVmcmVzaC5ub09sZGVyVGhhbig2MDBfMDAwKTsgLy8gMTAgbWluc1xuXG4gICAgICAgIGNvbnN0IHsgaW5jbHVkZWQ6IGlzb2xhdGVkLCBleGNsdWRlZDogbm90SXNvbGF0ZWQgfSA9IHBhcnRpdGlvbihiYXRjaCwgYXNzZXQgPT4gIWFzc2V0LnRhZ3Muc29tZSh0ID0+IGFjdGl2ZUFzc2V0cy5jb250YWlucyh0KSkpO1xuXG4gICAgICAgIGRlYnVnKGAke2lzb2xhdGVkLmxlbmd0aH0gaXNvbGF0ZWQgaW1hZ2VzYCk7XG4gICAgICAgIGRlYnVnKGAke25vdElzb2xhdGVkLmxlbmd0aH0gbm90IGlzb2xhdGVkIGltYWdlc2ApO1xuICAgICAgICBkZWJ1ZyhgJHtiYXRjaC5sZW5ndGh9IGltYWdlcyB0b3RhbGApO1xuXG4gICAgICAgIGxldCBkZWxldGFibGVzOiBJbWFnZUFzc2V0W10gPSBpc29sYXRlZDtcbiAgICAgICAgbGV0IHRhZ2dhYmxlczogSW1hZ2VBc3NldFtdID0gW107XG4gICAgICAgIGxldCB1bnRhZ2dhYmxlczogSW1hZ2VBc3NldFtdID0gW107XG5cbiAgICAgICAgaWYgKGdyYWNlRGF5cyA+IDApIHtcbiAgICAgICAgICBkZWJ1ZygnRmlsdGVyaW5nIG91dCBpbWFnZXMgdGhhdCBhcmUgbm90IG9sZCBlbm91Z2ggdG8gZGVsZXRlJyk7XG5cbiAgICAgICAgICAvLyBXZSBkZWxldGUgaW1hZ2VzIHRoYXQgYXJlIG5vdCByZWZlcmVuY2VkIGluIEFjdGl2ZUFzc2V0cyBhbmQgaGF2ZSB0aGUgSXNvbGF0ZWQgVGFnIHdpdGggYSBkYXRlXG4gICAgICAgICAgLy8gZWFybGllciB0aGFuIHRoZSBjdXJyZW50IHRpbWUgLSBncmFjZSBwZXJpb2QuXG4gICAgICAgICAgZGVsZXRhYmxlcyA9IGlzb2xhdGVkLmZpbHRlcihpbWcgPT4gaW1nLmlzb2xhdGVkVGFnQmVmb3JlKG5ldyBEYXRlKGN1cnJlbnRUaW1lIC0gKGdyYWNlRGF5cyAqIERBWSkpKSk7XG5cbiAgICAgICAgICAvLyBXZSB0YWcgaW1hZ2VzIHRoYXQgYXJlIG5vdCByZWZlcmVuY2VkIGluIEFjdGl2ZUFzc2V0cyBhbmQgZG8gbm90IGhhdmUgdGhlIElzb2xhdGVkIFRhZy5cbiAgICAgICAgICB0YWdnYWJsZXMgPSBpc29sYXRlZC5maWx0ZXIoaW1nID0+ICFpbWcuaGFzSXNvbGF0ZWRUYWcoKSk7XG5cbiAgICAgICAgICAvLyBXZSB1bnRhZyBpbWFnZXMgdGhhdCBhcmUgcmVmZXJlbmNlZCBpbiBBY3RpdmVBc3NldHMgYW5kIGN1cnJlbnRseSBoYXZlIHRoZSBJc29sYXRlZCBUYWcuXG4gICAgICAgICAgdW50YWdnYWJsZXMgPSBub3RJc29sYXRlZC5maWx0ZXIoaW1nID0+IGltZy5oYXNJc29sYXRlZFRhZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlYnVnKGAke2RlbGV0YWJsZXMubGVuZ3RofSBkZWxldGFibGUgYXNzZXRzYCk7XG4gICAgICAgIGRlYnVnKGAke3RhZ2dhYmxlcy5sZW5ndGh9IHRhZ2dhYmxlIGFzc2V0c2ApO1xuICAgICAgICBkZWJ1ZyhgJHt1bnRhZ2dhYmxlcy5sZW5ndGh9IGFzc2V0cyB0byB1bnRhZ2ApO1xuXG4gICAgICAgIGlmICh0aGlzLnBlcm1pc3Npb25Ub0RlbGV0ZSAmJiBkZWxldGFibGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbmZpcm1hdGlvblByb21wdChwcmludGVyLCBkZWxldGFibGVzLCAnaW1hZ2UnKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLnBhcmFsbGVsRGVsZXRlRWNyKGVjciwgcmVwbywgZGVsZXRhYmxlcywgcHJpbnRlcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wZXJtaXNzaW9uVG9UYWcgJiYgdGFnZ2FibGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnBhcmFsbGVsVGFnRWNyKGVjciwgcmVwbywgdGFnZ2FibGVzLCBwcmludGVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnBlcm1pc3Npb25Ub1RhZyAmJiB1bnRhZ2dhYmxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5wYXJhbGxlbFVudGFnRWNyKGVjciwgcmVwbywgdW50YWdnYWJsZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJpbnRlci5yZXBvcnRTY2FubmVkQXNzZXQoYmF0Y2gubGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFRvb2xraXRFcnJvcihlcnIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBwcmludGVyLnN0b3AoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSBnYXJiYWdlIGNvbGxlY3Rpb24gb24gUzMgYXNzZXRzXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2FyYmFnZUNvbGxlY3RTMyhzZGs6IFNESywgYWN0aXZlQXNzZXRzOiBBY3RpdmVBc3NldENhY2hlLCBiYWNrZ3JvdW5kU3RhY2tSZWZyZXNoOiBCYWNrZ3JvdW5kU3RhY2tSZWZyZXNoKSB7XG4gICAgY29uc3QgczMgPSBzZGsuczMoKTtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLmJvb3RzdHJhcEJ1Y2tldE5hbWUoc2RrLCB0aGlzLmJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgY29uc3QgbnVtT2JqZWN0cyA9IGF3YWl0IHRoaXMubnVtT2JqZWN0c0luQnVja2V0KHMzLCBidWNrZXQpO1xuICAgIGNvbnN0IHByaW50ZXIgPSBuZXcgUHJvZ3Jlc3NQcmludGVyKG51bU9iamVjdHMsIDEwMDApO1xuXG4gICAgZGVidWcoYEZvdW5kIGJvb3RzdHJhcCBidWNrZXQgJHtidWNrZXR9IHdpdGggJHtudW1PYmplY3RzfSBvYmplY3RzYCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYmF0Y2hTaXplID0gMTAwMDtcbiAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IGdyYWNlRGF5cyA9IHRoaXMucHJvcHMucm9sbGJhY2tCdWZmZXJEYXlzO1xuXG4gICAgICBkZWJ1ZyhgUGFyc2luZyB0aHJvdWdoICR7bnVtT2JqZWN0c30gb2JqZWN0cyBpbiBiYXRjaGVzYCk7XG5cbiAgICAgIHByaW50ZXIuc3RhcnQoKTtcblxuICAgICAgLy8gUHJvY2VzcyBvYmplY3RzIGluIGJhdGNoZXMgb2YgMTAwMFxuICAgICAgLy8gVGhpcyBpcyB0aGUgYmF0Y2ggbGltaXQgb2YgczMuRGVsZXRlT2JqZWN0IGFuZCB3ZSBpbnRlbmQgdG8gb3B0aW1pemUgZm9yIHRoZSBcIndvcnN0IGNhc2VcIiBzY2VuYXJpb1xuICAgICAgLy8gd2hlcmUgZ2MgaXMgcnVuIGZvciB0aGUgZmlyc3QgdGltZSBvbiBhIGxvbmctc3RhbmRpbmcgYnVja2V0IHdoZXJlIH4xMDAlIG9mIG9iamVjdHMgYXJlIGlzb2xhdGVkLlxuICAgICAgZm9yIGF3YWl0IChjb25zdCBiYXRjaCBvZiB0aGlzLnJlYWRCdWNrZXRJbkJhdGNoZXMoczMsIGJ1Y2tldCwgYmF0Y2hTaXplLCBjdXJyZW50VGltZSkpIHtcbiAgICAgICAgYXdhaXQgYmFja2dyb3VuZFN0YWNrUmVmcmVzaC5ub09sZGVyVGhhbig2MDBfMDAwKTsgLy8gMTAgbWluc1xuXG4gICAgICAgIGNvbnN0IHsgaW5jbHVkZWQ6IGlzb2xhdGVkLCBleGNsdWRlZDogbm90SXNvbGF0ZWQgfSA9IHBhcnRpdGlvbihiYXRjaCwgYXNzZXQgPT4gIWFjdGl2ZUFzc2V0cy5jb250YWlucyhhc3NldC5maWxlTmFtZSgpKSk7XG5cbiAgICAgICAgZGVidWcoYCR7aXNvbGF0ZWQubGVuZ3RofSBpc29sYXRlZCBhc3NldHNgKTtcbiAgICAgICAgZGVidWcoYCR7bm90SXNvbGF0ZWQubGVuZ3RofSBub3QgaXNvbGF0ZWQgYXNzZXRzYCk7XG4gICAgICAgIGRlYnVnKGAke2JhdGNoLmxlbmd0aH0gb2JqZWN0cyB0b3RhbGApO1xuXG4gICAgICAgIGxldCBkZWxldGFibGVzOiBPYmplY3RBc3NldFtdID0gaXNvbGF0ZWQ7XG4gICAgICAgIGxldCB0YWdnYWJsZXM6IE9iamVjdEFzc2V0W10gPSBbXTtcbiAgICAgICAgbGV0IHVudGFnZ2FibGVzOiBPYmplY3RBc3NldFtdID0gW107XG5cbiAgICAgICAgaWYgKGdyYWNlRGF5cyA+IDApIHtcbiAgICAgICAgICBkZWJ1ZygnRmlsdGVyaW5nIG91dCBhc3NldHMgdGhhdCBhcmUgbm90IG9sZCBlbm91Z2ggdG8gZGVsZXRlJyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5wYXJhbGxlbFJlYWRBbGxUYWdzKHMzLCBiYXRjaCk7XG5cbiAgICAgICAgICAvLyBXZSBkZWxldGUgb2JqZWN0cyB0aGF0IGFyZSBub3QgcmVmZXJlbmNlZCBpbiBBY3RpdmVBc3NldHMgYW5kIGhhdmUgdGhlIElzb2xhdGVkIFRhZyB3aXRoIGEgZGF0ZVxuICAgICAgICAgIC8vIGVhcmxpZXIgdGhhbiB0aGUgY3VycmVudCB0aW1lIC0gZ3JhY2UgcGVyaW9kLlxuICAgICAgICAgIGRlbGV0YWJsZXMgPSBpc29sYXRlZC5maWx0ZXIob2JqID0+IG9iai5pc29sYXRlZFRhZ0JlZm9yZShuZXcgRGF0ZShjdXJyZW50VGltZSAtIChncmFjZURheXMgKiBEQVkpKSkpO1xuXG4gICAgICAgICAgLy8gV2UgdGFnIG9iamVjdHMgdGhhdCBhcmUgbm90IHJlZmVyZW5jZWQgaW4gQWN0aXZlQXNzZXRzIGFuZCBkbyBub3QgaGF2ZSB0aGUgSXNvbGF0ZWQgVGFnLlxuICAgICAgICAgIHRhZ2dhYmxlcyA9IGlzb2xhdGVkLmZpbHRlcihvYmogPT4gIW9iai5oYXNJc29sYXRlZFRhZygpKTtcblxuICAgICAgICAgIC8vIFdlIHVudGFnIG9iamVjdHMgdGhhdCBhcmUgcmVmZXJlbmNlZCBpbiBBY3RpdmVBc3NldHMgYW5kIGN1cnJlbnRseSBoYXZlIHRoZSBJc29sYXRlZCBUYWcuXG4gICAgICAgICAgdW50YWdnYWJsZXMgPSBub3RJc29sYXRlZC5maWx0ZXIob2JqID0+IG9iai5oYXNJc29sYXRlZFRhZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlYnVnKGAke2RlbGV0YWJsZXMubGVuZ3RofSBkZWxldGFibGUgYXNzZXRzYCk7XG4gICAgICAgIGRlYnVnKGAke3RhZ2dhYmxlcy5sZW5ndGh9IHRhZ2dhYmxlIGFzc2V0c2ApO1xuICAgICAgICBkZWJ1ZyhgJHt1bnRhZ2dhYmxlcy5sZW5ndGh9IGFzc2V0cyB0byB1bnRhZ2ApO1xuXG4gICAgICAgIGlmICh0aGlzLnBlcm1pc3Npb25Ub0RlbGV0ZSAmJiBkZWxldGFibGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbmZpcm1hdGlvblByb21wdChwcmludGVyLCBkZWxldGFibGVzLCAnb2JqZWN0Jyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5wYXJhbGxlbERlbGV0ZVMzKHMzLCBidWNrZXQsIGRlbGV0YWJsZXMsIHByaW50ZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucGVybWlzc2lvblRvVGFnICYmIHRhZ2dhYmxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5wYXJhbGxlbFRhZ1MzKHMzLCBidWNrZXQsIHRhZ2dhYmxlcywgY3VycmVudFRpbWUsIHByaW50ZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucGVybWlzc2lvblRvVGFnICYmIHVudGFnZ2FibGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnBhcmFsbGVsVW50YWdTMyhzMywgYnVja2V0LCB1bnRhZ2dhYmxlcyk7XG4gICAgICAgIH1cblxuICAgICAgICBwcmludGVyLnJlcG9ydFNjYW5uZWRBc3NldChiYXRjaC5sZW5ndGgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKGVycik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHByaW50ZXIuc3RvcCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGFyYWxsZWxSZWFkQWxsVGFncyhzMzogSVMzQ2xpZW50LCBvYmplY3RzOiBPYmplY3RBc3NldFtdKSB7XG4gICAgY29uc3QgbGltaXQgPSBwTGltaXQoUF9MSU1JVCk7XG5cbiAgICBmb3IgKGNvbnN0IG9iaiBvZiBvYmplY3RzKSB7XG4gICAgICBhd2FpdCBsaW1pdCgoKSA9PiBvYmouYWxsVGFncyhzMykpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnRhZyBhc3NldHMgdGhhdCB3ZXJlIHByZXZpb3VzbHkgdGFnZ2VkLCBidXQgbm93IGN1cnJlbnRseSByZWZlcmVuY2VkLlxuICAgKiBTaW5jZSB0aGlzIGlzIHRyZWF0ZWQgYXMgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCB3ZSBkbyBub3QgcHJpbnQgdGhlIHJlc3VsdHMgaW4gdGhlIHByaW50ZXIuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHBhcmFsbGVsVW50YWdFY3IoZWNyOiBJRUNSQ2xpZW50LCByZXBvOiBzdHJpbmcsIHVudGFnZ2FibGVzOiBJbWFnZUFzc2V0W10pIHtcbiAgICBjb25zdCBsaW1pdCA9IHBMaW1pdChQX0xJTUlUKTtcblxuICAgIGZvciAoY29uc3QgaW1nIG9mIHVudGFnZ2FibGVzKSB7XG4gICAgICBjb25zdCB0YWcgPSBpbWcuZ2V0SXNvbGF0ZWRUYWcoKTtcbiAgICAgIGF3YWl0IGxpbWl0KCgpID0+XG4gICAgICAgIGVjci5iYXRjaERlbGV0ZUltYWdlKHtcbiAgICAgICAgICByZXBvc2l0b3J5TmFtZTogcmVwbyxcbiAgICAgICAgICBpbWFnZUlkczogW3tcbiAgICAgICAgICAgIGltYWdlVGFnOiB0YWcsXG4gICAgICAgICAgfV0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBkZWJ1ZyhgVW50YWdnZWQgJHt1bnRhZ2dhYmxlcy5sZW5ndGh9IGFzc2V0c2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIFVudGFnIGFzc2V0cyB0aGF0IHdlcmUgcHJldmlvdXNseSB0YWdnZWQsIGJ1dCBub3cgY3VycmVudGx5IHJlZmVyZW5jZWQuXG4gICAqIFNpbmNlIHRoaXMgaXMgdHJlYXRlZCBhcyBhbiBpbXBsZW1lbnRhdGlvbiBkZXRhaWwsIHdlIGRvIG5vdCBwcmludCB0aGUgcmVzdWx0cyBpbiB0aGUgcHJpbnRlci5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcGFyYWxsZWxVbnRhZ1MzKHMzOiBJUzNDbGllbnQsIGJ1Y2tldDogc3RyaW5nLCB1bnRhZ2dhYmxlczogT2JqZWN0QXNzZXRbXSkge1xuICAgIGNvbnN0IGxpbWl0ID0gcExpbWl0KFBfTElNSVQpO1xuXG4gICAgZm9yIChjb25zdCBvYmogb2YgdW50YWdnYWJsZXMpIHtcbiAgICAgIGNvbnN0IHRhZ3MgPSBhd2FpdCBvYmouYWxsVGFncyhzMykgPz8gW107XG4gICAgICBjb25zdCB1cGRhdGVkVGFncyA9IHRhZ3MuZmlsdGVyKCh0YWc6IFRhZykgPT4gdGFnLktleSAhPT0gUzNfSVNPTEFURURfVEFHKTtcbiAgICAgIGF3YWl0IGxpbWl0KCgpID0+XG4gICAgICAgIHMzLmRlbGV0ZU9iamVjdFRhZ2dpbmcoe1xuICAgICAgICAgIEJ1Y2tldDogYnVja2V0LFxuICAgICAgICAgIEtleTogb2JqLmtleSxcblxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBhd2FpdCBsaW1pdCgoKSA9PlxuICAgICAgICBzMy5wdXRPYmplY3RUYWdnaW5nKHtcbiAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldCxcbiAgICAgICAgICBLZXk6IG9iai5rZXksXG4gICAgICAgICAgVGFnZ2luZzoge1xuICAgICAgICAgICAgVGFnU2V0OiB1cGRhdGVkVGFncyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgZGVidWcoYFVudGFnZ2VkICR7dW50YWdnYWJsZXMubGVuZ3RofSBhc3NldHNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYWcgaW1hZ2VzIGluIHBhcmFsbGVsIHVzaW5nIHAtbGltaXRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcGFyYWxsZWxUYWdFY3IoZWNyOiBJRUNSQ2xpZW50LCByZXBvOiBzdHJpbmcsIHRhZ2dhYmxlczogSW1hZ2VBc3NldFtdLCBwcmludGVyOiBQcm9ncmVzc1ByaW50ZXIpIHtcbiAgICBjb25zdCBsaW1pdCA9IHBMaW1pdChQX0xJTUlUKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFnZ2FibGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbWcgPSB0YWdnYWJsZXNbaV07XG4gICAgICBjb25zdCB0YWdFY3IgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZWNyLnB1dEltYWdlKHtcbiAgICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiByZXBvLFxuICAgICAgICAgICAgaW1hZ2VEaWdlc3Q6IGltZy5kaWdlc3QsXG4gICAgICAgICAgICBpbWFnZU1hbmlmZXN0OiBpbWcubWFuaWZlc3QsXG4gICAgICAgICAgICBpbWFnZVRhZzogaW1nLmJ1aWxkSW1hZ2VUYWcoaSksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgLy8gVGhpcyBpcyBhIGZhbHNlIG5lZ2F0aXZlIC0tIGFuIGlzb2xhdGVkIGFzc2V0IGlzIHVudGFnZ2VkXG4gICAgICAgICAgLy8gbGlrZWx5IGR1ZSB0byBhbiBpbWFnZVRhZyBjb2xsaXNpb24uIFdlIGNhbiBzYWZlbHkgaWdub3JlLFxuICAgICAgICAgIC8vIGFuZCB0aGUgaXNvbGF0ZWQgYXNzZXQgd2lsbCBiZSB0YWdnZWQgbmV4dCB0aW1lLlxuICAgICAgICAgIGRlYnVnKGBXYXJuaW5nOiB1bmFibGUgdG8gdGFnIGltYWdlICR7SlNPTi5zdHJpbmdpZnkoaW1nLnRhZ3MpfSB3aXRoICR7aW1nLmJ1aWxkSW1hZ2VUYWcoaSl9IGR1ZSB0byB0aGUgZm9sbG93aW5nIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgYXdhaXQgbGltaXQoKCkgPT4gdGFnRWNyKCkpO1xuICAgIH1cblxuICAgIHByaW50ZXIucmVwb3J0VGFnZ2VkQXNzZXQodGFnZ2FibGVzKTtcbiAgICBkZWJ1ZyhgVGFnZ2VkICR7dGFnZ2FibGVzLmxlbmd0aH0gYXNzZXRzYCk7XG4gIH1cblxuICAvKipcbiAgICogVGFnIG9iamVjdHMgaW4gcGFyYWxsZWwgdXNpbmcgcC1saW1pdC4gVGhlIHB1dE9iamVjdFRhZ2dpbmcgQVBJIGRvZXMgbm90XG4gICAqIHN1cHBvcnQgYmF0Y2ggdGFnZ2luZyBzbyB3ZSBtdXN0IGhhbmRsZSB0aGUgcGFyYWxsZWxpc20gY2xpZW50LXNpZGUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHBhcmFsbGVsVGFnUzMoczM6IElTM0NsaWVudCwgYnVja2V0OiBzdHJpbmcsIHRhZ2dhYmxlczogT2JqZWN0QXNzZXRbXSwgZGF0ZTogbnVtYmVyLCBwcmludGVyOiBQcm9ncmVzc1ByaW50ZXIpIHtcbiAgICBjb25zdCBsaW1pdCA9IHBMaW1pdChQX0xJTUlUKTtcblxuICAgIGZvciAoY29uc3Qgb2JqIG9mIHRhZ2dhYmxlcykge1xuICAgICAgYXdhaXQgbGltaXQoKCkgPT5cbiAgICAgICAgczMucHV0T2JqZWN0VGFnZ2luZyh7XG4gICAgICAgICAgQnVja2V0OiBidWNrZXQsXG4gICAgICAgICAgS2V5OiBvYmoua2V5LFxuICAgICAgICAgIFRhZ2dpbmc6IHtcbiAgICAgICAgICAgIFRhZ1NldDogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgS2V5OiBTM19JU09MQVRFRF9UQUcsXG4gICAgICAgICAgICAgICAgVmFsdWU6IFN0cmluZyhkYXRlKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIHByaW50ZXIucmVwb3J0VGFnZ2VkQXNzZXQodGFnZ2FibGVzKTtcbiAgICBkZWJ1ZyhgVGFnZ2VkICR7dGFnZ2FibGVzLmxlbmd0aH0gYXNzZXRzYCk7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGltYWdlcyBpbiBwYXJhbGxlbC4gVGhlIGRlbGV0ZUltYWdlIEFQSSBzdXBwb3J0cyBiYXRjaGVzIG9mIDEwMC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcGFyYWxsZWxEZWxldGVFY3IoZWNyOiBJRUNSQ2xpZW50LCByZXBvOiBzdHJpbmcsIGRlbGV0YWJsZXM6IEltYWdlQXNzZXRbXSwgcHJpbnRlcjogUHJvZ3Jlc3NQcmludGVyKSB7XG4gICAgY29uc3QgYmF0Y2hTaXplID0gMTAwO1xuICAgIGNvbnN0IGltYWdlc1RvRGVsZXRlID0gZGVsZXRhYmxlcy5tYXAoaW1nID0+ICh7XG4gICAgICBpbWFnZURpZ2VzdDogaW1nLmRpZ2VzdCxcbiAgICB9KSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgYmF0Y2hlcyA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbWFnZXNUb0RlbGV0ZS5sZW5ndGg7IGkgKz0gYmF0Y2hTaXplKSB7XG4gICAgICAgIGJhdGNoZXMucHVzaChpbWFnZXNUb0RlbGV0ZS5zbGljZShpLCBpICsgYmF0Y2hTaXplKSk7XG4gICAgICB9XG4gICAgICAvLyBEZWxldGUgaW1hZ2VzIGluIGJhdGNoZXNcbiAgICAgIGZvciAoY29uc3QgYmF0Y2ggb2YgYmF0Y2hlcykge1xuICAgICAgICBhd2FpdCBlY3IuYmF0Y2hEZWxldGVJbWFnZSh7XG4gICAgICAgICAgaW1hZ2VJZHM6IGJhdGNoLFxuICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiByZXBvLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZWxldGVkQ291bnQgPSBiYXRjaC5sZW5ndGg7XG4gICAgICAgIGRlYnVnKGBEZWxldGVkICR7ZGVsZXRlZENvdW50fSBhc3NldHNgKTtcbiAgICAgICAgcHJpbnRlci5yZXBvcnREZWxldGVkQXNzZXQoZGVsZXRhYmxlcy5zbGljZSgwLCBkZWxldGVkQ291bnQpKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGluZm8oY2hhbGsucmVkKGBFcnJvciBkZWxldGluZyBpbWFnZXM6ICR7ZXJyfWApKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIG9iamVjdHMgaW4gcGFyYWxsZWwuIFRoZSBkZWxldGVPYmplY3RzIEFQSSBzdXBwb3J0cyBiYXRjaGVzIG9mIDEwMDAuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHBhcmFsbGVsRGVsZXRlUzMoczM6IElTM0NsaWVudCwgYnVja2V0OiBzdHJpbmcsIGRlbGV0YWJsZXM6IE9iamVjdEFzc2V0W10sIHByaW50ZXI6IFByb2dyZXNzUHJpbnRlcikge1xuICAgIGNvbnN0IGJhdGNoU2l6ZSA9IDEwMDA7XG4gICAgY29uc3Qgb2JqZWN0c1RvRGVsZXRlID0gZGVsZXRhYmxlcy5tYXAoYXNzZXQgPT4gKHtcbiAgICAgIEtleTogYXNzZXQua2V5LFxuICAgIH0pKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBiYXRjaGVzID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9iamVjdHNUb0RlbGV0ZS5sZW5ndGg7IGkgKz0gYmF0Y2hTaXplKSB7XG4gICAgICAgIGJhdGNoZXMucHVzaChvYmplY3RzVG9EZWxldGUuc2xpY2UoaSwgaSArIGJhdGNoU2l6ZSkpO1xuICAgICAgfVxuICAgICAgLy8gRGVsZXRlIG9iamVjdHMgaW4gYmF0Y2hlc1xuICAgICAgZm9yIChjb25zdCBiYXRjaCBvZiBiYXRjaGVzKSB7XG4gICAgICAgIGF3YWl0IHMzLmRlbGV0ZU9iamVjdHMoe1xuICAgICAgICAgIEJ1Y2tldDogYnVja2V0LFxuICAgICAgICAgIERlbGV0ZToge1xuICAgICAgICAgICAgT2JqZWN0czogYmF0Y2gsXG4gICAgICAgICAgICBRdWlldDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZWxldGVkQ291bnQgPSBiYXRjaC5sZW5ndGg7XG4gICAgICAgIGRlYnVnKGBEZWxldGVkICR7ZGVsZXRlZENvdW50fSBhc3NldHNgKTtcbiAgICAgICAgcHJpbnRlci5yZXBvcnREZWxldGVkQXNzZXQoZGVsZXRhYmxlcy5zbGljZSgwLCBkZWxldGVkQ291bnQpKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGluZm8oY2hhbGsucmVkKGBFcnJvciBkZWxldGluZyBvYmplY3RzOiAke2Vycn1gKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBib290c3RyYXBCdWNrZXROYW1lKHNkazogU0RLLCBib290c3RyYXBTdGFja05hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdG9vbGtpdEluZm8gPSBhd2FpdCBUb29sa2l0SW5mby5sb29rdXAodGhpcy5wcm9wcy5yZXNvbHZlZEVudmlyb25tZW50LCBzZGssIGJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgcmV0dXJuIHRvb2xraXRJbmZvLmJ1Y2tldE5hbWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3RzdHJhcFJlcG9zaXRvcnlOYW1lKHNkazogU0RLLCBib290c3RyYXBTdGFja05hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgdG9vbGtpdEluZm8gPSBhd2FpdCBUb29sa2l0SW5mby5sb29rdXAodGhpcy5wcm9wcy5yZXNvbHZlZEVudmlyb25tZW50LCBzZGssIGJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgcmV0dXJuIHRvb2xraXRJbmZvLnJlcG9zaXRvcnlOYW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBib290c3RyYXBRdWFsaWZpZXIoc2RrOiBTREssIGJvb3RzdHJhcFN0YWNrTmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB0b29sa2l0SW5mbyA9IGF3YWl0IFRvb2xraXRJbmZvLmxvb2t1cCh0aGlzLnByb3BzLnJlc29sdmVkRW52aXJvbm1lbnQsIHNkaywgYm9vdHN0cmFwU3RhY2tOYW1lKTtcbiAgICByZXR1cm4gdG9vbGtpdEluZm8uYm9vdHN0cmFwU3RhY2sucGFyYW1ldGVycy5RdWFsaWZpZXI7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG51bU9iamVjdHNJbkJ1Y2tldChzMzogSVMzQ2xpZW50LCBidWNrZXQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgbGV0IHRvdGFsQ291bnQgPSAwO1xuICAgIGxldCBjb250aW51YXRpb25Ub2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzMy5saXN0T2JqZWN0c1YyKHtcbiAgICAgICAgQnVja2V0OiBidWNrZXQsXG4gICAgICAgIENvbnRpbnVhdGlvblRva2VuOiBjb250aW51YXRpb25Ub2tlbixcbiAgICAgIH0pO1xuXG4gICAgICB0b3RhbENvdW50ICs9IHJlc3BvbnNlLktleUNvdW50ID8/IDA7XG4gICAgICBjb250aW51YXRpb25Ub2tlbiA9IHJlc3BvbnNlLk5leHRDb250aW51YXRpb25Ub2tlbjtcbiAgICB9IHdoaWxlIChjb250aW51YXRpb25Ub2tlbik7XG5cbiAgICByZXR1cm4gdG90YWxDb3VudDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbnVtSW1hZ2VzSW5SZXBvKGVjcjogSUVDUkNsaWVudCwgcmVwbzogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBsZXQgdG90YWxDb3VudCA9IDA7XG4gICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgZG8ge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBlY3IubGlzdEltYWdlcyh7XG4gICAgICAgIHJlcG9zaXRvcnlOYW1lOiByZXBvLFxuICAgICAgICBuZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgIH0pO1xuXG4gICAgICB0b3RhbENvdW50ICs9IHJlc3BvbnNlLmltYWdlSWRzPy5sZW5ndGggPz8gMDtcbiAgICAgIG5leHRUb2tlbiA9IHJlc3BvbnNlLm5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuXG4gICAgcmV0dXJuIHRvdGFsQ291bnQ7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jICpyZWFkUmVwb0luQmF0Y2hlcyhlY3I6IElFQ1JDbGllbnQsIHJlcG86IHN0cmluZywgYmF0Y2hTaXplOiBudW1iZXIgPSAxMDAwLCBjdXJyZW50VGltZTogbnVtYmVyKTogQXN5bmNHZW5lcmF0b3I8SW1hZ2VBc3NldFtdPiB7XG4gICAgbGV0IGNvbnRpbnVhdGlvblRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICBkbyB7XG4gICAgICBjb25zdCBiYXRjaDogSW1hZ2VBc3NldFtdID0gW107XG5cbiAgICAgIHdoaWxlIChiYXRjaC5sZW5ndGggPCBiYXRjaFNpemUpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBlY3IubGlzdEltYWdlcyh7XG4gICAgICAgICAgcmVwb3NpdG9yeU5hbWU6IHJlcG8sXG4gICAgICAgICAgbmV4dFRva2VuOiBjb250aW51YXRpb25Ub2tlbixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTm8gaW1hZ2VzIGluIHRoZSByZXBvc2l0b3J5XG4gICAgICAgIGlmICghcmVzcG9uc2UuaW1hZ2VJZHMgfHwgcmVzcG9uc2UuaW1hZ2VJZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBtYXAgdW5pcXVlIGltYWdlIGRpZ2VzdCB0byAocG9zc2libHkgbXVsdGlwbGUpIHRhZ3NcbiAgICAgICAgY29uc3QgaW1hZ2VzID0gaW1hZ2VNYXAocmVzcG9uc2UuaW1hZ2VJZHMgPz8gW10pO1xuXG4gICAgICAgIGNvbnN0IGltYWdlSWRzID0gT2JqZWN0LmtleXMoaW1hZ2VzKS5tYXAoa2V5ID0+ICh7XG4gICAgICAgICAgaW1hZ2VEaWdlc3Q6IGtleSxcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIGNvbnN0IGRlc2NyaWJlSW1hZ2VJbmZvID0gYXdhaXQgZWNyLmRlc2NyaWJlSW1hZ2VzKHtcbiAgICAgICAgICByZXBvc2l0b3J5TmFtZTogcmVwbyxcbiAgICAgICAgICBpbWFnZUlkczogaW1hZ2VJZHMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGdldEltYWdlSW5mbyA9IGF3YWl0IGVjci5iYXRjaEdldEltYWdlKHtcbiAgICAgICAgICByZXBvc2l0b3J5TmFtZTogcmVwbyxcbiAgICAgICAgICBpbWFnZUlkczogaW1hZ2VJZHMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNvbWJpbmVkSW1hZ2VJbmZvID0gZGVzY3JpYmVJbWFnZUluZm8uaW1hZ2VEZXRhaWxzPy5tYXAoaW1hZ2VEZXRhaWwgPT4ge1xuICAgICAgICAgIGNvbnN0IG1hdGNoaW5nSW1hZ2UgPSBnZXRJbWFnZUluZm8uaW1hZ2VzPy5maW5kKFxuICAgICAgICAgICAgaW1nID0+IGltZy5pbWFnZUlkPy5pbWFnZURpZ2VzdCA9PT0gaW1hZ2VEZXRhaWwuaW1hZ2VEaWdlc3QsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5pbWFnZURldGFpbCxcbiAgICAgICAgICAgIG1hbmlmZXN0OiBtYXRjaGluZ0ltYWdlPy5pbWFnZU1hbmlmZXN0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgaW1hZ2Ugb2YgY29tYmluZWRJbWFnZUluZm8gPz8gW10pIHtcbiAgICAgICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBpbWFnZS5pbWFnZVB1c2hlZEF0ID8/IG5ldyBEYXRlKGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAvLyBTdG9yZSB0aGUgaW1hZ2UgaWYgaXQgd2FzIHB1c2hlZCBlYXJsaWVyIHRoYW4gdG9kYXkgLSBjcmVhdGVkQnVmZmVyRGF5c1xuICAgICAgICAgIGlmIChpbWFnZS5pbWFnZURpZ2VzdCAmJiBsYXN0TW9kaWZpZWQgPCBuZXcgRGF0ZShjdXJyZW50VGltZSAtICh0aGlzLnByb3BzLmNyZWF0ZWRCdWZmZXJEYXlzICogREFZKSkpIHtcbiAgICAgICAgICAgIGJhdGNoLnB1c2gobmV3IEltYWdlQXNzZXQoaW1hZ2UuaW1hZ2VEaWdlc3QsIGltYWdlLmltYWdlU2l6ZUluQnl0ZXMgPz8gMCwgaW1hZ2UuaW1hZ2VUYWdzID8/IFtdLCBpbWFnZS5tYW5pZmVzdCA/PyAnJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVhdGlvblRva2VuID0gcmVzcG9uc2UubmV4dFRva2VuO1xuXG4gICAgICAgIGlmICghY29udGludWF0aW9uVG9rZW4pIGJyZWFrOyAvLyBObyBtb3JlIGltYWdlcyB0byBmZXRjaFxuICAgICAgfVxuXG4gICAgICBpZiAoYmF0Y2gubGVuZ3RoID4gMCkge1xuICAgICAgICB5aWVsZCBiYXRjaDtcbiAgICAgIH1cbiAgICB9IHdoaWxlIChjb250aW51YXRpb25Ub2tlbik7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdG9yIGZ1bmN0aW9uIHRoYXQgcmVhZHMgb2JqZWN0cyBmcm9tIHRoZSBTMyBCdWNrZXQgaW4gYmF0Y2hlcy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgKnJlYWRCdWNrZXRJbkJhdGNoZXMoczM6IElTM0NsaWVudCwgYnVja2V0OiBzdHJpbmcsIGJhdGNoU2l6ZTogbnVtYmVyID0gMTAwMCwgY3VycmVudFRpbWU6IG51bWJlcik6IEFzeW5jR2VuZXJhdG9yPE9iamVjdEFzc2V0W10+IHtcbiAgICBsZXQgY29udGludWF0aW9uVG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IGJhdGNoOiBPYmplY3RBc3NldFtdID0gW107XG5cbiAgICAgIHdoaWxlIChiYXRjaC5sZW5ndGggPCBiYXRjaFNpemUpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzMy5saXN0T2JqZWN0c1YyKHtcbiAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldCxcbiAgICAgICAgICBDb250aW51YXRpb25Ub2tlbjogY29udGludWF0aW9uVG9rZW4sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLkNvbnRlbnRzPy5mb3JFYWNoKChvYmo6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGtleSA9IG9iai5LZXkgPz8gJyc7XG4gICAgICAgICAgY29uc3Qgc2l6ZSA9IG9iai5TaXplID8/IDA7XG4gICAgICAgICAgY29uc3QgbGFzdE1vZGlmaWVkID0gb2JqLkxhc3RNb2RpZmllZCA/PyBuZXcgRGF0ZShjdXJyZW50VGltZSk7XG4gICAgICAgICAgLy8gU3RvcmUgdGhlIG9iamVjdCBpZiBpdCBoYXMgYSBLZXkgYW5kXG4gICAgICAgICAgLy8gaWYgaXQgaGFzIG5vdCBiZWVuIG1vZGlmaWVkIHNpbmNlIHRvZGF5IC0gY3JlYXRlZEJ1ZmZlckRheXNcbiAgICAgICAgICBpZiAoa2V5ICYmIGxhc3RNb2RpZmllZCA8IG5ldyBEYXRlKGN1cnJlbnRUaW1lIC0gKHRoaXMucHJvcHMuY3JlYXRlZEJ1ZmZlckRheXMgKiBEQVkpKSkge1xuICAgICAgICAgICAgYmF0Y2gucHVzaChuZXcgT2JqZWN0QXNzZXQoYnVja2V0LCBrZXksIHNpemUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnRpbnVhdGlvblRva2VuID0gcmVzcG9uc2UuTmV4dENvbnRpbnVhdGlvblRva2VuO1xuXG4gICAgICAgIGlmICghY29udGludWF0aW9uVG9rZW4pIGJyZWFrOyAvLyBObyBtb3JlIG9iamVjdHMgdG8gZmV0Y2hcbiAgICAgIH1cblxuICAgICAgaWYgKGJhdGNoLmxlbmd0aCA+IDApIHtcbiAgICAgICAgeWllbGQgYmF0Y2g7XG4gICAgICB9XG4gICAgfSB3aGlsZSAoY29udGludWF0aW9uVG9rZW4pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjb25maXJtYXRpb25Qcm9tcHQocHJpbnRlcjogUHJvZ3Jlc3NQcmludGVyLCBkZWxldGFibGVzOiBHY0Fzc2V0W10sIHR5cGU6IHN0cmluZykge1xuICAgIGNvbnN0IHBsdXJhbGl6ZSA9IChuYW1lOiBzdHJpbmcsIGNvdW50OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgcmV0dXJuIGNvdW50ID09PSAxID8gbmFtZSA6IGAke25hbWV9c2A7XG4gICAgfTtcblxuICAgIGlmICh0aGlzLmNvbmZpcm0pIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBbXG4gICAgICAgIGBGb3VuZCAke2RlbGV0YWJsZXMubGVuZ3RofSAke3BsdXJhbGl6ZSh0eXBlLCBkZWxldGFibGVzLmxlbmd0aCl9IHRvIGRlbGV0ZSBiYXNlZCBvZmYgb2YgdGhlIGZvbGxvd2luZyBjcml0ZXJpYTpgLFxuICAgICAgICBgLSAke3R5cGV9cyBoYXZlIGJlZW4gaXNvbGF0ZWQgZm9yID4gJHt0aGlzLnByb3BzLnJvbGxiYWNrQnVmZmVyRGF5c30gZGF5c2AsXG4gICAgICAgIGAtICR7dHlwZX1zIHdlcmUgY3JlYXRlZCA+ICR7dGhpcy5wcm9wcy5jcmVhdGVkQnVmZmVyRGF5c30gZGF5cyBhZ29gLFxuICAgICAgICAnJyxcbiAgICAgICAgJ0RlbGV0ZSB0aGlzIGJhdGNoICh5ZXMvbm8vZGVsZXRlLWFsbCk/JyxcbiAgICAgIF0uam9pbignXFxuJyk7XG4gICAgICBwcmludGVyLnBhdXNlKCk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHByb21wdGx5LnByb21wdChtZXNzYWdlLFxuICAgICAgICB7IHRyaW06IHRydWUgfSxcbiAgICAgICk7XG5cbiAgICAgIC8vIEFueXRoaW5nIG90aGVyIHRoYW4geWVzL3kvZGVsZXRlLWFsbCBpcyB0cmVhdGVkIGFzIG5vXG4gICAgICBpZiAoIXJlc3BvbnNlIHx8ICFbJ3llcycsICd5JywgJ2RlbGV0ZS1hbGwnXS5pbmNsdWRlcyhyZXNwb25zZS50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICB0aHJvdyBuZXcgVG9vbGtpdEVycm9yKCdEZWxldGlvbiBhYm9ydGVkIGJ5IHVzZXInKTtcbiAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UudG9Mb3dlckNhc2UoKSA9PSAnZGVsZXRlLWFsbCcpIHtcbiAgICAgICAgdGhpcy5jb25maXJtID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHByaW50ZXIucmVzdW1lKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFydGl0aW9uPEE+KHhzOiBJdGVyYWJsZTxBPiwgcHJlZDogKHg6IEEpID0+IGJvb2xlYW4pOiB7IGluY2x1ZGVkOiBBW107IGV4Y2x1ZGVkOiBBW10gfSB7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBpbmNsdWRlZDogW10gYXMgQVtdLFxuICAgIGV4Y2x1ZGVkOiBbXSBhcyBBW10sXG4gIH07XG5cbiAgZm9yIChjb25zdCB4IG9mIHhzKSB7XG4gICAgaWYgKHByZWQoeCkpIHtcbiAgICAgIHJlc3VsdC5pbmNsdWRlZC5wdXNoKHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQuZXhjbHVkZWQucHVzaCh4KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpbWFnZU1hcChpbWFnZUlkczogSW1hZ2VJZGVudGlmaWVyW10pIHtcbiAgY29uc3QgaW1hZ2VzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gPSB7fTtcbiAgZm9yIChjb25zdCBpbWFnZSBvZiBpbWFnZUlkcyA/PyBbXSkge1xuICAgIGlmICghaW1hZ2UuaW1hZ2VEaWdlc3QgfHwgIWltYWdlLmltYWdlVGFnKSB7IGNvbnRpbnVlOyB9XG4gICAgaWYgKCFpbWFnZXNbaW1hZ2UuaW1hZ2VEaWdlc3RdKSB7XG4gICAgICBpbWFnZXNbaW1hZ2UuaW1hZ2VEaWdlc3RdID0gW107XG4gICAgfVxuICAgIGltYWdlc1tpbWFnZS5pbWFnZURpZ2VzdF0ucHVzaChpbWFnZS5pbWFnZVRhZyk7XG4gIH1cbiAgcmV0dXJuIGltYWdlcztcbn1cbiJdfQ==