@bitgo-beta/sdk-coin-sol 7.6.4-beta.31 → 7.6.4-beta.310
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/bigint-buffer-guard.d.ts.map +1 -0
- package/dist/cjs/src/bigint-buffer-guard.js +29 -0
- package/dist/cjs/src/config/token2022StaticConfig.d.ts.map +1 -0
- package/dist/cjs/src/config/token2022StaticConfig.js +50 -0
- package/dist/cjs/src/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/index.js +1 -1
- package/dist/cjs/src/lib/ataInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/ataInitializationBuilder.js +196 -0
- package/dist/cjs/src/lib/closeAtaBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/closeAtaBuilder.js +69 -0
- package/dist/{src → cjs/src}/lib/constants.d.ts +24 -0
- package/dist/cjs/src/lib/constants.d.ts.map +1 -0
- package/dist/cjs/src/lib/constants.js +196 -0
- package/dist/cjs/src/lib/customInstructionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/customInstructionBuilder.js +289 -0
- package/dist/cjs/src/lib/explainTransactionWasm.d.ts +21 -0
- package/dist/cjs/src/lib/explainTransactionWasm.d.ts.map +1 -0
- package/dist/cjs/src/lib/explainTransactionWasm.js +264 -0
- package/dist/{src → cjs/src}/lib/iface.d.ts +20 -2
- package/dist/cjs/src/lib/iface.d.ts.map +1 -0
- package/dist/cjs/src/lib/iface.js +7 -0
- package/dist/{src → cjs/src}/lib/index.d.ts +1 -0
- package/dist/cjs/src/lib/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/lib/index.js +4 -2
- package/dist/{src → cjs/src}/lib/instructionParamsFactory.d.ts +1 -0
- package/dist/cjs/src/lib/instructionParamsFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/instructionParamsFactory.js +1059 -0
- package/dist/cjs/src/lib/jitoStakePoolOperations.d.ts.map +1 -0
- package/dist/cjs/src/lib/jitoStakePoolOperations.js +200 -0
- package/dist/cjs/src/lib/keyPair.d.ts.map +1 -0
- package/dist/cjs/src/lib/keyPair.js +63 -0
- package/dist/cjs/src/lib/messages/index.d.ts.map +1 -0
- package/dist/{src → cjs/src}/lib/messages/index.js +1 -1
- package/dist/cjs/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/messages/messageBuilderFactory.js +19 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts +25 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/recoverNestedAtaBuilder.js +90 -0
- package/dist/cjs/src/lib/solInstructionFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/solInstructionFactory.js +595 -0
- package/dist/cjs/src/lib/stakingActivateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingActivateBuilder.js +120 -0
- package/dist/cjs/src/lib/stakingAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingAuthorizeBuilder.js +89 -0
- package/dist/cjs/src/lib/stakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingDeactivateBuilder.js +208 -0
- package/dist/cjs/src/lib/stakingDelegateBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingDelegateBuilder.js +120 -0
- package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingRawMsgAuthorizeBuilder.js +110 -0
- package/dist/cjs/src/lib/stakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/stakingWithdrawBuilder.js +78 -0
- package/dist/cjs/src/lib/token2022Config.d.ts.map +1 -0
- package/dist/cjs/src/lib/token2022Config.js +27 -0
- package/dist/cjs/src/lib/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/tokenTransferBuilder.js +188 -0
- package/dist/cjs/src/lib/transaction.d.ts.map +1 -0
- package/dist/cjs/src/lib/transaction.js +612 -0
- package/dist/cjs/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilder.js +380 -0
- package/dist/{src → cjs/src}/lib/transactionBuilderFactory.d.ts +5 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/src/lib/transactionBuilderFactory.js +209 -0
- package/dist/cjs/src/lib/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/transferBuilder.js +70 -0
- package/dist/cjs/src/lib/transferBuilderV2.d.ts.map +1 -0
- package/dist/cjs/src/lib/transferBuilderV2.js +210 -0
- package/dist/cjs/src/lib/utils.d.ts.map +1 -0
- package/dist/cjs/src/lib/utils.js +595 -0
- package/dist/cjs/src/lib/walletInitializationBuilder.d.ts.map +1 -0
- package/dist/cjs/src/lib/walletInitializationBuilder.js +71 -0
- package/dist/cjs/src/register.d.ts.map +1 -0
- package/dist/cjs/src/register.js +15 -0
- package/dist/{src → cjs/src}/sol.d.ts +40 -0
- package/dist/cjs/src/sol.d.ts.map +1 -0
- package/dist/cjs/src/sol.js +1402 -0
- package/dist/cjs/src/solToken.d.ts.map +1 -0
- package/dist/cjs/src/solToken.js +69 -0
- package/dist/cjs/src/tsol.d.ts.map +1 -0
- package/dist/cjs/src/tsol.js +24 -0
- package/dist/{test → cjs/test}/fixtures/sol.d.ts.map +1 -1
- package/dist/cjs/test/fixtures/sol.js +1433 -0
- package/dist/{test → cjs/test}/resources/sol.d.ts +27 -27
- package/dist/cjs/test/resources/sol.d.ts.map +1 -0
- package/dist/cjs/test/resources/sol.js +320 -0
- package/dist/cjs/test/unit/explainTransactionWasm.d.ts +5 -0
- package/dist/cjs/test/unit/explainTransactionWasm.d.ts.map +1 -0
- package/dist/cjs/test/unit/explainTransactionWasm.js +26 -0
- package/dist/cjs/test/unit/fixtures/solBackupKey.d.ts.map +1 -0
- package/dist/cjs/test/unit/fixtures/solBackupKey.js +8 -0
- package/dist/cjs/test/unit/getBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/getBuilderFactory.js +10 -0
- package/dist/cjs/test/unit/instructionParamsFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/instructionParamsFactory.js +412 -0
- package/dist/cjs/test/unit/instructionParamsFactory.staking.d.ts.map +1 -0
- package/dist/cjs/test/unit/instructionParamsFactory.staking.js +1059 -0
- package/dist/cjs/test/unit/jitoWasmVerification.d.ts +2 -0
- package/dist/cjs/test/unit/jitoWasmVerification.d.ts.map +1 -0
- package/dist/cjs/test/unit/jitoWasmVerification.js +78 -0
- package/dist/{test → cjs/test}/unit/keyPair.d.ts.map +1 -1
- package/dist/cjs/test/unit/keyPair.js +177 -0
- package/dist/cjs/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/messages/messageBuilderFactory.js +118 -0
- package/dist/cjs/test/unit/messages/simpleMessageBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/messages/simpleMessageBuilder.js +194 -0
- package/dist/{test → cjs/test}/unit/sol.d.ts.map +1 -1
- package/dist/cjs/test/unit/sol.js +3326 -0
- package/dist/cjs/test/unit/solInstructionFactory.d.ts.map +1 -0
- package/dist/cjs/test/unit/solInstructionFactory.js +454 -0
- package/dist/cjs/test/unit/solToken.d.ts.map +1 -0
- package/dist/cjs/test/unit/solToken.js +31 -0
- package/dist/cjs/test/unit/transaction.d.ts.map +1 -0
- package/dist/cjs/test/unit/transaction.js +1108 -0
- package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/StakingWithdrawBuilder.js +202 -0
- package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/ataInitBuilder.js +471 -0
- package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/customInstructionBuilder.js +413 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingActivateBuilder.js +430 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +157 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDeactivateBuilder.js +384 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingDelegateBuilder.js +224 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +259 -0
- package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/tokenTransferBuilder.js +787 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transactionBuilder.js +495 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilder.js +286 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/transferBuilderV2.js +862 -0
- package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +1 -0
- package/dist/cjs/test/unit/transactionBuilder/walletInitBuilder.js +259 -0
- package/dist/{test → cjs/test}/unit/utils.d.ts.map +1 -1
- package/dist/cjs/test/unit/utils.js +517 -0
- package/dist/cjs/test/unit/versionedTransaction.d.ts.map +1 -0
- package/dist/cjs/test/unit/versionedTransaction.js +207 -0
- package/dist/cjs/tsconfig.tsbuildinfo +1 -0
- package/dist/esm/bigint-buffer-guard.d.ts +1 -0
- package/dist/esm/config/token2022StaticConfig.d.ts +3 -0
- package/dist/esm/config/token2022StaticConfig.js +47 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/lib/ataInitializationBuilder.d.ts +47 -0
- package/dist/esm/lib/ataInitializationBuilder.js +156 -0
- package/dist/esm/lib/closeAtaBuilder.d.ts +19 -0
- package/dist/esm/lib/closeAtaBuilder.js +62 -0
- package/dist/esm/lib/constants.d.ts +164 -0
- package/dist/esm/lib/constants.d.ts.map +1 -0
- package/dist/esm/lib/constants.js +193 -0
- package/dist/esm/lib/customInstructionBuilder.d.ts +72 -0
- package/dist/esm/lib/customInstructionBuilder.js +282 -0
- package/dist/esm/lib/explainTransactionWasm.d.ts +21 -0
- package/dist/esm/lib/explainTransactionWasm.d.ts.map +1 -0
- package/dist/esm/lib/explainTransactionWasm.js +261 -0
- package/dist/esm/lib/iface.d.ts +262 -0
- package/dist/esm/lib/iface.d.ts.map +1 -0
- package/dist/esm/lib/iface.js +3 -0
- package/dist/esm/lib/index.d.ts +23 -0
- package/dist/{src → esm}/lib/index.d.ts.map +1 -1
- package/dist/esm/lib/index.js +23 -0
- package/dist/esm/lib/instructionParamsFactory.d.ts +13 -0
- package/dist/{src → esm}/lib/instructionParamsFactory.d.ts.map +1 -1
- package/dist/esm/lib/instructionParamsFactory.js +1052 -0
- package/dist/esm/lib/jitoStakePoolOperations.d.ts +113 -0
- package/dist/esm/lib/jitoStakePoolOperations.js +189 -0
- package/dist/esm/lib/keyPair.d.ts +26 -0
- package/dist/esm/lib/keyPair.js +59 -0
- package/dist/esm/lib/messages/index.d.ts +2 -0
- package/dist/esm/lib/messages/index.js +2 -0
- package/dist/esm/lib/messages/messageBuilderFactory.d.ts +7 -0
- package/dist/{src → esm}/lib/messages/messageBuilderFactory.js +5 -9
- package/dist/esm/lib/recoverNestedAtaBuilder.d.ts +25 -0
- package/dist/esm/lib/recoverNestedAtaBuilder.d.ts.map +1 -0
- package/dist/esm/lib/recoverNestedAtaBuilder.js +83 -0
- package/dist/esm/lib/solInstructionFactory.d.ts +10 -0
- package/dist/esm/lib/solInstructionFactory.d.ts.map +1 -0
- package/dist/esm/lib/solInstructionFactory.js +589 -0
- package/dist/esm/lib/stakingActivateBuilder.d.ts +59 -0
- package/dist/esm/lib/stakingActivateBuilder.js +113 -0
- package/dist/esm/lib/stakingAuthorizeBuilder.d.ts +43 -0
- package/dist/esm/lib/stakingAuthorizeBuilder.js +82 -0
- package/dist/esm/lib/stakingDeactivateBuilder.d.ts +81 -0
- package/dist/{src → esm}/lib/stakingDeactivateBuilder.js +31 -38
- package/dist/esm/lib/stakingDelegateBuilder.d.ts +42 -0
- package/dist/esm/lib/stakingDelegateBuilder.js +113 -0
- package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.d.ts +33 -0
- package/dist/esm/lib/stakingRawMsgAuthorizeBuilder.js +103 -0
- package/dist/esm/lib/stakingWithdrawBuilder.d.ts +31 -0
- package/dist/esm/lib/stakingWithdrawBuilder.js +71 -0
- package/dist/esm/lib/token2022Config.d.ts +44 -0
- package/dist/esm/lib/token2022Config.js +23 -0
- package/dist/esm/lib/tokenTransferBuilder.d.ts +41 -0
- package/dist/esm/lib/tokenTransferBuilder.js +181 -0
- package/dist/esm/lib/transaction.d.ts +103 -0
- package/dist/esm/lib/transaction.d.ts.map +1 -0
- package/dist/esm/lib/transaction.js +605 -0
- package/dist/esm/lib/transactionBuilder.d.ts +128 -0
- package/dist/esm/lib/transactionBuilder.js +373 -0
- package/dist/esm/lib/transactionBuilderFactory.d.ts +120 -0
- package/dist/esm/lib/transactionBuilderFactory.d.ts.map +1 -0
- package/dist/esm/lib/transactionBuilderFactory.js +205 -0
- package/dist/esm/lib/transferBuilder.d.ts +26 -0
- package/dist/esm/lib/transferBuilder.js +63 -0
- package/dist/esm/lib/transferBuilderV2.d.ts +43 -0
- package/dist/esm/lib/transferBuilderV2.js +203 -0
- package/dist/esm/lib/utils.d.ts +200 -0
- package/dist/{src → esm}/lib/utils.d.ts.map +1 -1
- package/dist/esm/lib/utils.js +558 -0
- package/dist/esm/lib/walletInitializationBuilder.d.ts +26 -0
- package/dist/esm/lib/walletInitializationBuilder.js +64 -0
- package/dist/esm/register.d.ts +3 -0
- package/dist/esm/register.js +11 -0
- package/dist/esm/sol.d.ts +267 -0
- package/dist/esm/sol.d.ts.map +1 -0
- package/dist/esm/sol.js +1361 -0
- package/dist/esm/solToken.d.ts +37 -0
- package/dist/esm/solToken.js +65 -0
- package/dist/esm/tsol.d.ts +11 -0
- package/dist/esm/tsol.js +20 -0
- package/package.json +34 -15
- package/dist/src/config/token2022StaticConfig.js +0 -50
- package/dist/src/lib/ataInitializationBuilder.js +0 -196
- package/dist/src/lib/closeAtaBuilder.js +0 -69
- package/dist/src/lib/constants.d.ts.map +0 -1
- package/dist/src/lib/constants.js +0 -171
- package/dist/src/lib/customInstructionBuilder.js +0 -289
- package/dist/src/lib/iface.d.ts.map +0 -1
- package/dist/src/lib/iface.js +0 -7
- package/dist/src/lib/instructionParamsFactory.js +0 -1036
- package/dist/src/lib/jitoStakePoolOperations.js +0 -200
- package/dist/src/lib/keyPair.js +0 -63
- package/dist/src/lib/solInstructionFactory.d.ts.map +0 -1
- package/dist/src/lib/solInstructionFactory.js +0 -572
- package/dist/src/lib/stakingActivateBuilder.js +0 -120
- package/dist/src/lib/stakingAuthorizeBuilder.js +0 -89
- package/dist/src/lib/stakingDelegateBuilder.js +0 -120
- package/dist/src/lib/stakingRawMsgAuthorizeBuilder.js +0 -110
- package/dist/src/lib/stakingWithdrawBuilder.js +0 -78
- package/dist/src/lib/token2022Config.js +0 -27
- package/dist/src/lib/tokenTransferBuilder.js +0 -188
- package/dist/src/lib/transaction.d.ts.map +0 -1
- package/dist/src/lib/transaction.js +0 -595
- package/dist/src/lib/transactionBuilder.js +0 -380
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +0 -1
- package/dist/src/lib/transactionBuilderFactory.js +0 -202
- package/dist/src/lib/transferBuilder.js +0 -70
- package/dist/src/lib/transferBuilderV2.js +0 -210
- package/dist/src/lib/utils.js +0 -589
- package/dist/src/lib/walletInitializationBuilder.js +0 -71
- package/dist/src/register.js +0 -15
- package/dist/src/sol.d.ts.map +0 -1
- package/dist/src/sol.js +0 -1285
- package/dist/src/solToken.js +0 -69
- package/dist/src/tsol.js +0 -24
- package/dist/test/fixtures/sol.js +0 -1433
- package/dist/test/resources/sol.d.ts.map +0 -1
- package/dist/test/resources/sol.js +0 -320
- package/dist/test/unit/fixtures/solBackupKey.d.ts.map +0 -1
- package/dist/test/unit/fixtures/solBackupKey.js +0 -8
- package/dist/test/unit/getBuilderFactory.d.ts.map +0 -1
- package/dist/test/unit/getBuilderFactory.js +0 -10
- package/dist/test/unit/instructionParamsFactory.d.ts.map +0 -1
- package/dist/test/unit/instructionParamsFactory.js +0 -412
- package/dist/test/unit/instructionParamsFactory.staking.d.ts.map +0 -1
- package/dist/test/unit/instructionParamsFactory.staking.js +0 -1059
- package/dist/test/unit/keyPair.js +0 -177
- package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +0 -1
- package/dist/test/unit/messages/messageBuilderFactory.js +0 -118
- package/dist/test/unit/messages/simpleMessageBuilder.d.ts.map +0 -1
- package/dist/test/unit/messages/simpleMessageBuilder.js +0 -194
- package/dist/test/unit/sol.js +0 -3108
- package/dist/test/unit/solInstructionFactory.d.ts.map +0 -1
- package/dist/test/unit/solInstructionFactory.js +0 -454
- package/dist/test/unit/solToken.d.ts.map +0 -1
- package/dist/test/unit/solToken.js +0 -31
- package/dist/test/unit/transaction.d.ts.map +0 -1
- package/dist/test/unit/transaction.js +0 -983
- package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/StakingWithdrawBuilder.js +0 -202
- package/dist/test/unit/transactionBuilder/ataInitBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/ataInitBuilder.js +0 -471
- package/dist/test/unit/transactionBuilder/customInstructionBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/customInstructionBuilder.js +0 -413
- package/dist/test/unit/transactionBuilder/stakingActivateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingActivateBuilder.js +0 -430
- package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingAuthorizeBuilder.js +0 -157
- package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingDeactivateBuilder.js +0 -384
- package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingDelegateBuilder.js +0 -224
- package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.js +0 -259
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +0 -787
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transactionBuilder.js +0 -495
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transferBuilder.js +0 -286
- package/dist/test/unit/transactionBuilder/transferBuilderV2.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/transferBuilderV2.js +0 -862
- package/dist/test/unit/transactionBuilder/walletInitBuilder.d.ts.map +0 -1
- package/dist/test/unit/transactionBuilder/walletInitBuilder.js +0 -259
- package/dist/test/unit/utils.js +0 -517
- package/dist/test/unit/versionedTransaction.d.ts.map +0 -1
- package/dist/test/unit/versionedTransaction.js +0 -207
- package/dist/tsconfig.tsbuildinfo +0 -1
- /package/dist/{src → cjs/src}/bigint-buffer-guard.d.ts +0 -0
- /package/dist/{src → cjs/src}/config/token2022StaticConfig.d.ts +0 -0
- /package/dist/{src → cjs/src}/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/ataInitializationBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/closeAtaBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/customInstructionBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/jitoStakePoolOperations.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/keyPair.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/messages/index.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/messages/messageBuilderFactory.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/solInstructionFactory.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingActivateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingAuthorizeBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingDeactivateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingDelegateBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/stakingWithdrawBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/token2022Config.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/tokenTransferBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transaction.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transactionBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transferBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/transferBuilderV2.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/utils.d.ts +0 -0
- /package/dist/{src → cjs/src}/lib/walletInitializationBuilder.d.ts +0 -0
- /package/dist/{src → cjs/src}/register.d.ts +0 -0
- /package/dist/{src → cjs/src}/solToken.d.ts +0 -0
- /package/dist/{src → cjs/src}/tsol.d.ts +0 -0
- /package/dist/{test → cjs/test}/fixtures/sol.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/fixtures/solBackupKey.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/getBuilderFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/instructionParamsFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/instructionParamsFactory.staking.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/keyPair.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/messages/messageBuilderFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/messages/simpleMessageBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/sol.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/solInstructionFactory.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/solToken.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transaction.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/StakingWithdrawBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/ataInitBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/customInstructionBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingActivateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingAuthorizeBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDeactivateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingDelegateBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/stakingRawMsgAuthorizeBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/tokenTransferBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transactionBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/transferBuilderV2.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/transactionBuilder/walletInitBuilder.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/utils.d.ts +0 -0
- /package/dist/{test → cjs/test}/unit/versionedTransaction.d.ts +0 -0
- /package/dist/{src → esm}/bigint-buffer-guard.d.ts.map +0 -0
- /package/dist/{src → esm}/bigint-buffer-guard.js +0 -0
- /package/dist/{src → esm}/config/token2022StaticConfig.d.ts.map +0 -0
- /package/dist/{src → esm}/index.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/ataInitializationBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/closeAtaBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/customInstructionBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/jitoStakePoolOperations.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/keyPair.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/messages/index.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/messages/messageBuilderFactory.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingActivateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingAuthorizeBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingDeactivateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingDelegateBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingRawMsgAuthorizeBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/stakingWithdrawBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/token2022Config.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/tokenTransferBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transactionBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transferBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/transferBuilderV2.d.ts.map +0 -0
- /package/dist/{src → esm}/lib/walletInitializationBuilder.d.ts.map +0 -0
- /package/dist/{src → esm}/register.d.ts.map +0 -0
- /package/dist/{src → esm}/solToken.d.ts.map +0 -0
- /package/dist/{src → esm}/tsol.d.ts.map +0 -0
|
@@ -0,0 +1,3326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const assert_1 = __importDefault(require("assert"));
|
|
40
|
+
const _ = __importStar(require("lodash"));
|
|
41
|
+
const nock_1 = __importDefault(require("nock"));
|
|
42
|
+
const should = __importStar(require("should"));
|
|
43
|
+
const sinon = __importStar(require("sinon"));
|
|
44
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
45
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
46
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
47
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
48
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
49
|
+
const src_1 = require("../../src");
|
|
50
|
+
const lib_1 = require("../../src/lib");
|
|
51
|
+
const utils_1 = require("../../src/lib/utils");
|
|
52
|
+
const testData = __importStar(require("../fixtures/sol"));
|
|
53
|
+
const resources = __importStar(require("../resources/sol"));
|
|
54
|
+
const solBackupKey_1 = require("./fixtures/solBackupKey");
|
|
55
|
+
const getBuilderFactory_1 = require("./getBuilderFactory");
|
|
56
|
+
describe('SOL:', function () {
|
|
57
|
+
let bitgo;
|
|
58
|
+
let basecoin;
|
|
59
|
+
let keyPair;
|
|
60
|
+
let newTxPrebuild;
|
|
61
|
+
let newTxPrebuildTokenTransfer;
|
|
62
|
+
let newTxParams;
|
|
63
|
+
let newTxParamsWithError;
|
|
64
|
+
let newTxParamsWithExtraData;
|
|
65
|
+
let newTxParamsTokenTransfer;
|
|
66
|
+
const badAddresses = resources.addresses.invalidAddresses;
|
|
67
|
+
const goodAddresses = resources.addresses.validAddresses;
|
|
68
|
+
const keypair = {
|
|
69
|
+
pub: resources.accountWithSeed.publicKey,
|
|
70
|
+
prv: resources.accountWithSeed.privateKey.base58,
|
|
71
|
+
};
|
|
72
|
+
const txPrebuild = {
|
|
73
|
+
recipients: [
|
|
74
|
+
{
|
|
75
|
+
address: 'lionteste212',
|
|
76
|
+
amount: '1000',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
txBase64: resources.TRANSFER_UNSIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE,
|
|
80
|
+
txInfo: {
|
|
81
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
82
|
+
nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
83
|
+
},
|
|
84
|
+
txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
|
|
85
|
+
isVotingTransaction: false,
|
|
86
|
+
coin: 'tsol',
|
|
87
|
+
};
|
|
88
|
+
const txParams = {
|
|
89
|
+
txPrebuild,
|
|
90
|
+
recipients: [
|
|
91
|
+
{
|
|
92
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
93
|
+
amount: '300000',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
const memo = { value: 'test memo' };
|
|
98
|
+
const durableNonce = {
|
|
99
|
+
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
100
|
+
authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
101
|
+
};
|
|
102
|
+
const errorDurableNonce = {
|
|
103
|
+
walletNonceAddress: '8YM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
104
|
+
authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
105
|
+
};
|
|
106
|
+
const txParamsWithError = {
|
|
107
|
+
txPrebuild,
|
|
108
|
+
recipients: [
|
|
109
|
+
{
|
|
110
|
+
address: 'CP5Dpaa42mMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
111
|
+
amount: '300000',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
const txParamsWithExtraData = {
|
|
116
|
+
txPrebuild,
|
|
117
|
+
recipients: [
|
|
118
|
+
{
|
|
119
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
120
|
+
amount: '300000',
|
|
121
|
+
data: undefined,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
const txPrebuildTokenTransfer = {
|
|
126
|
+
recipients: [
|
|
127
|
+
{
|
|
128
|
+
address: 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg',
|
|
129
|
+
amount: '1',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
txHex: resources.TOKEN_TRANSFER_TO_NATIVE_UNSIGNED_TX_HEX,
|
|
133
|
+
txInfo: {
|
|
134
|
+
feePayer: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
|
|
135
|
+
nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
136
|
+
},
|
|
137
|
+
txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
|
|
138
|
+
isVotingTransaction: false,
|
|
139
|
+
coin: 'tsol',
|
|
140
|
+
};
|
|
141
|
+
const txParamsTokenTransfer = {
|
|
142
|
+
txPrebuild,
|
|
143
|
+
recipients: [
|
|
144
|
+
{
|
|
145
|
+
address: 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg',
|
|
146
|
+
amount: '1',
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
const errorMemo = { value: 'different memo' };
|
|
151
|
+
const errorFeePayer = '5hr5fisPi6DXCuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe';
|
|
152
|
+
const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
|
|
153
|
+
const wallet = new src_1.KeyPair(resources.authAccount).getKeys();
|
|
154
|
+
const stakeAccount = new src_1.KeyPair(resources.stakeAccount).getKeys();
|
|
155
|
+
const blockHash = resources.blockHashes.validBlockHashes[0];
|
|
156
|
+
const amount = '10000';
|
|
157
|
+
const validator = resources.validator;
|
|
158
|
+
before(function () {
|
|
159
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
160
|
+
bitgo.safeRegister('sol', src_1.Tsol.createInstance);
|
|
161
|
+
bitgo.safeRegister('tsol', src_1.Tsol.createInstance);
|
|
162
|
+
bitgo.initializeTestVars();
|
|
163
|
+
basecoin = bitgo.coin('tsol');
|
|
164
|
+
keyPair = basecoin.generateKeyPair(resources.accountWithSeed.seed);
|
|
165
|
+
newTxPrebuild = () => {
|
|
166
|
+
return _.cloneDeep(txPrebuild);
|
|
167
|
+
};
|
|
168
|
+
newTxPrebuildTokenTransfer = () => {
|
|
169
|
+
return _.cloneDeep(txPrebuildTokenTransfer);
|
|
170
|
+
};
|
|
171
|
+
newTxParams = () => {
|
|
172
|
+
return _.cloneDeep(txParams);
|
|
173
|
+
};
|
|
174
|
+
newTxParamsWithError = () => {
|
|
175
|
+
return _.cloneDeep(txParamsWithError);
|
|
176
|
+
};
|
|
177
|
+
newTxParamsWithExtraData = () => {
|
|
178
|
+
return _.cloneDeep(txParamsWithExtraData);
|
|
179
|
+
};
|
|
180
|
+
newTxParamsTokenTransfer = () => {
|
|
181
|
+
return _.cloneDeep(txParamsTokenTransfer);
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
it('should instantiate the coin', async function () {
|
|
185
|
+
let localBasecoin = bitgo.coin('tsol');
|
|
186
|
+
localBasecoin.should.be.an.instanceof(src_1.Tsol);
|
|
187
|
+
localBasecoin = bitgo.coin('sol');
|
|
188
|
+
localBasecoin.should.be.an.instanceof(src_1.Sol);
|
|
189
|
+
});
|
|
190
|
+
it('should retun the right info', function () {
|
|
191
|
+
basecoin.getChain().should.equal('tsol');
|
|
192
|
+
basecoin.getFamily().should.equal('sol');
|
|
193
|
+
basecoin.getFullName().should.equal('Testnet Solana');
|
|
194
|
+
basecoin.getBaseFactor().should.equal(1000000000);
|
|
195
|
+
});
|
|
196
|
+
describe('verify transactions', () => {
|
|
197
|
+
const walletData = {
|
|
198
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
199
|
+
coin: 'tsol',
|
|
200
|
+
keys: [
|
|
201
|
+
'5b3424f91bf349930e34017500000000',
|
|
202
|
+
'5b3424f91bf349930e34017600000000',
|
|
203
|
+
'5b3424f91bf349930e34017700000000',
|
|
204
|
+
],
|
|
205
|
+
coinSpecific: {
|
|
206
|
+
rootAddress: wallet.pub,
|
|
207
|
+
},
|
|
208
|
+
multisigType: 'tss',
|
|
209
|
+
};
|
|
210
|
+
const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
211
|
+
it('should verify transactions', async function () {
|
|
212
|
+
const txParams = newTxParams();
|
|
213
|
+
const txPrebuild = newTxPrebuild();
|
|
214
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
215
|
+
txParams,
|
|
216
|
+
txPrebuild,
|
|
217
|
+
memo,
|
|
218
|
+
durableNonce,
|
|
219
|
+
wallet: walletObj,
|
|
220
|
+
});
|
|
221
|
+
validTransaction.should.equal(true);
|
|
222
|
+
});
|
|
223
|
+
it('should verify consolidate transaction', async function () {
|
|
224
|
+
const txParams = newTxParams();
|
|
225
|
+
const txPrebuild = newTxPrebuild();
|
|
226
|
+
txPrebuild.consolidateId = 'consolidateId';
|
|
227
|
+
const walletData = {
|
|
228
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
229
|
+
coin: 'tsol',
|
|
230
|
+
keys: [
|
|
231
|
+
'5b3424f91bf349930e34017500000000',
|
|
232
|
+
'5b3424f91bf349930e34017600000000',
|
|
233
|
+
'5b3424f91bf349930e34017700000000',
|
|
234
|
+
],
|
|
235
|
+
coinSpecific: {
|
|
236
|
+
rootAddress: stakeAccount.pub,
|
|
237
|
+
},
|
|
238
|
+
multisigType: 'tss',
|
|
239
|
+
};
|
|
240
|
+
const walletWithDifferentAddress = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
241
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
242
|
+
txParams,
|
|
243
|
+
txPrebuild,
|
|
244
|
+
memo,
|
|
245
|
+
durableNonce,
|
|
246
|
+
wallet: walletWithDifferentAddress,
|
|
247
|
+
});
|
|
248
|
+
validTransaction.should.be.true();
|
|
249
|
+
});
|
|
250
|
+
it('should handle txBase64 and txHex interchangeably', async function () {
|
|
251
|
+
const txParams = newTxParams();
|
|
252
|
+
const txPrebuild = newTxPrebuild();
|
|
253
|
+
txPrebuild.txHex = txPrebuild.txBase64;
|
|
254
|
+
txPrebuild.txBase64 = undefined;
|
|
255
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
256
|
+
txParams,
|
|
257
|
+
txPrebuild,
|
|
258
|
+
memo,
|
|
259
|
+
durableNonce,
|
|
260
|
+
wallet: walletObj,
|
|
261
|
+
});
|
|
262
|
+
validTransaction.should.equal(true);
|
|
263
|
+
});
|
|
264
|
+
it('should convert serialized hex string to base64', async function () {
|
|
265
|
+
const txParams = newTxParams();
|
|
266
|
+
const txPrebuild = newTxPrebuild();
|
|
267
|
+
txPrebuild.txBase64 = Buffer.from(txPrebuild.txBase64, 'base64').toString('hex');
|
|
268
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
269
|
+
txParams,
|
|
270
|
+
txPrebuild,
|
|
271
|
+
memo,
|
|
272
|
+
durableNonce,
|
|
273
|
+
wallet: walletObj,
|
|
274
|
+
});
|
|
275
|
+
validTransaction.should.equal(true);
|
|
276
|
+
});
|
|
277
|
+
it('should verify when input `recipients` is absent', async function () {
|
|
278
|
+
const txParams = newTxParams();
|
|
279
|
+
txParams.recipients = undefined;
|
|
280
|
+
const txPrebuild = newTxPrebuild();
|
|
281
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
282
|
+
txParams,
|
|
283
|
+
txPrebuild,
|
|
284
|
+
memo,
|
|
285
|
+
durableNonce,
|
|
286
|
+
wallet: walletObj,
|
|
287
|
+
});
|
|
288
|
+
validTransaction.should.equal(true);
|
|
289
|
+
});
|
|
290
|
+
it('should fail verify transactions when have different memo', async function () {
|
|
291
|
+
const txParams = newTxParams();
|
|
292
|
+
const txPrebuild = newTxPrebuild();
|
|
293
|
+
await basecoin
|
|
294
|
+
.verifyTransaction({ txParams, txPrebuild, memo: errorMemo, wallet: walletObj })
|
|
295
|
+
.should.be.rejectedWith('Tx memo does not match with expected txParams recipient memo');
|
|
296
|
+
});
|
|
297
|
+
it('should pass if we pass PDA address', async function () {
|
|
298
|
+
const walletData = {
|
|
299
|
+
id: '67f8ddff4c9b8b57a2e16acffac9a3b5',
|
|
300
|
+
coin: 'tsol',
|
|
301
|
+
keys: [
|
|
302
|
+
'5b3424f91bf349930e34017500000000',
|
|
303
|
+
'5b3424f91bf349930e34017600000000',
|
|
304
|
+
'5b3424f91bf349930e34017700000000',
|
|
305
|
+
],
|
|
306
|
+
coinSpecific: {
|
|
307
|
+
rootAddress: '8zbsJA5c8HPR7BPjZkrSVrus2uMuXqCfzksGwB3Uscjb',
|
|
308
|
+
},
|
|
309
|
+
multisigType: 'tss',
|
|
310
|
+
};
|
|
311
|
+
const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
312
|
+
const txPrebuild = {
|
|
313
|
+
recipients: [
|
|
314
|
+
{
|
|
315
|
+
address: '11111111111111111111111111111112',
|
|
316
|
+
amount: '1000000000',
|
|
317
|
+
tokenName: 'tsol:usdc',
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
txBase64: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ec1adcc89bb564f1f8225821140a9723efa80e8d506765770b7e201d66d8200d4f690e9a8163291b69f8c3827aad96cfd2105eee3aae76cbca38fcad2bf7f0a0201070c76c356cb069b66c2b35a8638b4d4afca75b303f29f0deeb4bff8528299a9c9d21c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f60129e6ecb20309c27dcba5fc6c441438d33a1568004a1860e22c16f071976a7d2e2008bd34b53a08aa9c8ec04eb2196745fc6029224447417e2fb0fced601240cabba4ce534c02fc154ba559ed2a02ac971e3385acb426ff63bb1040e2c2435000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f859d10389fbcee528f208611dccc734b31092540cb2b8d58d100f2eaa2cedb4da5e06a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006a7d517192c5c51218cc94c3d4af17f58daee089ba1fd44e3dbd98a0000000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9e680634533882f880a3e7dfa999dfb864b88968d242a0c9a90b5df149e42da050305030209010404000000070700030608050b0a000b04040803000a0c00ca9a3b0000000009',
|
|
321
|
+
txInfo: {
|
|
322
|
+
feePayer: '8zbsJA5c8HPR7BPjZkrSVrus2uMuXqCfzksGwB3Uscjb',
|
|
323
|
+
nonce: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
324
|
+
},
|
|
325
|
+
txid: '586c5b59b10b134d04c16ac1b273fe3c5529f34aef75db4456cd469c5cdac7e2',
|
|
326
|
+
isVotingTransaction: false,
|
|
327
|
+
coin: 'tsol',
|
|
328
|
+
};
|
|
329
|
+
const txParams = {
|
|
330
|
+
txPrebuild,
|
|
331
|
+
recipients: [
|
|
332
|
+
{
|
|
333
|
+
address: '11111111111111111111111111111112',
|
|
334
|
+
amount: '1000000000',
|
|
335
|
+
tokenName: 'tsol:usdc',
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
|
+
const memo = {
|
|
340
|
+
value: undefined,
|
|
341
|
+
};
|
|
342
|
+
const verifyTransaction = await basecoin.verifyTransaction({
|
|
343
|
+
txParams,
|
|
344
|
+
txPrebuild,
|
|
345
|
+
memo: memo,
|
|
346
|
+
wallet: walletObj,
|
|
347
|
+
});
|
|
348
|
+
verifyTransaction.should.equal(true);
|
|
349
|
+
});
|
|
350
|
+
it('should fail verify transactions when have different durableNonce', async function () {
|
|
351
|
+
const txParams = newTxParams();
|
|
352
|
+
const txPrebuild = newTxPrebuild();
|
|
353
|
+
await basecoin
|
|
354
|
+
.verifyTransaction({ txParams, txPrebuild, memo, durableNonce: errorDurableNonce, wallet: walletObj })
|
|
355
|
+
.should.be.rejectedWith('Tx durableNonce does not match with param durableNonce');
|
|
356
|
+
});
|
|
357
|
+
it('should fail verify transactions when have different feePayer', async function () {
|
|
358
|
+
const txParams = newTxParams();
|
|
359
|
+
const txPrebuild = newTxPrebuild();
|
|
360
|
+
const walletData = {
|
|
361
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
362
|
+
coin: 'tsol',
|
|
363
|
+
keys: [
|
|
364
|
+
'5b3424f91bf349930e34017500000000',
|
|
365
|
+
'5b3424f91bf349930e34017600000000',
|
|
366
|
+
'5b3424f91bf349930e34017700000000',
|
|
367
|
+
],
|
|
368
|
+
coinSpecific: {
|
|
369
|
+
rootAddress: stakeAccount.pub,
|
|
370
|
+
},
|
|
371
|
+
multisigType: 'tss',
|
|
372
|
+
};
|
|
373
|
+
const walletWithDifferentAddress = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
374
|
+
await basecoin
|
|
375
|
+
.verifyTransaction({ txParams, txPrebuild, memo, wallet: walletWithDifferentAddress })
|
|
376
|
+
.should.be.rejectedWith('Tx fee payer is not the wallet root address');
|
|
377
|
+
});
|
|
378
|
+
it('should fail verify transactions when have different recipients', async function () {
|
|
379
|
+
const txParams = newTxParamsWithError();
|
|
380
|
+
const txPrebuild = newTxPrebuild();
|
|
381
|
+
await basecoin
|
|
382
|
+
.verifyTransaction({ txParams, txPrebuild, memo, errorFeePayer, wallet: walletObj })
|
|
383
|
+
.should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
384
|
+
});
|
|
385
|
+
it('should succeed to verify token transaction with native address recipient', async function () {
|
|
386
|
+
const txParams = newTxParamsTokenTransfer();
|
|
387
|
+
const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
|
|
388
|
+
txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdc' }];
|
|
389
|
+
const txPrebuild = newTxPrebuildTokenTransfer();
|
|
390
|
+
const feePayerWalletData = {
|
|
391
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
392
|
+
coin: 'tsol',
|
|
393
|
+
keys: [
|
|
394
|
+
'5b3424f91bf349930e34017500000000',
|
|
395
|
+
'5b3424f91bf349930e34017600000000',
|
|
396
|
+
'5b3424f91bf349930e34017700000000',
|
|
397
|
+
],
|
|
398
|
+
coinSpecific: {
|
|
399
|
+
rootAddress: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
|
|
400
|
+
},
|
|
401
|
+
multisigType: 'tss',
|
|
402
|
+
};
|
|
403
|
+
const feePayerWallet = new sdk_core_1.Wallet(bitgo, basecoin, feePayerWalletData);
|
|
404
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
405
|
+
txParams,
|
|
406
|
+
txPrebuild,
|
|
407
|
+
wallet: feePayerWallet,
|
|
408
|
+
});
|
|
409
|
+
validTransaction.should.equal(true);
|
|
410
|
+
});
|
|
411
|
+
it('should succeed to verify token transaction with leading zero recipient amount', async function () {
|
|
412
|
+
const txParams = newTxParamsTokenTransfer();
|
|
413
|
+
const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
|
|
414
|
+
txParams.recipients = [{ address, amount: '0001', tokenName: 'tsol:usdc' }];
|
|
415
|
+
const txPrebuild = newTxPrebuildTokenTransfer();
|
|
416
|
+
const feePayerWalletData = {
|
|
417
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
418
|
+
coin: 'tsol',
|
|
419
|
+
keys: [
|
|
420
|
+
'5b3424f91bf349930e34017500000000',
|
|
421
|
+
'5b3424f91bf349930e34017600000000',
|
|
422
|
+
'5b3424f91bf349930e34017700000000',
|
|
423
|
+
],
|
|
424
|
+
coinSpecific: {
|
|
425
|
+
rootAddress: '4DujymUFbQ8GBKtAwAZrQ6QqpvtBEivL48h4ta2oJGd2',
|
|
426
|
+
},
|
|
427
|
+
multisigType: 'tss',
|
|
428
|
+
};
|
|
429
|
+
const feePayerWallet = new sdk_core_1.Wallet(bitgo, basecoin, feePayerWalletData);
|
|
430
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
431
|
+
txParams,
|
|
432
|
+
txPrebuild,
|
|
433
|
+
wallet: feePayerWallet,
|
|
434
|
+
});
|
|
435
|
+
validTransaction.should.equal(true);
|
|
436
|
+
});
|
|
437
|
+
it('should fail to verify token transaction with different recipient tokenName', async function () {
|
|
438
|
+
const txParams = newTxParamsTokenTransfer();
|
|
439
|
+
const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
|
|
440
|
+
txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdt' }]; // Different tokenName, should fail to verify tx
|
|
441
|
+
const txPrebuild = newTxPrebuildTokenTransfer();
|
|
442
|
+
await basecoin
|
|
443
|
+
.verifyTransaction({
|
|
444
|
+
txParams,
|
|
445
|
+
txPrebuild,
|
|
446
|
+
wallet: walletObj,
|
|
447
|
+
})
|
|
448
|
+
.should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
449
|
+
});
|
|
450
|
+
it('should fail to verify token transaction with different recipient amounts', async function () {
|
|
451
|
+
const txParams = newTxParamsTokenTransfer();
|
|
452
|
+
const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvg'; // Native SOL address
|
|
453
|
+
txParams.recipients = [{ address, amount: '2', tokenName: 'tsol:usdt' }];
|
|
454
|
+
const txPrebuild = newTxPrebuildTokenTransfer();
|
|
455
|
+
await basecoin
|
|
456
|
+
.verifyTransaction({
|
|
457
|
+
txParams,
|
|
458
|
+
txPrebuild,
|
|
459
|
+
wallet: walletObj,
|
|
460
|
+
})
|
|
461
|
+
.should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
462
|
+
});
|
|
463
|
+
it('should fail to verify token transaction with different native address', async function () {
|
|
464
|
+
const txParams = newTxParamsTokenTransfer();
|
|
465
|
+
const address = 'AF5H6vBkFnJuVqChRPgPQ4JRcQ5Gk25HBFhQQkyojmvX'; // Native SOL address, different than tx recipients
|
|
466
|
+
txParams.recipients = [{ address, amount: '1', tokenName: 'tsol:usdc' }];
|
|
467
|
+
const txPrebuild = newTxPrebuildTokenTransfer();
|
|
468
|
+
await basecoin
|
|
469
|
+
.verifyTransaction({
|
|
470
|
+
txParams,
|
|
471
|
+
txPrebuild,
|
|
472
|
+
wallet: walletObj,
|
|
473
|
+
})
|
|
474
|
+
.should.be.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
475
|
+
});
|
|
476
|
+
it('should succeed to verify transactions when recipients has extra data', async function () {
|
|
477
|
+
const txParams = newTxParamsWithExtraData();
|
|
478
|
+
const txPrebuild = newTxPrebuild();
|
|
479
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
480
|
+
txParams,
|
|
481
|
+
txPrebuild,
|
|
482
|
+
memo,
|
|
483
|
+
durableNonce,
|
|
484
|
+
wallet: walletObj,
|
|
485
|
+
});
|
|
486
|
+
validTransaction.should.equal(true);
|
|
487
|
+
});
|
|
488
|
+
it('should verify activate staking transaction', async function () {
|
|
489
|
+
const tx = await factory
|
|
490
|
+
.getStakingActivateBuilder()
|
|
491
|
+
.stakingAddress(stakeAccount.pub)
|
|
492
|
+
.sender(wallet.pub)
|
|
493
|
+
.nonce(blockHash)
|
|
494
|
+
.amount(amount)
|
|
495
|
+
.validator(validator.pub)
|
|
496
|
+
.memo('test memo')
|
|
497
|
+
.fee({ amount: 5000 })
|
|
498
|
+
.build();
|
|
499
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
500
|
+
const txParams = newTxParams();
|
|
501
|
+
const txPrebuild = newTxPrebuild();
|
|
502
|
+
txPrebuild.txBase64 = txToBroadcastFormat;
|
|
503
|
+
txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
|
|
504
|
+
txParams.recipients = [
|
|
505
|
+
{
|
|
506
|
+
address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
|
|
507
|
+
amount: amount,
|
|
508
|
+
},
|
|
509
|
+
];
|
|
510
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
511
|
+
txParams,
|
|
512
|
+
txPrebuild,
|
|
513
|
+
memo,
|
|
514
|
+
wallet: walletObj,
|
|
515
|
+
});
|
|
516
|
+
validTransaction.should.equal(true);
|
|
517
|
+
});
|
|
518
|
+
it('should verify withdraw staking transaction', async function () {
|
|
519
|
+
const tx = await factory
|
|
520
|
+
.getStakingWithdrawBuilder()
|
|
521
|
+
.stakingAddress(stakeAccount.pub)
|
|
522
|
+
.sender(wallet.pub)
|
|
523
|
+
.nonce(blockHash)
|
|
524
|
+
.amount(amount)
|
|
525
|
+
.memo('test memo')
|
|
526
|
+
.fee({ amount: 5000 })
|
|
527
|
+
.build();
|
|
528
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
529
|
+
const txParams = newTxParams();
|
|
530
|
+
const txPrebuild = newTxPrebuild();
|
|
531
|
+
txPrebuild.txBase64 = txToBroadcastFormat;
|
|
532
|
+
txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
|
|
533
|
+
txParams.recipients = [
|
|
534
|
+
{
|
|
535
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
536
|
+
amount: amount,
|
|
537
|
+
},
|
|
538
|
+
];
|
|
539
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
540
|
+
txParams,
|
|
541
|
+
txPrebuild,
|
|
542
|
+
memo,
|
|
543
|
+
wallet: walletObj,
|
|
544
|
+
});
|
|
545
|
+
validTransaction.should.equal(true);
|
|
546
|
+
});
|
|
547
|
+
it('should verify deactivate staking transaction', async function () {
|
|
548
|
+
const tx = await factory
|
|
549
|
+
.getStakingDeactivateBuilder()
|
|
550
|
+
.stakingAddress(stakeAccount.pub)
|
|
551
|
+
.sender(wallet.pub)
|
|
552
|
+
.nonce(blockHash)
|
|
553
|
+
.memo('test memo')
|
|
554
|
+
.fee({ amount: 5000 })
|
|
555
|
+
.build();
|
|
556
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
557
|
+
const txParams = newTxParams();
|
|
558
|
+
const txPrebuild = newTxPrebuild();
|
|
559
|
+
txPrebuild.txBase64 = txToBroadcastFormat;
|
|
560
|
+
txPrebuild.txInfo.nonce = '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen';
|
|
561
|
+
txParams.recipients = [];
|
|
562
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
563
|
+
txParams,
|
|
564
|
+
txPrebuild,
|
|
565
|
+
memo,
|
|
566
|
+
wallet: walletObj,
|
|
567
|
+
});
|
|
568
|
+
validTransaction.should.equal(true);
|
|
569
|
+
});
|
|
570
|
+
it('should verify create associated token account transaction', async function () {
|
|
571
|
+
const tx = await factory
|
|
572
|
+
.getAtaInitializationBuilder()
|
|
573
|
+
.mint('tsol:usdc')
|
|
574
|
+
.sender(wallet.pub)
|
|
575
|
+
.nonce(blockHash)
|
|
576
|
+
.memo('test memo')
|
|
577
|
+
.fee({ amount: 5000 })
|
|
578
|
+
.build();
|
|
579
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
580
|
+
const txParams = newTxParams();
|
|
581
|
+
const txPrebuild = newTxPrebuild();
|
|
582
|
+
txPrebuild.txBase64 = txToBroadcastFormat;
|
|
583
|
+
txPrebuild.txInfo.nonce = blockHash;
|
|
584
|
+
txParams.recipients = [];
|
|
585
|
+
const validTransaction = await basecoin.verifyTransaction({
|
|
586
|
+
txParams,
|
|
587
|
+
txPrebuild,
|
|
588
|
+
memo,
|
|
589
|
+
wallet: walletObj,
|
|
590
|
+
});
|
|
591
|
+
validTransaction.should.equal(true);
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
describe('getAmountBasedOnEndianness', () => {
|
|
595
|
+
let originalArch;
|
|
596
|
+
beforeEach(() => {
|
|
597
|
+
originalArch = process.arch;
|
|
598
|
+
});
|
|
599
|
+
afterEach(() => {
|
|
600
|
+
Object.defineProperty(process, 'arch', {
|
|
601
|
+
value: originalArch,
|
|
602
|
+
writable: true,
|
|
603
|
+
configurable: true,
|
|
604
|
+
});
|
|
605
|
+
});
|
|
606
|
+
it('should return amount unchanged on non-s390x architectures', function () {
|
|
607
|
+
Object.defineProperty(process, 'arch', {
|
|
608
|
+
value: 'x64',
|
|
609
|
+
writable: true,
|
|
610
|
+
configurable: true,
|
|
611
|
+
});
|
|
612
|
+
(0, src_1.getAmountBasedOnEndianness)('300000').should.equal('300000');
|
|
613
|
+
(0, src_1.getAmountBasedOnEndianness)('10000').should.equal('10000');
|
|
614
|
+
(0, src_1.getAmountBasedOnEndianness)('504403158265495552').should.equal('504403158265495552');
|
|
615
|
+
});
|
|
616
|
+
it('should byte-swap small amounts on s390x (small becomes huge)', function () {
|
|
617
|
+
Object.defineProperty(process, 'arch', {
|
|
618
|
+
value: 's390x',
|
|
619
|
+
writable: true,
|
|
620
|
+
configurable: true,
|
|
621
|
+
});
|
|
622
|
+
// Small amount 10,000 (0x2710) swaps to 1,163,899,028,698,562,560
|
|
623
|
+
(0, src_1.getAmountBasedOnEndianness)('10000').should.equal('1163899028698562560');
|
|
624
|
+
});
|
|
625
|
+
it('should byte-swap large amounts on s390x (large becomes tiny)', function () {
|
|
626
|
+
Object.defineProperty(process, 'arch', {
|
|
627
|
+
value: 's390x',
|
|
628
|
+
writable: true,
|
|
629
|
+
configurable: true,
|
|
630
|
+
});
|
|
631
|
+
// Large amount 504,403,158,265,495,552 (0x0700000000000000) swaps to 7
|
|
632
|
+
(0, src_1.getAmountBasedOnEndianness)('504403158265495552').should.equal('7');
|
|
633
|
+
});
|
|
634
|
+
it('should handle numeric input', function () {
|
|
635
|
+
Object.defineProperty(process, 'arch', {
|
|
636
|
+
value: 's390x',
|
|
637
|
+
writable: true,
|
|
638
|
+
configurable: true,
|
|
639
|
+
});
|
|
640
|
+
// Should work with numbers, not just strings
|
|
641
|
+
(0, src_1.getAmountBasedOnEndianness)(10000).should.equal('1163899028698562560');
|
|
642
|
+
});
|
|
643
|
+
it('should handle standard transaction amounts on s390x', function () {
|
|
644
|
+
Object.defineProperty(process, 'arch', {
|
|
645
|
+
value: 's390x',
|
|
646
|
+
writable: true,
|
|
647
|
+
configurable: true,
|
|
648
|
+
});
|
|
649
|
+
// Standard amount 300,000 (0x493E0) swaps to large value
|
|
650
|
+
const result = (0, src_1.getAmountBasedOnEndianness)('300000');
|
|
651
|
+
// Verify it's different (swapped)
|
|
652
|
+
result.should.not.equal('300000');
|
|
653
|
+
// Verify swapping back gives original
|
|
654
|
+
(0, src_1.getAmountBasedOnEndianness)(result).should.equal('300000');
|
|
655
|
+
});
|
|
656
|
+
it('should handle invalid input gracefully', function () {
|
|
657
|
+
Object.defineProperty(process, 'arch', {
|
|
658
|
+
value: 's390x',
|
|
659
|
+
writable: true,
|
|
660
|
+
configurable: true,
|
|
661
|
+
});
|
|
662
|
+
// Invalid BigInt input should return original string
|
|
663
|
+
(0, src_1.getAmountBasedOnEndianness)('not-a-number').should.equal('not-a-number');
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
it('should accept valid address', function () {
|
|
667
|
+
goodAddresses.forEach((addr) => {
|
|
668
|
+
basecoin.isValidAddress(addr).should.equal(true);
|
|
669
|
+
});
|
|
670
|
+
});
|
|
671
|
+
it('should reject invalid address', function () {
|
|
672
|
+
badAddresses.forEach((addr) => {
|
|
673
|
+
basecoin.isValidAddress(addr).should.equal(false);
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
it('should check valid pub keys', function () {
|
|
677
|
+
keyPair.should.have.property('pub');
|
|
678
|
+
basecoin.isValidPub(keyPair.pub).should.equal(true);
|
|
679
|
+
});
|
|
680
|
+
it('should check an invalid pub keys', function () {
|
|
681
|
+
const badPubKey = keyPair.pub.slice(0, keyPair.pub.length - 1) + '-';
|
|
682
|
+
basecoin.isValidPub(badPubKey).should.equal(false);
|
|
683
|
+
});
|
|
684
|
+
it('should check valid prv keys', function () {
|
|
685
|
+
keyPair.should.have.property('prv');
|
|
686
|
+
basecoin.isValidPrv(keyPair.prv).should.equal(true);
|
|
687
|
+
});
|
|
688
|
+
it('should check an invalid prv keys', function () {
|
|
689
|
+
const badPrvKey = keyPair.prv ? keyPair.prv.slice(0, keyPair.prv.length - 1) + '-' : undefined;
|
|
690
|
+
basecoin.isValidPrv(badPrvKey).should.equal(false);
|
|
691
|
+
});
|
|
692
|
+
describe('Parse Transactions:', () => {
|
|
693
|
+
it('should parse an unsigned transfer transaction', async function () {
|
|
694
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
695
|
+
txBase64: testData.rawTransactions.transfer.unsigned,
|
|
696
|
+
feeInfo: {
|
|
697
|
+
fee: '5000',
|
|
698
|
+
},
|
|
699
|
+
});
|
|
700
|
+
parsedTransaction.should.deepEqual({
|
|
701
|
+
inputs: [
|
|
702
|
+
{
|
|
703
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
704
|
+
amount: 305000,
|
|
705
|
+
},
|
|
706
|
+
],
|
|
707
|
+
outputs: [
|
|
708
|
+
{
|
|
709
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
710
|
+
amount: '300000',
|
|
711
|
+
},
|
|
712
|
+
],
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
it('should parse a signed transfer transaction', async function () {
|
|
716
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
717
|
+
txBase64: testData.rawTransactions.transfer.signed,
|
|
718
|
+
feeInfo: {
|
|
719
|
+
fee: '5000',
|
|
720
|
+
},
|
|
721
|
+
});
|
|
722
|
+
parsedTransaction.should.deepEqual({
|
|
723
|
+
inputs: [
|
|
724
|
+
{
|
|
725
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
726
|
+
amount: 305000,
|
|
727
|
+
},
|
|
728
|
+
],
|
|
729
|
+
outputs: [
|
|
730
|
+
{
|
|
731
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
732
|
+
amount: '300000',
|
|
733
|
+
},
|
|
734
|
+
],
|
|
735
|
+
});
|
|
736
|
+
});
|
|
737
|
+
it('should parse an unsigned wallet init transaction', async function () {
|
|
738
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
739
|
+
txBase64: testData.rawTransactions.walletInit.unsigned,
|
|
740
|
+
feeInfo: {
|
|
741
|
+
fee: '5000',
|
|
742
|
+
},
|
|
743
|
+
});
|
|
744
|
+
parsedTransaction.should.deepEqual({
|
|
745
|
+
inputs: [
|
|
746
|
+
{
|
|
747
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
748
|
+
amount: 310000,
|
|
749
|
+
},
|
|
750
|
+
],
|
|
751
|
+
outputs: [
|
|
752
|
+
{
|
|
753
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
754
|
+
amount: '300000',
|
|
755
|
+
},
|
|
756
|
+
],
|
|
757
|
+
});
|
|
758
|
+
});
|
|
759
|
+
it('should parse a signed wallet init transaction', async function () {
|
|
760
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
761
|
+
txBase64: testData.rawTransactions.walletInit.signed,
|
|
762
|
+
feeInfo: {
|
|
763
|
+
fee: '5000',
|
|
764
|
+
},
|
|
765
|
+
});
|
|
766
|
+
parsedTransaction.should.deepEqual({
|
|
767
|
+
inputs: [
|
|
768
|
+
{
|
|
769
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
770
|
+
amount: 310000,
|
|
771
|
+
},
|
|
772
|
+
],
|
|
773
|
+
outputs: [
|
|
774
|
+
{
|
|
775
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
776
|
+
amount: '300000',
|
|
777
|
+
},
|
|
778
|
+
],
|
|
779
|
+
});
|
|
780
|
+
});
|
|
781
|
+
it('should parse an unsigned transfer token transaction', async function () {
|
|
782
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
783
|
+
txBase64: testData.rawTransactions.transferToken.unsigned,
|
|
784
|
+
feeInfo: {
|
|
785
|
+
fee: '5000',
|
|
786
|
+
},
|
|
787
|
+
});
|
|
788
|
+
parsedTransaction.should.deepEqual({
|
|
789
|
+
inputs: [
|
|
790
|
+
{
|
|
791
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
792
|
+
amount: 5000,
|
|
793
|
+
},
|
|
794
|
+
],
|
|
795
|
+
outputs: [
|
|
796
|
+
{
|
|
797
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
798
|
+
amount: '300000',
|
|
799
|
+
tokenName: 'tsol:usdc',
|
|
800
|
+
},
|
|
801
|
+
],
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
it('should parse a signed transfer token transaction', async function () {
|
|
805
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
806
|
+
txBase64: testData.rawTransactions.transferToken.signed,
|
|
807
|
+
feeInfo: {
|
|
808
|
+
fee: '5000',
|
|
809
|
+
},
|
|
810
|
+
});
|
|
811
|
+
parsedTransaction.should.deepEqual({
|
|
812
|
+
inputs: [
|
|
813
|
+
{
|
|
814
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
815
|
+
amount: 5000,
|
|
816
|
+
},
|
|
817
|
+
],
|
|
818
|
+
outputs: [
|
|
819
|
+
{
|
|
820
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
821
|
+
amount: '300000',
|
|
822
|
+
tokenName: 'tsol:usdc',
|
|
823
|
+
},
|
|
824
|
+
],
|
|
825
|
+
});
|
|
826
|
+
});
|
|
827
|
+
});
|
|
828
|
+
describe('Explain Transactions:', () => {
|
|
829
|
+
it('should explain an unsigned transfer transaction', async function () {
|
|
830
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
831
|
+
txBase64: testData.rawTransactions.transfer.unsigned,
|
|
832
|
+
feeInfo: {
|
|
833
|
+
fee: '5000',
|
|
834
|
+
},
|
|
835
|
+
});
|
|
836
|
+
explainedTransaction.should.deepEqual({
|
|
837
|
+
displayOrder: [
|
|
838
|
+
'id',
|
|
839
|
+
'type',
|
|
840
|
+
'blockhash',
|
|
841
|
+
'durableNonce',
|
|
842
|
+
'outputAmount',
|
|
843
|
+
'changeAmount',
|
|
844
|
+
'outputs',
|
|
845
|
+
'changeOutputs',
|
|
846
|
+
'tokenEnablements',
|
|
847
|
+
'fee',
|
|
848
|
+
'memo',
|
|
849
|
+
],
|
|
850
|
+
id: 'UNAVAILABLE',
|
|
851
|
+
type: 'Send',
|
|
852
|
+
changeOutputs: [],
|
|
853
|
+
changeAmount: '0',
|
|
854
|
+
outputAmount: '300000',
|
|
855
|
+
outputs: [
|
|
856
|
+
{
|
|
857
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
858
|
+
amount: '300000',
|
|
859
|
+
},
|
|
860
|
+
],
|
|
861
|
+
inputs: [
|
|
862
|
+
{
|
|
863
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
864
|
+
value: '300000',
|
|
865
|
+
},
|
|
866
|
+
],
|
|
867
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
868
|
+
fee: {
|
|
869
|
+
fee: '5000',
|
|
870
|
+
feeRate: 5000,
|
|
871
|
+
},
|
|
872
|
+
memo: 'test memo',
|
|
873
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
874
|
+
durableNonce: {
|
|
875
|
+
authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
876
|
+
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
877
|
+
},
|
|
878
|
+
tokenEnablements: [],
|
|
879
|
+
ataOwnerMap: {},
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
it('should explain a signed transfer transaction', async function () {
|
|
883
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
884
|
+
txBase64: testData.rawTransactions.transfer.signed,
|
|
885
|
+
feeInfo: {
|
|
886
|
+
fee: '5000',
|
|
887
|
+
},
|
|
888
|
+
});
|
|
889
|
+
explainedTransaction.should.deepEqual({
|
|
890
|
+
displayOrder: [
|
|
891
|
+
'id',
|
|
892
|
+
'type',
|
|
893
|
+
'blockhash',
|
|
894
|
+
'durableNonce',
|
|
895
|
+
'outputAmount',
|
|
896
|
+
'changeAmount',
|
|
897
|
+
'outputs',
|
|
898
|
+
'changeOutputs',
|
|
899
|
+
'tokenEnablements',
|
|
900
|
+
'fee',
|
|
901
|
+
'memo',
|
|
902
|
+
],
|
|
903
|
+
id: '2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L',
|
|
904
|
+
type: 'Send',
|
|
905
|
+
changeOutputs: [],
|
|
906
|
+
changeAmount: '0',
|
|
907
|
+
outputAmount: '300000',
|
|
908
|
+
outputs: [
|
|
909
|
+
{
|
|
910
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
911
|
+
amount: '300000',
|
|
912
|
+
},
|
|
913
|
+
],
|
|
914
|
+
inputs: [
|
|
915
|
+
{
|
|
916
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
917
|
+
value: '300000',
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
921
|
+
fee: {
|
|
922
|
+
fee: '5000',
|
|
923
|
+
feeRate: 5000,
|
|
924
|
+
},
|
|
925
|
+
memo: 'test memo',
|
|
926
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
927
|
+
durableNonce: {
|
|
928
|
+
authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
929
|
+
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
930
|
+
},
|
|
931
|
+
tokenEnablements: [],
|
|
932
|
+
ataOwnerMap: {},
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
it('should explain an unsigned wallet init transaction', async function () {
|
|
936
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
937
|
+
txBase64: testData.rawTransactions.walletInit.unsigned,
|
|
938
|
+
feeInfo: {
|
|
939
|
+
fee: '5000',
|
|
940
|
+
},
|
|
941
|
+
});
|
|
942
|
+
explainedTransaction.should.deepEqual({
|
|
943
|
+
displayOrder: [
|
|
944
|
+
'id',
|
|
945
|
+
'type',
|
|
946
|
+
'blockhash',
|
|
947
|
+
'durableNonce',
|
|
948
|
+
'outputAmount',
|
|
949
|
+
'changeAmount',
|
|
950
|
+
'outputs',
|
|
951
|
+
'changeOutputs',
|
|
952
|
+
'tokenEnablements',
|
|
953
|
+
'fee',
|
|
954
|
+
'memo',
|
|
955
|
+
],
|
|
956
|
+
id: 'UNAVAILABLE',
|
|
957
|
+
type: 'WalletInitialization',
|
|
958
|
+
changeOutputs: [],
|
|
959
|
+
changeAmount: '0',
|
|
960
|
+
outputAmount: '300000',
|
|
961
|
+
outputs: [
|
|
962
|
+
{
|
|
963
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
964
|
+
amount: '300000',
|
|
965
|
+
},
|
|
966
|
+
],
|
|
967
|
+
inputs: [
|
|
968
|
+
{
|
|
969
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
970
|
+
value: '300000',
|
|
971
|
+
},
|
|
972
|
+
],
|
|
973
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
974
|
+
fee: {
|
|
975
|
+
fee: '10000',
|
|
976
|
+
feeRate: 5000,
|
|
977
|
+
},
|
|
978
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
979
|
+
durableNonce: undefined,
|
|
980
|
+
memo: undefined,
|
|
981
|
+
tokenEnablements: [],
|
|
982
|
+
ataOwnerMap: {},
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
it('should explain a signed wallet init transaction', async function () {
|
|
986
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
987
|
+
txBase64: testData.rawTransactions.walletInit.signed,
|
|
988
|
+
feeInfo: {
|
|
989
|
+
fee: '5000',
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
explainedTransaction.should.deepEqual({
|
|
993
|
+
displayOrder: [
|
|
994
|
+
'id',
|
|
995
|
+
'type',
|
|
996
|
+
'blockhash',
|
|
997
|
+
'durableNonce',
|
|
998
|
+
'outputAmount',
|
|
999
|
+
'changeAmount',
|
|
1000
|
+
'outputs',
|
|
1001
|
+
'changeOutputs',
|
|
1002
|
+
'tokenEnablements',
|
|
1003
|
+
'fee',
|
|
1004
|
+
'memo',
|
|
1005
|
+
],
|
|
1006
|
+
id: '7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg',
|
|
1007
|
+
type: 'WalletInitialization',
|
|
1008
|
+
changeOutputs: [],
|
|
1009
|
+
changeAmount: '0',
|
|
1010
|
+
outputAmount: '300000',
|
|
1011
|
+
outputs: [
|
|
1012
|
+
{
|
|
1013
|
+
address: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
1014
|
+
amount: '300000',
|
|
1015
|
+
},
|
|
1016
|
+
],
|
|
1017
|
+
inputs: [
|
|
1018
|
+
{
|
|
1019
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1020
|
+
value: '300000',
|
|
1021
|
+
},
|
|
1022
|
+
],
|
|
1023
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1024
|
+
fee: {
|
|
1025
|
+
fee: '10000',
|
|
1026
|
+
feeRate: 5000,
|
|
1027
|
+
},
|
|
1028
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
1029
|
+
durableNonce: undefined,
|
|
1030
|
+
memo: undefined,
|
|
1031
|
+
tokenEnablements: [],
|
|
1032
|
+
ataOwnerMap: {},
|
|
1033
|
+
});
|
|
1034
|
+
});
|
|
1035
|
+
it('should explain an unsigned token transfer transaction', async function () {
|
|
1036
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1037
|
+
txBase64: testData.rawTransactions.transferToken.unsigned,
|
|
1038
|
+
feeInfo: {
|
|
1039
|
+
fee: '5000',
|
|
1040
|
+
},
|
|
1041
|
+
});
|
|
1042
|
+
explainedTransaction.should.deepEqual({
|
|
1043
|
+
displayOrder: [
|
|
1044
|
+
'id',
|
|
1045
|
+
'type',
|
|
1046
|
+
'blockhash',
|
|
1047
|
+
'durableNonce',
|
|
1048
|
+
'outputAmount',
|
|
1049
|
+
'changeAmount',
|
|
1050
|
+
'outputs',
|
|
1051
|
+
'changeOutputs',
|
|
1052
|
+
'tokenEnablements',
|
|
1053
|
+
'fee',
|
|
1054
|
+
'memo',
|
|
1055
|
+
],
|
|
1056
|
+
id: 'UNAVAILABLE',
|
|
1057
|
+
type: 'Send',
|
|
1058
|
+
changeOutputs: [],
|
|
1059
|
+
changeAmount: '0',
|
|
1060
|
+
outputAmount: '0',
|
|
1061
|
+
outputs: [
|
|
1062
|
+
{
|
|
1063
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
1064
|
+
amount: '300000',
|
|
1065
|
+
tokenName: 'tsol:usdc',
|
|
1066
|
+
},
|
|
1067
|
+
],
|
|
1068
|
+
inputs: [
|
|
1069
|
+
{
|
|
1070
|
+
address: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1071
|
+
value: '300000',
|
|
1072
|
+
},
|
|
1073
|
+
],
|
|
1074
|
+
feePayer: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1075
|
+
fee: {
|
|
1076
|
+
fee: '5000',
|
|
1077
|
+
feeRate: 5000,
|
|
1078
|
+
},
|
|
1079
|
+
memo: 'test memo',
|
|
1080
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
1081
|
+
durableNonce: {
|
|
1082
|
+
authWalletAddress: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1083
|
+
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
1084
|
+
},
|
|
1085
|
+
tokenEnablements: [],
|
|
1086
|
+
ataOwnerMap: {},
|
|
1087
|
+
});
|
|
1088
|
+
});
|
|
1089
|
+
it('should explain a signed token transfer transaction', async function () {
|
|
1090
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1091
|
+
txBase64: testData.rawTransactions.transferToken.signed,
|
|
1092
|
+
feeInfo: {
|
|
1093
|
+
fee: '5000',
|
|
1094
|
+
},
|
|
1095
|
+
});
|
|
1096
|
+
explainedTransaction.should.deepEqual({
|
|
1097
|
+
displayOrder: [
|
|
1098
|
+
'id',
|
|
1099
|
+
'type',
|
|
1100
|
+
'blockhash',
|
|
1101
|
+
'durableNonce',
|
|
1102
|
+
'outputAmount',
|
|
1103
|
+
'changeAmount',
|
|
1104
|
+
'outputs',
|
|
1105
|
+
'changeOutputs',
|
|
1106
|
+
'tokenEnablements',
|
|
1107
|
+
'fee',
|
|
1108
|
+
'memo',
|
|
1109
|
+
],
|
|
1110
|
+
id: '2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ',
|
|
1111
|
+
type: 'Send',
|
|
1112
|
+
changeOutputs: [],
|
|
1113
|
+
changeAmount: '0',
|
|
1114
|
+
outputAmount: '0',
|
|
1115
|
+
outputs: [
|
|
1116
|
+
{
|
|
1117
|
+
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
|
|
1118
|
+
amount: '300000',
|
|
1119
|
+
tokenName: 'tsol:usdc',
|
|
1120
|
+
},
|
|
1121
|
+
],
|
|
1122
|
+
inputs: [
|
|
1123
|
+
{
|
|
1124
|
+
address: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1125
|
+
value: '300000',
|
|
1126
|
+
},
|
|
1127
|
+
],
|
|
1128
|
+
feePayer: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1129
|
+
fee: {
|
|
1130
|
+
fee: '5000',
|
|
1131
|
+
feeRate: 5000,
|
|
1132
|
+
},
|
|
1133
|
+
memo: 'test memo',
|
|
1134
|
+
blockhash: 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi',
|
|
1135
|
+
durableNonce: {
|
|
1136
|
+
authWalletAddress: '12f6D3WubGVeQoH2m8kTvvcrasWdXWwtVzUCyRNDZxA2',
|
|
1137
|
+
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
1138
|
+
},
|
|
1139
|
+
tokenEnablements: [],
|
|
1140
|
+
ataOwnerMap: {},
|
|
1141
|
+
});
|
|
1142
|
+
});
|
|
1143
|
+
it('should explain activate staking transaction', async function () {
|
|
1144
|
+
const tx = await factory
|
|
1145
|
+
.getStakingActivateBuilder()
|
|
1146
|
+
.stakingAddress(stakeAccount.pub)
|
|
1147
|
+
.sender(wallet.pub)
|
|
1148
|
+
.nonce(blockHash)
|
|
1149
|
+
.amount(amount)
|
|
1150
|
+
.validator(validator.pub)
|
|
1151
|
+
.memo('test memo')
|
|
1152
|
+
.fee({ amount: 5000 })
|
|
1153
|
+
.build();
|
|
1154
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
1155
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1156
|
+
txBase64: txToBroadcastFormat,
|
|
1157
|
+
feeInfo: {
|
|
1158
|
+
fee: '5000',
|
|
1159
|
+
},
|
|
1160
|
+
});
|
|
1161
|
+
explainedTransaction.should.deepEqual({
|
|
1162
|
+
displayOrder: [
|
|
1163
|
+
'id',
|
|
1164
|
+
'type',
|
|
1165
|
+
'blockhash',
|
|
1166
|
+
'durableNonce',
|
|
1167
|
+
'outputAmount',
|
|
1168
|
+
'changeAmount',
|
|
1169
|
+
'outputs',
|
|
1170
|
+
'changeOutputs',
|
|
1171
|
+
'tokenEnablements',
|
|
1172
|
+
'fee',
|
|
1173
|
+
'memo',
|
|
1174
|
+
],
|
|
1175
|
+
id: 'UNAVAILABLE',
|
|
1176
|
+
type: 'StakingActivate',
|
|
1177
|
+
changeOutputs: [],
|
|
1178
|
+
changeAmount: '0',
|
|
1179
|
+
outputAmount: '10000',
|
|
1180
|
+
outputs: [
|
|
1181
|
+
{
|
|
1182
|
+
address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
|
|
1183
|
+
amount: '10000',
|
|
1184
|
+
},
|
|
1185
|
+
],
|
|
1186
|
+
inputs: [
|
|
1187
|
+
{
|
|
1188
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1189
|
+
value: '10000',
|
|
1190
|
+
},
|
|
1191
|
+
],
|
|
1192
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1193
|
+
fee: {
|
|
1194
|
+
fee: '10000',
|
|
1195
|
+
feeRate: 5000,
|
|
1196
|
+
},
|
|
1197
|
+
memo: 'test memo',
|
|
1198
|
+
blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
|
|
1199
|
+
durableNonce: undefined,
|
|
1200
|
+
tokenEnablements: [],
|
|
1201
|
+
ataOwnerMap: {},
|
|
1202
|
+
});
|
|
1203
|
+
});
|
|
1204
|
+
it('should explain deactivate staking transaction', async function () {
|
|
1205
|
+
const tx = await factory
|
|
1206
|
+
.getStakingDeactivateBuilder()
|
|
1207
|
+
.stakingAddress(stakeAccount.pub)
|
|
1208
|
+
.sender(wallet.pub)
|
|
1209
|
+
.nonce(blockHash)
|
|
1210
|
+
.memo('test memo')
|
|
1211
|
+
.fee({ amount: 5000 })
|
|
1212
|
+
.build();
|
|
1213
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
1214
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1215
|
+
txBase64: txToBroadcastFormat,
|
|
1216
|
+
feeInfo: {
|
|
1217
|
+
fee: '5000',
|
|
1218
|
+
},
|
|
1219
|
+
});
|
|
1220
|
+
explainedTransaction.should.deepEqual({
|
|
1221
|
+
displayOrder: [
|
|
1222
|
+
'id',
|
|
1223
|
+
'type',
|
|
1224
|
+
'blockhash',
|
|
1225
|
+
'durableNonce',
|
|
1226
|
+
'outputAmount',
|
|
1227
|
+
'changeAmount',
|
|
1228
|
+
'outputs',
|
|
1229
|
+
'changeOutputs',
|
|
1230
|
+
'tokenEnablements',
|
|
1231
|
+
'fee',
|
|
1232
|
+
'memo',
|
|
1233
|
+
],
|
|
1234
|
+
id: 'UNAVAILABLE',
|
|
1235
|
+
type: 'StakingDeactivate',
|
|
1236
|
+
changeOutputs: [],
|
|
1237
|
+
changeAmount: '0',
|
|
1238
|
+
outputAmount: '0',
|
|
1239
|
+
outputs: [],
|
|
1240
|
+
inputs: [],
|
|
1241
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1242
|
+
fee: {
|
|
1243
|
+
fee: '5000',
|
|
1244
|
+
feeRate: 5000,
|
|
1245
|
+
},
|
|
1246
|
+
memo: 'test memo',
|
|
1247
|
+
blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
|
|
1248
|
+
durableNonce: undefined,
|
|
1249
|
+
tokenEnablements: [],
|
|
1250
|
+
ataOwnerMap: {},
|
|
1251
|
+
});
|
|
1252
|
+
});
|
|
1253
|
+
it('should explain withdraw staking transaction', async function () {
|
|
1254
|
+
const tx = await factory
|
|
1255
|
+
.getStakingWithdrawBuilder()
|
|
1256
|
+
.stakingAddress(stakeAccount.pub)
|
|
1257
|
+
.sender(wallet.pub)
|
|
1258
|
+
.nonce(blockHash)
|
|
1259
|
+
.amount(amount)
|
|
1260
|
+
.memo('test memo')
|
|
1261
|
+
.fee({ amount: 5000 })
|
|
1262
|
+
.build();
|
|
1263
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
1264
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1265
|
+
txBase64: txToBroadcastFormat,
|
|
1266
|
+
feeInfo: {
|
|
1267
|
+
fee: '5000',
|
|
1268
|
+
},
|
|
1269
|
+
});
|
|
1270
|
+
explainedTransaction.should.deepEqual({
|
|
1271
|
+
displayOrder: [
|
|
1272
|
+
'id',
|
|
1273
|
+
'type',
|
|
1274
|
+
'blockhash',
|
|
1275
|
+
'durableNonce',
|
|
1276
|
+
'outputAmount',
|
|
1277
|
+
'changeAmount',
|
|
1278
|
+
'outputs',
|
|
1279
|
+
'changeOutputs',
|
|
1280
|
+
'tokenEnablements',
|
|
1281
|
+
'fee',
|
|
1282
|
+
'memo',
|
|
1283
|
+
],
|
|
1284
|
+
id: 'UNAVAILABLE',
|
|
1285
|
+
type: 'StakingWithdraw',
|
|
1286
|
+
changeOutputs: [],
|
|
1287
|
+
changeAmount: '0',
|
|
1288
|
+
outputAmount: '10000',
|
|
1289
|
+
outputs: [
|
|
1290
|
+
{
|
|
1291
|
+
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1292
|
+
amount: '10000',
|
|
1293
|
+
},
|
|
1294
|
+
],
|
|
1295
|
+
inputs: [
|
|
1296
|
+
{
|
|
1297
|
+
address: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
|
|
1298
|
+
value: '10000',
|
|
1299
|
+
},
|
|
1300
|
+
],
|
|
1301
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1302
|
+
fee: {
|
|
1303
|
+
fee: '5000',
|
|
1304
|
+
feeRate: 5000,
|
|
1305
|
+
},
|
|
1306
|
+
memo: 'test memo',
|
|
1307
|
+
blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
|
|
1308
|
+
durableNonce: undefined,
|
|
1309
|
+
tokenEnablements: [],
|
|
1310
|
+
ataOwnerMap: {},
|
|
1311
|
+
});
|
|
1312
|
+
});
|
|
1313
|
+
it('should explain create ATA transaction', async function () {
|
|
1314
|
+
const tokenName = 'tsol:usdc';
|
|
1315
|
+
const rentExemptAmount = '3000000';
|
|
1316
|
+
const tx = await factory
|
|
1317
|
+
.getAtaInitializationBuilder()
|
|
1318
|
+
.sender(wallet.pub)
|
|
1319
|
+
.nonce(blockHash)
|
|
1320
|
+
.mint(tokenName)
|
|
1321
|
+
.rentExemptAmount(rentExemptAmount)
|
|
1322
|
+
.memo('test memo')
|
|
1323
|
+
.fee({ amount: 5000 })
|
|
1324
|
+
.build();
|
|
1325
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
1326
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1327
|
+
txBase64: txToBroadcastFormat,
|
|
1328
|
+
feeInfo: {
|
|
1329
|
+
fee: '5000',
|
|
1330
|
+
},
|
|
1331
|
+
tokenAccountRentExemptAmount: rentExemptAmount,
|
|
1332
|
+
});
|
|
1333
|
+
explainedTransaction.should.deepEqual({
|
|
1334
|
+
displayOrder: [
|
|
1335
|
+
'id',
|
|
1336
|
+
'type',
|
|
1337
|
+
'blockhash',
|
|
1338
|
+
'durableNonce',
|
|
1339
|
+
'outputAmount',
|
|
1340
|
+
'changeAmount',
|
|
1341
|
+
'outputs',
|
|
1342
|
+
'changeOutputs',
|
|
1343
|
+
'tokenEnablements',
|
|
1344
|
+
'fee',
|
|
1345
|
+
'memo',
|
|
1346
|
+
],
|
|
1347
|
+
id: 'UNAVAILABLE',
|
|
1348
|
+
type: 'AssociatedTokenAccountInitialization',
|
|
1349
|
+
changeOutputs: [],
|
|
1350
|
+
changeAmount: '0',
|
|
1351
|
+
outputAmount: '0',
|
|
1352
|
+
outputs: [],
|
|
1353
|
+
inputs: [],
|
|
1354
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1355
|
+
fee: {
|
|
1356
|
+
fee: '3005000',
|
|
1357
|
+
feeRate: 5000,
|
|
1358
|
+
},
|
|
1359
|
+
memo: 'test memo',
|
|
1360
|
+
blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
|
|
1361
|
+
durableNonce: undefined,
|
|
1362
|
+
tokenEnablements: [
|
|
1363
|
+
{
|
|
1364
|
+
address: '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU',
|
|
1365
|
+
tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
|
|
1366
|
+
tokenName: 'tsol:usdc',
|
|
1367
|
+
},
|
|
1368
|
+
],
|
|
1369
|
+
ataOwnerMap: {
|
|
1370
|
+
'141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU': '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1371
|
+
},
|
|
1372
|
+
});
|
|
1373
|
+
});
|
|
1374
|
+
it('should explain create multi ATA transaction', async function () {
|
|
1375
|
+
const recipients = [
|
|
1376
|
+
{
|
|
1377
|
+
ownerAddress: wallet.pub,
|
|
1378
|
+
tokenName: 'tsol:usdc',
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
ownerAddress: durableNonce.walletNonceAddress,
|
|
1382
|
+
tokenName: 'tsol:ray',
|
|
1383
|
+
},
|
|
1384
|
+
];
|
|
1385
|
+
const rentExemptAmount = '3000000';
|
|
1386
|
+
const tx = await factory
|
|
1387
|
+
.getAtaInitializationBuilder()
|
|
1388
|
+
.sender(wallet.pub)
|
|
1389
|
+
.nonce(blockHash)
|
|
1390
|
+
.enableToken(recipients[0])
|
|
1391
|
+
.enableToken(recipients[1])
|
|
1392
|
+
.rentExemptAmount(rentExemptAmount)
|
|
1393
|
+
.memo('test memo')
|
|
1394
|
+
.fee({ amount: 5000 })
|
|
1395
|
+
.build();
|
|
1396
|
+
const txToBroadcastFormat = tx.toBroadcastFormat();
|
|
1397
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1398
|
+
txBase64: txToBroadcastFormat,
|
|
1399
|
+
feeInfo: {
|
|
1400
|
+
fee: '5000',
|
|
1401
|
+
},
|
|
1402
|
+
tokenAccountRentExemptAmount: rentExemptAmount,
|
|
1403
|
+
});
|
|
1404
|
+
explainedTransaction.should.deepEqual({
|
|
1405
|
+
displayOrder: [
|
|
1406
|
+
'id',
|
|
1407
|
+
'type',
|
|
1408
|
+
'blockhash',
|
|
1409
|
+
'durableNonce',
|
|
1410
|
+
'outputAmount',
|
|
1411
|
+
'changeAmount',
|
|
1412
|
+
'outputs',
|
|
1413
|
+
'changeOutputs',
|
|
1414
|
+
'tokenEnablements',
|
|
1415
|
+
'fee',
|
|
1416
|
+
'memo',
|
|
1417
|
+
],
|
|
1418
|
+
id: 'UNAVAILABLE',
|
|
1419
|
+
type: 'AssociatedTokenAccountInitialization',
|
|
1420
|
+
changeOutputs: [],
|
|
1421
|
+
changeAmount: '0',
|
|
1422
|
+
outputAmount: '0',
|
|
1423
|
+
outputs: [],
|
|
1424
|
+
inputs: [],
|
|
1425
|
+
feePayer: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1426
|
+
fee: {
|
|
1427
|
+
fee: '6005000',
|
|
1428
|
+
feeRate: 5000,
|
|
1429
|
+
},
|
|
1430
|
+
memo: 'test memo',
|
|
1431
|
+
blockhash: '5ne7phA48Jrvpn39AtupB8ZkCCAy8gLTfpGihZPuDqen',
|
|
1432
|
+
durableNonce: undefined,
|
|
1433
|
+
tokenEnablements: [
|
|
1434
|
+
{
|
|
1435
|
+
address: '141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU',
|
|
1436
|
+
tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
|
|
1437
|
+
tokenName: 'tsol:usdc',
|
|
1438
|
+
},
|
|
1439
|
+
{
|
|
1440
|
+
address: '9KaLinZFNW5chL4J8UoKnTECppWVMz3ewgx4FAkxUDcf',
|
|
1441
|
+
tokenAddress: '9kLJoGbMgSteptkhKKuh7ken4JEvHrT83157ezEGrZ7R',
|
|
1442
|
+
tokenName: 'tsol:ray',
|
|
1443
|
+
},
|
|
1444
|
+
],
|
|
1445
|
+
ataOwnerMap: {
|
|
1446
|
+
'141BFNem3pknc8CzPVLv1Ri3btgKdCsafYP5nXwmXfxU': '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
|
|
1447
|
+
'9KaLinZFNW5chL4J8UoKnTECppWVMz3ewgx4FAkxUDcf': '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
|
|
1448
|
+
},
|
|
1449
|
+
});
|
|
1450
|
+
});
|
|
1451
|
+
it('should explain an unsigned token transfer with ATA creation transaction', async function () {
|
|
1452
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
1453
|
+
txBase64: testData.rawTransactions.tokenTransferWithAtaCreation.unsigned,
|
|
1454
|
+
feeInfo: {
|
|
1455
|
+
fee: '5000',
|
|
1456
|
+
},
|
|
1457
|
+
tokenAccountRentExemptAmount: '3000000',
|
|
1458
|
+
});
|
|
1459
|
+
explainedTransaction.should.deepEqual({
|
|
1460
|
+
displayOrder: [
|
|
1461
|
+
'id',
|
|
1462
|
+
'type',
|
|
1463
|
+
'blockhash',
|
|
1464
|
+
'durableNonce',
|
|
1465
|
+
'outputAmount',
|
|
1466
|
+
'changeAmount',
|
|
1467
|
+
'outputs',
|
|
1468
|
+
'changeOutputs',
|
|
1469
|
+
'tokenEnablements',
|
|
1470
|
+
'fee',
|
|
1471
|
+
'memo',
|
|
1472
|
+
],
|
|
1473
|
+
id: 'UNAVAILABLE',
|
|
1474
|
+
type: 'Send',
|
|
1475
|
+
changeOutputs: [],
|
|
1476
|
+
changeAmount: '0',
|
|
1477
|
+
outputAmount: '0',
|
|
1478
|
+
outputs: [
|
|
1479
|
+
{
|
|
1480
|
+
address: '2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS',
|
|
1481
|
+
amount: '10000',
|
|
1482
|
+
tokenName: 'tsol:usdc',
|
|
1483
|
+
},
|
|
1484
|
+
],
|
|
1485
|
+
inputs: [
|
|
1486
|
+
{
|
|
1487
|
+
address: '5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7',
|
|
1488
|
+
value: '10000',
|
|
1489
|
+
},
|
|
1490
|
+
],
|
|
1491
|
+
feePayer: '5U3bH5b6XtG99aVWLqwVzYPVpQiFHytBD68Rz2eFPZd7',
|
|
1492
|
+
fee: { fee: '3005000', feeRate: 5000 },
|
|
1493
|
+
memo: undefined,
|
|
1494
|
+
blockhash: '27E3MXFvXMUNYeMJeX1pAbERGsJfUbkaZTfgMgpmNN5g',
|
|
1495
|
+
durableNonce: undefined,
|
|
1496
|
+
tokenEnablements: [
|
|
1497
|
+
{
|
|
1498
|
+
address: '2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS',
|
|
1499
|
+
tokenAddress: 'F4uLeXJoFz3hw13MposuwaQbMcZbCjqvEGPPeRRB1Byf',
|
|
1500
|
+
tokenName: 'tsol:usdc',
|
|
1501
|
+
},
|
|
1502
|
+
],
|
|
1503
|
+
ataOwnerMap: {
|
|
1504
|
+
'2eKjVtzV3oPTXFdtRSDj3Em9k1MV7k8WjKkBszQUwizS': 'C4zCqCaDm4D78zgaH3CeBEEBEAoMNhzSCj23qE92ndiP',
|
|
1505
|
+
},
|
|
1506
|
+
});
|
|
1507
|
+
});
|
|
1508
|
+
});
|
|
1509
|
+
describe('Keypair:', () => {
|
|
1510
|
+
it('should generate a keypair from random seed', function () {
|
|
1511
|
+
should.throws(() => basecoin.generateKeyPair('placeholder'), 'generateKeyPair method not implemented');
|
|
1512
|
+
});
|
|
1513
|
+
it('should generate a keypair from a seed', function () {
|
|
1514
|
+
should.throws(() => basecoin.generateKeyPair('placeholder'), 'generateKeyPair method not implemented');
|
|
1515
|
+
});
|
|
1516
|
+
});
|
|
1517
|
+
describe('Sign transaction:', () => {
|
|
1518
|
+
it('should sign transaction', async function () {
|
|
1519
|
+
const signed = await basecoin.signTransaction({
|
|
1520
|
+
txPrebuild: {
|
|
1521
|
+
txBase64: resources.RAW_TX_UNSIGNED,
|
|
1522
|
+
keys: [resources.accountWithSeed.publicKey.toString()],
|
|
1523
|
+
},
|
|
1524
|
+
prv: resources.accountWithSeed.privateKey.base58,
|
|
1525
|
+
});
|
|
1526
|
+
signed.txHex.should.equal(resources.RAW_TX_SIGNED);
|
|
1527
|
+
});
|
|
1528
|
+
it('should handle txHex and txBase64 interchangeably', async function () {
|
|
1529
|
+
const signed = await basecoin.signTransaction({
|
|
1530
|
+
txPrebuild: {
|
|
1531
|
+
txHex: resources.RAW_TX_UNSIGNED,
|
|
1532
|
+
keys: [resources.accountWithSeed.publicKey.toString()],
|
|
1533
|
+
},
|
|
1534
|
+
prv: resources.accountWithSeed.privateKey.base58,
|
|
1535
|
+
});
|
|
1536
|
+
signed.txHex.should.equal(resources.RAW_TX_SIGNED);
|
|
1537
|
+
});
|
|
1538
|
+
it('should throw invalid transaction when sign with public key', async function () {
|
|
1539
|
+
await basecoin
|
|
1540
|
+
.signTransaction({
|
|
1541
|
+
txPrebuild: {
|
|
1542
|
+
txBase64: resources.RAW_TX_UNSIGNED,
|
|
1543
|
+
keys: [resources.accountWithSeed.publicKey.toString()],
|
|
1544
|
+
},
|
|
1545
|
+
prv: resources.accountWithSeed.publicKey,
|
|
1546
|
+
})
|
|
1547
|
+
.should.be.rejectedWith('Invalid key');
|
|
1548
|
+
});
|
|
1549
|
+
});
|
|
1550
|
+
describe('Sign message', () => {
|
|
1551
|
+
it('should sign message', async function () {
|
|
1552
|
+
const signed = await basecoin.signMessage(keypair, 'signed message');
|
|
1553
|
+
signed
|
|
1554
|
+
.toString('base64')
|
|
1555
|
+
.should.equal('s+7d/8aW/twfM/0wLSKOGxd9+LhDIiz/g0FfJ39ylJhQIkjK0RYPm/Y+gdeJ5DIy6K6h6gCXXESDomlv12DBBQ==');
|
|
1556
|
+
});
|
|
1557
|
+
it('shouldnt sign message when message is undefined', async function () {
|
|
1558
|
+
await basecoin
|
|
1559
|
+
.signMessage(keypair, undefined)
|
|
1560
|
+
.should.be.rejectedWith('The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined');
|
|
1561
|
+
});
|
|
1562
|
+
});
|
|
1563
|
+
describe('Get Signing Payload', () => {
|
|
1564
|
+
it('should return a valid signing payload', async function () {
|
|
1565
|
+
const factory = (0, getBuilderFactory_1.getBuilderFactory)(basecoin.getChain());
|
|
1566
|
+
const rebuiltSignablePayload = (await factory.from(resources.TRANSFER_UNSIGNED_TX_WITH_MEMO).build())
|
|
1567
|
+
.signablePayload;
|
|
1568
|
+
const signingPayload = await basecoin.getSignablePayload(resources.TRANSFER_UNSIGNED_TX_WITH_MEMO);
|
|
1569
|
+
signingPayload.should.be.deepEqual(rebuiltSignablePayload);
|
|
1570
|
+
});
|
|
1571
|
+
it('should build CloseAssociatedTokenAccount txn builder from raw txn', async function () {
|
|
1572
|
+
const factory = (0, getBuilderFactory_1.getBuilderFactory)(basecoin.getChain());
|
|
1573
|
+
const txnBuilder = factory.from(resources.TRANSFER_UNSIGNED_TX_CLOSE_ATA);
|
|
1574
|
+
assert_1.default.ok(txnBuilder);
|
|
1575
|
+
});
|
|
1576
|
+
});
|
|
1577
|
+
describe('Presign transaction', () => {
|
|
1578
|
+
const txRequestId = 'txRequestId';
|
|
1579
|
+
let sandbox;
|
|
1580
|
+
beforeEach(() => {
|
|
1581
|
+
sandbox = sinon.createSandbox();
|
|
1582
|
+
});
|
|
1583
|
+
afterEach(() => {
|
|
1584
|
+
sandbox.verifyAndRestore();
|
|
1585
|
+
});
|
|
1586
|
+
it('should rebuild tx request for hot wallets', async () => {
|
|
1587
|
+
const rebuiltTx = {
|
|
1588
|
+
txRequestId,
|
|
1589
|
+
unsignedTxs: [
|
|
1590
|
+
{
|
|
1591
|
+
serializedTxHex: 'deadbeef',
|
|
1592
|
+
signableHex: 'serializedTxHex',
|
|
1593
|
+
derivationPath: 'm/0',
|
|
1594
|
+
},
|
|
1595
|
+
],
|
|
1596
|
+
transactions: [],
|
|
1597
|
+
date: new Date().toISOString(),
|
|
1598
|
+
intent: {
|
|
1599
|
+
intentType: 'payment',
|
|
1600
|
+
},
|
|
1601
|
+
latest: true,
|
|
1602
|
+
state: 'pendingUserSignature',
|
|
1603
|
+
walletType: 'hot',
|
|
1604
|
+
walletId: 'walletId',
|
|
1605
|
+
policiesChecked: true,
|
|
1606
|
+
version: 1,
|
|
1607
|
+
userId: 'userId',
|
|
1608
|
+
};
|
|
1609
|
+
const stubTssUtils = sandbox.createStubInstance(sdk_core_1.TssUtils);
|
|
1610
|
+
stubTssUtils.deleteSignatureShares.resolves([]);
|
|
1611
|
+
stubTssUtils.getTxRequest.resolves(rebuiltTx);
|
|
1612
|
+
const hotWallet = {
|
|
1613
|
+
type: 'hot',
|
|
1614
|
+
};
|
|
1615
|
+
const presignedTransaction = await basecoin.presignTransaction({
|
|
1616
|
+
walletData: hotWallet,
|
|
1617
|
+
tssUtils: stubTssUtils,
|
|
1618
|
+
txPrebuild: {
|
|
1619
|
+
txRequestId,
|
|
1620
|
+
},
|
|
1621
|
+
});
|
|
1622
|
+
presignedTransaction.walletData.should.deepEqual(hotWallet);
|
|
1623
|
+
presignedTransaction.txPrebuild.should.deepEqual(rebuiltTx);
|
|
1624
|
+
presignedTransaction.txHex.should.equal(rebuiltTx.unsignedTxs[0].serializedTxHex);
|
|
1625
|
+
});
|
|
1626
|
+
it('should do nothing for non-hot wallets', async () => {
|
|
1627
|
+
const coldWallet = {
|
|
1628
|
+
type: 'cold',
|
|
1629
|
+
};
|
|
1630
|
+
const presignedTransaction = await basecoin.presignTransaction({
|
|
1631
|
+
walletData: coldWallet,
|
|
1632
|
+
});
|
|
1633
|
+
presignedTransaction.should.deepEqual({
|
|
1634
|
+
walletData: coldWallet,
|
|
1635
|
+
});
|
|
1636
|
+
});
|
|
1637
|
+
it('should error if txRequestId is missing', async () => {
|
|
1638
|
+
const hotWallet = {
|
|
1639
|
+
type: 'hot',
|
|
1640
|
+
};
|
|
1641
|
+
await basecoin
|
|
1642
|
+
.presignTransaction({
|
|
1643
|
+
walletData: hotWallet,
|
|
1644
|
+
txPrebuild: {},
|
|
1645
|
+
})
|
|
1646
|
+
.should.rejectedWith('Missing txRequestId');
|
|
1647
|
+
});
|
|
1648
|
+
});
|
|
1649
|
+
describe('API Key parameter:', () => {
|
|
1650
|
+
// Test the getPublicNodeUrl method directly
|
|
1651
|
+
it('should append apiKey to node URL when provided', function () {
|
|
1652
|
+
// Access the protected method using type casting
|
|
1653
|
+
const url = basecoin.getPublicNodeUrl('test-api-key-123');
|
|
1654
|
+
url.should.equal(`${sdk_core_1.Environments.test.solAlchemyNodeUrl}/test-api-key-123`);
|
|
1655
|
+
});
|
|
1656
|
+
it('should use regular node URL when apiKey is not provided', function () {
|
|
1657
|
+
// Access the protected method using type casting
|
|
1658
|
+
const url = basecoin.getPublicNodeUrl();
|
|
1659
|
+
url.should.equal(sdk_core_1.Environments.test.solNodeUrl);
|
|
1660
|
+
});
|
|
1661
|
+
});
|
|
1662
|
+
describe('Recover Transactions:', () => {
|
|
1663
|
+
const sandBox = sinon.createSandbox();
|
|
1664
|
+
const coin = statics_1.coins.get('tsol');
|
|
1665
|
+
const usdtMintAddress = '9cgpBeNZ2HnLda7NWaaU1i3NyTstk2c4zCMUcoAGsi9C';
|
|
1666
|
+
const t22mintAddress = '5NR1bQwLWqjbkhbQ1hx72HKJybbuvwkDnUZNoAZ2VhW6';
|
|
1667
|
+
let callBack;
|
|
1668
|
+
beforeEach(() => {
|
|
1669
|
+
callBack = sandBox.stub(src_1.Sol.prototype, 'getDataFromNode');
|
|
1670
|
+
callBack
|
|
1671
|
+
.withArgs({
|
|
1672
|
+
payload: {
|
|
1673
|
+
id: '1',
|
|
1674
|
+
jsonrpc: '2.0',
|
|
1675
|
+
method: 'getLatestBlockhash',
|
|
1676
|
+
params: [
|
|
1677
|
+
{
|
|
1678
|
+
commitment: 'finalized',
|
|
1679
|
+
},
|
|
1680
|
+
],
|
|
1681
|
+
},
|
|
1682
|
+
})
|
|
1683
|
+
.resolves(testData.SolResponses.getBlockhashResponse);
|
|
1684
|
+
callBack
|
|
1685
|
+
.withArgs({
|
|
1686
|
+
payload: {
|
|
1687
|
+
id: '1',
|
|
1688
|
+
jsonrpc: '2.0',
|
|
1689
|
+
method: 'getFeeForMessage',
|
|
1690
|
+
params: [
|
|
1691
|
+
sinon.match.string,
|
|
1692
|
+
{
|
|
1693
|
+
commitment: 'finalized',
|
|
1694
|
+
},
|
|
1695
|
+
],
|
|
1696
|
+
},
|
|
1697
|
+
})
|
|
1698
|
+
.resolves(testData.SolResponses.getFeesForMessageResponse);
|
|
1699
|
+
callBack
|
|
1700
|
+
.withArgs({
|
|
1701
|
+
payload: {
|
|
1702
|
+
id: '1',
|
|
1703
|
+
jsonrpc: '2.0',
|
|
1704
|
+
method: 'getMinimumBalanceForRentExemption',
|
|
1705
|
+
params: [165],
|
|
1706
|
+
},
|
|
1707
|
+
})
|
|
1708
|
+
.resolves(testData.SolResponses.getMinimumBalanceForRentExemptionResponse);
|
|
1709
|
+
callBack
|
|
1710
|
+
.withArgs({
|
|
1711
|
+
payload: {
|
|
1712
|
+
id: '1',
|
|
1713
|
+
jsonrpc: '2.0',
|
|
1714
|
+
method: 'getBalance',
|
|
1715
|
+
params: [testData.accountInfo.bs58EncodedPublicKey],
|
|
1716
|
+
},
|
|
1717
|
+
})
|
|
1718
|
+
.resolves(testData.SolResponses.getAccountBalanceResponse);
|
|
1719
|
+
callBack
|
|
1720
|
+
.withArgs({
|
|
1721
|
+
payload: {
|
|
1722
|
+
id: '1',
|
|
1723
|
+
jsonrpc: '2.0',
|
|
1724
|
+
method: 'getBalance',
|
|
1725
|
+
params: [testData.accountInfo.bs58EncodedPublicKeyNoFunds],
|
|
1726
|
+
},
|
|
1727
|
+
})
|
|
1728
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseNoFunds);
|
|
1729
|
+
callBack
|
|
1730
|
+
.withArgs({
|
|
1731
|
+
payload: {
|
|
1732
|
+
id: '1',
|
|
1733
|
+
jsonrpc: '2.0',
|
|
1734
|
+
method: 'getBalance',
|
|
1735
|
+
params: [testData.accountInfo.bs58EncodedPublicKeyM1Derivation],
|
|
1736
|
+
},
|
|
1737
|
+
})
|
|
1738
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseM1Derivation);
|
|
1739
|
+
callBack
|
|
1740
|
+
.withArgs({
|
|
1741
|
+
payload: {
|
|
1742
|
+
id: '1',
|
|
1743
|
+
jsonrpc: '2.0',
|
|
1744
|
+
method: 'getBalance',
|
|
1745
|
+
params: [testData.accountInfo.bs58EncodedPublicKeyM2Derivation],
|
|
1746
|
+
},
|
|
1747
|
+
})
|
|
1748
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
|
|
1749
|
+
callBack
|
|
1750
|
+
.withArgs({
|
|
1751
|
+
payload: {
|
|
1752
|
+
id: '1',
|
|
1753
|
+
jsonrpc: '2.0',
|
|
1754
|
+
method: 'getBalance',
|
|
1755
|
+
params: [testData.accountInfo.bs58EncodedPublicKeyWithManyTokens],
|
|
1756
|
+
},
|
|
1757
|
+
})
|
|
1758
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
|
|
1759
|
+
callBack
|
|
1760
|
+
.withArgs({
|
|
1761
|
+
payload: {
|
|
1762
|
+
id: '1',
|
|
1763
|
+
jsonrpc: '2.0',
|
|
1764
|
+
method: 'getBalance',
|
|
1765
|
+
params: [testData.closeATAkeys.closeAtaAddress],
|
|
1766
|
+
},
|
|
1767
|
+
})
|
|
1768
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
|
|
1769
|
+
callBack
|
|
1770
|
+
.withArgs({
|
|
1771
|
+
payload: {
|
|
1772
|
+
id: '1',
|
|
1773
|
+
jsonrpc: '2.0',
|
|
1774
|
+
method: 'getBalance',
|
|
1775
|
+
params: [testData.closeATAkeys.bs58EncodedPublicKey],
|
|
1776
|
+
},
|
|
1777
|
+
})
|
|
1778
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseM2Derivation);
|
|
1779
|
+
callBack
|
|
1780
|
+
.withArgs({
|
|
1781
|
+
payload: {
|
|
1782
|
+
id: '1',
|
|
1783
|
+
jsonrpc: '2.0',
|
|
1784
|
+
method: 'getAccountInfo',
|
|
1785
|
+
params: [
|
|
1786
|
+
testData.closeATAkeys.closeAtaAddress,
|
|
1787
|
+
{
|
|
1788
|
+
encoding: 'jsonParsed',
|
|
1789
|
+
},
|
|
1790
|
+
],
|
|
1791
|
+
},
|
|
1792
|
+
})
|
|
1793
|
+
.resolves(testData.SolResponses.getTokenInfoResponse);
|
|
1794
|
+
callBack
|
|
1795
|
+
.withArgs({
|
|
1796
|
+
payload: {
|
|
1797
|
+
id: '1',
|
|
1798
|
+
jsonrpc: '2.0',
|
|
1799
|
+
method: 'getAccountInfo',
|
|
1800
|
+
params: [
|
|
1801
|
+
testData.keys.durableNoncePubKey,
|
|
1802
|
+
{
|
|
1803
|
+
encoding: 'jsonParsed',
|
|
1804
|
+
},
|
|
1805
|
+
],
|
|
1806
|
+
},
|
|
1807
|
+
})
|
|
1808
|
+
.resolves(testData.SolResponses.getAccountInfoResponse);
|
|
1809
|
+
callBack
|
|
1810
|
+
.withArgs({
|
|
1811
|
+
payload: {
|
|
1812
|
+
id: '1',
|
|
1813
|
+
jsonrpc: '2.0',
|
|
1814
|
+
method: 'getTokenAccountsByOwner',
|
|
1815
|
+
params: [
|
|
1816
|
+
testData.keys.destinationPubKey,
|
|
1817
|
+
{
|
|
1818
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
encoding: 'jsonParsed',
|
|
1822
|
+
},
|
|
1823
|
+
],
|
|
1824
|
+
},
|
|
1825
|
+
})
|
|
1826
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
1827
|
+
callBack
|
|
1828
|
+
.withArgs({
|
|
1829
|
+
payload: {
|
|
1830
|
+
id: '1',
|
|
1831
|
+
jsonrpc: '2.0',
|
|
1832
|
+
method: 'getTokenAccountsByOwner',
|
|
1833
|
+
params: [
|
|
1834
|
+
testData.accountInfo.bs58EncodedPublicKey,
|
|
1835
|
+
{
|
|
1836
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
1837
|
+
},
|
|
1838
|
+
{
|
|
1839
|
+
encoding: 'jsonParsed',
|
|
1840
|
+
},
|
|
1841
|
+
],
|
|
1842
|
+
},
|
|
1843
|
+
})
|
|
1844
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
1845
|
+
callBack
|
|
1846
|
+
.withArgs({
|
|
1847
|
+
payload: {
|
|
1848
|
+
id: '1',
|
|
1849
|
+
jsonrpc: '2.0',
|
|
1850
|
+
method: 'getTokenAccountsByOwner',
|
|
1851
|
+
params: [
|
|
1852
|
+
testData.keys.destinationPubKey2,
|
|
1853
|
+
{
|
|
1854
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
encoding: 'jsonParsed',
|
|
1858
|
+
},
|
|
1859
|
+
],
|
|
1860
|
+
},
|
|
1861
|
+
})
|
|
1862
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
|
|
1863
|
+
callBack
|
|
1864
|
+
.withArgs({
|
|
1865
|
+
payload: {
|
|
1866
|
+
id: '1',
|
|
1867
|
+
jsonrpc: '2.0',
|
|
1868
|
+
method: 'getTokenAccountsByOwner',
|
|
1869
|
+
params: [
|
|
1870
|
+
testData.keys.destinationPubKey2,
|
|
1871
|
+
{
|
|
1872
|
+
programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
|
|
1873
|
+
},
|
|
1874
|
+
{
|
|
1875
|
+
encoding: 'jsonParsed',
|
|
1876
|
+
},
|
|
1877
|
+
],
|
|
1878
|
+
},
|
|
1879
|
+
})
|
|
1880
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerForSol2022Response2);
|
|
1881
|
+
callBack
|
|
1882
|
+
.withArgs({
|
|
1883
|
+
payload: {
|
|
1884
|
+
id: '1',
|
|
1885
|
+
jsonrpc: '2.0',
|
|
1886
|
+
method: 'getTokenAccountsByOwner',
|
|
1887
|
+
params: [
|
|
1888
|
+
testData.wrwUser.walletAddress0,
|
|
1889
|
+
{
|
|
1890
|
+
programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
|
|
1891
|
+
},
|
|
1892
|
+
{
|
|
1893
|
+
encoding: 'jsonParsed',
|
|
1894
|
+
},
|
|
1895
|
+
],
|
|
1896
|
+
},
|
|
1897
|
+
})
|
|
1898
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerForSol2022Response);
|
|
1899
|
+
callBack
|
|
1900
|
+
.withArgs({
|
|
1901
|
+
payload: {
|
|
1902
|
+
id: '1',
|
|
1903
|
+
jsonrpc: '2.0',
|
|
1904
|
+
method: 'getTokenAccountsByOwner',
|
|
1905
|
+
params: [
|
|
1906
|
+
testData.wrwUser.walletAddress0,
|
|
1907
|
+
{
|
|
1908
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
encoding: 'jsonParsed',
|
|
1912
|
+
},
|
|
1913
|
+
],
|
|
1914
|
+
},
|
|
1915
|
+
})
|
|
1916
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponse2);
|
|
1917
|
+
callBack
|
|
1918
|
+
.withArgs({
|
|
1919
|
+
payload: {
|
|
1920
|
+
id: '1',
|
|
1921
|
+
jsonrpc: '2.0',
|
|
1922
|
+
method: 'getTokenAccountsByOwner',
|
|
1923
|
+
params: [
|
|
1924
|
+
testData.wrwUser.walletAddress4,
|
|
1925
|
+
{
|
|
1926
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
encoding: 'jsonParsed',
|
|
1930
|
+
},
|
|
1931
|
+
],
|
|
1932
|
+
},
|
|
1933
|
+
})
|
|
1934
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponse3);
|
|
1935
|
+
callBack
|
|
1936
|
+
.withArgs({
|
|
1937
|
+
payload: {
|
|
1938
|
+
id: '1',
|
|
1939
|
+
jsonrpc: '2.0',
|
|
1940
|
+
method: 'getBalance',
|
|
1941
|
+
params: [testData.wrwUser.walletAddress0],
|
|
1942
|
+
},
|
|
1943
|
+
})
|
|
1944
|
+
.resolves(testData.SolResponses.getAccountBalanceResponse);
|
|
1945
|
+
callBack
|
|
1946
|
+
.withArgs({
|
|
1947
|
+
payload: {
|
|
1948
|
+
id: '1',
|
|
1949
|
+
jsonrpc: '2.0',
|
|
1950
|
+
method: 'getTokenAccountsByOwner',
|
|
1951
|
+
params: [
|
|
1952
|
+
testData.keys.destinationPubKey,
|
|
1953
|
+
{
|
|
1954
|
+
programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
|
|
1955
|
+
},
|
|
1956
|
+
{
|
|
1957
|
+
encoding: 'jsonParsed',
|
|
1958
|
+
},
|
|
1959
|
+
],
|
|
1960
|
+
},
|
|
1961
|
+
})
|
|
1962
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
1963
|
+
callBack
|
|
1964
|
+
.withArgs({
|
|
1965
|
+
payload: {
|
|
1966
|
+
id: '1',
|
|
1967
|
+
jsonrpc: '2.0',
|
|
1968
|
+
method: 'sendTransaction',
|
|
1969
|
+
params: sinon.match.array,
|
|
1970
|
+
},
|
|
1971
|
+
})
|
|
1972
|
+
.onCall(0)
|
|
1973
|
+
.resolves(testData.SolResponses.broadcastTransactionResponse)
|
|
1974
|
+
.onCall(1)
|
|
1975
|
+
.resolves(testData.SolResponses.broadcastTransactionResponse1);
|
|
1976
|
+
});
|
|
1977
|
+
afterEach(() => {
|
|
1978
|
+
sandBox.restore();
|
|
1979
|
+
});
|
|
1980
|
+
it('should take OVC output and generate a signed sweep transaction', async function () {
|
|
1981
|
+
const params = testData.ovcResponse;
|
|
1982
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
1983
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('AvR+L909kzRq6NuaUe9F6Jt97MOiFs7jpW8MuOrwz4EbKF40d31dci/bgLTq4gpk/Hh3s5cA8FtbLkDQr15PqAE7yd8LOXvsLtO2REqMM/OCZ8wItfsqfTfia2xIfibRW3wHgw63jiaojbXeSqaYajJ/Ca7YwBUz5blydI3fYLgPAgECBsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQvLqE/j/nXlY2/JpxuNr/fXLXEPeS04dPvt9qz1dAoYEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAADpiH20cxLj7KnOaoI5ANNoPxYjs472FdjDeMPft3kXdAgQDAgUBBAQAAAAEAgADDAIAAADwopo7AAAAAA==');
|
|
1984
|
+
(recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(0);
|
|
1985
|
+
(recoveryTxn.lastScanIndex ?? 0).should.equal(0);
|
|
1986
|
+
});
|
|
1987
|
+
it('should take sol 2022 token OVC output and generate a signed sweep transaction', async function () {
|
|
1988
|
+
const params = testData.ovcResponse;
|
|
1989
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
1990
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('AvR+L909kzRq6NuaUe9F6Jt97MOiFs7jpW8MuOrwz4EbKF40d31dci/bgLTq4gpk/Hh3s5cA8FtbLkDQr15PqAE7yd8LOXvsLtO2REqMM/OCZ8wItfsqfTfia2xIfibRW3wHgw63jiaojbXeSqaYajJ/Ca7YwBUz5blydI3fYLgPAgECBsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQvLqE/j/nXlY2/JpxuNr/fXLXEPeS04dPvt9qz1dAoYEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAADpiH20cxLj7KnOaoI5ANNoPxYjs472FdjDeMPft3kXdAgQDAgUBBAQAAAAEAgADDAIAAADwopo7AAAAAA==');
|
|
1991
|
+
(recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(0);
|
|
1992
|
+
(recoveryTxn.lastScanIndex ?? 0).should.equal(0);
|
|
1993
|
+
});
|
|
1994
|
+
it('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
|
|
1995
|
+
const params = testData.ovcResponse2;
|
|
1996
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
1997
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('AtQPLzOmLuKwHY6N5XoJIZK/T7W10uYWm/MRte3GFUdl+w3gHLjSa9H66WSfFNubQxIPckxJDyltkP7ksLDf9QgBNJM2UWbBUH5wT0JJHILlhCs33HX8DeE/8Tdsw6tGfZoMhCnSKv6TPWtBxy7Sb6sW8ksCUPnAWuHGGKmgjEMBAgECBmLrqxJrY2kbN/tcrQw3P8P15OljFGabFJAKBrUO1grNBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHxPX1mHv+JqpmAT79ltNjYPK0M2yR+ZMln7VgUTBWFNQsLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAAIZQniiS73D6mwfpnfhVMC4lyYJtRSrmoZpF7yIlUdIDAgQDAgUBBAQAAAAEAgADDAIAAADwPc0dAAAAAA==');
|
|
1998
|
+
(recoveryTxn.transactions[0].scanIndex ?? 0).should.equal(1);
|
|
1999
|
+
recoveryTxn.transactions[1].serializedTx.should.equal('AuLhOA5zmOBZR85lo+nKdTopVwJAMrMp6NW+8UnGNsSBSpBkqfWZQqSg9s+7aTlXezm5vxol+Pl6t7PpVNTOHwLcp9xJp3TFHdivEbhwJKldR4Ny+pasoFx+Bgk8q6g1iNiq7XSi1Ov3bs7euMkTj7nDRFqP8lv7xLTcvrBm9OQJAgECBp14ImBCdmVROlw0UveYS1MvG/ljCRI3MJTFmsxuXEoWBRo0vIrNQ4djl2+Wh2EVBQ9zgoVTVm0RHXrIv/6/WHw0hyxvpVwtIx9/zeX2O16eTrY+aKIh1mdKg4MMg0eyxMLVtfT7mpvNii8wPk0G942N7TAHE/RW2iq/8LPqAYWqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxWjuCKhF9z0peIzwNcMUWyGrNE2AYuqUAAAC7ws1XFslinwgtpISUViVWIVTHyD2Q0qj24YjKmrAmXAgQDAgUBBAQAAAAEAgADDAIAAADwPc0dAAAAAA==');
|
|
2000
|
+
(recoveryTxn.transactions[1].scanIndex ?? 0).should.equal(2);
|
|
2001
|
+
(recoveryTxn.lastScanIndex ?? 0).should.equal(20);
|
|
2002
|
+
});
|
|
2003
|
+
it('should recover a txn for non-bitgo recoveries (latest blockhash)', async function () {
|
|
2004
|
+
// Latest Blockhash Recovery (BitGo-less)
|
|
2005
|
+
const latestBlockHashTxn = await basecoin.recover({
|
|
2006
|
+
userKey: testData.keys.userKey,
|
|
2007
|
+
backupKey: testData.keys.backupKey,
|
|
2008
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2009
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2010
|
+
walletPassphrase: testData.keys.walletPassword,
|
|
2011
|
+
});
|
|
2012
|
+
latestBlockHashTxn.should.not.be.empty();
|
|
2013
|
+
latestBlockHashTxn.should.hasOwnProperty('serializedTx');
|
|
2014
|
+
latestBlockHashTxn.should.hasOwnProperty('scanIndex');
|
|
2015
|
+
should.equal(latestBlockHashTxn.scanIndex, 0);
|
|
2016
|
+
const latestBlockhashTxnDeserialize = new lib_1.Transaction(coin);
|
|
2017
|
+
latestBlockhashTxnDeserialize.fromRawTransaction(latestBlockHashTxn.serializedTx);
|
|
2018
|
+
const latestBlockhashTxnJson = latestBlockhashTxnDeserialize.toJson();
|
|
2019
|
+
should.equal(latestBlockhashTxnJson.nonce, testData.SolInputData.blockhash);
|
|
2020
|
+
should.equal(latestBlockhashTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
|
|
2021
|
+
should.equal(latestBlockhashTxnJson.numSignatures, testData.SolInputData.latestBlockhashSignatures);
|
|
2022
|
+
const solCoin = basecoin;
|
|
2023
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 3);
|
|
2024
|
+
});
|
|
2025
|
+
it('should recover a txn for non-bitgo recoveries (durable nonce)', async function () {
|
|
2026
|
+
// Durable Nonce Recovery (BitGo-less)
|
|
2027
|
+
const durableNonceTxn = await basecoin.recover({
|
|
2028
|
+
userKey: testData.keys.userKey,
|
|
2029
|
+
backupKey: testData.keys.backupKey,
|
|
2030
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2031
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2032
|
+
walletPassphrase: testData.keys.walletPassword,
|
|
2033
|
+
durableNonce: {
|
|
2034
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2035
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2036
|
+
},
|
|
2037
|
+
});
|
|
2038
|
+
durableNonceTxn.should.not.be.empty();
|
|
2039
|
+
durableNonceTxn.should.hasOwnProperty('serializedTx');
|
|
2040
|
+
durableNonceTxn.should.hasOwnProperty('scanIndex');
|
|
2041
|
+
should.equal(durableNonceTxn.scanIndex, 0);
|
|
2042
|
+
const durableNonceTxnDeserialize = new lib_1.Transaction(coin);
|
|
2043
|
+
durableNonceTxnDeserialize.fromRawTransaction(durableNonceTxn.serializedTx);
|
|
2044
|
+
const durableNonceTxnJson = durableNonceTxnDeserialize.toJson();
|
|
2045
|
+
should.equal(durableNonceTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2046
|
+
should.equal(durableNonceTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
|
|
2047
|
+
should.equal(durableNonceTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2048
|
+
const solCoin = basecoin;
|
|
2049
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 4);
|
|
2050
|
+
});
|
|
2051
|
+
it('should recover a txn for unsigned sweep recoveries', async function () {
|
|
2052
|
+
// Unsigned Sweep Recovery
|
|
2053
|
+
const unsignedSweepTxn = (await basecoin.recover({
|
|
2054
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2055
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2056
|
+
durableNonce: {
|
|
2057
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2058
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2059
|
+
},
|
|
2060
|
+
}));
|
|
2061
|
+
unsignedSweepTxn.should.not.be.empty();
|
|
2062
|
+
unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
|
|
2063
|
+
unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('scanIndex');
|
|
2064
|
+
should.equal(unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.scanIndex, 0);
|
|
2065
|
+
const unsignedSweepTxnDeserialize = new lib_1.Transaction(coin);
|
|
2066
|
+
unsignedSweepTxnDeserialize.fromRawTransaction(unsignedSweepTxn.txRequests[0].transactions[0].unsignedTx.serializedTx);
|
|
2067
|
+
const unsignedSweepTxnJson = unsignedSweepTxnDeserialize.toJson();
|
|
2068
|
+
should.equal(unsignedSweepTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2069
|
+
should.equal(unsignedSweepTxnJson.feePayer, testData.accountInfo.bs58EncodedPublicKey);
|
|
2070
|
+
should.equal(unsignedSweepTxnJson.numSignatures, testData.SolInputData.unsignedSweepSignatures);
|
|
2071
|
+
const solCoin = basecoin;
|
|
2072
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 4);
|
|
2073
|
+
});
|
|
2074
|
+
it('should handle error in recover function if a required field is missing/incorrect', async function () {
|
|
2075
|
+
// missing userkey
|
|
2076
|
+
await basecoin
|
|
2077
|
+
.recover({
|
|
2078
|
+
backupKey: testData.keys.backupKey,
|
|
2079
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2080
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2081
|
+
walletPassphrase: testData.keys.walletPassword,
|
|
2082
|
+
})
|
|
2083
|
+
.should.rejectedWith('missing userKey');
|
|
2084
|
+
// missing backupkey
|
|
2085
|
+
await basecoin
|
|
2086
|
+
.recover({
|
|
2087
|
+
userKey: testData.keys.userKey,
|
|
2088
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2089
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2090
|
+
walletPassphrase: testData.keys.walletPassword,
|
|
2091
|
+
})
|
|
2092
|
+
.should.rejectedWith('missing backupKey');
|
|
2093
|
+
// incorrect wallet passphrase, user key, backup key combination
|
|
2094
|
+
await basecoin
|
|
2095
|
+
.recover({
|
|
2096
|
+
userKey: testData.keys.userKey,
|
|
2097
|
+
backupKey: testData.keys.backupKey,
|
|
2098
|
+
bitgoKey: testData.keys.bitgoKey,
|
|
2099
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2100
|
+
walletPassphrase: testData.keys.walletPassword + 'incorrect',
|
|
2101
|
+
})
|
|
2102
|
+
.should.rejectedWith("Error decrypting user keychain: password error - ccm: tag doesn't match");
|
|
2103
|
+
// no wallet with sufficient funds
|
|
2104
|
+
await basecoin
|
|
2105
|
+
.recover({
|
|
2106
|
+
userKey: testData.keys.userKey,
|
|
2107
|
+
backupKey: testData.keys.backupKey,
|
|
2108
|
+
bitgoKey: testData.keys.bitgoKeyNoFunds,
|
|
2109
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2110
|
+
walletPassphrase: testData.keys.walletPassword,
|
|
2111
|
+
})
|
|
2112
|
+
.should.rejectedWith('Did not find address with funds to recover');
|
|
2113
|
+
});
|
|
2114
|
+
it('should recover sol tokens to recovery destination with no existing token accounts', async function () {
|
|
2115
|
+
const tokenTxn = await basecoin.recover({
|
|
2116
|
+
userKey: testData.wrwUser.userKey,
|
|
2117
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2118
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2119
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2120
|
+
tokenContractAddress: usdtMintAddress,
|
|
2121
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2122
|
+
durableNonce: {
|
|
2123
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2124
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2125
|
+
},
|
|
2126
|
+
});
|
|
2127
|
+
tokenTxn.should.not.be.empty();
|
|
2128
|
+
tokenTxn.should.hasOwnProperty('serializedTx');
|
|
2129
|
+
tokenTxn.should.hasOwnProperty('scanIndex');
|
|
2130
|
+
should.equal(tokenTxn.scanIndex, 0);
|
|
2131
|
+
const tokenTxnDeserialize = new lib_1.Transaction(coin);
|
|
2132
|
+
tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
|
|
2133
|
+
const tokenTxnJson = tokenTxnDeserialize.toJson();
|
|
2134
|
+
should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2135
|
+
should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
|
|
2136
|
+
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2137
|
+
const instructionsData = tokenTxnJson.instructionsData;
|
|
2138
|
+
should.equal(instructionsData.length, 3);
|
|
2139
|
+
should.equal(instructionsData[0].type, 'NonceAdvance');
|
|
2140
|
+
const destinationUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.keys.destinationPubKey);
|
|
2141
|
+
should.equal(instructionsData[1].type, 'CreateAssociatedTokenAccount');
|
|
2142
|
+
should.equal(instructionsData[1].params.mintAddress, usdtMintAddress);
|
|
2143
|
+
should.equal(instructionsData[1].params.ataAddress, destinationUSDTTokenAccount);
|
|
2144
|
+
should.equal(instructionsData[1].params.ownerAddress, testData.keys.destinationPubKey);
|
|
2145
|
+
should.equal(instructionsData[1].params.tokenName, 'tsol:usdt');
|
|
2146
|
+
should.equal(instructionsData[1].params.payerAddress, testData.wrwUser.walletAddress0);
|
|
2147
|
+
const sourceUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.wrwUser.walletAddress0);
|
|
2148
|
+
should.equal(instructionsData[2].type, 'TokenTransfer');
|
|
2149
|
+
should.equal(instructionsData[2].params.fromAddress, testData.wrwUser.walletAddress0);
|
|
2150
|
+
should.equal(instructionsData[2].params.toAddress, destinationUSDTTokenAccount);
|
|
2151
|
+
should.equal(instructionsData[2].params.amount, '2000000000');
|
|
2152
|
+
should.equal(instructionsData[2].params.tokenName, 'tsol:usdt');
|
|
2153
|
+
should.equal(instructionsData[2].params.sourceAddress, sourceUSDTTokenAccount);
|
|
2154
|
+
const solCoin = basecoin;
|
|
2155
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
|
|
2156
|
+
});
|
|
2157
|
+
it('should recover sol 2022 tokens to recovery destination with no existing token accounts', async function () {
|
|
2158
|
+
const tokenTxn = await basecoin.recover({
|
|
2159
|
+
userKey: testData.wrwUser.userKey,
|
|
2160
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2161
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2162
|
+
recoveryDestination: testData.keys.destinationPubKey,
|
|
2163
|
+
tokenContractAddress: t22mintAddress,
|
|
2164
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2165
|
+
durableNonce: {
|
|
2166
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2167
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2168
|
+
},
|
|
2169
|
+
programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
|
|
2170
|
+
});
|
|
2171
|
+
tokenTxn.should.not.be.empty();
|
|
2172
|
+
tokenTxn.should.hasOwnProperty('serializedTx');
|
|
2173
|
+
tokenTxn.should.hasOwnProperty('scanIndex');
|
|
2174
|
+
should.equal(tokenTxn.scanIndex, 0);
|
|
2175
|
+
const tokenTxnDeserialize = new lib_1.Transaction(coin);
|
|
2176
|
+
tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
|
|
2177
|
+
const tokenTxnJson = tokenTxnDeserialize.toJson();
|
|
2178
|
+
should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2179
|
+
should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
|
|
2180
|
+
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2181
|
+
const instructionsData = tokenTxnJson.instructionsData;
|
|
2182
|
+
should.equal(instructionsData.length, 3);
|
|
2183
|
+
should.equal(instructionsData[0].type, 'NonceAdvance');
|
|
2184
|
+
const destinationTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.keys.destinationPubKey);
|
|
2185
|
+
should.equal(instructionsData[1].type, 'CreateAssociatedTokenAccount');
|
|
2186
|
+
should.equal(instructionsData[1].params.mintAddress, t22mintAddress);
|
|
2187
|
+
should.equal(instructionsData[1].params.ataAddress, destinationTokenAccount);
|
|
2188
|
+
should.equal(instructionsData[1].params.ownerAddress, testData.keys.destinationPubKey);
|
|
2189
|
+
should.equal(instructionsData[1].params.tokenName, 'tsol:t22mint');
|
|
2190
|
+
should.equal(instructionsData[1].params.payerAddress, testData.wrwUser.walletAddress0);
|
|
2191
|
+
const sourceTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.wrwUser.walletAddress0);
|
|
2192
|
+
should.equal(instructionsData[2].type, 'TokenTransfer');
|
|
2193
|
+
should.equal(instructionsData[2].params.fromAddress, testData.wrwUser.walletAddress0);
|
|
2194
|
+
should.equal(instructionsData[2].params.toAddress, destinationTokenAccount);
|
|
2195
|
+
should.equal(instructionsData[2].params.amount, '2000000000');
|
|
2196
|
+
should.equal(instructionsData[2].params.tokenName, 'tsol:t22mint');
|
|
2197
|
+
should.equal(instructionsData[2].params.sourceAddress, sourceTokenAccount);
|
|
2198
|
+
should.equal(instructionsData[2].params.programId, 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
|
|
2199
|
+
const solCoin = basecoin;
|
|
2200
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
|
|
2201
|
+
});
|
|
2202
|
+
it('should recover sol tokens to recovery destination with existing token accounts', async function () {
|
|
2203
|
+
const tokenTxn = await basecoin.recover({
|
|
2204
|
+
userKey: testData.wrwUser.userKey,
|
|
2205
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2206
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2207
|
+
recoveryDestination: testData.keys.destinationPubKey2,
|
|
2208
|
+
tokenContractAddress: usdtMintAddress,
|
|
2209
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2210
|
+
durableNonce: {
|
|
2211
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2212
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2213
|
+
},
|
|
2214
|
+
});
|
|
2215
|
+
tokenTxn.should.not.be.empty();
|
|
2216
|
+
tokenTxn.should.hasOwnProperty('serializedTx');
|
|
2217
|
+
tokenTxn.should.hasOwnProperty('scanIndex');
|
|
2218
|
+
should.equal(tokenTxn.scanIndex, 0);
|
|
2219
|
+
const tokenTxnDeserialize = new lib_1.Transaction(coin);
|
|
2220
|
+
tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
|
|
2221
|
+
const tokenTxnJson = tokenTxnDeserialize.toJson();
|
|
2222
|
+
should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2223
|
+
should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
|
|
2224
|
+
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2225
|
+
const instructionsData = tokenTxnJson.instructionsData;
|
|
2226
|
+
should.equal(instructionsData.length, 2);
|
|
2227
|
+
should.equal(instructionsData[0].type, 'NonceAdvance');
|
|
2228
|
+
const sourceUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.wrwUser.walletAddress0);
|
|
2229
|
+
const destinationUSDTTokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(usdtMintAddress, testData.keys.destinationPubKey2);
|
|
2230
|
+
should.equal(instructionsData[1].type, 'TokenTransfer');
|
|
2231
|
+
should.equal(instructionsData[1].params.fromAddress, testData.wrwUser.walletAddress0);
|
|
2232
|
+
should.equal(instructionsData[1].params.toAddress, destinationUSDTTokenAccount);
|
|
2233
|
+
should.equal(instructionsData[1].params.amount, '2000000000');
|
|
2234
|
+
should.equal(instructionsData[1].params.tokenName, 'tsol:usdt');
|
|
2235
|
+
should.equal(instructionsData[1].params.sourceAddress, sourceUSDTTokenAccount);
|
|
2236
|
+
const solCoin = basecoin;
|
|
2237
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
|
|
2238
|
+
});
|
|
2239
|
+
it('should recover sol 2022 tokens to recovery destination with existing token accounts', async function () {
|
|
2240
|
+
const tokenTxn = await basecoin.recover({
|
|
2241
|
+
userKey: testData.wrwUser.userKey,
|
|
2242
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2243
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2244
|
+
recoveryDestination: testData.keys.destinationPubKey2,
|
|
2245
|
+
tokenContractAddress: t22mintAddress,
|
|
2246
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2247
|
+
durableNonce: {
|
|
2248
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2249
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2250
|
+
},
|
|
2251
|
+
programId: spl_token_1.TOKEN_2022_PROGRAM_ID.toString(),
|
|
2252
|
+
});
|
|
2253
|
+
tokenTxn.should.not.be.empty();
|
|
2254
|
+
tokenTxn.should.hasOwnProperty('serializedTx');
|
|
2255
|
+
tokenTxn.should.hasOwnProperty('scanIndex');
|
|
2256
|
+
should.equal(tokenTxn.scanIndex, 0);
|
|
2257
|
+
const tokenTxnDeserialize = new lib_1.Transaction(coin);
|
|
2258
|
+
tokenTxnDeserialize.fromRawTransaction(tokenTxn.serializedTx);
|
|
2259
|
+
const tokenTxnJson = tokenTxnDeserialize.toJson();
|
|
2260
|
+
console.log(tokenTxnJson);
|
|
2261
|
+
should.equal(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2262
|
+
should.equal(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
|
|
2263
|
+
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2264
|
+
const instructionsData = tokenTxnJson.instructionsData;
|
|
2265
|
+
should.equal(instructionsData.length, 2);
|
|
2266
|
+
should.equal(instructionsData[0].type, 'NonceAdvance');
|
|
2267
|
+
const source2022TokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.wrwUser.walletAddress0, false, spl_token_1.TOKEN_2022_PROGRAM_ID.toString());
|
|
2268
|
+
const destination2022TokenAccount = await (0, utils_1.getAssociatedTokenAccountAddress)(t22mintAddress, testData.keys.destinationPubKey2, false, spl_token_1.TOKEN_2022_PROGRAM_ID.toString());
|
|
2269
|
+
should.equal(instructionsData[1].type, 'TokenTransfer');
|
|
2270
|
+
should.equal(instructionsData[1].params.fromAddress, testData.wrwUser.walletAddress0);
|
|
2271
|
+
should.equal(instructionsData[1].params.toAddress, destination2022TokenAccount);
|
|
2272
|
+
should.equal(instructionsData[1].params.amount, '2000000000');
|
|
2273
|
+
should.equal(instructionsData[1].params.tokenName, 'tsol:t22mint');
|
|
2274
|
+
should.equal(instructionsData[1].params.sourceAddress, source2022TokenAccount);
|
|
2275
|
+
const solCoin = basecoin;
|
|
2276
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
|
|
2277
|
+
});
|
|
2278
|
+
it('should recover sol tokens to recovery destination with existing token accounts for unsigned sweep recoveries', async function () {
|
|
2279
|
+
const feeResponse = testData.SolResponses.getFeesForMessageResponse;
|
|
2280
|
+
feeResponse.body.result.value = 10000;
|
|
2281
|
+
callBack
|
|
2282
|
+
.withArgs({
|
|
2283
|
+
payload: {
|
|
2284
|
+
id: '1',
|
|
2285
|
+
jsonrpc: '2.0',
|
|
2286
|
+
method: 'getFeeForMessage',
|
|
2287
|
+
params: [
|
|
2288
|
+
sinon.match.string,
|
|
2289
|
+
{
|
|
2290
|
+
commitment: 'finalized',
|
|
2291
|
+
},
|
|
2292
|
+
],
|
|
2293
|
+
},
|
|
2294
|
+
})
|
|
2295
|
+
.resolves(feeResponse);
|
|
2296
|
+
const tokenTxn = (await basecoin.recover({
|
|
2297
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2298
|
+
recoveryDestination: testData.keys.destinationPubKey2,
|
|
2299
|
+
durableNonce: {
|
|
2300
|
+
publicKey: testData.keys.durableNoncePubKey,
|
|
2301
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2302
|
+
},
|
|
2303
|
+
tokenContractAddress: testData.tokenAddress.TestUSDC,
|
|
2304
|
+
}));
|
|
2305
|
+
// 2 signatures and no rent exemption fee since the destination already has token accounts
|
|
2306
|
+
const expectedFee = 5000 + 5000;
|
|
2307
|
+
const { serializedTx, scanIndex, feeInfo, parsedTx } = tokenTxn.txRequests[0].transactions[0].unsignedTx;
|
|
2308
|
+
assert_1.default.ok(serializedTx);
|
|
2309
|
+
assert_1.default.strictEqual(scanIndex, 0);
|
|
2310
|
+
assert_1.default.ok(feeInfo);
|
|
2311
|
+
assert_1.default.strictEqual(feeInfo.feeString, expectedFee.toString());
|
|
2312
|
+
assert_1.default.strictEqual(feeInfo.fee, expectedFee);
|
|
2313
|
+
assert_1.default.ok(parsedTx);
|
|
2314
|
+
assert_1.default.ok(parsedTx.inputs instanceof Array && parsedTx.inputs.length === 1);
|
|
2315
|
+
assert_1.default.ok(parsedTx.outputs instanceof Array && parsedTx.outputs.length === 1);
|
|
2316
|
+
const tokenTxnDeserialize = new lib_1.Transaction(coin);
|
|
2317
|
+
tokenTxnDeserialize.fromRawTransaction(tokenTxn.txRequests[0].transactions[0].unsignedTx.serializedTx);
|
|
2318
|
+
const tokenTxnJson = tokenTxnDeserialize.toJson();
|
|
2319
|
+
assert_1.default.strictEqual(tokenTxnJson.nonce, testData.SolInputData.durableNonceBlockhash);
|
|
2320
|
+
assert_1.default.strictEqual(tokenTxnJson.feePayer, testData.wrwUser.walletAddress0);
|
|
2321
|
+
assert_1.default.strictEqual(tokenTxnJson.numSignatures, testData.SolInputData.unsignedSweepSignatures);
|
|
2322
|
+
const solCoin = basecoin;
|
|
2323
|
+
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
|
|
2324
|
+
});
|
|
2325
|
+
it('should recover sol funds from ATA address for non-bitgo recoveries', async function () {
|
|
2326
|
+
// close ATA address instruction type txn
|
|
2327
|
+
const closeATATxns = await basecoin.recoverCloseATA({
|
|
2328
|
+
userKey: testData.closeATAkeys.userKey,
|
|
2329
|
+
backupKey: testData.closeATAkeys.backupKey,
|
|
2330
|
+
bitgoKey: testData.closeATAkeys.bitgoKey,
|
|
2331
|
+
recoveryDestination: testData.closeATAkeys.destinationPubKey,
|
|
2332
|
+
walletPassphrase: testData.closeATAkeys.walletPassword,
|
|
2333
|
+
closeAtaAddress: testData.closeATAkeys.closeAtaAddress,
|
|
2334
|
+
recoveryDestinationAtaAddress: testData.closeATAkeys.recoveryDestinationAtaAddress,
|
|
2335
|
+
});
|
|
2336
|
+
closeATATxns.should.not.be.empty();
|
|
2337
|
+
should.equal(closeATATxns[0].txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
|
|
2338
|
+
should.equal(closeATATxns[1].txId, '5oUBgXX4enGmFEspG64goy3PRysjfrekZGg3rZNkBHUCQFd482vrVWbfDcRYMBEJt65JXymfEPm8M6d89X4xV79n');
|
|
2339
|
+
});
|
|
2340
|
+
it('should recover tokens from a nested ATA (ATA whose owner is another ATA)', async function () {
|
|
2341
|
+
const result = await basecoin.recoverNestedAta({
|
|
2342
|
+
userKey: testData.closeATAkeys.userKey,
|
|
2343
|
+
backupKey: testData.closeATAkeys.backupKey,
|
|
2344
|
+
bitgoKey: testData.closeATAkeys.bitgoKey,
|
|
2345
|
+
recoveryDestination: testData.closeATAkeys.destinationPubKey,
|
|
2346
|
+
walletPassphrase: testData.closeATAkeys.walletPassword,
|
|
2347
|
+
nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
|
|
2348
|
+
ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
|
|
2349
|
+
tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
|
|
2350
|
+
});
|
|
2351
|
+
result.should.not.be.empty();
|
|
2352
|
+
should.equal(result.txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
|
|
2353
|
+
});
|
|
2354
|
+
it('should throw when nestedAtaAddress is missing for recoverNestedAta', async function () {
|
|
2355
|
+
await basecoin
|
|
2356
|
+
.recoverNestedAta({
|
|
2357
|
+
userKey: testData.closeATAkeys.userKey,
|
|
2358
|
+
backupKey: testData.closeATAkeys.backupKey,
|
|
2359
|
+
bitgoKey: testData.closeATAkeys.bitgoKey,
|
|
2360
|
+
recoveryDestination: testData.closeATAkeys.destinationPubKey,
|
|
2361
|
+
walletPassphrase: testData.closeATAkeys.walletPassword,
|
|
2362
|
+
ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
|
|
2363
|
+
tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
|
|
2364
|
+
})
|
|
2365
|
+
.should.be.rejectedWith('invalid nestedAtaAddress');
|
|
2366
|
+
});
|
|
2367
|
+
it('should throw when ownerAtaAddress is missing for recoverNestedAta', async function () {
|
|
2368
|
+
await basecoin
|
|
2369
|
+
.recoverNestedAta({
|
|
2370
|
+
userKey: testData.closeATAkeys.userKey,
|
|
2371
|
+
backupKey: testData.closeATAkeys.backupKey,
|
|
2372
|
+
bitgoKey: testData.closeATAkeys.bitgoKey,
|
|
2373
|
+
recoveryDestination: testData.closeATAkeys.destinationPubKey,
|
|
2374
|
+
walletPassphrase: testData.closeATAkeys.walletPassword,
|
|
2375
|
+
nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
|
|
2376
|
+
tokenMintAddress: 'ZBCNpuD7YMXzTHB2fhGkGi78MNsHGLRXUhRewNRm9RU',
|
|
2377
|
+
})
|
|
2378
|
+
.should.be.rejectedWith('invalid ownerAtaAddress');
|
|
2379
|
+
});
|
|
2380
|
+
it('should throw when tokenMintAddress is missing for recoverNestedAta', async function () {
|
|
2381
|
+
await basecoin
|
|
2382
|
+
.recoverNestedAta({
|
|
2383
|
+
userKey: testData.closeATAkeys.userKey,
|
|
2384
|
+
backupKey: testData.closeATAkeys.backupKey,
|
|
2385
|
+
bitgoKey: testData.closeATAkeys.bitgoKey,
|
|
2386
|
+
recoveryDestination: testData.closeATAkeys.destinationPubKey,
|
|
2387
|
+
walletPassphrase: testData.closeATAkeys.walletPassword,
|
|
2388
|
+
nestedAtaAddress: 'FGuZSBhtreqSUsE86xokyjKz2i8VBtJzy6uMXXKyGHug',
|
|
2389
|
+
ownerAtaAddress: 'Zfm98ZpVafydhFTYcsY6bHgubhB4cFgWFvbdEJxYhTA',
|
|
2390
|
+
})
|
|
2391
|
+
.should.be.rejectedWith('invalid tokenMintAddress');
|
|
2392
|
+
});
|
|
2393
|
+
});
|
|
2394
|
+
describe('Build Consolidation Recoveries:', () => {
|
|
2395
|
+
const sandBox = sinon.createSandbox();
|
|
2396
|
+
const coin = statics_1.coins.get('tsol');
|
|
2397
|
+
const usdtMintAddress = '9cgpBeNZ2HnLda7NWaaU1i3NyTstk2c4zCMUcoAGsi9C';
|
|
2398
|
+
const durableNonces = {
|
|
2399
|
+
publicKeys: [
|
|
2400
|
+
testData.keys.durableNoncePubKey,
|
|
2401
|
+
testData.keys.durableNoncePubKey2,
|
|
2402
|
+
testData.keys.durableNoncePubKey3,
|
|
2403
|
+
],
|
|
2404
|
+
secretKey: testData.keys.durableNoncePrivKey,
|
|
2405
|
+
};
|
|
2406
|
+
beforeEach(() => {
|
|
2407
|
+
const callBack = sandBox.stub(src_1.Sol.prototype, 'getDataFromNode');
|
|
2408
|
+
callBack
|
|
2409
|
+
.withArgs({
|
|
2410
|
+
payload: {
|
|
2411
|
+
id: '1',
|
|
2412
|
+
jsonrpc: '2.0',
|
|
2413
|
+
method: 'getLatestBlockhash',
|
|
2414
|
+
params: [
|
|
2415
|
+
{
|
|
2416
|
+
commitment: 'finalized',
|
|
2417
|
+
},
|
|
2418
|
+
],
|
|
2419
|
+
},
|
|
2420
|
+
})
|
|
2421
|
+
.resolves(testData.SolResponses.getBlockhashResponse);
|
|
2422
|
+
callBack
|
|
2423
|
+
.withArgs({
|
|
2424
|
+
payload: {
|
|
2425
|
+
id: '1',
|
|
2426
|
+
jsonrpc: '2.0',
|
|
2427
|
+
method: 'getFeeForMessage',
|
|
2428
|
+
params: [
|
|
2429
|
+
sinon.match.string,
|
|
2430
|
+
{
|
|
2431
|
+
commitment: 'finalized',
|
|
2432
|
+
},
|
|
2433
|
+
],
|
|
2434
|
+
},
|
|
2435
|
+
})
|
|
2436
|
+
.resolves(testData.SolResponses.getFeesForMessageResponse);
|
|
2437
|
+
callBack
|
|
2438
|
+
.withArgs({
|
|
2439
|
+
payload: {
|
|
2440
|
+
id: '1',
|
|
2441
|
+
jsonrpc: '2.0',
|
|
2442
|
+
method: 'getBalance',
|
|
2443
|
+
params: [testData.wrwUser.walletAddress1],
|
|
2444
|
+
},
|
|
2445
|
+
})
|
|
2446
|
+
.resolves(testData.SolResponses.getAccountBalanceResponseNoFunds);
|
|
2447
|
+
callBack
|
|
2448
|
+
.withArgs({
|
|
2449
|
+
payload: {
|
|
2450
|
+
id: '1',
|
|
2451
|
+
jsonrpc: '2.0',
|
|
2452
|
+
method: 'getBalance',
|
|
2453
|
+
params: [testData.wrwUser.walletAddress2],
|
|
2454
|
+
},
|
|
2455
|
+
})
|
|
2456
|
+
.resolves(testData.SolResponses.getAccountBalanceResponse);
|
|
2457
|
+
callBack
|
|
2458
|
+
.withArgs({
|
|
2459
|
+
payload: {
|
|
2460
|
+
id: '1',
|
|
2461
|
+
jsonrpc: '2.0',
|
|
2462
|
+
method: 'getBalance',
|
|
2463
|
+
params: [testData.wrwUser.walletAddress3],
|
|
2464
|
+
},
|
|
2465
|
+
})
|
|
2466
|
+
.resolves(testData.SolResponses.getAccountBalanceResponse);
|
|
2467
|
+
callBack
|
|
2468
|
+
.withArgs({
|
|
2469
|
+
payload: {
|
|
2470
|
+
id: '1',
|
|
2471
|
+
jsonrpc: '2.0',
|
|
2472
|
+
method: 'getBalance',
|
|
2473
|
+
params: [testData.wrwUser.walletAddress5],
|
|
2474
|
+
},
|
|
2475
|
+
})
|
|
2476
|
+
.resolves(testData.SolResponses.getAccountBalanceResponse);
|
|
2477
|
+
callBack
|
|
2478
|
+
.withArgs({
|
|
2479
|
+
payload: {
|
|
2480
|
+
id: '1',
|
|
2481
|
+
jsonrpc: '2.0',
|
|
2482
|
+
method: 'getMinimumBalanceForRentExemption',
|
|
2483
|
+
params: [165],
|
|
2484
|
+
},
|
|
2485
|
+
})
|
|
2486
|
+
.resolves(testData.SolResponses.getMinimumBalanceForRentExemptionResponse);
|
|
2487
|
+
callBack
|
|
2488
|
+
.withArgs({
|
|
2489
|
+
payload: {
|
|
2490
|
+
id: '1',
|
|
2491
|
+
jsonrpc: '2.0',
|
|
2492
|
+
method: 'getAccountInfo',
|
|
2493
|
+
params: [
|
|
2494
|
+
testData.keys.durableNoncePubKey,
|
|
2495
|
+
{
|
|
2496
|
+
encoding: 'jsonParsed',
|
|
2497
|
+
},
|
|
2498
|
+
],
|
|
2499
|
+
},
|
|
2500
|
+
})
|
|
2501
|
+
.resolves(testData.SolResponses.getAccountInfoResponse);
|
|
2502
|
+
callBack
|
|
2503
|
+
.withArgs({
|
|
2504
|
+
payload: {
|
|
2505
|
+
id: '1',
|
|
2506
|
+
jsonrpc: '2.0',
|
|
2507
|
+
method: 'getAccountInfo',
|
|
2508
|
+
params: [
|
|
2509
|
+
testData.keys.durableNoncePubKey2,
|
|
2510
|
+
{
|
|
2511
|
+
encoding: 'jsonParsed',
|
|
2512
|
+
},
|
|
2513
|
+
],
|
|
2514
|
+
},
|
|
2515
|
+
})
|
|
2516
|
+
.resolves(testData.SolResponses.getAccountInfoResponse2);
|
|
2517
|
+
callBack
|
|
2518
|
+
.withArgs({
|
|
2519
|
+
payload: {
|
|
2520
|
+
id: '1',
|
|
2521
|
+
jsonrpc: '2.0',
|
|
2522
|
+
method: 'getTokenAccountsByOwner',
|
|
2523
|
+
params: [
|
|
2524
|
+
testData.wrwUser.walletAddress1,
|
|
2525
|
+
{
|
|
2526
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
2527
|
+
},
|
|
2528
|
+
{
|
|
2529
|
+
encoding: 'jsonParsed',
|
|
2530
|
+
},
|
|
2531
|
+
],
|
|
2532
|
+
},
|
|
2533
|
+
})
|
|
2534
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
2535
|
+
callBack
|
|
2536
|
+
.withArgs({
|
|
2537
|
+
payload: {
|
|
2538
|
+
id: '1',
|
|
2539
|
+
jsonrpc: '2.0',
|
|
2540
|
+
method: 'getTokenAccountsByOwner',
|
|
2541
|
+
params: [
|
|
2542
|
+
testData.wrwUser.walletAddress2,
|
|
2543
|
+
{
|
|
2544
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
2545
|
+
},
|
|
2546
|
+
{
|
|
2547
|
+
encoding: 'jsonParsed',
|
|
2548
|
+
},
|
|
2549
|
+
],
|
|
2550
|
+
},
|
|
2551
|
+
})
|
|
2552
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
2553
|
+
callBack
|
|
2554
|
+
.withArgs({
|
|
2555
|
+
payload: {
|
|
2556
|
+
id: '1',
|
|
2557
|
+
jsonrpc: '2.0',
|
|
2558
|
+
method: 'getTokenAccountsByOwner',
|
|
2559
|
+
params: [
|
|
2560
|
+
testData.wrwUser.walletAddress3,
|
|
2561
|
+
{
|
|
2562
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
2563
|
+
},
|
|
2564
|
+
{
|
|
2565
|
+
encoding: 'jsonParsed',
|
|
2566
|
+
},
|
|
2567
|
+
],
|
|
2568
|
+
},
|
|
2569
|
+
})
|
|
2570
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponseNoAccounts);
|
|
2571
|
+
callBack
|
|
2572
|
+
.withArgs({
|
|
2573
|
+
payload: {
|
|
2574
|
+
id: '1',
|
|
2575
|
+
jsonrpc: '2.0',
|
|
2576
|
+
method: 'getTokenAccountsByOwner',
|
|
2577
|
+
params: [
|
|
2578
|
+
testData.wrwUser.walletAddress5,
|
|
2579
|
+
{
|
|
2580
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
2581
|
+
},
|
|
2582
|
+
{
|
|
2583
|
+
encoding: 'jsonParsed',
|
|
2584
|
+
},
|
|
2585
|
+
],
|
|
2586
|
+
},
|
|
2587
|
+
})
|
|
2588
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
|
|
2589
|
+
callBack
|
|
2590
|
+
.withArgs({
|
|
2591
|
+
payload: {
|
|
2592
|
+
id: '1',
|
|
2593
|
+
jsonrpc: '2.0',
|
|
2594
|
+
method: 'getTokenAccountsByOwner',
|
|
2595
|
+
params: [
|
|
2596
|
+
testData.wrwUser.walletAddress0,
|
|
2597
|
+
{
|
|
2598
|
+
programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
|
|
2599
|
+
},
|
|
2600
|
+
{
|
|
2601
|
+
encoding: 'jsonParsed',
|
|
2602
|
+
},
|
|
2603
|
+
],
|
|
2604
|
+
},
|
|
2605
|
+
})
|
|
2606
|
+
.resolves(testData.SolResponses.getTokenAccountsByOwnerResponse);
|
|
2607
|
+
});
|
|
2608
|
+
afterEach(() => {
|
|
2609
|
+
sandBox.restore();
|
|
2610
|
+
});
|
|
2611
|
+
it('should build signed consolidation recoveries', async function () {
|
|
2612
|
+
const res = (await basecoin.recoverConsolidations({
|
|
2613
|
+
userKey: testData.wrwUser.userKey,
|
|
2614
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2615
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2616
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2617
|
+
startingScanIndex: 1,
|
|
2618
|
+
endingScanIndex: 4,
|
|
2619
|
+
durableNonces: durableNonces,
|
|
2620
|
+
}));
|
|
2621
|
+
res.should.not.be.empty();
|
|
2622
|
+
res.transactions.length.should.equal(2);
|
|
2623
|
+
(res.lastScanIndex ?? 0).should.equal(3);
|
|
2624
|
+
const txn1 = res.transactions[0];
|
|
2625
|
+
const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
|
|
2626
|
+
latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
|
|
2627
|
+
const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
|
|
2628
|
+
const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
|
|
2629
|
+
should.equal(latestBlockhashTxnJson1.nonce, nonce1);
|
|
2630
|
+
should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress2);
|
|
2631
|
+
should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2632
|
+
const txn2 = res.transactions[1];
|
|
2633
|
+
const latestBlockhashTxnDeserialize2 = new lib_1.Transaction(coin);
|
|
2634
|
+
latestBlockhashTxnDeserialize2.fromRawTransaction(txn2.serializedTx);
|
|
2635
|
+
const latestBlockhashTxnJson2 = latestBlockhashTxnDeserialize2.toJson();
|
|
2636
|
+
const nonce2 = testData.SolResponses.getAccountInfoResponse2.body.result.value.data.parsed.info.blockhash;
|
|
2637
|
+
should.equal(latestBlockhashTxnJson2.nonce, nonce2);
|
|
2638
|
+
should.equal(latestBlockhashTxnJson2.feePayer, testData.wrwUser.walletAddress3);
|
|
2639
|
+
should.equal(latestBlockhashTxnJson2.numSignatures, testData.SolInputData.durableNonceSignatures);
|
|
2640
|
+
});
|
|
2641
|
+
it('should build unsigned consolidation recoveries', async function () {
|
|
2642
|
+
const res = (await basecoin.recoverConsolidations({
|
|
2643
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2644
|
+
startingScanIndex: 1,
|
|
2645
|
+
endingScanIndex: 4,
|
|
2646
|
+
durableNonces: durableNonces,
|
|
2647
|
+
}));
|
|
2648
|
+
res.should.not.be.empty();
|
|
2649
|
+
res.txRequests.length.should.equal(2);
|
|
2650
|
+
const txn1 = res.txRequests[0].transactions[0].unsignedTx;
|
|
2651
|
+
txn1.should.hasOwnProperty('serializedTx');
|
|
2652
|
+
txn1.should.hasOwnProperty('signableHex');
|
|
2653
|
+
txn1.should.hasOwnProperty('scanIndex');
|
|
2654
|
+
(txn1.scanIndex ?? 0).should.equal(2);
|
|
2655
|
+
txn1.should.hasOwnProperty('coin');
|
|
2656
|
+
txn1.coin?.should.equal('tsol');
|
|
2657
|
+
txn1.should.hasOwnProperty('derivationPath');
|
|
2658
|
+
txn1.derivationPath?.should.equal('m/2');
|
|
2659
|
+
txn1.should.hasOwnProperty('coinSpecific');
|
|
2660
|
+
const coinSpecific1 = txn1.coinSpecific;
|
|
2661
|
+
coinSpecific1?.should.hasOwnProperty('commonKeychain');
|
|
2662
|
+
const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
|
|
2663
|
+
latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
|
|
2664
|
+
const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
|
|
2665
|
+
const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
|
|
2666
|
+
should.equal(latestBlockhashTxnJson1.nonce, nonce1);
|
|
2667
|
+
should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress2);
|
|
2668
|
+
should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.unsignedSweepSignatures);
|
|
2669
|
+
const txn2 = res.txRequests[1].transactions[0].unsignedTx;
|
|
2670
|
+
txn2.should.hasOwnProperty('serializedTx');
|
|
2671
|
+
txn2.should.hasOwnProperty('signableHex');
|
|
2672
|
+
txn2.should.hasOwnProperty('scanIndex');
|
|
2673
|
+
(txn2.scanIndex ?? 0).should.equal(3);
|
|
2674
|
+
txn2.should.hasOwnProperty('coin');
|
|
2675
|
+
txn2.coin?.should.equal('tsol');
|
|
2676
|
+
txn2.should.hasOwnProperty('derivationPath');
|
|
2677
|
+
txn2.derivationPath?.should.equal('m/3');
|
|
2678
|
+
txn2.should.hasOwnProperty('coinSpecific');
|
|
2679
|
+
const coinSpecific2 = txn2.coinSpecific;
|
|
2680
|
+
coinSpecific2?.should.hasOwnProperty('commonKeychain');
|
|
2681
|
+
coinSpecific2?.should.hasOwnProperty('lastScanIndex');
|
|
2682
|
+
coinSpecific2?.lastScanIndex?.should.equal(3);
|
|
2683
|
+
const latestBlockhashTxnDeserialize2 = new lib_1.Transaction(coin);
|
|
2684
|
+
latestBlockhashTxnDeserialize2.fromRawTransaction(txn2.serializedTx);
|
|
2685
|
+
const latestBlockhashTxnJson2 = latestBlockhashTxnDeserialize2.toJson();
|
|
2686
|
+
const nonce2 = testData.SolResponses.getAccountInfoResponse2.body.result.value.data.parsed.info.blockhash;
|
|
2687
|
+
should.equal(latestBlockhashTxnJson2.nonce, nonce2);
|
|
2688
|
+
should.equal(latestBlockhashTxnJson2.feePayer, testData.wrwUser.walletAddress3);
|
|
2689
|
+
should.equal(latestBlockhashTxnJson2.numSignatures, testData.SolInputData.unsignedSweepSignatures);
|
|
2690
|
+
});
|
|
2691
|
+
it('should build unsigned token consolidation recoveries', async function () {
|
|
2692
|
+
const res = (await basecoin.recoverConsolidations({
|
|
2693
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2694
|
+
startingScanIndex: 3,
|
|
2695
|
+
endingScanIndex: 5,
|
|
2696
|
+
tokenContractAddress: usdtMintAddress,
|
|
2697
|
+
durableNonces: durableNonces,
|
|
2698
|
+
}));
|
|
2699
|
+
res.should.not.be.empty();
|
|
2700
|
+
res.txRequests.length.should.equal(1);
|
|
2701
|
+
const txn1 = res.txRequests[0].transactions[0].unsignedTx;
|
|
2702
|
+
txn1.should.hasOwnProperty('serializedTx');
|
|
2703
|
+
txn1.should.hasOwnProperty('signableHex');
|
|
2704
|
+
txn1.should.hasOwnProperty('scanIndex');
|
|
2705
|
+
(txn1.scanIndex ?? 0).should.equal(4);
|
|
2706
|
+
txn1.should.hasOwnProperty('coin');
|
|
2707
|
+
txn1.coin?.should.equal('tsol');
|
|
2708
|
+
txn1.should.hasOwnProperty('derivationPath');
|
|
2709
|
+
txn1.derivationPath?.should.equal('m/4');
|
|
2710
|
+
txn1.should.hasOwnProperty('coinSpecific');
|
|
2711
|
+
const coinSpecific1 = txn1.coinSpecific;
|
|
2712
|
+
coinSpecific1?.should.hasOwnProperty('commonKeychain');
|
|
2713
|
+
const latestBlockhashTxnDeserialize1 = new lib_1.Transaction(coin);
|
|
2714
|
+
latestBlockhashTxnDeserialize1.fromRawTransaction(txn1.serializedTx);
|
|
2715
|
+
const latestBlockhashTxnJson1 = latestBlockhashTxnDeserialize1.toJson();
|
|
2716
|
+
const nonce1 = testData.SolResponses.getAccountInfoResponse.body.result.value.data.parsed.info.blockhash;
|
|
2717
|
+
should.equal(latestBlockhashTxnJson1.nonce, nonce1);
|
|
2718
|
+
should.equal(latestBlockhashTxnJson1.feePayer, testData.wrwUser.walletAddress5);
|
|
2719
|
+
should.equal(latestBlockhashTxnJson1.numSignatures, testData.SolInputData.unsignedSweepSignatures);
|
|
2720
|
+
});
|
|
2721
|
+
it('should skip building consolidate transaction if balance is equal to zero', async function () {
|
|
2722
|
+
await basecoin
|
|
2723
|
+
.recoverConsolidations({
|
|
2724
|
+
userKey: testData.wrwUser.userKey,
|
|
2725
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2726
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2727
|
+
walletPassphrase: testData.wrwUser.walletPassphrase,
|
|
2728
|
+
startingScanIndex: 1,
|
|
2729
|
+
endingScanIndex: 2,
|
|
2730
|
+
durableNonces: durableNonces,
|
|
2731
|
+
})
|
|
2732
|
+
.should.rejectedWith('Did not find an address with funds to recover');
|
|
2733
|
+
});
|
|
2734
|
+
it('should throw if startingScanIndex is not ge to 1', async () => {
|
|
2735
|
+
await basecoin
|
|
2736
|
+
.recoverConsolidations({
|
|
2737
|
+
userKey: testData.wrwUser.userKey,
|
|
2738
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2739
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2740
|
+
startingScanIndex: -1,
|
|
2741
|
+
durableNonces: durableNonces,
|
|
2742
|
+
})
|
|
2743
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
|
|
2744
|
+
});
|
|
2745
|
+
it('should throw if scan factor is too high', async () => {
|
|
2746
|
+
await basecoin
|
|
2747
|
+
.recoverConsolidations({
|
|
2748
|
+
userKey: testData.wrwUser.userKey,
|
|
2749
|
+
backupKey: testData.wrwUser.backupKey,
|
|
2750
|
+
bitgoKey: testData.wrwUser.bitgoKey,
|
|
2751
|
+
startingScanIndex: 1,
|
|
2752
|
+
endingScanIndex: 300,
|
|
2753
|
+
durableNonces: durableNonces,
|
|
2754
|
+
})
|
|
2755
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
|
|
2756
|
+
});
|
|
2757
|
+
});
|
|
2758
|
+
describe('broadcastTransaction', function () {
|
|
2759
|
+
const sandBox = sinon.createSandbox();
|
|
2760
|
+
afterEach(() => {
|
|
2761
|
+
sandBox.restore();
|
|
2762
|
+
});
|
|
2763
|
+
it('should broadcast a transaction succesfully', async function () {
|
|
2764
|
+
const serializedSignedTransaction = testData.rawTransactions.transfer.signed;
|
|
2765
|
+
const broadcastStub = sandBox
|
|
2766
|
+
.stub(src_1.Sol.prototype, 'getDataFromNode')
|
|
2767
|
+
.withArgs({
|
|
2768
|
+
payload: {
|
|
2769
|
+
id: '1',
|
|
2770
|
+
jsonrpc: '2.0',
|
|
2771
|
+
method: 'sendTransaction',
|
|
2772
|
+
params: [
|
|
2773
|
+
serializedSignedTransaction,
|
|
2774
|
+
{
|
|
2775
|
+
encoding: 'base64',
|
|
2776
|
+
},
|
|
2777
|
+
],
|
|
2778
|
+
},
|
|
2779
|
+
})
|
|
2780
|
+
.resolves(testData.SolResponses.broadcastTransactionResponse);
|
|
2781
|
+
const broadcastTxn = await basecoin.broadcastTransaction({ serializedSignedTransaction });
|
|
2782
|
+
assert_1.default.ok(broadcastTxn);
|
|
2783
|
+
assert_1.default.ok(broadcastTxn.txId);
|
|
2784
|
+
assert_1.default.strictEqual(broadcastTxn.txId, '2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb');
|
|
2785
|
+
assert_1.default.strictEqual(broadcastStub.callCount, 1);
|
|
2786
|
+
});
|
|
2787
|
+
it('should throw if got an error from the node', async function () {
|
|
2788
|
+
const serializedSignedTransaction = testData.rawTransactions.transfer.signed;
|
|
2789
|
+
const broadcastStub = sandBox
|
|
2790
|
+
.stub(src_1.Sol.prototype, 'getDataFromNode')
|
|
2791
|
+
.withArgs({
|
|
2792
|
+
payload: {
|
|
2793
|
+
id: '1',
|
|
2794
|
+
jsonrpc: '2.0',
|
|
2795
|
+
method: 'sendTransaction',
|
|
2796
|
+
params: [
|
|
2797
|
+
serializedSignedTransaction,
|
|
2798
|
+
{
|
|
2799
|
+
encoding: 'base64',
|
|
2800
|
+
},
|
|
2801
|
+
],
|
|
2802
|
+
},
|
|
2803
|
+
})
|
|
2804
|
+
.resolves(testData.SolResponses.broadcastTransactionResponseError);
|
|
2805
|
+
await assert_1.default.rejects(async () => {
|
|
2806
|
+
await basecoin.broadcastTransaction({ serializedSignedTransaction });
|
|
2807
|
+
}, { message: 'Error broadcasting transaction: Transaction simulation failed: Blockhash not found' });
|
|
2808
|
+
assert_1.default.strictEqual(broadcastStub.callCount, 1);
|
|
2809
|
+
});
|
|
2810
|
+
it('should throw if is not a valid transaction', async function () {
|
|
2811
|
+
const serializedSignedTransaction = 'randomstring';
|
|
2812
|
+
await assert_1.default.rejects(async () => {
|
|
2813
|
+
await basecoin.broadcastTransaction({ serializedSignedTransaction });
|
|
2814
|
+
}, { message: 'Invalid raw transaction' });
|
|
2815
|
+
});
|
|
2816
|
+
it('should throw if is not a signed transaction', async function () {
|
|
2817
|
+
const serializedSignedTransaction = testData.rawTransactions.transfer.unsigned;
|
|
2818
|
+
await assert_1.default.rejects(async () => {
|
|
2819
|
+
await basecoin.broadcastTransaction({ serializedSignedTransaction });
|
|
2820
|
+
}, { message: 'Invalid raw transaction' });
|
|
2821
|
+
});
|
|
2822
|
+
});
|
|
2823
|
+
describe('AuditKey', () => {
|
|
2824
|
+
const { key: keyString, commonKeychain } = solBackupKey_1.solBackupKey;
|
|
2825
|
+
const key = keyString.replace(/\s/g, '');
|
|
2826
|
+
const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
|
|
2827
|
+
const multiSigType = 'tss';
|
|
2828
|
+
it('should return for valid inputs', () => {
|
|
2829
|
+
basecoin.assertIsValidKey({
|
|
2830
|
+
encryptedPrv: key,
|
|
2831
|
+
publicKey: commonKeychain,
|
|
2832
|
+
walletPassphrase,
|
|
2833
|
+
multiSigType,
|
|
2834
|
+
});
|
|
2835
|
+
});
|
|
2836
|
+
it('should throw error if the commonKeychain is invalid', () => {
|
|
2837
|
+
const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
|
|
2838
|
+
assert_1.default.throws(() => basecoin.assertIsValidKey({
|
|
2839
|
+
encryptedPrv: key,
|
|
2840
|
+
publicKey: alteredCommonKeychain,
|
|
2841
|
+
walletPassphrase,
|
|
2842
|
+
multiSigType,
|
|
2843
|
+
}), {
|
|
2844
|
+
message: 'Invalid common keychain',
|
|
2845
|
+
});
|
|
2846
|
+
});
|
|
2847
|
+
it('should throw error if the walletPassphrase is incorrect', () => {
|
|
2848
|
+
const incorrectPassphrase = 'foo';
|
|
2849
|
+
assert_1.default.throws(() => basecoin.assertIsValidKey({
|
|
2850
|
+
encryptedPrv: key,
|
|
2851
|
+
publicKey: commonKeychain,
|
|
2852
|
+
walletPassphrase: incorrectPassphrase,
|
|
2853
|
+
multiSigType,
|
|
2854
|
+
}), {
|
|
2855
|
+
message: "failed to decrypt prv: ccm: tag doesn't match",
|
|
2856
|
+
});
|
|
2857
|
+
});
|
|
2858
|
+
it('should throw error if the key is altered', () => {
|
|
2859
|
+
const alteredKey = key.replace(/[0-9]/g, '0');
|
|
2860
|
+
assert_1.default.throws(() => basecoin.assertIsValidKey({
|
|
2861
|
+
encryptedPrv: alteredKey,
|
|
2862
|
+
publicKey: commonKeychain,
|
|
2863
|
+
walletPassphrase,
|
|
2864
|
+
multiSigType,
|
|
2865
|
+
}), {
|
|
2866
|
+
message: 'failed to decrypt prv: json decrypt: invalid parameters',
|
|
2867
|
+
});
|
|
2868
|
+
});
|
|
2869
|
+
it('should verify consolidation transaction', async function () {
|
|
2870
|
+
// Set up wallet data
|
|
2871
|
+
const walletData = {
|
|
2872
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
2873
|
+
coin: 'tsol',
|
|
2874
|
+
keys: [
|
|
2875
|
+
'5b3424f91bf349930e34017500000000',
|
|
2876
|
+
'5b3424f91bf349930e34017600000000',
|
|
2877
|
+
'5b3424f91bf349930e34017700000000',
|
|
2878
|
+
],
|
|
2879
|
+
coinSpecific: {
|
|
2880
|
+
rootAddress: wallet.pub,
|
|
2881
|
+
},
|
|
2882
|
+
multisigType: 'tss',
|
|
2883
|
+
};
|
|
2884
|
+
const fakePrv = (0, sdk_api_1.encrypt)('password', 'prv');
|
|
2885
|
+
const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
2886
|
+
const bgUrl = sdk_core_1.common.Environments['mock'].uri;
|
|
2887
|
+
(0, nock_1.default)(bgUrl)
|
|
2888
|
+
.get('/api/v2/tsol/key/5b3424f91bf349930e34017500000000')
|
|
2889
|
+
.reply(200, [
|
|
2890
|
+
{
|
|
2891
|
+
encryptedPrv: fakePrv,
|
|
2892
|
+
},
|
|
2893
|
+
]);
|
|
2894
|
+
// Mock the API response for buildAccountConsolidations
|
|
2895
|
+
(0, nock_1.default)(bgUrl)
|
|
2896
|
+
.post('/api/v2/tsol/wallet/5b34252f1bf349930e34020a00000000/consolidateAccount/build')
|
|
2897
|
+
.reply(200, [
|
|
2898
|
+
{
|
|
2899
|
+
txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
|
|
2900
|
+
walletId: '63068ed4efa63a000877f02fd4b0fa6d',
|
|
2901
|
+
txHex: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f50130abf8d0d8943c5b9a51a574886a7d7b3d8db18f0ddb4ab8b6d3ec27e3c2f36f3339bb92d4296af6ae4d3abfbb07877f77d0033c883de08fa4a2eea670d0201020674a9df2b94aa4b4ada1202dc2891be366501d0acb4a01ca3e02e7fd6c1f505a71c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f8401c3f67cfa52518b34a09b08f4ea77e1c4fb9d89bfaccdc33cf8b8a9cf8d7bf0e04c89c50428e4eda5cbb759427c370f0a29a50bb0d1407e57924b0cc5b36f000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000040c9568195d67eb6b396fdbe97ba2e276622ef0023af09f23e6e0292abb678d90204030305010404000000040200020c020000000100000000000000',
|
|
2902
|
+
feeInfo: {
|
|
2903
|
+
fee: 10000,
|
|
2904
|
+
feeString: '10000',
|
|
2905
|
+
},
|
|
2906
|
+
txInfo: {
|
|
2907
|
+
minerFee: '10000',
|
|
2908
|
+
spendAmount: '1547864',
|
|
2909
|
+
spendAmounts: [
|
|
2910
|
+
{
|
|
2911
|
+
coinName: 'tsol',
|
|
2912
|
+
amountString: '1547864',
|
|
2913
|
+
},
|
|
2914
|
+
],
|
|
2915
|
+
payGoFee: '0',
|
|
2916
|
+
outputs: [
|
|
2917
|
+
{
|
|
2918
|
+
address: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
|
|
2919
|
+
value: 1547864,
|
|
2920
|
+
wallet: '63068ed4efa63a000877f02f',
|
|
2921
|
+
wallets: ['63068ed4efa63a000877f02f'],
|
|
2922
|
+
enterprise: '62d71a6b86068f0008f029fd',
|
|
2923
|
+
enterprises: ['62d71a6b86068f0008f029fd'],
|
|
2924
|
+
valueString: '1547864',
|
|
2925
|
+
coinName: 'tsol',
|
|
2926
|
+
walletType: 'hot',
|
|
2927
|
+
walletTypes: ['hot'],
|
|
2928
|
+
},
|
|
2929
|
+
],
|
|
2930
|
+
inputs: [
|
|
2931
|
+
{
|
|
2932
|
+
value: 1547864,
|
|
2933
|
+
address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
|
|
2934
|
+
valueString: '1547864',
|
|
2935
|
+
},
|
|
2936
|
+
{
|
|
2937
|
+
value: 10000,
|
|
2938
|
+
address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
|
|
2939
|
+
valueString: '10000',
|
|
2940
|
+
},
|
|
2941
|
+
],
|
|
2942
|
+
type: 'Send',
|
|
2943
|
+
},
|
|
2944
|
+
consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
|
|
2945
|
+
coin: 'tsol',
|
|
2946
|
+
},
|
|
2947
|
+
]);
|
|
2948
|
+
// Call the function to test
|
|
2949
|
+
await assert_1.default.rejects(async () => {
|
|
2950
|
+
await walletObj.sendAccountConsolidations({
|
|
2951
|
+
walletPassphrase: 'password',
|
|
2952
|
+
});
|
|
2953
|
+
}, {
|
|
2954
|
+
message: 'tx outputs does not match with expected address',
|
|
2955
|
+
});
|
|
2956
|
+
});
|
|
2957
|
+
it('should verify valid a consolidation transaction', async () => {
|
|
2958
|
+
const consolidationTx = {
|
|
2959
|
+
txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
|
|
2960
|
+
walletId: '63068ed4efa63a000877f02fd4b0fa6d',
|
|
2961
|
+
txHex: '02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002010206aeda253a331de489838246df93879440af8c62ac4967658edc2bb5d52b9759d91c96172044f1217c3784e8f02f49e2c8fc3591e81294ab54394f9d22fd7b7a8f74a9df2b94aa4b4ada1202dc2891be366501d0acb4a01ca3e02e7fd6c1f505a7d2734f3952f3eb4aefcf6c7a6092e979dd3fe5563ccfaca1cc92652a15ddd393000000000000000000000000000000000000000000000000000000000000000006a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea9400000428dad41bbedeb38018379e4ceeb7e80757d74dd00ae8c47c38d597477339ad80204030305010404000000040200020c02000000589e170000000000',
|
|
2962
|
+
feeInfo: {
|
|
2963
|
+
fee: 10000,
|
|
2964
|
+
feeString: '10000',
|
|
2965
|
+
},
|
|
2966
|
+
txInfo: {
|
|
2967
|
+
minerFee: '10000',
|
|
2968
|
+
spendAmount: '1547864',
|
|
2969
|
+
spendAmounts: [
|
|
2970
|
+
{
|
|
2971
|
+
coinName: 'tsol',
|
|
2972
|
+
amountString: '1547864',
|
|
2973
|
+
},
|
|
2974
|
+
],
|
|
2975
|
+
payGoFee: '0',
|
|
2976
|
+
outputs: [
|
|
2977
|
+
{
|
|
2978
|
+
address: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
|
|
2979
|
+
value: 1547864,
|
|
2980
|
+
wallet: '63068ed4efa63a000877f02f',
|
|
2981
|
+
wallets: ['63068ed4efa63a000877f02f'],
|
|
2982
|
+
enterprise: '62d71a6b86068f0008f029fd',
|
|
2983
|
+
enterprises: ['62d71a6b86068f0008f029fd'],
|
|
2984
|
+
valueString: '1547864',
|
|
2985
|
+
coinName: 'tsol',
|
|
2986
|
+
walletType: 'hot',
|
|
2987
|
+
walletTypes: ['hot'],
|
|
2988
|
+
},
|
|
2989
|
+
],
|
|
2990
|
+
inputs: [
|
|
2991
|
+
{
|
|
2992
|
+
value: 1547864,
|
|
2993
|
+
address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
|
|
2994
|
+
valueString: '1547864',
|
|
2995
|
+
},
|
|
2996
|
+
{
|
|
2997
|
+
value: 10000,
|
|
2998
|
+
address: 'CmYsN3f8bcm4BDkFJWNsvYgjRxMTLH6vbJWNfYdmH7GU',
|
|
2999
|
+
valueString: '10000',
|
|
3000
|
+
},
|
|
3001
|
+
],
|
|
3002
|
+
type: 'Send',
|
|
3003
|
+
},
|
|
3004
|
+
consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
|
|
3005
|
+
coin: 'tsol',
|
|
3006
|
+
};
|
|
3007
|
+
const mockedWallet = {
|
|
3008
|
+
coinSpecific: () => {
|
|
3009
|
+
const cs = {
|
|
3010
|
+
rootAddress: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
|
|
3011
|
+
};
|
|
3012
|
+
return cs;
|
|
3013
|
+
},
|
|
3014
|
+
};
|
|
3015
|
+
try {
|
|
3016
|
+
if (!(await basecoin.verifyTransaction({
|
|
3017
|
+
blockhash: '',
|
|
3018
|
+
feePayer: '',
|
|
3019
|
+
txParams: {},
|
|
3020
|
+
txPrebuild: consolidationTx,
|
|
3021
|
+
walletType: 'tss',
|
|
3022
|
+
wallet: mockedWallet,
|
|
3023
|
+
verification: {
|
|
3024
|
+
consolidationToBaseAddress: true,
|
|
3025
|
+
},
|
|
3026
|
+
}))) {
|
|
3027
|
+
assert_1.default.fail('Transaction should pass verification');
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
catch (e) {
|
|
3031
|
+
assert_1.default.fail('Transaction should pass verification');
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
it('should verify a token consolidation transaction', async () => {
|
|
3035
|
+
const consolidationTx = {
|
|
3036
|
+
txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
|
|
3037
|
+
walletId: '63068ed4efa63a000877f02fd4b0fa6d',
|
|
3038
|
+
txHex: '02b7c2c7829eded4e8f947c90ed3b9afce71f616eb47dfcfbf4b765778149060013acb33b9f67fdd9c2512f48fac4e4c049eab93829b69404f3bd166fe3242c90700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020104096da690bd558fd8634ac14f1645d8095afd0caea5953578c596e3c0dea38305ee7298bfac55101f177735659d42ed6be890ef3a1d204d9e33f32e24c5635327ca66d1fe00826e5a4f759f87b279c1aee19cce5301af4ed66ae17db48b201ed6c2a0e8a28bf565627f1ab8a34b1a95ee1b0a2a39084f1f0e2acb1c394b20185d8e0b22657c8d9c4ce5f6495efb6410c199011530f90e3ab9d8d1e4206f9ae0ffeb0000000000000000000000000000000000000000000000000000000000000000c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e406a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9de13c74d2b4d948e1608ea6eebdafe75bc2f995aad11b21d1e2c94f2a2d12f6802050303070004040000000804020604010a0ce0076bb20400000006',
|
|
3039
|
+
feeInfo: {
|
|
3040
|
+
fee: 10000,
|
|
3041
|
+
feeString: '10000',
|
|
3042
|
+
},
|
|
3043
|
+
txInfo: {
|
|
3044
|
+
inputs: [
|
|
3045
|
+
{
|
|
3046
|
+
address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
|
|
3047
|
+
value: 2.0173228e10,
|
|
3048
|
+
valueString: '20173228000',
|
|
3049
|
+
},
|
|
3050
|
+
{
|
|
3051
|
+
address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
|
|
3052
|
+
value: 10000,
|
|
3053
|
+
valueString: '10000',
|
|
3054
|
+
},
|
|
3055
|
+
],
|
|
3056
|
+
minerFee: '10000',
|
|
3057
|
+
outputs: [
|
|
3058
|
+
{
|
|
3059
|
+
address: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
|
|
3060
|
+
coinName: 'sol:wif',
|
|
3061
|
+
enterprise: {
|
|
3062
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
3063
|
+
},
|
|
3064
|
+
enterprises: [
|
|
3065
|
+
{
|
|
3066
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
3067
|
+
},
|
|
3068
|
+
],
|
|
3069
|
+
value: 2.0173228e10,
|
|
3070
|
+
valueString: '20173228000',
|
|
3071
|
+
wallet: {
|
|
3072
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
3073
|
+
},
|
|
3074
|
+
walletType: 'hot',
|
|
3075
|
+
wallets: [
|
|
3076
|
+
{
|
|
3077
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
3078
|
+
},
|
|
3079
|
+
],
|
|
3080
|
+
},
|
|
3081
|
+
],
|
|
3082
|
+
payGoFee: '0',
|
|
3083
|
+
spendAmount: '20173228000',
|
|
3084
|
+
spendAmounts: [
|
|
3085
|
+
{
|
|
3086
|
+
amountString: '20173228000',
|
|
3087
|
+
coinName: 'sol:wif',
|
|
3088
|
+
},
|
|
3089
|
+
],
|
|
3090
|
+
type: 'Send',
|
|
3091
|
+
},
|
|
3092
|
+
consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
|
|
3093
|
+
coin: 'tsol',
|
|
3094
|
+
};
|
|
3095
|
+
const mockedWallet = {
|
|
3096
|
+
coinSpecific: () => {
|
|
3097
|
+
const cs = {
|
|
3098
|
+
rootAddress: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
|
|
3099
|
+
};
|
|
3100
|
+
return cs;
|
|
3101
|
+
},
|
|
3102
|
+
};
|
|
3103
|
+
try {
|
|
3104
|
+
if (!(await basecoin.verifyTransaction({
|
|
3105
|
+
blockhash: '',
|
|
3106
|
+
feePayer: '',
|
|
3107
|
+
txParams: {},
|
|
3108
|
+
txPrebuild: consolidationTx,
|
|
3109
|
+
walletType: 'tss',
|
|
3110
|
+
wallet: mockedWallet,
|
|
3111
|
+
verification: {
|
|
3112
|
+
consolidationToBaseAddress: true,
|
|
3113
|
+
},
|
|
3114
|
+
}))) {
|
|
3115
|
+
assert_1.default.fail('Transaction should pass verification');
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
catch (e) {
|
|
3119
|
+
assert_1.default.fail('Transaction should pass verification');
|
|
3120
|
+
}
|
|
3121
|
+
});
|
|
3122
|
+
it('should verify a spoofed token consolidation transaction', async () => {
|
|
3123
|
+
const consolidationTx = {
|
|
3124
|
+
txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
|
|
3125
|
+
walletId: '63068ed4efa63a000877f02fd4b0fa6d',
|
|
3126
|
+
txHex: '02b7c2c7829eded4e8f947c90ed3b9afce71f616eb47dfcfbf4b765778149060013acb33b9f67fdd9c2512f48fac4e4c049eab93829b69404f3bd166fe3242c90700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020104096da690bd558fd8634ac14f1645d8095afd0caea5953578c596e3c0dea38305ee7298bfac55101f177735659d42ed6be890ef3a1d204d9e33f32e24c5635327ca66d1fe00826e5a4f759f87b279c1aee19cce5301af4ed66ae17db48b201ed6c2a0e8a28bf565627f1ab8a34b1a95ee1b0a2a39084f1f0e2acb1c394b20185d8e0b22657c8d9c4ce5f6495efb6410c199011530f90e3ab9d8d1e4206f9ae0ffeb0000000000000000000000000000000000000000000000000000000000000000c5f9fb32f49111ab20c33f2598fc836c113e291881ac21ee29169394011244e406a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000006ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9de13c74d2b4d948e1608ea6eebdafe75bc2f995aad11b21d1e2c94f2a2d12f6802050303070004040000000804020604010a0ce0076bb20400000006',
|
|
3127
|
+
feeInfo: {
|
|
3128
|
+
fee: 10000,
|
|
3129
|
+
feeString: '10000',
|
|
3130
|
+
},
|
|
3131
|
+
txInfo: {
|
|
3132
|
+
inputs: [
|
|
3133
|
+
{
|
|
3134
|
+
address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
|
|
3135
|
+
value: 2.0173228e10,
|
|
3136
|
+
valueString: '20173228000',
|
|
3137
|
+
},
|
|
3138
|
+
{
|
|
3139
|
+
address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
|
|
3140
|
+
value: 10000,
|
|
3141
|
+
valueString: '10000',
|
|
3142
|
+
},
|
|
3143
|
+
],
|
|
3144
|
+
minerFee: '10000',
|
|
3145
|
+
outputs: [
|
|
3146
|
+
{
|
|
3147
|
+
address: 'HBxZShcE86UMmF93KUM8eWJKqeEXi5cqWCLYLMMhqMYm',
|
|
3148
|
+
coinName: 'sol:wif',
|
|
3149
|
+
enterprise: {
|
|
3150
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
3151
|
+
},
|
|
3152
|
+
enterprises: [
|
|
3153
|
+
{
|
|
3154
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
3155
|
+
},
|
|
3156
|
+
],
|
|
3157
|
+
value: 2.0173228e10,
|
|
3158
|
+
valueString: '20173228000',
|
|
3159
|
+
wallet: {
|
|
3160
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
3161
|
+
},
|
|
3162
|
+
walletType: 'hot',
|
|
3163
|
+
wallets: [
|
|
3164
|
+
{
|
|
3165
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
3166
|
+
},
|
|
3167
|
+
],
|
|
3168
|
+
},
|
|
3169
|
+
],
|
|
3170
|
+
payGoFee: '0',
|
|
3171
|
+
spendAmount: '20173228000',
|
|
3172
|
+
spendAmounts: [
|
|
3173
|
+
{
|
|
3174
|
+
amountString: '20173228000',
|
|
3175
|
+
coinName: 'sol:wif',
|
|
3176
|
+
},
|
|
3177
|
+
],
|
|
3178
|
+
type: 'Send',
|
|
3179
|
+
},
|
|
3180
|
+
consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
|
|
3181
|
+
coin: 'tsol',
|
|
3182
|
+
};
|
|
3183
|
+
const mockedWallet = {
|
|
3184
|
+
coinSpecific: () => {
|
|
3185
|
+
const cs = {
|
|
3186
|
+
rootAddress: '8rQXeVEMrKvtWCEJirEM6cKYnbZuTqVTbqRPiMMAJ8R4',
|
|
3187
|
+
};
|
|
3188
|
+
return cs;
|
|
3189
|
+
},
|
|
3190
|
+
};
|
|
3191
|
+
await assert_1.default.rejects(async () => basecoin.verifyTransaction({
|
|
3192
|
+
blockhash: '',
|
|
3193
|
+
feePayer: '',
|
|
3194
|
+
txParams: {},
|
|
3195
|
+
txPrebuild: consolidationTx,
|
|
3196
|
+
walletType: 'tss',
|
|
3197
|
+
wallet: mockedWallet,
|
|
3198
|
+
verification: {
|
|
3199
|
+
consolidationToBaseAddress: true,
|
|
3200
|
+
},
|
|
3201
|
+
}), {
|
|
3202
|
+
message: 'tx outputs does not match with expected address',
|
|
3203
|
+
});
|
|
3204
|
+
});
|
|
3205
|
+
});
|
|
3206
|
+
describe('blind signing token enablement protection', () => {
|
|
3207
|
+
it('should verify as valid the enabletoken intent when prebuild tx matchs user intent ', async function () {
|
|
3208
|
+
const { txParams, txPrebuildRaw, walletData } = testData.enableTokenFixtures;
|
|
3209
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
3210
|
+
const sameIntentTx = await basecoin.verifyTransaction({
|
|
3211
|
+
txParams,
|
|
3212
|
+
txPrebuild: txPrebuildRaw,
|
|
3213
|
+
wallet,
|
|
3214
|
+
verification: { verifyTokenEnablement: true },
|
|
3215
|
+
});
|
|
3216
|
+
sameIntentTx.should.equal(true);
|
|
3217
|
+
});
|
|
3218
|
+
it('should thrown an error when tampered prebuild tx type ', async function () {
|
|
3219
|
+
const { txParams, txPrebuildRaw, sendTxHex, walletData } = testData.enableTokenFixtures;
|
|
3220
|
+
const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: sendTxHex };
|
|
3221
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
3222
|
+
await assert_1.default.rejects(async () => await basecoin.verifyTransaction({
|
|
3223
|
+
txParams,
|
|
3224
|
+
txPrebuild: tamperedTxPrebuild,
|
|
3225
|
+
wallet,
|
|
3226
|
+
verification: { verifyTokenEnablement: true },
|
|
3227
|
+
}), {
|
|
3228
|
+
message: 'Invalid transaction type on token enablement: expected "AssociatedTokenAccountInitialization", got "Send".',
|
|
3229
|
+
});
|
|
3230
|
+
});
|
|
3231
|
+
it('should verify that tokenName matches between user intent and hex', async function () {
|
|
3232
|
+
const { txParams, txPrebuildRaw, wrongTokenNameTxHex, walletData } = testData.enableTokenFixtures;
|
|
3233
|
+
const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: wrongTokenNameTxHex };
|
|
3234
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
3235
|
+
await assert_1.default.rejects(async () => basecoin.verifyTransaction({
|
|
3236
|
+
txParams,
|
|
3237
|
+
txPrebuild: tamperedTxPrebuild,
|
|
3238
|
+
wallet,
|
|
3239
|
+
verification: { verifyTokenEnablement: true },
|
|
3240
|
+
}), { message: 'Invalid token name: expected tsol:ray, got tsol:t22mint on token enablement tx' });
|
|
3241
|
+
});
|
|
3242
|
+
it('should verify that tokenAddr matches between user intent and hex', async function () {
|
|
3243
|
+
const { txParams, txPrebuildRaw, wrongAddrTxHex, walletData } = testData.enableTokenFixtures;
|
|
3244
|
+
const tamperedTxPrebuild = { ...txPrebuildRaw, txHex: wrongAddrTxHex };
|
|
3245
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
3246
|
+
await assert_1.default.rejects(async () => basecoin.verifyTransaction({
|
|
3247
|
+
txParams,
|
|
3248
|
+
txPrebuild: tamperedTxPrebuild,
|
|
3249
|
+
wallet,
|
|
3250
|
+
verification: { verifyTokenEnablement: true },
|
|
3251
|
+
}), {
|
|
3252
|
+
message: 'Invalid token address: expected 4bTYvvv2Hk4v2kQW8HZFFS4SzYPztQshw9Gm1suXmaBj, got G1LEgANAwKo7b8NfxTsMzrbBYDkXqi5REVJY8thrMRQm on token enablement tx',
|
|
3253
|
+
});
|
|
3254
|
+
});
|
|
3255
|
+
it('should fail sendTokenEnablement call on spoofed data', async function () {
|
|
3256
|
+
const { sendTokenEnablementPayload, walletData, wrongTokenNameTxHex } = testData.enableTokenFixtures;
|
|
3257
|
+
const wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
3258
|
+
(0, nock_1.default)('https://bitgo.fakeurl').get('/api/v2/tsol/key/68bafed588671cf94ed8a5dbba882ad3').reply(200, {});
|
|
3259
|
+
await assert_1.default.rejects(async () => wallet.sendTokenEnablement({
|
|
3260
|
+
verification: { verifyTokenEnablement: true },
|
|
3261
|
+
...sendTokenEnablementPayload,
|
|
3262
|
+
prebuildTx: { ...sendTokenEnablementPayload.prebuildTx, txHex: wrongTokenNameTxHex },
|
|
3263
|
+
}), {
|
|
3264
|
+
message: 'Invalid token name: expected tsol:ray, got tsol:t22mint on token enablement tx',
|
|
3265
|
+
});
|
|
3266
|
+
});
|
|
3267
|
+
});
|
|
3268
|
+
describe('isWalletAddress', () => {
|
|
3269
|
+
it('should verify valid wallet address with correct keychain and index', async function () {
|
|
3270
|
+
const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
|
|
3271
|
+
const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
|
|
3272
|
+
const index = '1';
|
|
3273
|
+
const keychains = [{ id: '1', type: 'tss', commonKeychain }];
|
|
3274
|
+
const result = await basecoin.isWalletAddress({ keychains, address, index });
|
|
3275
|
+
result.should.equal(true);
|
|
3276
|
+
});
|
|
3277
|
+
it('should throw error for address with incorrect keychain', async function () {
|
|
3278
|
+
const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
|
|
3279
|
+
const wrongKeychain = '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
|
|
3280
|
+
const index = '1';
|
|
3281
|
+
const keychains = [{ id: '1', type: 'tss', commonKeychain: wrongKeychain }];
|
|
3282
|
+
await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address, index }), {
|
|
3283
|
+
message: `address validation failure: ${address} is not a wallet address`,
|
|
3284
|
+
});
|
|
3285
|
+
});
|
|
3286
|
+
it('should throw error for address with incorrect index', async function () {
|
|
3287
|
+
const address = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
|
|
3288
|
+
const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
|
|
3289
|
+
const wrongIndex = '999';
|
|
3290
|
+
const keychains = [{ id: '1', type: 'tss', commonKeychain }];
|
|
3291
|
+
await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address, index: wrongIndex }), {
|
|
3292
|
+
message: `address validation failure: ${address} is not a wallet address`,
|
|
3293
|
+
});
|
|
3294
|
+
});
|
|
3295
|
+
it('should throw error for invalid address', async function () {
|
|
3296
|
+
const invalidAddress = 'invalidaddress';
|
|
3297
|
+
const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
|
|
3298
|
+
const index = '1';
|
|
3299
|
+
const keychains = [{ id: '1', type: 'tss', commonKeychain }];
|
|
3300
|
+
await assert_1.default.rejects(async () => await basecoin.isWalletAddress({ keychains, address: invalidAddress, index }), {
|
|
3301
|
+
message: `invalid address: ${invalidAddress}`,
|
|
3302
|
+
});
|
|
3303
|
+
});
|
|
3304
|
+
it('should verify address with derivation prefix for SMC wallets', async function () {
|
|
3305
|
+
// Address derived with derivation prefix m/999999/148242355/239336845/1
|
|
3306
|
+
const address = 'CC715Q92C8vuEFT5xujE55Do6BkWRdpDvr7Vh8iUNUBw';
|
|
3307
|
+
const commonKeychain = '8ea32ecacfc83effbd2e2790ee44fa7c59b4d86c29a12f09fb613d8195f93f4e21875cad3b98adada40c040c54c3569467df41a020881a6184096378701862bd';
|
|
3308
|
+
const index = '1';
|
|
3309
|
+
const derivedFromParentWithSeed = 'smc-test-seed-123';
|
|
3310
|
+
const keychains = [{ id: '1', type: 'tss', commonKeychain }];
|
|
3311
|
+
// This test verifies that derivedFromParentWithSeed is accepted as a parameter
|
|
3312
|
+
// and the verification function correctly computes the derivation prefix internally
|
|
3313
|
+
const result = await basecoin.isWalletAddress({ keychains, address, index, derivedFromParentWithSeed });
|
|
3314
|
+
result.should.equal(true);
|
|
3315
|
+
});
|
|
3316
|
+
});
|
|
3317
|
+
describe('getAddressFromPublicKey', () => {
|
|
3318
|
+
it('should convert public key to base58 address', function () {
|
|
3319
|
+
const publicKey = '61220a9394802b1d1df37b35f7a3197970f48081092cee011fc98f7b71b2bd43';
|
|
3320
|
+
const expectedAddress = '7YAesfwPk41VChUgr65bm8FEep7ymWqLSW5rpYB5zZPY';
|
|
3321
|
+
const address = basecoin.getAddressFromPublicKey(publicKey);
|
|
3322
|
+
address.should.equal(expectedAddress);
|
|
3323
|
+
});
|
|
3324
|
+
});
|
|
3325
|
+
});
|
|
3326
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3NvbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QiwwQ0FBNEI7QUFDNUIsZ0RBQXdCO0FBQ3hCLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFFL0IsaURBQTBEO0FBRTFELGlEQUF3RDtBQUN4RCxtREFjOEI7QUFDOUIsbURBQStEO0FBQy9ELGlEQUE0QztBQUM1QyxtQ0FBd0c7QUFDeEcsdUNBQTRDO0FBRTVDLCtDQUF1RTtBQUN2RSwwREFBNEM7QUFDNUMsNERBQThDO0FBQzlDLDBEQUF1RDtBQUN2RCwyREFBd0Q7QUFFeEQsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQWEsQ0FBQztJQUNsQixJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksYUFBYSxDQUFDO0lBQ2xCLElBQUksMEJBQTBCLENBQUM7SUFDL0IsSUFBSSxXQUFXLENBQUM7SUFDaEIsSUFBSSxvQkFBb0IsQ0FBQztJQUN6QixJQUFJLHdCQUF3QixDQUFDO0lBQzdCLElBQUksd0JBQXdCLENBQUM7SUFDN0IsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztJQUMxRCxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQztJQUV6RCxNQUFNLE9BQU8sR0FBRztRQUNkLEdBQUcsRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLFNBQVM7UUFDeEMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLE1BQU07S0FDakQsQ0FBQztJQUNGLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLFVBQVUsRUFBRTtZQUNWO2dCQUNFLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixNQUFNLEVBQUUsTUFB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QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1RCxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuXG5pbXBvcnQgeyBUT0tFTl8yMDIyX1BST0dSQU1fSUQgfSBmcm9tICdAc29sYW5hL3NwbC10b2tlbic7XG5cbmltcG9ydCB7IEJpdEdvQVBJLCBlbmNyeXB0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQge1xuICBjb21tb24sXG4gIEVudmlyb25tZW50cyxcbiAgZ2VuZXJhdGVSYW5kb21QYXNzd29yZCxcbiAgSVdhbGxldCxcbiAgTVBDU3dlZXBUeHMsXG4gIE1QQ1R4LFxuICBNUENUeHMsXG4gIFByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVHNzVXRpbHMsXG4gIFR4UmVxdWVzdCxcbiAgV2FsbGV0LFxuICBXYWxsZXRDb2luU3BlY2lmaWMsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzLCBLZXlQYWlyLCBTb2wsIFNvbFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucywgVHNvbCB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWInO1xuaW1wb3J0IHsgQXRhSW5pdCwgSW5zdHJ1Y3Rpb25QYXJhbXMsIFRva2VuVHJhbnNmZXIgfSBmcm9tICcuLi8uLi9zcmMvbGliL2lmYWNlJztcbmltcG9ydCB7IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi9maXh0dXJlcy9zb2wnO1xuaW1wb3J0ICogYXMgcmVzb3VyY2VzIGZyb20gJy4uL3Jlc291cmNlcy9zb2wnO1xuaW1wb3J0IHsgc29sQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9zb2xCYWNrdXBLZXknO1xuaW1wb3J0IHsgZ2V0QnVpbGRlckZhY3RvcnkgfSBmcm9tICcuL2dldEJ1aWxkZXJGYWN0b3J5JztcblxuZGVzY3JpYmUoJ1NPTDonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW46IFNvbDtcbiAgbGV0IGtleVBhaXI7XG4gIGxldCBuZXdUeFByZWJ1aWxkO1xuICBsZXQgbmV3VHhQcmVidWlsZFRva2VuVHJhbnNmZXI7XG4gIGxldCBuZXdUeFBhcmFtcztcbiAgbGV0IG5ld1R4UGFyYW1zV2l0aEVycm9yO1xuICBsZXQgbmV3VHhQYXJhbXNXaXRoRXh0cmFEYXRhO1xuICBsZXQgbmV3VHhQYXJhbXNUb2tlblRyYW5zZmVyO1xuICBjb25zdCBiYWRBZGRyZXNzZXMgPSByZXNvdXJjZXMuYWRkcmVzc2VzLmludmFsaWRBZGRyZXNzZXM7XG4gIGNvbnN0IGdvb2RBZGRyZXNzZXMgPSByZXNvdXJjZXMuYWRkcmVzc2VzLnZhbGlkQWRkcmVzc2VzO1xuXG4gIGNvbnN0IGtleXBhaXIgPSB7XG4gICAgcHViOiByZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnB1YmxpY0tleSxcbiAgICBwcnY6IHJlc291cmNlcy5hY2NvdW50V2l0aFNlZWQucHJpdmF0ZUtleS5iYXNlNTgsXG4gIH07XG4gIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgcmVjaXBpZW50czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiAnbGlvbnRlc3RlMjEyJyxcbiAgICAgICAgYW1vdW50OiAnMTAwMCcsXG4gICAgICB9LFxuICAgIF0sXG4gICAgdHhCYXNlNjQ6IHJlc291cmNlcy5UUkFOU0ZFUl9VTlNJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0UsXG4gICAgdHhJbmZvOiB7XG4gICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgIG5vbmNlOiAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknLFxuICAgIH0sXG4gICAgdHhpZDogJzU4NmM1YjU5YjEwYjEzNGQwNGMxNmFjMWIyNzNmZTNjNTUyOWYzNGFlZjc1ZGI0NDU2Y2Q0NjljNWNkYWM3ZTInLFxuICAgIGlzVm90aW5nVHJhbnNhY3Rpb246IGZhbHNlLFxuICAgIGNvaW46ICd0c29sJyxcbiAgfTtcbiAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgdHhQcmVidWlsZCxcbiAgICByZWNpcGllbnRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIGNvbnN0IG1lbW8gPSB7IHZhbHVlOiAndGVzdCBtZW1vJyB9O1xuICBjb25zdCBkdXJhYmxlTm9uY2UgPSB7XG4gICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICB9O1xuICBjb25zdCBlcnJvckR1cmFibGVOb25jZSA9IHtcbiAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WU02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICB9O1xuICBjb25zdCB0eFBhcmFtc1dpdGhFcnJvciA9IHtcbiAgICB0eFByZWJ1aWxkLFxuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0Mm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbiAgY29uc3QgdHhQYXJhbXNXaXRoRXh0cmFEYXRhID0ge1xuICAgIHR4UHJlYnVpbGQsXG4gICAgcmVjaXBpZW50czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICBkYXRhOiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIGNvbnN0IHR4UHJlYnVpbGRUb2tlblRyYW5zZmVyID0ge1xuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ0FGNUg2dkJrRm5KdVZxQ2hSUGdQUTRKUmNRNUdrMjVIQkZoUVFreW9qbXZnJyxcbiAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICB9LFxuICAgIF0sXG4gICAgdHhIZXg6IHJlc291cmNlcy5UT0tFTl9UUkFOU0ZFUl9UT19OQVRJVkVfVU5TSUdORURfVFhfSEVYLFxuICAgIHR4SW5mbzoge1xuICAgICAgZmVlUGF5ZXI6ICc0RHVqeW1VRmJROEdCS3RBd0FaclE2UXFwdnRCRWl2TDQ4aDR0YTJvSkdkMicsXG4gICAgICBub25jZTogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICB9LFxuICAgIHR4aWQ6ICc1ODZjNWI1OWIxMGIxMzRkMDRjMTZhYzFiMjczZmUzYzU1MjlmMzRhZWY3NWRiNDQ1NmNkNDY5YzVjZGFjN2UyJyxcbiAgICBpc1ZvdGluZ1RyYW5zYWN0aW9uOiBmYWxzZSxcbiAgICBjb2luOiAndHNvbCcsXG4gIH07XG4gIGNvbnN0IHR4UGFyYW1zVG9rZW5UcmFuc2ZlciA9IHtcbiAgICB0eFByZWJ1aWxkLFxuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ0FGNUg2dkJrRm5KdVZxQ2hSUGdQUTRKUmNRNUdrMjVIQkZoUVFreW9qbXZnJyxcbiAgICAgICAgYW1vdW50OiAnMScsXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG4gIGNvbnN0IGVycm9yTWVtbyA9IHsgdmFsdWU6ICdkaWZmZXJlbnQgbWVtbycgfTtcbiAgY29uc3QgZXJyb3JGZWVQYXllciA9ICc1aHI1ZmlzUGk2RFhDdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZSc7XG4gIGNvbnN0IGZhY3RvcnkgPSBnZXRCdWlsZGVyRmFjdG9yeSgndHNvbCcpO1xuICBjb25zdCB3YWxsZXQgPSBuZXcgS2V5UGFpcihyZXNvdXJjZXMuYXV0aEFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3Qgc3Rha2VBY2NvdW50ID0gbmV3IEtleVBhaXIocmVzb3VyY2VzLnN0YWtlQWNjb3VudCkuZ2V0S2V5cygpO1xuICBjb25zdCBibG9ja0hhc2ggPSByZXNvdXJjZXMuYmxvY2tIYXNoZXMudmFsaWRCbG9ja0hhc2hlc1swXTtcbiAgY29uc3QgYW1vdW50ID0gJzEwMDAwJztcbiAgY29uc3QgdmFsaWRhdG9yID0gcmVzb3VyY2VzLnZhbGlkYXRvcjtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3Rlcignc29sJywgVHNvbC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0c29sJywgVHNvbC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0c29sJykgYXMgVHNvbDtcbiAgICBrZXlQYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHJlc291cmNlcy5hY2NvdW50V2l0aFNlZWQuc2VlZCk7XG4gICAgbmV3VHhQcmVidWlsZCA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFByZWJ1aWxkKTtcbiAgICB9O1xuICAgIG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UHJlYnVpbGRUb2tlblRyYW5zZmVyKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UGFyYW1zKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zV2l0aEVycm9yID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UGFyYW1zV2l0aEVycm9yKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zV2l0aEV4dHJhRGF0YSA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFBhcmFtc1dpdGhFeHRyYURhdGEpO1xuICAgIH07XG4gICAgbmV3VHhQYXJhbXNUb2tlblRyYW5zZmVyID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UGFyYW1zVG9rZW5UcmFuc2Zlcik7XG4gICAgfTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBpbnN0YW50aWF0ZSB0aGUgY29pbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgbG9jYWxCYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICBsb2NhbEJhc2Vjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKFRzb2wpO1xuXG4gICAgbG9jYWxCYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3NvbCcpO1xuICAgIGxvY2FsQmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoU29sKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1biB0aGUgcmlnaHQgaW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgICBiYXNlY29pbi5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCgndHNvbCcpO1xuICAgIGJhc2Vjb2luLmdldEZhbWlseSgpLnNob3VsZC5lcXVhbCgnc29sJyk7XG4gICAgYmFzZWNvaW4uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1Rlc3RuZXQgU29sYW5hJyk7XG4gICAgYmFzZWNvaW4uZ2V0QmFzZUZhY3RvcigpLnNob3VsZC5lcXVhbCgxMDAwMDAwMDAwKTtcbiAgfSk7XG4gIGRlc2NyaWJlKCd2ZXJpZnkgdHJhbnNhY3Rpb25zJywgKCkgPT4ge1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgcm9vdEFkZHJlc3M6IHdhbGxldC5wdWIsXG4gICAgICB9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICB9O1xuICAgIGNvbnN0IHdhbGxldE9iaiA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgZHVyYWJsZU5vbmNlLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgY29uc29saWRhdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC5jb25zb2xpZGF0ZUlkID0gJ2NvbnNvbGlkYXRlSWQnO1xuXG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHdhbGxldFdpdGhEaWZmZXJlbnRBZGRyZXNzID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgZHVyYWJsZU5vbmNlLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldFdpdGhEaWZmZXJlbnRBZGRyZXNzLFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgdHhCYXNlNjQgYW5kIHR4SGV4IGludGVyY2hhbmdlYWJseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICB0eFByZWJ1aWxkLnR4SGV4ID0gdHhQcmVidWlsZC50eEJhc2U2NDtcbiAgICAgIHR4UHJlYnVpbGQudHhCYXNlNjQgPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgZHVyYWJsZU5vbmNlLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHNlcmlhbGl6ZWQgaGV4IHN0cmluZyB0byBiYXNlNjQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC50eEJhc2U2NCA9IEJ1ZmZlci5mcm9tKHR4UHJlYnVpbGQudHhCYXNlNjQsICdiYXNlNjQnKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgZHVyYWJsZU5vbmNlLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgd2hlbiBpbnB1dCBgcmVjaXBpZW50c2AgaXMgYWJzZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgZHVyYWJsZU5vbmNlLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHZlcmlmeSB0cmFuc2FjdGlvbnMgd2hlbiBoYXZlIGRpZmZlcmVudCBtZW1vJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCBtZW1vOiBlcnJvck1lbW8sIHdhbGxldDogd2FsbGV0T2JqIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVHggbWVtbyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudCBtZW1vJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3MgaWYgd2UgcGFzcyBQREEgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICAgIGlkOiAnNjdmOGRkZmY0YzliOGI1N2EyZTE2YWNmZmFjOWEzYjUnLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgICAgXSxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICc4emJzSkE1YzhIUFI3QlBqWmtyU1ZydXMydU11WHFDZnprc0d3QjNVc2NqYicsXG4gICAgICAgIH0sXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICB9O1xuICAgICAgY29uc3Qgd2FsbGV0T2JqID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMicsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgdHhCYXNlNjQ6XG4gICAgICAgICAgJzAyMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2ZWMxYWRjYzg5YmI1NjRmMWY4MjI1ODIxMTQwYTk3MjNlZmE4MGU4ZDUwNjc2NTc3MGI3ZTIwMWQ2NmQ4MjAwZDRmNjkwZTlhODE2MzI5MWI2OWY4YzM4MjdhYWQ5NmNmZDIxMDVlZWUzYWFlNzZjYmNhMzhmY2FkMmJmN2YwYTAyMDEwNzBjNzZjMzU2Y2IwNjliNjZjMmIzNWE4NjM4YjRkNGFmY2E3NWIzMDNmMjlmMGRlZWI0YmZmODUyODI5OWE5YzlkMjFjOTYxNzIwNDRmMTIxN2MzNzg0ZThmMDJmNDllMmM4ZmMzNTkxZTgxMjk0YWI1NDM5NGY5ZDIyZmQ3YjdhOGY2MDEyOWU2ZWNiMjAzMDljMjdkY2JhNWZjNmM0NDE0MzhkMzNhMTU2ODAwNGExODYwZTIyYzE2ZjA3MTk3NmE3ZDJlMjAwOGJkMzRiNTNhMDhhYTljOGVjMDRlYjIxOTY3NDVmYzYwMjkyMjQ0NDc0MTdlMmZiMGZjZWQ2MDEyNDBjYWJiYTRjZTUzNGMwMmZjMTU0YmE1NTllZDJhMDJhYzk3MWUzMzg1YWNiNDI2ZmY2M2JiMTA0MGUyYzI0MzUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMThjOTcyNThmNGUyNDg5ZjFiYjNkMTAyOTE0OGUwZDgzMGI1YTEzOTlkYWZmMTA4NDA0OGU3YmQ4ZGJlOWY4NTlkMTAzODlmYmNlZTUyOGYyMDg2MTFkY2NjNzM0YjMxMDkyNTQwY2IyYjhkNThkMTAwZjJlYWEyY2VkYjRkYTVlMDZhN2Q1MTcxOTJjNTY4ZWUwOGE4NDVmNzNkMjk3ODhjZjAzNWMzMTQ1YjIxYWIzNDRkODA2MmVhOTQwMDAwMDA2YTdkNTE3MTkyYzVjNTEyMThjYzk0YzNkNGFmMTdmNThkYWVlMDg5YmExZmQ0NGUzZGJkOThhMDAwMDAwMDAwNmRkZjZlMWQ3NjVhMTkzZDljYmUxNDZjZWViNzlhYzFjYjQ4NWVkNWY1YjM3OTEzYThjZjU4NTdlZmYwMGE5ZTY4MDYzNDUzMzg4MmY4ODBhM2U3ZGZhOTk5ZGZiODY0Yjg4OTY4ZDI0MmEwYzlhOTBiNWRmMTQ5ZTQyZGEwNTAzMDUwMzAyMDkwMTA0MDQwMDAwMDAwNzA3MDAwMzA2MDgwNTBiMGEwMDBiMDQwNDA4MDMwMDBhMGMwMGNhOWEzYjAwMDAwMDAwMDknLFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBmZWVQYXllcjogJzh6YnNKQTVjOEhQUjdCUGpaa3JTVnJ1czJ1TXVYcUNmemtzR3dCM1VzY2piJyxcbiAgICAgICAgICBub25jZTogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHhpZDogJzU4NmM1YjU5YjEwYjEzNGQwNGMxNmFjMWIyNzNmZTNjNTUyOWYzNGFlZjc1ZGI0NDU2Y2Q0NjljNWNkYWM3ZTInLFxuICAgICAgICBpc1ZvdGluZ1RyYW5zYWN0aW9uOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEyJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAnLFxuICAgICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1lbW8gPSB7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZ5VHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBtZW1vOiBtZW1vLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZlcmlmeVRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gaGF2ZSBkaWZmZXJlbnQgZHVyYWJsZU5vbmNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCBtZW1vLCBkdXJhYmxlTm9uY2U6IGVycm9yRHVyYWJsZU5vbmNlLCB3YWxsZXQ6IHdhbGxldE9iaiB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IGR1cmFibGVOb25jZSBkb2VzIG5vdCBtYXRjaCB3aXRoIHBhcmFtIGR1cmFibGVOb25jZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHZlcmlmeSB0cmFuc2FjdGlvbnMgd2hlbiBoYXZlIGRpZmZlcmVudCBmZWVQYXllcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiBzdGFrZUFjY291bnQucHViLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHdhbGxldFdpdGhEaWZmZXJlbnRBZGRyZXNzID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgbWVtbywgd2FsbGV0OiB3YWxsZXRXaXRoRGlmZmVyZW50QWRkcmVzcyB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1R4IGZlZSBwYXllciBpcyBub3QgdGhlIHdhbGxldCByb290IGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gaGF2ZSBkaWZmZXJlbnQgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXNXaXRoRXJyb3IoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgbWVtbywgZXJyb3JGZWVQYXllciwgd2FsbGV0OiB3YWxsZXRPYmogfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdUeCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdHhQYXJhbXMgcmVjaXBpZW50cycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0b2tlbiB0cmFuc2FjdGlvbiB3aXRoIG5hdGl2ZSBhZGRyZXNzIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXNUb2tlblRyYW5zZmVyKCk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ0FGNUg2dkJrRm5KdVZxQ2hSUGdQUTRKUmNRNUdrMjVIQkZoUVFreW9qbXZnJzsgLy8gTmF0aXZlIFNPTCBhZGRyZXNzXG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gW3sgYWRkcmVzcywgYW1vdW50OiAnMScsIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycgfV07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZFRva2VuVHJhbnNmZXIoKTtcbiAgICAgIGNvbnN0IGZlZVBheWVyV2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogJzREdWp5bVVGYlE4R0JLdEF3QVpyUTZRcXB2dEJFaXZMNDhoNHRhMm9KR2QyJyxcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBmZWVQYXllcldhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCBmZWVQYXllcldhbGxldERhdGEpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHdhbGxldDogZmVlUGF5ZXJXYWxsZXQsXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBsZWFkaW5nIHplcm8gcmVjaXBpZW50IGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXNUb2tlblRyYW5zZmVyKCk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ0FGNUg2dkJrRm5KdVZxQ2hSUGdQUTRKUmNRNUdrMjVIQkZoUVFreW9qbXZnJzsgLy8gTmF0aXZlIFNPTCBhZGRyZXNzXG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gW3sgYWRkcmVzcywgYW1vdW50OiAnMDAwMScsIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycgfV07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZFRva2VuVHJhbnNmZXIoKTtcbiAgICAgIGNvbnN0IGZlZVBheWVyV2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczogJzREdWp5bVVGYlE4R0JLdEF3QVpyUTZRcXB2dEJFaXZMNDhoNHRhMm9KR2QyJyxcbiAgICAgICAgfSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBmZWVQYXllcldhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCBmZWVQYXllcldhbGxldERhdGEpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHdhbGxldDogZmVlUGF5ZXJXYWxsZXQsXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBkaWZmZXJlbnQgcmVjaXBpZW50IHRva2VuTmFtZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXNUb2tlblRyYW5zZmVyKCk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ0FGNUg2dkJrRm5KdVZxQ2hSUGdQUTRKUmNRNUdrMjVIQkZoUVFreW9qbXZnJzsgLy8gTmF0aXZlIFNPTCBhZGRyZXNzXG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gW3sgYWRkcmVzcywgYW1vdW50OiAnMScsIHRva2VuTmFtZTogJ3Rzb2w6dXNkdCcgfV07IC8vIERpZmZlcmVudCB0b2tlbk5hbWUsIHNob3VsZCBmYWlsIHRvIHZlcmlmeSB0eFxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBkaWZmZXJlbnQgcmVjaXBpZW50IGFtb3VudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12Zyc7IC8vIE5hdGl2ZSBTT0wgYWRkcmVzc1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFt7IGFkZHJlc3MsIGFtb3VudDogJzInLCB0b2tlbk5hbWU6ICd0c29sOnVzZHQnIH1dO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdG9rZW4gdHJhbnNhY3Rpb24gd2l0aCBkaWZmZXJlbnQgbmF0aXZlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zVG9rZW5UcmFuc2ZlcigpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdBRjVINnZCa0ZuSnVWcUNoUlBnUFE0SlJjUTVHazI1SEJGaFFRa3lvam12WCc7IC8vIE5hdGl2ZSBTT0wgYWRkcmVzcywgZGlmZmVyZW50IHRoYW4gdHggcmVjaXBpZW50c1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFt7IGFkZHJlc3MsIGFtb3VudDogJzEnLCB0b2tlbk5hbWU6ICd0c29sOnVzZGMnIH1dO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGRUb2tlblRyYW5zZmVyKCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICAgIH0gYXMgYW55KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gcmVjaXBpZW50cyBoYXMgZXh0cmEgZGF0YScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXNXaXRoRXh0cmFEYXRhKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIGR1cmFibGVOb25jZSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFjdGl2YXRlIHN0YWtpbmcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdBY3RpdmF0ZUJ1aWxkZXIoKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnZhbGlkYXRvcih2YWxpZGF0b3IucHViKVxuICAgICAgICAubWVtbygndGVzdCBtZW1vJylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4VG9Ccm9hZGNhc3RGb3JtYXQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIHR4UHJlYnVpbGQudHhCYXNlNjQgPSB0eFRvQnJvYWRjYXN0Rm9ybWF0O1xuICAgICAgdHhQcmVidWlsZC50eEluZm8ubm9uY2UgPSAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nO1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICc3ZFJ1R0ZiVTJ5MmtpalA2bzFMWU56Vnl6NHlmMTNNb29xb2lvbkN6djVaYScsXG4gICAgICAgICAgYW1vdW50OiBhbW91bnQsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB3aXRoZHJhdyBzdGFraW5nIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRTdGFraW5nV2l0aGRyYXdCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgdHhQcmVidWlsZC50eEJhc2U2NCA9IHR4VG9Ccm9hZGNhc3RGb3JtYXQ7XG4gICAgICB0eFByZWJ1aWxkLnR4SW5mby5ub25jZSA9ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbic7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICBhbW91bnQ6IGFtb3VudCxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgbWVtbyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXRPYmosXG4gICAgICB9IGFzIGFueSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGRlYWN0aXZhdGUgc3Rha2luZyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICB0eFByZWJ1aWxkLnR4QmFzZTY0ID0gdHhUb0Jyb2FkY2FzdEZvcm1hdDtcbiAgICAgIHR4UHJlYnVpbGQudHhJbmZvLm5vbmNlID0gJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJztcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSBbXTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICBtZW1vLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldE9iaixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgY3JlYXRlIGFzc29jaWF0ZWQgdG9rZW4gYWNjb3VudCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0QXRhSW5pdGlhbGl6YXRpb25CdWlsZGVyKClcbiAgICAgICAgLm1pbnQoJ3Rzb2w6dXNkYycpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG4gICAgICB0eFByZWJ1aWxkLnR4QmFzZTY0ID0gdHhUb0Jyb2FkY2FzdEZvcm1hdDtcbiAgICAgIHR4UHJlYnVpbGQudHhJbmZvLm5vbmNlID0gYmxvY2tIYXNoO1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IFtdO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIG1lbW8sXG4gICAgICAgIHdhbGxldDogd2FsbGV0T2JqLFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcycsICgpID0+IHtcbiAgICBsZXQgb3JpZ2luYWxBcmNoOiBzdHJpbmc7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIG9yaWdpbmFsQXJjaCA9IHByb2Nlc3MuYXJjaDtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiBvcmlnaW5hbEFyY2gsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGFtb3VudCB1bmNoYW5nZWQgb24gbm9uLXMzOTB4IGFyY2hpdGVjdHVyZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiAneDY0JyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnMzAwMDAwJykuc2hvdWxkLmVxdWFsKCczMDAwMDAnKTtcbiAgICAgIGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKCcxMDAwMCcpLnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKCc1MDQ0MDMxNTgyNjU0OTU1NTInKS5zaG91bGQuZXF1YWwoJzUwNDQwMzE1ODI2NTQ5NTU1MicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBieXRlLXN3YXAgc21hbGwgYW1vdW50cyBvbiBzMzkweCAoc21hbGwgYmVjb21lcyBodWdlKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9jZXNzLCAnYXJjaCcsIHtcbiAgICAgICAgdmFsdWU6ICdzMzkweCcsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgLy8gU21hbGwgYW1vdW50IDEwLDAwMCAoMHgyNzEwKSBzd2FwcyB0byAxLDE2Myw4OTksMDI4LDY5OCw1NjIsNTYwXG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnMTAwMDAnKS5zaG91bGQuZXF1YWwoJzExNjM4OTkwMjg2OTg1NjI1NjAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnl0ZS1zd2FwIGxhcmdlIGFtb3VudHMgb24gczM5MHggKGxhcmdlIGJlY29tZXMgdGlueSknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiAnczM5MHgnLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIExhcmdlIGFtb3VudCA1MDQsNDAzLDE1OCwyNjUsNDk1LDU1MiAoMHgwNzAwMDAwMDAwMDAwMDAwKSBzd2FwcyB0byA3XG4gICAgICBnZXRBbW91bnRCYXNlZE9uRW5kaWFubmVzcygnNTA0NDAzMTU4MjY1NDk1NTUyJykuc2hvdWxkLmVxdWFsKCc3Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBudW1lcmljIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb2Nlc3MsICdhcmNoJywge1xuICAgICAgICB2YWx1ZTogJ3MzOTB4JyxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTaG91bGQgd29yayB3aXRoIG51bWJlcnMsIG5vdCBqdXN0IHN0cmluZ3NcbiAgICAgIGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKDEwMDAwKS5zaG91bGQuZXF1YWwoJzExNjM4OTkwMjg2OTg1NjI1NjAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHN0YW5kYXJkIHRyYW5zYWN0aW9uIGFtb3VudHMgb24gczM5MHgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvY2VzcywgJ2FyY2gnLCB7XG4gICAgICAgIHZhbHVlOiAnczM5MHgnLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFN0YW5kYXJkIGFtb3VudCAzMDAsMDAwICgweDQ5M0UwKSBzd2FwcyB0byBsYXJnZSB2YWx1ZVxuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0QW1vdW50QmFzZWRPbkVuZGlhbm5lc3MoJzMwMDAwMCcpO1xuICAgICAgLy8gVmVyaWZ5IGl0J3MgZGlmZmVyZW50IChzd2FwcGVkKVxuICAgICAgcmVzdWx0LnNob3VsZC5ub3QuZXF1YWwoJzMwMDAwMCcpO1xuICAgICAgLy8gVmVyaWZ5IHN3YXBwaW5nIGJhY2sgZ2l2ZXMgb3JpZ2luYWxcbiAgICAgIGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKHJlc3VsdCkuc2hvdWxkLmVxdWFsKCczMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGludmFsaWQgaW5wdXQgZ3JhY2VmdWxseScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9jZXNzLCAnYXJjaCcsIHtcbiAgICAgICAgdmFsdWU6ICdzMzkweCcsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB9KTtcblxuICAgICAgLy8gSW52YWxpZCBCaWdJbnQgaW5wdXQgc2hvdWxkIHJldHVybiBvcmlnaW5hbCBzdHJpbmdcbiAgICAgIGdldEFtb3VudEJhc2VkT25FbmRpYW5uZXNzKCdub3QtYS1udW1iZXInKS5zaG91bGQuZXF1YWwoJ25vdC1hLW51bWJlcicpO1xuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGFjY2VwdCB2YWxpZCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGdvb2RBZGRyZXNzZXMuZm9yRWFjaCgoYWRkcikgPT4ge1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHJlamVjdCBpbnZhbGlkIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmFkQWRkcmVzc2VzLmZvckVhY2goKGFkZHIpID0+IHtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHIpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY2hlY2sgdmFsaWQgcHViIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAga2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHViJyk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrZXlQYWlyLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNoZWNrIGFuIGludmFsaWQgcHViIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFkUHViS2V5ID0ga2V5UGFpci5wdWIuc2xpY2UoMCwga2V5UGFpci5wdWIubGVuZ3RoIC0gMSkgKyAnLSc7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFB1YihiYWRQdWJLZXkpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY2hlY2sgdmFsaWQgcHJ2IGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAga2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFBydihrZXlQYWlyLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGNoZWNrIGFuIGludmFsaWQgcHJ2IGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFkUHJ2S2V5ID0ga2V5UGFpci5wcnYgPyBrZXlQYWlyLnBydi5zbGljZSgwLCBrZXlQYWlyLnBydi5sZW5ndGggLSAxKSArICctJyA6IHVuZGVmaW5lZDtcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGJhZFBydktleSBhcyBzdHJpbmcpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQYXJzZSBUcmFuc2FjdGlvbnM6JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcGFyc2UgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6IDMwNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgICBhbW91bnQ6IDMwNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhbiB1bnNpZ25lZCB3YWxsZXQgaW5pdCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMud2FsbGV0SW5pdC51bnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICAgICAgYW1vdW50OiAzMTAwMDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYSBzaWduZWQgd2FsbGV0IGluaXQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLndhbGxldEluaXQuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhbW91bnQ6IDMxMDAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhbiB1bnNpZ25lZCB0cmFuc2ZlciB0b2tlbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXJUb2tlbi51bnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiA1MDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHNpZ25lZCB0cmFuc2ZlciB0b2tlbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXJUb2tlbi5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogNTAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0V4cGxhaW4gVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICAgIHZhbHVlOiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICB9LFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnMlhGeEdmWGRkS1ducUdhTUFzZk5MOEhnWHFEdmpCTDJBZTI4S1dyUnZnOWJRQm1DcnBIWVZEYWN1WkZlQVV5WXdqWEc2ZXkyalRBUlg1VlFDbmo3U0Y0TCcsXG4gICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICAgIHZhbHVlOiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICB9LFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgd2FsbGV0IGluaXQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMud2FsbGV0SW5pdC51bnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnV2FsbGV0SW5pdGlhbGl6YXRpb24nLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdmFsdWU6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZVBheWVyOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICcxMDAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgYmxvY2toYXNoOiAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbWVtbzogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgd2FsbGV0IGluaXQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMud2FsbGV0SW5pdC5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJzdUa1U4d0xnWERlTEZiVnlkdGc2bXFNc3A5R2F0c2V0aXRTbmd5c2dqeEZob2ZLU1VjTFBCb0tQSGNpTGVHRWZKRk1zcWV6cFptR1JTRlFUQnk3WkRzZycsXG4gICAgICAgIHR5cGU6ICdXYWxsZXRJbml0aWFsaXphdGlvbicsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgICB2YWx1ZTogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzEwMDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICBtZW1vOiB1bmRlZmluZWQsXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtdLFxuICAgICAgICBhdGFPd25lck1hcDoge30sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0b2tlbiB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy50cmFuc2ZlclRva2VuLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzEyZjZEM1d1YkdWZVFvSDJtOGtUdnZjcmFzV2RYV3d0VnpVQ3lSTkRaeEEyJyxcbiAgICAgICAgICAgIHZhbHVlOiAnMzAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzEyZjZEM1d1YkdWZVFvSDJtOGtUdnZjcmFzV2RYV3d0VnpVQ3lSTkRaeEEyJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6ICcxMmY2RDNXdWJHVmVRb0gybThrVHZ2Y3Jhc1dkWFd3dFZ6VUN5Uk5EWnhBMicsXG4gICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiAnOFk3Uk02SmZjWDRBU1NOQmtya3JtU2JSdTQzMVlWaTlZM29MRm56QzJkQ2gnLFxuICAgICAgICB9LFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHt9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdG9rZW4gdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXJUb2tlbi5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICcydGljVTRaa0VxZFRIVUxyNkxvYlRnV0JoaW02RTd3U3NjRGhNNGd6eXVHVW1ReVV3TFlob3FhaWZ1dndtTnp6RWYxVDVhZWZWY2dNUWtTSGRKNW5zcmZaJyxcbiAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxMmY2RDNXdWJHVmVRb0gybThrVHZ2Y3Jhc1dkWFd3dFZ6VUN5Uk5EWnhBMicsXG4gICAgICAgICAgICB2YWx1ZTogJzMwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICcxMmY2RDNXdWJHVmVRb0gybThrVHZ2Y3Jhc1dkWFd3dFZ6VUN5Uk5EWnhBMicsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiAnMTJmNkQzV3ViR1ZlUW9IMm04a1R2dmNyYXNXZFhXd3RWelVDeVJORFp4QTInLFxuICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFjdGl2YXRlIHN0YWtpbmcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGZhY3RvcnlcbiAgICAgICAgLmdldFN0YWtpbmdBY3RpdmF0ZUJ1aWxkZXIoKVxuICAgICAgICAuc3Rha2luZ0FkZHJlc3Moc3Rha2VBY2NvdW50LnB1YilcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnZhbGlkYXRvcih2YWxpZGF0b3IucHViKVxuICAgICAgICAubWVtbygndGVzdCBtZW1vJylcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4VG9Ccm9hZGNhc3RGb3JtYXQgPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdHhUb0Jyb2FkY2FzdEZvcm1hdCxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogJzUwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1N0YWtpbmdBY3RpdmF0ZScsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMTAwMDAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzdkUnVHRmJVMnkya2lqUDZvMUxZTnpWeXo0eWYxM01vb3FvaW9uQ3p2NVphJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgdmFsdWU6ICcxMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzEwMDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiAndGVzdCBtZW1vJyxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW10sXG4gICAgICAgIGF0YU93bmVyTWFwOiB7fSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGRlYWN0aXZhdGUgc3Rha2luZyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0U3Rha2luZ0RlYWN0aXZhdGVCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4VG9Ccm9hZGNhc3RGb3JtYXQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdTdGFraW5nRGVhY3RpdmF0ZScsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtdLFxuICAgICAgICBpbnB1dHM6IFtdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtdLFxuICAgICAgICBhdGFPd25lck1hcDoge30sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiB3aXRoZHJhdyBzdGFraW5nIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRTdGFraW5nV2l0aGRyYXdCdWlsZGVyKClcbiAgICAgICAgLnN0YWtpbmdBZGRyZXNzKHN0YWtlQWNjb3VudC5wdWIpXG4gICAgICAgIC5zZW5kZXIod2FsbGV0LnB1YilcbiAgICAgICAgLm5vbmNlKGJsb2NrSGFzaClcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0eFRvQnJvYWRjYXN0Rm9ybWF0LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnU3Rha2luZ1dpdGhkcmF3JyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcxMDAwMCcsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc3ZFJ1R0ZiVTJ5MmtpalA2bzFMWU56Vnl6NHlmMTNNb29xb2lvbkN6djVaYScsXG4gICAgICAgICAgICB2YWx1ZTogJzEwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBmZWVQYXllcjogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgICAgZmVlUmF0ZTogNTAwMCxcbiAgICAgICAgfSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgbWVtbycsXG4gICAgICAgIGJsb2NraGFzaDogJzVuZTdwaEE0OEpydnBuMzlBdHVwQjhaa0NDQXk4Z0xUZnBHaWhaUHVEcWVuJyxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgIHRva2VuRW5hYmxlbWVudHM6IFtdLFxuICAgICAgICBhdGFPd25lck1hcDoge30sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBjcmVhdGUgQVRBIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9rZW5OYW1lID0gJ3Rzb2w6dXNkYyc7XG4gICAgICBjb25zdCByZW50RXhlbXB0QW1vdW50ID0gJzMwMDAwMDAnO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5XG4gICAgICAgIC5nZXRBdGFJbml0aWFsaXphdGlvbkJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKHdhbGxldC5wdWIpXG4gICAgICAgIC5ub25jZShibG9ja0hhc2gpXG4gICAgICAgIC5taW50KHRva2VuTmFtZSlcbiAgICAgICAgLnJlbnRFeGVtcHRBbW91bnQocmVudEV4ZW1wdEFtb3VudClcbiAgICAgICAgLm1lbW8oJ3Rlc3QgbWVtbycpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eFRvQnJvYWRjYXN0Rm9ybWF0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4VG9Ccm9hZGNhc3RGb3JtYXQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5BY2NvdW50UmVudEV4ZW1wdEFtb3VudDogcmVudEV4ZW1wdEFtb3VudCxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogW1xuICAgICAgICAgICdpZCcsXG4gICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICdibG9ja2hhc2gnLFxuICAgICAgICAgICdkdXJhYmxlTm9uY2UnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ3Rva2VuRW5hYmxlbWVudHMnLFxuICAgICAgICAgICdmZWUnLFxuICAgICAgICAgICdtZW1vJyxcbiAgICAgICAgXSxcbiAgICAgICAgaWQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgIHR5cGU6ICdBc3NvY2lhdGVkVG9rZW5BY2NvdW50SW5pdGlhbGl6YXRpb24nLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgICAgaW5wdXRzOiBbXSxcbiAgICAgICAgZmVlUGF5ZXI6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgIGZlZToge1xuICAgICAgICAgIGZlZTogJzMwMDUwMDAnLFxuICAgICAgICAgIGZlZVJhdGU6IDUwMDAsXG4gICAgICAgIH0sXG4gICAgICAgIG1lbW86ICd0ZXN0IG1lbW8nLFxuICAgICAgICBibG9ja2hhc2g6ICc1bmU3cGhBNDhKcnZwbjM5QXR1cEI4WmtDQ0F5OGdMVGZwR2loWlB1RHFlbicsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzE0MUJGTmVtM3BrbmM4Q3pQVkx2MVJpM2J0Z0tkQ3NhZllQNW5Yd21YZnhVJyxcbiAgICAgICAgICAgIHRva2VuQWRkcmVzczogJ0Y0dUxlWEpvRnozaHcxM01wb3N1d2FRYk1jWmJDanF2RUdQUGVSUkIxQnlmJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHtcbiAgICAgICAgICAnMTQxQkZOZW0zcGtuYzhDelBWTHYxUmkzYnRnS2RDc2FmWVA1blh3bVhmeFUnOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gY3JlYXRlIG11bHRpIEFUQSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBvd25lckFkZHJlc3M6IHdhbGxldC5wdWIsXG4gICAgICAgICAgdG9rZW5OYW1lOiAndHNvbDp1c2RjJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG93bmVyQWRkcmVzczogZHVyYWJsZU5vbmNlLndhbGxldE5vbmNlQWRkcmVzcyxcbiAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnJheScsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgcmVudEV4ZW1wdEFtb3VudCA9ICczMDAwMDAwJztcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgZmFjdG9yeVxuICAgICAgICAuZ2V0QXRhSW5pdGlhbGl6YXRpb25CdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcih3YWxsZXQucHViKVxuICAgICAgICAubm9uY2UoYmxvY2tIYXNoKVxuICAgICAgICAuZW5hYmxlVG9rZW4ocmVjaXBpZW50c1swXSlcbiAgICAgICAgLmVuYWJsZVRva2VuKHJlY2lwaWVudHNbMV0pXG4gICAgICAgIC5yZW50RXhlbXB0QW1vdW50KHJlbnRFeGVtcHRBbW91bnQpXG4gICAgICAgIC5tZW1vKCd0ZXN0IG1lbW8nKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5idWlsZCgpO1xuICAgICAgY29uc3QgdHhUb0Jyb2FkY2FzdEZvcm1hdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4QmFzZTY0OiB0eFRvQnJvYWRjYXN0Rm9ybWF0LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAnNTAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuQWNjb3VudFJlbnRFeGVtcHRBbW91bnQ6IHJlbnRFeGVtcHRBbW91bnQsXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAnYmxvY2toYXNoJyxcbiAgICAgICAgICAnZHVyYWJsZU5vbmNlJyxcbiAgICAgICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgICAnb3V0cHV0cycsXG4gICAgICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgICAgICd0b2tlbkVuYWJsZW1lbnRzJyxcbiAgICAgICAgICAnZmVlJyxcbiAgICAgICAgICAnbWVtbycsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICB0eXBlOiAnQXNzb2NpYXRlZFRva2VuQWNjb3VudEluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICAgIGlucHV0czogW10sXG4gICAgICAgIGZlZVBheWVyOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6ICc2MDA1MDAwJyxcbiAgICAgICAgICBmZWVSYXRlOiA1MDAwLFxuICAgICAgICB9LFxuICAgICAgICBtZW1vOiAndGVzdCBtZW1vJyxcbiAgICAgICAgYmxvY2toYXNoOiAnNW5lN3BoQTQ4SnJ2cG4zOUF0dXBCOFprQ0NBeThnTFRmcEdpaFpQdURxZW4nLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgdG9rZW5FbmFibGVtZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcxNDFCRk5lbTNwa25jOEN6UFZMdjFSaTNidGdLZENzYWZZUDVuWHdtWGZ4VScsXG4gICAgICAgICAgICB0b2tlbkFkZHJlc3M6ICdGNHVMZVhKb0Z6M2h3MTNNcG9zdXdhUWJNY1piQ2pxdkVHUFBlUlJCMUJ5ZicsXG4gICAgICAgICAgICB0b2tlbk5hbWU6ICd0c29sOnVzZGMnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzlLYUxpblpGTlc1Y2hMNEo4VW9LblRFQ3BwV1ZNejNld2d4NEZBa3hVRGNmJyxcbiAgICAgICAgICAgIHRva2VuQWRkcmVzczogJzlrTEpvR2JNZ1N0ZXB0a2hLS3VoN2tlbjRKRXZIclQ4MzE1N2V6RUdyWjdSJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6cmF5JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBhdGFPd25lck1hcDoge1xuICAgICAgICAgICcxNDFCRk5lbTNwa25jOEN6UFZMdjFSaTNidGdLZENzYWZZUDVuWHdtWGZ4VSc6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgJzlLYUxpblpGTlc1Y2hMNEo4VW9LblRFQ3BwV1ZNejNld2d4NEZBa3hVRGNmJzogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRva2VuIHRyYW5zZmVyIHdpdGggQVRBIGNyZWF0aW9uIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEJhc2U2NDogdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRva2VuVHJhbnNmZXJXaXRoQXRhQ3JlYXRpb24udW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgdG9rZW5BY2NvdW50UmVudEV4ZW1wdEFtb3VudDogJzMwMDAwMDAnLFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbXG4gICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgJ2Jsb2NraGFzaCcsXG4gICAgICAgICAgJ2R1cmFibGVOb25jZScsXG4gICAgICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAgICAgJ2NoYW5nZUFtb3VudCcsXG4gICAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICAgICAndG9rZW5FbmFibGVtZW50cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ21lbW8nLFxuICAgICAgICBdLFxuICAgICAgICBpZDogJ1VOQVZBSUxBQkxFJyxcbiAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dEFtb3VudDogJzAnLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJlS2pWdHpWM29QVFhGZHRSU0RqM0VtOWsxTVY3azhXaktrQnN6UVV3aXpTJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzVVM2JINWI2WHRHOTlhVldMcXdWellQVnBRaUZIeXRCRDY4UnoyZUZQWmQ3JyxcbiAgICAgICAgICAgIHZhbHVlOiAnMTAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGZlZVBheWVyOiAnNVUzYkg1YjZYdEc5OWFWV0xxd1Z6WVBWcFFpRkh5dEJENjhSejJlRlBaZDcnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnMzAwNTAwMCcsIGZlZVJhdGU6IDUwMDAgfSxcbiAgICAgICAgbWVtbzogdW5kZWZpbmVkLFxuICAgICAgICBibG9ja2hhc2g6ICcyN0UzTVhGdlhNVU5ZZU1KZVgxcEFiRVJHc0pmVWJrYVpUZmdNZ3BtTk41ZycsXG4gICAgICAgIGR1cmFibGVOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICB0b2tlbkVuYWJsZW1lbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJlS2pWdHpWM29QVFhGZHRSU0RqM0VtOWsxTVY3azhXaktrQnN6UVV3aXpTJyxcbiAgICAgICAgICAgIHRva2VuQWRkcmVzczogJ0Y0dUxlWEpvRnozaHcxM01wb3N1d2FRYk1jWmJDanF2RUdQUGVSUkIxQnlmJyxcbiAgICAgICAgICAgIHRva2VuTmFtZTogJ3Rzb2w6dXNkYycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYXRhT3duZXJNYXA6IHtcbiAgICAgICAgICAnMmVLalZ0elYzb1BUWEZkdFJTRGozRW05azFNVjdrOFdqS2tCc3pRVXdpelMnOiAnQzR6Q3FDYURtNEQ3OHpnYUgzQ2VCRUVCRUFvTU5oelNDajIzcUU5Mm5kaVAnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdLZXlwYWlyOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEga2V5cGFpciBmcm9tIHJhbmRvbSBzZWVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2hvdWxkLnRocm93cygoKSA9PiBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoJ3BsYWNlaG9sZGVyJyBhcyBhbnkpLCAnZ2VuZXJhdGVLZXlQYWlyIG1ldGhvZCBub3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYSBrZXlwYWlyIGZyb20gYSBzZWVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2hvdWxkLnRocm93cygoKSA9PiBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoJ3BsYWNlaG9sZGVyJyBhcyBhbnkpLCAnZ2VuZXJhdGVLZXlQYWlyIG1ldGhvZCBub3QgaW1wbGVtZW50ZWQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ24gdHJhbnNhY3Rpb246JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc2lnbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZDogYW55ID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4QmFzZTY0OiByZXNvdXJjZXMuUkFXX1RYX1VOU0lHTkVELFxuICAgICAgICAgIGtleXM6IFtyZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnB1YmxpY0tleS50b1N0cmluZygpXSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiByZXNvdXJjZXMuYWNjb3VudFdpdGhTZWVkLnByaXZhdGVLZXkuYmFzZTU4LFxuICAgICAgfSBhcyBhbnkpO1xuICAgICAgc2lnbmVkLnR4SGV4LnNob3VsZC5lcXVhbChyZXNvdXJjZXMuUkFXX1RYX1NJR05FRCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSB0eEhleCBhbmQgdHhCYXNlNjQgaW50ZXJjaGFuZ2VhYmx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkOiBhbnkgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHJlc291cmNlcy5SQVdfVFhfVU5TSUdORUQsXG4gICAgICAgICAga2V5czogW3Jlc291cmNlcy5hY2NvdW50V2l0aFNlZWQucHVibGljS2V5LnRvU3RyaW5nKCldLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IHJlc291cmNlcy5hY2NvdW50V2l0aFNlZWQucHJpdmF0ZUtleS5iYXNlNTgsXG4gICAgICB9IGFzIGFueSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKHJlc291cmNlcy5SQVdfVFhfU0lHTkVEKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaW52YWxpZCB0cmFuc2FjdGlvbiB3aGVuIHNpZ24gd2l0aCBwdWJsaWMga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhCYXNlNjQ6IHJlc291cmNlcy5SQVdfVFhfVU5TSUdORUQsXG4gICAgICAgICAgICBrZXlzOiBbcmVzb3VyY2VzLmFjY291bnRXaXRoU2VlZC5wdWJsaWNLZXkudG9TdHJpbmcoKV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcnY6IHJlc291cmNlcy5hY2NvdW50V2l0aFNlZWQucHVibGljS2V5LFxuICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQga2V5Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaWduIG1lc3NhZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzaWduIG1lc3NhZ2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduTWVzc2FnZShrZXlwYWlyLCAnc2lnbmVkIG1lc3NhZ2UnKTtcbiAgICAgIHNpZ25lZFxuICAgICAgICAudG9TdHJpbmcoJ2Jhc2U2NCcpXG4gICAgICAgIC5zaG91bGQuZXF1YWwoJ3MrN2QvOGFXL3R3Zk0vMHdMU0tPR3hkOStMaERJaXovZzBGZkozOXlsSmhRSWtqSzBSWVBtL1krZ2RlSjVESXk2SzZoNmdDWFhFU0RvbWx2MTJEQkJRPT0nKTtcbiAgICB9KTtcbiAgICBpdCgnc2hvdWxkbnQgc2lnbiBtZXNzYWdlIHdoZW4gbWVzc2FnZSBpcyB1bmRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuc2lnbk1lc3NhZ2Uoa2V5cGFpciwgdW5kZWZpbmVkIGFzIGFueSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ1RoZSBmaXJzdCBhcmd1bWVudCBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nIG9yIGFuIGluc3RhbmNlIG9mIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIG9yIEFycmF5IG9yIGFuIEFycmF5LWxpa2UgT2JqZWN0LiBSZWNlaXZlZCB1bmRlZmluZWQnXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZXQgU2lnbmluZyBQYXlsb2FkJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgdmFsaWQgc2lnbmluZyBwYXlsb2FkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZmFjdG9yeSA9IGdldEJ1aWxkZXJGYWN0b3J5KGJhc2Vjb2luLmdldENoYWluKCkpO1xuICAgICAgY29uc3QgcmVidWlsdFNpZ25hYmxlUGF5bG9hZCA9IChhd2FpdCBmYWN0b3J5LmZyb20ocmVzb3VyY2VzLlRSQU5TRkVSX1VOU0lHTkVEX1RYX1dJVEhfTUVNTykuYnVpbGQoKSlcbiAgICAgICAgLnNpZ25hYmxlUGF5bG9hZDtcbiAgICAgIGNvbnN0IHNpZ25pbmdQYXlsb2FkID0gYXdhaXQgYmFzZWNvaW4uZ2V0U2lnbmFibGVQYXlsb2FkKHJlc291cmNlcy5UUkFOU0ZFUl9VTlNJR05FRF9UWF9XSVRIX01FTU8pO1xuICAgICAgc2lnbmluZ1BheWxvYWQuc2hvdWxkLmJlLmRlZXBFcXVhbChyZWJ1aWx0U2lnbmFibGVQYXlsb2FkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgQ2xvc2VBc3NvY2lhdGVkVG9rZW5BY2NvdW50IHR4biBidWlsZGVyIGZyb20gcmF3IHR4bicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBnZXRCdWlsZGVyRmFjdG9yeShiYXNlY29pbi5nZXRDaGFpbigpKTtcbiAgICAgIGNvbnN0IHR4bkJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmVzb3VyY2VzLlRSQU5TRkVSX1VOU0lHTkVEX1RYX0NMT1NFX0FUQSk7XG4gICAgICBhc3NlcnQub2sodHhuQnVpbGRlcik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQcmVzaWduIHRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IHR4UmVxdWVzdElkID0gJ3R4UmVxdWVzdElkJztcbiAgICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWJ1aWxkIHR4IHJlcXVlc3QgZm9yIGhvdCB3YWxsZXRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVidWlsdFR4OiBUeFJlcXVlc3QgPSB7XG4gICAgICAgIHR4UmVxdWVzdElkLFxuICAgICAgICB1bnNpZ25lZFR4czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgICAgIHNpZ25hYmxlSGV4OiAnc2VyaWFsaXplZFR4SGV4JyxcbiAgICAgICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtdLFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIGludGVudDoge1xuICAgICAgICAgIGludGVudFR5cGU6ICdwYXltZW50JyxcbiAgICAgICAgfSxcbiAgICAgICAgbGF0ZXN0OiB0cnVlLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdVc2VyU2lnbmF0dXJlJyxcbiAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgIHdhbGxldElkOiAnd2FsbGV0SWQnLFxuICAgICAgICBwb2xpY2llc0NoZWNrZWQ6IHRydWUsXG4gICAgICAgIHZlcnNpb246IDEsXG4gICAgICAgIHVzZXJJZDogJ3VzZXJJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzdHViVHNzVXRpbHMgPSBzYW5kYm94LmNyZWF0ZVN0dWJJbnN0YW5jZShUc3NVdGlscyk7XG4gICAgICBzdHViVHNzVXRpbHMuZGVsZXRlU2lnbmF0dXJlU2hhcmVzLnJlc29sdmVzKFtdKTtcbiAgICAgIHN0dWJUc3NVdGlscy5nZXRUeFJlcXVlc3QucmVzb2x2ZXMocmVidWlsdFR4KTtcblxuICAgICAgY29uc3QgaG90V2FsbGV0ID0ge1xuICAgICAgICB0eXBlOiAnaG90JyxcbiAgICAgIH07XG4gICAgICBjb25zdCBwcmVzaWduZWRUcmFuc2FjdGlvbjogYW55ID0gYXdhaXQgYmFzZWNvaW4ucHJlc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgd2FsbGV0RGF0YTogaG90V2FsbGV0LFxuICAgICAgICB0c3NVdGlsczogc3R1YlRzc1V0aWxzLFxuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhSZXF1ZXN0SWQsXG4gICAgICAgIH0sXG4gICAgICB9IGFzIGFueSk7XG5cbiAgICAgIHByZXNpZ25lZFRyYW5zYWN0aW9uLndhbGxldERhdGEuc2hvdWxkLmRlZXBFcXVhbChob3RXYWxsZXQpO1xuICAgICAgcHJlc2lnbmVkVHJhbnNhY3Rpb24udHhQcmVidWlsZC5zaG91bGQuZGVlcEVxdWFsKHJlYnVpbHRUeCk7XG4gICAgICBwcmVzaWduZWRUcmFuc2FjdGlvbi50eEhleC5zaG91bGQuZXF1YWwocmVidWlsdFR4LnVuc2lnbmVkVHhzWzBdLnNlcmlhbGl6ZWRUeEhleCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRvIG5vdGhpbmcgZm9yIG5vbi1ob3Qgd2FsbGV0cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbGRXYWxsZXQgPSB7XG4gICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByZXNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucHJlc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgd2FsbGV0RGF0YTogY29sZFdhbGxldCxcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIHByZXNpZ25lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICB3YWxsZXREYXRhOiBjb2xkV2FsbGV0LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVycm9yIGlmIHR4UmVxdWVzdElkIGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBob3RXYWxsZXQgPSB7XG4gICAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5wcmVzaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHdhbGxldERhdGE6IGhvdFdhbGxldCxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7fSxcbiAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHR4UmVxdWVzdElkJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBUEkgS2V5IHBhcmFtZXRlcjonLCAoKSA9PiB7XG4gICAgLy8gVGVzdCB0aGUgZ2V0UHVibGljTm9kZVVybCBtZXRob2QgZGlyZWN0bHlcbiAgICBpdCgnc2hvdWxkIGFwcGVuZCBhcGlLZXkgdG8gbm9kZSBVUkwgd2hlbiBwcm92aWRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEFjY2VzcyB0aGUgcHJvdGVjdGVkIG1ldGhvZCB1c2luZyB0eXBlIGNhc3RpbmdcbiAgICAgIGNvbnN0IHVybCA9IChiYXNlY29pbiBhcyBhbnkpLmdldFB1YmxpY05vZGVVcmwoJ3Rlc3QtYXBpLWtleS0xMjMnKTtcbiAgICAgIHVybC5zaG91bGQuZXF1YWwoYCR7RW52aXJvbm1lbnRzLnRlc3Quc29sQWxjaGVteU5vZGVVcmx9L3Rlc3QtYXBpLWtleS0xMjNgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXNlIHJlZ3VsYXIgbm9kZSBVUkwgd2hlbiBhcGlLZXkgaXMgbm90IHByb3ZpZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gQWNjZXNzIHRoZSBwcm90ZWN0ZWQgbWV0aG9kIHVzaW5nIHR5cGUgY2FzdGluZ1xuICAgICAgY29uc3QgdXJsID0gKGJhc2Vjb2luIGFzIGFueSkuZ2V0UHVibGljTm9kZVVybCgpO1xuICAgICAgdXJsLnNob3VsZC5lcXVhbChFbnZpcm9ubWVudHMudGVzdC5zb2xOb2RlVXJsKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGNvbnN0IGNvaW4gPSBjb2lucy5nZXQoJ3Rzb2wnKTtcbiAgICBjb25zdCB1c2R0TWludEFkZHJlc3MgPSAnOWNncEJlTloySG5MZGE3TldhYVUxaTNOeVRzdGsyYzR6Q01VY29BR3NpOUMnO1xuICAgIGNvbnN0IHQyMm1pbnRBZGRyZXNzID0gJzVOUjFiUXdMV3FqYmtoYlExaHg3MkhLSnliYnV2d2tEblVaTm9BWjJWaFc2JztcbiAgICBsZXQgY2FsbEJhY2s6IHNpbm9uLlNpbm9uU3R1YjtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgY2FsbEJhY2sgPSBzYW5kQm94LnN0dWIoU29sLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgU29sKTtcblxuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRMYXRlc3RCbG9ja2hhc2gnLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRCbG9ja2hhc2hSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEZlZUZvck1lc3NhZ2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHNpbm9uLm1hdGNoLnN0cmluZyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6ICdmaW5hbGl6ZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEZlZXNGb3JNZXNzYWdlUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRNaW5pbXVtQmFsYW5jZUZvclJlbnRFeGVtcHRpb24nLFxuICAgICAgICAgICAgcGFyYW1zOiBbMTY1XSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldE1pbmltdW1CYWxhbmNlRm9yUmVudEV4ZW1wdGlvblJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleU5vRnVuZHNdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZU5vRnVuZHMpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLmFjY291bnRJbmZvLmJzNThFbmNvZGVkUHVibGljS2V5TTFEZXJpdmF0aW9uXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2VNMURlcml2YXRpb24pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLmFjY291bnRJbmZvLmJzNThFbmNvZGVkUHVibGljS2V5TTJEZXJpdmF0aW9uXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2VNMkRlcml2YXRpb24pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLmFjY291bnRJbmZvLmJzNThFbmNvZGVkUHVibGljS2V5V2l0aE1hbnlUb2tlbnNdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZU0yRGVyaXZhdGlvbik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEuY2xvc2VBVEFrZXlzLmNsb3NlQXRhQWRkcmVzc10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlTTJEZXJpdmF0aW9uKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYnM1OEVuY29kZWRQdWJsaWNLZXldLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZU0yRGVyaXZhdGlvbik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEFjY291bnRJbmZvJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuY2xvc2VBdGFBZGRyZXNzLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkluZm9SZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEFjY291bnRJbmZvJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEluZm9SZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2VOb0FjY291bnRzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmFjY291bnRJbmZvLmJzNThFbmNvZGVkUHVibGljS2V5LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2VOb0FjY291bnRzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXkyLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleTIsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbnpRZEJOYkxxUDVWRWhka0FTNkVQRkxDMVBIbkJxQ1hFcFB4dUViJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJGb3JTb2wyMDIyUmVzcG9uc2UyKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbnpRZEJOYkxxUDVWRWhka0FTNkVQRkxDMVBIbkJxQ1hFcFB4dUViJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJGb3JTb2wyMDIyUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlMik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3M0LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2UzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2VuelFkQk5iTHFQNVZFaGRrQVM2RVBGTEMxUEhuQnFDWEVwUHh1RWInLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlTm9BY2NvdW50cyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ3NlbmRUcmFuc2FjdGlvbicsXG4gICAgICAgICAgICBwYXJhbXM6IHNpbm9uLm1hdGNoLmFycmF5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5vbkNhbGwoMClcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5icm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlKVxuICAgICAgICAub25DYWxsKDEpXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuYnJvYWRjYXN0VHJhbnNhY3Rpb25SZXNwb25zZTEpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIGEgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gdGVzdERhdGEub3ZjUmVzcG9uc2U7XG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ0F2UitMOTA5a3pScTZOdWFVZTlGNkp0OTdNT2lGczdqcFc4TXVPcnd6NEViS0Y0MGQzMWRjaS9iZ0xUcTRncGsvSGgzczVjQThGdGJMa0RRcjE1UHFBRTd5ZDhMT1h2c0x0TzJSRXFNTS9PQ1o4d0l0ZnNxZlRmaWEyeElmaWJSVzN3SGd3NjNqaWFvamJYZVNxYVlhakovQ2E3WXdCVXo1Ymx5ZEkzZllMZ1BBZ0VDQnNMVnRmVDdtcHZOaWk4d1BrMEc5NDJON1RBSEUvUlcyaXEvOExQcUFZV3FCUm8wdklyTlE0ZGpsMitXaDJFVkJROXpnb1ZUVm0wUkhYckl2LzYvV0h4UFgxbUh2K0pxcG1BVDc5bHROallQSzBNMnlSK1pNbG43VmdVVEJXRk5RdkxxRS9qL25YbFkyL0pweHVOci9mWExYRVBlUzA0ZFB2dDlxejFkQW9ZRUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHcDlVWEdTeFdqdUNLaEY5ejBwZUl6d05jTVVXeUdyTkUyQVl1cVVBQUFEcGlIMjBjeExqN0tuT2FvSTVBTk5vUHhZanM0NzJGZGpEZU1QZnQza1hkQWdRREFnVUJCQVFBQUFBRUFnQUREQUlBQUFEd29wbzdBQUFBQUE9PSdcbiAgICAgICk7XG4gICAgICAocmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAocmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRha2Ugc29sIDIwMjIgdG9rZW4gT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgYSBzaWduZWQgc3dlZXAgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB0ZXN0RGF0YS5vdmNSZXNwb25zZTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHhuID0gYXdhaXQgYmFzZWNvaW4uY3JlYXRlQnJvYWRjYXN0YWJsZVN3ZWVwVHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnQXZSK0w5MDlrelJxNk51YVVlOUY2SnQ5N01PaUZzN2pwVzhNdU9yd3o0RWJLRjQwZDMxZGNpL2JnTFRxNGdway9IaDNzNWNBOEZ0YkxrRFFyMTVQcUFFN3lkOExPWHZzTHRPMlJFcU1NL09DWjh3SXRmc3FmVGZpYTJ4SWZpYlJXM3dIZ3c2M2ppYW9qYlhlU3FhWWFqSi9DYTdZd0JVejVibHlkSTNmWUxnUEFnRUNCc0xWdGZUN21wdk5paTh3UGswRzk0Mk43VEFIRS9SVzJpcS84TFBxQVlXcUJSbzB2SXJOUTRkamwyK1doMkVWQlE5emdvVlRWbTBSSFhySXYvNi9XSHhQWDFtSHYrSnFwbUFUNzlsdE5qWVBLME0yeVIrWk1sbjdWZ1VUQldGTlF2THFFL2ovblhsWTIvSnB4dU5yL2ZYTFhFUGVTMDRkUHZ0OXF6MWRBb1lFQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUdwOVVYR1N4V2p1Q0toRjl6MHBlSXp3TmNNVVd5R3JORTJBWXVxVUFBQURwaUgyMGN4TGo3S25PYW9JNUFOTm9QeFlqczQ3MkZkakRlTVBmdDNrWGRBZ1FEQWdVQkJBUUFBQUFFQWdBRERBSUFBQUR3b3BvN0FBQUFBQT09J1xuICAgICAgKTtcbiAgICAgIChyZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4ID8/IDApLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIChyZWNvdmVyeVR4bi5sYXN0U2NhbkluZGV4ID8/IDApLnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGFrZSBjb25zb2xpZGF0aW9uIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIG11bHRpcGxlIHNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB0ZXN0RGF0YS5vdmNSZXNwb25zZTI7XG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ0F0UVBMek9tTHVLd0hZNk41WG9KSVpLL1Q3VzEwdVlXbS9NUnRlM0dGVWRsK3czZ0hMalNhOUg2NldTZkZOdWJReElQY2t4SkR5bHRrUDdrc0xEZjlRZ0JOSk0yVVdiQlVINXdUMEpKSElMbGhDczMzSFg4RGVFLzhUZHN3NnRHZlpvTWhDblNLdjZUUFd0Qnh5N1NiNnNXOGtzQ1VQbkFXdUhHR0ttZ2pFTUJBZ0VDQm1McnF4SnJZMmtiTi90Y3JRdzNQOFAxNU9sakZHYWJGSkFLQnJVTzFnck5CUm8wdklyTlE0ZGpsMitXaDJFVkJROXpnb1ZUVm0wUkhYckl2LzYvV0h4UFgxbUh2K0pxcG1BVDc5bHROallQSzBNMnlSK1pNbG43VmdVVEJXRk5Rc0xWdGZUN21wdk5paTh3UGswRzk0Mk43VEFIRS9SVzJpcS84TFBxQVlXcUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHcDlVWEdTeFdqdUNLaEY5ejBwZUl6d05jTVVXeUdyTkUyQVl1cVVBQUFJWlFuaWlTNzNENm13ZnBuZmhWTUM0bHlZSnRSU3Jtb1pwRjd5SWxVZElEQWdRREFnVUJCQVFBQUFBRUFnQUREQUlBQUFEd1BjMGRBQUFBQUE9PSdcbiAgICAgICk7XG4gICAgICAocmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMSk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMV0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ0F1TGhPQTV6bU9CWlI4NWxvK25LZFRvcFZ3SkFNck1wNk5XKzhVbkdOc1NCU3BCa3FmV1pRcVNnOXMrN2FUbFhlem01dnhvbCtQbDZ0N1BwVk5UT0h3TGNwOXhKcDNURkhkaXZFYmh3SktsZFI0TnkrcGFzb0Z4K0JnazhxNmcxaU5pcTdYU2kxT3YzYnM3ZXVNa1RqN25EUkZxUDhsdjd4TFRjdnJCbTlPUUpBZ0VDQnAxNEltQkNkbVZST2x3MFV2ZVlTMU12Ry9sakNSSTNNSlRGbXN4dVhFb1dCUm8wdklyTlE0ZGpsMitXaDJFVkJROXpnb1ZUVm0wUkhYckl2LzYvV0h3MGh5eHZwVnd0SXg5L3plWDJPMTZlVHJZK2FLSWgxbWRLZzRNTWcwZXl4TUxWdGZUN21wdk5paTh3UGswRzk0Mk43VEFIRS9SVzJpcS84TFBxQVlXcUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFHcDlVWEdTeFdqdUNLaEY5ejBwZUl6d05jTVVXeUdyTkUyQVl1cVVBQUFDN3dzMVhGc2xpbndndHBJU1VWaVZXSVZUSHlEMlEwcWoyNFlqS21yQW1YQWdRREFnVUJCQVFBQUFBRUFnQUREQUlBQUFEd1BjMGRBQUFBQUE9PSdcbiAgICAgICk7XG4gICAgICAocmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMik7XG4gICAgICAocmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleCA/PyAwKS5zaG91bGQuZXF1YWwoMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciBub24tYml0Z28gcmVjb3ZlcmllcyAobGF0ZXN0IGJsb2NraGFzaCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBMYXRlc3QgQmxvY2toYXNoIFJlY292ZXJ5IChCaXRHby1sZXNzKVxuICAgICAgY29uc3QgbGF0ZXN0QmxvY2tIYXNoVHhuID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmtleXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5rZXlzLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmtleXMuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICB9KTtcbiAgICAgIGxhdGVzdEJsb2NrSGFzaFR4bi5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICBsYXRlc3RCbG9ja0hhc2hUeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIGxhdGVzdEJsb2NrSGFzaFR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChsYXRlc3RCbG9ja0hhc2hUeG4gYXMgTVBDVHgpLnNjYW5JbmRleCwgMCk7XG5cbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKChsYXRlc3RCbG9ja0hhc2hUeG4gYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5Kc29uID0gbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uLm5vbmNlLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuYmxvY2toYXNoKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEubGF0ZXN0QmxvY2toYXNoU2lnbmF0dXJlcyk7XG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCAzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3Igbm9uLWJpdGdvIHJlY292ZXJpZXMgKGR1cmFibGUgbm9uY2UpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gRHVyYWJsZSBOb25jZSBSZWNvdmVyeSAoQml0R28tbGVzcylcbiAgICAgIGNvbnN0IGR1cmFibGVOb25jZVR4biA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5rZXlzLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEua2V5cy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5rZXlzLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5rZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBwdWJsaWNLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgIHNlY3JldEtleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQcml2S2V5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGR1cmFibGVOb25jZVR4bi5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICBkdXJhYmxlTm9uY2VUeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIGR1cmFibGVOb25jZVR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChkdXJhYmxlTm9uY2VUeG4gYXMgTVBDVHgpLnNjYW5JbmRleCwgMCk7XG5cbiAgICAgIGNvbnN0IGR1cmFibGVOb25jZVR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgZHVyYWJsZU5vbmNlVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKChkdXJhYmxlTm9uY2VUeG4gYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBkdXJhYmxlTm9uY2VUeG5Kc29uID0gZHVyYWJsZU5vbmNlVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5lcXVhbChkdXJhYmxlTm9uY2VUeG5Kc29uLm5vbmNlLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlQmxvY2toYXNoKTtcbiAgICAgIHNob3VsZC5lcXVhbChkdXJhYmxlTm9uY2VUeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS5hY2NvdW50SW5mby5iczU4RW5jb2RlZFB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwoZHVyYWJsZU5vbmNlVHhuSnNvbi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEuZHVyYWJsZU5vbmNlU2lnbmF0dXJlcyk7XG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCA0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3IgdW5zaWduZWQgc3dlZXAgcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFVuc2lnbmVkIFN3ZWVwIFJlY292ZXJ5XG4gICAgICBjb25zdCB1bnNpZ25lZFN3ZWVwVHhuID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEua2V5cy5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICAgICAgfSxcbiAgICAgIH0pKSBhcyBNUENTd2VlcFR4cztcblxuICAgICAgdW5zaWduZWRTd2VlcFR4bi5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICB1bnNpZ25lZFN3ZWVwVHhuLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHVuc2lnbmVkU3dlZXBUeG4udHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKHVuc2lnbmVkU3dlZXBUeG4udHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFN3ZWVwVHhuRGVzZXJpYWxpemUgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB1bnNpZ25lZFN3ZWVwVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKFxuICAgICAgICB1bnNpZ25lZFN3ZWVwVHhuLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4XG4gICAgICApO1xuICAgICAgY29uc3QgdW5zaWduZWRTd2VlcFR4bkpzb24gPSB1bnNpZ25lZFN3ZWVwVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5lcXVhbCh1bnNpZ25lZFN3ZWVwVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwodW5zaWduZWRTd2VlcFR4bkpzb24uZmVlUGF5ZXIsIHRlc3REYXRhLmFjY291bnRJbmZvLmJzNThFbmNvZGVkUHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbCh1bnNpZ25lZFN3ZWVwVHhuSnNvbi5udW1TaWduYXR1cmVzLCB0ZXN0RGF0YS5Tb2xJbnB1dERhdGEudW5zaWduZWRTd2VlcFNpZ25hdHVyZXMpO1xuICAgICAgY29uc3Qgc29sQ29pbiA9IGJhc2Vjb2luIGFzIGFueTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxDb3VudChzb2xDb2luLmdldERhdGFGcm9tTm9kZSwgNCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBlcnJvciBpbiByZWNvdmVyIGZ1bmN0aW9uIGlmIGEgcmVxdWlyZWQgZmllbGQgaXMgbWlzc2luZy9pbmNvcnJlY3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBtaXNzaW5nIHVzZXJrZXlcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmtleXMuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS5rZXlzLmJpdGdvS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEua2V5cy53YWxsZXRQYXNzd29yZCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ21pc3NpbmcgdXNlcktleScpO1xuXG4gICAgICAvLyBtaXNzaW5nIGJhY2t1cGtleVxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmtleXMudXNlcktleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEua2V5cy5iaXRnb0tleSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGJhY2t1cEtleScpO1xuXG4gICAgICAvLyBpbmNvcnJlY3Qgd2FsbGV0IHBhc3NwaHJhc2UsIHVzZXIga2V5LCBiYWNrdXAga2V5IGNvbWJpbmF0aW9uXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEua2V5cy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEua2V5cy5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmtleXMuYml0Z29LZXksXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5rZXlzLndhbGxldFBhc3N3b3JkICsgJ2luY29ycmVjdCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKFwiRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluOiBwYXNzd29yZCBlcnJvciAtIGNjbTogdGFnIGRvZXNuJ3QgbWF0Y2hcIik7XG5cbiAgICAgIC8vIG5vIHdhbGxldCB3aXRoIHN1ZmZpY2llbnQgZnVuZHNcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5rZXlzLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5rZXlzLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEua2V5cy5iaXRnb0tleU5vRnVuZHMsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5rZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgc29sIHRva2VucyB0byByZWNvdmVyeSBkZXN0aW5hdGlvbiB3aXRoIG5vIGV4aXN0aW5nIHRva2VuIGFjY291bnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdG9rZW5UeG4gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLndyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IHVzZHRNaW50QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBwdWJsaWNLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgIHNlY3JldEtleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQcml2S2V5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHRva2VuVHhuLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0b2tlblR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKCh0b2tlblR4biBhcyBNUENUeCkuc2NhbkluZGV4LCAwKTtcblxuICAgICAgY29uc3QgdG9rZW5UeG5EZXNlcmlhbGl6ZSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHRva2VuVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKCh0b2tlblR4biBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHRva2VuVHhuSnNvbiA9IHRva2VuVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubm9uY2UsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VCbG9ja2hhc2gpO1xuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLm51bVNpZ25hdHVyZXMsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VTaWduYXR1cmVzKTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IHRva2VuVHhuSnNvbi5pbnN0cnVjdGlvbnNEYXRhIGFzIEluc3RydWN0aW9uUGFyYW1zW107XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YS5sZW5ndGgsIDMpO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMF0udHlwZSwgJ05vbmNlQWR2YW5jZScpO1xuXG4gICAgICBjb25zdCBkZXN0aW5hdGlvblVTRFRUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5XG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0udHlwZSwgJ0NyZWF0ZUFzc29jaWF0ZWRUb2tlbkFjY291bnQnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMubWludEFkZHJlc3MsIHVzZHRNaW50QWRkcmVzcyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLmF0YUFkZHJlc3MsIGRlc3RpbmF0aW9uVVNEVFRva2VuQWNjb3VudCk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLm93bmVyQWRkcmVzcywgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMV0gYXMgQXRhSW5pdCkucGFyYW1zLnRva2VuTmFtZSwgJ3Rzb2w6dXNkdCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5wYXllckFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuXG4gICAgICBjb25zdCBzb3VyY2VVU0RUVG9rZW5BY2NvdW50ID0gYXdhaXQgZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgIHVzZHRNaW50QWRkcmVzcyxcbiAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMFxuICAgICAgKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzJdLnR5cGUsICdUb2tlblRyYW5zZmVyJyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLmZyb21BZGRyZXNzLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMudG9BZGRyZXNzLCBkZXN0aW5hdGlvblVTRFRUb2tlbkFjY291bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy5hbW91bnQsICcyMDAwMDAwMDAwJyk7XG4gICAgICBzaG91bGQuZXF1YWwoKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLnRva2VuTmFtZSwgJ3Rzb2w6dXNkdCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy5zb3VyY2VBZGRyZXNzLCBzb3VyY2VVU0RUVG9rZW5BY2NvdW50KTtcblxuICAgICAgY29uc3Qgc29sQ29pbiA9IGJhc2Vjb2luIGFzIGFueTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxDb3VudChzb2xDb2luLmdldERhdGFGcm9tTm9kZSwgNyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgc29sIDIwMjIgdG9rZW5zIHRvIHJlY292ZXJ5IGRlc3RpbmF0aW9uIHdpdGggbm8gZXhpc3RpbmcgdG9rZW4gYWNjb3VudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0b2tlblR4biA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdDIybWludEFkZHJlc3MsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLndyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW56UWRCTmJMcVA1VkVoZGtBUzZFUEZMQzFQSG5CcUNYRXBQeHVFYicsXG4gICAgICB9KTtcblxuICAgICAgdG9rZW5UeG4uc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgdG9rZW5UeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoKHRva2VuVHhuIGFzIE1QQ1R4KS5zY2FuSW5kZXgsIDApO1xuXG4gICAgICBjb25zdCB0b2tlblR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdG9rZW5UeG5EZXNlcmlhbGl6ZS5mcm9tUmF3VHJhbnNhY3Rpb24oKHRva2VuVHhuIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdG9rZW5UeG5Kc29uID0gdG9rZW5UeG5EZXNlcmlhbGl6ZS50b0pzb24oKTtcblxuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuXG4gICAgICBjb25zdCBpbnN0cnVjdGlvbnNEYXRhID0gdG9rZW5UeG5Kc29uLmluc3RydWN0aW9uc0RhdGEgYXMgSW5zdHJ1Y3Rpb25QYXJhbXNbXTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhLmxlbmd0aCwgMyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVswXS50eXBlLCAnTm9uY2VBZHZhbmNlJyk7XG5cbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uVG9rZW5BY2NvdW50ID0gYXdhaXQgZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgIHQyMm1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5XG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0udHlwZSwgJ0NyZWF0ZUFzc29jaWF0ZWRUb2tlbkFjY291bnQnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMubWludEFkZHJlc3MsIHQyMm1pbnRBZGRyZXNzKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMuYXRhQWRkcmVzcywgZGVzdGluYXRpb25Ub2tlbkFjY291bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy5vd25lckFkZHJlc3MsIHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzFdIGFzIEF0YUluaXQpLnBhcmFtcy50b2tlbk5hbWUsICd0c29sOnQyMm1pbnQnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsxXSBhcyBBdGFJbml0KS5wYXJhbXMucGF5ZXJBZGRyZXNzLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcblxuICAgICAgY29uc3Qgc291cmNlVG9rZW5BY2NvdW50ID0gYXdhaXQgZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgIHQyMm1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMl0udHlwZSwgJ1Rva2VuVHJhbnNmZXInKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMuZnJvbUFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy50b0FkZHJlc3MsIGRlc3RpbmF0aW9uVG9rZW5BY2NvdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMuYW1vdW50LCAnMjAwMDAwMDAwMCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKChpbnN0cnVjdGlvbnNEYXRhWzJdIGFzIFRva2VuVHJhbnNmZXIpLnBhcmFtcy50b2tlbk5hbWUsICd0c29sOnQyMm1pbnQnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgoaW5zdHJ1Y3Rpb25zRGF0YVsyXSBhcyBUb2tlblRyYW5zZmVyKS5wYXJhbXMuc291cmNlQWRkcmVzcywgc291cmNlVG9rZW5BY2NvdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgKGluc3RydWN0aW9uc0RhdGFbMl0gYXMgVG9rZW5UcmFuc2ZlcikucGFyYW1zLnByb2dyYW1JZCxcbiAgICAgICAgJ1Rva2VuelFkQk5iTHFQNVZFaGRrQVM2RVBGTEMxUEhuQnFDWEVwUHh1RWInXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCA3KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzb2wgdG9rZW5zIHRvIHJlY292ZXJ5IGRlc3RpbmF0aW9uIHdpdGggZXhpc3RpbmcgdG9rZW4gYWNjb3VudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0b2tlblR4biA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS53cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5MixcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IHVzZHRNaW50QWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBkdXJhYmxlTm9uY2U6IHtcbiAgICAgICAgICBwdWJsaWNLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgIHNlY3JldEtleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQcml2S2V5LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHRva2VuVHhuLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHRva2VuVHhuLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICB0b2tlblR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKCh0b2tlblR4biBhcyBNUENUeCkuc2NhbkluZGV4LCAwKTtcblxuICAgICAgY29uc3QgdG9rZW5UeG5EZXNlcmlhbGl6ZSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIHRva2VuVHhuRGVzZXJpYWxpemUuZnJvbVJhd1RyYW5zYWN0aW9uKCh0b2tlblR4biBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHRva2VuVHhuSnNvbiA9IHRva2VuVHhuRGVzZXJpYWxpemUudG9Kc29uKCk7XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubm9uY2UsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VCbG9ja2hhc2gpO1xuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLm51bVNpZ25hdHVyZXMsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VTaWduYXR1cmVzKTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IHRva2VuVHhuSnNvbi5pbnN0cnVjdGlvbnNEYXRhIGFzIFRva2VuVHJhbnNmZXJbXTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhLmxlbmd0aCwgMik7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVswXS50eXBlLCAnTm9uY2VBZHZhbmNlJyk7XG5cbiAgICAgIGNvbnN0IHNvdXJjZVVTRFRUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwXG4gICAgICApO1xuICAgICAgY29uc3QgZGVzdGluYXRpb25VU0RUVG9rZW5BY2NvdW50ID0gYXdhaXQgZ2V0QXNzb2NpYXRlZFRva2VuQWNjb3VudEFkZHJlc3MoXG4gICAgICAgIHVzZHRNaW50QWRkcmVzcyxcbiAgICAgICAgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleTJcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS50eXBlLCAnVG9rZW5UcmFuc2ZlcicpO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLmZyb21BZGRyZXNzLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy50b0FkZHJlc3MsIGRlc3RpbmF0aW9uVVNEVFRva2VuQWNjb3VudCk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMuYW1vdW50LCAnMjAwMDAwMDAwMCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLnRva2VuTmFtZSwgJ3Rzb2w6dXNkdCcpO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLnNvdXJjZUFkZHJlc3MsIHNvdXJjZVVTRFRUb2tlbkFjY291bnQpO1xuXG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCA3KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzb2wgMjAyMiB0b2tlbnMgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gd2l0aCBleGlzdGluZyB0b2tlbiBhY2NvdW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRva2VuVHhuID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLndyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXkyLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdDIybWludEFkZHJlc3MsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLndyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgZHVyYWJsZU5vbmNlOiB7XG4gICAgICAgICAgcHVibGljS2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgICBzZWNyZXRLZXk6IHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHJpdktleSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJvZ3JhbUlkOiBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKSxcbiAgICAgIH0pO1xuXG4gICAgICB0b2tlblR4bi5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICB0b2tlblR4bi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdG9rZW5UeG4uc2hvdWxkLmhhc093blByb3BlcnR5KCdzY2FuSW5kZXgnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgodG9rZW5UeG4gYXMgTVBDVHgpLnNjYW5JbmRleCwgMCk7XG5cbiAgICAgIGNvbnN0IHRva2VuVHhuRGVzZXJpYWxpemUgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICB0b2tlblR4bkRlc2VyaWFsaXplLmZyb21SYXdUcmFuc2FjdGlvbigodG9rZW5UeG4gYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0b2tlblR4bkpzb24gPSB0b2tlblR4bkRlc2VyaWFsaXplLnRvSnNvbigpO1xuICAgICAgY29uc29sZS5sb2codG9rZW5UeG5Kc29uKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0b2tlblR4bkpzb24ubm9uY2UsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VCbG9ja2hhc2gpO1xuICAgICAgc2hvdWxkLmVxdWFsKHRva2VuVHhuSnNvbi5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMCk7XG4gICAgICBzaG91bGQuZXF1YWwodG9rZW5UeG5Kc29uLm51bVNpZ25hdHVyZXMsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VTaWduYXR1cmVzKTtcblxuICAgICAgY29uc3QgaW5zdHJ1Y3Rpb25zRGF0YSA9IHRva2VuVHhuSnNvbi5pbnN0cnVjdGlvbnNEYXRhIGFzIFRva2VuVHJhbnNmZXJbXTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhLmxlbmd0aCwgMik7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVswXS50eXBlLCAnTm9uY2VBZHZhbmNlJyk7XG5cbiAgICAgIGNvbnN0IHNvdXJjZTIwMjJUb2tlbkFjY291bnQgPSBhd2FpdCBnZXRBc3NvY2lhdGVkVG9rZW5BY2NvdW50QWRkcmVzcyhcbiAgICAgICAgdDIybWludEFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczAsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uMjAyMlRva2VuQWNjb3VudCA9IGF3YWl0IGdldEFzc29jaWF0ZWRUb2tlbkFjY291bnRBZGRyZXNzKFxuICAgICAgICB0MjJtaW50QWRkcmVzcyxcbiAgICAgICAgdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleTIsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBUT0tFTl8yMDIyX1BST0dSQU1fSUQudG9TdHJpbmcoKVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnR5cGUsICdUb2tlblRyYW5zZmVyJyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMuZnJvbUFkZHJlc3MsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczApO1xuICAgICAgc2hvdWxkLmVxdWFsKGluc3RydWN0aW9uc0RhdGFbMV0ucGFyYW1zLnRvQWRkcmVzcywgZGVzdGluYXRpb24yMDIyVG9rZW5BY2NvdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbChpbnN0cnVjdGlvbnNEYXRhWzFdLnBhcmFtcy5hbW91bnQsICcyMDAwMDAwMDAwJyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMudG9rZW5OYW1lLCAndHNvbDp0MjJtaW50Jyk7XG4gICAgICBzaG91bGQuZXF1YWwoaW5zdHJ1Y3Rpb25zRGF0YVsxXS5wYXJhbXMuc291cmNlQWRkcmVzcywgc291cmNlMjAyMlRva2VuQWNjb3VudCk7XG4gICAgICBjb25zdCBzb2xDb2luID0gYmFzZWNvaW4gYXMgYW55O1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbENvdW50KHNvbENvaW4uZ2V0RGF0YUZyb21Ob2RlLCA3KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzb2wgdG9rZW5zIHRvIHJlY292ZXJ5IGRlc3RpbmF0aW9uIHdpdGggZXhpc3RpbmcgdG9rZW4gYWNjb3VudHMgZm9yIHVuc2lnbmVkIHN3ZWVwIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBmZWVSZXNwb25zZSA9IHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRGZWVzRm9yTWVzc2FnZVJlc3BvbnNlO1xuICAgICAgZmVlUmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUgPSAxMDAwMDtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0RmVlRm9yTWVzc2FnZScsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgc2lub24ubWF0Y2guc3RyaW5nLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY29tbWl0bWVudDogJ2ZpbmFsaXplZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhmZWVSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHRva2VuVHhuID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleTIsXG4gICAgICAgIGR1cmFibGVOb25jZToge1xuICAgICAgICAgIHB1YmxpY0tleTogdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXksXG4gICAgICAgICAgc2VjcmV0S2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVByaXZLZXksXG4gICAgICAgIH0sXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0ZXN0RGF0YS50b2tlbkFkZHJlc3MuVGVzdFVTREMsXG4gICAgICB9KSkgYXMgTVBDU3dlZXBUeHM7XG5cbiAgICAgIC8vIDIgc2lnbmF0dXJlcyBhbmQgbm8gcmVudCBleGVtcHRpb24gZmVlIHNpbmNlIHRoZSBkZXN0aW5hdGlvbiBhbHJlYWR5IGhhcyB0b2tlbiBhY2NvdW50c1xuICAgICAgY29uc3QgZXhwZWN0ZWRGZWUgPSA1MDAwICsgNTAwMDtcblxuICAgICAgY29uc3QgeyBzZXJpYWxpemVkVHgsIHNjYW5JbmRleCwgZmVlSW5mbywgcGFyc2VkVHggfSA9IHRva2VuVHhuLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgICBhc3NlcnQub2soc2VyaWFsaXplZFR4KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzY2FuSW5kZXgsIDApO1xuICAgICAgYXNzZXJ0Lm9rKGZlZUluZm8pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGZlZUluZm8uZmVlU3RyaW5nLCBleHBlY3RlZEZlZS50b1N0cmluZygpKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChmZWVJbmZvLmZlZSwgZXhwZWN0ZWRGZWUpO1xuICAgICAgYXNzZXJ0Lm9rKHBhcnNlZFR4KTtcbiAgICAgIGFzc2VydC5vayhwYXJzZWRUeC5pbnB1dHMgaW5zdGFuY2VvZiBBcnJheSAmJiBwYXJzZWRUeC5pbnB1dHMubGVuZ3RoID09PSAxKTtcbiAgICAgIGFzc2VydC5vayhwYXJzZWRUeC5vdXRwdXRzIGluc3RhbmNlb2YgQXJyYXkgJiYgcGFyc2VkVHgub3V0cHV0cy5sZW5ndGggPT09IDEpO1xuXG4gICAgICBjb25zdCB0b2tlblR4bkRlc2VyaWFsaXplID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgdG9rZW5UeG5EZXNlcmlhbGl6ZS5mcm9tUmF3VHJhbnNhY3Rpb24odG9rZW5UeG4udHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdG9rZW5UeG5Kc29uID0gdG9rZW5UeG5EZXNlcmlhbGl6ZS50b0pzb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRva2VuVHhuSnNvbi5ub25jZSwgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZUJsb2NraGFzaCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodG9rZW5UeG5Kc29uLmZlZVBheWVyLCB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MwKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0b2tlblR4bkpzb24ubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLnVuc2lnbmVkU3dlZXBTaWduYXR1cmVzKTtcbiAgICAgIGNvbnN0IHNvbENvaW4gPSBiYXNlY29pbiBhcyBhbnk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsQ291bnQoc29sQ29pbi5nZXREYXRhRnJvbU5vZGUsIDcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNvbCBmdW5kcyBmcm9tIEFUQSBhZGRyZXNzIGZvciBub24tYml0Z28gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGNsb3NlIEFUQSBhZGRyZXNzIGluc3RydWN0aW9uIHR5cGUgdHhuXG4gICAgICBjb25zdCBjbG9zZUFUQVR4bnMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ2xvc2VBVEEoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy53YWxsZXRQYXNzd29yZCxcbiAgICAgICAgY2xvc2VBdGFBZGRyZXNzOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuY2xvc2VBdGFBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uQXRhQWRkcmVzczogdGVzdERhdGEuY2xvc2VBVEFrZXlzLnJlY292ZXJ5RGVzdGluYXRpb25BdGFBZGRyZXNzLFxuICAgICAgfSk7XG4gICAgICBjbG9zZUFUQVR4bnMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBjbG9zZUFUQVR4bnNbMF0udHhJZCxcbiAgICAgICAgJzJpZDNZQzJqSzlHNVdvMnBoRHg0Z0pWQWV3OERjWTVOQW9qblZ1YW84cmt4d1BZUGU4Y1N3RTVHemhFZ0pBMnk4ZlZqREVvNmlSNnlrQnZEeHJUUXJ0cGInXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBjbG9zZUFUQVR4bnNbMV0udHhJZCxcbiAgICAgICAgJzVvVUJnWFg0ZW5HbUZFc3BHNjRnb3kzUFJ5c2pmcmVrWkdnM3JaTmtCSFVDUUZkNDgydnJWV2JmRGNSWU1CRUp0NjVKWHltZkVQbThNNmQ4OVg0eFY3OW4nXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHRva2VucyBmcm9tIGEgbmVzdGVkIEFUQSAoQVRBIHdob3NlIG93bmVyIGlzIGFub3RoZXIgQVRBKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXJOZXN0ZWRBdGEoe1xuICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy53YWxsZXRQYXNzd29yZCxcbiAgICAgICAgbmVzdGVkQXRhQWRkcmVzczogJ0ZHdVpTQmh0cmVxU1VzRTg2eG9reWpLejJpOFZCdEp6eTZ1TVhYS3lHSHVnJyxcbiAgICAgICAgb3duZXJBdGFBZGRyZXNzOiAnWmZtOThacFZhZnlkaEZUWWNzWTZiSGd1YmhCNGNGZ1dGdmJkRUp4WWhUQScsXG4gICAgICAgIHRva2VuTWludEFkZHJlc3M6ICdaQkNOcHVEN1lNWHpUSEIyZmhHa0dpNzhNTnNIR0xSWFVoUmV3TlJtOVJVJyxcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICByZXN1bHQudHhJZCxcbiAgICAgICAgJzJpZDNZQzJqSzlHNVdvMnBoRHg0Z0pWQWV3OERjWTVOQW9qblZ1YW84cmt4d1BZUGU4Y1N3RTVHemhFZ0pBMnk4ZlZqREVvNmlSNnlrQnZEeHJUUXJ0cGInXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIG5lc3RlZEF0YUFkZHJlc3MgaXMgbWlzc2luZyBmb3IgcmVjb3Zlck5lc3RlZEF0YScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyTmVzdGVkQXRhKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iaXRnb0tleSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICAgIG93bmVyQXRhQWRkcmVzczogJ1pmbTk4WnBWYWZ5ZGhGVFljc1k2YkhndWJoQjRjRmdXRnZiZEVKeFloVEEnLFxuICAgICAgICAgIHRva2VuTWludEFkZHJlc3M6ICdaQkNOcHVEN1lNWHpUSEIyZmhHa0dpNzhNTnNIR0xSWFVoUmV3TlJtOVJVJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgbmVzdGVkQXRhQWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIG93bmVyQXRhQWRkcmVzcyBpcyBtaXNzaW5nIGZvciByZWNvdmVyTmVzdGVkQXRhJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJOZXN0ZWRBdGEoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLmJpdGdvS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMud2FsbGV0UGFzc3dvcmQsXG4gICAgICAgICAgbmVzdGVkQXRhQWRkcmVzczogJ0ZHdVpTQmh0cmVxU1VzRTg2eG9reWpLejJpOFZCdEp6eTZ1TVhYS3lHSHVnJyxcbiAgICAgICAgICB0b2tlbk1pbnRBZGRyZXNzOiAnWkJDTnB1RDdZTVh6VEhCMmZoR2tHaTc4TU5zSEdMUlhVaFJld05SbTlSVScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIG93bmVyQXRhQWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHRva2VuTWludEFkZHJlc3MgaXMgbWlzc2luZyBmb3IgcmVjb3Zlck5lc3RlZEF0YScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyTmVzdGVkQXRhKHtcbiAgICAgICAgICB1c2VyS2V5OiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLmNsb3NlQVRBa2V5cy5iaXRnb0tleSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5jbG9zZUFUQWtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEuY2xvc2VBVEFrZXlzLndhbGxldFBhc3N3b3JkLFxuICAgICAgICAgIG5lc3RlZEF0YUFkZHJlc3M6ICdGR3VaU0JodHJlcVNVc0U4Nnhva3lqS3oyaThWQnRKenk2dU1YWEt5R0h1ZycsXG4gICAgICAgICAgb3duZXJBdGFBZGRyZXNzOiAnWmZtOThacFZhZnlkaEZUWWNzWTZiSGd1YmhCNGNGZ1dGdmJkRUp4WWhUQScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHRva2VuTWludEFkZHJlc3MnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0J1aWxkIENvbnNvbGlkYXRpb24gUmVjb3ZlcmllczonLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0c29sJyk7XG4gICAgY29uc3QgdXNkdE1pbnRBZGRyZXNzID0gJzljZ3BCZU5aMkhuTGRhN05XYWFVMWkzTnlUc3RrMmM0ekNNVWNvQUdzaTlDJztcbiAgICBjb25zdCBkdXJhYmxlTm9uY2VzID0ge1xuICAgICAgcHVibGljS2V5czogW1xuICAgICAgICB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleSxcbiAgICAgICAgdGVzdERhdGEua2V5cy5kdXJhYmxlTm9uY2VQdWJLZXkyLFxuICAgICAgICB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVB1YktleTMsXG4gICAgICBdLFxuICAgICAgc2VjcmV0S2V5OiB0ZXN0RGF0YS5rZXlzLmR1cmFibGVOb25jZVByaXZLZXksXG4gICAgfTtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgY29uc3QgY2FsbEJhY2sgPSBzYW5kQm94LnN0dWIoU29sLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgU29sKTtcblxuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRMYXRlc3RCbG9ja2hhc2gnLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiAnZmluYWxpemVkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRCbG9ja2hhc2hSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEZlZUZvck1lc3NhZ2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHNpbm9uLm1hdGNoLnN0cmluZyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6ICdmaW5hbGl6ZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEZlZXNGb3JNZXNzYWdlUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczFdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZU5vRnVuZHMpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRCYWxhbmNlJyxcbiAgICAgICAgICAgIHBhcmFtczogW3Rlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldEJhbGFuY2UnLFxuICAgICAgICAgICAgcGFyYW1zOiBbdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzM10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QmFsYW5jZScsXG4gICAgICAgICAgICBwYXJhbXM6IFt0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3M1XSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRNaW5pbXVtQmFsYW5jZUZvclJlbnRFeGVtcHRpb24nLFxuICAgICAgICAgICAgcGFyYW1zOiBbMTY1XSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldE1pbmltdW1CYWxhbmNlRm9yUmVudEV4ZW1wdGlvblJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QWNjb3VudEluZm8nLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50SW5mb1Jlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0QWNjb3VudEluZm8nLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLmtleXMuZHVyYWJsZU5vbmNlUHViS2V5MixcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEluZm9SZXNwb25zZTIpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlTm9BY2NvdW50cyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICAgIG1ldGhvZDogJ2dldFRva2VuQWNjb3VudHNCeU93bmVyJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICB0ZXN0RGF0YS53cndVc2VyLndhbGxldEFkZHJlc3MyLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHJvZ3JhbUlkOiAnVG9rZW5rZWdRZmVaeWlOd0FKYk5iR0tQRlhDV3VCdmY5U3M2MjNWUTVEQScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2pzb25QYXJzZWQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldFRva2VuQWNjb3VudHNCeU93bmVyUmVzcG9uc2VOb0FjY291bnRzKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczMsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbmtlZ1FmZVp5aU53QUpiTmJHS1BGWENXdUJ2ZjlTczYyM1ZRNURBJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJSZXNwb25zZU5vQWNjb3VudHMpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdnZXRUb2tlbkFjY291bnRzQnlPd25lcicsXG4gICAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgICAgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzNSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHByb2dyYW1JZDogJ1Rva2Vua2VnUWZlWnlpTndBSmJOYkdLUEZYQ1d1QnZmOVNzNjIzVlE1REEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZW5jb2Rpbmc6ICdqc29uUGFyc2VkJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRUb2tlbkFjY291bnRzQnlPd25lclJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnZ2V0VG9rZW5BY2NvdW50c0J5T3duZXInLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwcm9ncmFtSWQ6ICdUb2tlbmtlZ1FmZVp5aU53QUpiTmJHS1BGWENXdUJ2ZjlTczYyM1ZRNURBJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnanNvblBhcnNlZCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0VG9rZW5BY2NvdW50c0J5T3duZXJSZXNwb25zZSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIHNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHRlc3REYXRhLndyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogdGVzdERhdGEud3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA0LFxuICAgICAgICBkdXJhYmxlTm9uY2VzOiBkdXJhYmxlTm9uY2VzLFxuICAgICAgfSkpIGFzIE1QQ1R4cztcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICAocmVzLmxhc3RTY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDMpO1xuXG4gICAgICBjb25zdCB0eG4xID0gcmVzLnRyYW5zYWN0aW9uc1swXTtcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMS5mcm9tUmF3VHJhbnNhY3Rpb24oKHR4bjEgYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMSA9IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMS50b0pzb24oKTtcblxuICAgICAgY29uc3Qgbm9uY2UxID0gdGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUuZGF0YS5wYXJzZWQuaW5mby5ibG9ja2hhc2g7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEubm9uY2UsIG5vbmNlMSk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEuZmVlUGF5ZXIsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczIpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24xLm51bVNpZ25hdHVyZXMsIHRlc3REYXRhLlNvbElucHV0RGF0YS5kdXJhYmxlTm9uY2VTaWduYXR1cmVzKTtcblxuICAgICAgY29uc3QgdHhuMiA9IHJlcy50cmFuc2FjdGlvbnNbMV07XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIuZnJvbVJhd1RyYW5zYWN0aW9uKCh0eG4yIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuSnNvbjIgPSBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIudG9Kc29uKCk7XG5cbiAgICAgIGNvbnN0IG5vbmNlMiA9IHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50SW5mb1Jlc3BvbnNlMi5ib2R5LnJlc3VsdC52YWx1ZS5kYXRhLnBhcnNlZC5pbmZvLmJsb2NraGFzaDtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5ub25jZSwgbm9uY2UyKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMyk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjIubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLmR1cmFibGVOb25jZVNpZ25hdHVyZXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICAgIGR1cmFibGVOb25jZXM6IGR1cmFibGVOb25jZXMsXG4gICAgICB9KSkgYXMgTVBDU3dlZXBUeHM7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnR4UmVxdWVzdHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcblxuICAgICAgY29uc3QgdHhuMSA9IHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICAodHhuMS5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHR4bjEuY29pbj8uc2hvdWxkLmVxdWFsKCd0c29sJyk7XG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIHR4bjEuZGVyaXZhdGlvblBhdGg/LnNob3VsZC5lcXVhbCgnbS8yJyk7XG5cbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzEgPSB0eG4xLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzE/LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29tbW9uS2V5Y2hhaW4nKTtcblxuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxID0gbmV3IFRyYW5zYWN0aW9uKGNvaW4pO1xuICAgICAgbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLmZyb21SYXdUcmFuc2FjdGlvbigodHhuMSBhcyBNUENUeCkuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkpzb24xID0gbGF0ZXN0QmxvY2toYXNoVHhuRGVzZXJpYWxpemUxLnRvSnNvbigpO1xuXG4gICAgICBjb25zdCBub25jZTEgPSB0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0QWNjb3VudEluZm9SZXNwb25zZS5ib2R5LnJlc3VsdC52YWx1ZS5kYXRhLnBhcnNlZC5pbmZvLmJsb2NraGFzaDtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5ub25jZSwgbm9uY2UxKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMS5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMik7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLnVuc2lnbmVkU3dlZXBTaWduYXR1cmVzKTtcblxuICAgICAgY29uc3QgdHhuMiA9IHJlcy50eFJlcXVlc3RzWzFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2NhbkluZGV4Jyk7XG4gICAgICAodHhuMi5zY2FuSW5kZXggPz8gMCkuc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgdHhuMi5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHR4bjIuY29pbj8uc2hvdWxkLmVxdWFsKCd0c29sJyk7XG4gICAgICB0eG4yLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIHR4bjIuZGVyaXZhdGlvblBhdGg/LnNob3VsZC5lcXVhbCgnbS8zJyk7XG5cbiAgICAgIHR4bjIuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luU3BlY2lmaWMnKTtcbiAgICAgIGNvbnN0IGNvaW5TcGVjaWZpYzIgPSB0eG4yLmNvaW5TcGVjaWZpYztcbiAgICAgIGNvaW5TcGVjaWZpYzI/LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29tbW9uS2V5Y2hhaW4nKTtcbiAgICAgIGNvaW5TcGVjaWZpYzI/LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnbGFzdFNjYW5JbmRleCcpO1xuICAgICAgY29pblNwZWNpZmljMj8ubGFzdFNjYW5JbmRleD8uc2hvdWxkLmVxdWFsKDMpO1xuXG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIgPSBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gICAgICBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIuZnJvbVJhd1RyYW5zYWN0aW9uKCh0eG4yIGFzIE1QQ1R4KS5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgbGF0ZXN0QmxvY2toYXNoVHhuSnNvbjIgPSBsYXRlc3RCbG9ja2hhc2hUeG5EZXNlcmlhbGl6ZTIudG9Kc29uKCk7XG5cbiAgICAgIGNvbnN0IG5vbmNlMiA9IHRlc3REYXRhLlNvbFJlc3BvbnNlcy5nZXRBY2NvdW50SW5mb1Jlc3BvbnNlMi5ib2R5LnJlc3VsdC52YWx1ZS5kYXRhLnBhcnNlZC5pbmZvLmJsb2NraGFzaDtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5ub25jZSwgbm9uY2UyKTtcbiAgICAgIHNob3VsZC5lcXVhbChsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMi5mZWVQYXllciwgdGVzdERhdGEud3J3VXNlci53YWxsZXRBZGRyZXNzMyk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjIubnVtU2lnbmF0dXJlcywgdGVzdERhdGEuU29sSW5wdXREYXRhLnVuc2lnbmVkU3dlZXBTaWduYXR1cmVzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgdW5zaWduZWQgdG9rZW4gY29uc29saWRhdGlvbiByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gKGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIGJpdGdvS2V5OiB0ZXN0RGF0YS53cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMyxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA1LFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdXNkdE1pbnRBZGRyZXNzLFxuICAgICAgICBkdXJhYmxlTm9uY2VzOiBkdXJhYmxlTm9uY2VzLFxuICAgICAgfSkpIGFzIE1QQ1N3ZWVwVHhzO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgIGNvbnN0IHR4bjEgPSByZXMudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeDtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NjYW5JbmRleCcpO1xuICAgICAgKHR4bjEuc2NhbkluZGV4ID8/IDApLnNob3VsZC5lcXVhbCg0KTtcbiAgICAgIHR4bjEuc2hvdWxkLmhhc093blByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0eG4xLmNvaW4/LnNob3VsZC5lcXVhbCgndHNvbCcpO1xuICAgICAgdHhuMS5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICB0eG4xLmRlcml2YXRpb25QYXRoPy5zaG91bGQuZXF1YWwoJ20vNCcpO1xuXG4gICAgICB0eG4xLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnY29pblNwZWNpZmljJyk7XG4gICAgICBjb25zdCBjb2luU3BlY2lmaWMxID0gdHhuMS5jb2luU3BlY2lmaWM7XG4gICAgICBjb2luU3BlY2lmaWMxPy5zaG91bGQuaGFzT3duUHJvcGVydHkoJ2NvbW1vbktleWNoYWluJyk7XG5cbiAgICAgIGNvbnN0IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMSA9IG5ldyBUcmFuc2FjdGlvbihjb2luKTtcbiAgICAgIGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMS5mcm9tUmF3VHJhbnNhY3Rpb24oKHR4bjEgYXMgTVBDVHgpLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCBsYXRlc3RCbG9ja2hhc2hUeG5Kc29uMSA9IGxhdGVzdEJsb2NraGFzaFR4bkRlc2VyaWFsaXplMS50b0pzb24oKTtcblxuICAgICAgY29uc3Qgbm9uY2UxID0gdGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRJbmZvUmVzcG9uc2UuYm9keS5yZXN1bHQudmFsdWUuZGF0YS5wYXJzZWQuaW5mby5ibG9ja2hhc2g7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEubm9uY2UsIG5vbmNlMSk7XG4gICAgICBzaG91bGQuZXF1YWwobGF0ZXN0QmxvY2toYXNoVHhuSnNvbjEuZmVlUGF5ZXIsIHRlc3REYXRhLndyd1VzZXIud2FsbGV0QWRkcmVzczUpO1xuICAgICAgc2hvdWxkLmVxdWFsKGxhdGVzdEJsb2NraGFzaFR4bkpzb24xLm51bVNpZ25hdHVyZXMsIHRlc3REYXRhLlNvbElucHV0RGF0YS51bnNpZ25lZFN3ZWVwU2lnbmF0dXJlcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNraXAgYnVpbGRpbmcgY29uc29saWRhdGUgdHJhbnNhY3Rpb24gaWYgYmFsYW5jZSBpcyBlcXVhbCB0byB6ZXJvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdGVzdERhdGEud3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgICBkdXJhYmxlTm9uY2VzOiBkdXJhYmxlTm9uY2VzLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHN0YXJ0aW5nU2NhbkluZGV4IGlzIG5vdCBnZSB0byAxJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IC0xLFxuICAgICAgICAgIGR1cmFibGVOb25jZXM6IGR1cmFibGVOb25jZXMsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAtMSwgZW5kaW5nU2NhbkluZGV4OiAxOS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHNjYW4gZmFjdG9yIGlzIHRvbyBoaWdoJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogdGVzdERhdGEud3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogdGVzdERhdGEud3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHRlc3REYXRhLndyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAzMDAsXG4gICAgICAgICAgZHVyYWJsZU5vbmNlczogZHVyYWJsZU5vbmNlcyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IDEsIGVuZGluZ1NjYW5JbmRleDogMzAwLidcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2Jyb2FkY2FzdFRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJyb2FkY2FzdCBhIHRyYW5zYWN0aW9uIHN1Y2Nlc2Z1bGx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uID0gdGVzdERhdGEucmF3VHJhbnNhY3Rpb25zLnRyYW5zZmVyLnNpZ25lZDtcbiAgICAgIGNvbnN0IGJyb2FkY2FzdFN0dWIgPSBzYW5kQm94XG4gICAgICAgIC5zdHViKFNvbC5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIFNvbClcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgICBtZXRob2Q6ICdzZW5kVHJhbnNhY3Rpb24nLFxuICAgICAgICAgICAgcGFyYW1zOiBbXG4gICAgICAgICAgICAgIHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbixcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGVuY29kaW5nOiAnYmFzZTY0JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHRlc3REYXRhLlNvbFJlc3BvbnNlcy5icm9hZGNhc3RUcmFuc2FjdGlvblJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgYnJvYWRjYXN0VHhuID0gYXdhaXQgYmFzZWNvaW4uYnJvYWRjYXN0VHJhbnNhY3Rpb24oeyBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gfSk7XG4gICAgICBhc3NlcnQub2soYnJvYWRjYXN0VHhuKTtcbiAgICAgIGFzc2VydC5vayhicm9hZGNhc3RUeG4udHhJZCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIGJyb2FkY2FzdFR4bi50eElkLFxuICAgICAgICAnMmlkM1lDMmpLOUc1V28ycGhEeDRnSlZBZXc4RGNZNU5Bb2puVnVhbzhya3h3UFlQZThjU3dFNUd6aEVnSkEyeThmVmpERW82aVI2eWtCdkR4clRRcnRwYidcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnJvYWRjYXN0U3R1Yi5jYWxsQ291bnQsIDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBnb3QgYW4gZXJyb3IgZnJvbSB0aGUgbm9kZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiA9IHRlc3REYXRhLnJhd1RyYW5zYWN0aW9ucy50cmFuc2Zlci5zaWduZWQ7XG4gICAgICBjb25zdCBicm9hZGNhc3RTdHViID0gc2FuZEJveFxuICAgICAgICAuc3R1YihTb2wucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBTb2wpXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgICAgbWV0aG9kOiAnc2VuZFRyYW5zYWN0aW9uJyxcbiAgICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAgICBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmNvZGluZzogJ2Jhc2U2NCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuYnJvYWRjYXN0VHJhbnNhY3Rpb25SZXNwb25zZUVycm9yKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBiYXNlY29pbi5icm9hZGNhc3RUcmFuc2FjdGlvbih7IHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbiB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtZXNzYWdlOiAnRXJyb3IgYnJvYWRjYXN0aW5nIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbiBzaW11bGF0aW9uIGZhaWxlZDogQmxvY2toYXNoIG5vdCBmb3VuZCcgfVxuICAgICAgKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChicm9hZGNhc3RTdHViLmNhbGxDb3VudCwgMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGlzIG5vdCBhIHZhbGlkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFNpZ25lZFRyYW5zYWN0aW9uID0gJ3JhbmRvbXN0cmluZyc7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgYmFzZWNvaW4uYnJvYWRjYXN0VHJhbnNhY3Rpb24oeyBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gfSk7XG4gICAgICAgIH0sXG4gICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgcmF3IHRyYW5zYWN0aW9uJyB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBpcyBub3QgYSBzaWduZWQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gPSB0ZXN0RGF0YS5yYXdUcmFuc2FjdGlvbnMudHJhbnNmZXIudW5zaWduZWQ7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgYmFzZWNvaW4uYnJvYWRjYXN0VHJhbnNhY3Rpb24oeyBzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24gfSk7XG4gICAgICAgIH0sXG4gICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgcmF3IHRyYW5zYWN0aW9uJyB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQXVkaXRLZXknLCAoKSA9PiB7XG4gICAgY29uc3QgeyBrZXk6IGtleVN0cmluZywgY29tbW9uS2V5Y2hhaW4gfSA9IHNvbEJhY2t1cEtleTtcbiAgICBjb25zdCBrZXkgPSBrZXlTdHJpbmcucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2tBbVtFRlE2bz1TeGxjTEZEdyUsJztcbiAgICBjb25zdCBtdWx0aVNpZ1R5cGUgPSAndHNzJztcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZvciB2YWxpZCBpbnB1dHMnLCAoKSA9PiB7XG4gICAgICBiYXNlY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgY29tbW9uS2V5Y2hhaW4gaXMgaW52YWxpZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGFsdGVyZWRDb21tb25LZXljaGFpbiA9IGdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoMTApO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgcHVibGljS2V5OiBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICAgIH0pLFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTogJ0ludmFsaWQgY29tbW9uIGtleWNoYWluJyxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIHdhbGxldFBhc3NwaHJhc2UgaXMgaW5jb3JyZWN0JywgKCkgPT4ge1xuICAgICAgY29uc3QgaW5jb3JyZWN0UGFzc3BocmFzZSA9ICdmb28nO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGluY29ycmVjdFBhc3NwaHJhc2UsXG4gICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiBcImZhaWxlZCB0byBkZWNyeXB0IHBydjogY2NtOiB0YWcgZG9lc24ndCBtYXRjaFwiLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUga2V5IGlzIGFsdGVyZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBhbHRlcmVkS2V5ID0ga2V5LnJlcGxhY2UoL1swLTldL2csICcwJyk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhbHRlcmVkS2V5LFxuICAgICAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBqc29uIGRlY3J5cHQ6IGludmFsaWQgcGFyYW1ldGVycycsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gU2V0IHVwIHdhbGxldCBkYXRhXG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiB3YWxsZXQucHViLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGZha2VQcnYgPSBlbmNyeXB0KCdwYXNzd29yZCcsICdwcnYnKTtcblxuICAgICAgY29uc3Qgd2FsbGV0T2JqID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzWydtb2NrJ10udXJpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzb2wva2V5LzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJylcbiAgICAgICAgLnJlcGx5KDIwMCwgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZmFrZVBydixcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgLy8gTW9jayB0aGUgQVBJIHJlc3BvbnNlIGZvciBidWlsZEFjY291bnRDb25zb2xpZGF0aW9uc1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAvY29uc29saWRhdGVBY2NvdW50L2J1aWxkJylcbiAgICAgICAgLnJlcGx5KDIwMCwgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgICAgIHdhbGxldElkOiAnNjMwNjhlZDRlZmE2M2EwMDA4NzdmMDJmZDRiMGZhNmQnLFxuICAgICAgICAgICAgdHhIZXg6XG4gICAgICAgICAgICAgICcwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNmY1MDEzMGFiZjhkMGQ4OTQzYzViOWE1MWE1NzQ4ODZhN2Q3YjNkOGRiMThmMGRkYjRhYjhiNmQzZWMyN2UzYzJmMzZmMzMzOWJiOTJkNDI5NmFmNmFlNGQzYWJmYmIwNzg3N2Y3N2QwMDMzYzg4M2RlMDhmYTRhMmVlYTY3MGQwMjAxMDIwNjc0YTlkZjJiOTRhYTRiNGFkYTEyMDJkYzI4OTFiZTM2NjUwMWQwYWNiNGEwMWNhM2UwMmU3ZmQ2YzFmNTA1YTcxYzk2MTcyMDQ0ZjEyMTdjMzc4NGU4ZjAyZjQ5ZTJjOGZjMzU5MWU4MTI5NGFiNTQzOTRmOWQyMmZkN2I3YThmODQwMWMzZjY3Y2ZhNTI1MThiMzRhMDliMDhmNGVhNzdlMWM0ZmI5ZDg5YmZhY2NkYzMzY2Y4YjhhOWNmOGQ3YmYwZTA0Yzg5YzUwNDI4ZTRlZGE1Y2JiNzU5NDI3YzM3MGYwYTI5YTUwYmIwZDE0MDdlNTc5MjRiMGNjNWIzNmYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDZhN2Q1MTcxOTJjNTY4ZWUwOGE4NDVmNzNkMjk3ODhjZjAzNWMzMTQ1YjIxYWIzNDRkODA2MmVhOTQwMDAwMDQwYzk1NjgxOTVkNjdlYjZiMzk2ZmRiZTk3YmEyZTI3NjYyMmVmMDAyM2FmMDlmMjNlNmUwMjkyYWJiNjc4ZDkwMjA0MDMwMzA1MDEwNDA0MDAwMDAwMDQwMjAwMDIwYzAyMDAwMDAwMDEwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgICAgIGZlZTogMTAwMDAsXG4gICAgICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICAgICAgbWluZXJGZWU6ICcxMDAwMCcsXG4gICAgICAgICAgICAgIHNwZW5kQW1vdW50OiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICAgIHNwZW5kQW1vdW50czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNvaW5OYW1lOiAndHNvbCcsXG4gICAgICAgICAgICAgICAgICBhbW91bnRTdHJpbmc6ICcxNTQ3ODY0JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICBwYXlHb0ZlZTogJzAnLFxuICAgICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgYWRkcmVzczogJzhyUVhlVkVNckt2dFdDRUppckVNNmNLWW5iWnVUcVZUYnFSUGlNTUFKOFI0JyxcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiAxNTQ3ODY0LFxuICAgICAgICAgICAgICAgICAgd2FsbGV0OiAnNjMwNjhlZDRlZmE2M2EwMDA4NzdmMDJmJyxcbiAgICAgICAgICAgICAgICAgIHdhbGxldHM6IFsnNjMwNjhlZDRlZmE2M2EwMDA4NzdmMDJmJ10sXG4gICAgICAgICAgICAgICAgICBlbnRlcnByaXNlOiAnNjJkNzFhNmI4NjA2OGYwMDA4ZjAyOWZkJyxcbiAgICAgICAgICAgICAgICAgIGVudGVycHJpc2VzOiBbJzYyZDcxYTZiODYwNjhmMDAwOGYwMjlmZCddLFxuICAgICAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxNTQ3ODY0JyxcbiAgICAgICAgICAgICAgICAgIGNvaW5OYW1lOiAndHNvbCcsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgICAgIHdhbGxldFR5cGVzOiBbJ2hvdCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIGlucHV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiAxNTQ3ODY0LFxuICAgICAgICAgICAgICAgICAgYWRkcmVzczogJ0NtWXNOM2Y4YmNtNEJEa0ZKV05zdllnalJ4TVRMSDZ2YkpXTmZZZG1IN0dVJyxcbiAgICAgICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgICBhZGRyZXNzOiAnQ21Zc04zZjhiY200QkRrRkpXTnN2WWdqUnhNVExINnZiSldOZllkbUg3R1UnLFxuICAgICAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgIC8vIENhbGwgdGhlIGZ1bmN0aW9uIHRvIHRlc3RcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgd2FsbGV0T2JqLnNlbmRBY2NvdW50Q29uc29saWRhdGlvbnMoe1xuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6ICd0eCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgYWRkcmVzcycsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB2YWxpZCBhIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmZkNGIwZmE2ZCcsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICcwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAxMDIwNmFlZGEyNTNhMzMxZGU0ODk4MzgyNDZkZjkzODc5NDQwYWY4YzYyYWM0OTY3NjU4ZWRjMmJiNWQ1MmI5NzU5ZDkxYzk2MTcyMDQ0ZjEyMTdjMzc4NGU4ZjAyZjQ5ZTJjOGZjMzU5MWU4MTI5NGFiNTQzOTRmOWQyMmZkN2I3YThmNzRhOWRmMmI5NGFhNGI0YWRhMTIwMmRjMjg5MWJlMzY2NTAxZDBhY2I0YTAxY2EzZTAyZTdmZDZjMWY1MDVhN2QyNzM0ZjM5NTJmM2ViNGFlZmNmNmM3YTYwOTJlOTc5ZGQzZmU1NTYzY2NmYWNhMWNjOTI2NTJhMTVkZGQzOTMwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDZhN2Q1MTcxOTJjNTY4ZWUwOGE4NDVmNzNkMjk3ODhjZjAzNWMzMTQ1YjIxYWIzNDRkODA2MmVhOTQwMDAwMDQyOGRhZDQxYmJlZGViMzgwMTgzNzllNGNlZWI3ZTgwNzU3ZDc0ZGQwMGFlOGM0N2MzOGQ1OTc0NzczMzlhZDgwMjA0MDMwMzA1MDEwNDA0MDAwMDAwMDQwMjAwMDIwYzAyMDAwMDAwNTg5ZTE3MDAwMDAwMDAwMCcsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6IDEwMDAwLFxuICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgdHhJbmZvOiB7XG4gICAgICAgICAgbWluZXJGZWU6ICcxMDAwMCcsXG4gICAgICAgICAgc3BlbmRBbW91bnQ6ICcxNTQ3ODY0JyxcbiAgICAgICAgICBzcGVuZEFtb3VudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0c29sJyxcbiAgICAgICAgICAgICAgYW1vdW50U3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICc4clFYZVZFTXJLdnRXQ0VKaXJFTTZjS1luYlp1VHFWVGJxUlBpTU1BSjhSNCcsXG4gICAgICAgICAgICAgIHZhbHVlOiAxNTQ3ODY0LFxuICAgICAgICAgICAgICB3YWxsZXQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmYnLFxuICAgICAgICAgICAgICB3YWxsZXRzOiBbJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZiddLFxuICAgICAgICAgICAgICBlbnRlcnByaXNlOiAnNjJkNzFhNmI4NjA2OGYwMDA4ZjAyOWZkJyxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZXM6IFsnNjJkNzFhNmI4NjA2OGYwMDA4ZjAyOWZkJ10sXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldFR5cGU6ICdob3QnLFxuICAgICAgICAgICAgICB3YWxsZXRUeXBlczogWydob3QnXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdmFsdWU6IDE1NDc4NjQsXG4gICAgICAgICAgICAgIGFkZHJlc3M6ICdDbVlzTjNmOGJjbTRCRGtGSldOc3ZZZ2pSeE1UTEg2dmJKV05mWWRtSDdHVScsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTU0Nzg2NCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgIGFkZHJlc3M6ICdDbVlzTjNmOGJjbTRCRGtGSldOc3ZZZ2pSeE1UTEg2dmJKV05mWWRtSDdHVScsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHR5cGU6ICdTZW5kJyxcbiAgICAgICAgfSxcbiAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbW9ja2VkV2FsbGV0OiBQYXJ0aWFsPElXYWxsZXQ+ID0ge1xuICAgICAgICBjb2luU3BlY2lmaWM6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjcyA9IHtcbiAgICAgICAgICAgIHJvb3RBZGRyZXNzOiAnOHJRWGVWRU1yS3Z0V0NFSmlyRU02Y0tZbmJadVRxVlRicVJQaU1NQUo4UjQnLFxuICAgICAgICAgIH0gYXMgV2FsbGV0Q29pblNwZWNpZmljO1xuICAgICAgICAgIHJldHVybiBjcztcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhKGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIGJsb2NraGFzaDogJycsXG4gICAgICAgICAgICBmZWVQYXllcjogJycsXG4gICAgICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiBjb25zb2xpZGF0aW9uVHggYXMgdW5rbm93biBhcyBUcmFuc2FjdGlvblByZWJ1aWxkLFxuICAgICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCBhcyBJV2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uOiB7XG4gICAgICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgYXNzZXJ0LmZhaWwoJ1RyYW5zYWN0aW9uIHNob3VsZCBwYXNzIHZlcmlmaWNhdGlvbicpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzc2VydC5mYWlsKCdUcmFuc2FjdGlvbiBzaG91bGQgcGFzcyB2ZXJpZmljYXRpb24nKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdG9rZW4gY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25UeCA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICc0ZmRkMGNhZS0yNTYzLTQzYjEtYjVjZi05NDg2NTE1OGNhMTAnLFxuICAgICAgICB3YWxsZXRJZDogJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZmQ0YjBmYTZkJyxcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzAyYjdjMmM3ODI5ZWRlZDRlOGY5NDdjOTBlZDNiOWFmY2U3MWY2MTZlYjQ3ZGZjZmJmNGI3NjU3NzgxNDkwNjAwMTNhY2IzM2I5ZjY3ZmRkOWMyNTEyZjQ4ZmFjNGU0YzA0OWVhYjkzODI5YjY5NDA0ZjNiZDE2NmZlMzI0MmM5MDcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAyMDEwNDA5NmRhNjkwYmQ1NThmZDg2MzRhYzE0ZjE2NDVkODA5NWFmZDBjYWVhNTk1MzU3OGM1OTZlM2MwZGVhMzgzMDVlZTcyOThiZmFjNTUxMDFmMTc3NzM1NjU5ZDQyZWQ2YmU4OTBlZjNhMWQyMDRkOWUzM2YzMmUyNGM1NjM1MzI3Y2E2NmQxZmUwMDgyNmU1YTRmNzU5Zjg3YjI3OWMxYWVlMTljY2U1MzAxYWY0ZWQ2NmFlMTdkYjQ4YjIwMWVkNmMyYTBlOGEyOGJmNTY1NjI3ZjFhYjhhMzRiMWE5NWVlMWIwYTJhMzkwODRmMWYwZTJhY2IxYzM5NGIyMDE4NWQ4ZTBiMjI2NTdjOGQ5YzRjZTVmNjQ5NWVmYjY0MTBjMTk5MDExNTMwZjkwZTNhYjlkOGQxZTQyMDZmOWFlMGZmZWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYzVmOWZiMzJmNDkxMTFhYjIwYzMzZjI1OThmYzgzNmMxMTNlMjkxODgxYWMyMWVlMjkxNjkzOTQwMTEyNDRlNDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDAwNmRkZjZlMWQ3NjVhMTkzZDljYmUxNDZjZWViNzlhYzFjYjQ4NWVkNWY1YjM3OTEzYThjZjU4NTdlZmYwMGE5ZGUxM2M3NGQyYjRkOTQ4ZTE2MDhlYTZlZWJkYWZlNzViYzJmOTk1YWFkMTFiMjFkMWUyYzk0ZjJhMmQxMmY2ODAyMDUwMzAzMDcwMDA0MDQwMDAwMDAwODA0MDIwNjA0MDEwYTBjZTAwNzZiYjIwNDAwMDAwMDA2JyxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogMTAwMDAsXG4gICAgICAgICAgZmVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICB9LFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzhpTGEyNktTYmRwQlV6Tks3dVlxOEZ2eXV5QTVoNGs0ZXJESHNEY1BiSHVzJyxcbiAgICAgICAgICAgICAgdmFsdWU6IDIuMDE3MzIyOGUxMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnOFAya1g3VHloOWVTM1JLZGFCaHFiRXRRR0FYNThEWHpMN21oRFFBQkdYMmQnLFxuICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG1pbmVyRmVlOiAnMTAwMDAnLFxuICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ0hCeFpTaGNFODZVTW1GOTNLVU04ZVdKS3FlRVhpNWNxV0NMWUxNTWhxTVltJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICdzb2w6d2lmJyxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZToge1xuICAgICAgICAgICAgICAgICRvaWQ6ICc1NTUzYmE4YWU3YTVjNzcwMDY3MTk2NjEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBlbnRlcnByaXNlczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICRvaWQ6ICc1NTUzYmE4YWU3YTVjNzcwMDY3MTk2NjEnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHZhbHVlOiAyLjAxNzMyMjhlMTAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgICB3YWxsZXQ6IHtcbiAgICAgICAgICAgICAgICAkb2lkOiAnNjJmNGMzNzIwZDkyYzUwMDA4MjU3ZWI1JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgICAgICAgIHdhbGxldHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAkb2lkOiAnNjJmNGMzNzIwZDkyYzUwMDA4MjU3ZWI1JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBheUdvRmVlOiAnMCcsXG4gICAgICAgICAgc3BlbmRBbW91bnQ6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgc3BlbmRBbW91bnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudFN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICdzb2w6d2lmJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2NzEyZDdmZGE2ZGU0OTA2ZDY1OGMwNGFlYmJmOGY5YicsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldDogUGFydGlhbDxJV2FsbGV0PiA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY3MgPSB7XG4gICAgICAgICAgICByb290QWRkcmVzczogJ0hCeFpTaGNFODZVTW1GOTNLVU04ZVdKS3FlRVhpNWNxV0NMWUxNTWhxTVltJyxcbiAgICAgICAgICB9IGFzIFdhbGxldENvaW5TcGVjaWZpYztcbiAgICAgICAgICByZXR1cm4gY3M7XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIShhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICBibG9ja2hhc2g6ICcnLFxuICAgICAgICAgICAgZmVlUGF5ZXI6ICcnLFxuICAgICAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogY29uc29saWRhdGlvblR4IGFzIHVua25vd24gYXMgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgSVdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSkpXG4gICAgICAgICkge1xuICAgICAgICAgIGFzc2VydC5mYWlsKCdUcmFuc2FjdGlvbiBzaG91bGQgcGFzcyB2ZXJpZmljYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhc3NlcnQuZmFpbCgnVHJhbnNhY3Rpb24gc2hvdWxkIHBhc3MgdmVyaWZpY2F0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHNwb29mZWQgdG9rZW4gY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25UeCA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICc0ZmRkMGNhZS0yNTYzLTQzYjEtYjVjZi05NDg2NTE1OGNhMTAnLFxuICAgICAgICB3YWxsZXRJZDogJzYzMDY4ZWQ0ZWZhNjNhMDAwODc3ZjAyZmQ0YjBmYTZkJyxcbiAgICAgICAgdHhIZXg6XG4gICAgICAgICAgJzAyYjdjMmM3ODI5ZWRlZDRlOGY5NDdjOTBlZDNiOWFmY2U3MWY2MTZlYjQ3ZGZjZmJmNGI3NjU3NzgxNDkwNjAwMTNhY2IzM2I5ZjY3ZmRkOWMyNTEyZjQ4ZmFjNGU0YzA0OWVhYjkzODI5YjY5NDA0ZjNiZDE2NmZlMzI0MmM5MDcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAyMDEwNDA5NmRhNjkwYmQ1NThmZDg2MzRhYzE0ZjE2NDVkODA5NWFmZDBjYWVhNTk1MzU3OGM1OTZlM2MwZGVhMzgzMDVlZTcyOThiZmFjNTUxMDFmMTc3NzM1NjU5ZDQyZWQ2YmU4OTBlZjNhMWQyMDRkOWUzM2YzMmUyNGM1NjM1MzI3Y2E2NmQxZmUwMDgyNmU1YTRmNzU5Zjg3YjI3OWMxYWVlMTljY2U1MzAxYWY0ZWQ2NmFlMTdkYjQ4YjIwMWVkNmMyYTBlOGEyOGJmNTY1NjI3ZjFhYjhhMzRiMWE5NWVlMWIwYTJhMzkwODRmMWYwZTJhY2IxYzM5NGIyMDE4NWQ4ZTBiMjI2NTdjOGQ5YzRjZTVmNjQ5NWVmYjY0MTBjMTk5MDExNTMwZjkwZTNhYjlkOGQxZTQyMDZmOWFlMGZmZWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYzVmOWZiMzJmNDkxMTFhYjIwYzMzZjI1OThmYzgzNmMxMTNlMjkxODgxYWMyMWVlMjkxNjkzOTQwMTEyNDRlNDA2YTdkNTE3MTkyYzU2OGVlMDhhODQ1ZjczZDI5Nzg4Y2YwMzVjMzE0NWIyMWFiMzQ0ZDgwNjJlYTk0MDAwMDAwNmRkZjZlMWQ3NjVhMTkzZDljYmUxNDZjZWViNzlhYzFjYjQ4NWVkNWY1YjM3OTEzYThjZjU4NTdlZmYwMGE5ZGUxM2M3NGQyYjRkOTQ4ZTE2MDhlYTZlZWJkYWZlNzViYzJmOTk1YWFkMTFiMjFkMWUyYzk0ZjJhMmQxMmY2ODAyMDUwMzAzMDcwMDA0MDQwMDAwMDAwODA0MDIwNjA0MDEwYTBjZTAwNzZiYjIwNDAwMDAwMDA2JyxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogMTAwMDAsXG4gICAgICAgICAgZmVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICB9LFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJzhpTGEyNktTYmRwQlV6Tks3dVlxOEZ2eXV5QTVoNGs0ZXJESHNEY1BiSHVzJyxcbiAgICAgICAgICAgICAgdmFsdWU6IDIuMDE3MzIyOGUxMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnOFAya1g3VHloOWVTM1JLZGFCaHFiRXRRR0FYNThEWHpMN21oRFFBQkdYMmQnLFxuICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG1pbmVyRmVlOiAnMTAwMDAnLFxuICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ0hCeFpTaGNFODZVTW1GOTNLVU04ZVdKS3FlRVhpNWNxV0NMWUxNTWhxTVltJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICdzb2w6d2lmJyxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZToge1xuICAgICAgICAgICAgICAgICRvaWQ6ICc1NTUzYmE4YWU3YTVjNzcwMDY3MTk2NjEnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBlbnRlcnByaXNlczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICRvaWQ6ICc1NTUzYmE4YWU3YTVjNzcwMDY3MTk2NjEnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHZhbHVlOiAyLjAxNzMyMjhlMTAsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgICB3YWxsZXQ6IHtcbiAgICAgICAgICAgICAgICAkb2lkOiAnNjJmNGMzNzIwZDkyYzUwMDA4MjU3ZWI1JyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgICAgICAgIHdhbGxldHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAkb2lkOiAnNjJmNGMzNzIwZDkyYzUwMDA4MjU3ZWI1JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBheUdvRmVlOiAnMCcsXG4gICAgICAgICAgc3BlbmRBbW91bnQ6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgc3BlbmRBbW91bnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudFN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICdzb2w6d2lmJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0eXBlOiAnU2VuZCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2NzEyZDdmZGE2ZGU0OTA2ZDY1OGMwNGFlYmJmOGY5YicsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldDogUGFydGlhbDxJV2FsbGV0PiA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY3MgPSB7XG4gICAgICAgICAgICByb290QWRkcmVzczogJzhyUVhlVkVNckt2dFdDRUppckVNNmNLWW5iWnVUcVZUYnFSUGlNTUFKOFI0JyxcbiAgICAgICAgICB9IGFzIFdhbGxldENvaW5TcGVjaWZpYztcbiAgICAgICAgICByZXR1cm4gY3M7XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICBibG9ja2hhc2g6ICcnLFxuICAgICAgICAgICAgZmVlUGF5ZXI6ICcnLFxuICAgICAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogY29uc29saWRhdGlvblR4IGFzIHVua25vd24gYXMgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQgYXMgSVdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiAndHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIGFkZHJlc3MnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYmxpbmQgc2lnbmluZyB0b2tlbiBlbmFibGVtZW50IHByb3RlY3Rpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYXMgdmFsaWQgdGhlIGVuYWJsZXRva2VuIGludGVudCB3aGVuIHByZWJ1aWxkIHR4IG1hdGNocyB1c2VyIGludGVudCAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkUmF3LCB3YWxsZXREYXRhIH0gPSB0ZXN0RGF0YS5lbmFibGVUb2tlbkZpeHR1cmVzO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgY29uc3Qgc2FtZUludGVudFR4ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZFJhdyxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb246IHsgdmVyaWZ5VG9rZW5FbmFibGVtZW50OiB0cnVlIH0sXG4gICAgICB9IGFzIHVua25vd24gYXMgU29sVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTtcblxuICAgICAgc2FtZUludGVudFR4LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3duIGFuIGVycm9yIHdoZW4gdGFtcGVyZWQgcHJlYnVpbGQgdHggdHlwZSAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkUmF3LCBzZW5kVHhIZXgsIHdhbGxldERhdGEgfSA9IHRlc3REYXRhLmVuYWJsZVRva2VuRml4dHVyZXM7XG4gICAgICBjb25zdCB0YW1wZXJlZFR4UHJlYnVpbGQgPSB7IC4uLnR4UHJlYnVpbGRSYXcsIHR4SGV4OiBzZW5kVHhIZXggfTtcblxuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHRhbXBlcmVkVHhQcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjogeyB2ZXJpZnlUb2tlbkVuYWJsZW1lbnQ6IHRydWUgfSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgU29sVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKSxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAnSW52YWxpZCB0cmFuc2FjdGlvbiB0eXBlIG9uIHRva2VuIGVuYWJsZW1lbnQ6IGV4cGVjdGVkIFwiQXNzb2NpYXRlZFRva2VuQWNjb3VudEluaXRpYWxpemF0aW9uXCIsIGdvdCBcIlNlbmRcIi4nLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdGhhdCB0b2tlbk5hbWUgbWF0Y2hlcyBiZXR3ZWVuIHVzZXIgaW50ZW50IGFuZCBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkUmF3LCB3cm9uZ1Rva2VuTmFtZVR4SGV4LCB3YWxsZXREYXRhIH0gPSB0ZXN0RGF0YS5lbmFibGVUb2tlbkZpeHR1cmVzO1xuICAgICAgY29uc3QgdGFtcGVyZWRUeFByZWJ1aWxkID0geyAuLi50eFByZWJ1aWxkUmF3LCB0eEhleDogd3JvbmdUb2tlbk5hbWVUeEhleCB9O1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHRhbXBlcmVkVHhQcmVidWlsZCxcbiAgICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjogeyB2ZXJpZnlUb2tlbkVuYWJsZW1lbnQ6IHRydWUgfSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgU29sVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKSxcbiAgICAgICAgeyBtZXNzYWdlOiAnSW52YWxpZCB0b2tlbiBuYW1lOiBleHBlY3RlZCB0c29sOnJheSwgZ290IHRzb2w6dDIybWludCBvbiB0b2tlbiBlbmFibGVtZW50IHR4JyB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdGhhdCB0b2tlbkFkZHIgbWF0Y2hlcyBiZXR3ZWVuIHVzZXIgaW50ZW50IGFuZCBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkUmF3LCB3cm9uZ0FkZHJUeEhleCwgd2FsbGV0RGF0YSB9ID0gdGVzdERhdGEuZW5hYmxlVG9rZW5GaXh0dXJlcztcbiAgICAgIGNvbnN0IHRhbXBlcmVkVHhQcmVidWlsZCA9IHsgLi4udHhQcmVidWlsZFJhdywgdHhIZXg6IHdyb25nQWRkclR4SGV4IH07XG5cbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgIGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgICAgdHhQcmVidWlsZDogdGFtcGVyZWRUeFByZWJ1aWxkLFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uOiB7IHZlcmlmeVRva2VuRW5hYmxlbWVudDogdHJ1ZSB9LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBTb2xWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMpLFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICdJbnZhbGlkIHRva2VuIGFkZHJlc3M6IGV4cGVjdGVkIDRiVFl2dnYySGs0djJrUVc4SFpGRlM0U3pZUHp0UXNodzlHbTFzdVhtYUJqLCBnb3QgRzFMRWdBTkF3S283YjhOZnhUc016cmJCWURrWHFpNVJFVkpZOHRock1SUW0gb24gdG9rZW4gZW5hYmxlbWVudCB0eCcsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgc2VuZFRva2VuRW5hYmxlbWVudCBjYWxsIG9uIHNwb29mZWQgZGF0YScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHsgc2VuZFRva2VuRW5hYmxlbWVudFBheWxvYWQsIHdhbGxldERhdGEsIHdyb25nVG9rZW5OYW1lVHhIZXggfSA9IHRlc3REYXRhLmVuYWJsZVRva2VuRml4dHVyZXM7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoJy9hcGkvdjIvdHNvbC9rZXkvNjhiYWZlZDU4ODY3MWNmOTRlZDhhNWRiYmE4ODJhZDMnKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgIHdhbGxldC5zZW5kVG9rZW5FbmFibGVtZW50KHtcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjogeyB2ZXJpZnlUb2tlbkVuYWJsZW1lbnQ6IHRydWUgfSxcbiAgICAgICAgICAgIC4uLnNlbmRUb2tlbkVuYWJsZW1lbnRQYXlsb2FkLFxuICAgICAgICAgICAgcHJlYnVpbGRUeDogeyAuLi5zZW5kVG9rZW5FbmFibGVtZW50UGF5bG9hZC5wcmVidWlsZFR4LCB0eEhleDogd3JvbmdUb2tlbk5hbWVUeEhleCB9LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBQcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpLFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTogJ0ludmFsaWQgdG9rZW4gbmFtZTogZXhwZWN0ZWQgdHNvbDpyYXksIGdvdCB0c29sOnQyMm1pbnQgb24gdG9rZW4gZW5hYmxlbWVudCB0eCcsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1dhbGxldEFkZHJlc3MnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdmFsaWQgd2FsbGV0IGFkZHJlc3Mgd2l0aCBjb3JyZWN0IGtleWNoYWluIGFuZCBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnN1lBZXNmd1BrNDFWQ2hVZ3I2NWJtOEZFZXA3eW1XcUxTVzVycFlCNXpaUFknO1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPVxuICAgICAgICAnOGVhMzJlY2FjZmM4M2VmZmJkMmUyNzkwZWU0NGZhN2M1OWI0ZDg2YzI5YTEyZjA5ZmI2MTNkODE5NWY5M2Y0ZTIxODc1Y2FkM2I5OGFkYWRhNDBjMDQwYzU0YzM1Njk0NjdkZjQxYTAyMDg4MWE2MTg0MDk2Mzc4NzAxODYyYmQnO1xuICAgICAgY29uc3QgaW5kZXggPSAnMSc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7IGtleWNoYWlucywgYWRkcmVzcywgaW5kZXggfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgYWRkcmVzcyB3aXRoIGluY29ycmVjdCBrZXljaGFpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnN1lBZXNmd1BrNDFWQ2hVZ3I2NWJtOEZFZXA3eW1XcUxTVzVycFlCNXpaUFknO1xuICAgICAgY29uc3Qgd3JvbmdLZXljaGFpbiA9XG4gICAgICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJztcbiAgICAgIGNvbnN0IGluZGV4ID0gJzEnO1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW3sgaWQ6ICcxJywgdHlwZTogJ3RzcycgYXMgY29uc3QsIGNvbW1vbktleWNoYWluOiB3cm9uZ0tleWNoYWluIH1dO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MoeyBrZXljaGFpbnMsIGFkZHJlc3MsIGluZGV4IH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6IGBhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogJHthZGRyZXNzfSBpcyBub3QgYSB3YWxsZXQgYWRkcmVzc2AsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGFkZHJlc3Mgd2l0aCBpbmNvcnJlY3QgaW5kZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzdZQWVzZndQazQxVkNoVWdyNjVibThGRWVwN3ltV3FMU1c1cnBZQjV6WlBZJztcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzhlYTMyZWNhY2ZjODNlZmZiZDJlMjc5MGVlNDRmYTdjNTliNGQ4NmMyOWExMmYwOWZiNjEzZDgxOTVmOTNmNGUyMTg3NWNhZDNiOThhZGFkYTQwYzA0MGM1NGMzNTY5NDY3ZGY0MWEwMjA4ODFhNjE4NDA5NjM3ODcwMTg2MmJkJztcbiAgICAgIGNvbnN0IHdyb25nSW5kZXggPSAnOTk5JztcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGlkOiAnMScsIHR5cGU6ICd0c3MnIGFzIGNvbnN0LCBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzLCBpbmRleDogd3JvbmdJbmRleCB9KSwge1xuICAgICAgICBtZXNzYWdlOiBgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6ICR7YWRkcmVzc30gaXMgbm90IGEgd2FsbGV0IGFkZHJlc3NgLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzcyA9ICdpbnZhbGlkYWRkcmVzcyc7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICc4ZWEzMmVjYWNmYzgzZWZmYmQyZTI3OTBlZTQ0ZmE3YzU5YjRkODZjMjlhMTJmMDlmYjYxM2Q4MTk1ZjkzZjRlMjE4NzVjYWQzYjk4YWRhZGE0MGMwNDBjNTRjMzU2OTQ2N2RmNDFhMDIwODgxYTYxODQwOTYzNzg3MDE4NjJiZCc7XG4gICAgICBjb25zdCBpbmRleCA9ICcxJztcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFt7IGlkOiAnMScsIHR5cGU6ICd0c3MnIGFzIGNvbnN0LCBjb21tb25LZXljaGFpbiB9XTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzOiBpbnZhbGlkQWRkcmVzcywgaW5kZXggfSksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHtpbnZhbGlkQWRkcmVzc31gLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhZGRyZXNzIHdpdGggZGVyaXZhdGlvbiBwcmVmaXggZm9yIFNNQyB3YWxsZXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gQWRkcmVzcyBkZXJpdmVkIHdpdGggZGVyaXZhdGlvbiBwcmVmaXggbS85OTk5OTkvMTQ4MjQyMzU1LzIzOTMzNjg0NS8xXG4gICAgICBjb25zdCBhZGRyZXNzID0gJ0NDNzE1UTkyQzh2dUVGVDV4dWpFNTVEbzZCa1dSZHBEdnI3Vmg4aVVOVUJ3JztcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzhlYTMyZWNhY2ZjODNlZmZiZDJlMjc5MGVlNDRmYTdjNTliNGQ4NmMyOWExMmYwOWZiNjEzZDgxOTVmOTNmNGUyMTg3NWNhZDNiOThhZGFkYTQwYzA0MGM1NGMzNTY5NDY3ZGY0MWEwMjA4ODFhNjE4NDA5NjM3ODcwMTg2MmJkJztcbiAgICAgIGNvbnN0IGluZGV4ID0gJzEnO1xuICAgICAgY29uc3QgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCA9ICdzbWMtdGVzdC1zZWVkLTEyMyc7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbeyBpZDogJzEnLCB0eXBlOiAndHNzJyBhcyBjb25zdCwgY29tbW9uS2V5Y2hhaW4gfV07XG5cbiAgICAgIC8vIFRoaXMgdGVzdCB2ZXJpZmllcyB0aGF0IGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQgaXMgYWNjZXB0ZWQgYXMgYSBwYXJhbWV0ZXJcbiAgICAgIC8vIGFuZCB0aGUgdmVyaWZpY2F0aW9uIGZ1bmN0aW9uIGNvcnJlY3RseSBjb21wdXRlcyB0aGUgZGVyaXZhdGlvbiBwcmVmaXggaW50ZXJuYWxseVxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHsga2V5Y2hhaW5zLCBhZGRyZXNzLCBpbmRleCwgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRBZGRyZXNzRnJvbVB1YmxpY0tleScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgcHVibGljIGtleSB0byBiYXNlNTggYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9ICc2MTIyMGE5Mzk0ODAyYjFkMWRmMzdiMzVmN2EzMTk3OTcwZjQ4MDgxMDkyY2VlMDExZmM5OGY3YjcxYjJiZDQzJztcbiAgICAgIGNvbnN0IGV4cGVjdGVkQWRkcmVzcyA9ICc3WUFlc2Z3UGs0MVZDaFVncjY1Ym04RkVlcDd5bVdxTFNXNXJwWUI1elpQWSc7XG5cbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBiYXNlY29pbi5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShwdWJsaWNLZXkpO1xuICAgICAgYWRkcmVzcy5zaG91bGQuZXF1YWwoZXhwZWN0ZWRBZGRyZXNzKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|