@bitgo-beta/sdk-coin-eth 4.4.1-beta.142 → 4.4.1-beta.1421

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/dist/src/erc20Token.d.ts +13 -5
  2. package/dist/src/erc20Token.d.ts.map +1 -1
  3. package/dist/src/erc20Token.js +65 -27
  4. package/dist/src/erc721Token.d.ts +60 -0
  5. package/dist/src/erc721Token.d.ts.map +1 -0
  6. package/dist/src/erc721Token.js +334 -0
  7. package/dist/src/eth.d.ts +23 -533
  8. package/dist/src/eth.d.ts.map +1 -1
  9. package/dist/src/eth.js +208 -1622
  10. package/dist/src/gteth.d.ts +0 -4
  11. package/dist/src/gteth.d.ts.map +1 -1
  12. package/dist/src/gteth.js +1 -11
  13. package/dist/src/hteth.d.ts +8 -0
  14. package/dist/src/hteth.d.ts.map +1 -0
  15. package/dist/src/hteth.js +14 -0
  16. package/dist/src/index.d.ts +2 -0
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/index.js +8 -2
  19. package/dist/src/lib/index.d.ts +5 -13
  20. package/dist/src/lib/index.d.ts.map +1 -1
  21. package/dist/src/lib/index.js +18 -30
  22. package/dist/src/lib/messages/index.d.ts +3 -0
  23. package/dist/src/lib/messages/index.d.ts.map +1 -0
  24. package/dist/src/lib/messages/index.js +6 -0
  25. package/dist/src/lib/transactionBuilder.d.ts +9 -213
  26. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  27. package/dist/src/lib/transactionBuilder.js +18 -677
  28. package/dist/src/lib/transferBuilder.d.ts +2 -50
  29. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  30. package/dist/src/lib/transferBuilder.js +3 -199
  31. package/dist/src/lib/transferBuilders/index.d.ts +2 -3
  32. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
  33. package/dist/src/lib/transferBuilders/index.js +6 -14
  34. package/dist/src/lib/walletUtil.d.ts +0 -25
  35. package/dist/src/lib/walletUtil.d.ts.map +1 -1
  36. package/dist/src/lib/walletUtil.js +2 -27
  37. package/dist/src/register.d.ts.map +1 -1
  38. package/dist/src/register.js +7 -1
  39. package/dist/src/teth.d.ts +0 -3
  40. package/dist/src/teth.d.ts.map +1 -1
  41. package/dist/src/teth.js +1 -8
  42. package/dist/test/fixtures/eth.d.ts +39 -0
  43. package/dist/test/fixtures/eth.d.ts.map +1 -0
  44. package/dist/test/fixtures/eth.js +262 -0
  45. package/dist/test/resources/erc1155Abi.d.ts +40 -0
  46. package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
  47. package/dist/test/resources/erc1155Abi.js +329 -0
  48. package/dist/test/resources/erc721Abi.d.ts +12 -0
  49. package/dist/test/resources/erc721Abi.d.ts.map +1 -0
  50. package/dist/test/resources/erc721Abi.js +34 -0
  51. package/dist/test/resources/eth.d.ts +51 -0
  52. package/dist/test/resources/eth.d.ts.map +1 -0
  53. package/dist/test/resources/eth.js +72 -0
  54. package/dist/test/resources/nftEncodings.d.ts +4 -0
  55. package/dist/test/resources/nftEncodings.d.ts.map +1 -0
  56. package/dist/test/resources/nftEncodings.js +7 -0
  57. package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
  58. package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
  59. package/dist/test/resources/walletSimpleAbi.js +44 -0
  60. package/dist/test/unit/eth.d.ts +2 -0
  61. package/dist/test/unit/eth.d.ts.map +1 -0
  62. package/dist/test/unit/eth.js +1810 -0
  63. package/dist/test/unit/ethWallet.d.ts +2 -0
  64. package/dist/test/unit/ethWallet.d.ts.map +1 -0
  65. package/dist/test/unit/ethWallet.js +472 -0
  66. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
  67. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
  68. package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
  69. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
  70. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
  71. package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -0
  72. package/dist/test/unit/getBuilder.d.ts +3 -0
  73. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  74. package/dist/test/unit/getBuilder.js +10 -0
  75. package/dist/test/unit/keyPair.d.ts +2 -0
  76. package/dist/test/unit/keyPair.d.ts.map +1 -0
  77. package/dist/test/unit/keyPair.js +175 -0
  78. package/dist/test/unit/transaction.d.ts +2 -0
  79. package/dist/test/unit/transaction.d.ts.map +1 -0
  80. package/dist/test/unit/transaction.js +96 -0
  81. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  82. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  83. package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
  84. package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
  85. package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
  86. package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
  87. package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
  88. package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
  89. package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
  90. package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
  91. package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
  92. package/dist/test/unit/transactionBuilder/flushTokens.js +281 -0
  93. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  94. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  95. package/dist/test/unit/transactionBuilder/send.js +331 -0
  96. package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
  97. package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
  98. package/dist/test/unit/transactionBuilder/sendNFT.js +250 -0
  99. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
  100. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
  101. package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
  102. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  103. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  104. package/dist/test/unit/transactionBuilder/walletInitialization.js +423 -0
  105. package/dist/test/unit/transferBuilder.d.ts +2 -0
  106. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  107. package/dist/test/unit/transferBuilder.js +124 -0
  108. package/dist/test/unit/utils.d.ts +2 -0
  109. package/dist/test/unit/utils.d.ts.map +1 -0
  110. package/dist/test/unit/utils.js +74 -0
  111. package/dist/tsconfig.tsbuildinfo +1 -0
  112. package/package.json +16 -18
  113. package/.eslintignore +0 -5
  114. package/.mocharc.yml +0 -8
  115. package/CHANGELOG.md +0 -354
  116. package/dist/src/lib/contractCall.d.ts +0 -8
  117. package/dist/src/lib/contractCall.d.ts.map +0 -1
  118. package/dist/src/lib/contractCall.js +0 -17
  119. package/dist/src/lib/iface.d.ts +0 -130
  120. package/dist/src/lib/iface.d.ts.map +0 -1
  121. package/dist/src/lib/iface.js +0 -8
  122. package/dist/src/lib/keyPair.d.ts +0 -26
  123. package/dist/src/lib/keyPair.d.ts.map +0 -1
  124. package/dist/src/lib/keyPair.js +0 -66
  125. package/dist/src/lib/transaction.d.ts +0 -64
  126. package/dist/src/lib/transaction.d.ts.map +0 -1
  127. package/dist/src/lib/transaction.js +0 -137
  128. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts +0 -47
  129. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts.map +0 -1
  130. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.js +0 -113
  131. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts +0 -14
  132. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts.map +0 -1
  133. package/dist/src/lib/transferBuilders/transferBuilderERC1155.js +0 -83
  134. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts +0 -13
  135. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts.map +0 -1
  136. package/dist/src/lib/transferBuilders/transferBuilderERC721.js +0 -68
  137. package/dist/src/lib/types.d.ts +0 -39
  138. package/dist/src/lib/types.d.ts.map +0 -1
  139. package/dist/src/lib/types.js +0 -137
  140. package/dist/src/lib/utils.d.ts +0 -228
  141. package/dist/src/lib/utils.d.ts.map +0 -1
  142. package/dist/src/lib/utils.js +0 -577
@@ -0,0 +1,1810 @@
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 sdk_test_1 = require("@bitgo-beta/sdk-test");
40
+ const nock_1 = __importDefault(require("nock"));
41
+ const sinon_1 = __importDefault(require("sinon"));
42
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
43
+ const secp256k1 = __importStar(require("secp256k1"));
44
+ const superagent_1 = __importDefault(require("superagent"));
45
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
46
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
47
+ const src_1 = require("../../src");
48
+ const assert_1 = __importDefault(require("assert"));
49
+ const getBuilder_1 = require("./getBuilder");
50
+ const testData = __importStar(require("../resources/eth"));
51
+ const mockData = __importStar(require("../fixtures/eth"));
52
+ const should_1 = __importDefault(require("should"));
53
+ const ethMultiSigBackupKey_1 = require("./fixtures/ethMultiSigBackupKey");
54
+ const ethTssBackupKey_1 = require("./fixtures/ethTssBackupKey");
55
+ nock_1.default.enableNetConnect();
56
+ describe('ETH:', function () {
57
+ let bitgo;
58
+ let hopTxBitgoSignature;
59
+ let sandbox;
60
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
61
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
62
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
63
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
64
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
65
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
66
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
67
+ before(function () {
68
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
69
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
70
+ if (!bitgoKey.privateKey) {
71
+ throw new Error('no privateKey');
72
+ }
73
+ const bitgoXpub = bitgoKey.neutered().toBase58();
74
+ hopTxBitgoSignature =
75
+ '0xaa' +
76
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
77
+ const env = 'test';
78
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
79
+ src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
80
+ bitgo.safeRegister(name, coinConstructor);
81
+ });
82
+ bitgo.safeRegister('teth', src_1.Teth.createInstance);
83
+ bitgo.safeRegister('hteth', src_1.Hteth.createInstance);
84
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
85
+ bitgo.initializeTestVars();
86
+ sandbox = sinon_1.default.createSandbox();
87
+ });
88
+ after(function () {
89
+ nock_1.default.cleanAll();
90
+ sandbox.restore();
91
+ });
92
+ describe('EIP1559', function () {
93
+ it('should sign a transaction with EIP1559 fee params', async function () {
94
+ const coin = bitgo.coin('teth');
95
+ const userKeychain = {
96
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
97
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
98
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
99
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
100
+ };
101
+ const halfSignedTransaction = await coin.signTransaction({
102
+ txPrebuild: {
103
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
104
+ isBatch: false,
105
+ recipients: [
106
+ {
107
+ amount: '42',
108
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
109
+ },
110
+ ],
111
+ expireTime: 1627949214,
112
+ contractSequenceId: 12,
113
+ gasLimit: undefined,
114
+ gasPrice: undefined,
115
+ hopTransaction: undefined,
116
+ backupKeyNonce: undefined,
117
+ sequenceId: undefined,
118
+ nextContractSequenceId: 0,
119
+ },
120
+ prv: userKeychain.prv,
121
+ });
122
+ halfSignedTransaction.halfSigned.eip1559.maxPriorityFeePerGas.should.equal(10);
123
+ halfSignedTransaction.halfSigned.eip1559.maxFeePerGas.should.equal(10);
124
+ });
125
+ it('should sign a transaction with EIP1559 fee params for CCR', async function () {
126
+ const coin = bitgo.coin('hteth');
127
+ const signTransaction = sinon_1.default.spy(src_1.AbstractEthLikeNewCoins.prototype, 'signTransaction');
128
+ const userKeychain = {
129
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
130
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
131
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
132
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
133
+ };
134
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
135
+ txBuilder.type(sdk_core_1.TransactionType.Send);
136
+ txBuilder.fee({
137
+ fee: '10',
138
+ gasLimit: '1000',
139
+ });
140
+ const key = testData.KEYPAIR_PRV.getKeys().prv;
141
+ const transferBuilder = txBuilder.transfer();
142
+ transferBuilder
143
+ .amount('0')
144
+ .to('0x19645032c7f1533395d44a629462e751084d3e4c')
145
+ .expirationTime(1590066728)
146
+ .contractSequenceId(5)
147
+ .key(key);
148
+ txBuilder.contract(address1);
149
+ const tx = await txBuilder.build();
150
+ const halfSignedTransaction = await coin.signTransaction({
151
+ txPrebuild: {
152
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
153
+ isBatch: false,
154
+ recipients: [
155
+ {
156
+ amount: '42',
157
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
158
+ },
159
+ ],
160
+ expireTime: 1627949214,
161
+ contractSequenceId: 12,
162
+ gasLimit: undefined,
163
+ gasPrice: undefined,
164
+ hopTransaction: undefined,
165
+ backupKeyNonce: undefined,
166
+ sequenceId: undefined,
167
+ nextContractSequenceId: 0,
168
+ txHex: tx.toBroadcastFormat(),
169
+ },
170
+ prv: userKeychain.prv,
171
+ isEvmBasedCrossChainRecovery: true,
172
+ });
173
+ (0, assert_1.default)(halfSignedTransaction.halfSigned.txHex);
174
+ assert_1.default.strictEqual(halfSignedTransaction.halfSigned.eip1559.maxFeePerGas, 10);
175
+ sandbox.assert.calledOnce(signTransaction);
176
+ });
177
+ });
178
+ describe('Transaction Verification', function () {
179
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
180
+ const coin = bitgo.coin('teth');
181
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
182
+ const txParams = {
183
+ recipients: [{ amount: '1000000000000', address: address1 }],
184
+ wallet: wallet,
185
+ walletPassphrase: 'fakeWalletPassphrase',
186
+ };
187
+ const txPrebuild = {
188
+ recipients: [{ amount: '1000000000000', address: address1 }],
189
+ nextContractSequenceId: 0,
190
+ gasPrice: 20000000000,
191
+ gasLimit: 500000,
192
+ isBatch: false,
193
+ coin: 'teth',
194
+ wallet: 'fakeWalletId',
195
+ walletContractAddress: 'fakeWalletContractAddress',
196
+ };
197
+ const verification = {};
198
+ const isTransactionVerified = await coin.verifyTransaction({
199
+ txParams,
200
+ txPrebuild: txPrebuild,
201
+ wallet,
202
+ verification,
203
+ });
204
+ isTransactionVerified.should.equal(true);
205
+ });
206
+ it('should verify a batch txPrebuild from the bitgo server that matches the client txParams', async function () {
207
+ const coin = bitgo.coin('teth');
208
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
209
+ const txParams = {
210
+ recipients: [
211
+ { amount: '1000000000000', address: address1 },
212
+ { amount: '2500000000000', address: address2 },
213
+ ],
214
+ wallet: wallet,
215
+ walletPassphrase: 'fakeWalletPassphrase',
216
+ };
217
+ const txPrebuild = {
218
+ recipients: [
219
+ { amount: '3500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
220
+ ],
221
+ nextContractSequenceId: 0,
222
+ gasPrice: 20000000000,
223
+ gasLimit: 500000,
224
+ isBatch: true,
225
+ coin: 'teth',
226
+ walletId: 'fakeWalletId',
227
+ walletContractAddress: 'fakeWalletContractAddress',
228
+ };
229
+ const verification = {};
230
+ const isTransactionVerified = await coin.verifyTransaction({
231
+ txParams,
232
+ txPrebuild: txPrebuild,
233
+ wallet,
234
+ verification,
235
+ });
236
+ isTransactionVerified.should.equal(true);
237
+ });
238
+ it('should verify ENS address resolution changing recipient address in client txParams', async function () {
239
+ const coin = bitgo.coin('teth');
240
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
241
+ const txParams = {
242
+ recipients: [{ amount: '1000000000000', address: 'bitgotestwallet.eth' }],
243
+ wallet: wallet,
244
+ walletPassphrase: 'fakeWalletPassphrase',
245
+ };
246
+ const txPrebuild = {
247
+ recipients: [{ amount: '1000000000000', address: '0x40a663963810449d6e72533657a74f112c3b901a' }],
248
+ nextContractSequenceId: 0,
249
+ gasPrice: 20000000000,
250
+ gasLimit: 500000,
251
+ isBatch: false,
252
+ coin: 'teth',
253
+ walletId: 'fakeWalletId',
254
+ walletContractAddress: 'fakeWalletContractAddress',
255
+ };
256
+ const verification = {};
257
+ const isTransactionVerified = await coin.verifyTransaction({
258
+ txParams,
259
+ txPrebuild: txPrebuild,
260
+ wallet,
261
+ verification,
262
+ });
263
+ isTransactionVerified.should.equal(true);
264
+ });
265
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
266
+ const coin = bitgo.coin('teth');
267
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
268
+ const txParams = {
269
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
270
+ wallet: wallet,
271
+ walletPassphrase: 'fakeWalletPassphrase',
272
+ hop: true,
273
+ };
274
+ const txPrebuild = {
275
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
276
+ nextContractSequenceId: 0,
277
+ gasPrice: 20000000000,
278
+ gasLimit: 500000,
279
+ isBatch: false,
280
+ coin: 'teth',
281
+ walletId: 'fakeWalletId',
282
+ walletContractAddress: 'fakeWalletContractAddress',
283
+ hopTransaction: {
284
+ tx: hopTx,
285
+ id: hopTxid,
286
+ signature: hopTxBitgoSignature,
287
+ paymentId: '2773928196',
288
+ gasPrice: 20000000000,
289
+ gasLimit: 500000,
290
+ amount: '1000000000000000',
291
+ recipient: hopDestinationAddress,
292
+ nonce: 0,
293
+ userReqSig: userReqSig,
294
+ gasPriceMax: 500000000000,
295
+ },
296
+ };
297
+ const verification = {};
298
+ const isTransactionVerified = await coin.verifyTransaction({
299
+ txParams,
300
+ txPrebuild: txPrebuild,
301
+ wallet,
302
+ verification,
303
+ });
304
+ isTransactionVerified.should.equal(true);
305
+ });
306
+ it('should reject when client txParams are missing', async function () {
307
+ const coin = bitgo.coin('teth');
308
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
309
+ const txParams = null;
310
+ const txPrebuild = {
311
+ recipients: [{ amount: '1000000000000', address: address1 }],
312
+ nextContractSequenceId: 0,
313
+ gasPrice: 20000000000,
314
+ gasLimit: 500000,
315
+ isBatch: false,
316
+ coin: 'teth',
317
+ walletId: 'fakeWalletId',
318
+ walletContractAddress: 'fakeWalletContractAddress',
319
+ };
320
+ const verification = {};
321
+ await coin
322
+ .verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
323
+ .should.be.rejectedWith('missing params');
324
+ });
325
+ it('should reject txPrebuild that is both batch and hop', async function () {
326
+ const coin = bitgo.coin('teth');
327
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
328
+ const txParams = {
329
+ recipients: [
330
+ { amount: '1000000000000', address: address1 },
331
+ { amount: '2500000000000', address: address2 },
332
+ ],
333
+ wallet: wallet,
334
+ walletPassphrase: 'fakeWalletPassphrase',
335
+ hop: true,
336
+ };
337
+ const txPrebuild = {
338
+ recipients: [{ amount: '3500000000000', address: address1 }],
339
+ nextContractSequenceId: 0,
340
+ gasPrice: 20000000000,
341
+ gasLimit: 500000,
342
+ isBatch: true,
343
+ coin: 'teth',
344
+ walletId: 'fakeWalletId',
345
+ walletContractAddress: 'fakeWalletContractAddress',
346
+ hopTransaction: {
347
+ tx: hopTx,
348
+ id: hopTxid,
349
+ signature: hopTxBitgoSignature,
350
+ paymentId: '2773928196',
351
+ gasPrice: 20000000000,
352
+ gasLimit: 500000,
353
+ amount: '1000000000000000',
354
+ recipient: hopDestinationAddress,
355
+ nonce: 0,
356
+ userReqSig: userReqSig,
357
+ gasPriceMax: 500000000000,
358
+ },
359
+ };
360
+ const verification = {};
361
+ await coin
362
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
363
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
364
+ });
365
+ it('should reject a txPrebuild with more than one recipient', async function () {
366
+ const coin = bitgo.coin('teth');
367
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
368
+ const txParams = {
369
+ recipients: [
370
+ { amount: '1000000000000', address: address1 },
371
+ { amount: '2500000000000', address: address2 },
372
+ ],
373
+ wallet: wallet,
374
+ walletPassphrase: 'fakeWalletPassphrase',
375
+ };
376
+ const txPrebuild = {
377
+ recipients: [
378
+ { amount: '1000000000000', address: address1 },
379
+ { amount: '2500000000000', address: address2 },
380
+ ],
381
+ nextContractSequenceId: 0,
382
+ gasPrice: 20000000000,
383
+ gasLimit: 500000,
384
+ isBatch: true,
385
+ coin: 'teth',
386
+ walletId: 'fakeWalletId',
387
+ walletContractAddress: 'fakeWalletContractAddress',
388
+ };
389
+ const verification = {};
390
+ await coin
391
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
392
+ .should.be.rejectedWith(`teth doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
393
+ });
394
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
395
+ const coin = bitgo.coin('teth');
396
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
397
+ const txParams = {
398
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
399
+ wallet: wallet,
400
+ walletPassphrase: 'fakeWalletPassphrase',
401
+ hop: true,
402
+ };
403
+ const txPrebuild = {
404
+ recipients: [{ amount: '5000000000000000', address: address1 }],
405
+ nextContractSequenceId: 0,
406
+ gasPrice: 20000000000,
407
+ gasLimit: 500000,
408
+ isBatch: false,
409
+ coin: 'teth',
410
+ walletId: 'fakeWalletId',
411
+ walletContractAddress: 'fakeWalletContractAddress',
412
+ hopTransaction: {
413
+ tx: hopTx,
414
+ id: hopTxid,
415
+ signature: hopTxBitgoSignature,
416
+ paymentId: '0',
417
+ gasPrice: 20000000000,
418
+ gasLimit: 500000,
419
+ amount: '1000000000000000',
420
+ recipient: hopDestinationAddress,
421
+ nonce: 0,
422
+ userReqSig: userReqSig,
423
+ gasPriceMax: 500000000000,
424
+ },
425
+ };
426
+ const verification = {};
427
+ await coin
428
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
429
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
430
+ });
431
+ it('should reject a batch txPrebuild from the bitgo server with the wrong total amount', async function () {
432
+ const coin = bitgo.coin('teth');
433
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
434
+ const txParams = {
435
+ recipients: [
436
+ { amount: '1000000000000', address: address1 },
437
+ { amount: '2500000000000', address: address2 },
438
+ ],
439
+ wallet: wallet,
440
+ walletPassphrase: 'fakeWalletPassphrase',
441
+ };
442
+ const txPrebuild = {
443
+ recipients: [
444
+ { amount: '5500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
445
+ ],
446
+ nextContractSequenceId: 0,
447
+ gasPrice: 20000000000,
448
+ gasLimit: 500000,
449
+ isBatch: true,
450
+ coin: 'teth',
451
+ walletId: 'fakeWalletId',
452
+ walletContractAddress: 'fakeWalletContractAddress',
453
+ };
454
+ const verification = {};
455
+ await coin
456
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
457
+ .should.be.rejectedWith('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
458
+ });
459
+ it('should reject a batch txPrebuild from the bitgo server that does not send to the batcher contract address', async function () {
460
+ const coin = bitgo.coin('teth');
461
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
462
+ const txParams = {
463
+ recipients: [
464
+ { amount: '1000000000000', address: address1 },
465
+ { amount: '2500000000000', address: address2 },
466
+ ],
467
+ wallet: wallet,
468
+ walletPassphrase: 'fakeWalletPassphrase',
469
+ };
470
+ const txPrebuild = {
471
+ recipients: [{ amount: '3500000000000', address: hopContractAddress }],
472
+ nextContractSequenceId: 0,
473
+ gasPrice: 20000000000,
474
+ gasLimit: 500000,
475
+ isBatch: true,
476
+ coin: 'teth',
477
+ walletId: 'fakeWalletId',
478
+ walletContractAddress: 'fakeWalletContractAddress',
479
+ };
480
+ const verification = {};
481
+ await coin
482
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
483
+ .should.be.rejectedWith('recipient address of txPrebuild does not match batcher address');
484
+ });
485
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
486
+ const coin = bitgo.coin('teth');
487
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
488
+ const txParams = {
489
+ recipients: [{ amount: '1000000000000', address: address1 }],
490
+ wallet: wallet,
491
+ walletPassphrase: 'fakeWalletPassphrase',
492
+ };
493
+ const txPrebuild = {
494
+ recipients: [{ amount: '2000000000000', address: address1 }],
495
+ nextContractSequenceId: 0,
496
+ gasPrice: 20000000000,
497
+ gasLimit: 500000,
498
+ isBatch: false,
499
+ coin: 'teth',
500
+ walletId: 'fakeWalletId',
501
+ walletContractAddress: 'fakeWalletContractAddress',
502
+ };
503
+ const verification = {};
504
+ await coin
505
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
506
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
507
+ });
508
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
509
+ const coin = bitgo.coin('teth');
510
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
511
+ const txParams = {
512
+ recipients: [{ amount: '1000000000000', address: address1 }],
513
+ wallet: wallet,
514
+ walletPassphrase: 'fakeWalletPassphrase',
515
+ };
516
+ const txPrebuild = {
517
+ recipients: [{ amount: '1000000000000', address: address2 }],
518
+ nextContractSequenceId: 0,
519
+ gasPrice: 20000000000,
520
+ gasLimit: 500000,
521
+ isBatch: false,
522
+ coin: 'teth',
523
+ walletId: 'fakeWalletId',
524
+ walletContractAddress: 'fakeWalletContractAddress',
525
+ };
526
+ const verification = {};
527
+ await coin
528
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
529
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
530
+ });
531
+ it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
532
+ const coin = bitgo.coin('test');
533
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
534
+ const txParams = {
535
+ recipients: [{ amount: '1000000000000', address: address1 }],
536
+ wallet: wallet,
537
+ walletPassphrase: 'fakeWalletPassphrase',
538
+ };
539
+ const txPrebuild = {
540
+ recipients: [{ amount: '1000000000000', address: address1 }],
541
+ nextContractSequenceId: 0,
542
+ gasPrice: 20000000000,
543
+ gasLimit: 500000,
544
+ isBatch: false,
545
+ coin: 'teth',
546
+ token: 'test',
547
+ walletId: 'fakeWalletId',
548
+ walletContractAddress: 'fakeWalletContractAddress',
549
+ };
550
+ const verification = {};
551
+ const isTransactionVerified = await coin.verifyTransaction({
552
+ txParams,
553
+ txPrebuild: txPrebuild,
554
+ wallet,
555
+ verification,
556
+ });
557
+ isTransactionVerified.should.equal(true);
558
+ });
559
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
560
+ const coin = bitgo.coin('teth');
561
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
562
+ const txParams = {
563
+ recipients: [{ amount: '1000000000000', address: address1 }],
564
+ wallet: wallet,
565
+ walletPassphrase: 'fakeWalletPassphrase',
566
+ };
567
+ const txPrebuild = {
568
+ recipients: [{ amount: '1000000000000', address: address1 }],
569
+ nextContractSequenceId: 0,
570
+ gasPrice: 20000000000,
571
+ gasLimit: 500000,
572
+ isBatch: false,
573
+ coin: 'btc',
574
+ walletId: 'fakeWalletId',
575
+ walletContractAddress: 'fakeWalletContractAddress',
576
+ };
577
+ const verification = {};
578
+ await coin
579
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
580
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
581
+ });
582
+ });
583
+ describe('Address Verification', function () {
584
+ describe('isWalletAddress', function () {
585
+ it('should verify an address generated using forwarder version 1', async function () {
586
+ const coin = bitgo.coin('hteth');
587
+ const keychains = [
588
+ {
589
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
590
+ source: 'user',
591
+ type: 'independent',
592
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVmsa5SriNrfKZZAcAvRgxh1Augm6s8yoD8gSkq2FdZ8YCdVXUgLjf9QxvdYAJK5UthAmpQshU',
593
+ },
594
+ {
595
+ id: '691f638f0b74e73b1f440ea4aceda87e',
596
+ source: 'backup',
597
+ type: 'independent',
598
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqAU9JRod8huYtyV4NY2oeJXsis7r26L1vmLntf9BcZJe1m4CQNSvYWfwpe1hSpo6J4x6YF1eN',
599
+ },
600
+ {
601
+ id: '68b9ec587d0ba1c7440de551068c36a7',
602
+ source: 'bitgo',
603
+ type: 'independent',
604
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
605
+ },
606
+ ];
607
+ const params = {
608
+ address: '0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae',
609
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
610
+ coinSpecific: {
611
+ salt: '0x7',
612
+ forwarderVersion: 1,
613
+ },
614
+ keychains,
615
+ index: 7,
616
+ walletVersion: 1,
617
+ };
618
+ const isWalletAddr = await coin.isWalletAddress(params);
619
+ isWalletAddr.should.equal(true);
620
+ });
621
+ it('should verify an address generated using forwarder version 2', async function () {
622
+ const coin = bitgo.coin('hteth');
623
+ const keychains = [
624
+ {
625
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
626
+ source: 'user',
627
+ type: 'independent',
628
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
629
+ },
630
+ {
631
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
632
+ source: 'backup',
633
+ type: 'independent',
634
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
635
+ },
636
+ {
637
+ id: '68b9ec587d0ba1c7440de551068c36a7',
638
+ source: 'bitgo',
639
+ type: 'independent',
640
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
641
+ },
642
+ ];
643
+ const params = {
644
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
645
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
646
+ coinSpecific: {
647
+ salt: '0x17',
648
+ forwarderVersion: 2,
649
+ },
650
+ keychains,
651
+ index: 23,
652
+ walletVersion: 2,
653
+ };
654
+ const isWalletAddr = await coin.isWalletAddress(params);
655
+ isWalletAddr.should.equal(true);
656
+ });
657
+ it('should verify a wallet version 5 forwarder version 4', async function () {
658
+ const coin = bitgo.coin('hteth');
659
+ const keychains = [
660
+ {
661
+ id: '691e242d93f8d7ad0705887449763c96',
662
+ source: 'user',
663
+ type: 'tss',
664
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
665
+ },
666
+ {
667
+ id: '691e242df8b6323d4b08df366864af66',
668
+ source: 'backup',
669
+ type: 'tss',
670
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
671
+ },
672
+ {
673
+ id: '691e242c0595b4cfee6f957c1d6458f7',
674
+ source: 'bitgo',
675
+ type: 'tss',
676
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
677
+ },
678
+ ];
679
+ const params = {
680
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
681
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
682
+ coinSpecific: {
683
+ salt: '0x75',
684
+ forwarderVersion: 4,
685
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
686
+ },
687
+ keychains,
688
+ index: 117,
689
+ walletVersion: 5,
690
+ };
691
+ const isWalletAddr = await coin.isWalletAddress(params);
692
+ isWalletAddr.should.equal(true);
693
+ });
694
+ it('should verify a wallet version 6 forwarder version 5', async function () {
695
+ const coin = bitgo.coin('hteth');
696
+ const keychains = [
697
+ {
698
+ id: '691f630e0c56098288a9b7fa107db144',
699
+ source: 'user',
700
+ type: 'tss',
701
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
702
+ },
703
+ {
704
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
705
+ source: 'backup',
706
+ type: 'tss',
707
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
708
+ },
709
+ {
710
+ id: '691f630d56735e5eb61b06e353fe7639',
711
+ source: 'bitgo',
712
+ type: 'tss',
713
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
714
+ },
715
+ ];
716
+ const params = {
717
+ address: '0xa33f0975f53cdcfcc0cb564d25fb5be03b0651cf',
718
+ baseAddress: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
719
+ coinSpecific: {
720
+ forwarderVersion: 5,
721
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
722
+ },
723
+ keychains,
724
+ index: 7,
725
+ walletVersion: 6,
726
+ };
727
+ const isWalletAddr = await coin.isWalletAddress(params);
728
+ isWalletAddr.should.equal(true);
729
+ });
730
+ it('should reject when actual address differs from expected address', async function () {
731
+ const coin = bitgo.coin('hteth');
732
+ const params = {
733
+ address: '0x28904591f735994f050804fda3b61b813b16e04c',
734
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
735
+ walletVersion: 1,
736
+ coinSpecific: {
737
+ salt: '0xc5a',
738
+ forwarderVersion: 1,
739
+ },
740
+ };
741
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.UnexpectedAddressError);
742
+ });
743
+ it('should reject if coinSpecific field is not an object', async function () {
744
+ const coin = bitgo.coin('teth');
745
+ const params = {
746
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
747
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
748
+ };
749
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressVerificationObjectPropertyError);
750
+ });
751
+ it('should reject if the derived address is in invalid format', async function () {
752
+ const coin = bitgo.coin('teth');
753
+ const params = {
754
+ address: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
755
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
756
+ coinSpecific: {
757
+ salt: '0xc5a',
758
+ forwarderVersion: 1,
759
+ },
760
+ };
761
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
762
+ });
763
+ it('should reject if base address is undefined', async function () {
764
+ const coin = bitgo.coin('teth');
765
+ const params = {
766
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
767
+ coinSpecific: {
768
+ salt: '0xc5a',
769
+ forwarderVersion: 1,
770
+ },
771
+ };
772
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
773
+ });
774
+ it('should reject if base address is in invalid format', async function () {
775
+ const coin = bitgo.coin('teth');
776
+ const params = {
777
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
778
+ baseAddress: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
779
+ coinSpecific: {
780
+ salt: '0xc5a',
781
+ forwarderVersion: 1,
782
+ },
783
+ };
784
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
785
+ });
786
+ describe('MPC wallet addresses', function () {
787
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
788
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
789
+ const keychains = [
790
+ { pub: 'user_pub', commonKeychain },
791
+ { pub: 'backup_pub', commonKeychain },
792
+ { pub: 'bitgo_pub', commonKeychain },
793
+ ];
794
+ it('should verify an MPC wallet address with forwarder version 3', async function () {
795
+ const coin = bitgo.coin('teth');
796
+ const params = {
797
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
798
+ coinSpecific: {
799
+ forwarderVersion: 3,
800
+ },
801
+ keychains,
802
+ index: 0,
803
+ walletVersion: 3,
804
+ };
805
+ const isWalletAddr = await coin.isWalletAddress(params);
806
+ isWalletAddr.should.equal(true);
807
+ });
808
+ it('should verify an MPC wallet address with forwarder version 5', async function () {
809
+ const coin = bitgo.coin('teth');
810
+ const params = {
811
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
812
+ coinSpecific: {
813
+ forwarderVersion: 5,
814
+ },
815
+ keychains,
816
+ index: 0,
817
+ walletVersion: 6,
818
+ };
819
+ const isWalletAddr = await coin.isWalletAddress(params);
820
+ isWalletAddr.should.equal(true);
821
+ });
822
+ it('should reject MPC wallet address with wrong address', async function () {
823
+ const coin = bitgo.coin('teth');
824
+ const params = {
825
+ address: '0x0000000000000000000000000000000000000001',
826
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
827
+ coinSpecific: {
828
+ forwarderVersion: 3,
829
+ },
830
+ keychains,
831
+ index: 0,
832
+ walletVersion: 3,
833
+ };
834
+ const isWalletAddr = await coin.isWalletAddress(params);
835
+ isWalletAddr.should.equal(false);
836
+ });
837
+ it('should reject MPC wallet address with invalid address format', async function () {
838
+ const coin = bitgo.coin('teth');
839
+ const params = {
840
+ address: '0xinvalid',
841
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
842
+ coinSpecific: {
843
+ forwarderVersion: 3,
844
+ },
845
+ keychains,
846
+ index: 0,
847
+ walletVersion: 3,
848
+ };
849
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
850
+ });
851
+ it('should reject if keychains are missing for MPC wallet', async function () {
852
+ const coin = bitgo.coin('teth');
853
+ const params = {
854
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
855
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
856
+ coinSpecific: {
857
+ forwarderVersion: 3,
858
+ },
859
+ index: 0,
860
+ walletVersion: 3,
861
+ };
862
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
863
+ });
864
+ it('should reject if commonKeychain is missing for MPC wallet', async function () {
865
+ const coin = bitgo.coin('teth');
866
+ const invalidKeychains = [{ pub: 'user_pub' }, { pub: 'backup_pub' }, { pub: 'bitgo_pub' }];
867
+ const params = {
868
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
869
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
870
+ coinSpecific: {
871
+ forwarderVersion: 3,
872
+ },
873
+ keychains: invalidKeychains,
874
+ index: 0,
875
+ walletVersion: 3,
876
+ };
877
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
878
+ });
879
+ });
880
+ describe('Base Address Verification', function () {
881
+ it('should verify base address for wallet version 6 (TSS)', async function () {
882
+ const coin = bitgo.coin('hteth');
883
+ const keychains = [
884
+ {
885
+ id: '691f630e0c56098288a9b7fa107db144',
886
+ source: 'user',
887
+ type: 'tss',
888
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
889
+ },
890
+ {
891
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
892
+ source: 'backup',
893
+ type: 'tss',
894
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
895
+ },
896
+ {
897
+ id: '691f630d56735e5eb61b06e353fe7639',
898
+ source: 'bitgo',
899
+ type: 'tss',
900
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
901
+ },
902
+ ];
903
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
904
+ const params = {
905
+ address: baseAddress,
906
+ baseAddress: baseAddress,
907
+ coinSpecific: {
908
+ salt: '0x0',
909
+ forwarderVersion: 5,
910
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
911
+ },
912
+ keychains,
913
+ index: 0,
914
+ walletVersion: 6,
915
+ };
916
+ const isWalletAddr = await coin.isWalletAddress(params);
917
+ isWalletAddr.should.equal(true);
918
+ });
919
+ it('should verify base address for wallet version 5 (TSS)', async function () {
920
+ const coin = bitgo.coin('hteth');
921
+ const keychains = [
922
+ {
923
+ id: '691e242d93f8d7ad0705887449763c96',
924
+ source: 'user',
925
+ type: 'tss',
926
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
927
+ },
928
+ {
929
+ id: '691e242df8b6323d4b08df366864af66',
930
+ source: 'backup',
931
+ type: 'tss',
932
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
933
+ },
934
+ {
935
+ id: '691e242c0595b4cfee6f957c1d6458f7',
936
+ source: 'bitgo',
937
+ type: 'tss',
938
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
939
+ },
940
+ ];
941
+ const baseAddress = '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11';
942
+ const params = {
943
+ address: baseAddress,
944
+ baseAddress: baseAddress,
945
+ coinSpecific: {
946
+ salt: '0x0',
947
+ forwarderVersion: 4,
948
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
949
+ },
950
+ keychains,
951
+ index: 0,
952
+ walletVersion: 5,
953
+ };
954
+ const isWalletAddr = await coin.isWalletAddress(params);
955
+ isWalletAddr.should.equal(true);
956
+ });
957
+ it('should reject base address verification with non-zero index', async function () {
958
+ const coin = bitgo.coin('hteth');
959
+ const keychains = [
960
+ {
961
+ id: '691f630e0c56098288a9b7fa107db144',
962
+ source: 'user',
963
+ type: 'tss',
964
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
965
+ },
966
+ {
967
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
968
+ source: 'backup',
969
+ type: 'tss',
970
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
971
+ },
972
+ {
973
+ id: '691f630d56735e5eb61b06e353fe7639',
974
+ source: 'bitgo',
975
+ type: 'tss',
976
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
977
+ },
978
+ ];
979
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
980
+ const params = {
981
+ address: baseAddress,
982
+ baseAddress: baseAddress,
983
+ coinSpecific: {
984
+ salt: '0x0',
985
+ forwarderVersion: 5,
986
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
987
+ },
988
+ keychains,
989
+ index: 5, // Wrong index - should be 0 for base address
990
+ walletVersion: 6,
991
+ };
992
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), /Base address verification requires index 0, but got index 5/);
993
+ });
994
+ it('should reject base address verification with wrong address', async function () {
995
+ const coin = bitgo.coin('hteth');
996
+ const keychains = [
997
+ {
998
+ id: '691f630e0c56098288a9b7fa107db144',
999
+ source: 'user',
1000
+ type: 'tss',
1001
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1002
+ },
1003
+ {
1004
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1005
+ source: 'backup',
1006
+ type: 'tss',
1007
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1008
+ },
1009
+ {
1010
+ id: '691f630d56735e5eb61b06e353fe7639',
1011
+ source: 'bitgo',
1012
+ type: 'tss',
1013
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1014
+ },
1015
+ ];
1016
+ const wrongAddress = '0x0000000000000000000000000000000000000001';
1017
+ const actualBaseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1018
+ const params = {
1019
+ address: wrongAddress,
1020
+ baseAddress: actualBaseAddress,
1021
+ coinSpecific: {
1022
+ salt: '0x0',
1023
+ forwarderVersion: 5,
1024
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1025
+ },
1026
+ keychains,
1027
+ index: 0,
1028
+ walletVersion: 6,
1029
+ };
1030
+ const isWalletAddr = await coin.isWalletAddress(params);
1031
+ isWalletAddr.should.equal(false);
1032
+ });
1033
+ it('should verify base address for wallet version 2 (BIP32) using wallet factory', async function () {
1034
+ const coin = bitgo.coin('hteth');
1035
+ const baseAddress = '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4';
1036
+ const walletSalt = '0x2';
1037
+ const keychains = [
1038
+ {
1039
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1040
+ source: 'user',
1041
+ type: 'independent',
1042
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1043
+ },
1044
+ {
1045
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1046
+ source: 'backup',
1047
+ type: 'independent',
1048
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1049
+ },
1050
+ {
1051
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1052
+ source: 'bitgo',
1053
+ type: 'independent',
1054
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1055
+ },
1056
+ ];
1057
+ const params = {
1058
+ address: baseAddress,
1059
+ baseAddress: baseAddress,
1060
+ coinSpecific: {
1061
+ salt: walletSalt,
1062
+ forwarderVersion: 2,
1063
+ },
1064
+ keychains: keychains,
1065
+ index: 0,
1066
+ walletVersion: 2,
1067
+ };
1068
+ const isWalletAddr = await coin.isWalletAddress(params);
1069
+ isWalletAddr.should.equal(true);
1070
+ });
1071
+ it('should verify base address for wallet version 1 (BIP32) using wallet factory', async function () {
1072
+ const coin = bitgo.coin('hteth');
1073
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1074
+ const walletSalt = '0x5';
1075
+ const keychains = [
1076
+ {
1077
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1078
+ source: 'user',
1079
+ type: 'independent',
1080
+ ethAddress: '0xf45dadce751a317957f2a247ff37cb764b97620d',
1081
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVm...',
1082
+ },
1083
+ {
1084
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1085
+ source: 'backup',
1086
+ type: 'independent',
1087
+ ethAddress: '0x5bdf3ae1d2c2fadeeb70a45872bf4f4252312b55',
1088
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqA...',
1089
+ },
1090
+ {
1091
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1092
+ source: 'bitgo',
1093
+ type: 'independent',
1094
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1095
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79Hok...',
1096
+ },
1097
+ ];
1098
+ const params = {
1099
+ address: baseAddress,
1100
+ baseAddress: baseAddress,
1101
+ coinSpecific: {
1102
+ salt: walletSalt,
1103
+ forwarderVersion: 1,
1104
+ },
1105
+ keychains: keychains,
1106
+ index: 0,
1107
+ walletVersion: 1,
1108
+ };
1109
+ const isWalletAddr = await coin.isWalletAddress(params);
1110
+ isWalletAddr.should.equal(true);
1111
+ });
1112
+ });
1113
+ });
1114
+ });
1115
+ describe('Address Creation', function () {
1116
+ it('should pass walletVersion 6 to isWalletAddress during address creation', async function () {
1117
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1118
+ const ethCoin = bitgo.coin('hteth');
1119
+ const walletDataV6 = {
1120
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1121
+ coinSpecific: {
1122
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1123
+ walletVersion: 6,
1124
+ },
1125
+ coin: 'hteth',
1126
+ keys: [
1127
+ '598f606cd8fc24710d2ebad89dce86c2',
1128
+ '598f606cc8e43aef09fcb785221d9dd2',
1129
+ '5935d59cf660764331bafcade1855fd7',
1130
+ ],
1131
+ receiveAddress: {
1132
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1133
+ },
1134
+ };
1135
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
1136
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1137
+ // Mock keychain requests
1138
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1139
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1140
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1141
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1142
+ source: 'user',
1143
+ type: 'tss',
1144
+ });
1145
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1146
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1147
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1148
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1149
+ source: 'backup',
1150
+ type: 'tss',
1151
+ });
1152
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1153
+ id: '5935d59cf660764331bafcade1855fd7',
1154
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1155
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1156
+ source: 'bitgo',
1157
+ type: 'tss',
1158
+ });
1159
+ // Mock address creation API
1160
+ (0, nock_1.default)(bgUrl)
1161
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
1162
+ .reply(200, {
1163
+ id: '638a48c6c3dba40007a3497fa49a080c',
1164
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1165
+ chain: 0,
1166
+ index: 0,
1167
+ coin: 'hteth',
1168
+ wallet: ethWalletV6.id(),
1169
+ coinSpecific: {
1170
+ forwarderVersion: 4,
1171
+ salt: '0x0',
1172
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1173
+ },
1174
+ });
1175
+ await ethWalletV6.createAddress({ chain: 0 });
1176
+ isWalletAddressSpy.calledOnce.should.be.true();
1177
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1178
+ calledParams.should.have.property('walletVersion', 6);
1179
+ });
1180
+ it('should pass walletVersion 5 to isWalletAddress during address creation', async function () {
1181
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1182
+ const ethCoin = bitgo.coin('hteth');
1183
+ const walletDataV5 = {
1184
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1185
+ coinSpecific: {
1186
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1187
+ walletVersion: 5,
1188
+ },
1189
+ coin: 'hteth',
1190
+ keys: [
1191
+ '598f606cd8fc24710d2ebad89dce86c2',
1192
+ '598f606cc8e43aef09fcb785221d9dd2',
1193
+ '5935d59cf660764331bafcade1855fd7',
1194
+ ],
1195
+ receiveAddress: {
1196
+ address: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1197
+ },
1198
+ };
1199
+ const ethWalletV5 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV5);
1200
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1201
+ // Mock keychain requests
1202
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1203
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1204
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1205
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1206
+ source: 'user',
1207
+ type: 'tss',
1208
+ });
1209
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1210
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1211
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1212
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1213
+ source: 'backup',
1214
+ type: 'tss',
1215
+ });
1216
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1217
+ id: '5935d59cf660764331bafcade1855fd7',
1218
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1219
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1220
+ source: 'bitgo',
1221
+ type: 'tss',
1222
+ });
1223
+ // Mock address creation API
1224
+ (0, nock_1.default)(bgUrl)
1225
+ .post(`/api/v2/hteth/wallet/${ethWalletV5.id()}/address`)
1226
+ .reply(200, {
1227
+ id: '638a48c6c3dba40007a3497fa49a080c',
1228
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1229
+ chain: 0,
1230
+ index: 117,
1231
+ coin: 'hteth',
1232
+ wallet: ethWalletV5.id(),
1233
+ coinSpecific: {
1234
+ forwarderVersion: 4,
1235
+ salt: '0x75',
1236
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1237
+ },
1238
+ });
1239
+ await ethWalletV5.createAddress({ chain: 0 });
1240
+ // Verify isWalletAddress was called with walletVersion 5
1241
+ isWalletAddressSpy.calledOnce.should.be.true();
1242
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1243
+ calledParams.should.have.property('walletVersion', 5);
1244
+ });
1245
+ it('should pass walletVersion 2 to isWalletAddress during address creation', async function () {
1246
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1247
+ const ethCoin = bitgo.coin('hteth');
1248
+ const walletDataV2 = {
1249
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1250
+ coinSpecific: {
1251
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1252
+ walletVersion: 2,
1253
+ },
1254
+ coin: 'hteth',
1255
+ keys: [
1256
+ '598f606cd8fc24710d2ebad89dce86c2',
1257
+ '598f606cc8e43aef09fcb785221d9dd2',
1258
+ '5935d59cf660764331bafcade1855fd7',
1259
+ ],
1260
+ receiveAddress: {
1261
+ address: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1262
+ },
1263
+ };
1264
+ const ethWalletV2 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV2);
1265
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1266
+ // Mock keychain requests
1267
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1268
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1269
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1270
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1271
+ source: 'user',
1272
+ type: 'independent',
1273
+ });
1274
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1275
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1276
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1277
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1278
+ source: 'backup',
1279
+ type: 'independent',
1280
+ });
1281
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1282
+ id: '5935d59cf660764331bafcade1855fd7',
1283
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1284
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1285
+ source: 'bitgo',
1286
+ type: 'independent',
1287
+ });
1288
+ // Mock address creation API
1289
+ (0, nock_1.default)(bgUrl)
1290
+ .post(`/api/v2/hteth/wallet/${ethWalletV2.id()}/address`)
1291
+ .reply(200, {
1292
+ id: '638a48c6c3dba40007a3497fa49a080c',
1293
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1294
+ chain: 0,
1295
+ index: 23,
1296
+ coin: 'hteth',
1297
+ wallet: ethWalletV2.id(),
1298
+ coinSpecific: {
1299
+ forwarderVersion: 2,
1300
+ salt: '0x17',
1301
+ },
1302
+ });
1303
+ await ethWalletV2.createAddress({ chain: 0 });
1304
+ // Verify isWalletAddress was called with walletVersion 2
1305
+ isWalletAddressSpy.calledOnce.should.be.true();
1306
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1307
+ calledParams.should.have.property('walletVersion', 2);
1308
+ });
1309
+ it('should fail v6 address creation if walletVersion was not passed (simulates old bug)', async function () {
1310
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1311
+ const ethCoin = bitgo.coin('hteth');
1312
+ const walletDataV6 = {
1313
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1314
+ coinSpecific: {
1315
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1316
+ walletVersion: 6,
1317
+ },
1318
+ coin: 'hteth',
1319
+ keys: [
1320
+ '598f606cd8fc24710d2ebad89dce86c2',
1321
+ '598f606cc8e43aef09fcb785221d9dd2',
1322
+ '5935d59cf660764331bafcade1855fd7',
1323
+ ],
1324
+ receiveAddress: {
1325
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1326
+ },
1327
+ };
1328
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
1329
+ // Stub isWalletAddress to simulate the OLD bug where walletVersion was not passed
1330
+ const originalIsWalletAddress = ethCoin.isWalletAddress.bind(ethCoin);
1331
+ const isWalletAddressStub = sinon_1.default.stub(ethCoin, 'isWalletAddress').callsFake(async (params) => {
1332
+ // Remove walletVersion to simulate the old bug
1333
+ const paramsWithoutWalletVersion = { ...params };
1334
+ delete paramsWithoutWalletVersion.walletVersion;
1335
+ return originalIsWalletAddress(paramsWithoutWalletVersion);
1336
+ });
1337
+ // Mock keychain requests
1338
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1339
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1340
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1341
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1342
+ source: 'user',
1343
+ type: 'tss',
1344
+ });
1345
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1346
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1347
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1348
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1349
+ source: 'backup',
1350
+ type: 'tss',
1351
+ });
1352
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1353
+ id: '5935d59cf660764331bafcade1855fd7',
1354
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1355
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1356
+ source: 'bitgo',
1357
+ type: 'tss',
1358
+ });
1359
+ // Mock address creation API
1360
+ (0, nock_1.default)(bgUrl)
1361
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
1362
+ .reply(200, {
1363
+ id: '638a48c6c3dba40007a3497fa49a080c',
1364
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1365
+ chain: 0,
1366
+ index: 0,
1367
+ coin: 'hteth',
1368
+ wallet: ethWalletV6.id(),
1369
+ coinSpecific: {
1370
+ forwarderVersion: 4,
1371
+ salt: '0x0',
1372
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1373
+ },
1374
+ });
1375
+ // Without walletVersion, address creation should fail because
1376
+ // the code doesn't know to use TSS verification for v6 wallets
1377
+ await assert_1.default.rejects(async () => ethWalletV6.createAddress({ chain: 0 }), sdk_core_1.UnexpectedAddressError);
1378
+ isWalletAddressStub.restore();
1379
+ });
1380
+ });
1381
+ describe('EVM Cross Chain Recovery', function () {
1382
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1383
+ it('should build a recovery transaction for hot wallet', async function () {
1384
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
1385
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
1386
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
1387
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
1388
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
1389
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
1390
+ const destinationAddress = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
1391
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
1392
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
1393
+ const basecoin = bitgo.coin('hteth');
1394
+ (0, nock_1.default)(baseUrl)
1395
+ .get('/api')
1396
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
1397
+ .reply(200, mockData.getTxListResponse);
1398
+ (0, nock_1.default)(baseUrl)
1399
+ .get('/api')
1400
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
1401
+ .reply(200, mockData.getBalanceResponse);
1402
+ (0, nock_1.default)(baseUrl)
1403
+ .get('/api')
1404
+ .query(mockData.getBalanceRequest(walletContractAddress))
1405
+ .reply(200, mockData.getBalanceResponse);
1406
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1407
+ const spy = sinon_1.default.spy(src_1.TransactionBuilder.prototype, 'coinUsesNonPackedEncodingForTxData');
1408
+ await basecoin.recover({
1409
+ userKey: userKey,
1410
+ backupKey: '',
1411
+ walletPassphrase: walletPassphrase,
1412
+ walletContractAddress: walletContractAddress,
1413
+ bitgoFeeAddress: bitgoFeeAddress,
1414
+ recoveryDestination: destinationAddress,
1415
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
1416
+ gasLimit: 500000,
1417
+ bitgoDestinationAddress: bitgoDestinationAddress,
1418
+ intendedChain: 'tarbeth',
1419
+ });
1420
+ (0, assert_1.default)(spy.returned(true));
1421
+ });
1422
+ describe('Non-BitGo Recovery for Hot Wallets (MPCv2)', function () {
1423
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1424
+ let bitgo;
1425
+ let basecoin;
1426
+ before(function () {
1427
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
1428
+ basecoin = bitgo.coin('hteth');
1429
+ });
1430
+ it('should build a recovery transaction for MPCv2 kind of hot wallets', async function () {
1431
+ (0, nock_1.default)(baseUrl)
1432
+ .get('/api')
1433
+ .query(mockData.getTxListRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
1434
+ .reply(200, mockData.getTxListResponse);
1435
+ (0, nock_1.default)(baseUrl)
1436
+ .get('/api')
1437
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
1438
+ .reply(200, mockData.getBalanceResponse);
1439
+ (0, nock_1.default)(baseUrl)
1440
+ .get('/api')
1441
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().walletContractAddress))
1442
+ .reply(200, mockData.getBalanceResponse);
1443
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1444
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
1445
+ const transaction = await basecoin.recover({
1446
+ userKey: params.userKey,
1447
+ backupKey: params.backupKey,
1448
+ walletPassphrase: params.walletPassphrase,
1449
+ walletContractAddress: params.walletContractAddress,
1450
+ bitgoFeeAddress: params.bitgoFeeAddress,
1451
+ recoveryDestination: params.recoveryDestination,
1452
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
1453
+ gasLimit: 500000,
1454
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
1455
+ intendedChain: params.intendedChain,
1456
+ });
1457
+ should_1.default.exist(transaction);
1458
+ transaction.should.have.property('txHex');
1459
+ });
1460
+ it('should throw an error for invalid user key', async function () {
1461
+ const params = mockData.getInvalidNonBitGoRecoveryParams();
1462
+ await assert_1.default.rejects(async () => {
1463
+ await basecoin.recover({
1464
+ userKey: params.userKey,
1465
+ backupKey: params.backupKey,
1466
+ walletPassphrase: params.walletPassphrase,
1467
+ walletContractAddress: params.walletContractAddress,
1468
+ bitgoFeeAddress: params.bitgoFeeAddress,
1469
+ recoveryDestination: params.recoveryDestination,
1470
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
1471
+ gasLimit: 500000,
1472
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
1473
+ intendedChain: params.intendedChain,
1474
+ });
1475
+ }, Error, 'user key is invalid');
1476
+ });
1477
+ });
1478
+ describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
1479
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1480
+ let bitgo;
1481
+ let basecoin;
1482
+ before(function () {
1483
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
1484
+ basecoin = bitgo.coin('hteth');
1485
+ });
1486
+ it('should generate an unsigned sweep without derivation seed', async function () {
1487
+ (0, nock_1.default)(baseUrl)
1488
+ .get('/api')
1489
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1490
+ .reply(200, mockData.getTxListResponse);
1491
+ (0, nock_1.default)(baseUrl)
1492
+ .get('/api')
1493
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1494
+ .reply(200, mockData.getBalanceResponse);
1495
+ (0, nock_1.default)(baseUrl)
1496
+ .get('/api')
1497
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
1498
+ .reply(200, mockData.getBalanceResponse);
1499
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1500
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1501
+ const sweepResult = await basecoin.recover({
1502
+ userKey: params.commonKeyChain, // Box A Data
1503
+ backupKey: params.commonKeyChain, // Box B Data
1504
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
1505
+ recoveryDestination: params.recoveryDestination, // Destination Address
1506
+ gasLimit: 200000, // Gas Limit
1507
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1508
+ walletContractAddress: params.walletContractAddress,
1509
+ isTss: true,
1510
+ replayProtectionOptions: {
1511
+ chain: '42',
1512
+ hardfork: 'london',
1513
+ },
1514
+ });
1515
+ should_1.default.exist(sweepResult);
1516
+ const output = sweepResult;
1517
+ output.should.have.property('txRequests');
1518
+ output.txRequests.should.have.length(1);
1519
+ output.txRequests[0].should.have.property('transactions');
1520
+ output.txRequests[0].transactions.should.have.length(1);
1521
+ output.txRequests[0].should.have.property('walletCoin');
1522
+ output.txRequests[0].transactions.should.have.length(1);
1523
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
1524
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
1525
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
1526
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
1527
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
1528
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
1529
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
1530
+ parsedTx.should.have.property('spendAmount');
1531
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
1532
+ });
1533
+ it('should throw an error for invalid address', async function () {
1534
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1535
+ params.recoveryDestination = 'invalidAddress';
1536
+ // Ensure userKey and backupKey are the same
1537
+ params.userKey =
1538
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1539
+ params.backupKey =
1540
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1541
+ await assert_1.default.rejects(async () => {
1542
+ await basecoin.recover({
1543
+ recoveryDestination: params.recoveryDestination, // Destination Address
1544
+ gasLimit: 2000, // Gas Limit
1545
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1546
+ userKey: params.userKey, // Provide the userKey
1547
+ backupKey: params.backupKey, // Provide the backupKey
1548
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
1549
+ isTss: true,
1550
+ replayProtectionOptions: {
1551
+ chain: '42',
1552
+ hardfork: 'london',
1553
+ },
1554
+ });
1555
+ }, Error, 'Error: invalid address');
1556
+ });
1557
+ });
1558
+ describe('Build Unsigned Consolidation for Self-Custody Cold Wallets (MPCv2)', function () {
1559
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1560
+ let bitgo;
1561
+ let basecoin;
1562
+ before(function () {
1563
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
1564
+ basecoin = bitgo.coin('hteth');
1565
+ });
1566
+ it('should generate an unsigned consolidation for wallet v5', async function () {
1567
+ (0, nock_1.default)(baseUrl)
1568
+ .get('/api')
1569
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1570
+ .times(2)
1571
+ .reply(200, mockData.getTxListResponse);
1572
+ (0, nock_1.default)(baseUrl)
1573
+ .get('/api')
1574
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1575
+ .times(2)
1576
+ .reply(200, mockData.getBalanceResponse);
1577
+ (0, nock_1.default)(baseUrl)
1578
+ .get('/api')
1579
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
1580
+ .reply(200, mockData.getBalanceResponse);
1581
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1582
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1583
+ const consolidationResult = await basecoin.recoverConsolidations({
1584
+ backupKey: params.commonKeyChain, // Box B Data
1585
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
1586
+ recoveryDestination: params.recoveryDestination, // Destination Address
1587
+ gasLimit: 200000, // Gas Limit
1588
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1589
+ walletContractAddress: params.walletContractAddress,
1590
+ isTss: true,
1591
+ replayProtectionOptions: {
1592
+ chain: '42',
1593
+ hardfork: 'london',
1594
+ },
1595
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
1596
+ startingScanIndex: 1,
1597
+ endingScanIndex: 2,
1598
+ });
1599
+ should_1.default.exist(consolidationResult);
1600
+ const unsignedBuilConsolidation = consolidationResult;
1601
+ unsignedBuilConsolidation.should.have.property('transactions');
1602
+ unsignedBuilConsolidation.transactions.should.have.length(1);
1603
+ const output = unsignedBuilConsolidation.transactions[0];
1604
+ output.should.have.property('txRequests');
1605
+ output.txRequests[0].should.have.property('transactions');
1606
+ output.txRequests[0].transactions.should.have.length(1);
1607
+ output.txRequests[0].should.have.property('walletCoin');
1608
+ output.txRequests[0].transactions.should.have.length(1);
1609
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
1610
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
1611
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
1612
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
1613
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
1614
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
1615
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
1616
+ parsedTx.should.have.property('spendAmount');
1617
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
1618
+ });
1619
+ it('should generate an unsigned consolidation for wallet v6', async function () {
1620
+ (0, nock_1.default)(baseUrl)
1621
+ .get('/api')
1622
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1623
+ .times(2)
1624
+ .reply(200, mockData.getTxListResponse);
1625
+ (0, nock_1.default)(baseUrl)
1626
+ .get('/api')
1627
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
1628
+ .times(2)
1629
+ .reply(200, mockData.getBalanceResponse);
1630
+ (0, nock_1.default)(baseUrl)
1631
+ .get('/api')
1632
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
1633
+ .reply(200, mockData.getBalanceResponse);
1634
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1635
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1636
+ const consolidationResult = await basecoin.recoverConsolidations({
1637
+ userKey: params.commonKeyChain, // Box A Data
1638
+ backupKey: params.commonKeyChain, // Box B Data
1639
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
1640
+ recoveryDestination: params.recoveryDestination, // Destination Address
1641
+ gasLimit: 200000, // Gas Limit
1642
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1643
+ isTss: true,
1644
+ walletContractAddress: '123', // Wrong wallet address so that we can skip v5 address generation
1645
+ replayProtectionOptions: {
1646
+ chain: '42',
1647
+ hardfork: 'london',
1648
+ },
1649
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
1650
+ startingScanIndex: 1,
1651
+ endingScanIndex: 2,
1652
+ });
1653
+ should_1.default.exist(consolidationResult);
1654
+ const unsignedBuilConsolidation = consolidationResult;
1655
+ unsignedBuilConsolidation.should.have.property('transactions');
1656
+ unsignedBuilConsolidation.transactions.should.have.length(1);
1657
+ const output = unsignedBuilConsolidation.transactions[0];
1658
+ output.should.have.property('txRequests');
1659
+ output.txRequests[0].should.have.property('transactions');
1660
+ output.txRequests[0].transactions.should.have.length(1);
1661
+ output.txRequests[0].should.have.property('walletCoin');
1662
+ output.txRequests[0].transactions.should.have.length(1);
1663
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
1664
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
1665
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
1666
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
1667
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
1668
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
1669
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
1670
+ parsedTx.should.have.property('spendAmount');
1671
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
1672
+ });
1673
+ it('should throw an error for invalid address', async function () {
1674
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1675
+ params.recoveryDestination = 'invalidAddress';
1676
+ // Ensure userKey and backupKey are the same
1677
+ params.userKey =
1678
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1679
+ params.backupKey =
1680
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1681
+ await assert_1.default.rejects(async () => {
1682
+ await basecoin.recover({
1683
+ recoveryDestination: params.recoveryDestination, // Destination Address
1684
+ gasLimit: 2000, // Gas Limit
1685
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1686
+ userKey: params.userKey, // Provide the userKey
1687
+ backupKey: params.backupKey, // Provide the backupKey
1688
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
1689
+ isTss: true,
1690
+ replayProtectionOptions: {
1691
+ chain: '42',
1692
+ hardfork: 'london',
1693
+ },
1694
+ });
1695
+ }, Error, 'Error: invalid address');
1696
+ });
1697
+ });
1698
+ });
1699
+ describe('RecoveryBlockchainExplorerQuery', () => {
1700
+ it('should override the token parameter with a custom API key', async function () {
1701
+ const coin = bitgo.coin('teth');
1702
+ const query = {
1703
+ module: 'account',
1704
+ action: 'balance',
1705
+ address: '0x1234567890123456789012345678901234567890',
1706
+ };
1707
+ const customApiKey = 'custom-api-key-for-test';
1708
+ // Mock the environment API token
1709
+ const originalApiToken = sdk_core_1.common.Environments.test.etherscanApiToken;
1710
+ sdk_core_1.common.Environments.test.etherscanApiToken = 'default-environment-api-key';
1711
+ // Mock the request.get function to capture the query parameters
1712
+ const originalGet = superagent_1.default.get;
1713
+ let capturedQuery;
1714
+ superagent_1.default.get = function (url) {
1715
+ return {
1716
+ query: function (params) {
1717
+ capturedQuery = params;
1718
+ return {
1719
+ ok: true,
1720
+ body: { result: '100000000' },
1721
+ };
1722
+ },
1723
+ };
1724
+ };
1725
+ try {
1726
+ // Call with default API key
1727
+ await coin.recoveryBlockchainExplorerQuery(query);
1728
+ capturedQuery.should.have.property('apikey', 'default-environment-api-key');
1729
+ // Call with custom API key
1730
+ await coin.recoveryBlockchainExplorerQuery(query, customApiKey);
1731
+ capturedQuery.should.have.property('apikey', customApiKey);
1732
+ }
1733
+ finally {
1734
+ // Restore original function and API token
1735
+ superagent_1.default.get = originalGet;
1736
+ sdk_core_1.common.Environments.test.etherscanApiToken = originalApiToken;
1737
+ }
1738
+ });
1739
+ });
1740
+ describe('Audit Key', () => {
1741
+ let coin;
1742
+ before(() => {
1743
+ coin = bitgo.coin('hteth');
1744
+ });
1745
+ describe('MultiSig', () => {
1746
+ const { key } = ethMultiSigBackupKey_1.ethMultiSigBackupKey;
1747
+ it('should return { isValid: true } for valid inputs', () => {
1748
+ coin.assertIsValidKey({
1749
+ encryptedPrv: key,
1750
+ walletPassphrase: 'ZQ8MhxT84m4P',
1751
+ });
1752
+ });
1753
+ it('should throw error if the walletPassphrase is incorrect', () => {
1754
+ assert_1.default.throws(() => coin.assertIsValidKey({
1755
+ encryptedPrv: key,
1756
+ walletPassphrase: 'foo',
1757
+ }), { message: "failed to decrypt prv: ccm: tag doesn't match" });
1758
+ });
1759
+ it('should throw error if the key is altered', () => {
1760
+ const alteredKey = key.replace(/[0-9]/g, '0');
1761
+ assert_1.default.throws(() => coin.assertIsValidKey({
1762
+ encryptedPrv: alteredKey,
1763
+ walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
1764
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1765
+ });
1766
+ });
1767
+ describe('TSS', () => {
1768
+ const { key: keyString, commonKeychain } = ethTssBackupKey_1.ethTssBackupKey;
1769
+ const key = keyString.replace(/\s/g, '');
1770
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
1771
+ const multiSigType = 'tss';
1772
+ it('should not throw for valid inputs', () => {
1773
+ coin.assertIsValidKey({
1774
+ encryptedPrv: key,
1775
+ publicKey: commonKeychain,
1776
+ walletPassphrase,
1777
+ multiSigType,
1778
+ });
1779
+ });
1780
+ it('should throw if the commonKeychain is altered', () => {
1781
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
1782
+ assert_1.default.throws(() => coin.assertIsValidKey({
1783
+ encryptedPrv: key,
1784
+ publicKey: alteredCommonKeychain,
1785
+ walletPassphrase,
1786
+ multiSigType,
1787
+ }), { message: 'Invalid common keychain' });
1788
+ });
1789
+ it('should throw error if the walletPassphrase is incorrect', () => {
1790
+ const incorrectPassphrase = 'foo';
1791
+ assert_1.default.throws(() => coin.assertIsValidKey({
1792
+ encryptedPrv: key,
1793
+ publicKey: commonKeychain,
1794
+ walletPassphrase: incorrectPassphrase,
1795
+ multiSigType,
1796
+ }), { message: "failed to decrypt prv: ccm: tag doesn't match" });
1797
+ });
1798
+ it('should throw error if the key is altered', () => {
1799
+ const alteredKey = key.replace(/[0-9]/g, '0');
1800
+ assert_1.default.throws(() => coin.assertIsValidKey({
1801
+ encryptedPrv: alteredKey,
1802
+ publicKey: commonKeychain,
1803
+ walletPassphrase,
1804
+ multiSigType,
1805
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1806
+ });
1807
+ });
1808
+ });
1809
+ });
1810
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUErRDtBQUUvRCxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLHFEQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsNERBQWlDO0FBQ2pDLG1EQVM4QjtBQUM5QixpREFBK0M7QUFDL0MsbUNBV21CO0FBRW5CLG9EQUE0QjtBQUM1Qiw2Q0FBMEM7QUFDMUMsMkRBQTZDO0FBQzdDLDBEQUE0QztBQUM1QyxvREFBNEI7QUFDNUIsMEVBQXVFO0FBQ3ZFLGdFQUE2RDtBQUU3RCxjQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUV4QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksbUJBQW1CLENBQUM7SUFDeEIsSUFBSSxPQUEyQixDQUFDO0lBRWhDLE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sa0JBQWtCLEdBQUcsNENBQTRDLENBQUM7SUFDeEUsTUFBTSxxQkFBcUIsR0FBRyw0Q0FBNEMsQ0FBQztJQUMzRSxNQUFNLEtBQUssR0FDVCw4TkFBOE4sQ0FBQztJQUNqTyxNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQztJQUNyRixNQUFNLFVBQVUsR0FDZCxvSUFBb0ksQ0FBQztJQUV2SSxNQUFNLENBQUM7UUFDTCxNQUFNLFlBQVksR0FDaEIsaUhBQWlILENBQUM7UUFDcEgsTUFBTSxRQUFRLEdBQUcsaUJBQUssQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFD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InNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuXG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBiaXAzMiB9IGZyb20gJ0BiaXRnby1iZXRhL3NlY3AyNTZrMSc7XG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBnZW5lcmF0ZVJhbmRvbVBhc3N3b3JkLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3IsXG4gIE1QQ1N3ZWVwVHhzLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7XG4gIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLFxuICBFcmMyMFRva2VuLFxuICBIdGV0aCxcbiAgVGV0aCxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBUcmFuc2ZlckJ1aWxkZXIsXG4gIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zLFxuICBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLFxuICBVbnNpZ25lZFN3ZWVwVHhNUEN2MixcbiAgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnMsXG59IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBFdGhlcmV1bU5ldHdvcmsgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2V0aCc7XG5pbXBvcnQgKiBhcyBtb2NrRGF0YSBmcm9tICcuLi9maXh0dXJlcy9ldGgnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHsgZXRoTXVsdGlTaWdCYWNrdXBLZXkgfSBmcm9tICcuL2ZpeHR1cmVzL2V0aE11bHRpU2lnQmFja3VwS2V5JztcbmltcG9ydCB7IGV0aFRzc0JhY2t1cEtleSB9IGZyb20gJy4vZml4dHVyZXMvZXRoVHNzQmFja3VwS2V5Jztcblxubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmRlc2NyaWJlKCdFVEg6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGhvcFR4Qml0Z29TaWduYXR1cmU7XG4gIGxldCBzYW5kYm94OiBzaW5vbi5TaW5vblNhbmRib3g7XG5cbiAgY29uc3QgYWRkcmVzczEgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgY29uc3QgYWRkcmVzczIgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcbiAgY29uc3QgaG9wQ29udHJhY3RBZGRyZXNzID0gJzB4NDdjZTdjYzg2ZWZlZmVmMTlmOGZiNTE2YjExNzM1ZDE4M2RhODYzNSc7XG4gIGNvbnN0IGhvcERlc3RpbmF0aW9uQWRkcmVzcyA9ICcweDljN2U4Y2U2ODI1YkQ0ODI3OEIzQWI1OTIyOEVFMjZmOEJFNzkyNWInO1xuICBjb25zdCBob3BUeCA9XG4gICAgJzB4Zjg2YjgwODUwNGE4MTdjOGZmODI1MmZmOTQ5YzdlOGNlNjgyNWJkNDgyNzhiM2FiNTkyMjhlZTI2ZjhiZTc5MjViODcwMzhkN2VhNGM2ODAwMDgwMWNhMDExYmMyMmM2NjQ1NzAxMzNkZmNhNGYwOGEwYjhkMDIzMzljZjQ2NzA0NmQ2YTQxNTJmMDRmMzY4ZDBlYWY5OWVhMDFkNmRjNWNmMGM4OTdjOGQ0YzNlMWRmNTNkMGQwNDI3ODRjNDI0NTM2YTRjYzViODAyNTUyYjdkNjRmZWU4YjUnO1xuICBjb25zdCBob3BUeGlkID0gJzB4NGFmNjUxNDNiYzc3ZGEyYjUwZjM1YjNkMTNjYWNiNGRiMThmMDI2YmY4NGJjMDc0MzU1MGJjNTdiOWI1MzM1MSc7XG4gIGNvbnN0IHVzZXJSZXFTaWcgPVxuICAgICcweDQwNGRiMzA3ZjYxNDdmMGQ4Y2QzMzhjMzRjMTM5MDZlZjQ2YTZmYWE3ZTBlMTE5ZDUxOTRlZjA1YWVjMTZlNmYzZDcxMGY5Yjc5MDE0NjBmOTdlOTI0MDY2YjYyZWZkNzQ0NDNiZDM0NDAyYzZkNDBiNDljMjAzYTU1OWZmMmM4JztcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvS2V5WHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzN0cFdCSFdlMzFzTG9YTlJROUF2UllKZ2l0a0t4UTRBVEZRTXd2cjdoSE5xWVJVblM3UHNqekI3YUsxVnhxSEx1TlFqajFzY2tKMkp3bzJxeG1zdmVqd0VDU3BGTWZDJztcbiAgICBjb25zdCBiaXRnb0tleSA9IGJpcDMyLmZyb21CYXNlNTgoYml0Z29LZXlYcHJ2KTtcbiAgICBpZiAoIWJpdGdvS2V5LnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBjb25zdCBiaXRnb1hwdWIgPSBiaXRnb0tleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgaG9wVHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oc2VjcDI1NmsxLmVjZHNhU2lnbihCdWZmZXIuZnJvbShob3BUeGlkLnNsaWNlKDIpLCAnaGV4JyksIGJpdGdvS2V5LnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoXG4gICAgICAgICdoZXgnXG4gICAgICApO1xuXG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIEVyYzIwVG9rZW4uY3JlYXRlVG9rZW5Db25zdHJ1Y3RvcnMoKS5mb3JFYWNoKCh7IG5hbWUsIGNvaW5Db25zdHJ1Y3RvciB9KSA9PiB7XG4gICAgICBiaXRnby5zYWZlUmVnaXN0ZXIobmFtZSwgY29pbkNvbnN0cnVjdG9yKTtcbiAgICB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RldGgnLCBUZXRoLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2h0ZXRoJywgSHRldGguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGNvbW1vbi5FbnZpcm9ubWVudHNbZW52XS5oc21YcHViID0gYml0Z29YcHViO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFSVAxNTU5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHdpdGggRUlQMTU1OSBmZWUgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgIHBydjogJ3hwcnY5czIxWnJRSDE0M0szaGVreU5qN1RjaVI0WE5ZZTFrTWo2OFcyaXBqSkdOSEVUV1A3bzQyQWpEblNQZ0toZFo0eDhOQkF2YUw3MlJyWGp1WE5kbWtNcUxFUlp6YTczb1l1Z0d0YkxGWEc4ZycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHQmpFNVFHN3BrZjljWkQzM1VVRDZLNDZxN0VMcmJ1RzdGcVhmTE5HaVhZR0hlRW5HQmI1QVdSRW5rMWVBMjhnOEFyWnZVUmJoc2hYV2tUdGRkSFJvNTRmZ3lWdkxkYicsXG4gICAgICAgIHJhd1B1YjogJzAyMzYzNmU2OGI3YjIwNDU3M2FiZGEyNjE2YWZmNmI1ODQ5MTBkZWNlMjU0M2YxY2M2ZDg0MmNhYWM3ZDc0OTc0YicsXG4gICAgICAgIHJhd1BydjogJzc0MzhhNTAwMTBjZTdiMWRmZDg2ZTY4MDQ2Y2M3OGJhMWViZDI0MmQ2ZDg1ZDk5MDRkM2ZjYzA4NzM0YmMxNzInLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhQcmlvcml0eUZlZVBlckdhczogMTAsIG1heEZlZVBlckdhczogMTAgfSxcbiAgICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudDogJzQyJyxcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4YzkzYjEzNjQyZDkzYjQyMThiYjg1ZjY3MzE3ZDZiMzcyODZlODAyOCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZXhwaXJlVGltZTogMTYyNzk0OTIxNCxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IDEyLFxuICAgICAgICAgIGdhc0xpbWl0OiB1bmRlZmluZWQsXG4gICAgICAgICAgZ2FzUHJpY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBob3BUcmFuc2FjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGJhY2t1cEtleU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgc2VxdWVuY2VJZDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogdXNlcktleWNoYWluLnBydixcbiAgICAgIH0gYXMgYW55KTtcblxuICAgICAgKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQuZWlwMTU1OS5tYXhQcmlvcml0eUZlZVBlckdhcy5zaG91bGQuZXF1YWwoMTApO1xuICAgICAgKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKDEwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHdpdGggRUlQMTU1OSBmZWUgcGFyYW1zIGZvciBDQ1InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHNpZ25UcmFuc2FjdGlvbiA9IHNpbm9uLnNweShBYnN0cmFjdEV0aExpa2VOZXdDb2lucy5wcm90b3R5cGUsICdzaWduVHJhbnNhY3Rpb24nKTtcblxuICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICBwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLM2hla3lOajdUY2lSNFhOWWUxa01qNjhXMmlwakpHTkhFVFdQN280MkFqRG5TUGdLaGRaNHg4TkJBdmFMNzJSclhqdVhOZG1rTXFMRVJaemE3M29ZdWdHdGJMRlhHOGcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0JqRTVRRzdwa2Y5Y1pEMzNVVUQ2SzQ2cTdFTHJidUc3RnFYZkxOR2lYWUdIZUVuR0JiNUFXUkVuazFlQTI4ZzhBclp2VVJiaHNoWFdrVHRkZEhSbzU0Zmd5VnZMZGInLFxuICAgICAgICByYXdQdWI6ICcwMjM2MzZlNjhiN2IyMDQ1NzNhYmRhMjYxNmFmZjZiNTg0OTEwZGVjZTI1NDNmMWNjNmQ4NDJjYWFjN2Q3NDk3NGInLFxuICAgICAgICByYXdQcnY6ICc3NDM4YTUwMDEwY2U3YjFkZmQ4NmU2ODA0NmNjNzhiYTFlYmQyNDJkNmQ4NWQ5OTA0ZDNmY2MwODczNGJjMTcyJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcxMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnMTAwMCcsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGtleSA9IHRlc3REYXRhLktFWVBBSVJfUFJWLmdldEtleXMoKS5wcnYgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyXG4gICAgICAgIC5hbW91bnQoJzAnKVxuICAgICAgICAudG8oJzB4MTk2NDUwMzJjN2YxNTMzMzk1ZDQ0YTYyOTQ2MmU3NTEwODRkM2U0YycpXG4gICAgICAgIC5leHBpcmF0aW9uVGltZSgxNTkwMDY2NzI4KVxuICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDUpXG4gICAgICAgIC5rZXkoa2V5KTtcbiAgICAgIHR4QnVpbGRlci5jb250cmFjdChhZGRyZXNzMSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMCwgbWF4RmVlUGVyR2FzOiAxMCB9LFxuICAgICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYW1vdW50OiAnNDInLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnMHhjOTNiMTM2NDJkOTNiNDIxOGJiODVmNjczMTdkNmIzNzI4NmU4MDI4JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBleHBpcmVUaW1lOiAxNjI3OTQ5MjE0LFxuICAgICAgICAgIGNvbnRyYWN0U2VxdWVuY2VJZDogMTIsXG4gICAgICAgICAgZ2FzTGltaXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBnYXNQcmljZTogdW5kZWZpbmVkLFxuICAgICAgICAgIGhvcFRyYW5zYWN0aW9uOiB1bmRlZmluZWQsXG4gICAgICAgICAgYmFja3VwS2V5Tm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzZXF1ZW5jZUlkOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgICB0eEhleDogdHgudG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiB1c2VyS2V5Y2hhaW4ucHJ2LFxuICAgICAgICBpc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5OiB0cnVlLFxuICAgICAgfSBhcyBhbnkpO1xuXG4gICAgICBhc3NlcnQoKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQudHhIZXgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4RmVlUGVyR2FzLCAxMCk7XG5cbiAgICAgIHNhbmRib3guYXNzZXJ0LmNhbGxlZE9uY2Uoc2lnblRyYW5zYWN0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0OiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIGJhdGNoIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICczNTAwMDAwMDAwMDAwJywgYWRkcmVzczogKGNvaW4/LnN0YXRpY3NDb2luPy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaykuYmF0Y2hlckNvbnRyYWN0QWRkcmVzcyB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IEVOUyBhZGRyZXNzIHJlc29sdXRpb24gY2hhbmdpbmcgcmVjaXBpZW50IGFkZHJlc3MgaW4gY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICdiaXRnb3Rlc3R3YWxsZXQuZXRoJyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogJzB4NDBhNjYzOTYzODEwNDQ5ZDZlNzI1MzM2NTdhNzRmMTEyYzNiOTAxYScgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgaG9wIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAxMDAwMDAwMDAwMDAwMDAwLCBhZGRyZXNzOiBob3BEZXN0aW5hdGlvbkFkZHJlc3MgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICc1MDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wQ29udHJhY3RBZGRyZXNzIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIGNsaWVudCB0eFBhcmFtcyBhcmUgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSBudWxsO1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBwYXJhbXMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHR4UHJlYnVpbGQgdGhhdCBpcyBib3RoIGJhdGNoIGFuZCBob3AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzI3NzM5MjgxOTYnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4IGNhbm5vdCBiZSBib3RoIGEgYmF0Y2ggYW5kIGhvcCB0cmFuc2FjdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIG9uZSByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgdGV0aCBkb2Vzbid0IHN1cHBvcnQgc2VuZGluZyB0byBtb3JlIHRoYW4gMSBkZXN0aW5hdGlvbiBhZGRyZXNzIHdpdGhpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbi4gVHJ5IGFnYWluLCB1c2luZyBvbmx5IGEgc2luZ2xlIHJlY2lwaWVudC5gXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGhvcCB0eFByZWJ1aWxkIHRoYXQgZG9lcyBub3Qgc2VuZCB0byBpdHMgaG9wIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcwJyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdyZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGhvcCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGJhdGNoIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIHRvdGFsIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnNTUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IChjb2luPy5zdGF0aWNzQ29pbj8ubmV0d29yayBhcyBFdGhlcmV1bU5ldHdvcmspLmJhdGNoZXJDb250cmFjdEFkZHJlc3MgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdiYXRjaCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IGRvZXMgbm90IHNlbmQgdG8gdGhlIGJhdGNoZXIgY29udHJhY3QgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdyZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGJhdGNoZXIgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzIwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnbm9ybWFsIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0b2tlbiB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXN0Jyk7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHRva2VuOiAndGVzdCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIGNvaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAnYnRjJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2NvaW4gaW4gdHhQcmVidWlsZCBkaWQgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGRyZXNzIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnaXNXYWxsZXRBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gYWRkcmVzcyBnZW5lcmF0ZWQgdXNpbmcgZm9yd2FyZGVyIHZlcnNpb24gMScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYxZDNjOWZjZThmNWFhNjkxNTY5YTk5ZWInLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dWYjNQZkN6d2lFWDk0QUIxbkpRdHpWbXNhNVNyaU5yZktaWkFjQXZSZ3hoMUF1Z202czh5b0Q4Z1NrcTJGZFo4WUNkVlhVZ0xqZjlReHZkWUFKSzVVdGhBbXBRc2hVJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYwYjc0ZTczYjFmNDQwZWE0YWNlZGE4N2UnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjQ2cFJIZGEzc1pidVB6emE5QTlNaXFBVTlKUm9kOGh1WXR5VjROWTJvZUpYc2lzN3IyNkwxdm1MbnRmOUJjWkplMW00Q1FOU3ZZV2Z3cGUxaFNwbzZKNHg2WUYxZU4nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhva1lMYzVQWFpNMTlWOFVyYnVMZFZSYUNRTXM0RWVDQWpucW1vWVhxZnl1c1RVNDZXb1pNRHlMcG1Uem9VWDY2WkJ3R0ZqdDFhJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHg2MDY5YTRiYWYyMzYwYmY2N2E2ZDAyYTdmYzQzZDhmMzkxMDAxNmFlJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTEyNTNiY2NlN2Q4N2RiNTIyZmJjZWVjNmU1NWM5Zjc4YzM3NmQ5ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3JyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFuIGFkZHJlc3MgZ2VuZXJhdGVkIHVzaW5nIGZvcndhcmRlciB2ZXJzaW9uIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiM2M4YWFhNzkxMTE4ZDljZTYxNmQzYjIxJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHckN4Q1gzOXpiM1R2WWpUcWZVR3dFVVpIam5yYVJGbTFXZU13OWdmQ0Qxd3djMndVRG1CQloyVGtjY0pNd2Y1ZUJUamE4cjN6NkhNeG9UWkdXNm52eW9KTVFGc2VjdicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiMTk2N2ZkNmQ5ODY3YTIyYTFhNDEzMWEwJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dLaGRlQzRucjF0YThkMjd4VGh0ZkZGSGdieFdNclZiNTk1bWVNUzhpM2ZCTXJUejhFZFFNV0JLSEhLenhhcEdnaGVvTXltVnZSY1FtYUdEeWtSVEJidFhxYml1OXBzJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2tZTGM1UFhaTTE5VjhVcmJ1TGRWUmFDUU1zNEVlQ0FqbnFtb1lYcWZ5dXNUVTQ2V29aTUR5THBtVHpvVVg2NlpCd0dGanQxYScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZjYzNmNlZGRmZmU0MWQxMDY1ODY4NzVjMGU1NmRjOGZlYjYyNjhmNycsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgc2FsdDogJzB4MTcnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMjMsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgd2FsbGV0IHZlcnNpb24gNSBmb3J3YXJkZXIgdmVyc2lvbiA0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZTI0MmQ5M2Y4ZDdhZDA3MDU4ODc0NDk3NjNjOTYnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJkZjhiNjMyM2Q0YjA4ZGYzNjY4NjRhZjY2JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJjMDU5NWI0Y2ZlZTZmOTU3YzFkNjQ1OGY3JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkNjNiNWUyYjhkMWI0ZmJhMzYyNTQ2MDUwODkwMGJmMmEwNDk5YTRkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3NScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHdhbGxldCB2ZXJzaW9uIDYgZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4YTMzZjA5NzVmNTNjZGNmY2MwY2I1NjRkMjVmYjViZTAzYjA2NTFjZicsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gYWN0dWFsIGFkZHJlc3MgZGlmZmVycyBmcm9tIGV4cGVjdGVkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHgyODkwNDU5MWY3MzU5OTRmMDUwODA0ZmRhM2I2MWI4MTNiMTZlMDRjJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb2luU3BlY2lmaWMgZmllbGQgaXMgbm90IGFuIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksXG4gICAgICAgICAgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgdGhlIGRlcml2ZWQgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhlMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4YnZmJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgYmFzZSBhZGRyZXNzIGlzIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksIEludmFsaWRBZGRyZXNzRXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlmIGJhc2UgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTBiNTZlZWFlMWIyODM5MThjYWNhMDJhMTRhZGEyZGYxN2E5OGJ2ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ01QQyB3YWxsZXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICAgJzAzZjljMmZiMmU1YThiNzhhNDRmNWQxZTRmOTA2ZjhlM2Q3YTBlNmI1YzRkM2UyZjFhMGI5YzhkN2U2ZjVhNGIzYzJkMWUwZjllOGQ3YzZiNWE0JyArXG4gICAgICAgICAgJzkzODI3MTYwNTk0ODU3NDYzNzI4MTkwYTBiMGMwZDBlMGYxMDExMTIxMzE0MTUxNjE3MTgxOTFhMWIxYzFkMWUxZic7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7IHB1YjogJ3VzZXJfcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgICB7IHB1YjogJ2JhY2t1cF9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYml0Z29fcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBNUEMgd2FsbGV0IGFkZHJlc3Mgd2l0aCBmb3J3YXJkZXIgdmVyc2lvbiAzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDAxMTUzZjNhZGZlNDU0YTcyNTg5Y2E5ZWY3NGYwMTNjMTllNTQ5NjEnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHgwMTE1M2YzYWRmZTQ1NGE3MjU4OWNhOWVmNzRmMDEzYzE5ZTU0OTYxJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IE1QQyB3YWxsZXQgYWRkcmVzcyB3aXRoIHdyb25nIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggaW52YWxpZCBhZGRyZXNzIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHhpbnZhbGlkJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYga2V5Y2hhaW5zIGFyZSBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDllN2NlOGMyNGQ5Zjc2YTgxNGUyMzYzM2U2MWJlN2NiOGU2ZTJkNWUnLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMgYXMgYW55KSwgRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IGludmFsaWRLZXljaGFpbnMgPSBbeyBwdWI6ICd1c2VyX3B1YicgfSwgeyBwdWI6ICdiYWNrdXBfcHViJyB9LCB7IHB1YjogJ2JpdGdvX3B1YicgfV07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg5ZTdjZThjMjRkOWY3NmE4MTRlMjM2MzNlNjFiZTdjYjhlNmUyZDVlJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWluczogaW52YWxpZEtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBFcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdCYXNlIEFkZHJlc3MgVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBiYXNlIGFkZHJlc3MgZm9yIHdhbGxldCB2ZXJzaW9uIDYgKFRTUyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGUwYzU2MDk4Mjg4YTliN2ZhMTA3ZGIxNDQnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGYxZDNjOWZjZThmNWE3MzBiZmY4MjZjZjknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NSc7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmFzZSBhZGRyZXNzIGZvciB3YWxsZXQgdmVyc2lvbiA1IChUU1MpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWUyNDJkOTNmOGQ3YWQwNzA1ODg3NDQ5NzYzYzk2JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWUyNDJkZjhiNjMyM2Q0YjA4ZGYzNjY4NjRhZjY2JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZTI0MmMwNTk1YjRjZmVlNmY5NTdjMWQ2NDU4ZjcnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGYxZTNkMzA3OThhY2RmM2ExMmZhNWJlYjVmYWQ4ZWZiMjNkNWJlMTEnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGJhc2UgYWRkcmVzcyB2ZXJpZmljYXRpb24gd2l0aCBub24temVybyBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZTBjNTYwOTgyODhhOWI3ZmExMDdkYjE0NCcsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBkNTY3MzVlNWViNjFiMDZlMzUzZmU3NjM5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JztcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogNSwgLy8gV3JvbmcgaW5kZXggLSBzaG91bGQgYmUgMCBmb3IgYmFzZSBhZGRyZXNzXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSxcbiAgICAgICAgICAgIC9CYXNlIGFkZHJlc3MgdmVyaWZpY2F0aW9uIHJlcXVpcmVzIGluZGV4IDAsIGJ1dCBnb3QgaW5kZXggNS9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBiYXNlIGFkZHJlc3MgdmVyaWZpY2F0aW9uIHdpdGggd3JvbmcgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZTBjNTYwOTgyODhhOWI3ZmExMDdkYjE0NCcsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBkNTY3MzVlNWViNjFiMDZlMzUzZmU3NjM5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3Qgd3JvbmdBZGRyZXNzID0gJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMSc7XG4gICAgICAgICAgY29uc3QgYWN0dWFsQmFzZUFkZHJlc3MgPSAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JztcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHdyb25nQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBhY3R1YWxCYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gMiAoQklQMzIpIHVzaW5nIHdhbGxldCBmYWN0b3J5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhkYzQ4NWRhMDc2ZWQ0YTJiMTk1ODRlOWExZmRiYjk3NGY4OWI2MGY0JztcbiAgICAgICAgICBjb25zdCB3YWxsZXRTYWx0ID0gJzB4Mic7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZThjN2IzYzhhYWE3OTExMThkOWNlNjE2ZDNiMjEnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4OWQxNmJiODY3Yjc5MmM1ZTNiZjYzNmEwMjc1ZjJkYjg2MDFiZDdkNCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWU4YzdiMTk2N2ZkNmQ5ODY3YTIyYTFhNDEzMWEwJyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4MmRmY2U1Y2ZlYjVjMDNmYmU2ODBjZDM5YWMwZDJiMjUzOTliN2QyMicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY4YjllYzU4N2QwYmExYzc0NDBkZTU1MTA2OGMzNmE3JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6IHdhbGxldFNhbHQsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zOiBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDIsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBiYXNlIGFkZHJlc3MgZm9yIHdhbGxldCB2ZXJzaW9uIDEgKEJJUDMyKSB1c2luZyB3YWxsZXQgZmFjdG9yeScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4ZTEyNTNiY2NlN2Q4N2RiNTIyZmJjZWVjNmU1NWM5Zjc4YzM3NmQ5Zic7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0U2FsdCA9ICcweDUnO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzhmMWQzYzlmY2U4ZjVhYTY5MTU2OWE5OWViJyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweGY0NWRhZGNlNzUxYTMxNzk1N2YyYTI0N2ZmMzdjYjc2NGI5NzYyMGQnLFxuICAgICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR1ZiM1BmQ3p3aUVYOTRBQjFuSlF0elZtLi4uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYwYjc0ZTczYjFmNDQwZWE0YWNlZGE4N2UnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHg1YmRmM2FlMWQyYzJmYWRlZWI3MGE0NTg3MmJmNGY0MjUyMzEyYjU1JyxcbiAgICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0Y0NnBSSGRhM3NaYnVQenphOUE5TWlxQS4uLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY4YjllYzU4N2QwYmExYzc0NDBkZTU1MTA2OGMzNmE3JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhvay4uLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiB3YWxsZXRTYWx0LFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWluczoga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZHJlc3MgQ3JlYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwYXNzIHdhbGxldFZlcnNpb24gNiB0byBpc1dhbGxldEFkZHJlc3MgZHVyaW5nIGFkZHJlc3MgY3JlYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGNvbnN0IGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YVY2ID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBldGhXYWxsZXRWNiA9IG5ldyBXYWxsZXQoYml0Z28sIGV0aENvaW4sIHdhbGxldERhdGFWNik7XG4gICAgICBjb25zdCBpc1dhbGxldEFkZHJlc3NTcHkgPSBzaW5vbi5zcHkoZXRoQ29pbiwgJ2lzV2FsbGV0QWRkcmVzcycpO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIHJlcXVlc3RzXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkN2ApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgYWRkcmVzcyBjcmVhdGlvbiBBUElcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldFY2LmlkKCl9L2FkZHJlc3NgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NScsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFY2LmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgYXdhaXQgZXRoV2FsbGV0VjYuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwIH0pO1xuXG4gICAgICBpc1dhbGxldEFkZHJlc3NTcHkuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgY29uc3QgY2FsbGVkUGFyYW1zID0gaXNXYWxsZXRBZGRyZXNzU3B5LmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgY2FsbGVkUGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRWZXJzaW9uJywgNik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgd2FsbGV0VmVyc2lvbiA1IHRvIGlzV2FsbGV0QWRkcmVzcyBkdXJpbmcgYWRkcmVzcyBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjUgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGYxZTNkMzA3OThhY2RmM2ExMmZhNWJlYjVmYWQ4ZWZiMjNkNWJlMTEnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFY1ID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVY1KTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1NweSA9IHNpbm9uLnNweShldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJyk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRnNYU2hXOFIzaEpzSE5UWVRVd3pjZWpuTGtZN0tDdGFKYkRxY0drY0JGOTlCckVKU2pOWkhlSHZlaVlVcnNBZHdualVNR3dwZ21FYmlLY1pXUnVWQTlIeG5SYUEzcjMnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjUuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkNjNiNWUyYjhkMWI0ZmJhMzYyNTQ2MDUwODkwMGJmMmEwNDk5YTRkJyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMTE3LFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0OiBldGhXYWxsZXRWNS5pZCgpLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNCxcbiAgICAgICAgICAgIHNhbHQ6ICcweDc1JyxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRWNS5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBpc1dhbGxldEFkZHJlc3Mgd2FzIGNhbGxlZCB3aXRoIHdhbGxldFZlcnNpb24gNVxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3B5LmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGNvbnN0IGNhbGxlZFBhcmFtcyA9IGlzV2FsbGV0QWRkcmVzc1NweS5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIGNhbGxlZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0VmVyc2lvbicsIDUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIHdhbGxldFZlcnNpb24gMiB0byBpc1dhbGxldEFkZHJlc3MgZHVyaW5nIGFkZHJlc3MgY3JlYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGNvbnN0IGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YVYyID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDIsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkYzQ4NWRhMDc2ZWQ0YTJiMTk1ODRlOWExZmRiYjk3NGY4OWI2MGY0JyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBldGhXYWxsZXRWMiA9IG5ldyBXYWxsZXQoYml0Z28sIGV0aENvaW4sIHdhbGxldERhdGFWMik7XG4gICAgICBjb25zdCBpc1dhbGxldEFkZHJlc3NTcHkgPSBzaW5vbi5zcHkoZXRoQ29pbiwgJ2lzV2FsbGV0QWRkcmVzcycpO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIHJlcXVlc3RzXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR3JDeENYMzl6YjNUdllqVHFmVUd3RVVaSGpucmFSRm0xV2VNdzlnZkNEMXd3YzJ3VURtQkJaMlRrY2NKTXdmNWVCVGphOHIzejZITXhvVFpHVzZudnlvSk1RRnNlY3YnLFxuICAgICAgICBldGhBZGRyZXNzOiAnMHg5ZDE2YmI4NjdiNzkyYzVlM2JmNjM2YTAyNzVmMmRiODYwMWJkN2Q0JyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHS2hkZUM0bnIxdGE4ZDI3eFRodGZGRkhnYnhXTXJWYjU5NW1lTVM4aTNmQk1yVHo4RWRRTVdCS0hIS3p4YXBHZ2hlb015bVZ2UmNRbWFHRHlrUlRCYnRYcWJpdTlwcycsXG4gICAgICAgIGV0aEFkZHJlc3M6ICcweDJkZmNlNWNmZWI1YzAzZmJlNjgwY2QzOWFjMGQyYjI1Mzk5YjdkMjInLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR3pUbjVleU5HRGtiMThSNDNuSDc5SG9rWUxjNVBYWk0xOVY4VXJidUxkVlJhQ1FNczRFZUNBam5xbW9ZWHFmeXVzVFU0NldvWk1EeUxwbVR6b1VYNjZaQndHRmp0MWEnLFxuICAgICAgICBldGhBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgYWRkcmVzcyBjcmVhdGlvbiBBUElcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldFYyLmlkKCl9L2FkZHJlc3NgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogJzB4ZjYzNmNlZGRmZmU0MWQxMDY1ODY4NzVjMGU1NmRjOGZlYjYyNjhmNycsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDIzLFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0OiBldGhXYWxsZXRWMi5pZCgpLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICAgIHNhbHQ6ICcweDE3JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgYXdhaXQgZXRoV2FsbGV0VjIuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgaXNXYWxsZXRBZGRyZXNzIHdhcyBjYWxsZWQgd2l0aCB3YWxsZXRWZXJzaW9uIDJcbiAgICAgIGlzV2FsbGV0QWRkcmVzc1NweS5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjb25zdCBjYWxsZWRQYXJhbXMgPSBpc1dhbGxldEFkZHJlc3NTcHkuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBjYWxsZWRQYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFZlcnNpb24nLCAyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2NiBhZGRyZXNzIGNyZWF0aW9uIGlmIHdhbGxldFZlcnNpb24gd2FzIG5vdCBwYXNzZWQgKHNpbXVsYXRlcyBvbGQgYnVnKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjYgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFY2ID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVY2KTtcblxuICAgICAgLy8gU3R1YiBpc1dhbGxldEFkZHJlc3MgdG8gc2ltdWxhdGUgdGhlIE9MRCBidWcgd2hlcmUgd2FsbGV0VmVyc2lvbiB3YXMgbm90IHBhc3NlZFxuICAgICAgY29uc3Qgb3JpZ2luYWxJc1dhbGxldEFkZHJlc3MgPSBldGhDb2luLmlzV2FsbGV0QWRkcmVzcy5iaW5kKGV0aENvaW4pO1xuICAgICAgY29uc3QgaXNXYWxsZXRBZGRyZXNzU3R1YiA9IHNpbm9uLnN0dWIoZXRoQ29pbiwgJ2lzV2FsbGV0QWRkcmVzcycpLmNhbGxzRmFrZShhc3luYyAocGFyYW1zKSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSB3YWxsZXRWZXJzaW9uIHRvIHNpbXVsYXRlIHRoZSBvbGQgYnVnXG4gICAgICAgIGNvbnN0IHBhcmFtc1dpdGhvdXRXYWxsZXRWZXJzaW9uID0geyAuLi5wYXJhbXMgfTtcbiAgICAgICAgZGVsZXRlIChwYXJhbXNXaXRob3V0V2FsbGV0VmVyc2lvbiBhcyBhbnkpLndhbGxldFZlcnNpb247XG4gICAgICAgIHJldHVybiBvcmlnaW5hbElzV2FsbGV0QWRkcmVzcyhwYXJhbXNXaXRob3V0V2FsbGV0VmVyc2lvbik7XG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBrZXljaGFpbiByZXF1ZXN0c1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGc1hTaFc4UjNoSnNITlRZVFV3emNlam5Ma1k3S0N0YUpiRHFjR2tjQkY5OUJyRUpTak5aSGVIdmVpWVVyc0Fkd25qVU1Hd3BnbUViaUtjWldSdVZBOUh4blJhQTNyMycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGFkZHJlc3MgY3JlYXRpb24gQVBJXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXRWNi5pZCgpfS9hZGRyZXNzYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0OiBldGhXYWxsZXRWNi5pZCgpLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNCxcbiAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgIC8vIFdpdGhvdXQgd2FsbGV0VmVyc2lvbiwgYWRkcmVzcyBjcmVhdGlvbiBzaG91bGQgZmFpbCBiZWNhdXNlXG4gICAgICAvLyB0aGUgY29kZSBkb2Vzbid0IGtub3cgdG8gdXNlIFRTUyB2ZXJpZmljYXRpb24gZm9yIHY2IHdhbGxldHNcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGV0aFdhbGxldFY2LmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCB9KSwgVW5leHBlY3RlZEFkZHJlc3NFcnJvcik7XG5cbiAgICAgIGlzV2FsbGV0QWRkcmVzc1N0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRVZNIENyb3NzIENoYWluIFJlY292ZXJ5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdXNlcktleSA9XG4gICAgICAgICd7XCJpdlwiOlwiVkZaM2p2WGh4bzFaK1lhZjJNdFpuQT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwicCtma0h1TGEvOGs9XCIsXCJjdFwiOlwiaFlHN3B2bGpMSWdDalpcXG4nICtcbiAgICAgICAgJzUzUEJsQ2RlNUtaUm1sVUtLSEx0RE1rK0hKZnVVNDZoVyt4K0M5V3NJQU80Z0ZQblRDdkZWbVE4eDdjekN0Y05GdWI1QU8yb3RPR1xcbicgK1xuICAgICAgICAnT3NYNEdFMmdYT0VtQ2wxVHBXd3dOaG03eU1VakdKVXBnVzZaWmdYU1hkRGl0U0tpNFYvaGs3OFNHU3pqRk9CU1BZUmE2ST1cIn1cXG4nO1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3RBZGRyZXNzID0gVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGJpdGdvRmVlQWRkcmVzcyA9ICcweDMzYTQyZmFlYTNjNmU4NzAyMTM0N2U1MTcwMGI0OGFhZjQ5YWExZTcnO1xuICAgICAgY29uc3QgZGVzdGluYXRpb25BZGRyZXNzID0gJzB4ZDVBRGRFMTdmZUQ4YmFlZDNGMzJiODRBRjA1QjhGMjgxNmY3YjU2MCc7XG4gICAgICBjb25zdCBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyA9ICcweEU1OTg2Q0U0NDkwRGViNjdkMjk1MDU2MkNlYjkzMERkZjliZTdhMTQnO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFIGFzIHN0cmluZztcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3Qod2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHNweSA9IHNpbm9uLnNweShUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLCAnY29pblVzZXNOb25QYWNrZWRFbmNvZGluZ0ZvclR4RGF0YScpO1xuICAgICAgYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGludGVuZGVkQ2hhaW46ICd0YXJiZXRoJyxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0KHNweS5yZXR1cm5lZCh0cnVlKSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTm9uLUJpdEdvIFJlY292ZXJ5IGZvciBIb3QgV2FsbGV0cyAoTVBDdjIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICAgIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICAgICAgbGV0IGJhc2Vjb2luOiBIdGV0aDtcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIE1QQ3YyIGtpbmQgb2YgaG90IHdhbGxldHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCkuYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCkuYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKTtcblxuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IHBhcmFtcy5iaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBwYXJhbXMuYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgaW50ZW5kZWRDaGFpbjogcGFyYW1zLmludGVuZGVkQ2hhaW4sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgdXNlciBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEludmFsaWROb25CaXRHb1JlY292ZXJ5UGFyYW1zKCk7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcGFyYW1zLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBwYXJhbXMuYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IHBhcmFtcy5iaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICAgICAgaW50ZW5kZWRDaGFpbjogcGFyYW1zLmludGVuZGVkQ2hhaW4sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICd1c2VyIGtleSBpcyBpbnZhbGlkJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQnVpbGQgVW5zaWduZWQgU3dlZXAgZm9yIFNlbGYtQ3VzdG9keSBDb2xkIFdhbGxldHMgKE1QQ3YyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgICAgIGxldCBiYXNlY29pbjogSHRldGg7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBzd2VlcCB3aXRob3V0IGRlcml2YXRpb24gc2VlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3Qgc3dlZXBSZXN1bHQgPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEEgRGF0YVxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5leGlzdChzd2VlcFJlc3VsdCk7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IHN3ZWVwUmVzdWx0IGFzIFVuc2lnbmVkU3dlZXBUeE1QQ3YyO1xuICAgICAgICBvdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UmVxdWVzdHMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdpbnZhbGlkQWRkcmVzcyc7XG5cbiAgICAgICAgLy8gRW5zdXJlIHVzZXJLZXkgYW5kIGJhY2t1cEtleSBhcmUgdGhlIHNhbWVcbiAgICAgICAgcGFyYW1zLnVzZXJLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcbiAgICAgICAgcGFyYW1zLmJhY2t1cEtleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiAyMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LCAvLyBQcm92aWRlIHRoZSB1c2VyS2V5XG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSwgLy8gUHJvdmlkZSB0aGUgYmFja3VwS2V5XG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcywgLy8gUHJvdmlkZSB0aGUgd2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgJ0Vycm9yOiBpbnZhbGlkIGFkZHJlc3MnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdCdWlsZCBVbnNpZ25lZCBDb25zb2xpZGF0aW9uIGZvciBTZWxmLUN1c3RvZHkgQ29sZCBXYWxsZXRzIChNUEN2MiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgICAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gICAgICBsZXQgYmFzZWNvaW46IEh0ZXRoO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgY29uc29saWRhdGlvbiBmb3Igd2FsbGV0IHY1JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShcbiAgICAgICAgICAgIG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KFxuICAgICAgICAgICAgICBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9uUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6ICcweDMzYTQyZmFlYTNjNmU4NzAyMTM0N2U1MTcwMGI0OGFhZjQ5YWExZTcnLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5leGlzdChjb25zb2xpZGF0aW9uUmVzdWx0KTtcbiAgICAgICAgY29uc3QgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbiA9IGNvbnNvbGlkYXRpb25SZXN1bHQgYXMgVW5zaWduZWRCdWlsQ29uc29saWRhdGlvbjtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcblxuICAgICAgICBjb25zdCBvdXRwdXQgPSB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9uc1swXSBhcyBNUENTd2VlcFR4cztcbiAgICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzZXJpYWxpemVkVHhIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgICAgY29uc3QgcGFyc2VkVHggPSBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IHNwZW5kQW1vdW50OiBzdHJpbmcgfTtcbiAgICAgICAgcGFyc2VkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NwZW5kQW1vdW50Jyk7XG4gICAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICdvdXRwdXRzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgY29uc29saWRhdGlvbiBmb3Igd2FsbGV0IHY2JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShcbiAgICAgICAgICAgIG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KFxuICAgICAgICAgICAgICBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9uUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEEgRGF0YVxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJzEyMycsIC8vIFdyb25nIHdhbGxldCBhZGRyZXNzIHNvIHRoYXQgd2UgY2FuIHNraXAgdjUgYWRkcmVzcyBnZW5lcmF0aW9uXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JyxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3QoY29uc29saWRhdGlvblJlc3VsdCk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24gPSBjb25zb2xpZGF0aW9uUmVzdWx0IGFzIFVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb247XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnNbMF0gYXMgTVBDU3dlZXBUeHM7XG4gICAgICAgIG91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdpbnZhbGlkQWRkcmVzcyc7XG5cbiAgICAgICAgLy8gRW5zdXJlIHVzZXJLZXkgYW5kIGJhY2t1cEtleSBhcmUgdGhlIHNhbWVcbiAgICAgICAgcGFyYW1zLnVzZXJLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcbiAgICAgICAgcGFyYW1zLmJhY2t1cEtleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiAyMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LCAvLyBQcm92aWRlIHRoZSB1c2VyS2V5XG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSwgLy8gUHJvdmlkZSB0aGUgYmFja3VwS2V5XG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcywgLy8gUHJvdmlkZSB0aGUgd2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgJ0Vycm9yOiBpbnZhbGlkIGFkZHJlc3MnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBvdmVycmlkZSB0aGUgdG9rZW4gcGFyYW1ldGVyIHdpdGggYSBjdXN0b20gQVBJIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgIGFkZHJlc3M6ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGN1c3RvbUFwaUtleSA9ICdjdXN0b20tYXBpLWtleS1mb3ItdGVzdCc7XG5cbiAgICAgIC8vIE1vY2sgdGhlIGVudmlyb25tZW50IEFQSSB0b2tlblxuICAgICAgY29uc3Qgb3JpZ2luYWxBcGlUb2tlbiA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5BcGlUb2tlbjtcbiAgICAgIGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5BcGlUb2tlbiA9ICdkZWZhdWx0LWVudmlyb25tZW50LWFwaS1rZXknO1xuXG4gICAgICAvLyBNb2NrIHRoZSByZXF1ZXN0LmdldCBmdW5jdGlvbiB0byBjYXB0dXJlIHRoZSBxdWVyeSBwYXJhbWV0ZXJzXG4gICAgICBjb25zdCBvcmlnaW5hbEdldCA9IHJlcXVlc3QuZ2V0O1xuICAgICAgbGV0IGNhcHR1cmVkUXVlcnk7XG5cbiAgICAgIHJlcXVlc3QuZ2V0ID0gZnVuY3Rpb24gKHVybDogc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcXVlcnk6IGZ1bmN0aW9uIChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICAgICAgICAgIGNhcHR1cmVkUXVlcnkgPSBwYXJhbXM7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICAgICAgYm9keTogeyByZXN1bHQ6ICcxMDAwMDAwMDAnIH0sXG4gICAgICAgICAgICB9IGFzIGFueTtcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIGFueTtcbiAgICAgIH07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIENhbGwgd2l0aCBkZWZhdWx0IEFQSSBrZXlcbiAgICAgICAgYXdhaXQgY29pbi5yZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgY2FwdHVyZWRRdWVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYXBpa2V5JywgJ2RlZmF1bHQtZW52aXJvbm1lbnQtYXBpLWtleScpO1xuXG4gICAgICAgIC8vIENhbGwgd2l0aCBjdXN0b20gQVBJIGtleVxuICAgICAgICBhd2FpdCBjb2luLnJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnkocXVlcnksIGN1c3RvbUFwaUtleSk7XG4gICAgICAgIGNhcHR1cmVkUXVlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FwaWtleScsIGN1c3RvbUFwaUtleSk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIGZ1bmN0aW9uIGFuZCBBUEkgdG9rZW5cbiAgICAgICAgcmVxdWVzdC5nZXQgPSBvcmlnaW5hbEdldDtcbiAgICAgICAgY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkFwaVRva2VuID0gb3JpZ2luYWxBcGlUb2tlbjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0F1ZGl0IEtleScsICgpID0+IHtcbiAgICBsZXQgY29pbjogSHRldGg7XG4gICAgYmVmb3JlKCgpID0+IHtcbiAgICAgIGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ011bHRpU2lnJywgKCkgPT4ge1xuICAgICAgY29uc3QgeyBrZXkgfSA9IGV0aE11bHRpU2lnQmFja3VwS2V5O1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB7IGlzVmFsaWQ6IHRydWUgfSBmb3IgdmFsaWQgaW5wdXRzJywgKCkgPT4ge1xuICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdaUThNaHhUODRtNFAnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSB3YWxsZXRQYXNzcGhyYXNlIGlzIGluY29ycmVjdCcsICgpID0+IHtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmb28nLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiBcImZhaWxlZCB0byBkZWNyeXB0IHBydjogY2NtOiB0YWcgZG9lc24ndCBtYXRjaFwiIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSBrZXkgaXMgYWx0ZXJlZCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGFsdGVyZWRLZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdrQW1bRUZRNm89U3hsY0xGRHclLCcsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGpzb24gZGVjcnlwdDogaW52YWxpZCBwYXJhbWV0ZXJzJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdUU1MnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGtleToga2V5U3RyaW5nLCBjb21tb25LZXljaGFpbiB9ID0gZXRoVHNzQmFja3VwS2V5O1xuICAgICAgY29uc3Qga2V5ID0ga2V5U3RyaW5nLnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2tBbVtFRlE2bz1TeGxjTEZEdyUsJztcbiAgICAgIGNvbnN0IG11bHRpU2lnVHlwZSA9ICd0c3MnO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgaW5wdXRzJywgKCkgPT4ge1xuICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdGhlIGNvbW1vbktleWNoYWluIGlzIGFsdGVyZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRDb21tb25LZXljaGFpbiA9IGdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoMTApO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgY29tbW9uIGtleWNoYWluJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluY29ycmVjdFBhc3NwaHJhc2UgPSAnZm9vJztcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGluY29ycmVjdFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogXCJmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGNjbTogdGFnIGRvZXNuJ3QgbWF0Y2hcIiB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUga2V5IGlzIGFsdGVyZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRLZXkgPSBrZXkucmVwbGFjZSgvWzAtOV0vZywgJzAnKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhbHRlcmVkS2V5LFxuICAgICAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGpzb24gZGVjcnlwdDogaW52YWxpZCBwYXJhbWV0ZXJzJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==