@bitgo-beta/sdk-core 8.2.1-beta.162 → 8.2.1-beta.1621

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