@bitgo-beta/sdk-coin-sol 7.6.4-beta.31 → 7.6.4-beta.310

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 (395) 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.map +1 -0
  10. package/dist/cjs/src/lib/closeAtaBuilder.js +69 -0
  11. package/dist/{src → cjs/src}/lib/constants.d.ts +24 -0
  12. package/dist/cjs/src/lib/constants.d.ts.map +1 -0
  13. package/dist/cjs/src/lib/constants.js +196 -0
  14. package/dist/cjs/src/lib/customInstructionBuilder.d.ts.map +1 -0
  15. package/dist/cjs/src/lib/customInstructionBuilder.js +289 -0
  16. package/dist/cjs/src/lib/explainTransactionWasm.d.ts +21 -0
  17. package/dist/cjs/src/lib/explainTransactionWasm.d.ts.map +1 -0
  18. package/dist/cjs/src/lib/explainTransactionWasm.js +264 -0
  19. package/dist/{src → cjs/src}/lib/iface.d.ts +20 -2
  20. package/dist/cjs/src/lib/iface.d.ts.map +1 -0
  21. package/dist/cjs/src/lib/iface.js +7 -0
  22. package/dist/{src → cjs/src}/lib/index.d.ts +1 -0
  23. package/dist/cjs/src/lib/index.d.ts.map +1 -0
  24. package/dist/{src → cjs/src}/lib/index.js +4 -2
  25. package/dist/{src → cjs/src}/lib/instructionParamsFactory.d.ts +1 -0
  26. package/dist/cjs/src/lib/instructionParamsFactory.d.ts.map +1 -0
  27. package/dist/cjs/src/lib/instructionParamsFactory.js +1059 -0
  28. package/dist/cjs/src/lib/jitoStakePoolOperations.d.ts.map +1 -0
  29. package/dist/cjs/src/lib/jitoStakePoolOperations.js +200 -0
  30. package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
  31. package/dist/cjs/src/lib/keyPair.js +63 -0
  32. package/dist/cjs/src/lib/messages/index.d.ts.map +1 -0
  33. package/dist/{src → cjs/src}/lib/messages/index.js +1 -1
  34. package/dist/cjs/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  35. package/dist/cjs/src/lib/messages/messageBuilderFactory.js +19 -0
  36. package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts +25 -0
  37. package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
  38. package/dist/cjs/src/lib/recoverNestedAtaBuilder.js +90 -0
  39. package/dist/cjs/src/lib/solInstructionFactory.d.ts.map +1 -0
  40. package/dist/cjs/src/lib/solInstructionFactory.js +595 -0
  41. package/dist/cjs/src/lib/stakingActivateBuilder.d.ts.map +1 -0
  42. package/dist/cjs/src/lib/stakingActivateBuilder.js +120 -0
  43. package/dist/cjs/src/lib/stakingAuthorizeBuilder.d.ts.map +1 -0
  44. package/dist/cjs/src/lib/stakingAuthorizeBuilder.js +89 -0
  45. package/dist/cjs/src/lib/stakingDeactivateBuilder.d.ts.map +1 -0
  46. package/dist/cjs/src/lib/stakingDeactivateBuilder.js +208 -0
  47. package/dist/cjs/src/lib/stakingDelegateBuilder.d.ts.map +1 -0
  48. package/dist/cjs/src/lib/stakingDelegateBuilder.js +120 -0
  49. package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
  50. package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.js +110 -0
  51. package/dist/cjs/src/lib/stakingWithdrawBuilder.d.ts.map +1 -0
  52. package/dist/cjs/src/lib/stakingWithdrawBuilder.js +78 -0
  53. package/dist/cjs/src/lib/token2022Config.d.ts.map +1 -0
  54. package/dist/cjs/src/lib/token2022Config.js +27 -0
  55. package/dist/cjs/src/lib/tokenTransferBuilder.d.ts.map +1 -0
  56. package/dist/cjs/src/lib/tokenTransferBuilder.js +188 -0
  57. package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
  58. package/dist/cjs/src/lib/transaction.js +612 -0
  59. package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
  60. package/dist/cjs/src/lib/transactionBuilder.js +380 -0
  61. package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +5 -0
  62. package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  63. package/dist/cjs/src/lib/transactionBuilderFactory.js +209 -0
  64. package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
  65. package/dist/cjs/src/lib/transferBuilder.js +70 -0
  66. package/dist/cjs/src/lib/transferBuilderV2.d.ts.map +1 -0
  67. package/dist/cjs/src/lib/transferBuilderV2.js +210 -0
  68. package/dist/cjs/src/lib/utils.d.ts.map +1 -0
  69. package/dist/cjs/src/lib/utils.js +595 -0
  70. package/dist/cjs/src/lib/walletInitializationBuilder.d.ts.map +1 -0
  71. package/dist/cjs/src/lib/walletInitializationBuilder.js +71 -0
  72. package/dist/cjs/src/register.d.ts.map +1 -0
  73. package/dist/cjs/src/register.js +15 -0
  74. package/dist/{src → cjs/src}/sol.d.ts +40 -0
  75. package/dist/cjs/src/sol.d.ts.map +1 -0
  76. package/dist/cjs/src/sol.js +1402 -0
  77. package/dist/cjs/src/solToken.d.ts.map +1 -0
  78. package/dist/cjs/src/solToken.js +69 -0
  79. package/dist/cjs/src/tsol.d.ts.map +1 -0
  80. package/dist/cjs/src/tsol.js +24 -0
  81. package/dist/{test → cjs/test}/fixtures/sol.d.ts.map +1 -1
  82. package/dist/cjs/test/fixtures/sol.js +1433 -0
  83. package/dist/{test → cjs/test}/resources/sol.d.ts +27 -27
  84. package/dist/cjs/test/resources/sol.d.ts.map +1 -0
  85. package/dist/cjs/test/resources/sol.js +320 -0
  86. package/dist/cjs/test/unit/explainTransactionWasm.d.ts +5 -0
  87. package/dist/cjs/test/unit/explainTransactionWasm.d.ts.map +1 -0
  88. package/dist/cjs/test/unit/explainTransactionWasm.js +26 -0
  89. package/dist/cjs/test/unit/fixtures/solBackupKey.d.ts.map +1 -0
  90. package/dist/cjs/test/unit/fixtures/solBackupKey.js +8 -0
  91. package/dist/cjs/test/unit/getBuilderFactory.d.ts.map +1 -0
  92. package/dist/cjs/test/unit/getBuilderFactory.js +10 -0
  93. package/dist/cjs/test/unit/instructionParamsFactory.d.ts.map +1 -0
  94. package/dist/cjs/test/unit/instructionParamsFactory.js +412 -0
  95. package/dist/cjs/test/unit/instructionParamsFactory.staking.d.ts.map +1 -0
  96. package/dist/cjs/test/unit/instructionParamsFactory.staking.js +1059 -0
  97. package/dist/cjs/test/unit/jitoWasmVerification.d.ts +2 -0
  98. package/dist/cjs/test/unit/jitoWasmVerification.d.ts.map +1 -0
  99. package/dist/cjs/test/unit/jitoWasmVerification.js +78 -0
  100. package/dist/{test → cjs/test}/unit/keyPair.d.ts.map +1 -1
  101. package/dist/cjs/test/unit/keyPair.js +177 -0
  102. package/dist/cjs/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  103. package/dist/cjs/test/unit/messages/messageBuilderFactory.js +118 -0
  104. package/dist/cjs/test/unit/messages/simpleMessageBuilder.d.ts.map +1 -0
  105. package/dist/cjs/test/unit/messages/simpleMessageBuilder.js +194 -0
  106. package/dist/{test → cjs/test}/unit/sol.d.ts.map +1 -1
  107. package/dist/cjs/test/unit/sol.js +3326 -0
  108. package/dist/cjs/test/unit/solInstructionFactory.d.ts.map +1 -0
  109. package/dist/cjs/test/unit/solInstructionFactory.js +454 -0
  110. package/dist/cjs/test/unit/solToken.d.ts.map +1 -0
  111. package/dist/cjs/test/unit/solToken.js +31 -0
  112. package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
  113. package/dist/cjs/test/unit/transaction.js +1108 -0
  114. package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +1 -0
  115. package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.js +202 -0
  116. package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +1 -0
  117. package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.js +471 -0
  118. package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +1 -0
  119. package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.js +413 -0
  120. package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +1 -0
  121. package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.js +430 -0
  122. package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +1 -0
  123. package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +157 -0
  124. package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +1 -0
  125. package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.js +384 -0
  126. package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +1 -0
  127. package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.js +224 -0
  128. package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
  129. package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +259 -0
  130. package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
  131. package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.js +787 -0
  132. package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  133. package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.js +495 -0
  134. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  135. package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +286 -0
  136. package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +1 -0
  137. package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.js +862 -0
  138. package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +1 -0
  139. package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.js +259 -0
  140. package/dist/{test → cjs/test}/unit/utils.d.ts.map +1 -1
  141. package/dist/cjs/test/unit/utils.js +517 -0
  142. package/dist/cjs/test/unit/versionedTransaction.d.ts.map +1 -0
  143. package/dist/cjs/test/unit/versionedTransaction.js +207 -0
  144. package/dist/cjs/tsconfig.tsbuildinfo +1 -0
  145. package/dist/esm/bigint-buffer-guard.d.ts +1 -0
  146. package/dist/esm/config/token2022StaticConfig.d.ts +3 -0
  147. package/dist/esm/config/token2022StaticConfig.js +47 -0
  148. package/dist/esm/index.d.ts +7 -0
  149. package/dist/esm/index.js +7 -0
  150. package/dist/esm/lib/ataInitializationBuilder.d.ts +47 -0
  151. package/dist/esm/lib/ataInitializationBuilder.js +156 -0
  152. package/dist/esm/lib/closeAtaBuilder.d.ts +19 -0
  153. package/dist/esm/lib/closeAtaBuilder.js +62 -0
  154. package/dist/esm/lib/constants.d.ts +164 -0
  155. package/dist/esm/lib/constants.d.ts.map +1 -0
  156. package/dist/esm/lib/constants.js +193 -0
  157. package/dist/esm/lib/customInstructionBuilder.d.ts +72 -0
  158. package/dist/esm/lib/customInstructionBuilder.js +282 -0
  159. package/dist/esm/lib/explainTransactionWasm.d.ts +21 -0
  160. package/dist/esm/lib/explainTransactionWasm.d.ts.map +1 -0
  161. package/dist/esm/lib/explainTransactionWasm.js +261 -0
  162. package/dist/esm/lib/iface.d.ts +262 -0
  163. package/dist/esm/lib/iface.d.ts.map +1 -0
  164. package/dist/esm/lib/iface.js +3 -0
  165. package/dist/esm/lib/index.d.ts +23 -0
  166. package/dist/{src → esm}/lib/index.d.ts.map +1 -1
  167. package/dist/esm/lib/index.js +23 -0
  168. package/dist/esm/lib/instructionParamsFactory.d.ts +13 -0
  169. package/dist/{src → esm}/lib/instructionParamsFactory.d.ts.map +1 -1
  170. package/dist/esm/lib/instructionParamsFactory.js +1052 -0
  171. package/dist/esm/lib/jitoStakePoolOperations.d.ts +113 -0
  172. package/dist/esm/lib/jitoStakePoolOperations.js +189 -0
  173. package/dist/esm/lib/keyPair.d.ts +26 -0
  174. package/dist/esm/lib/keyPair.js +59 -0
  175. package/dist/esm/lib/messages/index.d.ts +2 -0
  176. package/dist/esm/lib/messages/index.js +2 -0
  177. package/dist/esm/lib/messages/messageBuilderFactory.d.ts +7 -0
  178. package/dist/{src → esm}/lib/messages/messageBuilderFactory.js +5 -9
  179. package/dist/esm/lib/recoverNestedAtaBuilder.d.ts +25 -0
  180. package/dist/esm/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
  181. package/dist/esm/lib/recoverNestedAtaBuilder.js +83 -0
  182. package/dist/esm/lib/solInstructionFactory.d.ts +10 -0
  183. package/dist/esm/lib/solInstructionFactory.d.ts.map +1 -0
  184. package/dist/esm/lib/solInstructionFactory.js +589 -0
  185. package/dist/esm/lib/stakingActivateBuilder.d.ts +59 -0
  186. package/dist/esm/lib/stakingActivateBuilder.js +113 -0
  187. package/dist/esm/lib/stakingAuthorizeBuilder.d.ts +43 -0
  188. package/dist/esm/lib/stakingAuthorizeBuilder.js +82 -0
  189. package/dist/esm/lib/stakingDeactivateBuilder.d.ts +81 -0
  190. package/dist/{src → esm}/lib/stakingDeactivateBuilder.js +31 -38
  191. package/dist/esm/lib/stakingDelegateBuilder.d.ts +42 -0
  192. package/dist/esm/lib/stakingDelegateBuilder.js +113 -0
  193. package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.d.ts +33 -0
  194. package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.js +103 -0
  195. package/dist/esm/lib/stakingWithdrawBuilder.d.ts +31 -0
  196. package/dist/esm/lib/stakingWithdrawBuilder.js +71 -0
  197. package/dist/esm/lib/token2022Config.d.ts +44 -0
  198. package/dist/esm/lib/token2022Config.js +23 -0
  199. package/dist/esm/lib/tokenTransferBuilder.d.ts +41 -0
  200. package/dist/esm/lib/tokenTransferBuilder.js +181 -0
  201. package/dist/esm/lib/transaction.d.ts +103 -0
  202. package/dist/esm/lib/transaction.d.ts.map +1 -0
  203. package/dist/esm/lib/transaction.js +605 -0
  204. package/dist/esm/lib/transactionBuilder.d.ts +128 -0
  205. package/dist/esm/lib/transactionBuilder.js +373 -0
  206. package/dist/esm/lib/transactionBuilderFactory.d.ts +120 -0
  207. package/dist/esm/lib/transactionBuilderFactory.d.ts.map +1 -0
  208. package/dist/esm/lib/transactionBuilderFactory.js +205 -0
  209. package/dist/esm/lib/transferBuilder.d.ts +26 -0
  210. package/dist/esm/lib/transferBuilder.js +63 -0
  211. package/dist/esm/lib/transferBuilderV2.d.ts +43 -0
  212. package/dist/esm/lib/transferBuilderV2.js +203 -0
  213. package/dist/esm/lib/utils.d.ts +200 -0
  214. package/dist/{src → esm}/lib/utils.d.ts.map +1 -1
  215. package/dist/esm/lib/utils.js +558 -0
  216. package/dist/esm/lib/walletInitializationBuilder.d.ts +26 -0
  217. package/dist/esm/lib/walletInitializationBuilder.js +64 -0
  218. package/dist/esm/register.d.ts +3 -0
  219. package/dist/esm/register.js +11 -0
  220. package/dist/esm/sol.d.ts +267 -0
  221. package/dist/esm/sol.d.ts.map +1 -0
  222. package/dist/esm/sol.js +1361 -0
  223. package/dist/esm/solToken.d.ts +37 -0
  224. package/dist/esm/solToken.js +65 -0
  225. package/dist/esm/tsol.d.ts +11 -0
  226. package/dist/esm/tsol.js +20 -0
  227. package/package.json +34 -15
  228. package/dist/src/config/token2022StaticConfig.js +0 -50
  229. package/dist/src/lib/ataInitializationBuilder.js +0 -196
  230. package/dist/src/lib/closeAtaBuilder.js +0 -69
  231. package/dist/src/lib/constants.d.ts.map +0 -1
  232. package/dist/src/lib/constants.js +0 -171
  233. package/dist/src/lib/customInstructionBuilder.js +0 -289
  234. package/dist/src/lib/iface.d.ts.map +0 -1
  235. package/dist/src/lib/iface.js +0 -7
  236. package/dist/src/lib/instructionParamsFactory.js +0 -1036
  237. package/dist/src/lib/jitoStakePoolOperations.js +0 -200
  238. package/dist/src/lib/keyPair.js +0 -63
  239. package/dist/src/lib/solInstructionFactory.d.ts.map +0 -1
  240. package/dist/src/lib/solInstructionFactory.js +0 -572
  241. package/dist/src/lib/stakingActivateBuilder.js +0 -120
  242. package/dist/src/lib/stakingAuthorizeBuilder.js +0 -89
  243. package/dist/src/lib/stakingDelegateBuilder.js +0 -120
  244. package/dist/src/lib/stakingRawMsgAuthorizeBuilder.js +0 -110
  245. package/dist/src/lib/stakingWithdrawBuilder.js +0 -78
  246. package/dist/src/lib/token2022Config.js +0 -27
  247. package/dist/src/lib/tokenTransferBuilder.js +0 -188
  248. package/dist/src/lib/transaction.d.ts.map +0 -1
  249. package/dist/src/lib/transaction.js +0 -595
  250. package/dist/src/lib/transactionBuilder.js +0 -380
  251. package/dist/src/lib/transactionBuilderFactory.d.ts.map +0 -1
  252. package/dist/src/lib/transactionBuilderFactory.js +0 -202
  253. package/dist/src/lib/transferBuilder.js +0 -70
  254. package/dist/src/lib/transferBuilderV2.js +0 -210
  255. package/dist/src/lib/utils.js +0 -589
  256. package/dist/src/lib/walletInitializationBuilder.js +0 -71
  257. package/dist/src/register.js +0 -15
  258. package/dist/src/sol.d.ts.map +0 -1
  259. package/dist/src/sol.js +0 -1285
  260. package/dist/src/solToken.js +0 -69
  261. package/dist/src/tsol.js +0 -24
  262. package/dist/test/fixtures/sol.js +0 -1433
  263. package/dist/test/resources/sol.d.ts.map +0 -1
  264. package/dist/test/resources/sol.js +0 -320
  265. package/dist/test/unit/fixtures/solBackupKey.d.ts.map +0 -1
  266. package/dist/test/unit/fixtures/solBackupKey.js +0 -8
  267. package/dist/test/unit/getBuilderFactory.d.ts.map +0 -1
  268. package/dist/test/unit/getBuilderFactory.js +0 -10
  269. package/dist/test/unit/instructionParamsFactory.d.ts.map +0 -1
  270. package/dist/test/unit/instructionParamsFactory.js +0 -412
  271. package/dist/test/unit/instructionParamsFactory.staking.d.ts.map +0 -1
  272. package/dist/test/unit/instructionParamsFactory.staking.js +0 -1059
  273. package/dist/test/unit/keyPair.js +0 -177
  274. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +0 -1
  275. package/dist/test/unit/messages/messageBuilderFactory.js +0 -118
  276. package/dist/test/unit/messages/simpleMessageBuilder.d.ts.map +0 -1
  277. package/dist/test/unit/messages/simpleMessageBuilder.js +0 -194
  278. package/dist/test/unit/sol.js +0 -3108
  279. package/dist/test/unit/solInstructionFactory.d.ts.map +0 -1
  280. package/dist/test/unit/solInstructionFactory.js +0 -454
  281. package/dist/test/unit/solToken.d.ts.map +0 -1
  282. package/dist/test/unit/solToken.js +0 -31
  283. package/dist/test/unit/transaction.d.ts.map +0 -1
  284. package/dist/test/unit/transaction.js +0 -983
  285. package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +0 -1
  286. package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.js +0 -202
  287. package/dist/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +0 -1
  288. package/dist/test/unit/transactionBuilder/ataInitBuilder.js +0 -471
  289. package/dist/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +0 -1
  290. package/dist/test/unit/transactionBuilder/customInstructionBuilder.js +0 -413
  291. package/dist/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +0 -1
  292. package/dist/test/unit/transactionBuilder/stakingActivateBuilder.js +0 -430
  293. package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +0 -1
  294. package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +0 -157
  295. package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +0 -1
  296. package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.js +0 -384
  297. package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +0 -1
  298. package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.js +0 -224
  299. package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -1
  300. package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +0 -259
  301. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +0 -1
  302. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +0 -787
  303. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +0 -1
  304. package/dist/test/unit/transactionBuilder/transactionBuilder.js +0 -495
  305. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +0 -1
  306. package/dist/test/unit/transactionBuilder/transferBuilder.js +0 -286
  307. package/dist/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +0 -1
  308. package/dist/test/unit/transactionBuilder/transferBuilderV2.js +0 -862
  309. package/dist/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +0 -1
  310. package/dist/test/unit/transactionBuilder/walletInitBuilder.js +0 -259
  311. package/dist/test/unit/utils.js +0 -517
  312. package/dist/test/unit/versionedTransaction.d.ts.map +0 -1
  313. package/dist/test/unit/versionedTransaction.js +0 -207
  314. package/dist/tsconfig.tsbuildinfo +0 -1
  315. /package/dist/{src → cjs/src}/bigint-buffer-guard.d.ts +0 -0
  316. /package/dist/{src → cjs/src}/config/token2022StaticConfig.d.ts +0 -0
  317. /package/dist/{src → cjs/src}/index.d.ts +0 -0
  318. /package/dist/{src → cjs/src}/lib/ataInitializationBuilder.d.ts +0 -0
  319. /package/dist/{src → cjs/src}/lib/closeAtaBuilder.d.ts +0 -0
  320. /package/dist/{src → cjs/src}/lib/customInstructionBuilder.d.ts +0 -0
  321. /package/dist/{src → cjs/src}/lib/jitoStakePoolOperations.d.ts +0 -0
  322. /package/dist/{src → cjs/src}/lib/keyPair.d.ts +0 -0
  323. /package/dist/{src → cjs/src}/lib/messages/index.d.ts +0 -0
  324. /package/dist/{src → cjs/src}/lib/messages/messageBuilderFactory.d.ts +0 -0
  325. /package/dist/{src → cjs/src}/lib/solInstructionFactory.d.ts +0 -0
  326. /package/dist/{src → cjs/src}/lib/stakingActivateBuilder.d.ts +0 -0
  327. /package/dist/{src → cjs/src}/lib/stakingAuthorizeBuilder.d.ts +0 -0
  328. /package/dist/{src → cjs/src}/lib/stakingDeactivateBuilder.d.ts +0 -0
  329. /package/dist/{src → cjs/src}/lib/stakingDelegateBuilder.d.ts +0 -0
  330. /package/dist/{src → cjs/src}/lib/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
  331. /package/dist/{src → cjs/src}/lib/stakingWithdrawBuilder.d.ts +0 -0
  332. /package/dist/{src → cjs/src}/lib/token2022Config.d.ts +0 -0
  333. /package/dist/{src → cjs/src}/lib/tokenTransferBuilder.d.ts +0 -0
  334. /package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -0
  335. /package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -0
  336. /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
  337. /package/dist/{src → cjs/src}/lib/transferBuilderV2.d.ts +0 -0
  338. /package/dist/{src → cjs/src}/lib/utils.d.ts +0 -0
  339. /package/dist/{src → cjs/src}/lib/walletInitializationBuilder.d.ts +0 -0
  340. /package/dist/{src → cjs/src}/register.d.ts +0 -0
  341. /package/dist/{src → cjs/src}/solToken.d.ts +0 -0
  342. /package/dist/{src → cjs/src}/tsol.d.ts +0 -0
  343. /package/dist/{test → cjs/test}/fixtures/sol.d.ts +0 -0
  344. /package/dist/{test → cjs/test}/unit/fixtures/solBackupKey.d.ts +0 -0
  345. /package/dist/{test → cjs/test}/unit/getBuilderFactory.d.ts +0 -0
  346. /package/dist/{test → cjs/test}/unit/instructionParamsFactory.d.ts +0 -0
  347. /package/dist/{test → cjs/test}/unit/instructionParamsFactory.staking.d.ts +0 -0
  348. /package/dist/{test → cjs/test}/unit/keyPair.d.ts +0 -0
  349. /package/dist/{test → cjs/test}/unit/messages/messageBuilderFactory.d.ts +0 -0
  350. /package/dist/{test → cjs/test}/unit/messages/simpleMessageBuilder.d.ts +0 -0
  351. /package/dist/{test → cjs/test}/unit/sol.d.ts +0 -0
  352. /package/dist/{test → cjs/test}/unit/solInstructionFactory.d.ts +0 -0
  353. /package/dist/{test → cjs/test}/unit/solToken.d.ts +0 -0
  354. /package/dist/{test → cjs/test}/unit/transaction.d.ts +0 -0
  355. /package/dist/{test → cjs/test}/unit/transactionBuilder/StakingWithdrawBuilder.d.ts +0 -0
  356. /package/dist/{test → cjs/test}/unit/transactionBuilder/ataInitBuilder.d.ts +0 -0
  357. /package/dist/{test → cjs/test}/unit/transactionBuilder/customInstructionBuilder.d.ts +0 -0
  358. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingActivateBuilder.d.ts +0 -0
  359. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts +0 -0
  360. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDeactivateBuilder.d.ts +0 -0
  361. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDelegateBuilder.d.ts +0 -0
  362. /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
  363. /package/dist/{test → cjs/test}/unit/transactionBuilder/tokenTransferBuilder.d.ts +0 -0
  364. /package/dist/{test → cjs/test}/unit/transactionBuilder/transactionBuilder.d.ts +0 -0
  365. /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilder.d.ts +0 -0
  366. /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilderV2.d.ts +0 -0
  367. /package/dist/{test → cjs/test}/unit/transactionBuilder/walletInitBuilder.d.ts +0 -0
  368. /package/dist/{test → cjs/test}/unit/utils.d.ts +0 -0
  369. /package/dist/{test → cjs/test}/unit/versionedTransaction.d.ts +0 -0
  370. /package/dist/{src → esm}/bigint-buffer-guard.d.ts.map +0 -0
  371. /package/dist/{src → esm}/bigint-buffer-guard.js +0 -0
  372. /package/dist/{src → esm}/config/token2022StaticConfig.d.ts.map +0 -0
  373. /package/dist/{src → esm}/index.d.ts.map +0 -0
  374. /package/dist/{src → esm}/lib/ataInitializationBuilder.d.ts.map +0 -0
  375. /package/dist/{src → esm}/lib/closeAtaBuilder.d.ts.map +0 -0
  376. /package/dist/{src → esm}/lib/customInstructionBuilder.d.ts.map +0 -0
  377. /package/dist/{src → esm}/lib/jitoStakePoolOperations.d.ts.map +0 -0
  378. /package/dist/{src → esm}/lib/keyPair.d.ts.map +0 -0
  379. /package/dist/{src → esm}/lib/messages/index.d.ts.map +0 -0
  380. /package/dist/{src → esm}/lib/messages/messageBuilderFactory.d.ts.map +0 -0
  381. /package/dist/{src → esm}/lib/stakingActivateBuilder.d.ts.map +0 -0
  382. /package/dist/{src → esm}/lib/stakingAuthorizeBuilder.d.ts.map +0 -0
  383. /package/dist/{src → esm}/lib/stakingDeactivateBuilder.d.ts.map +0 -0
  384. /package/dist/{src → esm}/lib/stakingDelegateBuilder.d.ts.map +0 -0
  385. /package/dist/{src → esm}/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -0
  386. /package/dist/{src → esm}/lib/stakingWithdrawBuilder.d.ts.map +0 -0
  387. /package/dist/{src → esm}/lib/token2022Config.d.ts.map +0 -0
  388. /package/dist/{src → esm}/lib/tokenTransferBuilder.d.ts.map +0 -0
  389. /package/dist/{src → esm}/lib/transactionBuilder.d.ts.map +0 -0
  390. /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
  391. /package/dist/{src → esm}/lib/transferBuilderV2.d.ts.map +0 -0
  392. /package/dist/{src → esm}/lib/walletInitializationBuilder.d.ts.map +0 -0
  393. /package/dist/{src → esm}/register.d.ts.map +0 -0
  394. /package/dist/{src → esm}/solToken.d.ts.map +0 -0
  395. /package/dist/{src → esm}/tsol.d.ts.map +0 -0
@@ -0,0 +1,1402 @@
1
+ "use strict";
2
+ /**
3
+ * @prettier
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.Sol = exports.DEFAULT_SCAN_FACTOR = void 0;
43
+ exports.getAmountBasedOnEndianness = getAmountBasedOnEndianness;
44
+ const spl_token_1 = require("@solana/spl-token");
45
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
46
+ const base58 = __importStar(require("bs58"));
47
+ const _ = __importStar(require("lodash"));
48
+ const request = __importStar(require("superagent"));
49
+ const logger_1 = require("@bitgo-beta/logger");
50
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
51
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
52
+ const statics_1 = require("@bitgo-beta/statics");
53
+ const lib_1 = require("./lib");
54
+ const utils_1 = require("./lib/utils");
55
+ exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
56
+ const HEX_REGEX = /^[0-9a-fA-F]+$/;
57
+ const BLIND_SIGNING_TX_TYPES_TO_CHECK = { enabletoken: 'AssociatedTokenAccountInitialization' };
58
+ /**
59
+ * Get amount string corrected for architecture-specific endianness issues.
60
+ *
61
+ * On s390x (big-endian) architecture, the Solana transaction parser (via @solana/web3.js)
62
+ * incorrectly reads little-endian u64 amounts as big-endian, resulting in corrupted values.
63
+ *
64
+ * This function corrects all amounts on s390x by swapping byte order to undo
65
+ * the incorrect byte order that happened during transaction parsing.
66
+ *
67
+ * @param amount - The amount to check and potentially fix
68
+ * @returns The corrected amount as a string
69
+ */
70
+ function getAmountBasedOnEndianness(amount) {
71
+ const amountStr = String(amount);
72
+ // Only s390x architecture has this endianness issue
73
+ const isS390x = process.arch === 's390x';
74
+ if (!isS390x) {
75
+ return amountStr;
76
+ }
77
+ try {
78
+ const amountBN = BigInt(amountStr);
79
+ // On s390x, the parser ALWAYS reads u64 as big-endian when it's actually little-endian
80
+ // So we ALWAYS need to swap bytes to get the correct value
81
+ const buf = Buffer.alloc(8);
82
+ buf.writeBigUInt64BE(amountBN, 0);
83
+ const fixed = buf.readBigUInt64LE(0);
84
+ return fixed.toString();
85
+ }
86
+ catch (e) {
87
+ // If conversion fails, return original value
88
+ return amountStr;
89
+ }
90
+ }
91
+ class Sol extends sdk_core_1.BaseCoin {
92
+ constructor(bitgo, staticsCoin) {
93
+ super(bitgo);
94
+ if (!staticsCoin) {
95
+ throw new Error('missing required constructor parameter staticsCoin');
96
+ }
97
+ this._staticsCoin = staticsCoin;
98
+ }
99
+ static createInstance(bitgo, staticsCoin) {
100
+ return new Sol(bitgo, staticsCoin);
101
+ }
102
+ allowsAccountConsolidations() {
103
+ return true;
104
+ }
105
+ supportsTss() {
106
+ return true;
107
+ }
108
+ /** @inheritDoc */
109
+ supportsMessageSigning() {
110
+ return true;
111
+ }
112
+ /** inherited doc */
113
+ getDefaultMultisigType() {
114
+ return sdk_core_1.multisigTypes.tss;
115
+ }
116
+ getMPCAlgorithm() {
117
+ return 'eddsa';
118
+ }
119
+ getChain() {
120
+ return this._staticsCoin.name;
121
+ }
122
+ getFamily() {
123
+ return this._staticsCoin.family;
124
+ }
125
+ getFullName() {
126
+ return this._staticsCoin.fullName;
127
+ }
128
+ getNetwork() {
129
+ return this._staticsCoin.network;
130
+ }
131
+ getBaseFactor() {
132
+ return Math.pow(10, this._staticsCoin.decimalPlaces);
133
+ }
134
+ verifyTxType(expectedTypeFromUserParams, actualTypeFromDecoded) {
135
+ const matchFromUserToDecodedType = BLIND_SIGNING_TX_TYPES_TO_CHECK[expectedTypeFromUserParams];
136
+ if (matchFromUserToDecodedType !== actualTypeFromDecoded) {
137
+ throw new Error(`Invalid transaction type on token enablement: expected "${matchFromUserToDecodedType}", got "${actualTypeFromDecoded}".`);
138
+ }
139
+ }
140
+ throwIfMissingTokenEnablementsOrReturn(explanation) {
141
+ if (!explanation.tokenEnablements || explanation.tokenEnablements.length === 0)
142
+ throw new Error('Missing tx token enablements data on token enablement tx prebuild');
143
+ return explanation.tokenEnablements;
144
+ }
145
+ throwIfMissingEnableTokenConfigOrReturn(txParams) {
146
+ if (!txParams.enableTokens || txParams.enableTokens.length === 0)
147
+ throw new Error('Missing enable token config');
148
+ return txParams.enableTokens;
149
+ }
150
+ verifyTokenName(tokenEnablementsPrebuild, enableTokensConfig) {
151
+ enableTokensConfig.forEach((enableTokenConfig) => {
152
+ const expectedTokenName = enableTokenConfig.name;
153
+ tokenEnablementsPrebuild.forEach((tokenEnablement) => {
154
+ if (!tokenEnablement.tokenName)
155
+ throw new Error('Missing token name on token enablement tx');
156
+ if (tokenEnablement.tokenName !== expectedTokenName)
157
+ throw new Error(`Invalid token name: expected ${expectedTokenName}, got ${tokenEnablement.tokenName} on token enablement tx`);
158
+ });
159
+ });
160
+ }
161
+ async verifyTokenAddress(tokenEnablementsPrebuild, enableTokensConfig) {
162
+ for (const enableTokenConfig of enableTokensConfig) {
163
+ const expectedTokenAddress = enableTokenConfig.address;
164
+ const expectedTokenName = enableTokenConfig.name;
165
+ if (!expectedTokenAddress)
166
+ throw new Error('Missing token address on token enablement tx');
167
+ if (!expectedTokenName)
168
+ throw new Error('Missing token name on token enablement tx');
169
+ for (const tokenEnablement of tokenEnablementsPrebuild) {
170
+ let tokenMintAddress;
171
+ try {
172
+ tokenMintAddress = (0, utils_1.getSolTokenFromTokenName)(expectedTokenName);
173
+ }
174
+ catch {
175
+ throw new Error(`Unable to derive ATA for token address: ${expectedTokenAddress}`);
176
+ }
177
+ if (!tokenMintAddress ||
178
+ tokenMintAddress.tokenAddress === undefined ||
179
+ tokenMintAddress.programId === undefined) {
180
+ throw new Error(`Unable to get token mint address for ${expectedTokenName}`);
181
+ }
182
+ let ata;
183
+ try {
184
+ ata = await (0, utils_1.getAssociatedTokenAccountAddress)(tokenMintAddress.tokenAddress, expectedTokenAddress, true, tokenMintAddress.programId);
185
+ }
186
+ catch {
187
+ throw new Error(`Unable to derive ATA for token address: ${expectedTokenAddress}`);
188
+ }
189
+ if (ata !== tokenEnablement.address) {
190
+ throw new Error(`Invalid token address: expected ${ata}, got ${tokenEnablement.address} on token enablement tx`);
191
+ }
192
+ }
193
+ }
194
+ }
195
+ hasSolVersionedTransactionData(txParams) {
196
+ return 'solVersionedTransactionData' in txParams && txParams.solVersionedTransactionData !== undefined;
197
+ }
198
+ /**
199
+ * Verify a versioned Solana transaction with basic structural validation
200
+ * @param params - verification parameters
201
+ * @returns true if verification passes
202
+ */
203
+ async verifyVersionedTransaction(params) {
204
+ const { txParams, txPrebuild } = params;
205
+ const rawTx = txPrebuild.txBase64 || txPrebuild.txHex;
206
+ if (!rawTx) {
207
+ throw new Error('missing required tx prebuild property txBase64 or txHex');
208
+ }
209
+ // Validate that the versioned transaction data is well-formed
210
+ if (!this.hasSolVersionedTransactionData(txParams)) {
211
+ throw new Error('solVersionedTransactionData is required for versioned transaction verification');
212
+ }
213
+ const versionedData = txParams.solVersionedTransactionData;
214
+ if (!versionedData.versionedInstructions || versionedData.versionedInstructions.length === 0) {
215
+ throw new Error('versioned transaction must have at least one instruction');
216
+ }
217
+ if (!versionedData.staticAccountKeys || versionedData.staticAccountKeys.length === 0) {
218
+ throw new Error('versioned transaction must have at least one static account key');
219
+ }
220
+ if (!versionedData.messageHeader) {
221
+ throw new Error('versioned transaction must have a message header');
222
+ }
223
+ // Validate that we can deserialize the transaction
224
+ let rawTxBase64 = rawTx;
225
+ if (HEX_REGEX.test(rawTx)) {
226
+ rawTxBase64 = Buffer.from(rawTx, 'hex').toString('base64');
227
+ }
228
+ try {
229
+ const txBytes = Buffer.from(rawTxBase64, 'base64');
230
+ if (txBytes.length < 1) {
231
+ throw new Error('transaction bytes are empty');
232
+ }
233
+ // Check version byte (after signatures)
234
+ const numSignatures = txBytes[0];
235
+ const signatureSize = 64;
236
+ const versionByteOffset = 1 + numSignatures * signatureSize;
237
+ if (txBytes.length <= versionByteOffset) {
238
+ throw new Error('transaction bytes are too short to contain version byte');
239
+ }
240
+ const versionByte = txBytes[versionByteOffset];
241
+ const isVersioned = (versionByte & 0x80) !== 0;
242
+ if (!isVersioned) {
243
+ throw new Error('transaction does not have versioned format');
244
+ }
245
+ }
246
+ catch (error) {
247
+ throw new Error(`failed to validate versioned transaction format: ${error.message}`);
248
+ }
249
+ return true;
250
+ }
251
+ async verifyTransaction(params) {
252
+ // asset name to transfer amount map
253
+ const totalAmount = {};
254
+ const coinConfig = statics_1.coins.get(this.getChain());
255
+ const { txParams: txParams, txPrebuild: txPrebuild, memo: memo, durableNonce: durableNonce, verification: verificationOptions, } = params;
256
+ if (this.hasSolVersionedTransactionData(txParams)) {
257
+ return this.verifyVersionedTransaction(params);
258
+ }
259
+ const transaction = new lib_1.Transaction(coinConfig);
260
+ const rawTx = txPrebuild.txBase64 || txPrebuild.txHex;
261
+ const consolidateId = txPrebuild.consolidateId;
262
+ const walletRootAddress = params.wallet.coinSpecific()?.rootAddress;
263
+ if (!rawTx) {
264
+ throw new Error('missing required tx prebuild property txBase64 or txHex');
265
+ }
266
+ let rawTxBase64 = rawTx;
267
+ if (HEX_REGEX.test(rawTx)) {
268
+ rawTxBase64 = Buffer.from(rawTx, 'hex').toString('base64');
269
+ }
270
+ transaction.fromRawTransaction(rawTxBase64);
271
+ const explainedTx = transaction.explainTransaction();
272
+ if (txParams.type === 'enabletoken' && verificationOptions?.verifyTokenEnablement) {
273
+ this.verifyTxType(txParams.type, explainedTx.type);
274
+ const tokenEnablementsPrebuild = this.throwIfMissingTokenEnablementsOrReturn(explainedTx);
275
+ const enableTokensConfig = this.throwIfMissingEnableTokenConfigOrReturn(txParams);
276
+ this.verifyTokenName(tokenEnablementsPrebuild, enableTokensConfig);
277
+ await this.verifyTokenAddress(tokenEnablementsPrebuild, enableTokensConfig);
278
+ }
279
+ // users do not input recipients for consolidation requests as they are generated by the server
280
+ if (txParams.recipients !== undefined) {
281
+ const filteredRecipients = txParams.recipients?.map((recipient) => _.pick(recipient, ['address', 'amount', 'tokenName']));
282
+ const filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount', 'tokenName']));
283
+ if (filteredRecipients.length !== filteredOutputs.length) {
284
+ throw new Error('Number of tx outputs does not match with number of txParams recipients');
285
+ }
286
+ // For each recipient, check if it's a token tx (tokenName will exist if so)
287
+ // If it is a token tx, verify that the recipient address equals the derived address from explainedTx
288
+ // Derive the ATA if it is a native address and confirm it is equal to the explained tx recipient
289
+ const recipientChecks = await Promise.all(filteredRecipients.map(async (recipientFromUser, index) => {
290
+ const recipientFromTx = filteredOutputs[index]; // This address should be an ATA
291
+ // Compare the BigNumber values because amount is (string | number)
292
+ // Apply s390x endianness fix if needed
293
+ const userAmountStr = String(recipientFromUser.amount);
294
+ const txAmountStr = getAmountBasedOnEndianness(recipientFromTx.amount);
295
+ const userAmount = new bignumber_js_1.default(userAmountStr);
296
+ const txAmount = new bignumber_js_1.default(txAmountStr);
297
+ if (!userAmount.isEqualTo(txAmount)) {
298
+ return false;
299
+ }
300
+ // Compare the addresses and tokenNames
301
+ // Else if the addresses are not the same, check the derived ATA for parity
302
+ if (recipientFromUser.address === recipientFromTx.address &&
303
+ recipientFromUser.tokenName === recipientFromTx.tokenName) {
304
+ return true;
305
+ }
306
+ else if (recipientFromUser.address !== recipientFromTx.address && recipientFromUser.tokenName) {
307
+ // Try to check if the user's derived ATA is equal to the tx recipient address
308
+ // If getAssociatedTokenAccountAddress throws an error, then we are unable to derive the ATA for that address.
309
+ // Return false and throw an error if that is the case.
310
+ try {
311
+ const tokenMintAddress = (0, utils_1.getSolTokenFromTokenName)(recipientFromUser.tokenName);
312
+ return (0, utils_1.getAssociatedTokenAccountAddress)(tokenMintAddress.tokenAddress, recipientFromUser.address, true, tokenMintAddress.programId).then((ata) => {
313
+ return ata === recipientFromTx.address;
314
+ });
315
+ }
316
+ catch {
317
+ // Unable to derive ATA
318
+ return false;
319
+ }
320
+ }
321
+ return false;
322
+ }));
323
+ if (recipientChecks.includes(false)) {
324
+ throw new Error('Tx outputs does not match with expected txParams recipients');
325
+ }
326
+ }
327
+ else if (verificationOptions?.consolidationToBaseAddress) {
328
+ //verify funds are sent to walletRootAddress for a consolidation
329
+ const filteredOutputs = explainedTx.outputs.map((output) => _.pick(output, ['address', 'amount', 'tokenName']));
330
+ // Cache to store already derived ATA addresses
331
+ const ataAddressCache = {};
332
+ for (const output of filteredOutputs) {
333
+ if (output.tokenName) {
334
+ // Check cache first before deriving ATA address
335
+ if (!ataAddressCache[output.tokenName]) {
336
+ const tokenMintAddress = (0, utils_1.getSolTokenFromTokenName)(output.tokenName);
337
+ if (tokenMintAddress?.tokenAddress && tokenMintAddress?.programId) {
338
+ ataAddressCache[output.tokenName] = await (0, utils_1.getAssociatedTokenAccountAddress)(tokenMintAddress.tokenAddress, walletRootAddress, true, tokenMintAddress.programId);
339
+ }
340
+ else {
341
+ throw new Error(`Unable to get token information for ${output.tokenName}`);
342
+ }
343
+ }
344
+ if (ataAddressCache[output.tokenName] !== output.address) {
345
+ throw new Error('tx outputs does not match with expected address');
346
+ }
347
+ }
348
+ else if (output.address !== walletRootAddress) {
349
+ throw new Error('tx outputs does not match with expected address');
350
+ }
351
+ }
352
+ }
353
+ const transactionJson = transaction.toJson();
354
+ if (memo && memo.value !== explainedTx.memo) {
355
+ throw new Error('Tx memo does not match with expected txParams recipient memo');
356
+ }
357
+ if (txParams.recipients) {
358
+ for (const recipients of txParams.recipients) {
359
+ // totalAmount based on each token
360
+ const assetName = recipients.tokenName || this.getChain();
361
+ const amount = totalAmount[assetName] || new bignumber_js_1.default(0);
362
+ totalAmount[assetName] = amount.plus(recipients.amount);
363
+ }
364
+ // total output amount from explainedTx
365
+ const explainedTxTotal = {};
366
+ for (const output of explainedTx.outputs) {
367
+ // Apply s390x endianness fix to output amounts before summing
368
+ const outputAmountStr = getAmountBasedOnEndianness(output.amount);
369
+ // total output amount based on each token
370
+ const assetName = output.tokenName || this.getChain();
371
+ const amount = explainedTxTotal[assetName] || new bignumber_js_1.default(0);
372
+ explainedTxTotal[assetName] = amount.plus(outputAmountStr);
373
+ }
374
+ if (!_.isEqual(explainedTxTotal, totalAmount)) {
375
+ throw new Error('Tx total amount does not match with expected total amount field');
376
+ }
377
+ }
378
+ // For non-consolidate transactions, feePayer must be the wallet's root address
379
+ if (consolidateId === undefined && transactionJson.feePayer !== walletRootAddress) {
380
+ throw new Error('Tx fee payer is not the wallet root address');
381
+ }
382
+ if (durableNonce && !_.isEqual(explainedTx.durableNonce, durableNonce)) {
383
+ throw new Error('Tx durableNonce does not match with param durableNonce');
384
+ }
385
+ return true;
386
+ }
387
+ async isWalletAddress(params) {
388
+ const result = await (0, sdk_core_1.verifyEddsaTssWalletAddress)(params, (address) => this.isValidAddress(address), (publicKey) => this.getAddressFromPublicKey(publicKey));
389
+ if (!result) {
390
+ throw new sdk_core_1.UnexpectedAddressError(`address validation failure: ${params.address} is not a wallet address`);
391
+ }
392
+ return true;
393
+ }
394
+ /**
395
+ * Converts a Solana public key to an address
396
+ * @param publicKey Hex-encoded public key (64 hex characters = 32 bytes)
397
+ * @returns Base58-encoded Solana address
398
+ */
399
+ getAddressFromPublicKey(publicKey) {
400
+ const publicKeyBuffer = Buffer.from(publicKey, 'hex');
401
+ return base58.encode(publicKeyBuffer);
402
+ }
403
+ /**
404
+ * Generate Solana key pair
405
+ *
406
+ * @param {Buffer} seed - Seed from which the new SolKeyPair should be generated, otherwise a random seed is used
407
+ * @returns {Object} object with generated pub and prv
408
+ */
409
+ generateKeyPair(seed) {
410
+ const result = seed ? new lib_1.KeyPair({ seed }).getKeys() : new lib_1.KeyPair().getKeys();
411
+ return result;
412
+ }
413
+ /**
414
+ * Return boolean indicating whether input is valid public key for the coin
415
+ *
416
+ * @param {string} pub the prv to be checked
417
+ * @returns is it valid?
418
+ */
419
+ isValidPub(pub) {
420
+ return (0, utils_1.isValidPublicKey)(pub);
421
+ }
422
+ /**
423
+ * Return boolean indicating whether input is valid private key for the coin
424
+ *
425
+ * @param {string} prv the prv to be checked
426
+ * @returns is it valid?
427
+ */
428
+ isValidPrv(prv) {
429
+ return (0, utils_1.isValidPrivateKey)(prv);
430
+ }
431
+ isValidAddress(address) {
432
+ return (0, utils_1.isValidAddress)(address);
433
+ }
434
+ async signMessage(key, message) {
435
+ const solKeypair = new lib_1.KeyPair({ prv: key.prv });
436
+ if (Buffer.isBuffer(message)) {
437
+ message = base58.encode(message);
438
+ }
439
+ return Buffer.from(solKeypair.signMessage(message));
440
+ }
441
+ /**
442
+ * Signs Solana transaction
443
+ * @param params
444
+ * @param callback
445
+ */
446
+ async signTransaction(params) {
447
+ const factory = this.getBuilder();
448
+ const rawTx = params.txPrebuild.txHex || params.txPrebuild.txBase64;
449
+ const txBuilder = factory.from(rawTx);
450
+ txBuilder.sign({ key: params.prv });
451
+ const transaction = await txBuilder.build();
452
+ if (!transaction) {
453
+ throw new Error('Invalid transaction');
454
+ }
455
+ const serializedTx = transaction.toBroadcastFormat();
456
+ return {
457
+ txHex: serializedTx,
458
+ };
459
+ }
460
+ async parseTransaction(params) {
461
+ // explainTransaction now uses WASM for testnet automatically
462
+ const transactionExplanation = await this.explainTransaction({
463
+ txBase64: params.txBase64,
464
+ feeInfo: params.feeInfo,
465
+ tokenAccountRentExemptAmount: params.tokenAccountRentExemptAmount,
466
+ });
467
+ if (!transactionExplanation) {
468
+ throw new Error('Invalid transaction');
469
+ }
470
+ const solTransaction = transactionExplanation;
471
+ if (solTransaction.outputs.length <= 0) {
472
+ return {
473
+ inputs: [],
474
+ outputs: [],
475
+ };
476
+ }
477
+ const senderAddress = solTransaction.outputs[0].address;
478
+ const feeAmount = new bignumber_js_1.default(solTransaction.fee.fee);
479
+ // assume 1 sender, who is also the fee payer
480
+ const inputs = [
481
+ {
482
+ address: senderAddress,
483
+ amount: new bignumber_js_1.default(solTransaction.outputAmount).plus(feeAmount).toNumber(),
484
+ },
485
+ ];
486
+ const outputs = solTransaction.outputs.map(({ address, amount, tokenName }) => {
487
+ const output = { address, amount };
488
+ if (tokenName) {
489
+ output.tokenName = tokenName;
490
+ }
491
+ return output;
492
+ });
493
+ return {
494
+ inputs,
495
+ outputs,
496
+ };
497
+ }
498
+ /**
499
+ * Explain a Solana transaction from txBase64
500
+ * Uses WASM-based parsing for testnet, with fallback to legacy builder approach.
501
+ * @param params
502
+ */
503
+ async explainTransaction(params) {
504
+ // Use WASM-based parsing for testnet (simpler, faster, no @solana/web3.js rebuild)
505
+ if (this.getChain() === 'tsol') {
506
+ return this.explainTransactionWithWasm(params);
507
+ }
508
+ // Legacy approach for mainnet (until WASM is fully validated)
509
+ const factory = this.getBuilder();
510
+ let rebuiltTransaction;
511
+ try {
512
+ const transactionBuilder = factory.from(params.txBase64);
513
+ if (transactionBuilder instanceof lib_1.TransactionBuilder) {
514
+ const txBuilder = transactionBuilder;
515
+ txBuilder.fee({ amount: params.feeInfo.fee });
516
+ if (params.tokenAccountRentExemptAmount) {
517
+ txBuilder.associatedTokenAccountRent(params.tokenAccountRentExemptAmount);
518
+ }
519
+ }
520
+ rebuiltTransaction = await transactionBuilder.build();
521
+ }
522
+ catch (e) {
523
+ logger_1.logger.error(e);
524
+ throw new Error('Invalid transaction');
525
+ }
526
+ const explainedTransaction = rebuiltTransaction.explainTransaction();
527
+ return explainedTransaction;
528
+ }
529
+ /**
530
+ * Explain a Solana transaction using WASM parsing (bypasses @solana/web3.js rebuild).
531
+ * Delegates to standalone explainSolTransaction().
532
+ */
533
+ explainTransactionWithWasm(params) {
534
+ return (0, lib_1.explainSolTransaction)({ ...params, coinName: params.coinName ?? this.getChain() });
535
+ }
536
+ /** @inheritDoc */
537
+ async getSignablePayload(serializedTx) {
538
+ const factory = this.getBuilder();
539
+ const rebuiltTransaction = await factory.from(serializedTx).build();
540
+ return rebuiltTransaction.signablePayload;
541
+ }
542
+ /** @inheritDoc */
543
+ async presignTransaction(params) {
544
+ // Hot wallet txns are only valid for 1-2 minutes.
545
+ // To buy more time, we rebuild the transaction with a new blockhash right before we sign.
546
+ if (params.walletData.type !== 'hot') {
547
+ return Promise.resolve(params);
548
+ }
549
+ const txRequestId = params.txPrebuild?.txRequestId;
550
+ if (txRequestId === undefined) {
551
+ throw new Error('Missing txRequestId');
552
+ }
553
+ const { tssUtils } = params;
554
+ await tssUtils.deleteSignatureShares(txRequestId);
555
+ const recreated = await tssUtils.getTxRequest(txRequestId);
556
+ let txHex = '';
557
+ if (recreated.unsignedTxs) {
558
+ txHex = recreated.unsignedTxs[0]?.serializedTxHex;
559
+ }
560
+ else {
561
+ txHex = recreated.transactions ? recreated.transactions[0]?.unsignedTx.serializedTxHex : '';
562
+ }
563
+ if (!txHex) {
564
+ throw new Error('Missing serialized tx hex');
565
+ }
566
+ return Promise.resolve({
567
+ ...params,
568
+ txPrebuild: recreated,
569
+ txHex,
570
+ });
571
+ }
572
+ getPublicNodeUrl(apiKey) {
573
+ if (apiKey) {
574
+ return sdk_core_1.Environments[this.bitgo.getEnv()].solAlchemyNodeUrl + `/${apiKey}`;
575
+ }
576
+ return sdk_core_1.Environments[this.bitgo.getEnv()].solNodeUrl;
577
+ }
578
+ /**
579
+ * Make a request to one of the public SOL nodes available
580
+ * @param params.payload
581
+ */
582
+ async getDataFromNode(params, apiKey) {
583
+ const nodeUrl = this.getPublicNodeUrl(apiKey);
584
+ try {
585
+ return await request.post(nodeUrl).send(params.payload);
586
+ }
587
+ catch (e) {
588
+ console.debug(e);
589
+ }
590
+ throw new Error(`Unable to call endpoint: '/' from node: ${nodeUrl}`);
591
+ }
592
+ async getBlockhash(apiKey) {
593
+ const response = await this.getDataFromNode({
594
+ payload: {
595
+ id: '1',
596
+ jsonrpc: '2.0',
597
+ method: 'getLatestBlockhash',
598
+ params: [
599
+ {
600
+ commitment: 'finalized',
601
+ },
602
+ ],
603
+ },
604
+ }, apiKey);
605
+ if (response.status !== 200) {
606
+ throw new Error('Account not found');
607
+ }
608
+ return response.body.result.value.blockhash;
609
+ }
610
+ async getFeeForMessage(message, apiKey) {
611
+ const response = await this.getDataFromNode({
612
+ payload: {
613
+ id: '1',
614
+ jsonrpc: '2.0',
615
+ method: 'getFeeForMessage',
616
+ params: [
617
+ message,
618
+ {
619
+ commitment: 'finalized',
620
+ },
621
+ ],
622
+ },
623
+ }, apiKey);
624
+ if (response.status !== 200) {
625
+ throw new Error('Account not found');
626
+ }
627
+ return response.body.result.value;
628
+ }
629
+ async getRentExemptAmount(apiKey) {
630
+ const response = await this.getDataFromNode({
631
+ payload: {
632
+ jsonrpc: '2.0',
633
+ id: '1',
634
+ method: 'getMinimumBalanceForRentExemption',
635
+ params: [165],
636
+ },
637
+ }, apiKey);
638
+ if (response.status !== 200 || response.error) {
639
+ throw new Error(JSON.stringify(response.error));
640
+ }
641
+ return response.body.result;
642
+ }
643
+ async getAccountBalance(pubKey, apiKey) {
644
+ const response = await this.getDataFromNode({
645
+ payload: {
646
+ id: '1',
647
+ jsonrpc: '2.0',
648
+ method: 'getBalance',
649
+ params: [pubKey],
650
+ },
651
+ }, apiKey);
652
+ if (response.status !== 200) {
653
+ throw new Error('Account not found');
654
+ }
655
+ return response.body.result.value;
656
+ }
657
+ async getAccountInfo(pubKey, apiKey) {
658
+ const response = await this.getDataFromNode({
659
+ payload: {
660
+ id: '1',
661
+ jsonrpc: '2.0',
662
+ method: 'getAccountInfo',
663
+ params: [
664
+ pubKey,
665
+ {
666
+ encoding: 'jsonParsed',
667
+ },
668
+ ],
669
+ },
670
+ }, apiKey);
671
+ if (response.status !== 200) {
672
+ throw new Error('Account not found');
673
+ }
674
+ return {
675
+ authority: response.body.result.value.data.parsed.info.authority,
676
+ blockhash: response.body.result.value.data.parsed.info.blockhash,
677
+ };
678
+ }
679
+ async getTokenAccountsByOwner(pubKey = '', programId = '', apiKey) {
680
+ const response = await this.getDataFromNode({
681
+ payload: {
682
+ id: '1',
683
+ jsonrpc: '2.0',
684
+ method: 'getTokenAccountsByOwner',
685
+ params: [
686
+ pubKey,
687
+ {
688
+ programId: programId.toString().toLowerCase() === spl_token_1.TOKEN_2022_PROGRAM_ID.toString().toLowerCase()
689
+ ? spl_token_1.TOKEN_2022_PROGRAM_ID.toString()
690
+ : spl_token_1.TOKEN_PROGRAM_ID.toString(),
691
+ },
692
+ {
693
+ encoding: 'jsonParsed',
694
+ },
695
+ ],
696
+ },
697
+ }, apiKey);
698
+ if (response.status !== 200) {
699
+ throw new Error('Account not found');
700
+ }
701
+ if (response.body.result.value.length !== 0) {
702
+ const tokenAccounts = [];
703
+ for (const tokenAccount of response.body.result.value) {
704
+ tokenAccounts.push({ info: tokenAccount.account.data.parsed.info, pubKey: tokenAccount.pubKey });
705
+ }
706
+ return tokenAccounts;
707
+ }
708
+ return [];
709
+ }
710
+ async getTokenAccountInfo(pubKey, apiKey) {
711
+ const response = await this.getDataFromNode({
712
+ payload: {
713
+ id: '1',
714
+ jsonrpc: '2.0',
715
+ method: 'getAccountInfo',
716
+ params: [
717
+ pubKey,
718
+ {
719
+ encoding: 'jsonParsed',
720
+ },
721
+ ],
722
+ },
723
+ }, apiKey);
724
+ if (response.status !== 200) {
725
+ throw new Error('Account not found');
726
+ }
727
+ return {
728
+ pubKey: pubKey,
729
+ info: response.body.result.value.data.parsed.info,
730
+ };
731
+ }
732
+ /** inherited doc */
733
+ async createBroadcastableSweepTransaction(params) {
734
+ if (!params.signatureShares) {
735
+ ('Missing transaction(s)');
736
+ }
737
+ const req = params.signatureShares;
738
+ const broadcastableTransactions = [];
739
+ let lastScanIndex = 0;
740
+ for (let i = 0; i < req.length; i++) {
741
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
742
+ const transaction = req[i].txRequest.transactions[0].unsignedTx;
743
+ if (!req[i].ovc || !req[i].ovc[0].eddsaSignature) {
744
+ throw new Error('Missing signature(s)');
745
+ }
746
+ const signature = req[i].ovc[0].eddsaSignature;
747
+ if (!transaction.signableHex) {
748
+ throw new Error('Missing signable hex');
749
+ }
750
+ const messageBuffer = Buffer.from(transaction.signableHex, 'hex');
751
+ const result = MPC.verify(messageBuffer, signature);
752
+ if (!result) {
753
+ throw new Error('Invalid signature');
754
+ }
755
+ const signatureHex = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
756
+ const txBuilder = this.getBuilder().from(transaction.serializedTx);
757
+ if (!transaction.coinSpecific?.commonKeychain) {
758
+ throw new Error('Missing common keychain');
759
+ }
760
+ const commonKeychain = transaction.coinSpecific.commonKeychain;
761
+ if (!transaction.derivationPath) {
762
+ throw new Error('Missing derivation path');
763
+ }
764
+ const derivationPath = transaction.derivationPath;
765
+ const accountId = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
766
+ const bs58EncodedPublicKey = new lib_1.KeyPair({ pub: accountId }).getAddress();
767
+ // add combined signature from ovc
768
+ const publicKeyObj = { pub: bs58EncodedPublicKey };
769
+ txBuilder.addSignature(publicKeyObj, signatureHex);
770
+ const signedTransaction = await txBuilder.build();
771
+ const serializedTx = signedTransaction.toBroadcastFormat();
772
+ broadcastableTransactions.push({
773
+ serializedTx: serializedTx,
774
+ scanIndex: transaction.scanIndex,
775
+ });
776
+ if (i === req.length - 1 && transaction.coinSpecific.lastScanIndex) {
777
+ lastScanIndex = transaction.coinSpecific.lastScanIndex;
778
+ }
779
+ }
780
+ return { transactions: broadcastableTransactions, lastScanIndex };
781
+ }
782
+ /**
783
+ * Builds a funds recovery transaction without BitGo
784
+ * @param {SolRecoveryOptions} params parameters needed to construct and
785
+ * (maybe) sign the transaction
786
+ *
787
+ * @returns {MPCTx | MPCSweepTxs} the serialized transaction hex string and index
788
+ * of the address being swept
789
+ */
790
+ async recover(params) {
791
+ if (!params.bitgoKey) {
792
+ throw new Error('missing bitgoKey');
793
+ }
794
+ if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
795
+ throw new Error('invalid recoveryDestination');
796
+ }
797
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
798
+ const isUnsignedSweep = !params.walletPassphrase;
799
+ // Build the transaction
800
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
801
+ let balance = 0;
802
+ const index = params.index || 0;
803
+ const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
804
+ const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
805
+ const bs58EncodedPublicKey = new lib_1.KeyPair({ pub: accountId }).getAddress();
806
+ balance = await this.getAccountBalance(bs58EncodedPublicKey, params.apiKey);
807
+ const factory = this.getBuilder();
808
+ const walletCoin = this.getChain();
809
+ let txBuilder;
810
+ let blockhash = await this.getBlockhash(params.apiKey);
811
+ let rentExemptAmount;
812
+ let authority = '';
813
+ let totalFee = new bignumber_js_1.default(0);
814
+ let totalFeeForTokenRecovery = new bignumber_js_1.default(0);
815
+ // check for possible token recovery, recover the token provide by user
816
+ if (params.tokenContractAddress) {
817
+ let isUnsupportedToken = false;
818
+ const tokenAccounts = await this.getTokenAccountsByOwner(bs58EncodedPublicKey, params.programId, params.apiKey);
819
+ if (tokenAccounts.length !== 0) {
820
+ // there exists token accounts on the given address, but need to check certain conditions:
821
+ // 1. if there is a recoverable balance
822
+ // 2. if the token is supported by bitgo
823
+ const recovereableTokenAccounts = [];
824
+ for (const tokenAccount of tokenAccounts) {
825
+ if (params.tokenContractAddress === tokenAccount.info.mint) {
826
+ const tokenAmount = new bignumber_js_1.default(tokenAccount.info.tokenAmount.amount);
827
+ const network = this.getNetwork();
828
+ const token = (0, utils_1.getSolTokenFromAddress)(tokenAccount.info.mint, network); // todo(WIN-5894) fix for ams
829
+ if (!token) {
830
+ isUnsupportedToken = true;
831
+ }
832
+ if (tokenAmount.gt(new bignumber_js_1.default(0))) {
833
+ tokenAccount.tokenName = token?.name || 'Unsupported Token';
834
+ recovereableTokenAccounts.push(tokenAccount);
835
+ }
836
+ break;
837
+ }
838
+ }
839
+ if (recovereableTokenAccounts.length !== 0) {
840
+ rentExemptAmount = await this.getRentExemptAmount(params.apiKey);
841
+ txBuilder = factory
842
+ .getTokenTransferBuilder()
843
+ .nonce(blockhash)
844
+ .sender(bs58EncodedPublicKey)
845
+ .associatedTokenAccountRent(rentExemptAmount.toString())
846
+ .feePayer(bs58EncodedPublicKey);
847
+ // need to get all token accounts of the recipient address and need to create them if they do not exist
848
+ const recipientTokenAccounts = await this.getTokenAccountsByOwner(params.recoveryDestination, params.programId, params.apiKey);
849
+ for (const tokenAccount of recovereableTokenAccounts) {
850
+ let recipientTokenAccountExists = false;
851
+ for (const recipientTokenAccount of recipientTokenAccounts) {
852
+ if (recipientTokenAccount.info.mint === tokenAccount.info.mint) {
853
+ recipientTokenAccountExists = true;
854
+ break;
855
+ }
856
+ }
857
+ const recipientTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(tokenAccount.info.mint, params.recoveryDestination, false, params.programId?.toString());
858
+ const tokenName = tokenAccount.tokenName;
859
+ const sendParams = {
860
+ address: recipientTokenAccount,
861
+ amount: tokenAccount.info.tokenAmount.amount,
862
+ tokenName,
863
+ ...(isUnsupportedToken
864
+ ? {
865
+ tokenAddress: tokenAccount.info.mint,
866
+ programId: params.programId?.toString(),
867
+ decimalPlaces: tokenAccount.info.tokenAmount.decimals,
868
+ }
869
+ : {}),
870
+ };
871
+ txBuilder.send(sendParams);
872
+ if (!recipientTokenAccountExists) {
873
+ // recipient token account does not exist for token and must be created
874
+ txBuilder.createAssociatedTokenAccount({
875
+ ownerAddress: params.recoveryDestination,
876
+ tokenName: tokenName,
877
+ ...(isUnsupportedToken ? { tokenAddress: tokenAccount.info.mint } : {}),
878
+ programId: params.programId?.toString().toLowerCase() === spl_token_1.TOKEN_2022_PROGRAM_ID.toString().toLowerCase()
879
+ ? spl_token_1.TOKEN_2022_PROGRAM_ID.toString()
880
+ : spl_token_1.TOKEN_PROGRAM_ID.toString(),
881
+ });
882
+ // add rent exempt amount to total fee for each token account that has to be created
883
+ totalFeeForTokenRecovery = totalFeeForTokenRecovery.plus(rentExemptAmount);
884
+ }
885
+ }
886
+ }
887
+ else {
888
+ throw Error('Not enough token funds to recover');
889
+ }
890
+ }
891
+ else {
892
+ // there are no recoverable token accounts , need to check if there are tokens to recover
893
+ throw Error('Did not find token account to recover tokens, please check token account');
894
+ }
895
+ }
896
+ else {
897
+ txBuilder = factory
898
+ .getTransferBuilder()
899
+ .nonce(blockhash)
900
+ .sender(bs58EncodedPublicKey)
901
+ .send({ address: params.recoveryDestination, amount: balance.toString() })
902
+ .feePayer(bs58EncodedPublicKey);
903
+ }
904
+ if (params.durableNonce) {
905
+ const durableNonceInfo = await this.getAccountInfo(params.durableNonce.publicKey, params.apiKey);
906
+ blockhash = durableNonceInfo.blockhash;
907
+ authority = durableNonceInfo.authority;
908
+ txBuilder.nonce(blockhash, {
909
+ walletNonceAddress: params.durableNonce.publicKey,
910
+ authWalletAddress: authority,
911
+ });
912
+ }
913
+ // build the transaction without fee
914
+ const unsignedTransactionWithoutFee = (await txBuilder.build());
915
+ const serializedMessage = unsignedTransactionWithoutFee.solTransaction.serializeMessage().toString('base64');
916
+ const baseFee = await this.getFeeForMessage(serializedMessage, params.apiKey);
917
+ const feePerSignature = params.durableNonce ? baseFee / 2 : baseFee;
918
+ totalFee = totalFee.plus(new bignumber_js_1.default(baseFee));
919
+ totalFeeForTokenRecovery = totalFeeForTokenRecovery.plus(new bignumber_js_1.default(baseFee));
920
+ if (totalFee.gt(balance)) {
921
+ throw Error('Did not find address with funds to recover');
922
+ }
923
+ if (params.tokenContractAddress) {
924
+ // Check if there is sufficient native solana to recover tokens
925
+ if (new bignumber_js_1.default(balance).lt(totalFeeForTokenRecovery)) {
926
+ throw Error('Not enough funds to pay for recover tokens fees, have: ' +
927
+ balance +
928
+ ' need: ' +
929
+ totalFeeForTokenRecovery.toString());
930
+ }
931
+ txBuilder.fee({ amount: feePerSignature });
932
+ }
933
+ else {
934
+ const netAmount = new bignumber_js_1.default(balance).minus(totalFee);
935
+ txBuilder = factory
936
+ .getTransferBuilder()
937
+ .nonce(blockhash)
938
+ .sender(bs58EncodedPublicKey)
939
+ .send({ address: params.recoveryDestination, amount: netAmount.toString() })
940
+ .feePayer(bs58EncodedPublicKey)
941
+ .fee({ amount: feePerSignature });
942
+ if (params.durableNonce) {
943
+ txBuilder.nonce(blockhash, {
944
+ walletNonceAddress: params.durableNonce.publicKey,
945
+ authWalletAddress: authority,
946
+ });
947
+ }
948
+ }
949
+ if (!isUnsignedSweep) {
950
+ // Sign the txn
951
+ if (!params.userKey) {
952
+ throw new Error('missing userKey');
953
+ }
954
+ if (!params.backupKey) {
955
+ throw new Error('missing backupKey');
956
+ }
957
+ if (!params.walletPassphrase) {
958
+ throw new Error('missing wallet passphrase');
959
+ }
960
+ // build the transaction with fee
961
+ const unsignedTransaction = (await txBuilder.build());
962
+ const userKey = params.userKey.replace(/\s/g, '');
963
+ const backupKey = params.backupKey.replace(/\s/g, '');
964
+ // Decrypt private keys from KeyCard values
965
+ let userPrv;
966
+ try {
967
+ userPrv = this.bitgo.decrypt({
968
+ input: userKey,
969
+ password: params.walletPassphrase,
970
+ });
971
+ }
972
+ catch (e) {
973
+ throw new Error(`Error decrypting user keychain: ${e.message}`);
974
+ }
975
+ const userSigningMaterial = JSON.parse(userPrv);
976
+ let backupPrv;
977
+ try {
978
+ backupPrv = this.bitgo.decrypt({
979
+ input: backupKey,
980
+ password: params.walletPassphrase,
981
+ });
982
+ }
983
+ catch (e) {
984
+ throw new Error(`Error decrypting backup keychain: ${e.message}`);
985
+ }
986
+ const backupSigningMaterial = JSON.parse(backupPrv);
987
+ const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
988
+ const publicKeyObj = { pub: bs58EncodedPublicKey };
989
+ txBuilder.addSignature(publicKeyObj, signatureHex);
990
+ }
991
+ if (params.durableNonce) {
992
+ // add durable nonce account signature
993
+ txBuilder.sign({ key: params.durableNonce.secretKey });
994
+ }
995
+ const completedTransaction = await txBuilder.build();
996
+ const serializedTx = completedTransaction.toBroadcastFormat();
997
+ const derivationPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
998
+ const inputs = [];
999
+ for (const input of completedTransaction.inputs) {
1000
+ inputs.push({
1001
+ address: input.address,
1002
+ valueString: input.value,
1003
+ value: new bignumber_js_1.default(input.value).toNumber(),
1004
+ });
1005
+ }
1006
+ const outputs = [];
1007
+ for (const output of completedTransaction.outputs) {
1008
+ outputs.push({
1009
+ address: output.address,
1010
+ valueString: output.value,
1011
+ coinName: output.coin ? output.coin : walletCoin,
1012
+ });
1013
+ }
1014
+ const spendAmount = completedTransaction.inputs.length === 1 ? completedTransaction.inputs[0].value : 0;
1015
+ const parsedTx = { inputs: inputs, outputs: outputs, spendAmount: spendAmount, type: '' };
1016
+ const feeInfo = { fee: totalFeeForTokenRecovery.toNumber(), feeString: totalFee.toString() };
1017
+ const coinSpecific = { commonKeychain: bitgoKey };
1018
+ if (isUnsignedSweep) {
1019
+ const transaction = {
1020
+ serializedTx: serializedTx,
1021
+ scanIndex: index,
1022
+ coin: walletCoin,
1023
+ signableHex: completedTransaction.signablePayload.toString('hex'),
1024
+ derivationPath: derivationPath,
1025
+ parsedTx: parsedTx,
1026
+ feeInfo: feeInfo,
1027
+ coinSpecific: coinSpecific,
1028
+ };
1029
+ const unsignedTx = { unsignedTx: transaction, signatureShares: [] };
1030
+ const transactions = [unsignedTx];
1031
+ const txRequest = {
1032
+ transactions: transactions,
1033
+ walletCoin: walletCoin,
1034
+ };
1035
+ const txRequests = { txRequests: [txRequest] };
1036
+ return txRequests;
1037
+ }
1038
+ const transaction = {
1039
+ serializedTx: serializedTx,
1040
+ scanIndex: index,
1041
+ };
1042
+ return transaction;
1043
+ }
1044
+ /**
1045
+ * Builds a funds recovery transaction without BitGo
1046
+ * @param {SolRecoveryOptions} params parameters needed to construct and
1047
+ * (maybe) sign the transaction
1048
+ *
1049
+ * @returns {BaseBroadcastTransactionResult[]} the serialized transaction hex string and index
1050
+ * of the address being swept
1051
+ */
1052
+ async recoverCloseATA(params) {
1053
+ if (!params.bitgoKey) {
1054
+ throw new Error('missing bitgoKey');
1055
+ }
1056
+ if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
1057
+ throw new Error('invalid recoveryDestination');
1058
+ }
1059
+ if (!params.closeAtaAddress || !this.isValidAddress(params.closeAtaAddress)) {
1060
+ throw new Error('invalid closeAtaAddress');
1061
+ }
1062
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
1063
+ // Build the transaction
1064
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
1065
+ let balance = 0;
1066
+ const index = params.index || 0;
1067
+ const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
1068
+ const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
1069
+ const bs58EncodedPublicKey = new lib_1.KeyPair({ pub: accountId }).getAddress();
1070
+ const accountBalance = await this.getAccountBalance(bs58EncodedPublicKey);
1071
+ balance = await this.getAccountBalance(params.closeAtaAddress);
1072
+ if (balance <= 0) {
1073
+ throw Error('Did not find closeAtaAddress with sol funds to recover');
1074
+ }
1075
+ const factory = this.getBuilder();
1076
+ let txBuilder;
1077
+ let blockhash;
1078
+ const recovertTxns = [];
1079
+ const rentExemptAmount = await this.getRentExemptAmount();
1080
+ // do token recovery before closing ATA address
1081
+ // check if any token is present on the closeAtaAddress
1082
+ const tokenInfo = await this.getTokenAccountInfo(params.closeAtaAddress);
1083
+ const tokenBalance = Number(tokenInfo.info.tokenAmount.amount);
1084
+ if (tokenBalance > 0) {
1085
+ // closeATA address has some token balance, it needs to be withdrawn before closing ATA
1086
+ console.log(`closeATA address ${params.closeAtaAddress} has token balance ${tokenBalance}, it needs to be withdrawn before closing ATA address`);
1087
+ if (!params.recoveryDestinationAtaAddress || !this.isValidAddress(params.recoveryDestinationAtaAddress)) {
1088
+ throw new Error('invalid recoveryDestinationAtaAddress');
1089
+ }
1090
+ blockhash = await this.getBlockhash(params.apiKey);
1091
+ txBuilder = factory
1092
+ .getTokenTransferBuilder()
1093
+ .nonce(blockhash)
1094
+ .sender(bs58EncodedPublicKey)
1095
+ .associatedTokenAccountRent(rentExemptAmount.toString())
1096
+ .feePayer(bs58EncodedPublicKey);
1097
+ const unsignedTransaction = (await txBuilder.build());
1098
+ const serializedMessage = unsignedTransaction.solTransaction.serializeMessage().toString('base64');
1099
+ const feePerSignature = await this.getFeeForMessage(serializedMessage, params.apiKey);
1100
+ const baseFee = params.durableNonce ? feePerSignature * 2 : feePerSignature;
1101
+ const totalFee = new bignumber_js_1.default(baseFee);
1102
+ if (totalFee.gt(accountBalance)) {
1103
+ throw Error('Did not find address with funds to recover');
1104
+ }
1105
+ txBuilder.fee({ amount: feePerSignature });
1106
+ const network = this.getNetwork();
1107
+ const token = (0, utils_1.getSolTokenFromAddress)(tokenInfo.info.mint, network); // todo(WIN-5894) fix for ams
1108
+ txBuilder.send({
1109
+ address: params.recoveryDestinationAtaAddress,
1110
+ amount: tokenBalance,
1111
+ tokenName: token?.name,
1112
+ });
1113
+ const tokenRecoveryTxn = await this.signAndGenerateBroadcastableTransaction(params, txBuilder, bs58EncodedPublicKey);
1114
+ const serializedTokenRecoveryTxn = (await tokenRecoveryTxn).serializedTx;
1115
+ const broadcastTokenRecoveryTxn = await this.broadcastTransaction({
1116
+ serializedSignedTransaction: serializedTokenRecoveryTxn,
1117
+ });
1118
+ logger_1.logger.log(broadcastTokenRecoveryTxn);
1119
+ recovertTxns.push(broadcastTokenRecoveryTxn);
1120
+ }
1121
+ // after recovering the token amount, attempting to close the ATA address
1122
+ if (params.closeAtaAddress) {
1123
+ blockhash = await this.getBlockhash(params.apiKey);
1124
+ const ataCloseBuilder = () => {
1125
+ const txBuilder = factory.getCloseAtaInitializationBuilder();
1126
+ txBuilder.nonce(blockhash);
1127
+ txBuilder.sender(bs58EncodedPublicKey);
1128
+ txBuilder.accountAddress(params.closeAtaAddress ?? '');
1129
+ txBuilder.destinationAddress(params.recoveryDestination);
1130
+ txBuilder.authorityAddress(bs58EncodedPublicKey);
1131
+ txBuilder.associatedTokenAccountRent(rentExemptAmount.toString());
1132
+ return txBuilder;
1133
+ };
1134
+ txBuilder = ataCloseBuilder();
1135
+ }
1136
+ const closeATARecoveryTxn = await this.signAndGenerateBroadcastableTransaction(params, txBuilder, bs58EncodedPublicKey);
1137
+ const serializedCloseATARecoveryTxn = (await closeATARecoveryTxn).serializedTx;
1138
+ const broadcastCloseATARecoveryTxn = await this.broadcastTransaction({
1139
+ serializedSignedTransaction: serializedCloseATARecoveryTxn,
1140
+ });
1141
+ logger_1.logger.log(broadcastCloseATARecoveryTxn);
1142
+ recovertTxns.push(broadcastCloseATARecoveryTxn);
1143
+ return recovertTxns;
1144
+ }
1145
+ /**
1146
+ * Recovers tokens from a nested ATA — an ATA whose owner is another ATA rather than a wallet address.
1147
+ *
1148
+ * This situation occurs when an external sender mistakenly calls createAssociatedTokenAccount with
1149
+ * an ATA address as the owner instead of the root wallet address. The result is a "nested ATA"
1150
+ * (ATA-2) owned by the wallet's normal ATA (ATA-1). Because ATA-1 is a PDA with no private key,
1151
+ * the standard recoverCloseATA flow cannot sign for ATA-2.
1152
+ *
1153
+ * This method uses the Associated Token Account program's RecoverNested instruction, which allows
1154
+ * the root wallet owner to sign and atomically move tokens from ATA-2 → ATA-1 and close ATA-2,
1155
+ * returning the rent-exempt SOL to the wallet address.
1156
+ *
1157
+ * @param {SolRecoveryOptions} params - recovery params, requires nestedAtaAddress, ownerAtaAddress,
1158
+ * and tokenMintAddress in addition to the standard keychain fields
1159
+ */
1160
+ async recoverNestedAta(params) {
1161
+ if (!params.bitgoKey) {
1162
+ throw new Error('missing bitgoKey');
1163
+ }
1164
+ if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
1165
+ throw new Error('invalid recoveryDestination');
1166
+ }
1167
+ if (!params.nestedAtaAddress || !this.isValidAddress(params.nestedAtaAddress)) {
1168
+ throw new Error('invalid nestedAtaAddress');
1169
+ }
1170
+ if (!params.ownerAtaAddress || !this.isValidAddress(params.ownerAtaAddress)) {
1171
+ throw new Error('invalid ownerAtaAddress');
1172
+ }
1173
+ if (!params.tokenMintAddress || !this.isValidAddress(params.tokenMintAddress)) {
1174
+ throw new Error('invalid tokenMintAddress');
1175
+ }
1176
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
1177
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
1178
+ const index = params.index || 0;
1179
+ const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
1180
+ const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
1181
+ const bs58EncodedPublicKey = new lib_1.KeyPair({ pub: accountId }).getAddress();
1182
+ const blockhash = await this.getBlockhash(params.apiKey);
1183
+ const rentExemptAmount = await this.getRentExemptAmount();
1184
+ const factory = this.getBuilder();
1185
+ const txBuilder = factory.getRecoverNestedAtaBuilder();
1186
+ txBuilder.nonce(blockhash);
1187
+ txBuilder.sender(bs58EncodedPublicKey);
1188
+ txBuilder.feePayer(bs58EncodedPublicKey);
1189
+ txBuilder.associatedTokenAccountRent(rentExemptAmount.toString());
1190
+ txBuilder.nestedAccountAddress(params.nestedAtaAddress);
1191
+ txBuilder.nestedMintAddress(params.tokenMintAddress);
1192
+ txBuilder.destinationAccountAddress(params.ownerAtaAddress);
1193
+ txBuilder.ownerAccountAddress(params.ownerAtaAddress);
1194
+ txBuilder.ownerMintAddress(params.tokenMintAddress);
1195
+ txBuilder.walletAddress(bs58EncodedPublicKey);
1196
+ const recoverNestedTxn = await this.signAndGenerateBroadcastableTransaction(params, txBuilder, bs58EncodedPublicKey);
1197
+ const serializedTxn = (await recoverNestedTxn).serializedTx;
1198
+ const broadcastResult = await this.broadcastTransaction({
1199
+ serializedSignedTransaction: serializedTxn,
1200
+ });
1201
+ logger_1.logger.log(broadcastResult);
1202
+ return broadcastResult;
1203
+ }
1204
+ async signAndGenerateBroadcastableTransaction(params, txBuilder, bs58EncodedPublicKey) {
1205
+ // Sign the txn
1206
+ if (!params.userKey) {
1207
+ throw new Error('missing userKey');
1208
+ }
1209
+ if (!params.backupKey) {
1210
+ throw new Error('missing backupKey');
1211
+ }
1212
+ if (!params.walletPassphrase) {
1213
+ throw new Error('missing wallet passphrase');
1214
+ }
1215
+ const unsignedTransaction = (await txBuilder.build());
1216
+ const userKey = params.userKey.replace(/\s/g, '');
1217
+ const backupKey = params.backupKey.replace(/\s/g, '');
1218
+ // Decrypt private keys from KeyCard values
1219
+ let userPrv;
1220
+ try {
1221
+ userPrv = this.bitgo.decrypt({
1222
+ input: userKey,
1223
+ password: params.walletPassphrase,
1224
+ });
1225
+ }
1226
+ catch (e) {
1227
+ throw new Error(`Error decrypting user keychain: ${e.message}`);
1228
+ }
1229
+ const userSigningMaterial = JSON.parse(userPrv);
1230
+ let backupPrv;
1231
+ try {
1232
+ backupPrv = this.bitgo.decrypt({
1233
+ input: backupKey,
1234
+ password: params.walletPassphrase,
1235
+ });
1236
+ }
1237
+ catch (e) {
1238
+ throw new Error(`Error decrypting backup keychain: ${e.message}`);
1239
+ }
1240
+ const backupSigningMaterial = JSON.parse(backupPrv);
1241
+ const index = params.index || 0;
1242
+ const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
1243
+ const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
1244
+ const publicKeyObj = { pub: bs58EncodedPublicKey };
1245
+ txBuilder.addSignature(publicKeyObj, signatureHex);
1246
+ const completedTransaction = await txBuilder.build();
1247
+ const serializedTx = completedTransaction.toBroadcastFormat();
1248
+ const transaction = {
1249
+ serializedTx: serializedTx,
1250
+ scanIndex: index,
1251
+ };
1252
+ return transaction;
1253
+ }
1254
+ /**
1255
+ * Builds native SOL recoveries of receive addresses in batch without BitGo.
1256
+ * Funds will be recovered to base address first. You need to initiate another sweep txn after that.
1257
+ *
1258
+ * @param {SolConsolidationRecoveryOptions} params - options for consolidation recovery.
1259
+ * @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
1260
+ * @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
1261
+ */
1262
+ async recoverConsolidations(params) {
1263
+ const isUnsignedSweep = !params.walletPassphrase;
1264
+ const startIdx = params.startingScanIndex || 1;
1265
+ const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
1266
+ if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
1267
+ throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
1268
+ }
1269
+ // validate durable nonces array
1270
+ if (!params.durableNonces) {
1271
+ throw new Error('Missing durable nonces');
1272
+ }
1273
+ if (!params.durableNonces.publicKeys) {
1274
+ throw new Error('Invalid durable nonces: missing public keys');
1275
+ }
1276
+ if (!params.durableNonces.secretKey) {
1277
+ throw new Error('Invalid durable nonces array: missing secret key');
1278
+ }
1279
+ const bitgoKey = params.bitgoKey.replace(/\s/g, '');
1280
+ const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
1281
+ const baseAddressIndex = 0;
1282
+ const baseAddressPath = params.seed
1283
+ ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${baseAddressIndex}`
1284
+ : `m/${baseAddressIndex}`;
1285
+ const accountId = MPC.deriveUnhardened(bitgoKey, baseAddressPath).slice(0, 64);
1286
+ const baseAddress = new lib_1.KeyPair({ pub: accountId }).getAddress();
1287
+ let durableNoncePubKeysIndex = 0;
1288
+ const durableNoncePubKeysLength = params.durableNonces.publicKeys.length;
1289
+ const consolidationTransactions = [];
1290
+ let lastScanIndex = startIdx;
1291
+ for (let i = startIdx; i < endIdx; i++) {
1292
+ const recoverParams = {
1293
+ userKey: params.userKey,
1294
+ backupKey: params.backupKey,
1295
+ bitgoKey: params.bitgoKey,
1296
+ walletPassphrase: params.walletPassphrase,
1297
+ recoveryDestination: baseAddress,
1298
+ seed: params.seed,
1299
+ index: i,
1300
+ durableNonce: {
1301
+ publicKey: params.durableNonces.publicKeys[durableNoncePubKeysIndex],
1302
+ secretKey: params.durableNonces.secretKey,
1303
+ },
1304
+ tokenContractAddress: params.tokenContractAddress,
1305
+ apiKey: params.apiKey,
1306
+ programId: params.programId,
1307
+ };
1308
+ let recoveryTransaction;
1309
+ try {
1310
+ recoveryTransaction = await this.recover(recoverParams);
1311
+ }
1312
+ catch (e) {
1313
+ if (e.message === 'Did not find address with funds to recover' ||
1314
+ e.message === 'Did not find token account to recover tokens, please check token account' ||
1315
+ e.message === 'Not enough token funds to recover') {
1316
+ lastScanIndex = i;
1317
+ continue;
1318
+ }
1319
+ throw e;
1320
+ }
1321
+ if (isUnsignedSweep) {
1322
+ consolidationTransactions.push(recoveryTransaction.txRequests[0]);
1323
+ }
1324
+ else {
1325
+ consolidationTransactions.push(recoveryTransaction);
1326
+ }
1327
+ lastScanIndex = i;
1328
+ durableNoncePubKeysIndex++;
1329
+ if (durableNoncePubKeysIndex >= durableNoncePubKeysLength) {
1330
+ // no more available nonce accounts to create transactions
1331
+ break;
1332
+ }
1333
+ }
1334
+ if (consolidationTransactions.length === 0) {
1335
+ throw new Error('Did not find an address with funds to recover');
1336
+ }
1337
+ if (isUnsignedSweep) {
1338
+ // lastScanIndex will be used to inform user the last address index scanned for available funds (so they can
1339
+ // appropriately adjust the scan range on the next iteration of consolidation recoveries). In the case of unsigned
1340
+ // sweep consolidations, this lastScanIndex will be provided in the coinSpecific of the last txn made.
1341
+ const lastTransactionCoinSpecific = {
1342
+ commonKeychain: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
1343
+ .commonKeychain,
1344
+ lastScanIndex: lastScanIndex,
1345
+ };
1346
+ consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific =
1347
+ lastTransactionCoinSpecific;
1348
+ const consolidationSweepTransactions = { txRequests: consolidationTransactions };
1349
+ return consolidationSweepTransactions;
1350
+ }
1351
+ return { transactions: consolidationTransactions, lastScanIndex };
1352
+ }
1353
+ getTokenEnablementConfig() {
1354
+ return {
1355
+ requiresTokenEnablement: true,
1356
+ supportsMultipleTokenEnablements: true,
1357
+ };
1358
+ }
1359
+ getBuilder() {
1360
+ return new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
1361
+ }
1362
+ async broadcastTransaction({ serializedSignedTransaction, }) {
1363
+ (0, utils_1.validateRawTransaction)(serializedSignedTransaction, true, true);
1364
+ const response = await this.getDataFromNode({
1365
+ payload: {
1366
+ id: '1',
1367
+ jsonrpc: '2.0',
1368
+ method: 'sendTransaction',
1369
+ params: [
1370
+ serializedSignedTransaction,
1371
+ {
1372
+ encoding: 'base64',
1373
+ },
1374
+ ],
1375
+ },
1376
+ });
1377
+ if (response.body.error) {
1378
+ throw new Error('Error broadcasting transaction: ' + response.body.error.message);
1379
+ }
1380
+ return { txId: response.body.result };
1381
+ }
1382
+ /** @inheritDoc */
1383
+ auditDecryptedKey({ prv, publicKey, multiSigType }) {
1384
+ if (multiSigType !== 'tss') {
1385
+ throw new Error('Unsupported multiSigType');
1386
+ }
1387
+ (0, sdk_lib_mpc_1.auditEddsaPrivateKey)(prv, publicKey ?? '');
1388
+ }
1389
+ /** @inheritDoc */
1390
+ setCoinSpecificFieldsInIntent(intent, params) {
1391
+ // Handle custom instructions for Solana
1392
+ if (params.solInstructions) {
1393
+ intent.solInstructions = params.solInstructions;
1394
+ }
1395
+ // Handle versioned transaction data for Solana
1396
+ if (params.solVersionedTransactionData) {
1397
+ intent.solVersionedTransactionData = params.solVersionedTransactionData;
1398
+ }
1399
+ }
1400
+ }
1401
+ exports.Sol = Sol;
1402
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NvbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0dBRUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQStNSCxnRUFxQkM7QUFsT0QsaURBQTRFO0FBQzVFLGdFQUFxQztBQUNyQyw2Q0FBK0I7QUFDL0IsMENBQTRCO0FBQzVCLG9EQUFzQztBQUN0QywrQ0FBNEM7QUFFNUMsbURBNkM4QjtBQUM5Qix5REFBa0Y7QUFDbEYsaURBQTJHO0FBQzNHLCtCQU1lO0FBRWYsdUNBUXFCO0FBRVIsUUFBQSxtQkFBbUIsR0FBRyxFQUFFLENBQUMsQ0FBQyx3REFBd0Q7QUFxSC9GLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDO0FBQ25DLE1BQU0sK0JBQStCLEdBQUcsRUFBRSxXQUFXLEVBQUUsc0NBQXNDLEVBQUUsQ0FBQztBQUVoRzs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLDBCQUEwQixDQUFDLE1BQXVCO0lBQ2hFLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVqQyxvREFBb0Q7SUFDcEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksS0FBSyxPQUFPLENBQUM7SUFDekMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2IsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQyx1RkFBdUY7UUFDdkYsMkRBQTJEO1FBQzNELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsQyxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsZUFBZSxDQUFDLENB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QUFFLFlBQVksRUFBMkI7UUFDekUsSUFBSSxZQUFZLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFDRCxJQUFBLGtDQUFvQixFQUFDLEdBQUcsRUFBRSxTQUFTLElBQUksRUFBRSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGtCQUFrQjtJQUNsQiw2QkFBNkIsQ0FBQyxNQUF1QixFQUFFLE1BQTRDO1FBQ2pHLHdDQUF3QztRQUN4QyxJQUFJLE1BQU0sQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMzQixNQUFNLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUM7UUFDbEQsQ0FBQztRQUVELCtDQUErQztRQUMvQyxJQUFJLE1BQU0sQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUM7UUFDMUUsQ0FBQztJQUNILENBQUM7Q0FDRjtBQW5sREQsa0JBbWxEQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cblxuaW1wb3J0IHsgVE9LRU5fMjAyMl9QUk9HUkFNX0lELCBUT0tFTl9QUk9HUkFNX0lEIH0gZnJvbSAnQHNvbGFuYS9zcGwtdG9rZW4nO1xuaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0ICogYXMgYmFzZTU4IGZyb20gJ2JzNTgnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0ICogYXMgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJ0BiaXRnby1iZXRhL2xvZ2dlcic7XG5cbmltcG9ydCB7XG4gIEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zLFxuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25PcHRpb25zLFxuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXN1bHQsXG4gIEJhc2VDb2luLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIEJhc2VUcmFuc2FjdGlvbixcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCBhcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgQml0R29CYXNlLFxuICBFRERTQU1ldGhvZHMsXG4gIEVERFNBTWV0aG9kVHlwZXMsXG4gIEVudmlyb25tZW50cyxcbiAgSVRva2VuRW5hYmxlbWVudCxcbiAgS2V5UGFpcixcbiAgTWVtbyxcbiAgTVBDQWxnb3JpdGhtLFxuICBNUENDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zLFxuICBNUENSZWNvdmVyeU9wdGlvbnMsXG4gIE1QQ1N3ZWVwUmVjb3ZlcnlPcHRpb25zLFxuICBNUENTd2VlcFR4cyxcbiAgTVBDVHgsXG4gIE1QQ1R4cyxcbiAgTVBDVW5zaWduZWRUeCxcbiAgTXVsdGlzaWdUeXBlLFxuICBtdWx0aXNpZ1R5cGVzLFxuICBPdmNJbnB1dCxcbiAgT3ZjT3V0cHV0LFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUG9wdWxhdGVkSW50ZW50LFxuICBQcmVidWlsZFRyYW5zYWN0aW9uV2l0aEludGVudE9wdGlvbnMsXG4gIFByZXNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFB1YmxpY0tleSxcbiAgUmVjb3ZlcnlUeFJlcXVlc3QsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBTb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGEsXG4gIFRva2VuRW5hYmxlbWVudCxcbiAgVG9rZW5FbmFibGVtZW50Q29uZmlnLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUcmFuc2FjdGlvblBhcmFtcyxcbiAgVHJhbnNhY3Rpb25SZWNpcGllbnQsXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHNzVmVyaWZ5QWRkcmVzc09wdGlvbnMsXG4gIHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyxcbiAgVW5leHBlY3RlZEFkZHJlc3NFcnJvcixcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgYXVkaXRFZGRzYVByaXZhdGVLZXksIGdldERlcml2YXRpb25QYXRoIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0IHsgQmFzZU5ldHdvcmssIENvaW5GYW1pbHksIGNvaW5zLCBTb2xDb2luLCBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7XG4gIEtleVBhaXIgYXMgU29sS2V5UGFpcixcbiAgVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uQnVpbGRlcixcbiAgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSxcbiAgZXhwbGFpblNvbFRyYW5zYWN0aW9uLFxufSBmcm9tICcuL2xpYic7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGFzIFNvbExpYlRyYW5zYWN0aW9uRXhwbGFuYXRpb24gfSBmcm9tICcuL2xpYi9pZmFjZSc7XG5pbXBvcnQge1xuICBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyxcbiAgZ2V0U29sVG9rZW5Gcm9tQWRkcmVzcyxcbiAgZ2V0U29sVG9rZW5Gcm9tVG9rZW5OYW1lLFxuICBpc1ZhbGlkQWRkcmVzcyxcbiAgaXNWYWxpZFByaXZhdGVLZXksXG4gIGlzVmFsaWRQdWJsaWNLZXksXG4gIHZhbGlkYXRlUmF3VHJhbnNhY3Rpb24sXG59IGZyb20gJy4vbGliL3V0aWxzJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0NBTl9GQUNUT1IgPSAyMDsgLy8gZGVmYXVsdCBudW1iZXIgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgdG8gc2NhbiBmb3IgZnVuZHNcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvbkZlZSB7XG4gIGZlZTogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBTb2xUcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0gVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcblxuZXhwb3J0IGludGVyZmFjZSBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhCYXNlNjQ6IHN0cmluZztcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG4gIHRva2VuQWNjb3VudFJlbnRFeGVtcHRBbW91bnQ/OiBzdHJpbmc7XG4gIGNvaW5OYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFR4SW5mbyB7XG4gIHJlY2lwaWVudHM6IFRyYW5zYWN0aW9uUmVjaXBpZW50W107XG4gIGZyb206IHN0cmluZztcbiAgdHhpZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBTaWduVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcHJ2OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgcHViS2V5cz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zYWN0aW9uUHJlYnVpbGQgZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCB7XG4gIHR4QmFzZTY0OiBzdHJpbmc7XG4gIHR4SW5mbzogVHhJbmZvO1xuICBzb3VyY2U6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTb2xWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMge1xuICBtZW1vPzogTWVtbztcbiAgZmVlUGF5ZXI6IHN0cmluZztcbiAgYmxvY2toYXNoOiBzdHJpbmc7XG4gIGR1cmFibGVOb25jZT86IHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBzdHJpbmc7IGF1dGhXYWxsZXRBZGRyZXNzOiBudW1iZXIgfTtcbn1cblxuaW50ZXJmYWNlIFRyYW5zYWN0aW9uT3V0cHV0IHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBhbW91bnQ6IG51bWJlciB8IHN0cmluZztcbiAgdG9rZW5OYW1lPzogc3RyaW5nO1xufVxuXG50eXBlIFRyYW5zYWN0aW9uSW5wdXQgPSBUcmFuc2FjdGlvbk91dHB1dDtcblxuZXhwb3J0IGludGVyZmFjZSBTb2xQYXJzZWRUcmFuc2FjdGlvbiBleHRlbmRzIFBhcnNlZFRyYW5zYWN0aW9uIHtcbiAgLy8gdG90YWwgYXNzZXRzIGJlaW5nIG1vdmVkLCBpbmNsdWRpbmcgZmVlc1xuICBpbnB1dHM6IFRyYW5zYWN0aW9uSW5wdXRbXTtcblxuICAvLyB3aGVyZSBhc3NldHMgYXJlIG1vdmVkIHRvXG4gIG91dHB1dHM6IFRyYW5zYWN0aW9uT3V0cHV0W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29sUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEJhc2U2NDogc3RyaW5nO1xuICBmZWVJbmZvOiBUcmFuc2FjdGlvbkZlZTtcbiAgdG9rZW5BY2NvdW50UmVudEV4ZW1wdEFtb3VudD86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFNvbER1cmFibGVOb25jZUZyb21Ob2RlIHtcbiAgYXV0aG9yaXR5OiBzdHJpbmc7XG4gIGJsb2NraGFzaDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgVG9rZW5BbW91bnQge1xuICBhbW91bnQ6IHN0cmluZztcbiAgZGVjaW1hbHM6IG51bWJlcjtcbiAgdWlBbW91bnQ6IG51bWJlcjtcbiAgdWlBbW91bnRTdHJpbmc6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFRva2VuQWNjb3VudEluZm8ge1xuICBpc05hdGl2ZTogYm9vbGVhbjtcbiAgbWludDogc3RyaW5nO1xuICBvd25lcjogc3RyaW5nO1xuICBzdGF0ZTogc3RyaW5nO1xuICB0b2tlbkFtb3VudDogVG9rZW5BbW91bnQ7XG59XG5cbmludGVyZmFjZSBUb2tlbkFjY291bnQge1xuICBpbmZvOiBUb2tlbkFjY291bnRJbmZvO1xuICBwdWJLZXk6IHN0cmluZztcbiAgdG9rZW5OYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbFJlY292ZXJ5T3B0aW9ucyBleHRlbmRzIE1QQ1JlY292ZXJ5T3B0aW9ucyB7XG4gIGR1cmFibGVOb25jZT86IHtcbiAgICBwdWJsaWNLZXk6IHN0cmluZztcbiAgICBzZWNyZXRLZXk6IHN0cmluZztcbiAgfTtcbiAgdG9rZW5Db250cmFjdEFkZHJlc3M/OiBzdHJpbmc7XG4gIGNsb3NlQXRhQWRkcmVzcz86IHN0cmluZztcbiAgLy8gZGVzdGluYXRpb24gYWRkcmVzcyB3aGVyZSB0b2tlbiBzaG91bGQgYmUgc2VudCBiZWZvcmUgY2xvc2luZyB0aGUgQVRBIGFkZHJlc3NcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbkF0YUFkZHJlc3M/OiBzdHJpbmc7XG4gIC8vIG5lc3RlZCBBVEEgYWRkcmVzcyAoQVRBIHdob3NlIG93bmVyIGlzIGFub3RoZXIgQVRBKSB0byByZWNvdmVyIHRva2VucyBmcm9tXG4gIG5lc3RlZEF0YUFkZHJlc3M/OiBzdHJpbmc7XG4gIC8vIHRoZSBBVEEgdGhhdCBvd25zIHRoZSBuZXN0ZWQgQVRBIChhbmQgd2hlcmUgcmVjb3ZlcmVkIHRva2VucyB3aWxsIGJlIHNlbnQpXG4gIG93bmVyQXRhQWRkcmVzcz86IHN0cmluZztcbiAgLy8gdGhlIHRva2VuIG1pbnQgYWRkcmVzcyBmb3IgYm90aCBBVEFzIChyZXF1aXJlZCB3aGVuIHJlY292ZXJpbmcgZnJvbSBuZXN0ZWQgQVRBKVxuICB0b2tlbk1pbnRBZGRyZXNzPzogc3RyaW5nO1xuICBwcm9ncmFtSWQ/OiBzdHJpbmc7IC8vIHByb2dyYW1JZCBvZiB0aGUgdG9rZW5cbiAgYXBpS2V5Pzogc3RyaW5nOyAvLyBBUEkga2V5IGZvciBub2RlIHJlcXVlc3RzXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29sQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyBleHRlbmRzIE1QQ0NvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnMge1xuICBkdXJhYmxlTm9uY2VzOiB7XG4gICAgcHVibGljS2V5czogc3RyaW5nW107XG4gICAgc2VjcmV0S2V5OiBzdHJpbmc7XG4gIH07XG4gIHRva2VuQ29udHJhY3RBZGRyZXNzPzogc3RyaW5nO1xuICBhcGlLZXk/OiBzdHJpbmc7IC8vIEFQSSBrZXkgZm9yIG5vZGUgcmVxdWVzdHNcbiAgcHJvZ3JhbUlkPzogc3RyaW5nOyAvLyBwcm9ncmFtSWQgb2YgdGhlIHRva2VuXG59XG5cbmNvbnN0IEhFWF9SRUdFWCA9IC9eWzAtOWEtZkEtRl0rJC87XG5jb25zdCBCTElORF9TSUdOSU5HX1RYX1RZUEVTX1RPX0NIRUNLID0geyBlbmFibGV0b2tlbjogJ0Fzc29jaWF0ZWRUb2tlbkFjY291bnRJbml0aWFsaXphdGlvbicgfTtcblxuLyoqXG4gKiBHZXQgYW1vdW50IHN0cmluZyBjb3JyZWN0ZWQgZm9yIGFyY2hpdGVjdHVyZS1zcGVjaWZpYyBlbmRpYW5uZXNzIGlzc3Vlcy5cbiAqXG4gKiBPbiBzMzkweCAoYmlnLWVuZGlhbikgYXJjaGl0ZWN0dXJlLCB0aGUgU29sYW5hIHRyYW5zYWN0aW9uIHBhcnNlciAodmlhIEBzb2xhbmEvd2ViMy5qcylcbiAqIGluY29ycmVjdGx5IHJlYWRzIGxpdHRsZS1lbmRpYW4gdTY0IGFtb3VudHMgYXMgYmlnLWVuZGlhbiwgcmVzdWx0aW5nIGluIGNvcnJ1cHRlZCB2YWx1ZXMuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBjb3JyZWN0cyBhbGwgYW1vdW50cyBvbiBzMzkweCBieSBzd2FwcGluZyBieXRlIG9yZGVyIHRvIHVuZG9cbiAqIHRoZSBpbmNvcnJlY3QgYnl0ZSBvcmRlciB0aGF0IGhhcHBlbmVkIGR1cmluZyB0cmFuc2FjdGlvbiBwYXJzaW5nLlxuICpcbiAqIEBwYXJhbSBhbW91bnQgLSBUaGUgYW1vdW50IHRvIGNoZWNrIGFuZCBwb3RlbnRpYWxseSBmaXhcbiAqIEByZXR1cm5zIFRoZSBjb3JyZWN0ZWQgYW1vdW50IGFzIGEgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcyhhbW91bnQ6IHN0cmluZyB8IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGFtb3VudFN0ciA9IFN0cmluZyhhbW91bnQpO1xuXG4gIC8vIE9ubHkgczM5MHggYXJjaGl0ZWN0dXJlIGhhcyB0aGlzIGVuZGlhbm5lc3MgaXNzdWVcbiAgY29uc3QgaXNTMzkweCA9IHByb2Nlc3MuYXJjaCA9PT0gJ3MzOTB4JztcbiAgaWYgKCFpc1MzOTB4KSB7XG4gICAgcmV0dXJuIGFtb3VudFN0cjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgYW1vdW50Qk4gPSBCaWdJbnQoYW1vdW50U3RyKTtcbiAgICAvLyBPbiBzMzkweCwgdGhlIHBhcnNlciBBTFdBWVMgcmVhZHMgdTY0IGFzIGJpZy1lbmRpYW4gd2hlbiBpdCdzIGFjdHVhbGx5IGxpdHRsZS1lbmRpYW5cbiAgICAvLyBTbyB3ZSBBTFdBWVMgbmVlZCB0byBzd2FwIGJ5dGVzIHRvIGdldCB0aGUgY29ycmVjdCB2YWx1ZVxuICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlci5hbGxvYyg4KTtcbiAgICBidWYud3JpdGVCaWdVSW50NjRCRShhbW91bnRCTiwgMCk7XG4gICAgY29uc3QgZml4ZWQgPSBidWYucmVhZEJpZ1VJbnQ2NExFKDApO1xuICAgIHJldHVybiBmaXhlZC50b1N0cmluZygpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSWYgY29udmVyc2lvbiBmYWlscywgcmV0dXJuIG9yaWdpbmFsIHZhbHVlXG4gICAgcmV0dXJuIGFtb3VudFN0cjtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgU29sIGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuXG4gIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IFNvbChiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgYWxsb3dzQWNjb3VudENvbnNvbGlkYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgc3VwcG9ydHNUc3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNNZXNzYWdlU2lnbmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGdldERlZmF1bHRNdWx0aXNpZ1R5cGUoKTogTXVsdGlzaWdUeXBlIHtcbiAgICByZXR1cm4gbXVsdGlzaWdUeXBlcy50c3M7XG4gIH1cblxuICBnZXRNUENBbGdvcml0aG0oKTogTVBDQWxnb3JpdGhtIHtcbiAgICByZXR1cm4gJ2VkZHNhJztcbiAgfVxuXG4gIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICBnZXRGYW1pbHkoKTogQ29pbkZhbWlseSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZhbWlseTtcbiAgfVxuXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgZ2V0TmV0d29yaygpOiBCYXNlTmV0d29yayB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5ldHdvcms7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGF0aWNzQ29pbi5kZWNpbWFsUGxhY2VzKTtcbiAgfVxuXG4gIHZlcmlmeVR4VHlwZShleHBlY3RlZFR5cGVGcm9tVXNlclBhcmFtczogc3RyaW5nLCBhY3R1YWxUeXBlRnJvbURlY29kZWQ6IHN0cmluZyB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGNvbnN0IG1hdGNoRnJvbVVzZXJUb0RlY29kZWRUeXBlID0gQkxJTkRfU0lHTklOR19UWF9UWVBFU19UT19DSEVDS1tleHBlY3RlZFR5cGVGcm9tVXNlclBhcmFtc107XG4gICAgaWYgKG1hdGNoRnJvbVVzZXJUb0RlY29kZWRUeXBlICE9PSBhY3R1YWxUeXBlRnJvbURlY29kZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgdHJhbnNhY3Rpb24gdHlwZSBvbiB0b2tlbiBlbmFibGVtZW50OiBleHBlY3RlZCBcIiR7bWF0Y2hGcm9tVXNlclRvRGVjb2RlZFR5cGV9XCIsIGdvdCBcIiR7YWN0dWFsVHlwZUZyb21EZWNvZGVkfVwiLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3dJZk1pc3NpbmdUb2tlbkVuYWJsZW1lbnRzT3JSZXR1cm4oZXhwbGFuYXRpb246IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24pOiBJVG9rZW5FbmFibGVtZW50W10ge1xuICAgIGlmICghZXhwbGFuYXRpb24udG9rZW5FbmFibGVtZW50cyB8fCBleHBsYW5hdGlvbi50b2tlbkVuYWJsZW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0eCB0b2tlbiBlbmFibGVtZW50cyBkYXRhIG9uIHRva2VuIGVuYWJsZW1lbnQgdHggcHJlYnVpbGQnKTtcbiAgICByZXR1cm4gZXhwbGFuYXRpb24udG9rZW5FbmFibGVtZW50cztcbiAgfVxuXG4gIHRocm93SWZNaXNzaW5nRW5hYmxlVG9rZW5Db25maWdPclJldHVybih0eFBhcmFtczogVHJhbnNhY3Rpb25QYXJhbXMpOiBUb2tlbkVuYWJsZW1lbnRbXSB7XG4gICAgaWYgKCF0eFBhcmFtcy5lbmFibGVUb2tlbnMgfHwgdHhQYXJhbXMuZW5hYmxlVG9rZW5zLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGVuYWJsZSB0b2tlbiBjb25maWcnKTtcbiAgICByZXR1cm4gdHhQYXJhbXMuZW5hYmxlVG9rZW5zO1xuICB9XG5cbiAgdmVyaWZ5VG9rZW5OYW1lKHRva2VuRW5hYmxlbWVudHNQcmVidWlsZDogSVRva2VuRW5hYmxlbWVudFtdLCBlbmFibGVUb2tlbnNDb25maWc6IFRva2VuRW5hYmxlbWVudFtdKTogdm9pZCB7XG4gICAgZW5hYmxlVG9rZW5zQ29uZmlnLmZvckVhY2goKGVuYWJsZVRva2VuQ29uZmlnKSA9PiB7XG4gICAgICBjb25zdCBleHBlY3RlZFRva2VuTmFtZSA9IGVuYWJsZVRva2VuQ29uZmlnLm5hbWU7XG4gICAgICB0b2tlbkVuYWJsZW1lbnRzUHJlYnVpbGQuZm9yRWFjaCgodG9rZW5FbmFibGVtZW50KSA9PiB7XG4gICAgICAgIGlmICghdG9rZW5FbmFibGVtZW50LnRva2VuTmFtZSkgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRva2VuIG5hbWUgb24gdG9rZW4gZW5hYmxlbWVudCB0eCcpO1xuICAgICAgICBpZiAodG9rZW5FbmFibGVtZW50LnRva2VuTmFtZSAhPT0gZXhwZWN0ZWRUb2tlbk5hbWUpXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYEludmFsaWQgdG9rZW4gbmFtZTogZXhwZWN0ZWQgJHtleHBlY3RlZFRva2VuTmFtZX0sIGdvdCAke3Rva2VuRW5hYmxlbWVudC50b2tlbk5hbWV9IG9uIHRva2VuIGVuYWJsZW1lbnQgdHhgXG4gICAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5VG9rZW5BZGRyZXNzKFxuICAgIHRva2VuRW5hYmxlbWVudHNQcmVidWlsZDogSVRva2VuRW5hYmxlbWVudFtdLFxuICAgIGVuYWJsZVRva2Vuc0NvbmZpZzogVG9rZW5FbmFibGVtZW50W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChjb25zdCBlbmFibGVUb2tlbkNvbmZpZyBvZiBlbmFibGVUb2tlbnNDb25maWcpIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVG9rZW5BZGRyZXNzID0gZW5hYmxlVG9rZW5Db25maWcuYWRkcmVzcztcbiAgICAgIGNvbnN0IGV4cGVjdGVkVG9rZW5OYW1lID0gZW5hYmxlVG9rZW5Db25maWcubmFtZTtcblxuICAgICAgaWYgKCFleHBlY3RlZFRva2VuQWRkcmVzcykgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRva2VuIGFkZHJlc3Mgb24gdG9rZW4gZW5hYmxlbWVudCB0eCcpO1xuICAgICAgaWYgKCFleHBlY3RlZFRva2VuTmFtZSkgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRva2VuIG5hbWUgb24gdG9rZW4gZW5hYmxlbWVudCB0eCcpO1xuXG4gICAgICBmb3IgKGNvbnN0IHRva2VuRW5hYmxlbWVudCBvZiB0b2tlbkVuYWJsZW1lbnRzUHJlYnVpbGQpIHtcbiAgICAgICAgbGV0IHRva2VuTWludEFkZHJlc3M6IFJlYWRvbmx5PFNvbENvaW4+IHwgdW5kZWZpbmVkO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRva2VuTWludEFkZHJlc3MgPSBnZXRTb2xUb2tlbkZyb21Ub2tlbk5hbWUoZXhwZWN0ZWRUb2tlbk5hbWUpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBkZXJpdmUgQVRBIGZvciB0b2tlbiBhZGRyZXNzOiAke2V4cGVjdGVkVG9rZW5BZGRyZXNzfWApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhdG9rZW5NaW50QWRkcmVzcyB8fFxuICAgICAgICAgIHRva2VuTWludEFkZHJlc3MudG9rZW5BZGRyZXNzID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzLnByb2dyYW1JZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGdldCB0b2tlbiBtaW50IGFkZHJlc3MgZm9yICR7ZXhwZWN0ZWRUb2tlbk5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGF0YTogc3RyaW5nO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF0YSA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzKFxuICAgICAgICAgICAgdG9rZW5NaW50QWRkcmVzcy50b2tlbkFkZHJlc3MsXG4gICAgICAgICAgICBleHBlY3RlZFRva2VuQWRkcmVzcyxcbiAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzLnByb2dyYW1JZFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGRlcml2ZSBBVEEgZm9yIHRva2VuIGFkZHJlc3M6ICR7ZXhwZWN0ZWRUb2tlbkFkZHJlc3N9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGF0YSAhPT0gdG9rZW5FbmFibGVtZW50LmFkZHJlc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgSW52YWxpZCB0b2tlbiBhZGRyZXNzOiBleHBlY3RlZCAke2F0YX0sIGdvdCAke3Rva2VuRW5hYmxlbWVudC5hZGRyZXNzfSBvbiB0b2tlbiBlbmFibGVtZW50IHR4YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhc1NvbFZlcnNpb25lZFRyYW5zYWN0aW9uRGF0YShcbiAgICB0eFBhcmFtczogVHJhbnNhY3Rpb25QYXJhbXNcbiAgKTogdHhQYXJhbXMgaXMgVHJhbnNhY3Rpb25QYXJhbXMgJiB7IHNvbFZlcnNpb25lZFRyYW5zYWN0aW9uRGF0YTogU29sVmVyc2lvbmVkVHJhbnNhY3Rpb25EYXRhIH0ge1xuICAgIHJldHVybiAnc29sVmVyc2lvbmVkVHJhbnNhY3Rpb25EYXRhJyBpbiB0eFBhcmFtcyAmJiB0eFBhcmFtcy5zb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGEgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgYSB2ZXJzaW9uZWQgU29sYW5hIHRyYW5zYWN0aW9uIHdpdGggYmFzaWMgc3RydWN0dXJhbCB2YWxpZGF0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSB2ZXJpZmljYXRpb24gcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJucyB0cnVlIGlmIHZlcmlmaWNhdGlvbiBwYXNzZXNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdmVyaWZ5VmVyc2lvbmVkVHJhbnNhY3Rpb24ocGFyYW1zOiBTb2xWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgcmF3VHggPSB0eFByZWJ1aWxkLnR4QmFzZTY0IHx8IHR4UHJlYnVpbGQudHhIZXg7XG5cbiAgICBpZiAoIXJhd1R4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhCYXNlNjQgb3IgdHhIZXgnKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aGF0IHRoZSB2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gZGF0YSBpcyB3ZWxsLWZvcm1lZFxuICAgIGlmICghdGhpcy5oYXNTb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGEodHhQYXJhbXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvbFZlcnNpb25lZFRyYW5zYWN0aW9uRGF0YSBpcyByZXF1aXJlZCBmb3IgdmVyc2lvbmVkIHRyYW5zYWN0aW9uIHZlcmlmaWNhdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHZlcnNpb25lZERhdGEgPSB0eFBhcmFtcy5zb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGE7XG5cbiAgICBpZiAoIXZlcnNpb25lZERhdGEudmVyc2lvbmVkSW5zdHJ1Y3Rpb25zIHx8IHZlcnNpb25lZERhdGEudmVyc2lvbmVkSW5zdHJ1Y3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBpbnN0cnVjdGlvbicpO1xuICAgIH1cblxuICAgIGlmICghdmVyc2lvbmVkRGF0YS5zdGF0aWNBY2NvdW50S2V5cyB8fCB2ZXJzaW9uZWREYXRhLnN0YXRpY0FjY291bnRLZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBzdGF0aWMgYWNjb3VudCBrZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXZlcnNpb25lZERhdGEubWVzc2FnZUhlYWRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gbXVzdCBoYXZlIGEgbWVzc2FnZSBoZWFkZXInKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSB0aGF0IHdlIGNhbiBkZXNlcmlhbGl6ZSB0aGUgdHJhbnNhY3Rpb25cbiAgICBsZXQgcmF3VHhCYXNlNjQgPSByYXdUeDtcbiAgICBpZiAoSEVYX1JFR0VYLnRlc3QocmF3VHgpKSB7XG4gICAgICByYXdUeEJhc2U2NCA9IEJ1ZmZlci5mcm9tKHJhd1R4LCAnaGV4JykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0eEJ5dGVzID0gQnVmZmVyLmZyb20ocmF3VHhCYXNlNjQsICdiYXNlNjQnKTtcbiAgICAgIGlmICh0eEJ5dGVzLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0cmFuc2FjdGlvbiBieXRlcyBhcmUgZW1wdHknKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgdmVyc2lvbiBieXRlIChhZnRlciBzaWduYXR1cmVzKVxuICAgICAgY29uc3QgbnVtU2lnbmF0dXJlcyA9IHR4Qnl0ZXNbMF07XG4gICAgICBjb25zdCBzaWduYXR1cmVTaXplID0gNjQ7XG4gICAgICBjb25zdCB2ZXJzaW9uQnl0ZU9mZnNldCA9IDEgKyBudW1TaWduYXR1cmVzICogc2lnbmF0dXJlU2l6ZTtcblxuICAgICAgaWYgKHR4Qnl0ZXMubGVuZ3RoIDw9IHZlcnNpb25CeXRlT2Zmc2V0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndHJhbnNhY3Rpb24gYnl0ZXMgYXJlIHRvbyBzaG9ydCB0byBjb250YWluIHZlcnNpb24gYnl0ZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2ZXJzaW9uQnl0ZSA9IHR4Qnl0ZXNbdmVyc2lvbkJ5dGVPZmZzZXRdO1xuICAgICAgY29uc3QgaXNWZXJzaW9uZWQgPSAodmVyc2lvbkJ5dGUgJiAweDgwKSAhPT0gMDtcblxuICAgICAgaWYgKCFpc1ZlcnNpb25lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RyYW5zYWN0aW9uIGRvZXMgbm90IGhhdmUgdmVyc2lvbmVkIGZvcm1hdCcpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byB2YWxpZGF0ZSB2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gZm9ybWF0OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFNvbFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIGFzc2V0IG5hbWUgdG8gdHJhbnNmZXIgYW1vdW50IG1hcFxuICAgIGNvbnN0IHRvdGFsQW1vdW50OiBSZWNvcmQ8c3RyaW5nLCBCaWdOdW1iZXI+ID0ge307XG4gICAgY29uc3QgY29pbkNvbmZpZyA9IGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpO1xuICAgIGNvbnN0IHtcbiAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyxcbiAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQsXG4gICAgICBtZW1vOiBtZW1vLFxuICAgICAgZHVyYWJsZU5vbmNlOiBkdXJhYmxlTm9uY2UsXG4gICAgICB2ZXJpZmljYXRpb246IHZlcmlmaWNhdGlvbk9wdGlvbnMsXG4gICAgfSA9IHBhcmFtcztcblxuICAgIGlmICh0aGlzLmhhc1NvbFZlcnNpb25lZFRyYW5zYWN0aW9uRGF0YSh0eFBhcmFtcykpIHtcbiAgICAgIHJldHVybiB0aGlzLnZlcmlmeVZlcnNpb25lZFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oY29pbkNvbmZpZyk7XG4gICAgY29uc3QgcmF3VHggPSB0eFByZWJ1aWxkLnR4QmFzZTY0IHx8IHR4UHJlYnVpbGQudHhIZXg7XG4gICAgY29uc3QgY29uc29saWRhdGVJZCA9IHR4UHJlYnVpbGQuY29uc29saWRhdGVJZDtcblxuICAgIGNvbnN0IHdhbGxldFJvb3RBZGRyZXNzID0gcGFyYW1zLndhbGxldC5jb2luU3BlY2lmaWMoKT8ucm9vdEFkZHJlc3M7XG5cbiAgICBpZiAoIXJhd1R4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhCYXNlNjQgb3IgdHhIZXgnKTtcbiAgICB9XG5cbiAgICBsZXQgcmF3VHhCYXNlNjQgPSByYXdUeDtcbiAgICBpZiAoSEVYX1JFR0VYLnRlc3QocmF3VHgpKSB7XG4gICAgICByYXdUeEJhc2U2NCA9IEJ1ZmZlci5mcm9tKHJhd1R4LCAnaGV4JykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIH1cbiAgICB0cmFuc2FjdGlvbi5mcm9tUmF3VHJhbnNhY3Rpb24ocmF3VHhCYXNlNjQpO1xuICAgIGNvbnN0IGV4cGxhaW5lZFR4ID0gdHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG5cbiAgICBpZiAodHhQYXJhbXMudHlwZSA9PT0gJ2VuYWJsZXRva2VuJyAmJiB2ZXJpZmljYXRpb25PcHRpb25zPy52ZXJpZnlUb2tlbkVuYWJsZW1lbnQpIHtcbiAgICAgIHRoaXMudmVyaWZ5VHhUeXBlKHR4UGFyYW1zLnR5cGUsIGV4cGxhaW5lZFR4LnR5cGUpO1xuICAgICAgY29uc3QgdG9rZW5FbmFibGVtZW50c1ByZWJ1aWxkID0gdGhpcy50aHJvd0lmTWlzc2luZ1Rva2VuRW5hYmxlbWVudHNPclJldHVybihleHBsYWluZWRUeCk7XG4gICAgICBjb25zdCBlbmFibGVUb2tlbnNDb25maWcgPSB0aGlzLnRocm93SWZNaXNzaW5nRW5hYmxlVG9rZW5Db25maWdPclJldHVybih0eFBhcmFtcyk7XG5cbiAgICAgIHRoaXMudmVyaWZ5VG9rZW5OYW1lKHRva2VuRW5hYmxlbWVudHNQcmVidWlsZCwgZW5hYmxlVG9rZW5zQ29uZmlnKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5VG9rZW5BZGRyZXNzKHRva2VuRW5hYmxlbWVudHNQcmVidWlsZCwgZW5hYmxlVG9rZW5zQ29uZmlnKTtcbiAgICB9XG5cbiAgICAvLyB1c2VycyBkbyBub3QgaW5wdXQgcmVjaXBpZW50cyBmb3IgY29uc29saWRhdGlvbiByZXF1ZXN0cyBhcyB0aGV5IGFyZSBnZW5lcmF0ZWQgYnkgdGhlIHNlcnZlclxuICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkUmVjaXBpZW50cyA9IHR4UGFyYW1zLnJlY2lwaWVudHM/Lm1hcCgocmVjaXBpZW50KSA9PlxuICAgICAgICBfLnBpY2socmVjaXBpZW50LCBbJ2FkZHJlc3MnLCAnYW1vdW50JywgJ3Rva2VuTmFtZSddKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkT3V0cHV0cyA9IGV4cGxhaW5lZFR4Lm91dHB1dHMubWFwKChvdXRwdXQpID0+IF8ucGljayhvdXRwdXQsIFsnYWRkcmVzcycsICdhbW91bnQnLCAndG9rZW5OYW1lJ10pKTtcblxuICAgICAgaWYgKGZpbHRlcmVkUmVjaXBpZW50cy5sZW5ndGggIT09IGZpbHRlcmVkT3V0cHV0cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOdW1iZXIgb2YgdHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIG51bWJlciBvZiB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvciBlYWNoIHJlY2lwaWVudCwgY2hlY2sgaWYgaXQncyBhIHRva2VuIHR4ICh0b2tlbk5hbWUgd2lsbCBleGlzdCBpZiBzbylcbiAgICAgIC8vIElmIGl0IGlzIGEgdG9rZW4gdHgsIHZlcmlmeSB0aGF0IHRoZSByZWNpcGllbnQgYWRkcmVzcyBlcXVhbHMgdGhlIGRlcml2ZWQgYWRkcmVzcyBmcm9tIGV4cGxhaW5lZFR4XG4gICAgICAvLyBEZXJpdmUgdGhlIEFUQSBpZiBpdCBpcyBhIG5hdGl2ZSBhZGRyZXNzIGFuZCBjb25maXJtIGl0IGlzIGVxdWFsIHRvIHRoZSBleHBsYWluZWQgdHggcmVjaXBpZW50XG4gICAgICBjb25zdCByZWNpcGllbnRDaGVja3MgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgZmlsdGVyZWRSZWNpcGllbnRzLm1hcChhc3luYyAocmVjaXBpZW50RnJvbVVzZXIsIGluZGV4KSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVjaXBpZW50RnJvbVR4ID0gZmlsdGVyZWRPdXRwdXRzW2luZGV4XTsgLy8gVGhpcyBhZGRyZXNzIHNob3VsZCBiZSBhbiBBVEFcblxuICAgICAgICAgIC8vIENvbXBhcmUgdGhlIEJpZ051bWJlciB2YWx1ZXMgYmVjYXVzZSBhbW91bnQgaXMgKHN0cmluZyB8IG51bWJlcilcbiAgICAgICAgICAvLyBBcHBseSBzMzkweCBlbmRpYW5uZXNzIGZpeCBpZiBuZWVkZWRcbiAgICAgICAgICBjb25zdCB1c2VyQW1vdW50U3RyID0gU3RyaW5nKHJlY2lwaWVudEZyb21Vc2VyLmFtb3VudCk7XG4gICAgICAgICAgY29uc3QgdHhBbW91bnRTdHIgPSBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcyhyZWNpcGllbnRGcm9tVHguYW1vdW50KTtcblxuICAgICAgICAgIGNvbnN0IHVzZXJBbW91bnQgPSBuZXcgQmlnTnVtYmVyKHVzZXJBbW91bnRTdHIpO1xuICAgICAgICAgIGNvbnN0IHR4QW1vdW50ID0gbmV3IEJpZ051bWJlcih0eEFtb3VudFN0cik7XG4gICAgICAgICAgaWYgKCF1c2VyQW1vdW50LmlzRXF1YWxUbyh0eEFtb3VudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBDb21wYXJlIHRoZSBhZGRyZXNzZXMgYW5kIHRva2VuTmFtZXNcbiAgICAgICAgICAvLyBFbHNlIGlmIHRoZSBhZGRyZXNzZXMgYXJlIG5vdCB0aGUgc2FtZSwgY2hlY2sgdGhlIGRlcml2ZWQgQVRBIGZvciBwYXJpdHlcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICByZWNpcGllbnRGcm9tVXNlci5hZGRyZXNzID09PSByZWNpcGllbnRGcm9tVHguYWRkcmVzcyAmJlxuICAgICAgICAgICAgcmVjaXBpZW50RnJvbVVzZXIudG9rZW5OYW1lID09PSByZWNpcGllbnRGcm9tVHgudG9rZW5OYW1lXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlY2lwaWVudEZyb21Vc2VyLmFkZHJlc3MgIT09IHJlY2lwaWVudEZyb21UeC5hZGRyZXNzICYmIHJlY2lwaWVudEZyb21Vc2VyLnRva2VuTmFtZSkge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIGNoZWNrIGlmIHRoZSB1c2VyJ3MgZGVyaXZlZCBBVEEgaXMgZXF1YWwgdG8gdGhlIHR4IHJlY2lwaWVudCBhZGRyZXNzXG4gICAgICAgICAgICAvLyBJZiBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyB0aHJvd3MgYW4gZXJyb3IsIHRoZW4gd2UgYXJlIHVuYWJsZSB0byBkZXJpdmUgdGhlIEFUQSBmb3IgdGhhdCBhZGRyZXNzLlxuICAgICAgICAgICAgLy8gUmV0dXJuIGZhbHNlIGFuZCB0aHJvdyBhbiBlcnJvciBpZiB0aGF0IGlzIHRoZSBjYXNlLlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgdG9rZW5NaW50QWRkcmVzcyA9IGdldFNvbFRva2VuRnJvbVRva2VuTmFtZShyZWNpcGllbnRGcm9tVXNlci50b2tlbk5hbWUpO1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgICAgICAgICAgdG9rZW5NaW50QWRkcmVzcyEudG9rZW5BZGRyZXNzLFxuICAgICAgICAgICAgICAgIHJlY2lwaWVudEZyb21Vc2VyLmFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzIS5wcm9ncmFtSWRcbiAgICAgICAgICAgICAgKS50aGVuKChhdGE6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdGEgPT09IHJlY2lwaWVudEZyb21UeC5hZGRyZXNzO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAvLyBVbmFibGUgdG8gZGVyaXZlIEFUQVxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIGlmIChyZWNpcGllbnRDaGVja3MuaW5jbHVkZXMoZmFsc2UpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHZlcmlmaWNhdGlvbk9wdGlvbnM/LmNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzKSB7XG4gICAgICAvL3ZlcmlmeSBmdW5kcyBhcmUgc2VudCB0byB3YWxsZXRSb290QWRkcmVzcyBmb3IgYSBjb25zb2xpZGF0aW9uXG4gICAgICBjb25zdCBmaWx0ZXJlZE91dHB1dHMgPSBleHBsYWluZWRUeC5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiBfLnBpY2sob3V0cHV0LCBbJ2FkZHJlc3MnLCAnYW1vdW50JywgJ3Rva2VuTmFtZSddKSk7XG5cbiAgICAgIC8vIENhY2hlIHRvIHN0b3JlIGFscmVhZHkgZGVyaXZlZCBBVEEgYWRkcmVzc2VzXG4gICAgICBjb25zdCBhdGFBZGRyZXNzQ2FjaGU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2YgZmlsdGVyZWRPdXRwdXRzKSB7XG4gICAgICAgIGlmIChvdXRwdXQudG9rZW5OYW1lKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgY2FjaGUgZmlyc3QgYmVmb3JlIGRlcml2aW5nIEFUQSBhZGRyZXNzXG4gICAgICAgICAgaWYgKCFhdGFBZGRyZXNzQ2FjaGVbb3V0cHV0LnRva2VuTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IHRva2VuTWludEFkZHJlc3MgPSBnZXRTb2xUb2tlbkZyb21Ub2tlbk5hbWUob3V0cHV0LnRva2VuTmFtZSk7XG4gICAgICAgICAgICBpZiAodG9rZW5NaW50QWRkcmVzcz8udG9rZW5BZGRyZXNzICYmIHRva2VuTWludEFkZHJlc3M/LnByb2dyYW1JZCkge1xuICAgICAgICAgICAgICBhdGFBZGRyZXNzQ2FjaGVbb3V0cHV0LnRva2VuTmFtZV0gPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzLnRva2VuQWRkcmVzcyxcbiAgICAgICAgICAgICAgICB3YWxsZXRSb290QWRkcmVzcyBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzLnByb2dyYW1JZFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZ2V0IHRva2VuIGluZm9ybWF0aW9uIGZvciAke291dHB1dC50b2tlbk5hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGF0YUFkZHJlc3NDYWNoZVtvdXRwdXQudG9rZW5OYW1lXSAhPT0gb3V0cHV0LmFkZHJlc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigndHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIGFkZHJlc3MnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAob3V0cHV0LmFkZHJlc3MgIT09IHdhbGxldFJvb3RBZGRyZXNzKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0eCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgYWRkcmVzcycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25Kc29uID0gdHJhbnNhY3Rpb24udG9Kc29uKCk7XG4gICAgaWYgKG1lbW8gJiYgbWVtby52YWx1ZSAhPT0gZXhwbGFpbmVkVHgubWVtbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUeCBtZW1vIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdHhQYXJhbXMgcmVjaXBpZW50IG1lbW8nKTtcbiAgICB9XG4gICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHMpIHtcbiAgICAgIGZvciAoY29uc3QgcmVjaXBpZW50cyBvZiB0eFBhcmFtcy5yZWNpcGllbnRzKSB7XG4gICAgICAgIC8vIHRvdGFsQW1vdW50IGJhc2VkIG9uIGVhY2ggdG9rZW5cbiAgICAgICAgY29uc3QgYXNzZXROYW1lID0gcmVjaXBpZW50cy50b2tlbk5hbWUgfHwgdGhpcy5nZXRDaGFpbigpO1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b3RhbEFtb3VudFthc3NldE5hbWVdIHx8IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgICAgIHRvdGFsQW1vdW50W2Fzc2V0TmFtZV0gPSBhbW91bnQucGx1cyhyZWNpcGllbnRzLmFtb3VudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHRvdGFsIG91dHB1dCBhbW91bnQgZnJvbSBleHBsYWluZWRUeFxuICAgICAgY29uc3QgZXhwbGFpbmVkVHhUb3RhbDogUmVjb3JkPHN0cmluZywgQmlnTnVtYmVyPiA9IHt9O1xuXG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBleHBsYWluZWRUeC5vdXRwdXRzKSB7XG4gICAgICAgIC8vIEFwcGx5IHMzOTB4IGVuZGlhbm5lc3MgZml4IHRvIG91dHB1dCBhbW91bnRzIGJlZm9yZSBzdW1taW5nXG4gICAgICAgIGNvbnN0IG91dHB1dEFtb3VudFN0ciA9IGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKG91dHB1dC5hbW91bnQpO1xuXG4gICAgICAgIC8vIHRvdGFsIG91dHB1dCBhbW91bnQgYmFzZWQgb24gZWFjaCB0b2tlblxuICAgICAgICBjb25zdCBhc3NldE5hbWUgPSBvdXRwdXQudG9rZW5OYW1lIHx8IHRoaXMuZ2V0Q2hhaW4oKTtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gZXhwbGFpbmVkVHhUb3RhbFthc3NldE5hbWVdIHx8IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgICAgIGV4cGxhaW5lZFR4VG90YWxbYXNzZXROYW1lXSA9IGFtb3VudC5wbHVzKG91dHB1dEFtb3VudFN0cik7XG4gICAgICB9XG5cbiAgICAgIGlmICghXy5pc0VxdWFsKGV4cGxhaW5lZFR4VG90YWwsIHRvdGFsQW1vdW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1R4IHRvdGFsIGFtb3VudCBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHRvdGFsIGFtb3VudCBmaWVsZCcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZvciBub24tY29uc29saWRhdGUgdHJhbnNhY3Rpb25zLCBmZWVQYXllciBtdXN0IGJlIHRoZSB3YWxsZXQncyByb290IGFkZHJlc3NcbiAgICBpZiAoY29uc29saWRhdGVJZCA9PT0gdW5kZWZpbmVkICYmIHRyYW5zYWN0aW9uSnNvbi5mZWVQYXllciAhPT0gd2FsbGV0Um9vdEFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHggZmVlIHBheWVyIGlzIG5vdCB0aGUgd2FsbGV0IHJvb3QgYWRkcmVzcycpO1xuICAgIH1cblxuICAgIGlmIChkdXJhYmxlTm9uY2UgJiYgIV8uaXNFcXVhbChleHBsYWluZWRUeC5kdXJhYmxlTm9uY2UsIGR1cmFibGVOb25jZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHggZHVyYWJsZU5vbmNlIGRvZXMgbm90IG1hdGNoIHdpdGggcGFyYW0gZHVyYWJsZU5vbmNlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBUc3NWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyhcbiAgICAgIHBhcmFtcyxcbiAgICAgIChhZGRyZXNzKSA9PiB0aGlzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLFxuICAgICAgKHB1YmxpY0tleSkgPT4gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShwdWJsaWNLZXkpXG4gICAgKTtcblxuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEFkZHJlc3NFcnJvcihgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6ICR7cGFyYW1zLmFkZHJlc3N9IGlzIG5vdCBhIHdhbGxldCBhZGRyZXNzYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBTb2xhbmEgcHVibGljIGtleSB0byBhbiBhZGRyZXNzXG4gICAqIEBwYXJhbSBwdWJsaWNLZXkgSGV4LWVuY29kZWQgcHVibGljIGtleSAoNjQgaGV4IGNoYXJhY3RlcnMgPSAzMiBieXRlcylcbiAgICogQHJldHVybnMgQmFzZTU4LWVuY29kZWQgU29sYW5hIGFkZHJlc3NcbiAgICovXG4gIGdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YmxpY0tleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBwdWJsaWNLZXlCdWZmZXIgPSBCdWZmZXIuZnJvbShwdWJsaWNLZXksICdoZXgnKTtcbiAgICByZXR1cm4gYmFzZTU4LmVuY29kZShwdWJsaWNLZXlCdWZmZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIFNvbGFuYSBrZXkgcGFpclxuICAgKlxuICAgKiBAcGFyYW0ge0J1ZmZlcn0gc2VlZCAtIFNlZWQgZnJvbSB3aGljaCB0aGUgbmV3IFNvbEtleVBhaXIgc2hvdWxkIGJlIGdlbmVyYXRlZCwgb3RoZXJ3aXNlIGEgcmFuZG9tIHNlZWQgaXMgdXNlZFxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvYmplY3Qgd2l0aCBnZW5lcmF0ZWQgcHViIGFuZCBwcnZcbiAgICovXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkPzogQnVmZmVyIHwgdW5kZWZpbmVkKTogS2V5UGFpciB7XG4gICAgY29uc3QgcmVzdWx0ID0gc2VlZCA/IG5ldyBTb2xLZXlQYWlyKHsgc2VlZCB9KS5nZXRLZXlzKCkgOiBuZXcgU29sS2V5UGFpcigpLmdldEtleXMoKTtcbiAgICByZXR1cm4gcmVzdWx0IGFzIEtleVBhaXI7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHB1YmxpYyBrZXkgZm9yIHRoZSBjb2luXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwdWIgdGhlIHBydiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIGlzIGl0IHZhbGlkP1xuICAgKi9cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHByaXZhdGUga2V5IGZvciB0aGUgY29pblxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJ2IHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRQcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNWYWxpZFByaXZhdGVLZXkocHJ2KTtcbiAgfVxuXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIGFzeW5jIHNpZ25NZXNzYWdlKGtleTogS2V5UGFpciwgbWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCBzb2xLZXlwYWlyID0gbmV3IFNvbEtleVBhaXIoeyBwcnY6IGtleS5wcnYgfSk7XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgbWVzc2FnZSA9IGJhc2U1OC5lbmNvZGUobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNvbEtleXBhaXIuc2lnbk1lc3NhZ2UobWVzc2FnZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpZ25zIFNvbGFuYSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBjYWxsYmFja1xuICAgKi9cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogU29sU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBmYWN0b3J5ID0gdGhpcy5nZXRCdWlsZGVyKCk7XG4gICAgY29uc3QgcmF3VHggPSBwYXJhbXMudHhQcmVidWlsZC50eEhleCB8fCBwYXJhbXMudHhQcmVidWlsZC50eEJhc2U2NDtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmF3VHgpO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBwYXJhbXMucHJ2IH0pO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgIGlmICghdHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9ICh0cmFuc2FjdGlvbiBhcyBCYXNlVHJhbnNhY3Rpb24pLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHhIZXg6IHNlcmlhbGl6ZWRUeCxcbiAgICB9IGFzIGFueTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBTb2xQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U29sUGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICAvLyBleHBsYWluVHJhbnNhY3Rpb24gbm93IHVzZXMgV0FTTSBmb3IgdGVzdG5ldCBhdXRvbWF0aWNhbGx5XG4gICAgY29uc3QgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbiA9IGF3YWl0IHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4QmFzZTY0OiBwYXJhbXMudHhCYXNlNjQsXG4gICAgICBmZWVJbmZvOiBwYXJhbXMuZmVlSW5mbyxcbiAgICAgIHRva2VuQWNjb3VudFJlbnRFeGVtcHRBbW91bnQ6IHBhcmFtcy50b2tlbkFjY291bnRSZW50RXhlbXB0QW1vdW50LFxuICAgIH0pO1xuXG4gICAgaWYgKCF0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb2xUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gYXMgU29sVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgICBpZiAoc29sVHJhbnNhY3Rpb24ub3V0cHV0cy5sZW5ndGggPD0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaW5wdXRzOiBbXSxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBzb2xUcmFuc2FjdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3M7XG4gICAgY29uc3QgZmVlQW1vdW50ID0gbmV3IEJpZ051bWJlcihzb2xUcmFuc2FjdGlvbi5mZWUuZmVlKTtcblxuICAgIC8vIGFzc3VtZSAxIHNlbmRlciwgd2hvIGlzIGFsc28gdGhlIGZlZSBwYXllclxuICAgIGNvbnN0IGlucHV0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiBuZXcgQmlnTnVtYmVyKHNvbFRyYW5zYWN0aW9uLm91dHB1dEFtb3VudCkucGx1cyhmZWVBbW91bnQpLnRvTnVtYmVyKCksXG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCBvdXRwdXRzOiBUcmFuc2FjdGlvbk91dHB1dFtdID0gc29sVHJhbnNhY3Rpb24ub3V0cHV0cy5tYXAoKHsgYWRkcmVzcywgYW1vdW50LCB0b2tlbk5hbWUgfSkgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0OiBUcmFuc2FjdGlvbk91dHB1dCA9IHsgYWRkcmVzcywgYW1vdW50IH07XG4gICAgICBpZiAodG9rZW5OYW1lKSB7XG4gICAgICAgIG91dHB1dC50b2tlbk5hbWUgPSB0b2tlbk5hbWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlucHV0cyxcbiAgICAgIG91dHB1dHMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgU29sYW5hIHRyYW5zYWN0aW9uIGZyb20gdHhCYXNlNjRcbiAgICogVXNlcyBXQVNNLWJhc2VkIHBhcnNpbmcgZm9yIHRlc3RuZXQsIHdpdGggZmFsbGJhY2sgdG8gbGVnYWN5IGJ1aWxkZXIgYXBwcm9hY2guXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNvbFRyYW5zYWN0aW9uRXhwbGFuYXRpb24+IHtcbiAgICAvLyBVc2UgV0FTTS1iYXNlZCBwYXJzaW5nIGZvciB0ZXN0bmV0IChzaW1wbGVyLCBmYXN0ZXIsIG5vIEBzb2xhbmEvd2ViMy5qcyByZWJ1aWxkKVxuICAgIGlmICh0aGlzLmdldENoYWluKCkgPT09ICd0c29sJykge1xuICAgICAgcmV0dXJuIHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uV2l0aFdhc20ocGFyYW1zKSBhcyBTb2xUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuICAgIH1cblxuICAgIC8vIExlZ2FjeSBhcHByb2FjaCBmb3IgbWFpbm5ldCAodW50aWwgV0FTTSBpcyBmdWxseSB2YWxpZGF0ZWQpXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuICAgIGxldCByZWJ1aWx0VHJhbnNhY3Rpb247XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25CdWlsZGVyID0gZmFjdG9yeS5mcm9tKHBhcmFtcy50eEJhc2U2NCk7XG4gICAgICBpZiAodHJhbnNhY3Rpb25CdWlsZGVyIGluc3RhbmNlb2YgVHJhbnNhY3Rpb25CdWlsZGVyKSB7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IHRyYW5zYWN0aW9uQnVpbGRlciBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoeyBhbW91bnQ6IHBhcmFtcy5mZWVJbmZvLmZlZSB9KTtcbiAgICAgICAgaWYgKHBhcmFtcy50b2tlbkFjY291bnRSZW50RXhlbXB0QW1vdW50KSB7XG4gICAgICAgICAgdHhCdWlsZGVyLmFzc29jaWF0ZWRUb2tlbkFjY291bnRSZW50KHBhcmFtcy50b2tlbkFjY291bnRSZW50RXhlbXB0QW1vdW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmVidWlsdFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNhY3Rpb25CdWlsZGVyLmJ1aWxkKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLmVycm9yKGUpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSAocmVidWlsdFRyYW5zYWN0aW9uIGFzIEJhc2VUcmFuc2FjdGlvbikuZXhwbGFpblRyYW5zYWN0aW9uKCk7XG5cbiAgICByZXR1cm4gZXhwbGFpbmVkVHJhbnNhY3Rpb24gYXMgU29sVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgU29sYW5hIHRyYW5zYWN0aW9uIHVzaW5nIFdBU00gcGFyc2luZyAoYnlwYXNzZXMgQHNvbGFuYS93ZWIzLmpzIHJlYnVpbGQpLlxuICAgKiBEZWxlZ2F0ZXMgdG8gc3RhbmRhbG9uZSBleHBsYWluU29sVHJhbnNhY3Rpb24oKS5cbiAgICovXG4gIGV4cGxhaW5UcmFuc2FjdGlvbldpdGhXYXNtKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFNvbExpYlRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICAgIHJldHVybiBleHBsYWluU29sVHJhbnNhY3Rpb24oeyAuLi5wYXJhbXMsIGNvaW5OYW1lOiBwYXJhbXMuY29pbk5hbWUgPz8gdGhpcy5nZXRDaGFpbigpIH0pO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFzeW5jIGdldFNpZ25hYmxlUGF5bG9hZChzZXJpYWxpemVkVHg6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuICAgIGNvbnN0IHJlYnVpbHRUcmFuc2FjdGlvbiA9IGF3YWl0IGZhY3RvcnkuZnJvbShzZXJpYWxpemVkVHgpLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgYXN5bmMgcHJlc2lnblRyYW5zYWN0aW9uKHBhcmFtczogUHJlc2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UHJlc2lnblRyYW5zYWN0aW9uT3B0aW9ucz4ge1xuICAgIC8vIEhvdCB3YWxsZXQgdHhucyBhcmUgb25seSB2YWxpZCBmb3IgMS0yIG1pbnV0ZXMuXG4gICAgLy8gVG8gYnV5IG1vcmUgdGltZSwgd2UgcmVidWlsZCB0aGUgdHJhbnNhY3Rpb24gd2l0aCBhIG5ldyBibG9ja2hhc2ggcmlnaHQgYmVmb3JlIHdlIHNpZ24uXG4gICAgaWYgKHBhcmFtcy53YWxsZXREYXRhLnR5cGUgIT09ICdob3QnKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBhcmFtcyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHhSZXF1ZXN0SWQgPSBwYXJhbXMudHhQcmVidWlsZD8udHhSZXF1ZXN0SWQ7XG4gICAgaWYgKHR4UmVxdWVzdElkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0eFJlcXVlc3RJZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdHNzVXRpbHMgfSA9IHBhcmFtcztcblxuICAgIGF3YWl0IHRzc1V0aWxzIS5kZWxldGVTaWduYXR1cmVTaGFyZXModHhSZXF1ZXN0SWQpO1xuICAgIGNvbnN0IHJlY3JlYXRlZCA9IGF3YWl0IHRzc1V0aWxzIS5nZXRUeFJlcXVlc3QodHhSZXF1ZXN0SWQpO1xuICAgIGxldCB0eEhleCA9ICcnO1xuICAgIGlmIChyZWNyZWF0ZWQudW5zaWduZWRUeHMpIHtcbiAgICAgIHR4SGV4ID0gcmVjcmVhdGVkLnVuc2lnbmVkVHhzWzBdPy5zZXJpYWxpemVkVHhIZXg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHR4SGV4ID0gcmVjcmVhdGVkLnRyYW5zYWN0aW9ucyA/IHJlY3JlYXRlZC50cmFuc2FjdGlvbnNbMF0/LnVuc2lnbmVkVHguc2VyaWFsaXplZFR4SGV4IDogJyc7XG4gICAgfVxuXG4gICAgaWYgKCF0eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHNlcmlhbGl6ZWQgdHggaGV4Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAuLi5wYXJhbXMsXG4gICAgICB0eFByZWJ1aWxkOiByZWNyZWF0ZWQsXG4gICAgICB0eEhleCxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRQdWJsaWNOb2RlVXJsKGFwaUtleT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKGFwaUtleSkge1xuICAgICAgcmV0dXJuIEVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS5zb2xBbGNoZW15Tm9kZVVybCArIGAvJHthcGlLZXl9YDtcbiAgICB9XG4gICAgcmV0dXJuIEVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS5zb2xOb2RlVXJsO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYSByZXF1ZXN0IHRvIG9uZSBvZiB0aGUgcHVibGljIFNPTCBub2RlcyBhdmFpbGFibGVcbiAgICogQHBhcmFtIHBhcmFtcy5wYXlsb2FkXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RGF0YUZyb21Ob2RlKFxuICAgIHBhcmFtczogeyBwYXlsb2FkPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfSxcbiAgICBhcGlLZXk/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxyZXF1ZXN0LlJlc3BvbnNlPiB7XG4gICAgY29uc3Qgbm9kZVVybCA9IHRoaXMuZ2V0UHVibGljTm9kZVVybChhcGlLZXkpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVxdWVzdC5wb3N0KG5vZGVVcmwpLnNlbmQocGFyYW1zLnBheWxvYWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoZSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGNhbGwgZW5kcG9pbnQ6ICcvJyBmcm9tIG5vZGU6ICR7bm9kZVVybH1gKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRCbG9ja2hhc2goYXBpS2V5Pzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0RGF0YUZyb21Ob2RlKFxuICAgICAge1xuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdnZXRMYXRlc3RCbG9ja2hhc2gnLFxuICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhcGlLZXlcbiAgICApO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY2NvdW50IG5vdCBmb3VuZCcpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZS5ibG9ja2hhc2g7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RmVlRm9yTWVzc2FnZShtZXNzYWdlOiBzdHJpbmcsIGFwaUtleT86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZShcbiAgICAgIHtcbiAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0RmVlRm9yTWVzc2FnZScsXG4gICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhcGlLZXlcbiAgICApO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY2NvdW50IG5vdCBmb3VuZCcpO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRSZW50RXhlbXB0QW1vdW50KGFwaUtleT86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZShcbiAgICAgIHtcbiAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0TWluaW11bUJhbGFuY2VGb3JSZW50RXhlbXB0aW9uJyxcbiAgICAgICAgICBwYXJhbXM6IFsxNjVdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFwaUtleVxuICAgICk7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwIHx8IHJlc3BvbnNlLmVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuZXJyb3IpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5yZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2UocHViS2V5OiBzdHJpbmcsIGFwaUtleT86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZShcbiAgICAgIHtcbiAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgcGFyYW1zOiBbcHViS2V5XSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhcGlLZXlcbiAgICApO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY2NvdW50IG5vdCBmb3VuZCcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWU7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0QWNjb3VudEluZm8ocHViS2V5OiBzdHJpbmcsIGFwaUtleT86IHN0cmluZyk6IFByb21pc2U8U29sRHVyYWJsZU5vbmNlRnJvbU5vZGU+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0RGF0YUZyb21Ob2RlKFxuICAgICAge1xuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdnZXRBY2NvdW50SW5mbycsXG4gICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICBwdWJLZXksXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgYXBpS2V5XG4gICAgKTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBub3QgZm91bmQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGF1dGhvcml0eTogcmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUuZGF0YS5wYXJzZWQuaW5mby5hdXRob3JpdHksXG4gICAgICBibG9ja2hhc2g6IHJlc3BvbnNlLmJvZHkucmVzdWx0LnZhbHVlLmRhdGEucGFyc2VkLmluZm8uYmxvY2toYXNoLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0VG9rZW5BY2NvdW50c0J5T3duZXIocHViS2V5ID0gJycsIHByb2dyYW1JZCA9ICcnLCBhcGlLZXk/OiBzdHJpbmcpOiBQcm9taXNlPFtdIHwgVG9rZW5BY2NvdW50W10+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0RGF0YUZyb21Ob2RlKFxuICAgICAge1xuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICBwdWJLZXksXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHByb2dyYW1JZDpcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICAgICAgICA/IFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgICA6IFRPS0VOX1BST0dSQU1fSUQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgYXBpS2V5XG4gICAgKTtcbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBub3QgZm91bmQnKTtcbiAgICB9XG5cbiAgICBpZiAocmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUubGVuZ3RoICE9PSAwKSB7XG4gICAgICBjb25zdCB0b2tlbkFjY291bnRzOiBUb2tlbkFjY291bnRbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCB0b2tlbkFjY291bnQgb2YgcmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUpIHtcbiAgICAgICAgdG9rZW5BY2NvdW50cy5wdXNoKHsgaW5mbzogdG9rZW5BY2NvdW50LmFjY291bnQuZGF0YS5wYXJzZWQuaW5mbywgcHViS2V5OiB0b2tlbkFjY291bnQucHViS2V5IH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRva2VuQWNjb3VudHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldFRva2VuQWNjb3VudEluZm8ocHViS2V5OiBzdHJpbmcsIGFwaUtleT86IHN0cmluZyk6IFByb21pc2U8VG9rZW5BY2NvdW50PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldERhdGFGcm9tTm9kZShcbiAgICAgIHtcbiAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0QWNjb3VudEluZm8nLFxuICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgcHViS2V5LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFwaUtleVxuICAgICk7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjY291bnQgbm90IGZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBwdWJLZXk6IHB1YktleSxcbiAgICAgIGluZm86IHJlc3BvbnNlLmJvZHkucmVzdWx0LnZhbHVlLmRhdGEucGFyc2VkLmluZm8sXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGFzeW5jIGNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtczogTVBDU3dlZXBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPE1QQ1R4cz4ge1xuICAgIGlmICghcGFyYW1zLnNpZ25hdHVyZVNoYXJlcykge1xuICAgICAgKCdNaXNzaW5nIHRyYW5zYWN0aW9uKHMpJyk7XG4gICAgfVxuICAgIGNvbnN0IHJlcSA9IHBhcmFtcy5zaWduYXR1cmVTaGFyZXM7XG4gICAgY29uc3QgYnJvYWRjYXN0YWJsZVRyYW5zYWN0aW9uczogTVBDVHhbXSA9IFtdO1xuICAgIGxldCBsYXN0U2NhbkluZGV4ID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVxLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSByZXFbaV0udHhSZXF1ZXN0LnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgaWYgKCFyZXFbaV0ub3ZjIHx8ICFyZXFbaV0ub3ZjWzBdLmVkZHNhU2lnbmF0dXJlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYXR1cmUocyknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHJlcVtpXS5vdmNbMF0uZWRkc2FTaWduYXR1cmU7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLnNpZ25hYmxlSGV4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYWJsZSBoZXgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi5zaWduYWJsZUhleCEsICdoZXgnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IE1QQy52ZXJpZnkobWVzc2FnZUJ1ZmZlciwgc2lnbmF0dXJlKTtcbiAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZUhleCA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHNpZ25hdHVyZS5SLCAnaGV4JyksIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5zaWdtYSwgJ2hleCcpXSk7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSB0aGlzLmdldEJ1aWxkZXIoKS5mcm9tKHRyYW5zYWN0aW9uLnNlcmlhbGl6ZWRUeCBhcyBzdHJpbmcpO1xuICAgICAgaWYgKCF0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/LmNvbW1vbktleWNoYWluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBjb21tb24ga2V5Y2hhaW4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5jb21tb25LZXljaGFpbiEgYXMgc3RyaW5nO1xuICAgICAgaWYgKCF0cmFuc2FjdGlvbi5kZXJpdmF0aW9uUGF0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgZGVyaXZhdGlvbiBwYXRoJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IHRyYW5zYWN0aW9uLmRlcml2YXRpb25QYXRoIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGFjY291bnRJZCA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleWNoYWluLCBkZXJpdmF0aW9uUGF0aCkuc2xpY2UoMCwgNjQpO1xuICAgICAgY29uc3QgYnM1OEVuY29kZWRQdWJsaWNLZXkgPSBuZXcgU29sS2V5UGFpcih7IHB1YjogYWNjb3VudElkIH0pLmdldEFkZHJlc3MoKTtcblxuICAgICAgLy8gYWRkIGNvbWJpbmVkIHNpZ25hdHVyZSBmcm9tIG92Y1xuICAgICAgY29uc3QgcHVibGljS2V5T2JqID0geyBwdWI6IGJzNThFbmNvZGVkUHVibGljS2V5IH07XG4gICAgICB0eEJ1aWxkZXIuYWRkU2lnbmF0dXJlKHB1YmxpY0tleU9iaiBhcyBQdWJsaWNLZXksIHNpZ25hdHVyZUhleCk7XG5cbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBzZXJpYWxpemVkVHggPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBicm9hZGNhc3RhYmxlVHJhbnNhY3Rpb25zLnB1c2goe1xuICAgICAgICBzZXJpYWxpemVkVHg6IHNlcmlhbGl6ZWRUeCxcbiAgICAgICAgc2NhbkluZGV4OiB0cmFuc2FjdGlvbi5zY2FuSW5kZXgsXG4gICAgICB9KTtcblxuICAgICAgaWYgKGkgPT09IHJlcS5sZW5ndGggLSAxICYmIHRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYyEubGFzdFNjYW5JbmRleCkge1xuICAgICAgICBsYXN0U2NhbkluZGV4ID0gdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5sYXN0U2NhbkluZGV4IGFzIG51bWJlcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMsIGxhc3RTY2FuSW5kZXggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvXG4gICAqIEBwYXJhbSB7U29sUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgcGFyYW1ldGVycyBuZWVkZWQgdG8gY29uc3RydWN0IGFuZFxuICAgKiAobWF5YmUpIHNpZ24gdGhlIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHtNUENUeCB8IE1QQ1N3ZWVwVHhzfSB0aGUgc2VyaWFsaXplZCB0cmFuc2FjdGlvbiBoZXggc3RyaW5nIGFuZCBpbmRleFxuICAgKiBvZiB0aGUgYWRkcmVzcyBiZWluZyBzd2VwdFxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlcihwYXJhbXM6IFNvbFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8TVBDVHggfCBNUENTd2VlcFR4cz4ge1xuICAgIGlmICghcGFyYW1zLmJpdGdvS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYml0Z29LZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uIHx8ICF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHJlY292ZXJ5RGVzdGluYXRpb24nKTtcbiAgICB9XG5cbiAgICBjb25zdCBiaXRnb0tleSA9IHBhcmFtcy5iaXRnb0tleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9ICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcblxuICAgIC8vIEJ1aWxkIHRoZSB0cmFuc2FjdGlvblxuICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgbGV0IGJhbGFuY2UgPSAwO1xuXG4gICAgY29uc3QgaW5kZXggPSBwYXJhbXMuaW5kZXggfHwgMDtcbiAgICBjb25zdCBjdXJyUGF0aCA9IHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpICsgYC8ke2luZGV4fWAgOiBgbS8ke2luZGV4fWA7XG4gICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGN1cnJQYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgY29uc3QgYnM1OEVuY29kZWRQdWJsaWNLZXkgPSBuZXcgU29sS2V5UGFpcih7IHB1YjogYWNjb3VudElkIH0pLmdldEFkZHJlc3MoKTtcblxuICAgIGJhbGFuY2UgPSBhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlKGJzNThFbmNvZGVkUHVibGljS2V5LCBwYXJhbXMuYXBpS2V5KTtcblxuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB3YWxsZXRDb2luID0gdGhpcy5nZXRDaGFpbigpO1xuXG4gICAgbGV0IHR4QnVpbGRlcjtcbiAgICBsZXQgYmxvY2toYXNoID0gYXdhaXQgdGhpcy5nZXRCbG9ja2hhc2gocGFyYW1zLmFwaUtleSk7XG4gICAgbGV0IHJlbnRFeGVtcHRBbW91bnQ7XG4gICAgbGV0IGF1dGhvcml0eSA9ICcnO1xuICAgIGxldCB0b3RhbEZlZSA9IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgbGV0IHRvdGFsRmVlRm9yVG9rZW5SZWNvdmVyeSA9IG5ldyBCaWdOdW1iZXIoMCk7XG5cbiAgICAvLyBjaGVjayBmb3IgcG9zc2libGUgdG9rZW4gcmVjb3ZlcnksIHJlY292ZXIgdGhlIHRva2VuIHByb3ZpZGUgYnkgdXNlclxuICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MpIHtcbiAgICAgIGxldCBpc1Vuc3VwcG9ydGVkVG9rZW4gPSBmYWxzZTtcbiAgICAgIGNvbnN0IHRva2VuQWNjb3VudHMgPSBhd2FpdCB0aGlzLmdldFRva2VuQWNjb3VudHNCeU93bmVyKGJzNThFbmNvZGVkUHVibGljS2V5LCBwYXJhbXMucHJvZ3JhbUlkLCBwYXJhbXMuYXBpS2V5KTtcbiAgICAgIGlmICh0b2tlbkFjY291bnRzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAvLyB0aGVyZSBleGlzdHMgdG9rZW4gYWNjb3VudHMgb24gdGhlIGdpdmVuIGFkZHJlc3MsIGJ1dCBuZWVkIHRvIGNoZWNrIGNlcnRhaW4gY29uZGl0aW9uczpcbiAgICAgICAgLy8gMS4gaWYgdGhlcmUgaXMgYSByZWNvdmVyYWJsZSBiYWxhbmNlXG4gICAgICAgIC8vIDIuIGlmIHRoZSB0b2tlbiBpcyBzdXBwb3J0ZWQgYnkgYml0Z29cbiAgICAgICAgY29uc3QgcmVjb3ZlcmVhYmxlVG9rZW5BY2NvdW50czogVG9rZW5BY2NvdW50W10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCB0b2tlbkFjY291bnQgb2YgdG9rZW5BY2NvdW50cykge1xuICAgICAgICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MgPT09IHRva2VuQWNjb3VudC5pbmZvLm1pbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IHRva2VuQW1vdW50ID0gbmV3IEJpZ051bWJlcih0b2tlbkFjY291bnQuaW5mby50b2tlbkFtb3VudC5hbW91bnQpO1xuICAgICAgICAgICAgY29uc3QgbmV0d29yayA9IHRoaXMuZ2V0TmV0d29yaygpO1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSBnZXRTb2xUb2tlbkZyb21BZGRyZXNzKHRva2VuQWNjb3VudC5pbmZvLm1pbnQsIG5ldHdvcmspOyAvLyB0b2RvKFdJTi01ODk0KSBmaXggZm9yIGFtc1xuXG4gICAgICAgICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgICAgICAgIGlzVW5zdXBwb3J0ZWRUb2tlbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodG9rZW5BbW91bnQuZ3QobmV3IEJpZ051bWJlcigwKSkpIHtcbiAgICAgICAgICAgICAgdG9rZW5BY2NvdW50LnRva2VuTmFtZSA9IHRva2VuPy5uYW1lIHx8ICdVbnN1cHBvcnRlZCBUb2tlbic7XG4gICAgICAgICAgICAgIHJlY292ZXJlYWJsZVRva2VuQWNjb3VudHMucHVzaCh0b2tlbkFjY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlY292ZXJlYWJsZVRva2VuQWNjb3VudHMubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgcmVudEV4ZW1wdEFtb3VudCA9IGF3YWl0IHRoaXMuZ2V0UmVudEV4ZW1wdEFtb3VudChwYXJhbXMuYXBpS2V5KTtcblxuICAgICAgICAgIHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgICAgIC5nZXRUb2tlblRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgICAgICAubm9uY2UoYmxvY2toYXNoKVxuICAgICAgICAgICAgLnNlbmRlcihiczU4RW5jb2RlZFB1YmxpY0tleSlcbiAgICAgICAgICAgIC5hc3NvY2lhdGVkVG9rZW5BY2NvdW50UmVudChyZW50RXhlbXB0QW1vdW50LnRvU3RyaW5nKCkpXG4gICAgICAgICAgICAuZmVlUGF5ZXIoYnM1OEVuY29kZWRQdWJsaWNLZXkpO1xuXG4gICAgICAgICAgLy8gbmVlZCB0byBnZXQgYWxsIHRva2VuIGFjY291bnRzIG9mIHRoZSByZWNpcGllbnQgYWRkcmVzcyBhbmQgbmVlZCB0byBjcmVhdGUgdGhlbSBpZiB0aGV5IGRvIG5vdCBleGlzdFxuICAgICAgICAgIGNvbnN0IHJlY2lwaWVudFRva2VuQWNjb3VudHMgPSBhd2FpdCB0aGlzLmdldFRva2VuQWNjb3VudHNCeU93bmVyKFxuICAgICAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICBwYXJhbXMucHJvZ3JhbUlkLFxuICAgICAgICAgICAgcGFyYW1zLmFwaUtleVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IHRva2VuQWNjb3VudCBvZiByZWNvdmVyZWFibGVUb2tlbkFjY291bnRzKSB7XG4gICAgICAgICAgICBsZXQgcmVjaXBpZW50VG9rZW5BY2NvdW50RXhpc3RzID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlY2lwaWVudFRva2VuQWNjb3VudCBvZiByZWNpcGllbnRUb2tlbkFjY291bnRzIGFzIFRva2VuQWNjb3VudFtdKSB7XG4gICAgICAgICAgICAgIGlmIChyZWNpcGllbnRUb2tlbkFjY291bnQuaW5mby5taW50ID09PSB0b2tlbkFjY291bnQuaW5mby5taW50KSB7XG4gICAgICAgICAgICAgICAgcmVjaXBpZW50VG9rZW5BY2NvdW50RXhpc3RzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZWNpcGllbnRUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgICAgICAgdG9rZW5BY2NvdW50LmluZm8ubWludCxcbiAgICAgICAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICBwYXJhbXMucHJvZ3JhbUlkPy50b1N0cmluZygpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgdG9rZW5OYW1lID0gdG9rZW5BY2NvdW50LnRva2VuTmFtZSBhcyBzdHJpbmc7XG4gICAgICAgICAgICBjb25zdCBzZW5kUGFyYW1zID0ge1xuICAgICAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRUb2tlbkFjY291bnQsXG4gICAgICAgICAgICAgIGFtb3VudDogdG9rZW5BY2NvdW50LmluZm8udG9rZW5BbW91bnQuYW1vdW50LFxuICAgICAgICAgICAgICB0b2tlbk5hbWUsXG4gICAgICAgICAgICAgIC4uLihpc1Vuc3VwcG9ydGVkVG9rZW5cbiAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgdG9rZW5BZGRyZXNzOiB0b2tlbkFjY291bnQuaW5mby5taW50LFxuICAgICAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6IHBhcmFtcy5wcm9ncmFtSWQ/LnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgICAgIGRlY2ltYWxQbGFjZXM6IHRva2VuQWNjb3VudC5pbmZvLnRva2VuQW1vdW50LmRlY2ltYWxzLFxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHR4QnVpbGRlci5zZW5kKHNlbmRQYXJhbXMpO1xuXG4gICAgICAgICAgICBpZiAoIXJlY2lwaWVudFRva2VuQWNjb3VudEV4aXN0cykge1xuICAgICAgICAgICAgICAvLyByZWNpcGllbnQgdG9rZW4gYWNjb3VudCBkb2VzIG5vdCBleGlzdCBmb3IgdG9rZW4gYW5kIG11c3QgYmUgY3JlYXRlZFxuICAgICAgICAgICAgICB0eEJ1aWxkZXIuY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudCh7XG4gICAgICAgICAgICAgICAgb3duZXJBZGRyZXNzOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgICB0b2tlbk5hbWU6IHRva2VuTmFtZSxcbiAgICAgICAgICAgICAgICAuLi4oaXNVbnN1cHBvcnRlZFRva2VuID8geyB0b2tlbkFkZHJlc3M6IHRva2VuQWNjb3VudC5pbmZvLm1pbnQgfSA6IHt9KSxcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6XG4gICAgICAgICAgICAgICAgICBwYXJhbXMucHJvZ3JhbUlkPy50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgPT09IFRPS0VOXzIwMjJfUFJPR1JBTV9JRC50b1N0cmluZygpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAgICAgPyBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAgICAgICA6IFRPS0VOX1BST0dSQU1fSUQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIC8vIGFkZCByZW50IGV4ZW1wdCBhbW91bnQgdG8gdG90YWwgZmVlIGZvciBlYWNoIHRva2VuIGFjY291bnQgdGhhdCBoYXMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICB0b3RhbEZlZUZvclRva2VuUmVjb3ZlcnkgPSB0b3RhbEZlZUZvclRva2VuUmVjb3ZlcnkucGx1cyhyZW50RXhlbXB0QW1vdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgRXJyb3IoJ05vdCBlbm91Z2ggdG9rZW4gZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB0aGVyZSBhcmUgbm8gcmVjb3ZlcmFibGUgdG9rZW4gYWNjb3VudHMgLCBuZWVkIHRvIGNoZWNrIGlmIHRoZXJlIGFyZSB0b2tlbnMgdG8gcmVjb3ZlclxuICAgICAgICB0aHJvdyBFcnJvcignRGlkIG5vdCBmaW5kIHRva2VuIGFjY291bnQgdG8gcmVjb3ZlciB0b2tlbnMsIHBsZWFzZSBjaGVjayB0b2tlbiBhY2NvdW50Jyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5ub25jZShibG9ja2hhc2gpXG4gICAgICAgIC5zZW5kZXIoYnM1OEVuY29kZWRQdWJsaWNLZXkpXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIGFtb3VudDogYmFsYW5jZS50b1N0cmluZygpIH0pXG4gICAgICAgIC5mZWVQYXllcihiczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5kdXJhYmxlTm9uY2UpIHtcbiAgICAgIGNvbnN0IGR1cmFibGVOb25jZUluZm8gPSBhd2FpdCB0aGlzLmdldEFjY291bnRJbmZvKHBhcmFtcy5kdXJhYmxlTm9uY2UucHVibGljS2V5LCBwYXJhbXMuYXBpS2V5KTtcbiAgICAgIGJsb2NraGFzaCA9IGR1cmFibGVOb25jZUluZm8uYmxvY2toYXNoO1xuICAgICAgYXV0aG9yaXR5ID0gZHVyYWJsZU5vbmNlSW5mby5hdXRob3JpdHk7XG5cbiAgICAgIHR4QnVpbGRlci5ub25jZShibG9ja2hhc2gsIHtcbiAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiBwYXJhbXMuZHVyYWJsZU5vbmNlLnB1YmxpY0tleSxcbiAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6IGF1dGhvcml0eSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGJ1aWxkIHRoZSB0cmFuc2FjdGlvbiB3aXRob3V0IGZlZVxuICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb25XaXRob3V0RmVlID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICBjb25zdCBzZXJpYWxpemVkTWVzc2FnZSA9IHVuc2lnbmVkVHJhbnNhY3Rpb25XaXRob3V0RmVlLnNvbFRyYW5zYWN0aW9uLnNlcmlhbGl6ZU1lc3NhZ2UoKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgICBjb25zdCBiYXNlRmVlID0gYXdhaXQgdGhpcy5nZXRGZWVGb3JNZXNzYWdlKHNlcmlhbGl6ZWRNZXNzYWdlLCBwYXJhbXMuYXBpS2V5KTtcbiAgICBjb25zdCBmZWVQZXJTaWduYXR1cmUgPSBwYXJhbXMuZHVyYWJsZU5vbmNlID8gYmFzZUZlZSAvIDIgOiBiYXNlRmVlO1xuICAgIHRvdGFsRmVlID0gdG90YWxGZWUucGx1cyhuZXcgQmlnTnVtYmVyKGJhc2VGZWUpKTtcbiAgICB0b3RhbEZlZUZvclRva2VuUmVjb3ZlcnkgPSB0b3RhbEZlZUZvclRva2VuUmVjb3ZlcnkucGx1cyhuZXcgQmlnTnVtYmVyKGJhc2VGZWUpKTtcbiAgICBpZiAodG90YWxGZWUuZ3QoYmFsYW5jZSkpIHtcbiAgICAgIHRocm93IEVycm9yKCdEaWQgbm90IGZpbmQgYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzKSB7XG4gICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBzdWZmaWNpZW50IG5hdGl2ZSBzb2xhbmEgdG8gcmVjb3ZlciB0b2tlbnNcbiAgICAgIGlmIChuZXcgQmlnTnVtYmVyKGJhbGFuY2UpLmx0KHRvdGFsRmVlRm9yVG9rZW5SZWNvdmVyeSkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgJ05vdCBlbm91Z2ggZnVuZHMgdG8gcGF5IGZvciByZWNvdmVyIHRva2VucyBmZWVzLCBoYXZlOiAnICtcbiAgICAgICAgICAgIGJhbGFuY2UgK1xuICAgICAgICAgICAgJyBuZWVkOiAnICtcbiAgICAgICAgICAgIHRvdGFsRmVlRm9yVG9rZW5SZWNvdmVyeS50b1N0cmluZygpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0eEJ1aWxkZXIuZmVlKHsgYW1vdW50OiBmZWVQZXJTaWduYXR1cmUgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5ldEFtb3VudCA9IG5ldyBCaWdOdW1iZXIoYmFsYW5jZSkubWludXModG90YWxGZWUpO1xuICAgICAgdHhCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLm5vbmNlKGJsb2NraGFzaClcbiAgICAgICAgLnNlbmRlcihiczU4RW5jb2RlZFB1YmxpY0tleSlcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgYW1vdW50OiBuZXRBbW91bnQudG9TdHJpbmcoKSB9KVxuICAgICAgICAuZmVlUGF5ZXIoYnM1OEVuY29kZWRQdWJsaWNLZXkpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IGZlZVBlclNpZ25hdHVyZSB9KTtcblxuICAgICAgaWYgKHBhcmFtcy5kdXJhYmxlTm9uY2UpIHtcbiAgICAgICAgdHhCdWlsZGVyLm5vbmNlKGJsb2NraGFzaCwge1xuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogcGFyYW1zLmR1cmFibGVOb25jZS5wdWJsaWNLZXksXG4gICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6IGF1dGhvcml0eSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIC8vIFNpZ24gdGhlIHR4blxuICAgICAgaWYgKCFwYXJhbXMudXNlcktleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdXNlcktleScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXBhcmFtcy5iYWNrdXBLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJhY2t1cEtleScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgfVxuXG4gICAgICAvLyBidWlsZCB0aGUgdHJhbnNhY3Rpb24gd2l0aCBmZWVcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuXG4gICAgICBjb25zdCB1c2VyS2V5ID0gcGFyYW1zLnVzZXJLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleSA9IHBhcmFtcy5iYWNrdXBLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcblxuICAgICAgLy8gRGVjcnlwdCBwcml2YXRlIGtleXMgZnJvbSBLZXlDYXJkIHZhbHVlc1xuICAgICAgbGV0IHVzZXJQcnY7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHVzZXJQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIGlucHV0OiB1c2VyS2V5LFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluOiAke2UubWVzc2FnZX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlclNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UodXNlclBydikgYXMgRUREU0FNZXRob2RUeXBlcy5Vc2VyU2lnbmluZ01hdGVyaWFsO1xuXG4gICAgICBsZXQgYmFja3VwUHJ2O1xuICAgICAgdHJ5IHtcbiAgICAgICAgYmFja3VwUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogYmFja3VwS2V5LFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyBiYWNrdXAga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgYmFja3VwU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShiYWNrdXBQcnYpIGFzIEVERFNBTWV0aG9kVHlwZXMuQmFja3VwU2lnbmluZ01hdGVyaWFsO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmVIZXggPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0VFNTU2lnbmF0dXJlKFxuICAgICAgICB1c2VyU2lnbmluZ01hdGVyaWFsLFxuICAgICAgICBiYWNrdXBTaWduaW5nTWF0ZXJpYWwsXG4gICAgICAgIGN1cnJQYXRoLFxuICAgICAgICB1bnNpZ25lZFRyYW5zYWN0aW9uXG4gICAgICApO1xuXG4gICAgICBjb25zdCBwdWJsaWNLZXlPYmogPSB7IHB1YjogYnM1OEVuY29kZWRQdWJsaWNLZXkgfTtcbiAgICAgIHR4QnVpbGRlci5hZGRTaWduYXR1cmUocHVibGljS2V5T2JqIGFzIFB1YmxpY0tleSwgc2lnbmF0dXJlSGV4KTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmR1cmFibGVOb25jZSkge1xuICAgICAgLy8gYWRkIGR1cmFibGUgbm9uY2UgYWNjb3VudCBzaWduYXR1cmVcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBwYXJhbXMuZHVyYWJsZU5vbmNlLnNlY3JldEtleSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IGNvbXBsZXRlZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBwYXJhbXMuc2VlZCA/IGdldERlcml2YXRpb25QYXRoKHBhcmFtcy5zZWVkKSArIGAvJHtpbmRleH1gIDogYG0vJHtpbmRleH1gO1xuICAgIGNvbnN0IGlucHV0czogT3ZjSW5wdXRbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgaW5wdXQgb2YgY29tcGxldGVkVHJhbnNhY3Rpb24uaW5wdXRzKSB7XG4gICAgICBpbnB1dHMucHVzaCh7XG4gICAgICAgIGFkZHJlc3M6IGlucHV0LmFkZHJlc3MsXG4gICAgICAgIHZhbHVlU3RyaW5nOiBpbnB1dC52YWx1ZSxcbiAgICAgICAgdmFsdWU6IG5ldyBCaWdOdW1iZXIoaW5wdXQudmFsdWUpLnRvTnVtYmVyKCksXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3Qgb3V0cHV0czogT3ZjT3V0cHV0W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBjb21wbGV0ZWRUcmFuc2FjdGlvbi5vdXRwdXRzKSB7XG4gICAgICBvdXRwdXRzLnB1c2goe1xuICAgICAgICBhZGRyZXNzOiBvdXRwdXQuYWRkcmVzcyxcbiAgICAgICAgdmFsdWVTdHJpbmc6IG91dHB1dC52YWx1ZSxcbiAgICAgICAgY29pbk5hbWU6IG91dHB1dC5jb2luID8gb3V0cHV0LmNvaW4gOiB3YWxsZXRDb2luLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHNwZW5kQW1vdW50ID0gY29tcGxldGVkVHJhbnNhY3Rpb24uaW5wdXRzLmxlbmd0aCA9PT0gMSA/IGNvbXBsZXRlZFRyYW5zYWN0aW9uLmlucHV0c1swXS52YWx1ZSA6IDA7XG4gICAgY29uc3QgcGFyc2VkVHggPSB7IGlucHV0czogaW5wdXRzLCBvdXRwdXRzOiBvdXRwdXRzLCBzcGVuZEFtb3VudDogc3BlbmRBbW91bnQsIHR5cGU6ICcnIH07XG4gICAgY29uc3QgZmVlSW5mbyA9IHsgZmVlOiB0b3RhbEZlZUZvclRva2VuUmVjb3ZlcnkudG9OdW1iZXIoKSwgZmVlU3RyaW5nOiB0b3RhbEZlZS50b1N0cmluZygpIH07XG4gICAgY29uc3QgY29pblNwZWNpZmljID0geyBjb21tb25LZXljaGFpbjogYml0Z29LZXkgfTtcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbjogTVBDVHggPSB7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IGluZGV4LFxuICAgICAgICBjb2luOiB3YWxsZXRDb2luLFxuICAgICAgICBzaWduYWJsZUhleDogY29tcGxldGVkVHJhbnNhY3Rpb24uc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgZGVyaXZhdGlvblBhdGg6IGRlcml2YXRpb25QYXRoLFxuICAgICAgICBwYXJzZWRUeDogcGFyc2VkVHgsXG4gICAgICAgIGZlZUluZm86IGZlZUluZm8sXG4gICAgICAgIGNvaW5TcGVjaWZpYzogY29pblNwZWNpZmljLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHg6IE1QQ1Vuc2lnbmVkVHggPSB7IHVuc2lnbmVkVHg6IHRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IFtdIH07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbnM6IE1QQ1Vuc2lnbmVkVHhbXSA9IFt1bnNpZ25lZFR4XTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdDogUmVjb3ZlcnlUeFJlcXVlc3QgPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogdHJhbnNhY3Rpb25zLFxuICAgICAgICB3YWxsZXRDb2luOiB3YWxsZXRDb2luLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdHM6IE1QQ1N3ZWVwVHhzID0geyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0XSB9O1xuICAgICAgcmV0dXJuIHR4UmVxdWVzdHM7XG4gICAgfVxuICAgIGNvbnN0IHRyYW5zYWN0aW9uOiBNUENUeCA9IHtcbiAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgc2NhbkluZGV4OiBpbmRleCxcbiAgICB9O1xuICAgIHJldHVybiB0cmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvXG4gICAqIEBwYXJhbSB7U29sUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgcGFyYW1ldGVycyBuZWVkZWQgdG8gY29uc3RydWN0IGFuZFxuICAgKiAobWF5YmUpIHNpZ24gdGhlIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHtCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXN1bHRbXX0gdGhlIHNlcmlhbGl6ZWQgdHJhbnNhY3Rpb24gaGV4IHN0cmluZyBhbmQgaW5kZXhcbiAgICogb2YgdGhlIGFkZHJlc3MgYmVpbmcgc3dlcHRcbiAgICovXG4gIGFzeW5jIHJlY292ZXJDbG9zZUFUQShwYXJhbXM6IFNvbFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8QmFzZUJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzdWx0W10+IHtcbiAgICBpZiAoIXBhcmFtcy5iaXRnb0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJpdGdvS2V5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMuY2xvc2VBdGFBZGRyZXNzIHx8ICF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5jbG9zZUF0YUFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgY2xvc2VBdGFBZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXkgPSBwYXJhbXMuYml0Z29LZXkucmVwbGFjZSgvXFxzL2csICcnKTtcblxuICAgIC8vIEJ1aWxkIHRoZSB0cmFuc2FjdGlvblxuICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgbGV0IGJhbGFuY2UgPSAwO1xuXG4gICAgY29uc3QgaW5kZXggPSBwYXJhbXMuaW5kZXggfHwgMDtcbiAgICBjb25zdCBjdXJyUGF0aCA9IHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpICsgYC8ke2luZGV4fWAgOiBgbS8ke2luZGV4fWA7XG4gICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGN1cnJQYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgY29uc3QgYnM1OEVuY29kZWRQdWJsaWNLZXkgPSBuZXcgU29sS2V5UGFpcih7IHB1YjogYWNjb3VudElkIH0pLmdldEFkZHJlc3MoKTtcblxuICAgIGNvbnN0IGFjY291bnRCYWxhbmNlID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZShiczU4RW5jb2RlZFB1YmxpY0tleSk7XG5cbiAgICBiYWxhbmNlID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZShwYXJhbXMuY2xvc2VBdGFBZGRyZXNzKTtcbiAgICBpZiAoYmFsYW5jZSA8PSAwKSB7XG4gICAgICB0aHJvdyBFcnJvcignRGlkIG5vdCBmaW5kIGNsb3NlQXRhQWRkcmVzcyB3aXRoIHNvbCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuXG4gICAgbGV0IHR4QnVpbGRlcjtcbiAgICBsZXQgYmxvY2toYXNoO1xuICAgIGNvbnN0IHJlY292ZXJ0VHhuczogQmFzZUJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzdWx0W10gPSBbXTtcblxuICAgIGNvbnN0IHJlbnRFeGVtcHRBbW91bnQgPSBhd2FpdCB0aGlzLmdldFJlbnRFeGVtcHRBbW91bnQoKTtcblxuICAgIC8vIGRvIHRva2VuIHJlY292ZXJ5IGJlZm9yZSBjbG9zaW5nIEFUQSBhZGRyZXNzXG4gICAgLy8gY2hlY2sgaWYgYW55IHRva2VuIGlzIHByZXNlbnQgb24gdGhlIGNsb3NlQXRhQWRkcmVzc1xuICAgIGNvbnN0IHRva2VuSW5mbyA9IGF3YWl0IHRoaXMuZ2V0VG9rZW5BY2NvdW50SW5mbyhwYXJhbXMuY2xvc2VBdGFBZGRyZXNzKTtcbiAgICBjb25zdCB0b2tlbkJhbGFuY2UgPSBOdW1iZXIodG9rZW5JbmZvLmluZm8udG9rZW5BbW91bnQuYW1vdW50KTtcblxuICAgIGlmICh0b2tlbkJhbGFuY2UgPiAwKSB7XG4gICAgICAvLyBjbG9zZUFUQSBhZGRyZXNzIGhhcyBzb21lIHRva2VuIGJhbGFuY2UsIGl0IG5lZWRzIHRvIGJlIHdpdGhkcmF3biBiZWZvcmUgY2xvc2luZyBBVEFcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgY2xvc2VBVEEgYWRkcmVzcyAke3BhcmFtcy5jbG9zZUF0YUFkZHJlc3N9IGhhcyB0b2tlbiBiYWxhbmNlICR7dG9rZW5CYWxhbmNlfSwgaXQgbmVlZHMgdG8gYmUgd2l0aGRyYXduIGJlZm9yZSBjbG9zaW5nIEFUQSBhZGRyZXNzYFxuICAgICAgKTtcblxuICAgICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbkF0YUFkZHJlc3MgfHwgIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb25BdGFBZGRyZXNzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcmVjb3ZlcnlEZXN0aW5hdGlvbkF0YUFkZHJlc3MnKTtcbiAgICAgIH1cblxuICAgICAgYmxvY2toYXNoID0gYXdhaXQgdGhpcy5nZXRCbG9ja2hhc2gocGFyYW1zLmFwaUtleSk7XG5cbiAgICAgIHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldFRva2VuVHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLm5vbmNlKGJsb2NraGFzaClcbiAgICAgICAgLnNlbmRlcihiczU4RW5jb2RlZFB1YmxpY0tleSlcbiAgICAgICAgLmFzc29jaWF0ZWRUb2tlbkFjY291bnRSZW50KHJlbnRFeGVtcHRBbW91bnQudG9TdHJpbmcoKSlcbiAgICAgICAgLmZlZVBheWVyKGJzNThFbmNvZGVkUHVibGljS2V5KTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZE1lc3NhZ2UgPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnNvbFRyYW5zYWN0aW9uLnNlcmlhbGl6ZU1lc3NhZ2UoKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBjb25zdCBmZWVQZXJTaWduYXR1cmUgPSBhd2FpdCB0aGlzLmdldEZlZUZvck1lc3NhZ2Uoc2VyaWFsaXplZE1lc3NhZ2UsIHBhcmFtcy5hcGlLZXkpO1xuICAgICAgY29uc3QgYmFzZUZlZSA9IHBhcmFtcy5kdXJhYmxlTm9uY2UgPyBmZWVQZXJTaWduYXR1cmUgKiAyIDogZmVlUGVyU2lnbmF0dXJlO1xuICAgICAgY29uc3QgdG90YWxGZWUgPSBuZXcgQmlnTnVtYmVyKGJhc2VGZWUpO1xuICAgICAgaWYgKHRvdGFsRmVlLmd0KGFjY291bnRCYWxhbmNlKSkge1xuICAgICAgICB0aHJvdyBFcnJvcignRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgICB9XG4gICAgICB0eEJ1aWxkZXIuZmVlKHsgYW1vdW50OiBmZWVQZXJTaWduYXR1cmUgfSk7XG5cbiAgICAgIGNvbnN0IG5ldHdvcmsgPSB0aGlzLmdldE5ldHdvcmsoKTtcbiAgICAgIGNvbnN0IHRva2VuID0gZ2V0U29sVG9rZW5Gcm9tQWRkcmVzcyh0b2tlbkluZm8uaW5mby5taW50LCBuZXR3b3JrKTsgLy8gdG9kbyhXSU4tNTg5NCkgZml4IGZvciBhbXNcbiAgICAgIHR4QnVpbGRlci5zZW5kKHtcbiAgICAgICAgYWRkcmVzczogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb25BdGFBZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IHRva2VuQmFsYW5jZSxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbj8ubmFtZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0b2tlblJlY292ZXJ5VHhuID0gYXdhaXQgdGhpcy5zaWduQW5kR2VuZXJhdGVCcm9hZGNhc3RhYmxlVHJhbnNhY3Rpb24oXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgdHhCdWlsZGVyLFxuICAgICAgICBiczU4RW5jb2RlZFB1YmxpY0tleVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUb2tlblJlY292ZXJ5VHhuID0gKGF3YWl0IHRva2VuUmVjb3ZlcnlUeG4pLnNlcmlhbGl6ZWRUeDtcbiAgICAgIGNvbnN0IGJyb2FkY2FzdFRva2VuUmVjb3ZlcnlUeG4gPSBhd2FpdCB0aGlzLmJyb2FkY2FzdFRyYW5zYWN0aW9uKHtcbiAgICAgICAgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uOiBzZXJpYWxpemVkVG9rZW5SZWNvdmVyeVR4bixcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmxvZyhicm9hZGNhc3RUb2tlblJlY292ZXJ5VHhuKTtcbiAgICAgIHJlY292ZXJ0VHhucy5wdXNoKGJyb2FkY2FzdFRva2VuUmVjb3ZlcnlUeG4pO1xuICAgIH1cblxuICAgIC8vIGFmdGVyIHJlY292ZXJpbmcgdGhlIHRva2VuIGFtb3VudCwgYXR0ZW1wdGluZyB0byBjbG9zZSB0aGUgQVRBIGFkZHJlc3NcbiAgICBpZiAocGFyYW1zLmNsb3NlQXRhQWRkcmVzcykge1xuICAgICAgYmxvY2toYXNoID0gYXdhaXQgdGhpcy5nZXRCbG9ja2hhc2gocGFyYW1zLmFwaUtleSk7XG5cbiAgICAgIGNvbnN0IGF0YUNsb3NlQnVpbGRlciA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRDbG9zZUF0YUluaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuICAgICAgICB0eEJ1aWxkZXIubm9uY2UoYmxvY2toYXNoKTtcbiAgICAgICAgdHhCdWlsZGVyLnNlbmRlcihiczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgICAgIHR4QnVpbGRlci5hY2NvdW50QWRkcmVzcyhwYXJhbXMuY2xvc2VBdGFBZGRyZXNzID8/ICcnKTtcbiAgICAgICAgdHhCdWlsZGVyLmRlc3RpbmF0aW9uQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgICAgIHR4QnVpbGRlci5hdXRob3JpdHlBZGRyZXNzKGJzNThFbmNvZGVkUHVibGljS2V5KTtcbiAgICAgICAgdHhCdWlsZGVyLmFzc29jaWF0ZWRUb2tlbkFjY291bnRSZW50KHJlbnRFeGVtcHRBbW91bnQudG9TdHJpbmcoKSk7XG4gICAgICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gICAgICB9O1xuICAgICAgdHhCdWlsZGVyID0gYXRhQ2xvc2VCdWlsZGVyKCk7XG4gICAgfVxuICAgIGNvbnN0IGNsb3NlQVRBUmVjb3ZlcnlUeG4gPSBhd2FpdCB0aGlzLnNpZ25BbmRHZW5lcmF0ZUJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbihcbiAgICAgIHBhcmFtcyxcbiAgICAgIHR4QnVpbGRlcixcbiAgICAgIGJzNThFbmNvZGVkUHVibGljS2V5XG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQ2xvc2VBVEFSZWNvdmVyeVR4biA9IChhd2FpdCBjbG9zZUFUQVJlY292ZXJ5VHhuKS5zZXJpYWxpemVkVHg7XG4gICAgY29uc3QgYnJvYWRjYXN0Q2xvc2VBVEFSZWNvdmVyeVR4biA9IGF3YWl0IHRoaXMuYnJvYWRjYXN0VHJhbnNhY3Rpb24oe1xuICAgICAgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uOiBzZXJpYWxpemVkQ2xvc2VBVEFSZWNvdmVyeVR4bixcbiAgICB9KTtcbiAgICBsb2dnZXIubG9nKGJyb2FkY2FzdENsb3NlQVRBUmVjb3ZlcnlUeG4pO1xuICAgIHJlY292ZXJ0VHhucy5wdXNoKGJyb2FkY2FzdENsb3NlQVRBUmVjb3ZlcnlUeG4pO1xuXG4gICAgcmV0dXJuIHJlY292ZXJ0VHhucztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvdmVycyB0b2tlbnMgZnJvbSBhIG5lc3RlZCBBVEEg4oCUIGFuIEFUQSB3aG9zZSBvd25lciBpcyBhbm90aGVyIEFUQSByYXRoZXIgdGhhbiBhIHdhbGxldCBhZGRyZXNzLlxuICAgKlxuICAgKiBUaGlzIHNpdHVhdGlvbiBvY2N1cnMgd2hlbiBhbiBleHRlcm5hbCBzZW5kZXIgbWlzdGFrZW5seSBjYWxscyBjcmVhdGVBc3NvY2lhdGVkVG9rZW5BY2NvdW50IHdpdGhcbiAgICogYW4gQVRBIGFkZHJlc3MgYXMgdGhlIG93bmVyIGluc3RlYWQgb2YgdGhlIHJvb3Qgd2FsbGV0IGFkZHJlc3MuIFRoZSByZXN1bHQgaXMgYSBcIm5lc3RlZCBBVEFcIlxuICAgKiAoQVRBLTIpIG93bmVkIGJ5IHRoZSB3YWxsZXQncyBub3JtYWwgQVRBIChBVEEtMSkuIEJlY2F1c2UgQVRBLTEgaXMgYSBQREEgd2l0aCBubyBwcml2YXRlIGtleSxcbiAgICogdGhlIHN0YW5kYXJkIHJlY292ZXJDbG9zZUFUQSBmbG93IGNhbm5vdCBzaWduIGZvciBBVEEtMi5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgdXNlcyB0aGUgQXNzb2NpYXRlZCBUb2tlbiBBY2NvdW50IHByb2dyYW0ncyBSZWNvdmVyTmVzdGVkIGluc3RydWN0aW9uLCB3aGljaCBhbGxvd3NcbiAgICogdGhlIHJvb3Qgd2FsbGV0IG93bmVyIHRvIHNpZ24gYW5kIGF0b21pY2FsbHkgbW92ZSB0b2tlbnMgZnJvbSBBVEEtMiDihpIgQVRBLTEgYW5kIGNsb3NlIEFUQS0yLFxuICAgKiByZXR1cm5pbmcgdGhlIHJlbnQtZXhlbXB0IFNPTCB0byB0aGUgd2FsbGV0IGFkZHJlc3MuXG4gICAqXG4gICAqIEBwYXJhbSB7U29sUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgLSByZWNvdmVyeSBwYXJhbXMsIHJlcXVpcmVzIG5lc3RlZEF0YUFkZHJlc3MsIG93bmVyQXRhQWRkcmVzcyxcbiAgICogICBhbmQgdG9rZW5NaW50QWRkcmVzcyBpbiBhZGRpdGlvbiB0byB0aGUgc3RhbmRhcmQga2V5Y2hhaW4gZmllbGRzXG4gICAqL1xuICBhc3luYyByZWNvdmVyTmVzdGVkQXRhKHBhcmFtczogU29sUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXN1bHQ+IHtcbiAgICBpZiAoIXBhcmFtcy5iaXRnb0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGJpdGdvS2V5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMubmVzdGVkQXRhQWRkcmVzcyB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMubmVzdGVkQXRhQWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBuZXN0ZWRBdGFBZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMub3duZXJBdGFBZGRyZXNzIHx8ICF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5vd25lckF0YUFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgb3duZXJBdGFBZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwYXJhbXMudG9rZW5NaW50QWRkcmVzcyB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMudG9rZW5NaW50QWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB0b2tlbk1pbnRBZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXkgPSBwYXJhbXMuYml0Z29LZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuXG4gICAgY29uc3QgaW5kZXggPSBwYXJhbXMuaW5kZXggfHwgMDtcbiAgICBjb25zdCBjdXJyUGF0aCA9IHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpICsgYC8ke2luZGV4fWAgOiBgbS8ke2luZGV4fWA7XG4gICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGN1cnJQYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgY29uc3QgYnM1OEVuY29kZWRQdWJsaWNLZXkgPSBuZXcgU29sS2V5UGFpcih7IHB1YjogYWNjb3VudElkIH0pLmdldEFkZHJlc3MoKTtcblxuICAgIGNvbnN0IGJsb2NraGFzaCA9IGF3YWl0IHRoaXMuZ2V0QmxvY2toYXNoKHBhcmFtcy5hcGlLZXkpO1xuICAgIGNvbnN0IHJlbnRFeGVtcHRBbW91bnQgPSBhd2FpdCB0aGlzLmdldFJlbnRFeGVtcHRBbW91bnQoKTtcblxuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFJlY292ZXJOZXN0ZWRBdGFCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLm5vbmNlKGJsb2NraGFzaCk7XG4gICAgdHhCdWlsZGVyLnNlbmRlcihiczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgdHhCdWlsZGVyLmZlZVBheWVyKGJzNThFbmNvZGVkUHVibGljS2V5KTtcbiAgICB0eEJ1aWxkZXIuYXNzb2NpYXRlZFRva2VuQWNjb3VudFJlbnQocmVudEV4ZW1wdEFtb3VudC50b1N0cmluZygpKTtcbiAgICB0eEJ1aWxkZXIubmVzdGVkQWNjb3VudEFkZHJlc3MocGFyYW1zLm5lc3RlZEF0YUFkZHJlc3MpO1xuICAgIHR4QnVpbGRlci5uZXN0ZWRNaW50QWRkcmVzcyhwYXJhbXMudG9rZW5NaW50QWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLmRlc3RpbmF0aW9uQWNjb3VudEFkZHJlc3MocGFyYW1zLm93bmVyQXRhQWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLm93bmVyQWNjb3VudEFkZHJlc3MocGFyYW1zLm93bmVyQXRhQWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLm93bmVyTWludEFkZHJlc3MocGFyYW1zLnRva2VuTWludEFkZHJlc3MpO1xuICAgIHR4QnVpbGRlci53YWxsZXRBZGRyZXNzKGJzNThFbmNvZGVkUHVibGljS2V5KTtcblxuICAgIGNvbnN0IHJlY292ZXJOZXN0ZWRUeG4gPSBhd2FpdCB0aGlzLnNpZ25BbmRHZW5lcmF0ZUJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbihcbiAgICAgIHBhcmFtcyxcbiAgICAgIHR4QnVpbGRlcixcbiAgICAgIGJzNThFbmNvZGVkUHVibGljS2V5XG4gICAgKTtcblxuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeG4gPSAoYXdhaXQgcmVjb3Zlck5lc3RlZFR4bikuc2VyaWFsaXplZFR4O1xuICAgIGNvbnN0IGJyb2FkY2FzdFJlc3VsdCA9IGF3YWl0IHRoaXMuYnJvYWRjYXN0VHJhbnNhY3Rpb24oe1xuICAgICAgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uOiBzZXJpYWxpemVkVHhuLFxuICAgIH0pO1xuICAgIGxvZ2dlci5sb2coYnJvYWRjYXN0UmVzdWx0KTtcblxuICAgIHJldHVybiBicm9hZGNhc3RSZXN1bHQ7XG4gIH1cblxuICBhc3luYyBzaWduQW5kR2VuZXJhdGVCcm9hZGNhc3RhYmxlVHJhbnNhY3Rpb24oXG4gICAgcGFyYW1zOiBTb2xSZWNvdmVyeU9wdGlvbnMsXG4gICAgdHhCdWlsZGVyOiBhbnksXG4gICAgYnM1OEVuY29kZWRQdWJsaWNLZXk6IHN0cmluZ1xuICApOiBQcm9taXNlPE1QQ1R4PiB7XG4gICAgLy8gU2lnbiB0aGUgdHhuXG4gICAgaWYgKCFwYXJhbXMudXNlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5iYWNrdXBLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBiYWNrdXBLZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgd2FsbGV0IHBhc3NwaHJhc2UnKTtcbiAgICB9XG5cbiAgICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9uID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgIGNvbnN0IHVzZXJLZXkgPSBwYXJhbXMudXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9IHBhcmFtcy5iYWNrdXBLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcblxuICAgIC8vIERlY3J5cHQgcHJpdmF0ZSBrZXlzIGZyb20gS2V5Q2FyZCB2YWx1ZXNcbiAgICBsZXQgdXNlclBydjtcblxuICAgIHRyeSB7XG4gICAgICB1c2VyUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgaW5wdXQ6IHVzZXJLZXksXG4gICAgICAgIHBhc3N3b3JkOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZSh1c2VyUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLlVzZXJTaWduaW5nTWF0ZXJpYWw7XG5cbiAgICBsZXQgYmFja3VwUHJ2O1xuICAgIHRyeSB7XG4gICAgICBiYWNrdXBQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICBpbnB1dDogYmFja3VwS2V5LFxuICAgICAgICBwYXNzd29yZDogcGFyYW1zLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVycm9yIGRlY3J5cHRpbmcgYmFja3VwIGtleWNoYWluOiAke2UubWVzc2FnZX1gKTtcbiAgICB9XG4gICAgY29uc3QgYmFja3VwU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShiYWNrdXBQcnYpIGFzIEVERFNBTWV0aG9kVHlwZXMuQmFja3VwU2lnbmluZ01hdGVyaWFsO1xuXG4gICAgY29uc3QgaW5kZXggPSBwYXJhbXMuaW5kZXggfHwgMDtcbiAgICBjb25zdCBjdXJyUGF0aCA9IHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpICsgYC8ke2luZGV4fWAgOiBgbS8ke2luZGV4fWA7XG5cbiAgICBjb25zdCBzaWduYXR1cmVIZXggPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0VFNTU2lnbmF0dXJlKFxuICAgICAgdXNlclNpZ25pbmdNYXRlcmlhbCxcbiAgICAgIGJhY2t1cFNpZ25pbmdNYXRlcmlhbCxcbiAgICAgIGN1cnJQYXRoLFxuICAgICAgdW5zaWduZWRUcmFuc2FjdGlvblxuICAgICk7XG5cbiAgICBjb25zdCBwdWJsaWNLZXlPYmogPSB7IHB1YjogYnM1OEVuY29kZWRQdWJsaWNLZXkgfTtcbiAgICB0eEJ1aWxkZXIuYWRkU2lnbmF0dXJlKHB1YmxpY0tleU9iaiBhcyBQdWJsaWNLZXksIHNpZ25hdHVyZUhleCk7XG5cbiAgICBjb25zdCBjb21wbGV0ZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IGNvbXBsZXRlZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgY29uc3QgdHJhbnNhY3Rpb246IE1QQ1R4ID0ge1xuICAgICAgc2VyaWFsaXplZFR4OiBzZXJpYWxpemVkVHgsXG4gICAgICBzY2FuSW5kZXg6IGluZGV4LFxuICAgIH07XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBuYXRpdmUgU09MIHJlY292ZXJpZXMgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgaW4gYmF0Y2ggd2l0aG91dCBCaXRHby5cbiAgICogRnVuZHMgd2lsbCBiZSByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0LiBZb3UgbmVlZCB0byBpbml0aWF0ZSBhbm90aGVyIHN3ZWVwIHR4biBhZnRlciB0aGF0LlxuICAgKlxuICAgKiBAcGFyYW0ge1NvbENvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnN9IHBhcmFtcyAtIG9wdGlvbnMgZm9yIGNvbnNvbGlkYXRpb24gcmVjb3ZlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBzdGFydCBzY2FubmluZyBmcm9tLiBkZWZhdWx0IHRvIDEgKGluY2x1c2l2ZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLmVuZGluZ1NjYW5JbmRleF0gLSByZWNlaXZlIGFkZHJlc3MgaW5kZXggdG8gZW5kIHNjYW5uaW5nIGF0LiBkZWZhdWx0IHRvIHN0YXJ0aW5nU2NhbkluZGV4ICsgMjAgKGV4Y2x1c2l2ZSkuXG4gICAqL1xuICBhc3luYyByZWNvdmVyQ29uc29saWRhdGlvbnMocGFyYW1zOiBTb2xDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeHMgfCBNUENTd2VlcFR4cz4ge1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9ICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcbiAgICBjb25zdCBzdGFydElkeCA9IHBhcmFtcy5zdGFydGluZ1NjYW5JbmRleCB8fCAxO1xuICAgIGNvbnN0IGVuZElkeCA9IHBhcmFtcy5lbmRpbmdTY2FuSW5kZXggfHwgc3RhcnRJZHggKyBERUZBVUxUX1NDQU5fRkFDVE9SO1xuXG4gICAgaWYgKHN0YXJ0SWR4IDwgMSB8fCBlbmRJZHggPD0gc3RhcnRJZHggfHwgZW5kSWR4IC0gc3RhcnRJZHggPiAxMCAqIERFRkFVTFRfU0NBTl9GQUNUT1IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6ICR7c3RhcnRJZHh9LCBlbmRpbmdTY2FuSW5kZXg6ICR7ZW5kSWR4fS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIGR1cmFibGUgbm9uY2VzIGFycmF5XG4gICAgaWYgKCFwYXJhbXMuZHVyYWJsZU5vbmNlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGR1cmFibGUgbm9uY2VzJyk7XG4gICAgfVxuICAgIGlmICghcGFyYW1zLmR1cmFibGVOb25jZXMucHVibGljS2V5cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGR1cmFibGUgbm9uY2VzOiBtaXNzaW5nIHB1YmxpYyBrZXlzJyk7XG4gICAgfVxuICAgIGlmICghcGFyYW1zLmR1cmFibGVOb25jZXMuc2VjcmV0S2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZHVyYWJsZSBub25jZXMgYXJyYXk6IG1pc3Npbmcgc2VjcmV0IGtleScpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcbiAgICBjb25zdCBiYXNlQWRkcmVzc0luZGV4ID0gMDtcbiAgICBjb25zdCBiYXNlQWRkcmVzc1BhdGggPSBwYXJhbXMuc2VlZFxuICAgICAgPyBnZXREZXJpdmF0aW9uUGF0aChwYXJhbXMuc2VlZCkgKyBgLyR7YmFzZUFkZHJlc3NJbmRleH1gXG4gICAgICA6IGBtLyR7YmFzZUFkZHJlc3NJbmRleH1gO1xuICAgIGNvbnN0IGFjY291bnRJZCA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGJpdGdvS2V5LCBiYXNlQWRkcmVzc1BhdGgpLnNsaWNlKDAsIDY0KTtcbiAgICBjb25zdCBiYXNlQWRkcmVzcyA9IG5ldyBTb2xLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSkuZ2V0QWRkcmVzcygpO1xuXG4gICAgbGV0IGR1cmFibGVOb25jZVB1YktleXNJbmRleCA9IDA7XG4gICAgY29uc3QgZHVyYWJsZU5vbmNlUHViS2V5c0xlbmd0aCA9IHBhcmFtcy5kdXJhYmxlTm9uY2VzLnB1YmxpY0tleXMubGVuZ3RoO1xuICAgIGNvbnN0IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnM6IGFueVtdID0gW107XG4gICAgbGV0IGxhc3RTY2FuSW5kZXggPSBzdGFydElkeDtcblxuICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IGVuZElkeDsgaSsrKSB7XG4gICAgICBjb25zdCByZWNvdmVyUGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogcGFyYW1zLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogYmFzZUFkZHJlc3MsXG4gICAgICAgIHNlZWQ6IHBhcmFtcy5zZWVkLFxuICAgICAgICBpbmRleDogaSxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiBwYXJhbXMuZHVyYWJsZU5vbmNlcy5wdWJsaWNLZXlzW2R1cmFibGVOb25jZVB1YktleXNJbmRleF0sXG4gICAgICAgICAgc2VjcmV0S2V5OiBwYXJhbXMuZHVyYWJsZU5vbmNlcy5zZWNyZXRLZXksXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiBwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MsXG4gICAgICAgIGFwaUtleTogcGFyYW1zLmFwaUtleSxcbiAgICAgICAgcHJvZ3JhbUlkOiBwYXJhbXMucHJvZ3JhbUlkLFxuICAgICAgfTtcblxuICAgICAgbGV0IHJlY292ZXJ5VHJhbnNhY3Rpb247XG4gICAgICB0cnkge1xuICAgICAgICByZWNvdmVyeVRyYW5zYWN0aW9uID0gYXdhaXQgdGhpcy5yZWNvdmVyKHJlY292ZXJQYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZS5tZXNzYWdlID09PSAnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyB8fFxuICAgICAgICAgIGUubWVzc2FnZSA9PT0gJ0RpZCBub3QgZmluZCB0b2tlbiBhY2NvdW50IHRvIHJlY292ZXIgdG9rZW5zLCBwbGVhc2UgY2hlY2sgdG9rZW4gYWNjb3VudCcgfHxcbiAgICAgICAgICBlLm1lc3NhZ2UgPT09ICdOb3QgZW5vdWdoIHRva2VuIGZ1bmRzIHRvIHJlY292ZXInXG4gICAgICAgICkge1xuICAgICAgICAgIGxhc3RTY2FuSW5kZXggPSBpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5wdXNoKChyZWNvdmVyeVRyYW5zYWN0aW9uIGFzIE1QQ1N3ZWVwVHhzKS50eFJlcXVlc3RzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMucHVzaChyZWNvdmVyeVRyYW5zYWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgbGFzdFNjYW5JbmRleCA9IGk7XG4gICAgICBkdXJhYmxlTm9uY2VQdWJLZXlzSW5kZXgrKztcbiAgICAgIGlmIChkdXJhYmxlTm9uY2VQdWJLZXlzSW5kZXggPj0gZHVyYWJsZU5vbmNlUHViS2V5c0xlbmd0aCkge1xuICAgICAgICAvLyBubyBtb3JlIGF2YWlsYWJsZSBub25jZSBhY2NvdW50cyB0byBjcmVhdGUgdHJhbnNhY3Rpb25zXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaWQgbm90IGZpbmQgYW4gYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9XG5cbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICAvLyBsYXN0U2NhbkluZGV4IHdpbGwgYmUgdXNlZCB0byBpbmZvcm0gdXNlciB0aGUgbGFzdCBhZGRyZXNzIGluZGV4IHNjYW5uZWQgZm9yIGF2YWlsYWJsZSBmdW5kcyAoc28gdGhleSBjYW5cbiAgICAgIC8vIGFwcHJvcHJpYXRlbHkgYWRqdXN0IHRoZSBzY2FuIHJhbmdlIG9uIHRoZSBuZXh0IGl0ZXJhdGlvbiBvZiBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMpLiBJbiB0aGUgY2FzZSBvZiB1bnNpZ25lZFxuICAgICAgLy8gc3dlZXAgY29uc29saWRhdGlvbnMsIHRoaXMgbGFzdFNjYW5JbmRleCB3aWxsIGJlIHByb3ZpZGVkIGluIHRoZSBjb2luU3BlY2lmaWMgb2YgdGhlIGxhc3QgdHhuIG1hZGUuXG4gICAgICBjb25zdCBsYXN0VHJhbnNhY3Rpb25Db2luU3BlY2lmaWMgPSB7XG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgIGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnNbY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5sZW5ndGggLSAxXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luU3BlY2lmaWNcbiAgICAgICAgICAgIC5jb21tb25LZXljaGFpbixcbiAgICAgICAgbGFzdFNjYW5JbmRleDogbGFzdFNjYW5JbmRleCxcbiAgICAgIH07XG4gICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zW2NvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoIC0gMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljID1cbiAgICAgICAgbGFzdFRyYW5zYWN0aW9uQ29pblNwZWNpZmljO1xuICAgICAgY29uc3QgY29uc29saWRhdGlvblN3ZWVwVHJhbnNhY3Rpb25zOiBNUENTd2VlcFR4cyA9IHsgdHhSZXF1ZXN0czogY29uc29saWRhdGlvblRyYW5zYWN0aW9ucyB9O1xuICAgICAgcmV0dXJuIGNvbnNvbGlkYXRpb25Td2VlcFRyYW5zYWN0aW9ucztcbiAgICB9XG5cbiAgICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMsIGxhc3RTY2FuSW5kZXggfTtcbiAgfVxuXG4gIGdldFRva2VuRW5hYmxlbWVudENvbmZpZygpOiBUb2tlbkVuYWJsZW1lbnRDb25maWcge1xuICAgIHJldHVybiB7XG4gICAgICByZXF1aXJlc1Rva2VuRW5hYmxlbWVudDogdHJ1ZSxcbiAgICAgIHN1cHBvcnRzTXVsdGlwbGVUb2tlbkVuYWJsZW1lbnRzOiB0cnVlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIGFzeW5jIGJyb2FkY2FzdFRyYW5zYWN0aW9uKHtcbiAgICBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24sXG4gIH06IEJhc2VCcm9hZGNhc3RUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPEJhc2VCcm9hZGNhc3RUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIHZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uLCB0cnVlLCB0cnVlKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0RGF0YUZyb21Ob2RlKHtcbiAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgIG1ldGhvZDogJ3NlbmRUcmFuc2FjdGlvbicsXG4gICAgICAgIHBhcmFtczogW1xuICAgICAgICAgIHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBlbmNvZGluZzogJ2Jhc2U2NCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAocmVzcG9uc2UuYm9keS5lcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciBicm9hZGNhc3RpbmcgdHJhbnNhY3Rpb246ICcgKyByZXNwb25zZS5ib2R5LmVycm9yLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiB7IHR4SWQ6IHJlc3BvbnNlLmJvZHkucmVzdWx0IH07XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgYXVkaXREZWNyeXB0ZWRLZXkoeyBwcnYsIHB1YmxpY0tleSwgbXVsdGlTaWdUeXBlIH06IEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zKSB7XG4gICAgaWYgKG11bHRpU2lnVHlwZSAhPT0gJ3RzcycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgbXVsdGlTaWdUeXBlJyk7XG4gICAgfVxuICAgIGF1ZGl0RWRkc2FQcml2YXRlS2V5KHBydiwgcHVibGljS2V5ID8/ICcnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBzZXRDb2luU3BlY2lmaWNGaWVsZHNJbkludGVudChpbnRlbnQ6IFBvcHVsYXRlZEludGVudCwgcGFyYW1zOiBQcmVidWlsZFRyYW5zYWN0aW9uV2l0aEludGVudE9wdGlvbnMpOiB2b2lkIHtcbiAgICAvLyBIYW5kbGUgY3VzdG9tIGluc3RydWN0aW9ucyBmb3IgU29sYW5hXG4gICAgaWYgKHBhcmFtcy5zb2xJbnN0cnVjdGlvbnMpIHtcbiAgICAgIGludGVudC5zb2xJbnN0cnVjdGlvbnMgPSBwYXJhbXMuc29sSW5zdHJ1Y3Rpb25zO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSB2ZXJzaW9uZWQgdHJhbnNhY3Rpb24gZGF0YSBmb3IgU29sYW5hXG4gICAgaWYgKHBhcmFtcy5zb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGEpIHtcbiAgICAgIGludGVudC5zb2xWZXJzaW9uZWRUcmFuc2FjdGlvbkRhdGEgPSBwYXJhbXMuc29sVmVyc2lvbmVkVHJhbnNhY3Rpb25EYXRhO1xuICAgIH1cbiAgfVxufVxuIl19