@bitgo-beta/sdk-core 8.2.1-beta.13 → 8.2.1-beta.1300

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 (595) 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 +34 -2
  10. package/dist/src/account-lib/baseCoin/enum.d.ts.map +1 -1
  11. package/dist/src/account-lib/baseCoin/enum.js +62 -5
  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/curves/ed25519.d.ts +4 -18
  50. package/dist/src/account-lib/mpc/curves/ed25519.d.ts.map +1 -1
  51. package/dist/src/account-lib/mpc/curves/ed25519.js +6 -60
  52. package/dist/src/account-lib/mpc/index.d.ts +4 -4
  53. package/dist/src/account-lib/mpc/index.d.ts.map +1 -1
  54. package/dist/src/account-lib/mpc/index.js +11 -7
  55. package/dist/src/account-lib/mpc/shamir.d.ts +5 -37
  56. package/dist/src/account-lib/mpc/shamir.d.ts.map +1 -1
  57. package/dist/src/account-lib/mpc/shamir.js +6 -130
  58. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +68 -13
  59. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -1
  60. package/dist/src/account-lib/mpc/tss/ecdsa/ecdsa.js +794 -225
  61. package/dist/src/account-lib/mpc/tss/ecdsa/index.js +23 -9
  62. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts +2 -2
  63. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.d.ts.map +1 -1
  64. package/dist/src/account-lib/mpc/tss/ecdsa/rangeproof.js +3 -3
  65. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts +114 -78
  66. package/dist/src/account-lib/mpc/tss/ecdsa/types.d.ts.map +1 -1
  67. package/dist/src/account-lib/mpc/tss/ecdsa/types.js +1 -1
  68. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts +1 -2
  69. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.d.ts.map +1 -1
  70. package/dist/src/account-lib/mpc/tss/eddsa/eddsa.js +66 -69
  71. package/dist/src/account-lib/mpc/tss/eddsa/index.js +23 -9
  72. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts +1 -4
  73. package/dist/src/account-lib/mpc/tss/eddsa/types.d.ts.map +1 -1
  74. package/dist/src/account-lib/mpc/tss/eddsa/types.js +1 -1
  75. package/dist/src/account-lib/mpc/tss/index.js +23 -9
  76. package/dist/src/account-lib/mpc/util.d.ts +7 -1
  77. package/dist/src/account-lib/mpc/util.d.ts.map +1 -1
  78. package/dist/src/account-lib/mpc/util.js +19 -1
  79. package/dist/src/account-lib/staking/index.js +6 -2
  80. package/dist/src/account-lib/staking/utils.js +3 -3
  81. package/dist/src/account-lib/util/crypto.d.ts +8 -2
  82. package/dist/src/account-lib/util/crypto.d.ts.map +1 -1
  83. package/dist/src/account-lib/util/crypto.js +69 -38
  84. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts +2 -1
  85. package/dist/src/account-lib/util/ed25519KeyDeriver.d.ts.map +1 -1
  86. package/dist/src/account-lib/util/ed25519KeyDeriver.js +5 -3
  87. package/dist/src/api/bip32path.js +2 -3
  88. package/dist/src/api/index.js +6 -2
  89. package/dist/src/api/types.d.ts +8 -0
  90. package/dist/src/api/types.d.ts.map +1 -1
  91. package/dist/src/api/types.js +1 -1
  92. package/dist/src/bitgo/address-book/address-book.d.ts +61 -0
  93. package/dist/src/bitgo/address-book/address-book.d.ts.map +1 -0
  94. package/dist/src/bitgo/address-book/address-book.js +139 -0
  95. package/dist/src/bitgo/address-book/index.d.ts +3 -0
  96. package/dist/src/bitgo/address-book/index.d.ts.map +1 -0
  97. package/dist/src/{openssl → bitgo/address-book}/index.js +8 -3
  98. package/dist/src/bitgo/address-book/types.d.ts +170 -0
  99. package/dist/src/bitgo/address-book/types.d.ts.map +1 -0
  100. package/dist/src/bitgo/address-book/types.js +3 -0
  101. package/dist/src/bitgo/baseCoin/baseCoin.d.ts +112 -11
  102. package/dist/src/bitgo/baseCoin/baseCoin.d.ts.map +1 -1
  103. package/dist/src/bitgo/baseCoin/baseCoin.js +163 -16
  104. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +168 -25
  105. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  106. package/dist/src/bitgo/baseCoin/iBaseCoin.js +7 -3
  107. package/dist/src/bitgo/baseCoin/index.js +6 -2
  108. package/dist/src/bitgo/bip32util.d.ts +3 -16
  109. package/dist/src/bitgo/bip32util.d.ts.map +1 -1
  110. package/dist/src/bitgo/bip32util.js +4 -56
  111. package/dist/src/bitgo/bitcoin.d.ts +0 -1
  112. package/dist/src/bitgo/bitcoin.d.ts.map +1 -1
  113. package/dist/src/bitgo/bitcoin.js +26 -13
  114. package/dist/src/bitgo/bitgoBase.d.ts +6 -2
  115. package/dist/src/bitgo/bitgoBase.d.ts.map +1 -1
  116. package/dist/src/bitgo/bitgoBase.js +1 -1
  117. package/dist/src/bitgo/coinFactory.d.ts +17 -3
  118. package/dist/src/bitgo/coinFactory.d.ts.map +1 -1
  119. package/dist/src/bitgo/coinFactory.js +26 -3
  120. package/dist/src/bitgo/config.d.ts +158 -20
  121. package/dist/src/bitgo/config.d.ts.map +1 -1
  122. package/dist/src/bitgo/config.js +26 -15
  123. package/dist/src/bitgo/ecdh.d.ts +0 -1
  124. package/dist/src/bitgo/ecdh.d.ts.map +1 -1
  125. package/dist/src/bitgo/ecdh.js +26 -13
  126. package/dist/src/bitgo/enterprise/enterprise.d.ts +16 -14
  127. package/dist/src/bitgo/enterprise/enterprise.d.ts.map +1 -1
  128. package/dist/src/bitgo/enterprise/enterprise.js +64 -31
  129. package/dist/src/bitgo/enterprise/enterprises.d.ts +6 -0
  130. package/dist/src/bitgo/enterprise/enterprises.d.ts.map +1 -1
  131. package/dist/src/bitgo/enterprise/enterprises.js +48 -9
  132. package/dist/src/bitgo/enterprise/iEnterprise.d.ts +6 -7
  133. package/dist/src/bitgo/enterprise/iEnterprise.d.ts.map +1 -1
  134. package/dist/src/bitgo/enterprise/iEnterprise.js +1 -1
  135. package/dist/src/bitgo/enterprise/iEnterprises.d.ts +2 -0
  136. package/dist/src/bitgo/enterprise/iEnterprises.d.ts.map +1 -1
  137. package/dist/src/bitgo/enterprise/iEnterprises.js +1 -1
  138. package/dist/src/bitgo/enterprise/index.js +6 -2
  139. package/dist/src/bitgo/environments.d.ts +76 -5
  140. package/dist/src/bitgo/environments.d.ts.map +1 -1
  141. package/dist/src/bitgo/environments.js +224 -29
  142. package/dist/src/bitgo/errors.d.ts +151 -0
  143. package/dist/src/bitgo/errors.d.ts.map +1 -1
  144. package/dist/src/bitgo/errors.js +127 -2
  145. package/dist/src/bitgo/evm/evmUtils.d.ts +26 -0
  146. package/dist/src/bitgo/evm/evmUtils.d.ts.map +1 -0
  147. package/dist/src/bitgo/evm/evmUtils.js +50 -0
  148. package/dist/src/bitgo/index.d.ts +3 -1
  149. package/dist/src/bitgo/index.d.ts.map +1 -1
  150. package/dist/src/bitgo/index.js +29 -11
  151. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts +3 -3
  152. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.d.ts.map +1 -1
  153. package/dist/src/bitgo/inscriptionBuilder/iInscriptionBuilder.js +1 -1
  154. package/dist/src/bitgo/inscriptionBuilder/index.js +6 -2
  155. package/dist/src/bitgo/internal/index.js +6 -2
  156. package/dist/src/bitgo/internal/internal.js +5 -6
  157. package/dist/src/bitgo/internal/keycard.js +6 -7
  158. package/dist/src/bitgo/keychain/decryptKeychain.d.ts +13 -0
  159. package/dist/src/bitgo/keychain/decryptKeychain.d.ts.map +1 -0
  160. package/dist/src/bitgo/keychain/decryptKeychain.js +35 -0
  161. package/dist/src/bitgo/keychain/iKeychains.d.ts +65 -7
  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 +15 -4
  168. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  169. package/dist/src/bitgo/keychain/keychains.js +158 -59
  170. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts +126 -91
  171. package/dist/src/bitgo/keychain/ovcJsonCodec.d.ts.map +1 -1
  172. package/dist/src/bitgo/keychain/ovcJsonCodec.js +53 -32
  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 +3 -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 +224 -98
  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 +15 -2
  202. package/dist/src/bitgo/recovery/initiate.d.ts.map +1 -1
  203. package/dist/src/bitgo/recovery/initiate.js +14 -8
  204. package/dist/src/bitgo/staking/goStakingInterfaces.d.ts +129 -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 +143 -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 +157 -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 +26 -7
  220. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  221. package/dist/src/bitgo/staking/stakingWallet.js +148 -7
  222. package/dist/src/bitgo/trading/iTradingAccount.d.ts +2 -32
  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 -15
  226. package/dist/src/bitgo/trading/index.d.ts.map +1 -1
  227. package/dist/src/bitgo/trading/index.js +7 -17
  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 +101 -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 +11 -35
  262. package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
  263. package/dist/src/bitgo/trading/tradingAccount.js +9 -96
  264. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts +27 -0
  265. package/dist/src/bitgo/tss/bitgoPubKeys.d.ts.map +1 -0
  266. package/dist/src/bitgo/tss/bitgoPubKeys.js +61 -0
  267. package/dist/src/bitgo/tss/common.d.ts +50 -7
  268. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  269. package/dist/src/bitgo/tss/common.js +124 -23
  270. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts +17 -12
  271. package/dist/src/bitgo/tss/ecdsa/ecdsa.d.ts.map +1 -1
  272. package/dist/src/bitgo/tss/ecdsa/ecdsa.js +111 -96
  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 +162 -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 +19 -9
  283. package/dist/src/bitgo/tss/eddsa/eddsa.d.ts.map +1 -1
  284. package/dist/src/bitgo/tss/eddsa/eddsa.js +56 -38
  285. package/dist/src/bitgo/tss/eddsa/index.js +23 -9
  286. package/dist/src/bitgo/tss/eddsa/types.d.ts +4 -4
  287. package/dist/src/bitgo/tss/eddsa/types.d.ts.map +1 -1
  288. package/dist/src/bitgo/tss/index.d.ts +3 -2
  289. package/dist/src/bitgo/tss/index.d.ts.map +1 -1
  290. package/dist/src/bitgo/tss/index.js +26 -10
  291. package/dist/src/bitgo/tss/types.d.ts +19 -0
  292. package/dist/src/bitgo/tss/types.d.ts.map +1 -1
  293. package/dist/src/bitgo/tss/types.js +2 -2
  294. package/dist/src/bitgo/types.d.ts +3 -3
  295. package/dist/src/bitgo/types.d.ts.map +1 -1
  296. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts +11 -0
  297. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -1
  298. package/dist/src/bitgo/utils/abstractUtxoCoinUtil.js +66 -10
  299. package/dist/src/bitgo/utils/codecProps.d.ts +7 -0
  300. package/dist/src/bitgo/utils/codecProps.d.ts.map +1 -0
  301. package/dist/src/bitgo/utils/codecProps.js +54 -0
  302. package/dist/src/bitgo/utils/decode.d.ts.map +1 -1
  303. package/dist/src/bitgo/utils/decode.js +30 -16
  304. package/dist/src/bitgo/utils/index.d.ts +3 -2
  305. package/dist/src/bitgo/utils/index.d.ts.map +1 -1
  306. package/dist/src/bitgo/utils/index.js +26 -11
  307. package/dist/src/bitgo/utils/messageTypes.d.ts +38 -0
  308. package/dist/src/bitgo/utils/messageTypes.d.ts.map +1 -0
  309. package/dist/src/bitgo/utils/messageTypes.js +15 -0
  310. package/dist/src/bitgo/utils/mpcUtils.d.ts +2 -3
  311. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  312. package/dist/src/bitgo/utils/mpcUtils.js +52 -13
  313. package/dist/src/bitgo/utils/notEmpty.d.ts +2 -0
  314. package/dist/src/bitgo/utils/notEmpty.d.ts.map +1 -0
  315. package/dist/src/bitgo/utils/notEmpty.js +7 -0
  316. package/dist/src/bitgo/utils/opengpgUtils.d.ts +11 -9
  317. package/dist/src/bitgo/utils/opengpgUtils.d.ts.map +1 -1
  318. package/dist/src/bitgo/utils/opengpgUtils.js +74 -73
  319. package/dist/src/bitgo/utils/postWithCodec.d.ts +18 -0
  320. package/dist/src/bitgo/utils/postWithCodec.d.ts.map +1 -0
  321. package/dist/src/bitgo/utils/postWithCodec.js +25 -0
  322. package/dist/src/bitgo/utils/promise-utils.d.ts +1 -1
  323. package/dist/src/bitgo/utils/promise-utils.d.ts.map +1 -1
  324. package/dist/src/bitgo/utils/promise-utils.js +2 -3
  325. package/dist/src/bitgo/utils/transactionUtils.d.ts +9 -0
  326. package/dist/src/bitgo/utils/transactionUtils.d.ts.map +1 -0
  327. package/dist/src/bitgo/utils/transactionUtils.js +29 -0
  328. package/dist/src/bitgo/utils/triple.d.ts +1 -1
  329. package/dist/src/bitgo/utils/triple.d.ts.map +1 -1
  330. package/dist/src/bitgo/utils/triple.js +2 -3
  331. package/dist/src/bitgo/utils/tss/addressVerification.d.ts +23 -0
  332. package/dist/src/bitgo/utils/tss/addressVerification.d.ts.map +1 -0
  333. package/dist/src/bitgo/utils/tss/addressVerification.js +51 -0
  334. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts +105 -25
  335. package/dist/src/bitgo/utils/tss/baseTSSUtils.d.ts.map +1 -1
  336. package/dist/src/bitgo/utils/tss/baseTSSUtils.js +242 -42
  337. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +371 -31
  338. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  339. package/dist/src/bitgo/utils/tss/baseTypes.js +36 -10
  340. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts +23 -0
  341. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.d.ts.map +1 -0
  342. package/dist/src/bitgo/utils/tss/ecdsa/SMC/utils.js +157 -0
  343. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts +28 -0
  344. package/dist/src/bitgo/utils/tss/ecdsa/base.d.ts.map +1 -0
  345. package/dist/src/bitgo/utils/tss/ecdsa/base.js +53 -0
  346. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts +56 -49
  347. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.d.ts.map +1 -1
  348. package/dist/src/bitgo/utils/tss/ecdsa/ecdsa.js +332 -317
  349. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +199 -0
  350. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
  351. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +950 -0
  352. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +8 -0
  353. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -0
  354. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +13 -0
  355. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +4 -0
  356. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  357. package/dist/src/bitgo/utils/tss/ecdsa/index.js +10 -2
  358. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts +15 -9
  359. package/dist/src/bitgo/utils/tss/ecdsa/types.d.ts.map +1 -1
  360. package/dist/src/bitgo/utils/tss/ecdsa/types.js +1 -1
  361. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +107 -0
  362. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -0
  363. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +55 -0
  364. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts +38 -11
  365. package/dist/src/bitgo/utils/tss/eddsa/eddsa.d.ts.map +1 -1
  366. package/dist/src/bitgo/utils/tss/eddsa/eddsa.js +170 -65
  367. package/dist/src/bitgo/utils/tss/eddsa/index.js +23 -9
  368. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts +7 -7
  369. package/dist/src/bitgo/utils/tss/eddsa/types.d.ts.map +1 -1
  370. package/dist/src/bitgo/utils/tss/index.d.ts +1 -0
  371. package/dist/src/bitgo/utils/tss/index.d.ts.map +1 -1
  372. package/dist/src/bitgo/utils/tss/index.js +24 -9
  373. package/dist/src/bitgo/utils/txRequest.d.ts +10 -0
  374. package/dist/src/bitgo/utils/txRequest.d.ts.map +1 -0
  375. package/dist/src/bitgo/utils/txRequest.js +47 -0
  376. package/dist/src/bitgo/utils/util.js +24 -10
  377. package/dist/src/bitgo/utils/wallet.d.ts +7 -0
  378. package/dist/src/bitgo/utils/wallet.d.ts.map +1 -0
  379. package/dist/src/bitgo/utils/wallet.js +48 -0
  380. package/dist/src/bitgo/wallet/BuildParams.d.ts +134 -0
  381. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -0
  382. package/dist/src/bitgo/wallet/BuildParams.js +151 -0
  383. package/dist/src/bitgo/wallet/iWallet.d.ts +301 -21
  384. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  385. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  386. package/dist/src/bitgo/wallet/iWallets.d.ts +109 -16
  387. package/dist/src/bitgo/wallet/iWallets.d.ts.map +1 -1
  388. package/dist/src/bitgo/wallet/iWallets.js +50 -3
  389. package/dist/src/bitgo/wallet/index.js +6 -2
  390. package/dist/src/bitgo/wallet/wallet.d.ts +226 -24
  391. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  392. package/dist/src/bitgo/wallet/wallet.js +1239 -342
  393. package/dist/src/bitgo/wallet/wallets.d.ts +103 -9
  394. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  395. package/dist/src/bitgo/wallet/wallets.js +934 -195
  396. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts +12 -0
  397. package/dist/src/bitgo/walletUtil/iMessageProvider.d.ts.map +1 -0
  398. package/dist/src/bitgo/walletUtil/iMessageProvider.js +3 -0
  399. package/dist/src/bitgo/walletUtil/index.d.ts +3 -0
  400. package/dist/src/bitgo/walletUtil/index.d.ts.map +1 -0
  401. package/dist/src/bitgo/walletUtil/index.js +19 -0
  402. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts +22 -0
  403. package/dist/src/bitgo/walletUtil/midnightMessageProvider.d.ts.map +1 -0
  404. package/dist/src/bitgo/walletUtil/midnightMessageProvider.js +95 -0
  405. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts +9 -0
  406. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.d.ts.map +1 -0
  407. package/dist/src/bitgo/walletUtil/signAccountBasedMidnightClaimMessages.js +72 -0
  408. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts +15 -0
  409. package/dist/src/bitgo/walletUtil/utxoMessageProof.d.ts.map +1 -0
  410. package/dist/src/bitgo/walletUtil/utxoMessageProof.js +40 -0
  411. package/dist/src/bitgo/webhook/index.js +6 -2
  412. package/dist/src/bitgo/webhook/webhooks.js +23 -9
  413. package/dist/src/coins/fiataed.d.ts +32 -0
  414. package/dist/src/coins/fiataed.d.ts.map +1 -0
  415. package/dist/src/coins/fiataed.js +61 -0
  416. package/dist/src/coins/fiateur.d.ts +3 -2
  417. package/dist/src/coins/fiateur.d.ts.map +1 -1
  418. package/dist/src/coins/fiateur.js +5 -1
  419. package/dist/src/coins/fiatgbp.d.ts +3 -2
  420. package/dist/src/coins/fiatgbp.d.ts.map +1 -1
  421. package/dist/src/coins/fiatgbp.js +5 -1
  422. package/dist/src/coins/fiatsgd.d.ts +32 -0
  423. package/dist/src/coins/fiatsgd.d.ts.map +1 -0
  424. package/dist/src/coins/fiatsgd.js +61 -0
  425. package/dist/src/coins/fiatusd.d.ts +3 -2
  426. package/dist/src/coins/fiatusd.d.ts.map +1 -1
  427. package/dist/src/coins/fiatusd.js +5 -1
  428. package/dist/src/coins/index.d.ts +4 -0
  429. package/dist/src/coins/index.d.ts.map +1 -1
  430. package/dist/src/coins/index.js +10 -2
  431. package/dist/src/coins/ofc.d.ts +3 -2
  432. package/dist/src/coins/ofc.d.ts.map +1 -1
  433. package/dist/src/coins/ofc.js +6 -2
  434. package/dist/src/coins/ofcToken.js +2 -2
  435. package/dist/src/coins/susd.d.ts +3 -2
  436. package/dist/src/coins/susd.d.ts.map +1 -1
  437. package/dist/src/coins/susd.js +5 -1
  438. package/dist/src/coins/tfiataed.d.ts +11 -0
  439. package/dist/src/coins/tfiataed.d.ts.map +1 -0
  440. package/dist/src/coins/tfiataed.js +17 -0
  441. package/dist/src/coins/tfiatsgd.d.ts +11 -0
  442. package/dist/src/coins/tfiatsgd.d.ts.map +1 -0
  443. package/dist/src/coins/tfiatsgd.js +17 -0
  444. package/dist/src/common.js +27 -13
  445. package/dist/src/index.d.ts +6 -1
  446. package/dist/src/index.d.ts.map +1 -1
  447. package/dist/src/index.js +28 -11
  448. package/dist/src/units.js +5 -6
  449. package/dist/test/node.utils.d.ts +2 -0
  450. package/dist/test/node.utils.d.ts.map +1 -0
  451. package/dist/test/node.utils.js +5 -0
  452. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts +2 -0
  453. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.d.ts.map +1 -0
  454. package/dist/test/unit/account-lib/baseCoin/messages/baseMessage.js +207 -0
  455. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts +2 -0
  456. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.d.ts.map +1 -0
  457. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilder.js +174 -0
  458. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts +2 -0
  459. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.d.ts.map +1 -0
  460. package/dist/test/unit/account-lib/baseCoin/messages/baseMessageBuilderFactory.js +108 -0
  461. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts +46 -0
  462. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.d.ts.map +1 -0
  463. package/dist/test/unit/account-lib/baseCoin/messages/fixtures.js +69 -0
  464. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.d.ts +2 -0
  465. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.d.ts.map +1 -0
  466. package/dist/test/unit/account-lib/mpc/tss/ecdsa/ecdsa.js +235 -0
  467. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.d.ts +3 -0
  468. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.d.ts.map +1 -0
  469. package/dist/test/unit/account-lib/mpc/tss/ecdsa/fixtures.js +24 -0
  470. package/dist/test/unit/bitgo/errors.d.ts +2 -0
  471. package/dist/test/unit/bitgo/errors.d.ts.map +1 -0
  472. package/dist/test/unit/bitgo/errors.js +136 -0
  473. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts +2 -0
  474. package/dist/test/unit/bitgo/trading/network/encrypt.d.ts.map +1 -0
  475. package/dist/test/unit/bitgo/trading/network/encrypt.js +71 -0
  476. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.d.ts +2 -0
  477. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.d.ts.map +1 -0
  478. package/dist/test/unit/bitgo/utils/abstractUtxoCoinUtil.js +45 -0
  479. package/dist/test/unit/bitgo/utils/messageTypes.d.ts +2 -0
  480. package/dist/test/unit/bitgo/utils/messageTypes.d.ts.map +1 -0
  481. package/dist/test/unit/bitgo/utils/messageTypes.js +64 -0
  482. package/dist/test/unit/bitgo/utils/notEmpty.d.ts +2 -0
  483. package/dist/test/unit/bitgo/utils/notEmpty.d.ts.map +1 -0
  484. package/dist/test/unit/bitgo/utils/notEmpty.js +15 -0
  485. package/dist/test/unit/bitgo/utils/postWithCodec.d.ts +2 -0
  486. package/dist/test/unit/bitgo/utils/postWithCodec.d.ts.map +1 -0
  487. package/dist/test/unit/bitgo/utils/postWithCodec.js +73 -0
  488. package/dist/test/unit/bitgo/utils/txRequest.d.ts +2 -0
  489. package/dist/test/unit/bitgo/utils/txRequest.d.ts.map +1 -0
  490. package/dist/test/unit/bitgo/utils/txRequest.js +105 -0
  491. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts +2 -0
  492. package/dist/test/unit/bitgo/wallet/BuildParams.d.ts.map +1 -0
  493. package/dist/test/unit/bitgo/wallet/BuildParams.js +68 -0
  494. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.d.ts +2 -0
  495. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.d.ts.map +1 -0
  496. package/dist/test/unit/bitgo/wallet/SendTransactionRequest.js +58 -0
  497. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts +2 -0
  498. package/dist/test/unit/bitgo/wallet/tokenApproval.d.ts.map +1 -0
  499. package/dist/test/unit/bitgo/wallet/tokenApproval.js +135 -0
  500. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts +2 -0
  501. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.d.ts.map +1 -0
  502. package/dist/test/unit/bitgo/wallet/walletEvmAddressCreation.js +181 -0
  503. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts +2 -0
  504. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.d.ts.map +1 -0
  505. package/dist/test/unit/bitgo/wallet/walletsEvmKeyring.js +216 -0
  506. package/dist/test/unit/units.d.ts +2 -0
  507. package/dist/test/unit/units.d.ts.map +1 -0
  508. package/dist/test/unit/units.js +98 -0
  509. package/dist/tsconfig.tsbuildinfo +1 -8279
  510. package/package.json +29 -22
  511. package/.eslintignore +0 -5
  512. package/CHANGELOG.md +0 -662
  513. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts +0 -77
  514. package/dist/src/account-lib/baseCoin/blsKeyPair.d.ts.map +0 -1
  515. package/dist/src/account-lib/baseCoin/blsKeyPair.js +0 -209
  516. package/dist/src/account-lib/mpc/hdTree.d.ts +0 -31
  517. package/dist/src/account-lib/mpc/hdTree.d.ts.map +0 -1
  518. package/dist/src/account-lib/mpc/hdTree.js +0 -141
  519. package/dist/src/account-lib/mpc/types.d.ts +0 -5
  520. package/dist/src/account-lib/mpc/types.d.ts.map +0 -1
  521. package/dist/src/account-lib/mpc/types.js +0 -3
  522. package/dist/src/bitgo/lightning/iLightning.d.ts +0 -186
  523. package/dist/src/bitgo/lightning/iLightning.d.ts.map +0 -1
  524. package/dist/src/bitgo/lightning/iLightning.js +0 -106
  525. package/dist/src/bitgo/lightning/index.d.ts +0 -5
  526. package/dist/src/bitgo/lightning/index.d.ts.map +0 -1
  527. package/dist/src/bitgo/lightning/index.js +0 -17
  528. package/dist/src/bitgo/lightning/lightning.d.ts +0 -25
  529. package/dist/src/bitgo/lightning/lightning.d.ts.map +0 -1
  530. package/dist/src/bitgo/lightning/lightning.js +0 -111
  531. package/dist/src/bitgo/lightning/lightningUtils.d.ts +0 -46
  532. package/dist/src/bitgo/lightning/lightningUtils.d.ts.map +0 -1
  533. package/dist/src/bitgo/lightning/lightningUtils.js +0 -133
  534. package/dist/src/bitgo/lightning/lnurlCodec.d.ts +0 -3
  535. package/dist/src/bitgo/lightning/lnurlCodec.d.ts.map +0 -1
  536. package/dist/src/bitgo/lightning/lnurlCodec.js +0 -28
  537. package/dist/src/bitgo/trading/affirmation.d.ts +0 -35
  538. package/dist/src/bitgo/trading/affirmation.d.ts.map +0 -1
  539. package/dist/src/bitgo/trading/affirmation.js +0 -53
  540. package/dist/src/bitgo/trading/affirmations.d.ts +0 -23
  541. package/dist/src/bitgo/trading/affirmations.d.ts.map +0 -1
  542. package/dist/src/bitgo/trading/affirmations.js +0 -45
  543. package/dist/src/bitgo/trading/iAffirmation.d.ts +0 -15
  544. package/dist/src/bitgo/trading/iAffirmation.d.ts.map +0 -1
  545. package/dist/src/bitgo/trading/iAffirmation.js +0 -13
  546. package/dist/src/bitgo/trading/iAffirmations.d.ts +0 -10
  547. package/dist/src/bitgo/trading/iAffirmations.d.ts.map +0 -1
  548. package/dist/src/bitgo/trading/iAffirmations.js +0 -3
  549. package/dist/src/bitgo/trading/iSettlement.d.ts +0 -25
  550. package/dist/src/bitgo/trading/iSettlement.d.ts.map +0 -1
  551. package/dist/src/bitgo/trading/iSettlement.js +0 -17
  552. package/dist/src/bitgo/trading/iSettlements.d.ts +0 -19
  553. package/dist/src/bitgo/trading/iSettlements.d.ts.map +0 -1
  554. package/dist/src/bitgo/trading/iSettlements.js +0 -3
  555. package/dist/src/bitgo/trading/iTradingPartner.d.ts +0 -14
  556. package/dist/src/bitgo/trading/iTradingPartner.d.ts.map +0 -1
  557. package/dist/src/bitgo/trading/iTradingPartner.js +0 -17
  558. package/dist/src/bitgo/trading/iTradingPartners.d.ts +0 -15
  559. package/dist/src/bitgo/trading/iTradingPartners.d.ts.map +0 -1
  560. package/dist/src/bitgo/trading/iTradingPartners.js +0 -9
  561. package/dist/src/bitgo/trading/lock.d.ts +0 -16
  562. package/dist/src/bitgo/trading/lock.d.ts.map +0 -1
  563. package/dist/src/bitgo/trading/lock.js +0 -12
  564. package/dist/src/bitgo/trading/payload.d.ts +0 -22
  565. package/dist/src/bitgo/trading/payload.d.ts.map +0 -1
  566. package/dist/src/bitgo/trading/payload.js +0 -3
  567. package/dist/src/bitgo/trading/settlement.d.ts +0 -16
  568. package/dist/src/bitgo/trading/settlement.d.ts.map +0 -1
  569. package/dist/src/bitgo/trading/settlement.js +0 -21
  570. package/dist/src/bitgo/trading/settlements.d.ts +0 -32
  571. package/dist/src/bitgo/trading/settlements.d.ts.map +0 -1
  572. package/dist/src/bitgo/trading/settlements.js +0 -61
  573. package/dist/src/bitgo/trading/trade.d.ts +0 -29
  574. package/dist/src/bitgo/trading/trade.d.ts.map +0 -1
  575. package/dist/src/bitgo/trading/trade.js +0 -11
  576. package/dist/src/bitgo/trading/tradingPartner.d.ts +0 -26
  577. package/dist/src/bitgo/trading/tradingPartner.d.ts.map +0 -1
  578. package/dist/src/bitgo/trading/tradingPartner.js +0 -31
  579. package/dist/src/bitgo/trading/tradingPartners.d.ts +0 -24
  580. package/dist/src/bitgo/trading/tradingPartners.d.ts.map +0 -1
  581. package/dist/src/bitgo/trading/tradingPartners.js +0 -32
  582. package/dist/src/bitgo/utils/blsUtils.d.ts +0 -52
  583. package/dist/src/bitgo/utils/blsUtils.d.ts.map +0 -1
  584. package/dist/src/bitgo/utils/blsUtils.js +0 -237
  585. package/dist/src/bitgo/utils/iBlsUtils.d.ts +0 -14
  586. package/dist/src/bitgo/utils/iBlsUtils.d.ts.map +0 -1
  587. package/dist/src/bitgo/utils/iBlsUtils.js +0 -3
  588. package/dist/src/openssl/index.d.ts +0 -2
  589. package/dist/src/openssl/index.d.ts.map +0 -1
  590. package/dist/src/openssl/openssl.d.ts +0 -12
  591. package/dist/src/openssl/openssl.d.ts.map +0 -1
  592. package/dist/src/openssl/openssl.js +0 -48
  593. package/dist/src/openssl/opensslbytes.d.ts +0 -4
  594. package/dist/src/openssl/opensslbytes.d.ts.map +0 -1
  595. package/dist/src/openssl/opensslbytes.js +0 -20
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -11,18 +15,29 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
11
15
  }) : function(o, v) {
12
16
  o["default"] = v;
13
17
  });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
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
+ })();
21
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
37
  };
24
38
  Object.defineProperty(exports, "__esModule", { value: true });
25
39
  exports.Wallets = void 0;
40
+ exports.isWalletWithKeychains = isWalletWithKeychains;
26
41
  /**
27
42
  * @prettier
28
43
  */
@@ -30,11 +45,21 @@ const assert_1 = __importDefault(require("assert"));
30
45
  const bignumber_js_1 = require("bignumber.js");
31
46
  const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
32
47
  const _ = __importStar(require("lodash"));
48
+ const statics_1 = require("@bitgo-beta/statics");
33
49
  const api_1 = require("../../api");
34
50
  const common = __importStar(require("../../common"));
35
51
  const ecdh_1 = require("../ecdh");
52
+ const keychain_1 = require("../keychain");
36
53
  const utils_1 = require("../utils");
54
+ const iWallets_1 = require("./iWallets");
37
55
  const wallet_1 = require("./wallet");
56
+ const evmUtils_1 = require("../evm/evmUtils");
57
+ /**
58
+ * Check if a wallet is a WalletWithKeychains
59
+ */
60
+ function isWalletWithKeychains(wallet) {
61
+ return wallet.responseType === 'WalletWithKeychains';
62
+ }
38
63
  class Wallets {
39
64
  constructor(bitgo, baseCoin) {
40
65
  this.bitgo = bitgo;
@@ -53,35 +78,10 @@ class Wallets {
53
78
  * @returns {*}
54
79
  */
55
80
  async list(params = {}) {
56
- const queryObject = {};
57
81
  if (params.skip && params.prevId) {
58
82
  throw new Error('cannot specify both skip and prevId');
59
83
  }
60
- if (params.getbalances) {
61
- if (!_.isBoolean(params.getbalances)) {
62
- throw new Error('invalid getbalances argument, expecting boolean');
63
- }
64
- queryObject.getbalances = params.getbalances;
65
- }
66
- if (params.prevId) {
67
- if (!_.isString(params.prevId)) {
68
- throw new Error('invalid prevId argument, expecting string');
69
- }
70
- queryObject.prevId = params.prevId;
71
- }
72
- if (params.limit) {
73
- if (!_.isNumber(params.limit)) {
74
- throw new Error('invalid limit argument, expecting number');
75
- }
76
- queryObject.limit = params.limit;
77
- }
78
- if (params.allTokens) {
79
- if (!_.isBoolean(params.allTokens)) {
80
- throw new Error('invalid allTokens argument, expecting boolean');
81
- }
82
- queryObject.allTokens = params.allTokens;
83
- }
84
- const body = (await this.bitgo.get(this.baseCoin.url('/wallet')).query(queryObject).result());
84
+ const body = (await this.bitgo.get(this.baseCoin.url('/wallet')).query(params).result());
85
85
  body.wallets = body.wallets.map((w) => new wallet_1.Wallet(this.bitgo, this.baseCoin, w));
86
86
  return body;
87
87
  }
@@ -101,8 +101,9 @@ class Wallets {
101
101
  if (typeof params.label !== 'string') {
102
102
  throw new Error('missing required string parameter label');
103
103
  }
104
- // no need to pass keys for (single) custodial wallets
105
- if (params.type !== 'custodial') {
104
+ (0, evmUtils_1.validateEvmKeyRingWalletParams)(params, this.baseCoin);
105
+ if (!params.evmKeyRingReferenceWalletId && params.type !== 'custodial') {
106
+ // no need to pass keys for (single) custodial wallets
106
107
  if (Array.isArray(params.keys) === false || !_.isNumber(params.m) || !_.isNumber(params.n)) {
107
108
  throw new Error('invalid argument');
108
109
  }
@@ -114,8 +115,19 @@ class Wallets {
114
115
  if (params.gasPrice && !_.isNumber(params.gasPrice)) {
115
116
  throw new Error('invalid argument for gasPrice - number expected');
116
117
  }
117
- if (params.walletVersion && !_.isNumber(params.walletVersion)) {
118
- throw new Error('invalid argument for walletVersion - number expected');
118
+ if (params.walletVersion) {
119
+ if (!_.isNumber(params.walletVersion)) {
120
+ throw new Error('invalid argument for walletVersion - number expected');
121
+ }
122
+ if (params.multisigType === 'tss' && this.baseCoin.getMPCAlgorithm() === 'ecdsa' && params.walletVersion === 3) {
123
+ const tssSettings = await this.bitgo
124
+ .get(this.bitgo.microservicesUrl('/api/v2/tss/settings'))
125
+ .result();
126
+ const multisigTypeVersion = tssSettings.coinSettings[this.baseCoin.getFamily()]?.walletCreationSettings?.multiSigTypeVersion;
127
+ if (multisigTypeVersion === 'MPCv2') {
128
+ params.walletVersion = 5;
129
+ }
130
+ }
119
131
  }
120
132
  if (params.tags && Array.isArray(params.tags) === false) {
121
133
  throw new Error('invalid argument for tags - array expected');
@@ -132,11 +144,95 @@ class Wallets {
132
144
  if (params.address && (!_.isString(params.address) || !this.baseCoin.isValidAddress(params.address))) {
133
145
  throw new Error('invalid argument for address - valid address string expected');
134
146
  }
135
- const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet')).send(params).result();
147
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(params).result();
136
148
  return {
137
149
  wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
138
150
  };
139
151
  }
152
+ async generateLightningWallet(params) {
153
+ const reqId = new utils_1.RequestTracer();
154
+ this.bitgo.setRequestTracer(reqId);
155
+ const { label, passphrase, enterprise, passcodeEncryptionCode, subType } = params;
156
+ // TODO BTC-1899: only userAuth key is required for custodial lightning wallet. all 3 keys are required for self custodial lightning.
157
+ // to avoid changing the platform for custodial flow, let us all 3 keys both wallet types.
158
+ const keychainPromises = [undefined, 'userAuth', 'nodeAuth'].map((purpose) => {
159
+ return async () => {
160
+ const keychain = this.baseCoin.keychains().create();
161
+ const keychainParams = {
162
+ pub: keychain.pub,
163
+ encryptedPrv: this.bitgo.encrypt({ password: passphrase, input: keychain.prv }),
164
+ originalPasscodeEncryptionCode: purpose === undefined ? passcodeEncryptionCode : undefined,
165
+ coinSpecific: purpose === undefined ? undefined : { [this.baseCoin.getChain()]: { purpose } },
166
+ keyType: 'independent',
167
+ source: 'user',
168
+ };
169
+ return await this.baseCoin.keychains().add(keychainParams);
170
+ };
171
+ });
172
+ const { userKeychain, userAuthKeychain, nodeAuthKeychain } = await (0, utils_1.promiseProps)({
173
+ userKeychain: keychainPromises[0](),
174
+ userAuthKeychain: keychainPromises[1](),
175
+ nodeAuthKeychain: keychainPromises[2](),
176
+ });
177
+ const walletParams = {
178
+ label,
179
+ m: 1,
180
+ n: 1,
181
+ type: 'hot',
182
+ subType,
183
+ enterprise,
184
+ keys: [userKeychain.id],
185
+ coinSpecific: { [this.baseCoin.getChain()]: { keys: [userAuthKeychain.id, nodeAuthKeychain.id] } },
186
+ };
187
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(walletParams).result();
188
+ const wallet = new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet);
189
+ return {
190
+ wallet,
191
+ userKeychain,
192
+ userAuthKeychain,
193
+ nodeAuthKeychain,
194
+ responseType: 'LightningWalletWithKeychains',
195
+ };
196
+ }
197
+ /**
198
+ * Generate a Go Account wallet
199
+ * @param params GenerateGoAccountWalletOptions
200
+ * @returns Promise<GoAccountWalletWithUserKeychain>
201
+ */
202
+ async generateGoAccountWallet(params) {
203
+ const reqId = new utils_1.RequestTracer();
204
+ this.bitgo.setRequestTracer(reqId);
205
+ const { label, passphrase, enterprise, passcodeEncryptionCode } = params;
206
+ const keychain = this.baseCoin.keychains().create();
207
+ const keychainParams = {
208
+ pub: keychain.pub,
209
+ encryptedPrv: this.bitgo.encrypt({ password: passphrase, input: keychain.prv }),
210
+ originalPasscodeEncryptionCode: passcodeEncryptionCode,
211
+ keyType: 'independent',
212
+ source: 'user',
213
+ };
214
+ const userKeychain = await this.baseCoin.keychains().add(keychainParams);
215
+ const walletParams = {
216
+ label,
217
+ m: 1,
218
+ n: 1,
219
+ type: 'trading',
220
+ enterprise,
221
+ keys: [userKeychain.id],
222
+ };
223
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(walletParams).result();
224
+ const wallet = new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet);
225
+ const result = {
226
+ wallet,
227
+ userKeychain,
228
+ responseType: 'GoAccountWalletWithUserKeychain',
229
+ };
230
+ // Add warning if the user keychain has an encrypted private key
231
+ if (!_.isUndefined(userKeychain.encryptedPrv)) {
232
+ result.warning = 'Be sure to backup the user keychain -- it is not stored anywhere else!';
233
+ }
234
+ return result;
235
+ }
140
236
  /**
141
237
  * Generate a new wallet
142
238
  * 1. Creates the user keychain locally on the client, and encrypts it with the provided passphrase
@@ -145,89 +241,153 @@ class Wallets {
145
241
  * 4. Creates the BitGo key on the service
146
242
  * 5. Creates the wallet on BitGo with the 3 public keys above
147
243
  * @param params
148
- * @param params.label
149
- * @param params.passphrase
244
+ * @param params.label Label for the wallet
245
+ * @param params.passphrase Passphrase to be used to encrypt the user and backup keychains
150
246
  * @param params.userKey User xpub
151
247
  * @param params.backupXpub Backup xpub
152
248
  * @param params.backupXpubProvider
153
- * @param params.backupProvider Third party backup provider for TSS
154
- * @param params.enterprise
249
+ * @param params.enterprise the enterpriseId
155
250
  * @param params.disableTransactionNotifications
156
- * @param params.passcodeEncryptionCode
157
- * @param params.coldDerivationSeed
251
+ * @param params.passcodeEncryptionCode optional this is a recovery code that can be used to decrypt the original passphrase in a recovery case.
252
+ * The user must generate and keep the encrypted original passphrase safe while this code is stored on BitGo
253
+ * @param params.coldDerivationSeed optional seed for SMC wallets
158
254
  * @param params.gasPrice
159
255
  * @param params.disableKRSEmail
160
256
  * @param params.walletVersion
161
257
  * @param params.multisigType optional multisig type, 'onchain' or 'tss' or 'blsdkg'; if absent, we will defer to the coin's default type
258
+ * @param params.isDistributedCustody optional parameter for creating bitgo key. This is only necessary if you want to create
259
+ * a distributed custody wallet. If provided, you must have the enterprise license and pass in
260
+ * `params.enterprise` into `generateWallet` as well.
261
+ * @param params.type optional wallet type, 'hot' or 'cold' or 'custodial'; if absent, we will defer to 'hot'
262
+ * @param params.bitgoKeyId optional bitgo key id for SMC TSS wallets
263
+ * @param params.commonKeychain optional common keychain for SMC TSS wallets
264
+ *
162
265
  * @returns {*}
163
266
  */
164
267
  async generateWallet(params = {}) {
268
+ // Assign the default multiSig type value based on the coin
269
+ if (!params.multisigType) {
270
+ params.multisigType = this.baseCoin.getDefaultMultisigType();
271
+ }
272
+ if (this.baseCoin.getFamily() === 'lnbtc') {
273
+ const options = (0, utils_1.decodeOrElse)(iWallets_1.GenerateLightningWalletOptionsCodec.name, iWallets_1.GenerateLightningWalletOptionsCodec, params, (errors) => {
274
+ throw new Error(`error(s) parsing generate lightning wallet request params: ${errors}`);
275
+ });
276
+ const walletData = await this.generateLightningWallet(options);
277
+ walletData.encryptedWalletPassphrase = this.bitgo.encrypt({
278
+ input: options.passphrase,
279
+ password: options.passcodeEncryptionCode,
280
+ });
281
+ return walletData;
282
+ }
283
+ // Go Account wallet generation
284
+ if (this.baseCoin.getFamily() === 'ofc' && params.type === 'trading') {
285
+ const options = (0, utils_1.decodeOrElse)(iWallets_1.GenerateGoAccountWalletOptionsCodec.name, iWallets_1.GenerateGoAccountWalletOptionsCodec, params, (errors) => {
286
+ throw new Error(`error(s) parsing generate go account request params: ${errors}`);
287
+ });
288
+ const walletData = await this.generateGoAccountWallet(options);
289
+ walletData.encryptedWalletPassphrase = this.bitgo.encrypt({
290
+ input: options.passphrase,
291
+ password: options.passcodeEncryptionCode,
292
+ });
293
+ return walletData;
294
+ }
165
295
  common.validateParams(params, ['label'], ['passphrase', 'userKey', 'backupXpub']);
166
296
  if (typeof params.label !== 'string') {
167
297
  throw new Error('missing required string parameter label');
168
298
  }
299
+ const { type = 'hot', label, passphrase, enterprise, isDistributedCustody, evmKeyRingReferenceWalletId } = params;
169
300
  const isTss = params.multisigType === 'tss' && this.baseCoin.supportsTss();
170
- const label = params.label;
171
- const passphrase = params.passphrase;
172
301
  const canEncrypt = !!passphrase && typeof passphrase === 'string';
173
- const isCold = !!params.userKey && params.multisigType !== 'onchain';
302
+ if ((0, evmUtils_1.validateEvmKeyRingWalletParams)(params, this.baseCoin)) {
303
+ return await (0, evmUtils_1.createEvmKeyRingWallet)({
304
+ label,
305
+ evmKeyRingReferenceWalletId: evmKeyRingReferenceWalletId,
306
+ bitgo: this.bitgo,
307
+ baseCoin: this.baseCoin,
308
+ });
309
+ }
174
310
  const walletParams = {
175
311
  label: label,
176
312
  m: 2,
177
313
  n: 3,
178
314
  keys: [],
179
- isCold,
315
+ type: !!params.userKey && params.multisigType !== 'onchain' ? 'cold' : type,
180
316
  };
181
317
  if (!_.isUndefined(params.passcodeEncryptionCode)) {
182
318
  if (!_.isString(params.passcodeEncryptionCode)) {
183
319
  throw new Error('passcodeEncryptionCode must be a string');
184
320
  }
185
321
  }
186
- if (!_.isUndefined(params.enterprise)) {
187
- if (!_.isString(params.enterprise)) {
322
+ if (!_.isUndefined(enterprise)) {
323
+ if (!_.isString(enterprise)) {
188
324
  throw new Error('invalid enterprise argument, expecting string');
189
325
  }
190
- walletParams.enterprise = params.enterprise;
191
- }
192
- else {
193
- // enterprise not defined
194
- if (params.multisigType === 'tss' && params.backupProvider === 'BitGoTrustAsKrs') {
195
- throw new Error('The enterprise id is required when creating TSS wallet with BitGo Trust as KRS.');
196
- }
326
+ walletParams.enterprise = enterprise;
197
327
  }
198
- // EVM TSS wallets must use wallet version 3
199
- if ((isTss && this.baseCoin.isEVM()) !== (params.walletVersion === 3)) {
200
- throw new Error('EVM TSS wallets are only supported for wallet version 3');
328
+ // EVM TSS wallets must use wallet version 3, 5 and 6
329
+ if (isTss &&
330
+ this.baseCoin.isEVM() &&
331
+ !evmKeyRingReferenceWalletId &&
332
+ !(params.walletVersion === 3 || params.walletVersion === 5 || params.walletVersion === 6)) {
333
+ throw new Error('EVM TSS wallets are only supported for wallet version 3, 5 and 6');
201
334
  }
202
335
  if (isTss) {
203
- if (isCold) {
204
- throw new Error('TSS cold wallets are not supported at this time');
205
- }
206
336
  if (!this.baseCoin.supportsTss()) {
207
337
  throw new Error(`coin ${this.baseCoin.getFamily()} does not support TSS at this time`);
208
338
  }
209
- return this.generateMpcWallet({
339
+ if ((params.walletVersion === 5 || params.walletVersion === 6) &&
340
+ !this.baseCoin.getConfig().features.includes(statics_1.CoinFeature.MPCV2)) {
341
+ throw new Error(`coin ${this.baseCoin.getFamily()} does not support TSS MPCv2 at this time`);
342
+ }
343
+ (0, assert_1.default)(enterprise, 'enterprise is required for TSS wallet');
344
+ if (type === 'cold') {
345
+ // validate
346
+ (0, assert_1.default)(params.bitgoKeyId, 'bitgoKeyId is required for SMC TSS wallet');
347
+ (0, assert_1.default)(params.commonKeychain, 'commonKeychain is required for SMC TSS wallet');
348
+ return this.generateSMCMpcWallet({
349
+ multisigType: 'tss',
350
+ label,
351
+ enterprise,
352
+ walletVersion: params.walletVersion,
353
+ bitgoKeyId: params.bitgoKeyId,
354
+ commonKeychain: params.commonKeychain,
355
+ coldDerivationSeed: params.coldDerivationSeed,
356
+ });
357
+ }
358
+ if (type === 'custodial') {
359
+ return this.generateCustodialMpcWallet({
360
+ multisigType: 'tss',
361
+ label,
362
+ enterprise,
363
+ walletVersion: params.walletVersion,
364
+ });
365
+ }
366
+ (0, assert_1.default)(passphrase, 'cannot generate TSS keys without passphrase');
367
+ const walletData = await this.generateMpcWallet({
210
368
  multisigType: 'tss',
211
369
  label,
212
370
  passphrase,
213
371
  originalPasscodeEncryptionCode: params.passcodeEncryptionCode,
214
- enterprise: params.enterprise,
372
+ enterprise,
215
373
  walletVersion: params.walletVersion,
216
- backupProvider: params.backupProvider,
217
374
  });
218
- }
219
- const isBlsDkg = params.multisigType ? params.multisigType === 'blsdkg' : this.baseCoin.supportsBlsDkg();
220
- if (isBlsDkg) {
221
- if (!canEncrypt) {
222
- throw new Error('cannot generate BLS-DKG keys without passphrase');
375
+ if (params.passcodeEncryptionCode) {
376
+ walletData.encryptedWalletPassphrase = this.bitgo.encrypt({
377
+ input: passphrase,
378
+ password: params.passcodeEncryptionCode,
379
+ });
223
380
  }
224
- if (isCold) {
225
- throw new Error('BLS-DKG cold wallets are not supported at this time');
381
+ return walletData;
382
+ }
383
+ // Handle distributed custody
384
+ if (isDistributedCustody) {
385
+ if (!enterprise) {
386
+ throw new Error('must provide enterprise when creating distributed custody wallet');
226
387
  }
227
- if (!this.baseCoin.supportsBlsDkg()) {
228
- throw new Error(`coin ${this.baseCoin.getFamily()} does not support BLS-DKG at this time`);
388
+ if (!type || type !== 'cold') {
389
+ throw new Error('distributed custody wallets must be type: cold');
229
390
  }
230
- return this.generateMpcWallet({ multisigType: 'blsdkg', label, passphrase });
231
391
  }
232
392
  const hasBackupXpub = !!params.backupXpub;
233
393
  const hasBackupXpubProvider = !!params.backupXpubProvider;
@@ -288,110 +448,140 @@ class Wallets {
288
448
  }
289
449
  let derivationPath = undefined;
290
450
  const reqId = new utils_1.RequestTracer();
291
- // Add the user keychain
292
- const userKeychainPromise = async () => {
293
- let userKeychainParams;
294
- let userKeychain;
295
- // User provided user key
296
- if (params.userKey) {
297
- userKeychain = { pub: params.userKey };
298
- userKeychainParams = userKeychain;
299
- if (params.coldDerivationSeed) {
300
- // the derivation only makes sense when a key already exists
301
- const derivation = this.baseCoin.deriveKeyWithSeed({
302
- key: params.userKey,
303
- seed: params.coldDerivationSeed,
451
+ if (params.type === 'custodial' && (params.multisigType ?? 'onchain') === 'onchain') {
452
+ // for custodial multisig, when the wallet is created on the platfor side, the keys are not needed
453
+ walletParams.n = undefined;
454
+ walletParams.m = undefined;
455
+ walletParams.keys = undefined;
456
+ walletParams.keySignatures = undefined;
457
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(walletParams).result(); // returns the ids
458
+ const userKeychain = this.baseCoin.keychains().get({ id: newWallet.keys[keychain_1.KeyIndices.USER], reqId });
459
+ const backupKeychain = this.baseCoin.keychains().get({ id: newWallet.keys[keychain_1.KeyIndices.BACKUP], reqId });
460
+ const bitgoKeychain = this.baseCoin.keychains().get({ id: newWallet.keys[keychain_1.KeyIndices.BITGO], reqId });
461
+ const [userKey, bitgoKey, backupKey] = await Promise.all([userKeychain, bitgoKeychain, backupKeychain]);
462
+ const result = {
463
+ wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
464
+ userKeychain: userKey,
465
+ backupKeychain: bitgoKey,
466
+ bitgoKeychain: backupKey,
467
+ responseType: 'WalletWithKeychains',
468
+ };
469
+ return result;
470
+ }
471
+ else {
472
+ const userKeychainPromise = async () => {
473
+ let userKeychainParams;
474
+ let userKeychain;
475
+ // User provided user key
476
+ if (params.userKey) {
477
+ userKeychain = { pub: params.userKey };
478
+ userKeychainParams = userKeychain;
479
+ if (params.coldDerivationSeed) {
480
+ // the derivation only makes sense when a key already exists
481
+ const derivation = this.baseCoin.deriveKeyWithSeed({
482
+ key: params.userKey,
483
+ seed: params.coldDerivationSeed,
484
+ });
485
+ derivationPath = derivation.derivationPath;
486
+ userKeychain.pub = derivation.key;
487
+ userKeychain.derivedFromParentWithSeed = params.coldDerivationSeed;
488
+ }
489
+ }
490
+ else {
491
+ if (!canEncrypt) {
492
+ throw new Error('cannot generate user keypair without passphrase');
493
+ }
494
+ // Create the user key.
495
+ userKeychain = this.baseCoin.keychains().create();
496
+ userKeychain.encryptedPrv = this.bitgo.encrypt({ password: passphrase, input: userKeychain.prv });
497
+ userKeychainParams = {
498
+ pub: userKeychain.pub,
499
+ encryptedPrv: userKeychain.encryptedPrv,
500
+ originalPasscodeEncryptionCode: params.passcodeEncryptionCode,
501
+ };
502
+ }
503
+ userKeychainParams.reqId = reqId;
504
+ const newUserKeychain = await this.baseCoin.keychains().add(userKeychainParams);
505
+ return _.extend({}, newUserKeychain, userKeychain);
506
+ };
507
+ const backupKeychainPromise = async () => {
508
+ if (params.backupXpubProvider) {
509
+ // If requested, use a KRS or backup key provider
510
+ return this.baseCoin.keychains().createBackup({
511
+ provider: params.backupXpubProvider || 'defaultRMGBackupProvider',
512
+ disableKRSEmail: params.disableKRSEmail,
513
+ krsSpecific: params.krsSpecific,
514
+ type: this.baseCoin.getChain(),
515
+ passphrase: params.passphrase,
516
+ reqId,
304
517
  });
305
- derivationPath = derivation.derivationPath;
306
- userKeychain.pub = derivation.key;
307
- userKeychain.derivedFromParentWithSeed = params.coldDerivationSeed;
308
518
  }
309
- }
310
- else {
311
- if (!canEncrypt) {
312
- throw new Error('cannot generate user keypair without passphrase');
519
+ // User provided backup xpub
520
+ if (params.backupXpub) {
521
+ // user provided backup ethereum address
522
+ return this.baseCoin.keychains().add({
523
+ pub: params.backupXpub,
524
+ source: 'backup',
525
+ reqId,
526
+ });
313
527
  }
314
- // Create the user key.
315
- userKeychain = this.baseCoin.keychains().create();
316
- userKeychain.encryptedPrv = this.bitgo.encrypt({ password: passphrase, input: userKeychain.prv });
317
- userKeychainParams = {
318
- pub: userKeychain.pub,
319
- encryptedPrv: userKeychain.encryptedPrv,
320
- originalPasscodeEncryptionCode: params.passcodeEncryptionCode,
528
+ else {
529
+ if (!canEncrypt) {
530
+ throw new Error('cannot generate backup keypair without passphrase');
531
+ }
532
+ // No provided backup xpub or address, so default to creating one here
533
+ return this.baseCoin.keychains().createBackup({ reqId, passphrase: params.passphrase });
534
+ }
535
+ };
536
+ const { userKeychain, backupKeychain, bitgoKeychain } = await (0, utils_1.promiseProps)({
537
+ userKeychain: userKeychainPromise(),
538
+ backupKeychain: backupKeychainPromise(),
539
+ bitgoKeychain: this.baseCoin
540
+ .keychains()
541
+ .createBitGo({ enterprise: params.enterprise, reqId, isDistributedCustody: params.isDistributedCustody }),
542
+ });
543
+ walletParams.keys = [userKeychain.id, backupKeychain.id, bitgoKeychain.id];
544
+ const { prv } = userKeychain;
545
+ if (_.isString(prv)) {
546
+ (0, assert_1.default)(backupKeychain.pub);
547
+ (0, assert_1.default)(bitgoKeychain.pub);
548
+ walletParams.keySignatures = {
549
+ backup: (await this.baseCoin.signMessage({ prv }, backupKeychain.pub)).toString('hex'),
550
+ bitgo: (await this.baseCoin.signMessage({ prv }, bitgoKeychain.pub)).toString('hex'),
321
551
  };
322
552
  }
323
- userKeychainParams.reqId = reqId;
324
- const newUserKeychain = await this.baseCoin.keychains().add(userKeychainParams);
325
- return _.extend({}, newUserKeychain, userKeychain);
326
- };
327
- const backupKeychainPromise = async () => {
328
- if (params.backupXpubProvider) {
329
- // If requested, use a KRS or backup key provider
330
- return this.baseCoin.keychains().createBackup({
331
- provider: params.backupXpubProvider || 'defaultRMGBackupProvider',
332
- disableKRSEmail: params.disableKRSEmail,
333
- krsSpecific: params.krsSpecific,
334
- type: this.baseCoin.getChain(),
335
- reqId,
336
- });
553
+ const keychains = {
554
+ userKeychain,
555
+ backupKeychain,
556
+ bitgoKeychain,
557
+ };
558
+ const finalWalletParams = await this.baseCoin.supplementGenerateWallet(walletParams, keychains);
559
+ if (_.includes(['xrp', 'xlm', 'cspr'], this.baseCoin.getFamily()) && !_.isUndefined(params.rootPrivateKey)) {
560
+ walletParams.rootPrivateKey = params.rootPrivateKey;
337
561
  }
338
- // User provided backup xpub
339
- if (params.backupXpub) {
340
- // user provided backup ethereum address
341
- return this.baseCoin.keychains().add({
342
- pub: params.backupXpub,
343
- source: 'backup',
344
- reqId,
345
- });
562
+ this.bitgo.setRequestTracer(reqId);
563
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(finalWalletParams).result();
564
+ const result = {
565
+ wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
566
+ userKeychain: userKeychain,
567
+ backupKeychain: backupKeychain,
568
+ bitgoKeychain: bitgoKeychain,
569
+ responseType: 'WalletWithKeychains',
570
+ };
571
+ if (!_.isUndefined(backupKeychain.prv)) {
572
+ result.warning = 'Be sure to backup the backup keychain -- it is not stored anywhere else!';
346
573
  }
347
- else {
348
- if (!canEncrypt) {
349
- throw new Error('cannot generate backup keypair without passphrase');
350
- }
351
- // No provided backup xpub or address, so default to creating one here
352
- return this.baseCoin.keychains().createBackup({ reqId });
574
+ if (!_.isUndefined(derivationPath)) {
575
+ userKeychain.derivationPath = derivationPath;
353
576
  }
354
- };
355
- const { userKeychain, backupKeychain, bitgoKeychain } = await utils_1.promiseProps({
356
- userKeychain: userKeychainPromise(),
357
- backupKeychain: backupKeychainPromise(),
358
- bitgoKeychain: this.baseCoin.keychains().createBitGo({ enterprise: params.enterprise, reqId }),
359
- });
360
- walletParams.keys = [userKeychain.id, backupKeychain.id, bitgoKeychain.id];
361
- walletParams.isCold = isCold;
362
- const { prv } = userKeychain;
363
- if (_.isString(prv)) {
364
- assert_1.default(backupKeychain.pub);
365
- assert_1.default(bitgoKeychain.pub);
366
- walletParams.keySignatures = {
367
- backup: (await this.baseCoin.signMessage({ prv }, backupKeychain.pub)).toString('hex'),
368
- bitgo: (await this.baseCoin.signMessage({ prv }, bitgoKeychain.pub)).toString('hex'),
369
- };
370
- }
371
- if (_.includes(['xrp', 'xlm', 'cspr'], this.baseCoin.getFamily()) && !_.isUndefined(params.rootPrivateKey)) {
372
- walletParams.rootPrivateKey = params.rootPrivateKey;
373
- }
374
- const keychains = {
375
- userKeychain,
376
- backupKeychain,
377
- bitgoKeychain,
378
- };
379
- const finalWalletParams = await this.baseCoin.supplementGenerateWallet(walletParams, keychains);
380
- this.bitgo.setRequestTracer(reqId);
381
- const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet')).send(finalWalletParams).result();
382
- const result = {
383
- wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
384
- userKeychain: userKeychain,
385
- backupKeychain: backupKeychain,
386
- bitgoKeychain: bitgoKeychain,
387
- };
388
- if (!_.isUndefined(backupKeychain.prv)) {
389
- result.warning = 'Be sure to backup the backup keychain -- it is not stored anywhere else!';
390
- }
391
- if (!_.isUndefined(derivationPath)) {
392
- userKeychain.derivationPath = derivationPath;
577
+ if (canEncrypt && params.passcodeEncryptionCode) {
578
+ result.encryptedWalletPassphrase = this.bitgo.encrypt({
579
+ input: passphrase,
580
+ password: params.passcodeEncryptionCode,
581
+ });
582
+ }
583
+ return result;
393
584
  }
394
- return result;
395
585
  }
396
586
  /**
397
587
  * List the user's wallet shares
@@ -400,6 +590,13 @@ class Wallets {
400
590
  async listShares(params = {}) {
401
591
  return await this.bitgo.get(this.baseCoin.url('/walletshare')).result();
402
592
  }
593
+ /**
594
+ * List the user's wallet shares v2
595
+ * @returns {Promise<WalletShares>}
596
+ */
597
+ async listSharesV2() {
598
+ return await this.bitgo.get(this.bitgo.url('/walletshares', 2)).result();
599
+ }
403
600
  /**
404
601
  * Gets a wallet share information, including the encrypted sharing keychain. requires unlock if keychain is present.
405
602
  * @param params
@@ -422,6 +619,73 @@ class Wallets {
422
619
  .send(params)
423
620
  .result();
424
621
  }
622
+ /**
623
+ * Bulk accept wallet shares
624
+ * @param params AcceptShareOptionsRequest[]
625
+ * @returns {Promise<BulkAcceptShareResponse>}
626
+ */
627
+ async bulkAcceptShareRequest(params) {
628
+ return await this.bulkAcceptShareRequestWithRetry(params);
629
+ }
630
+ async bulkAcceptShareRequestWithRetry(params) {
631
+ // Server has a limit of approximately 1MB for payload size
632
+ let MAX_PAYLOAD_SIZE = 950000; // ~950KB to leave some buffer
633
+ // Function to calculate the size of a payload
634
+ const calculatePayloadSize = (items) => {
635
+ return Buffer.byteLength(JSON.stringify({ keysForWalletShares: items }), 'utf8');
636
+ };
637
+ const results = [];
638
+ const remainingParams = [...params];
639
+ while (remainingParams.length > 0) {
640
+ // Build optimal batch by adding items until we reach size limit
641
+ const batch = [];
642
+ // Start with empty batch
643
+ // Add items one by one while monitoring payload size
644
+ while (remainingParams.length > 0) {
645
+ // Test adding the next item
646
+ const testBatch = [...batch, remainingParams[0]];
647
+ const testSize = calculatePayloadSize(testBatch);
648
+ // If adding this item would exceed the size limit, stop adding
649
+ if (testSize > MAX_PAYLOAD_SIZE && batch.length > 0) {
650
+ break;
651
+ }
652
+ // Otherwise, add the item to the batch
653
+ batch.push(remainingParams.shift());
654
+ }
655
+ // Handle case where even a single item is too large
656
+ if (batch.length === 0 && remainingParams.length > 0) {
657
+ // Send just the first item even if it's oversized
658
+ batch.push(remainingParams.shift());
659
+ }
660
+ const payloadObj = { keysForWalletShares: batch };
661
+ try {
662
+ const result = await this.bitgo.put(this.bitgo.url('/walletshares/accept', 2)).send(payloadObj).result();
663
+ if (result.acceptedWalletShares && Array.isArray(result.acceptedWalletShares)) {
664
+ results.push(...result.acceptedWalletShares);
665
+ }
666
+ }
667
+ catch (error) {
668
+ if (error.status === 413 && batch.length > 1) {
669
+ // If we still get 413 with multiple items, put them back and try with half the batch size
670
+ remainingParams.unshift(...batch);
671
+ MAX_PAYLOAD_SIZE = Math.floor(MAX_PAYLOAD_SIZE / 2); // Reduce size limit for next attempt
672
+ continue;
673
+ }
674
+ throw error;
675
+ }
676
+ }
677
+ return {
678
+ acceptedWalletShares: results,
679
+ };
680
+ }
681
+ async bulkUpdateWalletShareRequest(params) {
682
+ return await this.bitgo
683
+ .put(this.bitgo.url('/walletshares/update', 2))
684
+ .send({
685
+ shares: params,
686
+ })
687
+ .result();
688
+ }
425
689
  /**
426
690
  * Resend a wallet share invitation email
427
691
  * @param params
@@ -444,6 +708,39 @@ class Wallets {
444
708
  .send()
445
709
  .result();
446
710
  }
711
+ /**
712
+ * Re-share wallet with existing spenders of the wallet
713
+ * @param walletId
714
+ * @param userPassword
715
+ */
716
+ async reshareWalletWithSpenders(walletId, userPassword) {
717
+ const wallet = await this.get({ id: walletId });
718
+ if (!wallet?._wallet?.enterprise) {
719
+ throw new Error('Enterprise not found for the wallet');
720
+ }
721
+ const enterpriseUsersResponse = await this.bitgo
722
+ .get(this.bitgo.url(`/enterprise/${wallet?._wallet?.enterprise}/user`))
723
+ .result();
724
+ // create a map of users for easy lookup - we need the user email id to share the wallet
725
+ const usersMap = new Map([...enterpriseUsersResponse?.adminUsers, ...enterpriseUsersResponse?.nonAdminUsers].map((obj) => [obj.id, obj]));
726
+ if (wallet._wallet.users) {
727
+ for (const user of wallet._wallet.users) {
728
+ const userObject = usersMap.get(user.user);
729
+ if (user.permissions.includes('spend') && !user.permissions.includes('admin') && userObject) {
730
+ const shareParams = {
731
+ walletId: walletId,
732
+ user: user.user,
733
+ permissions: user.permissions.join(','),
734
+ walletPassphrase: userPassword,
735
+ email: userObject.email.email,
736
+ reshare: true,
737
+ skipKeychain: false,
738
+ };
739
+ await wallet.shareWallet(shareParams);
740
+ }
741
+ }
742
+ }
743
+ }
447
744
  /**
448
745
  * Accepts a wallet share, adding the wallet to the user's list
449
746
  * Needs a user's password to decrypt the shared key
@@ -459,7 +756,47 @@ class Wallets {
459
756
  async acceptShare(params = {}) {
460
757
  common.validateParams(params, ['walletShareId'], ['overrideEncryptedPrv', 'userPassword', 'newWalletPassphrase']);
461
758
  let encryptedPrv = params.overrideEncryptedPrv;
462
- const walletShare = (await this.getShare({ walletShareId: params.walletShareId }));
759
+ const walletShare = await this.getShare({ walletShareId: params.walletShareId });
760
+ if (walletShare.keychainOverrideRequired &&
761
+ walletShare.permissions.indexOf('admin') !== -1 &&
762
+ walletShare.permissions.indexOf('spend') !== -1) {
763
+ if (_.isUndefined(params.userPassword)) {
764
+ throw new Error('userPassword param must be provided to decrypt shared key');
765
+ }
766
+ const walletKeychain = await this.baseCoin.keychains().createUserKeychain(params.userPassword);
767
+ if (_.isUndefined(walletKeychain.encryptedPrv)) {
768
+ throw new Error('encryptedPrv was not found on wallet keychain');
769
+ }
770
+ const payload = {
771
+ tradingAccountId: walletShare.wallet,
772
+ pubkey: walletKeychain.pub,
773
+ timestamp: new Date().toISOString(),
774
+ };
775
+ const payloadString = JSON.stringify(payload);
776
+ const privateKey = this.bitgo.decrypt({
777
+ password: params.userPassword,
778
+ input: walletKeychain.encryptedPrv,
779
+ });
780
+ const signature = await this.baseCoin.signMessage({ prv: privateKey }, payloadString);
781
+ const response = await this.updateShare({
782
+ walletShareId: params.walletShareId,
783
+ state: 'accepted',
784
+ keyId: walletKeychain.id,
785
+ signature: signature.toString('hex'),
786
+ payload: payloadString,
787
+ });
788
+ // If the wallet share was accepted successfully (changed=true), reshare the wallet with the spenders
789
+ if (response.changed && response.state === 'accepted') {
790
+ try {
791
+ await this.reshareWalletWithSpenders(walletShare.wallet, params.userPassword);
792
+ }
793
+ catch (e) {
794
+ // TODO: PX-3826
795
+ // Do nothing
796
+ }
797
+ }
798
+ return response;
799
+ }
463
800
  // Return right away if there is no keychain to decrypt, or if explicit encryptedPrv was provided
464
801
  if (!walletShare.keychain || !walletShare.keychain.encryptedPrv || encryptedPrv) {
465
802
  return this.updateShare({
@@ -480,9 +817,9 @@ class Wallets {
480
817
  password: params.userPassword,
481
818
  input: sharingKeychain.encryptedXprv,
482
819
  });
483
- const secret = ecdh_1.getSharedSecret(
820
+ const secret = (0, ecdh_1.getSharedSecret)(
484
821
  // Derive key by path (which is used between these 2 users only)
485
- utxo_lib_1.bip32.fromBase58(sharingKeychain.prv).derivePath(api_1.sanitizeLegacyPath(walletShare.keychain.path)), Buffer.from(walletShare.keychain.fromPubKey, 'hex')).toString('hex');
822
+ utxo_lib_1.bip32.fromBase58(sharingKeychain.prv).derivePath((0, api_1.sanitizeLegacyPath)(walletShare.keychain.path)), Buffer.from(walletShare.keychain.fromPubKey, 'hex')).toString('hex');
486
823
  // Yes! We got the secret successfully here, now decrypt the shared wallet prv
487
824
  const decryptedSharedWalletPrv = this.bitgo.decrypt({
488
825
  password: secret,
@@ -503,6 +840,286 @@ class Wallets {
503
840
  }
504
841
  return this.updateShare(updateParams);
505
842
  }
843
+ /**
844
+ * Bulk Accept wallet shares, adding the wallets to the user's list
845
+ * Needs a user's password to decrypt the shared key
846
+ *
847
+ * @param params BulkAcceptShareOptions
848
+ * @param params.walletShareId - array of the wallet shares to accept
849
+ * @param params.userPassword - user's password to decrypt the shared wallet key
850
+ * @param params.newWalletPassphrase - new wallet passphrase for saving the shared wallet prv.
851
+ * If left blank then the user's login password is used.
852
+ *
853
+ *@returns {Promise<BulkAcceptShareResponse>}
854
+ */
855
+ async bulkAcceptShare(params) {
856
+ try {
857
+ common.validateParams(params, ['userLoginPassword'], ['newWalletPassphrase']);
858
+ }
859
+ catch (e) {
860
+ if ('newWalletPassphrase' in params) {
861
+ throw new Error('Please provide a valid wallet passphrase');
862
+ }
863
+ throw new Error('Please provide a valid user login password');
864
+ }
865
+ (0, assert_1.default)(params.walletShareIds.length > 0, 'Please provide at least one wallet share to accept');
866
+ const allWalletShares = await this.listSharesV2();
867
+ const walletShareMap = allWalletShares.incoming.reduce((map, share) => ({ ...map, [share.id]: share }), {});
868
+ const walletShares = params.walletShareIds
869
+ .map((walletShareId) => walletShareMap[walletShareId])
870
+ .filter((walletShare) => walletShare && walletShare.keychain);
871
+ if (!walletShares.length) {
872
+ throw new Error('No valid wallet shares found to accept');
873
+ }
874
+ const sharingKeychain = await this.bitgo.getECDHKeychain();
875
+ if (_.isUndefined(sharingKeychain.encryptedXprv)) {
876
+ throw new Error('encryptedXprv was not found on sharing keychain');
877
+ }
878
+ sharingKeychain.prv = this.bitgo.decrypt({
879
+ password: params.userLoginPassword,
880
+ input: sharingKeychain.encryptedXprv,
881
+ });
882
+ const newWalletPassphrase = params.newWalletPassphrase || params.userLoginPassword;
883
+ const keysForWalletShares = walletShares.flatMap((walletShare) => {
884
+ if (!walletShare.keychain) {
885
+ return [];
886
+ }
887
+ const secret = (0, ecdh_1.getSharedSecret)(utxo_lib_1.bip32.fromBase58(sharingKeychain.prv).derivePath((0, api_1.sanitizeLegacyPath)(walletShare.keychain.path)), Buffer.from(walletShare.keychain.fromPubKey, 'hex')).toString('hex');
888
+ const decryptedSharedWalletPrv = this.bitgo.decrypt({
889
+ password: secret,
890
+ input: walletShare.keychain.encryptedPrv,
891
+ });
892
+ const newEncryptedPrv = this.bitgo.encrypt({
893
+ password: newWalletPassphrase,
894
+ input: decryptedSharedWalletPrv,
895
+ });
896
+ return [
897
+ {
898
+ walletShareId: walletShare.id,
899
+ encryptedPrv: newEncryptedPrv,
900
+ },
901
+ ];
902
+ });
903
+ return this.bulkAcceptShareRequest(keysForWalletShares);
904
+ }
905
+ /**
906
+ * Updates multiple wallet shares in bulk
907
+ * This method allows users to accept or reject multiple wallet shares in a single operation.
908
+ * It handles different types of wallet shares including those requiring special keychain overrides
909
+ * and those with encrypted private keys that need to be decrypted and re-encrypted.
910
+ * After processing, it also reshares accepted wallets with spenders for special override cases.
911
+ *
912
+ * @param params - Options for bulk updating wallet shares
913
+ * @param params.shares - Array of wallet shares to update with their status (accept/reject)
914
+ * @param params.userLoginPassword - User's login password for decryption operations
915
+ * @param params.newWalletPassphrase - New wallet passphrase for re-encryption
916
+ * @returns Array of responses for each wallet share update
917
+ */
918
+ async bulkUpdateWalletShare(params) {
919
+ if (!params.shares) {
920
+ throw new Error('Missing parameter: shares');
921
+ }
922
+ if (!Array.isArray(params.shares)) {
923
+ throw new Error('Expecting parameter array: shares but found ' + typeof params.shares);
924
+ }
925
+ // Validate each share in the array
926
+ for (const share of params.shares) {
927
+ if (!share.walletShareId) {
928
+ throw new Error('Missing walletShareId in share');
929
+ }
930
+ if (!share.status) {
931
+ throw new Error('Missing status in share');
932
+ }
933
+ if (share.status !== 'accept' && share.status !== 'reject') {
934
+ throw new Error('Invalid status in share: ' + share.status + '. Must be either "accept" or "reject"');
935
+ }
936
+ if (typeof share.walletShareId !== 'string') {
937
+ throw new Error('Expecting walletShareId to be a string but found ' + typeof share.walletShareId);
938
+ }
939
+ }
940
+ // Validate optional parameters if provided
941
+ if (params.userLoginPassword !== undefined && typeof params.userLoginPassword !== 'string') {
942
+ throw new Error('Expecting parameter string: userLoginPassword but found ' + typeof params.userLoginPassword);
943
+ }
944
+ if (params.newWalletPassphrase !== undefined && typeof params.newWalletPassphrase !== 'string') {
945
+ throw new Error('Expecting parameter string: newWalletPassphrase but found ' + typeof params.newWalletPassphrase);
946
+ }
947
+ (0, assert_1.default)(params.shares.length > 0, 'no shares are passed');
948
+ const { shares: inputShares, userLoginPassword, newWalletPassphrase } = params;
949
+ const allWalletShares = await this.listSharesV2();
950
+ // Only include shares that are in the input array for efficiency
951
+ const shareIds = new Set(inputShares.map((share) => share.walletShareId));
952
+ const walletShareMap = new Map();
953
+ allWalletShares.incoming
954
+ .filter((share) => shareIds.has(share.id))
955
+ .forEach((share) => walletShareMap.set(share.id, share));
956
+ allWalletShares.outgoing
957
+ .filter((share) => shareIds.has(share.id))
958
+ .forEach((share) => walletShareMap.set(share.id, share));
959
+ const resolvedShares = inputShares.map((share) => {
960
+ const walletShare = walletShareMap.get(share.walletShareId);
961
+ if (!walletShare) {
962
+ throw new Error(`invalid wallet share provided: ${share.walletShareId}`);
963
+ }
964
+ return { ...share, walletShare };
965
+ });
966
+ // Identify special override cases that need resharing after acceptance
967
+ const specialOverrideCases = new Map();
968
+ resolvedShares.forEach((share) => {
969
+ if (share.status === 'accept' &&
970
+ share.walletShare.keychainOverrideRequired &&
971
+ share.walletShare.permissions.includes('admin') &&
972
+ share.walletShare.permissions.includes('spend')) {
973
+ specialOverrideCases.set(share.walletShareId, share.walletShare.wallet);
974
+ }
975
+ });
976
+ // Decrypt sharing keychain if needed (only once)
977
+ let sharingKeychainPrv;
978
+ // Only decrypt if there are shares to accept that might need it
979
+ const hasSharesRequiringDecryption = specialOverrideCases.size > 0 ||
980
+ resolvedShares.some((share) => share.status === 'accept' && share.walletShare.keychain?.encryptedPrv);
981
+ if (userLoginPassword && hasSharesRequiringDecryption) {
982
+ const sharingKeychain = await this.bitgo.getECDHKeychain();
983
+ if (!sharingKeychain.encryptedXprv) {
984
+ throw new Error('encryptedXprv was not found on sharing keychain');
985
+ }
986
+ sharingKeychainPrv = this.bitgo.decrypt({
987
+ password: userLoginPassword,
988
+ input: sharingKeychain.encryptedXprv,
989
+ });
990
+ }
991
+ const settledUpdates = await Promise.allSettled(resolvedShares.map(async (share) => {
992
+ const { walletShareId, status, walletShare } = share;
993
+ // Handle accept case
994
+ if (status === 'accept') {
995
+ return this.processAcceptShare(walletShareId, walletShare, userLoginPassword, newWalletPassphrase, sharingKeychainPrv);
996
+ }
997
+ // Handle reject case
998
+ return [
999
+ {
1000
+ walletShareId,
1001
+ status: 'reject',
1002
+ },
1003
+ ];
1004
+ }));
1005
+ // Extract successful updates
1006
+ const successfulUpdates = settledUpdates.flatMap((result) => (result.status === 'fulfilled' ? result.value : []));
1007
+ // Extract failed updates - only from rejected promises
1008
+ const failedUpdates = settledUpdates.reduce((acc, result, index) => {
1009
+ if (result.status === 'rejected') {
1010
+ const rejectedResult = result;
1011
+ acc.push({
1012
+ walletShareId: resolvedShares[index].walletShareId,
1013
+ reason: rejectedResult.reason?.message || String(rejectedResult.reason),
1014
+ });
1015
+ }
1016
+ return acc;
1017
+ }, []);
1018
+ // Send successful updates to the server
1019
+ const response = await this.bulkUpdateWalletShareRequest(successfulUpdates);
1020
+ // Process accepted special override cases - reshare with spenders
1021
+ if (response.acceptedWalletShares && response.acceptedWalletShares.length > 0 && userLoginPassword) {
1022
+ // For each accepted wallet share that is a special override case, reshare with spenders
1023
+ for (const walletShareId of response.acceptedWalletShares) {
1024
+ if (specialOverrideCases.has(walletShareId)) {
1025
+ const walletId = specialOverrideCases.get(walletShareId);
1026
+ try {
1027
+ await this.reshareWalletWithSpenders(walletId, userLoginPassword);
1028
+ }
1029
+ catch (e) {
1030
+ // Log error but continue processing other shares
1031
+ console.error(`Error resharing wallet ${walletId} with spenders: ${e?.message}`);
1032
+ }
1033
+ }
1034
+ }
1035
+ }
1036
+ // Add information about failed updates to the response
1037
+ if (failedUpdates.length > 0) {
1038
+ response.walletShareUpdateErrors.push(...failedUpdates);
1039
+ }
1040
+ return response;
1041
+ }
1042
+ /**
1043
+ * Process a wallet share that is being accepted
1044
+ * This method handles the different cases for accepting a wallet share:
1045
+ * 1. Special override case requiring user keychain and signing
1046
+ * 2. Simple case with no keychain to decrypt
1047
+ * 3. Standard case requiring decryption and re-encryption
1048
+ *
1049
+ * @param walletShareId - ID of the wallet share
1050
+ * @param walletShare - Wallet share object
1051
+ * @param userLoginPassword - User's login password
1052
+ * @param newWalletPassphrase - New wallet passphrase
1053
+ * @param sharingKeychainPrv - Decrypted sharing keychain private key
1054
+ * @returns Array of wallet share update requests
1055
+ */
1056
+ async processAcceptShare(walletShareId, walletShare, userLoginPassword, newWalletPassphrase, sharingKeychainPrv) {
1057
+ // Special override case: requires user keychain and signing
1058
+ if (walletShare.keychainOverrideRequired &&
1059
+ walletShare.permissions.includes('admin') &&
1060
+ walletShare.permissions.includes('spend')) {
1061
+ if (!userLoginPassword) {
1062
+ throw new Error('userLoginPassword param must be provided to decrypt shared key');
1063
+ }
1064
+ const walletKeychain = await this.baseCoin.keychains().createUserKeychain(userLoginPassword);
1065
+ if (!walletKeychain.encryptedPrv) {
1066
+ throw new Error('encryptedPrv was not found on wallet keychain');
1067
+ }
1068
+ const payload = JSON.stringify({
1069
+ tradingAccountId: walletShare.wallet,
1070
+ pubkey: walletKeychain.pub,
1071
+ timestamp: new Date().toISOString(),
1072
+ });
1073
+ const prv = this.bitgo.decrypt({
1074
+ password: userLoginPassword,
1075
+ input: walletKeychain.encryptedPrv,
1076
+ });
1077
+ const signature = await this.baseCoin.signMessage({ prv }, payload);
1078
+ return [
1079
+ {
1080
+ walletShareId,
1081
+ status: 'accept',
1082
+ keyId: walletKeychain.id,
1083
+ signature: signature.toString('hex'),
1084
+ payload,
1085
+ },
1086
+ ];
1087
+ }
1088
+ // Return right away if there is no keychain to decrypt
1089
+ if (!walletShare.keychain || !walletShare.keychain.encryptedPrv) {
1090
+ return [
1091
+ {
1092
+ walletShareId,
1093
+ status: 'accept',
1094
+ },
1095
+ ];
1096
+ }
1097
+ // More than viewing was requested, so we need to process the wallet keys using the shared ecdh scheme
1098
+ if (!userLoginPassword) {
1099
+ throw new Error('userLoginPassword param must be provided to decrypt shared key');
1100
+ }
1101
+ if (!sharingKeychainPrv) {
1102
+ throw new Error('failed to retrieve and decrypt sharing keychain');
1103
+ }
1104
+ const derivedKey = utxo_lib_1.bip32.fromBase58(sharingKeychainPrv).derivePath((0, api_1.sanitizeLegacyPath)(walletShare.keychain.path));
1105
+ const sharedSecret = (0, ecdh_1.getSharedSecret)(derivedKey, Buffer.from(walletShare.keychain.fromPubKey, 'hex')).toString('hex');
1106
+ const decryptedPrv = this.bitgo.decrypt({
1107
+ password: sharedSecret,
1108
+ input: walletShare.keychain.encryptedPrv,
1109
+ });
1110
+ // We will now re-encrypt the wallet with our own password
1111
+ const encryptedPrv = this.bitgo.encrypt({
1112
+ password: newWalletPassphrase || userLoginPassword,
1113
+ input: decryptedPrv,
1114
+ });
1115
+ return [
1116
+ {
1117
+ walletShareId,
1118
+ status: 'accept',
1119
+ encryptedPrv,
1120
+ },
1121
+ ];
1122
+ }
506
1123
  /**
507
1124
  * Get a wallet by its ID
508
1125
  * @param params
@@ -518,6 +1135,9 @@ class Wallets {
518
1135
  }
519
1136
  query.allTokens = params.allTokens;
520
1137
  }
1138
+ if (params.includeBalance !== undefined) {
1139
+ query.includeBalance = params.includeBalance;
1140
+ }
521
1141
  this.bitgo.setRequestTracer(params.reqId || new utils_1.RequestTracer());
522
1142
  const wallet = await this.bitgo
523
1143
  .get(this.baseCoin.url('/wallet/' + params.id))
@@ -551,43 +1171,162 @@ class Wallets {
551
1171
  * @param params
552
1172
  * @private
553
1173
  */
554
- async generateMpcWallet(params) {
1174
+ async generateMpcWallet({ passphrase, label, multisigType, enterprise, walletVersion, originalPasscodeEncryptionCode, }) {
1175
+ if (multisigType === 'tss' && this.baseCoin.getMPCAlgorithm() === 'ecdsa') {
1176
+ const tssSettings = await this.bitgo
1177
+ .get(this.bitgo.microservicesUrl('/api/v2/tss/settings'))
1178
+ .result();
1179
+ const multisigTypeVersion = tssSettings.coinSettings[this.baseCoin.getFamily()]?.walletCreationSettings?.multiSigTypeVersion;
1180
+ walletVersion = this.determineEcdsaMpcWalletVersion(walletVersion, multisigTypeVersion);
1181
+ }
555
1182
  const reqId = new utils_1.RequestTracer();
556
1183
  this.bitgo.setRequestTracer(reqId);
1184
+ // Create MPC Keychains
1185
+ const keychains = await this.baseCoin.keychains().createMpc({
1186
+ multisigType,
1187
+ passphrase,
1188
+ enterprise,
1189
+ originalPasscodeEncryptionCode,
1190
+ });
1191
+ // Create Wallet
1192
+ const { userKeychain, backupKeychain, bitgoKeychain } = keychains;
557
1193
  const walletParams = {
558
- label: params.label,
1194
+ label,
559
1195
  m: 2,
560
1196
  n: 3,
561
- keys: [],
562
- isCold: false,
563
- multisigType: params.multisigType,
564
- enterprise: params.enterprise,
565
- walletVersion: params.walletVersion,
1197
+ keys: [userKeychain.id, backupKeychain.id, bitgoKeychain.id],
1198
+ type: 'hot',
1199
+ multisigType,
1200
+ enterprise,
1201
+ walletVersion,
1202
+ };
1203
+ const finalWalletParams = await this.baseCoin.supplementGenerateWallet(walletParams, keychains);
1204
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(finalWalletParams).result();
1205
+ const result = {
1206
+ wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
1207
+ userKeychain,
1208
+ backupKeychain,
1209
+ bitgoKeychain,
1210
+ responseType: 'WalletWithKeychains',
566
1211
  };
1212
+ if (!_.isUndefined(backupKeychain.prv)) {
1213
+ result.warning = 'Be sure to backup the backup keychain -- it is not stored anywhere else!';
1214
+ }
1215
+ return result;
1216
+ }
1217
+ /**
1218
+ * Generates a Self-Managed Cold TSS Wallet.
1219
+ * @param params
1220
+ * @private
1221
+ */
1222
+ async generateSMCMpcWallet({ label, multisigType, enterprise, walletVersion, bitgoKeyId, commonKeychain, coldDerivationSeed, }) {
1223
+ const reqId = new utils_1.RequestTracer();
1224
+ this.bitgo.setRequestTracer(reqId);
1225
+ let multisigTypeVersion;
1226
+ if (multisigType === 'tss' && this.baseCoin.getMPCAlgorithm() === 'ecdsa') {
1227
+ const tssSettings = await this.bitgo
1228
+ .get(this.bitgo.microservicesUrl('/api/v2/tss/settings'))
1229
+ .result();
1230
+ multisigTypeVersion =
1231
+ tssSettings.coinSettings[this.baseCoin.getFamily()]?.walletCreationSettings?.coldMultiSigTypeVersion;
1232
+ walletVersion = this.determineEcdsaMpcWalletVersion(walletVersion, multisigTypeVersion);
1233
+ }
567
1234
  // Create MPC Keychains
568
- const keychains = await this.baseCoin.keychains().createMpc({
569
- multisigType: params.multisigType,
570
- passphrase: params.passphrase,
571
- enterprise: params.enterprise,
572
- originalPasscodeEncryptionCode: params.originalPasscodeEncryptionCode,
573
- backupProvider: params.backupProvider,
574
- });
575
- const { userKeychain, backupKeychain, bitgoKeychain } = keychains;
576
- walletParams.keys = [userKeychain.id, backupKeychain.id, bitgoKeychain.id];
1235
+ const bitgoKeychain = await this.baseCoin.keychains().get({ id: bitgoKeyId });
1236
+ if (!bitgoKeychain || !bitgoKeychain.commonKeychain) {
1237
+ throw new Error('BitGo keychain not found');
1238
+ }
1239
+ if (bitgoKeychain.source !== 'bitgo') {
1240
+ throw new Error('The provided bitgoKeyId is not a BitGo keychain');
1241
+ }
1242
+ if (bitgoKeychain.commonKeychain !== commonKeychain) {
1243
+ throw new Error('The provided Common keychain mismatch with the provided Bitgo key');
1244
+ }
1245
+ if (!coldDerivationSeed) {
1246
+ throw new Error('derivedFromParentWithSeed is required');
1247
+ }
1248
+ const userKeychainParams = {
1249
+ source: 'user',
1250
+ keyType: 'tss',
1251
+ commonKeychain: commonKeychain,
1252
+ derivedFromParentWithSeed: coldDerivationSeed,
1253
+ isMPCv2: multisigTypeVersion === 'MPCv2' ? true : undefined,
1254
+ };
1255
+ const userKeychain = await this.baseCoin.keychains().add(userKeychainParams);
1256
+ const backupKeyChainParams = {
1257
+ source: 'backup',
1258
+ keyType: 'tss',
1259
+ commonKeychain: commonKeychain,
1260
+ derivedFromParentWithSeed: coldDerivationSeed,
1261
+ isMPCv2: multisigTypeVersion === 'MPCv2' ? true : undefined,
1262
+ };
1263
+ const backupKeychain = await this.baseCoin.keychains().add(backupKeyChainParams);
577
1264
  // Create Wallet
1265
+ const keychains = { userKeychain, backupKeychain, bitgoKeychain };
1266
+ const walletParams = {
1267
+ label,
1268
+ m: 2,
1269
+ n: 3,
1270
+ keys: [userKeychain.id, backupKeychain.id, bitgoKeychain.id],
1271
+ type: 'cold',
1272
+ multisigType,
1273
+ enterprise,
1274
+ walletVersion,
1275
+ };
578
1276
  const finalWalletParams = await this.baseCoin.supplementGenerateWallet(walletParams, keychains);
579
- const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet')).send(finalWalletParams).result();
1277
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(finalWalletParams).result();
580
1278
  const result = {
581
1279
  wallet: new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet),
582
1280
  userKeychain,
583
1281
  backupKeychain,
584
1282
  bitgoKeychain,
1283
+ responseType: 'WalletWithKeychains',
585
1284
  };
586
- if (!_.isUndefined(backupKeychain.prv) && !_.isUndefined(params.backupProvider)) {
587
- result.warning = 'Be sure to backup the backup keychain -- it is not stored anywhere else!';
1285
+ return result;
1286
+ }
1287
+ /**
1288
+ * Generates a Custodial TSS Wallet.
1289
+ * @param params
1290
+ * @private
1291
+ */
1292
+ async generateCustodialMpcWallet({ label, multisigType, enterprise, walletVersion, }) {
1293
+ const reqId = new utils_1.RequestTracer();
1294
+ this.bitgo.setRequestTracer(reqId);
1295
+ if (multisigType === 'tss' && this.baseCoin.getMPCAlgorithm() === 'ecdsa') {
1296
+ const tssSettings = await this.bitgo
1297
+ .get(this.bitgo.microservicesUrl('/api/v2/tss/settings'))
1298
+ .result();
1299
+ const multisigTypeVersion = tssSettings.coinSettings[this.baseCoin.getFamily()]?.walletCreationSettings?.custodialMultiSigTypeVersion;
1300
+ walletVersion = this.determineEcdsaMpcWalletVersion(walletVersion, multisigTypeVersion);
588
1301
  }
1302
+ const finalWalletParams = {
1303
+ label,
1304
+ multisigType,
1305
+ enterprise,
1306
+ walletVersion,
1307
+ type: 'custodial',
1308
+ };
1309
+ // Create Wallet
1310
+ const newWallet = await this.bitgo.post(this.baseCoin.url('/wallet/add')).send(finalWalletParams).result();
1311
+ const wallet = new wallet_1.Wallet(this.bitgo, this.baseCoin, newWallet);
1312
+ const keychains = wallet.keyIds();
1313
+ const result = {
1314
+ wallet,
1315
+ userKeychain: { id: keychains[0], type: multisigType, source: 'user' },
1316
+ backupKeychain: { id: keychains[1], type: multisigType, source: 'backup' },
1317
+ bitgoKeychain: { id: keychains[2], type: multisigType, source: 'bitgo' },
1318
+ responseType: 'WalletWithKeychains',
1319
+ };
589
1320
  return result;
590
1321
  }
1322
+ determineEcdsaMpcWalletVersion(walletVersion, multisigTypeVersion) {
1323
+ if (this.baseCoin.isEVM() && multisigTypeVersion === 'MPCv2') {
1324
+ if (!walletVersion || (walletVersion !== 5 && walletVersion !== 6)) {
1325
+ return 5;
1326
+ }
1327
+ }
1328
+ return walletVersion;
1329
+ }
591
1330
  }
592
1331
  exports.Wallets = Wallets;
593
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9iaXRnby93YWxsZXQvd2FsbGV0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCxvREFBNEI7QUFDNUIsK0NBQXlDO0FBQ3pDLG1EQUE2QztBQUM3QywwQ0FBNEI7QUFDNUIsbUNBQStDO0FBQy9DLHFEQUF1QztBQUd2QyxrQ0FBMEM7QUFFMUMsb0NBQXVEO0FBYXZELHFDQUFrQztBQUVsQyxNQUFhLE9BQU87SUFJbEIsWUFBWSxLQUFnQixFQUFFLFFBQW1CO1FBQy9DLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQTJCLEVBQUU7UUFDckMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUE0QixFQUFFO1FBQ3ZDLE1BQU0sV0FBVyxHQUFzQixFQUFFLENBQUM7UUFFMUMsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1NBQ3hEO1FBRUQsSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFO1lBQ3RCLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO2FBQ3BFO1lBQ0QsV0FBVyxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO1NBQzlDO1FBQ0QsSUFBSSxNQUFNLENB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QUFhLEVBQUUsR0FBRyxTQUFTLENBQUM7UUFDbEUsWUFBWSxDQUFDLElBQUksR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFM0UsZ0JBQWdCO1FBQ2hCLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLHdCQUF3QixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNoRyxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFdkcsTUFBTSxNQUFNLEdBQXdCO1lBQ2xDLE1BQU0sRUFBRSxJQUFJLGVBQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDO1lBQ3hELFlBQVk7WUFDWixjQUFjO1lBQ2QsYUFBYTtTQUNkLENBQUM7UUFFRixJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUMvRSxNQUFNLENBQUMsT0FBTyxHQUFHLDBFQUEwRSxDQUFDO1NBQzdGO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztDQUNGO0FBdG9CRCwwQkFzb0JDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgQmlnTnVtYmVyIH0gZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IGJpcDMyIH0gZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgc2FuaXRpemVMZWdhY3lQYXRoIH0gZnJvbSAnLi4vLi4vYXBpJztcbmltcG9ydCAqIGFzIGNvbW1vbiBmcm9tICcuLi8uLi9jb21tb24nO1xuaW1wb3J0IHsgSUJhc2VDb2luLCBLZXljaGFpbnNUcmlwbGV0LCBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zIH0gZnJvbSAnLi4vYmFzZUNvaW4nO1xuaW1wb3J0IHsgQml0R29CYXNlIH0gZnJvbSAnLi4vYml0Z29CYXNlJztcbmltcG9ydCB7IGdldFNoYXJlZFNlY3JldCB9IGZyb20gJy4uL2VjZGgnO1xuaW1wb3J0IHsgS2V5Y2hhaW4gfSBmcm9tICcuLi9rZXljaGFpbic7XG5pbXBvcnQgeyBwcm9taXNlUHJvcHMsIFJlcXVlc3RUcmFjZXIgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQge1xuICBBY2NlcHRTaGFyZU9wdGlvbnMsXG4gIEFkZFdhbGxldE9wdGlvbnMsXG4gIEdlbmVyYXRlTXBjV2FsbGV0T3B0aW9ucyxcbiAgR2VuZXJhdGVXYWxsZXRPcHRpb25zLFxuICBHZXRXYWxsZXRCeUFkZHJlc3NPcHRpb25zLFxuICBHZXRXYWxsZXRPcHRpb25zLFxuICBJV2FsbGV0cyxcbiAgTGlzdFdhbGxldE9wdGlvbnMsXG4gIFVwZGF0ZVNoYXJlT3B0aW9ucyxcbiAgV2FsbGV0V2l0aEtleWNoYWlucyxcbn0gZnJvbSAnLi9pV2FsbGV0cyc7XG5pbXBvcnQgeyBXYWxsZXQgfSBmcm9tICcuL3dhbGxldCc7XG5cbmV4cG9ydCBjbGFzcyBXYWxsZXRzIGltcGxlbWVudHMgSVdhbGxldHMge1xuICBwcml2YXRlIHJlYWRvbmx5IGJpdGdvOiBCaXRHb0Jhc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZUNvaW46IElCYXNlQ29pbjtcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBiYXNlQ29pbjogSUJhc2VDb2luKSB7XG4gICAgdGhpcy5iaXRnbyA9IGJpdGdvO1xuICAgIHRoaXMuYmFzZUNvaW4gPSBiYXNlQ29pbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSB3YWxsZXQgYnkgSUQgKHByb3h5IGZvciBnZXRXYWxsZXQpXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGdldChwYXJhbXM6IEdldFdhbGxldE9wdGlvbnMgPSB7fSk6IFByb21pc2U8V2FsbGV0PiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0V2FsbGV0KHBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBhIHVzZXIncyB3YWxsZXRzXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBsaXN0KHBhcmFtczogTGlzdFdhbGxldE9wdGlvbnMgPSB7fSk6IFByb21pc2U8eyB3YWxsZXRzOiBXYWxsZXRbXSB9PiB7XG4gICAgY29uc3QgcXVlcnlPYmplY3Q6IExpc3RXYWxsZXRPcHRpb25zID0ge307XG5cbiAgICBpZiAocGFyYW1zLnNraXAgJiYgcGFyYW1zLnByZXZJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3Qgc3BlY2lmeSBib3RoIHNraXAgYW5kIHByZXZJZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZ2V0YmFsYW5jZXMpIHtcbiAgICAgIGlmICghXy5pc0Jvb2xlYW4ocGFyYW1zLmdldGJhbGFuY2VzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZ2V0YmFsYW5jZXMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG4gICAgICB9XG4gICAgICBxdWVyeU9iamVjdC5nZXRiYWxhbmNlcyA9IHBhcmFtcy5nZXRiYWxhbmNlcztcbiAgICB9XG4gICAgaWYgKHBhcmFtcy5wcmV2SWQpIHtcbiAgICAgIGlmICghXy5pc1N0cmluZyhwYXJhbXMucHJldklkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcHJldklkIGFyZ3VtZW50LCBleHBlY3Rpbmcgc3RyaW5nJyk7XG4gICAgICB9XG4gICAgICBxdWVyeU9iamVjdC5wcmV2SWQgPSBwYXJhbXMucHJldklkO1xuICAgIH1cbiAgICBpZiAocGFyYW1zLmxpbWl0KSB7XG4gICAgICBpZiAoIV8uaXNOdW1iZXIocGFyYW1zLmxpbWl0KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgbGltaXQgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXInKTtcbiAgICAgIH1cbiAgICAgIHF1ZXJ5T2JqZWN0LmxpbWl0ID0gcGFyYW1zLmxpbWl0O1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuYWxsVG9rZW5zKSB7XG4gICAgICBpZiAoIV8uaXNCb29sZWFuKHBhcmFtcy5hbGxUb2tlbnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhbGxUb2tlbnMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG4gICAgICB9XG4gICAgICBxdWVyeU9iamVjdC5hbGxUb2tlbnMgPSBwYXJhbXMuYWxsVG9rZW5zO1xuICAgIH1cblxuICAgIGNvbnN0IGJvZHkgPSAoYXdhaXQgdGhpcy5iaXRnby5nZXQodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQnKSkucXVlcnkocXVlcnlPYmplY3QpLnJlc3VsdCgpKSBhcyBhbnk7XG4gICAgYm9keS53YWxsZXRzID0gYm9keS53YWxsZXRzLm1hcCgodykgPT4gbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCB3KSk7XG4gICAgcmV0dXJuIGJvZHk7XG4gIH1cblxuICAvKipcbiAgICogYWRkXG4gICAqIEFkZCBhIG5ldyB3YWxsZXQgKGFkdmFuY2VkIG1vZGUpLlxuICAgKiBUaGlzIGFsbG93cyB5b3UgdG8gbWFudWFsbHkgc3VibWl0IHRoZSBrZXlzLCB0eXBlLCBtIGFuZCBuIG9mIHRoZSB3YWxsZXRcbiAgICogUGFyYW1ldGVycyBpbmNsdWRlOlxuICAgKiAgICBcImxhYmVsXCI6IGxhYmVsIG9mIHRoZSB3YWxsZXQgdG8gYmUgc2hvd24gaW4gVUlcbiAgICogICAgXCJtXCI6IG51bWJlciBvZiBrZXlzIHJlcXVpcmVkIHRvIHVubG9jayB3YWxsZXQgKDIpXG4gICAqICAgIFwiblwiOiBudW1iZXIgb2Yga2V5cyBhdmFpbGFibGUgb24gdGhlIHdhbGxldCAoMylcbiAgICogICAgXCJrZXlzXCI6IGFycmF5IG9mIGtleWNoYWluIGlkc1xuICAgKi9cbiAgYXN5bmMgYWRkKHBhcmFtczogQWRkV2FsbGV0T3B0aW9ucyk6IFByb21pc2U8YW55PiB7XG4gICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgW10sIFsnbGFiZWwnLCAnZW50ZXJwcmlzZScsICd0eXBlJ10pO1xuXG4gICAgaWYgKHR5cGVvZiBwYXJhbXMubGFiZWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgc3RyaW5nIHBhcmFtZXRlciBsYWJlbCcpO1xuICAgIH1cblxuICAgIC8vIG5vIG5lZWQgdG8gcGFzcyBrZXlzIGZvciAoc2luZ2xlKSBjdXN0b2RpYWwgd2FsbGV0c1xuICAgIGlmIChwYXJhbXMudHlwZSAhPT0gJ2N1c3RvZGlhbCcpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcmFtcy5rZXlzKSA9PT0gZmFsc2UgfHwgIV8uaXNOdW1iZXIocGFyYW1zLm0pIHx8ICFfLmlzTnVtYmVyKHBhcmFtcy5uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQnKTtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBtb3JlIHR5cGVzIG9mIG11bHRpc2lnXG4gICAgICBpZiAoIXRoaXMuYmFzZUNvaW4uaXNWYWxpZE1vZk5TZXR1cChwYXJhbXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndW5zdXBwb3J0ZWQgbXVsdGktc2lnIHR5cGUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmdhc1ByaWNlICYmICFfLmlzTnVtYmVyKHBhcmFtcy5nYXNQcmljZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhcmd1bWVudCBmb3IgZ2FzUHJpY2UgLSBudW1iZXIgZXhwZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLndhbGxldFZlcnNpb24gJiYgIV8uaXNOdW1iZXIocGFyYW1zLndhbGxldFZlcnNpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIHdhbGxldFZlcnNpb24gLSBudW1iZXIgZXhwZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnRhZ3MgJiYgQXJyYXkuaXNBcnJheShwYXJhbXMudGFncykgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIHRhZ3MgLSBhcnJheSBleHBlY3RlZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY2xpZW50RmxhZ3MgJiYgQXJyYXkuaXNBcnJheShwYXJhbXMuY2xpZW50RmxhZ3MpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBjbGllbnRGbGFncyAtIGFycmF5IGV4cGVjdGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5pc0NvbGQgJiYgIV8uaXNCb29sZWFuKHBhcmFtcy5pc0NvbGQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ29sZCAtIGJvb2xlYW4gZXhwZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmlzQ3VzdG9kaWFsICYmICFfLmlzQm9vbGVhbihwYXJhbXMuaXNDdXN0b2RpYWwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ3VzdG9kaWFsIC0gYm9vbGVhbiBleHBlY3RlZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuYWRkcmVzcyAmJiAoIV8uaXNTdHJpbmcocGFyYW1zLmFkZHJlc3MpIHx8ICF0aGlzLmJhc2VDb2luLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5hZGRyZXNzKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhcmd1bWVudCBmb3IgYWRkcmVzcyAtIHZhbGlkIGFkZHJlc3Mgc3RyaW5nIGV4cGVjdGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbmV3V2FsbGV0ID0gYXdhaXQgdGhpcy5iaXRnby5wb3N0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0JykpLnNlbmQocGFyYW1zKS5yZXN1bHQoKTtcbiAgICByZXR1cm4ge1xuICAgICAgd2FsbGV0OiBuZXcgV2FsbGV0KHRoaXMuYml0Z28sIHRoaXMuYmFzZUNvaW4sIG5ld1dhbGxldCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIG5ldyB3YWxsZXRcbiAgICogMS4gQ3JlYXRlcyB0aGUgdXNlciBrZXljaGFpbiBsb2NhbGx5IG9uIHRoZSBjbGllbnQsIGFuZCBlbmNyeXB0cyBpdCB3aXRoIHRoZSBwcm92aWRlZCBwYXNzcGhyYXNlXG4gICAqIDIuIElmIG5vIHB1YiB3YXMgcHJvdmlkZWQsIGNyZWF0ZXMgdGhlIGJhY2t1cCBrZXljaGFpbiBsb2NhbGx5IG9uIHRoZSBjbGllbnQsIGFuZCBlbmNyeXB0cyBpdCB3aXRoIHRoZSBwcm92aWRlZCBwYXNzcGhyYXNlXG4gICAqIDMuIFVwbG9hZHMgdGhlIGVuY3J5cHRlZCB1c2VyIGFuZCBiYWNrdXAga2V5Y2hhaW5zIHRvIEJpdEdvXG4gICAqIDQuIENyZWF0ZXMgdGhlIEJpdEdvIGtleSBvbiB0aGUgc2VydmljZVxuICAgKiA1LiBDcmVhdGVzIHRoZSB3YWxsZXQgb24gQml0R28gd2l0aCB0aGUgMyBwdWJsaWMga2V5cyBhYm92ZVxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMubGFiZWxcbiAgICogQHBhcmFtIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAqIEBwYXJhbSBwYXJhbXMudXNlcktleSBVc2VyIHhwdWJcbiAgICogQHBhcmFtIHBhcmFtcy5iYWNrdXBYcHViIEJhY2t1cCB4cHViXG4gICAqIEBwYXJhbSBwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyXG4gICAqIEBwYXJhbSBwYXJhbXMuYmFja3VwUHJvdmlkZXIgVGhpcmQgcGFydHkgYmFja3VwIHByb3ZpZGVyIGZvciBUU1NcbiAgICogQHBhcmFtIHBhcmFtcy5lbnRlcnByaXNlXG4gICAqIEBwYXJhbSBwYXJhbXMuZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9uc1xuICAgKiBAcGFyYW0gcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGVcbiAgICogQHBhcmFtIHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWRcbiAgICogQHBhcmFtIHBhcmFtcy5nYXNQcmljZVxuICAgKiBAcGFyYW0gcGFyYW1zLmRpc2FibGVLUlNFbWFpbFxuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldFZlcnNpb25cbiAgICogQHBhcmFtIHBhcmFtcy5tdWx0aXNpZ1R5cGUgb3B0aW9uYWwgbXVsdGlzaWcgdHlwZSwgJ29uY2hhaW4nIG9yICd0c3MnIG9yICdibHNka2cnOyBpZiBhYnNlbnQsIHdlIHdpbGwgZGVmZXIgdG8gdGhlIGNvaW4ncyBkZWZhdWx0IHR5cGVcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZVdhbGxldChwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxXYWxsZXRXaXRoS2V5Y2hhaW5zPiB7XG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWydsYWJlbCddLCBbJ3Bhc3NwaHJhc2UnLCAndXNlcktleScsICdiYWNrdXBYcHViJ10pO1xuICAgIGlmICh0eXBlb2YgcGFyYW1zLmxhYmVsICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHN0cmluZyBwYXJhbWV0ZXIgbGFiZWwnKTtcbiAgICB9XG5cbiAgICBjb25zdCBpc1RzcyA9IHBhcmFtcy5tdWx0aXNpZ1R5cGUgPT09ICd0c3MnICYmIHRoaXMuYmFzZUNvaW4uc3VwcG9ydHNUc3MoKTtcbiAgICBjb25zdCBsYWJlbCA9IHBhcmFtcy5sYWJlbDtcbiAgICBjb25zdCBwYXNzcGhyYXNlID0gcGFyYW1zLnBhc3NwaHJhc2U7XG4gICAgY29uc3QgY2FuRW5jcnlwdCA9ICEhcGFzc3BocmFzZSAmJiB0eXBlb2YgcGFzc3BocmFzZSA9PT0gJ3N0cmluZyc7XG4gICAgY29uc3QgaXNDb2xkID0gISFwYXJhbXMudXNlcktleSAmJiBwYXJhbXMubXVsdGlzaWdUeXBlICE9PSAnb25jaGFpbic7XG4gICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgbGFiZWw6IGxhYmVsLFxuICAgICAgbTogMixcbiAgICAgIG46IDMsXG4gICAgICBrZXlzOiBbXSxcbiAgICAgIGlzQ29sZCxcbiAgICB9O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlKSkge1xuICAgICAgaWYgKCFfLmlzU3RyaW5nKHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Bhc3Njb2RlRW5jcnlwdGlvbkNvZGUgbXVzdCBiZSBhIHN0cmluZycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMuZW50ZXJwcmlzZSkpIHtcbiAgICAgIGlmICghXy5pc1N0cmluZyhwYXJhbXMuZW50ZXJwcmlzZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGVudGVycHJpc2UgYXJndW1lbnQsIGV4cGVjdGluZyBzdHJpbmcnKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5lbnRlcnByaXNlID0gcGFyYW1zLmVudGVycHJpc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGVudGVycHJpc2Ugbm90IGRlZmluZWRcbiAgICAgIGlmIChwYXJhbXMubXVsdGlzaWdUeXBlID09PSAndHNzJyAmJiBwYXJhbXMuYmFja3VwUHJvdmlkZXIgPT09ICdCaXRHb1RydXN0QXNLcnMnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGVudGVycHJpc2UgaWQgaXMgcmVxdWlyZWQgd2hlbiBjcmVhdGluZyBUU1Mgd2FsbGV0IHdpdGggQml0R28gVHJ1c3QgYXMgS1JTLicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEVWTSBUU1Mgd2FsbGV0cyBtdXN0IHVzZSB3YWxsZXQgdmVyc2lvbiAzXG4gICAgaWYgKChpc1RzcyAmJiB0aGlzLmJhc2VDb2luLmlzRVZNKCkpICE9PSAocGFyYW1zLndhbGxldFZlcnNpb24gPT09IDMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VWTSBUU1Mgd2FsbGV0cyBhcmUgb25seSBzdXBwb3J0ZWQgZm9yIHdhbGxldCB2ZXJzaW9uIDMnKTtcbiAgICB9XG5cbiAgICBpZiAoaXNUc3MpIHtcbiAgICAgIGlmIChpc0NvbGQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUU1MgY29sZCB3YWxsZXRzIGFyZSBub3Qgc3VwcG9ydGVkIGF0IHRoaXMgdGltZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuYmFzZUNvaW4uc3VwcG9ydHNUc3MoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNvaW4gJHt0aGlzLmJhc2VDb2luLmdldEZhbWlseSgpfSBkb2VzIG5vdCBzdXBwb3J0IFRTUyBhdCB0aGlzIHRpbWVgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVNcGNXYWxsZXQoe1xuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBsYWJlbCxcbiAgICAgICAgcGFzc3BocmFzZSxcbiAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgICAgZW50ZXJwcmlzZTogcGFyYW1zLmVudGVycHJpc2UsXG4gICAgICAgIHdhbGxldFZlcnNpb246IHBhcmFtcy53YWxsZXRWZXJzaW9uLFxuICAgICAgICBiYWNrdXBQcm92aWRlcjogcGFyYW1zLmJhY2t1cFByb3ZpZGVyLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgaXNCbHNEa2cgPSBwYXJhbXMubXVsdGlzaWdUeXBlID8gcGFyYW1zLm11bHRpc2lnVHlwZSA9PT0gJ2Jsc2RrZycgOiB0aGlzLmJhc2VDb2luLnN1cHBvcnRzQmxzRGtnKCk7XG4gICAgaWYgKGlzQmxzRGtnKSB7XG4gICAgICBpZiAoIWNhbkVuY3J5cHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYW5ub3QgZ2VuZXJhdGUgQkxTLURLRyBrZXlzIHdpdGhvdXQgcGFzc3BocmFzZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNDb2xkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQkxTLURLRyBjb2xkIHdhbGxldHMgYXJlIG5vdCBzdXBwb3J0ZWQgYXQgdGhpcyB0aW1lJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5iYXNlQ29pbi5zdXBwb3J0c0Jsc0RrZygpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY29pbiAke3RoaXMuYmFzZUNvaW4uZ2V0RmFtaWx5KCl9IGRvZXMgbm90IHN1cHBvcnQgQkxTLURLRyBhdCB0aGlzIHRpbWVgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVNcGNXYWxsZXQoeyBtdWx0aXNpZ1R5cGU6ICdibHNka2cnLCBsYWJlbCwgcGFzc3BocmFzZSB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNCYWNrdXBYcHViID0gISFwYXJhbXMuYmFja3VwWHB1YjtcbiAgICBjb25zdCBoYXNCYWNrdXBYcHViUHJvdmlkZXIgPSAhIXBhcmFtcy5iYWNrdXBYcHViUHJvdmlkZXI7XG4gICAgaWYgKGhhc0JhY2t1cFhwdWIgJiYgaGFzQmFja3VwWHB1YlByb3ZpZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBwcm92aWRlIG1vcmUgdGhhbiBvbmUgYmFja3VwWHB1YiBvciBiYWNrdXBYcHViUHJvdmlkZXIgZmxhZycpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZ2FzUHJpY2UgJiYgcGFyYW1zLmVpcDE1NTkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FuIG5vdCB1c2UgYm90aCBlaXAxNTU5IGFuZCBnYXNQcmljZSB2YWx1ZXMnKTtcbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQocGFyYW1zLmRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnMpKSB7XG4gICAgICBpZiAoIV8uaXNCb29sZWFuKHBhcmFtcy5kaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9ucyBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5kaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zID0gcGFyYW1zLmRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnM7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHBhcmFtcy5nYXNQcmljZSkpIHtcbiAgICAgIGNvbnN0IGdhc1ByaWNlQk4gPSBuZXcgQmlnTnVtYmVyKHBhcmFtcy5nYXNQcmljZSk7XG4gICAgICBpZiAoZ2FzUHJpY2VCTi5pc05hTigpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBnYXMgcHJpY2UgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuICAgICAgfVxuICAgICAgd2FsbGV0UGFyYW1zLmdhc1ByaWNlID0gZ2FzUHJpY2VCTi50b1N0cmluZygpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMuZWlwMTU1OSkgJiYgIV8uaXNFbXB0eShwYXJhbXMuZWlwMTU1OSkpIHtcbiAgICAgIGNvbnN0IG1heEZlZVBlckdhc0JOID0gbmV3IEJpZ051bWJlcihwYXJhbXMuZWlwMTU1OS5tYXhGZWVQZXJHYXMpO1xuICAgICAgaWYgKG1heEZlZVBlckdhc0JOLmlzTmFOKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIG1heCBmZWUgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuICAgICAgfVxuICAgICAgY29uc3QgbWF4UHJpb3JpdHlGZWVQZXJHYXNCTiA9IG5ldyBCaWdOdW1iZXIocGFyYW1zLmVpcDE1NTkubWF4UHJpb3JpdHlGZWVQZXJHYXMpO1xuICAgICAgaWYgKG1heFByaW9yaXR5RmVlUGVyR2FzQk4uaXNOYU4oKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcHJpb3JpdHkgZmVlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5laXAxNTU5ID0ge1xuICAgICAgICBtYXhGZWVQZXJHYXM6IG1heEZlZVBlckdhc0JOLnRvU3RyaW5nKCksXG4gICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiBtYXhQcmlvcml0eUZlZVBlckdhc0JOLnRvU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMuZGlzYWJsZUtSU0VtYWlsKSkge1xuICAgICAgaWYgKCFfLmlzQm9vbGVhbihwYXJhbXMuZGlzYWJsZUtSU0VtYWlsKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZGlzYWJsZUtSU0VtYWlsIGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuICAgICAgfVxuICAgICAgd2FsbGV0UGFyYW1zLmRpc2FibGVLUlNFbWFpbCA9IHBhcmFtcy5kaXNhYmxlS1JTRW1haWw7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHBhcmFtcy53YWxsZXRWZXJzaW9uKSkge1xuICAgICAgaWYgKCFfLmlzTnVtYmVyKHBhcmFtcy53YWxsZXRWZXJzaW9uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgd2FsbGV0VmVyc2lvbiBwcm92aWRlZCwgZXhwZWN0aW5nIG51bWJlcicpO1xuICAgICAgfVxuICAgICAgd2FsbGV0UGFyYW1zLndhbGxldFZlcnNpb24gPSBwYXJhbXMud2FsbGV0VmVyc2lvbjtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgZWFjaCBrcnNTcGVjaWZpYyBwYXJhbSBpcyBlaXRoZXIgYSBzdHJpbmcsIGJvb2xlYW4sIG9yIG51bWJlclxuICAgIGNvbnN0IHsga3JzU3BlY2lmaWMgfSA9IHBhcmFtcztcbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoa3JzU3BlY2lmaWMpKSB7XG4gICAgICBPYmplY3Qua2V5cyhrcnNTcGVjaWZpYykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbCA9IGtyc1NwZWNpZmljW2tleV07XG4gICAgICAgIGlmICghXy5pc0Jvb2xlYW4odmFsKSAmJiAhXy5pc1N0cmluZyh2YWwpICYmICFfLmlzTnVtYmVyKHZhbCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2tyc1NwZWNpZmljIG9iamVjdCBjb250YWlucyBpbGxlZ2FsIHZhbHVlcy4gdmFsdWVzIG11c3QgYmUgc3RyaW5ncywgYm9vbGVhbnMsIG9yIG51bWJlcnMnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IGRlcml2YXRpb25QYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG5cbiAgICAvLyBBZGQgdGhlIHVzZXIga2V5Y2hhaW5cbiAgICBjb25zdCB1c2VyS2V5Y2hhaW5Qcm9taXNlID0gYXN5bmMgKCk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgIGxldCB1c2VyS2V5Y2hhaW5QYXJhbXM7XG4gICAgICBsZXQgdXNlcktleWNoYWluO1xuICAgICAgLy8gVXNlciBwcm92aWRlZCB1c2VyIGtleVxuICAgICAgaWYgKHBhcmFtcy51c2VyS2V5KSB7XG4gICAgICAgIHVzZXJLZXljaGFpbiA9IHsgcHViOiBwYXJhbXMudXNlcktleSB9O1xuICAgICAgICB1c2VyS2V5Y2hhaW5QYXJhbXMgPSB1c2VyS2V5Y2hhaW47XG4gICAgICAgIGlmIChwYXJhbXMuY29sZERlcml2YXRpb25TZWVkKSB7XG4gICAgICAgICAgLy8gdGhlIGRlcml2YXRpb24gb25seSBtYWtlcyBzZW5zZSB3aGVuIGEga2V5IGFscmVhZHkgZXhpc3RzXG4gICAgICAgICAgY29uc3QgZGVyaXZhdGlvbiA9IHRoaXMuYmFzZUNvaW4uZGVyaXZlS2V5V2l0aFNlZWQoe1xuICAgICAgICAgICAga2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgICAgIHNlZWQ6IHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZGVyaXZhdGlvblBhdGggPSBkZXJpdmF0aW9uLmRlcml2YXRpb25QYXRoO1xuICAgICAgICAgIHVzZXJLZXljaGFpbi5wdWIgPSBkZXJpdmF0aW9uLmtleTtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW4uZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCA9IHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghY2FuRW5jcnlwdCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGdlbmVyYXRlIHVzZXIga2V5cGFpciB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDcmVhdGUgdGhlIHVzZXIga2V5LlxuICAgICAgICB1c2VyS2V5Y2hhaW4gPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICB1c2VyS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2ID0gdGhpcy5iaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsIGlucHV0OiB1c2VyS2V5Y2hhaW4ucHJ2IH0pO1xuICAgICAgICB1c2VyS2V5Y2hhaW5QYXJhbXMgPSB7XG4gICAgICAgICAgcHViOiB1c2VyS2V5Y2hhaW4ucHViLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogdXNlcktleWNoYWluLmVuY3J5cHRlZFBydixcbiAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICB1c2VyS2V5Y2hhaW5QYXJhbXMucmVxSWQgPSByZXFJZDtcbiAgICAgIGNvbnN0IG5ld1VzZXJLZXljaGFpbiA9IGF3YWl0IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuYWRkKHVzZXJLZXljaGFpblBhcmFtcyk7XG4gICAgICByZXR1cm4gXy5leHRlbmQoe30sIG5ld1VzZXJLZXljaGFpbiwgdXNlcktleWNoYWluKTtcbiAgICB9O1xuXG4gICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gYXN5bmMgKCk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgIGlmIChwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyKSB7XG4gICAgICAgIC8vIElmIHJlcXVlc3RlZCwgdXNlIGEgS1JTIG9yIGJhY2t1cCBrZXkgcHJvdmlkZXJcbiAgICAgICAgcmV0dXJuIHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlQmFja3VwKHtcbiAgICAgICAgICBwcm92aWRlcjogcGFyYW1zLmJhY2t1cFhwdWJQcm92aWRlciB8fCAnZGVmYXVsdFJNR0JhY2t1cFByb3ZpZGVyJyxcbiAgICAgICAgICBkaXNhYmxlS1JTRW1haWw6IHBhcmFtcy5kaXNhYmxlS1JTRW1haWwsXG4gICAgICAgICAga3JzU3BlY2lmaWM6IHBhcmFtcy5rcnNTcGVjaWZpYyxcbiAgICAgICAgICB0eXBlOiB0aGlzLmJhc2VDb2luLmdldENoYWluKCksXG4gICAgICAgICAgcmVxSWQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBVc2VyIHByb3ZpZGVkIGJhY2t1cCB4cHViXG4gICAgICBpZiAocGFyYW1zLmJhY2t1cFhwdWIpIHtcbiAgICAgICAgLy8gdXNlciBwcm92aWRlZCBiYWNrdXAgZXRoZXJldW0gYWRkcmVzc1xuICAgICAgICByZXR1cm4gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5hZGQoe1xuICAgICAgICAgIHB1YjogcGFyYW1zLmJhY2t1cFhwdWIsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICByZXFJZCxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIWNhbkVuY3J5cHQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBnZW5lcmF0ZSBiYWNrdXAga2V5cGFpciB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBwcm92aWRlZCBiYWNrdXAgeHB1YiBvciBhZGRyZXNzLCBzbyBkZWZhdWx0IHRvIGNyZWF0aW5nIG9uZSBoZXJlXG4gICAgICAgIHJldHVybiB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZUJhY2t1cCh7IHJlcUlkIH0pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW4gfTogS2V5Y2hhaW5zVHJpcGxldCA9IGF3YWl0IHByb21pc2VQcm9wcyh7XG4gICAgICB1c2VyS2V5Y2hhaW46IHVzZXJLZXljaGFpblByb21pc2UoKSxcbiAgICAgIGJhY2t1cEtleWNoYWluOiBiYWNrdXBLZXljaGFpblByb21pc2UoKSxcbiAgICAgIGJpdGdvS2V5Y2hhaW46IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlQml0R28oeyBlbnRlcnByaXNlOiBwYXJhbXMuZW50ZXJwcmlzZSwgcmVxSWQgfSksXG4gICAgfSk7XG5cbiAgICB3YWxsZXRQYXJhbXMua2V5cyA9IFt1c2VyS2V5Y2hhaW4uaWQsIGJhY2t1cEtleWNoYWluLmlkLCBiaXRnb0tleWNoYWluLmlkXTtcblxuICAgIHdhbGxldFBhcmFtcy5pc0NvbGQgPSBpc0NvbGQ7XG5cbiAgICBjb25zdCB7IHBydiB9ID0gdXNlcktleWNoYWluO1xuICAgIGlmIChfLmlzU3RyaW5nKHBydikpIHtcbiAgICAgIGFzc2VydChiYWNrdXBLZXljaGFpbi5wdWIpO1xuICAgICAgYXNzZXJ0KGJpdGdvS2V5Y2hhaW4ucHViKTtcbiAgICAgIHdhbGxldFBhcmFtcy5rZXlTaWduYXR1cmVzID0ge1xuICAgICAgICBiYWNrdXA6IChhd2FpdCB0aGlzLmJhc2VDb2luLnNpZ25NZXNzYWdlKHsgcHJ2IH0sIGJhY2t1cEtleWNoYWluLnB1YikpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgYml0Z286IChhd2FpdCB0aGlzLmJhc2VDb2luLnNpZ25NZXNzYWdlKHsgcHJ2IH0sIGJpdGdvS2V5Y2hhaW4ucHViKSkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoXy5pbmNsdWRlcyhbJ3hycCcsICd4bG0nLCAnY3NwciddLCB0aGlzLmJhc2VDb2luLmdldEZhbWlseSgpKSAmJiAhXy5pc1VuZGVmaW5lZChwYXJhbXMucm9vdFByaXZhdGVLZXkpKSB7XG4gICAgICB3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkgPSBwYXJhbXMucm9vdFByaXZhdGVLZXk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5Y2hhaW5zID0ge1xuICAgICAgdXNlcktleWNoYWluLFxuICAgICAgYmFja3VwS2V5Y2hhaW4sXG4gICAgICBiaXRnb0tleWNoYWluLFxuICAgIH07XG4gICAgY29uc3QgZmluYWxXYWxsZXRQYXJhbXMgPSBhd2FpdCB0aGlzLmJhc2VDb2luLnN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMsIGtleWNoYWlucyk7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcbiAgICBjb25zdCBuZXdXYWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQnKSkuc2VuZChmaW5hbFdhbGxldFBhcmFtcykucmVzdWx0KCk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFdhbGxldFdpdGhLZXljaGFpbnMgPSB7XG4gICAgICB3YWxsZXQ6IG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgbmV3V2FsbGV0KSxcbiAgICAgIHVzZXJLZXljaGFpbjogdXNlcktleWNoYWluLFxuICAgICAgYmFja3VwS2V5Y2hhaW46IGJhY2t1cEtleWNoYWluLFxuICAgICAgYml0Z29LZXljaGFpbjogYml0Z29LZXljaGFpbixcbiAgICB9O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGJhY2t1cEtleWNoYWluLnBydikpIHtcbiAgICAgIHJlc3VsdC53YXJuaW5nID0gJ0JlIHN1cmUgdG8gYmFja3VwIHRoZSBiYWNrdXAga2V5Y2hhaW4gLS0gaXQgaXMgbm90IHN0b3JlZCBhbnl3aGVyZSBlbHNlISc7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGRlcml2YXRpb25QYXRoKSkge1xuICAgICAgdXNlcktleWNoYWluLmRlcml2YXRpb25QYXRoID0gZGVyaXZhdGlvblBhdGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IHRoZSB1c2VyJ3Mgd2FsbGV0IHNoYXJlc1xuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBsaXN0U2hhcmVzKHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0c2hhcmUnKSkucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBhIHdhbGxldCBzaGFyZSBpbmZvcm1hdGlvbiwgaW5jbHVkaW5nIHRoZSBlbmNyeXB0ZWQgc2hhcmluZyBrZXljaGFpbi4gcmVxdWlyZXMgdW5sb2NrIGlmIGtleWNoYWluIGlzIHByZXNlbnQuXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy53YWxsZXRTaGFyZUlkIC0gdGhlIHdhbGxldCBzaGFyZSB0byBnZXQgaW5mb3JtYXRpb24gb25cbiAgICovXG4gIGFzeW5jIGdldFNoYXJlKHBhcmFtczogeyB3YWxsZXRTaGFyZUlkPzogc3RyaW5nIH0gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWyd3YWxsZXRTaGFyZUlkJ10sIFtdKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmJpdGdvLmdldCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyBwYXJhbXMud2FsbGV0U2hhcmVJZCkpLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhIHdhbGxldCBzaGFyZVxuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldFNoYXJlSWQgLSB0aGUgd2FsbGV0IHNoYXJlIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gcGFyYW1zLnN0YXRlIC0gdGhlIG5ldyBzdGF0ZSBvZiB0aGUgd2FsbGV0IHNoYXJlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHVwZGF0ZVNoYXJlKHBhcmFtczogVXBkYXRlU2hhcmVPcHRpb25zID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbXSk7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXRzaGFyZS8nICsgcGFyYW1zLndhbGxldFNoYXJlSWQpKVxuICAgICAgLnNlbmQocGFyYW1zKVxuICAgICAgLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2VuZCBhIHdhbGxldCBzaGFyZSBpbnZpdGF0aW9uIGVtYWlsXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy53YWxsZXRTaGFyZUlkIC0gdGhlIHdhbGxldCBzaGFyZSB3aG9zZSBpbnZpdGlhdGlvbiBzaG91bGQgYmUgcmVzZW50XG4gICAqL1xuICBhc3luYyByZXNlbmRTaGFyZUludml0ZShwYXJhbXM6IHsgd2FsbGV0U2hhcmVJZD86IHN0cmluZyB9ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbXSk7XG5cbiAgICBjb25zdCB1cmxQYXJ0cyA9IHBhcmFtcy53YWxsZXRTaGFyZUlkICsgJy9yZXNlbmRlbWFpbCc7XG4gICAgcmV0dXJuIHRoaXMuYml0Z28ucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyB1cmxQYXJ0cykpLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBhIHdhbGxldCBzaGFyZVxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0U2hhcmVJZCAtIHRoZSB3YWxsZXQgc2hhcmUgdG8gdXBkYXRlXG4gICAqL1xuICBhc3luYyBjYW5jZWxTaGFyZShwYXJhbXM6IHsgd2FsbGV0U2hhcmVJZD86IHN0cmluZyB9ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbXSk7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgLmRlbCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyBwYXJhbXMud2FsbGV0U2hhcmVJZCkpXG4gICAgICAuc2VuZCgpXG4gICAgICAucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0cyBhIHdhbGxldCBzaGFyZSwgYWRkaW5nIHRoZSB3YWxsZXQgdG8gdGhlIHVzZXIncyBsaXN0XG4gICAqIE5lZWRzIGEgdXNlcidzIHBhc3N3b3JkIHRvIGRlY3J5cHQgdGhlIHNoYXJlZCBrZXlcbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldFNoYXJlSWQgLSB0aGUgd2FsbGV0IHNoYXJlIHRvIGFjY2VwdFxuICAgKiBAcGFyYW0gcGFyYW1zLnVzZXJQYXNzd29yZCAtIChyZXF1aXJlZCBpZiBtb3JlIGEga2V5Y2hhaW4gd2FzIHNoYXJlZCkgdXNlcidzIHBhc3N3b3JkIHRvIGRlY3J5cHQgdGhlIHNoYXJlZCB3YWxsZXRcbiAgICogQHBhcmFtIHBhcmFtcy5uZXdXYWxsZXRQYXNzcGhyYXNlIC0gbmV3IHdhbGxldCBwYXNzcGhyYXNlIGZvciBzYXZpbmcgdGhlIHNoYXJlZCB3YWxsZXQgcHJ2LlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZiBsZWZ0IGJsYW5rIGFuZCBhIHdhbGxldCB3aXRoIG1vcmUgdGhhbiB2aWV3IHBlcm1pc3Npb25zIHdhcyBzaGFyZWQsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW4gdGhlIHVzZXIncyBsb2dpbiBwYXNzd29yZCBpcyB1c2VkLlxuICAgKiBAcGFyYW0gcGFyYW1zLm92ZXJyaWRlRW5jcnlwdGVkUHJ2IC0gc2V0IG9ubHkgaWYgdGhlIHBydiB3YXMgcmVjZWl2ZWQgb3V0LW9mLWJhbmQuXG4gICAqL1xuICBhc3luYyBhY2NlcHRTaGFyZShwYXJhbXM6IEFjY2VwdFNoYXJlT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb21tb24udmFsaWRhdGVQYXJhbXMocGFyYW1zLCBbJ3dhbGxldFNoYXJlSWQnXSwgWydvdmVycmlkZUVuY3J5cHRlZFBydicsICd1c2VyUGFzc3dvcmQnLCAnbmV3V2FsbGV0UGFzc3BocmFzZSddKTtcblxuICAgIGxldCBlbmNyeXB0ZWRQcnYgPSBwYXJhbXMub3ZlcnJpZGVFbmNyeXB0ZWRQcnY7XG5cbiAgICBjb25zdCB3YWxsZXRTaGFyZSA9IChhd2FpdCB0aGlzLmdldFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogcGFyYW1zLndhbGxldFNoYXJlSWQgfSkpIGFzIGFueTtcblxuICAgIC8vIFJldHVybiByaWdodCBhd2F5IGlmIHRoZXJlIGlzIG5vIGtleWNoYWluIHRvIGRlY3J5cHQsIG9yIGlmIGV4cGxpY2l0IGVuY3J5cHRlZFBydiB3YXMgcHJvdmlkZWRcbiAgICBpZiAoIXdhbGxldFNoYXJlLmtleWNoYWluIHx8ICF3YWxsZXRTaGFyZS5rZXljaGFpbi5lbmNyeXB0ZWRQcnYgfHwgZW5jcnlwdGVkUHJ2KSB7XG4gICAgICByZXR1cm4gdGhpcy51cGRhdGVTaGFyZSh7XG4gICAgICAgIHdhbGxldFNoYXJlSWQ6IHBhcmFtcy53YWxsZXRTaGFyZUlkLFxuICAgICAgICBzdGF0ZTogJ2FjY2VwdGVkJyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIE1vcmUgdGhhbiB2aWV3aW5nIHdhcyByZXF1ZXN0ZWQsIHNvIHdlIG5lZWQgdG8gcHJvY2VzcyB0aGUgd2FsbGV0IGtleXMgdXNpbmcgdGhlIHNoYXJlZCBlY2RoIHNjaGVtZVxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHBhcmFtcy51c2VyUGFzc3dvcmQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXJQYXNzd29yZCBwYXJhbSBtdXN0IGJlIHByb3ZpZGVkIHRvIGRlY3J5cHQgc2hhcmVkIGtleScpO1xuICAgIH1cblxuICAgIGNvbnN0IHNoYXJpbmdLZXljaGFpbiA9IChhd2FpdCB0aGlzLmJpdGdvLmdldEVDREhLZXljaGFpbigpKSBhcyBhbnk7XG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2hhcmluZ0tleWNoYWluLmVuY3J5cHRlZFhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgfVxuXG4gICAgLy8gTm93IHdlIGhhdmUgdGhlIHNoYXJpbmcga2V5Y2hhaW4sIHdlIGNhbiB3b3JrIG91dCB0aGUgc2VjcmV0IHVzZWQgZm9yIHNoYXJpbmcgdGhlIHdhbGxldCB3aXRoIHVzXG4gICAgc2hhcmluZ0tleWNoYWluLnBydiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7XG4gICAgICBwYXNzd29yZDogcGFyYW1zLnVzZXJQYXNzd29yZCxcbiAgICAgIGlucHV0OiBzaGFyaW5nS2V5Y2hhaW4uZW5jcnlwdGVkWHBydixcbiAgICB9KTtcbiAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoXG4gICAgICAvLyBEZXJpdmUga2V5IGJ5IHBhdGggKHdoaWNoIGlzIHVzZWQgYmV0d2VlbiB0aGVzZSAyIHVzZXJzIG9ubHkpXG4gICAgICBiaXAzMi5mcm9tQmFzZTU4KHNoYXJpbmdLZXljaGFpbi5wcnYpLmRlcml2ZVBhdGgoc2FuaXRpemVMZWdhY3lQYXRoKHdhbGxldFNoYXJlLmtleWNoYWluLnBhdGgpKSxcbiAgICAgIEJ1ZmZlci5mcm9tKHdhbGxldFNoYXJlLmtleWNoYWluLmZyb21QdWJLZXksICdoZXgnKVxuICAgICkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgLy8gWWVzISBXZSBnb3QgdGhlIHNlY3JldCBzdWNjZXNzZnVsbHkgaGVyZSwgbm93IGRlY3J5cHQgdGhlIHNoYXJlZCB3YWxsZXQgcHJ2XG4gICAgY29uc3QgZGVjcnlwdGVkU2hhcmVkV2FsbGV0UHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgIHBhc3N3b3JkOiBzZWNyZXQsXG4gICAgICBpbnB1dDogd2FsbGV0U2hhcmUua2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgIH0pO1xuXG4gICAgLy8gV2Ugd2lsbCBub3cgcmUtZW5jcnlwdCB0aGUgd2FsbGV0IHdpdGggb3VyIG93biBwYXNzd29yZFxuICAgIGNvbnN0IG5ld1dhbGxldFBhc3NwaHJhc2UgPSBwYXJhbXMubmV3V2FsbGV0UGFzc3BocmFzZSB8fCBwYXJhbXMudXNlclBhc3N3b3JkO1xuICAgIGVuY3J5cHRlZFBydiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7XG4gICAgICBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIGlucHV0OiBkZWNyeXB0ZWRTaGFyZWRXYWxsZXRQcnYsXG4gICAgfSk7XG4gICAgY29uc3QgdXBkYXRlUGFyYW1zOiBVcGRhdGVTaGFyZU9wdGlvbnMgPSB7XG4gICAgICB3YWxsZXRTaGFyZUlkOiBwYXJhbXMud2FsbGV0U2hhcmVJZCxcbiAgICAgIHN0YXRlOiAnYWNjZXB0ZWQnLFxuICAgIH07XG5cbiAgICBpZiAoZW5jcnlwdGVkUHJ2KSB7XG4gICAgICB1cGRhdGVQYXJhbXMuZW5jcnlwdGVkUHJ2ID0gZW5jcnlwdGVkUHJ2O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnVwZGF0ZVNoYXJlKHVwZGF0ZVBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgd2FsbGV0IGJ5IGl0cyBJRFxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMuaWQgd2FsbGV0IGlkXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgYXN5bmMgZ2V0V2FsbGV0KHBhcmFtczogR2V0V2FsbGV0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxXYWxsZXQ+IHtcbiAgICBjb21tb24udmFsaWRhdGVQYXJhbXMocGFyYW1zLCBbJ2lkJ10sIFtdKTtcblxuICAgIGNvbnN0IHF1ZXJ5OiBHZXRXYWxsZXRPcHRpb25zID0ge307XG4gICAgaWYgKHBhcmFtcy5hbGxUb2tlbnMpIHtcbiAgICAgIGlmICghXy5pc0Jvb2xlYW4ocGFyYW1zLmFsbFRva2VucykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFsbFRva2VucyBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcbiAgICAgIH1cbiAgICAgIHF1ZXJ5LmFsbFRva2VucyA9IHBhcmFtcy5hbGxUb2tlbnM7XG4gICAgfVxuXG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHBhcmFtcy5yZXFJZCB8fCBuZXcgUmVxdWVzdFRyYWNlcigpKTtcblxuICAgIGNvbnN0IHdhbGxldCA9IGF3YWl0IHRoaXMuYml0Z29cbiAgICAgIC5nZXQodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQvJyArIHBhcmFtcy5pZCkpXG4gICAgICAucXVlcnkocXVlcnkpXG4gICAgICAucmVzdWx0KCk7XG4gICAgcmV0dXJuIG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgd2FsbGV0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSB3YWxsZXQgYnkgaXRzIGFkZHJlc3NcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLmFkZHJlc3Mgd2FsbGV0IGFkZHJlc3NcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBnZXRXYWxsZXRCeUFkZHJlc3MocGFyYW1zOiBHZXRXYWxsZXRCeUFkZHJlc3NPcHRpb25zID0ge30pOiBQcm9taXNlPFdhbGxldD4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnYWRkcmVzcyddLCBbXSk7XG5cbiAgICB0aGlzLmJpdGdvLnNldFJlcXVlc3RUcmFjZXIocGFyYW1zLnJlcUlkIHx8IG5ldyBSZXF1ZXN0VHJhY2VyKCkpO1xuXG4gICAgY29uc3Qgd2FsbGV0ID0gYXdhaXQgdGhpcy5iaXRnby5nZXQodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQvYWRkcmVzcy8nICsgcGFyYW1zLmFkZHJlc3MpKS5yZXN1bHQoKTtcbiAgICByZXR1cm4gbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCB3YWxsZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvciBhbnkgZ2l2ZW4gc3VwcG9ydGVkIGNvaW4sIGdldCB0b3RhbCBiYWxhbmNlcyBmb3IgYWxsIHdhbGxldHMgb2YgdGhhdFxuICAgKiBjb2luIHR5cGUgb24gdGhlIGFjY291bnQuXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBnZXRUb3RhbEJhbGFuY2VzKHBhcmFtczogUmVjb3JkPHN0cmluZywgbmV2ZXI+ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJpdGdvLmdldCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC9iYWxhbmNlcycpKS5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSBUU1Mgb3IgQkxTLURLRyBXYWxsZXQuXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVNcGNXYWxsZXQocGFyYW1zOiBHZW5lcmF0ZU1wY1dhbGxldE9wdGlvbnMpOiBQcm9taXNlPFdhbGxldFdpdGhLZXljaGFpbnM+IHtcbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcblxuICAgIGNvbnN0IHdhbGxldFBhcmFtczogU3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgIGxhYmVsOiBwYXJhbXMubGFiZWwsXG4gICAgICBtOiAyLFxuICAgICAgbjogMyxcbiAgICAgIGtleXM6IFtdLFxuICAgICAgaXNDb2xkOiBmYWxzZSxcbiAgICAgIG11bHRpc2lnVHlwZTogcGFyYW1zLm11bHRpc2lnVHlwZSxcbiAgICAgIGVudGVycHJpc2U6IHBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgd2FsbGV0VmVyc2lvbjogcGFyYW1zLndhbGxldFZlcnNpb24sXG4gICAgfTtcblxuICAgIC8vIENyZWF0ZSBNUEMgS2V5Y2hhaW5zXG5cbiAgICBjb25zdCBrZXljaGFpbnMgPSBhd2FpdCB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICBtdWx0aXNpZ1R5cGU6IHBhcmFtcy5tdWx0aXNpZ1R5cGUsXG4gICAgICBwYXNzcGhyYXNlOiBwYXJhbXMucGFzc3BocmFzZSxcbiAgICAgIGVudGVycHJpc2U6IHBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgYmFja3VwUHJvdmlkZXI6IHBhcmFtcy5iYWNrdXBQcm92aWRlcixcbiAgICB9KTtcbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW4gfSA9IGtleWNoYWlucztcbiAgICB3YWxsZXRQYXJhbXMua2V5cyA9IFt1c2VyS2V5Y2hhaW4uaWQsIGJhY2t1cEtleWNoYWluLmlkLCBiaXRnb0tleWNoYWluLmlkXTtcblxuICAgIC8vIENyZWF0ZSBXYWxsZXRcbiAgICBjb25zdCBmaW5hbFdhbGxldFBhcmFtcyA9IGF3YWl0IHRoaXMuYmFzZUNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcywga2V5Y2hhaW5zKTtcbiAgICBjb25zdCBuZXdXYWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQnKSkuc2VuZChmaW5hbFdhbGxldFBhcmFtcykucmVzdWx0KCk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFdhbGxldFdpdGhLZXljaGFpbnMgPSB7XG4gICAgICB3YWxsZXQ6IG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgbmV3V2FsbGV0KSxcbiAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgIGJhY2t1cEtleWNoYWluLFxuICAgICAgYml0Z29LZXljaGFpbixcbiAgICB9O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGJhY2t1cEtleWNoYWluLnBydikgJiYgIV8uaXNVbmRlZmluZWQocGFyYW1zLmJhY2t1cFByb3ZpZGVyKSkge1xuICAgICAgcmVzdWx0Lndhcm5pbmcgPSAnQmUgc3VyZSB0byBiYWNrdXAgdGhlIGJhY2t1cCBrZXljaGFpbiAtLSBpdCBpcyBub3Qgc3RvcmVkIGFueXdoZXJlIGVsc2UhJztcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iXX0=
1332
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9iaXRnby93YWxsZXQvd2FsbGV0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtREEsc0RBSUM7QUF2REQ7O0dBRUc7QUFDSCxvREFBNEI7QUFDNUIsK0NBQXlDO0FBQ3pDLG1EQUE2QztBQUM3QywwQ0FBNEI7QUFDNUIsaURBQWtEO0FBRWxELG1DQUErQztBQUMvQyxxREFBdUM7QUFHdkMsa0NBQTBDO0FBQzFDLDBDQUF1RTtBQUN2RSxvQ0FBcUU7QUFDckUseUNBMEJvQjtBQUVwQixxQ0FBa0M7QUFFbEMsOENBQXlGO0FBRXpGOztHQUVHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQ25DLE1BQTRGO0lBRTVGLE9BQU8sTUFBTSxDQUFDLFlBQVksS0FBSyxxQkFBcUIsQ0FBQztBQUN2RCxDQUFDO0FBRUQsTUFBYSxPQUFPO0lBSWxCLFlBQVksS0FBZ0IsRUFBRSxRQUFtQjtRQUMvQyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUEyQixFQUFFO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBc0QsRUFBRTtRQUNqRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxD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LENBQUM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRjtBQXpnREQsMEJBeWdEQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IEJpZ051bWJlciB9IGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBiaXAzMiB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IENvaW5GZWF0dXJlIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5cbmltcG9ydCB7IHNhbml0aXplTGVnYWN5UGF0aCB9IGZyb20gJy4uLy4uL2FwaSc7XG5pbXBvcnQgKiBhcyBjb21tb24gZnJvbSAnLi4vLi4vY29tbW9uJztcbmltcG9ydCB7IElCYXNlQ29pbiwgS2V5Y2hhaW5zVHJpcGxldCwgU3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucyB9IGZyb20gJy4uL2Jhc2VDb2luJztcbmltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJy4uL2JpdGdvQmFzZSc7XG5pbXBvcnQgeyBnZXRTaGFyZWRTZWNyZXQgfSBmcm9tICcuLi9lY2RoJztcbmltcG9ydCB7IEFkZEtleWNoYWluT3B0aW9ucywgS2V5Y2hhaW4sIEtleUluZGljZXMgfSBmcm9tICcuLi9rZXljaGFpbic7XG5pbXBvcnQgeyBkZWNvZGVPckVsc2UsIHByb21pc2VQcm9wcywgUmVxdWVzdFRyYWNlciB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7XG4gIEFjY2VwdFNoYXJlT3B0aW9ucyxcbiAgQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdCxcbiAgQWRkV2FsbGV0T3B0aW9ucyxcbiAgQnVsa0FjY2VwdFNoYXJlT3B0aW9ucyxcbiAgQnVsa0FjY2VwdFNoYXJlUmVzcG9uc2UsXG4gIEJ1bGtVcGRhdGVXYWxsZXRTaGFyZU9wdGlvbnMsXG4gIEJ1bGtVcGRhdGVXYWxsZXRTaGFyZU9wdGlvbnNSZXF1ZXN0LFxuICBCdWxrVXBkYXRlV2FsbGV0U2hhcmVSZXNwb25zZSxcbiAgR2VuZXJhdGVCYXNlTXBjV2FsbGV0T3B0aW9ucyxcbiAgR2VuZXJhdGVHb0FjY291bnRXYWxsZXRPcHRpb25zLFxuICBHZW5lcmF0ZUdvQWNjb3VudFdhbGxldE9wdGlvbnNDb2RlYyxcbiAgR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zLFxuICBHZW5lcmF0ZUxpZ2h0bmluZ1dhbGxldE9wdGlvbnNDb2RlYyxcbiAgR2VuZXJhdGVNcGNXYWxsZXRPcHRpb25zLFxuICBHZW5lcmF0ZVNNQ01wY1dhbGxldE9wdGlvbnMsXG4gIEdlbmVyYXRlV2FsbGV0T3B0aW9ucyxcbiAgR2V0V2FsbGV0QnlBZGRyZXNzT3B0aW9ucyxcbiAgR2V0V2FsbGV0T3B0aW9ucyxcbiAgR29BY2NvdW50V2FsbGV0V2l0aFVzZXJLZXljaGFpbixcbiAgSVdhbGxldHMsXG4gIExpZ2h0bmluZ1dhbGxldFdpdGhLZXljaGFpbnMsXG4gIExpc3RXYWxsZXRPcHRpb25zLFxuICBVcGRhdGVTaGFyZU9wdGlvbnMsXG4gIFdhbGxldFNoYXJlcyxcbiAgV2FsbGV0V2l0aEtleWNoYWlucyxcbn0gZnJvbSAnLi9pV2FsbGV0cyc7XG5pbXBvcnQgeyBXYWxsZXRTaGFyZSB9IGZyb20gJy4vaVdhbGxldCc7XG5pbXBvcnQgeyBXYWxsZXQgfSBmcm9tICcuL3dhbGxldCc7XG5pbXBvcnQgeyBUc3NTZXR0aW5ncyB9IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuaW1wb3J0IHsgY3JlYXRlRXZtS2V5UmluZ1dhbGxldCwgdmFsaWRhdGVFdm1LZXlSaW5nV2FsbGV0UGFyYW1zIH0gZnJvbSAnLi4vZXZtL2V2bVV0aWxzJztcblxuLyoqXG4gKiBDaGVjayBpZiBhIHdhbGxldCBpcyBhIFdhbGxldFdpdGhLZXljaGFpbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzV2FsbGV0V2l0aEtleWNoYWlucyhcbiAgd2FsbGV0OiBXYWxsZXRXaXRoS2V5Y2hhaW5zIHwgTGlnaHRuaW5nV2FsbGV0V2l0aEtleWNoYWlucyB8IEdvQWNjb3VudFdhbGxldFdpdGhVc2VyS2V5Y2hhaW5cbik6IHdhbGxldCBpcyBXYWxsZXRXaXRoS2V5Y2hhaW5zIHtcbiAgcmV0dXJuIHdhbGxldC5yZXNwb25zZVR5cGUgPT09ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJztcbn1cblxuZXhwb3J0IGNsYXNzIFdhbGxldHMgaW1wbGVtZW50cyBJV2FsbGV0cyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYml0Z286IEJpdEdvQmFzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlQ29pbjogSUJhc2VDb2luO1xuXG4gIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIGJhc2VDb2luOiBJQmFzZUNvaW4pIHtcbiAgICB0aGlzLmJpdGdvID0gYml0Z287XG4gICAgdGhpcy5iYXNlQ29pbiA9IGJhc2VDb2luO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHdhbGxldCBieSBJRCAocHJveHkgZm9yIGdldFdhbGxldClcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZ2V0KHBhcmFtczogR2V0V2FsbGV0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxXYWxsZXQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRXYWxsZXQocGFyYW1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IGEgdXNlcidzIHdhbGxldHNcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIGxpc3QocGFyYW1zOiBMaXN0V2FsbGV0T3B0aW9ucyAmIHsgZW50ZXJwcmlzZT86IHN0cmluZyB9ID0ge30pOiBQcm9taXNlPHsgd2FsbGV0czogV2FsbGV0W10gfT4ge1xuICAgIGlmIChwYXJhbXMuc2tpcCAmJiBwYXJhbXMucHJldklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzcGVjaWZ5IGJvdGggc2tpcCBhbmQgcHJldklkJyk7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSAoYXdhaXQgdGhpcy5iaXRnby5nZXQodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQnKSkucXVlcnkocGFyYW1zKS5yZXN1bHQoKSkgYXMgYW55O1xuICAgIGJvZHkud2FsbGV0cyA9IGJvZHkud2FsbGV0cy5tYXAoKHcpID0+IG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgdykpO1xuICAgIHJldHVybiBib2R5O1xuICB9XG5cbiAgLyoqXG4gICAqIGFkZFxuICAgKiBBZGQgYSBuZXcgd2FsbGV0IChhZHZhbmNlZCBtb2RlKS5cbiAgICogVGhpcyBhbGxvd3MgeW91IHRvIG1hbnVhbGx5IHN1Ym1pdCB0aGUga2V5cywgdHlwZSwgbSBhbmQgbiBvZiB0aGUgd2FsbGV0XG4gICAqIFBhcmFtZXRlcnMgaW5jbHVkZTpcbiAgICogICAgXCJsYWJlbFwiOiBsYWJlbCBvZiB0aGUgd2FsbGV0IHRvIGJlIHNob3duIGluIFVJXG4gICAqICAgIFwibVwiOiBudW1iZXIgb2Yga2V5cyByZXF1aXJlZCB0byB1bmxvY2sgd2FsbGV0ICgyKVxuICAgKiAgICBcIm5cIjogbnVtYmVyIG9mIGtleXMgYXZhaWxhYmxlIG9uIHRoZSB3YWxsZXQgKDMpXG4gICAqICAgIFwia2V5c1wiOiBhcnJheSBvZiBrZXljaGFpbiBpZHNcbiAgICovXG4gIGFzeW5jIGFkZChwYXJhbXM6IEFkZFdhbGxldE9wdGlvbnMpOiBQcm9taXNlPGFueT4ge1xuICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFtdLCBbJ2xhYmVsJywgJ2VudGVycHJpc2UnLCAndHlwZSddKTtcblxuICAgIGlmICh0eXBlb2YgcGFyYW1zLmxhYmVsICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHN0cmluZyBwYXJhbWV0ZXIgbGFiZWwnKTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZUV2bUtleVJpbmdXYWxsZXRQYXJhbXMocGFyYW1zLCB0aGlzLmJhc2VDb2luKTtcblxuICAgIGlmICghcGFyYW1zLmV2bUtleVJpbmdSZWZlcmVuY2VXYWxsZXRJZCAmJiBwYXJhbXMudHlwZSAhPT0gJ2N1c3RvZGlhbCcpIHtcbiAgICAgIC8vIG5vIG5lZWQgdG8gcGFzcyBrZXlzIGZvciAoc2luZ2xlKSBjdXN0b2RpYWwgd2FsbGV0c1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocGFyYW1zLmtleXMpID09PSBmYWxzZSB8fCAhXy5pc051bWJlcihwYXJhbXMubSkgfHwgIV8uaXNOdW1iZXIocGFyYW1zLm4pKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhcmd1bWVudCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBzdXBwb3J0IG1vcmUgdHlwZXMgb2YgbXVsdGlzaWdcbiAgICAgIGlmICghdGhpcy5iYXNlQ29pbi5pc1ZhbGlkTW9mTlNldHVwKHBhcmFtcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnN1cHBvcnRlZCBtdWx0aS1zaWcgdHlwZScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZ2FzUHJpY2UgJiYgIV8uaXNOdW1iZXIocGFyYW1zLmdhc1ByaWNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBnYXNQcmljZSAtIG51bWJlciBleHBlY3RlZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMud2FsbGV0VmVyc2lvbikge1xuICAgICAgaWYgKCFfLmlzTnVtYmVyKHBhcmFtcy53YWxsZXRWZXJzaW9uKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIHdhbGxldFZlcnNpb24gLSBudW1iZXIgZXhwZWN0ZWQnKTtcbiAgICAgIH1cbiAgICAgIGlmIChwYXJhbXMubXVsdGlzaWdUeXBlID09PSAndHNzJyAmJiB0aGlzLmJhc2VDb2luLmdldE1QQ0FsZ29yaXRobSgpID09PSAnZWNkc2EnICYmIHBhcmFtcy53YWxsZXRWZXJzaW9uID09PSAzKSB7XG4gICAgICAgIGNvbnN0IHRzc1NldHRpbmdzOiBUc3NTZXR0aW5ncyA9IGF3YWl0IHRoaXMuYml0Z29cbiAgICAgICAgICAuZ2V0KHRoaXMuYml0Z28ubWljcm9zZXJ2aWNlc1VybCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKSlcbiAgICAgICAgICAucmVzdWx0KCk7XG4gICAgICAgIGNvbnN0IG11bHRpc2lnVHlwZVZlcnNpb24gPVxuICAgICAgICAgIHRzc1NldHRpbmdzLmNvaW5TZXR0aW5nc1t0aGlzLmJhc2VDb2luLmdldEZhbWlseSgpXT8ud2FsbGV0Q3JlYXRpb25TZXR0aW5ncz8ubXVsdGlTaWdUeXBlVmVyc2lvbjtcbiAgICAgICAgaWYgKG11bHRpc2lnVHlwZVZlcnNpb24gPT09ICdNUEN2MicpIHtcbiAgICAgICAgICBwYXJhbXMud2FsbGV0VmVyc2lvbiA9IDU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLnRhZ3MgJiYgQXJyYXkuaXNBcnJheShwYXJhbXMudGFncykgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIHRhZ3MgLSBhcnJheSBleHBlY3RlZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuY2xpZW50RmxhZ3MgJiYgQXJyYXkuaXNBcnJheShwYXJhbXMuY2xpZW50RmxhZ3MpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBjbGllbnRGbGFncyAtIGFycmF5IGV4cGVjdGVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5pc0NvbGQgJiYgIV8uaXNCb29sZWFuKHBhcmFtcy5pc0NvbGQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ29sZCAtIGJvb2xlYW4gZXhwZWN0ZWQnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmlzQ3VzdG9kaWFsICYmICFfLmlzQm9vbGVhbihwYXJhbXMuaXNDdXN0b2RpYWwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ3VzdG9kaWFsIC0gYm9vbGVhbiBleHBlY3RlZCcpO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuYWRkcmVzcyAmJiAoIV8uaXNTdHJpbmcocGFyYW1zLmFkZHJlc3MpIHx8ICF0aGlzLmJhc2VDb2luLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5hZGRyZXNzKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBhcmd1bWVudCBmb3IgYWRkcmVzcyAtIHZhbGlkIGFkZHJlc3Mgc3RyaW5nIGV4cGVjdGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgbmV3V2FsbGV0ID0gYXdhaXQgdGhpcy5iaXRnby5wb3N0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0L2FkZCcpKS5zZW5kKHBhcmFtcykucmVzdWx0KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdhbGxldDogbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCBuZXdXYWxsZXQpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0KHBhcmFtczogR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zKTogUHJvbWlzZTxMaWdodG5pbmdXYWxsZXRXaXRoS2V5Y2hhaW5zPiB7XG4gICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihyZXFJZCk7XG5cbiAgICBjb25zdCB7IGxhYmVsLCBwYXNzcGhyYXNlLCBlbnRlcnByaXNlLCBwYXNzY29kZUVuY3J5cHRpb25Db2RlLCBzdWJUeXBlIH0gPSBwYXJhbXM7XG5cbiAgICAvLyBUT0RPIEJUQy0xODk5OiBvbmx5IHVzZXJBdXRoIGtleSBpcyByZXF1aXJlZCBmb3IgY3VzdG9kaWFsIGxpZ2h0bmluZyB3YWxsZXQuIGFsbCAzIGtleXMgYXJlIHJlcXVpcmVkIGZvciBzZWxmIGN1c3RvZGlhbCBsaWdodG5pbmcuXG4gICAgLy8gdG8gYXZvaWQgY2hhbmdpbmcgdGhlIHBsYXRmb3JtIGZvciBjdXN0b2RpYWwgZmxvdywgbGV0IHVzIGFsbCAzIGtleXMgYm90aCB3YWxsZXQgdHlwZXMuXG4gICAgY29uc3Qga2V5Y2hhaW5Qcm9taXNlcyA9IChbdW5kZWZpbmVkLCAndXNlckF1dGgnLCAnbm9kZUF1dGgnXSBhcyBjb25zdCkubWFwKChwdXJwb3NlKSA9PiB7XG4gICAgICByZXR1cm4gYXN5bmMgKCk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpblBhcmFtczogQWRkS2V5Y2hhaW5PcHRpb25zID0ge1xuICAgICAgICAgIHB1Yjoga2V5Y2hhaW4ucHViLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogdGhpcy5iaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsIGlucHV0OiBrZXljaGFpbi5wcnYgfSksXG4gICAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiBwdXJwb3NlID09PSB1bmRlZmluZWQgPyBwYXNzY29kZUVuY3J5cHRpb25Db2RlIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzogcHVycG9zZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogeyBbdGhpcy5iYXNlQ29pbi5nZXRDaGFpbigpXTogeyBwdXJwb3NlIH0gfSxcbiAgICAgICAgICBrZXlUeXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5hZGQoa2V5Y2hhaW5QYXJhbXMpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgdXNlcktleWNoYWluLCB1c2VyQXV0aEtleWNoYWluLCBub2RlQXV0aEtleWNoYWluIH0gPSBhd2FpdCBwcm9taXNlUHJvcHMoe1xuICAgICAgdXNlcktleWNoYWluOiBrZXljaGFpblByb21pc2VzWzBdKCksXG4gICAgICB1c2VyQXV0aEtleWNoYWluOiBrZXljaGFpblByb21pc2VzWzFdKCksXG4gICAgICBub2RlQXV0aEtleWNoYWluOiBrZXljaGFpblByb21pc2VzWzJdKCksXG4gICAgfSk7XG5cbiAgICBjb25zdCB3YWxsZXRQYXJhbXM6IFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICBsYWJlbCxcbiAgICAgIG06IDEsXG4gICAgICBuOiAxLFxuICAgICAgdHlwZTogJ2hvdCcsXG4gICAgICBzdWJUeXBlLFxuICAgICAgZW50ZXJwcmlzZSxcbiAgICAgIGtleXM6IFt1c2VyS2V5Y2hhaW4uaWRdLFxuICAgICAgY29pblNwZWNpZmljOiB7IFt0aGlzLmJhc2VDb2luLmdldENoYWluKCldOiB7IGtleXM6IFt1c2VyQXV0aEtleWNoYWluLmlkLCBub2RlQXV0aEtleWNoYWluLmlkXSB9IH0sXG4gICAgfTtcblxuICAgIGNvbnN0IG5ld1dhbGxldCA9IGF3YWl0IHRoaXMuYml0Z28ucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC9hZGQnKSkuc2VuZCh3YWxsZXRQYXJhbXMpLnJlc3VsdCgpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgbmV3V2FsbGV0KTtcbiAgICByZXR1cm4ge1xuICAgICAgd2FsbGV0LFxuICAgICAgdXNlcktleWNoYWluLFxuICAgICAgdXNlckF1dGhLZXljaGFpbixcbiAgICAgIG5vZGVBdXRoS2V5Y2hhaW4sXG4gICAgICByZXNwb25zZVR5cGU6ICdMaWdodG5pbmdXYWxsZXRXaXRoS2V5Y2hhaW5zJyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgR28gQWNjb3VudCB3YWxsZXRcbiAgICogQHBhcmFtIHBhcmFtcyBHZW5lcmF0ZUdvQWNjb3VudFdhbGxldE9wdGlvbnNcbiAgICogQHJldHVybnMgUHJvbWlzZTxHb0FjY291bnRXYWxsZXRXaXRoVXNlcktleWNoYWluPlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUdvQWNjb3VudFdhbGxldChcbiAgICBwYXJhbXM6IEdlbmVyYXRlR29BY2NvdW50V2FsbGV0T3B0aW9uc1xuICApOiBQcm9taXNlPEdvQWNjb3VudFdhbGxldFdpdGhVc2VyS2V5Y2hhaW4+IHtcbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcblxuICAgIGNvbnN0IHsgbGFiZWwsIHBhc3NwaHJhc2UsIGVudGVycHJpc2UsIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSA9IHBhcmFtcztcblxuICAgIGNvbnN0IGtleWNoYWluID0gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5jcmVhdGUoKTtcblxuICAgIGNvbnN0IGtleWNoYWluUGFyYW1zOiBBZGRLZXljaGFpbk9wdGlvbnMgPSB7XG4gICAgICBwdWI6IGtleWNoYWluLnB1YixcbiAgICAgIGVuY3J5cHRlZFBydjogdGhpcy5iaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHBhc3NwaHJhc2UsIGlucHV0OiBrZXljaGFpbi5wcnYgfSksXG4gICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6IHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICBrZXlUeXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgfTtcblxuICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IGF3YWl0IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuYWRkKGtleWNoYWluUGFyYW1zKTtcblxuICAgIGNvbnN0IHdhbGxldFBhcmFtczogU3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgIGxhYmVsLFxuICAgICAgbTogMSxcbiAgICAgIG46IDEsXG4gICAgICB0eXBlOiAndHJhZGluZycsXG4gICAgICBlbnRlcnByaXNlLFxuICAgICAga2V5czogW3VzZXJLZXljaGFpbi5pZF0sXG4gICAgfTtcblxuICAgIGNvbnN0IG5ld1dhbGxldCA9IGF3YWl0IHRoaXMuYml0Z28ucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC9hZGQnKSkuc2VuZCh3YWxsZXRQYXJhbXMpLnJlc3VsdCgpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQodGhpcy5iaXRnbywgdGhpcy5iYXNlQ29pbiwgbmV3V2FsbGV0KTtcblxuICAgIGNvbnN0IHJlc3VsdDogR29BY2NvdW50V2FsbGV0V2l0aFVzZXJLZXljaGFpbiA9IHtcbiAgICAgIHdhbGxldCxcbiAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgIHJlc3BvbnNlVHlwZTogJ0dvQWNjb3VudFdhbGxldFdpdGhVc2VyS2V5Y2hhaW4nLFxuICAgIH07XG5cbiAgICAvLyBBZGQgd2FybmluZyBpZiB0aGUgdXNlciBrZXljaGFpbiBoYXMgYW4gZW5jcnlwdGVkIHByaXZhdGUga2V5XG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYpKSB7XG4gICAgICByZXN1bHQud2FybmluZyA9ICdCZSBzdXJlIHRvIGJhY2t1cCB0aGUgdXNlciBrZXljaGFpbiAtLSBpdCBpcyBub3Qgc3RvcmVkIGFueXdoZXJlIGVsc2UhJztcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgbmV3IHdhbGxldFxuICAgKiAxLiBDcmVhdGVzIHRoZSB1c2VyIGtleWNoYWluIGxvY2FsbHkgb24gdGhlIGNsaWVudCwgYW5kIGVuY3J5cHRzIGl0IHdpdGggdGhlIHByb3ZpZGVkIHBhc3NwaHJhc2VcbiAgICogMi4gSWYgbm8gcHViIHdhcyBwcm92aWRlZCwgY3JlYXRlcyB0aGUgYmFja3VwIGtleWNoYWluIGxvY2FsbHkgb24gdGhlIGNsaWVudCwgYW5kIGVuY3J5cHRzIGl0IHdpdGggdGhlIHByb3ZpZGVkIHBhc3NwaHJhc2VcbiAgICogMy4gVXBsb2FkcyB0aGUgZW5jcnlwdGVkIHVzZXIgYW5kIGJhY2t1cCBrZXljaGFpbnMgdG8gQml0R29cbiAgICogNC4gQ3JlYXRlcyB0aGUgQml0R28ga2V5IG9uIHRoZSBzZXJ2aWNlXG4gICAqIDUuIENyZWF0ZXMgdGhlIHdhbGxldCBvbiBCaXRHbyB3aXRoIHRoZSAzIHB1YmxpYyBrZXlzIGFib3ZlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy5sYWJlbCBMYWJlbCBmb3IgdGhlIHdhbGxldFxuICAgKiBAcGFyYW0gcGFyYW1zLnBhc3NwaHJhc2UgUGFzc3BocmFzZSB0byBiZSB1c2VkIHRvIGVuY3J5cHQgdGhlIHVzZXIgYW5kIGJhY2t1cCBrZXljaGFpbnNcbiAgICogQHBhcmFtIHBhcmFtcy51c2VyS2V5IFVzZXIgeHB1YlxuICAgKiBAcGFyYW0gcGFyYW1zLmJhY2t1cFhwdWIgQmFja3VwIHhwdWJcbiAgICogQHBhcmFtIHBhcmFtcy5iYWNrdXBYcHViUHJvdmlkZXJcbiAgICogQHBhcmFtIHBhcmFtcy5lbnRlcnByaXNlIHRoZSBlbnRlcnByaXNlSWRcbiAgICogQHBhcmFtIHBhcmFtcy5kaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zXG4gICAqIEBwYXJhbSBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSBvcHRpb25hbCB0aGlzIGlzIGEgcmVjb3ZlcnkgY29kZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlY3J5cHQgdGhlIG9yaWdpbmFsIHBhc3NwaHJhc2UgaW4gYSByZWNvdmVyeSBjYXNlLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhlIHVzZXIgbXVzdCBnZW5lcmF0ZSBhbmQga2VlcCB0aGUgZW5jcnlwdGVkIG9yaWdpbmFsIHBhc3NwaHJhc2Ugc2FmZSB3aGlsZSB0aGlzIGNvZGUgaXMgc3RvcmVkIG9uIEJpdEdvXG4gICAqIEBwYXJhbSBwYXJhbXMuY29sZERlcml2YXRpb25TZWVkIG9wdGlvbmFsIHNlZWQgZm9yIFNNQyB3YWxsZXRzXG4gICAqIEBwYXJhbSBwYXJhbXMuZ2FzUHJpY2VcbiAgICogQHBhcmFtIHBhcmFtcy5kaXNhYmxlS1JTRW1haWxcbiAgICogQHBhcmFtIHBhcmFtcy53YWxsZXRWZXJzaW9uXG4gICAqIEBwYXJhbSBwYXJhbXMubXVsdGlzaWdUeXBlIG9wdGlvbmFsIG11bHRpc2lnIHR5cGUsICdvbmNoYWluJyBvciAndHNzJyBvciAnYmxzZGtnJzsgaWYgYWJzZW50LCB3ZSB3aWxsIGRlZmVyIHRvIHRoZSBjb2luJ3MgZGVmYXVsdCB0eXBlXG4gICAqIEBwYXJhbSBwYXJhbXMuaXNEaXN0cmlidXRlZEN1c3RvZHkgb3B0aW9uYWwgcGFyYW1ldGVyIGZvciBjcmVhdGluZyBiaXRnbyBrZXkuIFRoaXMgaXMgb25seSBuZWNlc3NhcnkgaWYgeW91IHdhbnQgdG8gY3JlYXRlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYSBkaXN0cmlidXRlZCBjdXN0b2R5IHdhbGxldC4gSWYgcHJvdmlkZWQsIHlvdSBtdXN0IGhhdmUgdGhlIGVudGVycHJpc2UgbGljZW5zZSBhbmQgcGFzcyBpblxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBwYXJhbXMuZW50ZXJwcmlzZWAgaW50byBgZ2VuZXJhdGVXYWxsZXRgIGFzIHdlbGwuXG4gICAqIEBwYXJhbSBwYXJhbXMudHlwZSBvcHRpb25hbCB3YWxsZXQgdHlwZSwgJ2hvdCcgb3IgJ2NvbGQnIG9yICdjdXN0b2RpYWwnOyBpZiBhYnNlbnQsIHdlIHdpbGwgZGVmZXIgdG8gJ2hvdCdcbiAgICogQHBhcmFtIHBhcmFtcy5iaXRnb0tleUlkIG9wdGlvbmFsIGJpdGdvIGtleSBpZCBmb3IgU01DIFRTUyB3YWxsZXRzXG4gICAqIEBwYXJhbSBwYXJhbXMuY29tbW9uS2V5Y2hhaW4gb3B0aW9uYWwgY29tbW9uIGtleWNoYWluIGZvciBTTUMgVFNTIHdhbGxldHNcbiAgICpcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZVdhbGxldChcbiAgICBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHt9XG4gICk6IFByb21pc2U8V2FsbGV0V2l0aEtleWNoYWlucyB8IExpZ2h0bmluZ1dhbGxldFdpdGhLZXljaGFpbnMgfCBHb0FjY291bnRXYWxsZXRXaXRoVXNlcktleWNoYWluPiB7XG4gICAgLy8gQXNzaWduIHRoZSBkZWZhdWx0IG11bHRpU2lnIHR5cGUgdmFsdWUgYmFzZWQgb24gdGhlIGNvaW5cbiAgICBpZiAoIXBhcmFtcy5tdWx0aXNpZ1R5cGUpIHtcbiAgICAgIHBhcmFtcy5tdWx0aXNpZ1R5cGUgPSB0aGlzLmJhc2VDb2luLmdldERlZmF1bHRNdWx0aXNpZ1R5cGUoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5iYXNlQ29pbi5nZXRGYW1pbHkoKSA9PT0gJ2xuYnRjJykge1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IGRlY29kZU9yRWxzZShcbiAgICAgICAgR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zQ29kZWMubmFtZSxcbiAgICAgICAgR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zQ29kZWMsXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgKGVycm9ycykgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZXJyb3IocykgcGFyc2luZyBnZW5lcmF0ZSBsaWdodG5pbmcgd2FsbGV0IHJlcXVlc3QgcGFyYW1zOiAke2Vycm9yc31gKTtcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVMaWdodG5pbmdXYWxsZXQob3B0aW9ucyk7XG4gICAgICB3YWxsZXREYXRhLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UgPSB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgICBpbnB1dDogb3B0aW9ucy5wYXNzcGhyYXNlLFxuICAgICAgICBwYXNzd29yZDogb3B0aW9ucy5wYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gd2FsbGV0RGF0YTtcbiAgICB9XG5cbiAgICAvLyBHbyBBY2NvdW50IHdhbGxldCBnZW5lcmF0aW9uXG4gICAgaWYgKHRoaXMuYmFzZUNvaW4uZ2V0RmFtaWx5KCkgPT09ICdvZmMnICYmIHBhcmFtcy50eXBlID09PSAndHJhZGluZycpIHtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBkZWNvZGVPckVsc2UoXG4gICAgICAgIEdlbmVyYXRlR29BY2NvdW50V2FsbGV0T3B0aW9uc0NvZGVjLm5hbWUsXG4gICAgICAgIEdlbmVyYXRlR29BY2NvdW50V2FsbGV0T3B0aW9uc0NvZGVjLFxuICAgICAgICBwYXJhbXMsXG4gICAgICAgIChlcnJvcnMpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVycm9yKHMpIHBhcnNpbmcgZ2VuZXJhdGUgZ28gYWNjb3VudCByZXF1ZXN0IHBhcmFtczogJHtlcnJvcnN9YCk7XG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHdhbGxldERhdGEgPSBhd2FpdCB0aGlzLmdlbmVyYXRlR29BY2NvdW50V2FsbGV0KG9wdGlvbnMpO1xuICAgICAgd2FsbGV0RGF0YS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgaW5wdXQ6IG9wdGlvbnMucGFzc3BocmFzZSxcbiAgICAgICAgcGFzc3dvcmQ6IG9wdGlvbnMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHdhbGxldERhdGE7XG4gICAgfVxuXG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWydsYWJlbCddLCBbJ3Bhc3NwaHJhc2UnLCAndXNlcktleScsICdiYWNrdXBYcHViJ10pO1xuICAgIGlmICh0eXBlb2YgcGFyYW1zLmxhYmVsICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHN0cmluZyBwYXJhbWV0ZXIgbGFiZWwnKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IHR5cGUgPSAnaG90JywgbGFiZWwsIHBhc3NwaHJhc2UsIGVudGVycHJpc2UsIGlzRGlzdHJpYnV0ZWRDdXN0b2R5LCBldm1LZXlSaW5nUmVmZXJlbmNlV2FsbGV0SWQgfSA9IHBhcmFtcztcbiAgICBjb25zdCBpc1RzcyA9IHBhcmFtcy5tdWx0aXNpZ1R5cGUgPT09ICd0c3MnICYmIHRoaXMuYmFzZUNvaW4uc3VwcG9ydHNUc3MoKTtcbiAgICBjb25zdCBjYW5FbmNyeXB0ID0gISFwYXNzcGhyYXNlICYmIHR5cGVvZiBwYXNzcGhyYXNlID09PSAnc3RyaW5nJztcblxuICAgIGlmICh2YWxpZGF0ZUV2bUtleVJpbmdXYWxsZXRQYXJhbXMocGFyYW1zLCB0aGlzLmJhc2VDb2luKSkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNyZWF0ZUV2bUtleVJpbmdXYWxsZXQoe1xuICAgICAgICBsYWJlbCxcbiAgICAgICAgZXZtS2V5UmluZ1JlZmVyZW5jZVdhbGxldElkOiBldm1LZXlSaW5nUmVmZXJlbmNlV2FsbGV0SWQhLFxuICAgICAgICBiaXRnbzogdGhpcy5iaXRnbyxcbiAgICAgICAgYmFzZUNvaW46IHRoaXMuYmFzZUNvaW4sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCB3YWxsZXRQYXJhbXM6IFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICBsYWJlbDogbGFiZWwsXG4gICAgICBtOiAyLFxuICAgICAgbjogMyxcbiAgICAgIGtleXM6IFtdLFxuICAgICAgdHlwZTogISFwYXJhbXMudXNlcktleSAmJiBwYXJhbXMubXVsdGlzaWdUeXBlICE9PSAnb25jaGFpbicgPyAnY29sZCcgOiB0eXBlLFxuICAgIH07XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQocGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUpKSB7XG4gICAgICBpZiAoIV8uaXNTdHJpbmcocGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGFzc2NvZGVFbmNyeXB0aW9uQ29kZSBtdXN0IGJlIGEgc3RyaW5nJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGVudGVycHJpc2UpKSB7XG4gICAgICBpZiAoIV8uaXNTdHJpbmcoZW50ZXJwcmlzZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGVudGVycHJpc2UgYXJndW1lbnQsIGV4cGVjdGluZyBzdHJpbmcnKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5lbnRlcnByaXNlID0gZW50ZXJwcmlzZTtcbiAgICB9XG5cbiAgICAvLyBFVk0gVFNTIHdhbGxldHMgbXVzdCB1c2Ugd2FsbGV0IHZlcnNpb24gMywgNSBhbmQgNlxuICAgIGlmIChcbiAgICAgIGlzVHNzICYmXG4gICAgICB0aGlzLmJhc2VDb2luLmlzRVZNKCkgJiZcbiAgICAgICFldm1LZXlSaW5nUmVmZXJlbmNlV2FsbGV0SWQgJiZcbiAgICAgICEocGFyYW1zLndhbGxldFZlcnNpb24gPT09IDMgfHwgcGFyYW1zLndhbGxldFZlcnNpb24gPT09IDUgfHwgcGFyYW1zLndhbGxldFZlcnNpb24gPT09IDYpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VWTSBUU1Mgd2FsbGV0cyBhcmUgb25seSBzdXBwb3J0ZWQgZm9yIHdhbGxldCB2ZXJzaW9uIDMsIDUgYW5kIDYnKTtcbiAgICB9XG5cbiAgICBpZiAoaXNUc3MpIHtcbiAgICAgIGlmICghdGhpcy5iYXNlQ29pbi5zdXBwb3J0c1RzcygpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY29pbiAke3RoaXMuYmFzZUNvaW4uZ2V0RmFtaWx5KCl9IGRvZXMgbm90IHN1cHBvcnQgVFNTIGF0IHRoaXMgdGltZWApO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICAocGFyYW1zLndhbGxldFZlcnNpb24gPT09IDUgfHwgcGFyYW1zLndhbGxldFZlcnNpb24gPT09IDYpICYmXG4gICAgICAgICF0aGlzLmJhc2VDb2luLmdldENvbmZpZygpLmZlYXR1cmVzLmluY2x1ZGVzKENvaW5GZWF0dXJlLk1QQ1YyKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgY29pbiAke3RoaXMuYmFzZUNvaW4uZ2V0RmFtaWx5KCl9IGRvZXMgbm90IHN1cHBvcnQgVFNTIE1QQ3YyIGF0IHRoaXMgdGltZWApO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KGVudGVycHJpc2UsICdlbnRlcnByaXNlIGlzIHJlcXVpcmVkIGZvciBUU1Mgd2FsbGV0Jyk7XG5cbiAgICAgIGlmICh0eXBlID09PSAnY29sZCcpIHtcbiAgICAgICAgLy8gdmFsaWRhdGVcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy5iaXRnb0tleUlkLCAnYml0Z29LZXlJZCBpcyByZXF1aXJlZCBmb3IgU01DIFRTUyB3YWxsZXQnKTtcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy5jb21tb25LZXljaGFpbiwgJ2NvbW1vbktleWNoYWluIGlzIHJlcXVpcmVkIGZvciBTTUMgVFNTIHdhbGxldCcpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZVNNQ01wY1dhbGxldCh7XG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICBsYWJlbCxcbiAgICAgICAgICBlbnRlcnByaXNlLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IHBhcmFtcy53YWxsZXRWZXJzaW9uLFxuICAgICAgICAgIGJpdGdvS2V5SWQ6IHBhcmFtcy5iaXRnb0tleUlkLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiBwYXJhbXMuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiBwYXJhbXMuY29sZERlcml2YXRpb25TZWVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGUgPT09ICdjdXN0b2RpYWwnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlQ3VzdG9kaWFsTXBjV2FsbGV0KHtcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgIGVudGVycHJpc2UsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogcGFyYW1zLndhbGxldFZlcnNpb24sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBhc3NlcnQocGFzc3BocmFzZSwgJ2Nhbm5vdCBnZW5lcmF0ZSBUU1Mga2V5cyB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICAgIGNvbnN0IHdhbGxldERhdGEgPSBhd2FpdCB0aGlzLmdlbmVyYXRlTXBjV2FsbGV0KHtcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIHBhc3NwaHJhc2UsXG4gICAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICAgIGVudGVycHJpc2UsXG4gICAgICAgIHdhbGxldFZlcnNpb246IHBhcmFtcy53YWxsZXRWZXJzaW9uLFxuICAgICAgfSk7XG4gICAgICBpZiAocGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUpIHtcbiAgICAgICAgd2FsbGV0RGF0YS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogcGFzc3BocmFzZSxcbiAgICAgICAgICBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdhbGxldERhdGE7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGRpc3RyaWJ1dGVkIGN1c3RvZHlcbiAgICBpZiAoaXNEaXN0cmlidXRlZEN1c3RvZHkpIHtcbiAgICAgIGlmICghZW50ZXJwcmlzZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3QgcHJvdmlkZSBlbnRlcnByaXNlIHdoZW4gY3JlYXRpbmcgZGlzdHJpYnV0ZWQgY3VzdG9keSB3YWxsZXQnKTtcbiAgICAgIH1cbiAgICAgIGlmICghdHlwZSB8fCB0eXBlICE9PSAnY29sZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkaXN0cmlidXRlZCBjdXN0b2R5IHdhbGxldHMgbXVzdCBiZSB0eXBlOiBjb2xkJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaGFzQmFja3VwWHB1YiA9ICEhcGFyYW1zLmJhY2t1cFhwdWI7XG4gICAgY29uc3QgaGFzQmFja3VwWHB1YlByb3ZpZGVyID0gISFwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyO1xuICAgIGlmIChoYXNCYWNrdXBYcHViICYmIGhhc0JhY2t1cFhwdWJQcm92aWRlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgcHJvdmlkZSBtb3JlIHRoYW4gb25lIGJhY2t1cFhwdWIgb3IgYmFja3VwWHB1YlByb3ZpZGVyIGZsYWcnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLmdhc1ByaWNlICYmIHBhcmFtcy5laXAxNTU5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbiBub3QgdXNlIGJvdGggZWlwMTU1OSBhbmQgZ2FzUHJpY2UgdmFsdWVzJyk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHBhcmFtcy5kaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zKSkge1xuICAgICAgaWYgKCFfLmlzQm9vbGVhbihwYXJhbXMuZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9ucykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG4gICAgICB9XG4gICAgICB3YWxsZXRQYXJhbXMuZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9ucyA9IHBhcmFtcy5kaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zO1xuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMuZ2FzUHJpY2UpKSB7XG4gICAgICBjb25zdCBnYXNQcmljZUJOID0gbmV3IEJpZ051bWJlcihwYXJhbXMuZ2FzUHJpY2UpO1xuICAgICAgaWYgKGdhc1ByaWNlQk4uaXNOYU4oKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZ2FzIHByaWNlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5nYXNQcmljZSA9IGdhc1ByaWNlQk4udG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQocGFyYW1zLmVpcDE1NTkpICYmICFfLmlzRW1wdHkocGFyYW1zLmVpcDE1NTkpKSB7XG4gICAgICBjb25zdCBtYXhGZWVQZXJHYXNCTiA9IG5ldyBCaWdOdW1iZXIocGFyYW1zLmVpcDE1NTkubWF4RmVlUGVyR2FzKTtcbiAgICAgIGlmIChtYXhGZWVQZXJHYXNCTi5pc05hTigpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBtYXggZmVlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1heFByaW9yaXR5RmVlUGVyR2FzQk4gPSBuZXcgQmlnTnVtYmVyKHBhcmFtcy5laXAxNTU5Lm1heFByaW9yaXR5RmVlUGVyR2FzKTtcbiAgICAgIGlmIChtYXhQcmlvcml0eUZlZVBlckdhc0JOLmlzTmFOKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHByaW9yaXR5IGZlZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG4gICAgICB9XG4gICAgICB3YWxsZXRQYXJhbXMuZWlwMTU1OSA9IHtcbiAgICAgICAgbWF4RmVlUGVyR2FzOiBtYXhGZWVQZXJHYXNCTi50b1N0cmluZygpLFxuICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogbWF4UHJpb3JpdHlGZWVQZXJHYXNCTi50b1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQocGFyYW1zLmRpc2FibGVLUlNFbWFpbCkpIHtcbiAgICAgIGlmICghXy5pc0Jvb2xlYW4ocGFyYW1zLmRpc2FibGVLUlNFbWFpbCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGRpc2FibGVLUlNFbWFpbCBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy5kaXNhYmxlS1JTRW1haWwgPSBwYXJhbXMuZGlzYWJsZUtSU0VtYWlsO1xuICAgIH1cblxuICAgIGlmICghXy5pc1VuZGVmaW5lZChwYXJhbXMud2FsbGV0VmVyc2lvbikpIHtcbiAgICAgIGlmICghXy5pc051bWJlcihwYXJhbXMud2FsbGV0VmVyc2lvbikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHdhbGxldFZlcnNpb24gcHJvdmlkZWQsIGV4cGVjdGluZyBudW1iZXInKTtcbiAgICAgIH1cbiAgICAgIHdhbGxldFBhcmFtcy53YWxsZXRWZXJzaW9uID0gcGFyYW1zLndhbGxldFZlcnNpb247XG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIGVhY2gga3JzU3BlY2lmaWMgcGFyYW0gaXMgZWl0aGVyIGEgc3RyaW5nLCBib29sZWFuLCBvciBudW1iZXJcbiAgICBjb25zdCB7IGtyc1NwZWNpZmljIH0gPSBwYXJhbXM7XG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGtyc1NwZWNpZmljKSkge1xuICAgICAgT2JqZWN0LmtleXMoa3JzU3BlY2lmaWMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBjb25zdCB2YWwgPSBrcnNTcGVjaWZpY1trZXldO1xuICAgICAgICBpZiAoIV8uaXNCb29sZWFuKHZhbCkgJiYgIV8uaXNTdHJpbmcodmFsKSAmJiAhXy5pc051bWJlcih2YWwpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdrcnNTcGVjaWZpYyBvYmplY3QgY29udGFpbnMgaWxsZWdhbCB2YWx1ZXMuIHZhbHVlcyBtdXN0IGJlIHN0cmluZ3MsIGJvb2xlYW5zLCBvciBudW1iZXJzJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGxldCBkZXJpdmF0aW9uUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuXG4gICAgaWYgKHBhcmFtcy50eXBlID09PSAnY3VzdG9kaWFsJyAmJiAocGFyYW1zLm11bHRpc2lnVHlwZSA/PyAnb25jaGFpbicpID09PSAnb25jaGFpbicpIHtcbiAgICAgIC8vIGZvciBjdXN0b2RpYWwgbXVsdGlzaWcsIHdoZW4gdGhlIHdhbGxldCBpcyBjcmVhdGVkIG9uIHRoZSBwbGF0Zm9yIHNpZGUsIHRoZSBrZXlzIGFyZSBub3QgbmVlZGVkXG4gICAgICB3YWxsZXRQYXJhbXMubiA9IHVuZGVmaW5lZDtcbiAgICAgIHdhbGxldFBhcmFtcy5tID0gdW5kZWZpbmVkO1xuICAgICAgd2FsbGV0UGFyYW1zLmtleXMgPSB1bmRlZmluZWQ7XG4gICAgICB3YWxsZXRQYXJhbXMua2V5U2lnbmF0dXJlcyA9IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgbmV3V2FsbGV0ID0gYXdhaXQgdGhpcy5iaXRnby5wb3N0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0L2FkZCcpKS5zZW5kKHdhbGxldFBhcmFtcykucmVzdWx0KCk7IC8vIHJldHVybnMgdGhlIGlkc1xuXG4gICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmdldCh7IGlkOiBuZXdXYWxsZXQua2V5c1tLZXlJbmRpY2VzLlVTRVJdLCByZXFJZCB9KTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleWNoYWluID0gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5nZXQoeyBpZDogbmV3V2FsbGV0LmtleXNbS2V5SW5kaWNlcy5CQUNLVVBdLCByZXFJZCB9KTtcbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW4gPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmdldCh7IGlkOiBuZXdXYWxsZXQua2V5c1tLZXlJbmRpY2VzLkJJVEdPXSwgcmVxSWQgfSk7XG5cbiAgICAgIGNvbnN0IFt1c2VyS2V5LCBiaXRnb0tleSwgYmFja3VwS2V5XSA9IGF3YWl0IFByb21pc2UuYWxsKFt1c2VyS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluXSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdDogV2FsbGV0V2l0aEtleWNoYWlucyA9IHtcbiAgICAgICAgd2FsbGV0OiBuZXcgV2FsbGV0KHRoaXMuYml0Z28sIHRoaXMuYmFzZUNvaW4sIG5ld1dhbGxldCksXG4gICAgICAgIHVzZXJLZXljaGFpbjogdXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IGJpdGdvS2V5LFxuICAgICAgICBiaXRnb0tleWNoYWluOiBiYWNrdXBLZXksXG4gICAgICAgIHJlc3BvbnNlVHlwZTogJ1dhbGxldFdpdGhLZXljaGFpbnMnLFxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IGFzeW5jICgpOiBQcm9taXNlPEtleWNoYWluPiA9PiB7XG4gICAgICAgIGxldCB1c2VyS2V5Y2hhaW5QYXJhbXM7XG4gICAgICAgIGxldCB1c2VyS2V5Y2hhaW47XG4gICAgICAgIC8vIFVzZXIgcHJvdmlkZWQgdXNlciBrZXlcbiAgICAgICAgaWYgKHBhcmFtcy51c2VyS2V5KSB7XG4gICAgICAgICAgdXNlcktleWNoYWluID0geyBwdWI6IHBhcmFtcy51c2VyS2V5IH07XG4gICAgICAgICAgdXNlcktleWNoYWluUGFyYW1zID0gdXNlcktleWNoYWluO1xuICAgICAgICAgIGlmIChwYXJhbXMuY29sZERlcml2YXRpb25TZWVkKSB7XG4gICAgICAgICAgICAvLyB0aGUgZGVyaXZhdGlvbiBvbmx5IG1ha2VzIHNlbnNlIHdoZW4gYSBrZXkgYWxyZWFkeSBleGlzdHNcbiAgICAgICAgICAgIGNvbnN0IGRlcml2YXRpb24gPSB0aGlzLmJhc2VDb2luLmRlcml2ZUtleVdpdGhTZWVkKHtcbiAgICAgICAgICAgICAga2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgICAgICAgc2VlZDogcGFyYW1zLmNvbGREZXJpdmF0aW9uU2VlZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVyaXZhdGlvblBhdGggPSBkZXJpdmF0aW9uLmRlcml2YXRpb25QYXRoO1xuICAgICAgICAgICAgdXNlcktleWNoYWluLnB1YiA9IGRlcml2YXRpb24ua2V5O1xuICAgICAgICAgICAgdXNlcktleWNoYWluLmRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQgPSBwYXJhbXMuY29sZERlcml2YXRpb25TZWVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIWNhbkVuY3J5cHQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGdlbmVyYXRlIHVzZXIga2V5cGFpciB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ3JlYXRlIHRoZSB1c2VyIGtleS5cbiAgICAgICAgICB1c2VyS2V5Y2hhaW4gPSB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICAgIHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYgPSB0aGlzLmJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogcGFzc3BocmFzZSwgaW5wdXQ6IHVzZXJLZXljaGFpbi5wcnYgfSk7XG4gICAgICAgICAgdXNlcktleWNoYWluUGFyYW1zID0ge1xuICAgICAgICAgICAgcHViOiB1c2VyS2V5Y2hhaW4ucHViLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiB1c2VyS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgdXNlcktleWNoYWluUGFyYW1zLnJlcUlkID0gcmVxSWQ7XG4gICAgICAgIGNvbnN0IG5ld1VzZXJLZXljaGFpbiA9IGF3YWl0IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuYWRkKHVzZXJLZXljaGFpblBhcmFtcyk7XG4gICAgICAgIHJldHVybiBfLmV4dGVuZCh7fSwgbmV3VXNlcktleWNoYWluLCB1c2VyS2V5Y2hhaW4pO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gYXN5bmMgKCk6IFByb21pc2U8S2V5Y2hhaW4+ID0+IHtcbiAgICAgICAgaWYgKHBhcmFtcy5iYWNrdXBYcHViUHJvdmlkZXIpIHtcbiAgICAgICAgICAvLyBJZiByZXF1ZXN0ZWQsIHVzZSBhIEtSUyBvciBiYWNrdXAga2V5IHByb3ZpZGVyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlQmFja3VwKHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyIHx8ICdkZWZhdWx0Uk1HQmFja3VwUHJvdmlkZXInLFxuICAgICAgICAgICAgZGlzYWJsZUtSU0VtYWlsOiBwYXJhbXMuZGlzYWJsZUtSU0VtYWlsLFxuICAgICAgICAgICAga3JzU3BlY2lmaWM6IHBhcmFtcy5rcnNTcGVjaWZpYyxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMuYmFzZUNvaW4uZ2V0Q2hhaW4oKSxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6IHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgICAgICAgcmVxSWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVc2VyIHByb3ZpZGVkIGJhY2t1cCB4cHViXG4gICAgICAgIGlmIChwYXJhbXMuYmFja3VwWHB1Yikge1xuICAgICAgICAgIC8vIHVzZXIgcHJvdmlkZWQgYmFja3VwIGV0aGVyZXVtIGFkZHJlc3NcbiAgICAgICAgICByZXR1cm4gdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5hZGQoe1xuICAgICAgICAgICAgcHViOiBwYXJhbXMuYmFja3VwWHB1YixcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICByZXFJZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIWNhbkVuY3J5cHQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGdlbmVyYXRlIGJhY2t1cCBrZXlwYWlyIHdpdGhvdXQgcGFzc3BocmFzZScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBObyBwcm92aWRlZCBiYWNrdXAgeHB1YiBvciBhZGRyZXNzLCBzbyBkZWZhdWx0IHRvIGNyZWF0aW5nIG9uZSBoZXJlXG4gICAgICAgICAgcmV0dXJuIHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlQmFja3VwKHsgcmVxSWQsIHBhc3NwaHJhc2U6IHBhcmFtcy5wYXNzcGhyYXNlIH0pO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgY29uc3QgeyB1c2VyS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluLCBiaXRnb0tleWNoYWluIH06IEtleWNoYWluc1RyaXBsZXQgPSBhd2FpdCBwcm9taXNlUHJvcHMoe1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHVzZXJLZXljaGFpblByb21pc2UoKSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IGJhY2t1cEtleWNoYWluUHJvbWlzZSgpLFxuICAgICAgICBiaXRnb0tleWNoYWluOiB0aGlzLmJhc2VDb2luXG4gICAgICAgICAgLmtleWNoYWlucygpXG4gICAgICAgICAgLmNyZWF0ZUJpdEdvKHsgZW50ZXJwcmlzZTogcGFyYW1zLmVudGVycHJpc2UsIHJlcUlkLCBpc0Rpc3RyaWJ1dGVkQ3VzdG9keTogcGFyYW1zLmlzRGlzdHJpYnV0ZWRDdXN0b2R5IH0pLFxuICAgICAgfSk7XG5cbiAgICAgIHdhbGxldFBhcmFtcy5rZXlzID0gW3VzZXJLZXljaGFpbi5pZCwgYmFja3VwS2V5Y2hhaW4uaWQsIGJpdGdvS2V5Y2hhaW4uaWRdO1xuXG4gICAgICBjb25zdCB7IHBydiB9ID0gdXNlcktleWNoYWluO1xuICAgICAgaWYgKF8uaXNTdHJpbmcocHJ2KSkge1xuICAgICAgICBhc3NlcnQoYmFja3VwS2V5Y2hhaW4ucHViKTtcbiAgICAgICAgYXNzZXJ0KGJpdGdvS2V5Y2hhaW4ucHViKTtcbiAgICAgICAgd2FsbGV0UGFyYW1zLmtleVNpZ25hdHVyZXMgPSB7XG4gICAgICAgICAgYmFja3VwOiAoYXdhaXQgdGhpcy5iYXNlQ29pbi5zaWduTWVzc2FnZSh7IHBydiB9LCBiYWNrdXBLZXljaGFpbi5wdWIpKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgYml0Z286IChhd2FpdCB0aGlzLmJhc2VDb2luLnNpZ25NZXNzYWdlKHsgcHJ2IH0sIGJpdGdvS2V5Y2hhaW4ucHViKSkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBrZXljaGFpbnMgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgICAgYmFja3VwS2V5Y2hhaW4sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBmaW5hbFdhbGxldFBhcmFtcyA9IGF3YWl0IHRoaXMuYmFzZUNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcywga2V5Y2hhaW5zKTtcblxuICAgICAgaWYgKF8uaW5jbHVkZXMoWyd4cnAnLCAneGxtJywgJ2NzcHInXSwgdGhpcy5iYXNlQ29pbi5nZXRGYW1pbHkoKSkgJiYgIV8uaXNVbmRlZmluZWQocGFyYW1zLnJvb3RQcml2YXRlS2V5KSkge1xuICAgICAgICB3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkgPSBwYXJhbXMucm9vdFByaXZhdGVLZXk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihyZXFJZCk7XG4gICAgICBjb25zdCBuZXdXYWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQvYWRkJykpLnNlbmQoZmluYWxXYWxsZXRQYXJhbXMpLnJlc3VsdCgpO1xuXG4gICAgICBjb25zdCByZXN1bHQ6IFdhbGxldFdpdGhLZXljaGFpbnMgPSB7XG4gICAgICAgIHdhbGxldDogbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCBuZXdXYWxsZXQpLFxuICAgICAgICB1c2VyS2V5Y2hhaW46IHVzZXJLZXljaGFpbixcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IGJhY2t1cEtleWNoYWluLFxuICAgICAgICBiaXRnb0tleWNoYWluOiBiaXRnb0tleWNoYWluLFxuICAgICAgICByZXNwb25zZVR5cGU6ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJyxcbiAgICAgIH07XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChiYWNrdXBLZXljaGFpbi5wcnYpKSB7XG4gICAgICAgIHJlc3VsdC53YXJuaW5nID0gJ0JlIHN1cmUgdG8gYmFja3VwIHRoZSBiYWNrdXAga2V5Y2hhaW4gLS0gaXQgaXMgbm90IHN0b3JlZCBhbnl3aGVyZSBlbHNlISc7XG4gICAgICB9XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChkZXJpdmF0aW9uUGF0aCkpIHtcbiAgICAgICAgdXNlcktleWNoYWluLmRlcml2YXRpb25QYXRoID0gZGVyaXZhdGlvblBhdGg7XG4gICAgICB9XG5cbiAgICAgIGlmIChjYW5FbmNyeXB0ICYmIHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlKSB7XG4gICAgICAgIHJlc3VsdC5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlID0gdGhpcy5iaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogcGFzc3BocmFzZSxcbiAgICAgICAgICBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IHRoZSB1c2VyJ3Mgd2FsbGV0IHNoYXJlc1xuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBsaXN0U2hhcmVzKHBhcmFtczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0c2hhcmUnKSkucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCB0aGUgdXNlcidzIHdhbGxldCBzaGFyZXMgdjJcbiAgICogQHJldHVybnMge1Byb21pc2U8V2FsbGV0U2hhcmVzPn1cbiAgICovXG4gIGFzeW5jIGxpc3RTaGFyZXNWMigpOiBQcm9taXNlPFdhbGxldFNoYXJlcz4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJpdGdvLmdldCh0aGlzLmJpdGdvLnVybCgnL3dhbGxldHNoYXJlcycsIDIpKS5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgd2FsbGV0IHNoYXJlIGluZm9ybWF0aW9uLCBpbmNsdWRpbmcgdGhlIGVuY3J5cHRlZCBzaGFyaW5nIGtleWNoYWluLiByZXF1aXJlcyB1bmxvY2sgaWYga2V5Y2hhaW4gaXMgcHJlc2VudC5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldFNoYXJlSWQgLSB0aGUgd2FsbGV0IHNoYXJlIHRvIGdldCBpbmZvcm1hdGlvbiBvblxuICAgKi9cbiAgYXN5bmMgZ2V0U2hhcmUocGFyYW1zOiB7IHdhbGxldFNoYXJlSWQ/OiBzdHJpbmcgfSA9IHt9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb21tb24udmFsaWRhdGVQYXJhbXMocGFyYW1zLCBbJ3dhbGxldFNoYXJlSWQnXSwgW10pO1xuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0c2hhcmUvJyArIHBhcmFtcy53YWxsZXRTaGFyZUlkKSkucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGEgd2FsbGV0IHNoYXJlXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0U2hhcmVJZCAtIHRoZSB3YWxsZXQgc2hhcmUgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBwYXJhbXMuc3RhdGUgLSB0aGUgbmV3IHN0YXRlIG9mIHRoZSB3YWxsZXQgc2hhcmVcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgdXBkYXRlU2hhcmUocGFyYW1zOiBVcGRhdGVTaGFyZU9wdGlvbnMgPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWyd3YWxsZXRTaGFyZUlkJ10sIFtdKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmJpdGdvXG4gICAgICAucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyBwYXJhbXMud2FsbGV0U2hhcmVJZCkpXG4gICAgICAuc2VuZChwYXJhbXMpXG4gICAgICAucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogQnVsayBhY2NlcHQgd2FsbGV0IHNoYXJlc1xuICAgKiBAcGFyYW0gcGFyYW1zIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxCdWxrQWNjZXB0U2hhcmVSZXNwb25zZT59XG4gICAqL1xuICBhc3luYyBidWxrQWNjZXB0U2hhcmVSZXF1ZXN0KHBhcmFtczogQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdFtdKTogUHJvbWlzZTxCdWxrQWNjZXB0U2hhcmVSZXNwb25zZT4ge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmJ1bGtBY2NlcHRTaGFyZVJlcXVlc3RXaXRoUmV0cnkocGFyYW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYnVsa0FjY2VwdFNoYXJlUmVxdWVzdFdpdGhSZXRyeShwYXJhbXM6IEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXSk6IFByb21pc2U8QnVsa0FjY2VwdFNoYXJlUmVzcG9uc2U+IHtcbiAgICAvLyBTZXJ2ZXIgaGFzIGEgbGltaXQgb2YgYXBwcm94aW1hdGVseSAxTUIgZm9yIHBheWxvYWQgc2l6ZVxuICAgIGxldCBNQVhfUEFZTE9BRF9TSVpFID0gOTUwMDAwOyAvLyB+OTUwS0IgdG8gbGVhdmUgc29tZSBidWZmZXJcblxuICAgIC8vIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgc2l6ZSBvZiBhIHBheWxvYWRcbiAgICBjb25zdCBjYWxjdWxhdGVQYXlsb2FkU2l6ZSA9IChpdGVtczogQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdFtdKTogbnVtYmVyID0+IHtcbiAgICAgIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeSh7IGtleXNGb3JXYWxsZXRTaGFyZXM6IGl0ZW1zIH0pLCAndXRmOCcpO1xuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHRzOiBhbnlbXSA9IFtdO1xuICAgIGNvbnN0IHJlbWFpbmluZ1BhcmFtcyA9IFsuLi5wYXJhbXNdO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZ1BhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBCdWlsZCBvcHRpbWFsIGJhdGNoIGJ5IGFkZGluZyBpdGVtcyB1bnRpbCB3ZSByZWFjaCBzaXplIGxpbWl0XG4gICAgICBjb25zdCBiYXRjaDogQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdFtdID0gW107XG4gICAgICAvLyBTdGFydCB3aXRoIGVtcHR5IGJhdGNoXG5cbiAgICAgIC8vIEFkZCBpdGVtcyBvbmUgYnkgb25lIHdoaWxlIG1vbml0b3JpbmcgcGF5bG9hZCBzaXplXG4gICAgICB3aGlsZSAocmVtYWluaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gVGVzdCBhZGRpbmcgdGhlIG5leHQgaXRlbVxuICAgICAgICBjb25zdCB0ZXN0QmF0Y2ggPSBbLi4uYmF0Y2gsIHJlbWFpbmluZ1BhcmFtc1swXV07XG4gICAgICAgIGNvbnN0IHRlc3RTaXplID0gY2FsY3VsYXRlUGF5bG9hZFNpemUodGVzdEJhdGNoKTtcblxuICAgICAgICAvLyBJZiBhZGRpbmcgdGhpcyBpdGVtIHdvdWxkIGV4Y2VlZCB0aGUgc2l6ZSBsaW1pdCwgc3RvcCBhZGRpbmdcbiAgICAgICAgaWYgKHRlc3RTaXplID4gTUFYX1BBWUxPQURfU0laRSAmJiBiYXRjaC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBPdGhlcndpc2UsIGFkZCB0aGUgaXRlbSB0byB0aGUgYmF0Y2hcbiAgICAgICAgYmF0Y2gucHVzaChyZW1haW5pbmdQYXJhbXMuc2hpZnQoKSEpO1xuICAgICAgfVxuXG4gICAgICAvLyBIYW5kbGUgY2FzZSB3aGVyZSBldmVuIGEgc2luZ2xlIGl0ZW0gaXMgdG9vIGxhcmdlXG4gICAgICBpZiAoYmF0Y2gubGVuZ3RoID09PSAwICYmIHJlbWFpbmluZ1BhcmFtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIFNlbmQganVzdCB0aGUgZmlyc3QgaXRlbSBldmVuIGlmIGl0J3Mgb3ZlcnNpemVkXG4gICAgICAgIGJhdGNoLnB1c2gocmVtYWluaW5nUGFyYW1zLnNoaWZ0KCkhKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZE9iaiA9IHsga2V5c0ZvcldhbGxldFNoYXJlczogYmF0Y2ggfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5iaXRnby5wdXQodGhpcy5iaXRnby51cmwoJy93YWxsZXRzaGFyZXMvYWNjZXB0JywgMikpLnNlbmQocGF5bG9hZE9iaikucmVzdWx0KCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcyAmJiBBcnJheS5pc0FycmF5KHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcykpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goLi4ucmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICBpZiAoZXJyb3Iuc3RhdHVzID09PSA0MTMgJiYgYmF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgICAgIC8vIElmIHdlIHN0aWxsIGdldCA0MTMgd2l0aCBtdWx0aXBsZSBpdGVtcywgcHV0IHRoZW0gYmFjayBhbmQgdHJ5IHdpdGggaGFsZiB0aGUgYmF0Y2ggc2l6ZVxuICAgICAgICAgIHJlbWFpbmluZ1BhcmFtcy51bnNoaWZ0KC4uLmJhdGNoKTtcbiAgICAgICAgICBNQVhfUEFZTE9BRF9TSVpFID0gTWF0aC5mbG9vcihNQVhfUEFZTE9BRF9TSVpFIC8gMik7IC8vIFJlZHVjZSBzaXplIGxpbWl0IGZvciBuZXh0IGF0dGVtcHRcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHJlc3VsdHMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QoXG4gICAgcGFyYW1zOiBCdWxrVXBkYXRlV2FsbGV0U2hhcmVPcHRpb25zUmVxdWVzdFtdXG4gICk6IFByb21pc2U8QnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgLnB1dCh0aGlzLmJpdGdvLnVybCgnL3dhbGxldHNoYXJlcy91cGRhdGUnLCAyKSlcbiAgICAgIC5zZW5kKHtcbiAgICAgICAgc2hhcmVzOiBwYXJhbXMsXG4gICAgICB9KVxuICAgICAgLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2VuZCBhIHdhbGxldCBzaGFyZSBpbnZpdGF0aW9uIGVtYWlsXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy53YWxsZXRTaGFyZUlkIC0gdGhlIHdhbGxldCBzaGFyZSB3aG9zZSBpbnZpdGlhdGlvbiBzaG91bGQgYmUgcmVzZW50XG4gICAqL1xuICBhc3luYyByZXNlbmRTaGFyZUludml0ZShwYXJhbXM6IHsgd2FsbGV0U2hhcmVJZD86IHN0cmluZyB9ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbXSk7XG5cbiAgICBjb25zdCB1cmxQYXJ0cyA9IHBhcmFtcy53YWxsZXRTaGFyZUlkICsgJy9yZXNlbmRlbWFpbCc7XG4gICAgcmV0dXJuIHRoaXMuYml0Z28ucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyB1cmxQYXJ0cykpLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBhIHdhbGxldCBzaGFyZVxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0U2hhcmVJZCAtIHRoZSB3YWxsZXQgc2hhcmUgdG8gdXBkYXRlXG4gICAqL1xuICBhc3luYyBjYW5jZWxTaGFyZShwYXJhbXM6IHsgd2FsbGV0U2hhcmVJZD86IHN0cmluZyB9ID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbXSk7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgLmRlbCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldHNoYXJlLycgKyBwYXJhbXMud2FsbGV0U2hhcmVJZCkpXG4gICAgICAuc2VuZCgpXG4gICAgICAucmVzdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogUmUtc2hhcmUgd2FsbGV0IHdpdGggZXhpc3Rpbmcgc3BlbmRlcnMgb2YgdGhlIHdhbGxldFxuICAgKiBAcGFyYW0gd2FsbGV0SWRcbiAgICogQHBhcmFtIHVzZXJQYXNzd29yZFxuICAgKi9cbiAgYXN5bmMgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyh3YWxsZXRJZDogc3RyaW5nLCB1c2VyUGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHdhbGxldCA9IGF3YWl0IHRoaXMuZ2V0KHsgaWQ6IHdhbGxldElkIH0pO1xuICAgIGlmICghd2FsbGV0Py5fd2FsbGV0Py5lbnRlcnByaXNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VudGVycHJpc2Ugbm90IGZvdW5kIGZvciB0aGUgd2FsbGV0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZW50ZXJwcmlzZVVzZXJzUmVzcG9uc2UgPSBhd2FpdCB0aGlzLmJpdGdvXG4gICAgICAuZ2V0KHRoaXMuYml0Z28udXJsKGAvZW50ZXJwcmlzZS8ke3dhbGxldD8uX3dhbGxldD8uZW50ZXJwcmlzZX0vdXNlcmApKVxuICAgICAgLnJlc3VsdCgpO1xuICAgIC8vIGNyZWF0ZSBhIG1hcCBvZiB1c2VycyBmb3IgZWFzeSBsb29rdXAgLSB3ZSBuZWVkIHRoZSB1c2VyIGVtYWlsIGlkIHRvIHNoYXJlIHRoZSB3YWxsZXRcbiAgICBjb25zdCB1c2Vyc01hcCA9IG5ldyBNYXAoXG4gICAgICBbLi4uZW50ZXJwcmlzZVVzZXJzUmVzcG9uc2U/LmFkbWluVXNlcnMsIC4uLmVudGVycHJpc2VVc2Vyc1Jlc3BvbnNlPy5ub25BZG1pblVzZXJzXS5tYXAoKG9iaikgPT4gW29iai5pZCwgb2JqXSlcbiAgICApO1xuXG4gICAgaWYgKHdhbGxldC5fd2FsbGV0LnVzZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHVzZXIgb2Ygd2FsbGV0Ll93YWxsZXQudXNlcnMpIHtcbiAgICAgICAgY29uc3QgdXNlck9iamVjdCA9IHVzZXJzTWFwLmdldCh1c2VyLnVzZXIpO1xuICAgICAgICBpZiAodXNlci5wZXJtaXNzaW9ucy5pbmNsdWRlcygnc3BlbmQnKSAmJiAhdXNlci5wZXJtaXNzaW9ucy5pbmNsdWRlcygnYWRtaW4nKSAmJiB1c2VyT2JqZWN0KSB7XG4gICAgICAgICAgY29uc3Qgc2hhcmVQYXJhbXMgPSB7XG4gICAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgICB1c2VyOiB1c2VyLnVzZXIsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogdXNlci5wZXJtaXNzaW9ucy5qb2luKCcsJyksXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgICAgICBlbWFpbDogdXNlck9iamVjdC5lbWFpbC5lbWFpbCxcbiAgICAgICAgICAgIHJlc2hhcmU6IHRydWUsXG4gICAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgYXdhaXQgd2FsbGV0LnNoYXJlV2FsbGV0KHNoYXJlUGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBY2NlcHRzIGEgd2FsbGV0IHNoYXJlLCBhZGRpbmcgdGhlIHdhbGxldCB0byB0aGUgdXNlcidzIGxpc3RcbiAgICogTmVlZHMgYSB1c2VyJ3MgcGFzc3dvcmQgdG8gZGVjcnlwdCB0aGUgc2hhcmVkIGtleVxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0U2hhcmVJZCAtIHRoZSB3YWxsZXQgc2hhcmUgdG8gYWNjZXB0XG4gICAqIEBwYXJhbSBwYXJhbXMudXNlclBhc3N3b3JkIC0gKHJlcXVpcmVkIGlmIG1vcmUgYSBrZXljaGFpbiB3YXMgc2hhcmVkKSB1c2VyJ3MgcGFzc3dvcmQgdG8gZGVjcnlwdCB0aGUgc2hhcmVkIHdhbGxldFxuICAgKiBAcGFyYW0gcGFyYW1zLm5ld1dhbGxldFBhc3NwaHJhc2UgLSBuZXcgd2FsbGV0IHBhc3NwaHJhc2UgZm9yIHNhdmluZyB0aGUgc2hhcmVkIHdhbGxldCBwcnYuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGxlZnQgYmxhbmsgYW5kIGEgd2FsbGV0IHdpdGggbW9yZSB0aGFuIHZpZXcgcGVybWlzc2lvbnMgd2FzIHNoYXJlZCxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbiB0aGUgdXNlcidzIGxvZ2luIHBhc3N3b3JkIGlzIHVzZWQuXG4gICAqIEBwYXJhbSBwYXJhbXMub3ZlcnJpZGVFbmNyeXB0ZWRQcnYgLSBzZXQgb25seSBpZiB0aGUgcHJ2IHdhcyByZWNlaXZlZCBvdXQtb2YtYmFuZC5cbiAgICovXG4gIGFzeW5jIGFjY2VwdFNoYXJlKHBhcmFtczogQWNjZXB0U2hhcmVPcHRpb25zID0ge30pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbW1vbi52YWxpZGF0ZVBhcmFtcyhwYXJhbXMsIFsnd2FsbGV0U2hhcmVJZCddLCBbJ292ZXJyaWRlRW5jcnlwdGVkUHJ2JywgJ3VzZXJQYXNzd29yZCcsICduZXdXYWxsZXRQYXNzcGhyYXNlJ10pO1xuXG4gICAgbGV0IGVuY3J5cHRlZFBydiA9IHBhcmFtcy5vdmVycmlkZUVuY3J5cHRlZFBydjtcbiAgICBjb25zdCB3YWxsZXRTaGFyZSA9IGF3YWl0IHRoaXMuZ2V0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBwYXJhbXMud2FsbGV0U2hhcmVJZCB9KTtcbiAgICBpZiAoXG4gICAgICB3YWxsZXRTaGFyZS5rZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgJiZcbiAgICAgIHdhbGxldFNoYXJlLnBlcm1pc3Npb25zLmluZGV4T2YoJ2FkbWluJykgIT09IC0xICYmXG4gICAgICB3YWxsZXRTaGFyZS5wZXJtaXNzaW9ucy5pbmRleE9mKCdzcGVuZCcpICE9PSAtMVxuICAgICkge1xuICAgICAgaWYgKF8uaXNVbmRlZmluZWQocGFyYW1zLnVzZXJQYXNzd29yZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1c2VyUGFzc3dvcmQgcGFyYW0gbXVzdCBiZSBwcm92aWRlZCB0byBkZWNyeXB0IHNoYXJlZCBrZXknKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgd2FsbGV0S2V5Y2hhaW4gPSBhd2FpdCB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpbihwYXJhbXMudXNlclBhc3N3b3JkKTtcbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHdhbGxldEtleWNoYWluLmVuY3J5cHRlZFBydikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbmNyeXB0ZWRQcnYgd2FzIG5vdCBmb3VuZCBvbiB3YWxsZXQga2V5Y2hhaW4nKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgdHJhZGluZ0FjY291bnRJZDogd2FsbGV0U2hhcmUud2FsbGV0LFxuICAgICAgICBwdWJrZXk6IHdhbGxldEtleWNoYWluLnB1YixcbiAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgICAgY29uc3QgcGF5bG9hZFN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHBheWxvYWQpO1xuXG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgcGFzc3dvcmQ6IHBhcmFtcy51c2VyUGFzc3dvcmQsXG4gICAgICAgIGlucHV0OiB3YWxsZXRLZXljaGFpbi5lbmNyeXB0ZWRQcnYsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IHRoaXMuYmFzZUNvaW4uc2lnbk1lc3NhZ2UoeyBwcnY6IHByaXZhdGVLZXkgfSwgcGF5bG9hZFN0cmluZyk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy51cGRhdGVTaGFyZSh7XG4gICAgICAgIHdhbGxldFNoYXJlSWQ6IHBhcmFtcy53YWxsZXRTaGFyZUlkLFxuICAgICAgICBzdGF0ZTogJ2FjY2VwdGVkJyxcbiAgICAgICAga2V5SWQ6IHdhbGxldEtleWNoYWluLmlkLFxuICAgICAgICBzaWduYXR1cmU6IHNpZ25hdHVyZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHBheWxvYWQ6IHBheWxvYWRTdHJpbmcsXG4gICAgICB9KTtcbiAgICAgIC8vIElmIHRoZSB3YWxsZXQgc2hhcmUgd2FzIGFjY2VwdGVkIHN1Y2Nlc3NmdWxseSAoY2hhbmdlZD10cnVlKSwgcmVzaGFyZSB0aGUgd2FsbGV0IHdpdGggdGhlIHNwZW5kZXJzXG4gICAgICBpZiAocmVzcG9uc2UuY2hhbmdlZCAmJiByZXNwb25zZS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHRoaXMucmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyh3YWxsZXRTaGFyZS53YWxsZXQsIHBhcmFtcy51c2VyUGFzc3dvcmQpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gVE9ETzogUFgtMzgyNlxuICAgICAgICAgIC8vIERvIG5vdGhpbmdcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbiAgICAvLyBSZXR1cm4gcmlnaHQgYXdheSBpZiB0aGVyZSBpcyBubyBrZXljaGFpbiB0byBkZWNyeXB0LCBvciBpZiBleHBsaWNpdCBlbmNyeXB0ZWRQcnYgd2FzIHByb3ZpZGVkXG4gICAgaWYgKCF3YWxsZXRTaGFyZS5rZXljaGFpbiB8fCAhd2FsbGV0U2hhcmUua2V5Y2hhaW4uZW5jcnlwdGVkUHJ2IHx8IGVuY3J5cHRlZFBydikge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlU2hhcmUoe1xuICAgICAgICB3YWxsZXRTaGFyZUlkOiBwYXJhbXMud2FsbGV0U2hhcmVJZCxcbiAgICAgICAgc3RhdGU6ICdhY2NlcHRlZCcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBNb3JlIHRoYW4gdmlld2luZyB3YXMgcmVxdWVzdGVkLCBzbyB3ZSBuZWVkIHRvIHByb2Nlc3MgdGhlIHdhbGxldCBrZXlzIHVzaW5nIHRoZSBzaGFyZWQgZWNkaCBzY2hlbWVcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChwYXJhbXMudXNlclBhc3N3b3JkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1c2VyUGFzc3dvcmQgcGFyYW0gbXVzdCBiZSBwcm92aWRlZCB0byBkZWNyeXB0IHNoYXJlZCBrZXknKTtcbiAgICB9XG5cbiAgICBjb25zdCBzaGFyaW5nS2V5Y2hhaW4gPSAoYXdhaXQgdGhpcy5iaXRnby5nZXRFQ0RIS2V5Y2hhaW4oKSkgYXMgYW55O1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKHNoYXJpbmdLZXljaGFpbi5lbmNyeXB0ZWRYcHJ2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdlbmNyeXB0ZWRYcHJ2IHdhcyBub3QgZm91bmQgb24gc2hhcmluZyBrZXljaGFpbicpO1xuICAgIH1cblxuICAgIC8vIE5vdyB3ZSBoYXZlIHRoZSBzaGFyaW5nIGtleWNoYWluLCB3ZSBjYW4gd29yayBvdXQgdGhlIHNlY3JldCB1c2VkIGZvciBzaGFyaW5nIHRoZSB3YWxsZXQgd2l0aCB1c1xuICAgIHNoYXJpbmdLZXljaGFpbi5wcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgcGFzc3dvcmQ6IHBhcmFtcy51c2VyUGFzc3dvcmQsXG4gICAgICBpbnB1dDogc2hhcmluZ0tleWNoYWluLmVuY3J5cHRlZFhwcnYsXG4gICAgfSk7XG4gICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KFxuICAgICAgLy8gRGVyaXZlIGtleSBieSBwYXRoICh3aGljaCBpcyB1c2VkIGJldHdlZW4gdGhlc2UgMiB1c2VycyBvbmx5KVxuICAgICAgYmlwMzIuZnJvbUJhc2U1OChzaGFyaW5nS2V5Y2hhaW4ucHJ2KS5kZXJpdmVQYXRoKHNhbml0aXplTGVnYWN5UGF0aCh3YWxsZXRTaGFyZS5rZXljaGFpbi5wYXRoKSksXG4gICAgICBCdWZmZXIuZnJvbSh3YWxsZXRTaGFyZS5rZXljaGFpbi5mcm9tUHViS2V5LCAnaGV4JylcbiAgICApLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgIC8vIFllcyEgV2UgZ290IHRoZSBzZWNyZXQgc3VjY2Vzc2Z1bGx5IGhlcmUsIG5vdyBkZWNyeXB0IHRoZSBzaGFyZWQgd2FsbGV0IHBydlxuICAgIGNvbnN0IGRlY3J5cHRlZFNoYXJlZFdhbGxldFBydiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7XG4gICAgICBwYXNzd29yZDogc2VjcmV0LFxuICAgICAgaW5wdXQ6IHdhbGxldFNoYXJlLmtleWNoYWluLmVuY3J5cHRlZFBydixcbiAgICB9KTtcblxuICAgIC8vIFdlIHdpbGwgbm93IHJlLWVuY3J5cHQgdGhlIHdhbGxldCB3aXRoIG91ciBvd24gcGFzc3dvcmRcbiAgICBjb25zdCBuZXdXYWxsZXRQYXNzcGhyYXNlID0gcGFyYW1zLm5ld1dhbGxldFBhc3NwaHJhc2UgfHwgcGFyYW1zLnVzZXJQYXNzd29yZDtcbiAgICBlbmNyeXB0ZWRQcnYgPSB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgcGFzc3dvcmQ6IG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICBpbnB1dDogZGVjcnlwdGVkU2hhcmVkV2FsbGV0UHJ2LFxuICAgIH0pO1xuICAgIGNvbnN0IHVwZGF0ZVBhcmFtczogVXBkYXRlU2hhcmVPcHRpb25zID0ge1xuICAgICAgd2FsbGV0U2hhcmVJZDogcGFyYW1zLndhbGxldFNoYXJlSWQsXG4gICAgICBzdGF0ZTogJ2FjY2VwdGVkJyxcbiAgICB9O1xuXG4gICAgaWYgKGVuY3J5cHRlZFBydikge1xuICAgICAgdXBkYXRlUGFyYW1zLmVuY3J5cHRlZFBydiA9IGVuY3J5cHRlZFBydjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlU2hhcmUodXBkYXRlUGFyYW1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWxrIEFjY2VwdCB3YWxsZXQgc2hhcmVzLCBhZGRpbmcgdGhlIHdhbGxldHMgdG8gdGhlIHVzZXIncyBsaXN0XG4gICAqIE5lZWRzIGEgdXNlcidzIHBhc3N3b3JkIHRvIGRlY3J5cHQgdGhlIHNoYXJlZCBrZXlcbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyBCdWxrQWNjZXB0U2hhcmVPcHRpb25zXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0U2hhcmVJZCAtIGFycmF5IG9mIHRoZSB3YWxsZXQgc2hhcmVzIHRvIGFjY2VwdFxuICAgKiBAcGFyYW0gcGFyYW1zLnVzZXJQYXNzd29yZCAtIHVzZXIncyBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSBzaGFyZWQgd2FsbGV0IGtleVxuICAgKiBAcGFyYW0gcGFyYW1zLm5ld1dhbGxldFBhc3NwaHJhc2UgLSBuZXcgd2FsbGV0IHBhc3NwaHJhc2UgZm9yIHNhdmluZyB0aGUgc2hhcmVkIHdhbGxldCBwcnYuXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIGxlZnQgYmxhbmsgdGhlbiB0aGUgdXNlcidzIGxvZ2luIHBhc3N3b3JkIGlzIHVzZWQuXG4gICAqXG4gICAqQHJldHVybnMge1Byb21pc2U8QnVsa0FjY2VwdFNoYXJlUmVzcG9uc2U+fVxuICAgKi9cbiAgYXN5bmMgYnVsa0FjY2VwdFNoYXJlKHBhcmFtczogQnVsa0FjY2VwdFNoYXJlT3B0aW9ucyk6IFByb21pc2U8QnVsa0FjY2VwdFNoYXJlUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWyd1c2VyTG9naW5QYXNzd29yZCddLCBbJ25ld1dhbGxldFBhc3NwaHJhc2UnXSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKCduZXdXYWxsZXRQYXNzcGhyYXNlJyBpbiBwYXJhbXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSBhIHZhbGlkIHdhbGxldCBwYXNzcGhyYXNlJyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgdXNlciBsb2dpbiBwYXNzd29yZCcpO1xuICAgIH1cblxuICAgIGFzc2VydChwYXJhbXMud2FsbGV0U2hhcmVJZHMubGVuZ3RoID4gMCwgJ1BsZWFzZSBwcm92aWRlIGF0IGxlYXN0IG9uZSB3YWxsZXQgc2hhcmUgdG8gYWNjZXB0Jyk7XG5cbiAgICBjb25zdCBhbGxXYWxsZXRTaGFyZXMgPSBhd2FpdCB0aGlzLmxpc3RTaGFyZXNWMigpO1xuICAgIGNvbnN0IHdhbGxldFNoYXJlTWFwID0gYWxsV2FsbGV0U2hhcmVzLmluY29taW5nLnJlZHVjZShcbiAgICAgIChtYXA6IHsgW2tleTogc3RyaW5nXTogV2FsbGV0U2hhcmUgfSwgc2hhcmUpID0+ICh7IC4uLm1hcCwgW3NoYXJlLmlkXTogc2hhcmUgfSksXG4gICAgICB7fVxuICAgICk7XG5cbiAgICBjb25zdCB3YWxsZXRTaGFyZXMgPSBwYXJhbXMud2FsbGV0U2hhcmVJZHNcbiAgICAgIC5tYXAoKHdhbGxldFNoYXJlSWQpID0+IHdhbGxldFNoYXJlTWFwW3dhbGxldFNoYXJlSWRdKVxuICAgICAgLmZpbHRlcigod2FsbGV0U2hhcmUpID0+IHdhbGxldFNoYXJlICYmIHdhbGxldFNoYXJlLmtleWNoYWluKTtcblxuICAgIGlmICghd2FsbGV0U2hhcmVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB2YWxpZCB3YWxsZXQgc2hhcmVzIGZvdW5kIHRvIGFjY2VwdCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHNoYXJpbmdLZXljaGFpbiA9IGF3YWl0IHRoaXMuYml0Z28uZ2V0RUNESEtleWNoYWluKCk7XG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2hhcmluZ0tleWNoYWluLmVuY3J5cHRlZFhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgfVxuXG4gICAgc2hhcmluZ0tleWNoYWluLnBydiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7XG4gICAgICBwYXNzd29yZDogcGFyYW1zLnVzZXJMb2dpblBhc3N3b3JkLFxuICAgICAgaW5wdXQ6IHNoYXJpbmdLZXljaGFpbi5lbmNyeXB0ZWRYcHJ2LFxuICAgIH0pO1xuICAgIGNvbnN0IG5ld1dhbGxldFBhc3NwaHJhc2UgPSBwYXJhbXMubmV3V2FsbGV0UGFzc3BocmFzZSB8fCBwYXJhbXMudXNlckxvZ2luUGFzc3dvcmQ7XG4gICAgY29uc3Qga2V5c0ZvcldhbGxldFNoYXJlcyA9IHdhbGxldFNoYXJlcy5mbGF0TWFwKCh3YWxsZXRTaGFyZSkgPT4ge1xuICAgICAgaWYgKCF3YWxsZXRTaGFyZS5rZXljaGFpbikge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoXG4gICAgICAgIGJpcDMyLmZyb21CYXNlNTgoc2hhcmluZ0tleWNoYWluLnBydikuZGVyaXZlUGF0aChzYW5pdGl6ZUxlZ2FjeVBhdGgod2FsbGV0U2hhcmUua2V5Y2hhaW4ucGF0aCkpLFxuICAgICAgICBCdWZmZXIuZnJvbSh3YWxsZXRTaGFyZS5rZXljaGFpbi5mcm9tUHViS2V5LCAnaGV4JylcbiAgICAgICkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBjb25zdCBkZWNyeXB0ZWRTaGFyZWRXYWxsZXRQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICBwYXNzd29yZDogc2VjcmV0LFxuICAgICAgICBpbnB1dDogd2FsbGV0U2hhcmUua2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSB0aGlzLmJpdGdvLmVuY3J5cHQoe1xuICAgICAgICBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgaW5wdXQ6IGRlY3J5cHRlZFNoYXJlZFdhbGxldFBydixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIHdhbGxldFNoYXJlSWQ6IHdhbGxldFNoYXJlLmlkLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmJ1bGtBY2NlcHRTaGFyZVJlcXVlc3Qoa2V5c0ZvcldhbGxldFNoYXJlcyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyBtdWx0aXBsZSB3YWxsZXQgc2hhcmVzIGluIGJ1bGtcbiAgICogVGhpcyBtZXRob2QgYWxsb3dzIHVzZXJzIHRvIGFjY2VwdCBvciByZWplY3QgbXVsdGlwbGUgd2FsbGV0IHNoYXJlcyBpbiBhIHNpbmdsZSBvcGVyYXRpb24uXG4gICAqIEl0IGhhbmRsZXMgZGlmZmVyZW50IHR5cGVzIG9mIHdhbGxldCBzaGFyZXMgaW5jbHVkaW5nIHRob3NlIHJlcXVpcmluZyBzcGVjaWFsIGtleWNoYWluIG92ZXJyaWRlc1xuICAgKiBhbmQgdGhvc2Ugd2l0aCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXlzIHRoYXQgbmVlZCB0byBiZSBkZWNyeXB0ZWQgYW5kIHJlLWVuY3J5cHRlZC5cbiAgICogQWZ0ZXIgcHJvY2Vzc2luZywgaXQgYWxzbyByZXNoYXJlcyBhY2NlcHRlZCB3YWxsZXRzIHdpdGggc3BlbmRlcnMgZm9yIHNwZWNpYWwgb3ZlcnJpZGUgY2FzZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBPcHRpb25zIGZvciBidWxrIHVwZGF0aW5nIHdhbGxldCBzaGFyZXNcbiAgICogQHBhcmFtIHBhcmFtcy5zaGFyZXMgLSBBcnJheSBvZiB3YWxsZXQgc2hhcmVzIHRvIHVwZGF0ZSB3aXRoIHRoZWlyIHN0YXR1cyAoYWNjZXB0L3JlamVjdClcbiAgICogQHBhcmFtIHBhcmFtcy51c2VyTG9naW5QYXNzd29yZCAtIFVzZXIncyBsb2dpbiBwYXNzd29yZCBmb3IgZGVjcnlwdGlvbiBvcGVyYXRpb25zXG4gICAqIEBwYXJhbSBwYXJhbXMubmV3V2FsbGV0UGFzc3BocmFzZSAtIE5ldyB3YWxsZXQgcGFzc3BocmFzZSBmb3IgcmUtZW5jcnlwdGlvblxuICAgKiBAcmV0dXJucyBBcnJheSBvZiByZXNwb25zZXMgZm9yIGVhY2ggd2FsbGV0IHNoYXJlIHVwZGF0ZVxuICAgKi9cbiAgYXN5bmMgYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHBhcmFtczogQnVsa1VwZGF0ZVdhbGxldFNoYXJlT3B0aW9ucyk6IFByb21pc2U8QnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVzcG9uc2U+IHtcbiAgICBpZiAoIXBhcmFtcy5zaGFyZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBwYXJhbWV0ZXI6IHNoYXJlcycpO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShwYXJhbXMuc2hhcmVzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RpbmcgcGFyYW1ldGVyIGFycmF5OiBzaGFyZXMgYnV0IGZvdW5kICcgKyB0eXBlb2YgcGFyYW1zLnNoYXJlcyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgZWFjaCBzaGFyZSBpbiB0aGUgYXJyYXlcbiAgICBmb3IgKGNvbnN0IHNoYXJlIG9mIHBhcmFtcy5zaGFyZXMpIHtcbiAgICAgIGlmICghc2hhcmUud2FsbGV0U2hhcmVJZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgd2FsbGV0U2hhcmVJZCBpbiBzaGFyZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXNoYXJlLnN0YXR1cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc3RhdHVzIGluIHNoYXJlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaGFyZS5zdGF0dXMgIT09ICdhY2NlcHQnICYmIHNoYXJlLnN0YXR1cyAhPT0gJ3JlamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0YXR1cyBpbiBzaGFyZTogJyArIHNoYXJlLnN0YXR1cyArICcuIE11c3QgYmUgZWl0aGVyIFwiYWNjZXB0XCIgb3IgXCJyZWplY3RcIicpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHNoYXJlLndhbGxldFNoYXJlSWQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0aW5nIHdhbGxldFNoYXJlSWQgdG8gYmUgYSBzdHJpbmcgYnV0IGZvdW5kICcgKyB0eXBlb2Ygc2hhcmUud2FsbGV0U2hhcmVJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgb3B0aW9uYWwgcGFyYW1ldGVycyBpZiBwcm92aWRlZFxuICAgIGlmIChwYXJhbXMudXNlckxvZ2luUGFzc3dvcmQgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgcGFyYW1zLnVzZXJMb2dpblBhc3N3b3JkICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdXNlckxvZ2luUGFzc3dvcmQgYnV0IGZvdW5kICcgKyB0eXBlb2YgcGFyYW1zLnVzZXJMb2dpblBhc3N3b3JkKTtcbiAgICB9XG5cbiAgICBpZiAocGFyYW1zLm5ld1dhbGxldFBhc3NwaHJhc2UgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgcGFyYW1zLm5ld1dhbGxldFBhc3NwaHJhc2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiBuZXdXYWxsZXRQYXNzcGhyYXNlIGJ1dCBmb3VuZCAnICsgdHlwZW9mIHBhcmFtcy5uZXdXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICB9XG4gICAgYXNzZXJ0KHBhcmFtcy5zaGFyZXMubGVuZ3RoID4gMCwgJ25vIHNoYXJlcyBhcmUgcGFzc2VkJyk7XG5cbiAgICBjb25zdCB7IHNoYXJlczogaW5wdXRTaGFyZXMsIHVzZXJMb2dpblBhc3N3b3JkLCBuZXdXYWxsZXRQYXNzcGhyYXNlIH0gPSBwYXJhbXM7XG5cbiAgICBjb25zdCBhbGxXYWxsZXRTaGFyZXMgPSBhd2FpdCB0aGlzLmxpc3RTaGFyZXNWMigpO1xuXG4gICAgLy8gT25seSBpbmNsdWRlIHNoYXJlcyB0aGF0IGFyZSBpbiB0aGUgaW5wdXQgYXJyYXkgZm9yIGVmZmljaWVuY3lcbiAgICBjb25zdCBzaGFyZUlkcyA9IG5ldyBTZXQoaW5wdXRTaGFyZXMubWFwKChzaGFyZSkgPT4gc2hhcmUud2FsbGV0U2hhcmVJZCkpO1xuICAgIGNvbnN0IHdhbGxldFNoYXJlTWFwID0gbmV3IE1hcCgpO1xuXG4gICAgYWxsV2FsbGV0U2hhcmVzLmluY29taW5nXG4gICAgICAuZmlsdGVyKChzaGFyZSkgPT4gc2hhcmVJZHMuaGFzKHNoYXJlLmlkKSlcbiAgICAgIC5mb3JFYWNoKChzaGFyZSkgPT4gd2FsbGV0U2hhcmVNYXAuc2V0KHNoYXJlLmlkLCBzaGFyZSkpO1xuXG4gICAgYWxsV2FsbGV0U2hhcmVzLm91dGdvaW5nXG4gICAgICAuZmlsdGVyKChzaGFyZSkgPT4gc2hhcmVJZHMuaGFzKHNoYXJlLmlkKSlcbiAgICAgIC5mb3JFYWNoKChzaGFyZSkgPT4gd2FsbGV0U2hhcmVNYXAuc2V0KHNoYXJlLmlkLCBzaGFyZSkpO1xuXG4gICAgY29uc3QgcmVzb2x2ZWRTaGFyZXMgPSBpbnB1dFNoYXJlcy5tYXAoKHNoYXJlKSA9PiB7XG4gICAgICBjb25zdCB3YWxsZXRTaGFyZSA9IHdhbGxldFNoYXJlTWFwLmdldChzaGFyZS53YWxsZXRTaGFyZUlkKTtcbiAgICAgIGlmICghd2FsbGV0U2hhcmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHdhbGxldCBzaGFyZSBwcm92aWRlZDogJHtzaGFyZS53YWxsZXRTaGFyZUlkfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgLi4uc2hhcmUsIHdhbGxldFNoYXJlIH07XG4gICAgfSk7XG5cbiAgICAvLyBJZGVudGlmeSBzcGVjaWFsIG92ZXJyaWRlIGNhc2VzIHRoYXQgbmVlZCByZXNoYXJpbmcgYWZ0ZXIgYWNjZXB0YW5jZVxuICAgIGNvbnN0IHNwZWNpYWxPdmVycmlkZUNhc2VzID0gbmV3IE1hcCgpO1xuICAgIHJlc29sdmVkU2hhcmVzLmZvckVhY2goKHNoYXJlKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHNoYXJlLnN0YXR1cyA9PT0gJ2FjY2VwdCcgJiZcbiAgICAgICAgc2hhcmUud2FsbGV0U2hhcmUua2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkICYmXG4gICAgICAgIHNoYXJlLndhbGxldFNoYXJlLnBlcm1pc3Npb25zLmluY2x1ZGVzKCdhZG1pbicpICYmXG4gICAgICAgIHNoYXJlLndhbGxldFNoYXJlLnBlcm1pc3Npb25zLmluY2x1ZGVzKCdzcGVuZCcpXG4gICAgICApIHtcbiAgICAgICAgc3BlY2lhbE92ZXJyaWRlQ2FzZXMuc2V0KHNoYXJlLndhbGxldFNoYXJlSWQsIHNoYXJlLndhbGxldFNoYXJlLndhbGxldCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBEZWNyeXB0IHNoYXJpbmcga2V5Y2hhaW4gaWYgbmVlZGVkIChvbmx5IG9uY2UpXG4gICAgbGV0IHNoYXJpbmdLZXljaGFpblBydjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gT25seSBkZWNyeXB0IGlmIHRoZXJlIGFyZSBzaGFyZXMgdG8gYWNjZXB0IHRoYXQgbWlnaHQgbmVlZCBpdFxuICAgIGNvbnN0IGhhc1NoYXJlc1JlcXVpcmluZ0RlY3J5cHRpb24gPVxuICAgICAgc3BlY2lhbE92ZXJyaWRlQ2FzZXMuc2l6ZSA+IDAgfHxcbiAgICAgIHJlc29sdmVkU2hhcmVzLnNvbWUoKHNoYXJlKSA9PiBzaGFyZS5zdGF0dXMgPT09ICdhY2NlcHQnICYmIHNoYXJlLndhbGxldFNoYXJlLmtleWNoYWluPy5lbmNyeXB0ZWRQcnYpO1xuXG4gICAgaWYgKHVzZXJMb2dpblBhc3N3b3JkICYmIGhhc1NoYXJlc1JlcXVpcmluZ0RlY3J5cHRpb24pIHtcbiAgICAgIGNvbnN0IHNoYXJpbmdLZXljaGFpbiA9IGF3YWl0IHRoaXMuYml0Z28uZ2V0RUNESEtleWNoYWluKCk7XG4gICAgICBpZiAoIXNoYXJpbmdLZXljaGFpbi5lbmNyeXB0ZWRYcHJ2KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZW5jcnlwdGVkWHBydiB3YXMgbm90IGZvdW5kIG9uIHNoYXJpbmcga2V5Y2hhaW4nKTtcbiAgICAgIH1cbiAgICAgIHNoYXJpbmdLZXljaGFpblBydiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7XG4gICAgICAgIHBhc3N3b3JkOiB1c2VyTG9naW5QYXNzd29yZCxcbiAgICAgICAgaW5wdXQ6IHNoYXJpbmdLZXljaGFpbi5lbmNyeXB0ZWRYcHJ2LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2V0dGxlZFVwZGF0ZXMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICByZXNvbHZlZFNoYXJlcy5tYXAoYXN5bmMgKHNoYXJlKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgd2FsbGV0U2hhcmVJZCwgc3RhdHVzLCB3YWxsZXRTaGFyZSB9ID0gc2hhcmU7XG5cbiAgICAgICAgLy8gSGFuZGxlIGFjY2VwdCBjYXNlXG4gICAgICAgIGlmIChzdGF0dXMgPT09ICdhY2NlcHQnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0FjY2VwdFNoYXJlKFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZCxcbiAgICAgICAgICAgIHdhbGxldFNoYXJlLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQsXG4gICAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgc2hhcmluZ0tleWNoYWluUHJ2XG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSByZWplY3QgY2FzZVxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWQsXG4gICAgICAgICAgICBzdGF0dXM6ICdyZWplY3QnIGFzIGNvbnN0LFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBFeHRyYWN0IHN1Y2Nlc3NmdWwgdXBkYXRlc1xuICAgIGNvbnN0IHN1Y2Nlc3NmdWxVcGRhdGVzID0gc2V0dGxlZFVwZGF0ZXMuZmxhdE1hcCgocmVzdWx0KSA9PiAocmVzdWx0LnN0YXR1cyA9PT0gJ2Z1bGZpbGxlZCcgPyByZXN1bHQudmFsdWUgOiBbXSkpO1xuXG4gICAgLy8gRXh0cmFjdCBmYWlsZWQgdXBkYXRlcyAtIG9ubHkgZnJvbSByZWplY3RlZCBwcm9taXNlc1xuICAgIGNvbnN0IGZhaWxlZFVwZGF0ZXMgPSBzZXR0bGVkVXBkYXRlcy5yZWR1Y2U8QXJyYXk8eyB3YWxsZXRTaGFyZUlkOiBzdHJpbmc7IHJlYXNvbjogc3RyaW5nIH0+PihcbiAgICAgIChhY2MsIHJlc3VsdCwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdyZWplY3RlZCcpIHtcbiAgICAgICAgICBjb25zdCByZWplY3RlZFJlc3VsdCA9IHJlc3VsdDtcbiAgICAgICAgICBhY2MucHVzaCh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiByZXNvbHZlZFNoYXJlc1tpbmRleF0ud2FsbGV0U2hhcmVJZCxcbiAgICAgICAgICAgIHJlYXNvbjogcmVqZWN0ZWRSZXN1bHQucmVhc29uPy5tZXNzYWdlIHx8IFN0cmluZyhyZWplY3RlZFJlc3VsdC5yZWFzb24pLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgW11cbiAgICApO1xuXG4gICAgLy8gU2VuZCBzdWNjZXNzZnVsIHVwZGF0ZXMgdG8gdGhlIHNlcnZlclxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5idWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0KHN1Y2Nlc3NmdWxVcGRhdGVzKTtcblxuICAgIC8vIFByb2Nlc3MgYWNjZXB0ZWQgc3BlY2lhbCBvdmVycmlkZSBjYXNlcyAtIHJlc2hhcmUgd2l0aCBzcGVuZGVyc1xuICAgIGlmIChyZXNwb25zZS5hY2NlcHRlZFdhbGxldFNoYXJlcyAmJiByZXNwb25zZS5hY2NlcHRlZFdhbGxldFNoYXJlcy5sZW5ndGggPiAwICYmIHVzZXJMb2dpblBhc3N3b3JkKSB7XG4gICAgICAvLyBGb3IgZWFjaCBhY2NlcHRlZCB3YWxsZXQgc2hhcmUgdGhhdCBpcyBhIHNwZWNpYWwgb3ZlcnJpZGUgY2FzZSwgcmVzaGFyZSB3aXRoIHNwZW5kZXJzXG4gICAgICBmb3IgKGNvbnN0IHdhbGxldFNoYXJlSWQgb2YgcmVzcG9uc2UuYWNjZXB0ZWRXYWxsZXRTaGFyZXMpIHtcbiAgICAgICAgaWYgKHNwZWNpYWxPdmVycmlkZUNhc2VzLmhhcyh3YWxsZXRTaGFyZUlkKSkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldElkID0gc3BlY2lhbE92ZXJyaWRlQ2FzZXMuZ2V0KHdhbGxldFNoYXJlSWQpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMod2FsbGV0SWQsIHVzZXJMb2dpblBhc3N3b3JkKTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBMb2cgZXJyb3IgYnV0IGNvbnRpbnVlIHByb2Nlc3Npbmcgb3RoZXIgc2hhcmVzXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciByZXNoYXJpbmcgd2FsbGV0ICR7d2FsbGV0SWR9IHdpdGggc3BlbmRlcnM6ICR7ZT8ubWVzc2FnZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgaW5mb3JtYXRpb24gYWJvdXQgZmFpbGVkIHVwZGF0ZXMgdG8gdGhlIHJlc3BvbnNlXG4gICAgaWYgKGZhaWxlZFVwZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgcmVzcG9uc2Uud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMucHVzaCguLi5mYWlsZWRVcGRhdGVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICAvKipcbiAgICogUHJvY2VzcyBhIHdhbGxldCBzaGFyZSB0aGF0IGlzIGJlaW5nIGFjY2VwdGVkXG4gICAqIFRoaXMgbWV0aG9kIGhhbmRsZXMgdGhlIGRpZmZlcmVudCBjYXNlcyBmb3IgYWNjZXB0aW5nIGEgd2FsbGV0IHNoYXJlOlxuICAgKiAxLiBTcGVjaWFsIG92ZXJyaWRlIGNhc2UgcmVxdWlyaW5nIHVzZXIga2V5Y2hhaW4gYW5kIHNpZ25pbmdcbiAgICogMi4gU2ltcGxlIGNhc2Ugd2l0aCBubyBrZXljaGFpbiB0byBkZWNyeXB0XG4gICAqIDMuIFN0YW5kYXJkIGNhc2UgcmVxdWlyaW5nIGRlY3J5cHRpb24gYW5kIHJlLWVuY3J5cHRpb25cbiAgICpcbiAgICogQHBhcmFtIHdhbGxldFNoYXJlSWQgLSBJRCBvZiB0aGUgd2FsbGV0IHNoYXJlXG4gICAqIEBwYXJhbSB3YWxsZXRTaGFyZSAtIFdhbGxldCBzaGFyZSBvYmplY3RcbiAgICogQHBhcmFtIHVzZXJMb2dpblBhc3N3b3JkIC0gVXNlcidzIGxvZ2luIHBhc3N3b3JkXG4gICAqIEBwYXJhbSBuZXdXYWxsZXRQYXNzcGhyYXNlIC0gTmV3IHdhbGxldCBwYXNzcGhyYXNlXG4gICAqIEBwYXJhbSBzaGFyaW5nS2V5Y2hhaW5QcnYgLSBEZWNyeXB0ZWQgc2hhcmluZyBrZXljaGFpbiBwcml2YXRlIGtleVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiB3YWxsZXQgc2hhcmUgdXBkYXRlIHJlcXVlc3RzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NBY2NlcHRTaGFyZShcbiAgICB3YWxsZXRTaGFyZUlkOiBzdHJpbmcsXG4gICAgd2FsbGV0U2hhcmU6IFdhbGxldFNoYXJlLFxuICAgIHVzZXJMb2dpblBhc3N3b3JkPzogc3RyaW5nLFxuICAgIG5ld1dhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmcsXG4gICAgc2hhcmluZ0tleWNoYWluUHJ2Pzogc3RyaW5nXG4gICk6IFByb21pc2U8QnVsa1VwZGF0ZVdhbGxldFNoYXJlT3B0aW9uc1JlcXVlc3RbXT4ge1xuICAgIC8vIFNwZWNpYWwgb3ZlcnJpZGUgY2FzZTogcmVxdWlyZXMgdXNlciBrZXljaGFpbiBhbmQgc2lnbmluZ1xuICAgIGlmIChcbiAgICAgIHdhbGxldFNoYXJlLmtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZCAmJlxuICAgICAgd2FsbGV0U2hhcmUucGVybWlzc2lvbnMuaW5jbHVkZXMoJ2FkbWluJykgJiZcbiAgICAgIHdhbGxldFNoYXJlLnBlcm1pc3Npb25zLmluY2x1ZGVzKCdzcGVuZCcpXG4gICAgKSB7XG4gICAgICBpZiAoIXVzZXJMb2dpblBhc3N3b3JkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndXNlckxvZ2luUGFzc3dvcmQgcGFyYW0gbXVzdCBiZSBwcm92aWRlZCB0byBkZWNyeXB0IHNoYXJlZCBrZXknKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgd2FsbGV0S2V5Y2hhaW4gPSBhd2FpdCB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpbih1c2VyTG9naW5QYXNzd29yZCk7XG4gICAgICBpZiAoIXdhbGxldEtleWNoYWluLmVuY3J5cHRlZFBydikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2VuY3J5cHRlZFBydiB3YXMgbm90IGZvdW5kIG9uIHdhbGxldCBrZXljaGFpbicpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB0cmFkaW5nQWNjb3VudElkOiB3YWxsZXRTaGFyZS53YWxsZXQsXG4gICAgICAgIHB1YmtleTogd2FsbGV0S2V5Y2hhaW4ucHViLFxuICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoe1xuICAgICAgICBwYXNzd29yZDogdXNlckxvZ2luUGFzc3dvcmQsXG4gICAgICAgIGlucHV0OiB3YWxsZXRLZXljaGFpbi5lbmNyeXB0ZWRQcnYsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgdGhpcy5iYXNlQ29pbi5zaWduTWVzc2FnZSh7IHBydiB9LCBwYXlsb2FkKTtcblxuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIHdhbGxldFNoYXJlSWQsXG4gICAgICAgICAgc3RhdHVzOiAnYWNjZXB0JyBhcyBjb25zdCxcbiAgICAgICAgICBrZXlJZDogd2FsbGV0S2V5Y2hhaW4uaWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBzaWduYXR1cmUudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIC8vIFJldHVybiByaWdodCBhd2F5IGlmIHRoZXJlIGlzIG5vIGtleWNoYWluIHRvIGRlY3J5cHRcbiAgICBpZiAoIXdhbGxldFNoYXJlLmtleWNoYWluIHx8ICF3YWxsZXRTaGFyZS5rZXljaGFpbi5lbmNyeXB0ZWRQcnYpIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkLFxuICAgICAgICAgIHN0YXR1czogJ2FjY2VwdCcgYXMgY29uc3QsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIC8vIE1vcmUgdGhhbiB2aWV3aW5nIHdhcyByZXF1ZXN0ZWQsIHNvIHdlIG5lZWQgdG8gcHJvY2VzcyB0aGUgd2FsbGV0IGtleXMgdXNpbmcgdGhlIHNoYXJlZCBlY2RoIHNjaGVtZVxuICAgIGlmICghdXNlckxvZ2luUGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXNlckxvZ2luUGFzc3dvcmQgcGFyYW0gbXVzdCBiZSBwcm92aWRlZCB0byBkZWNyeXB0IHNoYXJlZCBrZXknKTtcbiAgICB9XG4gICAgaWYgKCFzaGFyaW5nS2V5Y2hhaW5QcnYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIHJldHJpZXZlIGFuZCBkZWNyeXB0IHNoYXJpbmcga2V5Y2hhaW4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXJpdmVkS2V5ID0gYmlwMzIuZnJvbUJhc2U1OChzaGFyaW5nS2V5Y2hhaW5QcnYpLmRlcml2ZVBhdGgoc2FuaXRpemVMZWdhY3lQYXRoKHdhbGxldFNoYXJlLmtleWNoYWluLnBhdGgpKTtcblxuICAgIGNvbnN0IHNoYXJlZFNlY3JldCA9IGdldFNoYXJlZFNlY3JldChkZXJpdmVkS2V5LCBCdWZmZXIuZnJvbSh3YWxsZXRTaGFyZS5rZXljaGFpbi5mcm9tUHViS2V5LCAnaGV4JykpLnRvU3RyaW5nKFxuICAgICAgJ2hleCdcbiAgICApO1xuXG4gICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgIHBhc3N3b3JkOiBzaGFyZWRTZWNyZXQsXG4gICAgICBpbnB1dDogd2FsbGV0U2hhcmUua2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LFxuICAgIH0pO1xuXG4gICAgLy8gV2Ugd2lsbCBub3cgcmUtZW5jcnlwdCB0aGUgd2FsbGV0IHdpdGggb3VyIG93biBwYXNzd29yZFxuICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IHRoaXMuYml0Z28uZW5jcnlwdCh7XG4gICAgICBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB8fCB1c2VyTG9naW5QYXNzd29yZCxcbiAgICAgIGlucHV0OiBkZWNyeXB0ZWRQcnYsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB3YWxsZXRTaGFyZUlkLFxuICAgICAgICBzdGF0dXM6ICdhY2NlcHQnIGFzIGNvbnN0LFxuICAgICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgICB9LFxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgd2FsbGV0IGJ5IGl0cyBJRFxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMuaWQgd2FsbGV0IGlkXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgYXN5bmMgZ2V0V2FsbGV0KHBhcmFtczogR2V0V2FsbGV0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxXYWxsZXQ+IHtcbiAgICBjb21tb24udmFsaWRhdGVQYXJhbXMocGFyYW1zLCBbJ2lkJ10sIFtdKTtcblxuICAgIGNvbnN0IHF1ZXJ5OiBHZXRXYWxsZXRPcHRpb25zID0ge307XG4gICAgaWYgKHBhcmFtcy5hbGxUb2tlbnMpIHtcbiAgICAgIGlmICghXy5pc0Jvb2xlYW4ocGFyYW1zLmFsbFRva2VucykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGFsbFRva2VucyBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcbiAgICAgIH1cbiAgICAgIHF1ZXJ5LmFsbFRva2VucyA9IHBhcmFtcy5hbGxUb2tlbnM7XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtcy5pbmNsdWRlQmFsYW5jZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBxdWVyeS5pbmNsdWRlQmFsYW5jZSA9IHBhcmFtcy5pbmNsdWRlQmFsYW5jZTtcbiAgICB9XG5cbiAgICB0aGlzLmJpdGdvLnNldFJlcXVlc3RUcmFjZXIocGFyYW1zLnJlcUlkIHx8IG5ldyBSZXF1ZXN0VHJhY2VyKCkpO1xuXG4gICAgY29uc3Qgd2FsbGV0ID0gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgLmdldCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC8nICsgcGFyYW1zLmlkKSlcbiAgICAgIC5xdWVyeShxdWVyeSlcbiAgICAgIC5yZXN1bHQoKTtcbiAgICByZXR1cm4gbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCB3YWxsZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHdhbGxldCBieSBpdHMgYWRkcmVzc1xuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwYXJhbSBwYXJhbXMuYWRkcmVzcyB3YWxsZXQgYWRkcmVzc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIGdldFdhbGxldEJ5QWRkcmVzcyhwYXJhbXM6IEdldFdhbGxldEJ5QWRkcmVzc09wdGlvbnMgPSB7fSk6IFByb21pc2U8V2FsbGV0PiB7XG4gICAgY29tbW9uLnZhbGlkYXRlUGFyYW1zKHBhcmFtcywgWydhZGRyZXNzJ10sIFtdKTtcblxuICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihwYXJhbXMucmVxSWQgfHwgbmV3IFJlcXVlc3RUcmFjZXIoKSk7XG5cbiAgICBjb25zdCB3YWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLmdldCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC9hZGRyZXNzLycgKyBwYXJhbXMuYWRkcmVzcykpLnJlc3VsdCgpO1xuICAgIHJldHVybiBuZXcgV2FsbGV0KHRoaXMuYml0Z28sIHRoaXMuYmFzZUNvaW4sIHdhbGxldCk7XG4gIH1cblxuICAvKipcbiAgICogRm9yIGFueSBnaXZlbiBzdXBwb3J0ZWQgY29pbiwgZ2V0IHRvdGFsIGJhbGFuY2VzIGZvciBhbGwgd2FsbGV0cyBvZiB0aGF0XG4gICAqIGNvaW4gdHlwZSBvbiB0aGUgYWNjb3VudC5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIGdldFRvdGFsQmFsYW5jZXMocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBuZXZlcj4gPSB7fSk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMuYmFzZUNvaW4udXJsKCcvd2FsbGV0L2JhbGFuY2VzJykpLnJlc3VsdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhIFRTUyBvciBCTFMtREtHIFdhbGxldC5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZU1wY1dhbGxldCh7XG4gICAgcGFzc3BocmFzZSxcbiAgICBsYWJlbCxcbiAgICBtdWx0aXNpZ1R5cGUsXG4gICAgZW50ZXJwcmlzZSxcbiAgICB3YWxsZXRWZXJzaW9uLFxuICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZSxcbiAgfTogR2VuZXJhdGVNcGNXYWxsZXRPcHRpb25zKTogUHJvbWlzZTxXYWxsZXRXaXRoS2V5Y2hhaW5zPiB7XG4gICAgaWYgKG11bHRpc2lnVHlwZSA9PT0gJ3RzcycgJiYgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSA9PT0gJ2VjZHNhJykge1xuICAgICAgY29uc3QgdHNzU2V0dGluZ3M6IFRzc1NldHRpbmdzID0gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgICAuZ2V0KHRoaXMuYml0Z28ubWljcm9zZXJ2aWNlc1VybCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKSlcbiAgICAgICAgLnJlc3VsdCgpO1xuICAgICAgY29uc3QgbXVsdGlzaWdUeXBlVmVyc2lvbiA9XG4gICAgICAgIHRzc1NldHRpbmdzLmNvaW5TZXR0aW5nc1t0aGlzLmJhc2VDb2luLmdldEZhbWlseSgpXT8ud2FsbGV0Q3JlYXRpb25TZXR0aW5ncz8ubXVsdGlTaWdUeXBlVmVyc2lvbjtcbiAgICAgIHdhbGxldFZlcnNpb24gPSB0aGlzLmRldGVybWluZUVjZHNhTXBjV2FsbGV0VmVyc2lvbih3YWxsZXRWZXJzaW9uLCBtdWx0aXNpZ1R5cGVWZXJzaW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcblxuICAgIC8vIENyZWF0ZSBNUEMgS2V5Y2hhaW5zXG4gICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgbXVsdGlzaWdUeXBlLFxuICAgICAgcGFzc3BocmFzZSxcbiAgICAgIGVudGVycHJpc2UsXG4gICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUsXG4gICAgfSk7XG5cbiAgICAvLyBDcmVhdGUgV2FsbGV0XG4gICAgY29uc3QgeyB1c2VyS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluLCBiaXRnb0tleWNoYWluIH0gPSBrZXljaGFpbnM7XG4gICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgbGFiZWwsXG4gICAgICBtOiAyLFxuICAgICAgbjogMyxcbiAgICAgIGtleXM6IFt1c2VyS2V5Y2hhaW4uaWQsIGJhY2t1cEtleWNoYWluLmlkLCBiaXRnb0tleWNoYWluLmlkXSxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgbXVsdGlzaWdUeXBlLFxuICAgICAgZW50ZXJwcmlzZSxcbiAgICAgIHdhbGxldFZlcnNpb24sXG4gICAgfTtcbiAgICBjb25zdCBmaW5hbFdhbGxldFBhcmFtcyA9IGF3YWl0IHRoaXMuYmFzZUNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcywga2V5Y2hhaW5zKTtcbiAgICBjb25zdCBuZXdXYWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQvYWRkJykpLnNlbmQoZmluYWxXYWxsZXRQYXJhbXMpLnJlc3VsdCgpO1xuXG4gICAgY29uc3QgcmVzdWx0OiBXYWxsZXRXaXRoS2V5Y2hhaW5zID0ge1xuICAgICAgd2FsbGV0OiBuZXcgV2FsbGV0KHRoaXMuYml0Z28sIHRoaXMuYmFzZUNvaW4sIG5ld1dhbGxldCksXG4gICAgICB1c2VyS2V5Y2hhaW4sXG4gICAgICBiYWNrdXBLZXljaGFpbixcbiAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICByZXNwb25zZVR5cGU6ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJyxcbiAgICB9O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKGJhY2t1cEtleWNoYWluLnBydikpIHtcbiAgICAgIHJlc3VsdC53YXJuaW5nID0gJ0JlIHN1cmUgdG8gYmFja3VwIHRoZSBiYWNrdXAga2V5Y2hhaW4gLS0gaXQgaXMgbm90IHN0b3JlZCBhbnl3aGVyZSBlbHNlISc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSBTZWxmLU1hbmFnZWQgQ29sZCBUU1MgV2FsbGV0LlxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlU01DTXBjV2FsbGV0KHtcbiAgICBsYWJlbCxcbiAgICBtdWx0aXNpZ1R5cGUsXG4gICAgZW50ZXJwcmlzZSxcbiAgICB3YWxsZXRWZXJzaW9uLFxuICAgIGJpdGdvS2V5SWQsXG4gICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgY29sZERlcml2YXRpb25TZWVkLFxuICB9OiBHZW5lcmF0ZVNNQ01wY1dhbGxldE9wdGlvbnMpOiBQcm9taXNlPFdhbGxldFdpdGhLZXljaGFpbnM+IHtcbiAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcblxuICAgIGxldCBtdWx0aXNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInIHwgdW5kZWZpbmVkO1xuICAgIGlmIChtdWx0aXNpZ1R5cGUgPT09ICd0c3MnICYmIHRoaXMuYmFzZUNvaW4uZ2V0TVBDQWxnb3JpdGhtKCkgPT09ICdlY2RzYScpIHtcbiAgICAgIGNvbnN0IHRzc1NldHRpbmdzOiBUc3NTZXR0aW5ncyA9IGF3YWl0IHRoaXMuYml0Z29cbiAgICAgICAgLmdldCh0aGlzLmJpdGdvLm1pY3Jvc2VydmljZXNVcmwoJy9hcGkvdjIvdHNzL3NldHRpbmdzJykpXG4gICAgICAgIC5yZXN1bHQoKTtcbiAgICAgIG11bHRpc2lnVHlwZVZlcnNpb24gPVxuICAgICAgICB0c3NTZXR0aW5ncy5jb2luU2V0dGluZ3NbdGhpcy5iYXNlQ29pbi5nZXRGYW1pbHkoKV0/LndhbGxldENyZWF0aW9uU2V0dGluZ3M/LmNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uO1xuICAgICAgd2FsbGV0VmVyc2lvbiA9IHRoaXMuZGV0ZXJtaW5lRWNkc2FNcGNXYWxsZXRWZXJzaW9uKHdhbGxldFZlcnNpb24sIG11bHRpc2lnVHlwZVZlcnNpb24pO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBNUEMgS2V5Y2hhaW5zXG4gICAgY29uc3QgYml0Z29LZXljaGFpbiA9IGF3YWl0IHRoaXMuYmFzZUNvaW4ua2V5Y2hhaW5zKCkuZ2V0KHsgaWQ6IGJpdGdvS2V5SWQgfSk7XG5cbiAgICBpZiAoIWJpdGdvS2V5Y2hhaW4gfHwgIWJpdGdvS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQml0R28ga2V5Y2hhaW4gbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgaWYgKGJpdGdvS2V5Y2hhaW4uc291cmNlICE9PSAnYml0Z28nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBwcm92aWRlZCBiaXRnb0tleUlkIGlzIG5vdCBhIEJpdEdvIGtleWNoYWluJyk7XG4gICAgfVxuXG4gICAgaWYgKGJpdGdvS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4gIT09IGNvbW1vbktleWNoYWluKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBwcm92aWRlZCBDb21tb24ga2V5Y2hhaW4gbWlzbWF0Y2ggd2l0aCB0aGUgcHJvdmlkZWQgQml0Z28ga2V5Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFjb2xkRGVyaXZhdGlvblNlZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJLZXljaGFpblBhcmFtczogQWRkS2V5Y2hhaW5PcHRpb25zID0ge1xuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgIGNvbW1vbktleWNoYWluOiBjb21tb25LZXljaGFpbixcbiAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IGNvbGREZXJpdmF0aW9uU2VlZCxcbiAgICAgIGlzTVBDdjI6IG11bHRpc2lnVHlwZVZlcnNpb24gPT09ICdNUEN2MicgPyB0cnVlIDogdW5kZWZpbmVkLFxuICAgIH07XG4gICAgY29uc3QgdXNlcktleWNoYWluID0gYXdhaXQgdGhpcy5iYXNlQ29pbi5rZXljaGFpbnMoKS5hZGQodXNlcktleWNoYWluUGFyYW1zKTtcblxuICAgIGNvbnN0IGJhY2t1cEtleUNoYWluUGFyYW1zOiBBZGRLZXljaGFpbk9wdGlvbnMgPSB7XG4gICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAga2V5VHlwZTogJ3RzcycsXG4gICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBjb2xkRGVyaXZhdGlvblNlZWQsXG4gICAgICBpc01QQ3YyOiBtdWx0aXNpZ1R5cGVWZXJzaW9uID09PSAnTVBDdjInID8gdHJ1ZSA6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgY29uc3QgYmFja3VwS2V5Y2hhaW4gPSBhd2FpdCB0aGlzLmJhc2VDb2luLmtleWNoYWlucygpLmFkZChiYWNrdXBLZXlDaGFpblBhcmFtcyk7XG5cbiAgICAvLyBDcmVhdGUgV2FsbGV0XG4gICAgY29uc3Qga2V5Y2hhaW5zID0geyB1c2VyS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluLCBiaXRnb0tleWNoYWluIH07XG4gICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgbGFiZWwsXG4gICAgICBtOiAyLFxuICAgICAgbjogMyxcbiAgICAgIGtleXM6IFt1c2VyS2V5Y2hhaW4uaWQsIGJhY2t1cEtleWNoYWluLmlkLCBiaXRnb0tleWNoYWluLmlkXSxcbiAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgIG11bHRpc2lnVHlwZSxcbiAgICAgIGVudGVycHJpc2UsXG4gICAgICB3YWxsZXRWZXJzaW9uLFxuICAgIH07XG5cbiAgICBjb25zdCBmaW5hbFdhbGxldFBhcmFtcyA9IGF3YWl0IHRoaXMuYmFzZUNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcywga2V5Y2hhaW5zKTtcbiAgICBjb25zdCBuZXdXYWxsZXQgPSBhd2FpdCB0aGlzLmJpdGdvLnBvc3QodGhpcy5iYXNlQ29pbi51cmwoJy93YWxsZXQvYWRkJykpLnNlbmQoZmluYWxXYWxsZXRQYXJhbXMpLnJlc3VsdCgpO1xuXG4gICAgY29uc3QgcmVzdWx0OiBXYWxsZXRXaXRoS2V5Y2hhaW5zID0ge1xuICAgICAgd2FsbGV0OiBuZXcgV2FsbGV0KHRoaXMuYml0Z28sIHRoaXMuYmFzZUNvaW4sIG5ld1dhbGxldCksXG4gICAgICB1c2VyS2V5Y2hhaW4sXG4gICAgICBiYWNrdXBLZXljaGFpbixcbiAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICByZXNwb25zZVR5cGU6ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYSBDdXN0b2RpYWwgVFNTIFdhbGxldC5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUN1c3RvZGlhbE1wY1dhbGxldCh7XG4gICAgbGFiZWwsXG4gICAgbXVsdGlzaWdUeXBlLFxuICAgIGVudGVycHJpc2UsXG4gICAgd2FsbGV0VmVyc2lvbixcbiAgfTogR2VuZXJhdGVCYXNlTXBjV2FsbGV0T3B0aW9ucyk6IFByb21pc2U8V2FsbGV0V2l0aEtleWNoYWlucz4ge1xuICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICB0aGlzLmJpdGdvLnNldFJlcXVlc3RUcmFjZXIocmVxSWQpO1xuXG4gICAgaWYgKG11bHRpc2lnVHlwZSA9PT0gJ3RzcycgJiYgdGhpcy5iYXNlQ29pbi5nZXRNUENBbGdvcml0aG0oKSA9PT0gJ2VjZHNhJykge1xuICAgICAgY29uc3QgdHNzU2V0dGluZ3M6IFRzc1NldHRpbmdzID0gYXdhaXQgdGhpcy5iaXRnb1xuICAgICAgICAuZ2V0KHRoaXMuYml0Z28ubWljcm9zZXJ2aWNlc1VybCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKSlcbiAgICAgICAgLnJlc3VsdCgpO1xuICAgICAgY29uc3QgbXVsdGlzaWdUeXBlVmVyc2lvbiA9XG4gICAgICAgIHRzc1NldHRpbmdzLmNvaW5TZXR0aW5nc1t0aGlzLmJhc2VDb2luLmdldEZhbWlseSgpXT8ud2FsbGV0Q3JlYXRpb25TZXR0aW5ncz8uY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjtcbiAgICAgIHdhbGxldFZlcnNpb24gPSB0aGlzLmRldGVybWluZUVjZHNhTXBjV2FsbGV0VmVyc2lvbih3YWxsZXRWZXJzaW9uLCBtdWx0aXNpZ1R5cGVWZXJzaW9uKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaW5hbFdhbGxldFBhcmFtcyA9IHtcbiAgICAgIGxhYmVsLFxuICAgICAgbXVsdGlzaWdUeXBlLFxuICAgICAgZW50ZXJwcmlzZSxcbiAgICAgIHdhbGxldFZlcnNpb24sXG4gICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICB9O1xuXG4gICAgLy8gQ3JlYXRlIFdhbGxldFxuICAgIGNvbnN0IG5ld1dhbGxldCA9IGF3YWl0IHRoaXMuYml0Z28ucG9zdCh0aGlzLmJhc2VDb2luLnVybCgnL3dhbGxldC9hZGQnKSkuc2VuZChmaW5hbFdhbGxldFBhcmFtcykucmVzdWx0KCk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldCh0aGlzLmJpdGdvLCB0aGlzLmJhc2VDb2luLCBuZXdXYWxsZXQpO1xuICAgIGNvbnN0IGtleWNoYWlucyA9IHdhbGxldC5rZXlJZHMoKTtcbiAgICBjb25zdCByZXN1bHQ6IFdhbGxldFdpdGhLZXljaGFpbnMgPSB7XG4gICAgICB3YWxsZXQsXG4gICAgICB1c2VyS2V5Y2hhaW46IHsgaWQ6IGtleWNoYWluc1swXSwgdHlwZTogbXVsdGlzaWdUeXBlLCBzb3VyY2U6ICd1c2VyJyB9LFxuICAgICAgYmFja3VwS2V5Y2hhaW46IHsgaWQ6IGtleWNoYWluc1sxXSwgdHlwZTogbXVsdGlzaWdUeXBlLCBzb3VyY2U6ICdiYWNrdXAnIH0sXG4gICAgICBiaXRnb0tleWNoYWluOiB7IGlkOiBrZXljaGFpbnNbMl0sIHR5cGU6IG11bHRpc2lnVHlwZSwgc291cmNlOiAnYml0Z28nIH0sXG4gICAgICByZXNwb25zZVR5cGU6ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZGV0ZXJtaW5lRWNkc2FNcGNXYWxsZXRWZXJzaW9uKHdhbGxldFZlcnNpb24/OiBudW1iZXIsIG11bHRpc2lnVHlwZVZlcnNpb24/OiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLmJhc2VDb2luLmlzRVZNKCkgJiYgbXVsdGlzaWdUeXBlVmVyc2lvbiA9PT0gJ01QQ3YyJykge1xuICAgICAgaWYgKCF3YWxsZXRWZXJzaW9uIHx8ICh3YWxsZXRWZXJzaW9uICE9PSA1ICYmIHdhbGxldFZlcnNpb24gIT09IDYpKSB7XG4gICAgICAgIHJldHVybiA1O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gd2FsbGV0VmVyc2lvbjtcbiAgfVxufVxuIl19