@bitgo-beta/sdk-core 8.2.1-beta.188 → 8.2.1-beta.1880

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 (640) 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 +53 -5
  10. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  11. package/dist/src/account-lib/baseCoin/enum.js +97 -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 +31 -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 +150 -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 +112 -11
  96. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  97. package/dist/src/bitgo/baseCoin/baseCoin.js +183 -16
  98. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +270 -27
  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 +8 -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/defi/defiVault.d.ts +87 -0
  118. package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -0
  119. package/dist/src/bitgo/defi/defiVault.js +225 -0
  120. package/dist/src/bitgo/defi/iDefiVault.d.ts +59 -0
  121. package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -0
  122. package/dist/src/bitgo/defi/iDefiVault.js +6 -0
  123. package/dist/src/bitgo/defi/index.d.ts +3 -0
  124. package/dist/src/bitgo/defi/index.d.ts.map +1 -0
  125. package/dist/src/bitgo/defi/index.js +22 -0
  126. package/dist/src/bitgo/ecdh.d.ts +0 -1
  127. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  128. package/dist/src/bitgo/ecdh.js +26 -13
  129. package/dist/src/bitgo/enterprise/enterprise.d.ts +3 -4
  130. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  131. package/dist/src/bitgo/enterprise/enterprise.js +39 -21
  132. package/dist/src/bitgo/enterprise/enterprises.js +27 -13
  133. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +2 -3
  134. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  135. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  136. package/dist/src/bitgo/enterprise/index.js +6 -2
  137. package/dist/src/bitgo/environments.d.ts +69 -5
  138. package/dist/src/bitgo/environments.d.ts.map +1 -1
  139. package/dist/src/bitgo/environments.js +409 -40
  140. package/dist/src/bitgo/errors.d.ts +175 -0
  141. package/dist/src/bitgo/errors.d.ts.map +1 -1
  142. package/dist/src/bitgo/errors.js +166 -2
  143. package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
  144. package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
  145. package/dist/src/bitgo/evm/evmUtils.js +50 -0
  146. package/dist/src/bitgo/index.d.ts +4 -1
  147. package/dist/src/bitgo/index.d.ts.map +1 -1
  148. package/dist/src/bitgo/index.js +30 -11
  149. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  150. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  151. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  152. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  153. package/dist/src/bitgo/internal/index.js +6 -2
  154. package/dist/src/bitgo/internal/internal.js +5 -6
  155. package/dist/src/bitgo/internal/keycard.d.ts +19 -6
  156. package/dist/src/bitgo/internal/keycard.d.ts.map +1 -1
  157. package/dist/src/bitgo/internal/keycard.js +108 -48
  158. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +24 -0
  159. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  160. package/dist/src/bitgo/keychain/decryptKeychain.js +67 -0
  161. package/dist/src/bitgo/keychain/iKeychains.d.ts +95 -9
  162. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  163. package/dist/src/bitgo/keychain/iKeychains.js +2 -2
  164. package/dist/src/bitgo/keychain/index.d.ts +1 -0
  165. package/dist/src/bitgo/keychain/index.d.ts.map +1 -1
  166. package/dist/src/bitgo/keychain/index.js +7 -2
  167. package/dist/src/bitgo/keychain/keychains.d.ts +49 -6
  168. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  169. package/dist/src/bitgo/keychain/keychains.js +249 -46
  170. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +3 -3
  171. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  172. package/dist/src/bitgo/keychain/ovcJsonCodec.js +23 -9
  173. package/dist/src/bitgo/legacyBitcoin.d.ts +0 -1
  174. package/dist/src/bitgo/legacyBitcoin.d.ts.map +1 -1
  175. package/dist/src/bitgo/legacyBitcoin.js +27 -13
  176. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts +7 -0
  177. package/dist/src/bitgo/lightning/lightningWalletUtil.d.ts.map +1 -0
  178. package/dist/src/bitgo/lightning/lightningWalletUtil.js +25 -0
  179. package/dist/src/bitgo/market/iMarkets.d.ts +2 -2
  180. package/dist/src/bitgo/market/iMarkets.d.ts.map +1 -1
  181. package/dist/src/bitgo/market/index.js +6 -2
  182. package/dist/src/bitgo/market/markets.js +23 -9
  183. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts +1 -0
  184. package/dist/src/bitgo/pendingApproval/iPendingApproval.d.ts.map +1 -1
  185. package/dist/src/bitgo/pendingApproval/iPendingApproval.js +4 -4
  186. package/dist/src/bitgo/pendingApproval/index.js +6 -2
  187. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts +20 -8
  188. package/dist/src/bitgo/pendingApproval/pendingApproval.d.ts.map +1 -1
  189. package/dist/src/bitgo/pendingApproval/pendingApproval.js +228 -110
  190. package/dist/src/bitgo/pendingApproval/pendingApprovals.js +23 -9
  191. package/dist/src/bitgo/proofs/WalletProofs.d.ts +19 -0
  192. package/dist/src/bitgo/proofs/WalletProofs.d.ts.map +1 -0
  193. package/dist/src/bitgo/proofs/WalletProofs.js +37 -0
  194. package/dist/src/bitgo/proofs/index.d.ts +2 -0
  195. package/dist/src/bitgo/proofs/index.d.ts.map +1 -0
  196. package/dist/src/bitgo/proofs/index.js +6 -0
  197. package/dist/src/bitgo/proofs/types.d.ts +80 -0
  198. package/dist/src/bitgo/proofs/types.d.ts.map +1 -0
  199. package/dist/src/bitgo/proofs/types.js +80 -0
  200. package/dist/src/bitgo/recovery/index.js +6 -2
  201. package/dist/src/bitgo/recovery/initiate.d.ts +24 -1
  202. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  203. package/dist/src/bitgo/recovery/initiate.js +88 -40
  204. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +136 -0
  205. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts.map +1 -0
  206. package/dist/src/bitgo/staking/goStakingInterfaces.js +3 -0
  207. package/dist/src/bitgo/staking/goStakingWallet.d.ts +62 -0
  208. package/dist/src/bitgo/staking/goStakingWallet.d.ts.map +1 -0
  209. package/dist/src/bitgo/staking/goStakingWallet.js +141 -0
  210. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts +17 -0
  211. package/dist/src/bitgo/staking/iGoStakingWallet.d.ts.map +1 -0
  212. package/dist/src/bitgo/staking/iGoStakingWallet.js +3 -0
  213. package/dist/src/bitgo/staking/iStakingWallet.d.ts +178 -7
  214. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  215. package/dist/src/bitgo/staking/iStakingWallet.js +2 -2
  216. package/dist/src/bitgo/staking/index.d.ts +3 -0
  217. package/dist/src/bitgo/staking/index.d.ts.map +1 -1
  218. package/dist/src/bitgo/staking/index.js +9 -2
  219. package/dist/src/bitgo/staking/stakingWallet.d.ts +21 -8
  220. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  221. package/dist/src/bitgo/staking/stakingWallet.js +140 -7
  222. package/dist/src/bitgo/trading/iTradingAccount.d.ts +15 -1
  223. package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
  224. package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
  225. package/dist/src/bitgo/trading/index.d.ts +1 -0
  226. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  227. package/dist/src/bitgo/trading/index.js +7 -2
  228. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts +8 -0
  229. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.d.ts.map +1 -0
  230. package/dist/src/bitgo/trading/network/decrypt-aes-gcm.js +31 -0
  231. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts +8 -0
  232. package/dist/src/bitgo/trading/network/decrypt-rsa.d.ts.map +1 -0
  233. package/dist/src/bitgo/trading/network/decrypt-rsa.js +23 -0
  234. package/dist/src/bitgo/trading/network/decrypt.d.ts +14 -0
  235. package/dist/src/bitgo/trading/network/decrypt.d.ts.map +1 -0
  236. package/dist/src/bitgo/trading/network/decrypt.js +23 -0
  237. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts +8 -0
  238. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.d.ts.map +1 -0
  239. package/dist/src/bitgo/trading/network/encrypt-aes-gcm.js +25 -0
  240. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts +8 -0
  241. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.d.ts.map +1 -0
  242. package/dist/src/bitgo/trading/network/encrypt-rsa-browser.js +65 -0
  243. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts +8 -0
  244. package/dist/src/bitgo/trading/network/encrypt-rsa.d.ts.map +1 -0
  245. package/dist/src/bitgo/trading/network/encrypt-rsa.js +23 -0
  246. package/dist/src/bitgo/trading/network/encrypt.d.ts +37 -0
  247. package/dist/src/bitgo/trading/network/encrypt.d.ts.map +1 -0
  248. package/dist/src/bitgo/trading/network/encrypt.js +58 -0
  249. package/dist/src/bitgo/trading/network/index.d.ts +5 -0
  250. package/dist/src/bitgo/trading/network/index.d.ts.map +1 -0
  251. package/dist/src/bitgo/trading/network/index.js +21 -0
  252. package/dist/src/bitgo/trading/network/network.d.ts +36 -0
  253. package/dist/src/bitgo/trading/network/network.d.ts.map +1 -0
  254. package/dist/src/bitgo/trading/network/network.js +99 -0
  255. package/dist/src/bitgo/trading/network/types.d.ts +277 -0
  256. package/dist/src/bitgo/trading/network/types.d.ts.map +1 -0
  257. package/dist/src/bitgo/trading/network/types.js +3 -0
  258. package/dist/src/bitgo/trading/network/utils.d.ts +20 -0
  259. package/dist/src/bitgo/trading/network/utils.d.ts.map +1 -0
  260. package/dist/src/bitgo/trading/network/utils.js +54 -0
  261. package/dist/src/bitgo/trading/tradingAccount.d.ts +22 -1
  262. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  263. package/dist/src/bitgo/trading/tradingAccount.js +64 -7
  264. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +38 -0
  265. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  266. package/dist/src/bitgo/tss/bitgoPubKeys.js +72 -0
  267. package/dist/src/bitgo/tss/common.d.ts +40 -6
  268. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  269. package/dist/src/bitgo/tss/common.js +122 -17
  270. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +6 -4
  271. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  272. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +78 -66
  273. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts +15 -0
  274. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  275. package/dist/src/bitgo/tss/ecdsa/ecdsaMPCv2.js +167 -0
  276. package/dist/src/bitgo/tss/ecdsa/index.d.ts +1 -0
  277. package/dist/src/bitgo/tss/ecdsa/index.d.ts.map +1 -1
  278. package/dist/src/bitgo/tss/ecdsa/index.js +25 -10
  279. package/dist/src/bitgo/tss/ecdsa/types.d.ts +27 -27
  280. package/dist/src/bitgo/tss/ecdsa/types.d.ts.map +1 -1
  281. package/dist/src/bitgo/tss/ecdsa/types.js +3 -3
  282. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts +15 -6
  283. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  284. package/dist/src/bitgo/tss/eddsa/eddsa.js +47 -40
  285. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts +37 -0
  286. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  287. package/dist/src/bitgo/tss/eddsa/eddsaMPCv2.js +95 -0
  288. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  289. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  290. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  291. package/dist/src/bitgo/tss/index.d.ts +3 -2
  292. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  293. package/dist/src/bitgo/tss/index.js +26 -10
  294. package/dist/src/bitgo/tss/types.d.ts +3 -3
  295. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  296. package/dist/src/bitgo/tss/types.js +2 -2
  297. package/dist/src/bitgo/types.d.ts +3 -3
  298. package/dist/src/bitgo/types.d.ts.map +1 -1
  299. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +8 -0
  300. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  301. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +55 -13
  302. package/dist/src/bitgo/utils/codecProps.js +24 -11
  303. package/dist/src/bitgo/utils/codecs.d.ts +11 -0
  304. package/dist/src/bitgo/utils/codecs.d.ts.map +1 -0
  305. package/dist/src/bitgo/utils/codecs.js +59 -0
  306. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  307. package/dist/src/bitgo/utils/decode.js +30 -16
  308. package/dist/src/bitgo/utils/index.d.ts +4 -2
  309. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  310. package/dist/src/bitgo/utils/index.js +27 -11
  311. package/dist/src/bitgo/utils/messageTypes.d.ts +40 -0
  312. package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
  313. package/dist/src/bitgo/utils/messageTypes.js +17 -0
  314. package/dist/src/bitgo/utils/mpcUtils.d.ts +4 -4
  315. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  316. package/dist/src/bitgo/utils/mpcUtils.js +153 -14
  317. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  318. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  319. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  320. package/dist/src/bitgo/utils/opengpgUtils.d.ts +10 -7
  321. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  322. package/dist/src/bitgo/utils/opengpgUtils.js +75 -62
  323. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -1
  324. package/dist/src/bitgo/utils/postWithCodec.js +4 -38
  325. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  326. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  327. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  328. package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
  329. package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
  330. package/dist/src/bitgo/utils/transactionUtils.js +29 -0
  331. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  332. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  333. package/dist/src/bitgo/utils/triple.js +2 -3
  334. package/dist/src/bitgo/utils/tss/addressVerification.d.ts +62 -0
  335. package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  336. package/dist/src/bitgo/utils/tss/addressVerification.js +100 -0
  337. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +97 -18
  338. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  339. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +307 -46
  340. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +414 -46
  341. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  342. package/dist/src/bitgo/utils/tss/baseTypes.js +47 -22
  343. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  344. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  345. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  346. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  347. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  348. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  349. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +24 -51
  350. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  351. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +172 -246
  352. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +210 -0
  353. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  354. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +1074 -0
  355. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
  356. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  357. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +13 -0
  358. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
  359. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  360. package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
  361. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +7 -10
  362. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  363. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  364. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
  365. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  366. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  367. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts +21 -0
  368. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.d.ts.map +1 -0
  369. package/dist/src/bitgo/utils/tss/eddsa/SMC/utils.js +118 -0
  370. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts +18 -0
  371. package/dist/src/bitgo/utils/tss/eddsa/base.d.ts.map +1 -0
  372. package/dist/src/bitgo/utils/tss/eddsa/base.js +64 -0
  373. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +28 -11
  374. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  375. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +218 -103
  376. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +137 -0
  377. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  378. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +659 -0
  379. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts +6 -0
  380. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.d.ts.map +1 -0
  381. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2KeyGenSender.js +13 -0
  382. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +4 -0
  383. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
  384. package/dist/src/bitgo/utils/tss/eddsa/index.js +29 -8
  385. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +12 -7
  386. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  387. package/dist/src/bitgo/utils/tss/eddsa/types.js +1 -1
  388. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +40 -0
  389. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -0
  390. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +44 -0
  391. package/dist/src/bitgo/utils/tss/index.d.ts +3 -0
  392. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  393. package/dist/src/bitgo/utils/tss/index.js +26 -9
  394. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts +23 -0
  395. package/dist/src/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  396. package/dist/src/bitgo/utils/tss/preHashedSignable.js +26 -0
  397. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts +33 -0
  398. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  399. package/dist/src/bitgo/utils/tss/recipientUtils.js +117 -0
  400. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  401. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  402. package/dist/src/bitgo/utils/txRequest.js +49 -0
  403. package/dist/src/bitgo/utils/util.js +24 -10
  404. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  405. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  406. package/dist/src/bitgo/utils/wallet.js +48 -0
  407. package/dist/src/bitgo/wallet/BuildParams.d.ts +50 -1
  408. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
  409. package/dist/src/bitgo/wallet/BuildParams.js +58 -11
  410. package/dist/src/bitgo/wallet/iWallet.d.ts +496 -21
  411. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  412. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  413. package/dist/src/bitgo/wallet/iWallets.d.ts +157 -16
  414. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  415. package/dist/src/bitgo/wallet/iWallets.js +63 -3
  416. package/dist/src/bitgo/wallet/index.js +6 -2
  417. package/dist/src/bitgo/wallet/wallet.d.ts +360 -24
  418. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  419. package/dist/src/bitgo/wallet/wallet.js +2017 -355
  420. package/dist/src/bitgo/wallet/wallets.d.ts +88 -4
  421. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  422. package/dist/src/bitgo/wallet/wallets.js +1048 -155
  423. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
  424. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
  425. package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
  426. package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
  427. package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
  428. package/dist/src/bitgo/walletUtil/index.js +19 -0
  429. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
  430. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
  431. package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
  432. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
  433. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
  434. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
  435. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
  436. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
  437. package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
  438. package/dist/src/bitgo/webhook/index.js +6 -2
  439. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  440. package/dist/src/coins/fiat.d.ts +45 -0
  441. package/dist/src/coins/fiat.d.ts.map +1 -0
  442. package/dist/src/coins/fiat.js +94 -0
  443. package/dist/src/coins/index.d.ts +1 -6
  444. package/dist/src/coins/index.d.ts.map +1 -1
  445. package/dist/src/coins/index.js +7 -8
  446. package/dist/src/coins/ofc.d.ts +21 -2
  447. package/dist/src/coins/ofc.d.ts.map +1 -1
  448. package/dist/src/coins/ofc.js +29 -3
  449. package/dist/src/coins/ofcToken.d.ts +15 -4
  450. package/dist/src/coins/ofcToken.d.ts.map +1 -1
  451. package/dist/src/coins/ofcToken.js +43 -5
  452. package/dist/src/coins/susd.d.ts +3 -2
  453. package/dist/src/coins/susd.d.ts.map +1 -1
  454. package/dist/src/coins/susd.js +5 -1
  455. package/dist/src/common.js +27 -13
  456. package/dist/src/index.d.ts +6 -1
  457. package/dist/src/index.d.ts.map +1 -1
  458. package/dist/src/index.js +32 -11
  459. package/dist/src/lightning.d.ts +20 -0
  460. package/dist/src/lightning.d.ts.map +1 -0
  461. package/dist/src/lightning.js +13 -0
  462. package/dist/src/units.js +5 -6
  463. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
  464. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  465. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
  466. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
  467. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  468. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
  469. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
  470. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  471. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
  472. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
  473. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
  474. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
  475. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +91 -29
  476. package/dist/test/unit/account-lib/mpc/util.d.ts +2 -0
  477. package/dist/test/unit/account-lib/mpc/util.d.ts.map +1 -0
  478. package/dist/test/unit/account-lib/mpc/util.js +53 -0
  479. package/dist/test/unit/bitgo/address-book/address-book.d.ts +2 -0
  480. package/dist/test/unit/bitgo/address-book/address-book.d.ts.map +1 -0
  481. package/dist/test/unit/bitgo/address-book/address-book.js +159 -0
  482. package/dist/test/unit/bitgo/defi/defiVault.d.ts +2 -0
  483. package/dist/test/unit/bitgo/defi/defiVault.d.ts.map +1 -0
  484. package/dist/test/unit/bitgo/defi/defiVault.js +338 -0
  485. package/dist/test/unit/bitgo/environment.d.ts +2 -0
  486. package/dist/test/unit/bitgo/environment.d.ts.map +1 -0
  487. package/dist/test/unit/bitgo/environment.js +38 -0
  488. package/dist/test/unit/bitgo/errors.d.ts +2 -0
  489. package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
  490. package/dist/test/unit/bitgo/errors.js +262 -0
  491. package/dist/test/unit/bitgo/recovery/initiate.d.ts +2 -0
  492. package/dist/test/unit/bitgo/recovery/initiate.d.ts.map +1 -0
  493. package/dist/test/unit/bitgo/recovery/initiate.js +230 -0
  494. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  495. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  496. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  497. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +2 -0
  498. package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +1 -0
  499. package/dist/test/unit/bitgo/trading/tradingAccount.js +192 -0
  500. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +24 -4
  501. package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
  502. package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
  503. package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
  504. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  505. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  506. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  507. package/dist/test/unit/bitgo/utils/postWithCodec.js +32 -38
  508. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts +2 -0
  509. package/dist/test/unit/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  510. package/dist/test/unit/bitgo/utils/tss/addressVerification.js +247 -0
  511. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts +2 -0
  512. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -0
  513. package/dist/test/unit/bitgo/utils/tss/baseTSSUtils.js +399 -0
  514. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts +2 -0
  515. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.d.ts.map +1 -0
  516. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaEncryptionVersion.js +94 -0
  517. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +2 -0
  518. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  519. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +880 -0
  520. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts +5 -0
  521. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts.map +1 -0
  522. package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.js +36 -0
  523. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +2 -0
  524. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -0
  525. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaMPCv2.js +1307 -0
  526. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts +2 -0
  527. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.d.ts.map +1 -0
  528. package/dist/test/unit/bitgo/utils/tss/eddsa/smcUtil.js +311 -0
  529. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts +2 -0
  530. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.d.ts.map +1 -0
  531. package/dist/test/unit/bitgo/utils/tss/preHashedSignable.js +55 -0
  532. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts +2 -0
  533. package/dist/test/unit/bitgo/utils/tss/recipientUtils.d.ts.map +1 -0
  534. package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +171 -0
  535. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  536. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  537. package/dist/test/unit/bitgo/utils/txRequest.js +179 -0
  538. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  539. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  540. package/dist/test/unit/bitgo/wallet/BuildParams.js +97 -0
  541. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +23 -9
  542. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts +2 -0
  543. package/dist/test/unit/bitgo/wallet/getAccountResources.d.ts.map +1 -0
  544. package/dist/test/unit/bitgo/wallet/getAccountResources.js +133 -0
  545. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts +2 -0
  546. package/dist/test/unit/bitgo/wallet/getResourceDelegations.d.ts.map +1 -0
  547. package/dist/test/unit/bitgo/wallet/getResourceDelegations.js +118 -0
  548. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts +2 -0
  549. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.d.ts.map +1 -0
  550. package/dist/test/unit/bitgo/wallet/ofcWalletAddressCreation.js +141 -0
  551. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +2 -0
  552. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +1 -0
  553. package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +185 -0
  554. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts +3 -0
  555. package/dist/test/unit/bitgo/wallet/resourceManagement.d.ts.map +1 -0
  556. package/dist/test/unit/bitgo/wallet/resourceManagement.js +441 -0
  557. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
  558. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
  559. package/dist/test/unit/bitgo/wallet/tokenApproval.js +201 -0
  560. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
  561. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
  562. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
  563. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts +2 -0
  564. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.d.ts.map +1 -0
  565. package/dist/test/unit/bitgo/wallet/walletOptionsCodecs.js +43 -0
  566. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts +2 -0
  567. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.d.ts.map +1 -0
  568. package/dist/test/unit/bitgo/wallet/walletTssAddressVerification.js +320 -0
  569. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts +2 -0
  570. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.d.ts.map +1 -0
  571. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.js +228 -0
  572. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
  573. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
  574. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
  575. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts +2 -0
  576. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.d.ts.map +1 -0
  577. package/dist/test/unit/bitgo/wallet/walletsExternalSigner.js +320 -0
  578. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts +2 -0
  579. package/dist/test/unit/bitgo/wallet/walletsWebauthn.d.ts.map +1 -0
  580. package/dist/test/unit/bitgo/wallet/walletsWebauthn.js +204 -0
  581. package/dist/test/unit/coins/ofc.d.ts +2 -0
  582. package/dist/test/unit/coins/ofc.d.ts.map +1 -0
  583. package/dist/test/unit/coins/ofc.js +124 -0
  584. package/dist/test/unit/lightning.d.ts +2 -0
  585. package/dist/test/unit/lightning.d.ts.map +1 -0
  586. package/dist/test/unit/lightning.js +23 -0
  587. package/dist/test/unit/units.d.ts.map +1 -1
  588. package/dist/test/unit/units.js +64 -64
  589. package/dist/tsconfig.tsbuildinfo +1 -1
  590. package/package.json +24 -21
  591. package/.eslintignore +0 -5
  592. package/CHANGELOG.md +0 -1568
  593. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  594. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  595. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  596. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  597. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  598. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  599. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  600. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  601. package/dist/src/bitgo/lightning/index.js +0 -17
  602. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  603. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  604. package/dist/src/bitgo/lightning/lightning.js +0 -111
  605. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  606. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  607. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  608. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  609. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  610. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  611. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  612. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  613. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  614. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  615. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  616. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  617. package/dist/src/coins/fiateur.d.ts +0 -31
  618. package/dist/src/coins/fiateur.d.ts.map +0 -1
  619. package/dist/src/coins/fiateur.js +0 -57
  620. package/dist/src/coins/fiatgbp.d.ts +0 -31
  621. package/dist/src/coins/fiatgbp.d.ts.map +0 -1
  622. package/dist/src/coins/fiatgbp.js +0 -57
  623. package/dist/src/coins/fiatusd.d.ts +0 -31
  624. package/dist/src/coins/fiatusd.d.ts.map +0 -1
  625. package/dist/src/coins/fiatusd.js +0 -57
  626. package/dist/src/coins/tfiateur.d.ts +0 -11
  627. package/dist/src/coins/tfiateur.d.ts.map +0 -1
  628. package/dist/src/coins/tfiateur.js +0 -17
  629. package/dist/src/coins/tfiatgbp.d.ts +0 -11
  630. package/dist/src/coins/tfiatgbp.d.ts.map +0 -1
  631. package/dist/src/coins/tfiatgbp.js +0 -17
  632. package/dist/src/coins/tfiatusd.d.ts +0 -11
  633. package/dist/src/coins/tfiatusd.d.ts.map +0 -1
  634. package/dist/src/coins/tfiatusd.js +0 -17
  635. package/dist/src/openssl/index.d.ts +0 -5
  636. package/dist/src/openssl/index.d.ts.map +0 -1
  637. package/dist/src/openssl/index.js +0 -9
  638. package/dist/test/unit/openssl.d.ts +0 -2
  639. package/dist/test/unit/openssl.d.ts.map +0 -1
  640. package/dist/test/unit/openssl.js +0 -39
@@ -0,0 +1,1307 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const sinon = __importStar(require("sinon"));
38
+ const pgp = __importStar(require("openpgp"));
39
+ const crypto_1 = require("crypto");
40
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
41
+ const ed25519_1 = require("@noble/curves/ed25519");
42
+ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
43
+ const public_types_1 = require("@bitgo/public-types");
44
+ const src_1 = require("../../../../../../src");
45
+ const eddsaMPCv2_1 = require("../../../../../../src/bitgo/tss/eddsa/eddsaMPCv2");
46
+ const common_1 = require("../../../../../../src/bitgo/tss/common");
47
+ const codecs_1 = require("../../../../../../src/bitgo/utils/codecs");
48
+ const opengpgUtils_1 = require("../../../../../../src/bitgo/utils/opengpgUtils");
49
+ const typesMPCv2_1 = require("../../../../../../src/bitgo/utils/tss/ecdsa/typesMPCv2");
50
+ const baseTypes_1 = require("../../../../../../src/bitgo/utils/tss/baseTypes");
51
+ describe('EdDSA MPS DSG helper functions', async () => {
52
+ let userKeyShare;
53
+ let backupKeyShare;
54
+ let bitgoKeyShare;
55
+ let userGpgPrivKey;
56
+ let backupGpgPrivKey;
57
+ let bitgoGpgPrivKey;
58
+ let bitgoGpgPubKey;
59
+ const signableHex = 'deadbeef';
60
+ const derivationPath = 'm/0';
61
+ before('generate EdDSA DKG key shares', async () => {
62
+ const userGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
63
+ const backupGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
64
+ const bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
65
+ userGpgPrivKey = await pgp.readPrivateKey({ armoredKey: userGpgKeyPair.privateKey });
66
+ backupGpgPrivKey = await pgp.readPrivateKey({ armoredKey: backupGpgKeyPair.privateKey });
67
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
68
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
69
+ const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
70
+ userKeyShare = userDkg.getKeyShare();
71
+ backupKeyShare = backupDkg.getKeyShare();
72
+ bitgoKeyShare = bitgoDkg.getKeyShare();
73
+ });
74
+ // ── Round 1 ─────────────────────────────────────────────────────────────────
75
+ it('getSignatureShareRoundOne should build a valid round-1 share', async () => {
76
+ const messageBuffer = Buffer.from(signableHex, 'hex');
77
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
78
+ userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
79
+ const userMsg1 = userDsg.getFirstMessage();
80
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(userMsg1, userGpgPrivKey);
81
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
82
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
83
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
84
+ assert.strictEqual(parsed.type, 'round1Input');
85
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
86
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
87
+ });
88
+ it('getSignatureShareRoundOne should build a valid backup round-1 share', async () => {
89
+ const messageBuffer = Buffer.from(signableHex, 'hex');
90
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
91
+ backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
92
+ const backupMsg1 = backupDsg.getFirstMessage();
93
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundOne)(backupMsg1, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
94
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
95
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
96
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound1Input');
97
+ assert.strictEqual(parsed.type, 'round1Input');
98
+ assert.ok(parsed.data.msg1.message, 'msg1.message should be set');
99
+ assert.ok(parsed.data.msg1.signature, 'msg1.signature should be set');
100
+ });
101
+ it('verifyPeerMessageRoundOne should verify a valid BitGo round-1 message', async () => {
102
+ const messageBuffer = Buffer.from(signableHex, 'hex');
103
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
104
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
105
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
106
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
107
+ const round1Output = {
108
+ type: 'round1Output',
109
+ data: { msg1: bitgoSignedMsg1 },
110
+ };
111
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey);
112
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
113
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
114
+ });
115
+ it('verifyPeerMessageRoundOne should throw on a tampered message', async () => {
116
+ const round1Output = {
117
+ type: 'round1Output',
118
+ data: {
119
+ msg1: {
120
+ message: Buffer.from('tampered').toString('base64'),
121
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
122
+ },
123
+ },
124
+ };
125
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundOne)(round1Output, bitgoGpgPubKey), 'should throw on invalid signature');
126
+ });
127
+ // ── Round 2 ─────────────────────────────────────────────────────────────────
128
+ it('getSignatureShareRoundTwo should build a valid round-2 share', async () => {
129
+ const messageBuffer = Buffer.from(signableHex, 'hex');
130
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
131
+ userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
132
+ const userMsg1 = userDsg.getFirstMessage();
133
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
134
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
135
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
136
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
137
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
138
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
139
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(userMsg2, userGpgPrivKey);
140
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
141
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
142
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
143
+ assert.strictEqual(parsed.type, 'round2Input');
144
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
145
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
146
+ });
147
+ it('getSignatureShareRoundTwo should build a valid backup round-2 share', async () => {
148
+ const messageBuffer = Buffer.from(signableHex, 'hex');
149
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
150
+ backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
151
+ const backupMsg1 = backupDsg.getFirstMessage();
152
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
153
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
154
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
155
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
156
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
157
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
158
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundTwo)(backupMsg2, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
159
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
160
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
161
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound2Input');
162
+ assert.strictEqual(parsed.type, 'round2Input');
163
+ assert.ok(parsed.data.msg2.message, 'msg2.message should be set');
164
+ assert.ok(parsed.data.msg2.signature, 'msg2.signature should be set');
165
+ });
166
+ it('verifyPeerMessageRoundTwo should verify a valid BitGo round-2 message', async () => {
167
+ const messageBuffer = Buffer.from(signableHex, 'hex');
168
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
169
+ userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
170
+ const userMsg1 = userDsg.getFirstMessage();
171
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
172
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
173
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
174
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
175
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
176
+ const round2Output = {
177
+ type: 'round2Output',
178
+ data: { msg2: bitgoSignedMsg2 },
179
+ };
180
+ const result = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey);
181
+ assert.strictEqual(result.from, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
182
+ assert.ok(result.payload.length > 0, 'payload should be non-empty');
183
+ });
184
+ it('verifyPeerMessageRoundTwo should throw on a tampered message', async () => {
185
+ const round2Output = {
186
+ type: 'round2Output',
187
+ data: {
188
+ msg2: {
189
+ message: Buffer.from('tampered').toString('base64'),
190
+ signature: '-----BEGIN PGP SIGNATURE-----\n\nINVALID\n-----END PGP SIGNATURE-----\n',
191
+ },
192
+ },
193
+ };
194
+ await assert.rejects((0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)(round2Output, bitgoGpgPubKey), 'should throw on invalid signature');
195
+ });
196
+ // ── Round 3 ─────────────────────────────────────────────────────────────────
197
+ it('getSignatureShareRoundThree should build a valid round-3 share', async () => {
198
+ const messageBuffer = Buffer.from(signableHex, 'hex');
199
+ const userDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.USER);
200
+ userDsg.initDsg(userKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
201
+ const userMsg1 = userDsg.getFirstMessage();
202
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
203
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
204
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
205
+ // Advance to round 2
206
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
207
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
208
+ const [userMsg2] = userDsg.handleIncomingMessages([userMsg1, bitgoDeserializedMsg1]);
209
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
210
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
211
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
212
+ const [userMsg3] = userDsg.handleIncomingMessages([userMsg2, bitgoDeserializedMsg2]);
213
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(userMsg3, userGpgPrivKey);
214
+ assert.strictEqual(share.from, src_1.SignatureShareType.USER);
215
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
216
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
217
+ assert.strictEqual(parsed.type, 'round3Input');
218
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
219
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
220
+ });
221
+ it('getSignatureShareRoundThree should build a valid backup round-3 share', async () => {
222
+ const messageBuffer = Buffer.from(signableHex, 'hex');
223
+ const backupDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
224
+ backupDsg.initDsg(backupKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BITGO);
225
+ const backupMsg1 = backupDsg.getFirstMessage();
226
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
227
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
228
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
229
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
230
+ const bitgoDeserializedMsg1 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundOne)({ type: 'round1Output', data: { msg1: bitgoSignedMsg1 } }, bitgoGpgPubKey);
231
+ const [backupMsg2] = backupDsg.handleIncomingMessages([backupMsg1, bitgoDeserializedMsg1]);
232
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, backupMsg1]);
233
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
234
+ const bitgoDeserializedMsg2 = await (0, eddsaMPCv2_1.verifyPeerMessageRoundTwo)({ type: 'round2Output', data: { msg2: bitgoSignedMsg2 } }, bitgoGpgPubKey);
235
+ const [backupMsg3] = backupDsg.handleIncomingMessages([backupMsg2, bitgoDeserializedMsg2]);
236
+ const share = await (0, eddsaMPCv2_1.getSignatureShareRoundThree)(backupMsg3, backupGpgPrivKey, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
237
+ assert.strictEqual(share.from, src_1.SignatureShareType.BACKUP);
238
+ assert.strictEqual(share.to, src_1.SignatureShareType.BITGO);
239
+ const parsed = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(share.share), 'EddsaMPCv2SignatureShareRound3Input');
240
+ assert.strictEqual(parsed.type, 'round3Input');
241
+ assert.ok(parsed.data.msg3.message, 'msg3.message should be set');
242
+ assert.ok(parsed.data.msg3.signature, 'msg3.signature should be set');
243
+ });
244
+ });
245
+ describe('getEddsaMPCv2RecoveryKeyShares', () => {
246
+ const walletPassphrase = 'testPass';
247
+ const encryptKey = (keyShare) => sjcl.encrypt(walletPassphrase, keyShare.toString('base64'));
248
+ it('should return recovery key shares from v1-encrypted reduced keys (no bitgo instance)', async () => {
249
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
250
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase);
251
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
252
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
253
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
254
+ });
255
+ it('should route decryption through bitgo.decryptAsync when a bitgo instance is provided', async () => {
256
+ // sdk-core has no devDependency on sdk-api or argon2, so we cannot encrypt with a real v2 envelope here.
257
+ // The stub verifies that the function delegates to bitgo.decryptAsync (which supports v1 + v2 in
258
+ // production) rather than falling back to sjcl.decrypt.
259
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
260
+ const userKeyBase64 = userDkg.getReducedKeyShare().toString('base64');
261
+ const backupKeyBase64 = backupDkg.getReducedKeyShare().toString('base64');
262
+ const mockBitgo = {
263
+ decryptAsync: sinon.stub().onFirstCall().resolves(userKeyBase64).onSecondCall().resolves(backupKeyBase64),
264
+ };
265
+ const result = await src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey('encrypted-user-key', 'encrypted-backup-key', walletPassphrase, mockBitgo);
266
+ sinon.assert.calledTwice(mockBitgo.decryptAsync);
267
+ assert.deepStrictEqual(result.userKeyShare, userDkg.getKeyShare());
268
+ assert.deepStrictEqual(result.backupKeyShare, backupDkg.getKeyShare());
269
+ assert.strictEqual(result.commonKeyChain, userDkg.getCommonKeychain());
270
+ });
271
+ it('should reject a malformed keycard with a descriptive error', async () => {
272
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
273
+ const malformedKey = sjcl.encrypt(walletPassphrase, (0, crypto_1.randomBytes)(64).toString('base64'));
274
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(malformedKey, encryptKey(userDkg.getReducedKeyShare()), walletPassphrase), /unable to decode reduced key share/);
275
+ });
276
+ it('should reject reduced keys from different wallets', async () => {
277
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
278
+ const [, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
279
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userDkg.getReducedKeyShare()), encryptKey(backupDkg.getReducedKeyShare()), walletPassphrase), /pub keys do not match/);
280
+ });
281
+ it('should reject reduced keys with matching pub but mismatched rootChainCodes', async () => {
282
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
283
+ const userReducedKeyShare = userDkg.getReducedKeyShare();
284
+ const backupReducedKeyShare = backupDkg.getReducedKeyShare();
285
+ const getDecodedReducedKeyShare = sdk_lib_mpc_1.MPSTypes.getDecodedReducedKeyShare;
286
+ const decodeStub = sinon.stub(sdk_lib_mpc_1.MPSTypes, 'getDecodedReducedKeyShare').callsFake((buf) => {
287
+ const reduced = getDecodedReducedKeyShare(buf);
288
+ if (Buffer.from(buf).equals(backupReducedKeyShare)) {
289
+ return {
290
+ ...reduced,
291
+ rootChainCode: Array.from((0, crypto_1.randomBytes)(32)),
292
+ };
293
+ }
294
+ return reduced;
295
+ });
296
+ try {
297
+ await assert.rejects(src_1.EDDSAUtils.getEddsaMpcV2RecoveryKeySharesFromReducedKey(encryptKey(userReducedKeyShare), encryptKey(backupReducedKeyShare), walletPassphrase), /rootChainCodes do not match/);
298
+ }
299
+ finally {
300
+ decodeStub.restore();
301
+ }
302
+ });
303
+ });
304
+ describe('EddsaMPCv2Utils.createOfflineRound1Share', () => {
305
+ let eddsaMPCv2Utils;
306
+ let mockBitgo;
307
+ let userKeyShare;
308
+ const walletPassphrase = 'testPass';
309
+ const signableHex = 'deadbeef';
310
+ const derivationPath = 'm/0/0';
311
+ const expectedAdata = `${signableHex}:${derivationPath}`;
312
+ const txRequest = {
313
+ txRequestId: 'txreq-eddsa-round1',
314
+ walletId: 'wallet-eddsa-round1',
315
+ enterpriseId: 'enterprise-eddsa-round1',
316
+ apiVersion: 'full',
317
+ transactions: [
318
+ {
319
+ unsignedTx: {
320
+ signableHex,
321
+ derivationPath,
322
+ serializedTxHex: signableHex,
323
+ },
324
+ signatureShares: [],
325
+ },
326
+ ],
327
+ intent: { intentType: 'payment' },
328
+ unsignedTxs: [],
329
+ };
330
+ before('generate EdDSA user key share', async () => {
331
+ const [userDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
332
+ userKeyShare = userDkg.getKeyShare();
333
+ });
334
+ beforeEach(() => {
335
+ const sjclEncrypt = (params) => {
336
+ const salt = (0, crypto_1.randomBytes)(8);
337
+ const iv = (0, crypto_1.randomBytes)(16);
338
+ return sjcl.encrypt(params.password, params.input, {
339
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
340
+ iv: [
341
+ bytesToWord(iv.subarray(0, 4)),
342
+ bytesToWord(iv.subarray(4, 8)),
343
+ bytesToWord(iv.subarray(8, 12)),
344
+ bytesToWord(iv.subarray(12, 16)),
345
+ ],
346
+ adata: params.adata,
347
+ });
348
+ };
349
+ mockBitgo = {
350
+ encrypt: sinon.stub().callsFake(sjclEncrypt),
351
+ encryptAsync: sinon.stub().callsFake(async (params) => sjclEncrypt(params)),
352
+ };
353
+ const mockCoin = {
354
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
355
+ };
356
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
357
+ });
358
+ it('should create a round-1 share and encrypted SJCL session payload', async () => {
359
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
360
+ txRequest,
361
+ prv: userKeyShare.toString('base64'),
362
+ walletPassphrase,
363
+ });
364
+ assert.strictEqual(result.signatureShareRound1.from, src_1.SignatureShareType.USER);
365
+ assert.strictEqual(result.signatureShareRound1.to, src_1.SignatureShareType.BITGO);
366
+ assert.ok(result.userGpgPubKey.includes('BEGIN PGP PUBLIC KEY BLOCK'));
367
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
368
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
369
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(result.signatureShareRound1.share), 'EddsaMPCv2SignatureShareRound1Input');
370
+ assert.strictEqual(parsedShare.type, 'round1Input');
371
+ assert.ok(parsedShare.data.msg1.message, 'msg1.message should be set');
372
+ assert.ok(parsedShare.data.msg1.signature, 'msg1.signature should be set');
373
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
374
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
375
+ assert.strictEqual(decodeURIComponent(encryptedRound1Session.adata), `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`, 'round-1 session adata should bind the signing context');
376
+ assert.strictEqual(decodeURIComponent(encryptedUserGpgPrvKey.adata), `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`, 'GPG private key adata should bind the signing context');
377
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, result.encryptedRound1Session));
378
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
379
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
380
+ });
381
+ it('should use v2 encryption when encryptedPrv is a v2 envelope', async () => {
382
+ const encrypt = sinon
383
+ .stub()
384
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
385
+ const destroy = sinon.stub();
386
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
387
+ mockBitgo.createEncryptionSession = createEncryptionSession;
388
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
389
+ txRequest,
390
+ prv: userKeyShare.toString('base64'),
391
+ walletPassphrase,
392
+ encryptedPrv: JSON.stringify({ v: 2 }),
393
+ });
394
+ sinon.assert.calledOnce(createEncryptionSession);
395
+ assert.strictEqual(createEncryptionSession.getCall(0).args[0], walletPassphrase);
396
+ sinon.assert.notCalled(mockBitgo.encryptAsync);
397
+ sinon.assert.calledTwice(encrypt);
398
+ sinon.assert.calledOnce(destroy);
399
+ const encryptedRound1Session = JSON.parse(result.encryptedRound1Session);
400
+ const encryptedUserGpgPrvKey = JSON.parse(result.encryptedUserGpgPrvKey);
401
+ assert.strictEqual(encryptedRound1Session.v, 2);
402
+ assert.strictEqual(encryptedRound1Session.adata, `MPS_DSG_SIGNING_ROUND1_STATE:${expectedAdata}`);
403
+ assert.strictEqual(encryptedUserGpgPrvKey.v, 2);
404
+ assert.strictEqual(encryptedUserGpgPrvKey.adata, `MPS_DSG_SIGNING_USER_GPG_KEY:${expectedAdata}`);
405
+ const sessionPayload = JSON.parse(encryptedRound1Session.input);
406
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 2');
407
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 2');
408
+ });
409
+ it('should use SJCL encryption when encryptedPrv is a v1 blob', async () => {
410
+ mockBitgo.createEncryptionSession = sinon.stub();
411
+ const encryptedPrv = sjcl.encrypt(walletPassphrase, userKeyShare.toString('base64'));
412
+ const result = await eddsaMPCv2Utils.createOfflineRound1Share({
413
+ txRequest,
414
+ prv: userKeyShare.toString('base64'),
415
+ walletPassphrase,
416
+ encryptedPrv,
417
+ });
418
+ sinon.assert.notCalled(mockBitgo.createEncryptionSession);
419
+ sinon.assert.calledTwice(mockBitgo.encryptAsync);
420
+ assert.ok(JSON.parse(result.encryptedRound1Session).ct, 'encryptedRound1Session should be an SJCL JSON blob');
421
+ assert.ok(JSON.parse(result.encryptedUserGpgPrvKey).ct, 'encryptedUserGpgPrvKey should be an SJCL JSON blob');
422
+ });
423
+ it('should propagate the tx-only guard when transactions are missing', async () => {
424
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound1Share({
425
+ txRequest: { ...txRequest, transactions: undefined },
426
+ prv: userKeyShare.toString('base64'),
427
+ walletPassphrase,
428
+ }), /Unable to find transactions in txRequest/);
429
+ });
430
+ });
431
+ describe('EddsaMPCv2Utils.createOfflineRound2Share', () => {
432
+ let eddsaMPCv2Utils;
433
+ let mockBitgo;
434
+ let userKeyShare;
435
+ let bitgoKeyShare;
436
+ let bitgoGpgKeyPair;
437
+ let bitgoGpgPrivKey;
438
+ const walletPassphrase = 'testPass';
439
+ const signableHex = 'deadbeef';
440
+ const derivationPath = 'm/0/0';
441
+ const expectedAdata = `${signableHex}:${derivationPath}`;
442
+ const baseTxRequest = {
443
+ txRequestId: 'txreq-eddsa-round2',
444
+ walletId: 'wallet-eddsa-round2',
445
+ enterpriseId: 'enterprise-eddsa-round2',
446
+ apiVersion: 'full',
447
+ transactions: [
448
+ {
449
+ unsignedTx: {
450
+ signableHex,
451
+ derivationPath,
452
+ serializedTxHex: signableHex,
453
+ },
454
+ signatureShares: [],
455
+ },
456
+ ],
457
+ intent: { intentType: 'payment' },
458
+ unsignedTxs: [],
459
+ };
460
+ before('generate EdDSA key shares and GPG keys', async () => {
461
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
462
+ userKeyShare = userDkg.getKeyShare();
463
+ bitgoKeyShare = bitgoDkg.getKeyShare();
464
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
465
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
466
+ });
467
+ beforeEach(() => {
468
+ mockBitgo = {
469
+ encrypt: sinon.stub().callsFake((params) => {
470
+ const salt = (0, crypto_1.randomBytes)(8);
471
+ const iv = (0, crypto_1.randomBytes)(16);
472
+ return sjcl.encrypt(params.password, params.input, {
473
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
474
+ iv: [
475
+ bytesToWord(iv.subarray(0, 4)),
476
+ bytesToWord(iv.subarray(4, 8)),
477
+ bytesToWord(iv.subarray(8, 12)),
478
+ bytesToWord(iv.subarray(12, 16)),
479
+ ],
480
+ adata: params.adata,
481
+ });
482
+ }),
483
+ encryptAsync: sinon.stub().callsFake(async (params) => {
484
+ const salt = (0, crypto_1.randomBytes)(8);
485
+ const iv = (0, crypto_1.randomBytes)(16);
486
+ return sjcl.encrypt(params.password, params.input, {
487
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
488
+ iv: [
489
+ bytesToWord(iv.subarray(0, 4)),
490
+ bytesToWord(iv.subarray(4, 8)),
491
+ bytesToWord(iv.subarray(8, 12)),
492
+ bytesToWord(iv.subarray(12, 16)),
493
+ ],
494
+ adata: params.adata,
495
+ });
496
+ }),
497
+ decrypt: sinon.stub().callsFake((params) => sjcl.decrypt(params.password, params.input)),
498
+ decryptAsync: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
499
+ };
500
+ const mockCoin = {
501
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
502
+ };
503
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
504
+ });
505
+ it('should create a round-2 share from offline round 1', async () => {
506
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
507
+ txRequest: baseTxRequest,
508
+ prv: userKeyShare.toString('base64'),
509
+ walletPassphrase,
510
+ });
511
+ const messageBuffer = Buffer.from(signableHex, 'hex');
512
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
513
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
514
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
515
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
516
+ txRequest: txRequestRound1,
517
+ walletPassphrase,
518
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
519
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
520
+ encryptedRound1Session: round1.encryptedRound1Session,
521
+ });
522
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
523
+ assert.strictEqual(round2.signatureShareRound2.to, src_1.SignatureShareType.BITGO);
524
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(round2.signatureShareRound2.share), 'EddsaMPCv2SignatureShareRound2Input');
525
+ assert.strictEqual(parsedShare.type, 'round2Input');
526
+ assert.ok(parsedShare.data.msg2.message, 'msg2.message should be set');
527
+ assert.ok(parsedShare.data.msg2.signature, 'msg2.signature should be set');
528
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
529
+ assert.strictEqual(decodeURIComponent(encryptedRound2Session.adata), `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
530
+ const sessionPayload = JSON.parse(sjcl.decrypt(walletPassphrase, round2.encryptedRound2Session));
531
+ assert.ok(sessionPayload.dsgSession, 'dsgSession should be persisted for round 3');
532
+ assert.ok(sessionPayload.userMsgPayload, 'userMsgPayload should be persisted for round 3');
533
+ });
534
+ it('should use v2 decryption when encryptedRound1Session is a v2 envelope', async () => {
535
+ const encrypt = sinon
536
+ .stub()
537
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
538
+ const destroy = sinon.stub();
539
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
540
+ mockBitgo.createEncryptionSession = createEncryptionSession;
541
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
542
+ txRequest: baseTxRequest,
543
+ prv: userKeyShare.toString('base64'),
544
+ walletPassphrase,
545
+ encryptedPrv: JSON.stringify({ v: 2 }),
546
+ });
547
+ const messageBuffer = Buffer.from(signableHex, 'hex');
548
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
549
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
550
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
551
+ const decryptAsync = sinon.stub().callsFake(async (params) => {
552
+ const envelope = JSON.parse(params.input);
553
+ return envelope.input;
554
+ });
555
+ mockBitgo.decryptAsync = decryptAsync;
556
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
557
+ txRequest: txRequestRound1,
558
+ walletPassphrase,
559
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
560
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
561
+ encryptedRound1Session: round1.encryptedRound1Session,
562
+ });
563
+ sinon.assert.called(mockBitgo.decryptAsync);
564
+ assert.strictEqual(round2.signatureShareRound2.from, src_1.SignatureShareType.USER);
565
+ const encryptedRound2Session = JSON.parse(round2.encryptedRound2Session);
566
+ assert.strictEqual(encryptedRound2Session.v, 2);
567
+ assert.strictEqual(encryptedRound2Session.adata, `MPS_DSG_SIGNING_ROUND2_STATE:${expectedAdata}`);
568
+ });
569
+ it('should reject tampered encryptedRound1Session adata', async () => {
570
+ const otherTxRequest = {
571
+ ...baseTxRequest,
572
+ transactions: [
573
+ {
574
+ unsignedTx: {
575
+ signableHex: 'cafebabe',
576
+ derivationPath: 'm/1/2',
577
+ serializedTxHex: 'cafebabe',
578
+ },
579
+ signatureShares: [],
580
+ },
581
+ ],
582
+ };
583
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
584
+ txRequest: otherTxRequest,
585
+ prv: userKeyShare.toString('base64'),
586
+ walletPassphrase,
587
+ });
588
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
589
+ txRequest: baseTxRequest,
590
+ prv: userKeyShare.toString('base64'),
591
+ walletPassphrase,
592
+ });
593
+ const messageBuffer = Buffer.from(signableHex, 'hex');
594
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
595
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
596
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
597
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
598
+ txRequest: txRequestRound1,
599
+ walletPassphrase,
600
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
601
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
602
+ encryptedRound1Session: round1Other.encryptedRound1Session,
603
+ }), /Adata does not match cyphertext adata/);
604
+ });
605
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
606
+ const otherTxRequest = {
607
+ ...baseTxRequest,
608
+ transactions: [
609
+ {
610
+ unsignedTx: {
611
+ signableHex: 'cafebabe',
612
+ derivationPath: 'm/1/2',
613
+ serializedTxHex: 'cafebabe',
614
+ },
615
+ signatureShares: [],
616
+ },
617
+ ],
618
+ };
619
+ const round1Other = await eddsaMPCv2Utils.createOfflineRound1Share({
620
+ txRequest: otherTxRequest,
621
+ prv: userKeyShare.toString('base64'),
622
+ walletPassphrase,
623
+ });
624
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
625
+ txRequest: baseTxRequest,
626
+ prv: userKeyShare.toString('base64'),
627
+ walletPassphrase,
628
+ });
629
+ const messageBuffer = Buffer.from(signableHex, 'hex');
630
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
631
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
632
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(baseTxRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
633
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
634
+ txRequest: txRequestRound1,
635
+ walletPassphrase,
636
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
637
+ encryptedUserGpgPrvKey: round1Other.encryptedUserGpgPrvKey,
638
+ encryptedRound1Session: round1.encryptedRound1Session,
639
+ }), /Adata does not match cyphertext adata/);
640
+ });
641
+ it('should reject when BitGo signature share is missing', async () => {
642
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
643
+ txRequest: baseTxRequest,
644
+ prv: userKeyShare.toString('base64'),
645
+ walletPassphrase,
646
+ });
647
+ const baseTransaction = assertSingleTransaction(baseTxRequest);
648
+ const txRequestNoBitgoShare = {
649
+ ...baseTxRequest,
650
+ transactions: [
651
+ {
652
+ ...baseTransaction,
653
+ signatureShares: [round1.signatureShareRound1],
654
+ },
655
+ ],
656
+ };
657
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
658
+ txRequest: txRequestNoBitgoShare,
659
+ walletPassphrase,
660
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
661
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
662
+ encryptedRound1Session: round1.encryptedRound1Session,
663
+ }), /Missing BitGo round1Output signature share/);
664
+ });
665
+ it('should propagate the tx-only guard when transactions are missing', async () => {
666
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
667
+ txRequest: baseTxRequest,
668
+ prv: userKeyShare.toString('base64'),
669
+ walletPassphrase,
670
+ });
671
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
672
+ txRequest: { ...baseTxRequest, transactions: undefined },
673
+ walletPassphrase,
674
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
675
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
676
+ encryptedRound1Session: round1.encryptedRound1Session,
677
+ }), /Unable to find transactions in txRequest/);
678
+ });
679
+ it('should reject when transactions array is empty', async () => {
680
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
681
+ txRequest: baseTxRequest,
682
+ prv: userKeyShare.toString('base64'),
683
+ walletPassphrase,
684
+ });
685
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound2Share({
686
+ txRequest: { ...baseTxRequest, transactions: [] },
687
+ walletPassphrase,
688
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
689
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
690
+ encryptedRound1Session: round1.encryptedRound1Session,
691
+ }), /Unable to find transactions in txRequest/);
692
+ });
693
+ });
694
+ describe('EddsaMPCv2Utils.createOfflineRound3Share', () => {
695
+ let eddsaMPCv2Utils;
696
+ let mockBitgo;
697
+ let userKeyShare;
698
+ let bitgoKeyShare;
699
+ let bitgoGpgKeyPair;
700
+ let bitgoGpgPrivKey;
701
+ const walletPassphrase = 'testPass';
702
+ const signableHex = 'deadbeef';
703
+ const derivationPath = 'm/0/0';
704
+ const baseTxRequest = {
705
+ txRequestId: 'txreq-eddsa-round3',
706
+ walletId: 'wallet-eddsa-round3',
707
+ enterpriseId: 'enterprise-eddsa-round3',
708
+ apiVersion: 'full',
709
+ transactions: [
710
+ {
711
+ unsignedTx: {
712
+ signableHex,
713
+ derivationPath,
714
+ serializedTxHex: signableHex,
715
+ },
716
+ signatureShares: [],
717
+ },
718
+ ],
719
+ intent: { intentType: 'payment' },
720
+ unsignedTxs: [],
721
+ };
722
+ before('generate EdDSA key shares and GPG keys', async () => {
723
+ const [userDkg, , bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
724
+ userKeyShare = userDkg.getKeyShare();
725
+ bitgoKeyShare = bitgoDkg.getKeyShare();
726
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
727
+ bitgoGpgPrivKey = await pgp.readPrivateKey({ armoredKey: bitgoGpgKeyPair.privateKey });
728
+ });
729
+ beforeEach(() => {
730
+ mockBitgo = {
731
+ encrypt: sinon.stub().callsFake((params) => {
732
+ const salt = (0, crypto_1.randomBytes)(8);
733
+ const iv = (0, crypto_1.randomBytes)(16);
734
+ return sjcl.encrypt(params.password, params.input, {
735
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
736
+ iv: [
737
+ bytesToWord(iv.subarray(0, 4)),
738
+ bytesToWord(iv.subarray(4, 8)),
739
+ bytesToWord(iv.subarray(8, 12)),
740
+ bytesToWord(iv.subarray(12, 16)),
741
+ ],
742
+ adata: params.adata,
743
+ });
744
+ }),
745
+ encryptAsync: sinon.stub().callsFake(async (params) => {
746
+ const salt = (0, crypto_1.randomBytes)(8);
747
+ const iv = (0, crypto_1.randomBytes)(16);
748
+ return sjcl.encrypt(params.password, params.input, {
749
+ salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
750
+ iv: [
751
+ bytesToWord(iv.subarray(0, 4)),
752
+ bytesToWord(iv.subarray(4, 8)),
753
+ bytesToWord(iv.subarray(8, 12)),
754
+ bytesToWord(iv.subarray(12, 16)),
755
+ ],
756
+ adata: params.adata,
757
+ });
758
+ }),
759
+ decrypt: sinon.stub().callsFake((params) => sjcl.decrypt(params.password, params.input)),
760
+ decryptAsync: sinon.stub().callsFake(async (params) => sjcl.decrypt(params.password, params.input)),
761
+ };
762
+ const mockCoin = {
763
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
764
+ };
765
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin);
766
+ });
767
+ async function createRound2Flow(txRequest, encryptedPrv) {
768
+ const round1 = await eddsaMPCv2Utils.createOfflineRound1Share({
769
+ txRequest,
770
+ prv: userKeyShare.toString('base64'),
771
+ walletPassphrase,
772
+ encryptedPrv,
773
+ });
774
+ const transaction = assertSingleTransaction(txRequest);
775
+ const messageBuffer = Buffer.from(transaction.unsignedTx.signableHex, 'hex');
776
+ const bitgoDsg = new sdk_lib_mpc_1.EddsaMPSDsg.DSG(typesMPCv2_1.MPCv2PartiesEnum.BITGO);
777
+ bitgoDsg.initDsg(bitgoKeyShare, messageBuffer, transaction.unsignedTx.derivationPath, typesMPCv2_1.MPCv2PartiesEnum.USER);
778
+ const txRequestRound1 = await signBitgoEddsaRound1(bitgoDsg, cloneTxRequestWithEmptySignatureShares(txRequest), round1.signatureShareRound1, round1.userGpgPubKey, bitgoGpgPrivKey);
779
+ const round2 = await eddsaMPCv2Utils.createOfflineRound2Share({
780
+ txRequest: txRequestRound1,
781
+ walletPassphrase,
782
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
783
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
784
+ encryptedRound1Session: round1.encryptedRound1Session,
785
+ });
786
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
787
+ const txRequestRound2 = await signBitgoEddsaRound2(bitgoDsg, {
788
+ ...txRequestRound1,
789
+ transactions: [
790
+ {
791
+ ...round1Transaction,
792
+ signatureShares: [...round1Transaction.signatureShares],
793
+ },
794
+ ],
795
+ }, round2.signatureShareRound2, round1.userGpgPubKey, bitgoGpgPrivKey);
796
+ return { round1, round2, txRequestRound1, txRequestRound2, messageBuffer };
797
+ }
798
+ it('should create a round-3 share from offline round 2', async () => {
799
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
800
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
801
+ txRequest: txRequestRound2,
802
+ walletPassphrase,
803
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
804
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
805
+ encryptedRound2Session: round2.encryptedRound2Session,
806
+ });
807
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
808
+ assert.strictEqual(round3.signatureShareRound3.to, src_1.SignatureShareType.BITGO);
809
+ const parsedShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound3Input, JSON.parse(round3.signatureShareRound3.share), 'EddsaMPCv2SignatureShareRound3Input');
810
+ assert.strictEqual(parsedShare.type, 'round3Input');
811
+ assert.ok(parsedShare.data.msg3.message, 'msg3.message should be set');
812
+ assert.ok(parsedShare.data.msg3.signature, 'msg3.signature should be set');
813
+ });
814
+ it('should use v2 decryption when encryptedRound2Session is a v2 envelope', async () => {
815
+ const encrypt = sinon
816
+ .stub()
817
+ .callsFake((input, adata) => Promise.resolve(JSON.stringify({ v: 2, input, adata })));
818
+ const destroy = sinon.stub();
819
+ const createEncryptionSession = sinon.stub().resolves({ encrypt, destroy });
820
+ mockBitgo.createEncryptionSession = createEncryptionSession;
821
+ const decryptAsync = sinon.stub().callsFake(async (params) => {
822
+ const envelope = JSON.parse(params.input);
823
+ return envelope.input;
824
+ });
825
+ mockBitgo.decryptAsync = decryptAsync;
826
+ const { round1, round2, txRequestRound2 } = await createRound2Flow(baseTxRequest, JSON.stringify({ v: 2 }));
827
+ const round3 = await eddsaMPCv2Utils.createOfflineRound3Share({
828
+ txRequest: txRequestRound2,
829
+ walletPassphrase,
830
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
831
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
832
+ encryptedRound2Session: round2.encryptedRound2Session,
833
+ });
834
+ assert.strictEqual(mockBitgo.decryptAsync.callCount, 4);
835
+ assert.strictEqual(round3.signatureShareRound3.from, src_1.SignatureShareType.USER);
836
+ });
837
+ it('should reject tampered encryptedRound2Session adata', async () => {
838
+ const otherTxRequest = {
839
+ ...baseTxRequest,
840
+ transactions: [
841
+ {
842
+ unsignedTx: {
843
+ signableHex: 'cafebabe',
844
+ derivationPath: 'm/1/2',
845
+ serializedTxHex: 'cafebabe',
846
+ },
847
+ signatureShares: [],
848
+ },
849
+ ],
850
+ };
851
+ const otherFlow = await createRound2Flow(otherTxRequest);
852
+ const { round1, txRequestRound2 } = await createRound2Flow(baseTxRequest);
853
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
854
+ txRequest: txRequestRound2,
855
+ walletPassphrase,
856
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
857
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
858
+ encryptedRound2Session: otherFlow.round2.encryptedRound2Session,
859
+ }), /Adata does not match cyphertext adata/);
860
+ });
861
+ it('should reject tampered encryptedUserGpgPrvKey adata', async () => {
862
+ const otherTxRequest = {
863
+ ...baseTxRequest,
864
+ transactions: [
865
+ {
866
+ unsignedTx: {
867
+ signableHex: 'cafebabe',
868
+ derivationPath: 'm/1/2',
869
+ serializedTxHex: 'cafebabe',
870
+ },
871
+ signatureShares: [],
872
+ },
873
+ ],
874
+ };
875
+ const otherFlow = await createRound2Flow(otherTxRequest);
876
+ const { round2, txRequestRound2 } = await createRound2Flow(baseTxRequest);
877
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
878
+ txRequest: txRequestRound2,
879
+ walletPassphrase,
880
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
881
+ encryptedUserGpgPrvKey: otherFlow.round1.encryptedUserGpgPrvKey,
882
+ encryptedRound2Session: round2.encryptedRound2Session,
883
+ }), /Adata does not match cyphertext adata/);
884
+ });
885
+ it('should reject when BitGo round-2 signature share is missing', async () => {
886
+ const { round1, round2, txRequestRound1 } = await createRound2Flow(baseTxRequest);
887
+ const round1Transaction = assertSingleTransaction(txRequestRound1);
888
+ const txRequestNoBitgoRound2Share = {
889
+ ...txRequestRound1,
890
+ transactions: [
891
+ {
892
+ ...round1Transaction,
893
+ signatureShares: [...round1Transaction.signatureShares, round2.signatureShareRound2],
894
+ },
895
+ ],
896
+ };
897
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
898
+ txRequest: txRequestNoBitgoRound2Share,
899
+ walletPassphrase,
900
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
901
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
902
+ encryptedRound2Session: round2.encryptedRound2Session,
903
+ }), /Missing BitGo round2Output signature share/);
904
+ });
905
+ it('should propagate the tx-only guard when transactions are missing', async () => {
906
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
907
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
908
+ txRequest: { ...baseTxRequest, transactions: undefined },
909
+ walletPassphrase,
910
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
911
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
912
+ encryptedRound2Session: round2.encryptedRound2Session,
913
+ }), /Unable to find transactions in txRequest/);
914
+ });
915
+ it('should reject when transactions array is empty', async () => {
916
+ const { round1, round2 } = await createRound2Flow(baseTxRequest);
917
+ await assert.rejects(() => eddsaMPCv2Utils.createOfflineRound3Share({
918
+ txRequest: { ...baseTxRequest, transactions: [] },
919
+ walletPassphrase,
920
+ bitgoPublicGpgKey: bitgoGpgKeyPair.publicKey,
921
+ encryptedUserGpgPrvKey: round1.encryptedUserGpgPrvKey,
922
+ encryptedRound2Session: round2.encryptedRound2Session,
923
+ }), /Unable to find transactions in txRequest/);
924
+ });
925
+ });
926
+ describe('getBitgoSignatureShare', () => {
927
+ const round1OutputShare = {
928
+ from: src_1.SignatureShareType.BITGO,
929
+ to: src_1.SignatureShareType.USER,
930
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
931
+ };
932
+ const round2OutputShare = {
933
+ from: src_1.SignatureShareType.BITGO,
934
+ to: src_1.SignatureShareType.USER,
935
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
936
+ };
937
+ it('selects the requested BitGo round output when multiple round outputs are present', () => {
938
+ const signatureShares = [round1OutputShare, round2OutputShare];
939
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
940
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)(signatureShares, src_1.SignatureShareType.USER, 'round1Output'), round1OutputShare);
941
+ });
942
+ it('skips malformed share records while selecting the requested BitGo round output', () => {
943
+ const malformedShare = {
944
+ from: src_1.SignatureShareType.BITGO,
945
+ to: src_1.SignatureShareType.USER,
946
+ share: 'not-json',
947
+ };
948
+ assert.strictEqual((0, common_1.getBitgoSignatureShare)([malformedShare, round2OutputShare], src_1.SignatureShareType.USER, 'round2Output'), round2OutputShare);
949
+ });
950
+ });
951
+ function assertSingleTransaction(txRequest) {
952
+ assert.ok(txRequest.transactions, 'txRequest must include transactions');
953
+ assert.strictEqual(txRequest.transactions.length, 1, 'txRequest must have exactly one transaction');
954
+ return txRequest.transactions[0];
955
+ }
956
+ function cloneTxRequestWithEmptySignatureShares(txRequest) {
957
+ const transaction = assertSingleTransaction(txRequest);
958
+ return {
959
+ ...txRequest,
960
+ transactions: [{ ...transaction, signatureShares: [] }],
961
+ };
962
+ }
963
+ async function signBitgoEddsaRound1(bitgoDsg, txRequest, userRound1Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
964
+ const transaction = assertSingleTransaction(txRequest);
965
+ transaction.signatureShares.push(userRound1Share);
966
+ const bitgoMsg1 = bitgoDsg.getFirstMessage();
967
+ const parsedUserShare = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound1Input, JSON.parse(userRound1Share.share), 'EddsaMPCv2SignatureShareRound1Input');
968
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
969
+ const userRawMsg1Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserShare.data.msg1, userGpgKey);
970
+ const userMsg1 = {
971
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
972
+ payload: new Uint8Array(userRawMsg1Bytes),
973
+ };
974
+ const [bitgoMsg2] = bitgoDsg.handleIncomingMessages([bitgoMsg1, userMsg1]);
975
+ assert.ok(bitgoMsg2, 'BitGo DSG produced no round-2 output');
976
+ bitgoDsg.round2Message = bitgoMsg2;
977
+ const bitgoSignedMsg1 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg1.payload), bitgoGpgPrivKey);
978
+ const round1Output = {
979
+ type: 'round1Output',
980
+ data: { msg1: bitgoSignedMsg1 },
981
+ };
982
+ transaction.signatureShares.push({
983
+ from: src_1.SignatureShareType.BITGO,
984
+ to: src_1.SignatureShareType.USER,
985
+ share: JSON.stringify(round1Output),
986
+ });
987
+ return txRequest;
988
+ }
989
+ async function signBitgoEddsaRound2(bitgoDsg, txRequest, userRound2Share, userGpgPubKeyArmored, bitgoGpgPrivKey) {
990
+ const transaction = assertSingleTransaction(txRequest);
991
+ transaction.signatureShares.push(userRound2Share);
992
+ const userGpgKey = await pgp.readKey({ armoredKey: userGpgPubKeyArmored });
993
+ const bitgoMsg2 = bitgoDsg.round2Message;
994
+ assert.ok(bitgoMsg2, 'BitGo DSG is missing the cached round-2 output');
995
+ const parsedUserRound2Share = (0, codecs_1.decodeWithCodec)(public_types_1.EddsaMPCv2SignatureShareRound2Input, JSON.parse(userRound2Share.share), 'EddsaMPCv2SignatureShareRound2Input');
996
+ const userRawMsg2Bytes = await sdk_lib_mpc_1.MPSComms.verifyMpsMessage(parsedUserRound2Share.data.msg2, userGpgKey);
997
+ const userMsg2 = {
998
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
999
+ payload: new Uint8Array(userRawMsg2Bytes),
1000
+ };
1001
+ const bitgoSignedMsg2 = await sdk_lib_mpc_1.MPSComms.detachSignMpsMessage(Buffer.from(bitgoMsg2.payload), bitgoGpgPrivKey);
1002
+ const round2Output = {
1003
+ type: 'round2Output',
1004
+ data: { msg2: bitgoSignedMsg2 },
1005
+ };
1006
+ transaction.signatureShares.push({
1007
+ from: src_1.SignatureShareType.BITGO,
1008
+ to: src_1.SignatureShareType.USER,
1009
+ share: JSON.stringify(round2Output),
1010
+ });
1011
+ bitgoDsg.handleIncomingMessages([bitgoMsg2, userMsg2]);
1012
+ return txRequest;
1013
+ }
1014
+ describe('EddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner', () => {
1015
+ let sandbox;
1016
+ let eddsaMPCv2Utils;
1017
+ let mockBitgo;
1018
+ let bitgoGpgKeyPair;
1019
+ let bitgoGpgPubKey;
1020
+ const walletId = 'abc123wallet';
1021
+ const txRequestId = 'txreq-001';
1022
+ const enterpriseId = 'ent-001';
1023
+ const mockTxRequest = {
1024
+ txRequestId,
1025
+ walletId,
1026
+ enterpriseId,
1027
+ apiVersion: 'full',
1028
+ transactions: [
1029
+ {
1030
+ unsignedTx: {
1031
+ signableHex: 'deadbeef',
1032
+ derivationPath: 'm/0',
1033
+ serializedTxHex: 'deadbeef',
1034
+ },
1035
+ signatureShares: [
1036
+ {
1037
+ from: src_1.SignatureShareType.BITGO,
1038
+ to: src_1.SignatureShareType.USER,
1039
+ share: JSON.stringify({ type: 'round1Output', data: {} }),
1040
+ },
1041
+ ],
1042
+ },
1043
+ ],
1044
+ intent: { intentType: 'payment' },
1045
+ unsignedTxs: [],
1046
+ };
1047
+ const mockTxRequestTransaction = assertSingleTransaction(mockTxRequest);
1048
+ const mockTxRequestRound2 = {
1049
+ ...mockTxRequest,
1050
+ transactions: [
1051
+ {
1052
+ ...mockTxRequestTransaction,
1053
+ signatureShares: [
1054
+ {
1055
+ from: src_1.SignatureShareType.BITGO,
1056
+ to: src_1.SignatureShareType.USER,
1057
+ share: JSON.stringify({ type: 'round2Output', data: {} }),
1058
+ },
1059
+ ],
1060
+ },
1061
+ ],
1062
+ };
1063
+ const dummyShare = {
1064
+ from: src_1.SignatureShareType.USER,
1065
+ to: src_1.SignatureShareType.BITGO,
1066
+ share: JSON.stringify({ type: 'round1Input', data: {} }),
1067
+ };
1068
+ // Returns a chain compatible with: bitgo.post(url).send(body).result()
1069
+ const makePostChain = (response) => ({ send: () => ({ result: sinon.stub().resolves(response) }) });
1070
+ // Returns a chain compatible with: bitgo.get(url).query(params).retry(n).result()
1071
+ const makeGetChain = (txRequests) => ({
1072
+ query: () => ({
1073
+ retry: () => ({ result: sinon.stub().resolves({ txRequests }) }),
1074
+ }),
1075
+ });
1076
+ before(async () => {
1077
+ bitgoGpgKeyPair = await (0, opengpgUtils_1.generateGPGKeyPair)('ed25519');
1078
+ bitgoGpgPubKey = await pgp.readKey({ armoredKey: bitgoGpgKeyPair.publicKey });
1079
+ });
1080
+ beforeEach(async () => {
1081
+ sandbox = sinon.createSandbox();
1082
+ // Full mock of the BitGo HTTP client (consistent with other sdk-core tests such as
1083
+ // tokenApproval.ts and walletsEvmKeyring.ts). Module-level stubs on tssCommon functions
1084
+ // do not work under tsx 4.x (ESM live bindings), so we mock at the bitgo object level.
1085
+ mockBitgo = {
1086
+ getEnv: sinon.stub().returns('test'),
1087
+ setRequestTracer: sinon.stub(),
1088
+ url: sinon.stub().callsFake((path) => `https://test.bitgo.com${path}`),
1089
+ post: sinon.stub(),
1090
+ get: sinon.stub(),
1091
+ };
1092
+ const mockCoin = {
1093
+ getMPCAlgorithm: sinon.stub().returns('eddsa'),
1094
+ };
1095
+ const mockWallet = {
1096
+ id: sinon.stub().returns(walletId),
1097
+ keyIds: sinon.stub().returns(['userKeyId', 'backupKeyId', 'bitgoKeyId']),
1098
+ multisigTypeVersion: sinon.stub().returns('MPCv2'),
1099
+ };
1100
+ eddsaMPCv2Utils = new src_1.EddsaMPCv2Utils(mockBitgo, mockCoin, mockWallet);
1101
+ sandbox.stub(eddsaMPCv2Utils, 'pickBitgoPubGpgKeyForSigning').resolves(bitgoGpgPubKey);
1102
+ });
1103
+ afterEach(() => {
1104
+ sandbox.restore();
1105
+ });
1106
+ it('should call all 3 generators and return the final tx request', async () => {
1107
+ const finalTxRequest = { ...mockTxRequest, txRequestId };
1108
+ // sendSignatureShareV2 is called 3 times (one per round), sendTxRequest once — all use bitgo.post
1109
+ mockBitgo.post
1110
+ .onCall(0)
1111
+ .returns(makePostChain(mockTxRequest)) // round 1 sign
1112
+ .onCall(1)
1113
+ .returns(makePostChain(mockTxRequestRound2)) // round 2 sign
1114
+ .onCall(2)
1115
+ .returns(makePostChain(mockTxRequestRound2)) // round 3 sign
1116
+ .onCall(3)
1117
+ .returns(makePostChain(finalTxRequest)); // sendTxRequest (send)
1118
+ const encryptedRound1Session = 'encrypted-r1-session';
1119
+ const encryptedRound2Session = 'encrypted-r2-session';
1120
+ const encryptedUserGpgPrvKey = 'encrypted-gpg-key';
1121
+ const userGpgPubKey = bitgoGpgKeyPair.publicKey;
1122
+ const round1Share = { ...dummyShare };
1123
+ const round2Share = { ...dummyShare, share: JSON.stringify({ type: 'round2Input' }) };
1124
+ const round3Share = { ...dummyShare, share: JSON.stringify({ type: 'round3Input' }) };
1125
+ const round1Generator = sinon
1126
+ .stub()
1127
+ .resolves({ signatureShareRound1: round1Share, userGpgPubKey, encryptedRound1Session, encryptedUserGpgPrvKey });
1128
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: round2Share, encryptedRound2Session });
1129
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: round3Share });
1130
+ const result = await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1131
+ assert.deepStrictEqual(result, finalTxRequest);
1132
+ sinon.assert.calledOnce(round1Generator);
1133
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1134
+ sinon.assert.calledOnce(round2Generator);
1135
+ const round2Call = round2Generator.getCall(0);
1136
+ assert.strictEqual(round2Call.args[0].txRequest, mockTxRequest);
1137
+ assert.strictEqual(round2Call.args[0].encryptedRound1Session, encryptedRound1Session);
1138
+ assert.strictEqual(round2Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1139
+ assert.strictEqual(round2Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1140
+ sinon.assert.calledOnce(round3Generator);
1141
+ const round3Call = round3Generator.getCall(0);
1142
+ assert.strictEqual(round3Call.args[0].txRequest, mockTxRequestRound2);
1143
+ assert.strictEqual(round3Call.args[0].encryptedRound2Session, encryptedRound2Session);
1144
+ assert.strictEqual(round3Call.args[0].encryptedUserGpgPrvKey, encryptedUserGpgPrvKey);
1145
+ assert.strictEqual(round3Call.args[0].bitgoPublicGpgKey, bitgoGpgPubKey.armor());
1146
+ // 3 sendSignatureShareV2 calls + 1 sendTxRequest = 4 POST calls total
1147
+ assert.strictEqual(mockBitgo.post.callCount, 4);
1148
+ });
1149
+ it('should resolve txRequest by ID string using getTxRequest', async () => {
1150
+ // getTxRequest uses bitgo.get; sendSignatureShareV2 (×3) + sendTxRequest use bitgo.post
1151
+ mockBitgo.get.returns(makeGetChain([mockTxRequest]));
1152
+ mockBitgo.post
1153
+ .onCall(0)
1154
+ .returns(makePostChain(mockTxRequest))
1155
+ .onCall(1)
1156
+ .returns(makePostChain(mockTxRequestRound2))
1157
+ .onCall(2)
1158
+ .returns(makePostChain(mockTxRequestRound2))
1159
+ .onCall(3)
1160
+ .returns(makePostChain(mockTxRequest));
1161
+ const round1Generator = sinon.stub().resolves({
1162
+ signatureShareRound1: dummyShare,
1163
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1164
+ encryptedRound1Session: 'r1',
1165
+ encryptedUserGpgPrvKey: 'key',
1166
+ });
1167
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1168
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1169
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: txRequestId, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1170
+ sinon.assert.calledOnce(mockBitgo.get);
1171
+ sinon.assert.calledWith(round1Generator, { txRequest: mockTxRequest });
1172
+ });
1173
+ it('should throw when round 2 txRequest is missing signatureShares', async () => {
1174
+ const round2NoShares = {
1175
+ ...mockTxRequest,
1176
+ transactions: [{ ...mockTxRequestTransaction, signatureShares: undefined }],
1177
+ };
1178
+ mockBitgo.post
1179
+ .onCall(0)
1180
+ .returns(makePostChain(mockTxRequest))
1181
+ .onCall(1)
1182
+ .returns(makePostChain(round2NoShares));
1183
+ const round1Generator = sinon.stub().resolves({
1184
+ signatureShareRound1: dummyShare,
1185
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1186
+ encryptedRound1Session: 'r1',
1187
+ encryptedUserGpgPrvKey: 'key',
1188
+ });
1189
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1190
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1191
+ await assert.rejects(() => eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator), /Missing signature shares in round 2 txRequest/);
1192
+ });
1193
+ it('should pass armored BitGo public GPG key to round 2 and round 3 generators', async () => {
1194
+ mockBitgo.post
1195
+ .onCall(0)
1196
+ .returns(makePostChain(mockTxRequest))
1197
+ .onCall(1)
1198
+ .returns(makePostChain(mockTxRequestRound2))
1199
+ .onCall(2)
1200
+ .returns(makePostChain(mockTxRequestRound2))
1201
+ .onCall(3)
1202
+ .returns(makePostChain(mockTxRequest));
1203
+ const round1Generator = sinon.stub().resolves({
1204
+ signatureShareRound1: dummyShare,
1205
+ userGpgPubKey: bitgoGpgKeyPair.publicKey,
1206
+ encryptedRound1Session: 'r1',
1207
+ encryptedUserGpgPrvKey: 'key',
1208
+ });
1209
+ const round2Generator = sinon.stub().resolves({ signatureShareRound2: dummyShare, encryptedRound2Session: 'r2' });
1210
+ const round3Generator = sinon.stub().resolves({ signatureShareRound3: dummyShare });
1211
+ await eddsaMPCv2Utils.signEddsaMPCv2TssUsingExternalSigner({ txRequest: mockTxRequest, reqId: new src_1.RequestTracer() }, round1Generator, round2Generator, round3Generator);
1212
+ const armoredKey = bitgoGpgPubKey.armor();
1213
+ assert.strictEqual(round2Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 2 should receive armored BitGo GPG key');
1214
+ assert.strictEqual(round3Generator.getCall(0).args[0].bitgoPublicGpgKey, armoredKey, 'round 3 should receive armored BitGo GPG key');
1215
+ });
1216
+ });
1217
+ function bytesToWord(bytes) {
1218
+ if (!(bytes instanceof Uint8Array) || bytes.length !== 4) {
1219
+ throw new Error('bytes must be a Uint8Array with length 4');
1220
+ }
1221
+ return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
1222
+ }
1223
+ describe('EDDSAUtils.isEddsaMpcV1SigningMaterial', () => {
1224
+ const PASSPHRASE = 'test-passphrase';
1225
+ const MPCv1_MATERIAL_BACKUP = {
1226
+ uShare: { i: 1, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1227
+ bitgoYShare: { i: 3, j: 1, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1228
+ backupYShare: { i: 2, j: 1, y: 'aabbcc', u: 'backup-u-value', chaincode: '00' },
1229
+ };
1230
+ const MPCv1_MATERIAL_USER = {
1231
+ uShare: { i: 2, t: 2, n: 3, y: 'aabbcc', seed: 'deadbeef01234567', chaincode: '00' },
1232
+ bitgoYShare: { i: 3, j: 2, y: 'aabbcc', u: 'bitgo-u-value', chaincode: '00' },
1233
+ userYShare: { i: 1, j: 2, y: 'aabbcc', u: 'user-u-value', chaincode: '00' },
1234
+ };
1235
+ const MPCv2_CBOR_BYTES = Buffer.from([0xd9, 0x01, 0x04, 0xa3, 0x61, 0x78, 0x18, 0x00]).toString('base64');
1236
+ let mockBitgo;
1237
+ beforeEach(() => {
1238
+ // sdk-core has no devDependency on sdk-api/argon2, so v2 envelopes are simulated here.
1239
+ // Real bitgo.decryptAsync routes v2 to Argon2id; the stub returns MPCv2 CBOR plaintext instead.
1240
+ mockBitgo = {
1241
+ decryptAsync: sinon.stub().callsFake(async (params) => {
1242
+ if ((0, baseTypes_1.isV2Envelope)(params.input)) {
1243
+ return MPCv2_CBOR_BYTES;
1244
+ }
1245
+ return sjcl.decrypt(params.password, params.input);
1246
+ }),
1247
+ };
1248
+ });
1249
+ it('returns true for MPCv1 SJCL-encrypted keycard with backupYShare + correct passphrase', async () => {
1250
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1251
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1252
+ });
1253
+ it('returns true for MPCv1 SJCL-encrypted keycard with userYShare + correct passphrase', async () => {
1254
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_USER));
1255
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), true);
1256
+ });
1257
+ it('returns false for MPCv2 CBOR content wrapped in SJCL envelope + correct passphrase', async () => {
1258
+ const encrypted = sjcl.encrypt(PASSPHRASE, MPCv2_CBOR_BYTES);
1259
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1260
+ });
1261
+ it('returns false for MPCv2 Argon2id envelope (v2) + correct passphrase (forward-compat)', async () => {
1262
+ const fakeV2Envelope = JSON.stringify({ v: 2, m: 65536, t: 3, p: 4, salt: 'AAAA', iv: 'AAAA', ct: 'AAAA' });
1263
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(fakeV2Envelope, PASSPHRASE, mockBitgo), false);
1264
+ });
1265
+ it('throws on wrong passphrase', async () => {
1266
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(MPCv1_MATERIAL_BACKUP));
1267
+ await assert.rejects(src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, 'wrong-passphrase'), /ccm: tag doesn't match/);
1268
+ });
1269
+ it('returns false when neither backupYShare.u nor userYShare.u is present', async () => {
1270
+ const partial = { uShare: { seed: 'abc' }, bitgoYShare: { u: 'xyz' } };
1271
+ const encrypted = sjcl.encrypt(PASSPHRASE, JSON.stringify(partial));
1272
+ assert.strictEqual(await src_1.EDDSAUtils.isEddsaMpcV1SigningMaterial(encrypted, PASSPHRASE), false);
1273
+ });
1274
+ });
1275
+ describe('signRecoveryEddsaMPCv2', () => {
1276
+ const derivationPath = 'm/0/0';
1277
+ it('should return a 64-byte signature that verifies against the derived public key', async () => {
1278
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1279
+ const message = Buffer.from('deadbeef', 'hex');
1280
+ const commonKeyChain = userDkg.getCommonKeychain();
1281
+ const signature = src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1282
+ assert.strictEqual(signature.length, 64);
1283
+ const derivedKeychain = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(commonKeyChain, derivationPath);
1284
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1285
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(message), new Uint8Array(publicKeyBytes));
1286
+ assert.strictEqual(ok, true);
1287
+ });
1288
+ it('should throw when the signed message is different from the verified message', async () => {
1289
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1290
+ const message = Buffer.from('deadbeef', 'hex');
1291
+ const commonKeyChain = userDkg.getCommonKeychain();
1292
+ const signature = src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), commonKeyChain);
1293
+ const differentMessage = Buffer.from('cafebabe', 'hex');
1294
+ const derivedKeychain = (0, sdk_lib_mpc_1.deriveUnhardenedMps)(commonKeyChain, derivationPath);
1295
+ const publicKeyBytes = Buffer.from(derivedKeychain.slice(0, 64), 'hex');
1296
+ const ok = ed25519_1.ed25519.verify(new Uint8Array(signature), new Uint8Array(differentMessage), new Uint8Array(publicKeyBytes));
1297
+ assert.strictEqual(ok, false);
1298
+ });
1299
+ it('should throw when a wrong commonKeyChain is provided (verification mismatch)', async () => {
1300
+ const [userDkg, backupDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1301
+ const [wrongDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
1302
+ const message = Buffer.from('deadbeef', 'hex');
1303
+ assert.throws(() => src_1.EDDSAUtils.signRecoveryEddsaMPCv2(message, derivationPath, userDkg.getKeyShare(), backupDkg.getKeyShare(), wrongDkg.getCommonKeychain() // key chain from a different wallet
1304
+ ), /EdDSA MPCv2 recovery signature verification failed/);
1305
+ });
1306
+ });
1307
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWRkc2EvZWRkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsNkNBQStCO0FBQy9CLG1DQUFxQztBQUNyQyx5REFBd0c7QUFDeEcsbURBQWdEO0FBQ2hELHVEQUF5QztBQUN6QyxzREFNNkI7QUFDN0IsK0NBYytCO0FBQy9CLGlGQU0wRDtBQUMxRCxtRUFBZ0Y7QUFDaEYscUVBQTJFO0FBQzNFLGlGQUFvRjtBQUNwRix1RkFBMEY7QUFDMUYsK0VBQStFO0FBRS9FLFFBQVEsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNwRCxJQUFJLFlBQW9CLENBQUM7SUFDekIsSUFBSSxjQUFzQixDQUFDO0lBQzNCLElBQUksYUFBcUIsQ0FBQztJQUMxQixJQUFJLGNBQThCLENBQUM7SUFDbkMsSUFBSSxnQkFBZ0MsQ0FBQztJQUNyQyxJQUFJLGVBQStCLENBQUM7SUFDcEMsSUFBSSxjQUF1QixDQUFDO0lBRTVCLE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQztJQUMvQixNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFN0IsTUFBTSxDQUFDLCtCQUErQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ2pELE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxTQUFTLENBQUMsQ0FBQztRQUMzRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBQSxpQ0FBa0IsRUFBQyxTQUFTLENBQUMsQ0FBQztRQUM3RCxNQUFNLGVBQWUsR0FBRyxNQUFNLElBQUEsaUNBQWtCLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFFNUQsY0FBYyxHQUFHLE1BQU0sR0FBRyxDQUFDLGNBQWMs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QUNYLEdBQUcsRUFBRSxDQUNILGdCQUFVLENBQUMsc0JBQXNCLENBQy9CLE9BQU8sRUFDUCxjQUFjLEVBQ2QsT0FBTyxDQUFDLFdBQVcsRUFBRSxFQUNyQixTQUFTLENBQUMsV0FBVyxFQUFFLEVBQ3ZCLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLG9DQUFvQztTQUNsRSxFQUNILG9EQUFvRCxDQUNyRCxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0ICogYXMgcGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgZGVyaXZlVW5oYXJkZW5lZE1wcywgRWRkc2FNUFNEc2csIE1QU0NvbW1zLCBNUFNUeXBlcywgTVBTVXRpbCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCB7IGVkMjU1MTkgfSBmcm9tICdAbm9ibGUvY3VydmVzL2VkMjU1MTknO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCB7XG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQsXG4gIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7XG4gIEJpdEdvQmFzZSxcbiAgQml0R29SZXF1ZXN0LFxuICBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICBFRERTQVV0aWxzLFxuICBFZGRzYU1QQ3YyVXRpbHMsXG4gIElCYXNlQ29pbixcbiAgSVdhbGxldCxcbiAgUmVxdWVzdFRyYWNlcixcbiAgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIFNpZ25hdHVyZVNoYXJlVHlwZSxcbiAgVHhSZXF1ZXN0LFxufSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHtcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZSxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFR3byxcbiAgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lLFxuICB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvLFxufSBmcm9tICcuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYml0Z28vdHNzL2VkZHNhL2VkZHNhTVBDdjInO1xuaW1wb3J0IHsgZ2V0Qml0Z29TaWduYXR1cmVTaGFyZSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby90c3MvY29tbW9uJztcbmltcG9ydCB7IGRlY29kZVdpdGhDb2RlYyB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy9jb2RlY3MnO1xuaW1wb3J0IHsgZ2VuZXJhdGVHUEdLZXlQYWlyIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL29wZW5ncGdVdGlscyc7XG5pbXBvcnQgeyBNUEN2MlBhcnRpZXNFbnVtIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2JpdGdvL3V0aWxzL3Rzcy9lY2RzYS90eXBlc01QQ3YyJztcbmltcG9ydCB7IGlzVjJFbnZlbG9wZSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvYmFzZVR5cGVzJztcblxuZGVzY3JpYmUoJ0VkRFNBIE1QUyBEU0cgaGVscGVyIGZ1bmN0aW9ucycsIGFzeW5jICgpID0+IHtcbiAgbGV0IHVzZXJLZXlTaGFyZTogQnVmZmVyO1xuICBsZXQgYmFja3VwS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IHVzZXJHcGdQcml2S2V5OiBwZ3AuUHJpdmF0ZUtleTtcbiAgbGV0IGJhY2t1cEdwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuICBsZXQgYml0Z29HcGdQcml2S2V5OiBwZ3AuUHJpdmF0ZUtleTtcbiAgbGV0IGJpdGdvR3BnUHViS2V5OiBwZ3AuS2V5O1xuXG4gIGNvbnN0IHNpZ25hYmxlSGV4ID0gJ2RlYWRiZWVmJztcbiAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8wJztcblxuICBiZWZvcmUoJ2dlbmVyYXRlIEVkRFNBIERLRyBrZXkgc2hhcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHVzZXJHcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgY29uc3QgYmFja3VwR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGNvbnN0IGJpdGdvR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuXG4gICAgdXNlckdwZ1ByaXZLZXkgPSBhd2FpdCBwZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiB1c2VyR3BnS2V5UGFpci5wcml2YXRlS2V5IH0pO1xuICAgIGJhY2t1cEdwZ1ByaXZLZXkgPSBhd2FpdCBwZ3AucmVhZFByaXZhdGVLZXkoeyBhcm1vcmVkS2V5OiBiYWNrdXBHcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gICAgYml0Z29HcGdQcml2S2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gICAgYml0Z29HcGdQdWJLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXkgfSk7XG5cbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnLCBiaXRnb0RrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICB1c2VyS2V5U2hhcmUgPSB1c2VyRGtnLmdldEtleVNoYXJlKCk7XG4gICAgYmFja3VwS2V5U2hhcmUgPSBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcbiAgfSk7XG5cbiAgLy8g4pSA4pSAIFJvdW5kIDEg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUgc2hvdWxkIGJ1aWxkIGEgdmFsaWQgcm91bmQtMSBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kT25lKHVzZXJNc2cxLCB1c2VyR3BnUHJpdktleSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDFJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cxLm1lc3NhZ2UsICdtc2cxLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cxLnNpZ25hdHVyZSwgJ21zZzEuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRPbmUgc2hvdWxkIGJ1aWxkIGEgdmFsaWQgYmFja3VwIHJvdW5kLTEgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYmFja3VwRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gICAgYmFja3VwRHNnLmluaXREc2coYmFja3VwS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCBiYWNrdXBNc2cxID0gYmFja3VwRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZE9uZShcbiAgICAgIGJhY2t1cE1zZzEsXG4gICAgICBiYWNrdXBHcGdQcml2S2V5LFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5CQUNLVVApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDFJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cxLm1lc3NhZ2UsICdtc2cxLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cxLnNpZ25hdHVyZSwgJ21zZzEuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ3ZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUgc2hvdWxkIHZlcmlmeSBhIHZhbGlkIEJpdEdvIHJvdW5kLTEgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCByb3VuZDFPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dCA9IHtcbiAgICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgICAgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZShyb3VuZDFPdXRwdXQsIGJpdGdvR3BnUHViS2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuZnJvbSwgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXNzZXJ0Lm9rKHJlc3VsdC5wYXlsb2FkLmxlbmd0aCA+IDAsICdwYXlsb2FkIHNob3VsZCBiZSBub24tZW1wdHknKTtcbiAgfSk7XG5cbiAgaXQoJ3ZlcmlmeVBlZXJNZXNzYWdlUm91bmRPbmUgc2hvdWxkIHRocm93IG9uIGEgdGFtcGVyZWQgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDFPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMU91dHB1dCA9IHtcbiAgICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgICAgZGF0YToge1xuICAgICAgICBtc2cxOiB7XG4gICAgICAgICAgbWVzc2FnZTogQnVmZmVyLmZyb20oJ3RhbXBlcmVkJykudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgICAgIHNpZ25hdHVyZTogJy0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxuXFxuSU5WQUxJRFxcbi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLVxcbicsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyh2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKHJvdW5kMU91dHB1dCwgYml0Z29HcGdQdWJLZXkpLCAnc2hvdWxkIHRocm93IG9uIGludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBSb3VuZCAyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGl0KCdnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvIHNob3VsZCBidWlsZCBhIHZhbGlkIHJvdW5kLTIgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgdXNlckRzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICB1c2VyRHNnLmluaXREc2codXNlcktleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgY29uc3QgdXNlck1zZzEgPSB1c2VyRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgY29uc3QgYml0Z29Nc2cxID0gYml0Z29Ec2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb1NpZ25lZE1zZzEgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzEucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gICAgY29uc3QgYml0Z29EZXNlcmlhbGl6ZWRNc2cxID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZE9uZShcbiAgICAgIHsgdHlwZTogJ3JvdW5kMU91dHB1dCcsIGRhdGE6IHsgbXNnMTogYml0Z29TaWduZWRNc2cxIH0gfSxcbiAgICAgIGJpdGdvR3BnUHViS2V5XG4gICAgKTtcbiAgICBjb25zdCBbdXNlck1zZzJdID0gdXNlckRzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFt1c2VyTXNnMSwgYml0Z29EZXNlcmlhbGl6ZWRNc2cxXSk7XG5cbiAgICBjb25zdCBzaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSBhd2FpdCBnZXRTaWduYXR1cmVTaGFyZVJvdW5kVHdvKHVzZXJNc2cyLCB1c2VyR3BnUHJpdktleSk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0LFxuICAgICAgSlNPTi5wYXJzZShzaGFyZS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLnR5cGUsICdyb3VuZDJJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLm1lc3NhZ2UsICdtc2cyLm1lc3NhZ2Ugc2hvdWxkIGJlIHNldCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWQuZGF0YS5tc2cyLnNpZ25hdHVyZSwgJ21zZzIuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcbiAgfSk7XG5cbiAgaXQoJ2dldFNpZ25hdHVyZVNoYXJlUm91bmRUd28gc2hvdWxkIGJ1aWxkIGEgdmFsaWQgYmFja3VwIHJvdW5kLTIgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYmFja3VwRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gICAgYmFja3VwRHNnLmluaXREc2coYmFja3VwS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCBiYWNrdXBNc2cxID0gYmFja3VwRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzEgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKFxuICAgICAgeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFtiYWNrdXBNc2cyXSA9IGJhY2t1cERzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiYWNrdXBNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUd28oXG4gICAgICBiYWNrdXBNc2cyLFxuICAgICAgYmFja3VwR3BnUHJpdktleSxcbiAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuQkFDS1VQKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWQgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgICAgIEpTT04ucGFyc2Uoc2hhcmUuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZC50eXBlLCAncm91bmQySW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMi5tZXNzYWdlLCAnbXNnMi5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMi5zaWduYXR1cmUsICdtc2cyLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xuXG4gIGl0KCd2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvIHNob3VsZCB2ZXJpZnkgYSB2YWxpZCBCaXRHbyByb3VuZC0yIG1lc3NhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgdXNlckRzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICB1c2VyRHNnLmluaXREc2codXNlcktleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgY29uc3QgdXNlck1zZzEgPSB1c2VyRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgY29uc3QgYml0Z29Nc2cxID0gYml0Z29Ec2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBbYml0Z29Nc2cyXSA9IGJpdGdvRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JpdGdvTXNnMSwgdXNlck1zZzFdKTtcbiAgICBjb25zdCBiaXRnb1NpZ25lZE1zZzIgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzIucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG5cbiAgICBjb25zdCByb3VuZDJPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dCA9IHtcbiAgICAgIHR5cGU6ICdyb3VuZDJPdXRwdXQnLFxuICAgICAgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmVyaWZ5UGVlck1lc3NhZ2VSb3VuZFR3byhyb3VuZDJPdXRwdXQsIGJpdGdvR3BnUHViS2V5KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuZnJvbSwgTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYXNzZXJ0Lm9rKHJlc3VsdC5wYXlsb2FkLmxlbmd0aCA+IDAsICdwYXlsb2FkIHNob3VsZCBiZSBub24tZW1wdHknKTtcbiAgfSk7XG5cbiAgaXQoJ3ZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28gc2hvdWxkIHRocm93IG9uIGEgdGFtcGVyZWQgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDJPdXRwdXQ6IEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dCA9IHtcbiAgICAgIHR5cGU6ICdyb3VuZDJPdXRwdXQnLFxuICAgICAgZGF0YToge1xuICAgICAgICBtc2cyOiB7XG4gICAgICAgICAgbWVzc2FnZTogQnVmZmVyLmZyb20oJ3RhbXBlcmVkJykudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgICAgIHNpZ25hdHVyZTogJy0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxuXFxuSU5WQUxJRFxcbi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLVxcbicsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyh2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvKHJvdW5kMk91dHB1dCwgYml0Z29HcGdQdWJLZXkpLCAnc2hvdWxkIHRocm93IG9uIGludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH0pO1xuXG4gIC8vIOKUgOKUgCBSb3VuZCAzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGl0KCdnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUgc2hvdWxkIGJ1aWxkIGEgdmFsaWQgcm91bmQtMyBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCB1c2VyRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuICAgIHVzZXJEc2cuaW5pdERzZyh1c2VyS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJEc2cuZ2V0Rmlyc3RNZXNzYWdlKCk7XG5cbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIC8vIEFkdmFuY2UgdG8gcm91bmQgMlxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzEgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKFxuICAgICAgeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFt1c2VyTXNnMl0gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcblxuICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cxLCB1c2VyTXNnMV0pO1xuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzIgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kVHdvKFxuICAgICAgeyB0eXBlOiAncm91bmQyT3V0cHV0JywgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFt1c2VyTXNnM10gPSB1c2VyRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW3VzZXJNc2cyLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzJdKTtcblxuICAgIGNvbnN0IHNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IGF3YWl0IGdldFNpZ25hdHVyZVNoYXJlUm91bmRUaHJlZSh1c2VyTXNnMywgdXNlckdwZ1ByaXZLZXkpO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWQgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCxcbiAgICAgIEpTT04ucGFyc2Uoc2hhcmUuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZC50eXBlLCAncm91bmQzSW5wdXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5tZXNzYWdlLCAnbXNnMy5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkLmRhdGEubXNnMy5zaWduYXR1cmUsICdtc2czLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xuXG4gIGl0KCdnZXRTaWduYXR1cmVTaGFyZVJvdW5kVGhyZWUgc2hvdWxkIGJ1aWxkIGEgdmFsaWQgYmFja3VwIHJvdW5kLTMgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYmFja3VwRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG4gICAgYmFja3VwRHNnLmluaXREc2coYmFja3VwS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBjb25zdCBiYWNrdXBNc2cxID0gYmFja3VwRHNnLmdldEZpcnN0TWVzc2FnZSgpO1xuXG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKTtcbiAgICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICAgIGNvbnN0IGJpdGdvU2lnbmVkTXNnMSA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMS5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgICBjb25zdCBiaXRnb0Rlc2VyaWFsaXplZE1zZzEgPSBhd2FpdCB2ZXJpZnlQZWVyTWVzc2FnZVJvdW5kT25lKFxuICAgICAgeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YTogeyBtc2cxOiBiaXRnb1NpZ25lZE1zZzEgfSB9LFxuICAgICAgYml0Z29HcGdQdWJLZXlcbiAgICApO1xuICAgIGNvbnN0IFtiYWNrdXBNc2cyXSA9IGJhY2t1cERzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiYWNrdXBNc2cxLCBiaXRnb0Rlc2VyaWFsaXplZE1zZzFdKTtcblxuICAgIGNvbnN0IFtiaXRnb01zZzJdID0gYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cxLCBiYWNrdXBNc2cxXSk7XG4gICAgY29uc3QgYml0Z29TaWduZWRNc2cyID0gYXdhaXQgTVBTQ29tbXMuZGV0YWNoU2lnbk1wc01lc3NhZ2UoQnVmZmVyLmZyb20oYml0Z29Nc2cyLnBheWxvYWQpLCBiaXRnb0dwZ1ByaXZLZXkpO1xuICAgIGNvbnN0IGJpdGdvRGVzZXJpYWxpemVkTXNnMiA9IGF3YWl0IHZlcmlmeVBlZXJNZXNzYWdlUm91bmRUd28oXG4gICAgICB7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7IG1zZzI6IGJpdGdvU2lnbmVkTXNnMiB9IH0sXG4gICAgICBiaXRnb0dwZ1B1YktleVxuICAgICk7XG4gICAgY29uc3QgW2JhY2t1cE1zZzNdID0gYmFja3VwRHNnLmhhbmRsZUluY29taW5nTWVzc2FnZXMoW2JhY2t1cE1zZzIsIGJpdGdvRGVzZXJpYWxpemVkTXNnMl0pO1xuXG4gICAgY29uc3Qgc2hhcmU6IFNpZ25hdHVyZVNoYXJlUmVjb3JkID0gYXdhaXQgZ2V0U2lnbmF0dXJlU2hhcmVSb3VuZFRocmVlKFxuICAgICAgYmFja3VwTXNnMyxcbiAgICAgIGJhY2t1cEdwZ1ByaXZLZXksXG4gICAgICBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmUuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLkJBQ0tVUCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNoYXJlLnRvLCBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08pO1xuXG4gICAgY29uc3QgcGFyc2VkID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHNoYXJlLnNoYXJlKSxcbiAgICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDNJbnB1dCdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQudHlwZSwgJ3JvdW5kM0lucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzMubWVzc2FnZSwgJ21zZzMubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5kYXRhLm1zZzMuc2lnbmF0dXJlLCAnbXNnMy5zaWduYXR1cmUgc2hvdWxkIGJlIHNldCcpO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnZ2V0RWRkc2FNUEN2MlJlY292ZXJ5S2V5U2hhcmVzJywgKCkgPT4ge1xuICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3RQYXNzJztcblxuICBjb25zdCBlbmNyeXB0S2V5ID0gKGtleVNoYXJlOiBCdWZmZXIpOiBzdHJpbmcgPT4gc2pjbC5lbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIGtleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gcmVjb3Zlcnkga2V5IHNoYXJlcyBmcm9tIHYxLWVuY3J5cHRlZCByZWR1Y2VkIGtleXMgKG5vIGJpdGdvIGluc3RhbmNlKScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEVERFNBVXRpbHMuZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gICAgICBlbmNyeXB0S2V5KHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgZW5jcnlwdEtleShiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZVxuICAgICk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdC51c2VyS2V5U2hhcmUsIHVzZXJEa2cuZ2V0S2V5U2hhcmUoKSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQuYmFja3VwS2V5U2hhcmUsIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmNvbW1vbktleUNoYWluLCB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJvdXRlIGRlY3J5cHRpb24gdGhyb3VnaCBiaXRnby5kZWNyeXB0QXN5bmMgd2hlbiBhIGJpdGdvIGluc3RhbmNlIGlzIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIHNkay1jb3JlIGhhcyBubyBkZXZEZXBlbmRlbmN5IG9uIHNkay1hcGkgb3IgYXJnb24yLCBzbyB3ZSBjYW5ub3QgZW5jcnlwdCB3aXRoIGEgcmVhbCB2MiBlbnZlbG9wZSBoZXJlLlxuICAgIC8vIFRoZSBzdHViIHZlcmlmaWVzIHRoYXQgdGhlIGZ1bmN0aW9uIGRlbGVnYXRlcyB0byBiaXRnby5kZWNyeXB0QXN5bmMgKHdoaWNoIHN1cHBvcnRzIHYxICsgdjIgaW5cbiAgICAvLyBwcm9kdWN0aW9uKSByYXRoZXIgdGhhbiBmYWxsaW5nIGJhY2sgdG8gc2pjbC5kZWNyeXB0LlxuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgdXNlcktleUJhc2U2NCA9IHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGJhY2t1cEtleUJhc2U2NCA9IGJhY2t1cERrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgICBjb25zdCBtb2NrQml0Z28gPSB7XG4gICAgICBkZWNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKS5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKHVzZXJLZXlCYXNlNjQpLm9uU2Vjb25kQ2FsbCgpLnJlc29sdmVzKGJhY2t1cEtleUJhc2U2NCksXG4gICAgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEVERFNBVXRpbHMuZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gICAgICAnZW5jcnlwdGVkLXVzZXIta2V5JyxcbiAgICAgICdlbmNyeXB0ZWQtYmFja3VwLWtleScsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgbW9ja0JpdGdvXG4gICAgKTtcblxuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRUd2ljZShtb2NrQml0Z28uZGVjcnlwdEFzeW5jIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQudXNlcktleVNoYXJlLCB1c2VyRGtnLmdldEtleVNoYXJlKCkpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LmJhY2t1cEtleVNoYXJlLCBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5jb21tb25LZXlDaGFpbiwgdXNlckRrZy5nZXRDb21tb25LZXljaGFpbigpKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgYSBtYWxmb3JtZWQga2V5Y2FyZCB3aXRoIGEgZGVzY3JpcHRpdmUgZXJyb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWFsZm9ybWVkS2V5ID0gc2pjbC5lbmNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHJhbmRvbUJ5dGVzKDY0KS50b1N0cmluZygnYmFzZTY0JykpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICAgbWFsZm9ybWVkS2V5LFxuICAgICAgICBlbmNyeXB0S2V5KHVzZXJEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgICApLFxuICAgICAgL3VuYWJsZSB0byBkZWNvZGUgcmVkdWNlZCBrZXkgc2hhcmUvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgcmVkdWNlZCBrZXlzIGZyb20gZGlmZmVyZW50IHdhbGxldHMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgWywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgRUREU0FVdGlscy5nZXRFZGRzYU1wY1YyUmVjb3ZlcnlLZXlTaGFyZXNGcm9tUmVkdWNlZEtleShcbiAgICAgICAgZW5jcnlwdEtleSh1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpKSxcbiAgICAgICAgZW5jcnlwdEtleShiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCkpLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlXG4gICAgICApLFxuICAgICAgL3B1YiBrZXlzIGRvIG5vdCBtYXRjaC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCByZWR1Y2VkIGtleXMgd2l0aCBtYXRjaGluZyBwdWIgYnV0IG1pc21hdGNoZWQgcm9vdENoYWluQ29kZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csIGJhY2t1cERrZ10gPSBhd2FpdCBNUFNVdGlsLmdlbmVyYXRlRWREc2FES0dLZXlTaGFyZXMoKTtcbiAgICBjb25zdCB1c2VyUmVkdWNlZEtleVNoYXJlID0gdXNlckRrZy5nZXRSZWR1Y2VkS2V5U2hhcmUoKTtcbiAgICBjb25zdCBiYWNrdXBSZWR1Y2VkS2V5U2hhcmUgPSBiYWNrdXBEa2cuZ2V0UmVkdWNlZEtleVNoYXJlKCk7XG4gICAgY29uc3QgZ2V0RGVjb2RlZFJlZHVjZWRLZXlTaGFyZSA9IE1QU1R5cGVzLmdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmU7XG4gICAgY29uc3QgZGVjb2RlU3R1YiA9IHNpbm9uLnN0dWIoTVBTVHlwZXMsICdnZXREZWNvZGVkUmVkdWNlZEtleVNoYXJlJykuY2FsbHNGYWtlKChidWYpID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZWQgPSBnZXREZWNvZGVkUmVkdWNlZEtleVNoYXJlKGJ1Zik7XG4gICAgICBpZiAoQnVmZmVyLmZyb20oYnVmKS5lcXVhbHMoYmFja3VwUmVkdWNlZEtleVNoYXJlKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJlZHVjZWQsXG4gICAgICAgICAgcm9vdENoYWluQ29kZTogQXJyYXkuZnJvbShyYW5kb21CeXRlcygzMikpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlZHVjZWQ7XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIEVERFNBVXRpbHMuZ2V0RWRkc2FNcGNWMlJlY292ZXJ5S2V5U2hhcmVzRnJvbVJlZHVjZWRLZXkoXG4gICAgICAgICAgZW5jcnlwdEtleSh1c2VyUmVkdWNlZEtleVNoYXJlKSxcbiAgICAgICAgICBlbmNyeXB0S2V5KGJhY2t1cFJlZHVjZWRLZXlTaGFyZSksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZVxuICAgICAgICApLFxuICAgICAgICAvcm9vdENoYWluQ29kZXMgZG8gbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVjb2RlU3R1Yi5yZXN0b3JlKCk7XG4gICAgfVxuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZScsICgpID0+IHtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcblxuICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3RQYXNzJztcbiAgY29uc3Qgc2lnbmFibGVIZXggPSAnZGVhZGJlZWYnO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG4gIGNvbnN0IGV4cGVjdGVkQWRhdGEgPSBgJHtzaWduYWJsZUhleH06JHtkZXJpdmF0aW9uUGF0aH1gO1xuICBjb25zdCB0eFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWVkZHNhLXJvdW5kMScsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXQtZWRkc2Etcm91bmQxJyxcbiAgICBlbnRlcnByaXNlSWQ6ICdlbnRlcnByaXNlLWVkZHNhLXJvdW5kMScsXG4gICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2lnbmFibGVIZXgsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiBzaWduYWJsZUhleCxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0EgdXNlciBrZXkgc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgdXNlcktleVNoYXJlID0gdXNlckRrZy5nZXRLZXlTaGFyZSgpO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBjb25zdCBzamNsRW5jcnlwdCA9IChwYXJhbXM6IHsgcGFzc3dvcmQ6IHN0cmluZzsgaW5wdXQ6IHN0cmluZzsgYWRhdGE/OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxNik7XG4gICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0LCB7XG4gICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICBpdjogW1xuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoOCwgMTIpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICAgICAgXSxcbiAgICAgICAgYWRhdGE6IHBhcmFtcy5hZGF0YSxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgbW9ja0JpdGdvID0ge1xuICAgICAgZW5jcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZShzamNsRW5jcnlwdCksXG4gICAgICBlbmNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtcykgPT4gc2pjbEVuY3J5cHQocGFyYW1zKSksXG4gICAgfSBhcyB1bmtub3duIGFzIEJpdEdvQmFzZTtcblxuICAgIGNvbnN0IG1vY2tDb2luID0ge1xuICAgICAgZ2V0TVBDQWxnb3JpdGhtOiBzaW5vbi5zdHViKCkucmV0dXJucygnZWRkc2EnKSxcbiAgICB9IGFzIHVua25vd24gYXMgSUJhc2VDb2luO1xuXG4gICAgZWRkc2FNUEN2MlV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0Z28sIG1vY2tDb2luKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBjcmVhdGUgYSByb3VuZC0xIHNoYXJlIGFuZCBlbmNyeXB0ZWQgU0pDTCBzZXNzaW9uIHBheWxvYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaWduYXR1cmVTaGFyZVJvdW5kMS5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaWduYXR1cmVTaGFyZVJvdW5kMS50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcbiAgICBhc3NlcnQub2socmVzdWx0LnVzZXJHcGdQdWJLZXkuaW5jbHVkZXMoJ0JFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLJykpO1xuICAgIGFzc2VydC5vayhKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKS5jdCwgJ2VuY3J5cHRlZFJvdW5kMVNlc3Npb24gc2hvdWxkIGJlIGFuIFNKQ0wgSlNPTiBibG9iJyk7XG4gICAgYXNzZXJ0Lm9rKEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFVzZXJHcGdQcnZLZXkpLmN0LCAnZW5jcnlwdGVkVXNlckdwZ1BydktleSBzaG91bGQgYmUgYW4gU0pDTCBKU09OIGJsb2InKTtcblxuICAgIGNvbnN0IHBhcnNlZFNoYXJlID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHJlc3VsdC5zaWduYXR1cmVTaGFyZVJvdW5kMS5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkU2hhcmUudHlwZSwgJ3JvdW5kMUlucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMS5tZXNzYWdlLCAnbXNnMS5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkU2hhcmUuZGF0YS5tc2cxLnNpZ25hdHVyZSwgJ21zZzEuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZGVjb2RlVVJJQ29tcG9uZW50KGVuY3J5cHRlZFJvdW5kMVNlc3Npb24uYWRhdGEpLFxuICAgICAgYE1QU19EU0dfU0lHTklOR19ST1VORDFfU1RBVEU6JHtleHBlY3RlZEFkYXRhfWAsXG4gICAgICAncm91bmQtMSBzZXNzaW9uIGFkYXRhIHNob3VsZCBiaW5kIHRoZSBzaWduaW5nIGNvbnRleHQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBkZWNvZGVVUklDb21wb25lbnQoZW5jcnlwdGVkVXNlckdwZ1BydktleS5hZGF0YSksXG4gICAgICBgTVBTX0RTR19TSUdOSU5HX1VTRVJfR1BHX0tFWToke2V4cGVjdGVkQWRhdGF9YCxcbiAgICAgICdHUEcgcHJpdmF0ZSBrZXkgYWRhdGEgc2hvdWxkIGJpbmQgdGhlIHNpZ25pbmcgY29udGV4dCdcbiAgICApO1xuXG4gICAgY29uc3Qgc2Vzc2lvblBheWxvYWQgPSBKU09OLnBhcnNlKHNqY2wuZGVjcnlwdCh3YWxsZXRQYXNzcGhyYXNlLCByZXN1bHQuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbikpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC5kc2dTZXNzaW9uLCAnZHNnU2Vzc2lvbiBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAyJyk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLnVzZXJNc2dQYXlsb2FkLCAndXNlck1zZ1BheWxvYWQgc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHVzZSB2MiBlbmNyeXB0aW9uIHdoZW4gZW5jcnlwdGVkUHJ2IGlzIGEgdjIgZW52ZWxvcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdCA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAuY2FsbHNGYWtlKChpbnB1dDogc3RyaW5nLCBhZGF0YTogc3RyaW5nKSA9PiBQcm9taXNlLnJlc29sdmUoSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpbnB1dCwgYWRhdGEgfSkpKTtcbiAgICBjb25zdCBkZXN0cm95ID0gc2lub24uc3R1YigpO1xuICAgIGNvbnN0IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgZW5jcnlwdCwgZGVzdHJveSB9KTtcbiAgICBtb2NrQml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbjtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGVuY3J5cHRlZFBydjogSlNPTi5zdHJpbmdpZnkoeyB2OiAyIH0pLFxuICAgIH0pO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoY3JlYXRlRW5jcnlwdGlvblNlc3Npb24pO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbi5nZXRDYWxsKDApLmFyZ3NbMF0sIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQobW9ja0JpdGdvLmVuY3J5cHRBc3luYyBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRUd2ljZShlbmNyeXB0KTtcbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShkZXN0cm95KTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSBKU09OLnBhcnNlKHJlc3VsdC5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24udiwgMik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24uYWRhdGEsIGBNUFNfRFNHX1NJR05JTkdfUk9VTkQxX1NUQVRFOiR7ZXhwZWN0ZWRBZGF0YX1gKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkVXNlckdwZ1BydktleS52LCAyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkVXNlckdwZ1BydktleS5hZGF0YSwgYE1QU19EU0dfU0lHTklOR19VU0VSX0dQR19LRVk6JHtleHBlY3RlZEFkYXRhfWApO1xuXG4gICAgY29uc3Qgc2Vzc2lvblBheWxvYWQgPSBKU09OLnBhcnNlKGVuY3J5cHRlZFJvdW5kMVNlc3Npb24uaW5wdXQpO1xuICAgIGFzc2VydC5vayhzZXNzaW9uUGF5bG9hZC5kc2dTZXNzaW9uLCAnZHNnU2Vzc2lvbiBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAyJyk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLnVzZXJNc2dQYXlsb2FkLCAndXNlck1zZ1BheWxvYWQgc2hvdWxkIGJlIHBlcnNpc3RlZCBmb3Igcm91bmQgMicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHVzZSBTSkNMIGVuY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRQcnYgaXMgYSB2MSBibG9iJywgYXN5bmMgKCkgPT4ge1xuICAgIG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiA9IHNpbm9uLnN0dWIoKTtcbiAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBzamNsLmVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKG1vY2tCaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiBhcyBzaW5vbi5TaW5vblN0dWIpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRUd2ljZShtb2NrQml0Z28uZW5jcnlwdEFzeW5jIGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgYXNzZXJ0Lm9rKEpTT04ucGFyc2UocmVzdWx0LmVuY3J5cHRlZFJvdW5kMVNlc3Npb24pLmN0LCAnZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiBzaG91bGQgYmUgYW4gU0pDTCBKU09OIGJsb2InKTtcbiAgICBhc3NlcnQub2soSlNPTi5wYXJzZShyZXN1bHQuZW5jcnlwdGVkVXNlckdwZ1BydktleSkuY3QsICdlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IHNob3VsZCBiZSBhbiBTSkNMIEpTT04gYmxvYicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHByb3BhZ2F0ZSB0aGUgdHgtb25seSBndWFyZCB3aGVuIHRyYW5zYWN0aW9ucyBhcmUgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi50eFJlcXVlc3QsIHRyYW5zYWN0aW9uczogdW5kZWZpbmVkIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3QsXG4gICAgICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pLFxuICAgICAgL1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QvXG4gICAgKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0VkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUnLCAoKSA9PiB7XG4gIGxldCBlZGRzYU1QQ3YyVXRpbHM6IEVkZHNhTVBDdjJVdGlscztcbiAgbGV0IG1vY2tCaXRnbzogQml0R29CYXNlO1xuICBsZXQgdXNlcktleVNoYXJlOiBCdWZmZXI7XG4gIGxldCBiaXRnb0tleVNoYXJlOiBCdWZmZXI7XG4gIGxldCBiaXRnb0dwZ0tleVBhaXI6IHBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+O1xuICBsZXQgYml0Z29HcGdQcml2S2V5OiBwZ3AuUHJpdmF0ZUtleTtcblxuICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Rlc3RQYXNzJztcbiAgY29uc3Qgc2lnbmFibGVIZXggPSAnZGVhZGJlZWYnO1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG4gIGNvbnN0IGV4cGVjdGVkQWRhdGEgPSBgJHtzaWduYWJsZUhleH06JHtkZXJpdmF0aW9uUGF0aH1gO1xuXG4gIGNvbnN0IGJhc2VUeFJlcXVlc3Q6IFR4UmVxdWVzdCA9IHtcbiAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWVkZHNhLXJvdW5kMicsXG4gICAgd2FsbGV0SWQ6ICd3YWxsZXQtZWRkc2Etcm91bmQyJyxcbiAgICBlbnRlcnByaXNlSWQ6ICdlbnRlcnByaXNlLWVkZHNhLXJvdW5kMicsXG4gICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAge1xuICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgc2lnbmFibGVIZXgsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiBzaWduYWJsZUhleCxcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGJlZm9yZSgnZ2VuZXJhdGUgRWREU0Ega2V5IHNoYXJlcyBhbmQgR1BHIGtleXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2csICwgYml0Z29Ea2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgdXNlcktleVNoYXJlID0gdXNlckRrZy5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvS2V5U2hhcmUgPSBiaXRnb0RrZy5nZXRLZXlTaGFyZSgpO1xuXG4gICAgYml0Z29HcGdLZXlQYWlyID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdlZDI1NTE5Jyk7XG4gICAgYml0Z29HcGdQcml2S2V5ID0gYXdhaXQgcGdwLnJlYWRQcml2YXRlS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnByaXZhdGVLZXkgfSk7XG4gIH0pO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIG1vY2tCaXRnbyA9IHtcbiAgICAgIGVuY3J5cHQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhcmFtcykgPT4ge1xuICAgICAgICBjb25zdCBzYWx0ID0gcmFuZG9tQnl0ZXMoOCk7XG4gICAgICAgIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTYpO1xuICAgICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0LCB7XG4gICAgICAgICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgICAgICAgaXY6IFtcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDgsIDEyKSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFkYXRhOiBwYXJhbXMuYWRhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICBlbmNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICBjb25zdCBzYWx0ID0gcmFuZG9tQnl0ZXMoOCk7XG4gICAgICAgIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTYpO1xuICAgICAgICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhcmFtcy5wYXNzd29yZCwgcGFyYW1zLmlucHV0LCB7XG4gICAgICAgICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgICAgICAgaXY6IFtcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDAsIDQpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDgsIDEyKSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgxMiwgMTYpKSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGFkYXRhOiBwYXJhbXMuYWRhdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICBkZWNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChwYXJhbXMpID0+IHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCkpLFxuICAgICAgZGVjcnlwdEFzeW5jOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCkpLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb0Jhc2U7XG5cbiAgICBjb25zdCBtb2NrQ29pbiA9IHtcbiAgICAgIGdldE1QQ0FsZ29yaXRobTogc2lub24uc3R1YigpLnJldHVybnMoJ2VkZHNhJyksXG4gICAgfSBhcyB1bmtub3duIGFzIElCYXNlQ29pbjtcblxuICAgIGVkZHNhTVBDdjJVdGlscyA9IG5ldyBFZGRzYU1QQ3YyVXRpbHMobW9ja0JpdGdvLCBtb2NrQ29pbik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY3JlYXRlIGEgcm91bmQtMiBzaGFyZSBmcm9tIG9mZmxpbmUgcm91bmQgMScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyhiYXNlVHhSZXF1ZXN0KSxcbiAgICAgIHJvdW5kMS5zaWduYXR1cmVTaGFyZVJvdW5kMSxcbiAgICAgIHJvdW5kMS51c2VyR3BnUHViS2V5LFxuICAgICAgYml0Z29HcGdQcml2S2V5XG4gICAgKTtcblxuICAgIGNvbnN0IHJvdW5kMiA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDEsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMi5mcm9tLCBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMi50bywgU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPKTtcblxuICAgIGNvbnN0IHBhcnNlZFNoYXJlID0gZGVjb2RlV2l0aENvZGVjKFxuICAgICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQsXG4gICAgICBKU09OLnBhcnNlKHJvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMi5zaGFyZSksXG4gICAgICAnRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQySW5wdXQnXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkU2hhcmUudHlwZSwgJ3JvdW5kMklucHV0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMi5tZXNzYWdlLCAnbXNnMi5tZXNzYWdlIHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQub2socGFyc2VkU2hhcmUuZGF0YS5tc2cyLnNpZ25hdHVyZSwgJ21zZzIuc2lnbmF0dXJlIHNob3VsZCBiZSBzZXQnKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gPSBKU09OLnBhcnNlKHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBkZWNvZGVVUklDb21wb25lbnQoZW5jcnlwdGVkUm91bmQyU2Vzc2lvbi5hZGF0YSksXG4gICAgICBgTVBTX0RTR19TSUdOSU5HX1JPVU5EMl9TVEFURToke2V4cGVjdGVkQWRhdGF9YFxuICAgICk7XG5cbiAgICBjb25zdCBzZXNzaW9uUGF5bG9hZCA9IEpTT04ucGFyc2Uoc2pjbC5kZWNyeXB0KHdhbGxldFBhc3NwaHJhc2UsIHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uKSk7XG4gICAgYXNzZXJ0Lm9rKHNlc3Npb25QYXlsb2FkLmRzZ1Nlc3Npb24sICdkc2dTZXNzaW9uIHNob3VsZCBiZSBwZXJzaXN0ZWQgZm9yIHJvdW5kIDMnKTtcbiAgICBhc3NlcnQub2soc2Vzc2lvblBheWxvYWQudXNlck1zZ1BheWxvYWQsICd1c2VyTXNnUGF5bG9hZCBzaG91bGQgYmUgcGVyc2lzdGVkIGZvciByb3VuZCAzJyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdXNlIHYyIGRlY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uIGlzIGEgdjIgZW52ZWxvcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdCA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAuY2FsbHNGYWtlKChpbnB1dDogc3RyaW5nLCBhZGF0YTogc3RyaW5nKSA9PiBQcm9taXNlLnJlc29sdmUoSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpbnB1dCwgYWRhdGEgfSkpKTtcbiAgICBjb25zdCBkZXN0cm95ID0gc2lub24uc3R1YigpO1xuICAgIGNvbnN0IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgZW5jcnlwdCwgZGVzdHJveSB9KTtcbiAgICBtb2NrQml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbjtcblxuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGVuY3J5cHRlZFBydjogSlNPTi5zdHJpbmdpZnkoeyB2OiAyIH0pLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWVzc2FnZUJ1ZmZlciA9IEJ1ZmZlci5mcm9tKHNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgZGVyaXZhdGlvblBhdGgsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RSb3VuZDEgPSBhd2FpdCBzaWduQml0Z29FZGRzYVJvdW5kMShcbiAgICAgIGJpdGdvRHNnLFxuICAgICAgY2xvbmVUeFJlcXVlc3RXaXRoRW1wdHlTaWduYXR1cmVTaGFyZXMoYmFzZVR4UmVxdWVzdCksXG4gICAgICByb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDEsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICBjb25zdCBkZWNyeXB0QXN5bmMgPSBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXM6IHsgaW5wdXQ6IHN0cmluZyB9KSA9PiB7XG4gICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04ucGFyc2UocGFyYW1zLmlucHV0KTtcbiAgICAgIHJldHVybiBlbnZlbG9wZS5pbnB1dDtcbiAgICB9KTtcbiAgICBtb2NrQml0Z28uZGVjcnlwdEFzeW5jID0gZGVjcnlwdEFzeW5jO1xuXG4gICAgY29uc3Qgcm91bmQyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkKG1vY2tCaXRnby5kZWNyeXB0QXN5bmMgYXMgc2lub24uU2lub25TdHViKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gPSBKU09OLnBhcnNlKHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQyU2Vzc2lvbi52LCAyKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZW5jcnlwdGVkUm91bmQyU2Vzc2lvbi5hZGF0YSwgYE1QU19EU0dfU0lHTklOR19ST1VORDJfU1RBVEU6JHtleHBlY3RlZEFkYXRhfWApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB0YW1wZXJlZCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uIGFkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG90aGVyVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8xLzInLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICAgIGNvbnN0IHJvdW5kMU90aGVyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IG90aGVyVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShzaWduYWJsZUhleCwgJ2hleCcpO1xuICAgIGNvbnN0IGJpdGdvRHNnID0gbmV3IEVkZHNhTVBTRHNnLkRTRyhNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBiaXRnb0RzZy5pbml0RHNnKGJpdGdvS2V5U2hhcmUsIG1lc3NhZ2VCdWZmZXIsIGRlcml2YXRpb25QYXRoLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDEoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKGJhc2VUeFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMlNoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMU90aGVyLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgdGFtcGVyZWQgZW5jcnlwdGVkVXNlckdwZ1BydktleSBhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBvdGhlclR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4uYmFzZVR4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgc2lnbmFibGVIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMS8yJyxcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgICBjb25zdCByb3VuZDFPdGhlciA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBvdGhlclR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXNzYWdlQnVmZmVyID0gQnVmZmVyLmZyb20oc2lnbmFibGVIZXgsICdoZXgnKTtcbiAgICBjb25zdCBiaXRnb0RzZyA9IG5ldyBFZGRzYU1QU0RzZy5EU0coTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG4gICAgYml0Z29Ec2cuaW5pdERzZyhiaXRnb0tleVNoYXJlLCBtZXNzYWdlQnVmZmVyLCBkZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyhiYXNlVHhSZXF1ZXN0KSxcbiAgICAgIHJvdW5kMS5zaWduYXR1cmVTaGFyZVJvdW5kMSxcbiAgICAgIHJvdW5kMS51c2VyR3BnUHViS2V5LFxuICAgICAgYml0Z29HcGdQcml2S2V5XG4gICAgKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDEsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDFPdGhlci5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9BZGF0YSBkb2VzIG5vdCBtYXRjaCBjeXBoZXJ0ZXh0IGFkYXRhL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gQml0R28gc2lnbmF0dXJlIHNoYXJlIGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IGJhc2VUeFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYmFzZVRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24oYmFzZVR4UmVxdWVzdCk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Tm9CaXRnb1NoYXJlOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5iYXNlVHJhbnNhY3Rpb24sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3ROb0JpdGdvU2hhcmUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvTWlzc2luZyBCaXRHbyByb3VuZDFPdXRwdXQgc2lnbmF0dXJlIHNoYXJlL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvcGFnYXRlIHRoZSB0eC1vbmx5IGd1YXJkIHdoZW4gdHJhbnNhY3Rpb25zIGFyZSBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMSA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQxU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiBiYXNlVHhSZXF1ZXN0LFxuICAgICAgcHJ2OiB1c2VyS2V5U2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB7IC4uLmJhc2VUeFJlcXVlc3QsIHRyYW5zYWN0aW9uczogdW5kZWZpbmVkIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3QsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIHRyYW5zYWN0aW9ucyBhcnJheSBpcyBlbXB0eScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByb3VuZDEgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogYmFzZVR4UmVxdWVzdCxcbiAgICAgIHBydjogdXNlcktleVNoYXJlLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgfSk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi5iYXNlVHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IFtdIH0sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiByb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvVW5hYmxlIHRvIGZpbmQgdHJhbnNhY3Rpb25zIGluIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnRWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZScsICgpID0+IHtcbiAgbGV0IGVkZHNhTVBDdjJVdGlsczogRWRkc2FNUEN2MlV0aWxzO1xuICBsZXQgbW9ja0JpdGdvOiBCaXRHb0Jhc2U7XG4gIGxldCB1c2VyS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ1ByaXZLZXk6IHBncC5Qcml2YXRlS2V5O1xuXG4gIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndGVzdFBhc3MnO1xuICBjb25zdCBzaWduYWJsZUhleCA9ICdkZWFkYmVlZic7XG4gIGNvbnN0IGRlcml2YXRpb25QYXRoID0gJ20vMC8wJztcblxuICBjb25zdCBiYXNlVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS1lZGRzYS1yb3VuZDMnLFxuICAgIHdhbGxldElkOiAnd2FsbGV0LWVkZHNhLXJvdW5kMycsXG4gICAgZW50ZXJwcmlzZUlkOiAnZW50ZXJwcmlzZS1lZGRzYS1yb3VuZDMnLFxuICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgIHNpZ25hYmxlSGV4LFxuICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogc2lnbmFibGVIZXgsXG4gICAgICAgIH0sXG4gICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICB9LFxuICAgIF0sXG4gICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdwYXltZW50JyB9LFxuICAgIHVuc2lnbmVkVHhzOiBbXSxcbiAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICBiZWZvcmUoJ2dlbmVyYXRlIEVkRFNBIGtleSBzaGFyZXMgYW5kIEdQRyBrZXlzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCAsIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIHVzZXJLZXlTaGFyZSA9IHVzZXJEa2cuZ2V0S2V5U2hhcmUoKTtcbiAgICBiaXRnb0tleVNoYXJlID0gYml0Z29Ea2cuZ2V0S2V5U2hhcmUoKTtcblxuICAgIGJpdGdvR3BnS2V5UGFpciA9IGF3YWl0IGdlbmVyYXRlR1BHS2V5UGFpcignZWQyNTUxOScpO1xuICAgIGJpdGdvR3BnUHJpdktleSA9IGF3YWl0IHBncC5yZWFkUHJpdmF0ZUtleSh7IGFybW9yZWRLZXk6IGJpdGdvR3BnS2V5UGFpci5wcml2YXRlS2V5IH0pO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBlbmNyeXB0OiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChwYXJhbXMpID0+IHtcbiAgICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgICAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCwge1xuICAgICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICAgIGl2OiBbXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMTIsIDE2KSksXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgZW5jcnlwdEFzeW5jOiBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgY29uc3Qgc2FsdCA9IHJhbmRvbUJ5dGVzKDgpO1xuICAgICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgICAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCwge1xuICAgICAgICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zdWJhcnJheSg0KSldLFxuICAgICAgICAgIGl2OiBbXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSgwLCA0KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg0LCA4KSksXG4gICAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMTIsIDE2KSksXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICAgZGVjcnlwdDogc2lub24uc3R1YigpLmNhbGxzRmFrZSgocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICAgIGRlY3J5cHRBc3luYzogc2lub24uc3R1YigpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBlZGRzYU1QQ3YyVXRpbHMgPSBuZXcgRWRkc2FNUEN2MlV0aWxzKG1vY2tCaXRnbywgbW9ja0NvaW4pO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVSb3VuZDJGbG93KFxuICAgIHR4UmVxdWVzdDogVHhSZXF1ZXN0LFxuICAgIGVuY3J5cHRlZFBydj86IHN0cmluZ1xuICApOiBQcm9taXNlPHtcbiAgICByb3VuZDE6IHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICAgIHVzZXJHcGdQdWJLZXk6IHN0cmluZztcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IHN0cmluZztcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHN0cmluZztcbiAgICB9O1xuICAgIHJvdW5kMjoge1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDI6IFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogc3RyaW5nO1xuICAgIH07XG4gICAgdHhSZXF1ZXN0Um91bmQxOiBUeFJlcXVlc3Q7XG4gICAgdHhSZXF1ZXN0Um91bmQyOiBUeFJlcXVlc3Q7XG4gICAgbWVzc2FnZUJ1ZmZlcjogQnVmZmVyO1xuICB9PiB7XG4gICAgY29uc3Qgcm91bmQxID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZSh7XG4gICAgICB0eFJlcXVlc3QsXG4gICAgICBwcnY6IHVzZXJLZXlTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgZW5jcnlwdGVkUHJ2LFxuICAgIH0pO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi51bnNpZ25lZFR4LnNpZ25hYmxlSGV4LCAnaGV4Jyk7XG4gICAgY29uc3QgYml0Z29Ec2cgPSBuZXcgRWRkc2FNUFNEc2cuRFNHKE1QQ3YyUGFydGllc0VudW0uQklUR08pO1xuICAgIGJpdGdvRHNnLmluaXREc2coYml0Z29LZXlTaGFyZSwgbWVzc2FnZUJ1ZmZlciwgdHJhbnNhY3Rpb24udW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aCwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdFJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb0VkZHNhUm91bmQxKFxuICAgICAgYml0Z29Ec2csXG4gICAgICBjbG9uZVR4UmVxdWVzdFdpdGhFbXB0eVNpZ25hdHVyZVNoYXJlcyh0eFJlcXVlc3QpLFxuICAgICAgcm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcm91bmQxLnVzZXJHcGdQdWJLZXksXG4gICAgICBiaXRnb0dwZ1ByaXZLZXlcbiAgICApO1xuXG4gICAgY29uc3Qgcm91bmQyID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZSh7XG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogcm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgfSk7XG5cbiAgICBjb25zdCByb3VuZDFUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdFJvdW5kMSk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQyID0gYXdhaXQgc2lnbkJpdGdvRWRkc2FSb3VuZDIoXG4gICAgICBiaXRnb0RzZyxcbiAgICAgIHtcbiAgICAgICAgLi4udHhSZXF1ZXN0Um91bmQxLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5yb3VuZDFUcmFuc2FjdGlvbixcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogWy4uLnJvdW5kMVRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlc10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICByb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIsXG4gICAgICByb3VuZDEudXNlckdwZ1B1YktleSxcbiAgICAgIGJpdGdvR3BnUHJpdktleVxuICAgICk7XG5cbiAgICByZXR1cm4geyByb3VuZDEsIHJvdW5kMiwgdHhSZXF1ZXN0Um91bmQxLCB0eFJlcXVlc3RSb3VuZDIsIG1lc3NhZ2VCdWZmZXIgfTtcbiAgfVxuXG4gIGl0KCdzaG91bGQgY3JlYXRlIGEgcm91bmQtMyBzaGFyZSBmcm9tIG9mZmxpbmUgcm91bmQgMicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBjb25zdCByb3VuZDMgPSBhd2FpdCBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQyLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICB9KTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMuZnJvbSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMudG8sIFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyk7XG5cbiAgICBjb25zdCBwYXJzZWRTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICAgIEVkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxuICAgICAgSlNPTi5wYXJzZShyb3VuZDMuc2lnbmF0dXJlU2hhcmVSb3VuZDMuc2hhcmUpLFxuICAgICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0J1xuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBhcnNlZFNoYXJlLnR5cGUsICdyb3VuZDNJbnB1dCcpO1xuICAgIGFzc2VydC5vayhwYXJzZWRTaGFyZS5kYXRhLm1zZzMubWVzc2FnZSwgJ21zZzMubWVzc2FnZSBzaG91bGQgYmUgc2V0Jyk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZFNoYXJlLmRhdGEubXNnMy5zaWduYXR1cmUsICdtc2czLnNpZ25hdHVyZSBzaG91bGQgYmUgc2V0Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdXNlIHYyIGRlY3J5cHRpb24gd2hlbiBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uIGlzIGEgdjIgZW52ZWxvcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW5jcnlwdCA9IHNpbm9uXG4gICAgICAuc3R1YigpXG4gICAgICAuY2FsbHNGYWtlKChpbnB1dDogc3RyaW5nLCBhZGF0YTogc3RyaW5nKSA9PiBQcm9taXNlLnJlc29sdmUoSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpbnB1dCwgYWRhdGEgfSkpKTtcbiAgICBjb25zdCBkZXN0cm95ID0gc2lub24uc3R1YigpO1xuICAgIGNvbnN0IGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgZW5jcnlwdCwgZGVzdHJveSB9KTtcbiAgICBtb2NrQml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24gPSBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbjtcblxuICAgIGNvbnN0IGRlY3J5cHRBc3luYyA9IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShwYXJhbXMuaW5wdXQpO1xuICAgICAgcmV0dXJuIGVudmVsb3BlLmlucHV0O1xuICAgIH0pO1xuICAgIG1vY2tCaXRnby5kZWNyeXB0QXN5bmMgPSBkZWNyeXB0QXN5bmM7XG5cbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCwgSlNPTi5zdHJpbmdpZnkoeyB2OiAyIH0pKTtcblxuICAgIGNvbnN0IHJvdW5kMyA9IGF3YWl0IGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDIsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgIH0pO1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKChtb2NrQml0Z28uZGVjcnlwdEFzeW5jIGFzIHNpbm9uLlNpbm9uU3R1YikuY2FsbENvdW50LCA0KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQzLnNpZ25hdHVyZVNoYXJlUm91bmQzLmZyb20sIFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3QgdGFtcGVyZWQgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiBhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBvdGhlclR4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgICAgLi4uYmFzZVR4UmVxdWVzdCxcbiAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgc2lnbmFibGVIZXg6ICdjYWZlYmFiZScsXG4gICAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMS8yJyxcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0gYXMgdW5rbm93biBhcyBUeFJlcXVlc3Q7XG5cbiAgICBjb25zdCBvdGhlckZsb3cgPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KG90aGVyVHhSZXF1ZXN0KTtcbiAgICBjb25zdCB7IHJvdW5kMSwgdHhSZXF1ZXN0Um91bmQyIH0gPSBhd2FpdCBjcmVhdGVSb3VuZDJGbG93KGJhc2VUeFJlcXVlc3QpO1xuXG4gICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAoKSA9PlxuICAgICAgICBlZGRzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHtcbiAgICAgICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMixcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IG90aGVyRmxvdy5yb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvQWRhdGEgZG9lcyBub3QgbWF0Y2ggY3lwaGVydGV4dCBhZGF0YS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCB0YW1wZXJlZCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5IGFkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG90aGVyVHhSZXF1ZXN0OiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5iYXNlVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICBzaWduYWJsZUhleDogJ2NhZmViYWJlJyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8xLzInLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnY2FmZWJhYmUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmVzOiBbXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSBhcyB1bmtub3duIGFzIFR4UmVxdWVzdDtcblxuICAgIGNvbnN0IG90aGVyRmxvdyA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3cob3RoZXJUeFJlcXVlc3QpO1xuICAgIGNvbnN0IHsgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQyLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogb3RoZXJGbG93LnJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9BZGF0YSBkb2VzIG5vdCBtYXRjaCBjeXBoZXJ0ZXh0IGFkYXRhL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gQml0R28gcm91bmQtMiBzaWduYXR1cmUgc2hhcmUgaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB7IHJvdW5kMSwgcm91bmQyLCB0eFJlcXVlc3RSb3VuZDEgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBjb25zdCByb3VuZDFUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdFJvdW5kMSk7XG4gICAgY29uc3QgdHhSZXF1ZXN0Tm9CaXRnb1JvdW5kMlNoYXJlOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi50eFJlcXVlc3RSb3VuZDEsXG4gICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIC4uLnJvdW5kMVRyYW5zYWN0aW9uLFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogWy4uLnJvdW5kMVRyYW5zYWN0aW9uLnNpZ25hdHVyZVNoYXJlcywgcm91bmQyLnNpZ25hdHVyZVNoYXJlUm91bmQyXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3ROb0JpdGdvUm91bmQyU2hhcmUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBiaXRnb1B1YmxpY0dwZ0tleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiByb3VuZDEuZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiByb3VuZDIuZW5jcnlwdGVkUm91bmQyU2Vzc2lvbixcbiAgICAgICAgfSksXG4gICAgICAvTWlzc2luZyBCaXRHbyByb3VuZDJPdXRwdXQgc2lnbmF0dXJlIHNoYXJlL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcHJvcGFnYXRlIHRoZSB0eC1vbmx5IGd1YXJkIHdoZW4gdHJhbnNhY3Rpb25zIGFyZSBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHsgcm91bmQxLCByb3VuZDIgfSA9IGF3YWl0IGNyZWF0ZVJvdW5kMkZsb3coYmFzZVR4UmVxdWVzdCk7XG5cbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICgpID0+XG4gICAgICAgIGVkZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoe1xuICAgICAgICAgIHR4UmVxdWVzdDogeyAuLi5iYXNlVHhSZXF1ZXN0LCB0cmFuc2FjdGlvbnM6IHVuZGVmaW5lZCB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleTogcm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksXG4gICAgICAgICAgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogcm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb24sXG4gICAgICAgIH0pLFxuICAgICAgL1VuYWJsZSB0byBmaW5kIHRyYW5zYWN0aW9ucyBpbiB0eFJlcXVlc3QvXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiB0cmFuc2FjdGlvbnMgYXJyYXkgaXMgZW1wdHknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeyByb3VuZDEsIHJvdW5kMiB9ID0gYXdhaXQgY3JlYXRlUm91bmQyRmxvdyhiYXNlVHhSZXF1ZXN0KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDNTaGFyZSh7XG4gICAgICAgICAgdHhSZXF1ZXN0OiB7IC4uLmJhc2VUeFJlcXVlc3QsIHRyYW5zYWN0aW9uczogW10gfSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6IHJvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IHJvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgICAgICB9KSxcbiAgICAgIC9VbmFibGUgdG8gZmluZCB0cmFuc2FjdGlvbnMgaW4gdHhSZXF1ZXN0L1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdnZXRCaXRnb1NpZ25hdHVyZVNoYXJlJywgKCkgPT4ge1xuICBjb25zdCByb3VuZDFPdXRwdXRTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YToge30gfSksXG4gIH07XG4gIGNvbnN0IHJvdW5kMk91dHB1dFNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDJPdXRwdXQnLCBkYXRhOiB7fSB9KSxcbiAgfTtcblxuICBpdCgnc2VsZWN0cyB0aGUgcmVxdWVzdGVkIEJpdEdvIHJvdW5kIG91dHB1dCB3aGVuIG11bHRpcGxlIHJvdW5kIG91dHB1dHMgYXJlIHByZXNlbnQnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2lnbmF0dXJlU2hhcmVzID0gW3JvdW5kMU91dHB1dFNoYXJlLCByb3VuZDJPdXRwdXRTaGFyZV07XG5cbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHNpZ25hdHVyZVNoYXJlcywgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDJPdXRwdXQnKSxcbiAgICAgIHJvdW5kMk91dHB1dFNoYXJlXG4gICAgKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICBnZXRCaXRnb1NpZ25hdHVyZVNoYXJlKHNpZ25hdHVyZVNoYXJlcywgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDFPdXRwdXQnKSxcbiAgICAgIHJvdW5kMU91dHB1dFNoYXJlXG4gICAgKTtcbiAgfSk7XG5cbiAgaXQoJ3NraXBzIG1hbGZvcm1lZCBzaGFyZSByZWNvcmRzIHdoaWxlIHNlbGVjdGluZyB0aGUgcmVxdWVzdGVkIEJpdEdvIHJvdW5kIG91dHB1dCcsICgpID0+IHtcbiAgICBjb25zdCBtYWxmb3JtZWRTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQgPSB7XG4gICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICBzaGFyZTogJ25vdC1qc29uJyxcbiAgICB9O1xuXG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgZ2V0Qml0Z29TaWduYXR1cmVTaGFyZShbbWFsZm9ybWVkU2hhcmUsIHJvdW5kMk91dHB1dFNoYXJlXSwgU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsICdyb3VuZDJPdXRwdXQnKSxcbiAgICAgIHJvdW5kMk91dHB1dFNoYXJlXG4gICAgKTtcbiAgfSk7XG59KTtcblxudHlwZSBUeFJlcXVlc3RUcmFuc2FjdGlvbiA9IE5vbk51bGxhYmxlPFR4UmVxdWVzdFsndHJhbnNhY3Rpb25zJ10+W251bWJlcl07XG5cbmZ1bmN0aW9uIGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKHR4UmVxdWVzdDogVHhSZXF1ZXN0KTogVHhSZXF1ZXN0VHJhbnNhY3Rpb24ge1xuICBhc3NlcnQub2sodHhSZXF1ZXN0LnRyYW5zYWN0aW9ucywgJ3R4UmVxdWVzdCBtdXN0IGluY2x1ZGUgdHJhbnNhY3Rpb25zJyk7XG4gIGFzc2VydC5zdHJpY3RFcXVhbCh0eFJlcXVlc3QudHJhbnNhY3Rpb25zLmxlbmd0aCwgMSwgJ3R4UmVxdWVzdCBtdXN0IGhhdmUgZXhhY3RseSBvbmUgdHJhbnNhY3Rpb24nKTtcbiAgcmV0dXJuIHR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF07XG59XG5cbmZ1bmN0aW9uIGNsb25lVHhSZXF1ZXN0V2l0aEVtcHR5U2lnbmF0dXJlU2hhcmVzKHR4UmVxdWVzdDogVHhSZXF1ZXN0KTogVHhSZXF1ZXN0IHtcbiAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICByZXR1cm4ge1xuICAgIC4uLnR4UmVxdWVzdCxcbiAgICB0cmFuc2FjdGlvbnM6IFt7IC4uLnRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IFtdIH1dLFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBzaWduQml0Z29FZGRzYVJvdW5kMShcbiAgYml0Z29Ec2c6IEVkZHNhTVBTRHNnLkRTRyxcbiAgdHhSZXF1ZXN0OiBUeFJlcXVlc3QsXG4gIHVzZXJSb3VuZDFTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIHVzZXJHcGdQdWJLZXlBcm1vcmVkOiBzdHJpbmcsXG4gIGJpdGdvR3BnUHJpdktleTogcGdwLlByaXZhdGVLZXlcbik6IFByb21pc2U8VHhSZXF1ZXN0PiB7XG4gIGNvbnN0IHRyYW5zYWN0aW9uID0gYXNzZXJ0U2luZ2xlVHJhbnNhY3Rpb24odHhSZXF1ZXN0KTtcbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2godXNlclJvdW5kMVNoYXJlKTtcblxuICBjb25zdCBiaXRnb01zZzEgPSBiaXRnb0RzZy5nZXRGaXJzdE1lc3NhZ2UoKTtcblxuICBjb25zdCBwYXJzZWRVc2VyU2hhcmUgPSBkZWNvZGVXaXRoQ29kZWMoXG4gICAgRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gICAgSlNPTi5wYXJzZSh1c2VyUm91bmQxU2hhcmUuc2hhcmUpLFxuICAgICdFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFJbnB1dCdcbiAgKTtcbiAgY29uc3QgdXNlckdwZ0tleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogdXNlckdwZ1B1YktleUFybW9yZWQgfSk7XG4gIGNvbnN0IHVzZXJSYXdNc2cxQnl0ZXMgPSBhd2FpdCBNUFNDb21tcy52ZXJpZnlNcHNNZXNzYWdlKHBhcnNlZFVzZXJTaGFyZS5kYXRhLm1zZzEsIHVzZXJHcGdLZXkpO1xuICBjb25zdCB1c2VyTXNnMSA9IHtcbiAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkodXNlclJhd01zZzFCeXRlcyksXG4gIH07XG5cbiAgY29uc3QgW2JpdGdvTXNnMl0gPSBiaXRnb0RzZy5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKFtiaXRnb01zZzEsIHVzZXJNc2cxXSk7XG4gIGFzc2VydC5vayhiaXRnb01zZzIsICdCaXRHbyBEU0cgcHJvZHVjZWQgbm8gcm91bmQtMiBvdXRwdXQnKTtcbiAgKGJpdGdvRHNnIGFzIEVkZHNhTVBTRHNnLkRTRyAmIHsgcm91bmQyTWVzc2FnZT86IE1QU1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2UgfSkucm91bmQyTWVzc2FnZSA9IGJpdGdvTXNnMjtcblxuICBjb25zdCBiaXRnb1NpZ25lZE1zZzEgPSBhd2FpdCBNUFNDb21tcy5kZXRhY2hTaWduTXBzTWVzc2FnZShCdWZmZXIuZnJvbShiaXRnb01zZzEucGF5bG9hZCksIGJpdGdvR3BnUHJpdktleSk7XG4gIGNvbnN0IHJvdW5kMU91dHB1dDogRWRkc2FNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgIGRhdGE6IHsgbXNnMTogYml0Z29TaWduZWRNc2cxIH0sXG4gIH07XG5cbiAgdHJhbnNhY3Rpb24uc2lnbmF0dXJlU2hhcmVzLnB1c2goe1xuICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHJvdW5kMU91dHB1dCksXG4gIH0pO1xuXG4gIHJldHVybiB0eFJlcXVlc3Q7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNpZ25CaXRnb0VkZHNhUm91bmQyKFxuICBiaXRnb0RzZzogRWRkc2FNUFNEc2cuRFNHLFxuICB0eFJlcXVlc3Q6IFR4UmVxdWVzdCxcbiAgdXNlclJvdW5kMlNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgdXNlckdwZ1B1YktleUFybW9yZWQ6IHN0cmluZyxcbiAgYml0Z29HcGdQcml2S2V5OiBwZ3AuUHJpdmF0ZUtleVxuKTogUHJvbWlzZTxUeFJlcXVlc3Q+IHtcbiAgY29uc3QgdHJhbnNhY3Rpb24gPSBhc3NlcnRTaW5nbGVUcmFuc2FjdGlvbih0eFJlcXVlc3QpO1xuICB0cmFuc2FjdGlvbi5zaWduYXR1cmVTaGFyZXMucHVzaCh1c2VyUm91bmQyU2hhcmUpO1xuXG4gIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBwZ3AucmVhZEtleSh7IGFybW9yZWRLZXk6IHVzZXJHcGdQdWJLZXlBcm1vcmVkIH0pO1xuICBjb25zdCBiaXRnb01zZzIgPSAoYml0Z29Ec2cgYXMgRWRkc2FNUFNEc2cuRFNHICYgeyByb3VuZDJNZXNzYWdlPzogTVBTVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZSB9KS5yb3VuZDJNZXNzYWdlO1xuICBhc3NlcnQub2soYml0Z29Nc2cyLCAnQml0R28gRFNHIGlzIG1pc3NpbmcgdGhlIGNhY2hlZCByb3VuZC0yIG91dHB1dCcpO1xuXG4gIGNvbnN0IHBhcnNlZFVzZXJSb3VuZDJTaGFyZSA9IGRlY29kZVdpdGhDb2RlYyhcbiAgICBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgICBKU09OLnBhcnNlKHVzZXJSb3VuZDJTaGFyZS5zaGFyZSksXG4gICAgJ0VkZHNhTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0J1xuICApO1xuICBjb25zdCB1c2VyUmF3TXNnMkJ5dGVzID0gYXdhaXQgTVBTQ29tbXMudmVyaWZ5TXBzTWVzc2FnZShwYXJzZWRVc2VyUm91bmQyU2hhcmUuZGF0YS5tc2cyLCB1c2VyR3BnS2V5KTtcbiAgY29uc3QgdXNlck1zZzIgPSB7XG4gICAgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KHVzZXJSYXdNc2cyQnl0ZXMpLFxuICB9O1xuXG4gIGNvbnN0IGJpdGdvU2lnbmVkTXNnMiA9IGF3YWl0IE1QU0NvbW1zLmRldGFjaFNpZ25NcHNNZXNzYWdlKEJ1ZmZlci5mcm9tKGJpdGdvTXNnMi5wYXlsb2FkKSwgYml0Z29HcGdQcml2S2V5KTtcbiAgY29uc3Qgcm91bmQyT3V0cHV0OiBFZGRzYU1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQgPSB7XG4gICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgZGF0YTogeyBtc2cyOiBiaXRnb1NpZ25lZE1zZzIgfSxcbiAgfTtcblxuICB0cmFuc2FjdGlvbi5zaWduYXR1cmVTaGFyZXMucHVzaCh7XG4gICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHRvOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkocm91bmQyT3V0cHV0KSxcbiAgfSk7XG5cbiAgYml0Z29Ec2cuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhbYml0Z29Nc2cyLCB1c2VyTXNnMl0pO1xuXG4gIHJldHVybiB0eFJlcXVlc3Q7XG59XG5cbmRlc2NyaWJlKCdFZGRzYU1QQ3YyVXRpbHMuc2lnbkVkZHNhTVBDdjJUc3NVc2luZ0V4dGVybmFsU2lnbmVyJywgKCkgPT4ge1xuICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuICBsZXQgZWRkc2FNUEN2MlV0aWxzOiBFZGRzYU1QQ3YyVXRpbHM7XG4gIGxldCBtb2NrQml0Z286IEJpdEdvQmFzZTtcbiAgbGV0IGJpdGdvR3BnS2V5UGFpcjogcGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz47XG4gIGxldCBiaXRnb0dwZ1B1YktleTogcGdwLktleTtcblxuICBjb25zdCB3YWxsZXRJZCA9ICdhYmMxMjN3YWxsZXQnO1xuICBjb25zdCB0eFJlcXVlc3RJZCA9ICd0eHJlcS0wMDEnO1xuICBjb25zdCBlbnRlcnByaXNlSWQgPSAnZW50LTAwMSc7XG5cbiAgY29uc3QgbW9ja1R4UmVxdWVzdDogVHhSZXF1ZXN0ID0ge1xuICAgIHR4UmVxdWVzdElkLFxuICAgIHdhbGxldElkLFxuICAgIGVudGVycHJpc2VJZCxcbiAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICB7XG4gICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICBzaWduYWJsZUhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgICBkZXJpdmF0aW9uUGF0aDogJ20vMCcsXG4gICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiAnZGVhZGJlZWYnLFxuICAgICAgICB9LFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQxT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3BheW1lbnQnIH0sXG4gICAgdW5zaWduZWRUeHM6IFtdLFxuICB9IGFzIHVua25vd24gYXMgVHhSZXF1ZXN0O1xuXG4gIGNvbnN0IG1vY2tUeFJlcXVlc3RUcmFuc2FjdGlvbiA9IGFzc2VydFNpbmdsZVRyYW5zYWN0aW9uKG1vY2tUeFJlcXVlc3QpO1xuICBjb25zdCBtb2NrVHhSZXF1ZXN0Um91bmQyOiBUeFJlcXVlc3QgPSB7XG4gICAgLi4ubW9ja1R4UmVxdWVzdCxcbiAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgIHtcbiAgICAgICAgLi4ubW9ja1R4UmVxdWVzdFRyYW5zYWN0aW9uLFxuICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICAgICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICAgICAgICBzaGFyZTogSlNPTi5zdHJpbmdpZnkoeyB0eXBlOiAncm91bmQyT3V0cHV0JywgZGF0YToge30gfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcblxuICBjb25zdCBkdW1teVNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuVVNFUixcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdyb3VuZDFJbnB1dCcsIGRhdGE6IHt9IH0pLFxuICB9O1xuXG4gIC8vIFJldHVybnMgYSBjaGFpbiBjb21wYXRpYmxlIHdpdGg6IGJpdGdvLnBvc3QodXJsKS5zZW5kKGJvZHkpLnJlc3VsdCgpXG4gIGNvbnN0IG1ha2VQb3N0Q2hhaW4gPSAocmVzcG9uc2U6IFR4UmVxdWVzdCk6IEJpdEdvUmVxdWVzdDxUeFJlcXVlc3Q+ID0+XG4gICAgKHsgc2VuZDogKCkgPT4gKHsgcmVzdWx0OiBzaW5vbi5zdHViKCkucmVzb2x2ZXMocmVzcG9uc2UpIH0pIH0gYXMgdW5rbm93biBhcyBCaXRHb1JlcXVlc3Q8VHhSZXF1ZXN0Pik7XG5cbiAgLy8gUmV0dXJucyBhIGNoYWluIGNvbXBhdGlibGUgd2l0aDogYml0Z28uZ2V0KHVybCkucXVlcnkocGFyYW1zKS5yZXRyeShuKS5yZXN1bHQoKVxuICBjb25zdCBtYWtlR2V0Q2hhaW4gPSAodHhSZXF1ZXN0czogVHhSZXF1ZXN0W10pOiBCaXRHb1JlcXVlc3Q8eyB0eFJlcXVlc3RzOiBUeFJlcXVlc3RbXSB9PiA9PlxuICAgICh7XG4gICAgICBxdWVyeTogKCkgPT4gKHtcbiAgICAgICAgcmV0cnk6ICgpID0+ICh7IHJlc3VsdDogc2lub24uc3R1YigpLnJlc29sdmVzKHsgdHhSZXF1ZXN0cyB9KSB9KSxcbiAgICAgIH0pLFxuICAgIH0gYXMgdW5rbm93biBhcyBCaXRHb1JlcXVlc3Q8eyB0eFJlcXVlc3RzOiBUeFJlcXVlc3RbXSB9Pik7XG5cbiAgYmVmb3JlKGFzeW5jICgpID0+IHtcbiAgICBiaXRnb0dwZ0tleVBhaXIgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ2VkMjU1MTknKTtcbiAgICBiaXRnb0dwZ1B1YktleSA9IGF3YWl0IHBncC5yZWFkS2V5KHsgYXJtb3JlZEtleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSB9KTtcbiAgfSk7XG5cbiAgYmVmb3JlRWFjaChhc3luYyAoKSA9PiB7XG4gICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIC8vIEZ1bGwgbW9jayBvZiB0aGUgQml0R28gSFRUUCBjbGllbnQgKGNvbnNpc3RlbnQgd2l0aCBvdGhlciBzZGstY29yZSB0ZXN0cyBzdWNoIGFzXG4gICAgLy8gdG9rZW5BcHByb3ZhbC50cyBhbmQgd2FsbGV0c0V2bUtleXJpbmcudHMpLiAgTW9kdWxlLWxldmVsIHN0dWJzIG9uIHRzc0NvbW1vbiBmdW5jdGlvbnNcbiAgICAvLyBkbyBub3Qgd29yayB1bmRlciB0c3ggNC54IChFU00gbGl2ZSBiaW5kaW5ncyksIHNvIHdlIG1vY2sgYXQgdGhlIGJpdGdvIG9iamVjdCBsZXZlbC5cbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBnZXRFbnY6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCd0ZXN0JyksXG4gICAgICBzZXRSZXF1ZXN0VHJhY2VyOiBzaW5vbi5zdHViKCksXG4gICAgICB1cmw6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhdGg6IHN0cmluZykgPT4gYGh0dHBzOi8vdGVzdC5iaXRnby5jb20ke3BhdGh9YCksXG4gICAgICBwb3N0OiBzaW5vbi5zdHViKCksXG4gICAgICBnZXQ6IHNpbm9uLnN0dWIoKSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7XG4gICAgICBnZXRNUENBbGdvcml0aG06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdlZGRzYScpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJQmFzZUNvaW47XG5cbiAgICBjb25zdCBtb2NrV2FsbGV0ID0ge1xuICAgICAgaWQ6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHdhbGxldElkKSxcbiAgICAgIGtleUlkczogc2lub24uc3R1YigpLnJldHVybnMoWyd1c2VyS2V5SWQnLCAnYmFja3VwS2V5SWQnLCAnYml0Z29LZXlJZCddKSxcbiAgICAgIG11bHRpc2lnVHlwZVZlcnNpb246IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdNUEN2MicpLFxuICAgIH0gYXMgdW5rbm93biBhcyBJV2FsbGV0O1xuXG4gICAgZWRkc2FNUEN2MlV0aWxzID0gbmV3IEVkZHNhTVBDdjJVdGlscyhtb2NrQml0Z28sIG1vY2tDb2luLCBtb2NrV2FsbGV0KTtcblxuICAgIHNhbmRib3guc3R1YihlZGRzYU1QQ3YyVXRpbHMsICdwaWNrQml0Z29QdWJHcGdLZXlGb3JTaWduaW5nJykucmVzb2x2ZXMoYml0Z29HcGdQdWJLZXkpO1xuICB9KTtcblxuICBhZnRlckVhY2goKCkgPT4ge1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNhbGwgYWxsIDMgZ2VuZXJhdG9ycyBhbmQgcmV0dXJuIHRoZSBmaW5hbCB0eCByZXF1ZXN0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGZpbmFsVHhSZXF1ZXN0ID0geyAuLi5tb2NrVHhSZXF1ZXN0LCB0eFJlcXVlc3RJZCB9O1xuXG4gICAgLy8gc2VuZFNpZ25hdHVyZVNoYXJlVjIgaXMgY2FsbGVkIDMgdGltZXMgKG9uZSBwZXIgcm91bmQpLCBzZW5kVHhSZXF1ZXN0IG9uY2Ug4oCUIGFsbCB1c2UgYml0Z28ucG9zdFxuICAgIChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpXG4gICAgICAub25DYWxsKDApXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKSAvLyByb3VuZCAxIHNpZ25cbiAgICAgIC5vbkNhbGwoMSlcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpIC8vIHJvdW5kIDIgc2lnblxuICAgICAgLm9uQ2FsbCgyKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSkgLy8gcm91bmQgMyBzaWduXG4gICAgICAub25DYWxsKDMpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKGZpbmFsVHhSZXF1ZXN0KSk7IC8vIHNlbmRUeFJlcXVlc3QgKHNlbmQpXG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uID0gJ2VuY3J5cHRlZC1yMS1zZXNzaW9uJztcbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gJ2VuY3J5cHRlZC1yMi1zZXNzaW9uJztcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gJ2VuY3J5cHRlZC1ncGcta2V5JztcbiAgICBjb25zdCB1c2VyR3BnUHViS2V5ID0gYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleTtcblxuICAgIGNvbnN0IHJvdW5kMVNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSB9O1xuICAgIGNvbnN0IHJvdW5kMlNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSwgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kMklucHV0JyB9KSB9O1xuICAgIGNvbnN0IHJvdW5kM1NoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCA9IHsgLi4uZHVtbXlTaGFyZSwgc2hhcmU6IEpTT04uc3RyaW5naWZ5KHsgdHlwZTogJ3JvdW5kM0lucHV0JyB9KSB9O1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub25cbiAgICAgIC5zdHViKClcbiAgICAgIC5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQxOiByb3VuZDFTaGFyZSwgdXNlckdwZ1B1YktleSwgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbiwgZW5jcnlwdGVkVXNlckdwZ1BydktleSB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogcm91bmQyU2hhcmUsIGVuY3J5cHRlZFJvdW5kMlNlc3Npb24gfSk7XG4gICAgY29uc3Qgcm91bmQzR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHsgc2lnbmF0dXJlU2hhcmVSb3VuZDM6IHJvdW5kM1NoYXJlIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgIHsgdHhSZXF1ZXN0OiBtb2NrVHhSZXF1ZXN0LCByZXFJZDogbmV3IFJlcXVlc3RUcmFjZXIoKSB9LFxuICAgICAgcm91bmQxR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDFHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDJHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgIHJvdW5kM0dlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQzR2VuZXJhdGluZ0Z1bmN0aW9uXG4gICAgKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocmVzdWx0LCBmaW5hbFR4UmVxdWVzdCk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShyb3VuZDFHZW5lcmF0b3IpO1xuICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHJvdW5kMUdlbmVyYXRvciwgeyB0eFJlcXVlc3Q6IG1vY2tUeFJlcXVlc3QgfSk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShyb3VuZDJHZW5lcmF0b3IpO1xuICAgIGNvbnN0IHJvdW5kMkNhbGwgPSByb3VuZDJHZW5lcmF0b3IuZ2V0Q2FsbCgwKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyQ2FsbC5hcmdzWzBdLnR4UmVxdWVzdCwgbW9ja1R4UmVxdWVzdCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kMkNhbGwuYXJnc1swXS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQyQ2FsbC5hcmdzWzBdLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXksIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDJDYWxsLmFyZ3NbMF0uYml0Z29QdWJsaWNHcGdLZXksIGJpdGdvR3BnUHViS2V5LmFybW9yKCkpO1xuXG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uocm91bmQzR2VuZXJhdG9yKTtcbiAgICBjb25zdCByb3VuZDNDYWxsID0gcm91bmQzR2VuZXJhdG9yLmdldENhbGwoMCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kM0NhbGwuYXJnc1swXS50eFJlcXVlc3QsIG1vY2tUeFJlcXVlc3RSb3VuZDIpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyb3VuZDNDYWxsLmFyZ3NbMF0uZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbik7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJvdW5kM0NhbGwuYXJnc1swXS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwocm91bmQzQ2FsbC5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LCBiaXRnb0dwZ1B1YktleS5hcm1vcigpKTtcblxuICAgIC8vIDMgc2VuZFNpZ25hdHVyZVNoYXJlVjIgY2FsbHMgKyAxIHNlbmRUeFJlcXVlc3QgPSA0IFBPU1QgY2FsbHMgdG90YWxcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoKG1vY2tCaXRnby5wb3N0IGFzIHNpbm9uLlNpbm9uU3R1YikuY2FsbENvdW50LCA0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXNvbHZlIHR4UmVxdWVzdCBieSBJRCBzdHJpbmcgdXNpbmcgZ2V0VHhSZXF1ZXN0JywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIGdldFR4UmVxdWVzdCB1c2VzIGJpdGdvLmdldDsgc2VuZFNpZ25hdHVyZVNoYXJlVjIgKMOXMykgKyBzZW5kVHhSZXF1ZXN0IHVzZSBiaXRnby5wb3N0XG4gICAgKG1vY2tCaXRnby5nZXQgYXMgc2lub24uU2lub25TdHViKS5yZXR1cm5zKG1ha2VHZXRDaGFpbihbbW9ja1R4UmVxdWVzdF0pKTtcbiAgICAobW9ja0JpdGdvLnBvc3QgYXMgc2lub24uU2lub25TdHViKVxuICAgICAgLm9uQ2FsbCgwKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSlcbiAgICAgIC5vbkNhbGwoMSlcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdFJvdW5kMikpXG4gICAgICAub25DYWxsKDIpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKVxuICAgICAgLm9uQ2FsbCgzKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0KSk7XG5cbiAgICBjb25zdCByb3VuZDFHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoe1xuICAgICAgc2lnbmF0dXJlU2hhcmVSb3VuZDE6IGR1bW15U2hhcmUsXG4gICAgICB1c2VyR3BnUHViS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogJ3IxJyxcbiAgICAgIGVuY3J5cHRlZFVzZXJHcGdQcnZLZXk6ICdrZXknLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMkdlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQyOiBkdW1teVNoYXJlLCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uOiAncjInIH0pO1xuICAgIGNvbnN0IHJvdW5kM0dlbmVyYXRvciA9IHNpbm9uLnN0dWIoKS5yZXNvbHZlcyh7IHNpZ25hdHVyZVNoYXJlUm91bmQzOiBkdW1teVNoYXJlIH0pO1xuXG4gICAgYXdhaXQgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgIHsgdHhSZXF1ZXN0OiB0eFJlcXVlc3RJZCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgIHJvdW5kMUdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICk7XG5cbiAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShtb2NrQml0Z28uZ2V0IGFzIHNpbm9uLlNpbm9uU3R1Yik7XG4gICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgocm91bmQxR2VuZXJhdG9yLCB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHJvdW5kIDIgdHhSZXF1ZXN0IGlzIG1pc3Npbmcgc2lnbmF0dXJlU2hhcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJvdW5kMk5vU2hhcmVzOiBUeFJlcXVlc3QgPSB7XG4gICAgICAuLi5tb2NrVHhSZXF1ZXN0LFxuICAgICAgdHJhbnNhY3Rpb25zOiBbeyAuLi5tb2NrVHhSZXF1ZXN0VHJhbnNhY3Rpb24sIHNpZ25hdHVyZVNoYXJlczogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgW10gfV0sXG4gICAgfTtcblxuICAgIChtb2NrQml0Z28ucG9zdCBhcyBzaW5vbi5TaW5vblN0dWIpXG4gICAgICAub25DYWxsKDApXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3QpKVxuICAgICAgLm9uQ2FsbCgxKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihyb3VuZDJOb1NoYXJlcykpO1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBkdW1teVNoYXJlLFxuICAgICAgdXNlckdwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246ICdyMScsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiAna2V5JyxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogZHVtbXlTaGFyZSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogJ3IyJyB9KTtcbiAgICBjb25zdCByb3VuZDNHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMzogZHVtbXlTaGFyZSB9KTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgKCkgPT5cbiAgICAgICAgZWRkc2FNUEN2MlV0aWxzLnNpZ25FZGRzYU1QQ3YyVHNzVXNpbmdFeHRlcm5hbFNpZ25lcihcbiAgICAgICAgICB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgICAgICByb3VuZDFHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMUdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgICAgICByb3VuZDJHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kMkdlbmVyYXRpbmdGdW5jdGlvbixcbiAgICAgICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICAgICApLFxuICAgICAgL01pc3Npbmcgc2lnbmF0dXJlIHNoYXJlcyBpbiByb3VuZCAyIHR4UmVxdWVzdC9cbiAgICApO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHBhc3MgYXJtb3JlZCBCaXRHbyBwdWJsaWMgR1BHIGtleSB0byByb3VuZCAyIGFuZCByb3VuZCAzIGdlbmVyYXRvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgKG1vY2tCaXRnby5wb3N0IGFzIHNpbm9uLlNpbm9uU3R1YilcbiAgICAgIC5vbkNhbGwoMClcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpXG4gICAgICAub25DYWxsKDEpXG4gICAgICAucmV0dXJucyhtYWtlUG9zdENoYWluKG1vY2tUeFJlcXVlc3RSb3VuZDIpKVxuICAgICAgLm9uQ2FsbCgyKVxuICAgICAgLnJldHVybnMobWFrZVBvc3RDaGFpbihtb2NrVHhSZXF1ZXN0Um91bmQyKSlcbiAgICAgIC5vbkNhbGwoMylcbiAgICAgIC5yZXR1cm5zKG1ha2VQb3N0Q2hhaW4obW9ja1R4UmVxdWVzdCkpO1xuXG4gICAgY29uc3Qgcm91bmQxR2VuZXJhdG9yID0gc2lub24uc3R1YigpLnJlc29sdmVzKHtcbiAgICAgIHNpZ25hdHVyZVNoYXJlUm91bmQxOiBkdW1teVNoYXJlLFxuICAgICAgdXNlckdwZ1B1YktleTogYml0Z29HcGdLZXlQYWlyLnB1YmxpY0tleSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246ICdyMScsXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiAna2V5JyxcbiAgICB9KTtcbiAgICBjb25zdCByb3VuZDJHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMjogZHVtbXlTaGFyZSwgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbjogJ3IyJyB9KTtcbiAgICBjb25zdCByb3VuZDNHZW5lcmF0b3IgPSBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBzaWduYXR1cmVTaGFyZVJvdW5kMzogZHVtbXlTaGFyZSB9KTtcblxuICAgIGF3YWl0IGVkZHNhTVBDdjJVdGlscy5zaWduRWRkc2FNUEN2MlRzc1VzaW5nRXh0ZXJuYWxTaWduZXIoXG4gICAgICB7IHR4UmVxdWVzdDogbW9ja1R4UmVxdWVzdCwgcmVxSWQ6IG5ldyBSZXF1ZXN0VHJhY2VyKCkgfSxcbiAgICAgIHJvdW5kMUdlbmVyYXRvciBhcyB1bmtub3duIGFzIEN1c3RvbUVkZHNhTVBDdjJTaWduaW5nUm91bmQxR2VuZXJhdGluZ0Z1bmN0aW9uLFxuICAgICAgcm91bmQyR2VuZXJhdG9yIGFzIHVua25vd24gYXMgQ3VzdG9tRWRkc2FNUEN2MlNpZ25pbmdSb3VuZDJHZW5lcmF0aW5nRnVuY3Rpb24sXG4gICAgICByb3VuZDNHZW5lcmF0b3IgYXMgdW5rbm93biBhcyBDdXN0b21FZGRzYU1QQ3YyU2lnbmluZ1JvdW5kM0dlbmVyYXRpbmdGdW5jdGlvblxuICAgICk7XG5cbiAgICBjb25zdCBhcm1vcmVkS2V5ID0gYml0Z29HcGdQdWJLZXkuYXJtb3IoKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICByb3VuZDJHZW5lcmF0b3IuZ2V0Q2FsbCgwKS5hcmdzWzBdLmJpdGdvUHVibGljR3BnS2V5LFxuICAgICAgYXJtb3JlZEtleSxcbiAgICAgICdyb3VuZCAyIHNob3VsZCByZWNlaXZlIGFybW9yZWQgQml0R28gR1BHIGtleSdcbiAgICApO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIHJvdW5kM0dlbmVyYXRvci5nZXRDYWxsKDApLmFyZ3NbMF0uYml0Z29QdWJsaWNHcGdLZXksXG4gICAgICBhcm1vcmVkS2V5LFxuICAgICAgJ3JvdW5kIDMgc2hvdWxkIHJlY2VpdmUgYXJtb3JlZCBCaXRHbyBHUEcga2V5J1xuICAgICk7XG4gIH0pO1xufSk7XG5cbmZ1bmN0aW9uIGJ5dGVzVG9Xb3JkKGJ5dGVzPzogVWludDhBcnJheSB8IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKCEoYnl0ZXMgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB8fCBieXRlcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2J5dGVzIG11c3QgYmUgYSBVaW50OEFycmF5IHdpdGggbGVuZ3RoIDQnKTtcbiAgfVxuXG4gIHJldHVybiBieXRlcy5yZWR1Y2UoKG51bSwgYnl0ZSkgPT4gbnVtICogMHgxMDAgKyBieXRlLCAwKTtcbn1cblxuZGVzY3JpYmUoJ0VERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsJywgKCkgPT4ge1xuICBjb25zdCBQQVNTUEhSQVNFID0gJ3Rlc3QtcGFzc3BocmFzZSc7XG5cbiAgY29uc3QgTVBDdjFfTUFURVJJQUxfQkFDS1VQID0ge1xuICAgIHVTaGFyZTogeyBpOiAxLCB0OiAyLCBuOiAzLCB5OiAnYWFiYmNjJywgc2VlZDogJ2RlYWRiZWVmMDEyMzQ1NjcnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICBiaXRnb1lTaGFyZTogeyBpOiAzLCBqOiAxLCB5OiAnYWFiYmNjJywgdTogJ2JpdGdvLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgICBiYWNrdXBZU2hhcmU6IHsgaTogMiwgajogMSwgeTogJ2FhYmJjYycsIHU6ICdiYWNrdXAtdS12YWx1ZScsIGNoYWluY29kZTogJzAwJyB9LFxuICB9O1xuXG4gIGNvbnN0IE1QQ3YxX01BVEVSSUFMX1VTRVIgPSB7XG4gICAgdVNoYXJlOiB7IGk6IDIsIHQ6IDIsIG46IDMsIHk6ICdhYWJiY2MnLCBzZWVkOiAnZGVhZGJlZWYwMTIzNDU2NycsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIGJpdGdvWVNoYXJlOiB7IGk6IDMsIGo6IDIsIHk6ICdhYWJiY2MnLCB1OiAnYml0Z28tdS12YWx1ZScsIGNoYWluY29kZTogJzAwJyB9LFxuICAgIHVzZXJZU2hhcmU6IHsgaTogMSwgajogMiwgeTogJ2FhYmJjYycsIHU6ICd1c2VyLXUtdmFsdWUnLCBjaGFpbmNvZGU6ICcwMCcgfSxcbiAgfTtcblxuICBjb25zdCBNUEN2Ml9DQk9SX0JZVEVTID0gQnVmZmVyLmZyb20oWzB4ZDksIDB4MDEsIDB4MDQsIDB4YTMsIDB4NjEsIDB4NzgsIDB4MTgsIDB4MDBdKS50b1N0cmluZygnYmFzZTY0Jyk7XG5cbiAgbGV0IG1vY2tCaXRnbzogQml0R29CYXNlO1xuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAvLyBzZGstY29yZSBoYXMgbm8gZGV2RGVwZW5kZW5jeSBvbiBzZGstYXBpL2FyZ29uMiwgc28gdjIgZW52ZWxvcGVzIGFyZSBzaW11bGF0ZWQgaGVyZS5cbiAgICAvLyBSZWFsIGJpdGdvLmRlY3J5cHRBc3luYyByb3V0ZXMgdjIgdG8gQXJnb24yaWQ7IHRoZSBzdHViIHJldHVybnMgTVBDdjIgQ0JPUiBwbGFpbnRleHQgaW5zdGVhZC5cbiAgICBtb2NrQml0Z28gPSB7XG4gICAgICBkZWNyeXB0QXN5bmM6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtczogeyBpbnB1dDogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH0pID0+IHtcbiAgICAgICAgaWYgKGlzVjJFbnZlbG9wZShwYXJhbXMuaW5wdXQpKSB7XG4gICAgICAgICAgcmV0dXJuIE1QQ3YyX0NCT1JfQllURVM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXJhbXMucGFzc3dvcmQsIHBhcmFtcy5pbnB1dCk7XG4gICAgICB9KSxcbiAgICB9IGFzIHVua25vd24gYXMgQml0R29CYXNlO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0cnVlIGZvciBNUEN2MSBTSkNMLWVuY3J5cHRlZCBrZXljYXJkIHdpdGggYmFja3VwWVNoYXJlICsgY29ycmVjdCBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9CQUNLVVApKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZW5jcnlwdGVkLCBQQVNTUEhSQVNFKSwgdHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHRydWUgZm9yIE1QQ3YxIFNKQ0wtZW5jcnlwdGVkIGtleWNhcmQgd2l0aCB1c2VyWVNoYXJlICsgY29ycmVjdCBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9VU0VSKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGF3YWl0IEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSksIHRydWUpO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBmYWxzZSBmb3IgTVBDdjIgQ0JPUiBjb250ZW50IHdyYXBwZWQgaW4gU0pDTCBlbnZlbG9wZSArIGNvcnJlY3QgcGFzc3BocmFzZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgTVBDdjJfQ0JPUl9CWVRFUyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGF3YWl0IEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgUEFTU1BIUkFTRSksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgZmFsc2UgZm9yIE1QQ3YyIEFyZ29uMmlkIGVudmVsb3BlICh2MikgKyBjb3JyZWN0IHBhc3NwaHJhc2UgKGZvcndhcmQtY29tcGF0KScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBmYWtlVjJFbnZlbG9wZSA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgbTogNjU1MzYsIHQ6IDMsIHA6IDQsIHNhbHQ6ICdBQUFBJywgaXY6ICdBQUFBJywgY3Q6ICdBQUFBJyB9KTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYXdhaXQgRUREU0FVdGlscy5pc0VkZHNhTXBjVjFTaWduaW5nTWF0ZXJpYWwoZmFrZVYyRW52ZWxvcGUsIFBBU1NQSFJBU0UsIG1vY2tCaXRnbyksIGZhbHNlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBvbiB3cm9uZyBwYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGVuY3J5cHRlZCA9IHNqY2wuZW5jcnlwdChQQVNTUEhSQVNFLCBKU09OLnN0cmluZ2lmeShNUEN2MV9NQVRFUklBTF9CQUNLVVApKTtcbiAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgIEVERFNBVXRpbHMuaXNFZGRzYU1wY1YxU2lnbmluZ01hdGVyaWFsKGVuY3J5cHRlZCwgJ3dyb25nLXBhc3NwaHJhc2UnKSxcbiAgICAgIC9jY206IHRhZyBkb2Vzbid0IG1hdGNoL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIGZhbHNlIHdoZW4gbmVpdGhlciBiYWNrdXBZU2hhcmUudSBub3IgdXNlcllTaGFyZS51IGlzIHByZXNlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGFydGlhbCA9IHsgdVNoYXJlOiB7IHNlZWQ6ICdhYmMnIH0sIGJpdGdvWVNoYXJlOiB7IHU6ICd4eXonIH0gfTtcbiAgICBjb25zdCBlbmNyeXB0ZWQgPSBzamNsLmVuY3J5cHQoUEFTU1BIUkFTRSwgSlNPTi5zdHJpbmdpZnkocGFydGlhbCkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChhd2FpdCBFRERTQVV0aWxzLmlzRWRkc2FNcGNWMVNpZ25pbmdNYXRlcmlhbChlbmNyeXB0ZWQsIFBBU1NQSFJBU0UpLCBmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdzaWduUmVjb3ZlcnlFZGRzYU1QQ3YyJywgKCkgPT4ge1xuICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzAvMCc7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gYSA2NC1ieXRlIHNpZ25hdHVyZSB0aGF0IHZlcmlmaWVzIGFnYWluc3QgdGhlIGRlcml2ZWQgcHVibGljIGtleScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBbdXNlckRrZywgYmFja3VwRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnZGVhZGJlZWYnLCAnaGV4Jyk7XG4gICAgY29uc3QgY29tbW9uS2V5Q2hhaW4gPSB1c2VyRGtnLmdldENvbW1vbktleWNoYWluKCk7XG5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBFRERTQVV0aWxzLnNpZ25SZWNvdmVyeUVkZHNhTVBDdjIoXG4gICAgICBtZXNzYWdlLFxuICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICB1c2VyRGtnLmdldEtleVNoYXJlKCksXG4gICAgICBiYWNrdXBEa2cuZ2V0S2V5U2hhcmUoKSxcbiAgICAgIGNvbW1vbktleUNoYWluXG4gICAgKTtcblxuICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmUubGVuZ3RoLCA2NCk7XG5cbiAgICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBkZXJpdmVVbmhhcmRlbmVkTXBzKGNvbW1vbktleUNoYWluLCBkZXJpdmF0aW9uUGF0aCk7XG4gICAgY29uc3QgcHVibGljS2V5Qnl0ZXMgPSBCdWZmZXIuZnJvbShkZXJpdmVkS2V5Y2hhaW4uc2xpY2UoMCwgNjQpLCAnaGV4Jyk7XG4gICAgY29uc3Qgb2sgPSBlZDI1NTE5LnZlcmlmeShuZXcgVWludDhBcnJheShzaWduYXR1cmUpLCBuZXcgVWludDhBcnJheShtZXNzYWdlKSwgbmV3IFVpbnQ4QXJyYXkocHVibGljS2V5Qnl0ZXMpKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwob2ssIHRydWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdGhlIHNpZ25lZCBtZXNzYWdlIGlzIGRpZmZlcmVudCBmcm9tIHRoZSB2ZXJpZmllZCBtZXNzYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdkZWFkYmVlZicsICdoZXgnKTtcbiAgICBjb25zdCBjb21tb25LZXlDaGFpbiA9IHVzZXJEa2cuZ2V0Q29tbW9uS2V5Y2hhaW4oKTtcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IEVERFNBVXRpbHMuc2lnblJlY292ZXJ5RWRkc2FNUEN2MihcbiAgICAgIG1lc3NhZ2UsXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIHVzZXJEa2cuZ2V0S2V5U2hhcmUoKSxcbiAgICAgIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgY29tbW9uS2V5Q2hhaW5cbiAgICApO1xuXG4gICAgY29uc3QgZGlmZmVyZW50TWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdjYWZlYmFiZScsICdoZXgnKTtcbiAgICBjb25zdCBkZXJpdmVkS2V5Y2hhaW4gPSBkZXJpdmVVbmhhcmRlbmVkTXBzKGNvbW1vbktleUNoYWluLCBkZXJpdmF0aW9uUGF0aCk7XG4gICAgY29uc3QgcHVibGljS2V5Qnl0ZXMgPSBCdWZmZXIuZnJvbShkZXJpdmVkS2V5Y2hhaW4uc2xpY2UoMCwgNjQpLCAnaGV4Jyk7XG4gICAgY29uc3Qgb2sgPSBlZDI1NTE5LnZlcmlmeShcbiAgICAgIG5ldyBVaW50OEFycmF5KHNpZ25hdHVyZSksXG4gICAgICBuZXcgVWludDhBcnJheShkaWZmZXJlbnRNZXNzYWdlKSxcbiAgICAgIG5ldyBVaW50OEFycmF5KHB1YmxpY0tleUJ5dGVzKVxuICAgICk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKG9rLCBmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBhIHdyb25nIGNvbW1vbktleUNoYWluIGlzIHByb3ZpZGVkICh2ZXJpZmljYXRpb24gbWlzbWF0Y2gpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2ddID0gYXdhaXQgTVBTVXRpbC5nZW5lcmF0ZUVkRHNhREtHS2V5U2hhcmVzKCk7XG4gICAgY29uc3QgW3dyb25nRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnZGVhZGJlZWYnLCAnaGV4Jyk7XG5cbiAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgKCkgPT5cbiAgICAgICAgRUREU0FVdGlscy5zaWduUmVjb3ZlcnlFZGRzYU1QQ3YyKFxuICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgdXNlckRrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgICAgIGJhY2t1cERrZy5nZXRLZXlTaGFyZSgpLFxuICAgICAgICAgIHdyb25nRGtnLmdldENvbW1vbktleWNoYWluKCkgLy8ga2V5IGNoYWluIGZyb20gYSBkaWZmZXJlbnQgd2FsbGV0XG4gICAgICAgICksXG4gICAgICAvRWREU0EgTVBDdjIgcmVjb3Zlcnkgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbiBmYWlsZWQvXG4gICAgKTtcbiAgfSk7XG59KTtcbiJdfQ==