@mavogel/cdk-vscode-server 0.0.2

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 (439) hide show
  1. package/.jsii +4351 -0
  2. package/API.md +367 -0
  3. package/CONTRIBUTING.md +59 -0
  4. package/LICENSE +202 -0
  5. package/README.md +183 -0
  6. package/assets/installer/installer.lambda/index.js +112 -0
  7. package/assets/secret-retriever/secret-retriever.lambda/index.js +57 -0
  8. package/docs/img/vscode-server-ui-login-min.png +0 -0
  9. package/docs/img/vscode-server-ui-min.png +0 -0
  10. package/docs/img/vscode-server.drawio +108 -0
  11. package/docs/img/vscode-server.drawio-min.png +0 -0
  12. package/integ-tests/code-server login.html +48 -0
  13. package/integ-tests/functions/login-handler.ts +63 -0
  14. package/integ-tests/integ.al2023.ts +69 -0
  15. package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.assets.json +32 -0
  16. package/integ-tests/integ.al2023.ts.snapshot/IntegSetupVSCodeOnAl2023DefaultTestDeployAssert74D8F645.template.json +337 -0
  17. package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.assets.json +110 -0
  18. package/integ-tests/integ.al2023.ts.snapshot/IntegTestStackAl2023.template.json +2459 -0
  19. package/integ-tests/integ.al2023.ts.snapshot/asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce/index.js +6169 -0
  20. package/integ-tests/integ.al2023.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
  21. package/integ-tests/integ.al2023.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/cfn-response.js +1 -0
  22. package/integ-tests/integ.al2023.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/consts.js +1 -0
  23. package/integ-tests/integ.al2023.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/framework.js +3 -0
  24. package/integ-tests/integ.al2023.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/outbound.js +1 -0
  25. package/integ-tests/integ.al2023.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/util.js +1 -0
  26. package/integ-tests/integ.al2023.ts.snapshot/asset.512cf155ada4793b37a885c1aa6d9bb8f534e88bac6f63c69672d4d73df2decf.lambda/index.js +112 -0
  27. package/integ-tests/integ.al2023.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
  28. package/integ-tests/integ.al2023.ts.snapshot/asset.c504585dae89ce8e394d7744ccae054318e7d1aff14afb545438d173d51dc97d.bundle/index.js +30572 -0
  29. package/integ-tests/integ.al2023.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a/index.js +1 -0
  30. package/integ-tests/integ.al2023.ts.snapshot/asset.ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a/__entrypoint__.js +1 -0
  31. package/integ-tests/integ.al2023.ts.snapshot/asset.ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a/index.js +1 -0
  32. package/integ-tests/integ.al2023.ts.snapshot/cdk.out +1 -0
  33. package/integ-tests/integ.al2023.ts.snapshot/integ.json +22 -0
  34. package/integ-tests/integ.al2023.ts.snapshot/manifest.json +510 -0
  35. package/integ-tests/integ.al2023.ts.snapshot/tree.json +2944 -0
  36. package/integ-tests/integ.ubuntu.ts +66 -0
  37. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.assets.json +32 -0
  38. package/integ-tests/integ.ubuntu.ts.snapshot/IntegSetupVSCodeOnUbuntuDefaultTestDeployAssertFF8DF2C5.template.json +337 -0
  39. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.assets.json +110 -0
  40. package/integ-tests/integ.ubuntu.ts.snapshot/IntegTestStackUbuntu22.template.json +2477 -0
  41. package/integ-tests/integ.ubuntu.ts.snapshot/asset.23732f3d1982f7fb0da3bd6638a8107337bb767fea165b45eae12000a1dd67ce/index.js +6169 -0
  42. package/integ-tests/integ.ubuntu.ts.snapshot/asset.2819175352ad1ce0dae768e83fc328fb70fb5f10b4a8ff0ccbcb791f02b0716d/index.js +1 -0
  43. package/integ-tests/integ.ubuntu.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/cfn-response.js +1 -0
  44. package/integ-tests/integ.ubuntu.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/consts.js +1 -0
  45. package/integ-tests/integ.ubuntu.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/framework.js +3 -0
  46. package/integ-tests/integ.ubuntu.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/outbound.js +1 -0
  47. package/integ-tests/integ.ubuntu.ts.snapshot/asset.4dc48ffba382f93077a1e6824599bbd4ceb6f91eb3d9442eca3b85bdb1a20b1e/util.js +1 -0
  48. package/integ-tests/integ.ubuntu.ts.snapshot/asset.512cf155ada4793b37a885c1aa6d9bb8f534e88bac6f63c69672d4d73df2decf.lambda/index.js +112 -0
  49. package/integ-tests/integ.ubuntu.ts.snapshot/asset.781ab0ab74634cdaf61539ab208ab777829ef07097ac21f95b9e15a3b1eedc1b.lambda/index.js +57 -0
  50. package/integ-tests/integ.ubuntu.ts.snapshot/asset.c504585dae89ce8e394d7744ccae054318e7d1aff14afb545438d173d51dc97d.bundle/index.js +30572 -0
  51. package/integ-tests/integ.ubuntu.ts.snapshot/asset.ce2f3595a340d6c519a65888ef97e3b9b64f053f83608e32cc28162e22d7d99a/index.js +1 -0
  52. package/integ-tests/integ.ubuntu.ts.snapshot/asset.ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a/__entrypoint__.js +1 -0
  53. package/integ-tests/integ.ubuntu.ts.snapshot/asset.ee7de53d64cc9d6248fa6aa550f92358f6c907b5efd6f3298aeab1b5e7ea358a/index.js +1 -0
  54. package/integ-tests/integ.ubuntu.ts.snapshot/cdk.out +1 -0
  55. package/integ-tests/integ.ubuntu.ts.snapshot/integ.json +22 -0
  56. package/integ-tests/integ.ubuntu.ts.snapshot/manifest.json +510 -0
  57. package/integ-tests/integ.ubuntu.ts.snapshot/tree.json +2962 -0
  58. package/lib/index.d.ts +1 -0
  59. package/lib/index.js +18 -0
  60. package/lib/installer/installer-function.d.ts +13 -0
  61. package/lib/installer/installer-function.js +23 -0
  62. package/lib/installer/installer.d.ts +64 -0
  63. package/lib/installer/installer.js +707 -0
  64. package/lib/installer/installer.lambda.d.ts +3 -0
  65. package/lib/installer/installer.lambda.js +94 -0
  66. package/lib/mappings.d.ts +2 -0
  67. package/lib/mappings.js +25 -0
  68. package/lib/prefixlist-retriever/prefixlist-retriever.d.ts +16 -0
  69. package/lib/prefixlist-retriever/prefixlist-retriever.js +56 -0
  70. package/lib/secret-retriever/secret-retriever-function.d.ts +13 -0
  71. package/lib/secret-retriever/secret-retriever-function.js +23 -0
  72. package/lib/secret-retriever/secret-retriever.d.ts +33 -0
  73. package/lib/secret-retriever/secret-retriever.js +72 -0
  74. package/lib/secret-retriever/secret-retriever.lambda.d.ts +2 -0
  75. package/lib/secret-retriever/secret-retriever.lambda.js +36 -0
  76. package/lib/vscode-server.d.ts +97 -0
  77. package/lib/vscode-server.js +417 -0
  78. package/node_modules/boolbase/README.md +10 -0
  79. package/node_modules/boolbase/index.js +8 -0
  80. package/node_modules/boolbase/package.json +23 -0
  81. package/node_modules/css-select/LICENSE +11 -0
  82. package/node_modules/css-select/README.md +264 -0
  83. package/node_modules/css-select/lib/attributes.d.ts +7 -0
  84. package/node_modules/css-select/lib/attributes.d.ts.map +1 -0
  85. package/node_modules/css-select/lib/attributes.js +236 -0
  86. package/node_modules/css-select/lib/attributes.js.map +1 -0
  87. package/node_modules/css-select/lib/compile.d.ts +13 -0
  88. package/node_modules/css-select/lib/compile.d.ts.map +1 -0
  89. package/node_modules/css-select/lib/compile.js +151 -0
  90. package/node_modules/css-select/lib/compile.js.map +1 -0
  91. package/node_modules/css-select/lib/esm/attributes.d.ts +7 -0
  92. package/node_modules/css-select/lib/esm/attributes.d.ts.map +1 -0
  93. package/node_modules/css-select/lib/esm/attributes.js +222 -0
  94. package/node_modules/css-select/lib/esm/attributes.js.map +1 -0
  95. package/node_modules/css-select/lib/esm/compile.d.ts +13 -0
  96. package/node_modules/css-select/lib/esm/compile.d.ts.map +1 -0
  97. package/node_modules/css-select/lib/esm/compile.js +115 -0
  98. package/node_modules/css-select/lib/esm/compile.js.map +1 -0
  99. package/node_modules/css-select/lib/esm/general.d.ts +3 -0
  100. package/node_modules/css-select/lib/esm/general.d.ts.map +1 -0
  101. package/node_modules/css-select/lib/esm/general.js +144 -0
  102. package/node_modules/css-select/lib/esm/general.js.map +1 -0
  103. package/node_modules/css-select/lib/esm/index.d.ts +50 -0
  104. package/node_modules/css-select/lib/esm/index.d.ts.map +1 -0
  105. package/node_modules/css-select/lib/esm/index.js +115 -0
  106. package/node_modules/css-select/lib/esm/index.js.map +1 -0
  107. package/node_modules/css-select/lib/esm/package.json +1 -0
  108. package/node_modules/css-select/lib/esm/pseudo-selectors/aliases.d.ts +5 -0
  109. package/node_modules/css-select/lib/esm/pseudo-selectors/aliases.d.ts.map +1 -0
  110. package/node_modules/css-select/lib/esm/pseudo-selectors/aliases.js +35 -0
  111. package/node_modules/css-select/lib/esm/pseudo-selectors/aliases.js.map +1 -0
  112. package/node_modules/css-select/lib/esm/pseudo-selectors/filters.d.ts +4 -0
  113. package/node_modules/css-select/lib/esm/pseudo-selectors/filters.d.ts.map +1 -0
  114. package/node_modules/css-select/lib/esm/pseudo-selectors/filters.js +143 -0
  115. package/node_modules/css-select/lib/esm/pseudo-selectors/filters.js.map +1 -0
  116. package/node_modules/css-select/lib/esm/pseudo-selectors/index.d.ts +8 -0
  117. package/node_modules/css-select/lib/esm/pseudo-selectors/index.d.ts.map +1 -0
  118. package/node_modules/css-select/lib/esm/pseudo-selectors/index.js +40 -0
  119. package/node_modules/css-select/lib/esm/pseudo-selectors/index.js.map +1 -0
  120. package/node_modules/css-select/lib/esm/pseudo-selectors/pseudos.d.ts +6 -0
  121. package/node_modules/css-select/lib/esm/pseudo-selectors/pseudos.d.ts.map +1 -0
  122. package/node_modules/css-select/lib/esm/pseudo-selectors/pseudos.js +79 -0
  123. package/node_modules/css-select/lib/esm/pseudo-selectors/pseudos.js.map +1 -0
  124. package/node_modules/css-select/lib/esm/pseudo-selectors/subselects.d.ts +9 -0
  125. package/node_modules/css-select/lib/esm/pseudo-selectors/subselects.d.ts.map +1 -0
  126. package/node_modules/css-select/lib/esm/pseudo-selectors/subselects.js +94 -0
  127. package/node_modules/css-select/lib/esm/pseudo-selectors/subselects.js.map +1 -0
  128. package/node_modules/css-select/lib/esm/sort.d.ts +12 -0
  129. package/node_modules/css-select/lib/esm/sort.d.ts.map +1 -0
  130. package/node_modules/css-select/lib/esm/sort.js +79 -0
  131. package/node_modules/css-select/lib/esm/sort.js.map +1 -0
  132. package/node_modules/css-select/lib/esm/types.d.ts +167 -0
  133. package/node_modules/css-select/lib/esm/types.d.ts.map +1 -0
  134. package/node_modules/css-select/lib/esm/types.js +2 -0
  135. package/node_modules/css-select/lib/esm/types.js.map +1 -0
  136. package/node_modules/css-select/lib/general.d.ts +3 -0
  137. package/node_modules/css-select/lib/general.d.ts.map +1 -0
  138. package/node_modules/css-select/lib/general.js +148 -0
  139. package/node_modules/css-select/lib/general.js.map +1 -0
  140. package/node_modules/css-select/lib/index.d.ts +50 -0
  141. package/node_modules/css-select/lib/index.d.ts.map +1 -0
  142. package/node_modules/css-select/lib/index.js +154 -0
  143. package/node_modules/css-select/lib/index.js.map +1 -0
  144. package/node_modules/css-select/lib/pseudo-selectors/aliases.d.ts +5 -0
  145. package/node_modules/css-select/lib/pseudo-selectors/aliases.d.ts.map +1 -0
  146. package/node_modules/css-select/lib/pseudo-selectors/aliases.js +34 -0
  147. package/node_modules/css-select/lib/pseudo-selectors/aliases.js.map +1 -0
  148. package/node_modules/css-select/lib/pseudo-selectors/filters.d.ts +4 -0
  149. package/node_modules/css-select/lib/pseudo-selectors/filters.d.ts.map +1 -0
  150. package/node_modules/css-select/lib/pseudo-selectors/filters.js +157 -0
  151. package/node_modules/css-select/lib/pseudo-selectors/filters.js.map +1 -0
  152. package/node_modules/css-select/lib/pseudo-selectors/index.d.ts +8 -0
  153. package/node_modules/css-select/lib/pseudo-selectors/index.d.ts.map +1 -0
  154. package/node_modules/css-select/lib/pseudo-selectors/index.js +46 -0
  155. package/node_modules/css-select/lib/pseudo-selectors/index.js.map +1 -0
  156. package/node_modules/css-select/lib/pseudo-selectors/pseudos.d.ts +6 -0
  157. package/node_modules/css-select/lib/pseudo-selectors/pseudos.d.ts.map +1 -0
  158. package/node_modules/css-select/lib/pseudo-selectors/pseudos.js +93 -0
  159. package/node_modules/css-select/lib/pseudo-selectors/pseudos.js.map +1 -0
  160. package/node_modules/css-select/lib/pseudo-selectors/subselects.d.ts +9 -0
  161. package/node_modules/css-select/lib/pseudo-selectors/subselects.d.ts.map +1 -0
  162. package/node_modules/css-select/lib/pseudo-selectors/subselects.js +112 -0
  163. package/node_modules/css-select/lib/pseudo-selectors/subselects.js.map +1 -0
  164. package/node_modules/css-select/lib/sort.d.ts +12 -0
  165. package/node_modules/css-select/lib/sort.d.ts.map +1 -0
  166. package/node_modules/css-select/lib/sort.js +84 -0
  167. package/node_modules/css-select/lib/sort.js.map +1 -0
  168. package/node_modules/css-select/lib/types.d.ts +167 -0
  169. package/node_modules/css-select/lib/types.d.ts.map +1 -0
  170. package/node_modules/css-select/lib/types.js +3 -0
  171. package/node_modules/css-select/lib/types.js.map +1 -0
  172. package/node_modules/css-select/package.json +81 -0
  173. package/node_modules/css-what/LICENSE +11 -0
  174. package/node_modules/css-what/lib/commonjs/index.d.ts +4 -0
  175. package/node_modules/css-what/lib/commonjs/index.d.ts.map +1 -0
  176. package/node_modules/css-what/lib/commonjs/index.js +23 -0
  177. package/node_modules/css-what/lib/commonjs/parse.d.ts +20 -0
  178. package/node_modules/css-what/lib/commonjs/parse.d.ts.map +1 -0
  179. package/node_modules/css-what/lib/commonjs/parse.js +425 -0
  180. package/node_modules/css-what/lib/commonjs/stringify.d.ts +8 -0
  181. package/node_modules/css-what/lib/commonjs/stringify.d.ts.map +1 -0
  182. package/node_modules/css-what/lib/commonjs/stringify.js +138 -0
  183. package/node_modules/css-what/lib/commonjs/types.d.ts +70 -0
  184. package/node_modules/css-what/lib/commonjs/types.d.ts.map +1 -0
  185. package/node_modules/css-what/lib/commonjs/types.js +42 -0
  186. package/node_modules/css-what/lib/es/index.d.ts +4 -0
  187. package/node_modules/css-what/lib/es/index.d.ts.map +1 -0
  188. package/node_modules/css-what/lib/es/index.js +3 -0
  189. package/node_modules/css-what/lib/es/parse.d.ts +20 -0
  190. package/node_modules/css-what/lib/es/parse.d.ts.map +1 -0
  191. package/node_modules/css-what/lib/es/parse.js +420 -0
  192. package/node_modules/css-what/lib/es/stringify.d.ts +8 -0
  193. package/node_modules/css-what/lib/es/stringify.d.ts.map +1 -0
  194. package/node_modules/css-what/lib/es/stringify.js +126 -0
  195. package/node_modules/css-what/lib/es/types.d.ts +70 -0
  196. package/node_modules/css-what/lib/es/types.d.ts.map +1 -0
  197. package/node_modules/css-what/lib/es/types.js +39 -0
  198. package/node_modules/css-what/package.json +59 -0
  199. package/node_modules/css-what/readme.md +69 -0
  200. package/node_modules/dom-serializer/LICENSE +11 -0
  201. package/node_modules/dom-serializer/README.md +109 -0
  202. package/node_modules/dom-serializer/lib/esm/foreignNames.d.ts +3 -0
  203. package/node_modules/dom-serializer/lib/esm/foreignNames.d.ts.map +1 -0
  204. package/node_modules/dom-serializer/lib/esm/foreignNames.js +100 -0
  205. package/node_modules/dom-serializer/lib/esm/index.d.ts +52 -0
  206. package/node_modules/dom-serializer/lib/esm/index.d.ts.map +1 -0
  207. package/node_modules/dom-serializer/lib/esm/index.js +190 -0
  208. package/node_modules/dom-serializer/lib/esm/package.json +1 -0
  209. package/node_modules/dom-serializer/lib/foreignNames.d.ts +3 -0
  210. package/node_modules/dom-serializer/lib/foreignNames.d.ts.map +1 -0
  211. package/node_modules/dom-serializer/lib/foreignNames.js +103 -0
  212. package/node_modules/dom-serializer/lib/index.d.ts +52 -0
  213. package/node_modules/dom-serializer/lib/index.d.ts.map +1 -0
  214. package/node_modules/dom-serializer/lib/index.js +229 -0
  215. package/node_modules/dom-serializer/package.json +69 -0
  216. package/node_modules/domelementtype/LICENSE +11 -0
  217. package/node_modules/domelementtype/lib/esm/index.d.ts +48 -0
  218. package/node_modules/domelementtype/lib/esm/index.d.ts.map +1 -0
  219. package/node_modules/domelementtype/lib/esm/index.js +51 -0
  220. package/node_modules/domelementtype/lib/esm/package.json +1 -0
  221. package/node_modules/domelementtype/lib/index.d.ts +48 -0
  222. package/node_modules/domelementtype/lib/index.d.ts.map +1 -0
  223. package/node_modules/domelementtype/lib/index.js +55 -0
  224. package/node_modules/domelementtype/package.json +54 -0
  225. package/node_modules/domelementtype/readme.md +1 -0
  226. package/node_modules/domhandler/LICENSE +11 -0
  227. package/node_modules/domhandler/lib/esm/index.d.ts +76 -0
  228. package/node_modules/domhandler/lib/esm/index.d.ts.map +1 -0
  229. package/node_modules/domhandler/lib/esm/index.js +146 -0
  230. package/node_modules/domhandler/lib/esm/node.d.ts +245 -0
  231. package/node_modules/domhandler/lib/esm/node.d.ts.map +1 -0
  232. package/node_modules/domhandler/lib/esm/node.js +338 -0
  233. package/node_modules/domhandler/lib/esm/package.json +1 -0
  234. package/node_modules/domhandler/lib/index.d.ts +76 -0
  235. package/node_modules/domhandler/lib/index.d.ts.map +1 -0
  236. package/node_modules/domhandler/lib/index.js +165 -0
  237. package/node_modules/domhandler/lib/node.d.ts +245 -0
  238. package/node_modules/domhandler/lib/node.d.ts.map +1 -0
  239. package/node_modules/domhandler/lib/node.js +474 -0
  240. package/node_modules/domhandler/package.json +73 -0
  241. package/node_modules/domhandler/readme.md +92 -0
  242. package/node_modules/domutils/LICENSE +11 -0
  243. package/node_modules/domutils/lib/esm/feeds.d.ts +71 -0
  244. package/node_modules/domutils/lib/esm/feeds.d.ts.map +1 -0
  245. package/node_modules/domutils/lib/esm/feeds.js +183 -0
  246. package/node_modules/domutils/lib/esm/feeds.js.map +1 -0
  247. package/node_modules/domutils/lib/esm/helpers.d.ts +59 -0
  248. package/node_modules/domutils/lib/esm/helpers.d.ts.map +1 -0
  249. package/node_modules/domutils/lib/esm/helpers.js +136 -0
  250. package/node_modules/domutils/lib/esm/helpers.js.map +1 -0
  251. package/node_modules/domutils/lib/esm/index.d.ts +10 -0
  252. package/node_modules/domutils/lib/esm/index.d.ts.map +1 -0
  253. package/node_modules/domutils/lib/esm/index.js +10 -0
  254. package/node_modules/domutils/lib/esm/index.js.map +1 -0
  255. package/node_modules/domutils/lib/esm/legacy.d.ts +79 -0
  256. package/node_modules/domutils/lib/esm/legacy.d.ts.map +1 -0
  257. package/node_modules/domutils/lib/esm/legacy.js +152 -0
  258. package/node_modules/domutils/lib/esm/legacy.js.map +1 -0
  259. package/node_modules/domutils/lib/esm/manipulation.d.ts +49 -0
  260. package/node_modules/domutils/lib/esm/manipulation.d.ts.map +1 -0
  261. package/node_modules/domutils/lib/esm/manipulation.js +134 -0
  262. package/node_modules/domutils/lib/esm/manipulation.js.map +1 -0
  263. package/node_modules/domutils/lib/esm/package.json +1 -0
  264. package/node_modules/domutils/lib/esm/querying.d.ts +64 -0
  265. package/node_modules/domutils/lib/esm/querying.d.ts.map +1 -0
  266. package/node_modules/domutils/lib/esm/querying.js +142 -0
  267. package/node_modules/domutils/lib/esm/querying.js.map +1 -0
  268. package/node_modules/domutils/lib/esm/stringify.d.ts +46 -0
  269. package/node_modules/domutils/lib/esm/stringify.d.ts.map +1 -0
  270. package/node_modules/domutils/lib/esm/stringify.js +81 -0
  271. package/node_modules/domutils/lib/esm/stringify.js.map +1 -0
  272. package/node_modules/domutils/lib/esm/traversal.d.ts +67 -0
  273. package/node_modules/domutils/lib/esm/traversal.d.ts.map +1 -0
  274. package/node_modules/domutils/lib/esm/traversal.js +112 -0
  275. package/node_modules/domutils/lib/esm/traversal.js.map +1 -0
  276. package/node_modules/domutils/lib/feeds.d.ts +71 -0
  277. package/node_modules/domutils/lib/feeds.d.ts.map +1 -0
  278. package/node_modules/domutils/lib/feeds.js +190 -0
  279. package/node_modules/domutils/lib/feeds.js.map +1 -0
  280. package/node_modules/domutils/lib/helpers.d.ts +59 -0
  281. package/node_modules/domutils/lib/helpers.d.ts.map +1 -0
  282. package/node_modules/domutils/lib/helpers.js +142 -0
  283. package/node_modules/domutils/lib/helpers.js.map +1 -0
  284. package/node_modules/domutils/lib/index.d.ts +10 -0
  285. package/node_modules/domutils/lib/index.d.ts.map +1 -0
  286. package/node_modules/domutils/lib/index.js +33 -0
  287. package/node_modules/domutils/lib/index.js.map +1 -0
  288. package/node_modules/domutils/lib/legacy.d.ts +79 -0
  289. package/node_modules/domutils/lib/legacy.d.ts.map +1 -0
  290. package/node_modules/domutils/lib/legacy.js +168 -0
  291. package/node_modules/domutils/lib/legacy.js.map +1 -0
  292. package/node_modules/domutils/lib/manipulation.d.ts +49 -0
  293. package/node_modules/domutils/lib/manipulation.d.ts.map +1 -0
  294. package/node_modules/domutils/lib/manipulation.js +142 -0
  295. package/node_modules/domutils/lib/manipulation.js.map +1 -0
  296. package/node_modules/domutils/lib/querying.d.ts +64 -0
  297. package/node_modules/domutils/lib/querying.d.ts.map +1 -0
  298. package/node_modules/domutils/lib/querying.js +155 -0
  299. package/node_modules/domutils/lib/querying.js.map +1 -0
  300. package/node_modules/domutils/lib/stringify.d.ts +46 -0
  301. package/node_modules/domutils/lib/stringify.d.ts.map +1 -0
  302. package/node_modules/domutils/lib/stringify.js +91 -0
  303. package/node_modules/domutils/lib/stringify.js.map +1 -0
  304. package/node_modules/domutils/lib/traversal.d.ts +67 -0
  305. package/node_modules/domutils/lib/traversal.d.ts.map +1 -0
  306. package/node_modules/domutils/lib/traversal.js +125 -0
  307. package/node_modules/domutils/lib/traversal.js.map +1 -0
  308. package/node_modules/domutils/package.json +79 -0
  309. package/node_modules/domutils/readme.md +31 -0
  310. package/node_modules/entities/LICENSE +11 -0
  311. package/node_modules/entities/lib/decode.d.ts +211 -0
  312. package/node_modules/entities/lib/decode.d.ts.map +1 -0
  313. package/node_modules/entities/lib/decode.js +536 -0
  314. package/node_modules/entities/lib/decode.js.map +1 -0
  315. package/node_modules/entities/lib/decode_codepoint.d.ts +19 -0
  316. package/node_modules/entities/lib/decode_codepoint.d.ts.map +1 -0
  317. package/node_modules/entities/lib/decode_codepoint.js +76 -0
  318. package/node_modules/entities/lib/decode_codepoint.js.map +1 -0
  319. package/node_modules/entities/lib/encode.d.ts +22 -0
  320. package/node_modules/entities/lib/encode.d.ts.map +1 -0
  321. package/node_modules/entities/lib/encode.js +77 -0
  322. package/node_modules/entities/lib/encode.js.map +1 -0
  323. package/node_modules/entities/lib/escape.d.ts +43 -0
  324. package/node_modules/entities/lib/escape.d.ts.map +1 -0
  325. package/node_modules/entities/lib/escape.js +122 -0
  326. package/node_modules/entities/lib/escape.js.map +1 -0
  327. package/node_modules/entities/lib/esm/decode.d.ts +211 -0
  328. package/node_modules/entities/lib/esm/decode.d.ts.map +1 -0
  329. package/node_modules/entities/lib/esm/decode.js +496 -0
  330. package/node_modules/entities/lib/esm/decode.js.map +1 -0
  331. package/node_modules/entities/lib/esm/decode_codepoint.d.ts +19 -0
  332. package/node_modules/entities/lib/esm/decode_codepoint.d.ts.map +1 -0
  333. package/node_modules/entities/lib/esm/decode_codepoint.js +71 -0
  334. package/node_modules/entities/lib/esm/decode_codepoint.js.map +1 -0
  335. package/node_modules/entities/lib/esm/encode.d.ts +22 -0
  336. package/node_modules/entities/lib/esm/encode.d.ts.map +1 -0
  337. package/node_modules/entities/lib/esm/encode.js +69 -0
  338. package/node_modules/entities/lib/esm/encode.js.map +1 -0
  339. package/node_modules/entities/lib/esm/escape.d.ts +43 -0
  340. package/node_modules/entities/lib/esm/escape.d.ts.map +1 -0
  341. package/node_modules/entities/lib/esm/escape.js +116 -0
  342. package/node_modules/entities/lib/esm/escape.js.map +1 -0
  343. package/node_modules/entities/lib/esm/generated/decode-data-html.d.ts +3 -0
  344. package/node_modules/entities/lib/esm/generated/decode-data-html.d.ts.map +1 -0
  345. package/node_modules/entities/lib/esm/generated/decode-data-html.js +7 -0
  346. package/node_modules/entities/lib/esm/generated/decode-data-html.js.map +1 -0
  347. package/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts +3 -0
  348. package/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts.map +1 -0
  349. package/node_modules/entities/lib/esm/generated/decode-data-xml.js +7 -0
  350. package/node_modules/entities/lib/esm/generated/decode-data-xml.js.map +1 -0
  351. package/node_modules/entities/lib/esm/generated/encode-html.d.ts +8 -0
  352. package/node_modules/entities/lib/esm/generated/encode-html.d.ts.map +1 -0
  353. package/node_modules/entities/lib/esm/generated/encode-html.js +10 -0
  354. package/node_modules/entities/lib/esm/generated/encode-html.js.map +1 -0
  355. package/node_modules/entities/lib/esm/index.d.ts +96 -0
  356. package/node_modules/entities/lib/esm/index.d.ts.map +1 -0
  357. package/node_modules/entities/lib/esm/index.js +99 -0
  358. package/node_modules/entities/lib/esm/index.js.map +1 -0
  359. package/node_modules/entities/lib/esm/package.json +1 -0
  360. package/node_modules/entities/lib/generated/decode-data-html.d.ts +3 -0
  361. package/node_modules/entities/lib/generated/decode-data-html.d.ts.map +1 -0
  362. package/node_modules/entities/lib/generated/decode-data-html.js +9 -0
  363. package/node_modules/entities/lib/generated/decode-data-html.js.map +1 -0
  364. package/node_modules/entities/lib/generated/decode-data-xml.d.ts +3 -0
  365. package/node_modules/entities/lib/generated/decode-data-xml.d.ts.map +1 -0
  366. package/node_modules/entities/lib/generated/decode-data-xml.js +9 -0
  367. package/node_modules/entities/lib/generated/decode-data-xml.js.map +1 -0
  368. package/node_modules/entities/lib/generated/encode-html.d.ts +8 -0
  369. package/node_modules/entities/lib/generated/encode-html.d.ts.map +1 -0
  370. package/node_modules/entities/lib/generated/encode-html.js +12 -0
  371. package/node_modules/entities/lib/generated/encode-html.js.map +1 -0
  372. package/node_modules/entities/lib/index.d.ts +96 -0
  373. package/node_modules/entities/lib/index.d.ts.map +1 -0
  374. package/node_modules/entities/lib/index.js +126 -0
  375. package/node_modules/entities/lib/index.js.map +1 -0
  376. package/node_modules/entities/package.json +90 -0
  377. package/node_modules/entities/readme.md +122 -0
  378. package/node_modules/he/LICENSE-MIT.txt +20 -0
  379. package/node_modules/he/README.md +379 -0
  380. package/node_modules/he/bin/he +148 -0
  381. package/node_modules/he/he.js +345 -0
  382. package/node_modules/he/man/he.1 +78 -0
  383. package/node_modules/he/package.json +58 -0
  384. package/node_modules/node-html-parser/CHANGELOG.md +137 -0
  385. package/node_modules/node-html-parser/LICENSE +7 -0
  386. package/node_modules/node-html-parser/README.md +365 -0
  387. package/node_modules/node-html-parser/dist/back.d.ts +1 -0
  388. package/node_modules/node-html-parser/dist/back.js +6 -0
  389. package/node_modules/node-html-parser/dist/index.d.ts +20 -0
  390. package/node_modules/node-html-parser/dist/index.js +32 -0
  391. package/node_modules/node-html-parser/dist/main.js +1646 -0
  392. package/node_modules/node-html-parser/dist/matcher.d.ts +6 -0
  393. package/node_modules/node-html-parser/dist/matcher.js +106 -0
  394. package/node_modules/node-html-parser/dist/nodes/comment.d.ts +20 -0
  395. package/node_modules/node-html-parser/dist/nodes/comment.js +57 -0
  396. package/node_modules/node-html-parser/dist/nodes/html.d.ts +240 -0
  397. package/node_modules/node-html-parser/dist/nodes/html.js +1218 -0
  398. package/node_modules/node-html-parser/dist/nodes/node.d.ts +24 -0
  399. package/node_modules/node-html-parser/dist/nodes/node.js +52 -0
  400. package/node_modules/node-html-parser/dist/nodes/text.d.ts +44 -0
  401. package/node_modules/node-html-parser/dist/nodes/text.js +144 -0
  402. package/node_modules/node-html-parser/dist/nodes/type.d.ts +6 -0
  403. package/node_modules/node-html-parser/dist/nodes/type.js +9 -0
  404. package/node_modules/node-html-parser/dist/parse.d.ts +1 -0
  405. package/node_modules/node-html-parser/dist/parse.js +5 -0
  406. package/node_modules/node-html-parser/dist/valid.d.ts +6 -0
  407. package/node_modules/node-html-parser/dist/valid.js +13 -0
  408. package/node_modules/node-html-parser/dist/void-tag.d.ts +7 -0
  409. package/node_modules/node-html-parser/dist/void-tag.js +29 -0
  410. package/node_modules/node-html-parser/package.json +114 -0
  411. package/node_modules/nth-check/LICENSE +11 -0
  412. package/node_modules/nth-check/README.md +136 -0
  413. package/node_modules/nth-check/lib/compile.d.ts +55 -0
  414. package/node_modules/nth-check/lib/compile.d.ts.map +1 -0
  415. package/node_modules/nth-check/lib/compile.js +121 -0
  416. package/node_modules/nth-check/lib/compile.js.map +1 -0
  417. package/node_modules/nth-check/lib/esm/compile.d.ts +55 -0
  418. package/node_modules/nth-check/lib/esm/compile.d.ts.map +1 -0
  419. package/node_modules/nth-check/lib/esm/compile.js +113 -0
  420. package/node_modules/nth-check/lib/esm/compile.js.map +1 -0
  421. package/node_modules/nth-check/lib/esm/index.d.ts +59 -0
  422. package/node_modules/nth-check/lib/esm/index.d.ts.map +1 -0
  423. package/node_modules/nth-check/lib/esm/index.js +63 -0
  424. package/node_modules/nth-check/lib/esm/index.js.map +1 -0
  425. package/node_modules/nth-check/lib/esm/package.json +1 -0
  426. package/node_modules/nth-check/lib/esm/parse.d.ts +9 -0
  427. package/node_modules/nth-check/lib/esm/parse.d.ts.map +1 -0
  428. package/node_modules/nth-check/lib/esm/parse.js +73 -0
  429. package/node_modules/nth-check/lib/esm/parse.js.map +1 -0
  430. package/node_modules/nth-check/lib/index.d.ts +59 -0
  431. package/node_modules/nth-check/lib/index.d.ts.map +1 -0
  432. package/node_modules/nth-check/lib/index.js +70 -0
  433. package/node_modules/nth-check/lib/index.js.map +1 -0
  434. package/node_modules/nth-check/lib/parse.d.ts +9 -0
  435. package/node_modules/nth-check/lib/parse.d.ts.map +1 -0
  436. package/node_modules/nth-check/lib/parse.js +77 -0
  437. package/node_modules/nth-check/lib/parse.js.map +1 -0
  438. package/node_modules/nth-check/package.json +78 -0
  439. package/package.json +154 -0
@@ -0,0 +1,707 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Installer = void 0;
4
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
5
+ const ssm = require("aws-cdk-lib/aws-ssm");
6
+ const core_1 = require("aws-cdk-lib/core");
7
+ const custom_resources_1 = require("aws-cdk-lib/custom-resources");
8
+ const cdk_nag_1 = require("cdk-nag");
9
+ const installer_function_1 = require("./installer-function");
10
+ const vscode_server_1 = require("../vscode-server");
11
+ ;
12
+ class Installer {
13
+ static ubuntu(options) {
14
+ return new (class extends Installer {
15
+ _bind(scope) {
16
+ let documentName;
17
+ const devServerBasePath = options.devServerBasePath ?? 'app';
18
+ const devServerPort = options.devServerPort ?? 8081;
19
+ if (options.documentName && options.documentName != '') {
20
+ documentName = options.documentName;
21
+ }
22
+ else {
23
+ const document = this.createSSMDocument(scope, devServerBasePath, devServerPort, options.vsCodeUser, options.homeFolder, vscode_server_1.LinuxFlavorType.UBUNTU_22);
24
+ documentName = document.name;
25
+ }
26
+ const cloudWatchLogGroupName = options.cloudWatchLogGroupName ?? `/aws/ssm/${documentName}`;
27
+ const installer = new CustomResourceInstaller(scope, {
28
+ instanceId: options.instanceId,
29
+ documentName: documentName,
30
+ cloudWatchLogGroupName: cloudWatchLogGroupName,
31
+ vsCodeUser: options.vsCodeUser,
32
+ vsCodePassword: options.vsCodePassword,
33
+ homeFolder: options.homeFolder,
34
+ });
35
+ return installer;
36
+ }
37
+ })();
38
+ }
39
+ static amazonLinux2023(options) {
40
+ return new (class extends Installer {
41
+ _bind(scope) {
42
+ let documentName;
43
+ const devServerBasePath = options.devServerBasePath ?? 'app';
44
+ const devServerPort = options.devServerPort ?? 8081;
45
+ if (options.documentName && options.documentName != '') {
46
+ documentName = options.documentName;
47
+ }
48
+ else {
49
+ const document = this.createSSMDocument(scope, devServerBasePath, devServerPort, options.vsCodeUser, options.homeFolder, vscode_server_1.LinuxFlavorType.AMAZON_LINUX_2023);
50
+ documentName = document.name;
51
+ }
52
+ const cloudWatchLogGroupName = options.cloudWatchLogGroupName ?? `/aws/ssm/${documentName}`;
53
+ const installer = new CustomResourceInstaller(scope, {
54
+ instanceId: options.instanceId,
55
+ documentName: documentName,
56
+ cloudWatchLogGroupName: cloudWatchLogGroupName,
57
+ vsCodeUser: options.vsCodeUser,
58
+ vsCodePassword: options.vsCodePassword,
59
+ homeFolder: options.homeFolder,
60
+ });
61
+ return installer;
62
+ }
63
+ })();
64
+ }
65
+ /**
66
+ * @internal
67
+ */
68
+ constructor() { }
69
+ createSSMDocument(scope, devServerBasePath, devServerPort, vsCodeUser, homeFolder, linuxFlavor) {
70
+ let ssmDocument;
71
+ switch (linuxFlavor) {
72
+ case vscode_server_1.LinuxFlavorType.UBUNTU_22:
73
+ case vscode_server_1.LinuxFlavorType.UBUNTU_24:
74
+ // Create an SSM document with multiple actions to install the software
75
+ ssmDocument = new ssm.CfnDocument(scope, 'ssm-document-ubuntu', {
76
+ name: `vscode-server-ubuntu-${core_1.Stack.of(scope).stackName}`,
77
+ documentType: 'Command',
78
+ content: {
79
+ schemaVersion: '2.2',
80
+ description: 'Bootstrap VSCode code-server instance',
81
+ parameters: {
82
+ VSCodePassword: {
83
+ type: 'String',
84
+ default: core_1.Stack.of(scope).stackId,
85
+ },
86
+ NodeVersion: {
87
+ type: 'String',
88
+ default: '20',
89
+ allowedValues: [
90
+ '22',
91
+ '20',
92
+ '18',
93
+ ],
94
+ },
95
+ DotNetVersion: {
96
+ type: 'String',
97
+ default: '8.0',
98
+ allowedValues: [
99
+ '8.0',
100
+ '7.0',
101
+ ],
102
+ },
103
+ },
104
+ // all mainSteps scripts are in in /var/lib/amazon/ssm/<instanceid>/document/orchestration/<uuid>/<StepName>/_script.sh
105
+ mainSteps: [
106
+ {
107
+ action: 'aws:configurePackage',
108
+ name: 'InstallCloudWatchAgent',
109
+ inputs: {
110
+ name: 'AmazonCloudWatchAgent',
111
+ action: 'Install',
112
+ },
113
+ },
114
+ {
115
+ action: 'aws:runDocument',
116
+ name: 'ConfigureCloudWatchAgent',
117
+ inputs: {
118
+ documentType: 'SSMDocument',
119
+ documentPath: 'AmazonCloudWatch-ManageAgent',
120
+ documentParameters: {
121
+ action: 'configure',
122
+ mode: 'ec2',
123
+ optionalConfigurationSource: 'default',
124
+ optionalRestart: 'yes',
125
+ },
126
+ },
127
+ },
128
+ {
129
+ action: 'aws:runShellScript',
130
+ name: 'InstallAptPackagesApt',
131
+ inputs: {
132
+ runCommand: [
133
+ '#!/bin/bash',
134
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q apt-utils',
135
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q needrestart unattended-upgrades',
136
+ 'sed -i \'s/#$nrconf{kernelhints} = -1;/$nrconf{kernelhints} = 0;/\' /etc/needrestart/needrestart.conf',
137
+ 'sed -i \'s/#$nrconf{verbosity} = 2;/$nrconf{verbosity} = 0;/\' /etc/needrestart/needrestart.conf',
138
+ 'sed -i "s/#\$nrconf{restart} = \'i\';/\$nrconf{restart} = \'a\';/" /etc/needrestart/needrestart.conf',
139
+ 'echo "Apt helper packages added. Checking configuration"',
140
+ 'cat /etc/needrestart/needrestart.conf',
141
+ ],
142
+ },
143
+ },
144
+ {
145
+ action: 'aws:runShellScript',
146
+ name: 'InstallBasePackagesApt',
147
+ inputs: {
148
+ runCommand: [
149
+ '#!/bin/bash',
150
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q curl gnupg whois argon2 openssl locales locales-all unzip apt-transport-https ca-certificates software-properties-common nginx',
151
+ ],
152
+ },
153
+ },
154
+ {
155
+ action: 'aws:runShellScript',
156
+ name: 'AddUserApt',
157
+ inputs: {
158
+ runCommand: [
159
+ '#!/bin/bash',
160
+ 'echo \'Adding user: ${VSCodeUser}\'',
161
+ `adduser --disabled-password --gecos '' ${vsCodeUser}`,
162
+ `echo "${vsCodeUser}:{{ VSCodePassword }}" | chpasswd`,
163
+ `usermod -aG sudo ${vsCodeUser}`,
164
+ `tee /etc/sudoers.d/91-vscode-user <<EOF
165
+ ${vsCodeUser} ALL=(ALL) NOPASSWD:ALL
166
+ EOF`,
167
+ `mkdir -p /home/${vsCodeUser} && chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
168
+ 'echo "User added. Checking configuration"',
169
+ `getent passwd ${vsCodeUser}`,
170
+ ],
171
+ },
172
+ },
173
+ {
174
+ action: 'aws:runShellScript',
175
+ name: 'InstallNodeApt',
176
+ inputs: {
177
+ runCommand: [
178
+ '#!/bin/bash',
179
+ 'curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /usr/share/keyrings/nodesource.gpg',
180
+ 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_{{ NodeVersion }}.x nodistro main" > /etc/apt/sources.list.d/nodesource.list',
181
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q nodejs',
182
+ 'npm install -g npm@latest',
183
+ 'echo "Node and npm installed. Checking configuration"',
184
+ 'node -v',
185
+ 'npm -v',
186
+ ],
187
+ },
188
+ },
189
+ {
190
+ action: 'aws:runShellScript',
191
+ name: 'InstallDockerApt',
192
+ inputs: {
193
+ runCommand: [
194
+ '#!/bin/bash',
195
+ 'curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg',
196
+ 'echo "deb [signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release --codename --short) stable" > /etc/apt/sources.list.d/docker.list',
197
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q docker-ce docker-ce-cli containerd.io',
198
+ `systemctl restart code-server@${vsCodeUser}.service`,
199
+ 'systemctl start docker.service',
200
+ 'echo "Docker installed. Checking configuration"',
201
+ 'docker --version',
202
+ 'systemctl status docker.service',
203
+ ],
204
+ },
205
+ },
206
+ {
207
+ action: 'aws:runShellScript',
208
+ name: 'InstallGitApt',
209
+ inputs: {
210
+ runCommand: [
211
+ '#!/bin/bash',
212
+ 'add-apt-repository ppa:git-core/ppa',
213
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q git',
214
+ `sudo -u ${vsCodeUser} git config --global user.email "${vsCodeUser}@example.com"`,
215
+ `sudo -u ${vsCodeUser} git config --global user.name "Workshop ${vsCodeUser}"`,
216
+ `sudo -u ${vsCodeUser} git config --global init.defaultBranch "main"`,
217
+ 'echo "Git installed. Checking configuration"',
218
+ 'git --version',
219
+ ],
220
+ },
221
+ },
222
+ {
223
+ action: 'aws:runShellScript',
224
+ name: 'InstallPythonApt',
225
+ inputs: {
226
+ runCommand: [
227
+ // Ubuntu 22 default is Python 3.10
228
+ // Ubuntu 24 default is Python 3.12
229
+ // The default installed Python version will map to Python3
230
+ '#!/bin/bash',
231
+ 'apt-get -q update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q python3-pip python3-venv python3-boto3 python3-pytest',
232
+ `echo 'alias pytest=pytest-3' >> /home/${vsCodeUser}/.bashrc`,
233
+ `systemctl restart code-server@${vsCodeUser}.service`,
234
+ 'systemctl start multipathd.service packagekit.service',
235
+ 'systemctl restart unattended-upgrades.service',
236
+ 'echo "Python and Pip installed. Checking configuration"',
237
+ 'python3 --version',
238
+ 'pip3 --version',
239
+ ],
240
+ },
241
+ },
242
+ {
243
+ action: 'aws:runShellScript',
244
+ name: 'InstallAWSCLI',
245
+ inputs: {
246
+ runCommand: [
247
+ '#!/bin/bash',
248
+ 'curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip -o /tmp/aws-cli.zip',
249
+ 'unzip -q -d /tmp /tmp/aws-cli.zip',
250
+ 'sudo /tmp/aws/install',
251
+ 'rm -rf /tmp/aws',
252
+ 'echo "AWS CLI installed. Checking configuration"',
253
+ 'aws --version',
254
+ ],
255
+ },
256
+ },
257
+ {
258
+ action: 'aws:runShellScript',
259
+ name: 'ConfigureCodeServer',
260
+ inputs: {
261
+ runCommand: [
262
+ '#!/bin/bash',
263
+ `export HOME=/home/${vsCodeUser}`,
264
+ 'curl -fsSL https://code-server.dev/install.sh | bash -s -- 2>&1',
265
+ `systemctl enable --now code-server@${vsCodeUser} 2>&1`,
266
+ `tee /etc/nginx/conf.d/code-server.conf <<EOF
267
+ server {
268
+ listen 80;
269
+ listen [::]:80;
270
+ # server_name distribution.distributionDomainName;
271
+ server_name *.cloudfront.net;
272
+ location / {
273
+ proxy_pass http://localhost:8080/;
274
+ proxy_set_header Host \\$host;
275
+ proxy_set_header Upgrade \\$http_upgrade;
276
+ proxy_set_header Connection upgrade;
277
+ proxy_set_header Accept-Encoding gzip;
278
+ }
279
+ location /${devServerBasePath} {
280
+ proxy_pass http://localhost:${devServerPort}/${devServerBasePath};
281
+ proxy_set_header Host \\$host;
282
+ proxy_set_header Upgrade \\$http_upgrade;
283
+ proxy_set_header Connection upgrade;
284
+ proxy_set_header Accept-Encoding gzip;
285
+ }
286
+ }
287
+ EOF`,
288
+ `mkdir -p /home/${vsCodeUser}/.config/code-server`,
289
+ `tee /home/${vsCodeUser}/.config/code-server/config.yaml <<EOF
290
+ cert: false
291
+ auth: password
292
+ hashed-password: "$(echo -n {{ VSCodePassword }} | argon2 $(openssl rand -base64 12) -e)"
293
+ EOF`,
294
+ `mkdir -p /home/${vsCodeUser}/.local/share/code-server/User/`,
295
+ `touch /home/${vsCodeUser}/.hushlogin`,
296
+ `mkdir -p ${homeFolder} && chown -R ${vsCodeUser}:${vsCodeUser} ${homeFolder}`,
297
+ `tee /home/${vsCodeUser}/.local/share/code-server/User/settings.json <<EOF
298
+ {
299
+ "extensions.autoUpdate": false,
300
+ "extensions.autoCheckUpdates": false,
301
+ "telemetry.telemetryLevel": "off",
302
+ "security.workspace.trust.startupPrompt": "never",
303
+ "security.workspace.trust.enabled": false,
304
+ "security.workspace.trust.banner": "never",
305
+ "security.workspace.trust.emptyWindow": false,
306
+ "python.testing.pytestEnabled": true,
307
+ "auto-run-command.rules": [
308
+ {
309
+ "command": "workbench.action.terminal.new"
310
+ }
311
+ ]
312
+ }
313
+ EOF`,
314
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
315
+ `systemctl restart code-server@${vsCodeUser}`,
316
+ 'systemctl restart nginx',
317
+ `sudo -u ${vsCodeUser} --login code-server --install-extension AmazonWebServices.aws-toolkit-vscode --force`,
318
+ `sudo -u ${vsCodeUser} --login code-server --install-extension AmazonWebServices.amazon-q-vscode --force`,
319
+ `sudo -u ${vsCodeUser} --login code-server --install-extension synedra.auto-run-command --force`,
320
+ `sudo -u ${vsCodeUser} --login code-server --install-extension vscjava.vscode-java-pack --force`,
321
+ `sudo -u ${vsCodeUser} --login code-server --install-extension ms-vscode.live-server --force`,
322
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
323
+ 'echo "Nginx installed. Checking configuration"',
324
+ 'nginx -t 2>&1',
325
+ 'systemctl status nginx',
326
+ 'echo "CodeServer installed. Checking configuration"',
327
+ 'code-server -v',
328
+ `systemctl status code-server@${vsCodeUser}`,
329
+ ],
330
+ },
331
+ },
332
+ {
333
+ action: 'aws:runShellScript',
334
+ name: 'UpdateProfile',
335
+ inputs: {
336
+ runCommand: [
337
+ '#!/bin/bash',
338
+ 'echo LANG=en_US.utf-8 >> /etc/environment',
339
+ 'echo LC_ALL=en_US.UTF-8 >> /etc/environment',
340
+ `echo 'PATH=$PATH:/home/${vsCodeUser}/.local/bin' >> /home/${vsCodeUser}/.bashrc`,
341
+ `echo 'export PATH' >> /home/${vsCodeUser}/.bashrc`,
342
+ `echo 'export AWS_REGION=${core_1.Stack.of(scope).region}' >> /home/${vsCodeUser}/.bashrc`,
343
+ `echo 'export AWS_ACCOUNTID=${core_1.Stack.of(scope).account}' >> /home/${vsCodeUser}/.bashrc`,
344
+ `echo 'export NEXT_TELEMETRY_DISABLED=1' >> /home/${vsCodeUser}/.bashrc`,
345
+ `echo "export PS1='\\[\\033[01;32m\\]\\u:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /home/${vsCodeUser}/.bashrc`,
346
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
347
+ ],
348
+ },
349
+ },
350
+ {
351
+ action: 'aws:runShellScript',
352
+ name: 'InstallCDK',
353
+ inputs: {
354
+ runCommand: [
355
+ '#!/bin/bash',
356
+ 'npm install -g aws-cdk',
357
+ 'echo "AWS CDK installed. Checking configuration"',
358
+ 'cdk --version',
359
+ ],
360
+ },
361
+ },
362
+ ],
363
+ },
364
+ });
365
+ break;
366
+ case vscode_server_1.LinuxFlavorType.AMAZON_LINUX_2023:
367
+ ssmDocument = new ssm.CfnDocument(scope, 'ssm-document-al2023', {
368
+ name: `vscode-server-al2023-${core_1.Stack.of(scope).stackName}`,
369
+ documentType: 'Command',
370
+ content: {
371
+ schemaVersion: '2.2',
372
+ description: 'Bootstrap VSCode code-server instance',
373
+ parameters: {
374
+ VSCodePassword: {
375
+ type: 'String',
376
+ default: core_1.Stack.of(scope).stackId,
377
+ },
378
+ NodeVersion: {
379
+ type: 'String',
380
+ default: '20',
381
+ allowedValues: [
382
+ '22',
383
+ '20',
384
+ '18',
385
+ ],
386
+ },
387
+ DotNetVersion: {
388
+ type: 'String',
389
+ default: '8.0',
390
+ allowedValues: [
391
+ '8.0',
392
+ '7.0',
393
+ ],
394
+ },
395
+ },
396
+ // all mainSteps scripts are in in /var/lib/amazon/ssm/<instanceid>/document/orchestration/<uuid>/<StepName>/_script.sh
397
+ mainSteps: [
398
+ {
399
+ action: 'aws:configurePackage',
400
+ name: 'InstallCloudWatchAgent',
401
+ inputs: {
402
+ name: 'AmazonCloudWatchAgent',
403
+ action: 'Install',
404
+ },
405
+ },
406
+ {
407
+ action: 'aws:runDocument',
408
+ name: 'ConfigureCloudWatchAgent',
409
+ inputs: {
410
+ documentType: 'SSMDocument',
411
+ documentPath: 'AmazonCloudWatch-ManageAgent',
412
+ documentParameters: {
413
+ action: 'configure',
414
+ mode: 'ec2',
415
+ optionalConfigurationSource: 'default',
416
+ optionalRestart: 'yes',
417
+ },
418
+ },
419
+ },
420
+ {
421
+ action: 'aws:runShellScript',
422
+ name: 'InstallBasePackagesDnf',
423
+ inputs: {
424
+ runCommand: [
425
+ '#!/bin/bash',
426
+ 'dnf install -y --allowerasing whois argon2 unzip nginx curl gnupg openssl',
427
+ ],
428
+ },
429
+ },
430
+ {
431
+ action: 'aws:runShellScript',
432
+ name: 'AddUserDnf',
433
+ inputs: {
434
+ runCommand: [
435
+ '#!/bin/bash',
436
+ `echo 'Adding user: ${vsCodeUser}'`,
437
+ `adduser -c '' ${vsCodeUser}`,
438
+ `passwd -l ${vsCodeUser}`,
439
+ `echo "${vsCodeUser}:{{ VSCodePassword }}" | chpasswd`,
440
+ `usermod -aG wheel ${vsCodeUser}`,
441
+ 'echo "User added. Checking configuration"',
442
+ `getent passwd ${vsCodeUser}`,
443
+ ],
444
+ },
445
+ },
446
+ {
447
+ action: 'aws:runShellScript',
448
+ name: 'InstallNodeDnf',
449
+ inputs: {
450
+ runCommand: [
451
+ '#!/bin/bash',
452
+ 'dnf install -y nodejs20 npm',
453
+ 'ln -s -f /usr/bin/node-20 /usr/bin/node',
454
+ 'npm install -g npm@latest',
455
+ 'echo "Node and npm installed. Checking configuration"',
456
+ 'node -v',
457
+ 'npm -v',
458
+ ],
459
+ },
460
+ },
461
+ {
462
+ action: 'aws:runShellScript',
463
+ name: 'InstallDockerDnf',
464
+ inputs: {
465
+ runCommand: [
466
+ '#!/bin/bash',
467
+ 'dnf install -y docker',
468
+ `usermod -aG docker ${vsCodeUser}`,
469
+ `systemctl restart code-server@${vsCodeUser}.service`,
470
+ 'systemctl start docker.service',
471
+ 'echo "Docker installed. Checking configuration"',
472
+ 'docker --version',
473
+ 'systemctl status docker.service',
474
+ ],
475
+ },
476
+ },
477
+ {
478
+ action: 'aws:runShellScript',
479
+ name: 'InstallGitDnf',
480
+ inputs: {
481
+ runCommand: [
482
+ '#!/bin/bash',
483
+ 'dnf install -y git',
484
+ `sudo -u ${vsCodeUser} git config --global user.email "${vsCodeUser}@example.com"`,
485
+ `sudo -u ${vsCodeUser} git config --global user.name "Workshop ${vsCodeUser}"`,
486
+ `sudo -u ${vsCodeUser} git config --global init.defaultBranch "main"`,
487
+ 'echo "Git installed. Checking configuration"',
488
+ 'git --version',
489
+ ],
490
+ },
491
+ },
492
+ {
493
+ action: 'aws:runShellScript',
494
+ name: 'InstallPythonDnf',
495
+ inputs: {
496
+ runCommand: [
497
+ // AL2023 currently ships with Python 3.9 preinstalled, but 3.11 is available in the repository
498
+ // Install 3.11 alongside 3.9 and setup some alias so that 3.11 is loaded when participant runs Python3
499
+ // If Python 3.12 become available, update below
500
+ '#!/bin/bash',
501
+ 'dnf install -y python3.11 python3.11-pip python3-virtualenv python3-pytest python3-boto3',
502
+ `echo 'alias pytest=pytest-3' >> /home/${vsCodeUser}/.bashrc`,
503
+ `echo 'alias python3=python3.11' >> /home/${vsCodeUser}/.bashrc`,
504
+ `echo 'alias pip3=pip3.11' >> /home/${vsCodeUser}/.bashrc`,
505
+ 'echo \'alias=python3=python3.11\' >> ~/.bashrc',
506
+ 'echo \'alias pip3=pip3.11\' >> ~/.bashrc',
507
+ 'python3.11 -m pip install --upgrade pip 2>&1',
508
+ 'echo "Python and Pip installed. Checking configuration"',
509
+ 'python3.11 --version',
510
+ 'python3.11 -m pip --version 2>&1',
511
+ ],
512
+ },
513
+ },
514
+ // add go, dotnet
515
+ {
516
+ action: 'aws:runShellScript',
517
+ name: 'InstallAWSCLI',
518
+ inputs: {
519
+ runCommand: [
520
+ '#!/bin/bash',
521
+ 'curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip -o /tmp/aws-cli.zip',
522
+ 'unzip -q -d /tmp /tmp/aws-cli.zip',
523
+ 'sudo /tmp/aws/install',
524
+ 'rm -rf /tmp/aws',
525
+ 'echo "AWS CLI installed. Checking configuration"',
526
+ 'aws --version',
527
+ ],
528
+ },
529
+ },
530
+ {
531
+ action: 'aws:runShellScript',
532
+ name: 'ConfigureCodeServer',
533
+ inputs: {
534
+ runCommand: [
535
+ '#!/bin/bash',
536
+ `export HOME=/home/${vsCodeUser}`,
537
+ 'curl -fsSL https://code-server.dev/install.sh | bash -s -- 2>&1',
538
+ `systemctl enable --now code-server@${vsCodeUser} 2>&1`,
539
+ `tee /etc/nginx/conf.d/code-server.conf <<EOF
540
+ server {
541
+ listen 80;
542
+ listen [::]:80;
543
+ # server_name distribution.distributionDomainName;
544
+ server_name *.cloudfront.net;
545
+ location / {
546
+ proxy_pass http://localhost:8080/;
547
+ proxy_set_header Host \\$host;
548
+ proxy_set_header Upgrade \\$http_upgrade;
549
+ proxy_set_header Connection upgrade;
550
+ proxy_set_header Accept-Encoding gzip;
551
+ }
552
+ location /${devServerBasePath} {
553
+ proxy_pass http://localhost:${devServerPort}/${devServerBasePath};
554
+ proxy_set_header Host \\$host;
555
+ proxy_set_header Upgrade \\$http_upgrade;
556
+ proxy_set_header Connection upgrade;
557
+ proxy_set_header Accept-Encoding gzip;
558
+ }
559
+ }
560
+ EOF`,
561
+ `mkdir -p /home/${vsCodeUser}/.config/code-server`,
562
+ `tee /home/${vsCodeUser}/.config/code-server/config.yaml <<EOF
563
+ cert: false
564
+ auth: password
565
+ hashed-password: "$(echo -n {{ VSCodePassword }} | argon2 $(openssl rand -base64 12) -e)"
566
+ EOF`,
567
+ `mkdir -p /home/${vsCodeUser}/.local/share/code-server/User/`,
568
+ `touch /home/${vsCodeUser}/.hushlogin`,
569
+ `mkdir -p ${homeFolder} && chown -R ${vsCodeUser}:${vsCodeUser} ${homeFolder}`,
570
+ `tee /home/${vsCodeUser}/.local/share/code-server/User/settings.json <<EOF
571
+ {
572
+ "extensions.autoUpdate": false,
573
+ "extensions.autoCheckUpdates": false,
574
+ "telemetry.telemetryLevel": "off",
575
+ "security.workspace.trust.startupPrompt": "never",
576
+ "security.workspace.trust.enabled": false,
577
+ "security.workspace.trust.banner": "never",
578
+ "security.workspace.trust.emptyWindow": false,
579
+ "python.testing.pytestEnabled": true,
580
+ "auto-run-command.rules": [
581
+ {
582
+ "command": "workbench.action.terminal.new"
583
+ }
584
+ ]
585
+ }
586
+ EOF`,
587
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
588
+ `systemctl restart code-server@${vsCodeUser}`,
589
+ 'systemctl restart nginx',
590
+ `sudo -u ${vsCodeUser} --login code-server --install-extension AmazonWebServices.aws-toolkit-vscode --force`,
591
+ `sudo -u ${vsCodeUser} --login code-server --install-extension AmazonWebServices.amazon-q-vscode --force`,
592
+ `sudo -u ${vsCodeUser} --login code-server --install-extension synedra.auto-run-command --force`,
593
+ `sudo -u ${vsCodeUser} --login code-server --install-extension vscjava.vscode-java-pack --force`,
594
+ `sudo -u ${vsCodeUser} --login code-server --install-extension ms-vscode.live-server --force`,
595
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
596
+ 'echo "Nginx installed. Checking configuration"',
597
+ 'nginx -t 2>&1',
598
+ 'systemctl status nginx',
599
+ 'echo "CodeServer installed. Checking configuration"',
600
+ 'code-server -v',
601
+ `systemctl status code-server@${vsCodeUser}`,
602
+ ],
603
+ },
604
+ },
605
+ {
606
+ action: 'aws:runShellScript',
607
+ name: 'UpdateProfile',
608
+ inputs: {
609
+ runCommand: [
610
+ '#!/bin/bash',
611
+ 'echo LANG=en_US.utf-8 >> /etc/environment',
612
+ 'echo LC_ALL=en_US.UTF-8 >> /etc/environment',
613
+ `echo 'PATH=$PATH:/home/${vsCodeUser}/.local/bin' >> /home/${vsCodeUser}/.bashrc`,
614
+ `echo 'export PATH' >> /home/${vsCodeUser}/.bashrc`,
615
+ `echo 'export AWS_REGION=${core_1.Stack.of(scope).region}' >> /home/${vsCodeUser}/.bashrc`,
616
+ `echo 'export AWS_ACCOUNTID=${core_1.Stack.of(scope).account}' >> /home/${vsCodeUser}/.bashrc`,
617
+ `echo 'export NEXT_TELEMETRY_DISABLED=1' >> /home/${vsCodeUser}/.bashrc`,
618
+ `echo "export PS1='\\[\\033[01;32m\\]\\u:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> /home/${vsCodeUser}/.bashrc`,
619
+ `chown -R ${vsCodeUser}:${vsCodeUser} /home/${vsCodeUser}`,
620
+ ],
621
+ },
622
+ },
623
+ {
624
+ action: 'aws:runShellScript',
625
+ name: 'InstallCDK',
626
+ inputs: {
627
+ runCommand: [
628
+ '#!/bin/bash',
629
+ 'npm install -g aws-cdk',
630
+ 'echo "AWS CDK installed. Checking configuration"',
631
+ 'cdk --version',
632
+ ],
633
+ },
634
+ },
635
+ ],
636
+ },
637
+ });
638
+ break;
639
+ default:
640
+ throw new Error(`Unsupported Linux flavor: ${linuxFlavor}`);
641
+ }
642
+ return ssmDocument;
643
+ }
644
+ }
645
+ exports.Installer = Installer;
646
+ class CustomResourceInstaller extends Installer {
647
+ constructor(scope, options) {
648
+ super();
649
+ const onEvent = new installer_function_1.InstallerFunction(scope, 'InstallerOnEventHandler', {
650
+ timeout: core_1.Duration.seconds(300), // TODO configurable
651
+ memorySize: 512, // TODO configurable
652
+ });
653
+ cdk_nag_1.NagSuppressions.addResourceSuppressions([
654
+ onEvent,
655
+ ], [
656
+ { id: 'AwsSolutions-IAM4', reason: 'For this event handler we do not need to restrict managed policies' },
657
+ { id: 'AwsSolutions-L1', reason: 'For this lambda the latest runtime is not needed' },
658
+ ], true);
659
+ const documentArn = core_1.Arn.format({
660
+ service: 'ssm',
661
+ resource: 'document',
662
+ resourceName: options.documentName,
663
+ }, core_1.Stack.of(scope));
664
+ const cwManageAgentArn = core_1.Arn.format({
665
+ service: 'ssm',
666
+ resource: 'document',
667
+ resourceName: 'AmazonCloudWatch-ManageAgent',
668
+ }, core_1.Stack.of(scope));
669
+ const targetEc2InstanceArn = core_1.Arn.format({
670
+ service: 'ec2',
671
+ resource: 'instance',
672
+ resourceName: options.instanceId,
673
+ }, core_1.Stack.of(scope));
674
+ onEvent.addToRolePolicy(new aws_iam_1.PolicyStatement({
675
+ actions: [
676
+ 'ssm:SendCommand',
677
+ ],
678
+ resources: [
679
+ documentArn,
680
+ cwManageAgentArn,
681
+ targetEc2InstanceArn,
682
+ ],
683
+ }));
684
+ const provider = new custom_resources_1.Provider(scope, 'InstallerProvider', {
685
+ onEventHandler: onEvent,
686
+ });
687
+ cdk_nag_1.NagSuppressions.addResourceSuppressions([
688
+ provider,
689
+ ], [
690
+ { id: 'AwsSolutions-IAM4', reason: 'For this provider we do not need to restrict managed policies' },
691
+ { id: 'AwsSolutions-IAM5', reason: 'For this provider wildcards are fine' },
692
+ { id: 'AwsSolutions-L1', reason: 'For this provider the latest runtime is not needed' },
693
+ ], true);
694
+ new core_1.CustomResource(scope, 'SSMInstallerCustomResource', {
695
+ serviceToken: provider.serviceToken,
696
+ properties: {
697
+ ServiceTimeout: 305, // TODO configurable
698
+ InstanceId: options.instanceId,
699
+ DocumentName: options.documentName,
700
+ CloudWatchLogGroupName: options.cloudWatchLogGroupName,
701
+ VSCodePassword: options.vsCodePassword,
702
+ },
703
+ });
704
+ }
705
+ _bind() { }
706
+ }
707
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2luc3RhbGxlci9pbnN0YWxsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaURBQXNEO0FBRXRELDJDQUEyQztBQUMzQywyQ0FBd0U7QUFDeEUsbUVBQXdEO0FBQ3hELHFDQUEwQztBQUUxQyw2REFBeUQ7QUFDekQsb0RBQW1EO0FBa0RsRCxDQUFDO0FBSUYsTUFBc0IsU0FBUztJQUN0QixNQUFNLENBQUMsTUFBTSxDQUFDLE9BQXlCO1FBQzVDLE9BQU8sSUFBSSxDQUFDLEtBQU0sU0FBUSxTQUFTO1lBQzFCLEtBQUssQ0FBQyxLQUFnQjtnQkFDM0IsSUFBSSxZQUFZLENBQUM7Z0JBQ2pCLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQztnQkFDN0QsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUM7Z0JBQ3BELElBQUksT0FBTyxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUMsWUFBWSxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUN2RCxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztnQkFDdEMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FDckMsS0FBSyxFQUNMLGlCQUFpQixFQUNqQixhQUFhLEVBQ2IsT0FBTyxDQUFDLFVBQVUsRUFDbEIsT0FBTyxDQUFDLFVBQVUsRUFDbEIsK0JBQWUsQ0FBQyxTQUFTLENBQzFCLENBQUM7b0JBQ0YsWUFBWSxHQUFHLFFBQVEsQ0FBQyxJQUFLLENBQUM7Z0JBQ2hDLENBQUM7Z0JBRUQsTUFBTSxzQkFBc0IsR0FBRyxPQUFPLENBQUMsc0JBQXNCLElBQUksWUFBWSxZQUFZLEVBQUUsQ0FBQztnQkFFNUYsTUFBTSxTQUFTLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxLQUFLLEVBQUU7b0JBQ25ELFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtvQkFDOUIsWUFBWSxFQUFFLFlBQVk7b0JBQzFCLHNCQUFzQixFQUFFLHNCQUFzQjtvQkFDOUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO29CQUM5QixjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWM7b0JBQ3RDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtpQkFDL0IsQ0FBQyxDQUFDO2dCQUVILE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7U0FDRixDQUFDLEVBQUUsQ0FBQztJQUNQLENBQUM7SUFFTSxNQUFNLENBQUMsZUFBZSxDQUFDLE9BQXlCO1FBQ3JELE9BQU8sSUFBSSxDQUFDLEtBQU0sU0FBUSxTQUFTO1lBQzFCLEtBQUssQ0FBQyxLQUFnQjtnQkFDM0IsSUFBSSxZQUFZLENBQUM7Z0JBQ2pCLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQztnQkFDN0QsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUM7Z0JBQ3BELElBQUksT0FBTyxDQUFDLFlBQVksSUFBSSxPQUFPLENBQUMsWUFBWSxJQUFJLEVBQUUsRUFBRSxDQUFDO29CQUN2RCxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztnQkFDdEMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FDckMsS0FBSyxFQUNMLGlCQUFpQixFQUNqQixhQUFhLEVBQ2IsT0FBTyxDQUFDLFVBQVUsRUFDbEIsT0FBTyxDQUFDLFVBQVUsRUFDbEIsK0JBQWUsQ0FBQyxpQkFBaUIsQ0FDbEMsQ0FBQztvQkFDRixZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUssQ0FBQztnQkFDaEMsQ0FBQztnQkFFRCxNQUFNLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsSUFBSSxZQUFZLFlBQVksRUFBRSxDQUFDO2dCQUU1RixNQUFNLFNBQVMsR0FBRyxJQUFJLHVCQUF1QixDQUFDLEtBQUssRUFBRTtvQkFDbkQsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO29CQUM5QixZQUFZLEVBQUUsWUFBWTtvQkFDMUIsc0JBQXNCLEVBQUUsc0JBQXNCO29CQUM5QyxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7b0JBQzlCLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztvQkFDdEMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO2lCQUMvQixDQUFDLENBQUM7Z0JBR0gsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztTQUNGLENBQUMsRUFBRSxDQUFDO0lBQ1AsQ0FBQztJQVFEOztPQUVHO0lBQ0gsZ0JBQTBCLENBQUM7SUFPbkIsaUJBQWlCLENBQ3ZCLEtBQWdCLEVBQ2hCLGlCQUF5QixFQUN6QixhQUFxQixFQUNyQixVQUFrQixFQUNsQixVQUFrQixFQUNsQixXQUE0QjtRQUU1QixJQUFJLFdBQTRCLENBQUM7UUFDakMsUUFBUSxXQUFXLEVBQUUsQ0FBQztZQUNwQixLQUFLLCtCQUFlLENBQUMsU0FBUyxDQUFDO1lBQy9CLEtBQUssK0JBQWUsQ0FBQyxTQUFTO2dCQUM1Qix1RUFBdUU7Z0JBQ3ZFLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLHFCQUFxQixFQUFFO29CQUM5RCxJQUFJLEVBQUUsd0JBQXdCLFlBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsU0FBUyxFQUFFO29CQUN6RCxZQUFZLEVBQUUsU0FBUztvQkFDdkIsT0FBTyxFQUFFO3dCQUNQLGFBQWEsRUFBRSxLQUFLO3dCQUNwQixXQUFXLEVBQUUsdUNBQXVDO3dCQUNwRCxVQUFVLEVBQUU7NEJBQ1YsY0FBYyxFQUFFO2dDQUNkLElBQUksRUFBRSxRQUFRO2dDQUNkLE9BQU8sRUFBRSxZQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU87NkJBQ2pDOzRCQUNELFdBQVcsRUFBRTtnQ0FDWCxJQUFJLEVBQUUsUUFBUTtnQ0FDZCxPQUFPLEVBQUUsSUFBSTtnQ0FDYixhQUFhLEVBQUU7b0NBQ2IsSUFBSTtvQ0FDSixJQUFJO29DQUNKLElBQUk7aUNBQ0w7NkJBQ0Y7NEJBQ0QsYUFBYSxFQUFFO2dDQUNiLElBQUksRUFBRSxRQUFRO2dDQUNkLE9BQU8sRUFBRSxLQUFLO2dDQUNkLGFBQWEsRUFBRTtvQ0FDYixLQUFLO29DQUNMLEtBQUs7aUNBQ047NkJBQ0Y7eUJBQ0Y7d0JBQ0QsdUhBQXVIO3dCQUN2SCxTQUFTLEVBQUU7NEJBQ1Q7Z0NBQ0UsTUFBTSxFQUFFLHNCQUFzQjtnQ0FDOUIsSUFBSSxFQUFFLHdCQUF3QjtnQ0FDOUIsTUFBTSxFQUFFO29DQUNOLElBQUksRUFBRSx1QkFBdUI7b0NBQzdCLE1BQU0sRUFBRSxTQUFTO2lDQUNsQjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsaUJBQWlCO2dDQUN6QixJQUFJLEVBQUUsMEJBQTBCO2dDQUNoQyxNQUFNLEVBQUU7b0NBQ04sWUFBWSxFQUFFLGFBQWE7b0NBQzNCLFlBQVksRUFBRSw4QkFBOEI7b0NBQzVDLGtCQUFrQixFQUFFO3dDQUNsQixNQUFNLEVBQUUsV0FBVzt3Q0FDbkIsSUFBSSxFQUFFLEtBQUs7d0NBQ1gsMkJBQTJCLEVBQUUsU0FBUzt3Q0FDdEMsZUFBZSxFQUFFLEtBQUs7cUNBQ3ZCO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSx1QkFBdUI7Z0NBQzdCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYixxRkFBcUY7d0NBQ3JGLDJHQUEyRzt3Q0FDM0csdUdBQXVHO3dDQUN2RyxrR0FBa0c7d0NBQ2xHLHNHQUFzRzt3Q0FDdEcsMERBQTBEO3dDQUMxRCx1Q0FBdUM7cUNBQ3hDO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSx3QkFBd0I7Z0NBQzlCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYiwwTUFBME07cUNBQzNNO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxZQUFZO2dDQUNsQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IscUNBQXFDO3dDQUNyQywwQ0FBMEMsVUFBVSxFQUFFO3dDQUN0RCxTQUFTLFVBQVUsbUNBQW1DO3dDQUN0RCxvQkFBb0IsVUFBVSxFQUFFO3dDQUNoQztFQUNsQixVQUFVO0lBQ1I7d0NBQ2dCLGtCQUFrQixVQUFVLGdCQUFnQixVQUFVLElBQUksVUFBVSxVQUFVLFVBQVUsRUFBRTt3Q0FDMUYsMkNBQTJDO3dDQUMzQyxpQkFBaUIsVUFBVSxFQUFFO3FDQUM5QjtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsZ0JBQWdCO2dDQUN0QixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsNEhBQTRIO3dDQUM1SCx5TUFBeU07d0NBQ3pNLGtGQUFrRjt3Q0FDbEYsMkJBQTJCO3dDQUMzQix1REFBdUQ7d0NBQ3ZELFNBQVM7d0NBQ1QsUUFBUTtxQ0FDVDtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsa0JBQWtCO2dDQUN4QixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsMkhBQTJIO3dDQUMzSCwrTEFBK0w7d0NBQy9MLGlIQUFpSDt3Q0FDakgsaUNBQWlDLFVBQVUsVUFBVTt3Q0FDckQsZ0NBQWdDO3dDQUNoQyxpREFBaUQ7d0NBQ2pELGtCQUFrQjt3Q0FDbEIsaUNBQWlDO3FDQUNsQztpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsZUFBZTtnQ0FDckIsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRTt3Q0FDVixhQUFhO3dDQUNiLHFDQUFxQzt3Q0FDckMsK0VBQStFO3dDQUMvRSxXQUFXLFVBQVUsb0NBQW9DLFVBQVUsZUFBZTt3Q0FDbEYsV0FBVyxVQUFVLDRDQUE0QyxVQUFVLEdBQUc7d0NBQzlFLFdBQVcsVUFBVSxnREFBZ0Q7d0NBQ3JFLDhDQUE4Qzt3Q0FDOUMsZUFBZTtxQ0FDaEI7aUNBQ0Y7NkJBQ0Y7NEJBQ0Q7Z0NBQ0UsTUFBTSxFQUFFLG9CQUFvQjtnQ0FDNUIsSUFBSSxFQUFFLGtCQUFrQjtnQ0FDeEIsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRTt3Q0FDVixtQ0FBbUM7d0NBQ25DLG1DQUFtQzt3Q0FDbkMsMkRBQTJEO3dDQUMzRCxhQUFhO3dDQUNiLGlJQUFpSTt3Q0FDakkseUNBQXlDLFVBQVUsVUFBVTt3Q0FDN0QsaUNBQWlDLFVBQVUsVUFBVTt3Q0FDckQsdURBQXVEO3dDQUN2RCwrQ0FBK0M7d0NBQy9DLHlEQUF5RDt3Q0FDekQsbUJBQW1CO3dDQUNuQixnQkFBZ0I7cUNBQ2pCO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxlQUFlO2dDQUNyQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsOEZBQThGO3dDQUM5RixtQ0FBbUM7d0NBQ25DLHVCQUF1Qjt3Q0FDdkIsaUJBQWlCO3dDQUNqQixrREFBa0Q7d0NBQ2xELGVBQWU7cUNBQ2hCO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxxQkFBcUI7Z0NBQzNCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYixxQkFBcUIsVUFBVSxFQUFFO3dDQUNqQyxpRUFBaUU7d0NBQ2pFLHNDQUFzQyxVQUFVLE9BQU87d0NBQ3ZEOzs7Ozs7Ozs7Ozs7O2dCQWFKLGlCQUFpQjtvQ0FDRyxhQUFhLElBQUksaUJBQWlCOzs7Ozs7O0lBT2xFO3dDQUNnQixrQkFBa0IsVUFBVSxzQkFBc0I7d0NBQ2xELGFBQWEsVUFBVTs7OztJQUl2Qzt3Q0FDZ0Isa0JBQWtCLFVBQVUsaUNBQWlDO3dDQUM3RCxlQUFlLFVBQVUsYUFBYTt3Q0FDdEMsWUFBWSxVQUFVLGdCQUFnQixVQUFVLElBQUksVUFBVSxJQUFJLFVBQVUsRUFBRTt3Q0FDOUUsYUFBYSxVQUFVOzs7Ozs7Ozs7Ozs7Ozs7O0lBZ0J2Qzt3Q0FDZ0IsWUFBWSxVQUFVLElBQUksVUFBVSxVQUFVLFVBQVUsRUFBRTt3Q0FDMUQsaUNBQWlDLFVBQVUsRUFBRTt3Q0FDN0MseUJBQXlCO3dDQUN6QixXQUFXLFVBQVUsdUZBQXVGO3dDQUM1RyxXQUFXLFVBQVUsb0ZBQW9GO3dDQUN6RyxXQUFXLFVBQVUsMkVBQTJFO3dDQUNoRyxXQUFXLFVBQVUsMkVBQTJFO3dDQUNoRyxXQUFXLFVBQVUsd0VBQXdFO3dDQUM3RixZQUFZLFVBQVUsSUFBSSxVQUFVLFVBQVUsVUFBVSxFQUFFO3dDQUMxRCxnREFBZ0Q7d0NBQ2hELGVBQWU7d0NBQ2Ysd0JBQXdCO3dDQUN4QixxREFBcUQ7d0NBQ3JELGdCQUFnQjt3Q0FDaEIsZ0NBQWdDLFVBQVUsRUFBRTtxQ0FDN0M7aUNBQ0Y7NkJBQ0Y7NEJBQ0Q7Z0NBQ0UsTUFBTSxFQUFFLG9CQUFvQjtnQ0FDNUIsSUFBSSxFQUFFLGVBQWU7Z0NBQ3JCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYiwyQ0FBMkM7d0NBQzNDLDZDQUE2Qzt3Q0FDN0MsMEJBQTBCLFVBQVUseUJBQXlCLFVBQVUsVUFBVTt3Q0FDakYsK0JBQStCLFVBQVUsVUFBVTt3Q0FDbkQsMkJBQTJCLFlBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxjQUFjLFVBQVUsVUFBVTt3Q0FDbkYsOEJBQThCLFlBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxjQUFjLFVBQVUsVUFBVTt3Q0FDdkYsb0RBQW9ELFVBQVUsVUFBVTt3Q0FDeEUsK0ZBQStGLFVBQVUsVUFBVTt3Q0FDbkgsWUFBWSxVQUFVLElBQUksVUFBVSxVQUFVLFVBQVUsRUFBRTtxQ0FDM0Q7aUNBQ0Y7NkJBQ0Y7NEJBQ0Q7Z0NBQ0UsTUFBTSxFQUFFLG9CQUFvQjtnQ0FDNUIsSUFBSSxFQUFFLFlBQVk7Z0NBQ2xCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYix3QkFBd0I7d0NBQ3hCLGtEQUFrRDt3Q0FDbEQsZUFBZTtxQ0FDaEI7aUNBQ0Y7NkJBQ0Y7eUJBQ0Y7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILE1BQU07WUFDUixLQUFLLCtCQUFlLENBQUMsaUJBQWlCO2dCQUNwQyxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxxQkFBcUIsRUFBRTtvQkFDOUQsSUFBSSxFQUFFLHdCQUF3QixZQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFNBQVMsRUFBRTtvQkFDekQsWUFBWSxFQUFFLFNBQVM7b0JBQ3ZCLE9BQU8sRUFBRTt3QkFDUCxhQUFhLEVBQUUsS0FBSzt3QkFDcEIsV0FBVyxFQUFFLHVDQUF1Qzt3QkFDcEQsVUFBVSxFQUFFOzRCQUNWLGNBQWMsRUFBRTtnQ0FDZCxJQUFJLEVBQUUsUUFBUTtnQ0FDZCxPQUFPLEVBQUUsWUFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPOzZCQUNqQzs0QkFDRCxXQUFXLEVBQUU7Z0NBQ1gsSUFBSSxFQUFFLFFBQVE7Z0NBQ2QsT0FBTyxFQUFFLElBQUk7Z0NBQ2IsYUFBYSxFQUFFO29DQUNiLElBQUk7b0NBQ0osSUFBSTtvQ0FDSixJQUFJO2lDQUNMOzZCQUNGOzRCQUNELGFBQWEsRUFBRTtnQ0FDYixJQUFJLEVBQUUsUUFBUTtnQ0FDZCxPQUFPLEVBQUUsS0FBSztnQ0FDZCxhQUFhLEVBQUU7b0NBQ2IsS0FBSztvQ0FDTCxLQUFLO2lDQUNOOzZCQUNGO3lCQUNGO3dCQUNELHVIQUF1SDt3QkFDdkgsU0FBUyxFQUFFOzRCQUNUO2dDQUNFLE1BQU0sRUFBRSxzQkFBc0I7Z0NBQzlCLElBQUksRUFBRSx3QkFBd0I7Z0NBQzlCLE1BQU0sRUFBRTtvQ0FDTixJQUFJLEVBQUUsdUJBQXVCO29DQUM3QixNQUFNLEVBQUUsU0FBUztpQ0FDbEI7NkJBQ0Y7NEJBQ0Q7Z0NBQ0UsTUFBTSxFQUFFLGlCQUFpQjtnQ0FDekIsSUFBSSxFQUFFLDBCQUEwQjtnQ0FDaEMsTUFBTSxFQUFFO29DQUNOLFlBQVksRUFBRSxhQUFhO29DQUMzQixZQUFZLEVBQUUsOEJBQThCO29DQUM1QyxrQkFBa0IsRUFBRTt3Q0FDbEIsTUFBTSxFQUFFLFdBQVc7d0NBQ25CLElBQUksRUFBRSxLQUFLO3dDQUNYLDJCQUEyQixFQUFFLFNBQVM7d0NBQ3RDLGVBQWUsRUFBRSxLQUFLO3FDQUN2QjtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsd0JBQXdCO2dDQUM5QixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsMkVBQTJFO3FDQUM1RTtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsWUFBWTtnQ0FDbEIsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRTt3Q0FDVixhQUFhO3dDQUNiLHNCQUFzQixVQUFVLEdBQUc7d0NBQ25DLGlCQUFpQixVQUFVLEVBQUU7d0NBQzdCLGFBQWEsVUFBVSxFQUFFO3dDQUN6QixTQUFTLFVBQVUsbUNBQW1DO3dDQUN0RCxxQkFBcUIsVUFBVSxFQUFFO3dDQUNqQywyQ0FBMkM7d0NBQzNDLGlCQUFpQixVQUFVLEVBQUU7cUNBQzlCO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxnQkFBZ0I7Z0NBQ3RCLE1BQU0sRUFBRTtvQ0FDTixVQUFVLEVBQUU7d0NBQ1YsYUFBYTt3Q0FDYiw2QkFBNkI7d0NBQzdCLHlDQUF5Qzt3Q0FDekMsMkJBQTJCO3dDQUMzQix1REFBdUQ7d0NBQ3ZELFNBQVM7d0NBQ1QsUUFBUTtxQ0FDVDtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsa0JBQWtCO2dDQUN4QixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsdUJBQXVCO3dDQUN2QixzQkFBc0IsVUFBVSxFQUFFO3dDQUNsQyxpQ0FBaUMsVUFBVSxVQUFVO3dDQUNyRCxnQ0FBZ0M7d0NBQ2hDLGlEQUFpRDt3Q0FDakQsa0JBQWtCO3dDQUNsQixpQ0FBaUM7cUNBQ2xDO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxlQUFlO2dDQUNyQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2Isb0JBQW9CO3dDQUNwQixXQUFXLFVBQVUsb0NBQW9DLFVBQVUsZUFBZTt3Q0FDbEYsV0FBVyxVQUFVLDRDQUE0QyxVQUFVLEdBQUc7d0NBQzlFLFdBQVcsVUFBVSxnREFBZ0Q7d0NBQ3JFLDhDQUE4Qzt3Q0FDOUMsZUFBZTtxQ0FDaEI7aUNBQ0Y7NkJBQ0Y7NEJBQ0Q7Z0NBQ0UsTUFBTSxFQUFFLG9CQUFvQjtnQ0FDNUIsSUFBSSxFQUFFLGtCQUFrQjtnQ0FDeEIsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRTt3Q0FDViwrRkFBK0Y7d0NBQy9GLHVHQUF1Rzt3Q0FDdkcsZ0RBQWdEO3dDQUNoRCxhQUFhO3dDQUNiLDBGQUEwRjt3Q0FDMUYseUNBQXlDLFVBQVUsVUFBVTt3Q0FDN0QsNENBQTRDLFVBQVUsVUFBVTt3Q0FDaEUsc0NBQXNDLFVBQVUsVUFBVTt3Q0FDMUQsZ0RBQWdEO3dDQUNoRCwwQ0FBMEM7d0NBQzFDLDhDQUE4Qzt3Q0FDOUMseURBQXlEO3dDQUN6RCxzQkFBc0I7d0NBQ3RCLGtDQUFrQztxQ0FDbkM7aUNBQ0Y7NkJBQ0Y7NEJBQ0QsaUJBQWlCOzRCQUNqQjtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUsZUFBZTtnQ0FDckIsTUFBTSxFQUFFO29DQUNOLFVBQVUsRUFBRTt3Q0FDVixhQUFhO3dDQUNiLDhGQUE4Rjt3Q0FDOUYsbUNBQW1DO3dDQUNuQyx1QkFBdUI7d0NBQ3ZCLGlCQUFpQjt3Q0FDakIsa0RBQWtEO3dDQUNsRCxlQUFlO3FDQUNoQjtpQ0FDRjs2QkFDRjs0QkFDRDtnQ0FDRSxNQUFNLEVBQUUsb0JBQW9CO2dDQUM1QixJQUFJLEVBQUUscUJBQXFCO2dDQUMzQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IscUJBQXFCLFVBQVUsRUFBRTt3Q0FDakMsaUVBQWlFO3dDQUNqRSxzQ0FBc0MsVUFBVSxPQUFPO3dDQUN2RDs7Ozs7Ozs7Ozs7OztnQkFhSixpQkFBaUI7b0NBQ0csYUFBYSxJQUFJLGlCQUFpQjs7Ozs7OztJQU9sRTt3Q0FDZ0Isa0JBQWtCLFVBQVUsc0JBQXNCO3dDQUNsRCxhQUFhLFVBQVU7Ozs7SUFJdkM7d0NBQ2dCLGtCQUFrQixVQUFVLGlDQUFpQzt3Q0FDN0QsZUFBZSxVQUFVLGFBQWE7d0NBQ3RDLFlBQVksVUFBVSxnQkFBZ0IsVUFBVSxJQUFJLFVBQVUsSUFBSSxVQUFVLEVBQUU7d0NBQzlFLGFBQWEsVUFBVTs7Ozs7Ozs7Ozs7Ozs7OztJQWdCdkM7d0NBQ2dCLFlBQVksVUFBVSxJQUFJLFVBQVUsVUFBVSxVQUFVLEVBQUU7d0NBQzFELGlDQUFpQyxVQUFVLEVBQUU7d0NBQzdDLHlCQUF5Qjt3Q0FDekIsV0FBVyxVQUFVLHVGQUF1Rjt3Q0FDNUcsV0FBVyxVQUFVLG9GQUFvRjt3Q0FDekcsV0FBVyxVQUFVLDJFQUEyRTt3Q0FDaEcsV0FBVyxVQUFVLDJFQUEyRTt3Q0FDaEcsV0FBVyxVQUFVLHdFQUF3RTt3Q0FDN0YsWUFBWSxVQUFVLElBQUksVUFBVSxVQUFVLFVBQVUsRUFBRTt3Q0FDMUQsZ0RBQWdEO3dDQUNoRCxlQUFlO3dDQUNmLHdCQUF3Qjt3Q0FDeEIscURBQXFEO3dDQUNyRCxnQkFBZ0I7d0NBQ2hCLGdDQUFnQyxVQUFVLEVBQUU7cUNBQzdDO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxlQUFlO2dDQUNyQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2IsMkNBQTJDO3dDQUMzQyw2Q0FBNkM7d0NBQzdDLDBCQUEwQixVQUFVLHlCQUF5QixVQUFVLFVBQVU7d0NBQ2pGLCtCQUErQixVQUFVLFVBQVU7d0NBQ25ELDJCQUEyQixZQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sY0FBYyxVQUFVLFVBQVU7d0NBQ25GLDhCQUE4QixZQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sY0FBYyxVQUFVLFVBQVU7d0NBQ3ZGLG9EQUFvRCxVQUFVLFVBQVU7d0NBQ3hFLCtGQUErRixVQUFVLFVBQVU7d0NBQ25ILFlBQVksVUFBVSxJQUFJLFVBQVUsVUFBVSxVQUFVLEVBQUU7cUNBQzNEO2lDQUNGOzZCQUNGOzRCQUNEO2dDQUNFLE1BQU0sRUFBRSxvQkFBb0I7Z0NBQzVCLElBQUksRUFBRSxZQUFZO2dDQUNsQixNQUFNLEVBQUU7b0NBQ04sVUFBVSxFQUFFO3dDQUNWLGFBQWE7d0NBQ2Isd0JBQXdCO3dDQUN4QixrREFBa0Q7d0NBQ2xELGVBQWU7cUNBQ2hCO2lDQUNGOzZCQUNGO3lCQUNGO3FCQUNGO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxNQUFNO1lBQ1I7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBRUQsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztDQUNGO0FBanFCRCw4QkFpcUJDO0FBSUQsTUFBTSx1QkFBd0IsU0FBUSxTQUFTO0lBQzdDLFlBQVksS0FBZ0IsRUFBRSxPQUF1QztRQUNuRSxLQUFLLEVBQUUsQ0FBQztRQUVSLE1BQU0sT0FBTyxHQUFhLElBQUksc0NBQWlCLENBQUMsS0FBSyxFQUFFLHlCQUF5QixFQUFFO1lBQ2hGLE9BQU8sRUFBRSxlQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLG9CQUFvQjtZQUNwRCxVQUFVLEVBQUUsR0FBRyxFQUFFLG9CQUFvQjtTQUN0QyxDQUFDLENBQUM7UUFDSCx5QkFBZSxDQUFDLHVCQUF1QixDQUFDO1lBQ3RDLE9BQU87U0FDUixFQUFFO1lBQ0QsRUFBRSxFQUFFLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFLG9FQUFvRSxFQUFFO1lBQ3pHLEVBQUUsRUFBRSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxrREFBa0QsRUFBRTtTQUN0RixFQUFFLElBQUksQ0FBQyxDQUFDO1FBRVQsTUFBTSxXQUFXLEdBQUcsVUFBRyxDQUFDLE1BQU0sQ0FBQztZQUM3QixPQUFPLEVBQUUsS0FBSztZQUNkLFFBQVEsRUFBRSxVQUFVO1lBQ3BCLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtTQUNuQyxFQUFFLFlBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUVwQixNQUFNLGdCQUFnQixHQUFHLFVBQUcsQ0FBQyxNQUFNLENBQUM7WUFDbEMsT0FBTyxFQUFFLEtBQUs7WUFDZCxRQUFRLEVBQUUsVUFBVTtZQUNwQixZQUFZLEVBQUUsOEJBQThCO1NBQzdDLEVBQUUsWUFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXBCLE1BQU0sb0JBQW9CLEdBQUcsVUFBRyxDQUFDLE1BQU0sQ0FBQztZQUN0QyxPQUFPLEVBQUUsS0FBSztZQUNkLFFBQVEsRUFBRSxVQUFVO1lBQ3BCLFlBQVksRUFBRSxPQUFPLENBQUMsVUFBVTtTQUNqQyxFQUFFLFlBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUVwQixPQUFPLENBQUMsZUFBZSxDQUFDLElBQUkseUJBQWUsQ0FBQztZQUMxQyxPQUFPLEVBQUU7Z0JBQ1AsaUJBQWlCO2FBQ2xCO1lBQ0QsU0FBUyxFQUFFO2dCQUNULFdBQVc7Z0JBQ1gsZ0JBQWdCO2dCQUNoQixvQkFBb0I7YUFDckI7U0FDRixDQUFDLENBQUMsQ0FBQztRQUVKLE1BQU0sUUFBUSxHQUFHLElBQUksMkJBQVEsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLEVBQUU7WUFDeEQsY0FBYyxFQUFFLE9BQU87U0FDeEIsQ0FBQyxDQUFDO1FBQ0gseUJBQWUsQ0FBQyx1QkFBdUIsQ0FBQztZQUN0QyxRQUFRO1NBQ1QsRUFBRTtZQUNELEVBQUUsRUFBRSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSwrREFBK0QsRUFBRTtZQUNwRyxFQUFFLEVBQUUsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLEVBQUUsc0NBQXNDLEVBQUU7WUFDM0UsRUFBRSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLG9EQUFvRCxFQUFFO1NBQ3hGLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFVCxJQUFJLHFCQUFjLENBQUMsS0FBSyxFQUFFLDRCQUE0QixFQUFFO1lBQ3RELFlBQVksRUFBRSxRQUFRLENBQUMsWUFBWTtZQUNuQyxVQUFVLEVBQUU7Z0JBQ1YsY0FBYyxFQUFFLEdBQUcsRUFBRSxvQkFBb0I7Z0JBQ3pDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtnQkFDOUIsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO2dCQUNsQyxzQkFBc0IsRUFBRSxPQUFPLENBQUMsc0JBQXNCO2dCQUN0RCxjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWM7YUFDdkM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBR00sS0FBSyxLQUFLLENBQUM7Q0FDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IEZ1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYSc7XG5pbXBvcnQgKiBhcyBzc20gZnJvbSAnYXdzLWNkay1saWIvYXdzLXNzbSc7XG5pbXBvcnQgeyBBcm4sIEN1c3RvbVJlc291cmNlLCBEdXJhdGlvbiwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlJztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBOYWdTdXBwcmVzc2lvbnMgfSBmcm9tICdjZGstbmFnJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSW5zdGFsbGVyRnVuY3Rpb24gfSBmcm9tICcuL2luc3RhbGxlci1mdW5jdGlvbic7XG5pbXBvcnQgeyBMaW51eEZsYXZvclR5cGUgfSBmcm9tICcuLi92c2NvZGUtc2VydmVyJztcblxuaW50ZXJmYWNlIEluc3RhbGxlck9wdGlvbnNCYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBlYzIgaW5zdGFuY2UgaWQgdG8gaW5zdGFsbCB0aGUgc3NtIGRvY3VtZW50IG9uXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBjdXN0b20gc3NtIGRvY3VtZW50IHRvIGluc3RhbGwuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRoZSBzc20gZG9jdW1lbnQgb2YgdGhlIGNvbnN0cnVjdFxuICAgKi9cbiAgcmVhZG9ubHkgZG9jdW1lbnROYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgY2xvdWR3YXRjaCBsb2cgZ3JvdXAgZm9yIHRoZSBpbnN0YWxsIGxvZ3NcbiAgICpcbiAgICogQGRlZmF1bHQgL2F3cy9zc20vJHtkb2N1bWVudE5hbWV9XG4gICAqL1xuICByZWFkb25seSBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgdXNlciB1bmRlciB3aGljaCB0aGUgdnNjb2RlIHNlcnZlciBydW5zXG4gICAqL1xuICByZWFkb25seSB2c0NvZGVVc2VyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXNzd29yZCBvZiB0aGUgdXNlciB1bmRlciB3aGljaCB0aGUgdnNjb2RlIHNlcnZlciBydW5zXG4gICAqL1xuICByZWFkb25seSB2c0NvZGVQYXNzd29yZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaG9tZSBmb2xkZXIgb2YgdGhlIHVzZXIgdW5kZXIgd2hpY2ggdGhlIHZzY29kZSBzZXJ2ZXIgcnVuc1xuICAgKi9cbiAgcmVhZG9ubHkgaG9tZUZvbGRlcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSByZXN0IHBhdGggdnMgY29kZSBzZXJ2ZXIgd2lsbCBydW5cbiAgICpcbiAgICogQGRlZmF1bHQgYXBwXG4gICAqL1xuICByZWFkb25seSBkZXZTZXJ2ZXJCYXNlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBvcnQgdnNjb2RlciBzZXJ2ZXIgd2lsbCBiZSBzZXJ2ZWQgaW4gdGhlIGluc3RhbmNlXG4gICAqXG4gICAqIEBkZWZhdWx0IDgwODFcbiAgICovXG4gIHJlYWRvbmx5IGRldlNlcnZlclBvcnQ/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEluc3RhbGxlck9wdGlvbnMgZXh0ZW5kcyBJbnN0YWxsZXJPcHRpb25zQmFzZSB7fVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSW5zdGFsbGVyIHtcbiAgcHVibGljIHN0YXRpYyB1YnVudHUob3B0aW9uczogSW5zdGFsbGVyT3B0aW9ucyk6IEluc3RhbGxlciB7XG4gICAgcmV0dXJuIG5ldyAoY2xhc3MgZXh0ZW5kcyBJbnN0YWxsZXIge1xuICAgICAgcHVibGljIF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QpOiBJbnN0YWxsZXIge1xuICAgICAgICBsZXQgZG9jdW1lbnROYW1lO1xuICAgICAgICBjb25zdCBkZXZTZXJ2ZXJCYXNlUGF0aCA9IG9wdGlvbnMuZGV2U2VydmVyQmFzZVBhdGggPz8gJ2FwcCc7XG4gICAgICAgIGNvbnN0IGRldlNlcnZlclBvcnQgPSBvcHRpb25zLmRldlNlcnZlclBvcnQgPz8gODA4MTtcbiAgICAgICAgaWYgKG9wdGlvbnMuZG9jdW1lbnROYW1lICYmIG9wdGlvbnMuZG9jdW1lbnROYW1lICE9ICcnKSB7XG4gICAgICAgICAgZG9jdW1lbnROYW1lID0gb3B0aW9ucy5kb2N1bWVudE5hbWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZG9jdW1lbnQgPSB0aGlzLmNyZWF0ZVNTTURvY3VtZW50KFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBkZXZTZXJ2ZXJCYXNlUGF0aCxcbiAgICAgICAgICAgIGRldlNlcnZlclBvcnQsXG4gICAgICAgICAgICBvcHRpb25zLnZzQ29kZVVzZXIsXG4gICAgICAgICAgICBvcHRpb25zLmhvbWVGb2xkZXIsXG4gICAgICAgICAgICBMaW51eEZsYXZvclR5cGUuVUJVTlRVXzIyLFxuICAgICAgICAgICk7XG4gICAgICAgICAgZG9jdW1lbnROYW1lID0gZG9jdW1lbnQubmFtZSE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lID0gb3B0aW9ucy5jbG91ZFdhdGNoTG9nR3JvdXBOYW1lID8/IGAvYXdzL3NzbS8ke2RvY3VtZW50TmFtZX1gO1xuXG4gICAgICAgIGNvbnN0IGluc3RhbGxlciA9IG5ldyBDdXN0b21SZXNvdXJjZUluc3RhbGxlcihzY29wZSwge1xuICAgICAgICAgIGluc3RhbmNlSWQ6IG9wdGlvbnMuaW5zdGFuY2VJZCxcbiAgICAgICAgICBkb2N1bWVudE5hbWU6IGRvY3VtZW50TmFtZSxcbiAgICAgICAgICBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lOiBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lLFxuICAgICAgICAgIHZzQ29kZVVzZXI6IG9wdGlvbnMudnNDb2RlVXNlcixcbiAgICAgICAgICB2c0NvZGVQYXNzd29yZDogb3B0aW9ucy52c0NvZGVQYXNzd29yZCxcbiAgICAgICAgICBob21lRm9sZGVyOiBvcHRpb25zLmhvbWVGb2xkZXIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBpbnN0YWxsZXI7XG4gICAgICB9XG4gICAgfSkoKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgYW1hem9uTGludXgyMDIzKG9wdGlvbnM6IEluc3RhbGxlck9wdGlvbnMpOiBJbnN0YWxsZXIge1xuICAgIHJldHVybiBuZXcgKGNsYXNzIGV4dGVuZHMgSW5zdGFsbGVyIHtcbiAgICAgIHB1YmxpYyBfYmluZChzY29wZTogQ29uc3RydWN0KTogSW5zdGFsbGVyIHtcbiAgICAgICAgbGV0IGRvY3VtZW50TmFtZTtcbiAgICAgICAgY29uc3QgZGV2U2VydmVyQmFzZVBhdGggPSBvcHRpb25zLmRldlNlcnZlckJhc2VQYXRoID8/ICdhcHAnO1xuICAgICAgICBjb25zdCBkZXZTZXJ2ZXJQb3J0ID0gb3B0aW9ucy5kZXZTZXJ2ZXJQb3J0ID8/IDgwODE7XG4gICAgICAgIGlmIChvcHRpb25zLmRvY3VtZW50TmFtZSAmJiBvcHRpb25zLmRvY3VtZW50TmFtZSAhPSAnJykge1xuICAgICAgICAgIGRvY3VtZW50TmFtZSA9IG9wdGlvbnMuZG9jdW1lbnROYW1lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGRvY3VtZW50ID0gdGhpcy5jcmVhdGVTU01Eb2N1bWVudChcbiAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgZGV2U2VydmVyQmFzZVBhdGgsXG4gICAgICAgICAgICBkZXZTZXJ2ZXJQb3J0LFxuICAgICAgICAgICAgb3B0aW9ucy52c0NvZGVVc2VyLFxuICAgICAgICAgICAgb3B0aW9ucy5ob21lRm9sZGVyLFxuICAgICAgICAgICAgTGludXhGbGF2b3JUeXBlLkFNQVpPTl9MSU5VWF8yMDIzLFxuICAgICAgICAgICk7XG4gICAgICAgICAgZG9jdW1lbnROYW1lID0gZG9jdW1lbnQubmFtZSE7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lID0gb3B0aW9ucy5jbG91ZFdhdGNoTG9nR3JvdXBOYW1lID8/IGAvYXdzL3NzbS8ke2RvY3VtZW50TmFtZX1gO1xuXG4gICAgICAgIGNvbnN0IGluc3RhbGxlciA9IG5ldyBDdXN0b21SZXNvdXJjZUluc3RhbGxlcihzY29wZSwge1xuICAgICAgICAgIGluc3RhbmNlSWQ6IG9wdGlvbnMuaW5zdGFuY2VJZCxcbiAgICAgICAgICBkb2N1bWVudE5hbWU6IGRvY3VtZW50TmFtZSxcbiAgICAgICAgICBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lOiBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lLFxuICAgICAgICAgIHZzQ29kZVVzZXI6IG9wdGlvbnMudnNDb2RlVXNlcixcbiAgICAgICAgICB2c0NvZGVQYXNzd29yZDogb3B0aW9ucy52c0NvZGVQYXNzd29yZCxcbiAgICAgICAgICBob21lRm9sZGVyOiBvcHRpb25zLmhvbWVGb2xkZXIsXG4gICAgICAgIH0pO1xuXG5cbiAgICAgICAgcmV0dXJuIGluc3RhbGxlcjtcbiAgICAgIH1cbiAgICB9KSgpO1xuICB9XG5cbiAgcHVibGljIGluc3RhbmNlSWQhOiBzdHJpbmc7XG4gIHB1YmxpYyBkb2N1bWVudE5hbWUhOiBzdHJpbmc7XG4gIHB1YmxpYyBjbG91ZFdhdGNoTG9nR3JvdXBOYW1lITogc3RyaW5nO1xuICBwdWJsaWMgdnNDb2RlUGFzc3dvcmQhOiBzdHJpbmc7XG4gIHB1YmxpYyB2c0NvZGVQYXNzd29yZFRlc3QhOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QpOiBhbnk7XG5cbiAgcHJpdmF0ZSBjcmVhdGVTU01Eb2N1bWVudChcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGRldlNlcnZlckJhc2VQYXRoOiBzdHJpbmcsXG4gICAgZGV2U2VydmVyUG9ydDogbnVtYmVyLFxuICAgIHZzQ29kZVVzZXI6IHN0cmluZyxcbiAgICBob21lRm9sZGVyOiBzdHJpbmcsXG4gICAgbGludXhGbGF2b3I6IExpbnV4Rmxhdm9yVHlwZSxcbiAgKTogc3NtLkNmbkRvY3VtZW50IHtcbiAgICBsZXQgc3NtRG9jdW1lbnQ6IHNzbS5DZm5Eb2N1bWVudDtcbiAgICBzd2l0Y2ggKGxpbnV4Rmxhdm9yKSB7XG4gICAgICBjYXNlIExpbnV4Rmxhdm9yVHlwZS5VQlVOVFVfMjI6XG4gICAgICBjYXNlIExpbnV4Rmxhdm9yVHlwZS5VQlVOVFVfMjQ6XG4gICAgICAgIC8vIENyZWF0ZSBhbiBTU00gZG9jdW1lbnQgd2l0aCBtdWx0aXBsZSBhY3Rpb25zIHRvIGluc3RhbGwgdGhlIHNvZnR3YXJlXG4gICAgICAgIHNzbURvY3VtZW50ID0gbmV3IHNzbS5DZm5Eb2N1bWVudChzY29wZSwgJ3NzbS1kb2N1bWVudC11YnVudHUnLCB7XG4gICAgICAgICAgbmFtZTogYHZzY29kZS1zZXJ2ZXItdWJ1bnR1LSR7U3RhY2sub2Yoc2NvcGUpLnN0YWNrTmFtZX1gLFxuICAgICAgICAgIGRvY3VtZW50VHlwZTogJ0NvbW1hbmQnLFxuICAgICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICAgIHNjaGVtYVZlcnNpb246ICcyLjInLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdCb290c3RyYXAgVlNDb2RlIGNvZGUtc2VydmVyIGluc3RhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgVlNDb2RlUGFzc3dvcmQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBTdGFjay5vZihzY29wZSkuc3RhY2tJZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgTm9kZVZlcnNpb246IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAnMjAnLFxuICAgICAgICAgICAgICAgIGFsbG93ZWRWYWx1ZXM6IFtcbiAgICAgICAgICAgICAgICAgICcyMicsXG4gICAgICAgICAgICAgICAgICAnMjAnLFxuICAgICAgICAgICAgICAgICAgJzE4JyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBEb3ROZXRWZXJzaW9uOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJzguMCcsXG4gICAgICAgICAgICAgICAgYWxsb3dlZFZhbHVlczogW1xuICAgICAgICAgICAgICAgICAgJzguMCcsXG4gICAgICAgICAgICAgICAgICAnNy4wJyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vIGFsbCBtYWluU3RlcHMgc2NyaXB0cyBhcmUgaW4gaW4gL3Zhci9saWIvYW1hem9uL3NzbS88aW5zdGFuY2VpZD4vZG9jdW1lbnQvb3JjaGVzdHJhdGlvbi88dXVpZD4vPFN0ZXBOYW1lPi9fc2NyaXB0LnNoXG4gICAgICAgICAgICBtYWluU3RlcHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpjb25maWd1cmVQYWNrYWdlJyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbENsb3VkV2F0Y2hBZ2VudCcsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBuYW1lOiAnQW1hem9uQ2xvdWRXYXRjaEFnZW50JyxcbiAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ0luc3RhbGwnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdDb25maWd1cmVDbG91ZFdhdGNoQWdlbnQnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgZG9jdW1lbnRUeXBlOiAnU1NNRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgZG9jdW1lbnRQYXRoOiAnQW1hem9uQ2xvdWRXYXRjaC1NYW5hZ2VBZ2VudCcsXG4gICAgICAgICAgICAgICAgICBkb2N1bWVudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnY29uZmlndXJlJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZTogJ2VjMicsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsQ29uZmlndXJhdGlvblNvdXJjZTogJ2RlZmF1bHQnLFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25hbFJlc3RhcnQ6ICd5ZXMnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnYXdzOnJ1blNoZWxsU2NyaXB0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbEFwdFBhY2thZ2VzQXB0JyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgJ2FwdC1nZXQgLXEgdXBkYXRlICYmIERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZSBhcHQtZ2V0IGluc3RhbGwgLXkgLXEgYXB0LXV0aWxzJyxcbiAgICAgICAgICAgICAgICAgICAgJ2FwdC1nZXQgLXEgdXBkYXRlICYmIERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZSBhcHQtZ2V0IGluc3RhbGwgLXkgLXEgbmVlZHJlc3RhcnQgdW5hdHRlbmRlZC11cGdyYWRlcycsXG4gICAgICAgICAgICAgICAgICAgICdzZWQgLWkgXFwncy8jJG5yY29uZntrZXJuZWxoaW50c30gPSAtMTsvJG5yY29uZntrZXJuZWxoaW50c30gPSAwOy9cXCcgL2V0Yy9uZWVkcmVzdGFydC9uZWVkcmVzdGFydC5jb25mJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NlZCAtaSBcXCdzLyMkbnJjb25me3ZlcmJvc2l0eX0gPSAyOy8kbnJjb25me3ZlcmJvc2l0eX0gPSAwOy9cXCcgL2V0Yy9uZWVkcmVzdGFydC9uZWVkcmVzdGFydC5jb25mJyxcbiAgICAgICAgICAgICAgICAgICAgJ3NlZCAtaSBcInMvI1xcJG5yY29uZntyZXN0YXJ0fSA9IFxcJ2lcXCc7L1xcJG5yY29uZntyZXN0YXJ0fSA9IFxcJ2FcXCc7L1wiIC9ldGMvbmVlZHJlc3RhcnQvbmVlZHJlc3RhcnQuY29uZicsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiQXB0IGhlbHBlciBwYWNrYWdlcyBhZGRlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ2NhdCAvZXRjL25lZWRyZXN0YXJ0L25lZWRyZXN0YXJ0LmNvbmYnLFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnYXdzOnJ1blNoZWxsU2NyaXB0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbEJhc2VQYWNrYWdlc0FwdCcsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdhcHQtZ2V0IC1xIHVwZGF0ZSAmJiBERUJJQU5fRlJPTlRFTkQ9bm9uaW50ZXJhY3RpdmUgYXB0LWdldCBpbnN0YWxsIC15IC1xIGN1cmwgZ251cGcgd2hvaXMgYXJnb24yIG9wZW5zc2wgbG9jYWxlcyBsb2NhbGVzLWFsbCB1bnppcCBhcHQtdHJhbnNwb3J0LWh0dHBzIGNhLWNlcnRpZmljYXRlcyBzb2Z0d2FyZS1wcm9wZXJ0aWVzLWNvbW1vbiBuZ2lueCcsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdBZGRVc2VyQXB0JyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgJ2VjaG8gXFwnQWRkaW5nIHVzZXI6ICR7VlNDb2RlVXNlcn1cXCcnLFxuICAgICAgICAgICAgICAgICAgICBgYWRkdXNlciAtLWRpc2FibGVkLXBhc3N3b3JkIC0tZ2Vjb3MgJycgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvIFwiJHt2c0NvZGVVc2VyfTp7eyBWU0NvZGVQYXNzd29yZCB9fVwiIHwgY2hwYXNzd2RgLFxuICAgICAgICAgICAgICAgICAgICBgdXNlcm1vZCAtYUcgc3VkbyAke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgICAgYHRlZSAvZXRjL3N1ZG9lcnMuZC85MS12c2NvZGUtdXNlciA8PEVPRlxuJHt2c0NvZGVVc2VyfSBBTEw9KEFMTCkgTk9QQVNTV0Q6QUxMXG5FT0ZgLFxuICAgICAgICAgICAgICAgICAgICBgbWtkaXIgLXAgL2hvbWUvJHt2c0NvZGVVc2VyfSAmJiBjaG93biAtUiAke3ZzQ29kZVVzZXJ9OiR7dnNDb2RlVXNlcn0gL2hvbWUvJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiVXNlciBhZGRlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgYGdldGVudCBwYXNzd2QgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdJbnN0YWxsTm9kZUFwdCcsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdjdXJsIC1mc1NMIGh0dHBzOi8vZGViLm5vZGVzb3VyY2UuY29tL2dwZ2tleS9ub2Rlc291cmNlLXJlcG8uZ3BnLmtleSB8IGdwZyAtLWRlYXJtb3IgLW8gL3Vzci9zaGFyZS9rZXlyaW5ncy9ub2Rlc291cmNlLmdwZycsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiZGViIFthcmNoPSQoZHBrZyAtLXByaW50LWFyY2hpdGVjdHVyZSkgc2lnbmVkLWJ5PS91c3Ivc2hhcmUva2V5cmluZ3Mvbm9kZXNvdXJjZS5ncGddIGh0dHBzOi8vZGViLm5vZGVzb3VyY2UuY29tL25vZGVfe3sgTm9kZVZlcnNpb24gfX0ueCBub2Rpc3RybyBtYWluXCIgPiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9ub2Rlc291cmNlLmxpc3QnLFxuICAgICAgICAgICAgICAgICAgICAnYXB0LWdldCAtcSB1cGRhdGUgJiYgREVCSUFOX0ZST05URU5EPW5vbmludGVyYWN0aXZlIGFwdC1nZXQgaW5zdGFsbCAteSAtcSBub2RlanMnLFxuICAgICAgICAgICAgICAgICAgICAnbnBtIGluc3RhbGwgLWcgbnBtQGxhdGVzdCcsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiTm9kZSBhbmQgbnBtIGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ25vZGUgLXYnLFxuICAgICAgICAgICAgICAgICAgICAnbnBtIC12JyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxEb2NrZXJBcHQnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnY3VybCAtZnNTTCBodHRwczovL2Rvd25sb2FkLmRvY2tlci5jb20vbGludXgvdWJ1bnR1L2dwZyB8IGdwZyAtLWRlYXJtb3IgLW8gL3Vzci9zaGFyZS9rZXlyaW5ncy9kb2NrZXItYXJjaGl2ZS1rZXlyaW5nLmdwZycsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiZGViIFtzaWduZWQtYnk9L3Vzci9zaGFyZS9rZXlyaW5ncy9kb2NrZXItYXJjaGl2ZS1rZXlyaW5nLmdwZ10gaHR0cHM6Ly9kb3dubG9hZC5kb2NrZXIuY29tL2xpbnV4L3VidW50dSAkKGxzYl9yZWxlYXNlIC0tY29kZW5hbWUgLS1zaG9ydCkgc3RhYmxlXCIgPiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9kb2NrZXIubGlzdCcsXG4gICAgICAgICAgICAgICAgICAgICdhcHQtZ2V0IC1xIHVwZGF0ZSAmJiBERUJJQU5fRlJPTlRFTkQ9bm9uaW50ZXJhY3RpdmUgYXB0LWdldCBpbnN0YWxsIC15IC1xIGRvY2tlci1jZSBkb2NrZXItY2UtY2xpIGNvbnRhaW5lcmQuaW8nLFxuICAgICAgICAgICAgICAgICAgICBgc3lzdGVtY3RsIHJlc3RhcnQgY29kZS1zZXJ2ZXJAJHt2c0NvZGVVc2VyfS5zZXJ2aWNlYCxcbiAgICAgICAgICAgICAgICAgICAgJ3N5c3RlbWN0bCBzdGFydCBkb2NrZXIuc2VydmljZScsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiRG9ja2VyIGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ2RvY2tlciAtLXZlcnNpb24nLFxuICAgICAgICAgICAgICAgICAgICAnc3lzdGVtY3RsIHN0YXR1cyBkb2NrZXIuc2VydmljZScsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdJbnN0YWxsR2l0QXB0JyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgJ2FkZC1hcHQtcmVwb3NpdG9yeSBwcGE6Z2l0LWNvcmUvcHBhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2FwdC1nZXQgLXEgdXBkYXRlICYmIERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZSBhcHQtZ2V0IGluc3RhbGwgLXkgLXEgZ2l0JyxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgXCIke3ZzQ29kZVVzZXJ9QGV4YW1wbGUuY29tXCJgLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IGdpdCBjb25maWcgLS1nbG9iYWwgdXNlci5uYW1lIFwiV29ya3Nob3AgJHt2c0NvZGVVc2VyfVwiYCxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSBnaXQgY29uZmlnIC0tZ2xvYmFsIGluaXQuZGVmYXVsdEJyYW5jaCBcIm1haW5cImAsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiR2l0IGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ2dpdCAtLXZlcnNpb24nLFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnYXdzOnJ1blNoZWxsU2NyaXB0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbFB5dGhvbkFwdCcsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgIC8vIFVidW50dSAyMiBkZWZhdWx0IGlzIFB5dGhvbiAzLjEwXG4gICAgICAgICAgICAgICAgICAgIC8vIFVidW50dSAyNCBkZWZhdWx0IGlzIFB5dGhvbiAzLjEyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBkZWZhdWx0IGluc3RhbGxlZCBQeXRob24gdmVyc2lvbiB3aWxsIG1hcCB0byBQeXRob24zXG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdhcHQtZ2V0IC1xIHVwZGF0ZSAmJiBERUJJQU5fRlJPTlRFTkQ9bm9uaW50ZXJhY3RpdmUgYXB0LWdldCBpbnN0YWxsIC15IC1xIHB5dGhvbjMtcGlwIHB5dGhvbjMtdmVudiBweXRob24zLWJvdG8zIHB5dGhvbjMtcHl0ZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2FsaWFzIHB5dGVzdD1weXRlc3QtMycgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYHN5c3RlbWN0bCByZXN0YXJ0IGNvZGUtc2VydmVyQCR7dnNDb2RlVXNlcn0uc2VydmljZWAsXG4gICAgICAgICAgICAgICAgICAgICdzeXN0ZW1jdGwgc3RhcnQgbXVsdGlwYXRoZC5zZXJ2aWNlIHBhY2thZ2VraXQuc2VydmljZScsXG4gICAgICAgICAgICAgICAgICAgICdzeXN0ZW1jdGwgcmVzdGFydCB1bmF0dGVuZGVkLXVwZ3JhZGVzLnNlcnZpY2UnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIlB5dGhvbiBhbmQgUGlwIGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ3B5dGhvbjMgLS12ZXJzaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgJ3BpcDMgLS12ZXJzaW9uJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxBV1NDTEknLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnY3VybCAtZnNTTCBodHRwczovL2F3c2NsaS5hbWF6b25hd3MuY29tL2F3c2NsaS1leGUtbGludXgtJCh1bmFtZSAtbSkuemlwIC1vIC90bXAvYXdzLWNsaS56aXAnLFxuICAgICAgICAgICAgICAgICAgICAndW56aXAgLXEgLWQgL3RtcCAvdG1wL2F3cy1jbGkuemlwJyxcbiAgICAgICAgICAgICAgICAgICAgJ3N1ZG8gL3RtcC9hd3MvaW5zdGFsbCcsXG4gICAgICAgICAgICAgICAgICAgICdybSAtcmYgL3RtcC9hd3MnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIkFXUyBDTEkgaW5zdGFsbGVkLiBDaGVja2luZyBjb25maWd1cmF0aW9uXCInLFxuICAgICAgICAgICAgICAgICAgICAnYXdzIC0tdmVyc2lvbicsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdDb25maWd1cmVDb2RlU2VydmVyJyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgYGV4cG9ydCBIT01FPS9ob21lLyR7dnNDb2RlVXNlcn1gLFxuICAgICAgICAgICAgICAgICAgICAnY3VybCAtZnNTTCBodHRwczovL2NvZGUtc2VydmVyLmRldi9pbnN0YWxsLnNoIHwgYmFzaCAtcyAtLSAyPiYxJyxcbiAgICAgICAgICAgICAgICAgICAgYHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgY29kZS1zZXJ2ZXJAJHt2c0NvZGVVc2VyfSAyPiYxYCxcbiAgICAgICAgICAgICAgICAgICAgYHRlZSAvZXRjL25naW54L2NvbmYuZC9jb2RlLXNlcnZlci5jb25mIDw8RU9GXG5zZXJ2ZXIge1xuICAgIGxpc3RlbiA4MDtcbiAgICBsaXN0ZW4gWzo6XTo4MDtcbiAgICAjIHNlcnZlcl9uYW1lIGRpc3RyaWJ1dGlvbi5kaXN0cmlidXRpb25Eb21haW5OYW1lO1xuICAgIHNlcnZlcl9uYW1lICouY2xvdWRmcm9udC5uZXQ7XG4gICAgbG9jYXRpb24gLyB7XG4gICAgICBwcm94eV9wYXNzIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC87XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgXFxcXCRob3N0O1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBVcGdyYWRlIFxcXFwkaHR0cF91cGdyYWRlO1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBDb25uZWN0aW9uIHVwZ3JhZGU7XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEFjY2VwdC1FbmNvZGluZyBnemlwO1xuICAgIH1cbiAgICBsb2NhdGlvbiAvJHtkZXZTZXJ2ZXJCYXNlUGF0aH0ge1xuICAgICAgcHJveHlfcGFzcyBodHRwOi8vbG9jYWxob3N0OiR7ZGV2U2VydmVyUG9ydH0vJHtkZXZTZXJ2ZXJCYXNlUGF0aH07XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgXFxcXCRob3N0O1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBVcGdyYWRlIFxcXFwkaHR0cF91cGdyYWRlO1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBDb25uZWN0aW9uIHVwZ3JhZGU7XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEFjY2VwdC1FbmNvZGluZyBnemlwO1xuICAgIH1cbn1cbkVPRmAsXG4gICAgICAgICAgICAgICAgICAgIGBta2RpciAtcCAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5jb25maWcvY29kZS1zZXJ2ZXJgLFxuICAgICAgICAgICAgICAgICAgICBgdGVlIC9ob21lLyR7dnNDb2RlVXNlcn0vLmNvbmZpZy9jb2RlLXNlcnZlci9jb25maWcueWFtbCA8PEVPRlxuY2VydDogZmFsc2VcbmF1dGg6IHBhc3N3b3JkXG5oYXNoZWQtcGFzc3dvcmQ6IFwiJChlY2hvIC1uIHt7IFZTQ29kZVBhc3N3b3JkIH19IHwgYXJnb24yICQob3BlbnNzbCByYW5kIC1iYXNlNjQgMTIpIC1lKVwiXG5FT0ZgLFxuICAgICAgICAgICAgICAgICAgICBgbWtkaXIgLXAgL2hvbWUvJHt2c0NvZGVVc2VyfS8ubG9jYWwvc2hhcmUvY29kZS1zZXJ2ZXIvVXNlci9gLFxuICAgICAgICAgICAgICAgICAgICBgdG91Y2ggL2hvbWUvJHt2c0NvZGVVc2VyfS8uaHVzaGxvZ2luYCxcbiAgICAgICAgICAgICAgICAgICAgYG1rZGlyIC1wICR7aG9tZUZvbGRlcn0gJiYgY2hvd24gLVIgJHt2c0NvZGVVc2VyfToke3ZzQ29kZVVzZXJ9ICR7aG9tZUZvbGRlcn1gLFxuICAgICAgICAgICAgICAgICAgICBgdGVlIC9ob21lLyR7dnNDb2RlVXNlcn0vLmxvY2FsL3NoYXJlL2NvZGUtc2VydmVyL1VzZXIvc2V0dGluZ3MuanNvbiA8PEVPRlxue1xuICBcImV4dGVuc2lvbnMuYXV0b1VwZGF0ZVwiOiBmYWxzZSxcbiAgXCJleHRlbnNpb25zLmF1dG9DaGVja1VwZGF0ZXNcIjogZmFsc2UsXG4gIFwidGVsZW1ldHJ5LnRlbGVtZXRyeUxldmVsXCI6IFwib2ZmXCIsXG4gIFwic2VjdXJpdHkud29ya3NwYWNlLnRydXN0LnN0YXJ0dXBQcm9tcHRcIjogXCJuZXZlclwiLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5lbmFibGVkXCI6IGZhbHNlLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5iYW5uZXJcIjogXCJuZXZlclwiLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5lbXB0eVdpbmRvd1wiOiBmYWxzZSxcbiAgXCJweXRob24udGVzdGluZy5weXRlc3RFbmFibGVkXCI6IHRydWUsXG4gIFwiYXV0by1ydW4tY29tbWFuZC5ydWxlc1wiOiBbXG4gICAge1xuICAgICAgXCJjb21tYW5kXCI6IFwid29ya2JlbmNoLmFjdGlvbi50ZXJtaW5hbC5uZXdcIlxuICAgIH1cbiAgXVxufVxuRU9GYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgICAgYHN5c3RlbWN0bCByZXN0YXJ0IGNvZGUtc2VydmVyQCR7dnNDb2RlVXNlcn1gLFxuICAgICAgICAgICAgICAgICAgICAnc3lzdGVtY3RsIHJlc3RhcnQgbmdpbngnLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IC0tbG9naW4gY29kZS1zZXJ2ZXIgLS1pbnN0YWxsLWV4dGVuc2lvbiBBbWF6b25XZWJTZXJ2aWNlcy5hd3MtdG9vbGtpdC12c2NvZGUgLS1mb3JjZWAsXG4gICAgICAgICAgICAgICAgICAgIGBzdWRvIC11ICR7dnNDb2RlVXNlcn0gLS1sb2dpbiBjb2RlLXNlcnZlciAtLWluc3RhbGwtZXh0ZW5zaW9uIEFtYXpvbldlYlNlcnZpY2VzLmFtYXpvbi1xLXZzY29kZSAtLWZvcmNlYCxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSAtLWxvZ2luIGNvZGUtc2VydmVyIC0taW5zdGFsbC1leHRlbnNpb24gc3luZWRyYS5hdXRvLXJ1bi1jb21tYW5kIC0tZm9yY2VgLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IC0tbG9naW4gY29kZS1zZXJ2ZXIgLS1pbnN0YWxsLWV4dGVuc2lvbiB2c2NqYXZhLnZzY29kZS1qYXZhLXBhY2sgLS1mb3JjZWAsXG4gICAgICAgICAgICAgICAgICAgIGBzdWRvIC11ICR7dnNDb2RlVXNlcn0gLS1sb2dpbiBjb2RlLXNlcnZlciAtLWluc3RhbGwtZXh0ZW5zaW9uIG1zLXZzY29kZS5saXZlLXNlcnZlciAtLWZvcmNlYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgICAgJ2VjaG8gXCJOZ2lueCBpbnN0YWxsZWQuIENoZWNraW5nIGNvbmZpZ3VyYXRpb25cIicsXG4gICAgICAgICAgICAgICAgICAgICduZ2lueCAtdCAyPiYxJyxcbiAgICAgICAgICAgICAgICAgICAgJ3N5c3RlbWN0bCBzdGF0dXMgbmdpbngnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIkNvZGVTZXJ2ZXIgaW5zdGFsbGVkLiBDaGVja2luZyBjb25maWd1cmF0aW9uXCInLFxuICAgICAgICAgICAgICAgICAgICAnY29kZS1zZXJ2ZXIgLXYnLFxuICAgICAgICAgICAgICAgICAgICBgc3lzdGVtY3RsIHN0YXR1cyBjb2RlLXNlcnZlckAke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ1VwZGF0ZVByb2ZpbGUnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBMQU5HPWVuX1VTLnV0Zi04ID4+IC9ldGMvZW52aXJvbm1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBMQ19BTEw9ZW5fVVMuVVRGLTggPj4gL2V0Yy9lbnZpcm9ubWVudCcsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvICdQQVRIPSRQQVRIOi9ob21lLyR7dnNDb2RlVXNlcn0vLmxvY2FsL2JpbicgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2V4cG9ydCBQQVRIJyA+PiAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5iYXNocmNgLFxuICAgICAgICAgICAgICAgICAgICBgZWNobyAnZXhwb3J0IEFXU19SRUdJT049JHtTdGFjay5vZihzY29wZSkucmVnaW9ufScgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2V4cG9ydCBBV1NfQUNDT1VOVElEPSR7U3RhY2sub2Yoc2NvcGUpLmFjY291bnR9JyA+PiAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5iYXNocmNgLFxuICAgICAgICAgICAgICAgICAgICBgZWNobyAnZXhwb3J0IE5FWFRfVEVMRU1FVFJZX0RJU0FCTEVEPTEnID4+IC9ob21lLyR7dnNDb2RlVXNlcn0vLmJhc2hyY2AsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvIFwiZXhwb3J0IFBTMT0nXFxcXFtcXFxcMDMzWzAxOzMybVxcXFxdXFxcXHU6XFxcXFtcXFxcMDMzWzAxOzM0bVxcXFxdXFxcXHdcXFxcW1xcXFwwMzNbMDBtXFxcXF1cXFxcJCAnXCIgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxDREsnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnbnBtIGluc3RhbGwgLWcgYXdzLWNkaycsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiQVdTIENESyBpbnN0YWxsZWQuIENoZWNraW5nIGNvbmZpZ3VyYXRpb25cIicsXG4gICAgICAgICAgICAgICAgICAgICdjZGsgLS12ZXJzaW9uJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBMaW51eEZsYXZvclR5cGUuQU1BWk9OX0xJTlVYXzIwMjM6XG4gICAgICAgIHNzbURvY3VtZW50ID0gbmV3IHNzbS5DZm5Eb2N1bWVudChzY29wZSwgJ3NzbS1kb2N1bWVudC1hbDIwMjMnLCB7XG4gICAgICAgICAgbmFtZTogYHZzY29kZS1zZXJ2ZXItYWwyMDIzLSR7U3RhY2sub2Yoc2NvcGUpLnN0YWNrTmFtZX1gLFxuICAgICAgICAgIGRvY3VtZW50VHlwZTogJ0NvbW1hbmQnLFxuICAgICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICAgIHNjaGVtYVZlcnNpb246ICcyLjInLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdCb290c3RyYXAgVlNDb2RlIGNvZGUtc2VydmVyIGluc3RhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgVlNDb2RlUGFzc3dvcmQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiBTdGFjay5vZihzY29wZSkuc3RhY2tJZCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgTm9kZVZlcnNpb246IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiAnMjAnLFxuICAgICAgICAgICAgICAgIGFsbG93ZWRWYWx1ZXM6IFtcbiAgICAgICAgICAgICAgICAgICcyMicsXG4gICAgICAgICAgICAgICAgICAnMjAnLFxuICAgICAgICAgICAgICAgICAgJzE4JyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBEb3ROZXRWZXJzaW9uOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ1N0cmluZycsXG4gICAgICAgICAgICAgICAgZGVmYXVsdDogJzguMCcsXG4gICAgICAgICAgICAgICAgYWxsb3dlZFZhbHVlczogW1xuICAgICAgICAgICAgICAgICAgJzguMCcsXG4gICAgICAgICAgICAgICAgICAnNy4wJyxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIC8vIGFsbCBtYWluU3RlcHMgc2NyaXB0cyBhcmUgaW4gaW4gL3Zhci9saWIvYW1hem9uL3NzbS88aW5zdGFuY2VpZD4vZG9jdW1lbnQvb3JjaGVzdHJhdGlvbi88dXVpZD4vPFN0ZXBOYW1lPi9fc2NyaXB0LnNoXG4gICAgICAgICAgICBtYWluU3RlcHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpjb25maWd1cmVQYWNrYWdlJyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbENsb3VkV2F0Y2hBZ2VudCcsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBuYW1lOiAnQW1hem9uQ2xvdWRXYXRjaEFnZW50JyxcbiAgICAgICAgICAgICAgICAgIGFjdGlvbjogJ0luc3RhbGwnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdDb25maWd1cmVDbG91ZFdhdGNoQWdlbnQnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgZG9jdW1lbnRUeXBlOiAnU1NNRG9jdW1lbnQnLFxuICAgICAgICAgICAgICAgICAgZG9jdW1lbnRQYXRoOiAnQW1hem9uQ2xvdWRXYXRjaC1NYW5hZ2VBZ2VudCcsXG4gICAgICAgICAgICAgICAgICBkb2N1bWVudFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uOiAnY29uZmlndXJlJyxcbiAgICAgICAgICAgICAgICAgICAgbW9kZTogJ2VjMicsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsQ29uZmlndXJhdGlvblNvdXJjZTogJ2RlZmF1bHQnLFxuICAgICAgICAgICAgICAgICAgICBvcHRpb25hbFJlc3RhcnQ6ICd5ZXMnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnYXdzOnJ1blNoZWxsU2NyaXB0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbEJhc2VQYWNrYWdlc0RuZicsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdkbmYgaW5zdGFsbCAteSAtLWFsbG93ZXJhc2luZyB3aG9pcyBhcmdvbjIgdW56aXAgbmdpbnggY3VybCBnbnVwZyBvcGVuc3NsJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0FkZFVzZXJEbmYnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICBgZWNobyAnQWRkaW5nIHVzZXI6ICR7dnNDb2RlVXNlcn0nYCxcbiAgICAgICAgICAgICAgICAgICAgYGFkZHVzZXIgLWMgJycgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgIGBwYXNzd2QgLWwgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvIFwiJHt2c0NvZGVVc2VyfTp7eyBWU0NvZGVQYXNzd29yZCB9fVwiIHwgY2hwYXNzd2RgLFxuICAgICAgICAgICAgICAgICAgICBgdXNlcm1vZCAtYUcgd2hlZWwgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiVXNlciBhZGRlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgYGdldGVudCBwYXNzd2QgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdJbnN0YWxsTm9kZURuZicsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdkbmYgaW5zdGFsbCAteSBub2RlanMyMCBucG0nLFxuICAgICAgICAgICAgICAgICAgICAnbG4gLXMgLWYgL3Vzci9iaW4vbm9kZS0yMCAvdXNyL2Jpbi9ub2RlJyxcbiAgICAgICAgICAgICAgICAgICAgJ25wbSBpbnN0YWxsIC1nIG5wbUBsYXRlc3QnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIk5vZGUgYW5kIG5wbSBpbnN0YWxsZWQuIENoZWNraW5nIGNvbmZpZ3VyYXRpb25cIicsXG4gICAgICAgICAgICAgICAgICAgICdub2RlIC12JyxcbiAgICAgICAgICAgICAgICAgICAgJ25wbSAtdicsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdJbnN0YWxsRG9ja2VyRG5mJyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgJ2RuZiBpbnN0YWxsIC15IGRvY2tlcicsXG4gICAgICAgICAgICAgICAgICAgIGB1c2VybW9kIC1hRyBkb2NrZXIgJHt2c0NvZGVVc2VyfWAsXG4gICAgICAgICAgICAgICAgICAgIGBzeXN0ZW1jdGwgcmVzdGFydCBjb2RlLXNlcnZlckAke3ZzQ29kZVVzZXJ9LnNlcnZpY2VgLFxuICAgICAgICAgICAgICAgICAgICAnc3lzdGVtY3RsIHN0YXJ0IGRvY2tlci5zZXJ2aWNlJyxcbiAgICAgICAgICAgICAgICAgICAgJ2VjaG8gXCJEb2NrZXIgaW5zdGFsbGVkLiBDaGVja2luZyBjb25maWd1cmF0aW9uXCInLFxuICAgICAgICAgICAgICAgICAgICAnZG9ja2VyIC0tdmVyc2lvbicsXG4gICAgICAgICAgICAgICAgICAgICdzeXN0ZW1jdGwgc3RhdHVzIGRvY2tlci5zZXJ2aWNlJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxHaXREbmYnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnZG5mIGluc3RhbGwgLXkgZ2l0JyxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgXCIke3ZzQ29kZVVzZXJ9QGV4YW1wbGUuY29tXCJgLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IGdpdCBjb25maWcgLS1nbG9iYWwgdXNlci5uYW1lIFwiV29ya3Nob3AgJHt2c0NvZGVVc2VyfVwiYCxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSBnaXQgY29uZmlnIC0tZ2xvYmFsIGluaXQuZGVmYXVsdEJyYW5jaCBcIm1haW5cImAsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiR2l0IGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ2dpdCAtLXZlcnNpb24nLFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiAnYXdzOnJ1blNoZWxsU2NyaXB0JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnSW5zdGFsbFB5dGhvbkRuZicsXG4gICAgICAgICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICAgICAgICBydW5Db21tYW5kOiBbXG4gICAgICAgICAgICAgICAgICAgIC8vIEFMMjAyMyBjdXJyZW50bHkgc2hpcHMgd2l0aCBQeXRob24gMy45IHByZWluc3RhbGxlZCwgYnV0IDMuMTEgaXMgYXZhaWxhYmxlIGluIHRoZSByZXBvc2l0b3J5XG4gICAgICAgICAgICAgICAgICAgIC8vIEluc3RhbGwgMy4xMSBhbG9uZ3NpZGUgMy45IGFuZCBzZXR1cCBzb21lIGFsaWFzIHNvIHRoYXQgMy4xMSBpcyBsb2FkZWQgd2hlbiBwYXJ0aWNpcGFudCBydW5zIFB5dGhvbjNcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgUHl0aG9uIDMuMTIgYmVjb21lIGF2YWlsYWJsZSwgdXBkYXRlIGJlbG93XG4gICAgICAgICAgICAgICAgICAgICcjIS9iaW4vYmFzaCcsXG4gICAgICAgICAgICAgICAgICAgICdkbmYgaW5zdGFsbCAteSBweXRob24zLjExIHB5dGhvbjMuMTEtcGlwIHB5dGhvbjMtdmlydHVhbGVudiBweXRob24zLXB5dGVzdCBweXRob24zLWJvdG8zJyxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2FsaWFzIHB5dGVzdD1weXRlc3QtMycgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2FsaWFzIHB5dGhvbjM9cHl0aG9uMy4xMScgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2FsaWFzIHBpcDM9cGlwMy4xMScgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgJ2VjaG8gXFwnYWxpYXM9cHl0aG9uMz1weXRob24zLjExXFwnID4+IH4vLmJhc2hyYycsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFxcJ2FsaWFzIHBpcDM9cGlwMy4xMVxcJyA+PiB+Ly5iYXNocmMnLFxuICAgICAgICAgICAgICAgICAgICAncHl0aG9uMy4xMSAtbSBwaXAgaW5zdGFsbCAtLXVwZ3JhZGUgcGlwIDI+JjEnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIlB5dGhvbiBhbmQgUGlwIGluc3RhbGxlZC4gQ2hlY2tpbmcgY29uZmlndXJhdGlvblwiJyxcbiAgICAgICAgICAgICAgICAgICAgJ3B5dGhvbjMuMTEgLS12ZXJzaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgJ3B5dGhvbjMuMTEgLW0gcGlwIC0tdmVyc2lvbiAyPiYxJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgLy8gYWRkIGdvLCBkb3RuZXRcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxBV1NDTEknLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnY3VybCAtZnNTTCBodHRwczovL2F3c2NsaS5hbWF6b25hd3MuY29tL2F3c2NsaS1leGUtbGludXgtJCh1bmFtZSAtbSkuemlwIC1vIC90bXAvYXdzLWNsaS56aXAnLFxuICAgICAgICAgICAgICAgICAgICAndW56aXAgLXEgLWQgL3RtcCAvdG1wL2F3cy1jbGkuemlwJyxcbiAgICAgICAgICAgICAgICAgICAgJ3N1ZG8gL3RtcC9hd3MvaW5zdGFsbCcsXG4gICAgICAgICAgICAgICAgICAgICdybSAtcmYgL3RtcC9hd3MnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIkFXUyBDTEkgaW5zdGFsbGVkLiBDaGVja2luZyBjb25maWd1cmF0aW9uXCInLFxuICAgICAgICAgICAgICAgICAgICAnYXdzIC0tdmVyc2lvbicsXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246ICdhd3M6cnVuU2hlbGxTY3JpcHQnLFxuICAgICAgICAgICAgICAgIG5hbWU6ICdDb25maWd1cmVDb2RlU2VydmVyJyxcbiAgICAgICAgICAgICAgICBpbnB1dHM6IHtcbiAgICAgICAgICAgICAgICAgIHJ1bkNvbW1hbmQ6IFtcbiAgICAgICAgICAgICAgICAgICAgJyMhL2Jpbi9iYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgYGV4cG9ydCBIT01FPS9ob21lLyR7dnNDb2RlVXNlcn1gLFxuICAgICAgICAgICAgICAgICAgICAnY3VybCAtZnNTTCBodHRwczovL2NvZGUtc2VydmVyLmRldi9pbnN0YWxsLnNoIHwgYmFzaCAtcyAtLSAyPiYxJyxcbiAgICAgICAgICAgICAgICAgICAgYHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgY29kZS1zZXJ2ZXJAJHt2c0NvZGVVc2VyfSAyPiYxYCxcbiAgICAgICAgICAgICAgICAgICAgYHRlZSAvZXRjL25naW54L2NvbmYuZC9jb2RlLXNlcnZlci5jb25mIDw8RU9GXG5zZXJ2ZXIge1xuICAgIGxpc3RlbiA4MDtcbiAgICBsaXN0ZW4gWzo6XTo4MDtcbiAgICAjIHNlcnZlcl9uYW1lIGRpc3RyaWJ1dGlvbi5kaXN0cmlidXRpb25Eb21haW5OYW1lO1xuICAgIHNlcnZlcl9uYW1lICouY2xvdWRmcm9udC5uZXQ7XG4gICAgbG9jYXRpb24gLyB7XG4gICAgICBwcm94eV9wYXNzIGh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC87XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgXFxcXCRob3N0O1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBVcGdyYWRlIFxcXFwkaHR0cF91cGdyYWRlO1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBDb25uZWN0aW9uIHVwZ3JhZGU7XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEFjY2VwdC1FbmNvZGluZyBnemlwO1xuICAgIH1cbiAgICBsb2NhdGlvbiAvJHtkZXZTZXJ2ZXJCYXNlUGF0aH0ge1xuICAgICAgcHJveHlfcGFzcyBodHRwOi8vbG9jYWxob3N0OiR7ZGV2U2VydmVyUG9ydH0vJHtkZXZTZXJ2ZXJCYXNlUGF0aH07XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgXFxcXCRob3N0O1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBVcGdyYWRlIFxcXFwkaHR0cF91cGdyYWRlO1xuICAgICAgcHJveHlfc2V0X2hlYWRlciBDb25uZWN0aW9uIHVwZ3JhZGU7XG4gICAgICBwcm94eV9zZXRfaGVhZGVyIEFjY2VwdC1FbmNvZGluZyBnemlwO1xuICAgIH1cbn1cbkVPRmAsXG4gICAgICAgICAgICAgICAgICAgIGBta2RpciAtcCAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5jb25maWcvY29kZS1zZXJ2ZXJgLFxuICAgICAgICAgICAgICAgICAgICBgdGVlIC9ob21lLyR7dnNDb2RlVXNlcn0vLmNvbmZpZy9jb2RlLXNlcnZlci9jb25maWcueWFtbCA8PEVPRlxuY2VydDogZmFsc2VcbmF1dGg6IHBhc3N3b3JkXG5oYXNoZWQtcGFzc3dvcmQ6IFwiJChlY2hvIC1uIHt7IFZTQ29kZVBhc3N3b3JkIH19IHwgYXJnb24yICQob3BlbnNzbCByYW5kIC1iYXNlNjQgMTIpIC1lKVwiXG5FT0ZgLFxuICAgICAgICAgICAgICAgICAgICBgbWtkaXIgLXAgL2hvbWUvJHt2c0NvZGVVc2VyfS8ubG9jYWwvc2hhcmUvY29kZS1zZXJ2ZXIvVXNlci9gLFxuICAgICAgICAgICAgICAgICAgICBgdG91Y2ggL2hvbWUvJHt2c0NvZGVVc2VyfS8uaHVzaGxvZ2luYCxcbiAgICAgICAgICAgICAgICAgICAgYG1rZGlyIC1wICR7aG9tZUZvbGRlcn0gJiYgY2hvd24gLVIgJHt2c0NvZGVVc2VyfToke3ZzQ29kZVVzZXJ9ICR7aG9tZUZvbGRlcn1gLFxuICAgICAgICAgICAgICAgICAgICBgdGVlIC9ob21lLyR7dnNDb2RlVXNlcn0vLmxvY2FsL3NoYXJlL2NvZGUtc2VydmVyL1VzZXIvc2V0dGluZ3MuanNvbiA8PEVPRlxue1xuICBcImV4dGVuc2lvbnMuYXV0b1VwZGF0ZVwiOiBmYWxzZSxcbiAgXCJleHRlbnNpb25zLmF1dG9DaGVja1VwZGF0ZXNcIjogZmFsc2UsXG4gIFwidGVsZW1ldHJ5LnRlbGVtZXRyeUxldmVsXCI6IFwib2ZmXCIsXG4gIFwic2VjdXJpdHkud29ya3NwYWNlLnRydXN0LnN0YXJ0dXBQcm9tcHRcIjogXCJuZXZlclwiLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5lbmFibGVkXCI6IGZhbHNlLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5iYW5uZXJcIjogXCJuZXZlclwiLFxuICBcInNlY3VyaXR5LndvcmtzcGFjZS50cnVzdC5lbXB0eVdpbmRvd1wiOiBmYWxzZSxcbiAgXCJweXRob24udGVzdGluZy5weXRlc3RFbmFibGVkXCI6IHRydWUsXG4gIFwiYXV0by1ydW4tY29tbWFuZC5ydWxlc1wiOiBbXG4gICAge1xuICAgICAgXCJjb21tYW5kXCI6IFwid29ya2JlbmNoLmFjdGlvbi50ZXJtaW5hbC5uZXdcIlxuICAgIH1cbiAgXVxufVxuRU9GYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgICAgYHN5c3RlbWN0bCByZXN0YXJ0IGNvZGUtc2VydmVyQCR7dnNDb2RlVXNlcn1gLFxuICAgICAgICAgICAgICAgICAgICAnc3lzdGVtY3RsIHJlc3RhcnQgbmdpbngnLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IC0tbG9naW4gY29kZS1zZXJ2ZXIgLS1pbnN0YWxsLWV4dGVuc2lvbiBBbWF6b25XZWJTZXJ2aWNlcy5hd3MtdG9vbGtpdC12c2NvZGUgLS1mb3JjZWAsXG4gICAgICAgICAgICAgICAgICAgIGBzdWRvIC11ICR7dnNDb2RlVXNlcn0gLS1sb2dpbiBjb2RlLXNlcnZlciAtLWluc3RhbGwtZXh0ZW5zaW9uIEFtYXpvbldlYlNlcnZpY2VzLmFtYXpvbi1xLXZzY29kZSAtLWZvcmNlYCxcbiAgICAgICAgICAgICAgICAgICAgYHN1ZG8gLXUgJHt2c0NvZGVVc2VyfSAtLWxvZ2luIGNvZGUtc2VydmVyIC0taW5zdGFsbC1leHRlbnNpb24gc3luZWRyYS5hdXRvLXJ1bi1jb21tYW5kIC0tZm9yY2VgLFxuICAgICAgICAgICAgICAgICAgICBgc3VkbyAtdSAke3ZzQ29kZVVzZXJ9IC0tbG9naW4gY29kZS1zZXJ2ZXIgLS1pbnN0YWxsLWV4dGVuc2lvbiB2c2NqYXZhLnZzY29kZS1qYXZhLXBhY2sgLS1mb3JjZWAsXG4gICAgICAgICAgICAgICAgICAgIGBzdWRvIC11ICR7dnNDb2RlVXNlcn0gLS1sb2dpbiBjb2RlLXNlcnZlciAtLWluc3RhbGwtZXh0ZW5zaW9uIG1zLXZzY29kZS5saXZlLXNlcnZlciAtLWZvcmNlYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgICAgJ2VjaG8gXCJOZ2lueCBpbnN0YWxsZWQuIENoZWNraW5nIGNvbmZpZ3VyYXRpb25cIicsXG4gICAgICAgICAgICAgICAgICAgICduZ2lueCAtdCAyPiYxJyxcbiAgICAgICAgICAgICAgICAgICAgJ3N5c3RlbWN0bCBzdGF0dXMgbmdpbngnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBcIkNvZGVTZXJ2ZXIgaW5zdGFsbGVkLiBDaGVja2luZyBjb25maWd1cmF0aW9uXCInLFxuICAgICAgICAgICAgICAgICAgICAnY29kZS1zZXJ2ZXIgLXYnLFxuICAgICAgICAgICAgICAgICAgICBgc3lzdGVtY3RsIHN0YXR1cyBjb2RlLXNlcnZlckAke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ1VwZGF0ZVByb2ZpbGUnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBMQU5HPWVuX1VTLnV0Zi04ID4+IC9ldGMvZW52aXJvbm1lbnQnLFxuICAgICAgICAgICAgICAgICAgICAnZWNobyBMQ19BTEw9ZW5fVVMuVVRGLTggPj4gL2V0Yy9lbnZpcm9ubWVudCcsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvICdQQVRIPSRQQVRIOi9ob21lLyR7dnNDb2RlVXNlcn0vLmxvY2FsL2JpbicgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2V4cG9ydCBQQVRIJyA+PiAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5iYXNocmNgLFxuICAgICAgICAgICAgICAgICAgICBgZWNobyAnZXhwb3J0IEFXU19SRUdJT049JHtTdGFjay5vZihzY29wZSkucmVnaW9ufScgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGVjaG8gJ2V4cG9ydCBBV1NfQUNDT1VOVElEPSR7U3RhY2sub2Yoc2NvcGUpLmFjY291bnR9JyA+PiAvaG9tZS8ke3ZzQ29kZVVzZXJ9Ly5iYXNocmNgLFxuICAgICAgICAgICAgICAgICAgICBgZWNobyAnZXhwb3J0IE5FWFRfVEVMRU1FVFJZX0RJU0FCTEVEPTEnID4+IC9ob21lLyR7dnNDb2RlVXNlcn0vLmJhc2hyY2AsXG4gICAgICAgICAgICAgICAgICAgIGBlY2hvIFwiZXhwb3J0IFBTMT0nXFxcXFtcXFxcMDMzWzAxOzMybVxcXFxdXFxcXHU6XFxcXFtcXFxcMDMzWzAxOzM0bVxcXFxdXFxcXHdcXFxcW1xcXFwwMzNbMDBtXFxcXF1cXFxcJCAnXCIgPj4gL2hvbWUvJHt2c0NvZGVVc2VyfS8uYmFzaHJjYCxcbiAgICAgICAgICAgICAgICAgICAgYGNob3duIC1SICR7dnNDb2RlVXNlcn06JHt2c0NvZGVVc2VyfSAvaG9tZS8ke3ZzQ29kZVVzZXJ9YCxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjdGlvbjogJ2F3czpydW5TaGVsbFNjcmlwdCcsXG4gICAgICAgICAgICAgICAgbmFtZTogJ0luc3RhbGxDREsnLFxuICAgICAgICAgICAgICAgIGlucHV0czoge1xuICAgICAgICAgICAgICAgICAgcnVuQ29tbWFuZDogW1xuICAgICAgICAgICAgICAgICAgICAnIyEvYmluL2Jhc2gnLFxuICAgICAgICAgICAgICAgICAgICAnbnBtIGluc3RhbGwgLWcgYXdzLWNkaycsXG4gICAgICAgICAgICAgICAgICAgICdlY2hvIFwiQVdTIENESyBpbnN0YWxsZWQuIENoZWNraW5nIGNvbmZpZ3VyYXRpb25cIicsXG4gICAgICAgICAgICAgICAgICAgICdjZGsgLS12ZXJzaW9uJyxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBMaW51eCBmbGF2b3I6ICR7bGludXhGbGF2b3J9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNzbURvY3VtZW50O1xuICB9XG59XG5cbmludGVyZmFjZSBDdXN0b21SZXNvdXJjZUluc3RhbGxlck9wdGlvbnMgZXh0ZW5kcyBJbnN0YWxsZXJPcHRpb25zIHt9XG5cbmNsYXNzIEN1c3RvbVJlc291cmNlSW5zdGFsbGVyIGV4dGVuZHMgSW5zdGFsbGVyIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgb3B0aW9uczogQ3VzdG9tUmVzb3VyY2VJbnN0YWxsZXJPcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGNvbnN0IG9uRXZlbnQ6IEZ1bmN0aW9uID0gbmV3IEluc3RhbGxlckZ1bmN0aW9uKHNjb3BlLCAnSW5zdGFsbGVyT25FdmVudEhhbmRsZXInLCB7XG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5zZWNvbmRzKDMwMCksIC8vIFRPRE8gY29uZmlndXJhYmxlXG4gICAgICBtZW1vcnlTaXplOiA1MTIsIC8vIFRPRE8gY29uZmlndXJhYmxlXG4gICAgfSk7XG4gICAgTmFnU3VwcHJlc3Npb25zLmFkZFJlc291cmNlU3VwcHJlc3Npb25zKFtcbiAgICAgIG9uRXZlbnQsXG4gICAgXSwgW1xuICAgICAgeyBpZDogJ0F3c1NvbHV0aW9ucy1JQU00JywgcmVhc29uOiAnRm9yIHRoaXMgZXZlbnQgaGFuZGxlciB3ZSBkbyBub3QgbmVlZCB0byByZXN0cmljdCBtYW5hZ2VkIHBvbGljaWVzJyB9LFxuICAgICAgeyBpZDogJ0F3c1NvbHV0aW9ucy1MMScsIHJlYXNvbjogJ0ZvciB0aGlzIGxhbWJkYSB0aGUgbGF0ZXN0IHJ1bnRpbWUgaXMgbm90IG5lZWRlZCcgfSxcbiAgICBdLCB0cnVlKTtcblxuICAgIGNvbnN0IGRvY3VtZW50QXJuID0gQXJuLmZvcm1hdCh7XG4gICAgICBzZXJ2aWNlOiAnc3NtJyxcbiAgICAgIHJlc291cmNlOiAnZG9jdW1lbnQnLFxuICAgICAgcmVzb3VyY2VOYW1lOiBvcHRpb25zLmRvY3VtZW50TmFtZSxcbiAgICB9LCBTdGFjay5vZihzY29wZSkpO1xuXG4gICAgY29uc3QgY3dNYW5hZ2VBZ2VudEFybiA9IEFybi5mb3JtYXQoe1xuICAgICAgc2VydmljZTogJ3NzbScsXG4gICAgICByZXNvdXJjZTogJ2RvY3VtZW50JyxcbiAgICAgIHJlc291cmNlTmFtZTogJ0FtYXpvbkNsb3VkV2F0Y2gtTWFuYWdlQWdlbnQnLFxuICAgIH0sIFN0YWNrLm9mKHNjb3BlKSk7XG5cbiAgICBjb25zdCB0YXJnZXRFYzJJbnN0YW5jZUFybiA9IEFybi5mb3JtYXQoe1xuICAgICAgc2VydmljZTogJ2VjMicsXG4gICAgICByZXNvdXJjZTogJ2luc3RhbmNlJyxcbiAgICAgIHJlc291cmNlTmFtZTogb3B0aW9ucy5pbnN0YW5jZUlkLFxuICAgIH0sIFN0YWNrLm9mKHNjb3BlKSk7XG5cbiAgICBvbkV2ZW50LmFkZFRvUm9sZVBvbGljeShuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgJ3NzbTpTZW5kQ29tbWFuZCcsXG4gICAgICBdLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIGRvY3VtZW50QXJuLFxuICAgICAgICBjd01hbmFnZUFnZW50QXJuLFxuICAgICAgICB0YXJnZXRFYzJJbnN0YW5jZUFybixcbiAgICAgIF0sXG4gICAgfSkpO1xuXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIoc2NvcGUsICdJbnN0YWxsZXJQcm92aWRlcicsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBvbkV2ZW50LFxuICAgIH0pO1xuICAgIE5hZ1N1cHByZXNzaW9ucy5hZGRSZXNvdXJjZVN1cHByZXNzaW9ucyhbXG4gICAgICBwcm92aWRlcixcbiAgICBdLCBbXG4gICAgICB7IGlkOiAnQXdzU29sdXRpb25zLUlBTTQnLCByZWFzb246ICdGb3IgdGhpcyBwcm92aWRlciB3ZSBkbyBub3QgbmVlZCB0byByZXN0cmljdCBtYW5hZ2VkIHBvbGljaWVzJyB9LFxuICAgICAgeyBpZDogJ0F3c1NvbHV0aW9ucy1JQU01JywgcmVhc29uOiAnRm9yIHRoaXMgcHJvdmlkZXIgd2lsZGNhcmRzIGFyZSBmaW5lJyB9LFxuICAgICAgeyBpZDogJ0F3c1NvbHV0aW9ucy1MMScsIHJlYXNvbjogJ0ZvciB0aGlzIHByb3ZpZGVyIHRoZSBsYXRlc3QgcnVudGltZSBpcyBub3QgbmVlZGVkJyB9LFxuICAgIF0sIHRydWUpO1xuXG4gICAgbmV3IEN1c3RvbVJlc291cmNlKHNjb3BlLCAnU1NNSW5zdGFsbGVyQ3VzdG9tUmVzb3VyY2UnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgU2VydmljZVRpbWVvdXQ6IDMwNSwgLy8gVE9ETyBjb25maWd1cmFibGVcbiAgICAgICAgSW5zdGFuY2VJZDogb3B0aW9ucy5pbnN0YW5jZUlkLFxuICAgICAgICBEb2N1bWVudE5hbWU6IG9wdGlvbnMuZG9jdW1lbnROYW1lLFxuICAgICAgICBDbG91ZFdhdGNoTG9nR3JvdXBOYW1lOiBvcHRpb25zLmNsb3VkV2F0Y2hMb2dHcm91cE5hbWUsXG4gICAgICAgIFZTQ29kZVBhc3N3b3JkOiBvcHRpb25zLnZzQ29kZVBhc3N3b3JkLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG5cbiAgcHVibGljIF9iaW5kKCkgeyB9XG59Il19