@bitgo-beta/sdk-coin-eth 4.4.1-beta.185 → 4.4.1-beta.1850

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 (119) hide show
  1. package/dist/src/erc20Token.d.ts +1 -1
  2. package/dist/src/erc20Token.d.ts.map +1 -1
  3. package/dist/src/erc20Token.js +49 -28
  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/erc7984Token.d.ts +94 -0
  8. package/dist/src/erc7984Token.d.ts.map +1 -0
  9. package/dist/src/erc7984Token.js +328 -0
  10. package/dist/src/eth.d.ts +10 -8
  11. package/dist/src/eth.d.ts.map +1 -1
  12. package/dist/src/eth.js +49 -35
  13. package/dist/src/index.d.ts +2 -0
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +8 -2
  16. package/dist/src/lib/index.d.ts +1 -0
  17. package/dist/src/lib/index.d.ts.map +1 -1
  18. package/dist/src/lib/index.js +7 -2
  19. package/dist/src/lib/messages/index.d.ts +3 -0
  20. package/dist/src/lib/messages/index.d.ts.map +1 -0
  21. package/dist/src/lib/messages/index.js +6 -0
  22. package/dist/src/lib/transactionBuilder.d.ts +10 -5
  23. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/transactionBuilder.js +17 -7
  25. package/dist/src/lib/transferBuilders/index.d.ts +2 -2
  26. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
  27. package/dist/src/lib/transferBuilders/index.js +3 -2
  28. package/dist/src/register.d.ts +2 -0
  29. package/dist/src/register.d.ts.map +1 -1
  30. package/dist/src/register.js +36 -2
  31. package/dist/test/fixtures/eth.d.ts +39 -0
  32. package/dist/test/fixtures/eth.d.ts.map +1 -0
  33. package/dist/test/fixtures/eth.js +262 -0
  34. package/dist/test/resources/erc1155Abi.d.ts +40 -0
  35. package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
  36. package/dist/test/resources/erc1155Abi.js +329 -0
  37. package/dist/test/resources/erc721Abi.d.ts +12 -0
  38. package/dist/test/resources/erc721Abi.d.ts.map +1 -0
  39. package/dist/test/resources/erc721Abi.js +34 -0
  40. package/dist/test/resources/eth.d.ts +51 -0
  41. package/dist/test/resources/eth.d.ts.map +1 -0
  42. package/dist/test/resources/eth.js +72 -0
  43. package/dist/test/resources/nftEncodings.d.ts +4 -0
  44. package/dist/test/resources/nftEncodings.d.ts.map +1 -0
  45. package/dist/test/resources/nftEncodings.js +7 -0
  46. package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
  47. package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
  48. package/dist/test/resources/walletSimpleAbi.js +44 -0
  49. package/dist/test/unit/erc7984Token.d.ts +2 -0
  50. package/dist/test/unit/erc7984Token.d.ts.map +1 -0
  51. package/dist/test/unit/erc7984Token.js +743 -0
  52. package/dist/test/unit/eth.d.ts +2 -0
  53. package/dist/test/unit/eth.d.ts.map +1 -0
  54. package/dist/test/unit/eth.js +2568 -0
  55. package/dist/test/unit/ethWallet.d.ts +2 -0
  56. package/dist/test/unit/ethWallet.d.ts.map +1 -0
  57. package/dist/test/unit/ethWallet.js +472 -0
  58. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
  59. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
  60. package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
  61. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
  62. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
  63. package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -0
  64. package/dist/test/unit/getBuilder.d.ts +3 -0
  65. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  66. package/dist/test/unit/getBuilder.js +10 -0
  67. package/dist/test/unit/keyPair.d.ts +2 -0
  68. package/dist/test/unit/keyPair.d.ts.map +1 -0
  69. package/dist/test/unit/keyPair.js +175 -0
  70. package/dist/test/unit/register.d.ts +2 -0
  71. package/dist/test/unit/register.d.ts.map +1 -0
  72. package/dist/test/unit/register.js +73 -0
  73. package/dist/test/unit/transaction.d.ts +2 -0
  74. package/dist/test/unit/transaction.d.ts.map +1 -0
  75. package/dist/test/unit/transaction.js +117 -0
  76. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  77. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  78. package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
  79. package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
  80. package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
  81. package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
  82. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +2 -0
  83. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
  84. package/dist/test/unit/transactionBuilder/decryptionDelegation.js +59 -0
  85. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts +2 -0
  86. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts.map +1 -0
  87. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.js +136 -0
  88. package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
  89. package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
  90. package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
  91. package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
  92. package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
  93. package/dist/test/unit/transactionBuilder/flushTokens.js +285 -0
  94. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  95. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  96. package/dist/test/unit/transactionBuilder/send.js +331 -0
  97. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts +2 -0
  98. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts.map +1 -0
  99. package/dist/test/unit/transactionBuilder/sendERC7984Token.js +361 -0
  100. package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
  101. package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
  102. package/dist/test/unit/transactionBuilder/sendNFT.js +295 -0
  103. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
  104. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
  105. package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
  106. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  107. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  108. package/dist/test/unit/transactionBuilder/walletInitialization.js +436 -0
  109. package/dist/test/unit/transferBuilder.d.ts +2 -0
  110. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  111. package/dist/test/unit/transferBuilder.js +124 -0
  112. package/dist/test/unit/utils.d.ts +2 -0
  113. package/dist/test/unit/utils.d.ts.map +1 -0
  114. package/dist/test/unit/utils.js +74 -0
  115. package/dist/tsconfig.tsbuildinfo +1 -0
  116. package/package.json +17 -13
  117. package/.eslintignore +0 -5
  118. package/.mocharc.yml +0 -8
  119. package/CHANGELOG.md +0 -663
@@ -0,0 +1,2568 @@
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 ethereumjs_abi_1 = __importDefault(require("ethereumjs-abi"));
54
+ const ethMultiSigBackupKey_1 = require("./fixtures/ethMultiSigBackupKey");
55
+ const ethTssBackupKey_1 = require("./fixtures/ethTssBackupKey");
56
+ nock_1.default.enableNetConnect();
57
+ describe('ETH:', function () {
58
+ let bitgo;
59
+ let hopTxBitgoSignature;
60
+ let sandbox;
61
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
62
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
63
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
64
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
65
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
66
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
67
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
68
+ before(function () {
69
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
70
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
71
+ if (!bitgoKey.privateKey) {
72
+ throw new Error('no privateKey');
73
+ }
74
+ const bitgoXpub = bitgoKey.neutered().toBase58();
75
+ hopTxBitgoSignature =
76
+ '0xaa' +
77
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
78
+ const env = 'test';
79
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
80
+ src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
81
+ bitgo.safeRegister(name, coinConstructor);
82
+ });
83
+ bitgo.safeRegister('teth', src_1.Teth.createInstance);
84
+ bitgo.safeRegister('hteth', src_1.Hteth.createInstance);
85
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
86
+ bitgo.initializeTestVars();
87
+ sandbox = sinon_1.default.createSandbox();
88
+ });
89
+ after(function () {
90
+ nock_1.default.cleanAll();
91
+ sandbox.restore();
92
+ });
93
+ describe('EIP1559', function () {
94
+ it('should sign a transaction with EIP1559 fee params', async function () {
95
+ const coin = bitgo.coin('teth');
96
+ const userKeychain = {
97
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
98
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
99
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
100
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
101
+ };
102
+ const halfSignedTransaction = await coin.signTransaction({
103
+ txPrebuild: {
104
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
105
+ isBatch: false,
106
+ recipients: [
107
+ {
108
+ amount: '42',
109
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
110
+ },
111
+ ],
112
+ expireTime: 1627949214,
113
+ contractSequenceId: 12,
114
+ gasLimit: undefined,
115
+ gasPrice: undefined,
116
+ hopTransaction: undefined,
117
+ backupKeyNonce: undefined,
118
+ sequenceId: undefined,
119
+ nextContractSequenceId: 0,
120
+ },
121
+ prv: userKeychain.prv,
122
+ });
123
+ halfSignedTransaction.halfSigned.eip1559.maxPriorityFeePerGas.should.equal(10);
124
+ halfSignedTransaction.halfSigned.eip1559.maxFeePerGas.should.equal(10);
125
+ });
126
+ it('should sign a transaction with EIP1559 fee params for CCR', async function () {
127
+ const coin = bitgo.coin('hteth');
128
+ const signTransaction = sinon_1.default.spy(src_1.AbstractEthLikeNewCoins.prototype, 'signTransaction');
129
+ const userKeychain = {
130
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
131
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
132
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
133
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
134
+ };
135
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
136
+ txBuilder.type(sdk_core_1.TransactionType.Send);
137
+ txBuilder.fee({
138
+ fee: '10',
139
+ gasLimit: '1000',
140
+ });
141
+ const key = testData.KEYPAIR_PRV.getKeys().prv;
142
+ const transferBuilder = txBuilder.transfer();
143
+ transferBuilder
144
+ .amount('0')
145
+ .to('0x19645032c7f1533395d44a629462e751084d3e4c')
146
+ .expirationTime(1590066728)
147
+ .contractSequenceId(5)
148
+ .key(key);
149
+ txBuilder.contract(address1);
150
+ const tx = await txBuilder.build();
151
+ const halfSignedTransaction = await coin.signTransaction({
152
+ txPrebuild: {
153
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
154
+ isBatch: false,
155
+ recipients: [
156
+ {
157
+ amount: '42',
158
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
159
+ },
160
+ ],
161
+ expireTime: 1627949214,
162
+ contractSequenceId: 12,
163
+ gasLimit: undefined,
164
+ gasPrice: undefined,
165
+ hopTransaction: undefined,
166
+ backupKeyNonce: undefined,
167
+ sequenceId: undefined,
168
+ nextContractSequenceId: 0,
169
+ txHex: tx.toBroadcastFormat(),
170
+ },
171
+ prv: userKeychain.prv,
172
+ isEvmBasedCrossChainRecovery: true,
173
+ });
174
+ (0, assert_1.default)(halfSignedTransaction.halfSigned.txHex);
175
+ assert_1.default.strictEqual(halfSignedTransaction.halfSigned.eip1559.maxFeePerGas, 10);
176
+ sandbox.assert.calledOnce(signTransaction);
177
+ });
178
+ });
179
+ describe('Transaction Verification', function () {
180
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
181
+ const coin = bitgo.coin('teth');
182
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
183
+ const txParams = {
184
+ recipients: [{ amount: '1000000000000', address: address1 }],
185
+ wallet: wallet,
186
+ walletPassphrase: 'fakeWalletPassphrase',
187
+ };
188
+ const txPrebuild = {
189
+ recipients: [{ amount: '1000000000000', address: address1 }],
190
+ nextContractSequenceId: 0,
191
+ gasPrice: 20000000000,
192
+ gasLimit: 500000,
193
+ isBatch: false,
194
+ coin: 'teth',
195
+ wallet: 'fakeWalletId',
196
+ walletContractAddress: 'fakeWalletContractAddress',
197
+ };
198
+ const verification = {};
199
+ const isTransactionVerified = await coin.verifyTransaction({
200
+ txParams,
201
+ txPrebuild: txPrebuild,
202
+ wallet,
203
+ verification,
204
+ });
205
+ isTransactionVerified.should.equal(true);
206
+ });
207
+ it('should verify a batch txPrebuild from the bitgo server that matches the client txParams', async function () {
208
+ const coin = bitgo.coin('teth');
209
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
210
+ const txParams = {
211
+ recipients: [
212
+ { amount: '1000000000000', address: address1 },
213
+ { amount: '2500000000000', address: address2 },
214
+ ],
215
+ wallet: wallet,
216
+ walletPassphrase: 'fakeWalletPassphrase',
217
+ };
218
+ const txPrebuild = {
219
+ recipients: [
220
+ { amount: '3500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
221
+ ],
222
+ nextContractSequenceId: 0,
223
+ gasPrice: 20000000000,
224
+ gasLimit: 500000,
225
+ isBatch: true,
226
+ coin: 'teth',
227
+ walletId: 'fakeWalletId',
228
+ walletContractAddress: 'fakeWalletContractAddress',
229
+ };
230
+ const verification = {};
231
+ const isTransactionVerified = await coin.verifyTransaction({
232
+ txParams,
233
+ txPrebuild: txPrebuild,
234
+ wallet,
235
+ verification,
236
+ });
237
+ isTransactionVerified.should.equal(true);
238
+ });
239
+ it('should verify ENS address resolution changing recipient address in client txParams', async function () {
240
+ const coin = bitgo.coin('teth');
241
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
242
+ const txParams = {
243
+ recipients: [{ amount: '1000000000000', address: 'bitgotestwallet.eth' }],
244
+ wallet: wallet,
245
+ walletPassphrase: 'fakeWalletPassphrase',
246
+ };
247
+ const txPrebuild = {
248
+ recipients: [{ amount: '1000000000000', address: '0x40a663963810449d6e72533657a74f112c3b901a' }],
249
+ nextContractSequenceId: 0,
250
+ gasPrice: 20000000000,
251
+ gasLimit: 500000,
252
+ isBatch: false,
253
+ coin: 'teth',
254
+ walletId: 'fakeWalletId',
255
+ walletContractAddress: 'fakeWalletContractAddress',
256
+ };
257
+ const verification = {};
258
+ const isTransactionVerified = await coin.verifyTransaction({
259
+ txParams,
260
+ txPrebuild: txPrebuild,
261
+ wallet,
262
+ verification,
263
+ });
264
+ isTransactionVerified.should.equal(true);
265
+ });
266
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
267
+ const coin = bitgo.coin('teth');
268
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
269
+ const txParams = {
270
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
271
+ wallet: wallet,
272
+ walletPassphrase: 'fakeWalletPassphrase',
273
+ hop: true,
274
+ };
275
+ const txPrebuild = {
276
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
277
+ nextContractSequenceId: 0,
278
+ gasPrice: 20000000000,
279
+ gasLimit: 500000,
280
+ isBatch: false,
281
+ coin: 'teth',
282
+ walletId: 'fakeWalletId',
283
+ walletContractAddress: 'fakeWalletContractAddress',
284
+ hopTransaction: {
285
+ tx: hopTx,
286
+ id: hopTxid,
287
+ signature: hopTxBitgoSignature,
288
+ paymentId: '2773928196',
289
+ gasPrice: 20000000000,
290
+ gasLimit: 500000,
291
+ amount: '1000000000000000',
292
+ recipient: hopDestinationAddress,
293
+ nonce: 0,
294
+ userReqSig: userReqSig,
295
+ gasPriceMax: 500000000000,
296
+ },
297
+ };
298
+ const verification = {};
299
+ const isTransactionVerified = await coin.verifyTransaction({
300
+ txParams,
301
+ txPrebuild: txPrebuild,
302
+ wallet,
303
+ verification,
304
+ });
305
+ isTransactionVerified.should.equal(true);
306
+ });
307
+ it('should reject when client txParams are missing', async function () {
308
+ const coin = bitgo.coin('teth');
309
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
310
+ const txParams = null;
311
+ const txPrebuild = {
312
+ recipients: [{ amount: '1000000000000', address: address1 }],
313
+ nextContractSequenceId: 0,
314
+ gasPrice: 20000000000,
315
+ gasLimit: 500000,
316
+ isBatch: false,
317
+ coin: 'teth',
318
+ walletId: 'fakeWalletId',
319
+ walletContractAddress: 'fakeWalletContractAddress',
320
+ };
321
+ const verification = {};
322
+ await coin
323
+ .verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
324
+ .should.be.rejectedWith('missing params');
325
+ });
326
+ it('should reject txPrebuild that is both batch and hop', async function () {
327
+ const coin = bitgo.coin('teth');
328
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
329
+ const txParams = {
330
+ recipients: [
331
+ { amount: '1000000000000', address: address1 },
332
+ { amount: '2500000000000', address: address2 },
333
+ ],
334
+ wallet: wallet,
335
+ walletPassphrase: 'fakeWalletPassphrase',
336
+ hop: true,
337
+ };
338
+ const txPrebuild = {
339
+ recipients: [{ amount: '3500000000000', address: address1 }],
340
+ nextContractSequenceId: 0,
341
+ gasPrice: 20000000000,
342
+ gasLimit: 500000,
343
+ isBatch: true,
344
+ coin: 'teth',
345
+ walletId: 'fakeWalletId',
346
+ walletContractAddress: 'fakeWalletContractAddress',
347
+ hopTransaction: {
348
+ tx: hopTx,
349
+ id: hopTxid,
350
+ signature: hopTxBitgoSignature,
351
+ paymentId: '2773928196',
352
+ gasPrice: 20000000000,
353
+ gasLimit: 500000,
354
+ amount: '1000000000000000',
355
+ recipient: hopDestinationAddress,
356
+ nonce: 0,
357
+ userReqSig: userReqSig,
358
+ gasPriceMax: 500000000000,
359
+ },
360
+ };
361
+ const verification = {};
362
+ await coin
363
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
364
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
365
+ });
366
+ it('should reject a txPrebuild with more than one recipient', async function () {
367
+ const coin = bitgo.coin('teth');
368
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
369
+ const txParams = {
370
+ recipients: [
371
+ { amount: '1000000000000', address: address1 },
372
+ { amount: '2500000000000', address: address2 },
373
+ ],
374
+ wallet: wallet,
375
+ walletPassphrase: 'fakeWalletPassphrase',
376
+ };
377
+ const txPrebuild = {
378
+ recipients: [
379
+ { amount: '1000000000000', address: address1 },
380
+ { amount: '2500000000000', address: address2 },
381
+ ],
382
+ nextContractSequenceId: 0,
383
+ gasPrice: 20000000000,
384
+ gasLimit: 500000,
385
+ isBatch: true,
386
+ coin: 'teth',
387
+ walletId: 'fakeWalletId',
388
+ walletContractAddress: 'fakeWalletContractAddress',
389
+ };
390
+ const verification = {};
391
+ await coin
392
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
393
+ .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.`);
394
+ });
395
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
396
+ const coin = bitgo.coin('teth');
397
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
398
+ const txParams = {
399
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
400
+ wallet: wallet,
401
+ walletPassphrase: 'fakeWalletPassphrase',
402
+ hop: true,
403
+ };
404
+ const txPrebuild = {
405
+ recipients: [{ amount: '5000000000000000', address: address1 }],
406
+ nextContractSequenceId: 0,
407
+ gasPrice: 20000000000,
408
+ gasLimit: 500000,
409
+ isBatch: false,
410
+ coin: 'teth',
411
+ walletId: 'fakeWalletId',
412
+ walletContractAddress: 'fakeWalletContractAddress',
413
+ hopTransaction: {
414
+ tx: hopTx,
415
+ id: hopTxid,
416
+ signature: hopTxBitgoSignature,
417
+ paymentId: '0',
418
+ gasPrice: 20000000000,
419
+ gasLimit: 500000,
420
+ amount: '1000000000000000',
421
+ recipient: hopDestinationAddress,
422
+ nonce: 0,
423
+ userReqSig: userReqSig,
424
+ gasPriceMax: 500000000000,
425
+ },
426
+ };
427
+ const verification = {};
428
+ await coin
429
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
430
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
431
+ });
432
+ it('should reject a batch txPrebuild from the bitgo server with the wrong total amount', async function () {
433
+ const coin = bitgo.coin('teth');
434
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
435
+ const txParams = {
436
+ recipients: [
437
+ { amount: '1000000000000', address: address1 },
438
+ { amount: '2500000000000', address: address2 },
439
+ ],
440
+ wallet: wallet,
441
+ walletPassphrase: 'fakeWalletPassphrase',
442
+ };
443
+ const txPrebuild = {
444
+ recipients: [
445
+ { amount: '5500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
446
+ ],
447
+ nextContractSequenceId: 0,
448
+ gasPrice: 20000000000,
449
+ gasLimit: 500000,
450
+ isBatch: true,
451
+ coin: 'teth',
452
+ walletId: 'fakeWalletId',
453
+ walletContractAddress: 'fakeWalletContractAddress',
454
+ };
455
+ const verification = {};
456
+ await coin
457
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
458
+ .should.be.rejectedWith('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
459
+ });
460
+ it('should reject a batch txPrebuild from the bitgo server that does not send to the batcher contract address', async function () {
461
+ const coin = bitgo.coin('teth');
462
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
463
+ const txParams = {
464
+ recipients: [
465
+ { amount: '1000000000000', address: address1 },
466
+ { amount: '2500000000000', address: address2 },
467
+ ],
468
+ wallet: wallet,
469
+ walletPassphrase: 'fakeWalletPassphrase',
470
+ };
471
+ const txPrebuild = {
472
+ recipients: [{ amount: '3500000000000', address: hopContractAddress }],
473
+ nextContractSequenceId: 0,
474
+ gasPrice: 20000000000,
475
+ gasLimit: 500000,
476
+ isBatch: true,
477
+ coin: 'teth',
478
+ walletId: 'fakeWalletId',
479
+ walletContractAddress: 'fakeWalletContractAddress',
480
+ };
481
+ const verification = {};
482
+ await coin
483
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
484
+ .should.be.rejectedWith('recipient address of txPrebuild does not match batcher address');
485
+ });
486
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
487
+ const coin = bitgo.coin('teth');
488
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
489
+ const txParams = {
490
+ recipients: [{ amount: '1000000000000', address: address1 }],
491
+ wallet: wallet,
492
+ walletPassphrase: 'fakeWalletPassphrase',
493
+ };
494
+ const txPrebuild = {
495
+ recipients: [{ amount: '2000000000000', address: address1 }],
496
+ nextContractSequenceId: 0,
497
+ gasPrice: 20000000000,
498
+ gasLimit: 500000,
499
+ isBatch: false,
500
+ coin: 'teth',
501
+ walletId: 'fakeWalletId',
502
+ walletContractAddress: 'fakeWalletContractAddress',
503
+ };
504
+ const verification = {};
505
+ await coin
506
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
507
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
508
+ });
509
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
510
+ const coin = bitgo.coin('teth');
511
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
512
+ const txParams = {
513
+ recipients: [{ amount: '1000000000000', address: address1 }],
514
+ wallet: wallet,
515
+ walletPassphrase: 'fakeWalletPassphrase',
516
+ };
517
+ const txPrebuild = {
518
+ recipients: [{ amount: '1000000000000', address: address2 }],
519
+ nextContractSequenceId: 0,
520
+ gasPrice: 20000000000,
521
+ gasLimit: 500000,
522
+ isBatch: false,
523
+ coin: 'teth',
524
+ walletId: 'fakeWalletId',
525
+ walletContractAddress: 'fakeWalletContractAddress',
526
+ };
527
+ const verification = {};
528
+ await coin
529
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
530
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
531
+ });
532
+ it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
533
+ const coin = bitgo.coin('test');
534
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
535
+ const txParams = {
536
+ recipients: [{ amount: '1000000000000', address: address1 }],
537
+ wallet: wallet,
538
+ walletPassphrase: 'fakeWalletPassphrase',
539
+ };
540
+ const txPrebuild = {
541
+ recipients: [{ amount: '1000000000000', address: address1 }],
542
+ nextContractSequenceId: 0,
543
+ gasPrice: 20000000000,
544
+ gasLimit: 500000,
545
+ isBatch: false,
546
+ coin: 'teth',
547
+ token: 'test',
548
+ walletId: 'fakeWalletId',
549
+ walletContractAddress: 'fakeWalletContractAddress',
550
+ };
551
+ const verification = {};
552
+ const isTransactionVerified = await coin.verifyTransaction({
553
+ txParams,
554
+ txPrebuild: txPrebuild,
555
+ wallet,
556
+ verification,
557
+ });
558
+ isTransactionVerified.should.equal(true);
559
+ });
560
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
561
+ const coin = bitgo.coin('teth');
562
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
563
+ const txParams = {
564
+ recipients: [{ amount: '1000000000000', address: address1 }],
565
+ wallet: wallet,
566
+ walletPassphrase: 'fakeWalletPassphrase',
567
+ };
568
+ const txPrebuild = {
569
+ recipients: [{ amount: '1000000000000', address: address1 }],
570
+ nextContractSequenceId: 0,
571
+ gasPrice: 20000000000,
572
+ gasLimit: 500000,
573
+ isBatch: false,
574
+ coin: 'btc',
575
+ walletId: 'fakeWalletId',
576
+ walletContractAddress: 'fakeWalletContractAddress',
577
+ };
578
+ const verification = {};
579
+ await coin
580
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
581
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
582
+ });
583
+ });
584
+ describe('TSS Transaction Verification', function () {
585
+ it('should verify TSS consolidation transaction when txPrebuild has consolidateId', async function () {
586
+ const coin = bitgo.coin('hteth');
587
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
588
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
589
+ coinSpecific: {
590
+ baseAddress: baseAddress,
591
+ },
592
+ });
593
+ // txParams without recipients (as in consolidation flow)
594
+ const txParams = {
595
+ wallet: wallet,
596
+ walletPassphrase: 'fakeWalletPassphrase',
597
+ };
598
+ // txPrebuild with consolidateId (set by server during consolidation build)
599
+ const txPrebuild = {
600
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
601
+ txHex: '0x',
602
+ coin: 'hteth',
603
+ walletId: 'fakeWalletId',
604
+ };
605
+ const verification = {};
606
+ const isTransactionVerified = await coin.verifyTransaction({
607
+ txParams: txParams,
608
+ txPrebuild: txPrebuild,
609
+ wallet,
610
+ verification,
611
+ walletType: 'tss',
612
+ });
613
+ isTransactionVerified.should.equal(true);
614
+ });
615
+ it('should verify TSS transaction when txParams.type is consolidate', async function () {
616
+ const coin = bitgo.coin('hteth');
617
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
618
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
619
+ coinSpecific: {
620
+ baseAddress: baseAddress,
621
+ },
622
+ });
623
+ const txParams = {
624
+ type: 'consolidate',
625
+ wallet: wallet,
626
+ walletPassphrase: 'fakeWalletPassphrase',
627
+ };
628
+ const txPrebuild = {
629
+ txHex: '0x',
630
+ coin: 'hteth',
631
+ walletId: 'fakeWalletId',
632
+ };
633
+ const verification = {};
634
+ const isTransactionVerified = await coin.verifyTransaction({
635
+ txParams: txParams,
636
+ txPrebuild: txPrebuild,
637
+ wallet,
638
+ verification,
639
+ walletType: 'tss',
640
+ });
641
+ isTransactionVerified.should.equal(true);
642
+ });
643
+ it('should verify TSS transaction when txParams.prebuildTx has consolidateId', async function () {
644
+ const coin = bitgo.coin('hteth');
645
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
646
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
647
+ coinSpecific: {
648
+ baseAddress: baseAddress,
649
+ },
650
+ });
651
+ const txParams = {
652
+ wallet: wallet,
653
+ walletPassphrase: 'fakeWalletPassphrase',
654
+ prebuildTx: {
655
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
656
+ },
657
+ };
658
+ const txPrebuild = {
659
+ txHex: '0x',
660
+ coin: 'hteth',
661
+ walletId: 'fakeWalletId',
662
+ };
663
+ const verification = {};
664
+ const isTransactionVerified = await coin.verifyTransaction({
665
+ txParams: txParams,
666
+ txPrebuild: txPrebuild,
667
+ wallet,
668
+ verification,
669
+ walletType: 'tss',
670
+ });
671
+ isTransactionVerified.should.equal(true);
672
+ });
673
+ it('should reject TSS transaction without recipients, consolidateId, or valid type', async function () {
674
+ const coin = bitgo.coin('hteth');
675
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
676
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
677
+ coinSpecific: {
678
+ baseAddress: baseAddress,
679
+ },
680
+ });
681
+ const txParams = {
682
+ wallet: wallet,
683
+ walletPassphrase: 'fakeWalletPassphrase',
684
+ };
685
+ const txPrebuild = {
686
+ txHex: '0x',
687
+ coin: 'hteth',
688
+ walletId: 'fakeWalletId',
689
+ };
690
+ const verification = {};
691
+ await coin
692
+ .verifyTransaction({
693
+ txParams: txParams,
694
+ txPrebuild: txPrebuild,
695
+ wallet,
696
+ verification,
697
+ walletType: 'tss',
698
+ })
699
+ .should.be.rejectedWith('missing txParams');
700
+ });
701
+ it('should verify TSS transaction with acceleration type', async function () {
702
+ const coin = bitgo.coin('hteth');
703
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
704
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
705
+ coinSpecific: {
706
+ baseAddress: baseAddress,
707
+ },
708
+ });
709
+ const txParams = {
710
+ type: 'acceleration',
711
+ wallet: wallet,
712
+ walletPassphrase: 'fakeWalletPassphrase',
713
+ };
714
+ const txPrebuild = {
715
+ txHex: '0x',
716
+ coin: 'hteth',
717
+ walletId: 'fakeWalletId',
718
+ };
719
+ const verification = {};
720
+ const isTransactionVerified = await coin.verifyTransaction({
721
+ txParams: txParams,
722
+ txPrebuild: txPrebuild,
723
+ wallet,
724
+ verification,
725
+ walletType: 'tss',
726
+ });
727
+ isTransactionVerified.should.equal(true);
728
+ });
729
+ it('should verify TSS transaction with fillNonce type', async function () {
730
+ const coin = bitgo.coin('hteth');
731
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
732
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
733
+ coinSpecific: {
734
+ baseAddress: baseAddress,
735
+ },
736
+ });
737
+ const txParams = {
738
+ type: 'fillNonce',
739
+ wallet: wallet,
740
+ walletPassphrase: 'fakeWalletPassphrase',
741
+ };
742
+ const txPrebuild = {
743
+ txHex: '0x',
744
+ coin: 'hteth',
745
+ walletId: 'fakeWalletId',
746
+ };
747
+ const verification = {};
748
+ const isTransactionVerified = await coin.verifyTransaction({
749
+ txParams: txParams,
750
+ txPrebuild: txPrebuild,
751
+ wallet,
752
+ verification,
753
+ walletType: 'tss',
754
+ });
755
+ isTransactionVerified.should.equal(true);
756
+ });
757
+ it('should verify TSS transaction with defiApprove type', async function () {
758
+ const coin = bitgo.coin('hteth');
759
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
760
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
761
+ coinSpecific: {
762
+ baseAddress: baseAddress,
763
+ },
764
+ });
765
+ // DeFi deposit flow is intent-based: recipients/calldata are built server-side
766
+ // from defiParams, so txParams has no recipients (see CGD-1815).
767
+ const txParams = {
768
+ type: 'defiApprove',
769
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10' },
770
+ wallet: wallet,
771
+ walletPassphrase: 'fakeWalletPassphrase',
772
+ };
773
+ const txPrebuild = {
774
+ txHex: '0x',
775
+ coin: 'hteth',
776
+ walletId: 'fakeWalletId',
777
+ };
778
+ const verification = {};
779
+ const isTransactionVerified = await coin.verifyTransaction({
780
+ txParams: txParams,
781
+ txPrebuild: txPrebuild,
782
+ wallet,
783
+ verification,
784
+ walletType: 'tss',
785
+ });
786
+ isTransactionVerified.should.equal(true);
787
+ });
788
+ it('should verify TSS transaction with defiDeposit type', async function () {
789
+ const coin = bitgo.coin('hteth');
790
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
791
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
792
+ coinSpecific: {
793
+ baseAddress: baseAddress,
794
+ },
795
+ });
796
+ const txParams = {
797
+ type: 'defiDeposit',
798
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10', operationId: 'fakeOperationId' },
799
+ wallet: wallet,
800
+ walletPassphrase: 'fakeWalletPassphrase',
801
+ };
802
+ const txPrebuild = {
803
+ txHex: '0x',
804
+ coin: 'hteth',
805
+ walletId: 'fakeWalletId',
806
+ };
807
+ const verification = {};
808
+ const isTransactionVerified = await coin.verifyTransaction({
809
+ txParams: txParams,
810
+ txPrebuild: txPrebuild,
811
+ wallet,
812
+ verification,
813
+ walletType: 'tss',
814
+ });
815
+ isTransactionVerified.should.equal(true);
816
+ });
817
+ describe('consolidationToBaseAddress verification', function () {
818
+ it('should verify consolidation when recipient matches base address', async function () {
819
+ const coin = bitgo.coin('hteth');
820
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
821
+ // Build a real transaction that sends to the baseAddress
822
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
823
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
824
+ txBuilder.fee({
825
+ fee: '10',
826
+ gasLimit: '21000',
827
+ });
828
+ txBuilder.counter(1);
829
+ txBuilder.contract(baseAddress);
830
+ txBuilder.value('1000000000000000000');
831
+ const tx = await txBuilder.build();
832
+ const txHex = tx.toBroadcastFormat();
833
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
834
+ coinSpecific: {
835
+ baseAddress: baseAddress,
836
+ },
837
+ });
838
+ const txParams = {
839
+ type: 'consolidate',
840
+ wallet: wallet,
841
+ walletPassphrase: 'fakeWalletPassphrase',
842
+ };
843
+ const txPrebuild = {
844
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
845
+ txHex: txHex,
846
+ coin: 'hteth',
847
+ walletId: 'fakeWalletId',
848
+ };
849
+ const verification = {
850
+ consolidationToBaseAddress: true,
851
+ };
852
+ const isTransactionVerified = await coin.verifyTransaction({
853
+ txParams: txParams,
854
+ txPrebuild: txPrebuild,
855
+ wallet,
856
+ verification,
857
+ walletType: 'tss',
858
+ });
859
+ isTransactionVerified.should.equal(true);
860
+ });
861
+ it('should reject consolidation when recipient does not match base address', async function () {
862
+ const coin = bitgo.coin('hteth');
863
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
864
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
865
+ // Build a transaction that sends to a DIFFERENT address (not baseAddress)
866
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
867
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
868
+ txBuilder.fee({
869
+ fee: '10',
870
+ gasLimit: '21000',
871
+ });
872
+ txBuilder.counter(1);
873
+ txBuilder.contract(wrongRecipient);
874
+ txBuilder.value('1000000000000000000');
875
+ const tx = await txBuilder.build();
876
+ const txHex = tx.toBroadcastFormat();
877
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
878
+ coinSpecific: {
879
+ baseAddress: baseAddress,
880
+ },
881
+ });
882
+ const txParams = {
883
+ type: 'consolidate',
884
+ wallet: wallet,
885
+ walletPassphrase: 'fakeWalletPassphrase',
886
+ };
887
+ const txPrebuild = {
888
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
889
+ txHex: txHex,
890
+ coin: 'hteth',
891
+ walletId: 'fakeWalletId',
892
+ };
893
+ const verification = {
894
+ consolidationToBaseAddress: true,
895
+ };
896
+ await coin
897
+ .verifyTransaction({
898
+ txParams: txParams,
899
+ txPrebuild: txPrebuild,
900
+ wallet,
901
+ verification,
902
+ walletType: 'tss',
903
+ })
904
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
905
+ });
906
+ it('should throw error when txHex is missing for consolidation verification', async function () {
907
+ const coin = bitgo.coin('hteth');
908
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
909
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
910
+ coinSpecific: {
911
+ baseAddress: baseAddress,
912
+ },
913
+ });
914
+ const txParams = {
915
+ type: 'consolidate',
916
+ wallet: wallet,
917
+ walletPassphrase: 'fakeWalletPassphrase',
918
+ };
919
+ const txPrebuild = {
920
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
921
+ // Intentionally missing txHex
922
+ coin: 'hteth',
923
+ walletId: 'fakeWalletId',
924
+ };
925
+ const verification = {
926
+ consolidationToBaseAddress: true,
927
+ };
928
+ await coin
929
+ .verifyTransaction({
930
+ txParams: txParams,
931
+ txPrebuild: txPrebuild,
932
+ wallet,
933
+ verification,
934
+ walletType: 'tss',
935
+ })
936
+ .should.be.rejectedWith('missing txHex in txPrebuild');
937
+ });
938
+ it('should verify ERC20 token consolidation when calldata recipient matches base address', async function () {
939
+ const coin = bitgo.coin('hteth');
940
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
941
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
942
+ // Build an ERC20 transfer(address, uint256) tx — mimics what the server returns
943
+ // for a v6 TSS wallet token consolidation: txJson.to = token contract,
944
+ // actual recipient is encoded in the 0xa9059cbb calldata
945
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
946
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [baseAddress, '10000000']);
947
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
948
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
949
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
950
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
951
+ txBuilder.counter(1);
952
+ txBuilder.contract(tokenContractAddress);
953
+ txBuilder.data(erc20TransferData);
954
+ const tx = await txBuilder.build();
955
+ const txHex = tx.toBroadcastFormat();
956
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
957
+ coinSpecific: { baseAddress },
958
+ });
959
+ const isTransactionVerified = await coin.verifyTransaction({
960
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
961
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
962
+ wallet,
963
+ verification: { consolidationToBaseAddress: true },
964
+ walletType: 'tss',
965
+ });
966
+ isTransactionVerified.should.equal(true);
967
+ });
968
+ it('should reject ERC20 token consolidation when calldata recipient does not match base address', async function () {
969
+ const coin = bitgo.coin('hteth');
970
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
971
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
972
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
973
+ // Build an ERC20 transfer where calldata recipient is a WRONG address
974
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
975
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [wrongRecipient, '10000000']);
976
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
977
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
978
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
979
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
980
+ txBuilder.counter(1);
981
+ txBuilder.contract(tokenContractAddress);
982
+ txBuilder.data(erc20TransferData);
983
+ const tx = await txBuilder.build();
984
+ const txHex = tx.toBroadcastFormat();
985
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
986
+ coinSpecific: { baseAddress },
987
+ });
988
+ await coin
989
+ .verifyTransaction({
990
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
991
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
992
+ wallet,
993
+ verification: { consolidationToBaseAddress: true },
994
+ walletType: 'tss',
995
+ })
996
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
997
+ });
998
+ it('should throw error when wallet is missing baseAddress for consolidation verification', async function () {
999
+ const coin = bitgo.coin('hteth');
1000
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1001
+ // Build a real transaction
1002
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1003
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1004
+ txBuilder.fee({
1005
+ fee: '10',
1006
+ gasLimit: '21000',
1007
+ });
1008
+ txBuilder.counter(1);
1009
+ txBuilder.contract(baseAddress);
1010
+ txBuilder.value('1000000000000000000');
1011
+ const tx = await txBuilder.build();
1012
+ const txHex = tx.toBroadcastFormat();
1013
+ // Wallet without baseAddress
1014
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1015
+ coinSpecific: {},
1016
+ });
1017
+ const txParams = {
1018
+ type: 'consolidate',
1019
+ wallet: wallet,
1020
+ walletPassphrase: 'fakeWalletPassphrase',
1021
+ };
1022
+ const txPrebuild = {
1023
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1024
+ txHex: txHex,
1025
+ coin: 'hteth',
1026
+ walletId: 'fakeWalletId',
1027
+ };
1028
+ const verification = {
1029
+ consolidationToBaseAddress: true,
1030
+ };
1031
+ await coin
1032
+ .verifyTransaction({
1033
+ txParams: txParams,
1034
+ txPrebuild: txPrebuild,
1035
+ wallet,
1036
+ verification,
1037
+ walletType: 'tss',
1038
+ })
1039
+ .should.be.rejectedWith('Unable to determine base address for consolidation');
1040
+ });
1041
+ });
1042
+ });
1043
+ describe('Address Verification', function () {
1044
+ describe('isWalletAddress', function () {
1045
+ it('should verify an address generated using forwarder version 1', async function () {
1046
+ const coin = bitgo.coin('hteth');
1047
+ const keychains = [
1048
+ {
1049
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1050
+ source: 'user',
1051
+ type: 'independent',
1052
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVmsa5SriNrfKZZAcAvRgxh1Augm6s8yoD8gSkq2FdZ8YCdVXUgLjf9QxvdYAJK5UthAmpQshU',
1053
+ },
1054
+ {
1055
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1056
+ source: 'backup',
1057
+ type: 'independent',
1058
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqAU9JRod8huYtyV4NY2oeJXsis7r26L1vmLntf9BcZJe1m4CQNSvYWfwpe1hSpo6J4x6YF1eN',
1059
+ },
1060
+ {
1061
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1062
+ source: 'bitgo',
1063
+ type: 'independent',
1064
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1065
+ },
1066
+ ];
1067
+ const params = {
1068
+ address: '0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae',
1069
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1070
+ coinSpecific: {
1071
+ salt: '0x7',
1072
+ forwarderVersion: 1,
1073
+ },
1074
+ keychains,
1075
+ index: 7,
1076
+ walletVersion: 1,
1077
+ };
1078
+ const isWalletAddr = await coin.isWalletAddress(params);
1079
+ isWalletAddr.should.equal(true);
1080
+ });
1081
+ it('should verify an address generated using forwarder version 2', async function () {
1082
+ const coin = bitgo.coin('hteth');
1083
+ const keychains = [
1084
+ {
1085
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1086
+ source: 'user',
1087
+ type: 'independent',
1088
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1089
+ },
1090
+ {
1091
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1092
+ source: 'backup',
1093
+ type: 'independent',
1094
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1095
+ },
1096
+ {
1097
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1098
+ source: 'bitgo',
1099
+ type: 'independent',
1100
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1101
+ },
1102
+ ];
1103
+ const params = {
1104
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1105
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1106
+ coinSpecific: {
1107
+ salt: '0x17',
1108
+ forwarderVersion: 2,
1109
+ },
1110
+ keychains,
1111
+ index: 23,
1112
+ walletVersion: 2,
1113
+ };
1114
+ const isWalletAddr = await coin.isWalletAddress(params);
1115
+ isWalletAddr.should.equal(true);
1116
+ });
1117
+ it('should verify a wallet version 5 forwarder version 4', async function () {
1118
+ const coin = bitgo.coin('hteth');
1119
+ const keychains = [
1120
+ {
1121
+ id: '691e242d93f8d7ad0705887449763c96',
1122
+ source: 'user',
1123
+ type: 'tss',
1124
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1125
+ },
1126
+ {
1127
+ id: '691e242df8b6323d4b08df366864af66',
1128
+ source: 'backup',
1129
+ type: 'tss',
1130
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1131
+ },
1132
+ {
1133
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1134
+ source: 'bitgo',
1135
+ type: 'tss',
1136
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1137
+ },
1138
+ ];
1139
+ const params = {
1140
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1141
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1142
+ coinSpecific: {
1143
+ salt: '0x75',
1144
+ forwarderVersion: 4,
1145
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1146
+ },
1147
+ keychains,
1148
+ index: 117,
1149
+ walletVersion: 5,
1150
+ };
1151
+ const isWalletAddr = await coin.isWalletAddress(params);
1152
+ isWalletAddr.should.equal(true);
1153
+ });
1154
+ it('should verify a wallet version 6 forwarder version 5', async function () {
1155
+ const coin = bitgo.coin('hteth');
1156
+ const keychains = [
1157
+ {
1158
+ id: '691f630e0c56098288a9b7fa107db144',
1159
+ source: 'user',
1160
+ type: 'tss',
1161
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1162
+ },
1163
+ {
1164
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1165
+ source: 'backup',
1166
+ type: 'tss',
1167
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1168
+ },
1169
+ {
1170
+ id: '691f630d56735e5eb61b06e353fe7639',
1171
+ source: 'bitgo',
1172
+ type: 'tss',
1173
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1174
+ },
1175
+ ];
1176
+ const params = {
1177
+ address: '0xa33f0975f53cdcfcc0cb564d25fb5be03b0651cf',
1178
+ baseAddress: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1179
+ coinSpecific: {
1180
+ forwarderVersion: 5,
1181
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1182
+ },
1183
+ keychains,
1184
+ index: 7,
1185
+ walletVersion: 6,
1186
+ };
1187
+ const isWalletAddr = await coin.isWalletAddress(params);
1188
+ isWalletAddr.should.equal(true);
1189
+ });
1190
+ it('should reject when actual address differs from expected address', async function () {
1191
+ const coin = bitgo.coin('hteth');
1192
+ const params = {
1193
+ address: '0x28904591f735994f050804fda3b61b813b16e04c',
1194
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1195
+ walletVersion: 1,
1196
+ coinSpecific: {
1197
+ salt: '0xc5a',
1198
+ forwarderVersion: 1,
1199
+ },
1200
+ };
1201
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.UnexpectedAddressError);
1202
+ });
1203
+ it('should reject if coinSpecific field is not an object', async function () {
1204
+ const coin = bitgo.coin('teth');
1205
+ const params = {
1206
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1207
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1208
+ };
1209
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressVerificationObjectPropertyError);
1210
+ });
1211
+ it('should reject if the derived address is in invalid format', async function () {
1212
+ const coin = bitgo.coin('teth');
1213
+ const params = {
1214
+ address: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1215
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1216
+ coinSpecific: {
1217
+ salt: '0xc5a',
1218
+ forwarderVersion: 1,
1219
+ },
1220
+ };
1221
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1222
+ });
1223
+ it('should reject if base address is undefined', async function () {
1224
+ const coin = bitgo.coin('teth');
1225
+ const params = {
1226
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1227
+ coinSpecific: {
1228
+ salt: '0xc5a',
1229
+ forwarderVersion: 1,
1230
+ },
1231
+ };
1232
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1233
+ });
1234
+ it('should reject if base address is in invalid format', async function () {
1235
+ const coin = bitgo.coin('teth');
1236
+ const params = {
1237
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1238
+ baseAddress: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1239
+ coinSpecific: {
1240
+ salt: '0xc5a',
1241
+ forwarderVersion: 1,
1242
+ },
1243
+ };
1244
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1245
+ });
1246
+ describe('MPC wallet addresses', function () {
1247
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1248
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1249
+ const keychains = [
1250
+ { pub: 'user_pub', commonKeychain },
1251
+ { pub: 'backup_pub', commonKeychain },
1252
+ { pub: 'bitgo_pub', commonKeychain },
1253
+ ];
1254
+ it('should verify an MPC wallet address with forwarder version 3', async function () {
1255
+ const coin = bitgo.coin('teth');
1256
+ const params = {
1257
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1258
+ coinSpecific: {
1259
+ forwarderVersion: 3,
1260
+ },
1261
+ keychains,
1262
+ index: 0,
1263
+ walletVersion: 3,
1264
+ };
1265
+ const isWalletAddr = await coin.isWalletAddress(params);
1266
+ isWalletAddr.should.equal(true);
1267
+ });
1268
+ it('should verify an MPC wallet address with forwarder version 5', async function () {
1269
+ const coin = bitgo.coin('teth');
1270
+ const params = {
1271
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1272
+ coinSpecific: {
1273
+ forwarderVersion: 5,
1274
+ },
1275
+ keychains,
1276
+ index: 0,
1277
+ walletVersion: 6,
1278
+ };
1279
+ const isWalletAddr = await coin.isWalletAddress(params);
1280
+ isWalletAddr.should.equal(true);
1281
+ });
1282
+ it('should reject MPC wallet address with wrong address', async function () {
1283
+ const coin = bitgo.coin('teth');
1284
+ const params = {
1285
+ address: '0x0000000000000000000000000000000000000001',
1286
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1287
+ coinSpecific: {
1288
+ forwarderVersion: 3,
1289
+ },
1290
+ keychains,
1291
+ index: 0,
1292
+ walletVersion: 3,
1293
+ };
1294
+ const isWalletAddr = await coin.isWalletAddress(params);
1295
+ isWalletAddr.should.equal(false);
1296
+ });
1297
+ it('should reject MPC wallet address with invalid address format', async function () {
1298
+ const coin = bitgo.coin('teth');
1299
+ const params = {
1300
+ address: '0xinvalid',
1301
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1302
+ coinSpecific: {
1303
+ forwarderVersion: 3,
1304
+ },
1305
+ keychains,
1306
+ index: 0,
1307
+ walletVersion: 3,
1308
+ };
1309
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1310
+ });
1311
+ it('should reject if keychains are missing for MPC wallet', async function () {
1312
+ const coin = bitgo.coin('teth');
1313
+ const params = {
1314
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1315
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1316
+ coinSpecific: {
1317
+ forwarderVersion: 3,
1318
+ },
1319
+ index: 0,
1320
+ walletVersion: 3,
1321
+ };
1322
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1323
+ });
1324
+ it('should reject if commonKeychain is missing for MPC wallet', async function () {
1325
+ const coin = bitgo.coin('teth');
1326
+ const invalidKeychains = [{ pub: 'user_pub' }, { pub: 'backup_pub' }, { pub: 'bitgo_pub' }];
1327
+ const params = {
1328
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1329
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1330
+ coinSpecific: {
1331
+ forwarderVersion: 3,
1332
+ },
1333
+ keychains: invalidKeychains,
1334
+ index: 0,
1335
+ walletVersion: 3,
1336
+ };
1337
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1338
+ });
1339
+ });
1340
+ describe('deriveAddress (MPC)', function () {
1341
+ // Same vector as the MPC isWalletAddress tests above:
1342
+ // commonKeychain @ index 0 -> 0x01153f3adfe454a72589ca9ef74f013c19e54961
1343
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1344
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1345
+ const keychains = [
1346
+ { pub: 'user_pub', commonKeychain },
1347
+ { pub: 'backup_pub', commonKeychain },
1348
+ { pub: 'bitgo_pub', commonKeychain },
1349
+ ];
1350
+ it('should derive the expected MPC address for a commonKeychain at index 0', async function () {
1351
+ const coin = bitgo.coin('teth');
1352
+ const result = await coin.deriveAddress({ keychains, index: 0, walletVersion: 3 });
1353
+ result.address.should.equal('0x01153f3adfe454a72589ca9ef74f013c19e54961');
1354
+ result.index.should.equal(0);
1355
+ assert_1.default.strictEqual(result.derivationPath, 'm/0');
1356
+ });
1357
+ it('round-trips with isWalletAddress (derived address verifies as true)', async function () {
1358
+ const coin = bitgo.coin('teth');
1359
+ const derived = await coin.deriveAddress({ keychains, index: 3, walletVersion: 6 });
1360
+ const verified = await coin.isWalletAddress({
1361
+ address: derived.address,
1362
+ coinSpecific: { forwarderVersion: 5 },
1363
+ keychains,
1364
+ index: 3,
1365
+ walletVersion: 6,
1366
+ });
1367
+ verified.should.equal(true);
1368
+ });
1369
+ it('should throw when neither MPC nor forwarder inputs are provided', async function () {
1370
+ const coin = bitgo.coin('teth');
1371
+ // walletVersion 1 with no coinSpecific.forwarderVersion and no baseAddress is ambiguous
1372
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains, index: 0, walletVersion: 1 }), /could not determine an ETH derivation strategy/);
1373
+ });
1374
+ it('should throw if keychains are missing', async function () {
1375
+ const coin = bitgo.coin('teth');
1376
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains: [], index: 0, walletVersion: 3 }), /keychains/);
1377
+ });
1378
+ });
1379
+ describe('deriveAddress (forwarder)', function () {
1380
+ // Same vectors as the forwarder isWalletAddress tests above (coin: hteth).
1381
+ // salt == index for BitGo forwarders, so deriving by index reproduces the address.
1382
+ it('derives the exact v1 forwarder address and round-trips', async function () {
1383
+ const coin = bitgo.coin('hteth');
1384
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1385
+ const result = await coin.deriveAddress({
1386
+ baseAddress,
1387
+ index: 7,
1388
+ walletVersion: 1,
1389
+ coinSpecific: { forwarderVersion: 1 },
1390
+ });
1391
+ result.address.should.equal('0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae');
1392
+ const verified = await coin.isWalletAddress({
1393
+ address: result.address,
1394
+ baseAddress,
1395
+ index: 7,
1396
+ walletVersion: 1,
1397
+ coinSpecific: { salt: '0x7', forwarderVersion: 1 },
1398
+ });
1399
+ verified.should.equal(true);
1400
+ });
1401
+ it('derives the exact v2 forwarder address', async function () {
1402
+ const coin = bitgo.coin('hteth');
1403
+ const result = await coin.deriveAddress({
1404
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1405
+ index: 23,
1406
+ walletVersion: 2,
1407
+ coinSpecific: { forwarderVersion: 2 },
1408
+ });
1409
+ result.address.should.equal('0xf636ceddffe41d106586875c0e56dc8feb6268f7');
1410
+ });
1411
+ it('derives the exact v4 forwarder address (wallet v5, needs feeAddress)', async function () {
1412
+ const coin = bitgo.coin('hteth');
1413
+ const result = await coin.deriveAddress({
1414
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1415
+ index: 117,
1416
+ walletVersion: 5,
1417
+ coinSpecific: { forwarderVersion: 4, feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09' },
1418
+ });
1419
+ result.address.should.equal('0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d');
1420
+ });
1421
+ it('throws if baseAddress is missing for a forwarder', async function () {
1422
+ const coin = bitgo.coin('hteth');
1423
+ await assert_1.default.rejects(async () => coin.deriveAddress({ index: 7, walletVersion: 1, coinSpecific: { forwarderVersion: 1 } }), /baseAddress is required/);
1424
+ });
1425
+ it('throws if feeAddress is missing for a v4 forwarder', async function () {
1426
+ const coin = bitgo.coin('hteth');
1427
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1428
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1429
+ index: 117,
1430
+ walletVersion: 5,
1431
+ coinSpecific: { forwarderVersion: 4 },
1432
+ }), /feeAddress is required/);
1433
+ });
1434
+ it('throws for forwarder version 0 (not derivable)', async function () {
1435
+ const coin = bitgo.coin('hteth');
1436
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1437
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1438
+ index: 0,
1439
+ walletVersion: 1,
1440
+ coinSpecific: { forwarderVersion: 0 },
1441
+ }), /version 0 addresses cannot be derived/);
1442
+ });
1443
+ });
1444
+ describe('Base Address Verification', function () {
1445
+ it('should verify base address for wallet version 6 (TSS)', async function () {
1446
+ const coin = bitgo.coin('hteth');
1447
+ const keychains = [
1448
+ {
1449
+ id: '691f630e0c56098288a9b7fa107db144',
1450
+ source: 'user',
1451
+ type: 'tss',
1452
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1453
+ },
1454
+ {
1455
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1456
+ source: 'backup',
1457
+ type: 'tss',
1458
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1459
+ },
1460
+ {
1461
+ id: '691f630d56735e5eb61b06e353fe7639',
1462
+ source: 'bitgo',
1463
+ type: 'tss',
1464
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1465
+ },
1466
+ ];
1467
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1468
+ const params = {
1469
+ address: baseAddress,
1470
+ baseAddress: baseAddress,
1471
+ coinSpecific: {
1472
+ salt: '0x0',
1473
+ forwarderVersion: 5,
1474
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1475
+ },
1476
+ keychains,
1477
+ index: 0,
1478
+ walletVersion: 6,
1479
+ };
1480
+ const isWalletAddr = await coin.isWalletAddress(params);
1481
+ isWalletAddr.should.equal(true);
1482
+ });
1483
+ it('should verify base address for wallet version 5 (TSS)', async function () {
1484
+ const coin = bitgo.coin('hteth');
1485
+ const keychains = [
1486
+ {
1487
+ id: '691e242d93f8d7ad0705887449763c96',
1488
+ source: 'user',
1489
+ type: 'tss',
1490
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1491
+ },
1492
+ {
1493
+ id: '691e242df8b6323d4b08df366864af66',
1494
+ source: 'backup',
1495
+ type: 'tss',
1496
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1497
+ },
1498
+ {
1499
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1500
+ source: 'bitgo',
1501
+ type: 'tss',
1502
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1503
+ },
1504
+ ];
1505
+ const baseAddress = '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11';
1506
+ const params = {
1507
+ address: baseAddress,
1508
+ baseAddress: baseAddress,
1509
+ coinSpecific: {
1510
+ salt: '0x0',
1511
+ forwarderVersion: 4,
1512
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1513
+ },
1514
+ keychains,
1515
+ index: 0,
1516
+ walletVersion: 5,
1517
+ };
1518
+ const isWalletAddr = await coin.isWalletAddress(params);
1519
+ isWalletAddr.should.equal(true);
1520
+ });
1521
+ it('should reject base address verification with non-zero index', async function () {
1522
+ const coin = bitgo.coin('hteth');
1523
+ const keychains = [
1524
+ {
1525
+ id: '691f630e0c56098288a9b7fa107db144',
1526
+ source: 'user',
1527
+ type: 'tss',
1528
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1529
+ },
1530
+ {
1531
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1532
+ source: 'backup',
1533
+ type: 'tss',
1534
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1535
+ },
1536
+ {
1537
+ id: '691f630d56735e5eb61b06e353fe7639',
1538
+ source: 'bitgo',
1539
+ type: 'tss',
1540
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1541
+ },
1542
+ ];
1543
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1544
+ const params = {
1545
+ address: baseAddress,
1546
+ baseAddress: baseAddress,
1547
+ coinSpecific: {
1548
+ salt: '0x0',
1549
+ forwarderVersion: 5,
1550
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1551
+ },
1552
+ keychains,
1553
+ index: 5, // Wrong index - should be 0 for base address
1554
+ walletVersion: 6,
1555
+ };
1556
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), /Base address verification requires index 0, but got index 5/);
1557
+ });
1558
+ it('should reject base address verification with wrong address', async function () {
1559
+ const coin = bitgo.coin('hteth');
1560
+ const keychains = [
1561
+ {
1562
+ id: '691f630e0c56098288a9b7fa107db144',
1563
+ source: 'user',
1564
+ type: 'tss',
1565
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1566
+ },
1567
+ {
1568
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1569
+ source: 'backup',
1570
+ type: 'tss',
1571
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1572
+ },
1573
+ {
1574
+ id: '691f630d56735e5eb61b06e353fe7639',
1575
+ source: 'bitgo',
1576
+ type: 'tss',
1577
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1578
+ },
1579
+ ];
1580
+ const wrongAddress = '0x0000000000000000000000000000000000000001';
1581
+ const actualBaseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1582
+ const params = {
1583
+ address: wrongAddress,
1584
+ baseAddress: actualBaseAddress,
1585
+ coinSpecific: {
1586
+ salt: '0x0',
1587
+ forwarderVersion: 5,
1588
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1589
+ },
1590
+ keychains,
1591
+ index: 0,
1592
+ walletVersion: 6,
1593
+ };
1594
+ const isWalletAddr = await coin.isWalletAddress(params);
1595
+ isWalletAddr.should.equal(false);
1596
+ });
1597
+ it('should verify base address for wallet version 2 (BIP32) using wallet factory', async function () {
1598
+ const coin = bitgo.coin('hteth');
1599
+ const baseAddress = '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4';
1600
+ const walletSalt = '0x2';
1601
+ const keychains = [
1602
+ {
1603
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1604
+ source: 'user',
1605
+ type: 'independent',
1606
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1607
+ },
1608
+ {
1609
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1610
+ source: 'backup',
1611
+ type: 'independent',
1612
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1613
+ },
1614
+ {
1615
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1616
+ source: 'bitgo',
1617
+ type: 'independent',
1618
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1619
+ },
1620
+ ];
1621
+ const params = {
1622
+ address: baseAddress,
1623
+ baseAddress: baseAddress,
1624
+ coinSpecific: {
1625
+ salt: walletSalt,
1626
+ forwarderVersion: 2,
1627
+ },
1628
+ keychains: keychains,
1629
+ index: 0,
1630
+ walletVersion: 2,
1631
+ };
1632
+ const isWalletAddr = await coin.isWalletAddress(params);
1633
+ isWalletAddr.should.equal(true);
1634
+ });
1635
+ it('should verify base address for wallet version 1 (BIP32) using wallet factory', async function () {
1636
+ const coin = bitgo.coin('hteth');
1637
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1638
+ const walletSalt = '0x5';
1639
+ const keychains = [
1640
+ {
1641
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1642
+ source: 'user',
1643
+ type: 'independent',
1644
+ ethAddress: '0xf45dadce751a317957f2a247ff37cb764b97620d',
1645
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVm...',
1646
+ },
1647
+ {
1648
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1649
+ source: 'backup',
1650
+ type: 'independent',
1651
+ ethAddress: '0x5bdf3ae1d2c2fadeeb70a45872bf4f4252312b55',
1652
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqA...',
1653
+ },
1654
+ {
1655
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1656
+ source: 'bitgo',
1657
+ type: 'independent',
1658
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1659
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79Hok...',
1660
+ },
1661
+ ];
1662
+ const params = {
1663
+ address: baseAddress,
1664
+ baseAddress: baseAddress,
1665
+ coinSpecific: {
1666
+ salt: walletSalt,
1667
+ forwarderVersion: 1,
1668
+ },
1669
+ keychains: keychains,
1670
+ index: 0,
1671
+ walletVersion: 1,
1672
+ };
1673
+ const isWalletAddr = await coin.isWalletAddress(params);
1674
+ isWalletAddr.should.equal(true);
1675
+ });
1676
+ });
1677
+ });
1678
+ });
1679
+ describe('Address Creation', function () {
1680
+ it('should pass walletVersion 6 to isWalletAddress during address creation', async function () {
1681
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1682
+ const ethCoin = bitgo.coin('hteth');
1683
+ const walletDataV6 = {
1684
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1685
+ coinSpecific: {
1686
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1687
+ walletVersion: 6,
1688
+ },
1689
+ coin: 'hteth',
1690
+ keys: [
1691
+ '598f606cd8fc24710d2ebad89dce86c2',
1692
+ '598f606cc8e43aef09fcb785221d9dd2',
1693
+ '5935d59cf660764331bafcade1855fd7',
1694
+ ],
1695
+ receiveAddress: {
1696
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1697
+ },
1698
+ };
1699
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
1700
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1701
+ // Mock keychain requests
1702
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1703
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1704
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1705
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1706
+ source: 'user',
1707
+ type: 'tss',
1708
+ });
1709
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1710
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1711
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1712
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1713
+ source: 'backup',
1714
+ type: 'tss',
1715
+ });
1716
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1717
+ id: '5935d59cf660764331bafcade1855fd7',
1718
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1719
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1720
+ source: 'bitgo',
1721
+ type: 'tss',
1722
+ });
1723
+ // Mock address creation API
1724
+ (0, nock_1.default)(bgUrl)
1725
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
1726
+ .reply(200, {
1727
+ id: '638a48c6c3dba40007a3497fa49a080c',
1728
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1729
+ chain: 0,
1730
+ index: 0,
1731
+ coin: 'hteth',
1732
+ wallet: ethWalletV6.id(),
1733
+ coinSpecific: {
1734
+ forwarderVersion: 4,
1735
+ salt: '0x0',
1736
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1737
+ },
1738
+ });
1739
+ await ethWalletV6.createAddress({ chain: 0 });
1740
+ isWalletAddressSpy.calledOnce.should.be.true();
1741
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1742
+ calledParams.should.have.property('walletVersion', 6);
1743
+ });
1744
+ it('should pass walletVersion 5 to isWalletAddress during address creation', async function () {
1745
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1746
+ const ethCoin = bitgo.coin('hteth');
1747
+ const walletDataV5 = {
1748
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1749
+ coinSpecific: {
1750
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1751
+ walletVersion: 5,
1752
+ },
1753
+ coin: 'hteth',
1754
+ keys: [
1755
+ '598f606cd8fc24710d2ebad89dce86c2',
1756
+ '598f606cc8e43aef09fcb785221d9dd2',
1757
+ '5935d59cf660764331bafcade1855fd7',
1758
+ ],
1759
+ receiveAddress: {
1760
+ address: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1761
+ },
1762
+ };
1763
+ const ethWalletV5 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV5);
1764
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1765
+ // Mock keychain requests
1766
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1767
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1768
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1769
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1770
+ source: 'user',
1771
+ type: 'tss',
1772
+ });
1773
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1774
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1775
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1776
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1777
+ source: 'backup',
1778
+ type: 'tss',
1779
+ });
1780
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1781
+ id: '5935d59cf660764331bafcade1855fd7',
1782
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1783
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1784
+ source: 'bitgo',
1785
+ type: 'tss',
1786
+ });
1787
+ // Mock address creation API
1788
+ (0, nock_1.default)(bgUrl)
1789
+ .post(`/api/v2/hteth/wallet/${ethWalletV5.id()}/address`)
1790
+ .reply(200, {
1791
+ id: '638a48c6c3dba40007a3497fa49a080c',
1792
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1793
+ chain: 0,
1794
+ index: 117,
1795
+ coin: 'hteth',
1796
+ wallet: ethWalletV5.id(),
1797
+ coinSpecific: {
1798
+ forwarderVersion: 4,
1799
+ salt: '0x75',
1800
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1801
+ },
1802
+ });
1803
+ await ethWalletV5.createAddress({ chain: 0 });
1804
+ // Verify isWalletAddress was called with walletVersion 5
1805
+ isWalletAddressSpy.calledOnce.should.be.true();
1806
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1807
+ calledParams.should.have.property('walletVersion', 5);
1808
+ });
1809
+ it('should pass walletVersion 2 to isWalletAddress during address creation', async function () {
1810
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1811
+ const ethCoin = bitgo.coin('hteth');
1812
+ const walletDataV2 = {
1813
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1814
+ coinSpecific: {
1815
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1816
+ walletVersion: 2,
1817
+ },
1818
+ coin: 'hteth',
1819
+ keys: [
1820
+ '598f606cd8fc24710d2ebad89dce86c2',
1821
+ '598f606cc8e43aef09fcb785221d9dd2',
1822
+ '5935d59cf660764331bafcade1855fd7',
1823
+ ],
1824
+ receiveAddress: {
1825
+ address: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1826
+ },
1827
+ };
1828
+ const ethWalletV2 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV2);
1829
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1830
+ // Mock keychain requests
1831
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1832
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1833
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1834
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1835
+ source: 'user',
1836
+ type: 'independent',
1837
+ });
1838
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1839
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1840
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1841
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1842
+ source: 'backup',
1843
+ type: 'independent',
1844
+ });
1845
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1846
+ id: '5935d59cf660764331bafcade1855fd7',
1847
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1848
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1849
+ source: 'bitgo',
1850
+ type: 'independent',
1851
+ });
1852
+ // Mock address creation API
1853
+ (0, nock_1.default)(bgUrl)
1854
+ .post(`/api/v2/hteth/wallet/${ethWalletV2.id()}/address`)
1855
+ .reply(200, {
1856
+ id: '638a48c6c3dba40007a3497fa49a080c',
1857
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1858
+ chain: 0,
1859
+ index: 23,
1860
+ coin: 'hteth',
1861
+ wallet: ethWalletV2.id(),
1862
+ coinSpecific: {
1863
+ forwarderVersion: 2,
1864
+ salt: '0x17',
1865
+ },
1866
+ });
1867
+ await ethWalletV2.createAddress({ chain: 0 });
1868
+ // Verify isWalletAddress was called with walletVersion 2
1869
+ isWalletAddressSpy.calledOnce.should.be.true();
1870
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1871
+ calledParams.should.have.property('walletVersion', 2);
1872
+ });
1873
+ it('should fail v6 address creation if walletVersion was not passed (simulates old bug)', async function () {
1874
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1875
+ const ethCoin = bitgo.coin('hteth');
1876
+ const walletDataV6 = {
1877
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1878
+ coinSpecific: {
1879
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1880
+ walletVersion: 6,
1881
+ },
1882
+ coin: 'hteth',
1883
+ keys: [
1884
+ '598f606cd8fc24710d2ebad89dce86c2',
1885
+ '598f606cc8e43aef09fcb785221d9dd2',
1886
+ '5935d59cf660764331bafcade1855fd7',
1887
+ ],
1888
+ receiveAddress: {
1889
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1890
+ },
1891
+ };
1892
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
1893
+ // Stub isWalletAddress to simulate the OLD bug where walletVersion was not passed
1894
+ const originalIsWalletAddress = ethCoin.isWalletAddress.bind(ethCoin);
1895
+ const isWalletAddressStub = sinon_1.default.stub(ethCoin, 'isWalletAddress').callsFake(async (params) => {
1896
+ // Remove walletVersion to simulate the old bug
1897
+ const paramsWithoutWalletVersion = { ...params };
1898
+ delete paramsWithoutWalletVersion.walletVersion;
1899
+ return originalIsWalletAddress(paramsWithoutWalletVersion);
1900
+ });
1901
+ // Mock keychain requests
1902
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1903
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1904
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1905
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1906
+ source: 'user',
1907
+ type: 'tss',
1908
+ });
1909
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1910
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1911
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1912
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1913
+ source: 'backup',
1914
+ type: 'tss',
1915
+ });
1916
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1917
+ id: '5935d59cf660764331bafcade1855fd7',
1918
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1919
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1920
+ source: 'bitgo',
1921
+ type: 'tss',
1922
+ });
1923
+ // Mock address creation API
1924
+ (0, nock_1.default)(bgUrl)
1925
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
1926
+ .reply(200, {
1927
+ id: '638a48c6c3dba40007a3497fa49a080c',
1928
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1929
+ chain: 0,
1930
+ index: 0,
1931
+ coin: 'hteth',
1932
+ wallet: ethWalletV6.id(),
1933
+ coinSpecific: {
1934
+ forwarderVersion: 4,
1935
+ salt: '0x0',
1936
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1937
+ },
1938
+ });
1939
+ // Without walletVersion, address creation should fail because
1940
+ // the code doesn't know to use TSS verification for v6 wallets
1941
+ await assert_1.default.rejects(async () => ethWalletV6.createAddress({ chain: 0 }), sdk_core_1.UnexpectedAddressError);
1942
+ isWalletAddressStub.restore();
1943
+ });
1944
+ });
1945
+ describe('EVM Cross Chain Recovery', function () {
1946
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1947
+ it('should build a recovery transaction for hot wallet', async function () {
1948
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
1949
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
1950
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
1951
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
1952
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
1953
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
1954
+ const destinationAddress = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
1955
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
1956
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
1957
+ const basecoin = bitgo.coin('hteth');
1958
+ (0, nock_1.default)(baseUrl)
1959
+ .get('/api')
1960
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
1961
+ .reply(200, mockData.getTxListResponse);
1962
+ (0, nock_1.default)(baseUrl)
1963
+ .get('/api')
1964
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
1965
+ .reply(200, mockData.getBalanceResponse);
1966
+ (0, nock_1.default)(baseUrl)
1967
+ .get('/api')
1968
+ .query(mockData.getBalanceRequest(walletContractAddress))
1969
+ .reply(200, mockData.getBalanceResponse);
1970
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
1971
+ const spy = sinon_1.default.spy(src_1.TransactionBuilder.prototype, 'coinUsesNonPackedEncodingForTxData');
1972
+ await basecoin.recover({
1973
+ userKey: userKey,
1974
+ backupKey: '',
1975
+ walletPassphrase: walletPassphrase,
1976
+ walletContractAddress: walletContractAddress,
1977
+ bitgoFeeAddress: bitgoFeeAddress,
1978
+ recoveryDestination: destinationAddress,
1979
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
1980
+ gasLimit: 500000,
1981
+ bitgoDestinationAddress: bitgoDestinationAddress,
1982
+ intendedChain: 'tarbeth',
1983
+ });
1984
+ (0, assert_1.default)(spy.returned(true));
1985
+ });
1986
+ describe('Non-BitGo Recovery for Hot Wallets (MPCv2)', function () {
1987
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
1988
+ let bitgo;
1989
+ let basecoin;
1990
+ before(function () {
1991
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
1992
+ basecoin = bitgo.coin('hteth');
1993
+ });
1994
+ it('should build a recovery transaction for MPCv2 kind of hot wallets', async function () {
1995
+ (0, nock_1.default)(baseUrl)
1996
+ .get('/api')
1997
+ .query(mockData.getTxListRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
1998
+ .reply(200, mockData.getTxListResponse);
1999
+ (0, nock_1.default)(baseUrl)
2000
+ .get('/api')
2001
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
2002
+ .reply(200, mockData.getBalanceResponse);
2003
+ (0, nock_1.default)(baseUrl)
2004
+ .get('/api')
2005
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().walletContractAddress))
2006
+ .reply(200, mockData.getBalanceResponse);
2007
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2008
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
2009
+ const transaction = await basecoin.recover({
2010
+ userKey: params.userKey,
2011
+ backupKey: params.backupKey,
2012
+ walletPassphrase: params.walletPassphrase,
2013
+ walletContractAddress: params.walletContractAddress,
2014
+ bitgoFeeAddress: params.bitgoFeeAddress,
2015
+ recoveryDestination: params.recoveryDestination,
2016
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2017
+ gasLimit: 500000,
2018
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2019
+ intendedChain: params.intendedChain,
2020
+ });
2021
+ should_1.default.exist(transaction);
2022
+ transaction.should.have.property('txHex');
2023
+ });
2024
+ it('should throw an error for invalid user key', async function () {
2025
+ const params = mockData.getInvalidNonBitGoRecoveryParams();
2026
+ await assert_1.default.rejects(async () => {
2027
+ await basecoin.recover({
2028
+ userKey: params.userKey,
2029
+ backupKey: params.backupKey,
2030
+ walletPassphrase: params.walletPassphrase,
2031
+ walletContractAddress: params.walletContractAddress,
2032
+ bitgoFeeAddress: params.bitgoFeeAddress,
2033
+ recoveryDestination: params.recoveryDestination,
2034
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2035
+ gasLimit: 500000,
2036
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2037
+ intendedChain: params.intendedChain,
2038
+ });
2039
+ }, Error, 'user key is invalid');
2040
+ });
2041
+ });
2042
+ describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
2043
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2044
+ let bitgo;
2045
+ let basecoin;
2046
+ before(function () {
2047
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2048
+ basecoin = bitgo.coin('hteth');
2049
+ });
2050
+ it('should generate an unsigned sweep without derivation seed', async function () {
2051
+ (0, nock_1.default)(baseUrl)
2052
+ .get('/api')
2053
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2054
+ .reply(200, mockData.getTxListResponse);
2055
+ (0, nock_1.default)(baseUrl)
2056
+ .get('/api')
2057
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2058
+ .reply(200, mockData.getBalanceResponse);
2059
+ (0, nock_1.default)(baseUrl)
2060
+ .get('/api')
2061
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2062
+ .reply(200, mockData.getBalanceResponse);
2063
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2064
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2065
+ const sweepResult = await basecoin.recover({
2066
+ userKey: params.commonKeyChain, // Box A Data
2067
+ backupKey: params.commonKeyChain, // Box B Data
2068
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2069
+ recoveryDestination: params.recoveryDestination, // Destination Address
2070
+ gasLimit: 200000, // Gas Limit
2071
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2072
+ walletContractAddress: params.walletContractAddress,
2073
+ isTss: true,
2074
+ replayProtectionOptions: {
2075
+ chain: '42',
2076
+ hardfork: 'london',
2077
+ },
2078
+ });
2079
+ should_1.default.exist(sweepResult);
2080
+ const output = sweepResult;
2081
+ output.should.have.property('txRequests');
2082
+ output.txRequests.should.have.length(1);
2083
+ output.txRequests[0].should.have.property('transactions');
2084
+ output.txRequests[0].transactions.should.have.length(1);
2085
+ output.txRequests[0].should.have.property('walletCoin');
2086
+ output.txRequests[0].transactions.should.have.length(1);
2087
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2088
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2089
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2090
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2091
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2092
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2093
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2094
+ parsedTx.should.have.property('spendAmount');
2095
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2096
+ });
2097
+ it('should throw an error for invalid address', async function () {
2098
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2099
+ params.recoveryDestination = 'invalidAddress';
2100
+ // Ensure userKey and backupKey are the same
2101
+ params.userKey =
2102
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2103
+ params.backupKey =
2104
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2105
+ await assert_1.default.rejects(async () => {
2106
+ await basecoin.recover({
2107
+ recoveryDestination: params.recoveryDestination, // Destination Address
2108
+ gasLimit: 2000, // Gas Limit
2109
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2110
+ userKey: params.userKey, // Provide the userKey
2111
+ backupKey: params.backupKey, // Provide the backupKey
2112
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2113
+ isTss: true,
2114
+ replayProtectionOptions: {
2115
+ chain: '42',
2116
+ hardfork: 'london',
2117
+ },
2118
+ });
2119
+ }, Error, 'Error: invalid address');
2120
+ });
2121
+ });
2122
+ describe('Build Unsigned Consolidation for Self-Custody Cold Wallets (MPCv2)', function () {
2123
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2124
+ let bitgo;
2125
+ let basecoin;
2126
+ before(function () {
2127
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2128
+ basecoin = bitgo.coin('hteth');
2129
+ });
2130
+ it('should generate an unsigned consolidation for wallet v5', async function () {
2131
+ (0, nock_1.default)(baseUrl)
2132
+ .get('/api')
2133
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2134
+ .times(2)
2135
+ .reply(200, mockData.getTxListResponse);
2136
+ (0, nock_1.default)(baseUrl)
2137
+ .get('/api')
2138
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2139
+ .times(2)
2140
+ .reply(200, mockData.getBalanceResponse);
2141
+ (0, nock_1.default)(baseUrl)
2142
+ .get('/api')
2143
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2144
+ .reply(200, mockData.getBalanceResponse);
2145
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2146
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2147
+ const consolidationResult = await basecoin.recoverConsolidations({
2148
+ backupKey: params.commonKeyChain, // Box B Data
2149
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2150
+ recoveryDestination: params.recoveryDestination, // Destination Address
2151
+ gasLimit: 200000, // Gas Limit
2152
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2153
+ walletContractAddress: params.walletContractAddress,
2154
+ isTss: true,
2155
+ replayProtectionOptions: {
2156
+ chain: '42',
2157
+ hardfork: 'london',
2158
+ },
2159
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2160
+ startingScanIndex: 1,
2161
+ endingScanIndex: 2,
2162
+ });
2163
+ should_1.default.exist(consolidationResult);
2164
+ const unsignedBuilConsolidation = consolidationResult;
2165
+ unsignedBuilConsolidation.should.have.property('transactions');
2166
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2167
+ const output = unsignedBuilConsolidation.transactions[0];
2168
+ output.should.have.property('txRequests');
2169
+ output.txRequests[0].should.have.property('transactions');
2170
+ output.txRequests[0].transactions.should.have.length(1);
2171
+ output.txRequests[0].should.have.property('walletCoin');
2172
+ output.txRequests[0].transactions.should.have.length(1);
2173
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2174
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2175
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2176
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2177
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2178
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2179
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2180
+ parsedTx.should.have.property('spendAmount');
2181
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2182
+ });
2183
+ it('should generate an unsigned consolidation for wallet v6', async function () {
2184
+ (0, nock_1.default)(baseUrl)
2185
+ .get('/api')
2186
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2187
+ .times(2)
2188
+ .reply(200, mockData.getTxListResponse);
2189
+ (0, nock_1.default)(baseUrl)
2190
+ .get('/api')
2191
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2192
+ .times(2)
2193
+ .reply(200, mockData.getBalanceResponse);
2194
+ (0, nock_1.default)(baseUrl)
2195
+ .get('/api')
2196
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2197
+ .reply(200, mockData.getBalanceResponse);
2198
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2199
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2200
+ const consolidationResult = await basecoin.recoverConsolidations({
2201
+ userKey: params.commonKeyChain, // Box A Data
2202
+ backupKey: params.commonKeyChain, // Box B Data
2203
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2204
+ recoveryDestination: params.recoveryDestination, // Destination Address
2205
+ gasLimit: 200000, // Gas Limit
2206
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2207
+ isTss: true,
2208
+ walletContractAddress: '123', // Wrong wallet address so that we can skip v5 address generation
2209
+ replayProtectionOptions: {
2210
+ chain: '42',
2211
+ hardfork: 'london',
2212
+ },
2213
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2214
+ startingScanIndex: 1,
2215
+ endingScanIndex: 2,
2216
+ });
2217
+ should_1.default.exist(consolidationResult);
2218
+ const unsignedBuilConsolidation = consolidationResult;
2219
+ unsignedBuilConsolidation.should.have.property('transactions');
2220
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2221
+ const output = unsignedBuilConsolidation.transactions[0];
2222
+ output.should.have.property('txRequests');
2223
+ output.txRequests[0].should.have.property('transactions');
2224
+ output.txRequests[0].transactions.should.have.length(1);
2225
+ output.txRequests[0].should.have.property('walletCoin');
2226
+ output.txRequests[0].transactions.should.have.length(1);
2227
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2228
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2229
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2230
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2231
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2232
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2233
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2234
+ parsedTx.should.have.property('spendAmount');
2235
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2236
+ });
2237
+ it('should throw an error for invalid address', async function () {
2238
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2239
+ params.recoveryDestination = 'invalidAddress';
2240
+ // Ensure userKey and backupKey are the same
2241
+ params.userKey =
2242
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2243
+ params.backupKey =
2244
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2245
+ await assert_1.default.rejects(async () => {
2246
+ await basecoin.recover({
2247
+ recoveryDestination: params.recoveryDestination, // Destination Address
2248
+ gasLimit: 2000, // Gas Limit
2249
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2250
+ userKey: params.userKey, // Provide the userKey
2251
+ backupKey: params.backupKey, // Provide the backupKey
2252
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2253
+ isTss: true,
2254
+ replayProtectionOptions: {
2255
+ chain: '42',
2256
+ hardfork: 'london',
2257
+ },
2258
+ });
2259
+ }, Error, 'Error: invalid address');
2260
+ });
2261
+ });
2262
+ });
2263
+ describe('RecoveryBlockchainExplorerQuery', () => {
2264
+ it('should override the token parameter with a custom API key', async function () {
2265
+ const coin = bitgo.coin('teth');
2266
+ const query = {
2267
+ module: 'account',
2268
+ action: 'balance',
2269
+ address: '0x1234567890123456789012345678901234567890',
2270
+ };
2271
+ const customApiKey = 'custom-api-key-for-test';
2272
+ // Mock the environment API token
2273
+ const originalApiToken = sdk_core_1.common.Environments.test.etherscanApiToken;
2274
+ sdk_core_1.common.Environments.test.etherscanApiToken = 'default-environment-api-key';
2275
+ // Mock the request.get function to capture the query parameters
2276
+ const originalGet = superagent_1.default.get;
2277
+ let capturedQuery;
2278
+ superagent_1.default.get = function (url) {
2279
+ return {
2280
+ query: function (params) {
2281
+ capturedQuery = params;
2282
+ return {
2283
+ ok: true,
2284
+ body: { result: '100000000' },
2285
+ };
2286
+ },
2287
+ };
2288
+ };
2289
+ try {
2290
+ // Call with default API key
2291
+ await coin.recoveryBlockchainExplorerQuery(query);
2292
+ capturedQuery.should.have.property('apikey', 'default-environment-api-key');
2293
+ // Call with custom API key
2294
+ await coin.recoveryBlockchainExplorerQuery(query, customApiKey);
2295
+ capturedQuery.should.have.property('apikey', customApiKey);
2296
+ }
2297
+ finally {
2298
+ // Restore original function and API token
2299
+ superagent_1.default.get = originalGet;
2300
+ sdk_core_1.common.Environments.test.etherscanApiToken = originalApiToken;
2301
+ }
2302
+ });
2303
+ });
2304
+ describe('Audit Key', () => {
2305
+ let coin;
2306
+ before(() => {
2307
+ coin = bitgo.coin('hteth');
2308
+ });
2309
+ describe('MultiSig', () => {
2310
+ const { key } = ethMultiSigBackupKey_1.ethMultiSigBackupKey;
2311
+ it('should return { isValid: true } for valid inputs', () => {
2312
+ coin.assertIsValidKey({
2313
+ encryptedPrv: key,
2314
+ walletPassphrase: 'ZQ8MhxT84m4P',
2315
+ });
2316
+ });
2317
+ it('should throw error if the walletPassphrase is incorrect', () => {
2318
+ assert_1.default.throws(() => coin.assertIsValidKey({
2319
+ encryptedPrv: key,
2320
+ walletPassphrase: 'foo',
2321
+ }), { message: "failed to decrypt prv: password error - ccm: tag doesn't match" });
2322
+ });
2323
+ it('should throw error if the key is altered', () => {
2324
+ const alteredKey = key.replace(/[0-9]/g, '0');
2325
+ assert_1.default.throws(() => coin.assertIsValidKey({
2326
+ encryptedPrv: alteredKey,
2327
+ walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
2328
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
2329
+ });
2330
+ });
2331
+ describe('TSS', () => {
2332
+ const { key: keyString, commonKeychain } = ethTssBackupKey_1.ethTssBackupKey;
2333
+ const key = keyString.replace(/\s/g, '');
2334
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
2335
+ const multiSigType = 'tss';
2336
+ it('should not throw for valid inputs', () => {
2337
+ coin.assertIsValidKey({
2338
+ encryptedPrv: key,
2339
+ publicKey: commonKeychain,
2340
+ walletPassphrase,
2341
+ multiSigType,
2342
+ });
2343
+ });
2344
+ it('should throw if the commonKeychain is altered', () => {
2345
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
2346
+ assert_1.default.throws(() => coin.assertIsValidKey({
2347
+ encryptedPrv: key,
2348
+ publicKey: alteredCommonKeychain,
2349
+ walletPassphrase,
2350
+ multiSigType,
2351
+ }), { message: 'Invalid common keychain' });
2352
+ });
2353
+ it('should throw error if the walletPassphrase is incorrect', () => {
2354
+ const incorrectPassphrase = 'foo';
2355
+ assert_1.default.throws(() => coin.assertIsValidKey({
2356
+ encryptedPrv: key,
2357
+ publicKey: commonKeychain,
2358
+ walletPassphrase: incorrectPassphrase,
2359
+ multiSigType,
2360
+ }), { message: "failed to decrypt prv: password error - ccm: tag doesn't match" });
2361
+ });
2362
+ it('should throw error if the key is altered', () => {
2363
+ const alteredKey = key.replace(/[0-9]/g, '0');
2364
+ assert_1.default.throws(() => coin.assertIsValidKey({
2365
+ encryptedPrv: alteredKey,
2366
+ publicKey: commonKeychain,
2367
+ walletPassphrase,
2368
+ multiSigType,
2369
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
2370
+ });
2371
+ });
2372
+ });
2373
+ describe('getSignablePayload', function () {
2374
+ let coin;
2375
+ before(function () {
2376
+ coin = bitgo.coin('teth');
2377
+ });
2378
+ it('should return a 32-byte keccak256 hash for a Legacy transaction', async function () {
2379
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2380
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2381
+ txBuilder.fee({ fee: '10000000000', gasLimit: '7000000' });
2382
+ txBuilder.counter(1);
2383
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
2384
+ const transferBuilder = txBuilder.transfer();
2385
+ transferBuilder
2386
+ .coin('teth')
2387
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
2388
+ .amount('100000')
2389
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
2390
+ .contractSequenceId(1);
2391
+ const tx = await txBuilder.build();
2392
+ const serializedTx = tx.toBroadcastFormat();
2393
+ const payload = await coin.getSignablePayload(serializedTx);
2394
+ assert_1.default.ok(Buffer.isBuffer(payload));
2395
+ assert_1.default.strictEqual(payload.length, 32);
2396
+ });
2397
+ it('should return a 32-byte keccak256 hash for an EIP1559 transaction', async function () {
2398
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2399
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2400
+ txBuilder.fee({
2401
+ fee: '280000000000',
2402
+ gasLimit: '7000000',
2403
+ eip1559: { maxFeePerGas: '7593123', maxPriorityFeePerGas: '150' },
2404
+ });
2405
+ txBuilder.counter(1);
2406
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
2407
+ const transferBuilder = txBuilder.transfer();
2408
+ transferBuilder
2409
+ .coin('teth')
2410
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
2411
+ .amount('100000')
2412
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
2413
+ .contractSequenceId(1);
2414
+ const tx = await txBuilder.build();
2415
+ const serializedTx = tx.toBroadcastFormat();
2416
+ const payload = await coin.getSignablePayload(serializedTx);
2417
+ assert_1.default.ok(Buffer.isBuffer(payload));
2418
+ assert_1.default.strictEqual(payload.length, 32);
2419
+ });
2420
+ });
2421
+ // ---------------------------------------------------------------------------
2422
+ // ERC-7984 token enablement — multisig verifyTransaction (all scenarios)
2423
+ // ---------------------------------------------------------------------------
2424
+ describe('verifyTransaction – ERC-7984 enabletoken (multisig wallet)', function () {
2425
+ // hteth Zama ACL contract (Networks.test.hoodi.zamaAclContractAddress)
2426
+ const ZAMA_ACL_ADDRESS = '0x6d3faf6f86e1ff9f3b0831dda920aba1cbd5bd68';
2427
+ // Simulated wallet base address (what the client sends as the recipient for base-address wallets)
2428
+ const WALLET_BASE_ADDRESS = '0x08e6736e876d772d2fa8f803a076cd6c9f845546';
2429
+ // Simulated forwarder address (what the client sends as recipient for forwarder wallets)
2430
+ const FORWARDER_ADDRESS = '0x1234567890123456789012345678901234567890';
2431
+ const WRONG_ADDRESS = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
2432
+ const makePrebuild = (recipientAddress) => ({
2433
+ recipients: [{ address: recipientAddress, amount: '0' }],
2434
+ nextContractSequenceId: 0,
2435
+ gasPrice: 20000000000,
2436
+ gasLimit: 300000,
2437
+ isBatch: false,
2438
+ coin: 'hteth',
2439
+ walletId: 'fakeWalletId',
2440
+ });
2441
+ // ── Base-address wallet ──────────────────────────────────────────────────
2442
+ it('base-address, single token: txParams → walletBase, txPrebuild → ACL', async function () {
2443
+ const htethCoin = bitgo.coin('hteth');
2444
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2445
+ const result = await htethCoin.verifyTransaction({
2446
+ txParams: {
2447
+ type: 'enabletoken',
2448
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2449
+ },
2450
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2451
+ wallet,
2452
+ });
2453
+ result.should.equal(true);
2454
+ });
2455
+ it('base-address, multi-token: multiple txParams recipients (same base address), txPrebuild → ACL multicall', async function () {
2456
+ const htethCoin = bitgo.coin('hteth');
2457
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2458
+ const result = await htethCoin.verifyTransaction({
2459
+ txParams: {
2460
+ type: 'enabletoken',
2461
+ recipients: [
2462
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2463
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2464
+ ],
2465
+ },
2466
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2467
+ wallet,
2468
+ });
2469
+ result.should.equal(true);
2470
+ });
2471
+ // ── Forwarder wallet ─────────────────────────────────────────────────────
2472
+ it('forwarder, single token: txParams → forwarder, txPrebuild → forwarder', async function () {
2473
+ const htethCoin = bitgo.coin('hteth');
2474
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2475
+ const result = await htethCoin.verifyTransaction({
2476
+ txParams: {
2477
+ type: 'enabletoken',
2478
+ recipients: [{ address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2479
+ },
2480
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
2481
+ wallet,
2482
+ });
2483
+ result.should.equal(true);
2484
+ });
2485
+ it('forwarder, multi-token: multiple txParams recipients (same forwarder), txPrebuild → forwarder', async function () {
2486
+ const htethCoin = bitgo.coin('hteth');
2487
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2488
+ const result = await htethCoin.verifyTransaction({
2489
+ txParams: {
2490
+ type: 'enabletoken',
2491
+ recipients: [
2492
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2493
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2494
+ ],
2495
+ },
2496
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
2497
+ wallet,
2498
+ });
2499
+ result.should.equal(true);
2500
+ });
2501
+ // ── Negative cases ───────────────────────────────────────────────────────
2502
+ it('should throw when txPrebuild recipient is neither the ACL contract nor the forwarder from txParams', async function () {
2503
+ const htethCoin = bitgo.coin('hteth');
2504
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2505
+ await htethCoin
2506
+ .verifyTransaction({
2507
+ txParams: {
2508
+ type: 'enabletoken',
2509
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2510
+ },
2511
+ txPrebuild: makePrebuild(WRONG_ADDRESS),
2512
+ wallet,
2513
+ })
2514
+ .should.be.rejectedWith(/token enablement txPrebuild recipient must be/);
2515
+ });
2516
+ it('should throw when txParams recipients have different addresses', async function () {
2517
+ const htethCoin = bitgo.coin('hteth');
2518
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2519
+ await htethCoin
2520
+ .verifyTransaction({
2521
+ txParams: {
2522
+ type: 'enabletoken',
2523
+ recipients: [
2524
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2525
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2526
+ ],
2527
+ },
2528
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2529
+ wallet,
2530
+ })
2531
+ .should.be.rejectedWith(/must all have the same address/);
2532
+ });
2533
+ it('should throw when a txParams recipient has non-zero amount', async function () {
2534
+ const htethCoin = bitgo.coin('hteth');
2535
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2536
+ await htethCoin
2537
+ .verifyTransaction({
2538
+ txParams: {
2539
+ type: 'enabletoken',
2540
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '100', tokenName: 'hteth:ctest1' }],
2541
+ },
2542
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2543
+ wallet,
2544
+ })
2545
+ .should.be.rejectedWith(/must all have amount 0/);
2546
+ });
2547
+ it('should throw when txPrebuild recipient has non-zero amount', async function () {
2548
+ const htethCoin = bitgo.coin('hteth');
2549
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2550
+ await htethCoin
2551
+ .verifyTransaction({
2552
+ txParams: {
2553
+ type: 'enabletoken',
2554
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2555
+ },
2556
+ txPrebuild: {
2557
+ recipients: [{ address: ZAMA_ACL_ADDRESS, amount: '500' }],
2558
+ nextContractSequenceId: 0,
2559
+ coin: 'hteth',
2560
+ walletId: 'fakeWalletId',
2561
+ },
2562
+ wallet,
2563
+ })
2564
+ .should.be.rejectedWith(/expected amount 0 in txPrebuild/);
2565
+ });
2566
+ });
2567
+ });
2568
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUErRDtBQUUvRCxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLHFEQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsNERBQWlDO0FBQ2pDLG1EQVM4QjtBQUM5QixpREFBK0M7QUFDL0MsbUNBV21CO0FBRW5CLG9EQUE0QjtBQUM1Qiw2Q0FBMEM7QUFDMUMsMkRBQTZDO0FBQzdDLDBEQUE0QztBQUM1QyxvREFBNEI7QUFDNUIsb0VBQXlDO0FBQ3pDLDBFQUF1RTtBQUN2RSxnRUFBNkQ7QUFFN0QsY0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFFeEIsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLG1CQUFtQixDQUFDO0lBQ3hCLElBQUksT0FBMkIsQ0FBQztJQUVoQyxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLGtCQUFrQixHQUFHLDRDQUE0QyxDQUFDO0lBQ3hFLE1BQU0scUJBQXFCLEdBQUcsNENBQTRDLENBQUM7SUFDM0UsTUFBTSxLQUFLLEdBQ1QsOE5BQThOLENBQUM7SUFDak8sTUFBTSxPQUFPLEdBQUcsb0VBQW9FLENBQUM7SUFDckYsTUFBTSxVQUFVLEdBQ2Qsb0lBQW9JLENBQUM7SUFFdkksTUFBTSxDQUFDO1FBQ0wsTUFBTSxZQUFZLEdBQ2hCLGlIQUFpSCxDQUFDO1FBQ3BILE1BQU0sUUFBUSxHQUFHLGlCQUFLLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxl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QUE0RCxFQUFFLEtBQUs7WUFDcEUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQVUsQ0FBQztZQUMvQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGlCQUFNLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxFQUFFLFlBQVksRUFBRSxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUVwRyxNQUFNLFNBQVM7aUJBQ1osaUJBQWlCLENBQUM7Z0JBQ2pCLFFBQVEsRUFBRTtvQkFDUixJQUFJLEVBQUUsYUFBYTtvQkFDbkIsVUFBVSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUM7aUJBQ2hGO2dCQUNSLFVBQVUsRUFBRTtvQkFDVixVQUFVLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUM7b0JBQzFELHNCQUFzQixFQUFFLENBQUM7b0JBQ3pCLElBQUksRUFBRSxPQUFPO29CQUNiLFFBQVEsRUFBRSxjQUFjO2lCQUNsQjtnQkFDUixNQUFNO2FBQ1AsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuXG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBiaXAzMiB9IGZyb20gJ0BiaXRnby1iZXRhL3NlY3AyNTZrMSc7XG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3N1cGVyYWdlbnQnO1xuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBnZW5lcmF0ZVJhbmRvbVBhc3N3b3JkLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3IsXG4gIE1QQ1N3ZWVwVHhzLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7XG4gIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLFxuICBFcmMyMFRva2VuLFxuICBIdGV0aCxcbiAgVGV0aCxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBUcmFuc2ZlckJ1aWxkZXIsXG4gIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zLFxuICBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLFxuICBVbnNpZ25lZFN3ZWVwVHhNUEN2MixcbiAgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnMsXG59IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBFdGhlcmV1bU5ldHdvcmsgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2V0aCc7XG5pbXBvcnQgKiBhcyBtb2NrRGF0YSBmcm9tICcuLi9maXh0dXJlcy9ldGgnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IEV0aGVyZXVtQWJpIGZyb20gJ2V0aGVyZXVtanMtYWJpJztcbmltcG9ydCB7IGV0aE11bHRpU2lnQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9ldGhNdWx0aVNpZ0JhY2t1cEtleSc7XG5pbXBvcnQgeyBldGhUc3NCYWNrdXBLZXkgfSBmcm9tICcuL2ZpeHR1cmVzL2V0aFRzc0JhY2t1cEtleSc7XG5cbm5vY2suZW5hYmxlTmV0Q29ubmVjdCgpO1xuXG5kZXNjcmliZSgnRVRIOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBob3BUeEJpdGdvU2lnbmF0dXJlO1xuICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuXG4gIGNvbnN0IGFkZHJlc3MxID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gIGNvbnN0IGFkZHJlc3MyID0gJzB4N2U4NWJkYzI3YzA1MGUzOTA1ZWJmNGI4ZTYzNGQ5YWQ2ZWRkMGRlNic7XG4gIGNvbnN0IGhvcENvbnRyYWN0QWRkcmVzcyA9ICcweDQ3Y2U3Y2M4NmVmZWZlZjE5ZjhmYjUxNmIxMTczNWQxODNkYTg2MzUnO1xuICBjb25zdCBob3BEZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHg5YzdlOGNlNjgyNWJENDgyNzhCM0FiNTkyMjhFRTI2ZjhCRTc5MjViJztcbiAgY29uc3QgaG9wVHggPVxuICAgICcweGY4NmI4MDg1MDRhODE3YzhmZjgyNTJmZjk0OWM3ZThjZTY4MjViZDQ4Mjc4YjNhYjU5MjI4ZWUyNmY4YmU3OTI1Yjg3MDM4ZDdlYTRjNjgwMDA4MDFjYTAxMWJjMjJjNjY0NTcwMTMzZGZjYTRmMDhhMGI4ZDAyMzM5Y2Y0NjcwNDZkNmE0MTUyZjA0ZjM2OGQwZWFmOTllYTAxZDZkYzVjZjBjODk3YzhkNGMzZTFkZjUzZDBkMDQyNzg0YzQyNDUzNmE0Y2M1YjgwMjU1MmI3ZDY0ZmVlOGI1JztcbiAgY29uc3QgaG9wVHhpZCA9ICcweDRhZjY1MTQzYmM3N2RhMmI1MGYzNWIzZDEzY2FjYjRkYjE4ZjAyNmJmODRiYzA3NDM1NTBiYzU3YjliNTMzNTEnO1xuICBjb25zdCB1c2VyUmVxU2lnID1cbiAgICAnMHg0MDRkYjMwN2Y2MTQ3ZjBkOGNkMzM4YzM0YzEzOTA2ZWY0NmE2ZmFhN2UwZTExOWQ1MTk0ZWYwNWFlYzE2ZTZmM2Q3MTBmOWI3OTAxNDYwZjk3ZTkyNDA2NmI2MmVmZDc0NDQzYmQzNDQwMmM2ZDQwYjQ5YzIwM2E1NTlmZjJjOCc7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRnb0tleVhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szdHBXQkhXZTMxc0xvWE5SUTlBdlJZSmdpdGtLeFE0QVRGUU13dnI3aEhOcVlSVW5TN1BzanpCN2FLMVZ4cUhMdU5Ramoxc2NrSjJKd28ycXhtc3ZlandFQ1NwRk1mQyc7XG4gICAgY29uc3QgYml0Z29LZXkgPSBiaXAzMi5mcm9tQmFzZTU4KGJpdGdvS2V5WHBydik7XG4gICAgaWYgKCFiaXRnb0tleS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgY29uc3QgYml0Z29YcHViID0gYml0Z29LZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIGhvcFR4Qml0Z29TaWduYXR1cmUgPVxuICAgICAgJzB4YWEnICtcbiAgICAgIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5lY2RzYVNpZ24oQnVmZmVyLmZyb20oaG9wVHhpZC5zbGljZSgyKSwgJ2hleCcpLCBiaXRnb0tleS5wcml2YXRlS2V5KS5zaWduYXR1cmUpLnRvU3RyaW5nKFxuICAgICAgICAnaGV4J1xuICAgICAgKTtcblxuICAgIGNvbnN0IGVudiA9ICd0ZXN0JztcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBFcmMyMFRva2VuLmNyZWF0ZVRva2VuQ29uc3RydWN0b3JzKCkuZm9yRWFjaCgoeyBuYW1lLCBjb2luQ29uc3RydWN0b3IgfSkgPT4ge1xuICAgICAgYml0Z28uc2FmZVJlZ2lzdGVyKG5hbWUsIGNvaW5Db25zdHJ1Y3Rvcik7XG4gICAgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdodGV0aCcsIEh0ZXRoLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBjb21tb24uRW52aXJvbm1lbnRzW2Vudl0uaHNtWHB1YiA9IGJpdGdvWHB1YjtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnRUlQMTU1OScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gYSB0cmFuc2FjdGlvbiB3aXRoIEVJUDE1NTkgZmVlIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICBwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLM2hla3lOajdUY2lSNFhOWWUxa01qNjhXMmlwakpHTkhFVFdQN280MkFqRG5TUGdLaGRaNHg4TkJBdmFMNzJSclhqdVhOZG1rTXFMRVJaemE3M29ZdWdHdGJMRlhHOGcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0JqRTVRRzdwa2Y5Y1pEMzNVVUQ2SzQ2cTdFTHJidUc3RnFYZkxOR2lYWUdIZUVuR0JiNUFXUkVuazFlQTI4ZzhBclp2VVJiaHNoWFdrVHRkZEhSbzU0Zmd5VnZMZGInLFxuICAgICAgICByYXdQdWI6ICcwMjM2MzZlNjhiN2IyMDQ1NzNhYmRhMjYxNmFmZjZiNTg0OTEwZGVjZTI1NDNmMWNjNmQ4NDJjYWFjN2Q3NDk3NGInLFxuICAgICAgICByYXdQcnY6ICc3NDM4YTUwMDEwY2U3YjFkZmQ4NmU2ODA0NmNjNzhiYTFlYmQyNDJkNmQ4NWQ5OTA0ZDNmY2MwODczNGJjMTcyJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwLCBtYXhGZWVQZXJHYXM6IDEwIH0sXG4gICAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnQ6ICc0MicsXG4gICAgICAgICAgICAgIGFkZHJlc3M6ICcweGM5M2IxMzY0MmQ5M2I0MjE4YmI4NWY2NzMxN2Q2YjM3Mjg2ZTgwMjgnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGV4cGlyZVRpbWU6IDE2Mjc5NDkyMTQsXG4gICAgICAgICAgY29udHJhY3RTZXF1ZW5jZUlkOiAxMixcbiAgICAgICAgICBnYXNMaW1pdDogdW5kZWZpbmVkLFxuICAgICAgICAgIGdhc1ByaWNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgaG9wVHJhbnNhY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgICAgICBiYWNrdXBLZXlOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICAgIHNlcXVlbmNlSWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IHVzZXJLZXljaGFpbi5wcnYsXG4gICAgICB9IGFzIGFueSk7XG5cbiAgICAgIChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4UHJpb3JpdHlGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKDEwKTtcbiAgICAgIChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgxMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYSB0cmFuc2FjdGlvbiB3aXRoIEVJUDE1NTkgZmVlIHBhcmFtcyBmb3IgQ0NSJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBzaWduVHJhbnNhY3Rpb24gPSBzaW5vbi5zcHkoQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMucHJvdG90eXBlLCAnc2lnblRyYW5zYWN0aW9uJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IHtcbiAgICAgICAgcHJ2OiAneHBydjlzMjFaclFIMTQzSzNoZWt5Tmo3VGNpUjRYTlllMWtNajY4VzJpcGpKR05IRVRXUDdvNDJBakRuU1BnS2hkWjR4OE5CQXZhTDcyUnJYanVYTmRta01xTEVSWnphNzNvWXVnR3RiTEZYRzhnJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dCakU1UUc3cGtmOWNaRDMzVVVENks0NnE3RUxyYnVHN0ZxWGZMTkdpWFlHSGVFbkdCYjVBV1JFbmsxZUEyOGc4QXJadlVSYmhzaFhXa1R0ZGRIUm81NGZneVZ2TGRiJyxcbiAgICAgICAgcmF3UHViOiAnMDIzNjM2ZTY4YjdiMjA0NTczYWJkYTI2MTZhZmY2YjU4NDkxMGRlY2UyNTQzZjFjYzZkODQyY2FhYzdkNzQ5NzRiJyxcbiAgICAgICAgcmF3UHJ2OiAnNzQzOGE1MDAxMGNlN2IxZGZkODZlNjgwNDZjYzc4YmExZWJkMjQyZDZkODVkOTkwNGQzZmNjMDg3MzRiYzE3MicsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICBnYXNMaW1pdDogJzEwMDAnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBrZXkgPSB0ZXN0RGF0YS5LRVlQQUlSX1BSVi5nZXRLZXlzKCkucHJ2IGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgICAuYW1vdW50KCcwJylcbiAgICAgICAgLnRvKCcweDE5NjQ1MDMyYzdmMTUzMzM5NWQ0NGE2Mjk0NjJlNzUxMDg0ZDNlNGMnKVxuICAgICAgICAuZXhwaXJhdGlvblRpbWUoMTU5MDA2NjcyOClcbiAgICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZCg1KVxuICAgICAgICAua2V5KGtleSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QoYWRkcmVzczEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhQcmlvcml0eUZlZVBlckdhczogMTAsIG1heEZlZVBlckdhczogMTAgfSxcbiAgICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudDogJzQyJyxcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4YzkzYjEzNjQyZDkzYjQyMThiYjg1ZjY3MzE3ZDZiMzcyODZlODAyOCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZXhwaXJlVGltZTogMTYyNzk0OTIxNCxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IDEyLFxuICAgICAgICAgIGdhc0xpbWl0OiB1bmRlZmluZWQsXG4gICAgICAgICAgZ2FzUHJpY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBob3BUcmFuc2FjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGJhY2t1cEtleU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgc2VxdWVuY2VJZDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgICAgdHhIZXg6IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogdXNlcktleWNoYWluLnBydixcbiAgICAgICAgaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeTogdHJ1ZSxcbiAgICAgIH0gYXMgYW55KTtcblxuICAgICAgYXNzZXJ0KChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCgoaGFsZlNpZ25lZFRyYW5zYWN0aW9uIGFzIGFueSkuaGFsZlNpZ25lZC5laXAxNTU5Lm1heEZlZVBlckdhcywgMTApO1xuXG4gICAgICBzYW5kYm94LmFzc2VydC5jYWxsZWRPbmNlKHNpZ25UcmFuc2FjdGlvbik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBWZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IChjb2luPy5zdGF0aWNzQ29pbj8ubmV0d29yayBhcyBFdGhlcmV1bU5ldHdvcmspLmJhdGNoZXJDb250cmFjdEFkZHJlc3MgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBFTlMgYWRkcmVzcyByZXNvbHV0aW9uIGNoYW5naW5nIHJlY2lwaWVudCBhZGRyZXNzIGluIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAnYml0Z290ZXN0d2FsbGV0LmV0aCcgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICcweDQwYTY2Mzk2MzgxMDQ0OWQ2ZTcyNTMzNjU3YTc0ZjExMmMzYjkwMWEnIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIGhvcCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogMTAwMDAwMDAwMDAwMDAwMCwgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMjc3MzkyODE5NicsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBjbGllbnQgdHhQYXJhbXMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbnVsbDtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCB0eFByZWJ1aWxkIHRoYXQgaXMgYm90aCBiYXRjaCBhbmQgaG9wJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0eCBjYW5ub3QgYmUgYm90aCBhIGJhdGNoIGFuZCBob3AgdHJhbnNhY3Rpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYHRldGggZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBob3AgdHhQcmVidWlsZCB0aGF0IGRvZXMgbm90IHNlbmQgdG8gaXRzIGhvcCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzUwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMCcsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBob3AgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyB0b3RhbCBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzU1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAoY29pbj8uc3RhdGljc0NvaW4/Lm5ldHdvcmsgYXMgRXRoZXJldW1OZXR3b3JrKS5iYXRjaGVyQ29udHJhY3RBZGRyZXNzIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnYmF0Y2ggdHJhbnNhY3Rpb24gYW1vdW50IGluIHR4UHJlYnVpbGQgcmVjZWl2ZWQgZnJvbSBCaXRHbyBzZXJ2ZXJzIGRvZXMgbm90IG1hdGNoIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgYmF0Y2ggdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBkb2VzIG5vdCBzZW5kIHRvIHRoZSBiYXRjaGVyIGNvbnRyYWN0IGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BDb250cmFjdEFkZHJlc3MgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBiYXRjaGVyIGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ25vcm1hbCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnZGVzdGluYXRpb24gYWRkcmVzcyBpbiBub3JtYWwgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGF0IGluIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdG9rZW4gdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGVzdCcpO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB0b2tlbjogJ3Rlc3QnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBjb2luJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ2J0YycsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjb2luIGluIHR4UHJlYnVpbGQgZGlkIG5vdCBtYXRjaCB0aGF0IGluIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVFNTIFRyYW5zYWN0aW9uIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbiB3aGVuIHR4UHJlYnVpbGQgaGFzIGNvbnNvbGlkYXRlSWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyB0eFBhcmFtcyB3aXRob3V0IHJlY2lwaWVudHMgKGFzIGluIGNvbnNvbGlkYXRpb24gZmxvdylcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIHR4UHJlYnVpbGQgd2l0aCBjb25zb2xpZGF0ZUlkIChzZXQgYnkgc2VydmVyIGR1cmluZyBjb25zb2xpZGF0aW9uIGJ1aWxkKVxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aGVuIHR4UGFyYW1zLnR5cGUgaXMgY29uc29saWRhdGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdoZW4gdHhQYXJhbXMucHJlYnVpbGRUeCBoYXMgY29uc29saWRhdGVJZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgcHJlYnVpbGRUeDoge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgVFNTIHRyYW5zYWN0aW9uIHdpdGhvdXQgcmVjaXBpZW50cywgY29uc29saWRhdGVJZCwgb3IgdmFsaWQgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgdHhQYXJhbXMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGFjY2VsZXJhdGlvbiB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICdhY2NlbGVyYXRpb24nLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgdHJhbnNhY3Rpb24gd2l0aCBmaWxsTm9uY2UgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZmlsbE5vbmNlJyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdpdGggZGVmaUFwcHJvdmUgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIERlRmkgZGVwb3NpdCBmbG93IGlzIGludGVudC1iYXNlZDogcmVjaXBpZW50cy9jYWxsZGF0YSBhcmUgYnVpbHQgc2VydmVyLXNpZGVcbiAgICAgIC8vIGZyb20gZGVmaVBhcmFtcywgc28gdHhQYXJhbXMgaGFzIG5vIHJlY2lwaWVudHMgKHNlZSBDR0QtMTgxNSkuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogJ2RlZmlBcHByb3ZlJyxcbiAgICAgICAgZGVmaVBhcmFtczogeyB2YXVsdElkOiAnaHRldGgtdXNkYy10ZXN0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGRlZmlEZXBvc2l0IHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogJ2RlZmlEZXBvc2l0JyxcbiAgICAgICAgZGVmaVBhcmFtczogeyB2YXVsdElkOiAnaHRldGgtdXNkYy10ZXN0JywgYW1vdW50OiAnMTAnLCBvcGVyYXRpb25JZDogJ2Zha2VPcGVyYXRpb25JZCcgfSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzIHZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGNvbnNvbGlkYXRpb24gd2hlbiByZWNpcGllbnQgbWF0Y2hlcyBiYXNlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuXG4gICAgICAgIC8vIEJ1aWxkIGEgcmVhbCB0cmFuc2FjdGlvbiB0aGF0IHNlbmRzIHRvIHRoZSBiYXNlQWRkcmVzc1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNpbmdsZVNpZ1NlbmQpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgICBmZWU6ICcxMCcsXG4gICAgICAgICAgZ2FzTGltaXQ6ICcyMTAwMCcsXG4gICAgICAgIH0pO1xuICAgICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KGJhc2VBZGRyZXNzKTtcbiAgICAgICAgdHhCdWlsZGVyLnZhbHVlKCcxMDAwMDAwMDAwMDAwMDAwMDAwJyk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgICB0eEhleDogdHhIZXgsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgY29uc29saWRhdGlvbiB3aGVuIHJlY2lwaWVudCBkb2VzIG5vdCBtYXRjaCBiYXNlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgICBjb25zdCB3cm9uZ1JlY2lwaWVudCA9ICcweDdlODViZGMyN2MwNTBlMzkwNWViZjRiOGU2MzRkOWFkNmVkZDBkZTYnO1xuXG4gICAgICAgIC8vIEJ1aWxkIGEgdHJhbnNhY3Rpb24gdGhhdCBzZW5kcyB0byBhIERJRkZFUkVOVCBhZGRyZXNzIChub3QgYmFzZUFkZHJlc3MpXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2luZ2xlU2lnU2VuZCk7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwJyxcbiAgICAgICAgICBnYXNMaW1pdDogJzIxMDAwJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3Qod3JvbmdSZWNpcGllbnQpO1xuICAgICAgICB0eEJ1aWxkZXIudmFsdWUoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgICB0eXBlOiAnY29uc29saWRhdGUnLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICAgIHR4SGV4OiB0eEhleCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHJlY2lwaWVudCBkb2VzIG5vdCBtYXRjaCB3YWxsZXQgYmFzZSBhZGRyZXNzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHR4SGV4IGlzIG1pc3NpbmcgZm9yIGNvbnNvbGlkYXRpb24gdmVyaWZpY2F0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgICAvLyBJbnRlbnRpb25hbGx5IG1pc3NpbmcgdHhIZXhcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHR4SGV4IGluIHR4UHJlYnVpbGQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBFUkMyMCB0b2tlbiBjb25zb2xpZGF0aW9uIHdoZW4gY2FsbGRhdGEgcmVjaXBpZW50IG1hdGNoZXMgYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJlc3MgPSAnMHhhMGI4Njk5MWM2MjE4YjM2YzFkMTlkNGEyZTllYjBjZTM2MDZlYjQ4JztcblxuICAgICAgICAvLyBCdWlsZCBhbiBFUkMyMCB0cmFuc2ZlcihhZGRyZXNzLCB1aW50MjU2KSB0eCDigJQgbWltaWNzIHdoYXQgdGhlIHNlcnZlciByZXR1cm5zXG4gICAgICAgIC8vIGZvciBhIHY2IFRTUyB3YWxsZXQgdG9rZW4gY29uc29saWRhdGlvbjogdHhKc29uLnRvID0gdG9rZW4gY29udHJhY3QsXG4gICAgICAgIC8vIGFjdHVhbCByZWNpcGllbnQgaXMgZW5jb2RlZCBpbiB0aGUgMHhhOTA1OWNiYiBjYWxsZGF0YVxuICAgICAgICBjb25zdCBtZXRob2RJZCA9IEV0aGVyZXVtQWJpLm1ldGhvZElEKCd0cmFuc2ZlcicsIFsnYWRkcmVzcycsICd1aW50MjU2J10pO1xuICAgICAgICBjb25zdCBlbmNvZGVkUGFyYW1zID0gRXRoZXJldW1BYmkucmF3RW5jb2RlKFsnYWRkcmVzcycsICd1aW50MjU2J10sIFtiYXNlQWRkcmVzcywgJzEwMDAwMDAwJ10pO1xuICAgICAgICBjb25zdCBlcmMyMFRyYW5zZmVyRGF0YSA9ICcweCcgKyBCdWZmZXIuY29uY2F0KFttZXRob2RJZCwgZW5jb2RlZFBhcmFtc10pLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCk7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMCcsIGdhc0xpbWl0OiAnNjAwMDAnIH0pO1xuICAgICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KHRva2VuQ29udHJhY3RBZGRyZXNzKTtcbiAgICAgICAgdHhCdWlsZGVyLmRhdGEoZXJjMjBUcmFuc2ZlckRhdGEpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzcyB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogeyB0eXBlOiAnY29uc29saWRhdGUnLCB3YWxsZXQsIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlJyB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IGNvbnNvbGlkYXRlSWQ6ICdhYmMxMjMnLCB0eEhleCwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHsgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUgfSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgRVJDMjAgdG9rZW4gY29uc29saWRhdGlvbiB3aGVuIGNhbGxkYXRhIHJlY2lwaWVudCBkb2VzIG5vdCBtYXRjaCBiYXNlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgICBjb25zdCB3cm9uZ1JlY2lwaWVudCA9ICcweDdlODViZGMyN2MwNTBlMzkwNWViZjRiOGU2MzRkOWFkNmVkZDBkZTYnO1xuICAgICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweGEwYjg2OTkxYzYyMThiMzZjMWQxOWQ0YTJlOWViMGNlMzYwNmViNDgnO1xuXG4gICAgICAgIC8vIEJ1aWxkIGFuIEVSQzIwIHRyYW5zZmVyIHdoZXJlIGNhbGxkYXRhIHJlY2lwaWVudCBpcyBhIFdST05HIGFkZHJlc3NcbiAgICAgICAgY29uc3QgbWV0aG9kSWQgPSBFdGhlcmV1bUFiaS5tZXRob2RJRCgndHJhbnNmZXInLCBbJ2FkZHJlc3MnLCAndWludDI1NiddKTtcbiAgICAgICAgY29uc3QgZW5jb2RlZFBhcmFtcyA9IEV0aGVyZXVtQWJpLnJhd0VuY29kZShbJ2FkZHJlc3MnLCAndWludDI1NiddLCBbd3JvbmdSZWNpcGllbnQsICcxMDAwMDAwMCddKTtcbiAgICAgICAgY29uc3QgZXJjMjBUcmFuc2ZlckRhdGEgPSAnMHgnICsgQnVmZmVyLmNvbmNhdChbbWV0aG9kSWQsIGVuY29kZWRQYXJhbXNdKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAnLCBnYXNMaW1pdDogJzYwMDAwJyB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdCh0b2tlbkNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci5kYXRhKGVyYzIwVHJhbnNmZXJEYXRhKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3MgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogeyB0eXBlOiAnY29uc29saWRhdGUnLCB3YWxsZXQsIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlJyB9IGFzIGFueSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHsgY29uc29saWRhdGVJZDogJ2FiYzEyMycsIHR4SGV4LCBjb2luOiAnaHRldGgnLCB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcgfSBhcyBhbnksXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb246IHsgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUgfSxcbiAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24gcmVjaXBpZW50IGRvZXMgbm90IG1hdGNoIHdhbGxldCBiYXNlIGFkZHJlc3MnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gd2FsbGV0IGlzIG1pc3NpbmcgYmFzZUFkZHJlc3MgZm9yIGNvbnNvbGlkYXRpb24gdmVyaWZpY2F0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcblxuICAgICAgICAvLyBCdWlsZCBhIHJlYWwgdHJhbnNhY3Rpb25cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICAgIGdhc0xpbWl0OiAnMjEwMDAnLFxuICAgICAgICB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdChiYXNlQWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci52YWx1ZSgnMTAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgICAgLy8gV2FsbGV0IHdpdGhvdXQgYmFzZUFkZHJlc3NcbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgdHhIZXg6IHR4SGV4LFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1VuYWJsZSB0byBkZXRlcm1pbmUgYmFzZSBhZGRyZXNzIGZvciBjb25zb2xpZGF0aW9uJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZHJlc3MgVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGRlc2NyaWJlKCdpc1dhbGxldEFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBhZGRyZXNzIGdlbmVyYXRlZCB1c2luZyBmb3J3YXJkZXIgdmVyc2lvbiAxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjM4ZjFkM2M5ZmNlOGY1YWE2OTE1NjlhOTllYicsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR1ZiM1BmQ3p3aUVYOTRBQjFuSlF0elZtc2E1U3JpTnJmS1paQWNBdlJneGgxQXVnbTZzOHlvRDhnU2txMkZkWjhZQ2RWWFVnTGpmOVF4dmRZQUpLNVV0aEFtcFFzaFUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjM4ZjBiNzRlNzNiMWY0NDBlYTRhY2VkYTg3ZScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGNDZwUkhkYTNzWmJ1UHp6YTlBOU1pcUFVOUpSb2Q4aHVZdHlWNE5ZMm9lSlhzaXM3cjI2TDF2bUxudGY5QmNaSmUxbTRDUU5TdllXZndwZTFoU3BvNko0eDZZRjFlTicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY4YjllYzU4N2QwYmExYzc0NDBkZTU1MTA2OGMzNmE3JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR3pUbjVleU5HRGtiMThSNDNuSDc5SG9rWUxjNVBYWk0xOVY4VXJidUxkVlJhQ1FNczRFZUNBam5xbW9ZWHFmeXVzVFU0NldvWk1EeUxwbVR6b1VYNjZaQndHRmp0MWEnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweDYwNjlhNGJhZjIzNjBiZjY3YTZkMDJhN2ZjNDNkOGYzOTEwMDE2YWUnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhlMTI1M2JjY2U3ZDg3ZGI1MjJmYmNlZWM2ZTU1YzlmNzhjMzc2ZDlmJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweDcnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogNyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSk7XG4gICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gYWRkcmVzcyBnZW5lcmF0ZWQgdXNpbmcgZm9yd2FyZGVyIHZlcnNpb24gMicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZThjN2IzYzhhYWE3OTExMThkOWNlNjE2ZDNiMjEnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dyQ3hDWDM5emIzVHZZalRxZlVHd0VVWkhqbnJhUkZtMVdlTXc5Z2ZDRDF3d2Myd1VEbUJCWjJUa2NjSk13ZjVlQlRqYThyM3o2SE14b1RaR1c2bnZ5b0pNUUZzZWN2JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZThjN2IxOTY3ZmQ2ZDk4NjdhMjJhMWE0MTMxYTAnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0toZGVDNG5yMXRhOGQyN3hUaHRmRkZIZ2J4V01yVmI1OTVtZU1TOGkzZkJNclR6OEVkUU1XQktISEt6eGFwR2doZW9NeW1WdlJjUW1hR0R5a1JUQmJ0WHFiaXU5cHMnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhva1lMYzVQWFpNMTlWOFVyYnVMZFZSYUNRTXM0RWVDQWpucW1vWVhxZnl1c1RVNDZXb1pNRHlMcG1Uem9VWDY2WkJ3R0ZqdDFhJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhmNjM2Y2VkZGZmZTQxZDEwNjU4Njg3NWMwZTU2ZGM4ZmViNjI2OGY3JyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGM0ODVkYTA3NmVkNGEyYjE5NTg0ZTlhMWZkYmI5NzRmODliNjBmNCcsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHgxNycsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAyLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgIGluZGV4OiAyMyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAyLFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSk7XG4gICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB3YWxsZXQgdmVyc2lvbiA1IGZvcndhcmRlciB2ZXJzaW9uIDQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFlMjQyZDkzZjhkN2FkMDcwNTg4NzQ0OTc2M2M5NicsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZTI0MmRmOGI2MzIzZDRiMDhkZjM2Njg2NGFmNjYnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZTI0MmMwNTk1YjRjZmVlNmY5NTdjMWQ2NDU4ZjcnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGQ2M2I1ZTJiOGQxYjRmYmEzNjI1NDYwNTA4OTAwYmYyYTA0OTlhNGQnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweDc1JyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMTE3LFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgd2FsbGV0IHZlcnNpb24gNiBmb3J3YXJkZXIgdmVyc2lvbiA1JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzMGUwYzU2MDk4Mjg4YTliN2ZhMTA3ZGIxNDQnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWY2MzBkNTY3MzVlNWViNjFiMDZlMzUzZmU3NjM5JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhhMzNmMDk3NWY1M2NkY2ZjYzBjYjU2NGQyNWZiNWJlMDNiMDY1MWNmJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBhY3R1YWwgYWRkcmVzcyBkaWZmZXJzIGZyb20gZXhwZWN0ZWQgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweDI4OTA0NTkxZjczNTk5NGYwNTA4MDRmZGEzYjYxYjgxM2IxNmUwNGMnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgc2FsdDogJzB4YzVhJyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlmIGNvaW5TcGVjaWZpYyBmaWVsZCBpcyBub3QgYW4gb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGIwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThlNmQnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMgYXMgYW55KSxcbiAgICAgICAgICBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3JcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiB0aGUgZGVyaXZlZCBhZGRyZXNzIGlzIGluIGludmFsaWQgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGUwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThidmYnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBiYXNlIGFkZHJlc3MgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGIwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThlNmQnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgc2FsdDogJzB4YzVhJyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMgYXMgYW55KSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgYmFzZSBhZGRyZXNzIGlzIGluIGludmFsaWQgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGIwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThlNmQnLFxuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhlMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4YnZmJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnTVBDIHdhbGxldCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgICAnMDNmOWMyZmIyZTVhOGI3OGE0NGY1ZDFlNGY5MDZmOGUzZDdhMGU2YjVjNGQzZTJmMWEwYjljOGQ3ZTZmNWE0YjNjMmQxZTBmOWU4ZDdjNmI1YTQnICtcbiAgICAgICAgICAnOTM4MjcxNjA1OTQ4NTc0NjM3MjgxOTBhMGIwYzBkMGUwZjEwMTExMjEzMTQxNTE2MTcxODE5MWExYjFjMWQxZTFmJztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHsgcHViOiAndXNlcl9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYmFja3VwX3B1YicsIGNvbW1vbktleWNoYWluIH0sXG4gICAgICAgICAgeyBwdWI6ICdiaXRnb19wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFuIE1QQyB3YWxsZXQgYWRkcmVzcyB3aXRoIGZvcndhcmRlciB2ZXJzaW9uIDMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4MDExNTNmM2FkZmU0NTRhNzI1ODljYTllZjc0ZjAxM2MxOWU1NDk2MScsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBNUEMgd2FsbGV0IGFkZHJlc3Mgd2l0aCBmb3J3YXJkZXIgdmVyc2lvbiA1JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDAxMTUzZjNhZGZlNDU0YTcyNTg5Y2E5ZWY3NGYwMTNjMTllNTQ5NjEnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggd3JvbmcgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBNUEMgd2FsbGV0IGFkZHJlc3Mgd2l0aCBpbnZhbGlkIGFkZHJlc3MgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweGludmFsaWQnLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIEludmFsaWRBZGRyZXNzRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBrZXljaGFpbnMgYXJlIG1pc3NpbmcgZm9yIE1QQyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4OWU3Y2U4YzI0ZDlmNzZhODE0ZTIzNjMzZTYxYmU3Y2I4ZTZlMmQ1ZScsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpLCBFcnJvcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlmIGNvbW1vbktleWNoYWluIGlzIG1pc3NpbmcgZm9yIE1QQyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgaW52YWxpZEtleWNoYWlucyA9IFt7IHB1YjogJ3VzZXJfcHViJyB9LCB7IHB1YjogJ2JhY2t1cF9wdWInIH0sIHsgcHViOiAnYml0Z29fcHViJyB9XTtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDllN2NlOGMyNGQ5Zjc2YTgxNGUyMzYzM2U2MWJlN2NiOGU2ZTJkNWUnLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zOiBpbnZhbGlkS2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIEVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ2Rlcml2ZUFkZHJlc3MgKE1QQyknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFNhbWUgdmVjdG9yIGFzIHRoZSBNUEMgaXNXYWxsZXRBZGRyZXNzIHRlc3RzIGFib3ZlOlxuICAgICAgICAvLyBjb21tb25LZXljaGFpbiBAIGluZGV4IDAgLT4gMHgwMTE1M2YzYWRmZTQ1NGE3MjU4OWNhOWVmNzRmMDEzYzE5ZTU0OTYxXG4gICAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID1cbiAgICAgICAgICAnMDNmOWMyZmIyZTVhOGI3OGE0NGY1ZDFlNGY5MDZmOGUzZDdhMGU2YjVjNGQzZTJmMWEwYjljOGQ3ZTZmNWE0YjNjMmQxZTBmOWU4ZDdjNmI1YTQnICtcbiAgICAgICAgICAnOTM4MjcxNjA1OTQ4NTc0NjM3MjgxOTBhMGIwYzBkMGUwZjEwMTExMjEzMTQxNTE2MTcxODE5MWExYjFjMWQxZTFmJztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHsgcHViOiAndXNlcl9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYmFja3VwX3B1YicsIGNvbW1vbktleWNoYWluIH0sXG4gICAgICAgICAgeyBwdWI6ICdiaXRnb19wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZGVyaXZlIHRoZSBleHBlY3RlZCBNUEMgYWRkcmVzcyBmb3IgYSBjb21tb25LZXljaGFpbiBhdCBpbmRleCAwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb2luLmRlcml2ZUFkZHJlc3MoeyBrZXljaGFpbnMsIGluZGV4OiAwLCB3YWxsZXRWZXJzaW9uOiAzIH0pO1xuICAgICAgICAgIHJlc3VsdC5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMHgwMTE1M2YzYWRmZTQ1NGE3MjU4OWNhOWVmNzRmMDEzYzE5ZTU0OTYxJyk7XG4gICAgICAgICAgcmVzdWx0LmluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LmRlcml2YXRpb25QYXRoLCAnbS8wJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdyb3VuZC10cmlwcyB3aXRoIGlzV2FsbGV0QWRkcmVzcyAoZGVyaXZlZCBhZGRyZXNzIHZlcmlmaWVzIGFzIHRydWUpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgICAgICBjb25zdCBkZXJpdmVkID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHsga2V5Y2hhaW5zLCBpbmRleDogMywgd2FsbGV0VmVyc2lvbjogNiB9KTtcbiAgICAgICAgICBjb25zdCB2ZXJpZmllZCA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGRlcml2ZWQuYWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiA1IH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zKTtcbiAgICAgICAgICB2ZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBuZWl0aGVyIE1QQyBub3IgZm9yd2FyZGVyIGlucHV0cyBhcmUgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgICAgIC8vIHdhbGxldFZlcnNpb24gMSB3aXRoIG5vIGNvaW5TcGVjaWZpYy5mb3J3YXJkZXJWZXJzaW9uIGFuZCBubyBiYXNlQWRkcmVzcyBpcyBhbWJpZ3VvdXNcbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICAgIGFzeW5jICgpID0+IGNvaW4uZGVyaXZlQWRkcmVzcyh7IGtleWNoYWlucywgaW5kZXg6IDAsIHdhbGxldFZlcnNpb246IDEgfSksXG4gICAgICAgICAgICAvY291bGQgbm90IGRldGVybWluZSBhbiBFVEggZGVyaXZhdGlvbiBzdHJhdGVneS9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IGlmIGtleWNoYWlucyBhcmUgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmRlcml2ZUFkZHJlc3MoeyBrZXljaGFpbnM6IFtdLCBpbmRleDogMCwgd2FsbGV0VmVyc2lvbjogMyB9KSxcbiAgICAgICAgICAgIC9rZXljaGFpbnMvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ2Rlcml2ZUFkZHJlc3MgKGZvcndhcmRlciknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFNhbWUgdmVjdG9ycyBhcyB0aGUgZm9yd2FyZGVyIGlzV2FsbGV0QWRkcmVzcyB0ZXN0cyBhYm92ZSAoY29pbjogaHRldGgpLlxuICAgICAgICAvLyBzYWx0ID09IGluZGV4IGZvciBCaXRHbyBmb3J3YXJkZXJzLCBzbyBkZXJpdmluZyBieSBpbmRleCByZXByb2R1Y2VzIHRoZSBhZGRyZXNzLlxuICAgICAgICBpdCgnZGVyaXZlcyB0aGUgZXhhY3QgdjEgZm9yd2FyZGVyIGFkZHJlc3MgYW5kIHJvdW5kLXRyaXBzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4ZTEyNTNiY2NlN2Q4N2RiNTIyZmJjZWVjNmU1NWM5Zjc4YzM3NmQ5Zic7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHtcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7IGZvcndhcmRlclZlcnNpb246IDEgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXN1bHQuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4NjA2OWE0YmFmMjM2MGJmNjdhNmQwMmE3ZmM0M2Q4ZjM5MTAwMTZhZScpO1xuXG4gICAgICAgICAgY29uc3QgdmVyaWZpZWQgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgICAgICBhZGRyZXNzOiByZXN1bHQuYWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7IHNhbHQ6ICcweDcnLCBmb3J3YXJkZXJWZXJzaW9uOiAxIH0sXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zKTtcbiAgICAgICAgICB2ZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdkZXJpdmVzIHRoZSBleGFjdCB2MiBmb3J3YXJkZXIgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICAgICAgaW5kZXg6IDIzLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAyIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzdWx0LmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweGY2MzZjZWRkZmZlNDFkMTA2NTg2ODc1YzBlNTZkYzhmZWI2MjY4ZjcnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2Rlcml2ZXMgdGhlIGV4YWN0IHY0IGZvcndhcmRlciBhZGRyZXNzICh3YWxsZXQgdjUsIG5lZWRzIGZlZUFkZHJlc3MpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvaW4uZGVyaXZlQWRkcmVzcyh7XG4gICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgICBpbmRleDogMTE3LFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiA0LCBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3VsdC5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMHhkNjNiNWUyYjhkMWI0ZmJhMzYyNTQ2MDUwODkwMGJmMmEwNDk5YTRkJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd0aHJvd3MgaWYgYmFzZUFkZHJlc3MgaXMgbWlzc2luZyBmb3IgYSBmb3J3YXJkZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmRlcml2ZUFkZHJlc3MoeyBpbmRleDogNywgd2FsbGV0VmVyc2lvbjogMSwgY29pblNwZWNpZmljOiB7IGZvcndhcmRlclZlcnNpb246IDEgfSB9KSxcbiAgICAgICAgICAgIC9iYXNlQWRkcmVzcyBpcyByZXF1aXJlZC9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyb3dzIGlmIGZlZUFkZHJlc3MgaXMgbWlzc2luZyBmb3IgYSB2NCBmb3J3YXJkZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgICAgICBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJyxcbiAgICAgICAgICAgICAgICBpbmRleDogMTE3LFxuICAgICAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7IGZvcndhcmRlclZlcnNpb246IDQgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAvZmVlQWRkcmVzcyBpcyByZXF1aXJlZC9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyb3dzIGZvciBmb3J3YXJkZXIgdmVyc2lvbiAwIChub3QgZGVyaXZhYmxlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICAgIGFzeW5jICgpID0+XG4gICAgICAgICAgICAgIGNvaW4uZGVyaXZlQWRkcmVzcyh7XG4gICAgICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGUxMjUzYmNjZTdkODdkYjUyMmZiY2VlYzZlNTVjOWY3OGMzNzZkOWYnLFxuICAgICAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDEsXG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7IGZvcndhcmRlclZlcnNpb246IDAgfSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAvdmVyc2lvbiAwIGFkZHJlc3NlcyBjYW5ub3QgYmUgZGVyaXZlZC9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnQmFzZSBBZGRyZXNzIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmFzZSBhZGRyZXNzIGZvciB3YWxsZXQgdmVyc2lvbiA2IChUU1MpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGQ1NjczNWU1ZWI2MWIwNmUzNTNmZTc2MzknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDUsXG4gICAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gNSAoVFNTKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlMjQyZDkzZjhkN2FkMDcwNTg4NzQ0OTc2M2M5NicsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlMjQyZGY4YjYzMjNkNGIwOGRmMzY2ODY0YWY2NicsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWUyNDJjMDU5NWI0Y2ZlZTZmOTU3YzFkNjQ1OGY3JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJztcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBiYXNlIGFkZHJlc3MgdmVyaWZpY2F0aW9uIHdpdGggbm9uLXplcm8gaW5kZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGUwYzU2MDk4Mjg4YTliN2ZhMTA3ZGIxNDQnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGYxZDNjOWZjZThmNWE3MzBiZmY4MjZjZjknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NSc7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDUsIC8vIFdyb25nIGluZGV4IC0gc2hvdWxkIGJlIDAgZm9yIGJhc2UgYWRkcmVzc1xuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICAgIGFzeW5jICgpID0+IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksXG4gICAgICAgICAgICAvQmFzZSBhZGRyZXNzIHZlcmlmaWNhdGlvbiByZXF1aXJlcyBpbmRleCAwLCBidXQgZ290IGluZGV4IDUvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYmFzZSBhZGRyZXNzIHZlcmlmaWNhdGlvbiB3aXRoIHdyb25nIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGUwYzU2MDk4Mjg4YTliN2ZhMTA3ZGIxNDQnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGYxZDNjOWZjZThmNWE3MzBiZmY4MjZjZjknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICcweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEnO1xuICAgICAgICAgIGNvbnN0IGFjdHVhbEJhc2VBZGRyZXNzID0gJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NSc7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiB3cm9uZ0FkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYWN0dWFsQmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDUsXG4gICAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBiYXNlIGFkZHJlc3MgZm9yIHdhbGxldCB2ZXJzaW9uIDIgKEJJUDMyKSB1c2luZyB3YWxsZXQgZmFjdG9yeScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4ZGM0ODVkYTA3NmVkNGEyYjE5NTg0ZTlhMWZkYmI5NzRmODliNjBmNCc7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0U2FsdCA9ICcweDInO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWU4YzdiM2M4YWFhNzkxMTE4ZDljZTYxNmQzYjIxJyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweDlkMTZiYjg2N2I3OTJjNWUzYmY2MzZhMDI3NWYyZGI4NjAxYmQ3ZDQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlOGM3YjE5NjdmZDZkOTg2N2EyMmExYTQxMzFhMCcsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweDJkZmNlNWNmZWI1YzAzZmJlNjgwY2QzOWFjMGQyYjI1Mzk5YjdkMjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiB3YWxsZXRTYWx0LFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWluczoga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAyLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmFzZSBhZGRyZXNzIGZvciB3YWxsZXQgdmVyc2lvbiAxIChCSVAzMikgdXNpbmcgd2FsbGV0IGZhY3RvcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGUxMjUzYmNjZTdkODdkYjUyMmZiY2VlYzZlNTVjOWY3OGMzNzZkOWYnO1xuICAgICAgICAgIGNvbnN0IHdhbGxldFNhbHQgPSAnMHg1JztcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjM4ZjFkM2M5ZmNlOGY1YWE2OTE1NjlhOTllYicsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHhmNDVkYWRjZTc1MWEzMTc5NTdmMmEyNDdmZjM3Y2I3NjRiOTc2MjBkJyxcbiAgICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dWYjNQZkN6d2lFWDk0QUIxbkpRdHpWbS4uLicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzhmMGI3NGU3M2IxZjQ0MGVhNGFjZWRhODdlJyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4NWJkZjNhZTFkMmMyZmFkZWViNzBhNDU4NzJiZjRmNDI1MjMxMmI1NScsXG4gICAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGNDZwUkhkYTNzWmJ1UHp6YTlBOU1pcUEuLi4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2suLi4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogd2FsbGV0U2FsdCxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnM6IGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGRyZXNzIENyZWF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcGFzcyB3YWxsZXRWZXJzaW9uIDYgdG8gaXNXYWxsZXRBZGRyZXNzIGR1cmluZyBhZGRyZXNzIGNyZWF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWNiA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjYgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjYpO1xuICAgICAgY29uc3QgaXNXYWxsZXRBZGRyZXNzU3B5ID0gc2lub24uc3B5KGV0aENvaW4sICdpc1dhbGxldEFkZHJlc3MnKTtcblxuICAgICAgLy8gTW9jayBrZXljaGFpbiByZXF1ZXN0c1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGc1hTaFc4UjNoSnNITlRZVFV3emNlam5Ma1k3S0N0YUpiRHFjR2tjQkY5OUJyRUpTak5aSGVIdmVpWVVyc0Fkd25qVU1Hd3BnbUViaUtjWldSdVZBOUh4blJhQTNyMycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGFkZHJlc3MgY3JlYXRpb24gQVBJXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXRWNi5pZCgpfS9hZGRyZXNzYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0OiBldGhXYWxsZXRWNi5pZCgpLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNCxcbiAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFY2LmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCB9KTtcblxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3B5LmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGNvbnN0IGNhbGxlZFBhcmFtcyA9IGlzV2FsbGV0QWRkcmVzc1NweS5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIGNhbGxlZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0VmVyc2lvbicsIDYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXNzIHdhbGxldFZlcnNpb24gNSB0byBpc1dhbGxldEFkZHJlc3MgZHVyaW5nIGFkZHJlc3MgY3JlYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGNvbnN0IGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YVY1ID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGYxZTNkMzA3OThhY2RmM2ExMmZhNWJlYjVmYWQ4ZWZiMjNkNWJlMTEnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBldGhXYWxsZXRWNSA9IG5ldyBXYWxsZXQoYml0Z28sIGV0aENvaW4sIHdhbGxldERhdGFWNSk7XG4gICAgICBjb25zdCBpc1dhbGxldEFkZHJlc3NTcHkgPSBzaW5vbi5zcHkoZXRoQ29pbiwgJ2lzV2FsbGV0QWRkcmVzcycpO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIHJlcXVlc3RzXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkN2ApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgYWRkcmVzcyBjcmVhdGlvbiBBUElcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldFY1LmlkKCl9L2FkZHJlc3NgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogJzB4ZDYzYjVlMmI4ZDFiNGZiYTM2MjU0NjA1MDg5MDBiZjJhMDQ5OWE0ZCcsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldDogZXRoV2FsbGV0VjUuaWQoKSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICBzYWx0OiAnMHg3NScsXG4gICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgYXdhaXQgZXRoV2FsbGV0VjUuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwIH0pO1xuXG4gICAgICAvLyBWZXJpZnkgaXNXYWxsZXRBZGRyZXNzIHdhcyBjYWxsZWQgd2l0aCB3YWxsZXRWZXJzaW9uIDVcbiAgICAgIGlzV2FsbGV0QWRkcmVzc1NweS5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjb25zdCBjYWxsZWRQYXJhbXMgPSBpc1dhbGxldEFkZHJlc3NTcHkuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBjYWxsZWRQYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFZlcnNpb24nLCA1KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyB3YWxsZXRWZXJzaW9uIDIgdG8gaXNXYWxsZXRBZGRyZXNzIGR1cmluZyBhZGRyZXNzIGNyZWF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWMiA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkYzQ4NWRhMDc2ZWQ0YTJiMTk1ODRlOWExZmRiYjk3NGY4OWI2MGY0JyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAyLFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZGM0ODVkYTA3NmVkNGEyYjE5NTg0ZTlhMWZkYmI5NzRmODliNjBmNCcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjIgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjIpO1xuICAgICAgY29uc3QgaXNXYWxsZXRBZGRyZXNzU3B5ID0gc2lub24uc3B5KGV0aENvaW4sICdpc1dhbGxldEFkZHJlc3MnKTtcblxuICAgICAgLy8gTW9jayBrZXljaGFpbiByZXF1ZXN0c1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dyQ3hDWDM5emIzVHZZalRxZlVHd0VVWkhqbnJhUkZtMVdlTXc5Z2ZDRDF3d2Myd1VEbUJCWjJUa2NjSk13ZjVlQlRqYThyM3o2SE14b1RaR1c2bnZ5b0pNUUZzZWN2JyxcbiAgICAgICAgZXRoQWRkcmVzczogJzB4OWQxNmJiODY3Yjc5MmM1ZTNiZjYzNmEwMjc1ZjJkYjg2MDFiZDdkNCcsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0toZGVDNG5yMXRhOGQyN3hUaHRmRkZIZ2J4V01yVmI1OTVtZU1TOGkzZkJNclR6OEVkUU1XQktISEt6eGFwR2doZW9NeW1WdlJjUW1hR0R5a1JUQmJ0WHFiaXU5cHMnLFxuICAgICAgICBldGhBZGRyZXNzOiAnMHgyZGZjZTVjZmViNWMwM2ZiZTY4MGNkMzlhYzBkMmIyNTM5OWI3ZDIyJyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkN2ApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhva1lMYzVQWFpNMTlWOFVyYnVMZFZSYUNRTXM0RWVDQWpucW1vWVhxZnl1c1RVNDZXb1pNRHlMcG1Uem9VWDY2WkJ3R0ZqdDFhJyxcbiAgICAgICAgZXRoQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGFkZHJlc3MgY3JlYXRpb24gQVBJXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXRWMi5pZCgpfS9hZGRyZXNzYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGY2MzZjZWRkZmZlNDFkMTA2NTg2ODc1YzBlNTZkYzhmZWI2MjY4ZjcnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAyMyxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldDogZXRoV2FsbGV0VjIuaWQoKSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDIsXG4gICAgICAgICAgICBzYWx0OiAnMHgxNycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFYyLmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCB9KTtcblxuICAgICAgLy8gVmVyaWZ5IGlzV2FsbGV0QWRkcmVzcyB3YXMgY2FsbGVkIHdpdGggd2FsbGV0VmVyc2lvbiAyXG4gICAgICBpc1dhbGxldEFkZHJlc3NTcHkuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgY29uc3QgY2FsbGVkUGFyYW1zID0gaXNXYWxsZXRBZGRyZXNzU3B5LmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgY2FsbGVkUGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRWZXJzaW9uJywgMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdjYgYWRkcmVzcyBjcmVhdGlvbiBpZiB3YWxsZXRWZXJzaW9uIHdhcyBub3QgcGFzc2VkIChzaW11bGF0ZXMgb2xkIGJ1ZyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGNvbnN0IGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YVY2ID0ge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgIH0sXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIGtleXM6IFtcbiAgICAgICAgICAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICAgICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgICAgJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgXSxcbiAgICAgICAgcmVjZWl2ZUFkZHJlc3M6IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBldGhXYWxsZXRWNiA9IG5ldyBXYWxsZXQoYml0Z28sIGV0aENvaW4sIHdhbGxldERhdGFWNik7XG5cbiAgICAgIC8vIFN0dWIgaXNXYWxsZXRBZGRyZXNzIHRvIHNpbXVsYXRlIHRoZSBPTEQgYnVnIHdoZXJlIHdhbGxldFZlcnNpb24gd2FzIG5vdCBwYXNzZWRcbiAgICAgIGNvbnN0IG9yaWdpbmFsSXNXYWxsZXRBZGRyZXNzID0gZXRoQ29pbi5pc1dhbGxldEFkZHJlc3MuYmluZChldGhDb2luKTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1N0dWIgPSBzaW5vbi5zdHViKGV0aENvaW4sICdpc1dhbGxldEFkZHJlc3MnKS5jYWxsc0Zha2UoYXN5bmMgKHBhcmFtcykgPT4ge1xuICAgICAgICAvLyBSZW1vdmUgd2FsbGV0VmVyc2lvbiB0byBzaW11bGF0ZSB0aGUgb2xkIGJ1Z1xuICAgICAgICBjb25zdCBwYXJhbXNXaXRob3V0V2FsbGV0VmVyc2lvbiA9IHsgLi4ucGFyYW1zIH07XG4gICAgICAgIGRlbGV0ZSAocGFyYW1zV2l0aG91dFdhbGxldFZlcnNpb24gYXMgYW55KS53YWxsZXRWZXJzaW9uO1xuICAgICAgICByZXR1cm4gb3JpZ2luYWxJc1dhbGxldEFkZHJlc3MocGFyYW1zV2l0aG91dFdhbGxldFZlcnNpb24pO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRnNYU2hXOFIzaEpzSE5UWVRVd3pjZWpuTGtZN0tDdGFKYkRxY0drY0JGOTlCckVKU2pOWkhlSHZlaVlVcnNBZHdualVNR3dwZ21FYmlLY1pXUnVWQTlIeG5SYUEzcjMnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjYuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldDogZXRoV2FsbGV0VjYuaWQoKSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBXaXRob3V0IHdhbGxldFZlcnNpb24sIGFkZHJlc3MgY3JlYXRpb24gc2hvdWxkIGZhaWwgYmVjYXVzZVxuICAgICAgLy8gdGhlIGNvZGUgZG9lc24ndCBrbm93IHRvIHVzZSBUU1MgdmVyaWZpY2F0aW9uIGZvciB2NiB3YWxsZXRzXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBldGhXYWxsZXRWNi5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSksIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IpO1xuXG4gICAgICBpc1dhbGxldEFkZHJlc3NTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0VWTSBDcm9zcyBDaGFpbiBSZWNvdmVyeScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgIGl0KCdzaG91bGQgYnVpbGQgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAne1wiaXZcIjpcIlZGWjNqdlhoeG8xWitZYWYyTXRabkE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICc1M1BCbENkZTVLWlJtbFVLS0hMdERNaytISmZ1VTQ2aFcreCtDOVdzSUFPNGdGUG5UQ3ZGVm1ROHg3Y3pDdGNORnViNUFPMm90T0dcXG4nICtcbiAgICAgICAgJ09zWDRHRTJnWE9FbUNsMVRwV3d3TmhtN3lNVWpHSlVwZ1c2WlpnWFNYZERpdFNLaTRWL2hrNzhTR1N6akZPQlNQWVJhNkk9XCJ9XFxuJztcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1QURkRTE3ZmVEOGJhZWQzRjMyYjg0QUYwNUI4RjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KHdhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBzcHkgPSBzaW5vbi5zcHkoVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZSwgJ2NvaW5Vc2VzTm9uUGFja2VkRW5jb2RpbmdGb3JUeERhdGEnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBpbnRlbmRlZENoYWluOiAndGFyYmV0aCcsXG4gICAgICB9KTtcbiAgICAgIGFzc2VydChzcHkucmV0dXJuZWQodHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ05vbi1CaXRHbyBSZWNvdmVyeSBmb3IgSG90IFdhbGxldHMgKE1QQ3YyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgICAgIGxldCBiYXNlY29pbjogSHRldGg7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBNUEN2MiBraW5kIG9mIGhvdCB3YWxsZXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLmJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLmJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCk7XG5cbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBwYXJhbXMuYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogcGFyYW1zLmJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIGludGVuZGVkQ2hhaW46IHBhcmFtcy5pbnRlbmRlZENoYWluLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIHVzZXIga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRJbnZhbGlkTm9uQml0R29SZWNvdmVyeVBhcmFtcygpO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogcGFyYW1zLmJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBwYXJhbXMuYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgICAgIGludGVuZGVkQ2hhaW46IHBhcmFtcy5pbnRlbmRlZENoYWluLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAndXNlciBrZXkgaXMgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0J1aWxkIFVuc2lnbmVkIFN3ZWVwIGZvciBTZWxmLUN1c3RvZHkgQ29sZCBXYWxsZXRzIChNUEN2MiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgICAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gICAgICBsZXQgYmFzZWNvaW46IEh0ZXRoO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgc3dlZXAgd2l0aG91dCBkZXJpdmF0aW9uIHNlZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KFxuICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoXG4gICAgICAgICAgICAgIG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIGNvbnN0IHN3ZWVwUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBBIERhdGFcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3Qoc3dlZXBSZXN1bHQpO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBzd2VlcFJlc3VsdCBhcyBVbnNpZ25lZFN3ZWVwVHhNUEN2MjtcbiAgICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29pbicpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc2lnbmVkVHgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXJzZWRUeCcpO1xuICAgICAgICBjb25zdCBwYXJzZWRUeCA9IG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgc3BlbmRBbW91bnQ6IHN0cmluZyB9O1xuICAgICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgICAgKG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgb3V0cHV0czogYW55W10gfSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ291dHB1dHMnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gPSAnaW52YWxpZEFkZHJlc3MnO1xuXG4gICAgICAgIC8vIEVuc3VyZSB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIHRoZSBzYW1lXG4gICAgICAgIHBhcmFtcy51c2VyS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICAgIHBhcmFtcy5iYWNrdXBLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgICAgICBnYXNMaW1pdDogMjAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSwgLy8gUHJvdmlkZSB0aGUgdXNlcktleVxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksIC8vIFByb3ZpZGUgdGhlIGJhY2t1cEtleVxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsIC8vIFByb3ZpZGUgdGhlIHdhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICdFcnJvcjogaW52YWxpZCBhZGRyZXNzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQnVpbGQgVW5zaWduZWQgQ29uc29saWRhdGlvbiBmb3IgU2VsZi1DdXN0b2R5IENvbGQgV2FsbGV0cyAoTVBDdjIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICAgIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICAgICAgbGV0IGJhc2Vjb2luOiBIdGV0aDtcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIGNvbnNvbGlkYXRpb24gZm9yIHdhbGxldCB2NScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3QgY29uc29saWRhdGlvblJlc3VsdCA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JyxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3QoY29uc29saWRhdGlvblJlc3VsdCk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24gPSBjb25zb2xpZGF0aW9uUmVzdWx0IGFzIFVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb247XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnNbMF0gYXMgTVBDU3dlZXBUeHM7XG4gICAgICAgIG91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIGNvbnNvbGlkYXRpb24gZm9yIHdhbGxldCB2NicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3QgY29uc29saWRhdGlvblJlc3VsdCA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBBIERhdGFcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcxMjMnLCAvLyBXcm9uZyB3YWxsZXQgYWRkcmVzcyBzbyB0aGF0IHdlIGNhbiBza2lwIHY1IGFkZHJlc3MgZ2VuZXJhdGlvblxuICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNycsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KGNvbnNvbGlkYXRpb25SZXN1bHQpO1xuICAgICAgICBjb25zdCB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uID0gY29uc29saWRhdGlvblJlc3VsdCBhcyBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dCA9IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zWzBdIGFzIE1QQ1N3ZWVwVHhzO1xuICAgICAgICBvdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UmVxdWVzdHMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29pbicpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc2lnbmVkVHgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXJzZWRUeCcpO1xuICAgICAgICBjb25zdCBwYXJzZWRUeCA9IG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgc3BlbmRBbW91bnQ6IHN0cmluZyB9O1xuICAgICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgICAgKG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgb3V0cHV0czogYW55W10gfSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ291dHB1dHMnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gPSAnaW52YWxpZEFkZHJlc3MnO1xuXG4gICAgICAgIC8vIEVuc3VyZSB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIHRoZSBzYW1lXG4gICAgICAgIHBhcmFtcy51c2VyS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICAgIHBhcmFtcy5iYWNrdXBLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgICAgICBnYXNMaW1pdDogMjAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSwgLy8gUHJvdmlkZSB0aGUgdXNlcktleVxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksIC8vIFByb3ZpZGUgdGhlIGJhY2t1cEtleVxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsIC8vIFByb3ZpZGUgdGhlIHdhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICdFcnJvcjogaW52YWxpZCBhZGRyZXNzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgb3ZlcnJpZGUgdGhlIHRva2VuIHBhcmFtZXRlciB3aXRoIGEgY3VzdG9tIEFQSSBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgIGFjdGlvbjogJ2JhbGFuY2UnLFxuICAgICAgICBhZGRyZXNzOiAnMHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBjdXN0b21BcGlLZXkgPSAnY3VzdG9tLWFwaS1rZXktZm9yLXRlc3QnO1xuXG4gICAgICAvLyBNb2NrIHRoZSBlbnZpcm9ubWVudCBBUEkgdG9rZW5cbiAgICAgIGNvbnN0IG9yaWdpbmFsQXBpVG9rZW4gPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW47XG4gICAgICBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW4gPSAnZGVmYXVsdC1lbnZpcm9ubWVudC1hcGkta2V5JztcblxuICAgICAgLy8gTW9jayB0aGUgcmVxdWVzdC5nZXQgZnVuY3Rpb24gdG8gY2FwdHVyZSB0aGUgcXVlcnkgcGFyYW1ldGVyc1xuICAgICAgY29uc3Qgb3JpZ2luYWxHZXQgPSByZXF1ZXN0LmdldDtcbiAgICAgIGxldCBjYXB0dXJlZFF1ZXJ5O1xuXG4gICAgICByZXF1ZXN0LmdldCA9IGZ1bmN0aW9uICh1cmw6IHN0cmluZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHF1ZXJ5OiBmdW5jdGlvbiAocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgICAgICAgICBjYXB0dXJlZFF1ZXJ5ID0gcGFyYW1zO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgIGJvZHk6IHsgcmVzdWx0OiAnMTAwMDAwMDAwJyB9LFxuICAgICAgICAgICAgfSBhcyBhbnk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBhbnk7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBDYWxsIHdpdGggZGVmYXVsdCBBUEkga2V5XG4gICAgICAgIGF3YWl0IGNvaW4ucmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSk7XG4gICAgICAgIGNhcHR1cmVkUXVlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FwaWtleScsICdkZWZhdWx0LWVudmlyb25tZW50LWFwaS1rZXknKTtcblxuICAgICAgICAvLyBDYWxsIHdpdGggY3VzdG9tIEFQSSBrZXlcbiAgICAgICAgYXdhaXQgY29pbi5yZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5KHF1ZXJ5LCBjdXN0b21BcGlLZXkpO1xuICAgICAgICBjYXB0dXJlZFF1ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhcGlrZXknLCBjdXN0b21BcGlLZXkpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gUmVzdG9yZSBvcmlnaW5hbCBmdW5jdGlvbiBhbmQgQVBJIHRva2VuXG4gICAgICAgIHJlcXVlc3QuZ2V0ID0gb3JpZ2luYWxHZXQ7XG4gICAgICAgIGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5BcGlUb2tlbiA9IG9yaWdpbmFsQXBpVG9rZW47XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBdWRpdCBLZXknLCAoKSA9PiB7XG4gICAgbGV0IGNvaW46IEh0ZXRoO1xuICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdNdWx0aVNpZycsICgpID0+IHtcbiAgICAgIGNvbnN0IHsga2V5IH0gPSBldGhNdWx0aVNpZ0JhY2t1cEtleTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4geyBpc1ZhbGlkOiB0cnVlIH0gZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnWlE4TWh4VDg0bTRQJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZm9vJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogXCJmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IHBhc3N3b3JkIGVycm9yIC0gY2NtOiB0YWcgZG9lc24ndCBtYXRjaFwiIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSBrZXkgaXMgYWx0ZXJlZCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGFsdGVyZWRLZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdrQW1bRUZRNm89U3hsY0xGRHclLCcsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGpzb24gZGVjcnlwdDogaW52YWxpZCBwYXJhbWV0ZXJzJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdUU1MnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGtleToga2V5U3RyaW5nLCBjb21tb25LZXljaGFpbiB9ID0gZXRoVHNzQmFja3VwS2V5O1xuICAgICAgY29uc3Qga2V5ID0ga2V5U3RyaW5nLnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2tBbVtFRlE2bz1TeGxjTEZEdyUsJztcbiAgICAgIGNvbnN0IG11bHRpU2lnVHlwZSA9ICd0c3MnO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgaW5wdXRzJywgKCkgPT4ge1xuICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdGhlIGNvbW1vbktleWNoYWluIGlzIGFsdGVyZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRDb21tb25LZXljaGFpbiA9IGdlbmVyYXRlUmFuZG9tUGFzc3dvcmQoMTApO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgY29tbW9uIGtleWNoYWluJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluY29ycmVjdFBhc3NwaHJhc2UgPSAnZm9vJztcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGluY29ycmVjdFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogXCJmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IHBhc3N3b3JkIGVycm9yIC0gY2NtOiB0YWcgZG9lc24ndCBtYXRjaFwiIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSBrZXkgaXMgYWx0ZXJlZCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGFsdGVyZWRLZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjoganNvbiBkZWNyeXB0OiBpbnZhbGlkIHBhcmFtZXRlcnMnIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0U2lnbmFibGVQYXlsb2FkJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBjb2luOiBUZXRoO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgMzItYnl0ZSBrZWNjYWsyNTYgaGFzaCBmb3IgYSBMZWdhY3kgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZTogJzEwMDAwMDAwMDAwJywgZ2FzTGltaXQ6ICc3MDAwMDAwJyB9KTtcbiAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KCcweDhDZTU5YzJkMTcwMjg0NEY4RWRFRDQ1MUFBMTAzOTYxYkMzN0I0ZTgnKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgICAuY29pbigndGV0aCcpXG4gICAgICAgIC5leHBpcmF0aW9uVGltZShNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDM2MDApXG4gICAgICAgIC5hbW91bnQoJzEwMDAwMCcpXG4gICAgICAgIC50bygnMHhlZWFmMEYwNWYzNzg5MWFiNGEyMTIwOEIxMDVBMDY4N2QxMmM1YUY3JylcbiAgICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZCgxKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBzZXJpYWxpemVkVHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgY29pbi5nZXRTaWduYWJsZVBheWxvYWQoc2VyaWFsaXplZFR4KTtcbiAgICAgIGFzc2VydC5vayhCdWZmZXIuaXNCdWZmZXIocGF5bG9hZCkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBheWxvYWQubGVuZ3RoLCAzMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIDMyLWJ5dGUga2VjY2FrMjU2IGhhc2ggZm9yIGFuIEVJUDE1NTkgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzI4MDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNzAwMDAwMCcsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAnNzU5MzEyMycsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAnMTUwJyB9LFxuICAgICAgfSk7XG4gICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIHR4QnVpbGRlci5jb250cmFjdCgnMHg4Q2U1OWMyZDE3MDI4NDRGOEVkRUQ0NTFBQTEwMzk2MWJDMzdCNGU4Jyk7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgLmNvaW4oJ3RldGgnKVxuICAgICAgICAuZXhwaXJhdGlvblRpbWUoTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCkgKyAzNjAwKVxuICAgICAgICAuYW1vdW50KCcxMDAwMDAnKVxuICAgICAgICAudG8oJzB4ZWVhZjBGMDVmMzc4OTFhYjRhMjEyMDhCMTA1QTA2ODdkMTJjNWFGNycpXG4gICAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFR4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGNvaW4uZ2V0U2lnbmFibGVQYXlsb2FkKHNlcmlhbGl6ZWRUeCk7XG4gICAgICBhc3NlcnQub2soQnVmZmVyLmlzQnVmZmVyKHBheWxvYWQpKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXlsb2FkLmxlbmd0aCwgMzIpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gRVJDLTc5ODQgdG9rZW4gZW5hYmxlbWVudCDigJQgbXVsdGlzaWcgdmVyaWZ5VHJhbnNhY3Rpb24gKGFsbCBzY2VuYXJpb3MpXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICBkZXNjcmliZSgndmVyaWZ5VHJhbnNhY3Rpb24g4oCTIEVSQy03OTg0IGVuYWJsZXRva2VuIChtdWx0aXNpZyB3YWxsZXQpJywgZnVuY3Rpb24gKCkge1xuICAgIC8vIGh0ZXRoIFphbWEgQUNMIGNvbnRyYWN0IChOZXR3b3Jrcy50ZXN0Lmhvb2RpLnphbWFBY2xDb250cmFjdEFkZHJlc3MpXG4gICAgY29uc3QgWkFNQV9BQ0xfQUREUkVTUyA9ICcweDZkM2ZhZjZmODZlMWZmOWYzYjA4MzFkZGE5MjBhYmExY2JkNWJkNjgnO1xuICAgIC8vIFNpbXVsYXRlZCB3YWxsZXQgYmFzZSBhZGRyZXNzICh3aGF0IHRoZSBjbGllbnQgc2VuZHMgYXMgdGhlIHJlY2lwaWVudCBmb3IgYmFzZS1hZGRyZXNzIHdhbGxldHMpXG4gICAgY29uc3QgV0FMTEVUX0JBU0VfQUREUkVTUyA9ICcweDA4ZTY3MzZlODc2ZDc3MmQyZmE4ZjgwM2EwNzZjZDZjOWY4NDU1NDYnO1xuICAgIC8vIFNpbXVsYXRlZCBmb3J3YXJkZXIgYWRkcmVzcyAod2hhdCB0aGUgY2xpZW50IHNlbmRzIGFzIHJlY2lwaWVudCBmb3IgZm9yd2FyZGVyIHdhbGxldHMpXG4gICAgY29uc3QgRk9SV0FSREVSX0FERFJFU1MgPSAnMHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJztcbiAgICBjb25zdCBXUk9OR19BRERSRVNTID0gJzB4YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSc7XG5cbiAgICBjb25zdCBtYWtlUHJlYnVpbGQgPSAocmVjaXBpZW50QWRkcmVzczogc3RyaW5nKSA9PiAoe1xuICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogcmVjaXBpZW50QWRkcmVzcywgYW1vdW50OiAnMCcgfV0sXG4gICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgZ2FzTGltaXQ6IDMwMDAwMCxcbiAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICB9KTtcblxuICAgIC8vIOKUgOKUgCBCYXNlLWFkZHJlc3Mgd2FsbGV0IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gICAgaXQoJ2Jhc2UtYWRkcmVzcywgc2luZ2xlIHRva2VuOiB0eFBhcmFtcyDihpIgd2FsbGV0QmFzZSwgdHhQcmVidWlsZCDihpIgQUNMJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaHRldGhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH1dLFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKFpBTUFfQUNMX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Jhc2UtYWRkcmVzcywgbXVsdGktdG9rZW46IG11bHRpcGxlIHR4UGFyYW1zIHJlY2lwaWVudHMgKHNhbWUgYmFzZSBhZGRyZXNzKSwgdHhQcmVidWlsZCDihpIgQUNMIG11bHRpY2FsbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGh0ZXRoQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH0sXG4gICAgICAgICAgICB7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKFpBTUFfQUNMX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgLy8g4pSA4pSAIEZvcndhcmRlciB3YWxsZXQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgICBpdCgnZm9yd2FyZGVyLCBzaW5nbGUgdG9rZW46IHR4UGFyYW1zIOKGkiBmb3J3YXJkZXIsIHR4UHJlYnVpbGQg4oaSIGZvcndhcmRlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGh0ZXRoQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBGT1JXQVJERVJfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfV0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoRk9SV0FSREVSX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2ZvcndhcmRlciwgbXVsdGktdG9rZW46IG11bHRpcGxlIHR4UGFyYW1zIHJlY2lwaWVudHMgKHNhbWUgZm9yd2FyZGVyKSwgdHhQcmVidWlsZCDihpIgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaHRldGhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHsgYWRkcmVzczogRk9SV0FSREVSX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH0sXG4gICAgICAgICAgICB7IGFkZHJlc3M6IEZPUldBUkRFUl9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3VzZHQnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChGT1JXQVJERVJfQUREUkVTUykgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICAvLyDilIDilIAgTmVnYXRpdmUgY2FzZXMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdHhQcmVidWlsZCByZWNpcGllbnQgaXMgbmVpdGhlciB0aGUgQUNMIGNvbnRyYWN0IG5vciB0aGUgZm9yd2FyZGVyIGZyb20gdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBhd2FpdCBodGV0aENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH1dLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChXUk9OR19BRERSRVNTKSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvdG9rZW4gZW5hYmxlbWVudCB0eFByZWJ1aWxkIHJlY2lwaWVudCBtdXN0IGJlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdHhQYXJhbXMgcmVjaXBpZW50cyBoYXZlIGRpZmZlcmVudCBhZGRyZXNzZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBhd2FpdCBodGV0aENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAgeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9LFxuICAgICAgICAgICAgICB7IGFkZHJlc3M6IEZPUldBUkRFUl9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3VzZHQnIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChaQU1BX0FDTF9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbXVzdCBhbGwgaGF2ZSB0aGUgc2FtZSBhZGRyZXNzLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gYSB0eFBhcmFtcyByZWNpcGllbnQgaGFzIG5vbi16ZXJvIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGF3YWl0IGh0ZXRoQ29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMTAwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9XSxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoWkFNQV9BQ0xfQUREUkVTUykgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL211c3QgYWxsIGhhdmUgYW1vdW50IDAvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB0eFByZWJ1aWxkIHJlY2lwaWVudCBoYXMgbm9uLXplcm8gYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgYXdhaXQgaHRldGhDb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9XSxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBaQU1BX0FDTF9BRERSRVNTLCBhbW91bnQ6ICc1MDAnIH1dLFxuICAgICAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvZXhwZWN0ZWQgYW1vdW50IDAgaW4gdHhQcmVidWlsZC8pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19