@bitgo-beta/sdk-coin-sol 7.6.4-beta.44 → 7.6.4-beta.441

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 (400) hide show
  1. package/dist/cjs/src/bigint-buffer-guard.d.ts.map +1 -0
  2. package/dist/cjs/src/bigint-buffer-guard.js +29 -0
  3. package/dist/cjs/src/config/token2022StaticConfig.d.ts.map +1 -0
  4. package/dist/cjs/src/config/token2022StaticConfig.js +50 -0
  5. package/dist/cjs/src/index.d.ts.map +1 -0
  6. package/dist/{src → cjs/src}/index.js +1 -1
  7. package/dist/cjs/src/lib/ataInitializationBuilder.d.ts.map +1 -0
  8. package/dist/cjs/src/lib/ataInitializationBuilder.js +196 -0
  9. package/dist/cjs/src/lib/closeAtaBuilder.d.ts +51 -0
  10. package/dist/cjs/src/lib/closeAtaBuilder.d.ts.map +1 -0
  11. package/dist/cjs/src/lib/closeAtaBuilder.js +147 -0
  12. package/dist/{src → cjs/src}/lib/constants.d.ts +24 -0
  13. package/dist/cjs/src/lib/constants.d.ts.map +1 -0
  14. package/dist/cjs/src/lib/constants.js +196 -0
  15. package/dist/cjs/src/lib/customInstructionBuilder.d.ts.map +1 -0
  16. package/dist/cjs/src/lib/customInstructionBuilder.js +289 -0
  17. package/dist/cjs/src/lib/explainTransactionWasm.d.ts +21 -0
  18. package/dist/cjs/src/lib/explainTransactionWasm.d.ts.map +1 -0
  19. package/dist/cjs/src/lib/explainTransactionWasm.js +264 -0
  20. package/dist/{src → cjs/src}/lib/iface.d.ts +20 -2
  21. package/dist/cjs/src/lib/iface.d.ts.map +1 -0
  22. package/dist/cjs/src/lib/iface.js +7 -0
  23. package/dist/{src → cjs/src}/lib/index.d.ts +1 -0
  24. package/dist/cjs/src/lib/index.d.ts.map +1 -0
  25. package/dist/{src → cjs/src}/lib/index.js +4 -2
  26. package/dist/{src → cjs/src}/lib/instructionParamsFactory.d.ts +1 -0
  27. package/dist/cjs/src/lib/instructionParamsFactory.d.ts.map +1 -0
  28. package/dist/cjs/src/lib/instructionParamsFactory.js +1059 -0
  29. package/dist/cjs/src/lib/jitoStakePoolOperations.d.ts.map +1 -0
  30. package/dist/cjs/src/lib/jitoStakePoolOperations.js +200 -0
  31. package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
  32. package/dist/cjs/src/lib/keyPair.js +63 -0
  33. package/dist/cjs/src/lib/messages/index.d.ts.map +1 -0
  34. package/dist/{src → cjs/src}/lib/messages/index.js +1 -1
  35. package/dist/cjs/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  36. package/dist/cjs/src/lib/messages/messageBuilderFactory.js +19 -0
  37. package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts +25 -0
  38. package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
  39. package/dist/cjs/src/lib/recoverNestedAtaBuilder.js +90 -0
  40. package/dist/cjs/src/lib/solInstructionFactory.d.ts.map +1 -0
  41. package/dist/cjs/src/lib/solInstructionFactory.js +595 -0
  42. package/dist/cjs/src/lib/stakingActivateBuilder.d.ts.map +1 -0
  43. package/dist/cjs/src/lib/stakingActivateBuilder.js +120 -0
  44. package/dist/cjs/src/lib/stakingAuthorizeBuilder.d.ts.map +1 -0
  45. package/dist/cjs/src/lib/stakingAuthorizeBuilder.js +89 -0
  46. package/dist/cjs/src/lib/stakingDeactivateBuilder.d.ts.map +1 -0
  47. package/dist/cjs/src/lib/stakingDeactivateBuilder.js +208 -0
  48. package/dist/cjs/src/lib/stakingDelegateBuilder.d.ts.map +1 -0
  49. package/dist/cjs/src/lib/stakingDelegateBuilder.js +120 -0
  50. package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
  51. package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.js +110 -0
  52. package/dist/cjs/src/lib/stakingWithdrawBuilder.d.ts.map +1 -0
  53. package/dist/cjs/src/lib/stakingWithdrawBuilder.js +78 -0
  54. package/dist/cjs/src/lib/token2022Config.d.ts.map +1 -0
  55. package/dist/cjs/src/lib/token2022Config.js +27 -0
  56. package/dist/cjs/src/lib/tokenTransferBuilder.d.ts.map +1 -0
  57. package/dist/cjs/src/lib/tokenTransferBuilder.js +188 -0
  58. package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
  59. package/dist/cjs/src/lib/transaction.js +612 -0
  60. package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
  61. package/dist/cjs/src/lib/transactionBuilder.js +380 -0
  62. package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +5 -0
  63. package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  64. package/dist/cjs/src/lib/transactionBuilderFactory.js +209 -0
  65. package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
  66. package/dist/cjs/src/lib/transferBuilder.js +70 -0
  67. package/dist/cjs/src/lib/transferBuilderV2.d.ts.map +1 -0
  68. package/dist/cjs/src/lib/transferBuilderV2.js +210 -0
  69. package/dist/cjs/src/lib/utils.d.ts.map +1 -0
  70. package/dist/cjs/src/lib/utils.js +604 -0
  71. package/dist/cjs/src/lib/walletInitializationBuilder.d.ts.map +1 -0
  72. package/dist/cjs/src/lib/walletInitializationBuilder.js +71 -0
  73. package/dist/cjs/src/register.d.ts.map +1 -0
  74. package/dist/cjs/src/register.js +15 -0
  75. package/dist/{src → cjs/src}/sol.d.ts +53 -0
  76. package/dist/cjs/src/sol.d.ts.map +1 -0
  77. package/dist/cjs/src/sol.js +1464 -0
  78. package/dist/{src → cjs/src}/solToken.d.ts +5 -0
  79. package/dist/cjs/src/solToken.d.ts.map +1 -0
  80. package/dist/cjs/src/solToken.js +76 -0
  81. package/dist/cjs/src/tsol.d.ts.map +1 -0
  82. package/dist/cjs/src/tsol.js +24 -0
  83. package/dist/{test → cjs/test}/fixtures/sol.d.ts.map +1 -1
  84. package/dist/cjs/test/fixtures/sol.js +1433 -0
  85. package/dist/{test → cjs/test}/resources/sol.d.ts +27 -27
  86. package/dist/cjs/test/resources/sol.d.ts.map +1 -0
  87. package/dist/cjs/test/resources/sol.js +320 -0
  88. package/dist/cjs/test/unit/explainTransactionWasm.d.ts +5 -0
  89. package/dist/cjs/test/unit/explainTransactionWasm.d.ts.map +1 -0
  90. package/dist/cjs/test/unit/explainTransactionWasm.js +26 -0
  91. package/dist/cjs/test/unit/fixtures/solBackupKey.d.ts.map +1 -0
  92. package/dist/cjs/test/unit/fixtures/solBackupKey.js +8 -0
  93. package/dist/cjs/test/unit/getBuilderFactory.d.ts.map +1 -0
  94. package/dist/cjs/test/unit/getBuilderFactory.js +10 -0
  95. package/dist/cjs/test/unit/instructionParamsFactory.d.ts.map +1 -0
  96. package/dist/cjs/test/unit/instructionParamsFactory.js +412 -0
  97. package/dist/cjs/test/unit/instructionParamsFactory.staking.d.ts.map +1 -0
  98. package/dist/cjs/test/unit/instructionParamsFactory.staking.js +1059 -0
  99. package/dist/cjs/test/unit/jitoWasmVerification.d.ts +2 -0
  100. package/dist/cjs/test/unit/jitoWasmVerification.d.ts.map +1 -0
  101. package/dist/cjs/test/unit/jitoWasmVerification.js +78 -0
  102. package/dist/{test → cjs/test}/unit/keyPair.d.ts.map +1 -1
  103. package/dist/cjs/test/unit/keyPair.js +177 -0
  104. package/dist/cjs/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  105. package/dist/cjs/test/unit/messages/messageBuilderFactory.js +118 -0
  106. package/dist/cjs/test/unit/messages/simpleMessageBuilder.d.ts.map +1 -0
  107. package/dist/cjs/test/unit/messages/simpleMessageBuilder.js +194 -0
  108. package/dist/{test → cjs/test}/unit/sol.d.ts.map +1 -1
  109. package/dist/cjs/test/unit/sol.js +3504 -0
  110. package/dist/cjs/test/unit/solInstructionFactory.d.ts.map +1 -0
  111. package/dist/cjs/test/unit/solInstructionFactory.js +454 -0
  112. package/dist/cjs/test/unit/solToken.d.ts.map +1 -0
  113. package/dist/cjs/test/unit/solToken.js +37 -0
  114. package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
  115. package/dist/cjs/test/unit/transaction.js +1108 -0
  116. package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +1 -0
  117. package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.js +202 -0
  118. package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +1 -0
  119. package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.js +471 -0
  120. package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.d.ts +2 -0
  121. package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.d.ts.map +1 -0
  122. package/dist/cjs/test/unit/transactionBuilder/closeAtaBuilder.js +333 -0
  123. package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +1 -0
  124. package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.js +413 -0
  125. package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +1 -0
  126. package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.js +430 -0
  127. package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +1 -0
  128. package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +157 -0
  129. package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +1 -0
  130. package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.js +384 -0
  131. package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +1 -0
  132. package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.js +224 -0
  133. package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
  134. package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +259 -0
  135. package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
  136. package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.js +787 -0
  137. package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  138. package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.js +495 -0
  139. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  140. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +286 -0
  141. package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +1 -0
  142. package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.js +862 -0
  143. package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +1 -0
  144. package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.js +259 -0
  145. package/dist/{test → cjs/test}/unit/utils.d.ts.map +1 -1
  146. package/dist/cjs/test/unit/utils.js +517 -0
  147. package/dist/cjs/test/unit/versionedTransaction.d.ts.map +1 -0
  148. package/dist/cjs/test/unit/versionedTransaction.js +207 -0
  149. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  150. package/dist/esm/bigint-buffer-guard.d.ts +1 -0
  151. package/dist/esm/config/token2022StaticConfig.d.ts +3 -0
  152. package/dist/esm/config/token2022StaticConfig.js +47 -0
  153. package/dist/esm/index.d.ts +7 -0
  154. package/dist/esm/index.js +7 -0
  155. package/dist/esm/lib/ataInitializationBuilder.d.ts +47 -0
  156. package/dist/esm/lib/ataInitializationBuilder.js +156 -0
  157. package/dist/esm/lib/closeAtaBuilder.d.ts +51 -0
  158. package/dist/esm/lib/closeAtaBuilder.d.ts.map +1 -0
  159. package/dist/esm/lib/closeAtaBuilder.js +140 -0
  160. package/dist/esm/lib/constants.d.ts +164 -0
  161. package/dist/esm/lib/constants.d.ts.map +1 -0
  162. package/dist/esm/lib/constants.js +193 -0
  163. package/dist/esm/lib/customInstructionBuilder.d.ts +72 -0
  164. package/dist/esm/lib/customInstructionBuilder.js +282 -0
  165. package/dist/esm/lib/explainTransactionWasm.d.ts +21 -0
  166. package/dist/esm/lib/explainTransactionWasm.d.ts.map +1 -0
  167. package/dist/esm/lib/explainTransactionWasm.js +261 -0
  168. package/dist/esm/lib/iface.d.ts +262 -0
  169. package/dist/esm/lib/iface.d.ts.map +1 -0
  170. package/dist/esm/lib/iface.js +3 -0
  171. package/dist/esm/lib/index.d.ts +23 -0
  172. package/dist/{src → esm}/lib/index.d.ts.map +1 -1
  173. package/dist/esm/lib/index.js +23 -0
  174. package/dist/esm/lib/instructionParamsFactory.d.ts +13 -0
  175. package/dist/{src → esm}/lib/instructionParamsFactory.d.ts.map +1 -1
  176. package/dist/esm/lib/instructionParamsFactory.js +1052 -0
  177. package/dist/esm/lib/jitoStakePoolOperations.d.ts +113 -0
  178. package/dist/esm/lib/jitoStakePoolOperations.js +189 -0
  179. package/dist/esm/lib/keyPair.d.ts +26 -0
  180. package/dist/esm/lib/keyPair.js +59 -0
  181. package/dist/esm/lib/messages/index.d.ts +2 -0
  182. package/dist/esm/lib/messages/index.js +2 -0
  183. package/dist/esm/lib/messages/messageBuilderFactory.d.ts +7 -0
  184. package/dist/{src → esm}/lib/messages/messageBuilderFactory.js +5 -9
  185. package/dist/esm/lib/recoverNestedAtaBuilder.d.ts +25 -0
  186. package/dist/esm/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
  187. package/dist/esm/lib/recoverNestedAtaBuilder.js +83 -0
  188. package/dist/esm/lib/solInstructionFactory.d.ts +10 -0
  189. package/dist/esm/lib/solInstructionFactory.d.ts.map +1 -0
  190. package/dist/esm/lib/solInstructionFactory.js +589 -0
  191. package/dist/esm/lib/stakingActivateBuilder.d.ts +59 -0
  192. package/dist/esm/lib/stakingActivateBuilder.js +113 -0
  193. package/dist/esm/lib/stakingAuthorizeBuilder.d.ts +43 -0
  194. package/dist/esm/lib/stakingAuthorizeBuilder.js +82 -0
  195. package/dist/esm/lib/stakingDeactivateBuilder.d.ts +81 -0
  196. package/dist/{src → esm}/lib/stakingDeactivateBuilder.js +31 -38
  197. package/dist/esm/lib/stakingDelegateBuilder.d.ts +42 -0
  198. package/dist/esm/lib/stakingDelegateBuilder.js +113 -0
  199. package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.d.ts +33 -0
  200. package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.js +103 -0
  201. package/dist/esm/lib/stakingWithdrawBuilder.d.ts +31 -0
  202. package/dist/esm/lib/stakingWithdrawBuilder.js +71 -0
  203. package/dist/esm/lib/token2022Config.d.ts +44 -0
  204. package/dist/esm/lib/token2022Config.js +23 -0
  205. package/dist/esm/lib/tokenTransferBuilder.d.ts +41 -0
  206. package/dist/esm/lib/tokenTransferBuilder.js +181 -0
  207. package/dist/esm/lib/transaction.d.ts +103 -0
  208. package/dist/esm/lib/transaction.d.ts.map +1 -0
  209. package/dist/esm/lib/transaction.js +605 -0
  210. package/dist/esm/lib/transactionBuilder.d.ts +128 -0
  211. package/dist/esm/lib/transactionBuilder.js +373 -0
  212. package/dist/esm/lib/transactionBuilderFactory.d.ts +120 -0
  213. package/dist/esm/lib/transactionBuilderFactory.d.ts.map +1 -0
  214. package/dist/esm/lib/transactionBuilderFactory.js +205 -0
  215. package/dist/esm/lib/transferBuilder.d.ts +26 -0
  216. package/dist/esm/lib/transferBuilder.js +63 -0
  217. package/dist/esm/lib/transferBuilderV2.d.ts +43 -0
  218. package/dist/esm/lib/transferBuilderV2.js +203 -0
  219. package/dist/esm/lib/utils.d.ts +200 -0
  220. package/dist/{src → esm}/lib/utils.d.ts.map +1 -1
  221. package/dist/esm/lib/utils.js +567 -0
  222. package/dist/esm/lib/walletInitializationBuilder.d.ts +26 -0
  223. package/dist/esm/lib/walletInitializationBuilder.js +64 -0
  224. package/dist/esm/register.d.ts +3 -0
  225. package/dist/esm/register.js +11 -0
  226. package/dist/esm/sol.d.ts +280 -0
  227. package/dist/esm/sol.d.ts.map +1 -0
  228. package/dist/esm/sol.js +1423 -0
  229. package/dist/esm/solToken.d.ts +42 -0
  230. package/dist/{src → esm}/solToken.d.ts.map +1 -1
  231. package/dist/esm/solToken.js +72 -0
  232. package/dist/esm/tsol.d.ts +11 -0
  233. package/dist/esm/tsol.js +20 -0
  234. package/package.json +35 -16
  235. package/dist/src/config/token2022StaticConfig.js +0 -50
  236. package/dist/src/lib/ataInitializationBuilder.js +0 -196
  237. package/dist/src/lib/closeAtaBuilder.d.ts +0 -19
  238. package/dist/src/lib/closeAtaBuilder.d.ts.map +0 -1
  239. package/dist/src/lib/closeAtaBuilder.js +0 -69
  240. package/dist/src/lib/constants.d.ts.map +0 -1
  241. package/dist/src/lib/constants.js +0 -171
  242. package/dist/src/lib/customInstructionBuilder.js +0 -289
  243. package/dist/src/lib/iface.d.ts.map +0 -1
  244. package/dist/src/lib/iface.js +0 -7
  245. package/dist/src/lib/instructionParamsFactory.js +0 -1036
  246. package/dist/src/lib/jitoStakePoolOperations.js +0 -200
  247. package/dist/src/lib/keyPair.js +0 -63
  248. package/dist/src/lib/solInstructionFactory.d.ts.map +0 -1
  249. package/dist/src/lib/solInstructionFactory.js +0 -572
  250. package/dist/src/lib/stakingActivateBuilder.js +0 -120
  251. package/dist/src/lib/stakingAuthorizeBuilder.js +0 -89
  252. package/dist/src/lib/stakingDelegateBuilder.js +0 -120
  253. package/dist/src/lib/stakingRawMsgAuthorizeBuilder.js +0 -110
  254. package/dist/src/lib/stakingWithdrawBuilder.js +0 -78
  255. package/dist/src/lib/token2022Config.js +0 -27
  256. package/dist/src/lib/tokenTransferBuilder.js +0 -188
  257. package/dist/src/lib/transaction.d.ts.map +0 -1
  258. package/dist/src/lib/transaction.js +0 -595
  259. package/dist/src/lib/transactionBuilder.js +0 -380
  260. package/dist/src/lib/transactionBuilderFactory.d.ts.map +0 -1
  261. package/dist/src/lib/transactionBuilderFactory.js +0 -202
  262. package/dist/src/lib/transferBuilder.js +0 -70
  263. package/dist/src/lib/transferBuilderV2.js +0 -210
  264. package/dist/src/lib/utils.js +0 -589
  265. package/dist/src/lib/walletInitializationBuilder.js +0 -71
  266. package/dist/src/register.js +0 -15
  267. package/dist/src/sol.d.ts.map +0 -1
  268. package/dist/src/sol.js +0 -1285
  269. package/dist/src/solToken.js +0 -69
  270. package/dist/src/tsol.js +0 -24
  271. package/dist/test/fixtures/sol.js +0 -1433
  272. package/dist/test/resources/sol.d.ts.map +0 -1
  273. package/dist/test/resources/sol.js +0 -320
  274. package/dist/test/unit/fixtures/solBackupKey.d.ts.map +0 -1
  275. package/dist/test/unit/fixtures/solBackupKey.js +0 -8
  276. package/dist/test/unit/getBuilderFactory.d.ts.map +0 -1
  277. package/dist/test/unit/getBuilderFactory.js +0 -10
  278. package/dist/test/unit/instructionParamsFactory.d.ts.map +0 -1
  279. package/dist/test/unit/instructionParamsFactory.js +0 -412
  280. package/dist/test/unit/instructionParamsFactory.staking.d.ts.map +0 -1
  281. package/dist/test/unit/instructionParamsFactory.staking.js +0 -1059
  282. package/dist/test/unit/keyPair.js +0 -177
  283. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +0 -1
  284. package/dist/test/unit/messages/messageBuilderFactory.js +0 -118
  285. package/dist/test/unit/messages/simpleMessageBuilder.d.ts.map +0 -1
  286. package/dist/test/unit/messages/simpleMessageBuilder.js +0 -194
  287. package/dist/test/unit/sol.js +0 -3108
  288. package/dist/test/unit/solInstructionFactory.d.ts.map +0 -1
  289. package/dist/test/unit/solInstructionFactory.js +0 -454
  290. package/dist/test/unit/solToken.d.ts.map +0 -1
  291. package/dist/test/unit/solToken.js +0 -31
  292. package/dist/test/unit/transaction.d.ts.map +0 -1
  293. package/dist/test/unit/transaction.js +0 -983
  294. package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +0 -1
  295. package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.js +0 -202
  296. package/dist/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +0 -1
  297. package/dist/test/unit/transactionBuilder/ataInitBuilder.js +0 -471
  298. package/dist/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +0 -1
  299. package/dist/test/unit/transactionBuilder/customInstructionBuilder.js +0 -413
  300. package/dist/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +0 -1
  301. package/dist/test/unit/transactionBuilder/stakingActivateBuilder.js +0 -430
  302. package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +0 -1
  303. package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +0 -157
  304. package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +0 -1
  305. package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.js +0 -384
  306. package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +0 -1
  307. package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.js +0 -224
  308. package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -1
  309. package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +0 -259
  310. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +0 -1
  311. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +0 -787
  312. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +0 -1
  313. package/dist/test/unit/transactionBuilder/transactionBuilder.js +0 -495
  314. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +0 -1
  315. package/dist/test/unit/transactionBuilder/transferBuilder.js +0 -286
  316. package/dist/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +0 -1
  317. package/dist/test/unit/transactionBuilder/transferBuilderV2.js +0 -862
  318. package/dist/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +0 -1
  319. package/dist/test/unit/transactionBuilder/walletInitBuilder.js +0 -259
  320. package/dist/test/unit/utils.js +0 -517
  321. package/dist/test/unit/versionedTransaction.d.ts.map +0 -1
  322. package/dist/test/unit/versionedTransaction.js +0 -207
  323. package/dist/tsconfig.tsbuildinfo +0 -1
  324. /package/dist/{src → cjs/src}/bigint-buffer-guard.d.ts +0 -0
  325. /package/dist/{src → cjs/src}/config/token2022StaticConfig.d.ts +0 -0
  326. /package/dist/{src → cjs/src}/index.d.ts +0 -0
  327. /package/dist/{src → cjs/src}/lib/ataInitializationBuilder.d.ts +0 -0
  328. /package/dist/{src → cjs/src}/lib/customInstructionBuilder.d.ts +0 -0
  329. /package/dist/{src → cjs/src}/lib/jitoStakePoolOperations.d.ts +0 -0
  330. /package/dist/{src → cjs/src}/lib/keyPair.d.ts +0 -0
  331. /package/dist/{src → cjs/src}/lib/messages/index.d.ts +0 -0
  332. /package/dist/{src → cjs/src}/lib/messages/messageBuilderFactory.d.ts +0 -0
  333. /package/dist/{src → cjs/src}/lib/solInstructionFactory.d.ts +0 -0
  334. /package/dist/{src → cjs/src}/lib/stakingActivateBuilder.d.ts +0 -0
  335. /package/dist/{src → cjs/src}/lib/stakingAuthorizeBuilder.d.ts +0 -0
  336. /package/dist/{src → cjs/src}/lib/stakingDeactivateBuilder.d.ts +0 -0
  337. /package/dist/{src → cjs/src}/lib/stakingDelegateBuilder.d.ts +0 -0
  338. /package/dist/{src → cjs/src}/lib/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
  339. /package/dist/{src → cjs/src}/lib/stakingWithdrawBuilder.d.ts +0 -0
  340. /package/dist/{src → cjs/src}/lib/token2022Config.d.ts +0 -0
  341. /package/dist/{src → cjs/src}/lib/tokenTransferBuilder.d.ts +0 -0
  342. /package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -0
  343. /package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -0
  344. /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
  345. /package/dist/{src → cjs/src}/lib/transferBuilderV2.d.ts +0 -0
  346. /package/dist/{src → cjs/src}/lib/utils.d.ts +0 -0
  347. /package/dist/{src → cjs/src}/lib/walletInitializationBuilder.d.ts +0 -0
  348. /package/dist/{src → cjs/src}/register.d.ts +0 -0
  349. /package/dist/{src → cjs/src}/tsol.d.ts +0 -0
  350. /package/dist/{test → cjs/test}/fixtures/sol.d.ts +0 -0
  351. /package/dist/{test → cjs/test}/unit/fixtures/solBackupKey.d.ts +0 -0
  352. /package/dist/{test → cjs/test}/unit/getBuilderFactory.d.ts +0 -0
  353. /package/dist/{test → cjs/test}/unit/instructionParamsFactory.d.ts +0 -0
  354. /package/dist/{test → cjs/test}/unit/instructionParamsFactory.staking.d.ts +0 -0
  355. /package/dist/{test → cjs/test}/unit/keyPair.d.ts +0 -0
  356. /package/dist/{test → cjs/test}/unit/messages/messageBuilderFactory.d.ts +0 -0
  357. /package/dist/{test → cjs/test}/unit/messages/simpleMessageBuilder.d.ts +0 -0
  358. /package/dist/{test → cjs/test}/unit/sol.d.ts +0 -0
  359. /package/dist/{test → cjs/test}/unit/solInstructionFactory.d.ts +0 -0
  360. /package/dist/{test → cjs/test}/unit/solToken.d.ts +0 -0
  361. /package/dist/{test → cjs/test}/unit/transaction.d.ts +0 -0
  362. /package/dist/{test → cjs/test}/unit/transactionBuilder/StakingWithdrawBuilder.d.ts +0 -0
  363. /package/dist/{test → cjs/test}/unit/transactionBuilder/ataInitBuilder.d.ts +0 -0
  364. /package/dist/{test → cjs/test}/unit/transactionBuilder/customInstructionBuilder.d.ts +0 -0
  365. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingActivateBuilder.d.ts +0 -0
  366. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts +0 -0
  367. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDeactivateBuilder.d.ts +0 -0
  368. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDelegateBuilder.d.ts +0 -0
  369. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
  370. /package/dist/{test → cjs/test}/unit/transactionBuilder/tokenTransferBuilder.d.ts +0 -0
  371. /package/dist/{test → cjs/test}/unit/transactionBuilder/transactionBuilder.d.ts +0 -0
  372. /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilder.d.ts +0 -0
  373. /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilderV2.d.ts +0 -0
  374. /package/dist/{test → cjs/test}/unit/transactionBuilder/walletInitBuilder.d.ts +0 -0
  375. /package/dist/{test → cjs/test}/unit/utils.d.ts +0 -0
  376. /package/dist/{test → cjs/test}/unit/versionedTransaction.d.ts +0 -0
  377. /package/dist/{src → esm}/bigint-buffer-guard.d.ts.map +0 -0
  378. /package/dist/{src → esm}/bigint-buffer-guard.js +0 -0
  379. /package/dist/{src → esm}/config/token2022StaticConfig.d.ts.map +0 -0
  380. /package/dist/{src → esm}/index.d.ts.map +0 -0
  381. /package/dist/{src → esm}/lib/ataInitializationBuilder.d.ts.map +0 -0
  382. /package/dist/{src → esm}/lib/customInstructionBuilder.d.ts.map +0 -0
  383. /package/dist/{src → esm}/lib/jitoStakePoolOperations.d.ts.map +0 -0
  384. /package/dist/{src → esm}/lib/keyPair.d.ts.map +0 -0
  385. /package/dist/{src → esm}/lib/messages/index.d.ts.map +0 -0
  386. /package/dist/{src → esm}/lib/messages/messageBuilderFactory.d.ts.map +0 -0
  387. /package/dist/{src → esm}/lib/stakingActivateBuilder.d.ts.map +0 -0
  388. /package/dist/{src → esm}/lib/stakingAuthorizeBuilder.d.ts.map +0 -0
  389. /package/dist/{src → esm}/lib/stakingDeactivateBuilder.d.ts.map +0 -0
  390. /package/dist/{src → esm}/lib/stakingDelegateBuilder.d.ts.map +0 -0
  391. /package/dist/{src → esm}/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -0
  392. /package/dist/{src → esm}/lib/stakingWithdrawBuilder.d.ts.map +0 -0
  393. /package/dist/{src → esm}/lib/token2022Config.d.ts.map +0 -0
  394. /package/dist/{src → esm}/lib/tokenTransferBuilder.d.ts.map +0 -0
  395. /package/dist/{src → esm}/lib/transactionBuilder.d.ts.map +0 -0
  396. /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
  397. /package/dist/{src → esm}/lib/transferBuilderV2.d.ts.map +0 -0
  398. /package/dist/{src → esm}/lib/walletInitializationBuilder.d.ts.map +0 -0
  399. /package/dist/{src → esm}/register.d.ts.map +0 -0
  400. /package/dist/{src → esm}/tsol.d.ts.map +0 -0
@@ -0,0 +1,3504 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert_1 = __importDefault(require("assert"));
40
+ const _ = __importStar(require("lodash"));
41
+ const nock_1 = __importDefault(require("nock"));
42
+ const should = __importStar(require("should"));
43
+ const sinon = __importStar(require("sinon"));
44
+ const spl_token_1 = require("@solana/spl-token");
45
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
46
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
47
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
48
+ const statics_1 = require("@bitgo-beta/statics");
49
+ const src_1 = require("../../src");
50
+ const lib_1 = require("../../src/lib");
51
+ const utils_1 = require("../../src/lib/utils");
52
+ const testData = __importStar(require("../fixtures/sol"));
53
+ const resources = __importStar(require("../resources/sol"));
54
+ const solBackupKey_1 = require("./fixtures/solBackupKey");
55
+ const getBuilderFactory_1 = require("./getBuilderFactory");
56
+ describe('SOL:', function () {
57
+ let bitgo;
58
+ let basecoin;
59
+ let keyPair;
60
+ let newTxPrebuild;
61
+ let newTxPrebuildTokenTransfer;
62
+ let newTxParams;
63
+ let newTxParamsWithError;
64
+ let newTxParamsWithExtraData;
65
+ let newTxParamsTokenTransfer;
66
+ const badAddresses = resources.addresses.invalidAddresses;
67
+ const goodAddresses = resources.addresses.validAddresses;
68
+ const keypair = {
69
+ pub: resources.accountWithSeed.publicKey,
70
+ prv: resources.accountWithSeed.privateKey.base58,
71
+ };
72
+ const txPrebuild = {
73
+ recipients: [
74
+ {
75
+ address: 'lionteste212',
76
+ amount: '1000',
77
+ },
78
+ ],
79
+ txBase64: resources.TRANSFER_UNSIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE,
80
+ txInfo: {
81
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
82
+ nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
83
+ },
84
+ txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
85
+ isVotingTransaction: false,
86
+ coin: 'tsol',
87
+ };
88
+ const txParams = {
89
+ txPrebuild,
90
+ recipients: [
91
+ {
92
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
93
+ amount: '300000',
94
+ },
95
+ ],
96
+ };
97
+ const memo = { value: 'test memo' };
98
+ const durableNonce = {
99
+ walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
100
+ authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
101
+ };
102
+ const errorDurableNonce = {
103
+ walletNonceAddress: '8YM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
104
+ authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
105
+ };
106
+ const txParamsWithError = {
107
+ txPrebuild,
108
+ recipients: [
109
+ {
110
+ address: 'CP5Dpaa42mMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
111
+ amount: '300000',
112
+ },
113
+ ],
114
+ };
115
+ const txParamsWithExtraData = {
116
+ txPrebuild,
117
+ recipients: [
118
+ {
119
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
120
+ amount: '300000',
121
+ data: undefined,
122
+ },
123
+ ],
124
+ };
125
+ const txPrebuildTokenTransfer = {
126
+ recipients: [
127
+ {
128
+ address: 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg',
129
+ amount: '1',
130
+ },
131
+ ],
132
+ txHex: resources.TOKEN_TRANSFER_TO_NATIVE_UNSIGNED_TX_HEX,
133
+ txInfo: {
134
+ feePayer: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
135
+ nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
136
+ },
137
+ txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
138
+ isVotingTransaction: false,
139
+ coin: 'tsol',
140
+ };
141
+ const txParamsTokenTransfer = {
142
+ txPrebuild,
143
+ recipients: [
144
+ {
145
+ address: 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg',
146
+ amount: '1',
147
+ },
148
+ ],
149
+ };
150
+ const errorMemo = { value: 'different memo' };
151
+ const errorFeePayer = '5hr5fisPi6DXCuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe';
152
+ const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
153
+ const wallet = new src_1.KeyPair(resources.authAccount).getKeys();
154
+ const stakeAccount = new src_1.KeyPair(resources.stakeAccount).getKeys();
155
+ const blockHash = resources.blockHashes.validBlockHashes[0];
156
+ const amount = '10000';
157
+ const validator = resources.validator;
158
+ before(function () {
159
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
160
+ bitgo.safeRegister('sol', src_1.Tsol.createInstance);
161
+ bitgo.safeRegister('tsol', src_1.Tsol.createInstance);
162
+ bitgo.initializeTestVars();
163
+ basecoin = bitgo.coin('tsol');
164
+ keyPair = basecoin.generateKeyPair(resources.accountWithSeed.seed);
165
+ newTxPrebuild = () => {
166
+ return _.cloneDeep(txPrebuild);
167
+ };
168
+ newTxPrebuildTokenTransfer = () => {
169
+ return _.cloneDeep(txPrebuildTokenTransfer);
170
+ };
171
+ newTxParams = () => {
172
+ return _.cloneDeep(txParams);
173
+ };
174
+ newTxParamsWithError = () => {
175
+ return _.cloneDeep(txParamsWithError);
176
+ };
177
+ newTxParamsWithExtraData = () => {
178
+ return _.cloneDeep(txParamsWithExtraData);
179
+ };
180
+ newTxParamsTokenTransfer = () => {
181
+ return _.cloneDeep(txParamsTokenTransfer);
182
+ };
183
+ });
184
+ it('should instantiate the coin', async function () {
185
+ let localBasecoin = bitgo.coin('tsol');
186
+ localBasecoin.should.be.an.instanceof(src_1.Tsol);
187
+ localBasecoin = bitgo.coin('sol');
188
+ localBasecoin.should.be.an.instanceof(src_1.Sol);
189
+ });
190
+ it('should retun the right info', function () {
191
+ basecoin.getChain().should.equal('tsol');
192
+ basecoin.getFamily().should.equal('sol');
193
+ basecoin.getFullName().should.equal('Testnet Solana');
194
+ basecoin.getBaseFactor().should.equal(1000000000);
195
+ });
196
+ describe('verify transactions', () => {
197
+ const walletData = {
198
+ id: '5b34252f1bf349930e34020a00000000',
199
+ coin: 'tsol',
200
+ keys: [
201
+ '5b3424f91bf349930e34017500000000',
202
+ '5b3424f91bf349930e34017600000000',
203
+ '5b3424f91bf349930e34017700000000',
204
+ ],
205
+ coinSpecific: {
206
+ rootAddress: wallet.pub,
207
+ },
208
+ multisigType: 'tss',
209
+ };
210
+ const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
211
+ it('should verify transactions', async function () {
212
+ const txParams = newTxParams();
213
+ const txPrebuild = newTxPrebuild();
214
+ const validTransaction = await basecoin.verifyTransaction({
215
+ txParams,
216
+ txPrebuild,
217
+ memo,
218
+ durableNonce,
219
+ wallet: walletObj,
220
+ });
221
+ validTransaction.should.equal(true);
222
+ });
223
+ it('should verify consolidate transaction', async function () {
224
+ const txParams = newTxParams();
225
+ const txPrebuild = newTxPrebuild();
226
+ txPrebuild.consolidateId = 'consolidateId';
227
+ const walletData = {
228
+ id: '5b34252f1bf349930e34020a00000000',
229
+ coin: 'tsol',
230
+ keys: [
231
+ '5b3424f91bf349930e34017500000000',
232
+ '5b3424f91bf349930e34017600000000',
233
+ '5b3424f91bf349930e34017700000000',
234
+ ],
235
+ coinSpecific: {
236
+ rootAddress: stakeAccount.pub,
237
+ },
238
+ multisigType: 'tss',
239
+ };
240
+ const walletWithDifferentAddress = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
241
+ const validTransaction = await basecoin.verifyTransaction({
242
+ txParams,
243
+ txPrebuild,
244
+ memo,
245
+ durableNonce,
246
+ wallet: walletWithDifferentAddress,
247
+ });
248
+ validTransaction.should.be.true();
249
+ });
250
+ it('should handle txBase64 and txHex interchangeably', async function () {
251
+ const txParams = newTxParams();
252
+ const txPrebuild = newTxPrebuild();
253
+ txPrebuild.txHex = txPrebuild.txBase64;
254
+ txPrebuild.txBase64 = undefined;
255
+ const validTransaction = await basecoin.verifyTransaction({
256
+ txParams,
257
+ txPrebuild,
258
+ memo,
259
+ durableNonce,
260
+ wallet: walletObj,
261
+ });
262
+ validTransaction.should.equal(true);
263
+ });
264
+ it('should convert serialized hex string to base64', async function () {
265
+ const txParams = newTxParams();
266
+ const txPrebuild = newTxPrebuild();
267
+ txPrebuild.txBase64 = Buffer.from(txPrebuild.txBase64, 'base64').toString('hex');
268
+ const validTransaction = await basecoin.verifyTransaction({
269
+ txParams,
270
+ txPrebuild,
271
+ memo,
272
+ durableNonce,
273
+ wallet: walletObj,
274
+ });
275
+ validTransaction.should.equal(true);
276
+ });
277
+ it('should verify when input `recipients` is absent', async function () {
278
+ const txParams = newTxParams();
279
+ txParams.recipients = undefined;
280
+ const txPrebuild = newTxPrebuild();
281
+ const validTransaction = await basecoin.verifyTransaction({
282
+ txParams,
283
+ txPrebuild,
284
+ memo,
285
+ durableNonce,
286
+ wallet: walletObj,
287
+ });
288
+ validTransaction.should.equal(true);
289
+ });
290
+ it('should verify bulk close-ATA tx when txParams.recipients is present (outputs not populated)', async function () {
291
+ const accountKeys = new src_1.KeyPair(resources.authAccount).getKeys();
292
+ const nonceAccountKeys = new src_1.KeyPair(resources.nonceAccount).getKeys();
293
+ const account2Keys = new src_1.KeyPair(resources.authAccount2).getKeys();
294
+ const ataAddress1 = nonceAccountKeys.pub;
295
+ const ataAddress2 = account2Keys.pub;
296
+ const txBuilder = factory.getCloseAtaInitializationBuilder();
297
+ txBuilder.nonce(blockHash);
298
+ txBuilder.sender(accountKeys.pub);
299
+ txBuilder.addCloseAtaInstruction(ataAddress1, accountKeys.pub, accountKeys.pub);
300
+ txBuilder.addCloseAtaInstruction(ataAddress2, accountKeys.pub, accountKeys.pub);
301
+ const built = await txBuilder.build();
302
+ const txPrebuild = {
303
+ txBase64: built.toBroadcastFormat(),
304
+ txInfo: {
305
+ feePayer: accountKeys.pub,
306
+ nonce: blockHash,
307
+ },
308
+ coin: 'tsol',
309
+ };
310
+ const validTransaction = await basecoin.verifyTransaction({
311
+ txParams: {
312
+ recipients: [
313
+ { address: ataAddress1, amount: '0' },
314
+ { address: ataAddress2, amount: '0' },
315
+ ],
316
+ },
317
+ txPrebuild,
318
+ wallet: walletObj,
319
+ });
320
+ validTransaction.should.equal(true);
321
+ });
322
+ it('should fail verify bulk close-ATA when txParams.recipients do not match close instructions', async function () {
323
+ const accountKeys = new src_1.KeyPair(resources.authAccount).getKeys();
324
+ const nonceAccountKeys = new src_1.KeyPair(resources.nonceAccount).getKeys();
325
+ const account2Keys = new src_1.KeyPair(resources.authAccount2).getKeys();
326
+ const wrongAta = new src_1.KeyPair(resources.stakeAccount).getKeys().pub;
327
+ const ataAddress1 = nonceAccountKeys.pub;
328
+ const ataAddress2 = account2Keys.pub;
329
+ const txBuilder = factory.getCloseAtaInitializationBuilder();
330
+ txBuilder.nonce(blockHash);
331
+ txBuilder.sender(accountKeys.pub);
332
+ txBuilder.addCloseAtaInstruction(ataAddress1, accountKeys.pub, accountKeys.pub);
333
+ txBuilder.addCloseAtaInstruction(ataAddress2, accountKeys.pub, accountKeys.pub);
334
+ const built = await txBuilder.build();
335
+ const txPrebuild = {
336
+ txBase64: built.toBroadcastFormat(),
337
+ txInfo: {
338
+ feePayer: accountKeys.pub,
339
+ nonce: blockHash,
340
+ },
341
+ coin: 'tsol',
342
+ };
343
+ await basecoin
344
+ .verifyTransaction({
345
+ txParams: {
346
+ recipients: [
347
+ { address: ataAddress1, amount: '0' },
348
+ { address: wrongAta, amount: '0' },
349
+ ],
350
+ },
351
+ txPrebuild,
352
+ wallet: walletObj,
353
+ })
354
+ .should.rejectedWith('Close ATA txParams.recipients addresses must match the ATA account addresses in the transaction instructions');
355
+ });
356
+ it('should fail verify bulk close-ATA when a recipient amount is non-zero', async function () {
357
+ const accountKeys = new src_1.KeyPair(resources.authAccount).getKeys();
358
+ const nonceAccountKeys = new src_1.KeyPair(resources.nonceAccount).getKeys();
359
+ const account2Keys = new src_1.KeyPair(resources.authAccount2).getKeys();
360
+ const ataAddress1 = nonceAccountKeys.pub;
361
+ const ataAddress2 = account2Keys.pub;
362
+ const txBuilder = factory.getCloseAtaInitializationBuilder();
363
+ txBuilder.nonce(blockHash);
364
+ txBuilder.sender(accountKeys.pub);
365
+ txBuilder.addCloseAtaInstruction(ataAddress1, accountKeys.pub, accountKeys.pub);
366
+ txBuilder.addCloseAtaInstruction(ataAddress2, accountKeys.pub, accountKeys.pub);
367
+ const built = await txBuilder.build();
368
+ const txPrebuild = {
369
+ txBase64: built.toBroadcastFormat(),
370
+ txInfo: {
371
+ feePayer: accountKeys.pub,
372
+ nonce: blockHash,
373
+ },
374
+ coin: 'tsol',
375
+ };
376
+ await basecoin
377
+ .verifyTransaction({
378
+ txParams: {
379
+ recipients: [
380
+ { address: ataAddress1, amount: '1' },
381
+ { address: ataAddress2, amount: '0' },
382
+ ],
383
+ },
384
+ txPrebuild,
385
+ wallet: walletObj,
386
+ })
387
+ .should.rejectedWith('Close ATA recipients must have zero amount');
388
+ });
389
+ it('should verify recover-nested tx when walletAddress matches root', async function () {
390
+ const accountKeys = new src_1.KeyPair(resources.authAccount).getKeys();
391
+ const nonceAccountKeys = new src_1.KeyPair(resources.nonceAccount).getKeys();
392
+ const account2Keys = new src_1.KeyPair(resources.authAccount2).getKeys();
393
+ const mint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
394
+ const txBuilder = factory.getRecoverNestedAtaBuilder();
395
+ txBuilder.nonce(blockHash);
396
+ txBuilder.sender(accountKeys.pub);
397
+ txBuilder.feePayer(accountKeys.pub);
398
+ txBuilder.associatedTokenAccountRent('2039280');
399
+ txBuilder.nestedAccountAddress(nonceAccountKeys.pub);
400
+ txBuilder.nestedMintAddress(mint);
401
+ txBuilder.destinationAccountAddress(account2Keys.pub);
402
+ txBuilder.ownerAccountAddress(account2Keys.pub);
403
+ txBuilder.ownerMintAddress(mint);
404
+ txBuilder.walletAddress(accountKeys.pub);
405
+ const built = await txBuilder.build();
406
+ const txPrebuild = {
407
+ txBase64: built.toBroadcastFormat(),
408
+ txInfo: {
409
+ feePayer: accountKeys.pub,
410
+ nonce: blockHash,
411
+ },
412
+ coin: 'tsol',
413
+ };
414
+ const validTransaction = await basecoin.verifyTransaction({
415
+ txParams: {},
416
+ txPrebuild,
417
+ wallet: walletObj,
418
+ });
419
+ validTransaction.should.equal(true);
420
+ });
421
+ it('should fail verify recover-nested tx when wallet root does not match instruction walletAddress', async function () {
422
+ const accountKeys = new src_1.KeyPair(resources.authAccount).getKeys();
423
+ const nonceAccountKeys = new src_1.KeyPair(resources.nonceAccount).getKeys();
424
+ const account2Keys = new src_1.KeyPair(resources.authAccount2).getKeys();
425
+ const mint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
426
+ const txBuilder = factory.getRecoverNestedAtaBuilder();
427
+ txBuilder.nonce(blockHash);
428
+ txBuilder.sender(accountKeys.pub);
429
+ txBuilder.feePayer(accountKeys.pub);
430
+ txBuilder.associatedTokenAccountRent('2039280');
431
+ txBuilder.nestedAccountAddress(nonceAccountKeys.pub);
432
+ txBuilder.nestedMintAddress(mint);
433
+ txBuilder.destinationAccountAddress(account2Keys.pub);
434
+ txBuilder.ownerAccountAddress(account2Keys.pub);
435
+ txBuilder.ownerMintAddress(mint);
436
+ txBuilder.walletAddress(accountKeys.pub);
437
+ const built = await txBuilder.build();
438
+ const txPrebuild = {
439
+ txBase64: built.toBroadcastFormat(),
440
+ txInfo: {
441
+ feePayer: accountKeys.pub,
442
+ nonce: blockHash,
443
+ },
444
+ coin: 'tsol',
445
+ };
446
+ const walletDataWrongRoot = {
447
+ id: '5b34252f1bf349930e34020a00000000',
448
+ coin: 'tsol',
449
+ keys: [
450
+ '5b3424f91bf349930e34017500000000',
451
+ '5b3424f91bf349930e34017600000000',
452
+ '5b3424f91bf349930e34017700000000',
453
+ ],
454
+ coinSpecific: {
455
+ rootAddress: stakeAccount.pub,
456
+ },
457
+ multisigType: 'tss',
458
+ };
459
+ const wrongRootWallet = new sdk_core_1.Wallet(bitgo, basecoin, walletDataWrongRoot);
460
+ await basecoin
461
+ .verifyTransaction({
462
+ txParams: {},
463
+ txPrebuild,
464
+ wallet: wrongRootWallet,
465
+ })
466
+ .should.rejectedWith(/Recover nested wallet address must be wallet root address/);
467
+ });
468
+ it('should fail verify transactions when have different memo', async function () {
469
+ const txParams = newTxParams();
470
+ const txPrebuild = newTxPrebuild();
471
+ await basecoin
472
+ .verifyTransaction({ txParams, txPrebuild, memo: errorMemo, wallet: walletObj })
473
+ .should.be.rejectedWith('Tx memo does not match with expected txParams recipient memo');
474
+ });
475
+ it('should pass if we pass PDA address', async function () {
476
+ const walletData = {
477
+ id: '67f8ddff4c9b8b57a2e16acffac9a3b5',
478
+ coin: 'tsol',
479
+ keys: [
480
+ '5b3424f91bf349930e34017500000000',
481
+ '5b3424f91bf349930e34017600000000',
482
+ '5b3424f91bf349930e34017700000000',
483
+ ],
484
+ coinSpecific: {
485
+ rootAddress: '8zbsJA5c8HPR7BPjZkrSVrus2uMuXqCfzksGwB3Uscjb',
486
+ },
487
+ multisigType: 'tss',
488
+ };
489
+ const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
490
+ const txPrebuild = {
491
+ recipients: [
492
+ {
493
+ address: '11111111111111111111111111111112',
494
+ amount: '1000000000',
495
+ tokenName: 'tsol:usdc',
496
+ },
497
+ ],
498
+ txBase64: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ec1adcc89bb564f1f8225821140a9723efa80e8d506765770b7e201d66d8200d4f690e9a8163291b69f8c3827aad96cfd2105eee3aae76cbca38fcad2bf7f0a0201070c76c356cb069b66c2b35a8638b4d4afca75b303f29f0deeb4bff8528299a9c9d21c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f60129e6ecb20309c27dcba5fc6c441438d33a1568004a1860e22c16f071976a7d2e2008bd34b53a08aa9c8ec04eb2196745fc6029224447417e2fb0fced601240cabba4ce534c02fc154ba559ed2a02ac971e3385acb426ff63bb1040e2c2435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f859d10389fbcee528f208611dccc734b31092540cb2b8d58d100f2eaa2cedb4da5e06a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a0000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9e680634533882f880a3e7dfa999dfb864b88968d242a0c9a90b5df149e42da050305030209010404000000070700030608050b0a000b04040803000a0c00ca9a3b0000000009',
499
+ txInfo: {
500
+ feePayer: '8zbsJA5c8HPR7BPjZkrSVrus2uMuXqCfzksGwB3Uscjb',
501
+ nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
502
+ },
503
+ txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
504
+ isVotingTransaction: false,
505
+ coin: 'tsol',
506
+ };
507
+ const txParams = {
508
+ txPrebuild,
509
+ recipients: [
510
+ {
511
+ address: '11111111111111111111111111111112',
512
+ amount: '1000000000',
513
+ tokenName: 'tsol:usdc',
514
+ },
515
+ ],
516
+ };
517
+ const memo = {
518
+ value: undefined,
519
+ };
520
+ const verifyTransaction = await basecoin.verifyTransaction({
521
+ txParams,
522
+ txPrebuild,
523
+ memo: memo,
524
+ wallet: walletObj,
525
+ });
526
+ verifyTransaction.should.equal(true);
527
+ });
528
+ it('should fail verify transactions when have different durableNonce', async function () {
529
+ const txParams = newTxParams();
530
+ const txPrebuild = newTxPrebuild();
531
+ await basecoin
532
+ .verifyTransaction({ txParams, txPrebuild, memo, durableNonce: errorDurableNonce, wallet: walletObj })
533
+ .should.be.rejectedWith('Tx durableNonce does not match with param durableNonce');
534
+ });
535
+ it('should fail verify transactions when have different feePayer', async function () {
536
+ const txParams = newTxParams();
537
+ const txPrebuild = newTxPrebuild();
538
+ const walletData = {
539
+ id: '5b34252f1bf349930e34020a00000000',
540
+ coin: 'tsol',
541
+ keys: [
542
+ '5b3424f91bf349930e34017500000000',
543
+ '5b3424f91bf349930e34017600000000',
544
+ '5b3424f91bf349930e34017700000000',
545
+ ],
546
+ coinSpecific: {
547
+ rootAddress: stakeAccount.pub,
548
+ },
549
+ multisigType: 'tss',
550
+ };
551
+ const walletWithDifferentAddress = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
552
+ await basecoin
553
+ .verifyTransaction({ txParams, txPrebuild, memo, wallet: walletWithDifferentAddress })
554
+ .should.be.rejectedWith('Tx fee payer is not the wallet root address');
555
+ });
556
+ it('should fail verify transactions when have different recipients', async function () {
557
+ const txParams = newTxParamsWithError();
558
+ const txPrebuild = newTxPrebuild();
559
+ await basecoin
560
+ .verifyTransaction({ txParams, txPrebuild, memo, errorFeePayer, wallet: walletObj })
561
+ .should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
562
+ });
563
+ it('should succeed to verify token transaction with native address recipient', async function () {
564
+ const txParams = newTxParamsTokenTransfer();
565
+ const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
566
+ txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdc' }];
567
+ const txPrebuild = newTxPrebuildTokenTransfer();
568
+ const feePayerWalletData = {
569
+ id: '5b34252f1bf349930e34020a00000000',
570
+ coin: 'tsol',
571
+ keys: [
572
+ '5b3424f91bf349930e34017500000000',
573
+ '5b3424f91bf349930e34017600000000',
574
+ '5b3424f91bf349930e34017700000000',
575
+ ],
576
+ coinSpecific: {
577
+ rootAddress: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
578
+ },
579
+ multisigType: 'tss',
580
+ };
581
+ const feePayerWallet = new sdk_core_1.Wallet(bitgo, basecoin, feePayerWalletData);
582
+ const validTransaction = await basecoin.verifyTransaction({
583
+ txParams,
584
+ txPrebuild,
585
+ wallet: feePayerWallet,
586
+ });
587
+ validTransaction.should.equal(true);
588
+ });
589
+ it('should succeed to verify token transaction with leading zero recipient amount', async function () {
590
+ const txParams = newTxParamsTokenTransfer();
591
+ const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
592
+ txParams.recipients = [{ address, amount: '0001', tokenName: 'tsol:usdc' }];
593
+ const txPrebuild = newTxPrebuildTokenTransfer();
594
+ const feePayerWalletData = {
595
+ id: '5b34252f1bf349930e34020a00000000',
596
+ coin: 'tsol',
597
+ keys: [
598
+ '5b3424f91bf349930e34017500000000',
599
+ '5b3424f91bf349930e34017600000000',
600
+ '5b3424f91bf349930e34017700000000',
601
+ ],
602
+ coinSpecific: {
603
+ rootAddress: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
604
+ },
605
+ multisigType: 'tss',
606
+ };
607
+ const feePayerWallet = new sdk_core_1.Wallet(bitgo, basecoin, feePayerWalletData);
608
+ const validTransaction = await basecoin.verifyTransaction({
609
+ txParams,
610
+ txPrebuild,
611
+ wallet: feePayerWallet,
612
+ });
613
+ validTransaction.should.equal(true);
614
+ });
615
+ it('should fail to verify token transaction with different recipient tokenName', async function () {
616
+ const txParams = newTxParamsTokenTransfer();
617
+ const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
618
+ txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdt' }]; // Different tokenName, should fail to verify tx
619
+ const txPrebuild = newTxPrebuildTokenTransfer();
620
+ await basecoin
621
+ .verifyTransaction({
622
+ txParams,
623
+ txPrebuild,
624
+ wallet: walletObj,
625
+ })
626
+ .should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
627
+ });
628
+ it('should fail to verify token transaction with different recipient amounts', async function () {
629
+ const txParams = newTxParamsTokenTransfer();
630
+ const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
631
+ txParams.recipients = [{ address, amount: '2', tokenName: 'tsol:usdt' }];
632
+ const txPrebuild = newTxPrebuildTokenTransfer();
633
+ await basecoin
634
+ .verifyTransaction({
635
+ txParams,
636
+ txPrebuild,
637
+ wallet: walletObj,
638
+ })
639
+ .should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
640
+ });
641
+ it('should fail to verify token transaction with different native address', async function () {
642
+ const txParams = newTxParamsTokenTransfer();
643
+ const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvX'; // Native SOL address, different than tx recipients
644
+ txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdc' }];
645
+ const txPrebuild = newTxPrebuildTokenTransfer();
646
+ await basecoin
647
+ .verifyTransaction({
648
+ txParams,
649
+ txPrebuild,
650
+ wallet: walletObj,
651
+ })
652
+ .should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
653
+ });
654
+ it('should succeed to verify transactions when recipients has extra data', async function () {
655
+ const txParams = newTxParamsWithExtraData();
656
+ const txPrebuild = newTxPrebuild();
657
+ const validTransaction = await basecoin.verifyTransaction({
658
+ txParams,
659
+ txPrebuild,
660
+ memo,
661
+ durableNonce,
662
+ wallet: walletObj,
663
+ });
664
+ validTransaction.should.equal(true);
665
+ });
666
+ it('should verify activate staking transaction', async function () {
667
+ const tx = await factory
668
+ .getStakingActivateBuilder()
669
+ .stakingAddress(stakeAccount.pub)
670
+ .sender(wallet.pub)
671
+ .nonce(blockHash)
672
+ .amount(amount)
673
+ .validator(validator.pub)
674
+ .memo('test memo')
675
+ .fee({ amount: 5000 })
676
+ .build();
677
+ const txToBroadcastFormat = tx.toBroadcastFormat();
678
+ const txParams = newTxParams();
679
+ const txPrebuild = newTxPrebuild();
680
+ txPrebuild.txBase64 = txToBroadcastFormat;
681
+ txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
682
+ txParams.recipients = [
683
+ {
684
+ address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
685
+ amount: amount,
686
+ },
687
+ ];
688
+ const validTransaction = await basecoin.verifyTransaction({
689
+ txParams,
690
+ txPrebuild,
691
+ memo,
692
+ wallet: walletObj,
693
+ });
694
+ validTransaction.should.equal(true);
695
+ });
696
+ it('should verify withdraw staking transaction', async function () {
697
+ const tx = await factory
698
+ .getStakingWithdrawBuilder()
699
+ .stakingAddress(stakeAccount.pub)
700
+ .sender(wallet.pub)
701
+ .nonce(blockHash)
702
+ .amount(amount)
703
+ .memo('test memo')
704
+ .fee({ amount: 5000 })
705
+ .build();
706
+ const txToBroadcastFormat = tx.toBroadcastFormat();
707
+ const txParams = newTxParams();
708
+ const txPrebuild = newTxPrebuild();
709
+ txPrebuild.txBase64 = txToBroadcastFormat;
710
+ txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
711
+ txParams.recipients = [
712
+ {
713
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
714
+ amount: amount,
715
+ },
716
+ ];
717
+ const validTransaction = await basecoin.verifyTransaction({
718
+ txParams,
719
+ txPrebuild,
720
+ memo,
721
+ wallet: walletObj,
722
+ });
723
+ validTransaction.should.equal(true);
724
+ });
725
+ it('should verify deactivate staking transaction', async function () {
726
+ const tx = await factory
727
+ .getStakingDeactivateBuilder()
728
+ .stakingAddress(stakeAccount.pub)
729
+ .sender(wallet.pub)
730
+ .nonce(blockHash)
731
+ .memo('test memo')
732
+ .fee({ amount: 5000 })
733
+ .build();
734
+ const txToBroadcastFormat = tx.toBroadcastFormat();
735
+ const txParams = newTxParams();
736
+ const txPrebuild = newTxPrebuild();
737
+ txPrebuild.txBase64 = txToBroadcastFormat;
738
+ txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
739
+ txParams.recipients = [];
740
+ const validTransaction = await basecoin.verifyTransaction({
741
+ txParams,
742
+ txPrebuild,
743
+ memo,
744
+ wallet: walletObj,
745
+ });
746
+ validTransaction.should.equal(true);
747
+ });
748
+ it('should verify create associated token account transaction', async function () {
749
+ const tx = await factory
750
+ .getAtaInitializationBuilder()
751
+ .mint('tsol:usdc')
752
+ .sender(wallet.pub)
753
+ .nonce(blockHash)
754
+ .memo('test memo')
755
+ .fee({ amount: 5000 })
756
+ .build();
757
+ const txToBroadcastFormat = tx.toBroadcastFormat();
758
+ const txParams = newTxParams();
759
+ const txPrebuild = newTxPrebuild();
760
+ txPrebuild.txBase64 = txToBroadcastFormat;
761
+ txPrebuild.txInfo.nonce = blockHash;
762
+ txParams.recipients = [];
763
+ const validTransaction = await basecoin.verifyTransaction({
764
+ txParams,
765
+ txPrebuild,
766
+ memo,
767
+ wallet: walletObj,
768
+ });
769
+ validTransaction.should.equal(true);
770
+ });
771
+ });
772
+ describe('getAmountBasedOnEndianness', () => {
773
+ let originalArch;
774
+ beforeEach(() => {
775
+ originalArch = process.arch;
776
+ });
777
+ afterEach(() => {
778
+ Object.defineProperty(process, 'arch', {
779
+ value: originalArch,
780
+ writable: true,
781
+ configurable: true,
782
+ });
783
+ });
784
+ it('should return amount unchanged on non-s390x architectures', function () {
785
+ Object.defineProperty(process, 'arch', {
786
+ value: 'x64',
787
+ writable: true,
788
+ configurable: true,
789
+ });
790
+ (0, src_1.getAmountBasedOnEndianness)('300000').should.equal('300000');
791
+ (0, src_1.getAmountBasedOnEndianness)('10000').should.equal('10000');
792
+ (0, src_1.getAmountBasedOnEndianness)('504403158265495552').should.equal('504403158265495552');
793
+ });
794
+ it('should byte-swap small amounts on s390x (small becomes huge)', function () {
795
+ Object.defineProperty(process, 'arch', {
796
+ value: 's390x',
797
+ writable: true,
798
+ configurable: true,
799
+ });
800
+ // Small amount 10,000 (0x2710) swaps to 1,163,899,028,698,562,560
801
+ (0, src_1.getAmountBasedOnEndianness)('10000').should.equal('1163899028698562560');
802
+ });
803
+ it('should byte-swap large amounts on s390x (large becomes tiny)', function () {
804
+ Object.defineProperty(process, 'arch', {
805
+ value: 's390x',
806
+ writable: true,
807
+ configurable: true,
808
+ });
809
+ // Large amount 504,403,158,265,495,552 (0x0700000000000000) swaps to 7
810
+ (0, src_1.getAmountBasedOnEndianness)('504403158265495552').should.equal('7');
811
+ });
812
+ it('should handle numeric input', function () {
813
+ Object.defineProperty(process, 'arch', {
814
+ value: 's390x',
815
+ writable: true,
816
+ configurable: true,
817
+ });
818
+ // Should work with numbers, not just strings
819
+ (0, src_1.getAmountBasedOnEndianness)(10000).should.equal('1163899028698562560');
820
+ });
821
+ it('should handle standard transaction amounts on s390x', function () {
822
+ Object.defineProperty(process, 'arch', {
823
+ value: 's390x',
824
+ writable: true,
825
+ configurable: true,
826
+ });
827
+ // Standard amount 300,000 (0x493E0) swaps to large value
828
+ const result = (0, src_1.getAmountBasedOnEndianness)('300000');
829
+ // Verify it's different (swapped)
830
+ result.should.not.equal('300000');
831
+ // Verify swapping back gives original
832
+ (0, src_1.getAmountBasedOnEndianness)(result).should.equal('300000');
833
+ });
834
+ it('should handle invalid input gracefully', function () {
835
+ Object.defineProperty(process, 'arch', {
836
+ value: 's390x',
837
+ writable: true,
838
+ configurable: true,
839
+ });
840
+ // Invalid BigInt input should return original string
841
+ (0, src_1.getAmountBasedOnEndianness)('not-a-number').should.equal('not-a-number');
842
+ });
843
+ });
844
+ it('should accept valid address', function () {
845
+ goodAddresses.forEach((addr) => {
846
+ basecoin.isValidAddress(addr).should.equal(true);
847
+ });
848
+ });
849
+ it('should reject invalid address', function () {
850
+ badAddresses.forEach((addr) => {
851
+ basecoin.isValidAddress(addr).should.equal(false);
852
+ });
853
+ });
854
+ it('should check valid pub keys', function () {
855
+ keyPair.should.have.property('pub');
856
+ basecoin.isValidPub(keyPair.pub).should.equal(true);
857
+ });
858
+ it('should check an invalid pub keys', function () {
859
+ const badPubKey = keyPair.pub.slice(0, keyPair.pub.length - 1) + '-';
860
+ basecoin.isValidPub(badPubKey).should.equal(false);
861
+ });
862
+ it('should check valid prv keys', function () {
863
+ keyPair.should.have.property('prv');
864
+ basecoin.isValidPrv(keyPair.prv).should.equal(true);
865
+ });
866
+ it('should check an invalid prv keys', function () {
867
+ const badPrvKey = keyPair.prv ? keyPair.prv.slice(0, keyPair.prv.length - 1) + '-' : undefined;
868
+ basecoin.isValidPrv(badPrvKey).should.equal(false);
869
+ });
870
+ describe('Parse Transactions:', () => {
871
+ it('should parse an unsigned transfer transaction', async function () {
872
+ const parsedTransaction = await basecoin.parseTransaction({
873
+ txBase64: testData.rawTransactions.transfer.unsigned,
874
+ feeInfo: {
875
+ fee: '5000',
876
+ },
877
+ });
878
+ parsedTransaction.should.deepEqual({
879
+ inputs: [
880
+ {
881
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
882
+ amount: 305000,
883
+ },
884
+ ],
885
+ outputs: [
886
+ {
887
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
888
+ amount: '300000',
889
+ },
890
+ ],
891
+ });
892
+ });
893
+ it('should parse a signed transfer transaction', async function () {
894
+ const parsedTransaction = await basecoin.parseTransaction({
895
+ txBase64: testData.rawTransactions.transfer.signed,
896
+ feeInfo: {
897
+ fee: '5000',
898
+ },
899
+ });
900
+ parsedTransaction.should.deepEqual({
901
+ inputs: [
902
+ {
903
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
904
+ amount: 305000,
905
+ },
906
+ ],
907
+ outputs: [
908
+ {
909
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
910
+ amount: '300000',
911
+ },
912
+ ],
913
+ });
914
+ });
915
+ it('should parse an unsigned wallet init transaction', async function () {
916
+ const parsedTransaction = await basecoin.parseTransaction({
917
+ txBase64: testData.rawTransactions.walletInit.unsigned,
918
+ feeInfo: {
919
+ fee: '5000',
920
+ },
921
+ });
922
+ parsedTransaction.should.deepEqual({
923
+ inputs: [
924
+ {
925
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
926
+ amount: 310000,
927
+ },
928
+ ],
929
+ outputs: [
930
+ {
931
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
932
+ amount: '300000',
933
+ },
934
+ ],
935
+ });
936
+ });
937
+ it('should parse a signed wallet init transaction', async function () {
938
+ const parsedTransaction = await basecoin.parseTransaction({
939
+ txBase64: testData.rawTransactions.walletInit.signed,
940
+ feeInfo: {
941
+ fee: '5000',
942
+ },
943
+ });
944
+ parsedTransaction.should.deepEqual({
945
+ inputs: [
946
+ {
947
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
948
+ amount: 310000,
949
+ },
950
+ ],
951
+ outputs: [
952
+ {
953
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
954
+ amount: '300000',
955
+ },
956
+ ],
957
+ });
958
+ });
959
+ it('should parse an unsigned transfer token transaction', async function () {
960
+ const parsedTransaction = await basecoin.parseTransaction({
961
+ txBase64: testData.rawTransactions.transferToken.unsigned,
962
+ feeInfo: {
963
+ fee: '5000',
964
+ },
965
+ });
966
+ parsedTransaction.should.deepEqual({
967
+ inputs: [
968
+ {
969
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
970
+ amount: 5000,
971
+ },
972
+ ],
973
+ outputs: [
974
+ {
975
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
976
+ amount: '300000',
977
+ tokenName: 'tsol:usdc',
978
+ },
979
+ ],
980
+ });
981
+ });
982
+ it('should parse a signed transfer token transaction', async function () {
983
+ const parsedTransaction = await basecoin.parseTransaction({
984
+ txBase64: testData.rawTransactions.transferToken.signed,
985
+ feeInfo: {
986
+ fee: '5000',
987
+ },
988
+ });
989
+ parsedTransaction.should.deepEqual({
990
+ inputs: [
991
+ {
992
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
993
+ amount: 5000,
994
+ },
995
+ ],
996
+ outputs: [
997
+ {
998
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
999
+ amount: '300000',
1000
+ tokenName: 'tsol:usdc',
1001
+ },
1002
+ ],
1003
+ });
1004
+ });
1005
+ });
1006
+ describe('Explain Transactions:', () => {
1007
+ it('should explain an unsigned transfer transaction', async function () {
1008
+ const explainedTransaction = await basecoin.explainTransaction({
1009
+ txBase64: testData.rawTransactions.transfer.unsigned,
1010
+ feeInfo: {
1011
+ fee: '5000',
1012
+ },
1013
+ });
1014
+ explainedTransaction.should.deepEqual({
1015
+ displayOrder: [
1016
+ 'id',
1017
+ 'type',
1018
+ 'blockhash',
1019
+ 'durableNonce',
1020
+ 'outputAmount',
1021
+ 'changeAmount',
1022
+ 'outputs',
1023
+ 'changeOutputs',
1024
+ 'tokenEnablements',
1025
+ 'fee',
1026
+ 'memo',
1027
+ ],
1028
+ id: 'UNAVAILABLE',
1029
+ type: 'Send',
1030
+ changeOutputs: [],
1031
+ changeAmount: '0',
1032
+ outputAmount: '300000',
1033
+ outputs: [
1034
+ {
1035
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
1036
+ amount: '300000',
1037
+ },
1038
+ ],
1039
+ inputs: [
1040
+ {
1041
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1042
+ value: '300000',
1043
+ },
1044
+ ],
1045
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1046
+ fee: {
1047
+ fee: '5000',
1048
+ feeRate: 5000,
1049
+ },
1050
+ memo: 'test memo',
1051
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1052
+ durableNonce: {
1053
+ authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1054
+ walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1055
+ },
1056
+ tokenEnablements: [],
1057
+ ataOwnerMap: {},
1058
+ });
1059
+ });
1060
+ it('should explain a signed transfer transaction', async function () {
1061
+ const explainedTransaction = await basecoin.explainTransaction({
1062
+ txBase64: testData.rawTransactions.transfer.signed,
1063
+ feeInfo: {
1064
+ fee: '5000',
1065
+ },
1066
+ });
1067
+ explainedTransaction.should.deepEqual({
1068
+ displayOrder: [
1069
+ 'id',
1070
+ 'type',
1071
+ 'blockhash',
1072
+ 'durableNonce',
1073
+ 'outputAmount',
1074
+ 'changeAmount',
1075
+ 'outputs',
1076
+ 'changeOutputs',
1077
+ 'tokenEnablements',
1078
+ 'fee',
1079
+ 'memo',
1080
+ ],
1081
+ id: '2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L',
1082
+ type: 'Send',
1083
+ changeOutputs: [],
1084
+ changeAmount: '0',
1085
+ outputAmount: '300000',
1086
+ outputs: [
1087
+ {
1088
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
1089
+ amount: '300000',
1090
+ },
1091
+ ],
1092
+ inputs: [
1093
+ {
1094
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1095
+ value: '300000',
1096
+ },
1097
+ ],
1098
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1099
+ fee: {
1100
+ fee: '5000',
1101
+ feeRate: 5000,
1102
+ },
1103
+ memo: 'test memo',
1104
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1105
+ durableNonce: {
1106
+ authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1107
+ walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1108
+ },
1109
+ tokenEnablements: [],
1110
+ ataOwnerMap: {},
1111
+ });
1112
+ });
1113
+ it('should explain an unsigned wallet init transaction', async function () {
1114
+ const explainedTransaction = await basecoin.explainTransaction({
1115
+ txBase64: testData.rawTransactions.walletInit.unsigned,
1116
+ feeInfo: {
1117
+ fee: '5000',
1118
+ },
1119
+ });
1120
+ explainedTransaction.should.deepEqual({
1121
+ displayOrder: [
1122
+ 'id',
1123
+ 'type',
1124
+ 'blockhash',
1125
+ 'durableNonce',
1126
+ 'outputAmount',
1127
+ 'changeAmount',
1128
+ 'outputs',
1129
+ 'changeOutputs',
1130
+ 'tokenEnablements',
1131
+ 'fee',
1132
+ 'memo',
1133
+ ],
1134
+ id: 'UNAVAILABLE',
1135
+ type: 'WalletInitialization',
1136
+ changeOutputs: [],
1137
+ changeAmount: '0',
1138
+ outputAmount: '300000',
1139
+ outputs: [
1140
+ {
1141
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1142
+ amount: '300000',
1143
+ },
1144
+ ],
1145
+ inputs: [
1146
+ {
1147
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1148
+ value: '300000',
1149
+ },
1150
+ ],
1151
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1152
+ fee: {
1153
+ fee: '10000',
1154
+ feeRate: 5000,
1155
+ },
1156
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1157
+ durableNonce: undefined,
1158
+ memo: undefined,
1159
+ tokenEnablements: [],
1160
+ ataOwnerMap: {},
1161
+ });
1162
+ });
1163
+ it('should explain a signed wallet init transaction', async function () {
1164
+ const explainedTransaction = await basecoin.explainTransaction({
1165
+ txBase64: testData.rawTransactions.walletInit.signed,
1166
+ feeInfo: {
1167
+ fee: '5000',
1168
+ },
1169
+ });
1170
+ explainedTransaction.should.deepEqual({
1171
+ displayOrder: [
1172
+ 'id',
1173
+ 'type',
1174
+ 'blockhash',
1175
+ 'durableNonce',
1176
+ 'outputAmount',
1177
+ 'changeAmount',
1178
+ 'outputs',
1179
+ 'changeOutputs',
1180
+ 'tokenEnablements',
1181
+ 'fee',
1182
+ 'memo',
1183
+ ],
1184
+ id: '7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg',
1185
+ type: 'WalletInitialization',
1186
+ changeOutputs: [],
1187
+ changeAmount: '0',
1188
+ outputAmount: '300000',
1189
+ outputs: [
1190
+ {
1191
+ address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1192
+ amount: '300000',
1193
+ },
1194
+ ],
1195
+ inputs: [
1196
+ {
1197
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1198
+ value: '300000',
1199
+ },
1200
+ ],
1201
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1202
+ fee: {
1203
+ fee: '10000',
1204
+ feeRate: 5000,
1205
+ },
1206
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1207
+ durableNonce: undefined,
1208
+ memo: undefined,
1209
+ tokenEnablements: [],
1210
+ ataOwnerMap: {},
1211
+ });
1212
+ });
1213
+ it('should explain an unsigned token transfer transaction', async function () {
1214
+ const explainedTransaction = await basecoin.explainTransaction({
1215
+ txBase64: testData.rawTransactions.transferToken.unsigned,
1216
+ feeInfo: {
1217
+ fee: '5000',
1218
+ },
1219
+ });
1220
+ explainedTransaction.should.deepEqual({
1221
+ displayOrder: [
1222
+ 'id',
1223
+ 'type',
1224
+ 'blockhash',
1225
+ 'durableNonce',
1226
+ 'outputAmount',
1227
+ 'changeAmount',
1228
+ 'outputs',
1229
+ 'changeOutputs',
1230
+ 'tokenEnablements',
1231
+ 'fee',
1232
+ 'memo',
1233
+ ],
1234
+ id: 'UNAVAILABLE',
1235
+ type: 'Send',
1236
+ changeOutputs: [],
1237
+ changeAmount: '0',
1238
+ outputAmount: '0',
1239
+ outputs: [
1240
+ {
1241
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
1242
+ amount: '300000',
1243
+ tokenName: 'tsol:usdc',
1244
+ },
1245
+ ],
1246
+ inputs: [
1247
+ {
1248
+ address: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1249
+ value: '300000',
1250
+ },
1251
+ ],
1252
+ feePayer: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1253
+ fee: {
1254
+ fee: '5000',
1255
+ feeRate: 5000,
1256
+ },
1257
+ memo: 'test memo',
1258
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1259
+ durableNonce: {
1260
+ authWalletAddress: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1261
+ walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1262
+ },
1263
+ tokenEnablements: [],
1264
+ ataOwnerMap: {},
1265
+ });
1266
+ });
1267
+ it('should explain a signed token transfer transaction', async function () {
1268
+ const explainedTransaction = await basecoin.explainTransaction({
1269
+ txBase64: testData.rawTransactions.transferToken.signed,
1270
+ feeInfo: {
1271
+ fee: '5000',
1272
+ },
1273
+ });
1274
+ explainedTransaction.should.deepEqual({
1275
+ displayOrder: [
1276
+ 'id',
1277
+ 'type',
1278
+ 'blockhash',
1279
+ 'durableNonce',
1280
+ 'outputAmount',
1281
+ 'changeAmount',
1282
+ 'outputs',
1283
+ 'changeOutputs',
1284
+ 'tokenEnablements',
1285
+ 'fee',
1286
+ 'memo',
1287
+ ],
1288
+ id: '2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ',
1289
+ type: 'Send',
1290
+ changeOutputs: [],
1291
+ changeAmount: '0',
1292
+ outputAmount: '0',
1293
+ outputs: [
1294
+ {
1295
+ address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
1296
+ amount: '300000',
1297
+ tokenName: 'tsol:usdc',
1298
+ },
1299
+ ],
1300
+ inputs: [
1301
+ {
1302
+ address: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1303
+ value: '300000',
1304
+ },
1305
+ ],
1306
+ feePayer: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1307
+ fee: {
1308
+ fee: '5000',
1309
+ feeRate: 5000,
1310
+ },
1311
+ memo: 'test memo',
1312
+ blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
1313
+ durableNonce: {
1314
+ authWalletAddress: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
1315
+ walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1316
+ },
1317
+ tokenEnablements: [],
1318
+ ataOwnerMap: {},
1319
+ });
1320
+ });
1321
+ it('should explain activate staking transaction', async function () {
1322
+ const tx = await factory
1323
+ .getStakingActivateBuilder()
1324
+ .stakingAddress(stakeAccount.pub)
1325
+ .sender(wallet.pub)
1326
+ .nonce(blockHash)
1327
+ .amount(amount)
1328
+ .validator(validator.pub)
1329
+ .memo('test memo')
1330
+ .fee({ amount: 5000 })
1331
+ .build();
1332
+ const txToBroadcastFormat = tx.toBroadcastFormat();
1333
+ const explainedTransaction = await basecoin.explainTransaction({
1334
+ txBase64: txToBroadcastFormat,
1335
+ feeInfo: {
1336
+ fee: '5000',
1337
+ },
1338
+ });
1339
+ explainedTransaction.should.deepEqual({
1340
+ displayOrder: [
1341
+ 'id',
1342
+ 'type',
1343
+ 'blockhash',
1344
+ 'durableNonce',
1345
+ 'outputAmount',
1346
+ 'changeAmount',
1347
+ 'outputs',
1348
+ 'changeOutputs',
1349
+ 'tokenEnablements',
1350
+ 'fee',
1351
+ 'memo',
1352
+ ],
1353
+ id: 'UNAVAILABLE',
1354
+ type: 'StakingActivate',
1355
+ changeOutputs: [],
1356
+ changeAmount: '0',
1357
+ outputAmount: '10000',
1358
+ outputs: [
1359
+ {
1360
+ address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
1361
+ amount: '10000',
1362
+ },
1363
+ ],
1364
+ inputs: [
1365
+ {
1366
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1367
+ value: '10000',
1368
+ },
1369
+ ],
1370
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1371
+ fee: {
1372
+ fee: '10000',
1373
+ feeRate: 5000,
1374
+ },
1375
+ memo: 'test memo',
1376
+ blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
1377
+ durableNonce: undefined,
1378
+ tokenEnablements: [],
1379
+ ataOwnerMap: {},
1380
+ });
1381
+ });
1382
+ it('should explain deactivate staking transaction', async function () {
1383
+ const tx = await factory
1384
+ .getStakingDeactivateBuilder()
1385
+ .stakingAddress(stakeAccount.pub)
1386
+ .sender(wallet.pub)
1387
+ .nonce(blockHash)
1388
+ .memo('test memo')
1389
+ .fee({ amount: 5000 })
1390
+ .build();
1391
+ const txToBroadcastFormat = tx.toBroadcastFormat();
1392
+ const explainedTransaction = await basecoin.explainTransaction({
1393
+ txBase64: txToBroadcastFormat,
1394
+ feeInfo: {
1395
+ fee: '5000',
1396
+ },
1397
+ });
1398
+ explainedTransaction.should.deepEqual({
1399
+ displayOrder: [
1400
+ 'id',
1401
+ 'type',
1402
+ 'blockhash',
1403
+ 'durableNonce',
1404
+ 'outputAmount',
1405
+ 'changeAmount',
1406
+ 'outputs',
1407
+ 'changeOutputs',
1408
+ 'tokenEnablements',
1409
+ 'fee',
1410
+ 'memo',
1411
+ ],
1412
+ id: 'UNAVAILABLE',
1413
+ type: 'StakingDeactivate',
1414
+ changeOutputs: [],
1415
+ changeAmount: '0',
1416
+ outputAmount: '0',
1417
+ outputs: [],
1418
+ inputs: [],
1419
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1420
+ fee: {
1421
+ fee: '5000',
1422
+ feeRate: 5000,
1423
+ },
1424
+ memo: 'test memo',
1425
+ blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
1426
+ durableNonce: undefined,
1427
+ tokenEnablements: [],
1428
+ ataOwnerMap: {},
1429
+ });
1430
+ });
1431
+ it('should explain withdraw staking transaction', async function () {
1432
+ const tx = await factory
1433
+ .getStakingWithdrawBuilder()
1434
+ .stakingAddress(stakeAccount.pub)
1435
+ .sender(wallet.pub)
1436
+ .nonce(blockHash)
1437
+ .amount(amount)
1438
+ .memo('test memo')
1439
+ .fee({ amount: 5000 })
1440
+ .build();
1441
+ const txToBroadcastFormat = tx.toBroadcastFormat();
1442
+ const explainedTransaction = await basecoin.explainTransaction({
1443
+ txBase64: txToBroadcastFormat,
1444
+ feeInfo: {
1445
+ fee: '5000',
1446
+ },
1447
+ });
1448
+ explainedTransaction.should.deepEqual({
1449
+ displayOrder: [
1450
+ 'id',
1451
+ 'type',
1452
+ 'blockhash',
1453
+ 'durableNonce',
1454
+ 'outputAmount',
1455
+ 'changeAmount',
1456
+ 'outputs',
1457
+ 'changeOutputs',
1458
+ 'tokenEnablements',
1459
+ 'fee',
1460
+ 'memo',
1461
+ ],
1462
+ id: 'UNAVAILABLE',
1463
+ type: 'StakingWithdraw',
1464
+ changeOutputs: [],
1465
+ changeAmount: '0',
1466
+ outputAmount: '10000',
1467
+ outputs: [
1468
+ {
1469
+ address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1470
+ amount: '10000',
1471
+ },
1472
+ ],
1473
+ inputs: [
1474
+ {
1475
+ address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
1476
+ value: '10000',
1477
+ },
1478
+ ],
1479
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1480
+ fee: {
1481
+ fee: '5000',
1482
+ feeRate: 5000,
1483
+ },
1484
+ memo: 'test memo',
1485
+ blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
1486
+ durableNonce: undefined,
1487
+ tokenEnablements: [],
1488
+ ataOwnerMap: {},
1489
+ });
1490
+ });
1491
+ it('should explain create ATA transaction', async function () {
1492
+ const tokenName = 'tsol:usdc';
1493
+ const rentExemptAmount = '3000000';
1494
+ const tx = await factory
1495
+ .getAtaInitializationBuilder()
1496
+ .sender(wallet.pub)
1497
+ .nonce(blockHash)
1498
+ .mint(tokenName)
1499
+ .rentExemptAmount(rentExemptAmount)
1500
+ .memo('test memo')
1501
+ .fee({ amount: 5000 })
1502
+ .build();
1503
+ const txToBroadcastFormat = tx.toBroadcastFormat();
1504
+ const explainedTransaction = await basecoin.explainTransaction({
1505
+ txBase64: txToBroadcastFormat,
1506
+ feeInfo: {
1507
+ fee: '5000',
1508
+ },
1509
+ tokenAccountRentExemptAmount: rentExemptAmount,
1510
+ });
1511
+ explainedTransaction.should.deepEqual({
1512
+ displayOrder: [
1513
+ 'id',
1514
+ 'type',
1515
+ 'blockhash',
1516
+ 'durableNonce',
1517
+ 'outputAmount',
1518
+ 'changeAmount',
1519
+ 'outputs',
1520
+ 'changeOutputs',
1521
+ 'tokenEnablements',
1522
+ 'fee',
1523
+ 'memo',
1524
+ ],
1525
+ id: 'UNAVAILABLE',
1526
+ type: 'AssociatedTokenAccountInitialization',
1527
+ changeOutputs: [],
1528
+ changeAmount: '0',
1529
+ outputAmount: '0',
1530
+ outputs: [],
1531
+ inputs: [],
1532
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1533
+ fee: {
1534
+ fee: '3005000',
1535
+ feeRate: 5000,
1536
+ },
1537
+ memo: 'test memo',
1538
+ blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
1539
+ durableNonce: undefined,
1540
+ tokenEnablements: [
1541
+ {
1542
+ address: '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU',
1543
+ tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
1544
+ tokenName: 'tsol:usdc',
1545
+ },
1546
+ ],
1547
+ ataOwnerMap: {
1548
+ '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU': '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1549
+ },
1550
+ });
1551
+ });
1552
+ it('should explain create multi ATA transaction', async function () {
1553
+ const recipients = [
1554
+ {
1555
+ ownerAddress: wallet.pub,
1556
+ tokenName: 'tsol:usdc',
1557
+ },
1558
+ {
1559
+ ownerAddress: durableNonce.walletNonceAddress,
1560
+ tokenName: 'tsol:ray',
1561
+ },
1562
+ ];
1563
+ const rentExemptAmount = '3000000';
1564
+ const tx = await factory
1565
+ .getAtaInitializationBuilder()
1566
+ .sender(wallet.pub)
1567
+ .nonce(blockHash)
1568
+ .enableToken(recipients[0])
1569
+ .enableToken(recipients[1])
1570
+ .rentExemptAmount(rentExemptAmount)
1571
+ .memo('test memo')
1572
+ .fee({ amount: 5000 })
1573
+ .build();
1574
+ const txToBroadcastFormat = tx.toBroadcastFormat();
1575
+ const explainedTransaction = await basecoin.explainTransaction({
1576
+ txBase64: txToBroadcastFormat,
1577
+ feeInfo: {
1578
+ fee: '5000',
1579
+ },
1580
+ tokenAccountRentExemptAmount: rentExemptAmount,
1581
+ });
1582
+ explainedTransaction.should.deepEqual({
1583
+ displayOrder: [
1584
+ 'id',
1585
+ 'type',
1586
+ 'blockhash',
1587
+ 'durableNonce',
1588
+ 'outputAmount',
1589
+ 'changeAmount',
1590
+ 'outputs',
1591
+ 'changeOutputs',
1592
+ 'tokenEnablements',
1593
+ 'fee',
1594
+ 'memo',
1595
+ ],
1596
+ id: 'UNAVAILABLE',
1597
+ type: 'AssociatedTokenAccountInitialization',
1598
+ changeOutputs: [],
1599
+ changeAmount: '0',
1600
+ outputAmount: '0',
1601
+ outputs: [],
1602
+ inputs: [],
1603
+ feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1604
+ fee: {
1605
+ fee: '6005000',
1606
+ feeRate: 5000,
1607
+ },
1608
+ memo: 'test memo',
1609
+ blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
1610
+ durableNonce: undefined,
1611
+ tokenEnablements: [
1612
+ {
1613
+ address: '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU',
1614
+ tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
1615
+ tokenName: 'tsol:usdc',
1616
+ },
1617
+ {
1618
+ address: '9KaLinZFNW5chL4J8UoKnTECppWVMz3ewgx4FAkxUDcf',
1619
+ tokenAddress: '9kLJoGbMgSteptkhKKuh7ken4JEvHrT83157ezEGrZ7R',
1620
+ tokenName: 'tsol:ray',
1621
+ },
1622
+ ],
1623
+ ataOwnerMap: {
1624
+ '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU': '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
1625
+ '9KaLinZFNW5chL4J8UoKnTECppWVMz3ewgx4FAkxUDcf': '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
1626
+ },
1627
+ });
1628
+ });
1629
+ it('should explain an unsigned token transfer with ATA creation transaction', async function () {
1630
+ const explainedTransaction = await basecoin.explainTransaction({
1631
+ txBase64: testData.rawTransactions.tokenTransferWithAtaCreation.unsigned,
1632
+ feeInfo: {
1633
+ fee: '5000',
1634
+ },
1635
+ tokenAccountRentExemptAmount: '3000000',
1636
+ });
1637
+ explainedTransaction.should.deepEqual({
1638
+ displayOrder: [
1639
+ 'id',
1640
+ 'type',
1641
+ 'blockhash',
1642
+ 'durableNonce',
1643
+ 'outputAmount',
1644
+ 'changeAmount',
1645
+ 'outputs',
1646
+ 'changeOutputs',
1647
+ 'tokenEnablements',
1648
+ 'fee',
1649
+ 'memo',
1650
+ ],
1651
+ id: 'UNAVAILABLE',
1652
+ type: 'Send',
1653
+ changeOutputs: [],
1654
+ changeAmount: '0',
1655
+ outputAmount: '0',
1656
+ outputs: [
1657
+ {
1658
+ address: '2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS',
1659
+ amount: '10000',
1660
+ tokenName: 'tsol:usdc',
1661
+ },
1662
+ ],
1663
+ inputs: [
1664
+ {
1665
+ address: '5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7',
1666
+ value: '10000',
1667
+ },
1668
+ ],
1669
+ feePayer: '5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7',
1670
+ fee: { fee: '3005000', feeRate: 5000 },
1671
+ memo: undefined,
1672
+ blockhash: '27E3MXFvXMUNYeMJeX1pAbERGsJfUbkaZTfgMgpmNN5g',
1673
+ durableNonce: undefined,
1674
+ tokenEnablements: [
1675
+ {
1676
+ address: '2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS',
1677
+ tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
1678
+ tokenName: 'tsol:usdc',
1679
+ },
1680
+ ],
1681
+ ataOwnerMap: {
1682
+ '2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS': 'C4zCqCaDm4D78zgaH3CeBEEBEAoMNhzSCj23qE92ndiP',
1683
+ },
1684
+ });
1685
+ });
1686
+ });
1687
+ describe('Keypair:', () => {
1688
+ it('should generate a keypair from random seed', function () {
1689
+ should.throws(() => basecoin.generateKeyPair('placeholder'), 'generateKeyPair method not implemented');
1690
+ });
1691
+ it('should generate a keypair from a seed', function () {
1692
+ should.throws(() => basecoin.generateKeyPair('placeholder'), 'generateKeyPair method not implemented');
1693
+ });
1694
+ });
1695
+ describe('Sign transaction:', () => {
1696
+ it('should sign transaction', async function () {
1697
+ const signed = await basecoin.signTransaction({
1698
+ txPrebuild: {
1699
+ txBase64: resources.RAW_TX_UNSIGNED,
1700
+ keys: [resources.accountWithSeed.publicKey.toString()],
1701
+ },
1702
+ prv: resources.accountWithSeed.privateKey.base58,
1703
+ });
1704
+ signed.txHex.should.equal(resources.RAW_TX_SIGNED);
1705
+ });
1706
+ it('should handle txHex and txBase64 interchangeably', async function () {
1707
+ const signed = await basecoin.signTransaction({
1708
+ txPrebuild: {
1709
+ txHex: resources.RAW_TX_UNSIGNED,
1710
+ keys: [resources.accountWithSeed.publicKey.toString()],
1711
+ },
1712
+ prv: resources.accountWithSeed.privateKey.base58,
1713
+ });
1714
+ signed.txHex.should.equal(resources.RAW_TX_SIGNED);
1715
+ });
1716
+ it('should throw invalid transaction when sign with public key', async function () {
1717
+ await basecoin
1718
+ .signTransaction({
1719
+ txPrebuild: {
1720
+ txBase64: resources.RAW_TX_UNSIGNED,
1721
+ keys: [resources.accountWithSeed.publicKey.toString()],
1722
+ },
1723
+ prv: resources.accountWithSeed.publicKey,
1724
+ })
1725
+ .should.be.rejectedWith('Invalid key');
1726
+ });
1727
+ });
1728
+ describe('Sign message', () => {
1729
+ it('should sign message', async function () {
1730
+ const signed = await basecoin.signMessage(keypair, 'signed message');
1731
+ signed
1732
+ .toString('base64')
1733
+ .should.equal('s+7d/8aW/twfM/0wLSKOGxd9+LhDIiz/g0FfJ39ylJhQIkjK0RYPm/Y+gdeJ5DIy6K6h6gCXXESDomlv12DBBQ==');
1734
+ });
1735
+ it('shouldnt sign message when message is undefined', async function () {
1736
+ await basecoin
1737
+ .signMessage(keypair, undefined)
1738
+ .should.be.rejectedWith('The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined');
1739
+ });
1740
+ });
1741
+ describe('Get Signing Payload', () => {
1742
+ it('should return a valid signing payload', async function () {
1743
+ const factory = (0, getBuilderFactory_1.getBuilderFactory)(basecoin.getChain());
1744
+ const rebuiltSignablePayload = (await factory.from(resources.TRANSFER_UNSIGNED_TX_WITH_MEMO).build())
1745
+ .signablePayload;
1746
+ const signingPayload = await basecoin.getSignablePayload(resources.TRANSFER_UNSIGNED_TX_WITH_MEMO);
1747
+ signingPayload.should.be.deepEqual(rebuiltSignablePayload);
1748
+ });
1749
+ it('should build CloseAssociatedTokenAccount txn builder from raw txn', async function () {
1750
+ const factory = (0, getBuilderFactory_1.getBuilderFactory)(basecoin.getChain());
1751
+ const txnBuilder = factory.from(resources.TRANSFER_UNSIGNED_TX_CLOSE_ATA);
1752
+ assert_1.default.ok(txnBuilder);
1753
+ });
1754
+ });
1755
+ describe('Presign transaction', () => {
1756
+ const txRequestId = 'txRequestId';
1757
+ let sandbox;
1758
+ beforeEach(() => {
1759
+ sandbox = sinon.createSandbox();
1760
+ });
1761
+ afterEach(() => {
1762
+ sandbox.verifyAndRestore();
1763
+ });
1764
+ it('should rebuild tx request for hot wallets', async () => {
1765
+ const rebuiltTx = {
1766
+ txRequestId,
1767
+ unsignedTxs: [
1768
+ {
1769
+ serializedTxHex: 'deadbeef',
1770
+ signableHex: 'serializedTxHex',
1771
+ derivationPath: 'm/0',
1772
+ },
1773
+ ],
1774
+ transactions: [],
1775
+ date: new Date().toISOString(),
1776
+ intent: {
1777
+ intentType: 'payment',
1778
+ },
1779
+ latest: true,
1780
+ state: 'pendingUserSignature',
1781
+ walletType: 'hot',
1782
+ walletId: 'walletId',
1783
+ policiesChecked: true,
1784
+ version: 1,
1785
+ userId: 'userId',
1786
+ };
1787
+ const stubTssUtils = sandbox.createStubInstance(sdk_core_1.TssUtils);
1788
+ stubTssUtils.deleteSignatureShares.resolves([]);
1789
+ stubTssUtils.getTxRequest.resolves(rebuiltTx);
1790
+ const hotWallet = {
1791
+ type: 'hot',
1792
+ };
1793
+ const presignedTransaction = await basecoin.presignTransaction({
1794
+ walletData: hotWallet,
1795
+ tssUtils: stubTssUtils,
1796
+ txPrebuild: {
1797
+ txRequestId,
1798
+ },
1799
+ });
1800
+ presignedTransaction.walletData.should.deepEqual(hotWallet);
1801
+ presignedTransaction.txPrebuild.should.deepEqual(rebuiltTx);
1802
+ presignedTransaction.txHex.should.equal(rebuiltTx.unsignedTxs[0].serializedTxHex);
1803
+ });
1804
+ it('should do nothing for non-hot wallets', async () => {
1805
+ const coldWallet = {
1806
+ type: 'cold',
1807
+ };
1808
+ const presignedTransaction = await basecoin.presignTransaction({
1809
+ walletData: coldWallet,
1810
+ });
1811
+ presignedTransaction.should.deepEqual({
1812
+ walletData: coldWallet,
1813
+ });
1814
+ });
1815
+ it('should error if txRequestId is missing', async () => {
1816
+ const hotWallet = {
1817
+ type: 'hot',
1818
+ };
1819
+ await basecoin
1820
+ .presignTransaction({
1821
+ walletData: hotWallet,
1822
+ txPrebuild: {},
1823
+ })
1824
+ .should.rejectedWith('Missing txRequestId');
1825
+ });
1826
+ });
1827
+ describe('API Key parameter:', () => {
1828
+ // Test the getPublicNodeUrl method directly
1829
+ it('should append apiKey to node URL when provided', function () {
1830
+ // Access the protected method using type casting
1831
+ const url = basecoin.getPublicNodeUrl('test-api-key-123');
1832
+ url.should.equal(`${sdk_core_1.Environments.test.solAlchemyNodeUrl}/test-api-key-123`);
1833
+ });
1834
+ it('should use regular node URL when apiKey is not provided', function () {
1835
+ // Access the protected method using type casting
1836
+ const url = basecoin.getPublicNodeUrl();
1837
+ url.should.equal(sdk_core_1.Environments.test.solNodeUrl);
1838
+ });
1839
+ });
1840
+ describe('Recover Transactions:', () => {
1841
+ const sandBox = sinon.createSandbox();
1842
+ const coin = statics_1.coins.get('tsol');
1843
+ const usdtMintAddress = '9cgpBeNZ2HnLda7NWaaU1i3NyTstk2c4zCMUcoAGsi9C';
1844
+ const t22mintAddress = '5NR1bQwLWqjbkhbQ1hx72HKJybbuvwkDnUZNoAZ2VhW6';
1845
+ let callBack;
1846
+ beforeEach(() => {
1847
+ callBack = sandBox.stub(src_1.Sol.prototype, 'getDataFromNode');
1848
+ callBack
1849
+ .withArgs({
1850
+ payload: {
1851
+ id: '1',
1852
+ jsonrpc: '2.0',
1853
+ method: 'getLatestBlockhash',
1854
+ params: [
1855
+ {
1856
+ commitment: 'finalized',
1857
+ },
1858
+ ],
1859
+ },
1860
+ })
1861
+ .resolves(testData.SolResponses.getBlockhashResponse);
1862
+ callBack
1863
+ .withArgs({
1864
+ payload: {
1865
+ id: '1',
1866
+ jsonrpc: '2.0',
1867
+ method: 'getFeeForMessage',
1868
+ params: [
1869
+ sinon.match.string,
1870
+ {
1871
+ commitment: 'finalized',
1872
+ },
1873
+ ],
1874
+ },
1875
+ })
1876
+ .resolves(testData.SolResponses.getFeesForMessageResponse);
1877
+ callBack
1878
+ .withArgs({
1879
+ payload: {
1880
+ id: '1',
1881
+ jsonrpc: '2.0',
1882
+ method: 'getMinimumBalanceForRentExemption',
1883
+ params: [165],
1884
+ },
1885
+ })
1886
+ .resolves(testData.SolResponses.getMinimumBalanceForRentExemptionResponse);
1887
+ callBack
1888
+ .withArgs({
1889
+ payload: {
1890
+ id: '1',
1891
+ jsonrpc: '2.0',
1892
+ method: 'getBalance',
1893
+ params: [testData.accountInfo.bs58EncodedPublicKey],
1894
+ },
1895
+ })
1896
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
1897
+ callBack
1898
+ .withArgs({
1899
+ payload: {
1900
+ id: '1',
1901
+ jsonrpc: '2.0',
1902
+ method: 'getBalance',
1903
+ params: [testData.accountInfo.bs58EncodedPublicKeyNoFunds],
1904
+ },
1905
+ })
1906
+ .resolves(testData.SolResponses.getAccountBalanceResponseNoFunds);
1907
+ callBack
1908
+ .withArgs({
1909
+ payload: {
1910
+ id: '1',
1911
+ jsonrpc: '2.0',
1912
+ method: 'getBalance',
1913
+ params: [testData.accountInfo.bs58EncodedPublicKeyM1Derivation],
1914
+ },
1915
+ })
1916
+ .resolves(testData.SolResponses.getAccountBalanceResponseM1Derivation);
1917
+ callBack
1918
+ .withArgs({
1919
+ payload: {
1920
+ id: '1',
1921
+ jsonrpc: '2.0',
1922
+ method: 'getBalance',
1923
+ params: [testData.accountInfo.bs58EncodedPublicKeyM2Derivation],
1924
+ },
1925
+ })
1926
+ .resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
1927
+ callBack
1928
+ .withArgs({
1929
+ payload: {
1930
+ id: '1',
1931
+ jsonrpc: '2.0',
1932
+ method: 'getBalance',
1933
+ params: [testData.accountInfo.bs58EncodedPublicKeyWithManyTokens],
1934
+ },
1935
+ })
1936
+ .resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
1937
+ callBack
1938
+ .withArgs({
1939
+ payload: {
1940
+ id: '1',
1941
+ jsonrpc: '2.0',
1942
+ method: 'getBalance',
1943
+ params: [testData.closeATAkeys.closeAtaAddress],
1944
+ },
1945
+ })
1946
+ .resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
1947
+ callBack
1948
+ .withArgs({
1949
+ payload: {
1950
+ id: '1',
1951
+ jsonrpc: '2.0',
1952
+ method: 'getBalance',
1953
+ params: [testData.closeATAkeys.bs58EncodedPublicKey],
1954
+ },
1955
+ })
1956
+ .resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
1957
+ callBack
1958
+ .withArgs({
1959
+ payload: {
1960
+ id: '1',
1961
+ jsonrpc: '2.0',
1962
+ method: 'getAccountInfo',
1963
+ params: [
1964
+ testData.closeATAkeys.closeAtaAddress,
1965
+ {
1966
+ encoding: 'jsonParsed',
1967
+ },
1968
+ ],
1969
+ },
1970
+ })
1971
+ .resolves(testData.SolResponses.getTokenInfoResponse);
1972
+ callBack
1973
+ .withArgs({
1974
+ payload: {
1975
+ id: '1',
1976
+ jsonrpc: '2.0',
1977
+ method: 'getAccountInfo',
1978
+ params: [
1979
+ testData.keys.durableNoncePubKey,
1980
+ {
1981
+ encoding: 'jsonParsed',
1982
+ },
1983
+ ],
1984
+ },
1985
+ })
1986
+ .resolves(testData.SolResponses.getAccountInfoResponse);
1987
+ callBack
1988
+ .withArgs({
1989
+ payload: {
1990
+ id: '1',
1991
+ jsonrpc: '2.0',
1992
+ method: 'getTokenAccountsByOwner',
1993
+ params: [
1994
+ testData.keys.destinationPubKey,
1995
+ {
1996
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
1997
+ },
1998
+ {
1999
+ encoding: 'jsonParsed',
2000
+ },
2001
+ ],
2002
+ },
2003
+ })
2004
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2005
+ callBack
2006
+ .withArgs({
2007
+ payload: {
2008
+ id: '1',
2009
+ jsonrpc: '2.0',
2010
+ method: 'getTokenAccountsByOwner',
2011
+ params: [
2012
+ testData.accountInfo.bs58EncodedPublicKey,
2013
+ {
2014
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2015
+ },
2016
+ {
2017
+ encoding: 'jsonParsed',
2018
+ },
2019
+ ],
2020
+ },
2021
+ })
2022
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2023
+ callBack
2024
+ .withArgs({
2025
+ payload: {
2026
+ id: '1',
2027
+ jsonrpc: '2.0',
2028
+ method: 'getTokenAccountsByOwner',
2029
+ params: [
2030
+ testData.keys.destinationPubKey2,
2031
+ {
2032
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2033
+ },
2034
+ {
2035
+ encoding: 'jsonParsed',
2036
+ },
2037
+ ],
2038
+ },
2039
+ })
2040
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
2041
+ callBack
2042
+ .withArgs({
2043
+ payload: {
2044
+ id: '1',
2045
+ jsonrpc: '2.0',
2046
+ method: 'getTokenAccountsByOwner',
2047
+ params: [
2048
+ testData.keys.destinationPubKey2,
2049
+ {
2050
+ programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
2051
+ },
2052
+ {
2053
+ encoding: 'jsonParsed',
2054
+ },
2055
+ ],
2056
+ },
2057
+ })
2058
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerForSol2022Response2);
2059
+ callBack
2060
+ .withArgs({
2061
+ payload: {
2062
+ id: '1',
2063
+ jsonrpc: '2.0',
2064
+ method: 'getTokenAccountsByOwner',
2065
+ params: [
2066
+ testData.wrwUser.walletAddress0,
2067
+ {
2068
+ programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
2069
+ },
2070
+ {
2071
+ encoding: 'jsonParsed',
2072
+ },
2073
+ ],
2074
+ },
2075
+ })
2076
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerForSol2022Response);
2077
+ callBack
2078
+ .withArgs({
2079
+ payload: {
2080
+ id: '1',
2081
+ jsonrpc: '2.0',
2082
+ method: 'getTokenAccountsByOwner',
2083
+ params: [
2084
+ testData.wrwUser.walletAddress0,
2085
+ {
2086
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2087
+ },
2088
+ {
2089
+ encoding: 'jsonParsed',
2090
+ },
2091
+ ],
2092
+ },
2093
+ })
2094
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponse2);
2095
+ callBack
2096
+ .withArgs({
2097
+ payload: {
2098
+ id: '1',
2099
+ jsonrpc: '2.0',
2100
+ method: 'getTokenAccountsByOwner',
2101
+ params: [
2102
+ testData.wrwUser.walletAddress4,
2103
+ {
2104
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2105
+ },
2106
+ {
2107
+ encoding: 'jsonParsed',
2108
+ },
2109
+ ],
2110
+ },
2111
+ })
2112
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponse3);
2113
+ callBack
2114
+ .withArgs({
2115
+ payload: {
2116
+ id: '1',
2117
+ jsonrpc: '2.0',
2118
+ method: 'getBalance',
2119
+ params: [testData.wrwUser.walletAddress0],
2120
+ },
2121
+ })
2122
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
2123
+ callBack
2124
+ .withArgs({
2125
+ payload: {
2126
+ id: '1',
2127
+ jsonrpc: '2.0',
2128
+ method: 'getTokenAccountsByOwner',
2129
+ params: [
2130
+ testData.keys.destinationPubKey,
2131
+ {
2132
+ programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
2133
+ },
2134
+ {
2135
+ encoding: 'jsonParsed',
2136
+ },
2137
+ ],
2138
+ },
2139
+ })
2140
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2141
+ callBack
2142
+ .withArgs({
2143
+ payload: {
2144
+ id: '1',
2145
+ jsonrpc: '2.0',
2146
+ method: 'sendTransaction',
2147
+ params: sinon.match.array,
2148
+ },
2149
+ })
2150
+ .onCall(0)
2151
+ .resolves(testData.SolResponses.broadcastTransactionResponse)
2152
+ .onCall(1)
2153
+ .resolves(testData.SolResponses.broadcastTransactionResponse1);
2154
+ });
2155
+ afterEach(() => {
2156
+ sandBox.restore();
2157
+ });
2158
+ it('should take OVC output and generate a signed sweep transaction', async function () {
2159
+ const params = testData.ovcResponse;
2160
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
2161
+ recoveryTxn.transactions[0].serializedTx.should.equal('AvR+L909kzRq6NuaUe9F6Jt97MOiFs7jpW8MuOrwz4EbKF40d31dci/bgLTq4gpk/Hh3s5cA8FtbLkDQr15PqAE7yd8LOXvsLtO2REqMM/OCZ8wItfsqfTfia2xIfibRW3wHgw63jiaojbXeSqaYajJ/Ca7YwBUz5blydI3fYLgPAgECBsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQvLqE/j/nXlY2/JpxuNr/fXLXEPeS04dPvt9qz1dAoYEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAADpiH20cxLj7KnOaoI5ANNoPxYjs472FdjDeMPft3kXdAgQDAgUBBAQAAAAEAgADDAIAAADwopo7AAAAAA==');
2162
+ (recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(0);
2163
+ (recoveryTxn.lastScanIndex ?? 0).should.equal(0);
2164
+ });
2165
+ it('should take sol 2022 token OVC output and generate a signed sweep transaction', async function () {
2166
+ const params = testData.ovcResponse;
2167
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
2168
+ recoveryTxn.transactions[0].serializedTx.should.equal('AvR+L909kzRq6NuaUe9F6Jt97MOiFs7jpW8MuOrwz4EbKF40d31dci/bgLTq4gpk/Hh3s5cA8FtbLkDQr15PqAE7yd8LOXvsLtO2REqMM/OCZ8wItfsqfTfia2xIfibRW3wHgw63jiaojbXeSqaYajJ/Ca7YwBUz5blydI3fYLgPAgECBsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQvLqE/j/nXlY2/JpxuNr/fXLXEPeS04dPvt9qz1dAoYEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAADpiH20cxLj7KnOaoI5ANNoPxYjs472FdjDeMPft3kXdAgQDAgUBBAQAAAAEAgADDAIAAADwopo7AAAAAA==');
2169
+ (recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(0);
2170
+ (recoveryTxn.lastScanIndex ?? 0).should.equal(0);
2171
+ });
2172
+ it('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
2173
+ const params = testData.ovcResponse2;
2174
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
2175
+ recoveryTxn.transactions[0].serializedTx.should.equal('AtQPLzOmLuKwHY6N5XoJIZK/T7W10uYWm/MRte3GFUdl+w3gHLjSa9H66WSfFNubQxIPckxJDyltkP7ksLDf9QgBNJM2UWbBUH5wT0JJHILlhCs33HX8DeE/8Tdsw6tGfZoMhCnSKv6TPWtBxy7Sb6sW8ksCUPnAWuHGGKmgjEMBAgECBmLrqxJrY2kbN/tcrQw3P8P15OljFGabFJAKBrUO1grNBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAAIZQniiS73D6mwfpnfhVMC4lyYJtRSrmoZpF7yIlUdIDAgQDAgUBBAQAAAAEAgADDAIAAADwPc0dAAAAAA==');
2176
+ (recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(1);
2177
+ recoveryTxn.transactions[1].serializedTx.should.equal('AuLhOA5zmOBZR85lo+nKdTopVwJAMrMp6NW+8UnGNsSBSpBkqfWZQqSg9s+7aTlXezm5vxol+Pl6t7PpVNTOHwLcp9xJp3TFHdivEbhwJKldR4Ny+pasoFx+Bgk8q6g1iNiq7XSi1Ov3bs7euMkTj7nDRFqP8lv7xLTcvrBm9OQJAgECBp14ImBCdmVROlw0UveYS1MvG/ljCRI3MJTFmsxuXEoWBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHw0hyxvpVwtIx9/zeX2O16eTrY+aKIh1mdKg4MMg0eyxMLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAAC7ws1XFslinwgtpISUViVWIVTHyD2Q0qj24YjKmrAmXAgQDAgUBBAQAAAAEAgADDAIAAADwPc0dAAAAAA==');
2178
+ (recoveryTxn.transactions[1].scanIndex ?? 0).should.equal(2);
2179
+ (recoveryTxn.lastScanIndex ?? 0).should.equal(20);
2180
+ });
2181
+ it('should recover a txn for non-bitgo recoveries (latest blockhash)', async function () {
2182
+ // Latest Blockhash Recovery (BitGo-less)
2183
+ const latestBlockHashTxn = await basecoin.recover({
2184
+ userKey: testData.keys.userKey,
2185
+ backupKey: testData.keys.backupKey,
2186
+ bitgoKey: testData.keys.bitgoKey,
2187
+ recoveryDestination: testData.keys.destinationPubKey,
2188
+ walletPassphrase: testData.keys.walletPassword,
2189
+ });
2190
+ latestBlockHashTxn.should.not.be.empty();
2191
+ latestBlockHashTxn.should.hasOwnProperty('serializedTx');
2192
+ latestBlockHashTxn.should.hasOwnProperty('scanIndex');
2193
+ should.equal(latestBlockHashTxn.scanIndex, 0);
2194
+ const latestBlockhashTxnDeserialize = new lib_1.Transaction(coin);
2195
+ latestBlockhashTxnDeserialize.fromRawTransaction(latestBlockHashTxn.serializedTx);
2196
+ const latestBlockhashTxnJson = latestBlockhashTxnDeserialize.toJson();
2197
+ should.equal(latestBlockhashTxnJson.nonce, testData.SolInputData.blockhash);
2198
+ should.equal(latestBlockhashTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
2199
+ should.equal(latestBlockhashTxnJson.numSignatures, testData.SolInputData.latestBlockhashSignatures);
2200
+ const solCoin = basecoin;
2201
+ sandBox.assert.callCount(solCoin.getDataFromNode, 3);
2202
+ });
2203
+ it('should recover a txn for non-bitgo recoveries (durable nonce)', async function () {
2204
+ // Durable Nonce Recovery (BitGo-less)
2205
+ const durableNonceTxn = await basecoin.recover({
2206
+ userKey: testData.keys.userKey,
2207
+ backupKey: testData.keys.backupKey,
2208
+ bitgoKey: testData.keys.bitgoKey,
2209
+ recoveryDestination: testData.keys.destinationPubKey,
2210
+ walletPassphrase: testData.keys.walletPassword,
2211
+ durableNonce: {
2212
+ publicKey: testData.keys.durableNoncePubKey,
2213
+ secretKey: testData.keys.durableNoncePrivKey,
2214
+ },
2215
+ });
2216
+ durableNonceTxn.should.not.be.empty();
2217
+ durableNonceTxn.should.hasOwnProperty('serializedTx');
2218
+ durableNonceTxn.should.hasOwnProperty('scanIndex');
2219
+ should.equal(durableNonceTxn.scanIndex, 0);
2220
+ const durableNonceTxnDeserialize = new lib_1.Transaction(coin);
2221
+ durableNonceTxnDeserialize.fromRawTransaction(durableNonceTxn.serializedTx);
2222
+ const durableNonceTxnJson = durableNonceTxnDeserialize.toJson();
2223
+ should.equal(durableNonceTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2224
+ should.equal(durableNonceTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
2225
+ should.equal(durableNonceTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
2226
+ const solCoin = basecoin;
2227
+ sandBox.assert.callCount(solCoin.getDataFromNode, 4);
2228
+ });
2229
+ it('should recover a txn for unsigned sweep recoveries', async function () {
2230
+ // Unsigned Sweep Recovery
2231
+ const unsignedSweepTxn = (await basecoin.recover({
2232
+ bitgoKey: testData.keys.bitgoKey,
2233
+ recoveryDestination: testData.keys.destinationPubKey,
2234
+ durableNonce: {
2235
+ publicKey: testData.keys.durableNoncePubKey,
2236
+ secretKey: testData.keys.durableNoncePrivKey,
2237
+ },
2238
+ }));
2239
+ unsignedSweepTxn.should.not.be.empty();
2240
+ unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
2241
+ unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('scanIndex');
2242
+ should.equal(unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.scanIndex, 0);
2243
+ const unsignedSweepTxnDeserialize = new lib_1.Transaction(coin);
2244
+ unsignedSweepTxnDeserialize.fromRawTransaction(unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.serializedTx);
2245
+ const unsignedSweepTxnJson = unsignedSweepTxnDeserialize.toJson();
2246
+ should.equal(unsignedSweepTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2247
+ should.equal(unsignedSweepTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
2248
+ should.equal(unsignedSweepTxnJson.numSignatures, testData.SolInputData.unsignedSweepSignatures);
2249
+ const solCoin = basecoin;
2250
+ sandBox.assert.callCount(solCoin.getDataFromNode, 4);
2251
+ });
2252
+ it('should handle error in recover function if a required field is missing/incorrect', async function () {
2253
+ // missing userkey
2254
+ await basecoin
2255
+ .recover({
2256
+ backupKey: testData.keys.backupKey,
2257
+ bitgoKey: testData.keys.bitgoKey,
2258
+ recoveryDestination: testData.keys.destinationPubKey,
2259
+ walletPassphrase: testData.keys.walletPassword,
2260
+ })
2261
+ .should.rejectedWith('missing userKey');
2262
+ // missing backupkey
2263
+ await basecoin
2264
+ .recover({
2265
+ userKey: testData.keys.userKey,
2266
+ bitgoKey: testData.keys.bitgoKey,
2267
+ recoveryDestination: testData.keys.destinationPubKey,
2268
+ walletPassphrase: testData.keys.walletPassword,
2269
+ })
2270
+ .should.rejectedWith('missing backupKey');
2271
+ // incorrect wallet passphrase, user key, backup key combination
2272
+ await basecoin
2273
+ .recover({
2274
+ userKey: testData.keys.userKey,
2275
+ backupKey: testData.keys.backupKey,
2276
+ bitgoKey: testData.keys.bitgoKey,
2277
+ recoveryDestination: testData.keys.destinationPubKey,
2278
+ walletPassphrase: testData.keys.walletPassword + 'incorrect',
2279
+ })
2280
+ .should.rejectedWith('Error decrypting user keychain: incorrect password');
2281
+ // no wallet with sufficient funds
2282
+ await basecoin
2283
+ .recover({
2284
+ userKey: testData.keys.userKey,
2285
+ backupKey: testData.keys.backupKey,
2286
+ bitgoKey: testData.keys.bitgoKeyNoFunds,
2287
+ recoveryDestination: testData.keys.destinationPubKey,
2288
+ walletPassphrase: testData.keys.walletPassword,
2289
+ })
2290
+ .should.rejectedWith('Did not find address with funds to recover');
2291
+ });
2292
+ it('should recover sol tokens to recovery destination with no existing token accounts', async function () {
2293
+ const tokenTxn = await basecoin.recover({
2294
+ userKey: testData.wrwUser.userKey,
2295
+ backupKey: testData.wrwUser.backupKey,
2296
+ bitgoKey: testData.wrwUser.bitgoKey,
2297
+ recoveryDestination: testData.keys.destinationPubKey,
2298
+ tokenContractAddress: usdtMintAddress,
2299
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2300
+ durableNonce: {
2301
+ publicKey: testData.keys.durableNoncePubKey,
2302
+ secretKey: testData.keys.durableNoncePrivKey,
2303
+ },
2304
+ });
2305
+ tokenTxn.should.not.be.empty();
2306
+ tokenTxn.should.hasOwnProperty('serializedTx');
2307
+ tokenTxn.should.hasOwnProperty('scanIndex');
2308
+ should.equal(tokenTxn.scanIndex, 0);
2309
+ const tokenTxnDeserialize = new lib_1.Transaction(coin);
2310
+ tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
2311
+ const tokenTxnJson = tokenTxnDeserialize.toJson();
2312
+ should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2313
+ should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
2314
+ should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
2315
+ const instructionsData = tokenTxnJson.instructionsData;
2316
+ should.equal(instructionsData.length, 3);
2317
+ should.equal(instructionsData[0].type, 'NonceAdvance');
2318
+ const destinationUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.keys.destinationPubKey);
2319
+ should.equal(instructionsData[1].type, 'CreateAssociatedTokenAccount');
2320
+ should.equal(instructionsData[1].params.mintAddress, usdtMintAddress);
2321
+ should.equal(instructionsData[1].params.ataAddress, destinationUSDTTokenAccount);
2322
+ should.equal(instructionsData[1].params.ownerAddress, testData.keys.destinationPubKey);
2323
+ should.equal(instructionsData[1].params.tokenName, 'tsol:usdt');
2324
+ should.equal(instructionsData[1].params.payerAddress, testData.wrwUser.walletAddress0);
2325
+ const sourceUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.wrwUser.walletAddress0);
2326
+ should.equal(instructionsData[2].type, 'TokenTransfer');
2327
+ should.equal(instructionsData[2].params.fromAddress, testData.wrwUser.walletAddress0);
2328
+ should.equal(instructionsData[2].params.toAddress, destinationUSDTTokenAccount);
2329
+ should.equal(instructionsData[2].params.amount, '2000000000');
2330
+ should.equal(instructionsData[2].params.tokenName, 'tsol:usdt');
2331
+ should.equal(instructionsData[2].params.sourceAddress, sourceUSDTTokenAccount);
2332
+ const solCoin = basecoin;
2333
+ sandBox.assert.callCount(solCoin.getDataFromNode, 7);
2334
+ });
2335
+ it('should recover sol 2022 tokens to recovery destination with no existing token accounts', async function () {
2336
+ const tokenTxn = await basecoin.recover({
2337
+ userKey: testData.wrwUser.userKey,
2338
+ backupKey: testData.wrwUser.backupKey,
2339
+ bitgoKey: testData.wrwUser.bitgoKey,
2340
+ recoveryDestination: testData.keys.destinationPubKey,
2341
+ tokenContractAddress: t22mintAddress,
2342
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2343
+ durableNonce: {
2344
+ publicKey: testData.keys.durableNoncePubKey,
2345
+ secretKey: testData.keys.durableNoncePrivKey,
2346
+ },
2347
+ programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
2348
+ });
2349
+ tokenTxn.should.not.be.empty();
2350
+ tokenTxn.should.hasOwnProperty('serializedTx');
2351
+ tokenTxn.should.hasOwnProperty('scanIndex');
2352
+ should.equal(tokenTxn.scanIndex, 0);
2353
+ const tokenTxnDeserialize = new lib_1.Transaction(coin);
2354
+ tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
2355
+ const tokenTxnJson = tokenTxnDeserialize.toJson();
2356
+ should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2357
+ should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
2358
+ should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
2359
+ const instructionsData = tokenTxnJson.instructionsData;
2360
+ should.equal(instructionsData.length, 3);
2361
+ should.equal(instructionsData[0].type, 'NonceAdvance');
2362
+ const destinationTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.keys.destinationPubKey);
2363
+ should.equal(instructionsData[1].type, 'CreateAssociatedTokenAccount');
2364
+ should.equal(instructionsData[1].params.mintAddress, t22mintAddress);
2365
+ should.equal(instructionsData[1].params.ataAddress, destinationTokenAccount);
2366
+ should.equal(instructionsData[1].params.ownerAddress, testData.keys.destinationPubKey);
2367
+ should.equal(instructionsData[1].params.tokenName, 'tsol:t22mint');
2368
+ should.equal(instructionsData[1].params.payerAddress, testData.wrwUser.walletAddress0);
2369
+ const sourceTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.wrwUser.walletAddress0);
2370
+ should.equal(instructionsData[2].type, 'TokenTransfer');
2371
+ should.equal(instructionsData[2].params.fromAddress, testData.wrwUser.walletAddress0);
2372
+ should.equal(instructionsData[2].params.toAddress, destinationTokenAccount);
2373
+ should.equal(instructionsData[2].params.amount, '2000000000');
2374
+ should.equal(instructionsData[2].params.tokenName, 'tsol:t22mint');
2375
+ should.equal(instructionsData[2].params.sourceAddress, sourceTokenAccount);
2376
+ should.equal(instructionsData[2].params.programId, 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
2377
+ const solCoin = basecoin;
2378
+ sandBox.assert.callCount(solCoin.getDataFromNode, 7);
2379
+ });
2380
+ it('should recover sol tokens to recovery destination with existing token accounts', async function () {
2381
+ const tokenTxn = await basecoin.recover({
2382
+ userKey: testData.wrwUser.userKey,
2383
+ backupKey: testData.wrwUser.backupKey,
2384
+ bitgoKey: testData.wrwUser.bitgoKey,
2385
+ recoveryDestination: testData.keys.destinationPubKey2,
2386
+ tokenContractAddress: usdtMintAddress,
2387
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2388
+ durableNonce: {
2389
+ publicKey: testData.keys.durableNoncePubKey,
2390
+ secretKey: testData.keys.durableNoncePrivKey,
2391
+ },
2392
+ });
2393
+ tokenTxn.should.not.be.empty();
2394
+ tokenTxn.should.hasOwnProperty('serializedTx');
2395
+ tokenTxn.should.hasOwnProperty('scanIndex');
2396
+ should.equal(tokenTxn.scanIndex, 0);
2397
+ const tokenTxnDeserialize = new lib_1.Transaction(coin);
2398
+ tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
2399
+ const tokenTxnJson = tokenTxnDeserialize.toJson();
2400
+ should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2401
+ should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
2402
+ should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
2403
+ const instructionsData = tokenTxnJson.instructionsData;
2404
+ should.equal(instructionsData.length, 2);
2405
+ should.equal(instructionsData[0].type, 'NonceAdvance');
2406
+ const sourceUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.wrwUser.walletAddress0);
2407
+ const destinationUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.keys.destinationPubKey2);
2408
+ should.equal(instructionsData[1].type, 'TokenTransfer');
2409
+ should.equal(instructionsData[1].params.fromAddress, testData.wrwUser.walletAddress0);
2410
+ should.equal(instructionsData[1].params.toAddress, destinationUSDTTokenAccount);
2411
+ should.equal(instructionsData[1].params.amount, '2000000000');
2412
+ should.equal(instructionsData[1].params.tokenName, 'tsol:usdt');
2413
+ should.equal(instructionsData[1].params.sourceAddress, sourceUSDTTokenAccount);
2414
+ const solCoin = basecoin;
2415
+ sandBox.assert.callCount(solCoin.getDataFromNode, 7);
2416
+ });
2417
+ it('should recover sol 2022 tokens to recovery destination with existing token accounts', async function () {
2418
+ const tokenTxn = await basecoin.recover({
2419
+ userKey: testData.wrwUser.userKey,
2420
+ backupKey: testData.wrwUser.backupKey,
2421
+ bitgoKey: testData.wrwUser.bitgoKey,
2422
+ recoveryDestination: testData.keys.destinationPubKey2,
2423
+ tokenContractAddress: t22mintAddress,
2424
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2425
+ durableNonce: {
2426
+ publicKey: testData.keys.durableNoncePubKey,
2427
+ secretKey: testData.keys.durableNoncePrivKey,
2428
+ },
2429
+ programId: spl_token_1.TOKEN_2022_PROGRAM_ID.toString(),
2430
+ });
2431
+ tokenTxn.should.not.be.empty();
2432
+ tokenTxn.should.hasOwnProperty('serializedTx');
2433
+ tokenTxn.should.hasOwnProperty('scanIndex');
2434
+ should.equal(tokenTxn.scanIndex, 0);
2435
+ const tokenTxnDeserialize = new lib_1.Transaction(coin);
2436
+ tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
2437
+ const tokenTxnJson = tokenTxnDeserialize.toJson();
2438
+ console.log(tokenTxnJson);
2439
+ should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2440
+ should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
2441
+ should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
2442
+ const instructionsData = tokenTxnJson.instructionsData;
2443
+ should.equal(instructionsData.length, 2);
2444
+ should.equal(instructionsData[0].type, 'NonceAdvance');
2445
+ const source2022TokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.wrwUser.walletAddress0, false, spl_token_1.TOKEN_2022_PROGRAM_ID.toString());
2446
+ const destination2022TokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.keys.destinationPubKey2, false, spl_token_1.TOKEN_2022_PROGRAM_ID.toString());
2447
+ should.equal(instructionsData[1].type, 'TokenTransfer');
2448
+ should.equal(instructionsData[1].params.fromAddress, testData.wrwUser.walletAddress0);
2449
+ should.equal(instructionsData[1].params.toAddress, destination2022TokenAccount);
2450
+ should.equal(instructionsData[1].params.amount, '2000000000');
2451
+ should.equal(instructionsData[1].params.tokenName, 'tsol:t22mint');
2452
+ should.equal(instructionsData[1].params.sourceAddress, source2022TokenAccount);
2453
+ const solCoin = basecoin;
2454
+ sandBox.assert.callCount(solCoin.getDataFromNode, 7);
2455
+ });
2456
+ it('should recover sol tokens to recovery destination with existing token accounts for unsigned sweep recoveries', async function () {
2457
+ const feeResponse = testData.SolResponses.getFeesForMessageResponse;
2458
+ feeResponse.body.result.value = 10000;
2459
+ callBack
2460
+ .withArgs({
2461
+ payload: {
2462
+ id: '1',
2463
+ jsonrpc: '2.0',
2464
+ method: 'getFeeForMessage',
2465
+ params: [
2466
+ sinon.match.string,
2467
+ {
2468
+ commitment: 'finalized',
2469
+ },
2470
+ ],
2471
+ },
2472
+ })
2473
+ .resolves(feeResponse);
2474
+ const tokenTxn = (await basecoin.recover({
2475
+ bitgoKey: testData.wrwUser.bitgoKey,
2476
+ recoveryDestination: testData.keys.destinationPubKey2,
2477
+ durableNonce: {
2478
+ publicKey: testData.keys.durableNoncePubKey,
2479
+ secretKey: testData.keys.durableNoncePrivKey,
2480
+ },
2481
+ tokenContractAddress: testData.tokenAddress.TestUSDC,
2482
+ }));
2483
+ // 2 signatures and no rent exemption fee since the destination already has token accounts
2484
+ const expectedFee = 5000 + 5000;
2485
+ const { serializedTx, scanIndex, feeInfo, parsedTx } = tokenTxn.txRequests[0].transactions[0].unsignedTx;
2486
+ assert_1.default.ok(serializedTx);
2487
+ assert_1.default.strictEqual(scanIndex, 0);
2488
+ assert_1.default.ok(feeInfo);
2489
+ assert_1.default.strictEqual(feeInfo.feeString, expectedFee.toString());
2490
+ assert_1.default.strictEqual(feeInfo.fee, expectedFee);
2491
+ assert_1.default.ok(parsedTx);
2492
+ assert_1.default.ok(parsedTx.inputs instanceof Array && parsedTx.inputs.length === 1);
2493
+ assert_1.default.ok(parsedTx.outputs instanceof Array && parsedTx.outputs.length === 1);
2494
+ const tokenTxnDeserialize = new lib_1.Transaction(coin);
2495
+ tokenTxnDeserialize.fromRawTransaction(tokenTxn.txRequests[0].transactions[0].unsignedTx.serializedTx);
2496
+ const tokenTxnJson = tokenTxnDeserialize.toJson();
2497
+ assert_1.default.strictEqual(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
2498
+ assert_1.default.strictEqual(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
2499
+ assert_1.default.strictEqual(tokenTxnJson.numSignatures, testData.SolInputData.unsignedSweepSignatures);
2500
+ const solCoin = basecoin;
2501
+ sandBox.assert.callCount(solCoin.getDataFromNode, 7);
2502
+ });
2503
+ it('should recover sol funds from ATA address for non-bitgo recoveries', async function () {
2504
+ // close ATA address instruction type txn
2505
+ const closeATATxns = await basecoin.recoverCloseATA({
2506
+ userKey: testData.closeATAkeys.userKey,
2507
+ backupKey: testData.closeATAkeys.backupKey,
2508
+ bitgoKey: testData.closeATAkeys.bitgoKey,
2509
+ recoveryDestination: testData.closeATAkeys.destinationPubKey,
2510
+ walletPassphrase: testData.closeATAkeys.walletPassword,
2511
+ closeAtaAddress: testData.closeATAkeys.closeAtaAddress,
2512
+ recoveryDestinationAtaAddress: testData.closeATAkeys.recoveryDestinationAtaAddress,
2513
+ });
2514
+ closeATATxns.should.not.be.empty();
2515
+ should.equal(closeATATxns[0].txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
2516
+ should.equal(closeATATxns[1].txId, '5oUBgXX4enGmFEspG64goy3PRysjfrekZGg3rZNkBHUCQFd482vrVWbfDcRYMBEJt65JXymfEPm8M6d89X4xV79n');
2517
+ });
2518
+ it('should recover tokens from a nested ATA (ATA whose owner is another ATA)', async function () {
2519
+ const result = await basecoin.recoverNestedAta({
2520
+ userKey: testData.closeATAkeys.userKey,
2521
+ backupKey: testData.closeATAkeys.backupKey,
2522
+ bitgoKey: testData.closeATAkeys.bitgoKey,
2523
+ recoveryDestination: testData.closeATAkeys.destinationPubKey,
2524
+ walletPassphrase: testData.closeATAkeys.walletPassword,
2525
+ nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
2526
+ ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
2527
+ tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
2528
+ });
2529
+ result.should.not.be.empty();
2530
+ should.equal(result.txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
2531
+ });
2532
+ it('should throw when nestedAtaAddress is missing for recoverNestedAta', async function () {
2533
+ await basecoin
2534
+ .recoverNestedAta({
2535
+ userKey: testData.closeATAkeys.userKey,
2536
+ backupKey: testData.closeATAkeys.backupKey,
2537
+ bitgoKey: testData.closeATAkeys.bitgoKey,
2538
+ recoveryDestination: testData.closeATAkeys.destinationPubKey,
2539
+ walletPassphrase: testData.closeATAkeys.walletPassword,
2540
+ ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
2541
+ tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
2542
+ })
2543
+ .should.be.rejectedWith('invalid nestedAtaAddress');
2544
+ });
2545
+ it('should throw when ownerAtaAddress is missing for recoverNestedAta', async function () {
2546
+ await basecoin
2547
+ .recoverNestedAta({
2548
+ userKey: testData.closeATAkeys.userKey,
2549
+ backupKey: testData.closeATAkeys.backupKey,
2550
+ bitgoKey: testData.closeATAkeys.bitgoKey,
2551
+ recoveryDestination: testData.closeATAkeys.destinationPubKey,
2552
+ walletPassphrase: testData.closeATAkeys.walletPassword,
2553
+ nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
2554
+ tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
2555
+ })
2556
+ .should.be.rejectedWith('invalid ownerAtaAddress');
2557
+ });
2558
+ it('should throw when tokenMintAddress is missing for recoverNestedAta', async function () {
2559
+ await basecoin
2560
+ .recoverNestedAta({
2561
+ userKey: testData.closeATAkeys.userKey,
2562
+ backupKey: testData.closeATAkeys.backupKey,
2563
+ bitgoKey: testData.closeATAkeys.bitgoKey,
2564
+ recoveryDestination: testData.closeATAkeys.destinationPubKey,
2565
+ walletPassphrase: testData.closeATAkeys.walletPassword,
2566
+ nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
2567
+ ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
2568
+ })
2569
+ .should.be.rejectedWith('invalid tokenMintAddress');
2570
+ });
2571
+ });
2572
+ describe('Build Consolidation Recoveries:', () => {
2573
+ const sandBox = sinon.createSandbox();
2574
+ const coin = statics_1.coins.get('tsol');
2575
+ const usdtMintAddress = '9cgpBeNZ2HnLda7NWaaU1i3NyTstk2c4zCMUcoAGsi9C';
2576
+ const durableNonces = {
2577
+ publicKeys: [
2578
+ testData.keys.durableNoncePubKey,
2579
+ testData.keys.durableNoncePubKey2,
2580
+ testData.keys.durableNoncePubKey3,
2581
+ ],
2582
+ secretKey: testData.keys.durableNoncePrivKey,
2583
+ };
2584
+ beforeEach(() => {
2585
+ const callBack = sandBox.stub(src_1.Sol.prototype, 'getDataFromNode');
2586
+ callBack
2587
+ .withArgs({
2588
+ payload: {
2589
+ id: '1',
2590
+ jsonrpc: '2.0',
2591
+ method: 'getLatestBlockhash',
2592
+ params: [
2593
+ {
2594
+ commitment: 'finalized',
2595
+ },
2596
+ ],
2597
+ },
2598
+ })
2599
+ .resolves(testData.SolResponses.getBlockhashResponse);
2600
+ callBack
2601
+ .withArgs({
2602
+ payload: {
2603
+ id: '1',
2604
+ jsonrpc: '2.0',
2605
+ method: 'getFeeForMessage',
2606
+ params: [
2607
+ sinon.match.string,
2608
+ {
2609
+ commitment: 'finalized',
2610
+ },
2611
+ ],
2612
+ },
2613
+ })
2614
+ .resolves(testData.SolResponses.getFeesForMessageResponse);
2615
+ callBack
2616
+ .withArgs({
2617
+ payload: {
2618
+ id: '1',
2619
+ jsonrpc: '2.0',
2620
+ method: 'getBalance',
2621
+ params: [testData.wrwUser.walletAddress1],
2622
+ },
2623
+ })
2624
+ .resolves(testData.SolResponses.getAccountBalanceResponseNoFunds);
2625
+ callBack
2626
+ .withArgs({
2627
+ payload: {
2628
+ id: '1',
2629
+ jsonrpc: '2.0',
2630
+ method: 'getBalance',
2631
+ params: [testData.wrwUser.walletAddress2],
2632
+ },
2633
+ })
2634
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
2635
+ callBack
2636
+ .withArgs({
2637
+ payload: {
2638
+ id: '1',
2639
+ jsonrpc: '2.0',
2640
+ method: 'getBalance',
2641
+ params: [testData.wrwUser.walletAddress3],
2642
+ },
2643
+ })
2644
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
2645
+ callBack
2646
+ .withArgs({
2647
+ payload: {
2648
+ id: '1',
2649
+ jsonrpc: '2.0',
2650
+ method: 'getBalance',
2651
+ params: [testData.wrwUser.walletAddress5],
2652
+ },
2653
+ })
2654
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
2655
+ callBack
2656
+ .withArgs({
2657
+ payload: {
2658
+ id: '1',
2659
+ jsonrpc: '2.0',
2660
+ method: 'getMinimumBalanceForRentExemption',
2661
+ params: [165],
2662
+ },
2663
+ })
2664
+ .resolves(testData.SolResponses.getMinimumBalanceForRentExemptionResponse);
2665
+ callBack
2666
+ .withArgs({
2667
+ payload: {
2668
+ id: '1',
2669
+ jsonrpc: '2.0',
2670
+ method: 'getAccountInfo',
2671
+ params: [
2672
+ testData.keys.durableNoncePubKey,
2673
+ {
2674
+ encoding: 'jsonParsed',
2675
+ },
2676
+ ],
2677
+ },
2678
+ })
2679
+ .resolves(testData.SolResponses.getAccountInfoResponse);
2680
+ callBack
2681
+ .withArgs({
2682
+ payload: {
2683
+ id: '1',
2684
+ jsonrpc: '2.0',
2685
+ method: 'getAccountInfo',
2686
+ params: [
2687
+ testData.keys.durableNoncePubKey2,
2688
+ {
2689
+ encoding: 'jsonParsed',
2690
+ },
2691
+ ],
2692
+ },
2693
+ })
2694
+ .resolves(testData.SolResponses.getAccountInfoResponse2);
2695
+ callBack
2696
+ .withArgs({
2697
+ payload: {
2698
+ id: '1',
2699
+ jsonrpc: '2.0',
2700
+ method: 'getTokenAccountsByOwner',
2701
+ params: [
2702
+ testData.wrwUser.walletAddress1,
2703
+ {
2704
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2705
+ },
2706
+ {
2707
+ encoding: 'jsonParsed',
2708
+ },
2709
+ ],
2710
+ },
2711
+ })
2712
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2713
+ callBack
2714
+ .withArgs({
2715
+ payload: {
2716
+ id: '1',
2717
+ jsonrpc: '2.0',
2718
+ method: 'getTokenAccountsByOwner',
2719
+ params: [
2720
+ testData.wrwUser.walletAddress2,
2721
+ {
2722
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2723
+ },
2724
+ {
2725
+ encoding: 'jsonParsed',
2726
+ },
2727
+ ],
2728
+ },
2729
+ })
2730
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2731
+ callBack
2732
+ .withArgs({
2733
+ payload: {
2734
+ id: '1',
2735
+ jsonrpc: '2.0',
2736
+ method: 'getTokenAccountsByOwner',
2737
+ params: [
2738
+ testData.wrwUser.walletAddress3,
2739
+ {
2740
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2741
+ },
2742
+ {
2743
+ encoding: 'jsonParsed',
2744
+ },
2745
+ ],
2746
+ },
2747
+ })
2748
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
2749
+ callBack
2750
+ .withArgs({
2751
+ payload: {
2752
+ id: '1',
2753
+ jsonrpc: '2.0',
2754
+ method: 'getTokenAccountsByOwner',
2755
+ params: [
2756
+ testData.wrwUser.walletAddress5,
2757
+ {
2758
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2759
+ },
2760
+ {
2761
+ encoding: 'jsonParsed',
2762
+ },
2763
+ ],
2764
+ },
2765
+ })
2766
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
2767
+ callBack
2768
+ .withArgs({
2769
+ payload: {
2770
+ id: '1',
2771
+ jsonrpc: '2.0',
2772
+ method: 'getTokenAccountsByOwner',
2773
+ params: [
2774
+ testData.wrwUser.walletAddress0,
2775
+ {
2776
+ programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
2777
+ },
2778
+ {
2779
+ encoding: 'jsonParsed',
2780
+ },
2781
+ ],
2782
+ },
2783
+ })
2784
+ .resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
2785
+ });
2786
+ afterEach(() => {
2787
+ sandBox.restore();
2788
+ });
2789
+ it('should build signed consolidation recoveries', async function () {
2790
+ const res = (await basecoin.recoverConsolidations({
2791
+ userKey: testData.wrwUser.userKey,
2792
+ backupKey: testData.wrwUser.backupKey,
2793
+ bitgoKey: testData.wrwUser.bitgoKey,
2794
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2795
+ startingScanIndex: 1,
2796
+ endingScanIndex: 4,
2797
+ durableNonces: durableNonces,
2798
+ }));
2799
+ res.should.not.be.empty();
2800
+ res.transactions.length.should.equal(2);
2801
+ (res.lastScanIndex ?? 0).should.equal(3);
2802
+ const txn1 = res.transactions[0];
2803
+ const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
2804
+ latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
2805
+ const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
2806
+ const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
2807
+ should.equal(latestBlockhashTxnJson1.nonce, nonce1);
2808
+ should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress2);
2809
+ should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.durableNonceSignatures);
2810
+ const txn2 = res.transactions[1];
2811
+ const latestBlockhashTxnDeserialize2 = new lib_1.Transaction(coin);
2812
+ latestBlockhashTxnDeserialize2.fromRawTransaction(txn2.serializedTx);
2813
+ const latestBlockhashTxnJson2 = latestBlockhashTxnDeserialize2.toJson();
2814
+ const nonce2 = testData.SolResponses.getAccountInfoResponse2.body.result.value.data.parsed.info.blockhash;
2815
+ should.equal(latestBlockhashTxnJson2.nonce, nonce2);
2816
+ should.equal(latestBlockhashTxnJson2.feePayer, testData.wrwUser.walletAddress3);
2817
+ should.equal(latestBlockhashTxnJson2.numSignatures, testData.SolInputData.durableNonceSignatures);
2818
+ });
2819
+ it('should build unsigned consolidation recoveries', async function () {
2820
+ const res = (await basecoin.recoverConsolidations({
2821
+ bitgoKey: testData.wrwUser.bitgoKey,
2822
+ startingScanIndex: 1,
2823
+ endingScanIndex: 4,
2824
+ durableNonces: durableNonces,
2825
+ }));
2826
+ res.should.not.be.empty();
2827
+ res.txRequests.length.should.equal(2);
2828
+ const txn1 = res.txRequests[0].transactions[0].unsignedTx;
2829
+ txn1.should.hasOwnProperty('serializedTx');
2830
+ txn1.should.hasOwnProperty('signableHex');
2831
+ txn1.should.hasOwnProperty('scanIndex');
2832
+ (txn1.scanIndex ?? 0).should.equal(2);
2833
+ txn1.should.hasOwnProperty('coin');
2834
+ txn1.coin?.should.equal('tsol');
2835
+ txn1.should.hasOwnProperty('derivationPath');
2836
+ txn1.derivationPath?.should.equal('m/2');
2837
+ txn1.should.hasOwnProperty('coinSpecific');
2838
+ const coinSpecific1 = txn1.coinSpecific;
2839
+ coinSpecific1?.should.hasOwnProperty('commonKeychain');
2840
+ const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
2841
+ latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
2842
+ const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
2843
+ const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
2844
+ should.equal(latestBlockhashTxnJson1.nonce, nonce1);
2845
+ should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress2);
2846
+ should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.unsignedSweepSignatures);
2847
+ const txn2 = res.txRequests[1].transactions[0].unsignedTx;
2848
+ txn2.should.hasOwnProperty('serializedTx');
2849
+ txn2.should.hasOwnProperty('signableHex');
2850
+ txn2.should.hasOwnProperty('scanIndex');
2851
+ (txn2.scanIndex ?? 0).should.equal(3);
2852
+ txn2.should.hasOwnProperty('coin');
2853
+ txn2.coin?.should.equal('tsol');
2854
+ txn2.should.hasOwnProperty('derivationPath');
2855
+ txn2.derivationPath?.should.equal('m/3');
2856
+ txn2.should.hasOwnProperty('coinSpecific');
2857
+ const coinSpecific2 = txn2.coinSpecific;
2858
+ coinSpecific2?.should.hasOwnProperty('commonKeychain');
2859
+ coinSpecific2?.should.hasOwnProperty('lastScanIndex');
2860
+ coinSpecific2?.lastScanIndex?.should.equal(3);
2861
+ const latestBlockhashTxnDeserialize2 = new lib_1.Transaction(coin);
2862
+ latestBlockhashTxnDeserialize2.fromRawTransaction(txn2.serializedTx);
2863
+ const latestBlockhashTxnJson2 = latestBlockhashTxnDeserialize2.toJson();
2864
+ const nonce2 = testData.SolResponses.getAccountInfoResponse2.body.result.value.data.parsed.info.blockhash;
2865
+ should.equal(latestBlockhashTxnJson2.nonce, nonce2);
2866
+ should.equal(latestBlockhashTxnJson2.feePayer, testData.wrwUser.walletAddress3);
2867
+ should.equal(latestBlockhashTxnJson2.numSignatures, testData.SolInputData.unsignedSweepSignatures);
2868
+ });
2869
+ it('should build unsigned token consolidation recoveries', async function () {
2870
+ const res = (await basecoin.recoverConsolidations({
2871
+ bitgoKey: testData.wrwUser.bitgoKey,
2872
+ startingScanIndex: 3,
2873
+ endingScanIndex: 5,
2874
+ tokenContractAddress: usdtMintAddress,
2875
+ durableNonces: durableNonces,
2876
+ }));
2877
+ res.should.not.be.empty();
2878
+ res.txRequests.length.should.equal(1);
2879
+ const txn1 = res.txRequests[0].transactions[0].unsignedTx;
2880
+ txn1.should.hasOwnProperty('serializedTx');
2881
+ txn1.should.hasOwnProperty('signableHex');
2882
+ txn1.should.hasOwnProperty('scanIndex');
2883
+ (txn1.scanIndex ?? 0).should.equal(4);
2884
+ txn1.should.hasOwnProperty('coin');
2885
+ txn1.coin?.should.equal('tsol');
2886
+ txn1.should.hasOwnProperty('derivationPath');
2887
+ txn1.derivationPath?.should.equal('m/4');
2888
+ txn1.should.hasOwnProperty('coinSpecific');
2889
+ const coinSpecific1 = txn1.coinSpecific;
2890
+ coinSpecific1?.should.hasOwnProperty('commonKeychain');
2891
+ const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
2892
+ latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
2893
+ const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
2894
+ const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
2895
+ should.equal(latestBlockhashTxnJson1.nonce, nonce1);
2896
+ should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress5);
2897
+ should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.unsignedSweepSignatures);
2898
+ });
2899
+ it('should skip building consolidate transaction if balance is equal to zero', async function () {
2900
+ await basecoin
2901
+ .recoverConsolidations({
2902
+ userKey: testData.wrwUser.userKey,
2903
+ backupKey: testData.wrwUser.backupKey,
2904
+ bitgoKey: testData.wrwUser.bitgoKey,
2905
+ walletPassphrase: testData.wrwUser.walletPassphrase,
2906
+ startingScanIndex: 1,
2907
+ endingScanIndex: 2,
2908
+ durableNonces: durableNonces,
2909
+ })
2910
+ .should.rejectedWith('Did not find an address with funds to recover');
2911
+ });
2912
+ it('should throw if startingScanIndex is not ge to 1', async () => {
2913
+ await basecoin
2914
+ .recoverConsolidations({
2915
+ userKey: testData.wrwUser.userKey,
2916
+ backupKey: testData.wrwUser.backupKey,
2917
+ bitgoKey: testData.wrwUser.bitgoKey,
2918
+ startingScanIndex: -1,
2919
+ durableNonces: durableNonces,
2920
+ })
2921
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
2922
+ });
2923
+ it('should throw if scan factor is too high', async () => {
2924
+ await basecoin
2925
+ .recoverConsolidations({
2926
+ userKey: testData.wrwUser.userKey,
2927
+ backupKey: testData.wrwUser.backupKey,
2928
+ bitgoKey: testData.wrwUser.bitgoKey,
2929
+ startingScanIndex: 1,
2930
+ endingScanIndex: 300,
2931
+ durableNonces: durableNonces,
2932
+ })
2933
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
2934
+ });
2935
+ });
2936
+ describe('broadcastTransaction', function () {
2937
+ const sandBox = sinon.createSandbox();
2938
+ afterEach(() => {
2939
+ sandBox.restore();
2940
+ });
2941
+ it('should broadcast a transaction succesfully', async function () {
2942
+ const serializedSignedTransaction = testData.rawTransactions.transfer.signed;
2943
+ const broadcastStub = sandBox
2944
+ .stub(src_1.Sol.prototype, 'getDataFromNode')
2945
+ .withArgs({
2946
+ payload: {
2947
+ id: '1',
2948
+ jsonrpc: '2.0',
2949
+ method: 'sendTransaction',
2950
+ params: [
2951
+ serializedSignedTransaction,
2952
+ {
2953
+ encoding: 'base64',
2954
+ },
2955
+ ],
2956
+ },
2957
+ })
2958
+ .resolves(testData.SolResponses.broadcastTransactionResponse);
2959
+ const broadcastTxn = await basecoin.broadcastTransaction({ serializedSignedTransaction });
2960
+ assert_1.default.ok(broadcastTxn);
2961
+ assert_1.default.ok(broadcastTxn.txId);
2962
+ assert_1.default.strictEqual(broadcastTxn.txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
2963
+ assert_1.default.strictEqual(broadcastStub.callCount, 1);
2964
+ });
2965
+ it('should throw if got an error from the node', async function () {
2966
+ const serializedSignedTransaction = testData.rawTransactions.transfer.signed;
2967
+ const broadcastStub = sandBox
2968
+ .stub(src_1.Sol.prototype, 'getDataFromNode')
2969
+ .withArgs({
2970
+ payload: {
2971
+ id: '1',
2972
+ jsonrpc: '2.0',
2973
+ method: 'sendTransaction',
2974
+ params: [
2975
+ serializedSignedTransaction,
2976
+ {
2977
+ encoding: 'base64',
2978
+ },
2979
+ ],
2980
+ },
2981
+ })
2982
+ .resolves(testData.SolResponses.broadcastTransactionResponseError);
2983
+ await assert_1.default.rejects(async () => {
2984
+ await basecoin.broadcastTransaction({ serializedSignedTransaction });
2985
+ }, { message: 'Error broadcasting transaction: Transaction simulation failed: Blockhash not found' });
2986
+ assert_1.default.strictEqual(broadcastStub.callCount, 1);
2987
+ });
2988
+ it('should throw if is not a valid transaction', async function () {
2989
+ const serializedSignedTransaction = 'randomstring';
2990
+ await assert_1.default.rejects(async () => {
2991
+ await basecoin.broadcastTransaction({ serializedSignedTransaction });
2992
+ }, { message: 'Invalid raw transaction' });
2993
+ });
2994
+ it('should throw if is not a signed transaction', async function () {
2995
+ const serializedSignedTransaction = testData.rawTransactions.transfer.unsigned;
2996
+ await assert_1.default.rejects(async () => {
2997
+ await basecoin.broadcastTransaction({ serializedSignedTransaction });
2998
+ }, { message: 'Invalid raw transaction' });
2999
+ });
3000
+ });
3001
+ describe('AuditKey', () => {
3002
+ const { key: keyString, commonKeychain } = solBackupKey_1.solBackupKey;
3003
+ const key = keyString.replace(/\s/g, '');
3004
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
3005
+ const multiSigType = 'tss';
3006
+ it('should return for valid inputs', () => {
3007
+ basecoin.assertIsValidKey({
3008
+ encryptedPrv: key,
3009
+ publicKey: commonKeychain,
3010
+ walletPassphrase,
3011
+ multiSigType,
3012
+ });
3013
+ });
3014
+ it('should throw error if the commonKeychain is invalid', () => {
3015
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
3016
+ assert_1.default.throws(() => basecoin.assertIsValidKey({
3017
+ encryptedPrv: key,
3018
+ publicKey: alteredCommonKeychain,
3019
+ walletPassphrase,
3020
+ multiSigType,
3021
+ }), {
3022
+ message: 'Invalid common keychain',
3023
+ });
3024
+ });
3025
+ it('should throw error if the walletPassphrase is incorrect', () => {
3026
+ const incorrectPassphrase = 'foo';
3027
+ assert_1.default.throws(() => basecoin.assertIsValidKey({
3028
+ encryptedPrv: key,
3029
+ publicKey: commonKeychain,
3030
+ walletPassphrase: incorrectPassphrase,
3031
+ multiSigType,
3032
+ }), {
3033
+ message: "failed to decrypt prv: password error - ccm: tag doesn't match",
3034
+ });
3035
+ });
3036
+ it('should throw error if the key is altered', () => {
3037
+ const alteredKey = key.replace(/[0-9]/g, '0');
3038
+ assert_1.default.throws(() => basecoin.assertIsValidKey({
3039
+ encryptedPrv: alteredKey,
3040
+ publicKey: commonKeychain,
3041
+ walletPassphrase,
3042
+ multiSigType,
3043
+ }), {
3044
+ message: 'failed to decrypt prv: json decrypt: invalid parameters',
3045
+ });
3046
+ });
3047
+ it('should verify consolidation transaction', async function () {
3048
+ // Set up wallet data
3049
+ const walletData = {
3050
+ id: '5b34252f1bf349930e34020a00000000',
3051
+ coin: 'tsol',
3052
+ keys: [
3053
+ '5b3424f91bf349930e34017500000000',
3054
+ '5b3424f91bf349930e34017600000000',
3055
+ '5b3424f91bf349930e34017700000000',
3056
+ ],
3057
+ coinSpecific: {
3058
+ rootAddress: wallet.pub,
3059
+ },
3060
+ multisigType: 'tss',
3061
+ };
3062
+ const fakePrv = (0, sdk_api_1.encrypt)('password', 'prv');
3063
+ const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3064
+ const bgUrl = sdk_core_1.common.Environments['mock'].uri;
3065
+ (0, nock_1.default)(bgUrl)
3066
+ .get('/api/v2/tsol/key/5b3424f91bf349930e34017500000000')
3067
+ .reply(200, [
3068
+ {
3069
+ encryptedPrv: fakePrv,
3070
+ },
3071
+ ]);
3072
+ // Mock the API response for buildAccountConsolidations
3073
+ (0, nock_1.default)(bgUrl)
3074
+ .post('/api/v2/tsol/wallet/5b34252f1bf349930e34020a00000000/consolidateAccount/build')
3075
+ .reply(200, [
3076
+ {
3077
+ txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
3078
+ walletId: '63068ed4efa63a000877f02fd4b0fa6d',
3079
+ txHex: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f50130abf8d0d8943c5b9a51a574886a7d7b3d8db18f0ddb4ab8b6d3ec27e3c2f36f3339bb92d4296af6ae4d3abfbb07877f77d0033c883de08fa4a2eea670d0201020674a9df2b94aa4b4ada1202dc2891be366501d0acb4a01ca3e02e7fd6c1f505a71c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f8401c3f67cfa52518b34a09b08f4ea77e1c4fb9d89bfaccdc33cf8b8a9cf8d7bf0e04c89c50428e4eda5cbb759427c370f0a29a50bb0d1407e57924b0cc5b36f000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000040c9568195d67eb6b396fdbe97ba2e276622ef0023af09f23e6e0292abb678d90204030305010404000000040200020c020000000100000000000000',
3080
+ feeInfo: {
3081
+ fee: 10000,
3082
+ feeString: '10000',
3083
+ },
3084
+ txInfo: {
3085
+ minerFee: '10000',
3086
+ spendAmount: '1547864',
3087
+ spendAmounts: [
3088
+ {
3089
+ coinName: 'tsol',
3090
+ amountString: '1547864',
3091
+ },
3092
+ ],
3093
+ payGoFee: '0',
3094
+ outputs: [
3095
+ {
3096
+ address: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
3097
+ value: 1547864,
3098
+ wallet: '63068ed4efa63a000877f02f',
3099
+ wallets: ['63068ed4efa63a000877f02f'],
3100
+ enterprise: '62d71a6b86068f0008f029fd',
3101
+ enterprises: ['62d71a6b86068f0008f029fd'],
3102
+ valueString: '1547864',
3103
+ coinName: 'tsol',
3104
+ walletType: 'hot',
3105
+ walletTypes: ['hot'],
3106
+ },
3107
+ ],
3108
+ inputs: [
3109
+ {
3110
+ value: 1547864,
3111
+ address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
3112
+ valueString: '1547864',
3113
+ },
3114
+ {
3115
+ value: 10000,
3116
+ address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
3117
+ valueString: '10000',
3118
+ },
3119
+ ],
3120
+ type: 'Send',
3121
+ },
3122
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
3123
+ coin: 'tsol',
3124
+ },
3125
+ ]);
3126
+ // Call the function to test
3127
+ await assert_1.default.rejects(async () => {
3128
+ await walletObj.sendAccountConsolidations({
3129
+ walletPassphrase: 'password',
3130
+ });
3131
+ }, {
3132
+ message: 'tx outputs does not match with expected address',
3133
+ });
3134
+ });
3135
+ it('should verify valid a consolidation transaction', async () => {
3136
+ const consolidationTx = {
3137
+ txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
3138
+ walletId: '63068ed4efa63a000877f02fd4b0fa6d',
3139
+ txHex: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002010206aeda253a331de489838246df93879440af8c62ac4967658edc2bb5d52b9759d91c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f74a9df2b94aa4b4ada1202dc2891be366501d0acb4a01ca3e02e7fd6c1f505a7d2734f3952f3eb4aefcf6c7a6092e979dd3fe5563ccfaca1cc92652a15ddd393000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea9400000428dad41bbedeb38018379e4ceeb7e80757d74dd00ae8c47c38d597477339ad80204030305010404000000040200020c02000000589e170000000000',
3140
+ feeInfo: {
3141
+ fee: 10000,
3142
+ feeString: '10000',
3143
+ },
3144
+ txInfo: {
3145
+ minerFee: '10000',
3146
+ spendAmount: '1547864',
3147
+ spendAmounts: [
3148
+ {
3149
+ coinName: 'tsol',
3150
+ amountString: '1547864',
3151
+ },
3152
+ ],
3153
+ payGoFee: '0',
3154
+ outputs: [
3155
+ {
3156
+ address: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
3157
+ value: 1547864,
3158
+ wallet: '63068ed4efa63a000877f02f',
3159
+ wallets: ['63068ed4efa63a000877f02f'],
3160
+ enterprise: '62d71a6b86068f0008f029fd',
3161
+ enterprises: ['62d71a6b86068f0008f029fd'],
3162
+ valueString: '1547864',
3163
+ coinName: 'tsol',
3164
+ walletType: 'hot',
3165
+ walletTypes: ['hot'],
3166
+ },
3167
+ ],
3168
+ inputs: [
3169
+ {
3170
+ value: 1547864,
3171
+ address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
3172
+ valueString: '1547864',
3173
+ },
3174
+ {
3175
+ value: 10000,
3176
+ address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
3177
+ valueString: '10000',
3178
+ },
3179
+ ],
3180
+ type: 'Send',
3181
+ },
3182
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
3183
+ coin: 'tsol',
3184
+ };
3185
+ const mockedWallet = {
3186
+ coinSpecific: () => {
3187
+ const cs = {
3188
+ rootAddress: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
3189
+ };
3190
+ return cs;
3191
+ },
3192
+ };
3193
+ try {
3194
+ if (!(await basecoin.verifyTransaction({
3195
+ blockhash: '',
3196
+ feePayer: '',
3197
+ txParams: {},
3198
+ txPrebuild: consolidationTx,
3199
+ walletType: 'tss',
3200
+ wallet: mockedWallet,
3201
+ verification: {
3202
+ consolidationToBaseAddress: true,
3203
+ },
3204
+ }))) {
3205
+ assert_1.default.fail('Transaction should pass verification');
3206
+ }
3207
+ }
3208
+ catch (e) {
3209
+ assert_1.default.fail('Transaction should pass verification');
3210
+ }
3211
+ });
3212
+ it('should verify a token consolidation transaction', async () => {
3213
+ const consolidationTx = {
3214
+ txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
3215
+ walletId: '63068ed4efa63a000877f02fd4b0fa6d',
3216
+ txHex: '02b7c2c7829eded4e8f947c90ed3b9afce71f616eb47dfcfbf4b765778149060013acb33b9f67fdd9c2512f48fac4e4c049eab93829b69404f3bd166fe3242c90700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020104096da690bd558fd8634ac14f1645d8095afd0caea5953578c596e3c0dea38305ee7298bfac55101f177735659d42ed6be890ef3a1d204d9e33f32e24c5635327ca66d1fe00826e5a4f759f87b279c1aee19cce5301af4ed66ae17db48b201ed6c2a0e8a28bf565627f1ab8a34b1a95ee1b0a2a39084f1f0e2acb1c394b20185d8e0b22657c8d9c4ce5f6495efb6410c199011530f90e3ab9d8d1e4206f9ae0ffeb0000000000000000000000000000000000000000000000000000000000000000c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e406a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9de13c74d2b4d948e1608ea6eebdafe75bc2f995aad11b21d1e2c94f2a2d12f6802050303070004040000000804020604010a0ce0076bb20400000006',
3217
+ feeInfo: {
3218
+ fee: 10000,
3219
+ feeString: '10000',
3220
+ },
3221
+ txInfo: {
3222
+ inputs: [
3223
+ {
3224
+ address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
3225
+ value: 2.0173228e10,
3226
+ valueString: '20173228000',
3227
+ },
3228
+ {
3229
+ address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
3230
+ value: 10000,
3231
+ valueString: '10000',
3232
+ },
3233
+ ],
3234
+ minerFee: '10000',
3235
+ outputs: [
3236
+ {
3237
+ address: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
3238
+ coinName: 'sol:wif',
3239
+ enterprise: {
3240
+ $oid: '5553ba8ae7a5c77006719661',
3241
+ },
3242
+ enterprises: [
3243
+ {
3244
+ $oid: '5553ba8ae7a5c77006719661',
3245
+ },
3246
+ ],
3247
+ value: 2.0173228e10,
3248
+ valueString: '20173228000',
3249
+ wallet: {
3250
+ $oid: '62f4c3720d92c50008257eb5',
3251
+ },
3252
+ walletType: 'hot',
3253
+ wallets: [
3254
+ {
3255
+ $oid: '62f4c3720d92c50008257eb5',
3256
+ },
3257
+ ],
3258
+ },
3259
+ ],
3260
+ payGoFee: '0',
3261
+ spendAmount: '20173228000',
3262
+ spendAmounts: [
3263
+ {
3264
+ amountString: '20173228000',
3265
+ coinName: 'sol:wif',
3266
+ },
3267
+ ],
3268
+ type: 'Send',
3269
+ },
3270
+ consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
3271
+ coin: 'tsol',
3272
+ };
3273
+ const mockedWallet = {
3274
+ coinSpecific: () => {
3275
+ const cs = {
3276
+ rootAddress: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
3277
+ };
3278
+ return cs;
3279
+ },
3280
+ };
3281
+ try {
3282
+ if (!(await basecoin.verifyTransaction({
3283
+ blockhash: '',
3284
+ feePayer: '',
3285
+ txParams: {},
3286
+ txPrebuild: consolidationTx,
3287
+ walletType: 'tss',
3288
+ wallet: mockedWallet,
3289
+ verification: {
3290
+ consolidationToBaseAddress: true,
3291
+ },
3292
+ }))) {
3293
+ assert_1.default.fail('Transaction should pass verification');
3294
+ }
3295
+ }
3296
+ catch (e) {
3297
+ assert_1.default.fail('Transaction should pass verification');
3298
+ }
3299
+ });
3300
+ it('should verify a spoofed token consolidation transaction', async () => {
3301
+ const consolidationTx = {
3302
+ txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
3303
+ walletId: '63068ed4efa63a000877f02fd4b0fa6d',
3304
+ txHex: '02b7c2c7829eded4e8f947c90ed3b9afce71f616eb47dfcfbf4b765778149060013acb33b9f67fdd9c2512f48fac4e4c049eab93829b69404f3bd166fe3242c90700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020104096da690bd558fd8634ac14f1645d8095afd0caea5953578c596e3c0dea38305ee7298bfac55101f177735659d42ed6be890ef3a1d204d9e33f32e24c5635327ca66d1fe00826e5a4f759f87b279c1aee19cce5301af4ed66ae17db48b201ed6c2a0e8a28bf565627f1ab8a34b1a95ee1b0a2a39084f1f0e2acb1c394b20185d8e0b22657c8d9c4ce5f6495efb6410c199011530f90e3ab9d8d1e4206f9ae0ffeb0000000000000000000000000000000000000000000000000000000000000000c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e406a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9de13c74d2b4d948e1608ea6eebdafe75bc2f995aad11b21d1e2c94f2a2d12f6802050303070004040000000804020604010a0ce0076bb20400000006',
3305
+ feeInfo: {
3306
+ fee: 10000,
3307
+ feeString: '10000',
3308
+ },
3309
+ txInfo: {
3310
+ inputs: [
3311
+ {
3312
+ address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
3313
+ value: 2.0173228e10,
3314
+ valueString: '20173228000',
3315
+ },
3316
+ {
3317
+ address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
3318
+ value: 10000,
3319
+ valueString: '10000',
3320
+ },
3321
+ ],
3322
+ minerFee: '10000',
3323
+ outputs: [
3324
+ {
3325
+ address: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
3326
+ coinName: 'sol:wif',
3327
+ enterprise: {
3328
+ $oid: '5553ba8ae7a5c77006719661',
3329
+ },
3330
+ enterprises: [
3331
+ {
3332
+ $oid: '5553ba8ae7a5c77006719661',
3333
+ },
3334
+ ],
3335
+ value: 2.0173228e10,
3336
+ valueString: '20173228000',
3337
+ wallet: {
3338
+ $oid: '62f4c3720d92c50008257eb5',
3339
+ },
3340
+ walletType: 'hot',
3341
+ wallets: [
3342
+ {
3343
+ $oid: '62f4c3720d92c50008257eb5',
3344
+ },
3345
+ ],
3346
+ },
3347
+ ],
3348
+ payGoFee: '0',
3349
+ spendAmount: '20173228000',
3350
+ spendAmounts: [
3351
+ {
3352
+ amountString: '20173228000',
3353
+ coinName: 'sol:wif',
3354
+ },
3355
+ ],
3356
+ type: 'Send',
3357
+ },
3358
+ consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
3359
+ coin: 'tsol',
3360
+ };
3361
+ const mockedWallet = {
3362
+ coinSpecific: () => {
3363
+ const cs = {
3364
+ rootAddress: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
3365
+ };
3366
+ return cs;
3367
+ },
3368
+ };
3369
+ await assert_1.default.rejects(async () => basecoin.verifyTransaction({
3370
+ blockhash: '',
3371
+ feePayer: '',
3372
+ txParams: {},
3373
+ txPrebuild: consolidationTx,
3374
+ walletType: 'tss',
3375
+ wallet: mockedWallet,
3376
+ verification: {
3377
+ consolidationToBaseAddress: true,
3378
+ },
3379
+ }), {
3380
+ message: 'tx outputs does not match with expected address',
3381
+ });
3382
+ });
3383
+ });
3384
+ describe('blind signing token enablement protection', () => {
3385
+ it('should verify as valid the enabletoken intent when prebuild tx matchs user intent ', async function () {
3386
+ const { txParams, txPrebuildRaw, walletData } = testData.enableTokenFixtures;
3387
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3388
+ const sameIntentTx = await basecoin.verifyTransaction({
3389
+ txParams,
3390
+ txPrebuild: txPrebuildRaw,
3391
+ wallet,
3392
+ verification: { verifyTokenEnablement: true },
3393
+ });
3394
+ sameIntentTx.should.equal(true);
3395
+ });
3396
+ it('should thrown an error when tampered prebuild tx type ', async function () {
3397
+ const { txParams, txPrebuildRaw, sendTxHex, walletData } = testData.enableTokenFixtures;
3398
+ const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: sendTxHex };
3399
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3400
+ await assert_1.default.rejects(async () => await basecoin.verifyTransaction({
3401
+ txParams,
3402
+ txPrebuild: tamperedTxPrebuild,
3403
+ wallet,
3404
+ verification: { verifyTokenEnablement: true },
3405
+ }), {
3406
+ message: 'Invalid transaction type on token enablement: expected "AssociatedTokenAccountInitialization", got "Send".',
3407
+ });
3408
+ });
3409
+ it('should verify that tokenName matches between user intent and hex', async function () {
3410
+ const { txParams, txPrebuildRaw, wrongTokenNameTxHex, walletData } = testData.enableTokenFixtures;
3411
+ const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: wrongTokenNameTxHex };
3412
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3413
+ await assert_1.default.rejects(async () => basecoin.verifyTransaction({
3414
+ txParams,
3415
+ txPrebuild: tamperedTxPrebuild,
3416
+ wallet,
3417
+ verification: { verifyTokenEnablement: true },
3418
+ }), { message: 'Invalid token name: expected tsol:ray, got tsol:t22mint on token enablement tx' });
3419
+ });
3420
+ it('should verify that tokenAddr matches between user intent and hex', async function () {
3421
+ const { txParams, txPrebuildRaw, wrongAddrTxHex, walletData } = testData.enableTokenFixtures;
3422
+ const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: wrongAddrTxHex };
3423
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3424
+ await assert_1.default.rejects(async () => basecoin.verifyTransaction({
3425
+ txParams,
3426
+ txPrebuild: tamperedTxPrebuild,
3427
+ wallet,
3428
+ verification: { verifyTokenEnablement: true },
3429
+ }), {
3430
+ message: 'Invalid token address: expected 4bTYvvv2Hk4v2kQW8HZFFS4SzYPztQshw9Gm1suXmaBj, got G1LEgANAwKo7b8NfxTsMzrbBYDkXqi5REVJY8thrMRQm on token enablement tx',
3431
+ });
3432
+ });
3433
+ it('should fail sendTokenEnablement call on spoofed data', async function () {
3434
+ const { sendTokenEnablementPayload, walletData, wrongTokenNameTxHex } = testData.enableTokenFixtures;
3435
+ const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
3436
+ (0, nock_1.default)('https://bitgo.fakeurl').get('/api/v2/tsol/key/68bafed588671cf94ed8a5dbba882ad3').reply(200, {});
3437
+ await assert_1.default.rejects(async () => wallet.sendTokenEnablement({
3438
+ verification: { verifyTokenEnablement: true },
3439
+ ...sendTokenEnablementPayload,
3440
+ prebuildTx: { ...sendTokenEnablementPayload.prebuildTx, txHex: wrongTokenNameTxHex },
3441
+ }), {
3442
+ message: 'Invalid token name: expected tsol:ray, got tsol:t22mint on token enablement tx',
3443
+ });
3444
+ });
3445
+ });
3446
+ describe('isWalletAddress', () => {
3447
+ it('should verify valid wallet address with correct keychain and index', async function () {
3448
+ const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
3449
+ const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
3450
+ const index = '1';
3451
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
3452
+ const result = await basecoin.isWalletAddress({ keychains, address, index });
3453
+ result.should.equal(true);
3454
+ });
3455
+ it('should throw error for address with incorrect keychain', async function () {
3456
+ const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
3457
+ const wrongKeychain = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
3458
+ const index = '1';
3459
+ const keychains = [{ id: '1', type: 'tss', commonKeychain: wrongKeychain }];
3460
+ await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address, index }), {
3461
+ message: `address validation failure: ${address} is not a wallet address`,
3462
+ });
3463
+ });
3464
+ it('should throw error for address with incorrect index', async function () {
3465
+ const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
3466
+ const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
3467
+ const wrongIndex = '999';
3468
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
3469
+ await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address, index: wrongIndex }), {
3470
+ message: `address validation failure: ${address} is not a wallet address`,
3471
+ });
3472
+ });
3473
+ it('should throw error for invalid address', async function () {
3474
+ const invalidAddress = 'invalidaddress';
3475
+ const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
3476
+ const index = '1';
3477
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
3478
+ await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address: invalidAddress, index }), {
3479
+ message: `invalid address: ${invalidAddress}`,
3480
+ });
3481
+ });
3482
+ it('should verify address with derivation prefix for SMC wallets', async function () {
3483
+ // Address derived with derivation prefix m/999999/148242355/239336845/1
3484
+ const address = 'CC715Q92C8vuEFT5xujE55Do6BkWRdpDvr7Vh8iUNUBw';
3485
+ const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
3486
+ const index = '1';
3487
+ const derivedFromParentWithSeed = 'smc-test-seed-123';
3488
+ const keychains = [{ id: '1', type: 'tss', commonKeychain }];
3489
+ // This test verifies that derivedFromParentWithSeed is accepted as a parameter
3490
+ // and the verification function correctly computes the derivation prefix internally
3491
+ const result = await basecoin.isWalletAddress({ keychains, address, index, derivedFromParentWithSeed });
3492
+ result.should.equal(true);
3493
+ });
3494
+ });
3495
+ describe('getAddressFromPublicKey', () => {
3496
+ it('should convert public key to base58 address', function () {
3497
+ const publicKey = '61220a9394802b1d1df37b35f7a3197970f48081092cee011fc98f7b71b2bd43';
3498
+ const expectedAddress = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
3499
+ const address = basecoin.getAddressFromPublicKey(publicKey);
3500
+ address.should.equal(expectedAddress);
3501
+ });
3502
+ });
3503
+ });
3504
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3NvbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QiwwQ0FBNEI7QUFDNUIsZ0RBQXdCO0FBQ3hCLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFFL0IsaURBQTBEO0FBRTFELGlEQUF3RDtBQUN4RCxtREFjOEI7QUFDOUIsbURBQStEO0FBQy9ELGlEQUE0QztBQUM1QyxtQ0FBd0c7QUFDeEcsdUNBQTRDO0FBRTVDLCtDQUF1RTtBQUN2RSwwREFBNEM7QUFDNUMsNERBQThDO0FBQzlDLDBEQUF1RDtBQUN2RCwyREFBd0Q7QUFFeEQsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQWEsQ0FBQztJQUNsQixJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksYUFBYSxDQUFDO0lBQ2xCLElBQUksMEJBQTBCLENBQUM7SUFDL0IsSUFBSSxXQUFXLENBQUM7SUFDaEIsSUFBSSxvQkFBb0IsQ0FBQztJQUN6QixJQUFJLHdCQUF3QixDQUFDO0lBQzdCLElBQUksd0JBQXdCLENBQUM7SUFDN0IsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztJQUMxRCxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQztJQUV6RCxNQUFNLE9BQU8sR0FBRztRQUNkLEdBQUcsRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLFNBQVM7UUFDeEMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLE1BQU07S0FDakQsQ0FBQztJQUNGLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLFVBQVUsRUFBRTtZQUNWO2dCQUNFLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixNQUFNLEVBQUUsTUFB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QUV2RSxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDNUQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IHsgVE9LRU5fMjAyMl9QUk9HUkFNX0lEIH0gZnJvbSAnQHNvbGFuYS9zcGwtdG9rZW4nO1xuXG5pbXBvcnQgeyBCaXRHb0FQSSwgZW5jcnlwdCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1hcGknO1xuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBFbnZpcm9ubWVudHMsXG4gIGdlbmVyYXRlUmFuZG9tUGFzc3dvcmQsXG4gIElXYWxsZXQsXG4gIE1QQ1N3ZWVwVHhzLFxuICBNUENUeCxcbiAgTVBDVHhzLFxuICBQcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uUHJlYnVpbGQsXG4gIFRzc1V0aWxzLFxuICBUeFJlcXVlc3QsXG4gIFdhbGxldCxcbiAgV2FsbGV0Q29pblNwZWNpZmljLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcbmltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcywgS2V5UGFpciwgU29sLCBTb2xWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsIFRzb2wgfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IEF0YUluaXQsIEluc3RydWN0aW9uUGFyYW1zLCBUb2tlblRyYW5zZmVyIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi9pZmFjZSc7XG5pbXBvcnQgeyBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyB9IGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vZml4dHVyZXMvc29sJztcbmltcG9ydCAqIGFzIHJlc291cmNlcyBmcm9tICcuLi9yZXNvdXJjZXMvc29sJztcbmltcG9ydCB7IHNvbEJhY2t1cEtleSB9IGZyb20gJy4vZml4dHVyZXMvc29sQmFja3VwS2V5JztcbmltcG9ydCB7IGdldEJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi9nZXRCdWlsZGVyRmFjdG9yeSc7XG5cbmRlc2NyaWJlKCdTT0w6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luOiBTb2w7XG4gIGxldCBrZXlQYWlyO1xuICBsZXQgbmV3VHhQcmVidWlsZDtcbiAgbGV0IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyO1xuICBsZXQgbmV3VHhQYXJhbXM7XG4gIGxldCBuZXdUeFBhcmFtc1dpdGhFcnJvcjtcbiAgbGV0IG5ld1R4UGFyYW1zV2l0aEV4dHJhRGF0YTtcbiAgbGV0IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcjtcbiAgY29uc3QgYmFkQWRkcmVzc2VzID0gcmVzb3VyY2VzLmFkZHJlc3Nlcy5pbnZhbGlkQWRkcmVzc2VzO1xuICBjb25zdCBnb29kQWRkcmVzc2VzID0gcmVzb3VyY2VzLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3NlcztcblxuICBjb25zdCBrZXlwYWlyID0ge1xuICAgIHB1YjogcmVzb3VyY2VzLmFjY291bnRXaXRoU2VlZC5wdWJsaWNLZXksXG4gICAgcHJ2OiByZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnByaXZhdGVLZXkuYmFzZTU4LFxuICB9O1xuICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ2xpb250ZXN0ZTIxMicsXG4gICAgICAgIGFtb3VudDogJzEwMDAnLFxuICAgICAgfSxcbiAgICBdLFxuICAgIHR4QmFzZTY0OiByZXNvdXJjZXMuVFJBTlNGRVJfVU5TSUdORURfVFhfV0lUSF9NRU1PX0FORF9EVVJBQkxFX05PTkNFLFxuICAgIHR4SW5mbzoge1xuICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICBub25jZTogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICB9LFxuICAgIHR4aWQ6ICc1ODZjNWI1OWIxMGIxMzRkMDRjMTZhYzFiMjczZmUzYzU1MjlmMzRhZWY3NWRiNDQ1NmNkNDY5YzVjZGFjN2UyJyxcbiAgICBpc1ZvdGluZ1RyYW5zYWN0aW9uOiBmYWxzZSxcbiAgICBjb2luOiAndHNvbCcsXG4gIH07XG4gIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgIHR4UHJlYnVpbGQsXG4gICAgcmVjaXBpZW50czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuICBjb25zdCBtZW1vID0geyB2YWx1ZTogJ3Rlc3QgbWVtbycgfTtcbiAgY29uc3QgZHVyYWJsZU5vbmNlID0ge1xuICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgfTtcbiAgY29uc3QgZXJyb3JEdXJhYmxlTm9uY2UgPSB7XG4gICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFlNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgfTtcbiAgY29uc3QgdHhQYXJhbXNXaXRoRXJyb3IgPSB7XG4gICAgdHhQcmVidWlsZCxcbiAgICByZWNpcGllbnRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJtTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIGNvbnN0IHR4UGFyYW1zV2l0aEV4dHJhRGF0YSA9IHtcbiAgICB0eFByZWJ1aWxkLFxuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgZGF0YTogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuICBjb25zdCB0eFByZWJ1aWxkVG9rZW5UcmFuc2ZlciA9IHtcbiAgICByZWNpcGllbnRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12ZycsXG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgfSxcbiAgICBdLFxuICAgIHR4SGV4OiByZXNvdXJjZXMuVE9LRU5fVFJBTlNGRVJfVE9fTkFUSVZFX1VOU0lHTkVEX1RYX0hFWCxcbiAgICB0eEluZm86IHtcbiAgICAgIGZlZVBheWVyOiAnNER1anltVUZiUThHQkt0QXdBWnJRNlFxcHZ0QkVpdkw0OGg0dGEyb0pHZDInLFxuICAgICAgbm9uY2U6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgfSxcbiAgICB0eGlkOiAnNTg2YzViNTliMTBiMTM0ZDA0YzE2YWMxYjI3M2ZlM2M1NTI5ZjM0YWVmNzVkYjQ0NTZjZDQ2OWM1Y2RhYzdlMicsXG4gICAgaXNWb3RpbmdUcmFuc2FjdGlvbjogZmFsc2UsXG4gICAgY29pbjogJ3Rzb2wnLFxuICB9O1xuICBjb25zdCB0eFBhcmFtc1Rva2VuVHJhbnNmZXIgPSB7XG4gICAgdHhQcmVidWlsZCxcbiAgICByZWNpcGllbnRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12ZycsXG4gICAgICAgIGFtb3VudDogJzEnLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuICBjb25zdCBlcnJvck1lbW8gPSB7IHZhbHVlOiAnZGlmZmVyZW50IG1lbW8nIH07XG4gIGNvbnN0IGVycm9yRmVlUGF5ZXIgPSAnNWhyNWZpc1BpNkRYQ3V1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnO1xuICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoJ3Rzb2wnKTtcbiAgY29uc3Qgd2FsbGV0ID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLmF1dGhBY2NvdW50KS5nZXRLZXlzKCk7XG4gIGNvbnN0IHN0YWtlQWNjb3VudCA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5zdGFrZUFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3QgYmxvY2tIYXNoID0gcmVzb3VyY2VzLmJsb2NrSGFzaGVzLnZhbGlkQmxvY2tIYXNoZXNbMF07XG4gIGNvbnN0IGFtb3VudCA9ICcxMDAwMCc7XG4gIGNvbnN0IHZhbGlkYXRvciA9IHJlc291cmNlcy52YWxpZGF0b3I7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3NvbCcsIFRzb2wuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndHNvbCcsIFRzb2wuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndHNvbCcpIGFzIFRzb2w7XG4gICAga2V5UGFpciA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcihyZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnNlZWQpO1xuICAgIG5ld1R4UHJlYnVpbGQgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gXy5jbG9uZURlZXAodHhQcmVidWlsZCk7XG4gICAgfTtcbiAgICBuZXdUeFByZWJ1aWxkVG9rZW5UcmFuc2ZlciA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFByZWJ1aWxkVG9rZW5UcmFuc2Zlcik7XG4gICAgfTtcbiAgICBuZXdUeFBhcmFtcyA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFBhcmFtcyk7XG4gICAgfTtcbiAgICBuZXdUeFBhcmFtc1dpdGhFcnJvciA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFBhcmFtc1dpdGhFcnJvcik7XG4gICAgfTtcbiAgICBuZXdUeFBhcmFtc1dpdGhFeHRyYURhdGEgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gXy5jbG9uZURlZXAodHhQYXJhbXNXaXRoRXh0cmFEYXRhKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlciA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFBhcmFtc1Rva2VuVHJhbnNmZXIpO1xuICAgIH07XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgaW5zdGFudGlhdGUgdGhlIGNvaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGxvY2FsQmFzZWNvaW4gPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihUc29sKTtcblxuICAgIGxvY2FsQmFzZWNvaW4gPSBiaXRnby5jb2luKCdzb2wnKTtcbiAgICBsb2NhbEJhc2Vjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKFNvbCk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmV0dW4gdGhlIHJpZ2h0IGluZm8nLCBmdW5jdGlvbiAoKSB7XG4gICAgYmFzZWNvaW4uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoJ3Rzb2wnKTtcbiAgICBiYXNlY29pbi5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ3NvbCcpO1xuICAgIGJhc2Vjb2luLmdldEZ1bGxOYW1lKCkuc2hvdWxkLmVxdWFsKCdUZXN0bmV0IFNvbGFuYScpO1xuICAgIGJhc2Vjb2luLmdldEJhc2VGYWN0b3IoKS5zaG91bGQuZXF1YWwoMTAwMDAwMDAwMCk7XG4gIH0pO1xuICBkZXNjcmliZSgndmVyaWZ5IHRyYW5zYWN0aW9ucycsICgpID0+IHtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICBdLFxuICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgIHJvb3RBZGRyZXNzOiB3YWxsZXQucHViLFxuICAgICAgfSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgfTtcbiAgICBjb25zdCB3YWxsZXRPYmogPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGNvbnNvbGlkYXRlIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQuY29uc29saWRhdGVJZCA9ICdjb25zb2xpZGF0ZUlkJztcblxuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogc3Rha2VBY2NvdW50LnB1YixcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRXaXRoRGlmZmVyZW50QWRkcmVzcyA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRXaXRoRGlmZmVyZW50QWRkcmVzcyxcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHR4QmFzZTY0IGFuZCB0eEhleCBpbnRlcmNoYW5nZWFibHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC50eEhleCA9IHR4UHJlYnVpbGQudHhCYXNlNjQ7XG4gICAgICB0eFByZWJ1aWxkLnR4QmFzZTY0ID0gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29udmVydCBzZXJpYWxpemVkIGhleCBzdHJpbmcgdG8gYmFzZTY0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQudHhCYXNlNjQgPSBCdWZmZXIuZnJvbSh0eFByZWJ1aWxkLnR4QmFzZTY0LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHdoZW4gaW5wdXQgYHJlY2lwaWVudHNgIGlzIGFic2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJ1bGsgY2xvc2UtQVRBIHR4IHdoZW4gdHhQYXJhbXMucmVjaXBpZW50cyBpcyBwcmVzZW50IChvdXRwdXRzIG5vdCBwb3B1bGF0ZWQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEtleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMuYXV0aEFjY291bnQpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG5vbmNlQWNjb3VudEtleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMubm9uY2VBY2NvdW50KS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBhY2NvdW50MktleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMuYXV0aEFjY291bnQyKS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBhdGFBZGRyZXNzMSA9IG5vbmNlQWNjb3VudEtleXMucHViO1xuICAgICAgY29uc3QgYXRhQWRkcmVzczIgPSBhY2NvdW50MktleXMucHViO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldENsb3NlQXRhSW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIubm9uY2UoYmxvY2tIYXNoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIoYWNjb3VudEtleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5hZGRDbG9zZUF0YUluc3RydWN0aW9uKGF0YUFkZHJlc3MxLCBhY2NvdW50S2V5cy5wdWIsIGFjY291bnRLZXlzLnB1Yik7XG4gICAgICB0eEJ1aWxkZXIuYWRkQ2xvc2VBdGFJbnN0cnVjdGlvbihhdGFBZGRyZXNzMiwgYWNjb3VudEtleXMucHViLCBhY2NvdW50S2V5cy5wdWIpO1xuICAgICAgY29uc3QgYnVpbHQgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4QmFzZTY0OiBidWlsdC50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBmZWVQYXllcjogYWNjb3VudEtleXMucHViLFxuICAgICAgICAgIG5vbmNlOiBibG9ja0hhc2gsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgeyBhZGRyZXNzOiBhdGFBZGRyZXNzMSwgYW1vdW50OiAnMCcgfSxcbiAgICAgICAgICAgIHsgYWRkcmVzczogYXRhQWRkcmVzczIsIGFtb3VudDogJzAnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgYnVsayBjbG9zZS1BVEEgd2hlbiB0eFBhcmFtcy5yZWNpcGllbnRzIGRvIG5vdCBtYXRjaCBjbG9zZSBpbnN0cnVjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY2NvdW50S2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5hdXRoQWNjb3VudCkuZ2V0S2V5cygpO1xuICAgICAgY29uc3Qgbm9uY2VBY2NvdW50S2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5ub25jZUFjY291bnQpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IGFjY291bnQyS2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5hdXRoQWNjb3VudDIpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IHdyb25nQXRhID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLnN0YWtlQWNjb3VudCkuZ2V0S2V5cygpLnB1YjtcbiAgICAgIGNvbnN0IGF0YUFkZHJlc3MxID0gbm9uY2VBY2NvdW50S2V5cy5wdWI7XG4gICAgICBjb25zdCBhdGFBZGRyZXNzMiA9IGFjY291bnQyS2V5cy5wdWI7XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0Q2xvc2VBdGFJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5ub25jZShibG9ja0hhc2gpO1xuICAgICAgdHhCdWlsZGVyLnNlbmRlcihhY2NvdW50S2V5cy5wdWIpO1xuICAgICAgdHhCdWlsZGVyLmFkZENsb3NlQXRhSW5zdHJ1Y3Rpb24oYXRhQWRkcmVzczEsIGFjY291bnRLZXlzLnB1YiwgYWNjb3VudEtleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5hZGRDbG9zZUF0YUluc3RydWN0aW9uKGF0YUFkZHJlc3MyLCBhY2NvdW50S2V5cy5wdWIsIGFjY291bnRLZXlzLnB1Yik7XG4gICAgICBjb25zdCBidWlsdCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhCYXNlNjQ6IGJ1aWx0LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgIGZlZVBheWVyOiBhY2NvdW50S2V5cy5wdWIsXG4gICAgICAgICAgbm9uY2U6IGJsb2NrSGFzaCxcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgICB7IGFkZHJlc3M6IGF0YUFkZHJlc3MxLCBhbW91bnQ6ICcwJyB9LFxuICAgICAgICAgICAgICB7IGFkZHJlc3M6IHdyb25nQXRhLCBhbW91bnQ6ICcwJyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnQ2xvc2UgQVRBIHR4UGFyYW1zLnJlY2lwaWVudHMgYWRkcmVzc2VzIG11c3QgbWF0Y2ggdGhlIEFUQSBhY2NvdW50IGFkZHJlc3NlcyBpbiB0aGUgdHJhbnNhY3Rpb24gaW5zdHJ1Y3Rpb25zJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHZlcmlmeSBidWxrIGNsb3NlLUFUQSB3aGVuIGEgcmVjaXBpZW50IGFtb3VudCBpcyBub24temVybycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFjY291bnRLZXlzID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLmF1dGhBY2NvdW50KS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBub25jZUFjY291bnRLZXlzID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLm5vbmNlQWNjb3VudCkuZ2V0S2V5cygpO1xuICAgICAgY29uc3QgYWNjb3VudDJLZXlzID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLmF1dGhBY2NvdW50MikuZ2V0S2V5cygpO1xuICAgICAgY29uc3QgYXRhQWRkcmVzczEgPSBub25jZUFjY291bnRLZXlzLnB1YjtcbiAgICAgIGNvbnN0IGF0YUFkZHJlc3MyID0gYWNjb3VudDJLZXlzLnB1YjtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRDbG9zZUF0YUluaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLm5vbmNlKGJsb2NrSGFzaCk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKGFjY291bnRLZXlzLnB1Yik7XG4gICAgICB0eEJ1aWxkZXIuYWRkQ2xvc2VBdGFJbnN0cnVjdGlvbihhdGFBZGRyZXNzMSwgYWNjb3VudEtleXMucHViLCBhY2NvdW50S2V5cy5wdWIpO1xuICAgICAgdHhCdWlsZGVyLmFkZENsb3NlQXRhSW5zdHJ1Y3Rpb24oYXRhQWRkcmVzczIsIGFjY291bnRLZXlzLnB1YiwgYWNjb3VudEtleXMucHViKTtcbiAgICAgIGNvbnN0IGJ1aWx0ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEJhc2U2NDogYnVpbHQudG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgZmVlUGF5ZXI6IGFjY291bnRLZXlzLnB1YixcbiAgICAgICAgICBub25jZTogYmxvY2tIYXNoLFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICAgIHsgYWRkcmVzczogYXRhQWRkcmVzczEsIGFtb3VudDogJzEnIH0sXG4gICAgICAgICAgICAgIHsgYWRkcmVzczogYXRhQWRkcmVzczIsIGFtb3VudDogJzAnIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdDbG9zZSBBVEEgcmVjaXBpZW50cyBtdXN0IGhhdmUgemVybyBhbW91bnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHJlY292ZXItbmVzdGVkIHR4IHdoZW4gd2FsbGV0QWRkcmVzcyBtYXRjaGVzIHJvb3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhY2NvdW50S2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5hdXRoQWNjb3VudCkuZ2V0S2V5cygpO1xuICAgICAgY29uc3Qgbm9uY2VBY2NvdW50S2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5ub25jZUFjY291bnQpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IGFjY291bnQyS2V5cyA9IG5ldyBLZXlQYWlyKHJlc291cmNlcy5hdXRoQWNjb3VudDIpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG1pbnQgPSAnRVBqRldkZDVBdWZxU1NxZU0ycU4xeHp5YmFwQzhHNHdFR0drWnd5VER0MXYnO1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFJlY292ZXJOZXN0ZWRBdGFCdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIubm9uY2UoYmxvY2tIYXNoKTtcbiAgICAgIHR4QnVpbGRlci5zZW5kZXIoYWNjb3VudEtleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5mZWVQYXllcihhY2NvdW50S2V5cy5wdWIpO1xuICAgICAgdHhCdWlsZGVyLmFzc29jaWF0ZWRUb2tlbkFjY291bnRSZW50KCcyMDM5MjgwJyk7XG4gICAgICB0eEJ1aWxkZXIubmVzdGVkQWNjb3VudEFkZHJlc3Mobm9uY2VBY2NvdW50S2V5cy5wdWIpO1xuICAgICAgdHhCdWlsZGVyLm5lc3RlZE1pbnRBZGRyZXNzKG1pbnQpO1xuICAgICAgdHhCdWlsZGVyLmRlc3RpbmF0aW9uQWNjb3VudEFkZHJlc3MoYWNjb3VudDJLZXlzLnB1Yik7XG4gICAgICB0eEJ1aWxkZXIub3duZXJBY2NvdW50QWRkcmVzcyhhY2NvdW50MktleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5vd25lck1pbnRBZGRyZXNzKG1pbnQpO1xuICAgICAgdHhCdWlsZGVyLndhbGxldEFkZHJlc3MoYWNjb3VudEtleXMucHViKTtcblxuICAgICAgY29uc3QgYnVpbHQgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4QmFzZTY0OiBidWlsdC50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBmZWVQYXllcjogYWNjb3VudEtleXMucHViLFxuICAgICAgICAgIG5vbmNlOiBibG9ja0hhc2gsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgcmVjb3Zlci1uZXN0ZWQgdHggd2hlbiB3YWxsZXQgcm9vdCBkb2VzIG5vdCBtYXRjaCBpbnN0cnVjdGlvbiB3YWxsZXRBZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWNjb3VudEtleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMuYXV0aEFjY291bnQpLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG5vbmNlQWNjb3VudEtleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMubm9uY2VBY2NvdW50KS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBhY2NvdW50MktleXMgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMuYXV0aEFjY291bnQyKS5nZXRLZXlzKCk7XG4gICAgICBjb25zdCBtaW50ID0gJ0VQakZXZGQ1QXVmcVNTcWVNMnFOMXh6eWJhcEM4RzR3RUdHa1p3eVREdDF2JztcblxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRSZWNvdmVyTmVzdGVkQXRhQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLm5vbmNlKGJsb2NrSGFzaCk7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKGFjY291bnRLZXlzLnB1Yik7XG4gICAgICB0eEJ1aWxkZXIuZmVlUGF5ZXIoYWNjb3VudEtleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5hc3NvY2lhdGVkVG9rZW5BY2NvdW50UmVudCgnMjAzOTI4MCcpO1xuICAgICAgdHhCdWlsZGVyLm5lc3RlZEFjY291bnRBZGRyZXNzKG5vbmNlQWNjb3VudEtleXMucHViKTtcbiAgICAgIHR4QnVpbGRlci5uZXN0ZWRNaW50QWRkcmVzcyhtaW50KTtcbiAgICAgIHR4QnVpbGRlci5kZXN0aW5hdGlvbkFjY291bnRBZGRyZXNzKGFjY291bnQyS2V5cy5wdWIpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyQWNjb3VudEFkZHJlc3MoYWNjb3VudDJLZXlzLnB1Yik7XG4gICAgICB0eEJ1aWxkZXIub3duZXJNaW50QWRkcmVzcyhtaW50KTtcbiAgICAgIHR4QnVpbGRlci53YWxsZXRBZGRyZXNzKGFjY291bnRLZXlzLnB1Yik7XG5cbiAgICAgIGNvbnN0IGJ1aWx0ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEJhc2U2NDogYnVpbHQudG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgZmVlUGF5ZXI6IGFjY291bnRLZXlzLnB1YixcbiAgICAgICAgICBub25jZTogYmxvY2tIYXNoLFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXREYXRhV3JvbmdSb290ID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHdyb25nUm9vdFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhV3JvbmdSb290KTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB3YWxsZXQ6IHdyb25nUm9vdFdhbGxldCxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKC9SZWNvdmVyIG5lc3RlZCB3YWxsZXQgYWRkcmVzcyBtdXN0IGJlIHdhbGxldCByb290IGFkZHJlc3MvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gaGF2ZSBkaWZmZXJlbnQgbWVtbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgbWVtbzogZXJyb3JNZW1vLCB3YWxsZXQ6IHdhbGxldE9iaiB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IG1lbW8gZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnQgbWVtbycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIGlmIHdlIHBhc3MgUERBIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzY3ZjhkZGZmNGM5YjhiNTdhMmUxNmFjZmZhYzlhM2I1JyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiAnOHpic0pBNWM4SFBSN0JQalprclNWcnVzMnVNdVhxQ2Z6a3NHd0IzVXNjamInLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHdhbGxldE9iaiA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTInLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHR4QmFzZTY0OlxuICAgICAgICAgICcwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNmVjMWFkY2M4OWJiNTY0ZjFmODIyNTgyMTE0MGE5NzIzZWZhODBlOGQ1MDY3NjU3NzBiN2UyMDFkNjZkODIwMGQ0ZjY5MGU5YTgxNjMyOTFiNjlmOGMzODI3YWFkOTZjZmQyMTA1ZWVlM2FhZTc2Y2JjYTM4ZmNhZDJiZjdmMGEwMjAxMDcwYzc2YzM1NmNiMDY5YjY2YzJiMzVhODYzOGI0ZDRhZmNhNzViMzAzZjI5ZjBkZWViNGJmZjg1MjgyOTlhOWM5ZDIxYzk2MTcyMDQ0ZjEyMTdjMzc4NGU4ZjAyZjQ5ZTJjOGZjMzU5MWU4MTI5NGFiNTQzOTRmOWQyMmZkN2I3YThmNjAxMjllNmVjYjIwMzA5YzI3ZGNiYTVmYzZjNDQxNDM4ZDMzYTE1NjgwMDRhMTg2MGUyMmMxNmYwNzE5NzZhN2QyZTIwMDhiZDM0YjUzYTA4YWE5YzhlYzA0ZWIyMTk2NzQ1ZmM2MDI5MjI0NDQ3NDE3ZTJmYjBmY2VkNjAxMjQwY2FiYmE0Y2U1MzRjMDJmYzE1NGJhNTU5ZWQyYTAyYWM5NzFlMzM4NWFjYjQyNmZmNjNiYjEwNDBlMmMyNDM1MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE4Yzk3MjU4ZjRlMjQ4OWYxYmIzZDEwMjkxNDhlMGQ4MzBiNWExMzk5ZGFmZjEwODQwNDhlN2JkOGRiZTlmODU5ZDEwMzg5ZmJjZWU1MjhmMjA4NjExZGNjYzczNGIzMTA5MjU0MGNiMmI4ZDU4ZDEwMGYyZWFhMmNlZGI0ZGE1ZTA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDAwNmE3ZDUxNzE5MmM1YzUxMjE4Y2M5NGMzZDRhZjE3ZjU4ZGFlZTA4OWJhMWZkNDRlM2RiZDk4YTAwMDAwMDAwMDZkZGY2ZTFkNzY1YTE5M2Q5Y2JlMTQ2Y2VlYjc5YWMxY2I0ODVlZDVmNWIzNzkxM2E4Y2Y1ODU3ZWZmMDBhOWU2ODA2MzQ1MzM4ODJmODgwYTNlN2RmYTk5OWRmYjg2NGI4ODk2OGQyNDJhMGM5YTkwYjVkZjE0OWU0MmRhMDUwMzA1MDMwMjA5MDEwNDA0MDAwMDAwMDcwNzAwMDMwNjA4MDUwYjBhMDAwYjA0MDQwODAzMDAwYTBjMDBjYTlhM2IwMDAwMDAwMDA5JyxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgZmVlUGF5ZXI6ICc4emJzSkE1YzhIUFI3QlBqWmtyU1ZydXMydU11WHFDZnprc0d3QjNVc2NqYicsXG4gICAgICAgICAgbm9uY2U6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIH0sXG4gICAgICAgIHR4aWQ6ICc1ODZjNWI1OWIxMGIxMzRkMDRjMTZhYzFiMjczZmUzYzU1MjlmMzRhZWY3NWRiNDQ1NmNkNDY5YzVjZGFjN2UyJyxcbiAgICAgICAgaXNWb3RpbmdUcmFuc2FjdGlvbjogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMicsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCBtZW1vID0ge1xuICAgICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZlcmlmeVRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbzogbWVtbyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2ZXJpZnlUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IHRyYW5zYWN0aW9ucyB3aGVuIGhhdmUgZGlmZmVyZW50IGR1cmFibGVOb25jZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgbWVtbywgZHVyYWJsZU5vbmNlOiBlcnJvckR1cmFibGVOb25jZSwgd2FsbGV0OiB3YWxsZXRPYmogfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdUeCBkdXJhYmxlTm9uY2UgZG9lcyBub3QgbWF0Y2ggd2l0aCBwYXJhbSBkdXJhYmxlTm9uY2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gaGF2ZSBkaWZmZXJlbnQgZmVlUGF5ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogc3Rha2VBY2NvdW50LnB1YixcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRXaXRoRGlmZmVyZW50QWRkcmVzcyA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIG1lbW8sIHdhbGxldDogd2FsbGV0V2l0aERpZmZlcmVudEFkZHJlc3MgfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdUeCBmZWUgcGF5ZXIgaXMgbm90IHRoZSB3YWxsZXQgcm9vdCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IHRyYW5zYWN0aW9ucyB3aGVuIGhhdmUgZGlmZmVyZW50IHJlY2lwaWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zV2l0aEVycm9yKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIG1lbW8sIGVycm9yRmVlUGF5ZXIsIHdhbGxldDogd2FsbGV0T2JqIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBuYXRpdmUgYWRkcmVzcyByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12Zyc7IC8vIE5hdGl2ZSBTT0wgYWRkcmVzc1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFt7IGFkZHJlc3MsIGFtb3VudDogJzEnLCB0b2tlbk5hbWU6ICd0c29sOnVzZGMnIH1dO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyKCk7XG4gICAgICBjb25zdCBmZWVQYXllcldhbGxldERhdGEgPSB7XG4gICAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAnLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgICAgXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICc0RHVqeW1VRmJROEdCS3RBd0FaclE2UXFwdnRCRWl2TDQ4aDR0YTJvSkdkMicsXG4gICAgICAgIH0sXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICB9O1xuICAgICAgY29uc3QgZmVlUGF5ZXJXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgZmVlUGF5ZXJXYWxsZXREYXRhKTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB3YWxsZXQ6IGZlZVBheWVyV2FsbGV0LFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRva2VuIHRyYW5zYWN0aW9uIHdpdGggbGVhZGluZyB6ZXJvIHJlY2lwaWVudCBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12Zyc7IC8vIE5hdGl2ZSBTT0wgYWRkcmVzc1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFt7IGFkZHJlc3MsIGFtb3VudDogJzAwMDEnLCB0b2tlbk5hbWU6ICd0c29sOnVzZGMnIH1dO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyKCk7XG4gICAgICBjb25zdCBmZWVQYXllcldhbGxldERhdGEgPSB7XG4gICAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAnLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgICAgXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICc0RHVqeW1VRmJROEdCS3RBd0FaclE2UXFwdnRCRWl2TDQ4aDR0YTJvSkdkMicsXG4gICAgICAgIH0sXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICB9O1xuICAgICAgY29uc3QgZmVlUGF5ZXJXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgZmVlUGF5ZXJXYWxsZXREYXRhKTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICB3YWxsZXQ6IGZlZVBheWVyV2FsbGV0LFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IHRva2VuIHRyYW5zYWN0aW9uIHdpdGggZGlmZmVyZW50IHJlY2lwaWVudCB0b2tlbk5hbWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12Zyc7IC8vIE5hdGl2ZSBTT0wgYWRkcmVzc1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFt7IGFkZHJlc3MsIGFtb3VudDogJzEnLCB0b2tlbk5hbWU6ICd0c29sOnVzZHQnIH1dOyAvLyBEaWZmZXJlbnQgdG9rZW5OYW1lLCBzaG91bGQgZmFpbCB0byB2ZXJpZnkgdHhcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IHRva2VuIHRyYW5zYWN0aW9uIHdpdGggZGlmZmVyZW50IHJlY2lwaWVudCBhbW91bnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtc1Rva2VuVHJhbnNmZXIoKTtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnQUY1SDZ2QmtGbkp1VnFDaFJQZ1BRNEpSY1E1R2syNUhCRmhRUWt5b2ptdmcnOyAvLyBOYXRpdmUgU09MIGFkZHJlc3NcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSBbeyBhZGRyZXNzLCBhbW91bnQ6ICcyJywgdG9rZW5OYW1lOiAndHNvbDp1c2R0JyB9XTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IHRva2VuIHRyYW5zYWN0aW9uIHdpdGggZGlmZmVyZW50IG5hdGl2ZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtc1Rva2VuVHJhbnNmZXIoKTtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnQUY1SDZ2QmtGbkp1VnFDaFJQZ1BRNEpSY1E1R2syNUhCRmhRUWt5b2ptdlgnOyAvLyBOYXRpdmUgU09MIGFkZHJlc3MsIGRpZmZlcmVudCB0aGFuIHR4IHJlY2lwaWVudHNcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSBbeyBhZGRyZXNzLCBhbW91bnQ6ICcxJywgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyB9XTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9ucyB3aGVuIHJlY2lwaWVudHMgaGFzIGV4dHJhIGRhdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zV2l0aEV4dHJhRGF0YSgpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBtZW1vLFxuICAgICAgICBkdXJhYmxlTm9uY2UsXG4gICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhY3RpdmF0ZSBzdGFraW5nIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRTdGFraW5nQWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC52YWxpZGF0b3IodmFsaWRhdG9yLnB1YilcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICB0eFByZWJ1aWxkLnR4QmFzZTY0ID0gdHhUb0Jyb2FkY2FzdEZvcm1hdDtcbiAgICAgIHR4UHJlYnVpbGQudHhJbmZvLm5vbmNlID0gJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJztcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnN2RSdUdGYlUyeTJraWpQNm8xTFlOelZ5ejR5ZjEzTW9vcW9pb25DenY1WmEnLFxuICAgICAgICAgIGFtb3VudDogYW1vdW50LFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBtZW1vLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgd2l0aGRyYXcgc3Rha2luZyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ1dpdGhkcmF3QnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAubWVtbygndGVzdCBtZW1vJylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4VG9Ccm9hZGNhc3RGb3JtYXQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQudHhCYXNlNjQgPSB0eFRvQnJvYWRjYXN0Rm9ybWF0O1xuICAgICAgdHhQcmVidWlsZC50eEluZm8ubm9uY2UgPSAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nO1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgYW1vdW50OiBhbW91bnQsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBkZWFjdGl2YXRlIHN0YWtpbmcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC50eEJhc2U2NCA9IHR4VG9Ccm9hZGNhc3RGb3JtYXQ7XG4gICAgICB0eFByZWJ1aWxkLnR4SW5mby5ub25jZSA9ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbic7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gW107XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGNyZWF0ZSBhc3NvY2lhdGVkIHRva2VuIGFjY291bnQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldEF0YUluaXRpYWxpemF0aW9uQnVpbGRlcigpXG4gICAgICAgIC5taW50KCd0c29sOnVzZGMnKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC50eEJhc2U2NCA9IHR4VG9Ccm9hZGNhc3RGb3JtYXQ7XG4gICAgICB0eFByZWJ1aWxkLnR4SW5mby5ub25jZSA9IGJsb2NrSGFzaDtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSBbXTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBtZW1vLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0QW1vdW50QmFzZWRPbkVuZGlhbm5lc3MnLCAoKSA9PiB7XG4gICAgbGV0IG9yaWdpbmFsQXJjaDogc3RyaW5nO1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBvcmlnaW5hbEFyY2ggPSBwcm9jZXNzLmFyY2g7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb2Nlc3MsICdhcmNoJywge1xuICAgICAgICB2YWx1ZTogb3JpZ2luYWxBcmNoLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbW91bnQgdW5jaGFuZ2VkIG9uIG5vbi1zMzkweCBhcmNoaXRlY3R1cmVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb2Nlc3MsICdhcmNoJywge1xuICAgICAgICB2YWx1ZTogJ3g2NCcsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgZ2V0QW1vdW50QmFzZWRPbkVuZGlhbm5lc3MoJzMwMDAwMCcpLnNob3VsZC5lcXVhbCgnMzAwMDAwJyk7XG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnMTAwMDAnKS5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnNTA0NDAzMTU4MjY1NDk1NTUyJykuc2hvdWxkLmVxdWFsKCc1MDQ0MDMxNTgyNjU0OTU1NTInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnl0ZS1zd2FwIHNtYWxsIGFtb3VudHMgb24gczM5MHggKHNtYWxsIGJlY29tZXMgaHVnZSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiAnczM5MHgnLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNtYWxsIGFtb3VudCAxMCwwMDAgKDB4MjcxMCkgc3dhcHMgdG8gMSwxNjMsODk5LDAyOCw2OTgsNTYyLDU2MFxuICAgICAgZ2V0QW1vdW50QmFzZWRPbkVuZGlhbm5lc3MoJzEwMDAwJykuc2hvdWxkLmVxdWFsKCcxMTYzODk5MDI4Njk4NTYyNTYwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ5dGUtc3dhcCBsYXJnZSBhbW91bnRzIG9uIHMzOTB4IChsYXJnZSBiZWNvbWVzIHRpbnkpJywgZnVuY3Rpb24gKCkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb2Nlc3MsICdhcmNoJywge1xuICAgICAgICB2YWx1ZTogJ3MzOTB4JyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBMYXJnZSBhbW91bnQgNTA0LDQwMywxNTgsMjY1LDQ5NSw1NTIgKDB4MDcwMDAwMDAwMDAwMDAwMCkgc3dhcHMgdG8gN1xuICAgICAgZ2V0QW1vdW50QmFzZWRPbkVuZGlhbm5lc3MoJzUwNDQwMzE1ODI2NTQ5NTU1MicpLnNob3VsZC5lcXVhbCgnNycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgbnVtZXJpYyBpbnB1dCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9jZXNzLCAnYXJjaCcsIHtcbiAgICAgICAgdmFsdWU6ICdzMzkweCcsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgLy8gU2hvdWxkIHdvcmsgd2l0aCBudW1iZXJzLCBub3QganVzdCBzdHJpbmdzXG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygxMDAwMCkuc2hvdWxkLmVxdWFsKCcxMTYzODk5MDI4Njk4NTYyNTYwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBzdGFuZGFyZCB0cmFuc2FjdGlvbiBhbW91bnRzIG9uIHMzOTB4JywgZnVuY3Rpb24gKCkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb2Nlc3MsICdhcmNoJywge1xuICAgICAgICB2YWx1ZTogJ3MzOTB4JyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTdGFuZGFyZCBhbW91bnQgMzAwLDAwMCAoMHg0OTNFMCkgc3dhcHMgdG8gbGFyZ2UgdmFsdWVcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKCczMDAwMDAnKTtcbiAgICAgIC8vIFZlcmlmeSBpdCdzIGRpZmZlcmVudCAoc3dhcHBlZClcbiAgICAgIHJlc3VsdC5zaG91bGQubm90LmVxdWFsKCczMDAwMDAnKTtcbiAgICAgIC8vIFZlcmlmeSBzd2FwcGluZyBiYWNrIGdpdmVzIG9yaWdpbmFsXG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcyhyZXN1bHQpLnNob3VsZC5lcXVhbCgnMzAwMDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBpbnZhbGlkIGlucHV0IGdyYWNlZnVsbHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiAnczM5MHgnLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIEludmFsaWQgQmlnSW50IGlucHV0IHNob3VsZCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nXG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnbm90LWEtbnVtYmVyJykuc2hvdWxkLmVxdWFsKCdub3QtYS1udW1iZXInKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBhY2NlcHQgdmFsaWQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBnb29kQWRkcmVzc2VzLmZvckVhY2goKGFkZHIpID0+IHtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgaW52YWxpZCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGJhZEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyKSA9PiB7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNoZWNrIHZhbGlkIHB1YiBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa2V5UGFpci5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjaGVjayBhbiBpbnZhbGlkIHB1YiBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhZFB1YktleSA9IGtleVBhaXIucHViLnNsaWNlKDAsIGtleVBhaXIucHViLmxlbmd0aCAtIDEpICsgJy0nO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoYmFkUHViS2V5KS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNoZWNrIHZhbGlkIHBydiBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BydicpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa2V5UGFpci5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjaGVjayBhbiBpbnZhbGlkIHBydiBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhZFBydktleSA9IGtleVBhaXIucHJ2ID8ga2V5UGFpci5wcnYuc2xpY2UoMCwga2V5UGFpci5wcnYubGVuZ3RoIC0gMSkgKyAnLScgOiB1bmRlZmluZWQ7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFBydihiYWRQcnZLZXkgYXMgc3RyaW5nKS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGFyc2UgVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5wYXJzZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAzMDUwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYSBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAzMDUwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYW4gdW5zaWduZWQgd2FsbGV0IGluaXQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLndhbGxldEluaXQudW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgICAgIGFtb3VudDogMzEwMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIGEgc2lnbmVkIHdhbGxldCBpbml0IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5wYXJzZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy53YWxsZXRJbml0LnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICAgICAgYW1vdW50OiAzMTAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYW4gdW5zaWduZWQgdHJhbnNmZXIgdG9rZW4gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyVG9rZW4udW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYSBzaWduZWQgdHJhbnNmZXIgdG9rZW4gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyVG9rZW4uc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6IDUwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgICB2YWx1ZTogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJzJYRnhHZlhkZEtXbnFHYU1Bc2ZOTDhIZ1hxRHZqQkwyQWUyOEtXclJ2ZzliUUJtQ3JwSFlWRGFjdVpGZUFVeVl3alhHNmV5MmpUQVJYNVZRQ25qN1NGNEwnLFxuICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgICB2YWx1ZTogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHdhbGxldCBpbml0IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLndhbGxldEluaXQudW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1dhbGxldEluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICAgIHZhbHVlOiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnMTAwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIGJsb2NraGFzaDogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgc2lnbmVkIHdhbGxldCBpbml0IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLndhbGxldEluaXQuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICc3VGtVOHdMZ1hEZUxGYlZ5ZHRnNm1xTXNwOUdhdHNldGl0U25neXNnanhGaG9mS1NVY0xQQm9LUEhjaUxlR0VmSkZNc3FlenBabUdSU0ZRVEJ5N1pEc2cnLFxuICAgICAgICB0eXBlOiAnV2FsbGV0SW5pdGlhbGl6YXRpb24nLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdmFsdWU6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZVBheWVyOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgYmxvY2toYXNoOiAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbWVtbzogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgdG9rZW4gdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXJUb2tlbi51bnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxMmY2RDNXdWJHVmVRb0gybThrVHZ2Y3Jhc1dkWFd3dFZ6VUN5Uk5EWnhBMicsXG4gICAgICAgICAgICB2YWx1ZTogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICcxMmY2RDNXdWJHVmVRb0gybThrVHZ2Y3Jhc1dkWFd3dFZ6VUN5Uk5EWnhBMicsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnMTJmNkQzV3ViR1ZlUW9IMm04a1R2dmNyYXNXZFhXd3RWelVDeVJORFp4QTInLFxuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgc2lnbmVkIHRva2VuIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyVG9rZW4uc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnMnRpY1U0WmtFcWRUSFVMcjZMb2JUZ1dCaGltNkU3d1NzY0RoTTRnenl1R1VtUXlVd0xZaG9xYWlmdXZ3bU56ekVmMVQ1YWVmVmNnTVFrU0hkSjVuc3JmWicsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMTJmNkQzV3ViR1ZlUW9IMm04a1R2dmNyYXNXZFhXd3RWelVDeVJORFp4QTInLFxuICAgICAgICAgICAgdmFsdWU6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZVBheWVyOiAnMTJmNkQzV3ViR1ZlUW9IMm04a1R2dmNyYXNXZFhXd3RWelVDeVJORFp4QTInLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiAndGVzdCBtZW1vJyxcbiAgICAgICAgYmxvY2toYXNoOiAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzEyZjZEM1d1YkdWZVFvSDJtOGtUdnZjcmFzV2RYV3d0VnpVQ3lSTkRaeEEyJyxcbiAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtdLFxuICAgICAgICBhdGFPd25lck1hcDoge30sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhY3RpdmF0ZSBzdGFraW5nIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRTdGFraW5nQWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC52YWxpZGF0b3IodmFsaWRhdG9yLnB1YilcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4VG9Ccm9hZGNhc3RGb3JtYXQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTdGFraW5nQWN0aXZhdGUnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc3ZFJ1R0ZiVTJ5MmtpalA2bzFMWU56Vnl6NHlmMTNNb29xb2lvbkN6djVaYScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICAgIHZhbHVlOiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZVBheWVyOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtdLFxuICAgICAgICBhdGFPd25lck1hcDoge30sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBkZWFjdGl2YXRlIHN0YWtpbmcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdEZWFjdGl2YXRlQnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0eFRvQnJvYWRjYXN0Rm9ybWF0LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU3Rha2luZ0RlYWN0aXZhdGUnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgICAgaW5wdXRzOiBbXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbicsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gd2l0aGRyYXcgc3Rha2luZyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ1dpdGhkcmF3QnVpbGRlcigpXG4gICAgICAgIC5zdGFraW5nQWRkcmVzcyhzdGFrZUFjY291bnQucHViKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAubWVtbygndGVzdCBtZW1vJylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4VG9Ccm9hZGNhc3RGb3JtYXQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdHhUb0Jyb2FkY2FzdEZvcm1hdCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1N0YWtpbmdXaXRoZHJhdycsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMTAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnN2RSdUdGYlUyeTJraWpQNm8xTFlOelZ5ejR5ZjEzTW9vcW9pb25DenY1WmEnLFxuICAgICAgICAgICAgdmFsdWU6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbicsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gY3JlYXRlIEFUQSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRva2VuTmFtZSA9ICd0c29sOnVzZGMnO1xuICAgICAgY29uc3QgcmVudEV4ZW1wdEFtb3VudCA9ICczMDAwMDAwJztcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0QXRhSW5pdGlhbGl6YXRpb25CdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAubWludCh0b2tlbk5hbWUpXG4gICAgICAgIC5yZW50RXhlbXB0QW1vdW50KHJlbnRFeGVtcHRBbW91bnQpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0eFRvQnJvYWRjYXN0Rm9ybWF0LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuQWNjb3VudFJlbnRFeGVtcHRBbW91bnQ6IHJlbnRFeGVtcHRBbW91bnQsXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnQXNzb2NpYXRlZFRva2VuQWNjb3VudEluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICAgIGlucHV0czogW10sXG4gICAgICAgIGZlZVBheWVyOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICczMDA1MDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiAndGVzdCBtZW1vJyxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxNDFCRk5lbTNwa25jOEN6UFZMdjFSaTNidGdLZENzYWZZUDVuWHdtWGZ4VScsXG4gICAgICAgICAgICB0b2tlbkFkZHJlc3M6ICdGNHVMZVhKb0Z6M2h3MTNNcG9zdXdhUWJNY1piQ2pxdkVHUFBlUlJCMUJ5ZicsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7XG4gICAgICAgICAgJzE0MUJGTmVtM3BrbmM4Q3pQVkx2MVJpM2J0Z0tkQ3NhZllQNW5Yd21YZnhVJzogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGNyZWF0ZSBtdWx0aSBBVEEgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgb3duZXJBZGRyZXNzOiB3YWxsZXQucHViLFxuICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBvd25lckFkZHJlc3M6IGR1cmFibGVOb25jZS53YWxsZXROb25jZUFkZHJlc3MsXG4gICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDpyYXknLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IHJlbnRFeGVtcHRBbW91bnQgPSAnMzAwMDAwMCc7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldEF0YUluaXRpYWxpemF0aW9uQnVpbGRlcigpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmVuYWJsZVRva2VuKHJlY2lwaWVudHNbMF0pXG4gICAgICAgIC5lbmFibGVUb2tlbihyZWNpcGllbnRzWzFdKVxuICAgICAgICAucmVudEV4ZW1wdEFtb3VudChyZW50RXhlbXB0QW1vdW50KVxuICAgICAgICAubWVtbygndGVzdCBtZW1vJylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4VG9Ccm9hZGNhc3RGb3JtYXQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdHhUb0Jyb2FkY2FzdEZvcm1hdCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgICB0b2tlbkFjY291bnRSZW50RXhlbXB0QW1vdW50OiByZW50RXhlbXB0QW1vdW50LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ0Fzc29jaWF0ZWRUb2tlbkFjY291bnRJbml0aWFsaXphdGlvbicsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtdLFxuICAgICAgICBpbnB1dHM6IFtdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNjAwNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMTQxQkZOZW0zcGtuYzhDelBWTHYxUmkzYnRnS2RDc2FmWVA1blh3bVhmeFUnLFxuICAgICAgICAgICAgdG9rZW5BZGRyZXNzOiAnRjR1TGVYSm9GejNodzEzTXBvc3V3YVFiTWNaYkNqcXZFR1BQZVJSQjFCeWYnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc5S2FMaW5aRk5XNWNoTDRKOFVvS25URUNwcFdWTXozZXdneDRGQWt4VURjZicsXG4gICAgICAgICAgICB0b2tlbkFkZHJlc3M6ICc5a0xKb0diTWdTdGVwdGtoS0t1aDdrZW40SkV2SHJUODMxNTdlekVHclo3UicsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnJheScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHtcbiAgICAgICAgICAnMTQxQkZOZW0zcGtuYzhDelBWTHYxUmkzYnRnS2RDc2FmWVA1blh3bVhmeFUnOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICc5S2FMaW5aRk5XNWNoTDRKOFVvS25URUNwcFdWTXozZXdneDRGQWt4VURjZic6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0b2tlbiB0cmFuc2ZlciB3aXRoIEFUQSBjcmVhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy50b2tlblRyYW5zZmVyV2l0aEF0YUNyZWF0aW9uLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuQWNjb3VudFJlbnRFeGVtcHRBbW91bnQ6ICczMDAwMDAwJyxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcyZUtqVnR6VjNvUFRYRmR0UlNEajNFbTlrMU1WN2s4V2pLa0JzelFVd2l6UycsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1VTNiSDViNlh0Rzk5YVZXTHF3VnpZUFZwUWlGSHl0QkQ2OFJ6MmVGUFpkNycsXG4gICAgICAgICAgICB2YWx1ZTogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzVVM2JINWI2WHRHOTlhVldMcXdWellQVnBRaUZIeXRCRDY4UnoyZUZQWmQ3JyxcbiAgICAgICAgZmVlOiB7IGZlZTogJzMwMDUwMDAnLCBmZWVSYXRlOiA1MDAwIH0sXG4gICAgICAgIG1lbW86IHVuZGVmaW5lZCxcbiAgICAgICAgYmxvY2toYXNoOiAnMjdFM01YRnZYTVVOWWVNSmVYMXBBYkVSR3NKZlVia2FaVGZnTWdwbU5ONWcnLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcyZUtqVnR6VjNvUFRYRmR0UlNEajNFbTlrMU1WN2s4V2pLa0JzelFVd2l6UycsXG4gICAgICAgICAgICB0b2tlbkFkZHJlc3M6ICdGNHVMZVhKb0Z6M2h3MTNNcG9zdXdhUWJNY1piQ2pxdkVHUFBlUlJCMUJ5ZicsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7XG4gICAgICAgICAgJzJlS2pWdHpWM29QVFhGZHRSU0RqM0VtOWsxTVY3azhXaktrQnN6UVV3aXpTJzogJ0M0ekNxQ2FEbTRENzh6Z2FIM0NlQkVFQkVBb01OaHpTQ2oyM3FFOTJuZGlQJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnS2V5cGFpcjonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhIGtleXBhaXIgZnJvbSByYW5kb20gc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKCdwbGFjZWhvbGRlcicgYXMgYW55KSwgJ2dlbmVyYXRlS2V5UGFpciBtZXRob2Qgbm90IGltcGxlbWVudGVkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEga2V5cGFpciBmcm9tIGEgc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKCdwbGFjZWhvbGRlcicgYXMgYW55KSwgJ2dlbmVyYXRlS2V5UGFpciBtZXRob2Qgbm90IGltcGxlbWVudGVkJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaWduIHRyYW5zYWN0aW9uOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQ6IGFueSA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEJhc2U2NDogcmVzb3VyY2VzLlJBV19UWF9VTlNJR05FRCxcbiAgICAgICAgICBrZXlzOiBbcmVzb3VyY2VzLmFjY291bnRXaXRoU2VlZC5wdWJsaWNLZXkudG9TdHJpbmcoKV0sXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogcmVzb3VyY2VzLmFjY291bnRXaXRoU2VlZC5wcml2YXRlS2V5LmJhc2U1OCxcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwocmVzb3VyY2VzLlJBV19UWF9TSUdORUQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgdHhIZXggYW5kIHR4QmFzZTY0IGludGVyY2hhbmdlYWJseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZDogYW55ID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiByZXNvdXJjZXMuUkFXX1RYX1VOU0lHTkVELFxuICAgICAgICAgIGtleXM6IFtyZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnB1YmxpY0tleS50b1N0cmluZygpXSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiByZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnByaXZhdGVLZXkuYmFzZTU4LFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgc2lnbmVkLnR4SGV4LnNob3VsZC5lcXVhbChyZXNvdXJjZXMuUkFXX1RYX1NJR05FRCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGludmFsaWQgdHJhbnNhY3Rpb24gd2hlbiBzaWduIHdpdGggcHVibGljIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4QmFzZTY0OiByZXNvdXJjZXMuUkFXX1RYX1VOU0lHTkVELFxuICAgICAgICAgICAga2V5czogW3Jlc291cmNlcy5hY2NvdW50V2l0aFNlZWQucHVibGljS2V5LnRvU3RyaW5nKCldLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJ2OiByZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnB1YmxpY0tleSxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIGtleScpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBtZXNzYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc2lnbiBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2Uoa2V5cGFpciwgJ3NpZ25lZCBtZXNzYWdlJyk7XG4gICAgICBzaWduZWRcbiAgICAgICAgLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgICAgICAuc2hvdWxkLmVxdWFsKCdzKzdkLzhhVy90d2ZNLzB3TFNLT0d4ZDkrTGhESWl6L2cwRmZKMzl5bEpoUUlrakswUllQbS9ZK2dkZUo1REl5Nks2aDZnQ1hYRVNEb21sdjEyREJCUT09Jyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZG50IHNpZ24gbWVzc2FnZSB3aGVuIG1lc3NhZ2UgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnNpZ25NZXNzYWdlKGtleXBhaXIsIHVuZGVmaW5lZCBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZyBvciBhbiBpbnN0YW5jZSBvZiBCdWZmZXIsIEFycmF5QnVmZmVyLCBvciBBcnJheSBvciBhbiBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdW5kZWZpbmVkJ1xuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2V0IFNpZ25pbmcgUGF5bG9hZCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIHZhbGlkIHNpZ25pbmcgcGF5bG9hZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBnZXRCdWlsZGVyRmFjdG9yeShiYXNlY29pbi5nZXRDaGFpbigpKTtcbiAgICAgIGNvbnN0IHJlYnVpbHRTaWduYWJsZVBheWxvYWQgPSAoYXdhaXQgZmFjdG9yeS5mcm9tKHJlc291cmNlcy5UUkFOU0ZFUl9VTlNJR05FRF9UWF9XSVRIX01FTU8pLmJ1aWxkKCkpXG4gICAgICAgIC5zaWduYWJsZVBheWxvYWQ7XG4gICAgICBjb25zdCBzaWduaW5nUGF5bG9hZCA9IGF3YWl0IGJhc2Vjb2luLmdldFNpZ25hYmxlUGF5bG9hZChyZXNvdXJjZXMuVFJBTlNGRVJfVU5TSUdORURfVFhfV0lUSF9NRU1PKTtcbiAgICAgIHNpZ25pbmdQYXlsb2FkLnNob3VsZC5iZS5kZWVwRXF1YWwocmVidWlsdFNpZ25hYmxlUGF5bG9hZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIENsb3NlQXNzb2NpYXRlZFRva2VuQWNjb3VudCB0eG4gYnVpbGRlciBmcm9tIHJhdyB0eG4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoYmFzZWNvaW4uZ2V0Q2hhaW4oKSk7XG4gICAgICBjb25zdCB0eG5CdWlsZGVyID0gZmFjdG9yeS5mcm9tKHJlc291cmNlcy5UUkFOU0ZFUl9VTlNJR05FRF9UWF9DTE9TRV9BVEEpO1xuICAgICAgYXNzZXJ0Lm9rKHR4bkJ1aWxkZXIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUHJlc2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBjb25zdCB0eFJlcXVlc3RJZCA9ICd0eFJlcXVlc3RJZCc7XG4gICAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVidWlsZCB0eCByZXF1ZXN0IGZvciBob3Qgd2FsbGV0cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlYnVpbHRUeDogVHhSZXF1ZXN0ID0ge1xuICAgICAgICB0eFJlcXVlc3RJZCxcbiAgICAgICAgdW5zaWduZWRUeHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6ICdkZWFkYmVlZicsXG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ3NlcmlhbGl6ZWRUeEhleCcsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXSxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICBpbnRlbnQ6IHtcbiAgICAgICAgICBpbnRlbnRUeXBlOiAncGF5bWVudCcsXG4gICAgICAgIH0sXG4gICAgICAgIGxhdGVzdDogdHJ1ZSxcbiAgICAgICAgc3RhdGU6ICdwZW5kaW5nVXNlclNpZ25hdHVyZScsXG4gICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICAgICAgcG9saWNpZXNDaGVja2VkOiB0cnVlLFxuICAgICAgICB2ZXJzaW9uOiAxLFxuICAgICAgICB1c2VySWQ6ICd1c2VySWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc3R1YlRzc1V0aWxzID0gc2FuZGJveC5jcmVhdGVTdHViSW5zdGFuY2UoVHNzVXRpbHMpO1xuICAgICAgc3R1YlRzc1V0aWxzLmRlbGV0ZVNpZ25hdHVyZVNoYXJlcy5yZXNvbHZlcyhbXSk7XG4gICAgICBzdHViVHNzVXRpbHMuZ2V0VHhSZXF1ZXN0LnJlc29sdmVzKHJlYnVpbHRUeCk7XG5cbiAgICAgIGNvbnN0IGhvdFdhbGxldCA9IHtcbiAgICAgICAgdHlwZTogJ2hvdCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgcHJlc2lnbmVkVHJhbnNhY3Rpb246IGFueSA9IGF3YWl0IGJhc2Vjb2luLnByZXNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHdhbGxldERhdGE6IGhvdFdhbGxldCxcbiAgICAgICAgdHNzVXRpbHM6IHN0dWJUc3NVdGlscyxcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4UmVxdWVzdElkLFxuICAgICAgICB9LFxuICAgICAgfSBhcyBhbnkpO1xuXG4gICAgICBwcmVzaWduZWRUcmFuc2FjdGlvbi53YWxsZXREYXRhLnNob3VsZC5kZWVwRXF1YWwoaG90V2FsbGV0KTtcbiAgICAgIHByZXNpZ25lZFRyYW5zYWN0aW9uLnR4UHJlYnVpbGQuc2hvdWxkLmRlZXBFcXVhbChyZWJ1aWx0VHgpO1xuICAgICAgcHJlc2lnbmVkVHJhbnNhY3Rpb24udHhIZXguc2hvdWxkLmVxdWFsKHJlYnVpbHRUeC51bnNpZ25lZFR4c1swXS5zZXJpYWxpemVkVHhIZXgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkbyBub3RoaW5nIGZvciBub24taG90IHdhbGxldHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xkV2FsbGV0ID0ge1xuICAgICAgICB0eXBlOiAnY29sZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcmVzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnByZXNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHdhbGxldERhdGE6IGNvbGRXYWxsZXQsXG4gICAgICB9IGFzIGFueSk7XG4gICAgICBwcmVzaWduZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgd2FsbGV0RGF0YTogY29sZFdhbGxldCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlcnJvciBpZiB0eFJlcXVlc3RJZCBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaG90V2FsbGV0ID0ge1xuICAgICAgICB0eXBlOiAnaG90JyxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucHJlc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB3YWxsZXREYXRhOiBob3RXYWxsZXQsXG4gICAgICAgICAgdHhQcmVidWlsZDoge30sXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnTWlzc2luZyB0eFJlcXVlc3RJZCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQVBJIEtleSBwYXJhbWV0ZXI6JywgKCkgPT4ge1xuICAgIC8vIFRlc3QgdGhlIGdldFB1YmxpY05vZGVVcmwgbWV0aG9kIGRpcmVjdGx5XG4gICAgaXQoJ3Nob3VsZCBhcHBlbmQgYXBpS2V5IHRvIG5vZGUgVVJMIHdoZW4gcHJvdmlkZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBBY2Nlc3MgdGhlIHByb3RlY3RlZCBtZXRob2QgdXNpbmcgdHlwZSBjYXN0aW5nXG4gICAgICBjb25zdCB1cmwgPSAoYmFzZWNvaW4gYXMgYW55KS5nZXRQdWJsaWNOb2RlVXJsKCd0ZXN0LWFwaS1rZXktMTIzJyk7XG4gICAgICB1cmwuc2hvdWxkLmVxdWFsKGAke0Vudmlyb25tZW50cy50ZXN0LnNvbEFsY2hlbXlOb2RlVXJsfS90ZXN0LWFwaS1rZXktMTIzYCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHVzZSByZWd1bGFyIG5vZGUgVVJMIHdoZW4gYXBpS2V5IGlzIG5vdCBwcm92aWRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEFjY2VzcyB0aGUgcHJvdGVjdGVkIG1ldGhvZCB1c2luZyB0eXBlIGNhc3RpbmdcbiAgICAgIGNvbnN0IHVybCA9IChiYXNlY29pbiBhcyBhbnkpLmdldFB1YmxpY05vZGVVcmwoKTtcbiAgICAgIHVybC5zaG91bGQuZXF1YWwoRW52aXJvbm1lbnRzLnRlc3Quc29sTm9kZVVybCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0c29sJyk7XG4gICAgY29uc3QgdXNkdE1pbnRBZGRyZXNzID0gJzljZ3BCZU5aMkhuTGRhN05XYWFVMWkzTnlUc3RrMmM0ekNNVWNvQUdzaTlDJztcbiAgICBjb25zdCB0MjJtaW50QWRkcmVzcyA9ICc1TlIxYlF3TFdxamJraGJRMWh4NzJIS0p5YmJ1dndrRG5VWk5vQVoyVmhXNic7XG4gICAgbGV0IGNhbGxCYWNrOiBzaW5vbi5TaW5vblN0dWI7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIGNhbGxCYWNrID0gc2FuZEJveC5zdHViKFNvbC5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIFNvbCk7XG5cbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0TGF0ZXN0QmxvY2toYXNoJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWl0bWVudDogJ2ZpbmFsaXplZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QmxvY2toYXNoUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRGZWVGb3JNZXNzYWdlJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICBzaW5vbi5tYXRjaC5zdHJpbmcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRGZWVzRm9yTWVzc2FnZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0TWluaW11bUJhbGFuY2VGb3JSZW50RXhlbXB0aW9uJyxcbiAgICAgICAgICAgIHBhcmFtczogWzE2NV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRNaW5pbXVtQmFsYW5jZUZvclJlbnRFeGVtcHRpb25SZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEuYWNjb3VudEluZm8uYnM1OEVuY29kZWRQdWJsaWNLZXldLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEuYWNjb3VudEluZm8uYnM1OEVuY29kZWRQdWJsaWNLZXlOb0Z1bmRzXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2VOb0Z1bmRzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleU0xRGVyaXZhdGlvbl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlTTFEZXJpdmF0aW9uKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleU0yRGVyaXZhdGlvbl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlTTJEZXJpdmF0aW9uKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleVdpdGhNYW55VG9rZW5zXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2VNMkRlcml2YXRpb24pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLmNsb3NlQVRBa2V5cy5jbG9zZUF0YUFkZHJlc3NdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZU0yRGVyaXZhdGlvbik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJzNThFbmNvZGVkUHVibGljS2V5XSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2VNMkRlcml2YXRpb24pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRBY2NvdW50SW5mbycsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEuY2xvc2VBVEFrZXlzLmNsb3NlQXRhQWRkcmVzcyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5JbmZvUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRBY2NvdW50SW5mbycsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlTm9BY2NvdW50cyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlTm9BY2NvdW50cyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5MixcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXkyLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW56UWRCTmJMcVA1VkVoZGtBUzZFUEZMQzFQSG5CcUNYRXBQeHVFYicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyRm9yU29sMjAyMlJlc3BvbnNlMik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW56UWRCTmJMcVA1VkVoZGtBUzZFUEZMQzFQSG5CcUNYRXBQeHVFYicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyRm9yU29sMjAyMlJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbmtlZ1FmZVp5aU53QUpiTmJHS1BGWENXdUJ2ZjlTczYyM1ZRNURBJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJSZXNwb25zZTIpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzNCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlMyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbnpRZEJOYkxxUDVWRWhka0FTNkVQRkxDMVBIbkJxQ1hFcFB4dUViJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJSZXNwb25zZU5vQWNjb3VudHMpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdzZW5kVHJhbnNhY3Rpb24nLFxuICAgICAgICAgICAgcGFyYW1zOiBzaW5vbi5tYXRjaC5hcnJheSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAub25DYWxsKDApXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuYnJvYWRjYXN0VHJhbnNhY3Rpb25SZXNwb25zZSlcbiAgICAgICAgLm9uQ2FsbCgxKVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzcG9uc2UxKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGFrZSBPVkMgb3V0cHV0IGFuZCBnZW5lcmF0ZSBhIHNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHRlc3REYXRhLm92Y1Jlc3BvbnNlO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICdBdlIrTDkwOWt6UnE2TnVhVWU5RjZKdDk3TU9pRnM3anBXOE11T3J3ejRFYktGNDBkMzFkY2kvYmdMVHE0Z3BrL0hoM3M1Y0E4RnRiTGtEUXIxNVBxQUU3eWQ4TE9YdnNMdE8yUkVxTU0vT0NaOHdJdGZzcWZUZmlhMnhJZmliUlczd0hndzYzamlhb2piWGVTcWFZYWpKL0NhN1l3QlV6NWJseWRJM2ZZTGdQQWdFQ0JzTFZ0ZlQ3bXB2TmlpOHdQazBHOTQyTjdUQUhFL1JXMmlxLzhMUHFBWVdxQlJvMHZJck5RNGRqbDIrV2gyRVZCUTl6Z29WVFZtMFJIWHJJdi82L1dIeFBYMW1IditKcXBtQVQ3OWx0TmpZUEswTTJ5UitaTWxuN1ZnVVRCV0ZOUXZMcUUvai9uWGxZMi9KcHh1TnIvZlhMWEVQZVMwNGRQdnQ5cXoxZEFvWUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBR3A5VVhHU3hXanVDS2hGOXowcGVJendOY01VV3lHck5FMkFZdXFVQUFBRHBpSDIwY3hMajdLbk9hb0k1QU5Ob1B4WWpzNDcyRmRqRGVNUGZ0M2tYZEFnUURBZ1VCQkFRQUFBQUVBZ0FEREFJQUFBRHdvcG83QUFBQUFBPT0nXG4gICAgICApO1xuICAgICAgKHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgKHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIHNvbCAyMDIyIHRva2VuIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIGEgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gdGVzdERhdGEub3ZjUmVzcG9uc2U7XG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ0F2UitMOTA5a3pScTZOdWFVZTlGNkp0OTdNT2lGczdqcFc4TXVPcnd6NEViS0Y0MGQzMWRjaS9iZ0xUcTRncGsvSGgzczVjQThGdGJMa0RRcjE1UHFBRTd5ZDhMT1h2c0x0TzJSRXFNTS9PQ1o4d0l0ZnNxZlRmaWEyeElmaWJSVzN3SGd3NjNqaWFvamJYZVNxYVlhakovQ2E3WXdCVXo1Ymx5ZEkzZllMZ1BBZ0VDQnNMVnRmVDdtcHZOaWk4d1BrMEc5NDJON1RBSEUvUlcyaXEvOExQcUFZV3FCUm8wdklyTlE0ZGpsMitXaDJFVkJROXpnb1ZUVm0wUkhYckl2LzYvV0h4UFgxbUh2K0pxcG1BVDc5bHROallQSzBNMnlSK1pNbG43VmdVVEJXRk5RdkxxRS9qL25YbFkyL0pweHVOci9mWExYRVBlUzA0ZFB2dDlxejFkQW9ZRUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHcDlVWEdTeFdqdUNLaEY5ejBwZUl6d05jTVVXeUdyTkUyQVl1cVVBQUFEcGlIMjBjeExqN0tuT2FvSTVBTk5vUHhZanM0NzJGZGpEZU1QZnQza1hkQWdRREFnVUJCQVFBQUFBRUFnQUREQUlBQUFEd29wbzdBQUFBQUE9PSdcbiAgICAgICk7XG4gICAgICAocmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAocmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRha2UgY29uc29saWRhdGlvbiBPVkMgb3V0cHV0IGFuZCBnZW5lcmF0ZSBtdWx0aXBsZSBzaWduZWQgc3dlZXAgdHJhbnNhY3Rpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gdGVzdERhdGEub3ZjUmVzcG9uc2UyO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICdBdFFQTHpPbUx1S3dIWTZONVhvSklaSy9UN1cxMHVZV20vTVJ0ZTNHRlVkbCt3M2dITGpTYTlINjZXU2ZGTnViUXhJUGNreEpEeWx0a1A3a3NMRGY5UWdCTkpNMlVXYkJVSDV3VDBKSkhJTGxoQ3MzM0hYOERlRS84VGRzdzZ0R2Zab01oQ25TS3Y2VFBXdEJ4eTdTYjZzVzhrc0NVUG5BV3VIR0dLbWdqRU1CQWdFQ0JtTHJxeEpyWTJrYk4vdGNyUXczUDhQMTVPbGpGR2FiRkpBS0JyVU8xZ3JOQlJvMHZJck5RNGRqbDIrV2gyRVZCUTl6Z29WVFZtMFJIWHJJdi82L1dIeFBYMW1IditKcXBtQVQ3OWx0TmpZUEswTTJ5UitaTWxuN1ZnVVRCV0ZOUXNMVnRmVDdtcHZOaWk4d1BrMEc5NDJON1RBSEUvUlcyaXEvOExQcUFZV3FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBR3A5VVhHU3hXanVDS2hGOXowcGVJendOY01VV3lHck5FMkFZdXFVQUFBSVpRbmlpUzczRDZtd2ZwbmZoVk1DNGx5WUp0UlNybW9acEY3eUlsVWRJREFnUURBZ1VCQkFRQUFBQUVBZ0FEREFJQUFBRHdQYzBkQUFBQUFBPT0nXG4gICAgICApO1xuICAgICAgKHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICdBdUxoT0E1em1PQlpSODVsbytuS2RUb3BWd0pBTXJNcDZOVys4VW5HTnNTQlNwQmtxZldaUXFTZzlzKzdhVGxYZXptNXZ4b2wrUGw2dDdQcFZOVE9Id0xjcDl4SnAzVEZIZGl2RWJod0pLbGRSNE55K3Bhc29GeCtCZ2s4cTZnMWlOaXE3WFNpMU92M2JzN2V1TWtUajduRFJGcVA4bHY3eExUY3ZyQm05T1FKQWdFQ0JwMTRJbUJDZG1WUk9sdzBVdmVZUzFNdkcvbGpDUkkzTUpURm1zeHVYRW9XQlJvMHZJck5RNGRqbDIrV2gyRVZCUTl6Z29WVFZtMFJIWHJJdi82L1dIdzBoeXh2cFZ3dEl4OS96ZVgyTzE2ZVRyWSthS0loMW1kS2c0TU1nMGV5eE1MVnRmVDdtcHZOaWk4d1BrMEc5NDJON1RBSEUvUlcyaXEvOExQcUFZV3FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBR3A5VVhHU3hXanVDS2hGOXowcGVJendOY01VV3lHck5FMkFZdXFVQUFBQzd3czFYRnNsaW53Z3RwSVNVVmlWV0lWVEh5RDJRMHFqMjRZakttckFtWEFnUURBZ1VCQkFRQUFBQUVBZ0FEREFJQUFBRHdQYzBkQUFBQUFBPT0nXG4gICAgICApO1xuICAgICAgKHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgKHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3Igbm9uLWJpdGdvIHJlY292ZXJpZXMgKGxhdGVzdCBibG9ja2hhc2gpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gTGF0ZXN0IEJsb2NraGFzaCBSZWNvdmVyeSAoQml0R28tbGVzcylcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NrSGFzaFR4biA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5rZXlzLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEua2V5cy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5rZXlzLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5rZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgfSk7XG4gICAgICBsYXRlc3RCbG9ja0hhc2hUeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgbGF0ZXN0QmxvY2tIYXNoVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBsYXRlc3RCbG9ja0hhc2hUeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgobGF0ZXN0QmxvY2tIYXNoVHhuIGFzIE1QQ1R4KS5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbigobGF0ZXN0QmxvY2tIYXNoVHhuIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuSnNvbiA9IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbi5mZWVQYXllciwgdGVzdERhdGEuYWNjb3VudEluZm8uYnM1OEVuY29kZWRQdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmxhdGVzdEJsb2NraGFzaFNpZ25hdHVyZXMpO1xuICAgICAgY29uc3Qgc29sQ29pbiA9IGJhc2Vjb2luIGFzIGFueTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxDb3VudChzb2xDb2luLmdldERhdGFGcm9tTm9kZSwgMyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIG5vbi1iaXRnbyByZWNvdmVyaWVzIChkdXJhYmxlIG5vbmNlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIER1cmFibGUgTm9uY2UgUmVjb3ZlcnkgKEJpdEdvLWxlc3MpXG4gICAgICBjb25zdCBkdXJhYmxlTm9uY2VUeG4gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEua2V5cy51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmtleXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEua2V5cy5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEua2V5cy53YWxsZXRQYXNzd29yZCxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBkdXJhYmxlTm9uY2VUeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgZHVyYWJsZU5vbmNlVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBkdXJhYmxlTm9uY2VUeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoZHVyYWJsZU5vbmNlVHhuIGFzIE1QQ1R4KS5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCBkdXJhYmxlTm9uY2VUeG5EZXNlcmlhbGl6ZSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGR1cmFibGVOb25jZVR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbigoZHVyYWJsZU5vbmNlVHhuIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgZHVyYWJsZU5vbmNlVHhuSnNvbiA9IGR1cmFibGVOb25jZVR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXF1YWwoZHVyYWJsZU5vbmNlVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwoZHVyYWJsZU5vbmNlVHhuSnNvbi5mZWVQYXllciwgdGVzdERhdGEuYWNjb3VudEluZm8uYnM1OEVuY29kZWRQdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKGR1cmFibGVOb25jZVR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuICAgICAgY29uc3Qgc29sQ29pbiA9IGJhc2Vjb2luIGFzIGFueTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxDb3VudChzb2xDb2luLmdldERhdGFGcm9tTm9kZSwgNCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIHVuc2lnbmVkIHN3ZWVwIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBVbnNpZ25lZCBTd2VlcCBSZWNvdmVyeVxuICAgICAgY29uc3QgdW5zaWduZWRTd2VlcFR4biA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmtleXMuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIHB1YmxpY0tleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgc2VjcmV0S2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVByaXZLZXksXG4gICAgICAgIH0sXG4gICAgICB9KSkgYXMgTVBDU3dlZXBUeHM7XG5cbiAgICAgIHVuc2lnbmVkU3dlZXBUeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgdW5zaWduZWRTd2VlcFR4bi50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB1bnNpZ25lZFN3ZWVwVHhuLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1bnNpZ25lZFN3ZWVwVHhuLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2NhbkluZGV4LCAwKTtcblxuICAgICAgY29uc3QgdW5zaWduZWRTd2VlcFR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdW5zaWduZWRTd2VlcFR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbihcbiAgICAgICAgdW5zaWduZWRTd2VlcFR4bi50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkU3dlZXBUeG5Kc29uID0gdW5zaWduZWRTd2VlcFR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXF1YWwodW5zaWduZWRTd2VlcFR4bkpzb24ubm9uY2UsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VCbG9ja2hhc2gpO1xuICAgICAgc2hvdWxkLmVxdWFsKHVuc2lnbmVkU3dlZXBUeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwodW5zaWduZWRTd2VlcFR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLnVuc2lnbmVkU3dlZXBTaWduYXR1cmVzKTtcbiAgICAgIGNvbnN0IHNvbENvaW4gPSBiYXNlY29pbiBhcyBhbnk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsQ291bnQoc29sQ29pbi5nZXREYXRhRnJvbU5vZGUsIDQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZXJyb3IgaW4gcmVjb3ZlciBmdW5jdGlvbiBpZiBhIHJlcXVpcmVkIGZpZWxkIGlzIG1pc3NpbmcvaW5jb3JyZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gbWlzc2luZyB1c2Vya2V5XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5rZXlzLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEua2V5cy5iaXRnb0tleSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHVzZXJLZXknKTtcblxuICAgICAgLy8gbWlzc2luZyBiYWNrdXBrZXlcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5rZXlzLnVzZXJLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmtleXMuYml0Z29LZXksXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5rZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyBiYWNrdXBLZXknKTtcblxuICAgICAgLy8gaW5jb3JyZWN0IHdhbGxldCBwYXNzcGhyYXNlLCB1c2VyIGtleSwgYmFja3VwIGtleSBjb21iaW5hdGlvblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmtleXMudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmtleXMuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5rZXlzLmJpdGdvS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEua2V5cy53YWxsZXRQYXNzd29yZCArICdpbmNvcnJlY3QnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluOiBpbmNvcnJlY3QgcGFzc3dvcmQnKTtcblxuICAgICAgLy8gbm8gd2FsbGV0IHdpdGggc3VmZmljaWVudCBmdW5kc1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmtleXMudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmtleXMuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5rZXlzLmJpdGdvS2V5Tm9GdW5kcyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdEaWQgbm90IGZpbmQgYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzb2wgdG9rZW5zIHRvIHJlY292ZXJ5IGRlc3RpbmF0aW9uIHdpdGggbm8gZXhpc3RpbmcgdG9rZW4gYWNjb3VudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0b2tlblR4biA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIHB1YmxpY0tleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgc2VjcmV0S2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVByaXZLZXksXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdG9rZW5UeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgdG9rZW5UeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoKHRva2VuVHhuIGFzIE1QQ1R4KS5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCB0b2tlblR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdG9rZW5UeG5EZXNlcmlhbGl6ZS5mcm9tUmF3VHJhbnNhY3Rpb24oKHRva2VuVHhuIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdG9rZW5UeG5Kc29uID0gdG9rZW5UeG5EZXNlcmlhbGl6ZS50b0pzb24oKTtcblxuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gdG9rZW5UeG5Kc29uLmluc3RydWN0aW9uc0RhdGEgYXMgSW5zdHJ1Y3Rpb25QYXJhbXNbXTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhLmxlbmd0aCwgMyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVswXS50eXBlLCAnTm9uY2VBZHZhbmNlJyk7XG5cbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uVVNEVFRva2VuQWNjb3VudCA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzKFxuICAgICAgICB1c2R0TWludEFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXlcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS50eXBlLCAnQ3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5taW50QWRkcmVzcywgdXNkdE1pbnRBZGRyZXNzKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMuYXRhQWRkcmVzcywgZGVzdGluYXRpb25VU0RUVG9rZW5BY2NvdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMub3duZXJBZGRyZXNzLCB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMudG9rZW5OYW1lLCAndHNvbDp1c2R0Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLnBheWVyQWRkcmVzcywgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG5cbiAgICAgIGNvbnN0IHNvdXJjZVVTRFRUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMl0udHlwZSwgJ1Rva2VuVHJhbnNmZXInKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMuZnJvbUFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy50b0FkZHJlc3MsIGRlc3RpbmF0aW9uVVNEVFRva2VuQWNjb3VudCk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLmFtb3VudCwgJzIwMDAwMDAwMDAnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMudG9rZW5OYW1lLCAndHNvbDp1c2R0Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLnNvdXJjZUFkZHJlc3MsIHNvdXJjZVVTRFRUb2tlbkFjY291bnQpO1xuXG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCA3KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzb2wgMjAyMiB0b2tlbnMgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gd2l0aCBubyBleGlzdGluZyB0b2tlbiBhY2NvdW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRva2VuVHhuID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLndyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0MjJtaW50QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBwdWJsaWNLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgIHNlY3JldEtleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQcml2S2V5LFxuICAgICAgICB9LFxuICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbnpRZEJOYkxxUDVWRWhka0FTNkVQRkxDMVBIbkJxQ1hFcFB4dUViJyxcbiAgICAgIH0pO1xuXG4gICAgICB0b2tlblR4bi5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICB0b2tlblR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdG9rZW5UeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgodG9rZW5UeG4gYXMgTVBDVHgpLnNjYW5JbmRleCwgMCk7XG5cbiAgICAgIGNvbnN0IHRva2VuVHhuRGVzZXJpYWxpemUgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0b2tlblR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbigodG9rZW5UeG4gYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0b2tlblR4bkpzb24gPSB0b2tlblR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuXG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLm5vbmNlLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlQmxvY2toYXNoKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24uZmVlUGF5ZXIsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlU2lnbmF0dXJlcyk7XG5cbiAgICAgIGNvbnN0IGluc3RydWN0aW9uc0RhdGEgPSB0b2tlblR4bkpzb24uaW5zdHJ1Y3Rpb25zRGF0YSBhcyBJbnN0cnVjdGlvblBhcmFtc1tdO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGEubGVuZ3RoLCAzKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzBdLnR5cGUsICdOb25jZUFkdmFuY2UnKTtcblxuICAgICAgY29uc3QgZGVzdGluYXRpb25Ub2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdDIybWludEFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXlcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS50eXBlLCAnQ3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5taW50QWRkcmVzcywgdDIybWludEFkZHJlc3MpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5hdGFBZGRyZXNzLCBkZXN0aW5hdGlvblRva2VuQWNjb3VudCk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLm93bmVyQWRkcmVzcywgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLnRva2VuTmFtZSwgJ3Rzb2w6dDIybWludCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5wYXllckFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuXG4gICAgICBjb25zdCBzb3VyY2VUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdDIybWludEFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczBcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsyXS50eXBlLCAnVG9rZW5UcmFuc2ZlcicpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy5mcm9tQWRkcmVzcywgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLnRvQWRkcmVzcywgZGVzdGluYXRpb25Ub2tlbkFjY291bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy5hbW91bnQsICcyMDAwMDAwMDAwJyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLnRva2VuTmFtZSwgJ3Rzb2w6dDIybWludCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy5zb3VyY2VBZGRyZXNzLCBzb3VyY2VUb2tlbkFjY291bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICAoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMucHJvZ3JhbUlkLFxuICAgICAgICAnVG9rZW56UWRCTmJMcVA1VkVoZGtBUzZFUEZMQzFQSG5CcUNYRXBQeHVFYidcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHNvbENvaW4gPSBiYXNlY29pbiBhcyBhbnk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsQ291bnQoc29sQ29pbi5nZXREYXRhRnJvbU5vZGUsIDcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNvbCB0b2tlbnMgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gd2l0aCBleGlzdGluZyB0b2tlbiBhY2NvdW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRva2VuVHhuID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLndyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXkyLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIHB1YmxpY0tleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgc2VjcmV0S2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVByaXZLZXksXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgdG9rZW5UeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgdG9rZW5UeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoKHRva2VuVHhuIGFzIE1QQ1R4KS5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCB0b2tlblR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdG9rZW5UeG5EZXNlcmlhbGl6ZS5mcm9tUmF3VHJhbnNhY3Rpb24oKHRva2VuVHhuIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdG9rZW5UeG5Kc29uID0gdG9rZW5UeG5EZXNlcmlhbGl6ZS50b0pzb24oKTtcblxuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gdG9rZW5UeG5Kc29uLmluc3RydWN0aW9uc0RhdGEgYXMgVG9rZW5UcmFuc2ZlcltdO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGEubGVuZ3RoLCAyKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzBdLnR5cGUsICdOb25jZUFkdmFuY2UnKTtcblxuICAgICAgY29uc3Qgc291cmNlVVNEVFRva2VuQWNjb3VudCA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzKFxuICAgICAgICB1c2R0TWludEFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczBcbiAgICAgICk7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvblVTRFRUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5MlxuICAgICAgKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnR5cGUsICdUb2tlblRyYW5zZmVyJyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMuZnJvbUFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLnRvQWRkcmVzcywgZGVzdGluYXRpb25VU0RUVG9rZW5BY2NvdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy5hbW91bnQsICcyMDAwMDAwMDAwJyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMudG9rZW5OYW1lLCAndHNvbDp1c2R0Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMuc291cmNlQWRkcmVzcywgc291cmNlVVNEVFRva2VuQWNjb3VudCk7XG5cbiAgICAgIGNvbnN0IHNvbENvaW4gPSBiYXNlY29pbiBhcyBhbnk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsQ291bnQoc29sQ29pbi5nZXREYXRhRnJvbU5vZGUsIDcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNvbCAyMDIyIHRva2VucyB0byByZWNvdmVyeSBkZXN0aW5hdGlvbiB3aXRoIGV4aXN0aW5nIHRva2VuIGFjY291bnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9rZW5UeG4gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLndyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleTIsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0MjJtaW50QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBwdWJsaWNLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgIHNlY3JldEtleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQcml2S2V5LFxuICAgICAgICB9LFxuICAgICAgICBwcm9ncmFtSWQ6IFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpLFxuICAgICAgfSk7XG5cbiAgICAgIHRva2VuVHhuLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0b2tlblR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKCh0b2tlblR4biBhcyBNUENUeCkuc2NhbkluZGV4LCAwKTtcblxuICAgICAgY29uc3QgdG9rZW5UeG5EZXNlcmlhbGl6ZSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHRva2VuVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKCh0b2tlblR4biBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHRva2VuVHhuSnNvbiA9IHRva2VuVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG4gICAgICBjb25zb2xlLmxvZyh0b2tlblR4bkpzb24pO1xuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gdG9rZW5UeG5Kc29uLmluc3RydWN0aW9uc0RhdGEgYXMgVG9rZW5UcmFuc2ZlcltdO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGEubGVuZ3RoLCAyKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzBdLnR5cGUsICdOb25jZUFkdmFuY2UnKTtcblxuICAgICAgY29uc3Qgc291cmNlMjAyMlRva2VuQWNjb3VudCA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzKFxuICAgICAgICB0MjJtaW50QWRkcmVzcyxcbiAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpXG4gICAgICApO1xuICAgICAgY29uc3QgZGVzdGluYXRpb24yMDIyVG9rZW5BY2NvdW50ID0gYXdhaXQgZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgIHQyMm1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5MixcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0udHlwZSwgJ1Rva2VuVHJhbnNmZXInKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy5mcm9tQWRkcmVzcywgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMudG9BZGRyZXNzLCBkZXN0aW5hdGlvbjIwMjJUb2tlbkFjY291bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLmFtb3VudCwgJzIwMDAwMDAwMDAnKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy50b2tlbk5hbWUsICd0c29sOnQyMm1pbnQnKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy5zb3VyY2VBZGRyZXNzLCBzb3VyY2UyMDIyVG9rZW5BY2NvdW50KTtcbiAgICAgIGNvbnN0IHNvbENvaW4gPSBiYXNlY29pbiBhcyBhbnk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsQ291bnQoc29sQ29pbi5nZXREYXRhRnJvbU5vZGUsIDcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNvbCB0b2tlbnMgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gd2l0aCBleGlzdGluZyB0b2tlbiBhY2NvdW50cyBmb3IgdW5zaWduZWQgc3dlZXAgcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGZlZVJlc3BvbnNlID0gdGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEZlZXNGb3JNZXNzYWdlUmVzcG9uc2U7XG4gICAgICBmZWVSZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZSA9IDEwMDAwO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRGZWVGb3JNZXNzYWdlJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICBzaW5vbi5tYXRjaC5zdHJpbmcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGZlZVJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdG9rZW5UeG4gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5MixcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IHRlc3REYXRhLnRva2VuQWRkcmVzcy5UZXN0VVNEQyxcbiAgICAgIH0pKSBhcyBNUENTd2VlcFR4cztcblxuICAgICAgLy8gMiBzaWduYXR1cmVzIGFuZCBubyByZW50IGV4ZW1wdGlvbiBmZWUgc2luY2UgdGhlIGRlc3RpbmF0aW9uIGFscmVhZHkgaGFzIHRva2VuIGFjY291bnRzXG4gICAgICBjb25zdCBleHBlY3RlZEZlZSA9IDUwMDAgKyA1MDAwO1xuXG4gICAgICBjb25zdCB7IHNlcmlhbGl6ZWRUeCwgc2NhbkluZGV4LCBmZWVJbmZvLCBwYXJzZWRUeCB9ID0gdG9rZW5UeG4udHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeDtcbiAgICAgIGFzc2VydC5vayhzZXJpYWxpemVkVHgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNjYW5JbmRleCwgMCk7XG4gICAgICBhc3NlcnQub2soZmVlSW5mbyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZmVlSW5mby5mZWVTdHJpbmcsIGV4cGVjdGVkRmVlLnRvU3RyaW5nKCkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZlZUluZm8uZmVlLCBleHBlY3RlZEZlZSk7XG4gICAgICBhc3NlcnQub2socGFyc2VkVHgpO1xuICAgICAgYXNzZXJ0Lm9rKHBhcnNlZFR4LmlucHV0cyBpbnN0YW5jZW9mIEFycmF5ICYmIHBhcnNlZFR4LmlucHV0cy5sZW5ndGggPT09IDEpO1xuICAgICAgYXNzZXJ0Lm9rKHBhcnNlZFR4Lm91dHB1dHMgaW5zdGFuY2VvZiBBcnJheSAmJiBwYXJzZWRUeC5vdXRwdXRzLmxlbmd0aCA9PT0gMSk7XG5cbiAgICAgIGNvbnN0IHRva2VuVHhuRGVzZXJpYWxpemUgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0b2tlblR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbih0b2tlblR4bi50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0b2tlblR4bkpzb24gPSB0b2tlblR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodG9rZW5UeG5Kc29uLm5vbmNlLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlQmxvY2toYXNoKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0b2tlblR4bkpzb24uZmVlUGF5ZXIsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRva2VuVHhuSnNvbi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEudW5zaWduZWRTd2VlcFNpZ25hdHVyZXMpO1xuICAgICAgY29uc3Qgc29sQ29pbiA9IGJhc2Vjb2luIGFzIGFueTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxDb3VudChzb2xDb2luLmdldERhdGFGcm9tTm9kZSwgNyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgc29sIGZ1bmRzIGZyb20gQVRBIGFkZHJlc3MgZm9yIG5vbi1iaXRnbyByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gY2xvc2UgQVRBIGFkZHJlc3MgaW5zdHJ1Y3Rpb24gdHlwZSB0eG5cbiAgICAgIGNvbnN0IGNsb3NlQVRBVHhucyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDbG9zZUFUQSh7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICBjbG9zZUF0YUFkZHJlc3M6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5jbG9zZUF0YUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb25BdGFBZGRyZXNzOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMucmVjb3ZlcnlEZXN0aW5hdGlvbkF0YUFkZHJlc3MsXG4gICAgICB9KTtcbiAgICAgIGNsb3NlQVRBVHhucy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIGNsb3NlQVRBVHhuc1swXS50eElkLFxuICAgICAgICAnMmlkM1lDMmpLOUc1V28ycGhEeDRnSlZBZXc4RGNZNU5Bb2puVnVhbzhya3h3UFlQZThjU3dFNUd6aEVnSkEyeThmVmpERW82aVI2eWtCdkR4clRRcnRwYidcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIGNsb3NlQVRBVHhuc1sxXS50eElkLFxuICAgICAgICAnNW9VQmdYWDRlbkdtRkVzcEc2NGdveTNQUnlzamZyZWtaR2czclpOa0JIVUNRRmQ0ODJ2clZXYmZEY1JZTUJFSnQ2NUpYeW1mRVBtOE02ZDg5WDR4Vjc5bidcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgdG9rZW5zIGZyb20gYSBuZXN0ZWQgQVRBIChBVEEgd2hvc2Ugb3duZXIgaXMgYW5vdGhlciBBVEEpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlck5lc3RlZEF0YSh7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICBuZXN0ZWRBdGFBZGRyZXNzOiAnRkd1WlNCaHRyZXFTVXNFODZ4b2t5akt6Mmk4VkJ0Snp5NnVNWFhLeUdIdWcnLFxuICAgICAgICBvd25lckF0YUFkZHJlc3M6ICdaZm05OFpwVmFmeWRoRlRZY3NZNmJIZ3ViaEI0Y0ZnV0Z2YmRFSnhZaFRBJyxcbiAgICAgICAgdG9rZW5NaW50QWRkcmVzczogJ1pCQ05wdUQ3WU1YelRIQjJmaEdrR2k3OE1Oc0hHTFJYVWhSZXdOUm05UlUnLFxuICAgICAgfSk7XG5cbiAgICAgIHJlc3VsdC5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIHJlc3VsdC50eElkLFxuICAgICAgICAnMmlkM1lDMmpLOUc1V28ycGhEeDRnSlZBZXc4RGNZNU5Bb2puVnVhbzhya3h3UFlQZThjU3dFNUd6aEVnSkEyeThmVmpERW82aVI2eWtCdkR4clRRcnRwYidcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gbmVzdGVkQXRhQWRkcmVzcyBpcyBtaXNzaW5nIGZvciByZWNvdmVyTmVzdGVkQXRhJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJOZXN0ZWRBdGEoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJpdGdvS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgICAgb3duZXJBdGFBZGRyZXNzOiAnWmZtOThacFZhZnlkaEZUWWNzWTZiSGd1YmhCNGNGZ1dGdmJkRUp4WWhUQScsXG4gICAgICAgICAgdG9rZW5NaW50QWRkcmVzczogJ1pCQ05wdUQ3WU1YelRIQjJmaEdrR2k3OE1Oc0hHTFJYVWhSZXdOUm05UlUnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBuZXN0ZWRBdGFBZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gb3duZXJBdGFBZGRyZXNzIGlzIG1pc3NpbmcgZm9yIHJlY292ZXJOZXN0ZWRBdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlck5lc3RlZEF0YSh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYml0Z29LZXksXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy53YWxsZXRQYXNzd29yZCxcbiAgICAgICAgICBuZXN0ZWRBdGFBZGRyZXNzOiAnRkd1WlNCaHRyZXFTVXNFODZ4b2t5akt6Mmk4VkJ0Snp5NnVNWFhLeUdIdWcnLFxuICAgICAgICAgIHRva2VuTWludEFkZHJlc3M6ICdaQkNOcHVEN1lNWHpUSEIyZmhHa0dpNzhNTnNIR0xSWFVoUmV3TlJtOVJVJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgb3duZXJBdGFBZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdG9rZW5NaW50QWRkcmVzcyBpcyBtaXNzaW5nIGZvciByZWNvdmVyTmVzdGVkQXRhJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJOZXN0ZWRBdGEoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJpdGdvS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgICAgbmVzdGVkQXRhQWRkcmVzczogJ0ZHdVpTQmh0cmVxU1VzRTg2eG9reWpLejJpOFZCdEp6eTZ1TVhYS3lHSHVnJyxcbiAgICAgICAgICBvd25lckF0YUFkZHJlc3M6ICdaZm05OFpwVmFmeWRoRlRZY3NZNmJIZ3ViaEI0Y0ZnV0Z2YmRFSnhZaFRBJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgdG9rZW5NaW50QWRkcmVzcycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQnVpbGQgQ29uc29saWRhdGlvbiBSZWNvdmVyaWVzOicsICgpID0+IHtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGNvbnN0IGNvaW4gPSBjb2lucy5nZXQoJ3Rzb2wnKTtcbiAgICBjb25zdCB1c2R0TWludEFkZHJlc3MgPSAnOWNncEJlTloySG5MZGE3TldhYVUxaTNOeVRzdGsyYzR6Q01VY29BR3NpOUMnO1xuICAgIGNvbnN0IGR1cmFibGVOb25jZXMgPSB7XG4gICAgICBwdWJsaWNLZXlzOiBbXG4gICAgICAgIHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleTIsXG4gICAgICAgIHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5MyxcbiAgICAgIF0sXG4gICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICB9O1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihTb2wucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBTb2wpO1xuXG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldExhdGVzdEJsb2NraGFzaCcsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6ICdmaW5hbGl6ZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEJsb2NraGFzaFJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0RmVlRm9yTWVzc2FnZScsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgc2lub24ubWF0Y2guc3RyaW5nLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWl0bWVudDogJ2ZpbmFsaXplZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0RmVlc0Zvck1lc3NhZ2VSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlTm9GdW5kcyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MzXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczVdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldE1pbmltdW1CYWxhbmNlRm9yUmVudEV4ZW1wdGlvbicsXG4gICAgICAgICAgICBwYXJhbXM6IFsxNjVdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0TWluaW11bUJhbGFuY2VGb3JSZW50RXhlbXB0aW9uUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRBY2NvdW50SW5mbycsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRBY2NvdW50SW5mbycsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXkyLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50SW5mb1Jlc3BvbnNlMik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MxLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2VOb0FjY291bnRzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczIsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbmtlZ1FmZVp5aU53QUpiTmJHS1BGWENXdUJ2ZjlTczYyM1ZRNURBJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJSZXNwb25zZU5vQWNjb3VudHMpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlTm9BY2NvdW50cyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3M1LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgc2lnbmVkIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICAgIGR1cmFibGVOb25jZXM6IGR1cmFibGVOb25jZXMsXG4gICAgICB9KSkgYXMgTVBDVHhzO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy50cmFuc2FjdGlvbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIChyZXMubGFzdFNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMyk7XG5cbiAgICAgIGNvbnN0IHR4bjEgPSByZXMudHJhbnNhY3Rpb25zWzBdO1xuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLmZyb21SYXdUcmFuc2FjdGlvbigodHhuMSBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkpzb24xID0gbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLnRvSnNvbigpO1xuXG4gICAgICBjb25zdCBub25jZTEgPSB0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEluZm9SZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZS5kYXRhLnBhcnNlZC5pbmZvLmJsb2NraGFzaDtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5ub25jZSwgbm9uY2UxKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMik7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCB0eG4yID0gcmVzLnRyYW5zYWN0aW9uc1sxXTtcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMiA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMi5mcm9tUmF3VHJhbnNhY3Rpb24oKHR4bjIgYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMiA9IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMi50b0pzb24oKTtcblxuICAgICAgY29uc3Qgbm9uY2UyID0gdGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UyLmJvZHkucmVzdWx0LnZhbHVlLmRhdGEucGFyc2VkLmluZm8uYmxvY2toYXNoO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24yLm5vbmNlLCBub25jZTIpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24yLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MzKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlU2lnbmF0dXJlcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIHVuc2lnbmVkIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgIGVuZGluZ1NjYW5JbmRleDogNCxcbiAgICAgICAgZHVyYWJsZU5vbmNlczogZHVyYWJsZU5vbmNlcyxcbiAgICAgIH0pKSBhcyBNUENTd2VlcFR4cztcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuXG4gICAgICBjb25zdCB0eG4xID0gcmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgICh0eG4xLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMik7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHhuMS5jb2luPy5zaG91bGQuZXF1YWwoJ3Rzb2wnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgdHhuMS5kZXJpdmF0aW9uUGF0aD8uc2hvdWxkLmVxdWFsKCdtLzInKTtcblxuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW5TcGVjaWZpYycpO1xuICAgICAgY29uc3QgY29pblNwZWNpZmljMSA9IHR4bjEuY29pblNwZWNpZmljO1xuICAgICAgY29pblNwZWNpZmljMT8uc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuXG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTEgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTEuZnJvbVJhd1RyYW5zYWN0aW9uKCh0eG4xIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEgPSBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTEudG9Kc29uKCk7XG5cbiAgICAgIGNvbnN0IG5vbmNlMSA9IHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50SW5mb1Jlc3BvbnNlLmJvZHkucmVzdWx0LnZhbHVlLmRhdGEucGFyc2VkLmluZm8uYmxvY2toYXNoO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24xLm5vbmNlLCBub25jZTEpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24xLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MyKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEudW5zaWduZWRTd2VlcFNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCB0eG4yID0gcmVzLnR4UmVxdWVzdHNbMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgICh0eG4yLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHhuMi5jb2luPy5zaG91bGQuZXF1YWwoJ3Rzb2wnKTtcbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgdHhuMi5kZXJpdmF0aW9uUGF0aD8uc2hvdWxkLmVxdWFsKCdtLzMnKTtcblxuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW5TcGVjaWZpYycpO1xuICAgICAgY29uc3QgY29pblNwZWNpZmljMiA9IHR4bjIuY29pblNwZWNpZmljO1xuICAgICAgY29pblNwZWNpZmljMj8uc2hvdWxkLmhhc093blByb3BlcnR5KCdjb21tb25LZXljaGFpbicpO1xuICAgICAgY29pblNwZWNpZmljMj8uc2hvdWxkLmhhc093blByb3BlcnR5KCdsYXN0U2NhbkluZGV4Jyk7XG4gICAgICBjb2luU3BlY2lmaWMyPy5sYXN0U2NhbkluZGV4Py5zaG91bGQuZXF1YWwoMyk7XG5cbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMiA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMi5mcm9tUmF3VHJhbnNhY3Rpb24oKHR4bjIgYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMiA9IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMi50b0pzb24oKTtcblxuICAgICAgY29uc3Qgbm9uY2UyID0gdGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UyLmJvZHkucmVzdWx0LnZhbHVlLmRhdGEucGFyc2VkLmluZm8uYmxvY2toYXNoO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24yLm5vbmNlLCBub25jZTIpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24yLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MzKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEudW5zaWduZWRTd2VlcFNpZ25hdHVyZXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCB0b2tlbiBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAzLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDUsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB1c2R0TWludEFkZHJlc3MsXG4gICAgICAgIGR1cmFibGVOb25jZXM6IGR1cmFibGVOb25jZXMsXG4gICAgICB9KSkgYXMgTVBDU3dlZXBUeHM7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgY29uc3QgdHhuMSA9IHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICAodHhuMS5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDQpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHR4bjEuY29pbj8uc2hvdWxkLmVxdWFsKCd0c29sJyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIHR4bjEuZGVyaXZhdGlvblBhdGg/LnNob3VsZC5lcXVhbCgnbS80Jyk7XG5cbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzEgPSB0eG4xLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzE/LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29tbW9uS2V5Y2hhaW4nKTtcblxuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLmZyb21SYXdUcmFuc2FjdGlvbigodHhuMSBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkpzb24xID0gbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLnRvSnNvbigpO1xuXG4gICAgICBjb25zdCBub25jZTEgPSB0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEluZm9SZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZS5kYXRhLnBhcnNlZC5pbmZvLmJsb2NraGFzaDtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5ub25jZSwgbm9uY2UxKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzNSk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLnVuc2lnbmVkU3dlZXBTaWduYXR1cmVzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2tpcCBidWlsZGluZyBjb25zb2xpZGF0ZSB0cmFuc2FjdGlvbiBpZiBiYWxhbmNlIGlzIGVxdWFsIHRvIHplcm8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS53cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICAgIGR1cmFibGVOb25jZXM6IGR1cmFibGVOb25jZXMsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdEaWQgbm90IGZpbmQgYW4gYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgc3RhcnRpbmdTY2FuSW5kZXggaXMgbm90IGdlIHRvIDEnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogLTEsXG4gICAgICAgICAgZHVyYWJsZU5vbmNlczogZHVyYWJsZU5vbmNlcyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IC0xLCBlbmRpbmdTY2FuSW5kZXg6IDE5LidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgc2NhbiBmYWN0b3IgaXMgdG9vIGhpZ2gnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDMwMCxcbiAgICAgICAgICBkdXJhYmxlTm9uY2VzOiBkdXJhYmxlTm9uY2VzLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogMSwgZW5kaW5nU2NhbkluZGV4OiAzMDAuJ1xuICAgICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYnJvYWRjYXN0VHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnJvYWRjYXN0IGEgdHJhbnNhY3Rpb24gc3VjY2VzZnVsbHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gPSB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXIuc2lnbmVkO1xuICAgICAgY29uc3QgYnJvYWRjYXN0U3R1YiA9IHNhbmRCb3hcbiAgICAgICAgLnN0dWIoU29sLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgU29sKVxuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ3NlbmRUcmFuc2FjdGlvbicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdiYXNlNjQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBicm9hZGNhc3RUeG4gPSBhd2FpdCBiYXNlY29pbi5icm9hZGNhc3RUcmFuc2FjdGlvbih7IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiB9KTtcbiAgICAgIGFzc2VydC5vayhicm9hZGNhc3RUeG4pO1xuICAgICAgYXNzZXJ0Lm9rKGJyb2FkY2FzdFR4bi50eElkKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgYnJvYWRjYXN0VHhuLnR4SWQsXG4gICAgICAgICcyaWQzWUMyaks5RzVXbzJwaER4NGdKVkFldzhEY1k1TkFvam5WdWFvOHJreHdQWVBlOGNTd0U1R3poRWdKQTJ5OGZWakRFbzZpUjZ5a0J2RHhyVFFydHBiJ1xuICAgICAgKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChicm9hZGNhc3RTdHViLmNhbGxDb3VudCwgMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGdvdCBhbiBlcnJvciBmcm9tIHRoZSBub2RlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uID0gdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnNpZ25lZDtcbiAgICAgIGNvbnN0IGJyb2FkY2FzdFN0dWIgPSBzYW5kQm94XG4gICAgICAgIC5zdHViKFNvbC5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIFNvbClcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdzZW5kVHJhbnNhY3Rpb24nLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbixcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnYmFzZTY0JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5icm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlRXJyb3IpO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLmJyb2FkY2FzdFRyYW5zYWN0aW9uKHsgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7IG1lc3NhZ2U6ICdFcnJvciBicm9hZGNhc3RpbmcgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uIHNpbXVsYXRpb24gZmFpbGVkOiBCbG9ja2hhc2ggbm90IGZvdW5kJyB9XG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJyb2FkY2FzdFN0dWIuY2FsbENvdW50LCAxKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgaXMgbm90IGEgdmFsaWQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gPSAncmFuZG9tc3RyaW5nJztcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBiYXNlY29pbi5icm9hZGNhc3RUcmFuc2FjdGlvbih7IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtZXNzYWdlOiAnSW52YWxpZCByYXcgdHJhbnNhY3Rpb24nIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGlzIG5vdCBhIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiA9IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy50cmFuc2Zlci51bnNpZ25lZDtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBiYXNlY29pbi5icm9hZGNhc3RUcmFuc2FjdGlvbih7IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtZXNzYWdlOiAnSW52YWxpZCByYXcgdHJhbnNhY3Rpb24nIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBdWRpdEtleScsICgpID0+IHtcbiAgICBjb25zdCB7IGtleToga2V5U3RyaW5nLCBjb21tb25LZXljaGFpbiB9ID0gc29sQmFja3VwS2V5O1xuICAgIGNvbnN0IGtleSA9IGtleVN0cmluZy5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAna0FtW0VGUTZvPVN4bGNMRkR3JSwnO1xuICAgIGNvbnN0IG11bHRpU2lnVHlwZSA9ICd0c3MnO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSBjb21tb25LZXljaGFpbiBpcyBpbnZhbGlkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWx0ZXJlZENvbW1vbktleWNoYWluID0gZ2VuZXJhdGVSYW5kb21QYXNzd29yZCgxMCk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IGFsdGVyZWRDb21tb25LZXljaGFpbixcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBjb21tb24ga2V5Y2hhaW4nLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbmNvcnJlY3RQYXNzcGhyYXNlID0gJ2Zvbyc7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogaW5jb3JyZWN0UGFzc3BocmFzZSxcbiAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6IFwiZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBwYXNzd29yZCBlcnJvciAtIGNjbTogdGFnIGRvZXNuJ3QgbWF0Y2hcIixcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjogYWx0ZXJlZEtleSxcbiAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjoganNvbiBkZWNyeXB0OiBpbnZhbGlkIHBhcmFtZXRlcnMnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFNldCB1cCB3YWxsZXQgZGF0YVxuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogd2FsbGV0LnB1YixcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBmYWtlUHJ2ID0gZW5jcnlwdCgncGFzc3dvcmQnLCAncHJ2Jyk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE9iaiA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1snbW9jayddLnVyaTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi90c29sL2tleS81YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcpXG4gICAgICAgIC5yZXBseSgyMDAsIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGZha2VQcnYsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgIC8vIE1vY2sgdGhlIEFQSSByZXNwb25zZSBmb3IgYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbnNcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0LzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwL2NvbnNvbGlkYXRlQWNjb3VudC9idWlsZCcpXG4gICAgICAgIC5yZXBseSgyMDAsIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eFJlcXVlc3RJZDogJzRmZGQwY2FlLTI1NjMtNDNiMS1iNWNmLTk0ODY1MTU4Y2ExMCcsXG4gICAgICAgICAgICB3YWxsZXRJZDogJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZmQ0YjBmYTZkJyxcbiAgICAgICAgICAgIHR4SGV4OlxuICAgICAgICAgICAgICAnMDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDZmNTAxMzBhYmY4ZDBkODk0M2M1YjlhNTFhNTc0ODg2YTdkN2IzZDhkYjE4ZjBkZGI0YWI4YjZkM2VjMjdlM2MyZjM2ZjMzMzliYjkyZDQyOTZhZjZhZTRkM2FiZmJiMDc4NzdmNzdkMDAzM2M4ODNkZTA4ZmE0YTJlZWE2NzBkMDIwMTAyMDY3NGE5ZGYyYjk0YWE0YjRhZGExMjAyZGMyODkxYmUzNjY1MDFkMGFjYjRhMDFjYTNlMDJlN2ZkNmMxZjUwNWE3MWM5NjE3MjA0NGYxMjE3YzM3ODRlOGYwMmY0OWUyYzhmYzM1OTFlODEyOTRhYjU0Mzk0ZjlkMjJmZDdiN2E4Zjg0MDFjM2Y2N2NmYTUyNTE4YjM0YTA5YjA4ZjRlYTc3ZTFjNGZiOWQ4OWJmYWNjZGMzM2NmOGI4YTljZjhkN2JmMGUwNGM4OWM1MDQyOGU0ZWRhNWNiYjc1OTQyN2MzNzBmMGEyOWE1MGJiMGQxNDA3ZTU3OTI0YjBjYzViMzZmMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDA0MGM5NTY4MTk1ZDY3ZWI2YjM5NmZkYmU5N2JhMmUyNzY2MjJlZjAwMjNhZjA5ZjIzZTZlMDI5MmFiYjY3OGQ5MDIwNDAzMDMwNTAxMDQwNDAwMDAwMDA0MDIwMDAyMGMwMjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgICBmZWU6IDEwMDAwLFxuICAgICAgICAgICAgICBmZWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgICAgIG1pbmVyRmVlOiAnMTAwMDAnLFxuICAgICAgICAgICAgICBzcGVuZEFtb3VudDogJzE1NDc4NjQnLFxuICAgICAgICAgICAgICBzcGVuZEFtb3VudHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBjb2luTmFtZTogJ3Rzb2wnLFxuICAgICAgICAgICAgICAgICAgYW1vdW50U3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGFkZHJlc3M6ICc4clFYZVZFTXJLdnRXQ0VKaXJFTTZjS1luYlp1VHFWVGJxUlBpTU1BSjhSNCcsXG4gICAgICAgICAgICAgICAgICB2YWx1ZTogMTU0Nzg2NCxcbiAgICAgICAgICAgICAgICAgIHdhbGxldDogJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZicsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRzOiBbJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZiddLFxuICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZTogJzYyZDcxYTZiODYwNjhmMDAwOGYwMjlmZCcsXG4gICAgICAgICAgICAgICAgICBlbnRlcnByaXNlczogWyc2MmQ3MWE2Yjg2MDY4ZjAwMDhmMDI5ZmQnXSxcbiAgICAgICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICAgICAgICBjb2luTmFtZTogJ3Rzb2wnLFxuICAgICAgICAgICAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRUeXBlczogWydob3QnXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZTogMTU0Nzg2NCxcbiAgICAgICAgICAgICAgICAgIGFkZHJlc3M6ICdDbVlzTjNmOGJjbTRCRGtGSldOc3ZZZ2pSeE1UTEg2dmJKV05mWWRtSDdHVScsXG4gICAgICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzE1NDc4NjQnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgICAgYWRkcmVzczogJ0NtWXNOM2Y4YmNtNEJEa0ZKV05zdllnalJ4TVRMSDZ2YkpXTmZZZG1IN0dVJyxcbiAgICAgICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuXG4gICAgICAvLyBDYWxsIHRoZSBmdW5jdGlvbiB0byB0ZXN0XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHdhbGxldE9iai5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiAndHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIGFkZHJlc3MnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdmFsaWQgYSBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgY29uc29saWRhdGlvblR4ID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogJzRmZGQwY2FlLTI1NjMtNDNiMS1iNWNmLTk0ODY1MTU4Y2ExMCcsXG4gICAgICAgIHdhbGxldElkOiAnNjMwNjhlZDRlZmE2M2EwMDA4NzdmMDJmZDRiMGZhNmQnLFxuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnMDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDIwMTAyMDZhZWRhMjUzYTMzMWRlNDg5ODM4MjQ2ZGY5Mzg3OTQ0MGFmOGM2MmFjNDk2NzY1OGVkYzJiYjVkNTJiOTc1OWQ5MWM5NjE3MjA0NGYxMjE3YzM3ODRlOGYwMmY0OWUyYzhmYzM1OTFlODEyOTRhYjU0Mzk0ZjlkMjJmZDdiN2E4Zjc0YTlkZjJiOTRhYTRiNGFkYTEyMDJkYzI4OTFiZTM2NjUwMWQwYWNiNGEwMWNhM2UwMmU3ZmQ2YzFmNTA1YTdkMjczNGYzOTUyZjNlYjRhZWZjZjZjN2E2MDkyZTk3OWRkM2ZlNTU2M2NjZmFjYTFjYzkyNjUyYTE1ZGRkMzkzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDA0MjhkYWQ0MWJiZWRlYjM4MDE4Mzc5ZTRjZWViN2U4MDc1N2Q3NGRkMDBhZThjNDdjMzhkNTk3NDc3MzM5YWQ4MDIwNDAzMDMwNTAxMDQwNDAwMDAwMDA0MDIwMDAyMGMwMjAwMDAwMDU4OWUxNzAwMDAwMDAwMDAnLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAxMDAwMCxcbiAgICAgICAgICBmZWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgIG1pbmVyRmVlOiAnMTAwMDAnLFxuICAgICAgICAgIHNwZW5kQW1vdW50OiAnMTU0Nzg2NCcsXG4gICAgICAgICAgc3BlbmRBbW91bnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAndHNvbCcsXG4gICAgICAgICAgICAgIGFtb3VudFN0cmluZzogJzE1NDc4NjQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBheUdvRmVlOiAnMCcsXG4gICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnOHJRWGVWRU1yS3Z0V0NFSmlyRU02Y0tZbmJadVRxVlRicVJQaU1NQUo4UjQnLFxuICAgICAgICAgICAgICB2YWx1ZTogMTU0Nzg2NCxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnNjMwNjhlZDRlZmE2M2EwMDA4NzdmMDJmJyxcbiAgICAgICAgICAgICAgd2FsbGV0czogWyc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmYnXSxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZTogJzYyZDcxYTZiODYwNjhmMDAwOGYwMjlmZCcsXG4gICAgICAgICAgICAgIGVudGVycHJpc2VzOiBbJzYyZDcxYTZiODYwNjhmMDAwOGYwMjlmZCddLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzE1NDc4NjQnLFxuICAgICAgICAgICAgICBjb2luTmFtZTogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgd2FsbGV0VHlwZXM6IFsnaG90J10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHZhbHVlOiAxNTQ3ODY0LFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnQ21Zc04zZjhiY200QkRrRkpXTnN2WWdqUnhNVExINnZiSldOZllkbUg3R1UnLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzE1NDc4NjQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnQ21Zc04zZjhiY200QkRrRkpXTnN2WWdqUnhNVExINnZiSldOZllkbUg3R1UnLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldDogUGFydGlhbDxJV2FsbGV0PiA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY3MgPSB7XG4gICAgICAgICAgICByb290QWRkcmVzczogJzhyUVhlVkVNckt2dFdDRUppckVNNmNLWW5iWnVUcVZUYnFSUGlNTUFKOFI0JyxcbiAgICAgICAgICB9IGFzIFdhbGxldENvaW5TcGVjaWZpYztcbiAgICAgICAgICByZXR1cm4gY3M7XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIShhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICBibG9ja2hhc2g6ICcnLFxuICAgICAgICAgICAgZmVlUGF5ZXI6ICcnLFxuICAgICAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogY29uc29saWRhdGlvblR4IGFzIHVua25vd24gYXMgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgSVdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSkpXG4gICAgICAgICkge1xuICAgICAgICAgIGFzc2VydC5mYWlsKCdUcmFuc2FjdGlvbiBzaG91bGQgcGFzcyB2ZXJpZmljYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhc3NlcnQuZmFpbCgnVHJhbnNhY3Rpb24gc2hvdWxkIHBhc3MgdmVyaWZpY2F0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHRva2VuIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmZkNGIwZmE2ZCcsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcwMmI3YzJjNzgyOWVkZWQ0ZThmOTQ3YzkwZWQzYjlhZmNlNzFmNjE2ZWI0N2RmY2ZiZjRiNzY1Nzc4MTQ5MDYwMDEzYWNiMzNiOWY2N2ZkZDljMjUxMmY0OGZhYzRlNGMwNDllYWI5MzgyOWI2OTQwNGYzYmQxNjZmZTMyNDJjOTA3MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAxMDQwOTZkYTY5MGJkNTU4ZmQ4NjM0YWMxNGYxNjQ1ZDgwOTVhZmQwY2FlYTU5NTM1NzhjNTk2ZTNjMGRlYTM4MzA1ZWU3Mjk4YmZhYzU1MTAxZjE3NzczNTY1OWQ0MmVkNmJlODkwZWYzYTFkMjA0ZDllMzNmMzJlMjRjNTYzNTMyN2NhNjZkMWZlMDA4MjZlNWE0Zjc1OWY4N2IyNzljMWFlZTE5Y2NlNTMwMWFmNGVkNjZhZTE3ZGI0OGIyMDFlZDZjMmEwZThhMjhiZjU2NTYyN2YxYWI4YTM0YjFhOTVlZTFiMGEyYTM5MDg0ZjFmMGUyYWNiMWMzOTRiMjAxODVkOGUwYjIyNjU3YzhkOWM0Y2U1ZjY0OTVlZmI2NDEwYzE5OTAxMTUzMGY5MGUzYWI5ZDhkMWU0MjA2ZjlhZTBmZmViMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGM1ZjlmYjMyZjQ5MTExYWIyMGMzM2YyNTk4ZmM4MzZjMTEzZTI5MTg4MWFjMjFlZTI5MTY5Mzk0MDExMjQ0ZTQwNmE3ZDUxNzE5MmM1NjhlZTA4YTg0NWY3M2QyOTc4OGNmMDM1YzMxNDViMjFhYjM0NGQ4MDYyZWE5NDAwMDAwMDZkZGY2ZTFkNzY1YTE5M2Q5Y2JlMTQ2Y2VlYjc5YWMxY2I0ODVlZDVmNWIzNzkxM2E4Y2Y1ODU3ZWZmMDBhOWRlMTNjNzRkMmI0ZDk0OGUxNjA4ZWE2ZWViZGFmZTc1YmMyZjk5NWFhZDExYjIxZDFlMmM5NGYyYTJkMTJmNjgwMjA1MDMwMzA3MDAwNDA0MDAwMDAwMDgwNDAyMDYwNDAxMGEwY2UwMDc2YmIyMDQwMDAwMDAwNicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6IDEwMDAwLFxuICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICc4aUxhMjZLU2JkcEJVek5LN3VZcThGdnl1eUE1aDRrNGVyREhzRGNQYkh1cycsXG4gICAgICAgICAgICAgIHZhbHVlOiAyLjAxNzMyMjhlMTAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzhQMmtYN1R5aDllUzNSS2RhQmhxYkV0UUdBWDU4RFh6TDdtaERRQUJHWDJkJyxcbiAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtaW5lckZlZTogJzEwMDAwJyxcbiAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICdIQnhaU2hjRTg2VU1tRjkzS1VNOGVXSktxZUVYaTVjcVdDTFlMTU1ocU1ZbScsXG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAnc29sOndpZicsXG4gICAgICAgICAgICAgIGVudGVycHJpc2U6IHtcbiAgICAgICAgICAgICAgICAkb2lkOiAnNTU1M2JhOGFlN2E1Yzc3MDA2NzE5NjYxJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZXM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAkb2lkOiAnNTU1M2JhOGFlN2E1Yzc3MDA2NzE5NjYxJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB2YWx1ZTogMi4wMTczMjI4ZTEwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiB7XG4gICAgICAgICAgICAgICAgJG9pZDogJzYyZjRjMzcyMGQ5MmM1MDAwODI1N2ViNScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgJG9pZDogJzYyZjRjMzcyMGQ5MmM1MDAwODI1N2ViNScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXlHb0ZlZTogJzAnLFxuICAgICAgICAgIHNwZW5kQW1vdW50OiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgIHNwZW5kQW1vdW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnRTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAnc29sOndpZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICB9LFxuICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjcxMmQ3ZmRhNmRlNDkwNmQ2NThjMDRhZWJiZjhmOWInLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQ6IFBhcnRpYWw8SVdhbGxldD4gPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNzID0ge1xuICAgICAgICAgICAgcm9vdEFkZHJlc3M6ICdIQnhaU2hjRTg2VU1tRjkzS1VNOGVXSktxZUVYaTVjcVdDTFlMTU1ocU1ZbScsXG4gICAgICAgICAgfSBhcyBXYWxsZXRDb2luU3BlY2lmaWM7XG4gICAgICAgICAgcmV0dXJuIGNzO1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEoYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgYmxvY2toYXNoOiAnJyxcbiAgICAgICAgICAgIGZlZVBheWVyOiAnJyxcbiAgICAgICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IGNvbnNvbGlkYXRpb25UeCBhcyB1bmtub3duIGFzIFRyYW5zYWN0aW9uUHJlYnVpbGQsXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0IGFzIElXYWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKVxuICAgICAgICApIHtcbiAgICAgICAgICBhc3NlcnQuZmFpbCgnVHJhbnNhY3Rpb24gc2hvdWxkIHBhc3MgdmVyaWZpY2F0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ1RyYW5zYWN0aW9uIHNob3VsZCBwYXNzIHZlcmlmaWNhdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBzcG9vZmVkIHRva2VuIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmZkNGIwZmE2ZCcsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcwMmI3YzJjNzgyOWVkZWQ0ZThmOTQ3YzkwZWQzYjlhZmNlNzFmNjE2ZWI0N2RmY2ZiZjRiNzY1Nzc4MTQ5MDYwMDEzYWNiMzNiOWY2N2ZkZDljMjUxMmY0OGZhYzRlNGMwNDllYWI5MzgyOWI2OTQwNGYzYmQxNjZmZTMyNDJjOTA3MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAxMDQwOTZkYTY5MGJkNTU4ZmQ4NjM0YWMxNGYxNjQ1ZDgwOTVhZmQwY2FlYTU5NTM1NzhjNTk2ZTNjMGRlYTM4MzA1ZWU3Mjk4YmZhYzU1MTAxZjE3NzczNTY1OWQ0MmVkNmJlODkwZWYzYTFkMjA0ZDllMzNmMzJlMjRjNTYzNTMyN2NhNjZkMWZlMDA4MjZlNWE0Zjc1OWY4N2IyNzljMWFlZTE5Y2NlNTMwMWFmNGVkNjZhZTE3ZGI0OGIyMDFlZDZjMmEwZThhMjhiZjU2NTYyN2YxYWI4YTM0YjFhOTVlZTFiMGEyYTM5MDg0ZjFmMGUyYWNiMWMzOTRiMjAxODVkOGUwYjIyNjU3YzhkOWM0Y2U1ZjY0OTVlZmI2NDEwYzE5OTAxMTUzMGY5MGUzYWI5ZDhkMWU0MjA2ZjlhZTBmZmViMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGM1ZjlmYjMyZjQ5MTExYWIyMGMzM2YyNTk4ZmM4MzZjMTEzZTI5MTg4MWFjMjFlZTI5MTY5Mzk0MDExMjQ0ZTQwNmE3ZDUxNzE5MmM1NjhlZTA4YTg0NWY3M2QyOTc4OGNmMDM1YzMxNDViMjFhYjM0NGQ4MDYyZWE5NDAwMDAwMDZkZGY2ZTFkNzY1YTE5M2Q5Y2JlMTQ2Y2VlYjc5YWMxY2I0ODVlZDVmNWIzNzkxM2E4Y2Y1ODU3ZWZmMDBhOWRlMTNjNzRkMmI0ZDk0OGUxNjA4ZWE2ZWViZGFmZTc1YmMyZjk5NWFhZDExYjIxZDFlMmM5NGYyYTJkMTJmNjgwMjA1MDMwMzA3MDAwNDA0MDAwMDAwMDgwNDAyMDYwNDAxMGEwY2UwMDc2YmIyMDQwMDAwMDAwNicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6IDEwMDAwLFxuICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICc4aUxhMjZLU2JkcEJVek5LN3VZcThGdnl1eUE1aDRrNGVyREhzRGNQYkh1cycsXG4gICAgICAgICAgICAgIHZhbHVlOiAyLjAxNzMyMjhlMTAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzhQMmtYN1R5aDllUzNSS2RhQmhxYkV0UUdBWDU4RFh6TDdtaERRQUJHWDJkJyxcbiAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtaW5lckZlZTogJzEwMDAwJyxcbiAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICdIQnhaU2hjRTg2VU1tRjkzS1VNOGVXSktxZUVYaTVjcVdDTFlMTU1ocU1ZbScsXG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAnc29sOndpZicsXG4gICAgICAgICAgICAgIGVudGVycHJpc2U6IHtcbiAgICAgICAgICAgICAgICAkb2lkOiAnNTU1M2JhOGFlN2E1Yzc3MDA2NzE5NjYxJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZXM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAkb2lkOiAnNTU1M2JhOGFlN2E1Yzc3MDA2NzE5NjYxJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB2YWx1ZTogMi4wMTczMjI4ZTEwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiB7XG4gICAgICAgICAgICAgICAgJG9pZDogJzYyZjRjMzcyMGQ5MmM1MDAwODI1N2ViNScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgJG9pZDogJzYyZjRjMzcyMGQ5MmM1MDAwODI1N2ViNScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXlHb0ZlZTogJzAnLFxuICAgICAgICAgIHNwZW5kQW1vdW50OiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgIHNwZW5kQW1vdW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnRTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAnc29sOndpZicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICB9LFxuICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjcxMmQ3ZmRhNmRlNDkwNmQ2NThjMDRhZWJiZjhmOWInLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQ6IFBhcnRpYWw8SVdhbGxldD4gPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNzID0ge1xuICAgICAgICAgICAgcm9vdEFkZHJlc3M6ICc4clFYZVZFTXJLdnRXQ0VKaXJFTTZjS1luYlp1VHFWVGJxUlBpTU1BSjhSNCcsXG4gICAgICAgICAgfSBhcyBXYWxsZXRDb2luU3BlY2lmaWM7XG4gICAgICAgICAgcmV0dXJuIGNzO1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+XG4gICAgICAgICAgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgYmxvY2toYXNoOiAnJyxcbiAgICAgICAgICAgIGZlZVBheWVyOiAnJyxcbiAgICAgICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IGNvbnNvbGlkYXRpb25UeCBhcyB1bmtub3duIGFzIFRyYW5zYWN0aW9uUHJlYnVpbGQsXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0IGFzIElXYWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTogJ3R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCBhZGRyZXNzJyxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2JsaW5kIHNpZ25pbmcgdG9rZW4gZW5hYmxlbWVudCBwcm90ZWN0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFzIHZhbGlkIHRoZSBlbmFibGV0b2tlbiBpbnRlbnQgd2hlbiBwcmVidWlsZCB0eCBtYXRjaHMgdXNlciBpbnRlbnQgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZFJhdywgd2FsbGV0RGF0YSB9ID0gdGVzdERhdGEuZW5hYmxlVG9rZW5GaXh0dXJlcztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICAgIGNvbnN0IHNhbWVJbnRlbnRUeCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGRSYXcsXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uOiB7IHZlcmlmeVRva2VuRW5hYmxlbWVudDogdHJ1ZSB9LFxuICAgICAgfSBhcyB1bmtub3duIGFzIFNvbFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk7XG5cbiAgICAgIHNhbWVJbnRlbnRUeC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93biBhbiBlcnJvciB3aGVuIHRhbXBlcmVkIHByZWJ1aWxkIHR4IHR5cGUgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZFJhdywgc2VuZFR4SGV4LCB3YWxsZXREYXRhIH0gPSB0ZXN0RGF0YS5lbmFibGVUb2tlbkZpeHR1cmVzO1xuICAgICAgY29uc3QgdGFtcGVyZWRUeFByZWJ1aWxkID0geyAuLi50eFByZWJ1aWxkUmF3LCB0eEhleDogc2VuZFR4SGV4IH07XG5cbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+XG4gICAgICAgICAgYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB0YW1wZXJlZFR4UHJlYnVpbGQsXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHsgdmVyaWZ5VG9rZW5FbmFibGVtZW50OiB0cnVlIH0sXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFNvbFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyksXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgJ0ludmFsaWQgdHJhbnNhY3Rpb24gdHlwZSBvbiB0b2tlbiBlbmFibGVtZW50OiBleHBlY3RlZCBcIkFzc29jaWF0ZWRUb2tlbkFjY291bnRJbml0aWFsaXphdGlvblwiLCBnb3QgXCJTZW5kXCIuJyxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHRoYXQgdG9rZW5OYW1lIG1hdGNoZXMgYmV0d2VlbiB1c2VyIGludGVudCBhbmQgaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZFJhdywgd3JvbmdUb2tlbk5hbWVUeEhleCwgd2FsbGV0RGF0YSB9ID0gdGVzdERhdGEuZW5hYmxlVG9rZW5GaXh0dXJlcztcbiAgICAgIGNvbnN0IHRhbXBlcmVkVHhQcmVidWlsZCA9IHsgLi4udHhQcmVidWlsZFJhdywgdHhIZXg6IHdyb25nVG9rZW5OYW1lVHhIZXggfTtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+XG4gICAgICAgICAgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB0YW1wZXJlZFR4UHJlYnVpbGQsXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHsgdmVyaWZ5VG9rZW5FbmFibGVtZW50OiB0cnVlIH0sXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFNvbFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyksXG4gICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgdG9rZW4gbmFtZTogZXhwZWN0ZWQgdHNvbDpyYXksIGdvdCB0c29sOnQyMm1pbnQgb24gdG9rZW4gZW5hYmxlbWVudCB0eCcgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHRoYXQgdG9rZW5BZGRyIG1hdGNoZXMgYmV0d2VlbiB1c2VyIGludGVudCBhbmQgaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZFJhdywgd3JvbmdBZGRyVHhIZXgsIHdhbGxldERhdGEgfSA9IHRlc3REYXRhLmVuYWJsZVRva2VuRml4dHVyZXM7XG4gICAgICBjb25zdCB0YW1wZXJlZFR4UHJlYnVpbGQgPSB7IC4uLnR4UHJlYnVpbGRSYXcsIHR4SGV4OiB3cm9uZ0FkZHJUeEhleCB9O1xuXG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHRhbXBlcmVkVHhQcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjogeyB2ZXJpZnlUb2tlbkVuYWJsZW1lbnQ6IHRydWUgfSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgU29sVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAnSW52YWxpZCB0b2tlbiBhZGRyZXNzOiBleHBlY3RlZCA0YlRZdnZ2MkhrNHYya1FXOEhaRkZTNFN6WVB6dFFzaHc5R20xc3VYbWFCaiwgZ290IEcxTEVnQU5Bd0tvN2I4TmZ4VHNNenJiQllEa1hxaTVSRVZKWTh0aHJNUlFtIG9uIHRva2VuIGVuYWJsZW1lbnQgdHgnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHNlbmRUb2tlbkVuYWJsZW1lbnQgY2FsbCBvbiBzcG9vZmVkIGRhdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IHNlbmRUb2tlbkVuYWJsZW1lbnRQYXlsb2FkLCB3YWxsZXREYXRhLCB3cm9uZ1Rva2VuTmFtZVR4SGV4IH0gPSB0ZXN0RGF0YS5lbmFibGVUb2tlbkZpeHR1cmVzO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykuZ2V0KCcvYXBpL3YyL3Rzb2wva2V5LzY4YmFmZWQ1ODg2NzFjZjk0ZWQ4YTVkYmJhODgyYWQzJykucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICB3YWxsZXQuc2VuZFRva2VuRW5hYmxlbWVudCh7XG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHsgdmVyaWZ5VG9rZW5FbmFibGVtZW50OiB0cnVlIH0sXG4gICAgICAgICAgICAuLi5zZW5kVG9rZW5FbmFibGVtZW50UGF5bG9hZCxcbiAgICAgICAgICAgIHByZWJ1aWxkVHg6IHsgLi4uc2VuZFRva2VuRW5hYmxlbWVudFBheWxvYWQucHJlYnVpbGRUeCwgdHhIZXg6IHdyb25nVG9rZW5OYW1lVHhIZXggfSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgUHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb25PcHRpb25zKSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHRva2VuIG5hbWU6IGV4cGVjdGVkIHRzb2w6cmF5LCBnb3QgdHNvbDp0MjJtaW50IG9uIHRva2VuIGVuYWJsZW1lbnQgdHgnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNXYWxsZXRBZGRyZXNzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHZhbGlkIHdhbGxldCBhZGRyZXNzIHdpdGggY29ycmVjdCBrZXljaGFpbiBhbmQgaW5kZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzdZQWVzZndQazQxVkNoVWdyNjVibThGRWVwN3ltV3FMU1c1cnBZQjV6WlBZJztcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzhlYTMyZWNhY2ZjODNlZmZiZDJlMjc5MGVlNDRmYTdjNTliNGQ4NmMyOWExMmYwOWZiNjEzZDgxOTVmOTNmNGUyMTg3NWNhZDNiOThhZGFkYTQwYzA0MGM1NGMzNTY5NDY3ZGY0MWEwMjA4ODFhNjE4NDA5NjM3ODcwMTg2MmJkJztcbiAgICAgIGNvbnN0IGluZGV4ID0gJzEnO1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW3sgaWQ6ICcxJywgdHlwZTogJ3RzcycgYXMgY29uc3QsIGNvbW1vbktleWNoYWluIH1dO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MoeyBrZXljaGFpbnMsIGFkZHJlc3MsIGluZGV4IH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGFkZHJlc3Mgd2l0aCBpbmNvcnJlY3Qga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzdZQWVzZndQazQxVkNoVWdyNjVibThGRWVwN3ltV3FMU1c1cnBZQjV6WlBZJztcbiAgICAgIGNvbnN0IHdyb25nS2V5Y2hhaW4gPVxuICAgICAgICAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCc7XG4gICAgICBjb25zdCBpbmRleCA9ICcxJztcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGlkOiAnMScsIHR5cGU6ICd0c3MnIGFzIGNvbnN0LCBjb21tb25LZXljaGFpbjogd3JvbmdLZXljaGFpbiB9XTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzLCBpbmRleCB9KSwge1xuICAgICAgICBtZXNzYWdlOiBgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6ICR7YWRkcmVzc30gaXMgbm90IGEgd2FsbGV0IGFkZHJlc3NgLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBhZGRyZXNzIHdpdGggaW5jb3JyZWN0IGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICc3WUFlc2Z3UGs0MVZDaFVncjY1Ym04RkVlcDd5bVdxTFNXNXJwWUI1elpQWSc7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICc4ZWEzMmVjYWNmYzgzZWZmYmQyZTI3OTBlZTQ0ZmE3YzU5YjRkODZjMjlhMTJmMDlmYjYxM2Q4MTk1ZjkzZjRlMjE4NzVjYWQzYjk4YWRhZGE0MGMwNDBjNTRjMzU2OTQ2N2RmNDFhMDIwODgxYTYxODQwOTYzNzg3MDE4NjJiZCc7XG4gICAgICBjb25zdCB3cm9uZ0luZGV4ID0gJzk5OSc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXg6IHdyb25nSW5kZXggfSksIHtcbiAgICAgICAgbWVzc2FnZTogYGFkZHJlc3MgdmFsaWRhdGlvbiBmYWlsdXJlOiAke2FkZHJlc3N9IGlzIG5vdCBhIHdhbGxldCBhZGRyZXNzYCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEFkZHJlc3MgPSAnaW52YWxpZGFkZHJlc3MnO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnOGVhMzJlY2FjZmM4M2VmZmJkMmUyNzkwZWU0NGZhN2M1OWI0ZDg2YzI5YTEyZjA5ZmI2MTNkODE5NWY5M2Y0ZTIxODc1Y2FkM2I5OGFkYWRhNDBjMDQwYzU0YzM1Njk0NjdkZjQxYTAyMDg4MWE2MTg0MDk2Mzc4NzAxODYyYmQnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMSc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzczogaW52YWxpZEFkZHJlc3MsIGluZGV4IH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6IGBpbnZhbGlkIGFkZHJlc3M6ICR7aW52YWxpZEFkZHJlc3N9YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYWRkcmVzcyB3aXRoIGRlcml2YXRpb24gcHJlZml4IGZvciBTTUMgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEFkZHJlc3MgZGVyaXZlZCB3aXRoIGRlcml2YXRpb24gcHJlZml4IG0vOTk5OTk5LzE0ODI0MjM1NS8yMzkzMzY4NDUvMVxuICAgICAgY29uc3QgYWRkcmVzcyA9ICdDQzcxNVE5MkM4dnVFRlQ1eHVqRTU1RG82QmtXUmRwRHZyN1ZoOGlVTlVCdyc7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICc4ZWEzMmVjYWNmYzgzZWZmYmQyZTI3OTBlZTQ0ZmE3YzU5YjRkODZjMjlhMTJmMDlmYjYxM2Q4MTk1ZjkzZjRlMjE4NzVjYWQzYjk4YWRhZGE0MGMwNDBjNTRjMzU2OTQ2N2RmNDFhMDIwODgxYTYxODQwOTYzNzg3MDE4NjJiZCc7XG4gICAgICBjb25zdCBpbmRleCA9ICcxJztcbiAgICAgIGNvbnN0IGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQgPSAnc21jLXRlc3Qtc2VlZC0xMjMnO1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW3sgaWQ6ICcxJywgdHlwZTogJ3RzcycgYXMgY29uc3QsIGNvbW1vbktleWNoYWluIH1dO1xuXG4gICAgICAvLyBUaGlzIHRlc3QgdmVyaWZpZXMgdGhhdCBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkIGlzIGFjY2VwdGVkIGFzIGEgcGFyYW1ldGVyXG4gICAgICAvLyBhbmQgdGhlIHZlcmlmaWNhdGlvbiBmdW5jdGlvbiBjb3JyZWN0bHkgY29tcHV0ZXMgdGhlIGRlcml2YXRpb24gcHJlZml4IGludGVybmFsbHlcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXgsIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHB1YmxpYyBrZXkgdG8gYmFzZTU4IGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSAnNjEyMjBhOTM5NDgwMmIxZDFkZjM3YjM1ZjdhMzE5Nzk3MGY0ODA4MTA5MmNlZTAxMWZjOThmN2I3MWIyYmQ0Myc7XG4gICAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSAnN1lBZXNmd1BrNDFWQ2hVZ3I2NWJtOEZFZXA3eW1XcUxTVzVycFlCNXpaUFknO1xuXG4gICAgICBjb25zdCBhZGRyZXNzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KTtcbiAgICAgIGFkZHJlc3Muc2hvdWxkLmVxdWFsKGV4cGVjdGVkQWRkcmVzcyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=