@bitgo-beta/sdk-core 8.2.1-beta.169 → 8.2.1-beta.1690

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 (590) hide show
  1. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts +0 -1
  2. package/dist/src/account-lib/baseCoin/baseTransaction.d.ts.map +1 -1
  3. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts +3 -3
  4. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.d.ts.map +1 -1
  5. package/dist/src/account-lib/baseCoin/baseTransactionBuilder.js +4 -3
  6. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts +1 -0
  7. package/dist/src/account-lib/baseCoin/ed25519KeyPair.d.ts.map +1 -1
  8. package/dist/src/account-lib/baseCoin/ed25519KeyPair.js +41 -29
  9. package/dist/src/account-lib/baseCoin/enum.d.ts +39 -5
  10. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  11. package/dist/src/account-lib/baseCoin/enum.js +68 -10
  12. package/dist/src/account-lib/baseCoin/errors.d.ts +3 -0
  13. package/dist/src/account-lib/baseCoin/errors.d.ts.map +1 -1
  14. package/dist/src/account-lib/baseCoin/errors.js +8 -2
  15. package/dist/src/account-lib/baseCoin/iface.d.ts +19 -35
  16. package/dist/src/account-lib/baseCoin/iface.d.ts.map +1 -1
  17. package/dist/src/account-lib/baseCoin/iface.js +26 -18
  18. package/dist/src/account-lib/baseCoin/index.d.ts +1 -1
  19. package/dist/src/account-lib/baseCoin/index.d.ts.map +1 -1
  20. package/dist/src/account-lib/baseCoin/index.js +8 -5
  21. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts +88 -0
  22. package/dist/src/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  23. package/dist/src/account-lib/baseCoin/messages/baseMessage.js +154 -0
  24. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +67 -0
  25. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  26. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilder.js +144 -0
  27. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +33 -0
  28. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  29. package/dist/src/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +45 -0
  30. package/dist/src/account-lib/baseCoin/messages/iface.d.ts +164 -0
  31. package/dist/src/account-lib/baseCoin/messages/iface.d.ts.map +1 -0
  32. package/dist/src/account-lib/baseCoin/messages/iface.js +3 -0
  33. package/dist/src/account-lib/baseCoin/messages/index.d.ts +6 -0
  34. package/dist/src/account-lib/baseCoin/messages/index.d.ts.map +1 -0
  35. package/dist/src/account-lib/baseCoin/messages/index.js +22 -0
  36. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts +3 -0
  37. package/dist/src/account-lib/baseCoin/messages/simple/index.d.ts.map +1 -0
  38. package/dist/src/account-lib/baseCoin/messages/simple/index.js +19 -0
  39. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts +13 -0
  40. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.d.ts.map +1 -0
  41. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessage.js +28 -0
  42. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts +21 -0
  43. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.d.ts.map +1 -0
  44. package/dist/src/account-lib/baseCoin/messages/simple/simpleMessageBuilder.js +28 -0
  45. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts +1 -2
  46. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.d.ts.map +1 -1
  47. package/dist/src/account-lib/baseCoin/secp256k1ExtendedKeyPair.js +38 -26
  48. package/dist/src/account-lib/index.js +23 -9
  49. package/dist/src/account-lib/mpc/index.d.ts +1 -1
  50. package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
  51. package/dist/src/account-lib/mpc/index.js +6 -2
  52. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -3
  53. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
  54. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +376 -354
  55. package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
  56. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
  57. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
  58. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
  59. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +46 -53
  60. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
  61. package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
  62. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +0 -1
  63. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
  64. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
  65. package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
  66. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -1
  67. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
  68. package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
  69. package/dist/src/account-lib/mpc/tss/index.js +23 -9
  70. package/dist/src/account-lib/mpc/util.d.ts +7 -1
  71. package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
  72. package/dist/src/account-lib/mpc/util.js +24 -1
  73. package/dist/src/account-lib/staking/index.js +6 -2
  74. package/dist/src/account-lib/staking/utils.js +3 -3
  75. package/dist/src/account-lib/util/crypto.d.ts +8 -2
  76. package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
  77. package/dist/src/account-lib/util/crypto.js +69 -38
  78. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +2 -1
  79. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +1 -1
  80. package/dist/src/account-lib/util/ed25519KeyDeriver.js +5 -3
  81. package/dist/src/api/bip32path.js +2 -3
  82. package/dist/src/api/index.js +6 -2
  83. package/dist/src/api/types.d.ts +8 -0
  84. package/dist/src/api/types.d.ts.map +1 -1
  85. package/dist/src/api/types.js +1 -1
  86. package/dist/src/bitgo/address-book/address-book.d.ts +61 -0
  87. package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -0
  88. package/dist/src/bitgo/address-book/address-book.js +139 -0
  89. package/dist/src/bitgo/address-book/index.d.ts +3 -0
  90. package/dist/src/bitgo/address-book/index.d.ts.map +1 -0
  91. package/dist/src/bitgo/address-book/index.js +19 -0
  92. package/dist/src/bitgo/address-book/types.d.ts +170 -0
  93. package/dist/src/bitgo/address-book/types.d.ts.map +1 -0
  94. package/dist/src/bitgo/address-book/types.js +3 -0
  95. package/dist/src/bitgo/baseCoin/baseCoin.d.ts +96 -11
  96. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  97. package/dist/src/bitgo/baseCoin/baseCoin.js +149 -16
  98. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +175 -28
  99. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  100. package/dist/src/bitgo/baseCoin/iBaseCoin.js +14 -3
  101. package/dist/src/bitgo/baseCoin/index.js +6 -2
  102. package/dist/src/bitgo/bip32util.d.ts +3 -16
  103. package/dist/src/bitgo/bip32util.d.ts.map +1 -1
  104. package/dist/src/bitgo/bip32util.js +4 -56
  105. package/dist/src/bitgo/bitcoin.d.ts +0 -1
  106. package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
  107. package/dist/src/bitgo/bitcoin.js +26 -13
  108. package/dist/src/bitgo/bitgoBase.d.ts +4 -1
  109. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  110. package/dist/src/bitgo/bitgoBase.js +1 -1
  111. package/dist/src/bitgo/coinFactory.d.ts +17 -3
  112. package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
  113. package/dist/src/bitgo/coinFactory.js +26 -3
  114. package/dist/src/bitgo/config.d.ts +3 -95
  115. package/dist/src/bitgo/config.d.ts.map +1 -1
  116. package/dist/src/bitgo/config.js +26 -15
  117. package/dist/src/bitgo/ecdh.d.ts +0 -1
  118. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  119. package/dist/src/bitgo/ecdh.js +26 -13
  120. package/dist/src/bitgo/enterprise/enterprise.d.ts +3 -13
  121. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  122. package/dist/src/bitgo/enterprise/enterprise.js +39 -34
  123. package/dist/src/bitgo/enterprise/enterprises.js +27 -13
  124. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +2 -6
  125. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  126. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  127. package/dist/src/bitgo/enterprise/index.js +6 -2
  128. package/dist/src/bitgo/environments.d.ts +69 -7
  129. package/dist/src/bitgo/environments.d.ts.map +1 -1
  130. package/dist/src/bitgo/environments.js +379 -44
  131. package/dist/src/bitgo/errors.d.ts +175 -0
  132. package/dist/src/bitgo/errors.d.ts.map +1 -1
  133. package/dist/src/bitgo/errors.js +166 -2
  134. package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
  135. package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
  136. package/dist/src/bitgo/evm/evmUtils.js +50 -0
  137. package/dist/src/bitgo/index.d.ts +3 -1
  138. package/dist/src/bitgo/index.d.ts.map +1 -1
  139. package/dist/src/bitgo/index.js +29 -11
  140. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  141. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  142. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  143. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  144. package/dist/src/bitgo/internal/index.js +6 -2
  145. package/dist/src/bitgo/internal/internal.js +5 -6
  146. package/dist/src/bitgo/internal/keycard.js +6 -7
  147. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +13 -0
  148. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  149. package/dist/src/bitgo/keychain/decryptKeychain.js +35 -0
  150. package/dist/src/bitgo/keychain/iKeychains.d.ts +74 -7
  151. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  152. package/dist/src/bitgo/keychain/iKeychains.js +2 -2
  153. package/dist/src/bitgo/keychain/index.d.ts +1 -0
  154. package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
  155. package/dist/src/bitgo/keychain/index.js +7 -2
  156. package/dist/src/bitgo/keychain/keychains.d.ts +29 -4
  157. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  158. package/dist/src/bitgo/keychain/keychains.js +177 -38
  159. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
  160. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  161. package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
  162. package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
  163. package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
  164. package/dist/src/bitgo/legacyBitcoin.js +27 -13
  165. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
  166. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
  167. package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
  168. package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
  169. package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
  170. package/dist/src/bitgo/market/index.js +6 -2
  171. package/dist/src/bitgo/market/markets.js +23 -9
  172. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +1 -0
  173. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
  174. package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
  175. package/dist/src/bitgo/pendingApproval/index.js +6 -2
  176. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
  177. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  178. package/dist/src/bitgo/pendingApproval/pendingApproval.js +226 -111
  179. package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
  180. package/dist/src/bitgo/proofs/WalletProofs.d.ts +19 -0
  181. package/dist/src/bitgo/proofs/WalletProofs.d.ts.map +1 -0
  182. package/dist/src/bitgo/proofs/WalletProofs.js +37 -0
  183. package/dist/src/bitgo/proofs/index.d.ts +2 -0
  184. package/dist/src/bitgo/proofs/index.d.ts.map +1 -0
  185. package/dist/src/bitgo/proofs/index.js +6 -0
  186. package/dist/src/bitgo/proofs/types.d.ts +80 -0
  187. package/dist/src/bitgo/proofs/types.d.ts.map +1 -0
  188. package/dist/src/bitgo/proofs/types.js +80 -0
  189. package/dist/src/bitgo/recovery/index.js +6 -2
  190. package/dist/src/bitgo/recovery/initiate.d.ts +8 -1
  191. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  192. package/dist/src/bitgo/recovery/initiate.js +14 -8
  193. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +132 -0
  194. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts.map +1 -0
  195. package/dist/src/bitgo/staking/goStakingInterfaces.js +3 -0
  196. package/dist/src/bitgo/staking/goStakingWallet.d.ts +62 -0
  197. package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
  198. package/dist/src/bitgo/staking/goStakingWallet.js +141 -0
  199. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +17 -0
  200. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
  201. package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
  202. package/dist/src/bitgo/staking/iStakingWallet.d.ts +173 -7
  203. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  204. package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
  205. package/dist/src/bitgo/staking/index.d.ts +3 -0
  206. package/dist/src/bitgo/staking/index.d.ts.map +1 -1
  207. package/dist/src/bitgo/staking/index.js +9 -2
  208. package/dist/src/bitgo/staking/stakingWallet.d.ts +21 -8
  209. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  210. package/dist/src/bitgo/staking/stakingWallet.js +140 -7
  211. package/dist/src/bitgo/trading/iTradingAccount.d.ts +2 -32
  212. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  213. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  214. package/dist/src/bitgo/trading/index.d.ts +1 -15
  215. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  216. package/dist/src/bitgo/trading/index.js +7 -17
  217. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
  218. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
  219. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
  220. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
  221. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
  222. package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
  223. package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
  224. package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
  225. package/dist/src/bitgo/trading/network/decrypt.js +23 -0
  226. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
  227. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
  228. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
  229. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
  230. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
  231. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
  232. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
  233. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
  234. package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
  235. package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
  236. package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
  237. package/dist/src/bitgo/trading/network/encrypt.js +58 -0
  238. package/dist/src/bitgo/trading/network/index.d.ts +5 -0
  239. package/dist/src/bitgo/trading/network/index.d.ts.map +1 -0
  240. package/dist/src/bitgo/trading/network/index.js +21 -0
  241. package/dist/src/bitgo/trading/network/network.d.ts +36 -0
  242. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -0
  243. package/dist/src/bitgo/trading/network/network.js +101 -0
  244. package/dist/src/bitgo/trading/network/types.d.ts +277 -0
  245. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -0
  246. package/dist/src/bitgo/trading/network/types.js +3 -0
  247. package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
  248. package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
  249. package/dist/src/bitgo/trading/network/utils.js +54 -0
  250. package/dist/src/bitgo/trading/tradingAccount.d.ts +11 -35
  251. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  252. package/dist/src/bitgo/trading/tradingAccount.js +9 -96
  253. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +27 -0
  254. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  255. package/dist/src/bitgo/tss/bitgoPubKeys.js +61 -0
  256. package/dist/src/bitgo/tss/common.d.ts +37 -5
  257. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  258. package/dist/src/bitgo/tss/common.js +103 -17
  259. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
  260. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  261. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
  262. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
  263. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  264. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +162 -0
  265. package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
  266. package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
  267. package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
  268. package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
  269. package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
  270. package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
  271. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +15 -6
  272. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  273. package/dist/src/bitgo/tss/eddsa/eddsa.js +47 -40
  274. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  275. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  276. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  277. package/dist/src/bitgo/tss/index.d.ts +3 -2
  278. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  279. package/dist/src/bitgo/tss/index.js +26 -10
  280. package/dist/src/bitgo/tss/types.d.ts +3 -3
  281. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  282. package/dist/src/bitgo/tss/types.js +2 -2
  283. package/dist/src/bitgo/types.d.ts +3 -3
  284. package/dist/src/bitgo/types.d.ts.map +1 -1
  285. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +8 -0
  286. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  287. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +55 -13
  288. package/dist/src/bitgo/utils/codecProps.js +24 -11
  289. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  290. package/dist/src/bitgo/utils/decode.js +30 -16
  291. package/dist/src/bitgo/utils/index.d.ts +3 -2
  292. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  293. package/dist/src/bitgo/utils/index.js +26 -11
  294. package/dist/src/bitgo/utils/messageTypes.d.ts +38 -0
  295. package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
  296. package/dist/src/bitgo/utils/messageTypes.js +15 -0
  297. package/dist/src/bitgo/utils/mpcUtils.d.ts +2 -3
  298. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  299. package/dist/src/bitgo/utils/mpcUtils.js +82 -14
  300. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  301. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  302. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  303. package/dist/src/bitgo/utils/opengpgUtils.d.ts +11 -9
  304. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  305. package/dist/src/bitgo/utils/opengpgUtils.js +68 -64
  306. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -1
  307. package/dist/src/bitgo/utils/postWithCodec.js +4 -38
  308. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  309. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  310. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  311. package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
  312. package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
  313. package/dist/src/bitgo/utils/transactionUtils.js +29 -0
  314. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  315. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  316. package/dist/src/bitgo/utils/triple.js +2 -3
  317. package/dist/src/bitgo/utils/tss/addressVerification.d.ts +37 -0
  318. package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  319. package/dist/src/bitgo/utils/tss/addressVerification.js +75 -0
  320. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +49 -15
  321. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  322. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +184 -46
  323. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +250 -38
  324. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  325. package/dist/src/bitgo/utils/tss/baseTypes.js +22 -21
  326. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  327. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  328. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  329. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  330. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  331. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  332. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +17 -50
  333. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  334. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +129 -238
  335. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +199 -0
  336. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  337. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +958 -0
  338. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
  339. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  340. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +13 -0
  341. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
  342. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  343. package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
  344. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +7 -10
  345. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  346. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  347. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
  348. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  349. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  350. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +22 -8
  351. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  352. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +111 -60
  353. package/dist/src/bitgo/utils/tss/eddsa/index.js +23 -9
  354. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +7 -7
  355. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  356. package/dist/src/bitgo/utils/tss/index.d.ts +1 -0
  357. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  358. package/dist/src/bitgo/utils/tss/index.js +24 -9
  359. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  360. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  361. package/dist/src/bitgo/utils/txRequest.js +47 -0
  362. package/dist/src/bitgo/utils/util.js +24 -10
  363. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  364. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  365. package/dist/src/bitgo/utils/wallet.js +48 -0
  366. package/dist/src/bitgo/wallet/BuildParams.d.ts +27 -1
  367. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
  368. package/dist/src/bitgo/wallet/BuildParams.js +45 -11
  369. package/dist/src/bitgo/wallet/iWallet.d.ts +391 -23
  370. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  371. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  372. package/dist/src/bitgo/wallet/iWallets.d.ts +136 -18
  373. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  374. package/dist/src/bitgo/wallet/iWallets.js +55 -3
  375. package/dist/src/bitgo/wallet/index.js +6 -2
  376. package/dist/src/bitgo/wallet/wallet.d.ts +266 -24
  377. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  378. package/dist/src/bitgo/wallet/wallet.js +1422 -334
  379. package/dist/src/bitgo/wallet/wallets.d.ts +100 -9
  380. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  381. package/dist/src/bitgo/wallet/wallets.js +1000 -203
  382. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
  383. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
  384. package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
  385. package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
  386. package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
  387. package/dist/src/bitgo/walletUtil/index.js +19 -0
  388. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
  389. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
  390. package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
  391. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
  392. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
  393. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
  394. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
  395. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
  396. package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
  397. package/dist/src/bitgo/webhook/index.js +6 -2
  398. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  399. package/dist/src/coins/fiataed.d.ts +32 -0
  400. package/dist/src/coins/fiataed.d.ts.map +1 -0
  401. package/dist/src/coins/fiataed.js +61 -0
  402. package/dist/src/coins/fiateur.d.ts +3 -2
  403. package/dist/src/coins/fiateur.d.ts.map +1 -1
  404. package/dist/src/coins/fiateur.js +5 -1
  405. package/dist/src/coins/fiatgbp.d.ts +3 -2
  406. package/dist/src/coins/fiatgbp.d.ts.map +1 -1
  407. package/dist/src/coins/fiatgbp.js +5 -1
  408. package/dist/src/coins/fiatinr.d.ts +32 -0
  409. package/dist/src/coins/fiatinr.d.ts.map +1 -0
  410. package/dist/src/coins/fiatinr.js +61 -0
  411. package/dist/src/coins/fiatsgd.d.ts +32 -0
  412. package/dist/src/coins/fiatsgd.d.ts.map +1 -0
  413. package/dist/src/coins/fiatsgd.js +61 -0
  414. package/dist/src/coins/fiatusd.d.ts +3 -2
  415. package/dist/src/coins/fiatusd.d.ts.map +1 -1
  416. package/dist/src/coins/fiatusd.js +5 -1
  417. package/dist/src/coins/index.d.ts +6 -0
  418. package/dist/src/coins/index.d.ts.map +1 -1
  419. package/dist/src/coins/index.js +12 -2
  420. package/dist/src/coins/ofc.d.ts +3 -2
  421. package/dist/src/coins/ofc.d.ts.map +1 -1
  422. package/dist/src/coins/ofc.js +6 -2
  423. package/dist/src/coins/ofcToken.d.ts +2 -1
  424. package/dist/src/coins/ofcToken.d.ts.map +1 -1
  425. package/dist/src/coins/ofcToken.js +27 -2
  426. package/dist/src/coins/susd.d.ts +3 -2
  427. package/dist/src/coins/susd.d.ts.map +1 -1
  428. package/dist/src/coins/susd.js +5 -1
  429. package/dist/src/coins/tfiataed.d.ts +11 -0
  430. package/dist/src/coins/tfiataed.d.ts.map +1 -0
  431. package/dist/src/coins/tfiataed.js +17 -0
  432. package/dist/src/coins/tfiatinr.d.ts +11 -0
  433. package/dist/src/coins/tfiatinr.d.ts.map +1 -0
  434. package/dist/src/coins/tfiatinr.js +17 -0
  435. package/dist/src/coins/tfiatsgd.d.ts +11 -0
  436. package/dist/src/coins/tfiatsgd.d.ts.map +1 -0
  437. package/dist/src/coins/tfiatsgd.js +17 -0
  438. package/dist/src/common.js +27 -13
  439. package/dist/src/index.d.ts +4 -1
  440. package/dist/src/index.d.ts.map +1 -1
  441. package/dist/src/index.js +30 -11
  442. package/dist/src/lightning.d.ts +2 -0
  443. package/dist/src/lightning.d.ts.map +1 -0
  444. package/dist/src/lightning.js +13 -0
  445. package/dist/src/units.js +5 -6
  446. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
  447. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  448. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
  449. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
  450. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  451. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
  452. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
  453. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  454. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
  455. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
  456. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
  457. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
  458. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +91 -29
  459. package/dist/test/unit/account-lib/mpc/util.d.ts +2 -0
  460. package/dist/test/unit/account-lib/mpc/util.d.ts.map +1 -0
  461. package/dist/test/unit/account-lib/mpc/util.js +53 -0
  462. package/dist/test/unit/bitgo/environment.d.ts +2 -0
  463. package/dist/test/unit/bitgo/environment.d.ts.map +1 -0
  464. package/dist/test/unit/bitgo/environment.js +38 -0
  465. package/dist/test/unit/bitgo/errors.d.ts +2 -0
  466. package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
  467. package/dist/test/unit/bitgo/errors.js +262 -0
  468. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  469. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  470. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  471. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +24 -4
  472. package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
  473. package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
  474. package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
  475. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  476. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  477. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  478. package/dist/test/unit/bitgo/utils/postWithCodec.js +32 -38
  479. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts +2 -0
  480. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  481. package/dist/test/unit/bitgo/utils/tss/addressVerification.js +85 -0
  482. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  483. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  484. package/dist/test/unit/bitgo/utils/txRequest.js +105 -0
  485. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  486. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  487. package/dist/test/unit/bitgo/wallet/BuildParams.js +68 -0
  488. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +23 -9
  489. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts +2 -0
  490. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts.map +1 -0
  491. package/dist/test/unit/bitgo/wallet/getAccountResources.js +133 -0
  492. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts +2 -0
  493. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts.map +1 -0
  494. package/dist/test/unit/bitgo/wallet/getResourceDelegations.js +118 -0
  495. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
  496. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
  497. package/dist/test/unit/bitgo/wallet/tokenApproval.js +135 -0
  498. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
  499. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
  500. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
  501. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts +2 -0
  502. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts.map +1 -0
  503. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.js +276 -0
  504. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
  505. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
  506. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
  507. package/dist/test/unit/lightning.d.ts +2 -0
  508. package/dist/test/unit/lightning.d.ts.map +1 -0
  509. package/dist/test/unit/lightning.js +23 -0
  510. package/dist/test/unit/units.d.ts.map +1 -1
  511. package/dist/test/unit/units.js +64 -64
  512. package/dist/tsconfig.tsbuildinfo +1 -1
  513. package/package.json +24 -21
  514. package/.eslintignore +0 -5
  515. package/CHANGELOG.md +0 -1367
  516. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  517. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  518. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  519. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  520. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  521. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  522. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  523. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  524. package/dist/src/bitgo/lightning/index.js +0 -17
  525. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  526. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  527. package/dist/src/bitgo/lightning/lightning.js +0 -111
  528. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  529. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  530. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  531. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  532. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  533. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  534. package/dist/src/bitgo/trading/affirmation.d.ts +0 -35
  535. package/dist/src/bitgo/trading/affirmation.d.ts.map +0 -1
  536. package/dist/src/bitgo/trading/affirmation.js +0 -53
  537. package/dist/src/bitgo/trading/affirmations.d.ts +0 -23
  538. package/dist/src/bitgo/trading/affirmations.d.ts.map +0 -1
  539. package/dist/src/bitgo/trading/affirmations.js +0 -45
  540. package/dist/src/bitgo/trading/iAffirmation.d.ts +0 -15
  541. package/dist/src/bitgo/trading/iAffirmation.d.ts.map +0 -1
  542. package/dist/src/bitgo/trading/iAffirmation.js +0 -13
  543. package/dist/src/bitgo/trading/iAffirmations.d.ts +0 -10
  544. package/dist/src/bitgo/trading/iAffirmations.d.ts.map +0 -1
  545. package/dist/src/bitgo/trading/iAffirmations.js +0 -3
  546. package/dist/src/bitgo/trading/iSettlement.d.ts +0 -25
  547. package/dist/src/bitgo/trading/iSettlement.d.ts.map +0 -1
  548. package/dist/src/bitgo/trading/iSettlement.js +0 -17
  549. package/dist/src/bitgo/trading/iSettlements.d.ts +0 -19
  550. package/dist/src/bitgo/trading/iSettlements.d.ts.map +0 -1
  551. package/dist/src/bitgo/trading/iSettlements.js +0 -3
  552. package/dist/src/bitgo/trading/iTradingPartner.d.ts +0 -14
  553. package/dist/src/bitgo/trading/iTradingPartner.d.ts.map +0 -1
  554. package/dist/src/bitgo/trading/iTradingPartner.js +0 -17
  555. package/dist/src/bitgo/trading/iTradingPartners.d.ts +0 -15
  556. package/dist/src/bitgo/trading/iTradingPartners.d.ts.map +0 -1
  557. package/dist/src/bitgo/trading/iTradingPartners.js +0 -9
  558. package/dist/src/bitgo/trading/lock.d.ts +0 -16
  559. package/dist/src/bitgo/trading/lock.d.ts.map +0 -1
  560. package/dist/src/bitgo/trading/lock.js +0 -12
  561. package/dist/src/bitgo/trading/payload.d.ts +0 -22
  562. package/dist/src/bitgo/trading/payload.d.ts.map +0 -1
  563. package/dist/src/bitgo/trading/payload.js +0 -3
  564. package/dist/src/bitgo/trading/settlement.d.ts +0 -16
  565. package/dist/src/bitgo/trading/settlement.d.ts.map +0 -1
  566. package/dist/src/bitgo/trading/settlement.js +0 -21
  567. package/dist/src/bitgo/trading/settlements.d.ts +0 -32
  568. package/dist/src/bitgo/trading/settlements.d.ts.map +0 -1
  569. package/dist/src/bitgo/trading/settlements.js +0 -61
  570. package/dist/src/bitgo/trading/trade.d.ts +0 -29
  571. package/dist/src/bitgo/trading/trade.d.ts.map +0 -1
  572. package/dist/src/bitgo/trading/trade.js +0 -11
  573. package/dist/src/bitgo/trading/tradingPartner.d.ts +0 -26
  574. package/dist/src/bitgo/trading/tradingPartner.d.ts.map +0 -1
  575. package/dist/src/bitgo/trading/tradingPartner.js +0 -31
  576. package/dist/src/bitgo/trading/tradingPartners.d.ts +0 -24
  577. package/dist/src/bitgo/trading/tradingPartners.d.ts.map +0 -1
  578. package/dist/src/bitgo/trading/tradingPartners.js +0 -32
  579. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  580. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  581. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  582. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  583. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  584. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  585. package/dist/src/openssl/index.d.ts +0 -5
  586. package/dist/src/openssl/index.d.ts.map +0 -1
  587. package/dist/src/openssl/index.js +0 -9
  588. package/dist/test/unit/openssl.d.ts +0 -2
  589. package/dist/test/unit/openssl.d.ts.map +0 -1
  590. package/dist/test/unit/openssl.js +0 -39
@@ -0,0 +1,958 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.EcdsaMPCv2Utils = void 0;
40
+ exports.isGG18SigningMaterial = isGG18SigningMaterial;
41
+ exports.getMpcV2RecoveryKeyShares = getMpcV2RecoveryKeyShares;
42
+ exports.signRecoveryMpcV2 = signRecoveryMpcV2;
43
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
44
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
45
+ const assert_1 = __importDefault(require("assert"));
46
+ const buffer_1 = require("buffer");
47
+ const io_ts_types_1 = require("io-ts-types");
48
+ const keccak_1 = __importDefault(require("keccak"));
49
+ const pgp = __importStar(require("openpgp"));
50
+ const public_types_1 = require("@bitgo/public-types");
51
+ const account_lib_1 = require("../../../../account-lib");
52
+ const tss_1 = require("../../../tss");
53
+ const common_1 = require("../../../tss/common");
54
+ const typesMPCv2_1 = require("./typesMPCv2");
55
+ const ecdsaMPCv2_1 = require("../../../tss/ecdsa/ecdsaMPCv2");
56
+ const errors_1 = require("../../../errors");
57
+ const opengpgUtils_1 = require("../../opengpgUtils");
58
+ const baseTypes_1 = require("../baseTypes");
59
+ const base_1 = require("./base");
60
+ const ecdsaMPCv2KeyGenSender_1 = require("./ecdsaMPCv2KeyGenSender");
61
+ const bitgoPubKeys_1 = require("../../../tss/bitgoPubKeys");
62
+ class EcdsaMPCv2Utils extends base_1.BaseEcdsaUtils {
63
+ /** @inheritdoc */
64
+ async createKeychains(params) {
65
+ const { userSession, backupSession } = this.getUserAndBackupSession(2, 3, params.retrofit);
66
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
67
+ const backupGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
68
+ // Get the BitGo public key based on user/enterprise feature flags
69
+ // If it doesn't work, use the default public key from the constants
70
+ const bitgoPublicGpgKey = ((await this.getBitgoGpgPubkeyBasedOnFeatureFlags(params.enterprise, true)) ?? this.bitgoMPCv2PublicGpgKey).armor();
71
+ if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
72
+ // Ensure the public key is one of the expected BitGo public keys when in test or prod.
73
+ (0, assert_1.default)((0, bitgoPubKeys_1.isBitgoMpcPubKey)(bitgoPublicGpgKey, 'mpcv2'), 'Invalid BitGo GPG public key');
74
+ }
75
+ const userGpgPrvKey = {
76
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.USER,
77
+ gpgKey: userGpgKey.privateKey,
78
+ };
79
+ const backupGpgPrvKey = {
80
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
81
+ gpgKey: backupGpgKey.privateKey,
82
+ };
83
+ const bitgoGpgPubKey = {
84
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
85
+ gpgKey: bitgoPublicGpgKey,
86
+ };
87
+ // #region round 1
88
+ const userRound1BroadcastMsg = await userSession.initDkg();
89
+ const backupRound1BroadcastMsg = await backupSession.initDkg();
90
+ const round1SerializedMessages = sdk_lib_mpc_1.DklsTypes.serializeMessages({
91
+ broadcastMessages: [userRound1BroadcastMsg, backupRound1BroadcastMsg],
92
+ p2pMessages: [],
93
+ });
94
+ const round1Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round1SerializedMessages, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
95
+ const { sessionId, bitgoMsg1, bitgoToBackupMsg2, bitgoToUserMsg2 } = await this.sendKeyGenerationRound1(params.enterprise, userGpgKey.publicKey, backupGpgKey.publicKey, params.retrofit?.walletId
96
+ ? {
97
+ ...round1Messages,
98
+ walletId: params.retrofit.walletId,
99
+ }
100
+ : round1Messages);
101
+ // #endregion
102
+ // #region round 2
103
+ const bitgoRound1BroadcastMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg1)] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
104
+ const bitgoRound1BroadcastMsg = bitgoRound1BroadcastMessages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
105
+ (0, assert_1.default)(bitgoRound1BroadcastMsg, 'BitGo message 1 not found in broadcast messages');
106
+ const userRound2P2PMessages = userSession.handleIncomingMessages({
107
+ p2pMessages: [],
108
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg), backupRound1BroadcastMsg],
109
+ });
110
+ const userToBitgoMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
111
+ (0, assert_1.default)(userToBitgoMsg2, 'User message 2 not found in P2P messages');
112
+ const serializedUserToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg2);
113
+ const backupRound2P2PMessages = backupSession.handleIncomingMessages({
114
+ p2pMessages: [],
115
+ broadcastMessages: [userRound1BroadcastMsg, sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg)],
116
+ });
117
+ const serializedBackupToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeMessages(backupRound2P2PMessages).p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
118
+ (0, assert_1.default)(serializedBackupToBitgoMsg2, 'Backup message 2 not found in P2P messages');
119
+ const round2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ p2pMessages: [serializedUserToBitgoMsg2, serializedBackupToBitgoMsg2], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
120
+ const { sessionId: sessionIdRound2, bitgoCommitment2, bitgoToUserMsg3, bitgoToBackupMsg3, } = await this.sendKeyGenerationRound2(params.enterprise, sessionId, round2Messages);
121
+ // #endregion
122
+ // #region round 3
123
+ assert_1.default.equal(sessionId, sessionIdRound2, 'Round 1 and 2 Session IDs do not match');
124
+ const decryptedBitgoToUserRound2Msgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToUserMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey]);
125
+ const serializedBitgoToUserRound2Msg = decryptedBitgoToUserRound2Msgs.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
126
+ (0, assert_1.default)(serializedBitgoToUserRound2Msg, 'BitGo to User message 2 not found in P2P messages');
127
+ const bitgoToUserRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound2Msg);
128
+ const decryptedBitgoToBackupRound2Msg = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
129
+ const serializedBitgoToBackupRound2Msg = decryptedBitgoToBackupRound2Msg.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
130
+ (0, assert_1.default)(serializedBitgoToBackupRound2Msg, 'BitGo to Backup message 2 not found in P2P messages');
131
+ const bitgoToBackupRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound2Msg);
132
+ const userToBackupMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
133
+ (0, assert_1.default)(userToBackupMsg2, 'User to Backup message 2 not found in P2P messages');
134
+ const backupToUserMsg2 = backupRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
135
+ (0, assert_1.default)(backupToUserMsg2, 'Backup to User message 2 not found in P2P messages');
136
+ const userRound3Messages = userSession.handleIncomingMessages({
137
+ broadcastMessages: [],
138
+ p2pMessages: [bitgoToUserRound2Msg, backupToUserMsg2],
139
+ });
140
+ const userToBackupMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
141
+ (0, assert_1.default)(userToBackupMsg3, 'User to Backup message 3 not found in P2P messages');
142
+ const userToBitgoMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
143
+ (0, assert_1.default)(userToBitgoMsg3, 'User to Bitgo message 3 not found in P2P messages');
144
+ const serializedUserToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg3);
145
+ const backupRound3Messages = backupSession.handleIncomingMessages({
146
+ broadcastMessages: [],
147
+ p2pMessages: [bitgoToBackupRound2Msg, userToBackupMsg2],
148
+ });
149
+ const backupToUserMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
150
+ (0, assert_1.default)(backupToUserMsg3, 'Backup to User message 3 not found in P2P messages');
151
+ const backupToBitgoMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
152
+ (0, assert_1.default)(backupToBitgoMsg3, 'Backup to Bitgo message 3 not found in P2P messages');
153
+ const serializedBackupToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(backupToBitgoMsg3);
154
+ const decryptedBitgoToUserRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToUserMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [userGpgPrvKey]);
155
+ const serializedBitgoToUserRound3Msg = decryptedBitgoToUserRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
156
+ (0, assert_1.default)(serializedBitgoToUserRound3Msg, 'BitGo to User message 3 not found in P2P messages');
157
+ const bitgoToUserRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound3Msg);
158
+ const decryptedBitgoToBackupRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
159
+ const serializedBitgoToBackupRound3Msg = decryptedBitgoToBackupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
160
+ (0, assert_1.default)(serializedBitgoToBackupRound3Msg, 'BitGo to Backup message 3 not found in P2P messages');
161
+ const bitgoToBackupRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound3Msg);
162
+ const userRound4Messages = userSession.handleIncomingMessages({
163
+ p2pMessages: [backupToUserMsg3, bitgoToUserRound3Msg],
164
+ broadcastMessages: [],
165
+ });
166
+ const userRound4BroadcastMsg = userRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER);
167
+ (0, assert_1.default)(userRound4BroadcastMsg, 'User message 4 not found in broadcast messages');
168
+ const serializedUserRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(userRound4BroadcastMsg);
169
+ const backupRound4Messages = backupSession.handleIncomingMessages({
170
+ p2pMessages: [userToBackupMsg3, bitgoToBackupRound3Msg],
171
+ broadcastMessages: [],
172
+ });
173
+ const backupRound4BroadcastMsg = backupRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
174
+ (0, assert_1.default)(backupRound4BroadcastMsg, 'Backup message 4 not found in broadcast messages');
175
+ const serializedBackupRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(backupRound4BroadcastMsg);
176
+ const round3Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({
177
+ p2pMessages: [serializedUserToBitgoMsg3, serializedBackupToBitgoMsg3],
178
+ broadcastMessages: [serializedUserRound4BroadcastMsg, serializedBackupRound4BroadcastMsg],
179
+ }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
180
+ const { sessionId: sessionIdRound3, bitgoMsg4, commonKeychain: bitgoCommonKeychain, } = await this.sendKeyGenerationRound3(params.enterprise, sessionId, round3Messages);
181
+ // #endregion
182
+ // #region keychain creation
183
+ assert_1.default.equal(sessionId, sessionIdRound3, 'Round 1 and 3 Session IDs do not match');
184
+ const bitgoRound4BroadcastMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg4)] }, [bitgoGpgPubKey], [])).broadcastMessages;
185
+ const bitgoRound4BroadcastMsg = bitgoRound4BroadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
186
+ (0, assert_1.default)(bitgoRound4BroadcastMsg, 'BitGo message 4 not found in broadcast messages');
187
+ userSession.handleIncomingMessages({
188
+ p2pMessages: [],
189
+ broadcastMessages: [bitgoRound4BroadcastMsg, backupRound4BroadcastMsg],
190
+ });
191
+ backupSession.handleIncomingMessages({
192
+ p2pMessages: [],
193
+ broadcastMessages: [bitgoRound4BroadcastMsg, userRound4BroadcastMsg],
194
+ });
195
+ const userPrivateMaterial = userSession.getKeyShare();
196
+ const backupPrivateMaterial = backupSession.getKeyShare();
197
+ const userReducedPrivateMaterial = userSession.getReducedKeyShare();
198
+ const backupReducedPrivateMaterial = backupSession.getReducedKeyShare();
199
+ const userCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userPrivateMaterial);
200
+ const backupCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupPrivateMaterial);
201
+ assert_1.default.equal(bitgoCommonKeychain, userCommonKeychain, 'User and Bitgo Common keychains do not match');
202
+ assert_1.default.equal(bitgoCommonKeychain, backupCommonKeychain, 'Backup and Bitgo Common keychains do not match');
203
+ const userKeychainPromise = this.addUserKeychain(bitgoCommonKeychain, userPrivateMaterial, userReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode);
204
+ const backupKeychainPromise = this.addBackupKeychain(bitgoCommonKeychain, backupPrivateMaterial, backupReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode);
205
+ const bitgoKeychainPromise = this.addBitgoKeychain(bitgoCommonKeychain);
206
+ const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
207
+ userKeychainPromise,
208
+ backupKeychainPromise,
209
+ bitgoKeychainPromise,
210
+ ]);
211
+ // #endregion
212
+ return {
213
+ userKeychain,
214
+ backupKeychain,
215
+ bitgoKeychain,
216
+ };
217
+ }
218
+ // #region keychain utils
219
+ async createParticipantKeychain(participantIndex, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
220
+ let source;
221
+ let encryptedPrv = undefined;
222
+ let reducedEncryptedPrv = undefined;
223
+ switch (participantIndex) {
224
+ case typesMPCv2_1.MPCv2PartiesEnum.USER:
225
+ case typesMPCv2_1.MPCv2PartiesEnum.BACKUP:
226
+ source = participantIndex === typesMPCv2_1.MPCv2PartiesEnum.USER ? 'user' : 'backup';
227
+ (0, assert_1.default)(privateMaterial, `Private material is required for ${source} keychain`);
228
+ (0, assert_1.default)(reducedPrivateMaterial, `Reduced private material is required for ${source} keychain`);
229
+ (0, assert_1.default)(passphrase, `Passphrase is required for ${source} keychain`);
230
+ encryptedPrv = this.bitgo.encrypt({
231
+ input: privateMaterial.toString('base64'),
232
+ password: passphrase,
233
+ });
234
+ // Encrypts the CBOR-encoded ReducedKeyShare (which contains the party's private
235
+ // scalar s_i) with the wallet passphrase. The result is stored as reducedEncryptedPrv
236
+ // on the key card QR code and represents a second copy of private key material
237
+ // beyond the server-stored encryptedPrv.
238
+ reducedEncryptedPrv = this.bitgo.encrypt({
239
+ // Buffer.toString('base64') can not be used here as it does not work on the browser.
240
+ // The browser deals with a Buffer as Uint8Array, therefore in the browser .toString('base64') just creates a comma seperated string of the array values.
241
+ input: btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(reducedPrivateMaterial)))),
242
+ password: passphrase,
243
+ });
244
+ break;
245
+ case typesMPCv2_1.MPCv2PartiesEnum.BITGO:
246
+ source = 'bitgo';
247
+ break;
248
+ default:
249
+ throw new Error('Invalid participant index');
250
+ }
251
+ const recipientKeychainParams = {
252
+ source,
253
+ keyType: 'tss',
254
+ commonKeychain,
255
+ encryptedPrv,
256
+ originalPasscodeEncryptionCode,
257
+ isMPCv2: true,
258
+ };
259
+ const keychains = this.baseCoin.keychains();
260
+ return { ...(await keychains.add(recipientKeychainParams)), reducedEncryptedPrv: reducedEncryptedPrv };
261
+ }
262
+ /**
263
+ * Converts a User or Backup MPCv1 SigningMaterial to RetrofitData needed by MPCv2 DKG.
264
+ *
265
+ * @param decryptedKeyshare - MPCv1 decrypted signing material for user or backup as a json.stringify string and bitgo's Big Si.
266
+ * @param partyId - The party ID of the MPCv1 keyshare.
267
+ * @returns The retrofit data needed to start an MPCv2 DKG session.
268
+ * @deprecated
269
+ */
270
+ static getKeyDataForRetrofit(decryptedKeyshare, partyId) {
271
+ const mpc = new account_lib_1.Ecdsa();
272
+ const xiList = [
273
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(1), 32)),
274
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(2), 32)),
275
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(3), 32)),
276
+ ];
277
+ return EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
278
+ mpcv1PartyKeyShare: decryptedKeyshare,
279
+ mpcv1PartyIndex: partyId === typesMPCv2_1.MPCv2PartiesEnum.USER ? 1 : 2,
280
+ xiList,
281
+ mpc,
282
+ });
283
+ }
284
+ /**
285
+ * Converts user and backup MPCv1 SigningMaterial to RetrofitData needed by MPCv2 DKG.
286
+ *
287
+ * @param {Object} params - MPCv1 decrypted signing material for user and backup as a json.stringify string and bitgo's Big Si.
288
+ * @returns {{ mpcv2UserKeyShare: DklsTypes.RetrofitData; mpcv2BakcupKeyShare: DklsTypes.RetrofitData }} - the retrofit data needed to start an MPCv2 DKG session.
289
+ */
290
+ getMpcV2RetrofitDataFromMpcV1Keys(params) {
291
+ const mpc = new account_lib_1.Ecdsa();
292
+ const xiList = [
293
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(1), 32)),
294
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(2), 32)),
295
+ Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(3), 32)),
296
+ ];
297
+ return {
298
+ mpcv2UserKeyShare: EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
299
+ mpcv1PartyKeyShare: params.mpcv1UserKeyShare,
300
+ mpcv1PartyIndex: 1,
301
+ xiList,
302
+ mpc,
303
+ }),
304
+ mpcv2BackupKeyShare: EcdsaMPCv2Utils.getMpcV2RetrofitDataFromMpcV1Key({
305
+ mpcv1PartyKeyShare: params.mpcv1BackupKeyShare,
306
+ mpcv1PartyIndex: 2,
307
+ xiList,
308
+ mpc,
309
+ }),
310
+ };
311
+ }
312
+ /**
313
+ * Get retrofit data from MPCv1 key share.
314
+ * @param mpcv1PartyKeyShare
315
+ * @param mpcv1PartyIndex
316
+ * @param xiList
317
+ * @param mpc
318
+ * @deprecated
319
+ */
320
+ static getMpcV2RetrofitDataFromMpcV1Key({ mpcv1PartyKeyShare, mpcv1PartyIndex, xiList, mpc, }) {
321
+ const signingMaterial = JSON.parse(mpcv1PartyKeyShare);
322
+ let keyCombined = undefined;
323
+ switch (mpcv1PartyIndex) {
324
+ case 1:
325
+ (0, assert_1.default)(signingMaterial.backupNShare, 'User MPCv1 key material should have backup NShare.');
326
+ (0, assert_1.default)(signingMaterial.bitgoNShare, 'BitGo MPCv1 key material should have user NShare.');
327
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [
328
+ signingMaterial.backupNShare,
329
+ signingMaterial.bitgoNShare,
330
+ ]);
331
+ break;
332
+ case 2:
333
+ (0, assert_1.default)(signingMaterial.userNShare, 'User MPCv1 key material should have backup NShare.');
334
+ (0, assert_1.default)(signingMaterial.bitgoNShare, 'BitGo MPCv1 key material should have user NShare.');
335
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [signingMaterial.userNShare, signingMaterial.bitgoNShare]);
336
+ break;
337
+ case 3:
338
+ (0, assert_1.default)(signingMaterial.userNShare, 'User MPCv1 key material should have backup NShare.');
339
+ (0, assert_1.default)(signingMaterial.backupNShare, 'Backup MPCv1 key material should have user NShare.');
340
+ keyCombined = mpc.keyCombine(signingMaterial.pShare, [
341
+ signingMaterial.userNShare,
342
+ signingMaterial.backupNShare,
343
+ ]);
344
+ break;
345
+ default:
346
+ throw new Error('Invalid participant index');
347
+ }
348
+ return {
349
+ xShare: keyCombined.xShare,
350
+ xiList: xiList,
351
+ };
352
+ }
353
+ async addUserKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
354
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode);
355
+ }
356
+ async addBackupKeychain(commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode) {
357
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, commonKeychain, privateMaterial, reducedPrivateMaterial, passphrase, originalPasscodeEncryptionCode);
358
+ }
359
+ getUserAndBackupSession(m, n, retrofit) {
360
+ if (retrofit) {
361
+ const retrofitData = this.getMpcV2RetrofitDataFromMpcV1Keys({
362
+ mpcv1UserKeyShare: retrofit.decryptedUserKey,
363
+ mpcv1BackupKeyShare: retrofit.decryptedBackupKey,
364
+ });
365
+ const userSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.USER, undefined, retrofitData.mpcv2UserKeyShare);
366
+ const backupSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.BACKUP, undefined, retrofitData.mpcv2BackupKeyShare);
367
+ return { userSession, backupSession };
368
+ }
369
+ const userSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.USER);
370
+ const backupSession = new sdk_lib_mpc_1.DklsDkg.Dkg(n, m, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
371
+ return { userSession, backupSession };
372
+ }
373
+ async addBitgoKeychain(commonKeychain) {
374
+ return this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BITGO, commonKeychain);
375
+ }
376
+ // #endregion
377
+ async sendKeyGenerationRound1(enterprise, userGpgPublicKey, backupGpgPublicKey, payload) {
378
+ return this.sendKeyGenerationRound1BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), userGpgPublicKey, backupGpgPublicKey, payload);
379
+ }
380
+ async sendKeyGenerationRound2(enterprise, sessionId, payload) {
381
+ return this.sendKeyGenerationRound2BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), sessionId, payload);
382
+ }
383
+ async sendKeyGenerationRound3(enterprise, sessionId, payload) {
384
+ return this.sendKeyGenerationRound3BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, enterprise), sessionId, payload);
385
+ }
386
+ async sendKeyGenerationRound1BySender(senderFn, userGpgPublicKey, backupGpgPublicKey, payload) {
387
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
388
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupGpgPublicKey), 'Backup GPG public key is required');
389
+ const userMsg1 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
390
+ (0, assert_1.default)(userMsg1, 'User message 1 not found in broadcast messages');
391
+ const backupMsg1 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP)?.payload;
392
+ (0, assert_1.default)(backupMsg1, 'Backup message 1 not found in broadcast messages');
393
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R1'], {
394
+ userGpgPublicKey,
395
+ backupGpgPublicKey,
396
+ userMsg1: { from: 0, ...userMsg1 },
397
+ backupMsg1: { from: 1, ...backupMsg1 },
398
+ walletId: payload.walletId,
399
+ });
400
+ }
401
+ async sendKeyGenerationRound2BySender(senderFn, sessionId, payload) {
402
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
403
+ const userMsg2 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
404
+ (0, assert_1.default)(userMsg2, 'User to Bitgo message 2 not found in P2P messages');
405
+ (0, assert_1.default)(userMsg2.commitment, 'User to Bitgo commitment not found in P2P messages');
406
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userMsg2.commitment), 'User to Bitgo commitment is required');
407
+ const backupMsg2 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
408
+ (0, assert_1.default)(backupMsg2, 'Backup to Bitgo message 2 not found in P2P messages');
409
+ (0, assert_1.default)(backupMsg2.commitment, 'Backup to Bitgo commitment not found in P2P messages');
410
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupMsg2.commitment), 'Backup to Bitgo commitment is required');
411
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R2'], {
412
+ sessionId,
413
+ userMsg2: {
414
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
415
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
416
+ signature: userMsg2.payload.signature,
417
+ encryptedMessage: userMsg2.payload.encryptedMessage,
418
+ },
419
+ userCommitment2: userMsg2.commitment,
420
+ backupMsg2: {
421
+ from: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
422
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
423
+ signature: backupMsg2.payload.signature,
424
+ encryptedMessage: backupMsg2.payload.encryptedMessage,
425
+ },
426
+ backupCommitment2: backupMsg2.commitment,
427
+ });
428
+ }
429
+ async sendKeyGenerationRound3BySender(senderFn, sessionId, payload) {
430
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
431
+ const userMsg3 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO)?.payload;
432
+ (0, assert_1.default)(userMsg3, 'User to Bitgo message 3 not found in P2P messages');
433
+ const backupMsg3 = payload.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO)?.payload;
434
+ (0, assert_1.default)(backupMsg3, 'Backup to Bitgo message 3 not found in P2P messages');
435
+ const userMsg4 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
436
+ (0, assert_1.default)(userMsg4, 'User message 1 not found in broadcast messages');
437
+ const backupMsg4 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP)?.payload;
438
+ (0, assert_1.default)(backupMsg4, 'Backup message 1 not found in broadcast messages');
439
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R3'], {
440
+ sessionId,
441
+ userMsg3: { from: 0, to: 2, ...userMsg3 },
442
+ backupMsg3: { from: 1, to: 2, ...backupMsg3 },
443
+ userMsg4: { from: 0, ...userMsg4 },
444
+ backupMsg4: { from: 1, ...backupMsg4 },
445
+ });
446
+ }
447
+ // #endregion
448
+ // #region sign tx request
449
+ /**
450
+ * Signs the transaction associated to the transaction request.
451
+ * @param {string | TxRequest} params.txRequest - transaction request object or id
452
+ * @param {string} params.prv - decrypted private key
453
+ * @param {string} params.reqId - request id
454
+ * @param {string} params.mpcv2PartyId - party id for the signer involved in this mpcv2 request (either 0 for user or 1 for backup)
455
+ * @returns {Promise<TxRequest>} fully signed TxRequest object
456
+ */
457
+ async signTxRequest(params) {
458
+ this.bitgo.setRequestTracer(params.reqId);
459
+ return this.signRequestBase(params, baseTypes_1.RequestType.tx);
460
+ }
461
+ /**
462
+ * Signs the message associated to the transaction request.
463
+ * @param {string | TxRequest} params.txRequest - transaction request object or id
464
+ * @param {string} params.prv - decrypted private key
465
+ * @param {string} params.reqId - request id
466
+ * @returns {Promise<TxRequest>} fully signed TxRequest object
467
+ */
468
+ async signTxRequestForMessage(params) {
469
+ this.bitgo.setRequestTracer(params.reqId);
470
+ return this.signRequestBase(params, baseTypes_1.RequestType.message);
471
+ }
472
+ async signRequestBase(params, requestType) {
473
+ const userKeyShare = buffer_1.Buffer.from(params.prv, 'base64');
474
+ const txRequest = typeof params.txRequest === 'string'
475
+ ? await (0, tss_1.getTxRequest)(this.bitgo, this.wallet.id(), params.txRequest, params.reqId)
476
+ : params.txRequest;
477
+ let txOrMessageToSign;
478
+ let derivationPath;
479
+ let bufferContent;
480
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
481
+ const bitgoGpgPubKey = await this.pickBitgoPubGpgKeyForSigning(true, params.reqId, txRequest.enterpriseId);
482
+ if (!bitgoGpgPubKey) {
483
+ throw new Error('Missing BitGo GPG key for MPCv2');
484
+ }
485
+ if (requestType === baseTypes_1.RequestType.tx) {
486
+ (0, assert_1.default)(txRequest.transactions || txRequest.unsignedTxs, 'Unable to find transactions in txRequest');
487
+ const unsignedTx = txRequest.apiVersion === 'full' ? txRequest.transactions[0].unsignedTx : txRequest.unsignedTxs[0];
488
+ if (!params.txParams?.recipients?.length) {
489
+ throw new errors_1.InvalidTransactionError('Recipient details are required to verify this transaction before signing. Pass txParams with at least one recipient.');
490
+ }
491
+ // For ICP transactions, the HSM signs the serializedTxHex, while the user signs the signableHex separately.
492
+ // Verification cannot be performed directly on the signableHex alone. However, we can parse the serializedTxHex
493
+ // to regenerate the signableHex and compare it against the provided value for verification.
494
+ // In contrast, for other coin families, verification is typically done using just the signableHex.
495
+ if (this.baseCoin.getConfig().family === 'icp') {
496
+ await this.baseCoin.verifyTransaction({
497
+ txPrebuild: { txHex: unsignedTx.serializedTxHex, txInfo: unsignedTx.signableHex },
498
+ txParams: params.txParams,
499
+ wallet: this.wallet,
500
+ walletType: this.wallet.multisigType(),
501
+ });
502
+ }
503
+ else {
504
+ await this.baseCoin.verifyTransaction({
505
+ txPrebuild: { txHex: unsignedTx.signableHex },
506
+ txParams: params.txParams,
507
+ wallet: this.wallet,
508
+ walletType: this.wallet.multisigType(),
509
+ });
510
+ }
511
+ txOrMessageToSign = unsignedTx.signableHex;
512
+ derivationPath = unsignedTx.derivationPath;
513
+ bufferContent = buffer_1.Buffer.from(txOrMessageToSign, 'hex');
514
+ }
515
+ else if (requestType === baseTypes_1.RequestType.message) {
516
+ txOrMessageToSign = txRequest.messages[0].messageEncoded;
517
+ derivationPath = txRequest.messages[0].derivationPath || 'm/0';
518
+ bufferContent = buffer_1.Buffer.from(txOrMessageToSign, 'hex');
519
+ }
520
+ else {
521
+ throw new Error('Invalid request type');
522
+ }
523
+ let hash;
524
+ try {
525
+ hash = this.baseCoin.getHashFunction();
526
+ }
527
+ catch (err) {
528
+ hash = (0, keccak_1.default)('keccak256');
529
+ }
530
+ // check what the encoding is supposed to be for message
531
+ const hashBuffer = hash.update(bufferContent).digest();
532
+ const otherSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, params.mpcv2PartyId !== undefined ? params.mpcv2PartyId : 0, derivationPath, hashBuffer);
533
+ const userSignerBroadcastMsg1 = await otherSigner.init();
534
+ const signatureShareRound1 = await (0, ecdsaMPCv2_1.getSignatureShareRoundOne)(userSignerBroadcastMsg1, userGpgKey, params.mpcv2PartyId);
535
+ let latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
536
+ (0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest Object');
537
+ let bitgoToUserMessages1And2;
538
+ if (requestType === baseTypes_1.RequestType.tx) {
539
+ bitgoToUserMessages1And2 = latestTxRequest.transactions[0].signatureShares;
540
+ }
541
+ else {
542
+ bitgoToUserMessages1And2 = latestTxRequest.messages[0].signatureShares;
543
+ }
544
+ // TODO: Use codec for parsing
545
+ const parsedBitGoToUserSigShareRoundOne = JSON.parse(bitgoToUserMessages1And2[bitgoToUserMessages1And2.length - 1].share);
546
+ if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
547
+ throw new Error('Unexpected signature share response. Unable to parse data.');
548
+ }
549
+ const serializedBitGoToUserMessagesRound1And2 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundOne)(parsedBitGoToUserSigShareRoundOne, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
550
+ /** Round 2 **/
551
+ const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(serializedBitGoToUserMessagesRound1And2);
552
+ const userToBitGoMessagesRound2 = otherSigner.handleIncomingMessages({
553
+ p2pMessages: [],
554
+ broadcastMessages: deserializedMessages.broadcastMessages,
555
+ });
556
+ const userToBitGoMessagesRound3 = otherSigner.handleIncomingMessages({
557
+ p2pMessages: deserializedMessages.p2pMessages,
558
+ broadcastMessages: [],
559
+ });
560
+ const signatureShareRoundTwo = await (0, ecdsaMPCv2_1.getSignatureShareRoundTwo)(userToBitGoMessagesRound2, userToBitGoMessagesRound3, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
561
+ latestTxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRoundTwo], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
562
+ (0, assert_1.default)(latestTxRequest.transactions || latestTxRequest.messages, 'Invalid txRequest Object');
563
+ const txRequestSignatureShares = requestType === baseTypes_1.RequestType.tx
564
+ ? latestTxRequest.transactions[0].signatureShares
565
+ : latestTxRequest.messages[0].signatureShares;
566
+ // TODO: Use codec for parsing
567
+ const parsedBitGoToUserSigShareRoundTwo = JSON.parse(txRequestSignatureShares[txRequestSignatureShares.length - 1].share);
568
+ if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
569
+ throw new Error('Unexpected signature share response. Unable to parse data.');
570
+ }
571
+ const serializedBitGoToUserMessagesRound3 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundTwo)(parsedBitGoToUserSigShareRoundTwo, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
572
+ /** Round 3 **/
573
+ const deserializedBitGoToUserMessagesRound3 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
574
+ p2pMessages: serializedBitGoToUserMessagesRound3.p2pMessages,
575
+ broadcastMessages: [],
576
+ });
577
+ const userToBitGoMessagesRound4 = otherSigner.handleIncomingMessages({
578
+ p2pMessages: deserializedBitGoToUserMessagesRound3.p2pMessages,
579
+ broadcastMessages: [],
580
+ });
581
+ const signatureShareRoundThree = await (0, ecdsaMPCv2_1.getSignatureShareRoundThree)(userToBitGoMessagesRound4, userGpgKey, bitgoGpgPubKey, params.mpcv2PartyId);
582
+ // Submit for final signature share combine
583
+ await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequest.walletId, txRequest.txRequestId, [signatureShareRoundThree], requestType, this.baseCoin.getMPCAlgorithm(), userGpgKey.publicKey, undefined, this.wallet.multisigTypeVersion(), params.reqId);
584
+ return (0, common_1.sendTxRequest)(this.bitgo, txRequest.walletId, txRequest.txRequestId, requestType, params.reqId);
585
+ }
586
+ // #endregion
587
+ // #region formatting utils
588
+ formatBitgoBroadcastMessage(broadcastMessage) {
589
+ return {
590
+ from: broadcastMessage.from,
591
+ payload: { message: broadcastMessage.message, signature: broadcastMessage.signature },
592
+ };
593
+ }
594
+ formatP2PMessage(p2pMessage, commitment) {
595
+ return {
596
+ payload: { encryptedMessage: p2pMessage.encryptedMessage, signature: p2pMessage.signature },
597
+ from: p2pMessage.from,
598
+ to: p2pMessage.to,
599
+ commitment,
600
+ };
601
+ }
602
+ // #endregion
603
+ // #region private utils
604
+ /**
605
+ * Get the hash string and derivation path from the transaction request.
606
+ * @param {TxRequest} txRequest - the transaction request object
607
+ * @param {RequestType} requestType - the request type
608
+ * @returns {{ hashBuffer: Buffer; derivationPath: string }} - the hash string and derivation path
609
+ */
610
+ getHashStringAndDerivationPath(txRequest, requestType = baseTypes_1.RequestType.tx) {
611
+ let txToSign;
612
+ let derivationPath;
613
+ if (requestType === baseTypes_1.RequestType.tx) {
614
+ (0, assert_1.default)(txRequest.transactions && txRequest.transactions.length === 1, 'Unable to find transactions in txRequest');
615
+ txToSign = txRequest.transactions[0].unsignedTx.signableHex;
616
+ derivationPath = txRequest.transactions[0].unsignedTx.derivationPath;
617
+ }
618
+ else if (requestType === baseTypes_1.RequestType.message) {
619
+ // TODO(WP-2176): Add support for message signing
620
+ throw new Error('MPCv2 message signing not supported yet.');
621
+ }
622
+ else {
623
+ throw new Error('Invalid request type, got: ' + requestType);
624
+ }
625
+ let hash;
626
+ try {
627
+ hash = this.baseCoin.getHashFunction();
628
+ }
629
+ catch (err) {
630
+ hash = (0, keccak_1.default)('keccak256');
631
+ }
632
+ const hashBuffer = hash.update(buffer_1.Buffer.from(txToSign, 'hex')).digest();
633
+ return { hashBuffer, derivationPath };
634
+ }
635
+ /**
636
+ * Gets the BitGo and user GPG keys from the BitGo public GPG key and the encrypted user GPG private key.
637
+ * @param {string} bitgoPublicGpgKey - the BitGo public GPG key
638
+ * @param {string} encryptedUserGpgPrvKey - the encrypted user GPG private key
639
+ * @param {string} walletPassphrase - the wallet passphrase
640
+ * @returns {Promise<{ bitgoGpgKey: pgp.Key; userGpgKey: pgp.SerializedKeyPair<string> }>} - the BitGo and user GPG keys
641
+ */
642
+ async getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase) {
643
+ const bitgoGpgKey = await pgp.readKey({ armoredKey: bitgoPublicGpgKey });
644
+ const userDecryptedKey = await pgp.readKey({
645
+ armoredKey: this.bitgo.decrypt({ input: encryptedUserGpgPrvKey, password: walletPassphrase }),
646
+ });
647
+ const userGpgKey = {
648
+ privateKey: userDecryptedKey.armor(),
649
+ publicKey: userDecryptedKey.toPublic().armor(),
650
+ };
651
+ return {
652
+ bitgoGpgKey,
653
+ userGpgKey,
654
+ };
655
+ }
656
+ /**
657
+ * Validates the adata and cyphertext.
658
+ * @param adata string
659
+ * @param cyphertext string
660
+ * @returns void
661
+ * @throws {Error} if the adata or cyphertext is invalid
662
+ */
663
+ validateAdata(adata, cyphertext) {
664
+ let cypherJson;
665
+ try {
666
+ cypherJson = JSON.parse(cyphertext);
667
+ }
668
+ catch (e) {
669
+ throw new Error('Failed to parse cyphertext to JSON, got: ' + cyphertext);
670
+ }
671
+ // using decodeURIComponent to handle special characters
672
+ if (decodeURIComponent(cypherJson.adata) !== decodeURIComponent(adata)) {
673
+ throw new Error('Adata does not match cyphertext adata');
674
+ }
675
+ }
676
+ // #endregion
677
+ // #region external signer
678
+ /** @inheritdoc */
679
+ async signEcdsaMPCv2TssUsingExternalSigner(params, externalSignerMPCv2SigningRound1Generator, externalSignerMPCv2SigningRound2Generator, externalSignerMPCv2SigningRound3Generator, requestType = baseTypes_1.RequestType.tx) {
680
+ const { txRequest, reqId } = params;
681
+ let txRequestResolved;
682
+ // TODO(WP-2176): Add support for message signing
683
+ (0, assert_1.default)(requestType === baseTypes_1.RequestType.tx, 'Only transaction signing is supported for external signer, got: ' + requestType);
684
+ if (typeof txRequest === 'string') {
685
+ txRequestResolved = await (0, tss_1.getTxRequest)(this.bitgo, this.wallet.id(), txRequest, reqId);
686
+ }
687
+ else {
688
+ txRequestResolved = txRequest;
689
+ }
690
+ const bitgoPublicGpgKey = await this.pickBitgoPubGpgKeyForSigning(true, params.reqId, txRequestResolved.enterpriseId);
691
+ if (!bitgoPublicGpgKey) {
692
+ throw new Error('Missing BitGo GPG key for MPCv2');
693
+ }
694
+ // round 1
695
+ const { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey } = await externalSignerMPCv2SigningRound1Generator({ txRequest: txRequestResolved });
696
+ const round1TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound1], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
697
+ // round 2
698
+ const { signatureShareRound2, encryptedRound2Session } = await externalSignerMPCv2SigningRound2Generator({
699
+ txRequest: round1TxRequest,
700
+ encryptedRound1Session,
701
+ encryptedUserGpgPrvKey,
702
+ bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
703
+ });
704
+ const round2TxRequest = await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound2], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
705
+ (0, assert_1.default)(round2TxRequest.transactions && round2TxRequest.transactions[0].signatureShares, 'Missing signature shares in round 2 txRequest');
706
+ // round 3
707
+ const { signatureShareRound3 } = await externalSignerMPCv2SigningRound3Generator({
708
+ txRequest: round2TxRequest,
709
+ encryptedRound2Session,
710
+ encryptedUserGpgPrvKey,
711
+ bitgoPublicGpgKey: bitgoPublicGpgKey.armor(),
712
+ });
713
+ await (0, common_1.sendSignatureShareV2)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, [signatureShareRound3], requestType, this.baseCoin.getMPCAlgorithm(), userGpgPubKey, undefined, this.wallet.multisigTypeVersion(), reqId);
714
+ return (0, common_1.sendTxRequest)(this.bitgo, txRequestResolved.walletId, txRequestResolved.txRequestId, requestType, reqId);
715
+ }
716
+ async createOfflineRound1Share(params) {
717
+ const { prv, walletPassphrase, txRequest } = params;
718
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
719
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
720
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
721
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
722
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
723
+ const userSignerBroadcastMsg1 = await userSigner.init();
724
+ const signatureShareRound1 = await (0, ecdsaMPCv2_1.getSignatureShareRoundOne)(userSignerBroadcastMsg1, userGpgKey);
725
+ const session = userSigner.getSession();
726
+ const encryptedRound1Session = this.bitgo.encrypt({ input: session, password: walletPassphrase, adata });
727
+ const userGpgPubKey = userGpgKey.publicKey;
728
+ const encryptedUserGpgPrvKey = this.bitgo.encrypt({
729
+ input: userGpgKey.privateKey,
730
+ password: walletPassphrase,
731
+ adata,
732
+ });
733
+ return { signatureShareRound1, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey };
734
+ }
735
+ async createOfflineRound2Share(params) {
736
+ const { prv, walletPassphrase, encryptedUserGpgPrvKey, encryptedRound1Session, bitgoPublicGpgKey, txRequest } = params;
737
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
738
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
739
+ const { bitgoGpgKey, userGpgKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase);
740
+ const signatureShares = txRequest.transactions?.[0].signatureShares;
741
+ (0, assert_1.default)(signatureShares, 'Missing signature shares in round 1 txRequest');
742
+ const parsedBitGoToUserSigShareRoundOne = JSON.parse(signatureShares[signatureShares.length - 1].share);
743
+ if (parsedBitGoToUserSigShareRoundOne.type !== 'round1Output') {
744
+ throw new Error('Unexpected signature share response. Unable to parse data.');
745
+ }
746
+ const serializedBitGoToUserMessagesRound1 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundOne)(parsedBitGoToUserSigShareRoundOne, userGpgKey, bitgoGpgKey);
747
+ const round1Session = this.bitgo.decrypt({ input: encryptedRound1Session, password: walletPassphrase });
748
+ this.validateAdata(adata, encryptedRound1Session);
749
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
750
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
751
+ await userSigner.setSession(round1Session);
752
+ const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(serializedBitGoToUserMessagesRound1);
753
+ const userToBitGoMessagesRound2 = userSigner.handleIncomingMessages({
754
+ p2pMessages: [],
755
+ broadcastMessages: deserializedMessages.broadcastMessages,
756
+ });
757
+ const userToBitGoMessagesRound3 = userSigner.handleIncomingMessages({
758
+ p2pMessages: deserializedMessages.p2pMessages,
759
+ broadcastMessages: [],
760
+ });
761
+ const signatureShareRound2 = await (0, ecdsaMPCv2_1.getSignatureShareRoundTwo)(userToBitGoMessagesRound2, userToBitGoMessagesRound3, userGpgKey, bitgoGpgKey);
762
+ const session = userSigner.getSession();
763
+ const encryptedRound2Session = this.bitgo.encrypt({ input: session, password: walletPassphrase, adata });
764
+ return {
765
+ signatureShareRound2,
766
+ encryptedRound2Session,
767
+ };
768
+ }
769
+ async createOfflineRound3Share(params) {
770
+ const { prv, walletPassphrase, encryptedUserGpgPrvKey, encryptedRound2Session, bitgoPublicGpgKey, txRequest } = params;
771
+ (0, assert_1.default)(txRequest.transactions && txRequest.transactions.length === 1, 'Unable to find transactions in txRequest');
772
+ const { hashBuffer, derivationPath } = this.getHashStringAndDerivationPath(txRequest);
773
+ const adata = `${hashBuffer.toString('hex')}:${derivationPath}`;
774
+ const { bitgoGpgKey, userGpgKey } = await this.getBitgoAndUserGpgKeys(bitgoPublicGpgKey, encryptedUserGpgPrvKey, walletPassphrase);
775
+ const signatureShares = txRequest.transactions?.[0].signatureShares;
776
+ (0, assert_1.default)(signatureShares, 'Missing signature shares in round 2 txRequest');
777
+ const parsedBitGoToUserSigShareRoundTwo = JSON.parse(signatureShares[signatureShares.length - 1].share);
778
+ if (parsedBitGoToUserSigShareRoundTwo.type !== 'round2Output') {
779
+ throw new Error('Unexpected signature share response. Unable to parse data.');
780
+ }
781
+ const serializedBitGoToUserMessagesRound3 = await (0, ecdsaMPCv2_1.verifyBitGoMessagesAndSignaturesRoundTwo)(parsedBitGoToUserSigShareRoundTwo, userGpgKey, bitgoGpgKey);
782
+ const deserializedBitGoToUserMessagesRound3 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
783
+ p2pMessages: serializedBitGoToUserMessagesRound3.p2pMessages,
784
+ broadcastMessages: [],
785
+ });
786
+ const round2Session = this.bitgo.decrypt({ input: encryptedRound2Session, password: walletPassphrase });
787
+ this.validateAdata(adata, encryptedRound2Session);
788
+ const userKeyShare = buffer_1.Buffer.from(prv, 'base64');
789
+ const userSigner = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, derivationPath, hashBuffer);
790
+ await userSigner.setSession(round2Session);
791
+ const userToBitGoMessagesRound4 = userSigner.handleIncomingMessages({
792
+ p2pMessages: deserializedBitGoToUserMessagesRound3.p2pMessages,
793
+ broadcastMessages: [],
794
+ });
795
+ const signatureShareRound3 = await (0, ecdsaMPCv2_1.getSignatureShareRoundThree)(userToBitGoMessagesRound4, userGpgKey, bitgoGpgKey);
796
+ return { signatureShareRound3 };
797
+ }
798
+ }
799
+ exports.EcdsaMPCv2Utils = EcdsaMPCv2Utils;
800
+ /**
801
+ * Checks if the given key share, when decrypted, contains valid GG18 signing material.
802
+ *
803
+ * @param {string} keyShare - The encrypted key share string.
804
+ * @param {string|undefined} walletPassphrase - The passphrase used to decrypt the key share
805
+ * @returns {boolean} - Returns `true` if the decrypted data contains valid signing material, otherwise `false`.
806
+ */
807
+ function isGG18SigningMaterial(keyShare, walletPassphrase) {
808
+ const prv = sjcl.decrypt(walletPassphrase, keyShare);
809
+ try {
810
+ const signingMaterial = JSON.parse(prv);
811
+ return (signingMaterial.pShare &&
812
+ signingMaterial.bitgoNShare &&
813
+ (signingMaterial.userNShare || signingMaterial.backupNShare));
814
+ }
815
+ catch (error) {
816
+ return false;
817
+ }
818
+ }
819
+ /**
820
+ * Get the MPC v2 recovery key shares from the provided user and backup key shares.
821
+ * @param encryptedUserKey encrypted gg18 or MPCv2 user key
822
+ * @param encryptedBackupKey encrypted gg18 or MPCv2 backup key
823
+ * @param walletPassphrase password for user and backup key
824
+ * @returns MPC v2 recovery key shares
825
+ */
826
+ async function getMpcV2RecoveryKeyShares(encryptedUserKey, encryptedBackupKey, walletPassphrase) {
827
+ if (isGG18SigningMaterial(encryptedUserKey, walletPassphrase)) {
828
+ return getMpcV2RecoveryKeySharesFromGG18(encryptedUserKey, encryptedBackupKey, walletPassphrase);
829
+ }
830
+ return getMpcV2RecoveryKeySharesFromReducedKey(encryptedUserKey, encryptedBackupKey, walletPassphrase);
831
+ }
832
+ /**
833
+ * Signs a message hash using MPC v2 recovery key shares.
834
+ *
835
+ * @param {Buffer} messageHash
836
+ * @param {Buffer} userKeyShare
837
+ * @param {Buffer} backupKeyShare
838
+ * @param {string} commonKeyChain
839
+ * @returns {Promise<{ recid: number, r: string, s: string, y: string }>}
840
+ *
841
+ * @async
842
+ */
843
+ async function signRecoveryMpcV2(messageHash, userKeyShare, backupKeyShare, commonKeyChain) {
844
+ const userDsg = new sdk_lib_mpc_1.DklsDsg.Dsg(userKeyShare, 0, 'm/0', messageHash);
845
+ const backupDsg = new sdk_lib_mpc_1.DklsDsg.Dsg(backupKeyShare, 1, 'm/0', messageHash);
846
+ const signatureString = sdk_lib_mpc_1.DklsUtils.verifyAndConvertDklsSignature(messageHash, (await sdk_lib_mpc_1.DklsUtils.executeTillRound(5, userDsg, backupDsg)), commonKeyChain, 'm/0', undefined, false);
847
+ const sigParts = signatureString.split(':');
848
+ return {
849
+ recid: parseInt(sigParts[0], 10),
850
+ r: sigParts[1],
851
+ s: sigParts[2],
852
+ y: sigParts[3],
853
+ };
854
+ }
855
+ // #region private utils
856
+ /**
857
+ * Get the MPC v2 recovery key shares from the provided user and backup key shares.
858
+ * @param encryptedGG18UserKey encrypted gg18 user key
859
+ * @param encryptedGG18BackupKey encrypted gg18 backup key
860
+ * @param walletPassphrase password for user and backup key
861
+ * @returns MPC v2 recovery key shares
862
+ */
863
+ async function getMpcV2RecoveryKeySharesFromGG18(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase) {
864
+ const [userKeyCombined, backupKeyCombined] = getKeyCombinedFromTssKeyShares(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase);
865
+ const retrofitDataA = {
866
+ xShare: userKeyCombined.xShare,
867
+ };
868
+ const retrofitDataB = {
869
+ xShare: backupKeyCombined.xShare,
870
+ };
871
+ const [user, backup] = await sdk_lib_mpc_1.DklsUtils.generate2of2KeyShares(retrofitDataA, retrofitDataB);
872
+ const userKeyShare = user.getKeyShare();
873
+ const backupKeyShare = backup.getKeyShare();
874
+ return {
875
+ userKeyShare,
876
+ backupKeyShare,
877
+ commonKeyChain: sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupKeyShare),
878
+ };
879
+ }
880
+ /**
881
+ * Retrieves the MPC v2 recovery key shares from the provided user and backup key shares.
882
+ *
883
+ * @param {string} encryptedMPCv2UserKey
884
+ * @param {string} encryptedMPCv2BackupKey
885
+ * @param {string} [walletPassphrase] - The passphrase used to decrypt the key shares
886
+ * @returns {Promise<{ userKeyShare: KeyShare, backupKeyShare: KeyShare, commonKeyChain: string }>}
887
+ *
888
+ * @async
889
+ */
890
+ async function getMpcV2RecoveryKeySharesFromReducedKey(encryptedMPCv2UserKey, encryptedMPCv2BackupKey, walletPassphrase) {
891
+ const userCompressedPrv = buffer_1.Buffer.from(sjcl.decrypt(walletPassphrase, encryptedMPCv2UserKey), 'base64');
892
+ const bakcupCompressedPrv = buffer_1.Buffer.from(sjcl.decrypt(walletPassphrase, encryptedMPCv2BackupKey), 'base64');
893
+ const userPrvJSON = sdk_lib_mpc_1.DklsTypes.getDecodedReducedKeyShare(userCompressedPrv);
894
+ const backupPrvJSON = sdk_lib_mpc_1.DklsTypes.getDecodedReducedKeyShare(bakcupCompressedPrv);
895
+ const userKeyRetrofit = {
896
+ xShare: {
897
+ x: buffer_1.Buffer.from(userPrvJSON.prv).toString('hex'),
898
+ y: buffer_1.Buffer.from(userPrvJSON.pub).toString('hex'),
899
+ chaincode: buffer_1.Buffer.from(userPrvJSON.rootChainCode).toString('hex'),
900
+ },
901
+ xiList: userPrvJSON.xList.slice(0, 2),
902
+ };
903
+ const backupKeyRetrofit = {
904
+ xShare: {
905
+ x: buffer_1.Buffer.from(backupPrvJSON.prv).toString('hex'),
906
+ y: buffer_1.Buffer.from(backupPrvJSON.pub).toString('hex'),
907
+ chaincode: buffer_1.Buffer.from(backupPrvJSON.rootChainCode).toString('hex'),
908
+ },
909
+ xiList: backupPrvJSON.xList.slice(0, 2),
910
+ };
911
+ const [user, backup] = await sdk_lib_mpc_1.DklsUtils.generate2of2KeyShares(userKeyRetrofit, backupKeyRetrofit);
912
+ const userKeyShare = user.getKeyShare();
913
+ const backupKeyShare = backup.getKeyShare();
914
+ const commonKeyChain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userKeyShare);
915
+ return { userKeyShare, backupKeyShare, commonKeyChain };
916
+ }
917
+ /**
918
+ * Gets the combined key for GG18
919
+ * @param encryptedGG18UserKey encrypted GG18 user key
920
+ * @param encryptedGG18BackupKey encrypted GG18 backup key
921
+ * @param walletPassphrase wallet passphrase
922
+ * @returns key shares
923
+ */
924
+ function getKeyCombinedFromTssKeyShares(encryptedGG18UserKey, encryptedGG18BackupKey, walletPassphrase) {
925
+ let backupPrv;
926
+ let userPrv;
927
+ try {
928
+ backupPrv = sjcl.decrypt(walletPassphrase, encryptedGG18BackupKey);
929
+ userPrv = sjcl.decrypt(walletPassphrase, encryptedGG18UserKey);
930
+ }
931
+ catch (e) {
932
+ throw new Error(`Error decrypting backup keychain: ${e.message}`);
933
+ }
934
+ const userSigningMaterial = JSON.parse(userPrv);
935
+ const backupSigningMaterial = JSON.parse(backupPrv);
936
+ if (!userSigningMaterial.backupNShare) {
937
+ throw new Error('Invalid user key - missing backupNShare');
938
+ }
939
+ if (!backupSigningMaterial.userNShare) {
940
+ throw new Error('Invalid backup key - missing userNShare');
941
+ }
942
+ const MPC = new account_lib_1.Ecdsa();
943
+ const userKeyCombined = MPC.keyCombine(userSigningMaterial.pShare, [
944
+ userSigningMaterial.bitgoNShare,
945
+ userSigningMaterial.backupNShare,
946
+ ]);
947
+ const backupKeyCombined = MPC.keyCombine(backupSigningMaterial.pShare, [
948
+ backupSigningMaterial.userNShare,
949
+ backupSigningMaterial.bitgoNShare,
950
+ ]);
951
+ if (userKeyCombined.xShare.y !== backupKeyCombined.xShare.y ||
952
+ userKeyCombined.xShare.chaincode !== backupKeyCombined.xShare.chaincode) {
953
+ throw new Error('Common keychains do not match');
954
+ }
955
+ return [userKeyCombined, backupKeyCombined];
956
+ }
957
+ // #endregion
958
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvZWNkc2EvZWNkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUErdkNBLHNEQVlDO0FBU0QsOERBYUM7QUFhRCw4Q0E4QkM7QUE1MENELHlEQUE4RztBQUM5Ryx1REFBeUM7QUFDekMsb0RBQTRCO0FBQzVCLG1DQUFnQztBQUVoQyw2Q0FBNkM7QUFDN0Msb0RBQXNDO0FBQ3RDLDZDQUErQjtBQUUvQixzREFVNkI7QUFFN0IseURBQWdEO0FBR2hELHNDQUE4RDtBQUM5RCxnREFBMEU7QUFDMUUsNkNBQWdEO0FBQ2hELDhEQU11QztBQUN2Qyw0Q0FBMEQ7QUFFMUQscURBQXdEO0FBQ3hELDRDQVdzQjtBQUN0QixpQ0FBd0M7QUFDeEMscUVBQTZGO0FBQzdGLDREQUE4RjtBQUU5RixNQUFhLGVBQWdCLFNBQVEscUJBQWM7SUFDakQsa0JBQWtCO0lBQ2xCLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFLckI7UUFDQyxNQUFNLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRixNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsV0FBVyxDQUFDLENBQUM7UUFDekQsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFBLGlDQUFrQixFQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTNELGtFQUFrRTtRQUNsRSxvRUFBb0U7UUFDcEUsTUFBTSxpQkFBaUIsR0FBRyxDQUN4QixDQUFDLE1BQU0sSUFBSSxDQUFDLG9DQUFvQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENB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LENBQUM7QUFDOUMsQ0FBQztBQUVELGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBiaWdJbnRUb0J1ZmZlckJFLCBEa2xzQ29tbXMsIERrbHNEa2csIERrbHNEc2csIERrbHNUeXBlcywgRGtsc1V0aWxzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ2J1ZmZlcic7XG5pbXBvcnQgeyBIYXNoIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IE5vbkVtcHR5U3RyaW5nIH0gZnJvbSAnaW8tdHMtdHlwZXMnO1xuaW1wb3J0IGNyZWF0ZUtlY2Nha0hhc2ggZnJvbSAna2VjY2FrJztcbmltcG9ydCAqIGFzIHBncCBmcm9tICdvcGVucGdwJztcbmltcG9ydCB7IEtleWNoYWluc1RyaXBsZXQgfSBmcm9tICcuLi8uLi8uLi9iYXNlQ29pbic7XG5pbXBvcnQge1xuICBNUEN2MkJyb2FkY2FzdE1lc3NhZ2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQzUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuU3RhdGVFbnVtLFxuICBNUEN2MlAyUE1lc3NhZ2UsXG4gIE1QQ3YyUGFydHlGcm9tU3RyaW5nT3JOdW1iZXIsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG59IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuXG5pbXBvcnQgeyBFY2RzYSB9IGZyb20gJy4uLy4uLy4uLy4uL2FjY291bnQtbGliJztcbmltcG9ydCB7IEFkZEtleWNoYWluT3B0aW9ucywgS2V5Y2hhaW4sIEtleVR5cGUgfSBmcm9tICcuLi8uLi8uLi9rZXljaGFpbic7XG5pbXBvcnQgeyBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQgfSBmcm9tICcuLi8uLi8uLi9rZXljaGFpbi9pS2V5Y2hhaW5zJztcbmltcG9ydCB7IEVDRFNBTWV0aG9kVHlwZXMsIGdldFR4UmVxdWVzdCB9IGZyb20gJy4uLy4uLy4uL3Rzcyc7XG5pbXBvcnQgeyBzZW5kU2lnbmF0dXJlU2hhcmVWMiwgc2VuZFR4UmVxdWVzdCB9IGZyb20gJy4uLy4uLy4uL3Rzcy9jb21tb24nO1xuaW1wb3J0IHsgTVBDdjJQYXJ0aWVzRW51bSB9IGZyb20gJy4vdHlwZXNNUEN2Mic7XG5pbXBvcnQge1xuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lLFxuICBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUsXG4gIGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28sXG4gIHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRPbmUsXG4gIHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRUd28sXG59IGZyb20gJy4uLy4uLy4uL3Rzcy9lY2RzYS9lY2RzYU1QQ3YyJztcbmltcG9ydCB7IEludmFsaWRUcmFuc2FjdGlvbkVycm9yIH0gZnJvbSAnLi4vLi4vLi4vZXJyb3JzJztcbmltcG9ydCB7IEtleUNvbWJpbmVkIH0gZnJvbSAnLi4vLi4vLi4vdHNzL2VjZHNhL3R5cGVzJztcbmltcG9ydCB7IGdlbmVyYXRlR1BHS2V5UGFpciB9IGZyb20gJy4uLy4uL29wZW5ncGdVdGlscyc7XG5pbXBvcnQge1xuICBDdXN0b21NUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEN1c3RvbU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBSZXF1ZXN0VHlwZSxcbiAgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIFRTU1BhcmFtcyxcbiAgVFNTUGFyYW1zRm9yTWVzc2FnZSxcbiAgVFNTUGFyYW1zRm9yTWVzc2FnZVdpdGhQcnYsXG4gIFRTU1BhcmFtc1dpdGhQcnYsXG4gIFR4UmVxdWVzdCxcbn0gZnJvbSAnLi4vYmFzZVR5cGVzJztcbmltcG9ydCB7IEJhc2VFY2RzYVV0aWxzIH0gZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7IEVjZHNhTVBDdjJLZXlHZW5TZW5kRm4sIEtleUdlblNlbmRlckZvckVudGVycHJpc2UgfSBmcm9tICcuL2VjZHNhTVBDdjJLZXlHZW5TZW5kZXInO1xuaW1wb3J0IHsgZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZywgaXNCaXRnb01wY1B1YktleSB9IGZyb20gJy4uLy4uLy4uL3Rzcy9iaXRnb1B1YktleXMnO1xuXG5leHBvcnQgY2xhc3MgRWNkc2FNUEN2MlV0aWxzIGV4dGVuZHMgQmFzZUVjZHNhVXRpbHMge1xuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgYXN5bmMgY3JlYXRlS2V5Y2hhaW5zKHBhcmFtczoge1xuICAgIHBhc3NwaHJhc2U6IHN0cmluZztcbiAgICBlbnRlcnByaXNlOiBzdHJpbmc7XG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nO1xuICAgIHJldHJvZml0PzogRGVjcnlwdGVkUmV0cm9maXRQYXlsb2FkO1xuICB9KTogUHJvbWlzZTxLZXljaGFpbnNUcmlwbGV0PiB7XG4gICAgY29uc3QgeyB1c2VyU2Vzc2lvbiwgYmFja3VwU2Vzc2lvbiB9ID0gdGhpcy5nZXRVc2VyQW5kQmFja3VwU2Vzc2lvbigyLCAzLCBwYXJhbXMucmV0cm9maXQpO1xuICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ3NlY3AyNTZrMScpO1xuICAgIGNvbnN0IGJhY2t1cEdwZ0tleSA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignc2VjcDI1NmsxJyk7XG5cbiAgICAvLyBHZXQgdGhlIEJpdEdvIHB1YmxpYyBrZXkgYmFzZWQgb24gdXNlci9lbnRlcnByaXNlIGZlYXR1cmUgZmxhZ3NcbiAgICAvLyBJZiBpdCBkb2Vzbid0IHdvcmssIHVzZSB0aGUgZGVmYXVsdCBwdWJsaWMga2V5IGZyb20gdGhlIGNvbnN0YW50c1xuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5ID0gKFxuICAgICAgKGF3YWl0IHRoaXMuZ2V0Qml0Z29HcGdQdWJrZXlCYXNlZE9uRmVhdHVyZUZsYWdzKHBhcmFtcy5lbnRlcnByaXNlLCB0cnVlKSkgPz8gdGhpcy5iaXRnb01QQ3YyUHVibGljR3BnS2V5XG4gICAgKS5hcm1vcigpO1xuXG4gICAgaWYgKGVudlJlcXVpcmVzQml0Z29QdWJHcGdLZXlDb25maWcodGhpcy5iaXRnby5nZXRFbnYoKSkpIHtcbiAgICAgIC8vIEVuc3VyZSB0aGUgcHVibGljIGtleSBpcyBvbmUgb2YgdGhlIGV4cGVjdGVkIEJpdEdvIHB1YmxpYyBrZXlzIHdoZW4gaW4gdGVzdCBvciBwcm9kLlxuICAgICAgYXNzZXJ0KGlzQml0Z29NcGNQdWJLZXkoYml0Z29QdWJsaWNHcGdLZXksICdtcGN2MicpLCAnSW52YWxpZCBCaXRHbyBHUEcgcHVibGljIGtleScpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJHcGdQcnZLZXk6IERrbHNUeXBlcy5QYXJ0eUdwZ0tleSA9IHtcbiAgICAgIHBhcnR5SWQ6IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgIGdwZ0tleTogdXNlckdwZ0tleS5wcml2YXRlS2V5LFxuICAgIH07XG4gICAgY29uc3QgYmFja3VwR3BnUHJ2S2V5OiBEa2xzVHlwZXMuUGFydHlHcGdLZXkgPSB7XG4gICAgICBwYXJ0eUlkOiBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCxcbiAgICAgIGdwZ0tleTogYmFja3VwR3BnS2V5LnByaXZhdGVLZXksXG4gICAgfTtcbiAgICBjb25zdCBiaXRnb0dwZ1B1YktleTogRGtsc1R5cGVzLlBhcnR5R3BnS2V5ID0ge1xuICAgICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgIGdwZ0tleTogYml0Z29QdWJsaWNHcGdLZXksXG4gICAgfTtcblxuICAgIC8vICNyZWdpb24gcm91bmQgMVxuICAgIGNvbnN0IHVzZXJSb3VuZDFCcm9hZGNhc3RNc2cgPSBhd2FpdCB1c2VyU2Vzc2lvbi5pbml0RGtnKCk7XG4gICAgY29uc3QgYmFja3VwUm91bmQxQnJvYWRjYXN0TXNnID0gYXdhaXQgYmFja3VwU2Vzc2lvbi5pbml0RGtnKCk7XG5cbiAgICBjb25zdCByb3VuZDFTZXJpYWxpemVkTWVzc2FnZXMgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt1c2VyUm91bmQxQnJvYWRjYXN0TXNnLCBiYWNrdXBSb3VuZDFCcm9hZGNhc3RNc2ddLFxuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgIHJvdW5kMVNlcmlhbGl6ZWRNZXNzYWdlcyxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleSwgYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25JZCwgYml0Z29Nc2cxLCBiaXRnb1RvQmFja3VwTXNnMiwgYml0Z29Ub1VzZXJNc2cyIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQxKFxuICAgICAgcGFyYW1zLmVudGVycHJpc2UsXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIGJhY2t1cEdwZ0tleS5wdWJsaWNLZXksXG4gICAgICBwYXJhbXMucmV0cm9maXQ/LndhbGxldElkXG4gICAgICAgID8ge1xuICAgICAgICAgICAgLi4ucm91bmQxTWVzc2FnZXMsXG4gICAgICAgICAgICB3YWxsZXRJZDogcGFyYW1zLnJldHJvZml0LndhbGxldElkLFxuICAgICAgICAgIH1cbiAgICAgICAgOiByb3VuZDFNZXNzYWdlc1xuICAgICk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiByb3VuZCAyXG4gICAgY29uc3QgYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFtdLCBicm9hZGNhc3RNZXNzYWdlczogW3RoaXMuZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJpdGdvTXNnMSldIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXksIGJhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnID0gYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnLCAnQml0R28gbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDJQMlBNZXNzYWdlcyA9IHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtEa2xzVHlwZXMuZGVzZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlKGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnKSwgYmFja3VwUm91bmQxQnJvYWRjYXN0TXNnXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJUb0JpdGdvTXNnMiA9IHVzZXJSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CaXRnb01zZzIsICdVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMiA9IERrbHNUeXBlcy5zZXJpYWxpemVQMlBNZXNzYWdlKHVzZXJUb0JpdGdvTXNnMik7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDJQMlBNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW3VzZXJSb3VuZDFCcm9hZGNhc3RNc2csIERrbHNUeXBlcy5kZXNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UoYml0Z29Sb3VuZDFCcm9hZGNhc3RNc2cpXSxcbiAgICB9KTtcbiAgICBjb25zdCBzZXJpYWxpemVkQmFja3VwVG9CaXRnb01zZzIgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoYmFja3VwUm91bmQyUDJQTWVzc2FnZXMpLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2cyLCAnQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCByb3VuZDJNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICB7IHAycE1lc3NhZ2VzOiBbc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMiwgc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2cyXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXksIGJhY2t1cEdwZ1BydktleV1cbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWRSb3VuZDIsXG4gICAgICBiaXRnb0NvbW1pdG1lbnQyLFxuICAgICAgYml0Z29Ub1VzZXJNc2czLFxuICAgICAgYml0Z29Ub0JhY2t1cE1zZzMsXG4gICAgfSA9IGF3YWl0IHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDIocGFyYW1zLmVudGVycHJpc2UsIHNlc3Npb25JZCwgcm91bmQyTWVzc2FnZXMpO1xuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24gcm91bmQgM1xuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMiwgJ1JvdW5kIDEgYW5kIDIgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDJNc2dzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgeyBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvVXNlck1zZzIpXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDJNc2cgPSBkZWNyeXB0ZWRCaXRnb1RvVXNlclJvdW5kMk1zZ3MucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR08gJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJpdGdvVG9Vc2VyUm91bmQyTXNnLCAnQml0R28gdG8gVXNlciBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IGJpdGdvVG9Vc2VyUm91bmQyTXNnID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZShzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDJNc2cpO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub0JhY2t1cFJvdW5kMk1zZyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFt0aGlzLmZvcm1hdFAyUE1lc3NhZ2UoYml0Z29Ub0JhY2t1cE1zZzIpXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFtdIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnID0gZGVjcnlwdGVkQml0Z29Ub0JhY2t1cFJvdW5kMk1zZy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnLCAnQml0R28gdG8gQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub0JhY2t1cFJvdW5kMk1zZyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2Uoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDJNc2cpO1xuXG4gICAgY29uc3QgdXNlclRvQmFja3VwTXNnMiA9IHVzZXJSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcbiAgICBhc3NlcnQodXNlclRvQmFja3VwTXNnMiwgJ1VzZXIgdG8gQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCBiYWNrdXBUb1VzZXJNc2cyID0gYmFja3VwUm91bmQyUDJQTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFRvVXNlck1zZzIsICdCYWNrdXAgdG8gVXNlciBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuXG4gICAgY29uc3QgdXNlclJvdW5kM01lc3NhZ2VzID0gdXNlclNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgICBwMnBNZXNzYWdlczogW2JpdGdvVG9Vc2VyUm91bmQyTXNnLCBiYWNrdXBUb1VzZXJNc2cyXSxcbiAgICB9KTtcbiAgICBjb25zdCB1c2VyVG9CYWNrdXBNc2czID0gdXNlclJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CYWNrdXBNc2czLCAnVXNlciB0byBCYWNrdXAgbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCB1c2VyVG9CaXRnb01zZzMgPSB1c2VyUm91bmQzTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQodXNlclRvQml0Z29Nc2czLCAnVXNlciB0byBCaXRnbyBtZXNzYWdlIDMgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRVc2VyVG9CaXRnb01zZzMgPSBEa2xzVHlwZXMuc2VyaWFsaXplUDJQTWVzc2FnZSh1c2VyVG9CaXRnb01zZzMpO1xuXG4gICAgY29uc3QgYmFja3VwUm91bmQzTWVzc2FnZXMgPSBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgcDJwTWVzc2FnZXM6IFtiaXRnb1RvQmFja3VwUm91bmQyTXNnLCB1c2VyVG9CYWNrdXBNc2cyXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJhY2t1cFRvVXNlck1zZzMgPSBiYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBhc3NlcnQoYmFja3VwVG9Vc2VyTXNnMywgJ0JhY2t1cCB0byBVc2VyIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYmFja3VwVG9CaXRnb01zZzMgPSBiYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFRvQml0Z29Nc2czLCAnQmFja3VwIHRvIEJpdGdvIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2czID0gRGtsc1R5cGVzLnNlcmlhbGl6ZVAyUE1lc3NhZ2UoYmFja3VwVG9CaXRnb01zZzMpO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDNNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLCBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvVXNlck1zZzMsIGJpdGdvQ29tbWl0bWVudDIpXSB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdGdvVG9Vc2VyUm91bmQzTXNnID0gZGVjcnlwdGVkQml0Z29Ub1VzZXJSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGFzc2VydChzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDNNc2csICdCaXRHbyB0byBVc2VyIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub1VzZXJSb3VuZDNNc2cgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVQMlBNZXNzYWdlKHNlcmlhbGl6ZWRCaXRnb1RvVXNlclJvdW5kM01zZyk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1RvQmFja3VwUm91bmQzTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICB7IGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSwgcDJwTWVzc2FnZXM6IFt0aGlzLmZvcm1hdFAyUE1lc3NhZ2UoYml0Z29Ub0JhY2t1cE1zZzMsIGJpdGdvQ29tbWl0bWVudDIpXSB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFtiYWNrdXBHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQml0Z29Ub0JhY2t1cFJvdW5kM01zZyA9IGRlY3J5cHRlZEJpdGdvVG9CYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQzTXNnLCAnQml0R28gdG8gQmFja3VwIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub0JhY2t1cFJvdW5kM01zZyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2Uoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDNNc2cpO1xuXG4gICAgY29uc3QgdXNlclJvdW5kNE1lc3NhZ2VzID0gdXNlclNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW2JhY2t1cFRvVXNlck1zZzMsIGJpdGdvVG9Vc2VyUm91bmQzTXNnXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDRCcm9hZGNhc3RNc2cgPSB1c2VyUm91bmQ0TWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIGFzc2VydCh1c2VyUm91bmQ0QnJvYWRjYXN0TXNnLCAnVXNlciBtZXNzYWdlIDQgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRVc2VyUm91bmQ0QnJvYWRjYXN0TXNnID0gRGtsc1R5cGVzLnNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UodXNlclJvdW5kNEJyb2FkY2FzdE1zZyk7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDRNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW3VzZXJUb0JhY2t1cE1zZzMsIGJpdGdvVG9CYWNrdXBSb3VuZDNNc2ddLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZyA9IGJhY2t1cFJvdW5kNE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZywgJ0JhY2t1cCBtZXNzYWdlIDQgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2cgPSBEa2xzVHlwZXMuc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZShiYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2cpO1xuXG4gICAgY29uc3Qgcm91bmQzTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAge1xuICAgICAgICBwMnBNZXNzYWdlczogW3NlcmlhbGl6ZWRVc2VyVG9CaXRnb01zZzMsIHNlcmlhbGl6ZWRCYWNrdXBUb0JpdGdvTXNnM10sXG4gICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbc2VyaWFsaXplZFVzZXJSb3VuZDRCcm9hZGNhc3RNc2csIHNlcmlhbGl6ZWRCYWNrdXBSb3VuZDRCcm9hZGNhc3RNc2ddLFxuICAgICAgfSxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleSwgYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG5cbiAgICBjb25zdCB7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMyxcbiAgICAgIGJpdGdvTXNnNCxcbiAgICAgIGNvbW1vbktleWNoYWluOiBiaXRnb0NvbW1vbktleWNoYWluLFxuICAgIH0gPSBhd2FpdCB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQzKHBhcmFtcy5lbnRlcnByaXNlLCBzZXNzaW9uSWQsIHJvdW5kM01lc3NhZ2VzKTtcblxuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24ga2V5Y2hhaW4gY3JlYXRpb25cbiAgICBhc3NlcnQuZXF1YWwoc2Vzc2lvbklkLCBzZXNzaW9uSWRSb3VuZDMsICdSb3VuZCAxIGFuZCAzIFNlc3Npb24gSURzIGRvIG5vdCBtYXRjaCcpO1xuICAgIGNvbnN0IGJpdGdvUm91bmQ0QnJvYWRjYXN0TWVzc2FnZXMgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhcbiAgICAgIGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgeyBwMnBNZXNzYWdlczogW10sIGJyb2FkY2FzdE1lc3NhZ2VzOiBbdGhpcy5mb3JtYXRCaXRnb0Jyb2FkY2FzdE1lc3NhZ2UoYml0Z29Nc2c0KV0gfSxcbiAgICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgICAgW11cbiAgICAgIClcbiAgICApLmJyb2FkY2FzdE1lc3NhZ2VzO1xuICAgIGNvbnN0IGJpdGdvUm91bmQ0QnJvYWRjYXN0TXNnID0gYml0Z29Sb3VuZDRCcm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuXG4gICAgYXNzZXJ0KGJpdGdvUm91bmQ0QnJvYWRjYXN0TXNnLCAnQml0R28gbWVzc2FnZSA0IG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICB1c2VyU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbYml0Z29Sb3VuZDRCcm9hZGNhc3RNc2csIGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZ10sXG4gICAgfSk7XG5cbiAgICBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtiaXRnb1JvdW5kNEJyb2FkY2FzdE1zZywgdXNlclJvdW5kNEJyb2FkY2FzdE1zZ10sXG4gICAgfSk7XG5cbiAgICBjb25zdCB1c2VyUHJpdmF0ZU1hdGVyaWFsID0gdXNlclNlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBQcml2YXRlTWF0ZXJpYWwgPSBiYWNrdXBTZXNzaW9uLmdldEtleVNoYXJlKCk7XG4gICAgY29uc3QgdXNlclJlZHVjZWRQcml2YXRlTWF0ZXJpYWwgPSB1c2VyU2Vzc2lvbi5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsID0gYmFja3VwU2Vzc2lvbi5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcblxuICAgIGNvbnN0IHVzZXJDb21tb25LZXljaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbih1c2VyUHJpdmF0ZU1hdGVyaWFsKTtcbiAgICBjb25zdCBiYWNrdXBDb21tb25LZXljaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbihiYWNrdXBQcml2YXRlTWF0ZXJpYWwpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKGJpdGdvQ29tbW9uS2V5Y2hhaW4sIHVzZXJDb21tb25LZXljaGFpbiwgJ1VzZXIgYW5kIEJpdGdvIENvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyk7XG4gICAgYXNzZXJ0LmVxdWFsKGJpdGdvQ29tbW9uS2V5Y2hhaW4sIGJhY2t1cENvbW1vbktleWNoYWluLCAnQmFja3VwIGFuZCBCaXRnbyBDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpO1xuXG4gICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IHRoaXMuYWRkVXNlcktleWNoYWluKFxuICAgICAgYml0Z29Db21tb25LZXljaGFpbixcbiAgICAgIHVzZXJQcml2YXRlTWF0ZXJpYWwsXG4gICAgICB1c2VyUmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgcGFyYW1zLm9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZVxuICAgICk7XG4gICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gdGhpcy5hZGRCYWNrdXBLZXljaGFpbihcbiAgICAgIGJpdGdvQ29tbW9uS2V5Y2hhaW4sXG4gICAgICBiYWNrdXBQcml2YXRlTWF0ZXJpYWwsXG4gICAgICBiYWNrdXBSZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcGFyYW1zLnBhc3NwaHJhc2UsXG4gICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlXG4gICAgKTtcbiAgICBjb25zdCBiaXRnb0tleWNoYWluUHJvbWlzZSA9IHRoaXMuYWRkQml0Z29LZXljaGFpbihiaXRnb0NvbW1vbktleWNoYWluKTtcblxuICAgIGNvbnN0IFt1c2VyS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluLCBiaXRnb0tleWNoYWluXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIHVzZXJLZXljaGFpblByb21pc2UsXG4gICAgICBiYWNrdXBLZXljaGFpblByb21pc2UsXG4gICAgICBiaXRnb0tleWNoYWluUHJvbWlzZSxcbiAgICBdKTtcbiAgICAvLyAjZW5kcmVnaW9uXG5cbiAgICByZXR1cm4ge1xuICAgICAgdXNlcktleWNoYWluLFxuICAgICAgYmFja3VwS2V5Y2hhaW4sXG4gICAgICBiaXRnb0tleWNoYWluLFxuICAgIH07XG4gIH1cblxuICAvLyAjcmVnaW9uIGtleWNoYWluIHV0aWxzXG4gIGFzeW5jIGNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgcGFydGljaXBhbnRJbmRleDogTVBDdjJQYXJ0eUZyb21TdHJpbmdPck51bWJlcixcbiAgICBjb21tb25LZXljaGFpbjogc3RyaW5nLFxuICAgIHByaXZhdGVNYXRlcmlhbD86IEJ1ZmZlcixcbiAgICByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsPzogQnVmZmVyLFxuICAgIHBhc3NwaHJhc2U/OiBzdHJpbmcsXG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICBsZXQgc291cmNlOiBzdHJpbmc7XG4gICAgbGV0IGVuY3J5cHRlZFBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGxldCByZWR1Y2VkRW5jcnlwdGVkUHJ2OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgc3dpdGNoIChwYXJ0aWNpcGFudEluZGV4KSB7XG4gICAgICBjYXNlIE1QQ3YyUGFydGllc0VudW0uVVNFUjpcbiAgICAgIGNhc2UgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVA6XG4gICAgICAgIHNvdXJjZSA9IHBhcnRpY2lwYW50SW5kZXggPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiA/ICd1c2VyJyA6ICdiYWNrdXAnO1xuICAgICAgICBhc3NlcnQocHJpdmF0ZU1hdGVyaWFsLCBgUHJpdmF0ZSBtYXRlcmlhbCBpcyByZXF1aXJlZCBmb3IgJHtzb3VyY2V9IGtleWNoYWluYCk7XG4gICAgICAgIGFzc2VydChyZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLCBgUmVkdWNlZCBwcml2YXRlIG1hdGVyaWFsIGlzIHJlcXVpcmVkIGZvciAke3NvdXJjZX0ga2V5Y2hhaW5gKTtcbiAgICAgICAgYXNzZXJ0KHBhc3NwaHJhc2UsIGBQYXNzcGhyYXNlIGlzIHJlcXVpcmVkIGZvciAke3NvdXJjZX0ga2V5Y2hhaW5gKTtcbiAgICAgICAgZW5jcnlwdGVkUHJ2ID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogcHJpdmF0ZU1hdGVyaWFsLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgICAgICBwYXNzd29yZDogcGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEVuY3J5cHRzIHRoZSBDQk9SLWVuY29kZWQgUmVkdWNlZEtleVNoYXJlICh3aGljaCBjb250YWlucyB0aGUgcGFydHkncyBwcml2YXRlXG4gICAgICAgIC8vIHNjYWxhciBzX2kpIHdpdGggdGhlIHdhbGxldCBwYXNzcGhyYXNlLiBUaGUgcmVzdWx0IGlzIHN0b3JlZCBhcyByZWR1Y2VkRW5jcnlwdGVkUHJ2XG4gICAgICAgIC8vIG9uIHRoZSBrZXkgY2FyZCBRUiBjb2RlIGFuZCByZXByZXNlbnRzIGEgc2Vjb25kIGNvcHkgb2YgcHJpdmF0ZSBrZXkgbWF0ZXJpYWxcbiAgICAgICAgLy8gYmV5b25kIHRoZSBzZXJ2ZXItc3RvcmVkIGVuY3J5cHRlZFBydi5cbiAgICAgICAgcmVkdWNlZEVuY3J5cHRlZFBydiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgLy8gQnVmZmVyLnRvU3RyaW5nKCdiYXNlNjQnKSBjYW4gbm90IGJlIHVzZWQgaGVyZSBhcyBpdCBkb2VzIG5vdCB3b3JrIG9uIHRoZSBicm93c2VyLlxuICAgICAgICAgIC8vIFRoZSBicm93c2VyIGRlYWxzIHdpdGggYSBCdWZmZXIgYXMgVWludDhBcnJheSwgdGhlcmVmb3JlIGluIHRoZSBicm93c2VyIC50b1N0cmluZygnYmFzZTY0JykganVzdCBjcmVhdGVzIGEgY29tbWEgc2VwZXJhdGVkIHN0cmluZyBvZiB0aGUgYXJyYXkgdmFsdWVzLlxuICAgICAgICAgIGlucHV0OiBidG9hKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgQXJyYXkuZnJvbShuZXcgVWludDhBcnJheShyZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsKSkpKSxcbiAgICAgICAgICBwYXNzd29yZDogcGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPOlxuICAgICAgICBzb3VyY2UgPSAnYml0Z28nO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYXJ0aWNpcGFudCBpbmRleCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlY2lwaWVudEtleWNoYWluUGFyYW1zOiBBZGRLZXljaGFpbk9wdGlvbnMgPSB7XG4gICAgICBzb3VyY2UsXG4gICAgICBrZXlUeXBlOiAndHNzJyBhcyBLZXlUeXBlLFxuICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICBpc01QQ3YyOiB0cnVlLFxuICAgIH07XG5cbiAgICBjb25zdCBrZXljaGFpbnMgPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgIHJldHVybiB7IC4uLihhd2FpdCBrZXljaGFpbnMuYWRkKHJlY2lwaWVudEtleWNoYWluUGFyYW1zKSksIHJlZHVjZWRFbmNyeXB0ZWRQcnY6IHJlZHVjZWRFbmNyeXB0ZWRQcnYgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIFVzZXIgb3IgQmFja3VwIE1QQ3YxIFNpZ25pbmdNYXRlcmlhbCB0byBSZXRyb2ZpdERhdGEgbmVlZGVkIGJ5IE1QQ3YyIERLRy5cbiAgICpcbiAgICogQHBhcmFtIGRlY3J5cHRlZEtleXNoYXJlIC0gTVBDdjEgZGVjcnlwdGVkIHNpZ25pbmcgbWF0ZXJpYWwgZm9yIHVzZXIgb3IgYmFja3VwIGFzIGEganNvbi5zdHJpbmdpZnkgc3RyaW5nIGFuZCBiaXRnbydzIEJpZyBTaS5cbiAgICogQHBhcmFtIHBhcnR5SWQgLSBUaGUgcGFydHkgSUQgb2YgdGhlIE1QQ3YxIGtleXNoYXJlLlxuICAgKiBAcmV0dXJucyBUaGUgcmV0cm9maXQgZGF0YSBuZWVkZWQgdG8gc3RhcnQgYW4gTVBDdjIgREtHIHNlc3Npb24uXG4gICAqIEBkZXByZWNhdGVkXG4gICAqL1xuICBzdGF0aWMgZ2V0S2V5RGF0YUZvclJldHJvZml0KFxuICAgIGRlY3J5cHRlZEtleXNoYXJlOiBzdHJpbmcsXG4gICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgfCBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgKTogRGtsc1R5cGVzLlJldHJvZml0RGF0YSB7XG4gICAgY29uc3QgbXBjID0gbmV3IEVjZHNhKCk7XG4gICAgY29uc3QgeGlMaXN0ID0gW1xuICAgICAgQXJyYXkuZnJvbShiaWdJbnRUb0J1ZmZlckJFKEJpZ0ludCgxKSwgMzIpKSxcbiAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMiksIDMyKSksXG4gICAgICBBcnJheS5mcm9tKGJpZ0ludFRvQnVmZmVyQkUoQmlnSW50KDMpLCAzMikpLFxuICAgIF07XG4gICAgcmV0dXJuIEVjZHNhTVBDdjJVdGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleSh7XG4gICAgICBtcGN2MVBhcnR5S2V5U2hhcmU6IGRlY3J5cHRlZEtleXNoYXJlLFxuICAgICAgbXBjdjFQYXJ0eUluZGV4OiBwYXJ0eUlkID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgPyAxIDogMixcbiAgICAgIHhpTGlzdCxcbiAgICAgIG1wYyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB1c2VyIGFuZCBiYWNrdXAgTVBDdjEgU2lnbmluZ01hdGVyaWFsIHRvIFJldHJvZml0RGF0YSBuZWVkZWQgYnkgTVBDdjIgREtHLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gTVBDdjEgZGVjcnlwdGVkIHNpZ25pbmcgbWF0ZXJpYWwgZm9yIHVzZXIgYW5kIGJhY2t1cCBhcyBhIGpzb24uc3RyaW5naWZ5IHN0cmluZyBhbmQgYml0Z28ncyBCaWcgU2kuXG4gICAqIEByZXR1cm5zIHt7IG1wY3YyVXNlcktleVNoYXJlOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhOyBtcGN2MkJha2N1cEtleVNoYXJlOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhIH19IC0gdGhlIHJldHJvZml0IGRhdGEgbmVlZGVkIHRvIHN0YXJ0IGFuIE1QQ3YyIERLRyBzZXNzaW9uLlxuICAgKi9cbiAgZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHBhcmFtczogeyBtcGN2MVVzZXJLZXlTaGFyZTogc3RyaW5nOyBtcGN2MUJhY2t1cEtleVNoYXJlOiBzdHJpbmcgfSk6IHtcbiAgICBtcGN2MlVzZXJLZXlTaGFyZTogRGtsc1R5cGVzLlJldHJvZml0RGF0YTtcbiAgICBtcGN2MkJhY2t1cEtleVNoYXJlOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhO1xuICB9IHtcbiAgICBjb25zdCBtcGMgPSBuZXcgRWNkc2EoKTtcbiAgICBjb25zdCB4aUxpc3QgPSBbXG4gICAgICBBcnJheS5mcm9tKGJpZ0ludFRvQnVmZmVyQkUoQmlnSW50KDEpLCAzMikpLFxuICAgICAgQXJyYXkuZnJvbShiaWdJbnRUb0J1ZmZlckJFKEJpZ0ludCgyKSwgMzIpKSxcbiAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMyksIDMyKSksXG4gICAgXTtcbiAgICByZXR1cm4ge1xuICAgICAgbXBjdjJVc2VyS2V5U2hhcmU6IEVjZHNhTVBDdjJVdGlscy5nZXRNcGNWMlJldHJvZml0RGF0YUZyb21NcGNWMUtleSh7XG4gICAgICAgIG1wY3YxUGFydHlLZXlTaGFyZTogcGFyYW1zLm1wY3YxVXNlcktleVNoYXJlLFxuICAgICAgICBtcGN2MVBhcnR5SW5kZXg6IDEsXG4gICAgICAgIHhpTGlzdCxcbiAgICAgICAgbXBjLFxuICAgICAgfSksXG4gICAgICBtcGN2MkJhY2t1cEtleVNoYXJlOiBFY2RzYU1QQ3YyVXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXkoe1xuICAgICAgICBtcGN2MVBhcnR5S2V5U2hhcmU6IHBhcmFtcy5tcGN2MUJhY2t1cEtleVNoYXJlLFxuICAgICAgICBtcGN2MVBhcnR5SW5kZXg6IDIsXG4gICAgICAgIHhpTGlzdCxcbiAgICAgICAgbXBjLFxuICAgICAgfSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgcmV0cm9maXQgZGF0YSBmcm9tIE1QQ3YxIGtleSBzaGFyZS5cbiAgICogQHBhcmFtIG1wY3YxUGFydHlLZXlTaGFyZVxuICAgKiBAcGFyYW0gbXBjdjFQYXJ0eUluZGV4XG4gICAqIEBwYXJhbSB4aUxpc3RcbiAgICogQHBhcmFtIG1wY1xuICAgKiBAZGVwcmVjYXRlZFxuICAgKi9cbiAgc3RhdGljIGdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5KHtcbiAgICBtcGN2MVBhcnR5S2V5U2hhcmUsXG4gICAgbXBjdjFQYXJ0eUluZGV4LFxuICAgIHhpTGlzdCxcbiAgICBtcGMsXG4gIH06IHtcbiAgICBtcGN2MVBhcnR5S2V5U2hhcmU6IHN0cmluZztcbiAgICBtcGN2MVBhcnR5SW5kZXg6IG51bWJlcjtcbiAgICB4aUxpc3Q6IG51bWJlcltdW107XG4gICAgbXBjOiBFY2RzYTtcbiAgfSk6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEge1xuICAgIGNvbnN0IHNpZ25pbmdNYXRlcmlhbDogRUNEU0FNZXRob2RUeXBlcy5TaWduaW5nTWF0ZXJpYWwgPSBKU09OLnBhcnNlKG1wY3YxUGFydHlLZXlTaGFyZSk7XG4gICAgbGV0IGtleUNvbWJpbmVkOiBLZXlDb21iaW5lZCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBzd2l0Y2ggKG1wY3YxUGFydHlJbmRleCkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICBhc3NlcnQoc2lnbmluZ01hdGVyaWFsLmJhY2t1cE5TaGFyZSwgJ1VzZXIgTVBDdjEga2V5IG1hdGVyaWFsIHNob3VsZCBoYXZlIGJhY2t1cCBOU2hhcmUuJyk7XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsICdCaXRHbyBNUEN2MSBrZXkgbWF0ZXJpYWwgc2hvdWxkIGhhdmUgdXNlciBOU2hhcmUuJyk7XG4gICAgICAgIGtleUNvbWJpbmVkID0gbXBjLmtleUNvbWJpbmUoc2lnbmluZ01hdGVyaWFsLnBTaGFyZSwgW1xuICAgICAgICAgIHNpZ25pbmdNYXRlcmlhbC5iYWNrdXBOU2hhcmUsXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLmJpdGdvTlNoYXJlLFxuICAgICAgICBdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSwgJ1VzZXIgTVBDdjEga2V5IG1hdGVyaWFsIHNob3VsZCBoYXZlIGJhY2t1cCBOU2hhcmUuJyk7XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmUsICdCaXRHbyBNUEN2MSBrZXkgbWF0ZXJpYWwgc2hvdWxkIGhhdmUgdXNlciBOU2hhcmUuJyk7XG4gICAgICAgIGtleUNvbWJpbmVkID0gbXBjLmtleUNvbWJpbmUoc2lnbmluZ01hdGVyaWFsLnBTaGFyZSwgW3NpZ25pbmdNYXRlcmlhbC51c2VyTlNoYXJlLCBzaWduaW5nTWF0ZXJpYWwuYml0Z29OU2hhcmVdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwudXNlck5TaGFyZSwgJ1VzZXIgTVBDdjEga2V5IG1hdGVyaWFsIHNob3VsZCBoYXZlIGJhY2t1cCBOU2hhcmUuJyk7XG4gICAgICAgIGFzc2VydChzaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlLCAnQmFja3VwIE1QQ3YxIGtleSBtYXRlcmlhbCBzaG91bGQgaGF2ZSB1c2VyIE5TaGFyZS4nKTtcbiAgICAgICAga2V5Q29tYmluZWQgPSBtcGMua2V5Q29tYmluZShzaWduaW5nTWF0ZXJpYWwucFNoYXJlLCBbXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUsXG4gICAgICAgICAgc2lnbmluZ01hdGVyaWFsLmJhY2t1cE5TaGFyZSxcbiAgICAgICAgXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhcnRpY2lwYW50IGluZGV4Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB4U2hhcmU6IGtleUNvbWJpbmVkLnhTaGFyZSxcbiAgICAgIHhpTGlzdDogeGlMaXN0LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZFVzZXJLZXljaGFpbihcbiAgICBjb21tb25LZXljaGFpbjogc3RyaW5nLFxuICAgIHByaXZhdGVNYXRlcmlhbDogQnVmZmVyLFxuICAgIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWw6IEJ1ZmZlcixcbiAgICBwYXNzcGhyYXNlOiBzdHJpbmcsXG4gICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlPzogc3RyaW5nXG4gICk6IFByb21pc2U8S2V5Y2hhaW4+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICBwcml2YXRlTWF0ZXJpYWwsXG4gICAgICByZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcGFzc3BocmFzZSxcbiAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZEJhY2t1cEtleWNoYWluKFxuICAgIGNvbW1vbktleWNoYWluOiBzdHJpbmcsXG4gICAgcHJpdmF0ZU1hdGVyaWFsOiBCdWZmZXIsXG4gICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbDogQnVmZmVyLFxuICAgIHBhc3NwaHJhc2U6IHN0cmluZyxcbiAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxLZXljaGFpbj4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCxcbiAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgcHJpdmF0ZU1hdGVyaWFsLFxuICAgICAgcmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHBhc3NwaHJhc2UsXG4gICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGVcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRVc2VyQW5kQmFja3VwU2Vzc2lvbihtOiBudW1iZXIsIG46IG51bWJlciwgcmV0cm9maXQ/OiBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQpIHtcbiAgICBpZiAocmV0cm9maXQpIHtcbiAgICAgIGNvbnN0IHJldHJvZml0RGF0YSA9IHRoaXMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHtcbiAgICAgICAgbXBjdjFVc2VyS2V5U2hhcmU6IHJldHJvZml0LmRlY3J5cHRlZFVzZXJLZXksXG4gICAgICAgIG1wY3YxQmFja3VwS2V5U2hhcmU6IHJldHJvZml0LmRlY3J5cHRlZEJhY2t1cEtleSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB1c2VyU2Vzc2lvbiA9IG5ldyBEa2xzRGtnLkRrZyhuLCBtLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsIHVuZGVmaW5lZCwgcmV0cm9maXREYXRhLm1wY3YyVXNlcktleVNoYXJlKTtcbiAgICAgIGNvbnN0IGJhY2t1cFNlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2cobiwgbSwgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsIHVuZGVmaW5lZCwgcmV0cm9maXREYXRhLm1wY3YyQmFja3VwS2V5U2hhcmUpO1xuXG4gICAgICByZXR1cm4geyB1c2VyU2Vzc2lvbiwgYmFja3VwU2Vzc2lvbiB9O1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJTZXNzaW9uID0gbmV3IERrbHNEa2cuRGtnKG4sIG0sIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgY29uc3QgYmFja3VwU2Vzc2lvbiA9IG5ldyBEa2xzRGtnLkRrZyhuLCBtLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG5cbiAgICByZXR1cm4geyB1c2VyU2Vzc2lvbiwgYmFja3VwU2Vzc2lvbiB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBhZGRCaXRnb0tleWNoYWluKGNvbW1vbktleWNoYWluOiBzdHJpbmcpOiBQcm9taXNlPEtleWNoYWluPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLCBjb21tb25LZXljaGFpbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvblxuXG4gIGFzeW5jIHNlbmRLZXlHZW5lcmF0aW9uUm91bmQxKFxuICAgIGVudGVycHJpc2U6IHN0cmluZyxcbiAgICB1c2VyR3BnUHVibGljS2V5OiBzdHJpbmcsXG4gICAgYmFja3VwR3BnUHVibGljS2V5OiBzdHJpbmcsXG4gICAgcGF5bG9hZDogRGtsc1R5cGVzLkF1dGhFbmNNZXNzYWdlcyAmIHsgd2FsbGV0SWQ/OiBzdHJpbmcgfVxuICApOiBQcm9taXNlPE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5zZW5kS2V5R2VuZXJhdGlvblJvdW5kMUJ5U2VuZGVyKFxuICAgICAgS2V5R2VuU2VuZGVyRm9yRW50ZXJwcmlzZSh0aGlzLmJpdGdvLCBlbnRlcnByaXNlKSxcbiAgICAgIHVzZXJHcGdQdWJsaWNLZXksXG4gICAgICBiYWNrdXBHcGdQdWJsaWNLZXksXG4gICAgICBwYXlsb2FkXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHNlbmRLZXlHZW5lcmF0aW9uUm91bmQyKFxuICAgIGVudGVycHJpc2U6IHN0cmluZyxcbiAgICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzXG4gICk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDJSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQyQnlTZW5kZXIoS2V5R2VuU2VuZGVyRm9yRW50ZXJwcmlzZSh0aGlzLmJpdGdvLCBlbnRlcnByaXNlKSwgc2Vzc2lvbklkLCBwYXlsb2FkKTtcbiAgfVxuXG4gIGFzeW5jIHNlbmRLZXlHZW5lcmF0aW9uUm91bmQzKFxuICAgIGVudGVycHJpc2U6IHN0cmluZyxcbiAgICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzXG4gICk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDNSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnNlbmRLZXlHZW5lcmF0aW9uUm91bmQzQnlTZW5kZXIoS2V5R2VuU2VuZGVyRm9yRW50ZXJwcmlzZSh0aGlzLmJpdGdvLCBlbnRlcnByaXNlKSwgc2Vzc2lvbklkLCBwYXlsb2FkKTtcbiAgfVxuXG4gIGFzeW5jIHNlbmRLZXlHZW5lcmF0aW9uUm91bmQxQnlTZW5kZXIoXG4gICAgc2VuZGVyRm46IEVjZHNhTVBDdjJLZXlHZW5TZW5kRm48TVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZT4sXG4gICAgdXNlckdwZ1B1YmxpY0tleTogc3RyaW5nLFxuICAgIGJhY2t1cEdwZ1B1YmxpY0tleTogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXMgJiB7IHdhbGxldElkPzogc3RyaW5nIH1cbiAgKTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kMVJlc3BvbnNlPiB7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHVzZXJHcGdQdWJsaWNLZXkpLCAnVXNlciBHUEcgcHVibGljIGtleSBpcyByZXF1aXJlZCcpO1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhiYWNrdXBHcGdQdWJsaWNLZXkpLCAnQmFja3VwIEdQRyBwdWJsaWMga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgdXNlck1zZzEgPSBwYXlsb2FkLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQodXNlck1zZzEsICdVc2VyIG1lc3NhZ2UgMSBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYmFja3VwTXNnMSA9IHBheWxvYWQuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk/LnBheWxvYWQ7XG4gICAgYXNzZXJ0KGJhY2t1cE1zZzEsICdCYWNrdXAgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcblxuICAgIHJldHVybiBzZW5kZXJGbihNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjItUjEnXSwge1xuICAgICAgdXNlckdwZ1B1YmxpY0tleSxcbiAgICAgIGJhY2t1cEdwZ1B1YmxpY0tleSxcbiAgICAgIHVzZXJNc2cxOiB7IGZyb206IDAsIC4uLnVzZXJNc2cxIH0sXG4gICAgICBiYWNrdXBNc2cxOiB7IGZyb206IDEsIC4uLmJhY2t1cE1zZzEgfSxcbiAgICAgIHdhbGxldElkOiBwYXlsb2FkLndhbGxldElkLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDJCeVNlbmRlcihcbiAgICBzZW5kZXJGbjogRWNkc2FNUEN2MktleUdlblNlbmRGbjxNUEN2MktleUdlblJvdW5kMlJlc3BvbnNlPixcbiAgICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzXG4gICk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDJSZXNwb25zZT4ge1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhzZXNzaW9uSWQpLCAnU2Vzc2lvbiBJRCBpcyByZXF1aXJlZCcpO1xuICAgIGNvbnN0IHVzZXJNc2cyID0gcGF5bG9hZC5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydCh1c2VyTXNnMiwgJ1VzZXIgdG8gQml0Z28gbWVzc2FnZSAyIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQodXNlck1zZzIuY29tbWl0bWVudCwgJ1VzZXIgdG8gQml0Z28gY29tbWl0bWVudCBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHVzZXJNc2cyLmNvbW1pdG1lbnQpLCAnVXNlciB0byBCaXRnbyBjb21taXRtZW50IGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgYmFja3VwTXNnMiA9IHBheWxvYWQucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydChiYWNrdXBNc2cyLCAnQmFja3VwIHRvIEJpdGdvIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgYXNzZXJ0KGJhY2t1cE1zZzIuY29tbWl0bWVudCwgJ0JhY2t1cCB0byBCaXRnbyBjb21taXRtZW50IG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXMoYmFja3VwTXNnMi5jb21taXRtZW50KSwgJ0JhY2t1cCB0byBCaXRnbyBjb21taXRtZW50IGlzIHJlcXVpcmVkJyk7XG5cbiAgICByZXR1cm4gc2VuZGVyRm4oTVBDdjJLZXlHZW5TdGF0ZUVudW1bJ01QQ3YyLVIyJ10sIHtcbiAgICAgIHNlc3Npb25JZCxcbiAgICAgIHVzZXJNc2cyOiB7XG4gICAgICAgIGZyb206IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgICAgdG86IE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICAgIHNpZ25hdHVyZTogdXNlck1zZzIucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IHVzZXJNc2cyLnBheWxvYWQuZW5jcnlwdGVkTWVzc2FnZSxcbiAgICAgIH0sXG4gICAgICB1c2VyQ29tbWl0bWVudDI6IHVzZXJNc2cyLmNvbW1pdG1lbnQsXG4gICAgICBiYWNrdXBNc2cyOiB7XG4gICAgICAgIGZyb206IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLFxuICAgICAgICB0bzogTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyxcbiAgICAgICAgc2lnbmF0dXJlOiBiYWNrdXBNc2cyLnBheWxvYWQuc2lnbmF0dXJlLFxuICAgICAgICBlbmNyeXB0ZWRNZXNzYWdlOiBiYWNrdXBNc2cyLnBheWxvYWQuZW5jcnlwdGVkTWVzc2FnZSxcbiAgICAgIH0sXG4gICAgICBiYWNrdXBDb21taXRtZW50MjogYmFja3VwTXNnMi5jb21taXRtZW50LFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2VuZEtleUdlbmVyYXRpb25Sb3VuZDNCeVNlbmRlcihcbiAgICBzZW5kZXJGbjogRWNkc2FNUEN2MktleUdlblNlbmRGbjxNUEN2MktleUdlblJvdW5kM1Jlc3BvbnNlPixcbiAgICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzXG4gICk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDNSZXNwb25zZT4ge1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhzZXNzaW9uSWQpLCAnU2Vzc2lvbiBJRCBpcyByZXF1aXJlZCcpO1xuICAgIGNvbnN0IHVzZXJNc2czID0gcGF5bG9hZC5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApPy5wYXlsb2FkO1xuICAgIGFzc2VydCh1c2VyTXNnMywgJ1VzZXIgdG8gQml0Z28gbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiYWNrdXBNc2czID0gcGF5bG9hZC5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk/LnBheWxvYWQ7XG4gICAgYXNzZXJ0KGJhY2t1cE1zZzMsICdCYWNrdXAgdG8gQml0Z28gbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCB1c2VyTXNnNCA9IHBheWxvYWQuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpPy5wYXlsb2FkO1xuICAgIGFzc2VydCh1c2VyTXNnNCwgJ1VzZXIgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiYWNrdXBNc2c0ID0gcGF5bG9hZC5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQoYmFja3VwTXNnNCwgJ0JhY2t1cCBtZXNzYWdlIDEgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuXG4gICAgcmV0dXJuIHNlbmRlckZuKE1QQ3YyS2V5R2VuU3RhdGVFbnVtWydNUEN2Mi1SMyddLCB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICB1c2VyTXNnMzogeyBmcm9tOiAwLCB0bzogMiwgLi4udXNlck1zZzMgfSxcbiAgICAgIGJhY2t1cE1zZzM6IHsgZnJvbTogMSwgdG86IDIsIC4uLmJhY2t1cE1zZzMgfSxcbiAgICAgIHVzZXJNc2c0OiB7IGZyb206IDAsIC4uLnVzZXJNc2c0IH0sXG4gICAgICBiYWNrdXBNc2c0OiB7IGZyb206IDEsIC4uLmJhY2t1cE1zZzQgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHNpZ24gdHggcmVxdWVzdFxuXG4gIC8qKlxuICAgKiBTaWducyB0aGUgdHJhbnNhY3Rpb24gYXNzb2NpYXRlZCB0byB0aGUgdHJhbnNhY3Rpb24gcmVxdWVzdC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBUeFJlcXVlc3R9IHBhcmFtcy50eFJlcXVlc3QgLSB0cmFuc2FjdGlvbiByZXF1ZXN0IG9iamVjdCBvciBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLnBydiAtIGRlY3J5cHRlZCBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLnJlcUlkIC0gcmVxdWVzdCBpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLm1wY3YyUGFydHlJZCAtIHBhcnR5IGlkIGZvciB0aGUgc2lnbmVyIGludm9sdmVkIGluIHRoaXMgbXBjdjIgcmVxdWVzdCAoZWl0aGVyIDAgZm9yIHVzZXIgb3IgMSBmb3IgYmFja3VwKVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUeFJlcXVlc3Q+fSBmdWxseSBzaWduZWQgVHhSZXF1ZXN0IG9iamVjdFxuICAgKi9cblxuICBhc3luYyBzaWduVHhSZXF1ZXN0KHBhcmFtczogVFNTUGFyYW1zV2l0aFBydik6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHBhcmFtcy5yZXFJZCk7XG4gICAgcmV0dXJuIHRoaXMuc2lnblJlcXVlc3RCYXNlKHBhcmFtcywgUmVxdWVzdFR5cGUudHgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpZ25zIHRoZSBtZXNzYWdlIGFzc29jaWF0ZWQgdG8gdGhlIHRyYW5zYWN0aW9uIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgVHhSZXF1ZXN0fSBwYXJhbXMudHhSZXF1ZXN0IC0gdHJhbnNhY3Rpb24gcmVxdWVzdCBvYmplY3Qgb3IgaWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtcy5wcnYgLSBkZWNyeXB0ZWQgcHJpdmF0ZSBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtcy5yZXFJZCAtIHJlcXVlc3QgaWRcbiAgICogQHJldHVybnMge1Byb21pc2U8VHhSZXF1ZXN0Pn0gZnVsbHkgc2lnbmVkIFR4UmVxdWVzdCBvYmplY3RcbiAgICovXG4gIGFzeW5jIHNpZ25UeFJlcXVlc3RGb3JNZXNzYWdlKHBhcmFtczogVFNTUGFyYW1zRm9yTWVzc2FnZVdpdGhQcnYpOiBQcm9taXNlPFR4UmVxdWVzdD4ge1xuICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihwYXJhbXMucmVxSWQpO1xuICAgIHJldHVybiB0aGlzLnNpZ25SZXF1ZXN0QmFzZShwYXJhbXMsIFJlcXVlc3RUeXBlLm1lc3NhZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzaWduUmVxdWVzdEJhc2UoXG4gICAgcGFyYW1zOiBUU1NQYXJhbXNXaXRoUHJ2IHwgVFNTUGFyYW1zRm9yTWVzc2FnZVdpdGhQcnYsXG4gICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlXG4gICk6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gICAgY29uc3QgdXNlcktleVNoYXJlID0gQnVmZmVyLmZyb20ocGFyYW1zLnBydiwgJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IHR4UmVxdWVzdDogVHhSZXF1ZXN0ID1cbiAgICAgIHR5cGVvZiBwYXJhbXMudHhSZXF1ZXN0ID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGF3YWl0IGdldFR4UmVxdWVzdCh0aGlzLmJpdGdvLCB0aGlzLndhbGxldC5pZCgpLCBwYXJhbXMudHhSZXF1ZXN0LCBwYXJhbXMucmVxSWQpXG4gICAgICAgIDogcGFyYW1zLnR4UmVxdWVzdDtcbiAgICBsZXQgdHhPck1lc3NhZ2VUb1NpZ247XG4gICAgbGV0IGRlcml2YXRpb25QYXRoO1xuICAgIGxldCBidWZmZXJDb250ZW50O1xuICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ3NlY3AyNTZrMScpO1xuICAgIGNvbnN0IGJpdGdvR3BnUHViS2V5ID0gYXdhaXQgdGhpcy5waWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nKHRydWUsIHBhcmFtcy5yZXFJZCwgdHhSZXF1ZXN0LmVudGVycHJpc2VJZCk7XG5cbiAgICBpZiAoIWJpdGdvR3BnUHViS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgQml0R28gR1BHIGtleSBmb3IgTVBDdjInKTtcbiAgICB9XG5cbiAgICBpZiAocmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4KSB7XG4gICAgICBhc3NlcnQodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyB8fCB0eFJlcXVlc3QudW5zaWduZWRUeHMsICdVbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0Jyk7XG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID1cbiAgICAgICAgdHhSZXF1ZXN0LmFwaVZlcnNpb24gPT09ICdmdWxsJyA/IHR4UmVxdWVzdC50cmFuc2FjdGlvbnMhWzBdLnVuc2lnbmVkVHggOiB0eFJlcXVlc3QudW5zaWduZWRUeHNbMF07XG5cbiAgICAgIGlmICghcGFyYW1zLnR4UGFyYW1zPy5yZWNpcGllbnRzPy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKFxuICAgICAgICAgICdSZWNpcGllbnQgZGV0YWlscyBhcmUgcmVxdWlyZWQgdG8gdmVyaWZ5IHRoaXMgdHJhbnNhY3Rpb24gYmVmb3JlIHNpZ25pbmcuIFBhc3MgdHhQYXJhbXMgd2l0aCBhdCBsZWFzdCBvbmUgcmVjaXBpZW50LidcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gRm9yIElDUCB0cmFuc2FjdGlvbnMsIHRoZSBIU00gc2lnbnMgdGhlIHNlcmlhbGl6ZWRUeEhleCwgd2hpbGUgdGhlIHVzZXIgc2lnbnMgdGhlIHNpZ25hYmxlSGV4IHNlcGFyYXRlbHkuXG4gICAgICAvLyBWZXJpZmljYXRpb24gY2Fubm90IGJlIHBlcmZvcm1lZCBkaXJlY3RseSBvbiB0aGUgc2lnbmFibGVIZXggYWxvbmUuIEhvd2V2ZXIsIHdlIGNhbiBwYXJzZSB0aGUgc2VyaWFsaXplZFR4SGV4XG4gICAgICAvLyB0byByZWdlbmVyYXRlIHRoZSBzaWduYWJsZUhleCBhbmQgY29tcGFyZSBpdCBhZ2FpbnN0IHRoZSBwcm92aWRlZCB2YWx1ZSBmb3IgdmVyaWZpY2F0aW9uLlxuICAgICAgLy8gSW4gY29udHJhc3QsIGZvciBvdGhlciBjb2luIGZhbWlsaWVzLCB2ZXJpZmljYXRpb24gaXMgdHlwaWNhbGx5IGRvbmUgdXNpbmcganVzdCB0aGUgc2lnbmFibGVIZXguXG4gICAgICBpZiAodGhpcy5iYXNlQ29pbi5nZXRDb25maWcoKS5mYW1pbHkgPT09ICdpY3AnKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYmFzZUNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgdHhIZXg6IHVuc2lnbmVkVHguc2VyaWFsaXplZFR4SGV4LCB0eEluZm86IHVuc2lnbmVkVHguc2lnbmFibGVIZXggfSxcbiAgICAgICAgICB0eFBhcmFtczogcGFyYW1zLnR4UGFyYW1zLFxuICAgICAgICAgIHdhbGxldDogdGhpcy53YWxsZXQsXG4gICAgICAgICAgd2FsbGV0VHlwZTogdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlKCksXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdGhpcy5iYXNlQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleDogdW5zaWduZWRUeC5zaWduYWJsZUhleCB9LFxuICAgICAgICAgIHR4UGFyYW1zOiBwYXJhbXMudHhQYXJhbXMsXG4gICAgICAgICAgd2FsbGV0OiB0aGlzLndhbGxldCxcbiAgICAgICAgICB3YWxsZXRUeXBlOiB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGUoKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0eE9yTWVzc2FnZVRvU2lnbiA9IHVuc2lnbmVkVHguc2lnbmFibGVIZXg7XG4gICAgICBkZXJpdmF0aW9uUGF0aCA9IHVuc2lnbmVkVHguZGVyaXZhdGlvblBhdGg7XG4gICAgICBidWZmZXJDb250ZW50ID0gQnVmZmVyLmZyb20odHhPck1lc3NhZ2VUb1NpZ24sICdoZXgnKTtcbiAgICB9IGVsc2UgaWYgKHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS5tZXNzYWdlKSB7XG4gICAgICB0eE9yTWVzc2FnZVRvU2lnbiA9IHR4UmVxdWVzdC5tZXNzYWdlcyFbMF0ubWVzc2FnZUVuY29kZWQ7XG4gICAgICBkZXJpdmF0aW9uUGF0aCA9IHR4UmVxdWVzdC5tZXNzYWdlcyFbMF0uZGVyaXZhdGlvblBhdGggfHwgJ20vMCc7XG4gICAgICBidWZmZXJDb250ZW50ID0gQnVmZmVyLmZyb20odHhPck1lc3NhZ2VUb1NpZ24sICdoZXgnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlcXVlc3QgdHlwZScpO1xuICAgIH1cblxuICAgIGxldCBoYXNoOiBIYXNoO1xuICAgIHRyeSB7XG4gICAgICBoYXNoID0gdGhpcy5iYXNlQ29pbi5nZXRIYXNoRnVuY3Rpb24oKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGhhc2ggPSBjcmVhdGVLZWNjYWtIYXNoKCdrZWNjYWsyNTYnKSBhcyBIYXNoO1xuICAgIH1cbiAgICAvLyBjaGVjayB3aGF0IHRoZSBlbmNvZGluZyBpcyBzdXBwb3NlZCB0byBiZSBmb3IgbWVzc2FnZVxuICAgIGNvbnN0IGhhc2hCdWZmZXIgPSBoYXNoLnVwZGF0ZShidWZmZXJDb250ZW50KS5kaWdlc3QoKTtcbiAgICBjb25zdCBvdGhlclNpZ25lciA9IG5ldyBEa2xzRHNnLkRzZyhcbiAgICAgIHVzZXJLZXlTaGFyZSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWQgIT09IHVuZGVmaW5lZCA/IHBhcmFtcy5tcGN2MlBhcnR5SWQgOiAwLFxuICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICBoYXNoQnVmZmVyXG4gICAgKTtcbiAgICBjb25zdCB1c2VyU2lnbmVyQnJvYWRjYXN0TXNnMSA9IGF3YWl0IG90aGVyU2lnbmVyLmluaXQoKTtcbiAgICBjb25zdCBzaWduYXR1cmVTaGFyZVJvdW5kMSA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUoXG4gICAgICB1c2VyU2lnbmVyQnJvYWRjYXN0TXNnMSxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBwYXJhbXMubXBjdjJQYXJ0eUlkXG4gICAgKTtcblxuICAgIGxldCBsYXRlc3RUeFJlcXVlc3QgPSBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3Qud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZDFdLFxuICAgICAgcmVxdWVzdFR5cGUsXG4gICAgICB0aGlzLmJhc2VDb2luLmdldE1QQ0FsZ29yaXRobSgpLFxuICAgICAgdXNlckdwZ0tleS5wdWJsaWNLZXksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGVWZXJzaW9uKCksXG4gICAgICBwYXJhbXMucmVxSWRcbiAgICApO1xuXG4gICAgYXNzZXJ0KGxhdGVzdFR4UmVxdWVzdC50cmFuc2FjdGlvbnMgfHwgbGF0ZXN0VHhSZXF1ZXN0Lm1lc3NhZ2VzLCAnSW52YWxpZCB0eFJlcXVlc3QgT2JqZWN0Jyk7XG5cbiAgICBsZXQgYml0Z29Ub1VzZXJNZXNzYWdlczFBbmQyOiBhbnk7XG4gICAgaWYgKHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS50eCkge1xuICAgICAgYml0Z29Ub1VzZXJNZXNzYWdlczFBbmQyID0gbGF0ZXN0VHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyFbMF0uc2lnbmF0dXJlU2hhcmVzO1xuICAgIH0gZWxzZSB7XG4gICAgICBiaXRnb1RvVXNlck1lc3NhZ2VzMUFuZDIgPSBsYXRlc3RUeFJlcXVlc3QubWVzc2FnZXMhWzBdLnNpZ25hdHVyZVNoYXJlcztcbiAgICB9XG4gICAgLy8gVE9ETzogVXNlIGNvZGVjIGZvciBwYXJzaW5nXG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lID0gSlNPTi5wYXJzZShcbiAgICAgIGJpdGdvVG9Vc2VyTWVzc2FnZXMxQW5kMltiaXRnb1RvVXNlck1lc3NhZ2VzMUFuZDIubGVuZ3RoIC0gMV0uc2hhcmVcbiAgICApIGFzIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQ7XG4gICAgaWYgKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZE9uZS50eXBlICE9PSAncm91bmQxT3V0cHV0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQxQW5kMiA9IGF3YWl0IHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRPbmUoXG4gICAgICBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRPbmUsXG4gICAgICB1c2VyR3BnS2V5LFxuICAgICAgYml0Z29HcGdQdWJLZXksXG4gICAgICBwYXJhbXMubXBjdjJQYXJ0eUlkXG4gICAgKTtcblxuICAgIC8qKiBSb3VuZCAyICoqL1xuICAgIGNvbnN0IGRlc2VyaWFsaXplZE1lc3NhZ2VzID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDFBbmQyKTtcbiAgICBjb25zdCB1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQyID0gb3RoZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogZGVzZXJpYWxpemVkTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMsXG4gICAgfSk7XG4gICAgY29uc3QgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMyA9IG90aGVyU2lnbmVyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IGRlc2VyaWFsaXplZE1lc3NhZ2VzLnAycE1lc3NhZ2VzLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmRUd28gPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvKFxuICAgICAgdXNlclRvQml0R29NZXNzYWdlc1JvdW5kMixcbiAgICAgIHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDMsXG4gICAgICB1c2VyR3BnS2V5LFxuICAgICAgYml0Z29HcGdQdWJLZXksXG4gICAgICBwYXJhbXMubXBjdjJQYXJ0eUlkXG4gICAgKTtcbiAgICBsYXRlc3RUeFJlcXVlc3QgPSBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3Qud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICBbc2lnbmF0dXJlU2hhcmVSb3VuZFR3b10sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHBhcmFtcy5yZXFJZFxuICAgICk7XG4gICAgYXNzZXJ0KGxhdGVzdFR4UmVxdWVzdC50cmFuc2FjdGlvbnMgfHwgbGF0ZXN0VHhSZXF1ZXN0Lm1lc3NhZ2VzLCAnSW52YWxpZCB0eFJlcXVlc3QgT2JqZWN0Jyk7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RTaWduYXR1cmVTaGFyZXMgPVxuICAgICAgcmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLnR4XG4gICAgICAgID8gbGF0ZXN0VHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyFbMF0uc2lnbmF0dXJlU2hhcmVzXG4gICAgICAgIDogbGF0ZXN0VHhSZXF1ZXN0Lm1lc3NhZ2VzIVswXS5zaWduYXR1cmVTaGFyZXM7XG4gICAgLy8gVE9ETzogVXNlIGNvZGVjIGZvciBwYXJzaW5nXG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kVHdvID0gSlNPTi5wYXJzZShcbiAgICAgIHR4UmVxdWVzdFNpZ25hdHVyZVNoYXJlc1t0eFJlcXVlc3RTaWduYXR1cmVTaGFyZXMubGVuZ3RoIC0gMV0uc2hhcmVcbiAgICApIGFzIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQ7XG4gICAgaWYgKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3by50eXBlICE9PSAncm91bmQyT3V0cHV0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQzID0gYXdhaXQgdmVyaWZ5Qml0R29NZXNzYWdlc0FuZFNpZ25hdHVyZXNSb3VuZFR3byhcbiAgICAgIHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3byxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ1B1YktleSxcbiAgICAgIHBhcmFtcy5tcGN2MlBhcnR5SWRcbiAgICApO1xuXG4gICAgLyoqIFJvdW5kIDMgKiovXG4gICAgY29uc3QgZGVzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMy5wMnBNZXNzYWdlcyxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcbiAgICBjb25zdCB1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQ0ID0gb3RoZXJTaWduZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogZGVzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMy5wMnBNZXNzYWdlcyxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZShcbiAgICAgIHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDQsXG4gICAgICB1c2VyR3BnS2V5LFxuICAgICAgYml0Z29HcGdQdWJLZXksXG4gICAgICBwYXJhbXMubXBjdjJQYXJ0eUlkXG4gICAgKTtcbiAgICAvLyBTdWJtaXQgZm9yIGZpbmFsIHNpZ25hdHVyZSBzaGFyZSBjb21iaW5lXG4gICAgYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlVjIoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdHhSZXF1ZXN0LndhbGxldElkLFxuICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgW3NpZ25hdHVyZVNoYXJlUm91bmRUaHJlZV0sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnS2V5LnB1YmxpY0tleSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHRoaXMud2FsbGV0Lm11bHRpc2lnVHlwZVZlcnNpb24oKSxcbiAgICAgIHBhcmFtcy5yZXFJZFxuICAgICk7XG5cbiAgICByZXR1cm4gc2VuZFR4UmVxdWVzdCh0aGlzLmJpdGdvLCB0eFJlcXVlc3Qud2FsbGV0SWQsIHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVxdWVzdFR5cGUsIHBhcmFtcy5yZXFJZCk7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBmb3JtYXR0aW5nIHV0aWxzXG4gIGZvcm1hdEJpdGdvQnJvYWRjYXN0TWVzc2FnZShicm9hZGNhc3RNZXNzYWdlOiBNUEN2MkJyb2FkY2FzdE1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZnJvbTogYnJvYWRjYXN0TWVzc2FnZS5mcm9tLFxuICAgICAgcGF5bG9hZDogeyBtZXNzYWdlOiBicm9hZGNhc3RNZXNzYWdlLm1lc3NhZ2UsIHNpZ25hdHVyZTogYnJvYWRjYXN0TWVzc2FnZS5zaWduYXR1cmUgfSxcbiAgICB9O1xuICB9XG5cbiAgZm9ybWF0UDJQTWVzc2FnZShwMnBNZXNzYWdlOiBNUEN2MlAyUE1lc3NhZ2UsIGNvbW1pdG1lbnQ/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcGF5bG9hZDogeyBlbmNyeXB0ZWRNZXNzYWdlOiBwMnBNZXNzYWdlLmVuY3J5cHRlZE1lc3NhZ2UsIHNpZ25hdHVyZTogcDJwTWVzc2FnZS5zaWduYXR1cmUgfSxcbiAgICAgIGZyb206IHAycE1lc3NhZ2UuZnJvbSxcbiAgICAgIHRvOiBwMnBNZXNzYWdlLnRvLFxuICAgICAgY29tbWl0bWVudCxcbiAgICB9O1xuICB9XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHByaXZhdGUgdXRpbHNcbiAgLyoqXG4gICAqIEdldCB0aGUgaGFzaCBzdHJpbmcgYW5kIGRlcml2YXRpb24gcGF0aCBmcm9tIHRoZSB0cmFuc2FjdGlvbiByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge1R4UmVxdWVzdH0gdHhSZXF1ZXN0IC0gdGhlIHRyYW5zYWN0aW9uIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEBwYXJhbSB7UmVxdWVzdFR5cGV9IHJlcXVlc3RUeXBlIC0gdGhlIHJlcXVlc3QgdHlwZVxuICAgKiBAcmV0dXJucyB7eyBoYXNoQnVmZmVyOiBCdWZmZXI7IGRlcml2YXRpb25QYXRoOiBzdHJpbmcgfX0gLSB0aGUgaGFzaCBzdHJpbmcgYW5kIGRlcml2YXRpb24gcGF0aFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGgoXG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlID0gUmVxdWVzdFR5cGUudHhcbiAgKTogeyBoYXNoQnVmZmVyOiBCdWZmZXI7IGRlcml2YXRpb25QYXRoOiBzdHJpbmcgfSB7XG4gICAgbGV0IHR4VG9TaWduOiBzdHJpbmc7XG4gICAgbGV0IGRlcml2YXRpb25QYXRoOiBzdHJpbmc7XG4gICAgaWYgKHJlcXVlc3RUeXBlID09PSBSZXF1ZXN0VHlwZS50eCkge1xuICAgICAgYXNzZXJ0KHR4UmVxdWVzdC50cmFuc2FjdGlvbnMgJiYgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEsICdVbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0Jyk7XG4gICAgICB0eFRvU2lnbiA9IHR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaWduYWJsZUhleDtcbiAgICAgIGRlcml2YXRpb25QYXRoID0gdHhSZXF1ZXN0LnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmRlcml2YXRpb25QYXRoO1xuICAgIH0gZWxzZSBpZiAocmVxdWVzdFR5cGUgPT09IFJlcXVlc3RUeXBlLm1lc3NhZ2UpIHtcbiAgICAgIC8vIFRPRE8oV1AtMjE3Nik6IEFkZCBzdXBwb3J0IGZvciBtZXNzYWdlIHNpZ25pbmdcbiAgICAgIHRocm93IG5ldyBFcnJvcignTVBDdjIgbWVzc2FnZSBzaWduaW5nIG5vdCBzdXBwb3J0ZWQgeWV0LicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcmVxdWVzdCB0eXBlLCBnb3Q6ICcgKyByZXF1ZXN0VHlwZSk7XG4gICAgfVxuXG4gICAgbGV0IGhhc2g6IEhhc2g7XG4gICAgdHJ5IHtcbiAgICAgIGhhc2ggPSB0aGlzLmJhc2VDb2luLmdldEhhc2hGdW5jdGlvbigpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaGFzaCA9IGNyZWF0ZUtlY2Nha0hhc2goJ2tlY2NhazI1NicpIGFzIEhhc2g7XG4gICAgfVxuICAgIGNvbnN0IGhhc2hCdWZmZXIgPSBoYXNoLnVwZGF0ZShCdWZmZXIuZnJvbSh0eFRvU2lnbiwgJ2hleCcpKS5kaWdlc3QoKTtcblxuICAgIHJldHVybiB7IGhhc2hCdWZmZXIsIGRlcml2YXRpb25QYXRoIH07XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgQml0R28gYW5kIHVzZXIgR1BHIGtleXMgZnJvbSB0aGUgQml0R28gcHVibGljIEdQRyBrZXkgYW5kIHRoZSBlbmNyeXB0ZWQgdXNlciBHUEcgcHJpdmF0ZSBrZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiaXRnb1B1YmxpY0dwZ0tleSAgLSB0aGUgQml0R28gcHVibGljIEdQRyBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgIC0gdGhlIGVuY3J5cHRlZCB1c2VyIEdQRyBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gd2FsbGV0UGFzc3BocmFzZSAgLSB0aGUgd2FsbGV0IHBhc3NwaHJhc2VcbiAgICogQHJldHVybnMge1Byb21pc2U8eyBiaXRnb0dwZ0tleTogcGdwLktleTsgdXNlckdwZ0tleTogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4gfT59IC0gdGhlIEJpdEdvIGFuZCB1c2VyIEdQRyBrZXlzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldEJpdGdvQW5kVXNlckdwZ0tleXMoXG4gICAgYml0Z29QdWJsaWNHcGdLZXk6IHN0cmluZyxcbiAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiBzdHJpbmcsXG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nXG4gICk6IFByb21pc2U8e1xuICAgIGJpdGdvR3BnS2V5OiBwZ3AuS2V5O1xuICAgIHVzZXJHcGdLZXk6IHBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuICB9PiB7XG4gICAgY29uc3QgYml0Z29HcGdLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvUHVibGljR3BnS2V5IH0pO1xuICAgIGNvbnN0IHVzZXJEZWNyeXB0ZWRLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7XG4gICAgICBhcm1vcmVkS2V5OiB0aGlzLmJpdGdvLmRlY3J5cHQoeyBpbnB1dDogZW5jcnlwdGVkVXNlckdwZ1BydktleSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgfSk7XG4gICAgY29uc3QgdXNlckdwZ0tleTogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz4gPSB7XG4gICAgICBwcml2YXRlS2V5OiB1c2VyRGVjcnlwdGVkS2V5LmFybW9yKCksXG4gICAgICBwdWJsaWNLZXk6IHVzZXJEZWNyeXB0ZWRLZXkudG9QdWJsaWMoKS5hcm1vcigpLFxuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgIGJpdGdvR3BnS2V5LFxuICAgICAgdXNlckdwZ0tleSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgYWRhdGEgYW5kIGN5cGhlcnRleHQuXG4gICAqIEBwYXJhbSBhZGF0YSBzdHJpbmdcbiAgICogQHBhcmFtIGN5cGhlcnRleHQgc3RyaW5nXG4gICAqIEByZXR1cm5zIHZvaWRcbiAgICogQHRocm93cyB7RXJyb3J9IGlmIHRoZSBhZGF0YSBvciBjeXBoZXJ0ZXh0IGlzIGludmFsaWRcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVBZGF0YShhZGF0YTogc3RyaW5nLCBjeXBoZXJ0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBsZXQgY3lwaGVySnNvbjtcbiAgICB0cnkge1xuICAgICAgY3lwaGVySnNvbiA9IEpTT04ucGFyc2UoY3lwaGVydGV4dCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcGFyc2UgY3lwaGVydGV4dCB0byBKU09OLCBnb3Q6ICcgKyBjeXBoZXJ0ZXh0KTtcbiAgICB9XG4gICAgLy8gdXNpbmcgZGVjb2RlVVJJQ29tcG9uZW50IHRvIGhhbmRsZSBzcGVjaWFsIGNoYXJhY3RlcnNcbiAgICBpZiAoZGVjb2RlVVJJQ29tcG9uZW50KGN5cGhlckpzb24uYWRhdGEpICE9PSBkZWNvZGVVUklDb21wb25lbnQoYWRhdGEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEnKTtcbiAgICB9XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uXG5cbiAgLy8gI3JlZ2lvbiBleHRlcm5hbCBzaWduZXJcbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGFzeW5jIHNpZ25FY2RzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICBwYXJhbXM6IFRTU1BhcmFtcyB8IFRTU1BhcmFtc0Zvck1lc3NhZ2UsXG4gICAgZXh0ZXJuYWxTaWduZXJNUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0b3I6IEN1c3RvbU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICBleHRlcm5hbFNpZ25lck1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRvcjogQ3VzdG9tTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgIGV4dGVybmFsU2lnbmVyTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdG9yOiBDdXN0b21NUEN2MlNpZ25pbmdSb3VuZDNHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgcmVxdWVzdFR5cGU6IFJlcXVlc3RUeXBlID0gUmVxdWVzdFR5cGUudHhcbiAgKTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgICBjb25zdCB7IHR4UmVxdWVzdCwgcmVxSWQgfSA9IHBhcmFtcztcbiAgICBsZXQgdHhSZXF1ZXN0UmVzb2x2ZWQ6IFR4UmVxdWVzdDtcblxuICAgIC8vIFRPRE8oV1AtMjE3Nik6IEFkZCBzdXBwb3J0IGZvciBtZXNzYWdlIHNpZ25pbmdcbiAgICBhc3NlcnQoXG4gICAgICByZXF1ZXN0VHlwZSA9PT0gUmVxdWVzdFR5cGUudHgsXG4gICAgICAnT25seSB0cmFuc2FjdGlvbiBzaWduaW5nIGlzIHN1cHBvcnRlZCBmb3IgZXh0ZXJuYWwgc2lnbmVyLCBnb3Q6ICcgKyByZXF1ZXN0VHlwZVxuICAgICk7XG5cbiAgICBpZiAodHlwZW9mIHR4UmVxdWVzdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkID0gYXdhaXQgZ2V0VHhSZXF1ZXN0KHRoaXMuYml0Z28sIHRoaXMud2FsbGV0LmlkKCksIHR4UmVxdWVzdCwgcmVxSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZCA9IHR4UmVxdWVzdDtcbiAgICB9XG5cbiAgICBjb25zdCBiaXRnb1B1YmxpY0dwZ0tleSA9IGF3YWl0IHRoaXMucGlja0JpdGdvUHViR3BnS2V5Rm9yU2lnbmluZyhcbiAgICAgIHRydWUsXG4gICAgICBwYXJhbXMucmVxSWQsXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC5lbnRlcnByaXNlSWRcbiAgICApO1xuXG4gICAgaWYgKCFiaXRnb1B1YmxpY0dwZ0tleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIEJpdEdvIEdQRyBrZXkgZm9yIE1QQ3YyJyk7XG4gICAgfVxuXG4gICAgLy8gcm91bmQgMVxuICAgIGNvbnN0IHsgc2lnbmF0dXJlU2hhcmVSb3VuZDEsIHVzZXJHcGdQdWJLZXksIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkgfSA9XG4gICAgICBhd2FpdCBleHRlcm5hbFNpZ25lck1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRvcih7IHR4UmVxdWVzdDogdHhSZXF1ZXN0UmVzb2x2ZWQgfSk7XG4gICAgY29uc3Qgcm91bmQxVHhSZXF1ZXN0ID0gYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlVjIoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kMV0sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnUHViS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcmVxSWRcbiAgICApO1xuXG4gICAgLy8gcm91bmQgMlxuICAgIGNvbnN0IHsgc2lnbmF0dXJlU2hhcmVSb3VuZDIsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfSA9IGF3YWl0IGV4dGVybmFsU2lnbmVyTVBDdjJTaWduaW5nUm91bmQyR2VuZXJhdG9yKHtcbiAgICAgIHR4UmVxdWVzdDogcm91bmQxVHhSZXF1ZXN0LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29QdWJsaWNHcGdLZXkuYXJtb3IoKSxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJUeFJlcXVlc3QgPSBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmVWMihcbiAgICAgIHRoaXMuYml0Z28sXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC53YWxsZXRJZCxcbiAgICAgIHR4UmVxdWVzdFJlc29sdmVkLnR4UmVxdWVzdElkLFxuICAgICAgW3NpZ25hdHVyZVNoYXJlUm91bmQyXSxcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSxcbiAgICAgIHVzZXJHcGdQdWJLZXksXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB0aGlzLndhbGxldC5tdWx0aXNpZ1R5cGVWZXJzaW9uKCksXG4gICAgICByZXFJZFxuICAgICk7XG4gICAgYXNzZXJ0KFxuICAgICAgcm91bmQyVHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyAmJiByb3VuZDJUeFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdLnNpZ25hdHVyZVNoYXJlcyxcbiAgICAgICdNaXNzaW5nIHNpZ25hdHVyZSBzaGFyZXMgaW4gcm91bmQgMiB0eFJlcXVlc3QnXG4gICAgKTtcblxuICAgIC8vIHJvdW5kIDNcbiAgICBjb25zdCB7IHNpZ25hdHVyZVNoYXJlUm91bmQzIH0gPSBhd2FpdCBleHRlcm5hbFNpZ25lck1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRvcih7XG4gICAgICB0eFJlcXVlc3Q6IHJvdW5kMlR4UmVxdWVzdCxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvUHVibGljR3BnS2V5LmFybW9yKCksXG4gICAgfSk7XG4gICAgYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlVjIoXG4gICAgICB0aGlzLmJpdGdvLFxuICAgICAgdHhSZXF1ZXN0UmVzb2x2ZWQud2FsbGV0SWQsXG4gICAgICB0eFJlcXVlc3RSZXNvbHZlZC50eFJlcXVlc3RJZCxcbiAgICAgIFtzaWduYXR1cmVTaGFyZVJvdW5kM10sXG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCksXG4gICAgICB1c2VyR3BnUHViS2V5LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgdGhpcy53YWxsZXQubXVsdGlzaWdUeXBlVmVyc2lvbigpLFxuICAgICAgcmVxSWRcbiAgICApO1xuXG4gICAgcmV0dXJuIHNlbmRUeFJlcXVlc3QodGhpcy5iaXRnbywgdHhSZXF1ZXN0UmVzb2x2ZWQud2FsbGV0SWQsIHR4UmVxdWVzdFJlc29sdmVkLnR4UmVxdWVzdElkLCByZXF1ZXN0VHlwZSwgcmVxSWQpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHBhcmFtczogeyB0eFJlcXVlc3Q6IFR4UmVxdWVzdDsgcHJ2OiBzdHJpbmc7IHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZyB9KTogUHJvbWlzZTx7XG4gICAgc2lnbmF0dXJlU2hhcmVSb3VuZDE6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgIHVzZXJHcGdQdWJLZXk6IHN0cmluZztcbiAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICB9PiB7XG4gICAgY29uc3QgeyBwcnYsIHdhbGxldFBhc3NwaHJhc2UsIHR4UmVxdWVzdCB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHsgaGFzaEJ1ZmZlciwgZGVyaXZhdGlvblBhdGggfSA9IHRoaXMuZ2V0SGFzaFN0cmluZ0FuZERlcml2YXRpb25QYXRoKHR4UmVxdWVzdCk7XG4gICAgY29uc3QgYWRhdGEgPSBgJHtoYXNoQnVmZmVyLnRvU3RyaW5nKCdoZXgnKX06JHtkZXJpdmF0aW9uUGF0aH1gO1xuXG4gICAgY29uc3QgdXNlcktleVNoYXJlID0gQnVmZmVyLmZyb20ocHJ2LCAnYmFzZTY0Jyk7XG4gICAgY29uc3QgdXNlckdwZ0tleSA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignc2VjcDI1NmsxJyk7XG5cbiAgICBjb25zdCB1c2VyU2lnbmVyID0gbmV3IERrbHNEc2cuRHNnKHVzZXJLZXlTaGFyZSwgMCwgZGVyaXZhdGlvblBhdGgsIGhhc2hCdWZmZXIpO1xuICAgIGNvbnN0IHVzZXJTaWduZXJCcm9hZGNhc3RNc2cxID0gYXdhaXQgdXNlclNpZ25lci5pbml0KCk7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVSb3VuZDEgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lKHVzZXJTaWduZXJCcm9hZGNhc3RNc2cxLCB1c2VyR3BnS2V5KTtcbiAgICBjb25zdCBzZXNzaW9uID0gdXNlclNpZ25lci5nZXRTZXNzaW9uKCk7XG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7IGlucHV0OiBzZXNzaW9uLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSwgYWRhdGEgfSk7XG5cbiAgICBjb25zdCB1c2VyR3BnUHViS2V5ID0gdXNlckdwZ0tleS5wdWJsaWNLZXk7XG4gICAgY29uc3QgZW5jcnlwdGVkVXNlckdwZ1BydktleSA9IHRoaXMuYml0Z28uZW5jcnlwdCh7XG4gICAgICBpbnB1dDogdXNlckdwZ0tleS5wcml2YXRlS2V5LFxuICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBhZGF0YSxcbiAgICB9KTtcblxuICAgIHJldHVybiB7IHNpZ25hdHVyZVNoYXJlUm91bmQxLCB1c2VyR3BnUHViS2V5LCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IH07XG4gIH1cblxuICBhc3luYyBjcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUocGFyYW1zOiB7XG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3Q7XG4gICAgcHJ2OiBzdHJpbmc7XG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGJpdGdvUHVibGljR3BnS2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHN0cmluZztcbiAgfSk6IFByb21pc2U8e1xuICAgIHNpZ25hdHVyZVNoYXJlUm91bmQyOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiBzdHJpbmc7XG4gIH0+IHtcbiAgICBjb25zdCB7IHBydiwgd2FsbGV0UGFzc3BocmFzZSwgZW5jcnlwdGVkVXNlckdwZ1BydktleSwgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgYml0Z29QdWJsaWNHcGdLZXksIHR4UmVxdWVzdCB9ID1cbiAgICAgIHBhcmFtcztcblxuICAgIGNvbnN0IHsgaGFzaEJ1ZmZlciwgZGVyaXZhdGlvblBhdGggfSA9IHRoaXMuZ2V0SGFzaFN0cmluZ0FuZERlcml2YXRpb25QYXRoKHR4UmVxdWVzdCk7XG4gICAgY29uc3QgYWRhdGEgPSBgJHtoYXNoQnVmZmVyLnRvU3RyaW5nKCdoZXgnKX06JHtkZXJpdmF0aW9uUGF0aH1gO1xuICAgIGNvbnN0IHsgYml0Z29HcGdLZXksIHVzZXJHcGdLZXkgfSA9IGF3YWl0IHRoaXMuZ2V0Qml0Z29BbmRVc2VyR3BnS2V5cyhcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2VcbiAgICApO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucz8uWzBdLnNpZ25hdHVyZVNoYXJlcztcbiAgICBhc3NlcnQoc2lnbmF0dXJlU2hhcmVzLCAnTWlzc2luZyBzaWduYXR1cmUgc2hhcmVzIGluIHJvdW5kIDEgdHhSZXF1ZXN0Jyk7XG4gICAgY29uc3QgcGFyc2VkQml0R29Ub1VzZXJTaWdTaGFyZVJvdW5kT25lID0gSlNPTi5wYXJzZShcbiAgICAgIHNpZ25hdHVyZVNoYXJlc1tzaWduYXR1cmVTaGFyZXMubGVuZ3RoIC0gMV0uc2hhcmVcbiAgICApIGFzIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQ7XG4gICAgaWYgKHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZE9uZS50eXBlICE9PSAncm91bmQxT3V0cHV0Jykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHNpZ25hdHVyZSBzaGFyZSByZXNwb25zZS4gVW5hYmxlIHRvIHBhcnNlIGRhdGEuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRHb1RvVXNlck1lc3NhZ2VzUm91bmQxID0gYXdhaXQgdmVyaWZ5Qml0R29NZXNzYWdlc0FuZFNpZ25hdHVyZXNSb3VuZE9uZShcbiAgICAgIHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZE9uZSxcbiAgICAgIHVzZXJHcGdLZXksXG4gICAgICBiaXRnb0dwZ0tleVxuICAgICk7XG5cbiAgICBjb25zdCByb3VuZDFTZXNzaW9uID0gdGhpcy5iaXRnby5kZWNyeXB0KHsgaW5wdXQ6IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pO1xuXG4gICAgdGhpcy52YWxpZGF0ZUFkYXRhKGFkYXRhLCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBCdWZmZXIuZnJvbShwcnYsICdiYXNlNjQnKTtcbiAgICBjb25zdCB1c2VyU2lnbmVyID0gbmV3IERrbHNEc2cuRHNnKHVzZXJLZXlTaGFyZSwgMCwgZGVyaXZhdGlvblBhdGgsIGhhc2hCdWZmZXIpO1xuICAgIGF3YWl0IHVzZXJTaWduZXIuc2V0U2Vzc2lvbihyb3VuZDFTZXNzaW9uKTtcblxuICAgIGNvbnN0IGRlc2VyaWFsaXplZE1lc3NhZ2VzID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDEpO1xuICAgIGNvbnN0IHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDIgPSB1c2VyU2lnbmVyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IGRlc2VyaWFsaXplZE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLFxuICAgIH0pO1xuICAgIGNvbnN0IHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDMgPSB1c2VyU2lnbmVyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IGRlc2VyaWFsaXplZE1lc3NhZ2VzLnAycE1lc3NhZ2VzLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlUm91bmQyID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byhcbiAgICAgIHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDIsXG4gICAgICB1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQzLFxuICAgICAgdXNlckdwZ0tleSxcbiAgICAgIGJpdGdvR3BnS2V5XG4gICAgKTtcbiAgICBjb25zdCBzZXNzaW9uID0gdXNlclNpZ25lci5nZXRTZXNzaW9uKCk7XG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7IGlucHV0OiBzZXNzaW9uLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSwgYWRhdGEgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDIsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBjcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUocGFyYW1zOiB7XG4gICAgdHhSZXF1ZXN0OiBUeFJlcXVlc3Q7XG4gICAgcHJ2OiBzdHJpbmc7XG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGJpdGdvUHVibGljR3BnS2V5OiBzdHJpbmc7XG4gICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogc3RyaW5nO1xuICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHN0cmluZztcbiAgfSk6IFByb21pc2U8e1xuICAgIHNpZ25hdHVyZVNoYXJlUm91bmQzOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgfT4ge1xuICAgIGNvbnN0IHsgcHJ2LCB3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLCBiaXRnb1B1YmxpY0dwZ0tleSwgdHhSZXF1ZXN0IH0gPVxuICAgICAgcGFyYW1zO1xuXG4gICAgYXNzZXJ0KHR4UmVxdWVzdC50cmFuc2FjdGlvbnMgJiYgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEsICdVbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0Jyk7XG4gICAgY29uc3QgeyBoYXNoQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCB9ID0gdGhpcy5nZXRIYXNoU3RyaW5nQW5kRGVyaXZhdGlvblBhdGgodHhSZXF1ZXN0KTtcbiAgICBjb25zdCBhZGF0YSA9IGAke2hhc2hCdWZmZXIudG9TdHJpbmcoJ2hleCcpfToke2Rlcml2YXRpb25QYXRofWA7XG5cbiAgICBjb25zdCB7IGJpdGdvR3BnS2V5LCB1c2VyR3BnS2V5IH0gPSBhd2FpdCB0aGlzLmdldEJpdGdvQW5kVXNlckdwZ0tleXMoXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgKTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlcyA9IHR4UmVxdWVzdC50cmFuc2FjdGlvbnM/LlswXS5zaWduYXR1cmVTaGFyZXM7XG4gICAgYXNzZXJ0KHNpZ25hdHVyZVNoYXJlcywgJ01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAyIHR4UmVxdWVzdCcpO1xuICAgIGNvbnN0IHBhcnNlZEJpdEdvVG9Vc2VyU2lnU2hhcmVSb3VuZFR3byA9IEpTT04ucGFyc2UoXG4gICAgICBzaWduYXR1cmVTaGFyZXNbc2lnbmF0dXJlU2hhcmVzLmxlbmd0aCAtIDFdLnNoYXJlXG4gICAgKSBhcyBNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQyT3V0cHV0O1xuICAgIGlmIChwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRUd28udHlwZSAhPT0gJ3JvdW5kMk91dHB1dCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLicpO1xuICAgIH1cbiAgICBjb25zdCBzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMyA9IGF3YWl0IHZlcmlmeUJpdEdvTWVzc2FnZXNBbmRTaWduYXR1cmVzUm91bmRUd28oXG4gICAgICBwYXJzZWRCaXRHb1RvVXNlclNpZ1NoYXJlUm91bmRUd28sXG4gICAgICB1c2VyR3BnS2V5LFxuICAgICAgYml0Z29HcGdLZXlcbiAgICApO1xuXG4gICAgY29uc3QgZGVzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBzZXJpYWxpemVkQml0R29Ub1VzZXJNZXNzYWdlc1JvdW5kMy5wMnBNZXNzYWdlcyxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvdW5kMlNlc3Npb24gPSB0aGlzLmJpdGdvLmRlY3J5cHQoeyBpbnB1dDogZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSk7XG4gICAgdGhpcy52YWxpZGF0ZUFkYXRhKGFkYXRhLCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uKTtcbiAgICBjb25zdCB1c2VyS2V5U2hhcmUgPSBCdWZmZXIuZnJvbShwcnYsICdiYXNlNjQnKTtcbiAgICBjb25zdCB1c2VyU2lnbmVyID0gbmV3IERrbHNEc2cuRHNnKHVzZXJLZXlTaGFyZSwgMCwgZGVyaXZhdGlvblBhdGgsIGhhc2hCdWZmZXIpO1xuICAgIGF3YWl0IHVzZXJTaWduZXIuc2V0U2Vzc2lvbihyb3VuZDJTZXNzaW9uKTtcblxuICAgIGNvbnN0IHVzZXJUb0JpdEdvTWVzc2FnZXNSb3VuZDQgPSB1c2VyU2lnbmVyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IGRlc2VyaWFsaXplZEJpdEdvVG9Vc2VyTWVzc2FnZXNSb3VuZDMucDJwTWVzc2FnZXMsXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgfSk7XG5cbiAgICBjb25zdCBzaWduYXR1cmVTaGFyZVJvdW5kMyA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSh1c2VyVG9CaXRHb01lc3NhZ2VzUm91bmQ0LCB1c2VyR3BnS2V5LCBiaXRnb0dwZ0tleSk7XG5cbiAgICByZXR1cm4geyBzaWduYXR1cmVTaGFyZVJvdW5kMyB9O1xuICB9XG4gIC8vICNlbmRyZWdpb25cbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGtleSBzaGFyZSwgd2hlbiBkZWNyeXB0ZWQsIGNvbnRhaW5zIHZhbGlkIEdHMTggc2lnbmluZyBtYXRlcmlhbC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5U2hhcmUgLSBUaGUgZW5jcnlwdGVkIGtleSBzaGFyZSBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHdhbGxldFBhc3NwaHJhc2UgLSBUaGUgcGFzc3BocmFzZSB1c2VkIHRvIGRlY3J5cHQgdGhlIGtleSBzaGFyZVxuICogQHJldHVybnMge2Jvb2xlYW59IC0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGRlY3J5cHRlZCBkYXRhIGNvbnRhaW5zIHZhbGlkIHNpZ25pbmcgbWF0ZXJpYWwsIG90aGVyd2lzZSBgZmFsc2VgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNHRzE4U2lnbmluZ01hdGVyaWFsKGtleVNoYXJlOiBzdHJpbmcsIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICBjb25zdCBwcnYgPSBzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwga2V5U2hhcmUpO1xuICB0cnkge1xuICAgIGNvbnN0IHNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UocHJ2KTtcbiAgICByZXR1cm4gKFxuICAgICAgc2lnbmluZ01hdGVyaWFsLnBTaGFyZSAmJlxuICAgICAgc2lnbmluZ01hdGVyaWFsLmJpdGdvTlNoYXJlICYmXG4gICAgICAoc2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUgfHwgc2lnbmluZ01hdGVyaWFsLmJhY2t1cE5TaGFyZSlcbiAgICApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCB0aGUgTVBDIHYyIHJlY292ZXJ5IGtleSBzaGFyZXMgZnJvbSB0aGUgcHJvdmlkZWQgdXNlciBhbmQgYmFja3VwIGtleSBzaGFyZXMuXG4gKiBAcGFyYW0gZW5jcnlwdGVkVXNlcktleSBlbmNyeXB0ZWQgZ2cxOCBvciBNUEN2MiB1c2VyIGtleVxuICogQHBhcmFtIGVuY3J5cHRlZEJhY2t1cEtleSBlbmNyeXB0ZWQgZ2cxOCBvciBNUEN2MiBiYWNrdXAga2V5XG4gKiBAcGFyYW0gd2FsbGV0UGFzc3BocmFzZSBwYXNzd29yZCBmb3IgdXNlciBhbmQgYmFja3VwIGtleVxuICogQHJldHVybnMgTVBDIHYyIHJlY292ZXJ5IGtleSBzaGFyZXNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldE1wY1YyUmVjb3ZlcnlLZXlTaGFyZXMoXG4gIGVuY3J5cHRlZFVzZXJLZXk6IHN0cmluZyxcbiAgZW5jcnlwdGVkQmFja3VwS2V5OiBzdHJpbmcsXG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmdcbik6IFByb21pc2U8e1xuICB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgY29tbW9uS2V5Q2hhaW46IHN0cmluZztcbn0+IHtcbiAgaWYgKGlzR0cxOFNpZ25pbmdNYXRlcmlhbChlbmNyeXB0ZWRVc2VyS2V5LCB3YWxsZXRQYXNzcGhyYXNlKSkge1xuICAgIHJldHVybiBnZXRNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbUdHMTgoZW5jcnlwdGVkVXNlcktleSwgZW5jcnlwdGVkQmFja3VwS2V5LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgfVxuICByZXR1cm4gZ2V0TXBjVjJSZWNvdmVyeUtleVNoYXJlc0Zyb21SZWR1Y2VkS2V5KGVuY3J5cHRlZFVzZXJLZXksIGVuY3J5cHRlZEJhY2t1cEtleSwgd2FsbGV0UGFzc3BocmFzZSk7XG59XG5cbi8qKlxuICogU2lnbnMgYSBtZXNzYWdlIGhhc2ggdXNpbmcgTVBDIHYyIHJlY292ZXJ5IGtleSBzaGFyZXMuXG4gKlxuICogQHBhcmFtIHtCdWZmZXJ9IG1lc3NhZ2VIYXNoXG4gKiBAcGFyYW0ge0J1ZmZlcn0gdXNlcktleVNoYXJlXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYmFja3VwS2V5U2hhcmVcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21tb25LZXlDaGFpblxuICogQHJldHVybnMge1Byb21pc2U8eyByZWNpZDogbnVtYmVyLCByOiBzdHJpbmcsIHM6IHN0cmluZywgeTogc3RyaW5nIH0+fVxuICpcbiAqIEBhc3luY1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2lnblJlY292ZXJ5TXBjVjIoXG4gIG1lc3NhZ2VIYXNoOiBCdWZmZXIsXG4gIHVzZXJLZXlTaGFyZTogQnVmZmVyLFxuICBiYWNrdXBLZXlTaGFyZTogQnVmZmVyLFxuICBjb21tb25LZXlDaGFpbjogc3RyaW5nXG4pOiBQcm9taXNlPHtcbiAgcmVjaWQ6IG51bWJlcjtcbiAgcjogc3RyaW5nO1xuICBzOiBzdHJpbmc7XG4gIHk6IHN0cmluZztcbn0+IHtcbiAgY29uc3QgdXNlckRzZyA9IG5ldyBEa2xzRHNnLkRzZyh1c2VyS2V5U2hhcmUsIDAsICdtLzAnLCBtZXNzYWdlSGFzaCk7XG4gIGNvbnN0IGJhY2t1cERzZyA9IG5ldyBEa2xzRHNnLkRzZyhiYWNrdXBLZXlTaGFyZSwgMSwgJ20vMCcsIG1lc3NhZ2VIYXNoKTtcblxuICBjb25zdCBzaWduYXR1cmVTdHJpbmcgPSBEa2xzVXRpbHMudmVyaWZ5QW5kQ29udmVydERrbHNTaWduYXR1cmUoXG4gICAgbWVzc2FnZUhhc2gsXG4gICAgKGF3YWl0IERrbHNVdGlscy5leGVjdXRlVGlsbFJvdW5kKDUsIHVzZXJEc2csIGJhY2t1cERzZykpIGFzIERrbHNUeXBlcy5EZXNlcmlhbGl6ZWREa2xzU2lnbmF0dXJlLFxuICAgIGNvbW1vbktleUNoYWluLFxuICAgICdtLzAnLFxuICAgIHVuZGVmaW5lZCxcbiAgICBmYWxzZVxuICApO1xuICBjb25zdCBzaWdQYXJ0cyA9IHNpZ25hdHVyZVN0cmluZy5zcGxpdCgnOicpO1xuXG4gIHJldHVybiB7XG4gICAgcmVjaWQ6IHBhcnNlSW50KHNpZ1BhcnRzWzBdLCAxMCksXG4gICAgcjogc2lnUGFydHNbMV0sXG4gICAgczogc2lnUGFydHNbMl0sXG4gICAgeTogc2lnUGFydHNbM10sXG4gIH07XG59XG5cbi8vICNyZWdpb24gcHJpdmF0ZSB1dGlsc1xuXG4vKipcbiAqIEdldCB0aGUgTVBDIHYyIHJlY292ZXJ5IGtleSBzaGFyZXMgZnJvbSB0aGUgcHJvdmlkZWQgdXNlciBhbmQgYmFja3VwIGtleSBzaGFyZXMuXG4gKiBAcGFyYW0gZW5jcnlwdGVkR0cxOFVzZXJLZXkgZW5jcnlwdGVkIGdnMTggdXNlciBrZXlcbiAqIEBwYXJhbSBlbmNyeXB0ZWRHRzE4QmFja3VwS2V5IGVuY3J5cHRlZCBnZzE4IGJhY2t1cCBrZXlcbiAqIEBwYXJhbSB3YWxsZXRQYXNzcGhyYXNlIHBhc3N3b3JkIGZvciB1c2VyIGFuZCBiYWNrdXAga2V5XG4gKiBAcmV0dXJucyBNUEMgdjIgcmVjb3Zlcnkga2V5IHNoYXJlc1xuICovXG5hc3luYyBmdW5jdGlvbiBnZXRNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbUdHMTgoXG4gIGVuY3J5cHRlZEdHMThVc2VyS2V5OiBzdHJpbmcsXG4gIGVuY3J5cHRlZEdHMThCYWNrdXBLZXk6IHN0cmluZyxcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZ1xuKTogUHJvbWlzZTx7XG4gIHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBiYWNrdXBLZXlTaGFyZTogQnVmZmVyO1xuICBjb21tb25LZXlDaGFpbjogc3RyaW5nO1xufT4ge1xuICBjb25zdCBbdXNlcktleUNvbWJpbmVkLCBiYWNrdXBLZXlDb21iaW5lZF0gPSBnZXRLZXlDb21iaW5lZEZyb21Uc3NLZXlTaGFyZXMoXG4gICAgZW5jcnlwdGVkR0cxOFVzZXJLZXksXG4gICAgZW5jcnlwdGVkR0cxOEJhY2t1cEtleSxcbiAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICk7XG4gIGNvbnN0IHJldHJvZml0RGF0YUE6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEgPSB7XG4gICAgeFNoYXJlOiB1c2VyS2V5Q29tYmluZWQueFNoYXJlLFxuICB9O1xuICBjb25zdCByZXRyb2ZpdERhdGFCOiBEa2xzVHlwZXMuUmV0cm9maXREYXRhID0ge1xuICAgIHhTaGFyZTogYmFja3VwS2V5Q29tYmluZWQueFNoYXJlLFxuICB9O1xuICBjb25zdCBbdXNlciwgYmFja3VwXSA9IGF3YWl0IERrbHNVdGlscy5nZW5lcmF0ZTJvZjJLZXlTaGFyZXMocmV0cm9maXREYXRhQSwgcmV0cm9maXREYXRhQik7XG5cbiAgY29uc3QgdXNlcktleVNoYXJlID0gdXNlci5nZXRLZXlTaGFyZSgpO1xuICBjb25zdCBiYWNrdXBLZXlTaGFyZSA9IGJhY2t1cC5nZXRLZXlTaGFyZSgpO1xuICByZXR1cm4ge1xuICAgIHVzZXJLZXlTaGFyZSxcbiAgICBiYWNrdXBLZXlTaGFyZSxcbiAgICBjb21tb25LZXlDaGFpbjogRGtsc1R5cGVzLmdldENvbW1vbktleWNoYWluKGJhY2t1cEtleVNoYXJlKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIE1QQyB2MiByZWNvdmVyeSBrZXkgc2hhcmVzIGZyb20gdGhlIHByb3ZpZGVkIHVzZXIgYW5kIGJhY2t1cCBrZXkgc2hhcmVzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmNyeXB0ZWRNUEN2MlVzZXJLZXlcbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmNyeXB0ZWRNUEN2MkJhY2t1cEtleVxuICogQHBhcmFtIHtzdHJpbmd9IFt3YWxsZXRQYXNzcGhyYXNlXSAtIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZGVjcnlwdCB0aGUga2V5IHNoYXJlc1xuICogQHJldHVybnMge1Byb21pc2U8eyB1c2VyS2V5U2hhcmU6IEtleVNoYXJlLCBiYWNrdXBLZXlTaGFyZTogS2V5U2hhcmUsIGNvbW1vbktleUNoYWluOiBzdHJpbmcgfT59XG4gKlxuICogQGFzeW5jXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdldE1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgZW5jcnlwdGVkTVBDdjJVc2VyS2V5OiBzdHJpbmcsXG4gIGVuY3J5cHRlZE1QQ3YyQmFja3VwS2V5OiBzdHJpbmcsXG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmdcbik6IFByb21pc2U8e1xuICB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgY29tbW9uS2V5Q2hhaW46IHN0cmluZztcbn0+IHtcbiAgY29uc3QgdXNlckNvbXByZXNzZWRQcnYgPSBCdWZmZXIuZnJvbShzamNsLmRlY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgZW5jcnlwdGVkTVBDdjJVc2VyS2V5KSwgJ2Jhc2U2NCcpO1xuICBjb25zdCBiYWtjdXBDb21wcmVzc2VkUHJ2ID0gQnVmZmVyLmZyb20oc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIGVuY3J5cHRlZE1QQ3YyQmFja3VwS2V5KSwgJ2Jhc2U2NCcpO1xuXG4gIGNvbnN0IHVzZXJQcnZKU09OOiBEa2xzVHlwZXMuUmVkdWNlZEtleVNoYXJlID0gRGtsc1R5cGVzLmdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUodXNlckNvbXByZXNzZWRQcnYpO1xuICBjb25zdCBiYWNrdXBQcnZKU09OOiBEa2xzVHlwZXMuUmVkdWNlZEtleVNoYXJlID0gRGtsc1R5cGVzLmdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUoYmFrY3VwQ29tcHJlc3NlZFBydik7XG4gIGNvbnN0IHVzZXJLZXlSZXRyb2ZpdDogRGtsc1R5cGVzLlJldHJvZml0RGF0YSA9IHtcbiAgICB4U2hhcmU6IHtcbiAgICAgIHg6IEJ1ZmZlci5mcm9tKHVzZXJQcnZKU09OLnBydikudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgeTogQnVmZmVyLmZyb20odXNlclBydkpTT04ucHViKS50b1N0cmluZygnaGV4JyksXG4gICAgICBjaGFpbmNvZGU6IEJ1ZmZlci5mcm9tKHVzZXJQcnZKU09OLnJvb3RDaGFpbkNvZGUpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICB9LFxuICAgIHhpTGlzdDogdXNlclBydkpTT04ueExpc3Quc2xpY2UoMCwgMiksXG4gIH07XG4gIGNvbnN0IGJhY2t1cEtleVJldHJvZml0OiBEa2xzVHlwZXMuUmV0cm9maXREYXRhID0ge1xuICAgIHhTaGFyZToge1xuICAgICAgeDogQnVmZmVyLmZyb20oYmFja3VwUHJ2SlNPTi5wcnYpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHk6IEJ1ZmZlci5mcm9tKGJhY2t1cFBydkpTT04ucHViKS50b1N0cmluZygnaGV4JyksXG4gICAgICBjaGFpbmNvZGU6IEJ1ZmZlci5mcm9tKGJhY2t1cFBydkpTT04ucm9vdENoYWluQ29kZSkudG9TdHJpbmcoJ2hleCcpLFxuICAgIH0sXG4gICAgeGlMaXN0OiBiYWNrdXBQcnZKU09OLnhMaXN0LnNsaWNlKDAsIDIpLFxuICB9O1xuICBjb25zdCBbdXNlciwgYmFja3VwXSA9IGF3YWl0IERrbHNVdGlscy5nZW5lcmF0ZTJvZjJLZXlTaGFyZXModXNlcktleVJldHJvZml0LCBiYWNrdXBLZXlSZXRyb2ZpdCk7XG4gIGNvbnN0IHVzZXJLZXlTaGFyZSA9IHVzZXIuZ2V0S2V5U2hhcmUoKTtcbiAgY29uc3QgYmFja3VwS2V5U2hhcmUgPSBiYWNrdXAuZ2V0S2V5U2hhcmUoKTtcbiAgY29uc3QgY29tbW9uS2V5Q2hhaW4gPSBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4odXNlcktleVNoYXJlKTtcbiAgcmV0dXJuIHsgdXNlcktleVNoYXJlLCBiYWNrdXBLZXlTaGFyZSwgY29tbW9uS2V5Q2hhaW4gfTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBjb21iaW5lZCBrZXkgZm9yIEdHMThcbiAqIEBwYXJhbSBlbmNyeXB0ZWRHRzE4VXNlcktleSBlbmNyeXB0ZWQgR0cxOCB1c2VyIGtleVxuICogQHBhcmFtIGVuY3J5cHRlZEdHMThCYWNrdXBLZXkgZW5jcnlwdGVkIEdHMTggYmFja3VwIGtleVxuICogQHBhcmFtIHdhbGxldFBhc3NwaHJhc2Ugd2FsbGV0IHBhc3NwaHJhc2VcbiAqIEByZXR1cm5zIGtleSBzaGFyZXNcbiAqL1xuZnVuY3Rpb24gZ2V0S2V5Q29tYmluZWRGcm9tVHNzS2V5U2hhcmVzKFxuICBlbmNyeXB0ZWRHRzE4VXNlcktleTogc3RyaW5nLFxuICBlbmNyeXB0ZWRHRzE4QmFja3VwS2V5OiBzdHJpbmcsXG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmdcbik6IFtFQ0RTQU1ldGhvZFR5cGVzLktleUNvbWJpbmVkLCBFQ0RTQU1ldGhvZFR5cGVzLktleUNvbWJpbmVkXSB7XG4gIGxldCBiYWNrdXBQcnY7XG4gIGxldCB1c2VyUHJ2O1xuICB0cnkge1xuICAgIGJhY2t1cFBydiA9IHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCBlbmNyeXB0ZWRHRzE4QmFja3VwS2V5KTtcbiAgICB1c2VyUHJ2ID0gc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIGVuY3J5cHRlZEdHMThVc2VyS2V5KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXJyb3IgZGVjcnlwdGluZyBiYWNrdXAga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICB9XG5cbiAgY29uc3QgdXNlclNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UodXNlclBydikgYXMgRUNEU0FNZXRob2RUeXBlcy5TaWduaW5nTWF0ZXJpYWw7XG4gIGNvbnN0IGJhY2t1cFNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UoYmFja3VwUHJ2KSBhcyBFQ0RTQU1ldGhvZFR5cGVzLlNpZ25pbmdNYXRlcmlhbDtcblxuICBpZiAoIXVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHVzZXIga2V5IC0gbWlzc2luZyBiYWNrdXBOU2hhcmUnKTtcbiAgfVxuXG4gIGlmICghYmFja3VwU2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYmFja3VwIGtleSAtIG1pc3NpbmcgdXNlck5TaGFyZScpO1xuICB9XG5cbiAgY29uc3QgTVBDID0gbmV3IEVjZHNhKCk7XG5cbiAgY29uc3QgdXNlcktleUNvbWJpbmVkID0gTVBDLmtleUNvbWJpbmUodXNlclNpZ25pbmdNYXRlcmlhbC5wU2hhcmUsIFtcbiAgICB1c2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvTlNoYXJlLFxuICAgIHVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwTlNoYXJlLFxuICBdKTtcbiAgY29uc3QgYmFja3VwS2V5Q29tYmluZWQgPSBNUEMua2V5Q29tYmluZShiYWNrdXBTaWduaW5nTWF0ZXJpYWwucFNoYXJlLCBbXG4gICAgYmFja3VwU2lnbmluZ01hdGVyaWFsLnVzZXJOU2hhcmUsXG4gICAgYmFja3VwU2lnbmluZ01hdGVyaWFsLmJpdGdvTlNoYXJlLFxuICBdKTtcbiAgaWYgKFxuICAgIHVzZXJLZXlDb21iaW5lZC54U2hhcmUueSAhPT0gYmFja3VwS2V5Q29tYmluZWQueFNoYXJlLnkgfHxcbiAgICB1c2VyS2V5Q29tYmluZWQueFNoYXJlLmNoYWluY29kZSAhPT0gYmFja3VwS2V5Q29tYmluZWQueFNoYXJlLmNoYWluY29kZVxuICApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyk7XG4gIH1cbiAgcmV0dXJuIFt1c2VyS2V5Q29tYmluZWQsIGJhY2t1cEtleUNvbWJpbmVkXTtcbn1cblxuLy8gI2VuZHJlZ2lvblxuIl19