@bitgo-beta/sdk-coin-eth 4.4.1-beta.21 → 4.4.1-beta.2100

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 (164) hide show
  1. package/dist/src/erc20Token.d.ts +13 -5
  2. package/dist/src/erc20Token.d.ts.map +1 -1
  3. package/dist/src/erc20Token.js +73 -32
  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 +337 -0
  7. package/dist/src/erc7984Token.d.ts +187 -0
  8. package/dist/src/erc7984Token.d.ts.map +1 -0
  9. package/dist/src/erc7984Token.js +944 -0
  10. package/dist/src/eth.d.ts +25 -537
  11. package/dist/src/eth.d.ts.map +1 -1
  12. package/dist/src/eth.js +252 -1657
  13. package/dist/src/gteth.d.ts +0 -4
  14. package/dist/src/gteth.d.ts.map +1 -1
  15. package/dist/src/gteth.js +1 -11
  16. package/dist/src/hteth.d.ts +8 -0
  17. package/dist/src/hteth.d.ts.map +1 -0
  18. package/dist/src/hteth.js +14 -0
  19. package/dist/src/index.d.ts +4 -0
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/dist/src/index.js +10 -2
  22. package/dist/src/lib/index.d.ts +5 -13
  23. package/dist/src/lib/index.d.ts.map +1 -1
  24. package/dist/src/lib/index.js +18 -30
  25. package/dist/src/lib/messages/index.d.ts +3 -0
  26. package/dist/src/lib/messages/index.d.ts.map +1 -0
  27. package/dist/src/lib/messages/index.js +6 -0
  28. package/dist/src/lib/transactionBuilder.d.ts +10 -214
  29. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  30. package/dist/src/lib/transactionBuilder.js +23 -678
  31. package/dist/src/lib/transferBuilder.d.ts +2 -50
  32. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  33. package/dist/src/lib/transferBuilder.js +3 -199
  34. package/dist/src/lib/transferBuilders/index.d.ts +2 -3
  35. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
  36. package/dist/src/lib/transferBuilders/index.js +7 -14
  37. package/dist/src/lib/walletUtil.d.ts +0 -25
  38. package/dist/src/lib/walletUtil.d.ts.map +1 -1
  39. package/dist/src/lib/walletUtil.js +2 -27
  40. package/dist/src/register.d.ts +2 -0
  41. package/dist/src/register.d.ts.map +1 -1
  42. package/dist/src/register.js +41 -2
  43. package/dist/src/sepeth.d.ts +8 -0
  44. package/dist/src/sepeth.d.ts.map +1 -0
  45. package/dist/src/sepeth.js +14 -0
  46. package/dist/src/teth.d.ts +0 -3
  47. package/dist/src/teth.d.ts.map +1 -1
  48. package/dist/src/teth.js +1 -8
  49. package/dist/test/fixtures/eth.d.ts +57 -0
  50. package/dist/test/fixtures/eth.d.ts.map +1 -0
  51. package/dist/test/fixtures/eth.js +277 -0
  52. package/dist/test/resources/erc1155Abi.d.ts +40 -0
  53. package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
  54. package/dist/test/resources/erc1155Abi.js +329 -0
  55. package/dist/test/resources/erc721Abi.d.ts +12 -0
  56. package/dist/test/resources/erc721Abi.d.ts.map +1 -0
  57. package/dist/test/resources/erc721Abi.js +34 -0
  58. package/dist/test/resources/eth.d.ts +51 -0
  59. package/dist/test/resources/eth.d.ts.map +1 -0
  60. package/dist/test/resources/eth.js +72 -0
  61. package/dist/test/resources/nftEncodings.d.ts +4 -0
  62. package/dist/test/resources/nftEncodings.d.ts.map +1 -0
  63. package/dist/test/resources/nftEncodings.js +7 -0
  64. package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
  65. package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
  66. package/dist/test/resources/walletSimpleAbi.js +44 -0
  67. package/dist/test/unit/erc7984Token.d.ts +2 -0
  68. package/dist/test/unit/erc7984Token.d.ts.map +1 -0
  69. package/dist/test/unit/erc7984Token.js +1645 -0
  70. package/dist/test/unit/eth.d.ts +2 -0
  71. package/dist/test/unit/eth.d.ts.map +1 -0
  72. package/dist/test/unit/eth.js +3164 -0
  73. package/dist/test/unit/ethWallet.d.ts +2 -0
  74. package/dist/test/unit/ethWallet.d.ts.map +1 -0
  75. package/dist/test/unit/ethWallet.js +552 -0
  76. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
  77. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
  78. package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
  79. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
  80. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
  81. package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -0
  82. package/dist/test/unit/getBuilder.d.ts +3 -0
  83. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  84. package/dist/test/unit/getBuilder.js +10 -0
  85. package/dist/test/unit/keyPair.d.ts +2 -0
  86. package/dist/test/unit/keyPair.d.ts.map +1 -0
  87. package/dist/test/unit/keyPair.js +175 -0
  88. package/dist/test/unit/register.d.ts +2 -0
  89. package/dist/test/unit/register.d.ts.map +1 -0
  90. package/dist/test/unit/register.js +75 -0
  91. package/dist/test/unit/transaction.d.ts +2 -0
  92. package/dist/test/unit/transaction.d.ts.map +1 -0
  93. package/dist/test/unit/transaction.js +117 -0
  94. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  95. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  96. package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
  97. package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
  98. package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
  99. package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
  100. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +2 -0
  101. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
  102. package/dist/test/unit/transactionBuilder/decryptionDelegation.js +59 -0
  103. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts +2 -0
  104. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts.map +1 -0
  105. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.js +136 -0
  106. package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
  107. package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
  108. package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
  109. package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
  110. package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
  111. package/dist/test/unit/transactionBuilder/flushTokens.js +298 -0
  112. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  113. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  114. package/dist/test/unit/transactionBuilder/send.js +331 -0
  115. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts +2 -0
  116. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts.map +1 -0
  117. package/dist/test/unit/transactionBuilder/sendERC7984Token.js +361 -0
  118. package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
  119. package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
  120. package/dist/test/unit/transactionBuilder/sendNFT.js +295 -0
  121. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
  122. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
  123. package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
  124. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  125. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  126. package/dist/test/unit/transactionBuilder/walletInitialization.js +436 -0
  127. package/dist/test/unit/transferBuilder.d.ts +2 -0
  128. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  129. package/dist/test/unit/transferBuilder.js +124 -0
  130. package/dist/test/unit/utils.d.ts +2 -0
  131. package/dist/test/unit/utils.d.ts.map +1 -0
  132. package/dist/test/unit/utils.js +74 -0
  133. package/dist/tsconfig.tsbuildinfo +1 -0
  134. package/package.json +18 -19
  135. package/.eslintignore +0 -5
  136. package/.mocharc.yml +0 -8
  137. package/CHANGELOG.md +0 -229
  138. package/dist/src/lib/contractCall.d.ts +0 -8
  139. package/dist/src/lib/contractCall.d.ts.map +0 -1
  140. package/dist/src/lib/contractCall.js +0 -17
  141. package/dist/src/lib/iface.d.ts +0 -130
  142. package/dist/src/lib/iface.d.ts.map +0 -1
  143. package/dist/src/lib/iface.js +0 -8
  144. package/dist/src/lib/keyPair.d.ts +0 -26
  145. package/dist/src/lib/keyPair.d.ts.map +0 -1
  146. package/dist/src/lib/keyPair.js +0 -66
  147. package/dist/src/lib/transaction.d.ts +0 -64
  148. package/dist/src/lib/transaction.d.ts.map +0 -1
  149. package/dist/src/lib/transaction.js +0 -137
  150. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts +0 -47
  151. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts.map +0 -1
  152. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.js +0 -113
  153. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts +0 -14
  154. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts.map +0 -1
  155. package/dist/src/lib/transferBuilders/transferBuilderERC1155.js +0 -83
  156. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts +0 -13
  157. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts.map +0 -1
  158. package/dist/src/lib/transferBuilders/transferBuilderERC721.js +0 -68
  159. package/dist/src/lib/types.d.ts +0 -39
  160. package/dist/src/lib/types.d.ts.map +0 -1
  161. package/dist/src/lib/types.js +0 -137
  162. package/dist/src/lib/utils.d.ts +0 -227
  163. package/dist/src/lib/utils.d.ts.map +0 -1
  164. package/dist/src/lib/utils.js +0 -577
@@ -0,0 +1,3164 @@
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 bn_js_1 = __importDefault(require("bn.js"));
47
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
48
+ const src_1 = require("../../src");
49
+ const statics_1 = require("@bitgo-beta/statics");
50
+ const assert_1 = __importDefault(require("assert"));
51
+ const getBuilder_1 = require("./getBuilder");
52
+ const testData = __importStar(require("../resources/eth"));
53
+ const mockData = __importStar(require("../fixtures/eth"));
54
+ const should_1 = __importDefault(require("should"));
55
+ const ethereumjs_abi_1 = __importDefault(require("ethereumjs-abi"));
56
+ const ethMultiSigBackupKey_1 = require("./fixtures/ethMultiSigBackupKey");
57
+ const ethTssBackupKey_1 = require("./fixtures/ethTssBackupKey");
58
+ nock_1.default.enableNetConnect();
59
+ describe('ETH:', function () {
60
+ let bitgo;
61
+ let hopTxBitgoSignature;
62
+ let sandbox;
63
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
64
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
65
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
66
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
67
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
68
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
69
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
70
+ const buildDefiTxHex = async (data, to = address1) => {
71
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
72
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
73
+ txBuilder.fee({ fee: '10', gasLimit: '100000' });
74
+ txBuilder.counter(1);
75
+ txBuilder.contract(to);
76
+ txBuilder.data(data);
77
+ return (await txBuilder.build()).toBroadcastFormat();
78
+ };
79
+ const defiCalldata = (signature, values) => {
80
+ const types = signature.slice(signature.indexOf('(') + 1, -1).split(',');
81
+ const methodId = ethereumjs_abi_1.default.methodID(signature.split('(')[0], types);
82
+ return '0x' + Buffer.concat([methodId, ethereumjs_abi_1.default.rawEncode(types, values)]).toString('hex');
83
+ };
84
+ before(function () {
85
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
86
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
87
+ if (!bitgoKey.privateKey) {
88
+ throw new Error('no privateKey');
89
+ }
90
+ const bitgoXpub = bitgoKey.neutered().toBase58();
91
+ hopTxBitgoSignature =
92
+ '0xaa' +
93
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
94
+ const env = 'test';
95
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
96
+ src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
97
+ bitgo.safeRegister(name, coinConstructor);
98
+ });
99
+ bitgo.safeRegister('teth', src_1.Teth.createInstance);
100
+ bitgo.safeRegister('hteth', src_1.Hteth.createInstance);
101
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
102
+ bitgo.initializeTestVars();
103
+ sandbox = sinon_1.default.createSandbox();
104
+ });
105
+ after(function () {
106
+ nock_1.default.cleanAll();
107
+ sandbox.restore();
108
+ });
109
+ describe('EIP1559', function () {
110
+ it('should sign a transaction with EIP1559 fee params', async function () {
111
+ const coin = bitgo.coin('teth');
112
+ const userKeychain = {
113
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
114
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
115
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
116
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
117
+ };
118
+ const halfSignedTransaction = await coin.signTransaction({
119
+ txPrebuild: {
120
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
121
+ isBatch: false,
122
+ recipients: [
123
+ {
124
+ amount: '42',
125
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
126
+ },
127
+ ],
128
+ expireTime: 1627949214,
129
+ contractSequenceId: 12,
130
+ gasLimit: undefined,
131
+ gasPrice: undefined,
132
+ hopTransaction: undefined,
133
+ backupKeyNonce: undefined,
134
+ sequenceId: undefined,
135
+ nextContractSequenceId: 0,
136
+ },
137
+ prv: userKeychain.prv,
138
+ });
139
+ halfSignedTransaction.halfSigned.eip1559.maxPriorityFeePerGas.should.equal(10);
140
+ halfSignedTransaction.halfSigned.eip1559.maxFeePerGas.should.equal(10);
141
+ });
142
+ it('should sign a transaction with EIP1559 fee params for CCR', async function () {
143
+ const coin = bitgo.coin('hteth');
144
+ const signTransaction = sinon_1.default.spy(src_1.AbstractEthLikeNewCoins.prototype, 'signTransaction');
145
+ const userKeychain = {
146
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
147
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
148
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
149
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
150
+ };
151
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
152
+ txBuilder.type(sdk_core_1.TransactionType.Send);
153
+ txBuilder.fee({
154
+ fee: '10',
155
+ gasLimit: '1000',
156
+ });
157
+ const key = testData.KEYPAIR_PRV.getKeys().prv;
158
+ const transferBuilder = txBuilder.transfer();
159
+ transferBuilder
160
+ .amount('0')
161
+ .to('0x19645032c7f1533395d44a629462e751084d3e4c')
162
+ .expirationTime(1590066728)
163
+ .contractSequenceId(5)
164
+ .key(key);
165
+ txBuilder.contract(address1);
166
+ const tx = await txBuilder.build();
167
+ const halfSignedTransaction = await coin.signTransaction({
168
+ txPrebuild: {
169
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
170
+ isBatch: false,
171
+ recipients: [
172
+ {
173
+ amount: '42',
174
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
175
+ },
176
+ ],
177
+ expireTime: 1627949214,
178
+ contractSequenceId: 12,
179
+ gasLimit: undefined,
180
+ gasPrice: undefined,
181
+ hopTransaction: undefined,
182
+ backupKeyNonce: undefined,
183
+ sequenceId: undefined,
184
+ nextContractSequenceId: 0,
185
+ txHex: tx.toBroadcastFormat(),
186
+ },
187
+ prv: userKeychain.prv,
188
+ isEvmBasedCrossChainRecovery: true,
189
+ });
190
+ (0, assert_1.default)(halfSignedTransaction.halfSigned.txHex);
191
+ assert_1.default.strictEqual(halfSignedTransaction.halfSigned.eip1559.maxFeePerGas, 10);
192
+ sandbox.assert.calledOnce(signTransaction);
193
+ });
194
+ });
195
+ describe('Transaction Verification', function () {
196
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
197
+ const coin = bitgo.coin('teth');
198
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
199
+ const txParams = {
200
+ recipients: [{ amount: '1000000000000', address: address1 }],
201
+ wallet: wallet,
202
+ walletPassphrase: 'fakeWalletPassphrase',
203
+ };
204
+ const txPrebuild = {
205
+ recipients: [{ amount: '1000000000000', address: address1 }],
206
+ nextContractSequenceId: 0,
207
+ gasPrice: 20000000000,
208
+ gasLimit: 500000,
209
+ isBatch: false,
210
+ coin: 'teth',
211
+ wallet: 'fakeWalletId',
212
+ walletContractAddress: 'fakeWalletContractAddress',
213
+ };
214
+ const verification = {};
215
+ const isTransactionVerified = await coin.verifyTransaction({
216
+ txParams,
217
+ txPrebuild: txPrebuild,
218
+ wallet,
219
+ verification,
220
+ });
221
+ isTransactionVerified.should.equal(true);
222
+ });
223
+ it('should verify a batch txPrebuild from the bitgo server that matches the client txParams', async function () {
224
+ const coin = bitgo.coin('teth');
225
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
226
+ const txParams = {
227
+ recipients: [
228
+ { amount: '1000000000000', address: address1 },
229
+ { amount: '2500000000000', address: address2 },
230
+ ],
231
+ wallet: wallet,
232
+ walletPassphrase: 'fakeWalletPassphrase',
233
+ };
234
+ const txPrebuild = {
235
+ recipients: [
236
+ { amount: '3500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
237
+ ],
238
+ nextContractSequenceId: 0,
239
+ gasPrice: 20000000000,
240
+ gasLimit: 500000,
241
+ isBatch: true,
242
+ coin: 'teth',
243
+ walletId: 'fakeWalletId',
244
+ walletContractAddress: 'fakeWalletContractAddress',
245
+ };
246
+ const verification = {};
247
+ const isTransactionVerified = await coin.verifyTransaction({
248
+ txParams,
249
+ txPrebuild: txPrebuild,
250
+ wallet,
251
+ verification,
252
+ });
253
+ isTransactionVerified.should.equal(true);
254
+ });
255
+ it('should verify ENS address resolution changing recipient address in client txParams', async function () {
256
+ const coin = bitgo.coin('teth');
257
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
258
+ const txParams = {
259
+ recipients: [{ amount: '1000000000000', address: 'bitgotestwallet.eth' }],
260
+ wallet: wallet,
261
+ walletPassphrase: 'fakeWalletPassphrase',
262
+ };
263
+ const txPrebuild = {
264
+ recipients: [{ amount: '1000000000000', address: '0x40a663963810449d6e72533657a74f112c3b901a' }],
265
+ nextContractSequenceId: 0,
266
+ gasPrice: 20000000000,
267
+ gasLimit: 500000,
268
+ isBatch: false,
269
+ coin: 'teth',
270
+ walletId: 'fakeWalletId',
271
+ walletContractAddress: 'fakeWalletContractAddress',
272
+ };
273
+ const verification = {};
274
+ const isTransactionVerified = await coin.verifyTransaction({
275
+ txParams,
276
+ txPrebuild: txPrebuild,
277
+ wallet,
278
+ verification,
279
+ });
280
+ isTransactionVerified.should.equal(true);
281
+ });
282
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
283
+ const coin = bitgo.coin('teth');
284
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
285
+ const txParams = {
286
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
287
+ wallet: wallet,
288
+ walletPassphrase: 'fakeWalletPassphrase',
289
+ hop: true,
290
+ };
291
+ const txPrebuild = {
292
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
293
+ nextContractSequenceId: 0,
294
+ gasPrice: 20000000000,
295
+ gasLimit: 500000,
296
+ isBatch: false,
297
+ coin: 'teth',
298
+ walletId: 'fakeWalletId',
299
+ walletContractAddress: 'fakeWalletContractAddress',
300
+ hopTransaction: {
301
+ tx: hopTx,
302
+ id: hopTxid,
303
+ signature: hopTxBitgoSignature,
304
+ paymentId: '2773928196',
305
+ gasPrice: 20000000000,
306
+ gasLimit: 500000,
307
+ amount: '1000000000000000',
308
+ recipient: hopDestinationAddress,
309
+ nonce: 0,
310
+ userReqSig: userReqSig,
311
+ gasPriceMax: 500000000000,
312
+ },
313
+ };
314
+ const verification = {};
315
+ const isTransactionVerified = await coin.verifyTransaction({
316
+ txParams,
317
+ txPrebuild: txPrebuild,
318
+ wallet,
319
+ verification,
320
+ });
321
+ isTransactionVerified.should.equal(true);
322
+ });
323
+ it('should reject when client txParams are missing', async function () {
324
+ const coin = bitgo.coin('teth');
325
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
326
+ const txParams = null;
327
+ const txPrebuild = {
328
+ recipients: [{ amount: '1000000000000', address: address1 }],
329
+ nextContractSequenceId: 0,
330
+ gasPrice: 20000000000,
331
+ gasLimit: 500000,
332
+ isBatch: false,
333
+ coin: 'teth',
334
+ walletId: 'fakeWalletId',
335
+ walletContractAddress: 'fakeWalletContractAddress',
336
+ };
337
+ const verification = {};
338
+ await coin
339
+ .verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
340
+ .should.be.rejectedWith('missing params');
341
+ });
342
+ it('should reject txPrebuild that is both batch and hop', async function () {
343
+ const coin = bitgo.coin('teth');
344
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
345
+ const txParams = {
346
+ recipients: [
347
+ { amount: '1000000000000', address: address1 },
348
+ { amount: '2500000000000', address: address2 },
349
+ ],
350
+ wallet: wallet,
351
+ walletPassphrase: 'fakeWalletPassphrase',
352
+ hop: true,
353
+ };
354
+ const txPrebuild = {
355
+ recipients: [{ amount: '3500000000000', address: address1 }],
356
+ nextContractSequenceId: 0,
357
+ gasPrice: 20000000000,
358
+ gasLimit: 500000,
359
+ isBatch: true,
360
+ coin: 'teth',
361
+ walletId: 'fakeWalletId',
362
+ walletContractAddress: 'fakeWalletContractAddress',
363
+ hopTransaction: {
364
+ tx: hopTx,
365
+ id: hopTxid,
366
+ signature: hopTxBitgoSignature,
367
+ paymentId: '2773928196',
368
+ gasPrice: 20000000000,
369
+ gasLimit: 500000,
370
+ amount: '1000000000000000',
371
+ recipient: hopDestinationAddress,
372
+ nonce: 0,
373
+ userReqSig: userReqSig,
374
+ gasPriceMax: 500000000000,
375
+ },
376
+ };
377
+ const verification = {};
378
+ await coin
379
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
380
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
381
+ });
382
+ it('should reject a txPrebuild with more than one recipient', async function () {
383
+ const coin = bitgo.coin('teth');
384
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
385
+ const txParams = {
386
+ recipients: [
387
+ { amount: '1000000000000', address: address1 },
388
+ { amount: '2500000000000', address: address2 },
389
+ ],
390
+ wallet: wallet,
391
+ walletPassphrase: 'fakeWalletPassphrase',
392
+ };
393
+ const txPrebuild = {
394
+ recipients: [
395
+ { amount: '1000000000000', address: address1 },
396
+ { amount: '2500000000000', address: address2 },
397
+ ],
398
+ nextContractSequenceId: 0,
399
+ gasPrice: 20000000000,
400
+ gasLimit: 500000,
401
+ isBatch: true,
402
+ coin: 'teth',
403
+ walletId: 'fakeWalletId',
404
+ walletContractAddress: 'fakeWalletContractAddress',
405
+ };
406
+ const verification = {};
407
+ await coin
408
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
409
+ .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.`);
410
+ });
411
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
412
+ const coin = bitgo.coin('teth');
413
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
414
+ const txParams = {
415
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
416
+ wallet: wallet,
417
+ walletPassphrase: 'fakeWalletPassphrase',
418
+ hop: true,
419
+ };
420
+ const txPrebuild = {
421
+ recipients: [{ amount: '5000000000000000', address: address1 }],
422
+ nextContractSequenceId: 0,
423
+ gasPrice: 20000000000,
424
+ gasLimit: 500000,
425
+ isBatch: false,
426
+ coin: 'teth',
427
+ walletId: 'fakeWalletId',
428
+ walletContractAddress: 'fakeWalletContractAddress',
429
+ hopTransaction: {
430
+ tx: hopTx,
431
+ id: hopTxid,
432
+ signature: hopTxBitgoSignature,
433
+ paymentId: '0',
434
+ gasPrice: 20000000000,
435
+ gasLimit: 500000,
436
+ amount: '1000000000000000',
437
+ recipient: hopDestinationAddress,
438
+ nonce: 0,
439
+ userReqSig: userReqSig,
440
+ gasPriceMax: 500000000000,
441
+ },
442
+ };
443
+ const verification = {};
444
+ await coin
445
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
446
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
447
+ });
448
+ it('should reject a batch txPrebuild from the bitgo server with the wrong total amount', async function () {
449
+ const coin = bitgo.coin('teth');
450
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
451
+ const txParams = {
452
+ recipients: [
453
+ { amount: '1000000000000', address: address1 },
454
+ { amount: '2500000000000', address: address2 },
455
+ ],
456
+ wallet: wallet,
457
+ walletPassphrase: 'fakeWalletPassphrase',
458
+ };
459
+ const txPrebuild = {
460
+ recipients: [
461
+ { amount: '5500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
462
+ ],
463
+ nextContractSequenceId: 0,
464
+ gasPrice: 20000000000,
465
+ gasLimit: 500000,
466
+ isBatch: true,
467
+ coin: 'teth',
468
+ walletId: 'fakeWalletId',
469
+ walletContractAddress: 'fakeWalletContractAddress',
470
+ };
471
+ const verification = {};
472
+ await coin
473
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
474
+ .should.be.rejectedWith('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
475
+ });
476
+ it('should reject a batch txPrebuild from the bitgo server that does not send to the batcher contract address', async function () {
477
+ const coin = bitgo.coin('teth');
478
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
479
+ const txParams = {
480
+ recipients: [
481
+ { amount: '1000000000000', address: address1 },
482
+ { amount: '2500000000000', address: address2 },
483
+ ],
484
+ wallet: wallet,
485
+ walletPassphrase: 'fakeWalletPassphrase',
486
+ };
487
+ const txPrebuild = {
488
+ recipients: [{ amount: '3500000000000', address: hopContractAddress }],
489
+ nextContractSequenceId: 0,
490
+ gasPrice: 20000000000,
491
+ gasLimit: 500000,
492
+ isBatch: true,
493
+ coin: 'teth',
494
+ walletId: 'fakeWalletId',
495
+ walletContractAddress: 'fakeWalletContractAddress',
496
+ };
497
+ const verification = {};
498
+ await coin
499
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
500
+ .should.be.rejectedWith('recipient address of txPrebuild does not match batcher address');
501
+ });
502
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
503
+ const coin = bitgo.coin('teth');
504
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
505
+ const txParams = {
506
+ recipients: [{ amount: '1000000000000', address: address1 }],
507
+ wallet: wallet,
508
+ walletPassphrase: 'fakeWalletPassphrase',
509
+ };
510
+ const txPrebuild = {
511
+ recipients: [{ amount: '2000000000000', address: address1 }],
512
+ nextContractSequenceId: 0,
513
+ gasPrice: 20000000000,
514
+ gasLimit: 500000,
515
+ isBatch: false,
516
+ coin: 'teth',
517
+ walletId: 'fakeWalletId',
518
+ walletContractAddress: 'fakeWalletContractAddress',
519
+ };
520
+ const verification = {};
521
+ await coin
522
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
523
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
524
+ });
525
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
526
+ const coin = bitgo.coin('teth');
527
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
528
+ const txParams = {
529
+ recipients: [{ amount: '1000000000000', address: address1 }],
530
+ wallet: wallet,
531
+ walletPassphrase: 'fakeWalletPassphrase',
532
+ };
533
+ const txPrebuild = {
534
+ recipients: [{ amount: '1000000000000', address: address2 }],
535
+ nextContractSequenceId: 0,
536
+ gasPrice: 20000000000,
537
+ gasLimit: 500000,
538
+ isBatch: false,
539
+ coin: 'teth',
540
+ walletId: 'fakeWalletId',
541
+ walletContractAddress: 'fakeWalletContractAddress',
542
+ };
543
+ const verification = {};
544
+ await coin
545
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
546
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
547
+ });
548
+ it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
549
+ const coin = bitgo.coin('test');
550
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
551
+ const txParams = {
552
+ recipients: [{ amount: '1000000000000', address: address1 }],
553
+ wallet: wallet,
554
+ walletPassphrase: 'fakeWalletPassphrase',
555
+ };
556
+ const txPrebuild = {
557
+ recipients: [{ amount: '1000000000000', address: address1 }],
558
+ nextContractSequenceId: 0,
559
+ gasPrice: 20000000000,
560
+ gasLimit: 500000,
561
+ isBatch: false,
562
+ coin: 'teth',
563
+ token: 'test',
564
+ walletId: 'fakeWalletId',
565
+ walletContractAddress: 'fakeWalletContractAddress',
566
+ };
567
+ const verification = {};
568
+ const isTransactionVerified = await coin.verifyTransaction({
569
+ txParams,
570
+ txPrebuild: txPrebuild,
571
+ wallet,
572
+ verification,
573
+ });
574
+ isTransactionVerified.should.equal(true);
575
+ });
576
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
577
+ const coin = bitgo.coin('teth');
578
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
579
+ const txParams = {
580
+ recipients: [{ amount: '1000000000000', address: address1 }],
581
+ wallet: wallet,
582
+ walletPassphrase: 'fakeWalletPassphrase',
583
+ };
584
+ const txPrebuild = {
585
+ recipients: [{ amount: '1000000000000', address: address1 }],
586
+ nextContractSequenceId: 0,
587
+ gasPrice: 20000000000,
588
+ gasLimit: 500000,
589
+ isBatch: false,
590
+ coin: 'btc',
591
+ walletId: 'fakeWalletId',
592
+ walletContractAddress: 'fakeWalletContractAddress',
593
+ };
594
+ const verification = {};
595
+ await coin
596
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
597
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
598
+ });
599
+ });
600
+ describe('TSS Transaction Verification', function () {
601
+ const expectDefiRejection = async (p, messagePattern) => {
602
+ try {
603
+ await p;
604
+ }
605
+ catch (err) {
606
+ err.should.be.instanceOf(sdk_core_1.TxIntentMismatchRecipientError);
607
+ err.message.should.match(messagePattern);
608
+ return;
609
+ }
610
+ throw new Error('expected verifyTransaction to be rejected, but it resolved');
611
+ };
612
+ it('should verify TSS consolidation transaction when txPrebuild has consolidateId', async function () {
613
+ const coin = bitgo.coin('hteth');
614
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
615
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
616
+ coinSpecific: {
617
+ baseAddress: baseAddress,
618
+ },
619
+ });
620
+ // txParams without recipients (as in consolidation flow)
621
+ const txParams = {
622
+ wallet: wallet,
623
+ walletPassphrase: 'fakeWalletPassphrase',
624
+ };
625
+ // txPrebuild with consolidateId (set by server during consolidation build)
626
+ const txPrebuild = {
627
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
628
+ txHex: '0x',
629
+ coin: 'hteth',
630
+ walletId: 'fakeWalletId',
631
+ };
632
+ const verification = {};
633
+ const isTransactionVerified = await coin.verifyTransaction({
634
+ txParams: txParams,
635
+ txPrebuild: txPrebuild,
636
+ wallet,
637
+ verification,
638
+ walletType: 'tss',
639
+ });
640
+ isTransactionVerified.should.equal(true);
641
+ });
642
+ it('should verify TSS transaction when txParams.type is consolidate', async function () {
643
+ const coin = bitgo.coin('hteth');
644
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
645
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
646
+ coinSpecific: {
647
+ baseAddress: baseAddress,
648
+ },
649
+ });
650
+ const txParams = {
651
+ type: 'consolidate',
652
+ wallet: wallet,
653
+ walletPassphrase: 'fakeWalletPassphrase',
654
+ };
655
+ const txPrebuild = {
656
+ txHex: '0x',
657
+ coin: 'hteth',
658
+ walletId: 'fakeWalletId',
659
+ };
660
+ const verification = {};
661
+ const isTransactionVerified = await coin.verifyTransaction({
662
+ txParams: txParams,
663
+ txPrebuild: txPrebuild,
664
+ wallet,
665
+ verification,
666
+ walletType: 'tss',
667
+ });
668
+ isTransactionVerified.should.equal(true);
669
+ });
670
+ it('should verify TSS transaction when txParams.prebuildTx has consolidateId', async function () {
671
+ const coin = bitgo.coin('hteth');
672
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
673
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
674
+ coinSpecific: {
675
+ baseAddress: baseAddress,
676
+ },
677
+ });
678
+ const txParams = {
679
+ wallet: wallet,
680
+ walletPassphrase: 'fakeWalletPassphrase',
681
+ prebuildTx: {
682
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
683
+ },
684
+ };
685
+ const txPrebuild = {
686
+ txHex: '0x',
687
+ coin: 'hteth',
688
+ walletId: 'fakeWalletId',
689
+ };
690
+ const verification = {};
691
+ const isTransactionVerified = await coin.verifyTransaction({
692
+ txParams: txParams,
693
+ txPrebuild: txPrebuild,
694
+ wallet,
695
+ verification,
696
+ walletType: 'tss',
697
+ });
698
+ isTransactionVerified.should.equal(true);
699
+ });
700
+ it('should reject TSS transaction without recipients, consolidateId, or valid type', async function () {
701
+ const coin = bitgo.coin('hteth');
702
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
703
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
704
+ coinSpecific: {
705
+ baseAddress: baseAddress,
706
+ },
707
+ });
708
+ const txParams = {
709
+ wallet: wallet,
710
+ walletPassphrase: 'fakeWalletPassphrase',
711
+ };
712
+ const txPrebuild = {
713
+ txHex: '0x',
714
+ coin: 'hteth',
715
+ walletId: 'fakeWalletId',
716
+ };
717
+ const verification = {};
718
+ await coin
719
+ .verifyTransaction({
720
+ txParams: txParams,
721
+ txPrebuild: txPrebuild,
722
+ wallet,
723
+ verification,
724
+ walletType: 'tss',
725
+ })
726
+ .should.be.rejectedWith('missing txParams');
727
+ });
728
+ it('should verify TSS transaction with acceleration type', async function () {
729
+ const coin = bitgo.coin('hteth');
730
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
731
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
732
+ coinSpecific: {
733
+ baseAddress: baseAddress,
734
+ },
735
+ });
736
+ const txParams = {
737
+ type: 'acceleration',
738
+ wallet: wallet,
739
+ walletPassphrase: 'fakeWalletPassphrase',
740
+ };
741
+ const txPrebuild = {
742
+ txHex: '0x',
743
+ coin: 'hteth',
744
+ walletId: 'fakeWalletId',
745
+ };
746
+ const verification = {};
747
+ const isTransactionVerified = await coin.verifyTransaction({
748
+ txParams: txParams,
749
+ txPrebuild: txPrebuild,
750
+ wallet,
751
+ verification,
752
+ walletType: 'tss',
753
+ });
754
+ isTransactionVerified.should.equal(true);
755
+ });
756
+ it('should verify TSS transaction with fillNonce type', async function () {
757
+ const coin = bitgo.coin('hteth');
758
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
759
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
760
+ coinSpecific: {
761
+ baseAddress: baseAddress,
762
+ },
763
+ });
764
+ const txParams = {
765
+ type: 'fillNonce',
766
+ wallet: wallet,
767
+ walletPassphrase: 'fakeWalletPassphrase',
768
+ };
769
+ const txPrebuild = {
770
+ txHex: '0x',
771
+ coin: 'hteth',
772
+ walletId: 'fakeWalletId',
773
+ };
774
+ const verification = {};
775
+ const isTransactionVerified = await coin.verifyTransaction({
776
+ txParams: txParams,
777
+ txPrebuild: txPrebuild,
778
+ wallet,
779
+ verification,
780
+ walletType: 'tss',
781
+ });
782
+ isTransactionVerified.should.equal(true);
783
+ });
784
+ it('should verify TSS transaction with defiApprove type', async function () {
785
+ const coin = bitgo.coin('hteth');
786
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
787
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
788
+ coinSpecific: {
789
+ baseAddress: baseAddress,
790
+ },
791
+ });
792
+ // DeFi deposit flow is intent-based: recipients/calldata are built server-side
793
+ // from defiParams, so txParams has no recipients (see CGD-1815).
794
+ const txParams = {
795
+ type: 'defiApprove',
796
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10' },
797
+ wallet: wallet,
798
+ walletPassphrase: 'fakeWalletPassphrase',
799
+ };
800
+ const txPrebuild = {
801
+ txHex: await buildDefiTxHex(defiCalldata('approve(address,uint256)', [address1, '10'])),
802
+ coin: 'hteth',
803
+ walletId: 'fakeWalletId',
804
+ };
805
+ const verification = {};
806
+ const isTransactionVerified = await coin.verifyTransaction({
807
+ txParams: txParams,
808
+ txPrebuild: txPrebuild,
809
+ wallet,
810
+ verification,
811
+ walletType: 'tss',
812
+ });
813
+ isTransactionVerified.should.equal(true);
814
+ });
815
+ describe('wrapApprove calldata assertion', function () {
816
+ const pair = statics_1.coins.get('hteth:cusdt');
817
+ const wrapper = String(pair.contractAddress);
818
+ const underlying = pair.underlyingErc20Address;
819
+ const amount = '1000000';
820
+ const verifyWrapApprove = async (data, opts = {}) => {
821
+ const coin = bitgo.coin('hteth');
822
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
823
+ // WP derives the underlying token, spender and calldata from wrapParams, so there are no recipients.
824
+ const wrapParams = opts.wrapParams === null ? undefined : opts.wrapParams ?? { tokenName: 'hteth:cusdt', amount };
825
+ return coin.verifyTransaction({
826
+ txParams: { type: 'wrapApprove', wrapParams },
827
+ txPrebuild: { txHex: await buildDefiTxHex(data, opts.to ?? underlying), coin: 'hteth', walletId: 'w' },
828
+ wallet,
829
+ verification: {},
830
+ walletType: 'tss',
831
+ });
832
+ };
833
+ it('should verify approve(wrapper, amount) on the underlying ERC-20', async function () {
834
+ const result = await verifyWrapApprove(defiCalldata('approve(address,uint256)', [wrapper, amount]));
835
+ result.should.equal(true);
836
+ });
837
+ it('should reject approve with a spender other than the wrapper', async function () {
838
+ await expectDefiRejection(verifyWrapApprove(defiCalldata('approve(address,uint256)', [address2, amount])), /spender does not match the wrapper/);
839
+ });
840
+ it('should reject approve with a mutated amount', async function () {
841
+ await expectDefiRejection(verifyWrapApprove(defiCalldata('approve(address,uint256)', [wrapper, '1000001'])), /amount does not match/);
842
+ });
843
+ it('should reject calldata that is not approve', async function () {
844
+ await expectDefiRejection(verifyWrapApprove(defiCalldata('transfer(address,uint256)', [address2, amount])), /approve\(address,uint256\)/);
845
+ });
846
+ it('should reject approve calldata with trailing bytes', async function () {
847
+ await expectDefiRejection(verifyWrapApprove(defiCalldata('approve(address,uint256)', [wrapper, amount]) + '00'), /expected 68 bytes/);
848
+ });
849
+ it('should reject approve sent to a contract other than the underlying ERC-20', async function () {
850
+ await expectDefiRejection(verifyWrapApprove(defiCalldata('approve(address,uint256)', [wrapper, amount]), { to: address2 }), /must target the underlying ERC-20/);
851
+ });
852
+ it('should reject when wrapParams is missing or names an unregistered pair', async function () {
853
+ const data = defiCalldata('approve(address,uint256)', [wrapper, amount]);
854
+ await expectDefiRejection(verifyWrapApprove(data, { wrapParams: null }), /requires wrapParams/);
855
+ await expectDefiRejection(verifyWrapApprove(data, { wrapParams: { tokenName: 'hteth', amount } }), /not a registered ERC-7984 shield pair/);
856
+ });
857
+ it('should reject approve that carries native value', async function () {
858
+ const coin = bitgo.coin('hteth');
859
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
860
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
861
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
862
+ txBuilder.fee({ fee: '10', gasLimit: '100000' });
863
+ txBuilder.counter(1);
864
+ txBuilder.contract(underlying);
865
+ txBuilder.data(defiCalldata('approve(address,uint256)', [wrapper, amount]));
866
+ txBuilder.value('1');
867
+ const txHex = (await txBuilder.build()).toBroadcastFormat();
868
+ await expectDefiRejection(coin.verifyTransaction({
869
+ txParams: { type: 'wrapApprove', wrapParams: { tokenName: 'hteth:cusdt', amount } },
870
+ txPrebuild: { txHex, coin: 'hteth', walletId: 'w' },
871
+ wallet,
872
+ verification: {},
873
+ walletType: 'tss',
874
+ }), /must not carry native value/);
875
+ });
876
+ it('should verify a pendingApproval re-sign where txParams are resolved from the persisted intent only', async function () {
877
+ const coin = bitgo.coin('hteth');
878
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
879
+ // recreateTxRequest() -> signTxRequest() carries no txParams; the intent is the only source.
880
+ const txRequest = { intent: { intentType: 'wrapApprove', tokenName: 'hteth:cusdt', amount } };
881
+ const txParams = (0, sdk_core_1.resolveEffectiveTxParams)(txRequest, undefined);
882
+ const txHex = await buildDefiTxHex(defiCalldata('approve(address,uint256)', [wrapper, amount]), underlying);
883
+ const result = await coin.verifyTransaction({
884
+ txParams: txParams,
885
+ txPrebuild: { txHex, coin: 'hteth', walletId: 'w' },
886
+ wallet,
887
+ verification: {},
888
+ walletType: 'tss',
889
+ });
890
+ result.should.equal(true);
891
+ });
892
+ });
893
+ describe('multisig wrapApprove verification', function () {
894
+ const pair = statics_1.coins.get('hteth:cusdt');
895
+ const wrapper = String(pair.contractAddress);
896
+ const underlying = pair.underlyingErc20Address;
897
+ const amount = '1000000';
898
+ const walletContract = address2;
899
+ // Server-built multisig shape: tx.to = wallet contract,
900
+ // data = sendMultiSig(underlying, 0, approve(wrapper, amount), expireTime, sequenceId, signature)
901
+ const sendMultiSigCalldata = (toAddress, value, innerData) => {
902
+ const types = ['address', 'uint', 'bytes', 'uint', 'uint', 'bytes'];
903
+ const methodId = ethereumjs_abi_1.default.methodID('sendMultiSig', types);
904
+ const encoded = ethereumjs_abi_1.default.rawEncode(types, [
905
+ toAddress,
906
+ new bn_js_1.default(value),
907
+ Buffer.from(innerData.slice(2), 'hex'),
908
+ 1234,
909
+ 1,
910
+ Buffer.alloc(0),
911
+ ]);
912
+ return '0x' + Buffer.concat([methodId, encoded]).toString('hex');
913
+ };
914
+ const verifyMultisigWrapApprove = async (data, opts = {}) => {
915
+ const coin = bitgo.coin('hteth');
916
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
917
+ const wrapParams = opts.wrapParams === null ? undefined : opts.wrapParams ?? { tokenName: 'hteth:cusdt', amount };
918
+ return coin.verifyTransaction({
919
+ txParams: { type: 'wrapApprove', wrapParams },
920
+ txPrebuild: {
921
+ txHex: await buildDefiTxHex(data, opts.to ?? walletContract),
922
+ coin: 'hteth',
923
+ walletId: 'w',
924
+ ...(opts.txPrebuildRecipients ? { recipients: opts.txPrebuildRecipients } : {}),
925
+ },
926
+ wallet,
927
+ verification: {},
928
+ });
929
+ };
930
+ const approveCalldata = (spender, approveAmount) => defiCalldata('approve(address,uint256)', [spender, approveAmount]);
931
+ it('should verify approve(wrapper, amount) wrapped in sendMultiSig', async function () {
932
+ const data = sendMultiSigCalldata(underlying, '0', approveCalldata(wrapper, amount));
933
+ const result = await verifyMultisigWrapApprove(data, {
934
+ txPrebuildRecipients: [{ address: underlying, amount: '0', data: approveCalldata(wrapper, amount) }],
935
+ });
936
+ result.should.equal(true);
937
+ });
938
+ it('should verify approve wrapped in sendMultiSig without prebuild recipients', async function () {
939
+ const data = sendMultiSigCalldata(underlying, '0', approveCalldata(wrapper, amount));
940
+ const result = await verifyMultisigWrapApprove(data);
941
+ result.should.equal(true);
942
+ });
943
+ it('should reject a spender other than the wrapper inside sendMultiSig', async function () {
944
+ await expectDefiRejection(verifyMultisigWrapApprove(sendMultiSigCalldata(underlying, '0', approveCalldata(address2, amount))), /spender does not match the wrapper/);
945
+ });
946
+ it('should reject a mutated amount inside sendMultiSig', async function () {
947
+ await expectDefiRejection(verifyMultisigWrapApprove(sendMultiSigCalldata(underlying, '0', approveCalldata(wrapper, '1000001'))), /amount does not match/);
948
+ });
949
+ it('should reject inner calldata that is not approve', async function () {
950
+ await expectDefiRejection(verifyMultisigWrapApprove(sendMultiSigCalldata(underlying, '0', defiCalldata('transfer(address,uint256)', [address2, amount]))), /approve\(address,uint256\)/);
951
+ });
952
+ it('should reject a sendMultiSig target other than the underlying ERC-20', async function () {
953
+ await expectDefiRejection(verifyMultisigWrapApprove(sendMultiSigCalldata(address2, '0', approveCalldata(wrapper, amount))), /must target the underlying ERC-20/);
954
+ });
955
+ it('should reject native value inside sendMultiSig', async function () {
956
+ await expectDefiRejection(verifyMultisigWrapApprove(sendMultiSigCalldata(underlying, '1', approveCalldata(wrapper, amount))), /must not carry native value/);
957
+ });
958
+ it('should reject when wrapParams is missing or names an unregistered pair', async function () {
959
+ const data = sendMultiSigCalldata(underlying, '0', approveCalldata(wrapper, amount));
960
+ await expectDefiRejection(verifyMultisigWrapApprove(data, { wrapParams: null }), /requires wrapParams/);
961
+ await expectDefiRejection(verifyMultisigWrapApprove(data, { wrapParams: { tokenName: 'hteth', amount } }), /not a registered ERC-7984 shield pair/);
962
+ });
963
+ it('should fail closed on a tx that is not sendMultiSig-wrapped', async function () {
964
+ await expectDefiRejection(verifyMultisigWrapApprove(approveCalldata(wrapper, amount)), /sendMultiSig/);
965
+ });
966
+ it('should reject prebuild recipients that do not mirror the sendMultiSig args in txHex', async function () {
967
+ const data = sendMultiSigCalldata(underlying, '0', approveCalldata(wrapper, amount));
968
+ await expectDefiRejection(verifyMultisigWrapApprove(data, {
969
+ txPrebuildRecipients: [{ address: address2, amount: '0', data: approveCalldata(wrapper, amount) }],
970
+ }), /recipient address does not match the sendMultiSig target/);
971
+ await expectDefiRejection(verifyMultisigWrapApprove(data, {
972
+ txPrebuildRecipients: [{ address: underlying, amount: '0', data: approveCalldata(address2, amount) }],
973
+ }), /recipient data does not match the sendMultiSig calldata/);
974
+ });
975
+ });
976
+ describe('wrapper-directed approve must be declared wrapApprove', function () {
977
+ const pair = statics_1.coins.get('hteth:cusdt');
978
+ const wrapper = String(pair.contractAddress);
979
+ const underlying = pair.underlyingErc20Address;
980
+ const amount = '1000000';
981
+ const verifyAs = async (type, data, to = underlying) => {
982
+ const coin = bitgo.coin('hteth');
983
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
984
+ return coin.verifyTransaction({
985
+ txParams: { type, defiParams: { vaultId: 'vault', amount }, wallet },
986
+ txPrebuild: { txHex: await buildDefiTxHex(data, to), coin: 'hteth', walletId: 'w' },
987
+ wallet,
988
+ verification: {},
989
+ walletType: 'tss',
990
+ });
991
+ };
992
+ ['tokenApproval', 'customTx', 'defiApprove'].forEach((type) => {
993
+ it(`should reject approve(wrapper, amount) on the underlying relabelled as ${type}`, async function () {
994
+ await expectDefiRejection(verifyAs(type, defiCalldata('approve(address,uint256)', [wrapper, amount])), /must be declared as a wrapApprove intent/);
995
+ });
996
+ });
997
+ it('should reject a mutated-amount wrapper approve relabelled as customTx', async function () {
998
+ await expectDefiRejection(verifyAs('customTx', defiCalldata('approve(address,uint256)', [wrapper, '999999999999'])), /must be declared as a wrapApprove intent/);
999
+ });
1000
+ it('should reject a wrapper approve with trailing bytes (an ERC-20 ignores them)', async function () {
1001
+ await expectDefiRejection(verifyAs('customTx', defiCalldata('approve(address,uint256)', [wrapper, amount]) + '00'), /must be declared as a wrapApprove intent/);
1002
+ });
1003
+ it('should not affect approvals of the underlying to other spenders', async function () {
1004
+ (await verifyAs('customTx', defiCalldata('approve(address,uint256)', [address2, amount]))).should.equal(true);
1005
+ (await verifyAs('tokenApproval', defiCalldata('approve(address,uint256)', [address2, amount]))).should.equal(true);
1006
+ });
1007
+ it('should not parse the tx at all when the calldata carries no approve selector', async function () {
1008
+ const coin = bitgo.coin('hteth');
1009
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1010
+ const verifyWith = async (data) => {
1011
+ const txHex = await buildDefiTxHex(data, underlying);
1012
+ // getTransactionBuilder is not part of the coin's public type, so spy through a minimal structural view.
1013
+ const builderSpy = sinon_1.default.spy(coin, 'getTransactionBuilder');
1014
+ try {
1015
+ await coin.verifyTransaction({
1016
+ txParams: { type: 'customTx', wallet },
1017
+ txPrebuild: { txHex, coin: 'hteth', walletId: 'w' },
1018
+ wallet,
1019
+ verification: {},
1020
+ walletType: 'tss',
1021
+ });
1022
+ return builderSpy.callCount;
1023
+ }
1024
+ finally {
1025
+ builderSpy.restore();
1026
+ }
1027
+ };
1028
+ (await verifyWith(defiCalldata('transfer(address,uint256)', [wrapper, amount]))).should.equal(0);
1029
+ (await verifyWith(defiCalldata('approve(address,uint256)', [address2, amount]))).should.equal(1);
1030
+ });
1031
+ it('should leave other declared types untouched for txs that are not a wrapper approve', async function () {
1032
+ // Every type below skips the wrapApprove check and reaches the guard; none of these txs is an approve of a
1033
+ // wrapper, so all must verify exactly as they did before the guard existed.
1034
+ const benign = [
1035
+ ['customTx', defiCalldata('transfer(address,uint256)', [address2, amount]), underlying],
1036
+ ['customTx', defiCalldata('approve(address,uint256)', [address2, amount]), underlying],
1037
+ ['customTx', defiCalldata('approve(address,uint256)', [wrapper, amount]), address2],
1038
+ ['tokenApproval', defiCalldata('approve(address,uint256)', [address2, amount]), underlying],
1039
+ ['tokenApproval', defiCalldata('approve(address,uint256)', [wrapper, amount]), address2],
1040
+ ['acceleration', defiCalldata('transfer(address,uint256)', [address2, amount]), address2],
1041
+ ['fillNonce', '0x', address2],
1042
+ ['enabletoken', defiCalldata('transfer(address,uint256)', [address2, amount]), address2],
1043
+ ];
1044
+ for (const [type, data, to] of benign) {
1045
+ (await verifyAs(type, data, to)).should.equal(true, `${type} to ${to} should still verify`);
1046
+ }
1047
+ });
1048
+ it('should not affect transfers to the underlying or approves of the wrapper on other contracts', async function () {
1049
+ (await verifyAs('customTx', defiCalldata('transfer(address,uint256)', [wrapper, amount]))).should.equal(true);
1050
+ (await verifyAs('customTx', defiCalldata('approve(address,uint256)', [wrapper, amount]), address2)).should.equal(true);
1051
+ });
1052
+ it('should still verify a declared wrapApprove through the full check', async function () {
1053
+ const coin = bitgo.coin('hteth');
1054
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1055
+ const result = await coin.verifyTransaction({
1056
+ txParams: { type: 'wrapApprove', wrapParams: { tokenName: 'hteth:cusdt', amount } },
1057
+ txPrebuild: {
1058
+ txHex: await buildDefiTxHex(defiCalldata('approve(address,uint256)', [wrapper, amount]), underlying),
1059
+ coin: 'hteth',
1060
+ walletId: 'w',
1061
+ },
1062
+ wallet,
1063
+ verification: {},
1064
+ walletType: 'tss',
1065
+ });
1066
+ result.should.equal(true);
1067
+ });
1068
+ });
1069
+ describe('multisig wrapper-directed approve must be declared wrapApprove', function () {
1070
+ const pair = statics_1.coins.get('hteth:cusdt');
1071
+ const wrapper = String(pair.contractAddress);
1072
+ const underlying = pair.underlyingErc20Address;
1073
+ const amount = '1000000';
1074
+ const walletContract = address2;
1075
+ const sendMultiSigCalldata = (toAddress, innerData) => {
1076
+ const types = ['address', 'uint', 'bytes', 'uint', 'uint', 'bytes'];
1077
+ const methodId = ethereumjs_abi_1.default.methodID('sendMultiSig', types);
1078
+ const encoded = ethereumjs_abi_1.default.rawEncode(types, [
1079
+ toAddress,
1080
+ new bn_js_1.default('0'),
1081
+ Buffer.from(innerData.slice(2), 'hex'),
1082
+ 1234,
1083
+ 1,
1084
+ Buffer.alloc(0),
1085
+ ]);
1086
+ return '0x' + Buffer.concat([methodId, encoded]).toString('hex');
1087
+ };
1088
+ const approveCalldata = (spender) => defiCalldata('approve(address,uint256)', [spender, amount]);
1089
+ const verifyAs = async (type, target, innerData) => {
1090
+ const coin = bitgo.coin('hteth');
1091
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1092
+ const recipients = [{ address: target, amount: '0' }];
1093
+ return coin.verifyTransaction({
1094
+ txParams: { type, recipients },
1095
+ txPrebuild: {
1096
+ txHex: await buildDefiTxHex(sendMultiSigCalldata(target, innerData), walletContract),
1097
+ coin: 'hteth',
1098
+ walletId: 'w',
1099
+ recipients,
1100
+ },
1101
+ wallet,
1102
+ verification: {},
1103
+ walletType: 'onchain',
1104
+ });
1105
+ };
1106
+ ['transfer', 'tokenApproval', 'customTx', 'defiApprove'].forEach((type) => {
1107
+ it(`should reject sendMultiSig(approve(wrapper, amount)) on the underlying relabelled as ${type}`, async function () {
1108
+ await expectDefiRejection(verifyAs(type, underlying, approveCalldata(wrapper)), /must be declared as a wrapApprove intent/);
1109
+ });
1110
+ });
1111
+ it('should reject a mutated-amount wrapper approve inside sendMultiSig', async function () {
1112
+ await expectDefiRejection(verifyAs('transfer', underlying, defiCalldata('approve(address,uint256)', [wrapper, '999999999999'])), /must be declared as a wrapApprove intent/);
1113
+ });
1114
+ it('should not affect sendMultiSig approvals of the underlying to other spenders', async function () {
1115
+ (await verifyAs('transfer', underlying, approveCalldata(address1))).should.equal(true);
1116
+ });
1117
+ it('should not affect a sendMultiSig approve of the wrapper aimed at a non-underlying contract', async function () {
1118
+ (await verifyAs('transfer', address1, approveCalldata(wrapper))).should.equal(true);
1119
+ });
1120
+ it('should not affect a plain native sendMultiSig transfer', async function () {
1121
+ (await verifyAs('transfer', address1, '0x')).should.equal(true);
1122
+ });
1123
+ it('should still verify a declared wrapApprove inside sendMultiSig', async function () {
1124
+ const coin = bitgo.coin('hteth');
1125
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1126
+ const result = await coin.verifyTransaction({
1127
+ txParams: { type: 'wrapApprove', wrapParams: { tokenName: 'hteth:cusdt', amount } },
1128
+ txPrebuild: {
1129
+ txHex: await buildDefiTxHex(sendMultiSigCalldata(underlying, approveCalldata(wrapper)), walletContract),
1130
+ coin: 'hteth',
1131
+ walletId: 'w',
1132
+ },
1133
+ wallet,
1134
+ verification: {},
1135
+ walletType: 'onchain',
1136
+ });
1137
+ result.should.equal(true);
1138
+ });
1139
+ });
1140
+ it('should verify TSS transaction with defiDeposit type', async function () {
1141
+ const coin = bitgo.coin('hteth');
1142
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1143
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1144
+ coinSpecific: {
1145
+ baseAddress: baseAddress,
1146
+ },
1147
+ });
1148
+ const txParams = {
1149
+ type: 'defiDeposit',
1150
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10', operationId: 'fakeOperationId' },
1151
+ wallet: wallet,
1152
+ walletPassphrase: 'fakeWalletPassphrase',
1153
+ };
1154
+ const txPrebuild = {
1155
+ txHex: await buildDefiTxHex(defiCalldata('deposit(uint256,address)', ['10', address1])),
1156
+ coin: 'hteth',
1157
+ walletId: 'fakeWalletId',
1158
+ };
1159
+ const verification = {};
1160
+ const isTransactionVerified = await coin.verifyTransaction({
1161
+ txParams: txParams,
1162
+ txPrebuild: txPrebuild,
1163
+ wallet,
1164
+ verification,
1165
+ walletType: 'tss',
1166
+ });
1167
+ isTransactionVerified.should.equal(true);
1168
+ });
1169
+ it('should reject DeFi calldata that redirects funds or grants excess approval', async function () {
1170
+ const coin = bitgo.coin('hteth');
1171
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1172
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
1173
+ txParams: { type, defiParams, wallet },
1174
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
1175
+ wallet,
1176
+ verification: {},
1177
+ walletType: 'tss',
1178
+ });
1179
+ // defiApprove: attacker approve(attacker, MAX_UINT256) disguised as defiApprove
1180
+ await expectDefiRejection(verify('defiApprove', { vaultId: 'vault', amount: '10' }, defiCalldata('approve(address,uint256)', [address2, '1000000000000000000'])), /amount does not match/);
1181
+ // defiDeposit: funds redirected to attacker receiver
1182
+ await expectDefiRejection(verify('defiDeposit', { vaultId: 'vault', amount: '10' }, defiCalldata('deposit(uint256,address)', ['10', address2])), /receiver does not match/);
1183
+ // defiWithdraw: receiver and owner both attacker
1184
+ await expectDefiRejection(verify('defiWithdraw', { vaultId: 'vault', amount: '10' }, defiCalldata('redeem(uint256,address,address)', ['5', address2, address2])), /receiver and owner/);
1185
+ });
1186
+ it('should reject DeFi calldata with wrong selector, wrong owner alone, or wrong deposit amount', async function () {
1187
+ const coin = bitgo.coin('hteth');
1188
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1189
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
1190
+ txParams: { type, defiParams, wallet },
1191
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
1192
+ wallet,
1193
+ verification: {},
1194
+ walletType: 'tss',
1195
+ });
1196
+ const defiParams = { vaultId: 'vault', amount: '10' };
1197
+ // defiApprove with a non-approve selector (transfer disguised as approve)
1198
+ await expectDefiRejection(verify('defiApprove', defiParams, defiCalldata('transfer(address,uint256)', [address2, '10'])), /approve\(address,uint256\)/);
1199
+ // defiDeposit with a non-deposit selector
1200
+ await expectDefiRejection(verify('defiDeposit', defiParams, defiCalldata('approve(address,uint256)', [address1, '10'])), /deposit\(uint256,address\)/);
1201
+ // defiWithdraw with a non-redeem selector
1202
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('approve(address,uint256)', [address1, '10'])), /redeem\(uint256,address,address\)/);
1203
+ // defiWithdraw: receiver ok but owner is attacker
1204
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('redeem(uint256,address,address)', ['10', address1, address2])), /receiver and owner/);
1205
+ // defiWithdraw: receiver and owner ok but shares do not match defiParams.amount
1206
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('redeem(uint256,address,address)', ['999', address1, address1])), /shares do not match/);
1207
+ // defiDeposit: receiver ok but amount mismatch
1208
+ await expectDefiRejection(verify('defiDeposit', defiParams, defiCalldata('deposit(uint256,address)', ['999', address1])), /amount does not match/);
1209
+ });
1210
+ it('should fail closed when defi intent parameters are missing or calldata is short', async function () {
1211
+ const coin = bitgo.coin('hteth');
1212
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1213
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
1214
+ txParams: { type, defiParams, wallet },
1215
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
1216
+ wallet,
1217
+ verification: {},
1218
+ walletType: 'tss',
1219
+ });
1220
+ // Missing defiParams for each defi type -> fail closed
1221
+ await expectDefiRejection(verify('defiApprove', undefined, defiCalldata('approve(address,uint256)', [address1, '10'])), /missing required intent parameters/);
1222
+ await expectDefiRejection(verify('defiDeposit', undefined, defiCalldata('deposit(uint256,address)', ['10', address1])), /missing required intent parameters/);
1223
+ await expectDefiRejection(verify('defiWithdraw', undefined, defiCalldata('redeem(uint256,address,address)', ['5', address1, address1])), /missing required intent parameters/);
1224
+ // Short/empty calldata with no valid selector prefix -> selector mismatch (fail closed)
1225
+ await expectDefiRejection(verify('defiApprove', { vaultId: 'vault', amount: '10' }, '0x'), /approve\(address,uint256\)/);
1226
+ });
1227
+ it('should verify TSS transaction with defiWithdraw type', async function () {
1228
+ const coin = bitgo.coin('hteth');
1229
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
1230
+ const txParams = {
1231
+ type: 'defiWithdraw',
1232
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10' },
1233
+ wallet,
1234
+ };
1235
+ const txPrebuild = {
1236
+ txHex: await buildDefiTxHex(defiCalldata('redeem(uint256,address,address)', ['10', address1, address1])),
1237
+ coin: 'hteth',
1238
+ walletId: 'fakeWalletId',
1239
+ };
1240
+ const isTransactionVerified = await coin.verifyTransaction({
1241
+ txParams: txParams,
1242
+ txPrebuild: txPrebuild,
1243
+ wallet,
1244
+ verification: {},
1245
+ walletType: 'tss',
1246
+ });
1247
+ isTransactionVerified.should.equal(true);
1248
+ });
1249
+ describe('consolidationToBaseAddress verification', function () {
1250
+ it('should verify consolidation when recipient matches base address', async function () {
1251
+ const coin = bitgo.coin('hteth');
1252
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1253
+ // Build a real transaction that sends to the baseAddress
1254
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1255
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1256
+ txBuilder.fee({
1257
+ fee: '10',
1258
+ gasLimit: '21000',
1259
+ });
1260
+ txBuilder.counter(1);
1261
+ txBuilder.contract(baseAddress);
1262
+ txBuilder.value('1000000000000000000');
1263
+ const tx = await txBuilder.build();
1264
+ const txHex = tx.toBroadcastFormat();
1265
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1266
+ coinSpecific: {
1267
+ baseAddress: baseAddress,
1268
+ },
1269
+ });
1270
+ const txParams = {
1271
+ type: 'consolidate',
1272
+ wallet: wallet,
1273
+ walletPassphrase: 'fakeWalletPassphrase',
1274
+ };
1275
+ const txPrebuild = {
1276
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1277
+ txHex: txHex,
1278
+ coin: 'hteth',
1279
+ walletId: 'fakeWalletId',
1280
+ };
1281
+ const verification = {
1282
+ consolidationToBaseAddress: true,
1283
+ };
1284
+ const isTransactionVerified = await coin.verifyTransaction({
1285
+ txParams: txParams,
1286
+ txPrebuild: txPrebuild,
1287
+ wallet,
1288
+ verification,
1289
+ walletType: 'tss',
1290
+ });
1291
+ isTransactionVerified.should.equal(true);
1292
+ });
1293
+ it('should reject consolidation when recipient does not match base address', async function () {
1294
+ const coin = bitgo.coin('hteth');
1295
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1296
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
1297
+ // Build a transaction that sends to a DIFFERENT address (not baseAddress)
1298
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1299
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1300
+ txBuilder.fee({
1301
+ fee: '10',
1302
+ gasLimit: '21000',
1303
+ });
1304
+ txBuilder.counter(1);
1305
+ txBuilder.contract(wrongRecipient);
1306
+ txBuilder.value('1000000000000000000');
1307
+ const tx = await txBuilder.build();
1308
+ const txHex = tx.toBroadcastFormat();
1309
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1310
+ coinSpecific: {
1311
+ baseAddress: baseAddress,
1312
+ },
1313
+ });
1314
+ const txParams = {
1315
+ type: 'consolidate',
1316
+ wallet: wallet,
1317
+ walletPassphrase: 'fakeWalletPassphrase',
1318
+ };
1319
+ const txPrebuild = {
1320
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1321
+ txHex: txHex,
1322
+ coin: 'hteth',
1323
+ walletId: 'fakeWalletId',
1324
+ };
1325
+ const verification = {
1326
+ consolidationToBaseAddress: true,
1327
+ };
1328
+ await coin
1329
+ .verifyTransaction({
1330
+ txParams: txParams,
1331
+ txPrebuild: txPrebuild,
1332
+ wallet,
1333
+ verification,
1334
+ walletType: 'tss',
1335
+ })
1336
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
1337
+ });
1338
+ it('should throw error when txHex is missing for consolidation verification', async function () {
1339
+ const coin = bitgo.coin('hteth');
1340
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1341
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1342
+ coinSpecific: {
1343
+ baseAddress: baseAddress,
1344
+ },
1345
+ });
1346
+ const txParams = {
1347
+ type: 'consolidate',
1348
+ wallet: wallet,
1349
+ walletPassphrase: 'fakeWalletPassphrase',
1350
+ };
1351
+ const txPrebuild = {
1352
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1353
+ // Intentionally missing txHex
1354
+ coin: 'hteth',
1355
+ walletId: 'fakeWalletId',
1356
+ };
1357
+ const verification = {
1358
+ consolidationToBaseAddress: true,
1359
+ };
1360
+ await coin
1361
+ .verifyTransaction({
1362
+ txParams: txParams,
1363
+ txPrebuild: txPrebuild,
1364
+ wallet,
1365
+ verification,
1366
+ walletType: 'tss',
1367
+ })
1368
+ .should.be.rejectedWith('missing txHex in txPrebuild');
1369
+ });
1370
+ it('should verify ERC20 token consolidation when calldata recipient matches base address', async function () {
1371
+ const coin = bitgo.coin('hteth');
1372
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1373
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
1374
+ // Build an ERC20 transfer(address, uint256) tx — mimics what the server returns
1375
+ // for a v6 TSS wallet token consolidation: txJson.to = token contract,
1376
+ // actual recipient is encoded in the 0xa9059cbb calldata
1377
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
1378
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [baseAddress, '10000000']);
1379
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
1380
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1381
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
1382
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
1383
+ txBuilder.counter(1);
1384
+ txBuilder.contract(tokenContractAddress);
1385
+ txBuilder.data(erc20TransferData);
1386
+ const tx = await txBuilder.build();
1387
+ const txHex = tx.toBroadcastFormat();
1388
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1389
+ coinSpecific: { baseAddress },
1390
+ });
1391
+ const isTransactionVerified = await coin.verifyTransaction({
1392
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
1393
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
1394
+ wallet,
1395
+ verification: { consolidationToBaseAddress: true },
1396
+ walletType: 'tss',
1397
+ });
1398
+ isTransactionVerified.should.equal(true);
1399
+ });
1400
+ it('should reject ERC20 token consolidation when calldata recipient does not match base address', async function () {
1401
+ const coin = bitgo.coin('hteth');
1402
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1403
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
1404
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
1405
+ // Build an ERC20 transfer where calldata recipient is a WRONG address
1406
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
1407
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [wrongRecipient, '10000000']);
1408
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
1409
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1410
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
1411
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
1412
+ txBuilder.counter(1);
1413
+ txBuilder.contract(tokenContractAddress);
1414
+ txBuilder.data(erc20TransferData);
1415
+ const tx = await txBuilder.build();
1416
+ const txHex = tx.toBroadcastFormat();
1417
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1418
+ coinSpecific: { baseAddress },
1419
+ });
1420
+ await coin
1421
+ .verifyTransaction({
1422
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
1423
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
1424
+ wallet,
1425
+ verification: { consolidationToBaseAddress: true },
1426
+ walletType: 'tss',
1427
+ })
1428
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
1429
+ });
1430
+ it('should throw error when wallet is missing baseAddress for consolidation verification', async function () {
1431
+ const coin = bitgo.coin('hteth');
1432
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1433
+ // Build a real transaction
1434
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1435
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1436
+ txBuilder.fee({
1437
+ fee: '10',
1438
+ gasLimit: '21000',
1439
+ });
1440
+ txBuilder.counter(1);
1441
+ txBuilder.contract(baseAddress);
1442
+ txBuilder.value('1000000000000000000');
1443
+ const tx = await txBuilder.build();
1444
+ const txHex = tx.toBroadcastFormat();
1445
+ // Wallet without baseAddress
1446
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1447
+ coinSpecific: {},
1448
+ });
1449
+ const txParams = {
1450
+ type: 'consolidate',
1451
+ wallet: wallet,
1452
+ walletPassphrase: 'fakeWalletPassphrase',
1453
+ };
1454
+ const txPrebuild = {
1455
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1456
+ txHex: txHex,
1457
+ coin: 'hteth',
1458
+ walletId: 'fakeWalletId',
1459
+ };
1460
+ const verification = {
1461
+ consolidationToBaseAddress: true,
1462
+ };
1463
+ await coin
1464
+ .verifyTransaction({
1465
+ txParams: txParams,
1466
+ txPrebuild: txPrebuild,
1467
+ wallet,
1468
+ verification,
1469
+ walletType: 'tss',
1470
+ })
1471
+ .should.be.rejectedWith('Unable to determine base address for consolidation');
1472
+ });
1473
+ });
1474
+ });
1475
+ describe('Address Verification', function () {
1476
+ describe('isWalletAddress', function () {
1477
+ it('should verify an address generated using forwarder version 1', async function () {
1478
+ const coin = bitgo.coin('hteth');
1479
+ const keychains = [
1480
+ {
1481
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1482
+ source: 'user',
1483
+ type: 'independent',
1484
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVmsa5SriNrfKZZAcAvRgxh1Augm6s8yoD8gSkq2FdZ8YCdVXUgLjf9QxvdYAJK5UthAmpQshU',
1485
+ },
1486
+ {
1487
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1488
+ source: 'backup',
1489
+ type: 'independent',
1490
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqAU9JRod8huYtyV4NY2oeJXsis7r26L1vmLntf9BcZJe1m4CQNSvYWfwpe1hSpo6J4x6YF1eN',
1491
+ },
1492
+ {
1493
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1494
+ source: 'bitgo',
1495
+ type: 'independent',
1496
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1497
+ },
1498
+ ];
1499
+ const params = {
1500
+ address: '0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae',
1501
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1502
+ coinSpecific: {
1503
+ salt: '0x7',
1504
+ forwarderVersion: 1,
1505
+ },
1506
+ keychains,
1507
+ index: 7,
1508
+ walletVersion: 1,
1509
+ };
1510
+ const isWalletAddr = await coin.isWalletAddress(params);
1511
+ isWalletAddr.should.equal(true);
1512
+ });
1513
+ it('should verify an address generated using forwarder version 2', async function () {
1514
+ const coin = bitgo.coin('hteth');
1515
+ const keychains = [
1516
+ {
1517
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1518
+ source: 'user',
1519
+ type: 'independent',
1520
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1521
+ },
1522
+ {
1523
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1524
+ source: 'backup',
1525
+ type: 'independent',
1526
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1527
+ },
1528
+ {
1529
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1530
+ source: 'bitgo',
1531
+ type: 'independent',
1532
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1533
+ },
1534
+ ];
1535
+ const params = {
1536
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1537
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1538
+ coinSpecific: {
1539
+ salt: '0x17',
1540
+ forwarderVersion: 2,
1541
+ },
1542
+ keychains,
1543
+ index: 23,
1544
+ walletVersion: 2,
1545
+ };
1546
+ const isWalletAddr = await coin.isWalletAddress(params);
1547
+ isWalletAddr.should.equal(true);
1548
+ });
1549
+ it('should verify a wallet version 5 forwarder version 4', async function () {
1550
+ const coin = bitgo.coin('hteth');
1551
+ const keychains = [
1552
+ {
1553
+ id: '691e242d93f8d7ad0705887449763c96',
1554
+ source: 'user',
1555
+ type: 'tss',
1556
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1557
+ },
1558
+ {
1559
+ id: '691e242df8b6323d4b08df366864af66',
1560
+ source: 'backup',
1561
+ type: 'tss',
1562
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1563
+ },
1564
+ {
1565
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1566
+ source: 'bitgo',
1567
+ type: 'tss',
1568
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1569
+ },
1570
+ ];
1571
+ const params = {
1572
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1573
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1574
+ coinSpecific: {
1575
+ salt: '0x75',
1576
+ forwarderVersion: 4,
1577
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1578
+ },
1579
+ keychains,
1580
+ index: 117,
1581
+ walletVersion: 5,
1582
+ };
1583
+ const isWalletAddr = await coin.isWalletAddress(params);
1584
+ isWalletAddr.should.equal(true);
1585
+ });
1586
+ it('should verify a wallet version 6 forwarder version 5', async function () {
1587
+ const coin = bitgo.coin('hteth');
1588
+ const keychains = [
1589
+ {
1590
+ id: '691f630e0c56098288a9b7fa107db144',
1591
+ source: 'user',
1592
+ type: 'tss',
1593
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1594
+ },
1595
+ {
1596
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1597
+ source: 'backup',
1598
+ type: 'tss',
1599
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1600
+ },
1601
+ {
1602
+ id: '691f630d56735e5eb61b06e353fe7639',
1603
+ source: 'bitgo',
1604
+ type: 'tss',
1605
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1606
+ },
1607
+ ];
1608
+ const params = {
1609
+ address: '0xa33f0975f53cdcfcc0cb564d25fb5be03b0651cf',
1610
+ baseAddress: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1611
+ coinSpecific: {
1612
+ forwarderVersion: 5,
1613
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1614
+ },
1615
+ keychains,
1616
+ index: 7,
1617
+ walletVersion: 6,
1618
+ };
1619
+ const isWalletAddr = await coin.isWalletAddress(params);
1620
+ isWalletAddr.should.equal(true);
1621
+ });
1622
+ it('should reject when actual address differs from expected address', async function () {
1623
+ const coin = bitgo.coin('hteth');
1624
+ const params = {
1625
+ address: '0x28904591f735994f050804fda3b61b813b16e04c',
1626
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1627
+ walletVersion: 1,
1628
+ coinSpecific: {
1629
+ salt: '0xc5a',
1630
+ forwarderVersion: 1,
1631
+ },
1632
+ };
1633
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.UnexpectedAddressError);
1634
+ });
1635
+ it('should reject if coinSpecific field is not an object', async function () {
1636
+ const coin = bitgo.coin('teth');
1637
+ const params = {
1638
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1639
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1640
+ };
1641
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressVerificationObjectPropertyError);
1642
+ });
1643
+ it('should reject if the derived address is in invalid format', async function () {
1644
+ const coin = bitgo.coin('teth');
1645
+ const params = {
1646
+ address: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1647
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1648
+ coinSpecific: {
1649
+ salt: '0xc5a',
1650
+ forwarderVersion: 1,
1651
+ },
1652
+ };
1653
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1654
+ });
1655
+ it('should reject if base address is undefined', async function () {
1656
+ const coin = bitgo.coin('teth');
1657
+ const params = {
1658
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1659
+ coinSpecific: {
1660
+ salt: '0xc5a',
1661
+ forwarderVersion: 1,
1662
+ },
1663
+ };
1664
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1665
+ });
1666
+ it('should reject if base address is in invalid format', async function () {
1667
+ const coin = bitgo.coin('teth');
1668
+ const params = {
1669
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1670
+ baseAddress: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1671
+ coinSpecific: {
1672
+ salt: '0xc5a',
1673
+ forwarderVersion: 1,
1674
+ },
1675
+ };
1676
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1677
+ });
1678
+ describe('MPC wallet addresses', function () {
1679
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1680
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1681
+ const keychains = [
1682
+ { pub: 'user_pub', commonKeychain },
1683
+ { pub: 'backup_pub', commonKeychain },
1684
+ { pub: 'bitgo_pub', commonKeychain },
1685
+ ];
1686
+ it('should verify an MPC wallet address with forwarder version 3', async function () {
1687
+ const coin = bitgo.coin('teth');
1688
+ const params = {
1689
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1690
+ coinSpecific: {
1691
+ forwarderVersion: 3,
1692
+ },
1693
+ keychains,
1694
+ index: 0,
1695
+ walletVersion: 3,
1696
+ };
1697
+ const isWalletAddr = await coin.isWalletAddress(params);
1698
+ isWalletAddr.should.equal(true);
1699
+ });
1700
+ it('should verify an MPC wallet address with forwarder version 5', async function () {
1701
+ const coin = bitgo.coin('teth');
1702
+ const params = {
1703
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1704
+ coinSpecific: {
1705
+ forwarderVersion: 5,
1706
+ },
1707
+ keychains,
1708
+ index: 0,
1709
+ walletVersion: 6,
1710
+ };
1711
+ const isWalletAddr = await coin.isWalletAddress(params);
1712
+ isWalletAddr.should.equal(true);
1713
+ });
1714
+ it('should reject MPC wallet address with wrong address', async function () {
1715
+ const coin = bitgo.coin('teth');
1716
+ const params = {
1717
+ address: '0x0000000000000000000000000000000000000001',
1718
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1719
+ coinSpecific: {
1720
+ forwarderVersion: 3,
1721
+ },
1722
+ keychains,
1723
+ index: 0,
1724
+ walletVersion: 3,
1725
+ };
1726
+ const isWalletAddr = await coin.isWalletAddress(params);
1727
+ isWalletAddr.should.equal(false);
1728
+ });
1729
+ it('should reject MPC wallet address with invalid address format', async function () {
1730
+ const coin = bitgo.coin('teth');
1731
+ const params = {
1732
+ address: '0xinvalid',
1733
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1734
+ coinSpecific: {
1735
+ forwarderVersion: 3,
1736
+ },
1737
+ keychains,
1738
+ index: 0,
1739
+ walletVersion: 3,
1740
+ };
1741
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1742
+ });
1743
+ it('should reject if keychains are missing for MPC wallet', async function () {
1744
+ const coin = bitgo.coin('teth');
1745
+ const params = {
1746
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1747
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1748
+ coinSpecific: {
1749
+ forwarderVersion: 3,
1750
+ },
1751
+ index: 0,
1752
+ walletVersion: 3,
1753
+ };
1754
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1755
+ });
1756
+ it('should reject if commonKeychain is missing for MPC wallet', async function () {
1757
+ const coin = bitgo.coin('teth');
1758
+ const invalidKeychains = [{ pub: 'user_pub' }, { pub: 'backup_pub' }, { pub: 'bitgo_pub' }];
1759
+ const params = {
1760
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1761
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1762
+ coinSpecific: {
1763
+ forwarderVersion: 3,
1764
+ },
1765
+ keychains: invalidKeychains,
1766
+ index: 0,
1767
+ walletVersion: 3,
1768
+ };
1769
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1770
+ });
1771
+ });
1772
+ describe('deriveAddress (MPC)', function () {
1773
+ // Same vector as the MPC isWalletAddress tests above:
1774
+ // commonKeychain @ index 0 -> 0x01153f3adfe454a72589ca9ef74f013c19e54961
1775
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1776
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1777
+ const keychains = [
1778
+ { pub: 'user_pub', commonKeychain },
1779
+ { pub: 'backup_pub', commonKeychain },
1780
+ { pub: 'bitgo_pub', commonKeychain },
1781
+ ];
1782
+ it('should derive the expected MPC address for a commonKeychain at index 0', async function () {
1783
+ const coin = bitgo.coin('teth');
1784
+ const result = await coin.deriveAddress({ keychains, index: 0, walletVersion: 3 });
1785
+ result.address.should.equal('0x01153f3adfe454a72589ca9ef74f013c19e54961');
1786
+ result.index.should.equal(0);
1787
+ assert_1.default.strictEqual(result.derivationPath, 'm/0');
1788
+ });
1789
+ it('round-trips with isWalletAddress (derived address verifies as true)', async function () {
1790
+ const coin = bitgo.coin('teth');
1791
+ const derived = await coin.deriveAddress({ keychains, index: 3, walletVersion: 6 });
1792
+ const verified = await coin.isWalletAddress({
1793
+ address: derived.address,
1794
+ coinSpecific: { forwarderVersion: 5 },
1795
+ keychains,
1796
+ index: 3,
1797
+ walletVersion: 6,
1798
+ });
1799
+ verified.should.equal(true);
1800
+ });
1801
+ it('should throw when neither MPC nor forwarder inputs are provided', async function () {
1802
+ const coin = bitgo.coin('teth');
1803
+ // walletVersion 1 with no coinSpecific.forwarderVersion and no baseAddress is ambiguous
1804
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains, index: 0, walletVersion: 1 }), /could not determine an ETH derivation strategy/);
1805
+ });
1806
+ it('should throw if keychains are missing', async function () {
1807
+ const coin = bitgo.coin('teth');
1808
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains: [], index: 0, walletVersion: 3 }), /keychains/);
1809
+ });
1810
+ });
1811
+ describe('deriveAddress (forwarder)', function () {
1812
+ // Same vectors as the forwarder isWalletAddress tests above (coin: hteth).
1813
+ // salt == index for BitGo forwarders, so deriving by index reproduces the address.
1814
+ it('derives the exact v1 forwarder address and round-trips', async function () {
1815
+ const coin = bitgo.coin('hteth');
1816
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1817
+ const result = await coin.deriveAddress({
1818
+ baseAddress,
1819
+ index: 7,
1820
+ walletVersion: 1,
1821
+ coinSpecific: { forwarderVersion: 1 },
1822
+ });
1823
+ result.address.should.equal('0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae');
1824
+ const verified = await coin.isWalletAddress({
1825
+ address: result.address,
1826
+ baseAddress,
1827
+ index: 7,
1828
+ walletVersion: 1,
1829
+ coinSpecific: { salt: '0x7', forwarderVersion: 1 },
1830
+ });
1831
+ verified.should.equal(true);
1832
+ });
1833
+ it('derives the exact v2 forwarder address', async function () {
1834
+ const coin = bitgo.coin('hteth');
1835
+ const result = await coin.deriveAddress({
1836
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1837
+ index: 23,
1838
+ walletVersion: 2,
1839
+ coinSpecific: { forwarderVersion: 2 },
1840
+ });
1841
+ result.address.should.equal('0xf636ceddffe41d106586875c0e56dc8feb6268f7');
1842
+ });
1843
+ it('derives the exact v4 forwarder address (wallet v5, needs feeAddress)', async function () {
1844
+ const coin = bitgo.coin('hteth');
1845
+ const result = await coin.deriveAddress({
1846
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1847
+ index: 117,
1848
+ walletVersion: 5,
1849
+ coinSpecific: { forwarderVersion: 4, feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09' },
1850
+ });
1851
+ result.address.should.equal('0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d');
1852
+ });
1853
+ it('throws if baseAddress is missing for a forwarder', async function () {
1854
+ const coin = bitgo.coin('hteth');
1855
+ await assert_1.default.rejects(async () => coin.deriveAddress({ index: 7, walletVersion: 1, coinSpecific: { forwarderVersion: 1 } }), /baseAddress is required/);
1856
+ });
1857
+ it('throws if feeAddress is missing for a v4 forwarder', async function () {
1858
+ const coin = bitgo.coin('hteth');
1859
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1860
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1861
+ index: 117,
1862
+ walletVersion: 5,
1863
+ coinSpecific: { forwarderVersion: 4 },
1864
+ }), /feeAddress is required/);
1865
+ });
1866
+ it('throws for forwarder version 0 (not derivable)', async function () {
1867
+ const coin = bitgo.coin('hteth');
1868
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1869
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1870
+ index: 0,
1871
+ walletVersion: 1,
1872
+ coinSpecific: { forwarderVersion: 0 },
1873
+ }), /version 0 addresses cannot be derived/);
1874
+ });
1875
+ });
1876
+ describe('Base Address Verification', function () {
1877
+ it('should verify base address for wallet version 6 (TSS)', async function () {
1878
+ const coin = bitgo.coin('hteth');
1879
+ const keychains = [
1880
+ {
1881
+ id: '691f630e0c56098288a9b7fa107db144',
1882
+ source: 'user',
1883
+ type: 'tss',
1884
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1885
+ },
1886
+ {
1887
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1888
+ source: 'backup',
1889
+ type: 'tss',
1890
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1891
+ },
1892
+ {
1893
+ id: '691f630d56735e5eb61b06e353fe7639',
1894
+ source: 'bitgo',
1895
+ type: 'tss',
1896
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1897
+ },
1898
+ ];
1899
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1900
+ const params = {
1901
+ address: baseAddress,
1902
+ baseAddress: baseAddress,
1903
+ coinSpecific: {
1904
+ salt: '0x0',
1905
+ forwarderVersion: 5,
1906
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1907
+ },
1908
+ keychains,
1909
+ index: 0,
1910
+ walletVersion: 6,
1911
+ };
1912
+ const isWalletAddr = await coin.isWalletAddress(params);
1913
+ isWalletAddr.should.equal(true);
1914
+ });
1915
+ it('should verify base address for wallet version 5 (TSS)', async function () {
1916
+ const coin = bitgo.coin('hteth');
1917
+ const keychains = [
1918
+ {
1919
+ id: '691e242d93f8d7ad0705887449763c96',
1920
+ source: 'user',
1921
+ type: 'tss',
1922
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1923
+ },
1924
+ {
1925
+ id: '691e242df8b6323d4b08df366864af66',
1926
+ source: 'backup',
1927
+ type: 'tss',
1928
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1929
+ },
1930
+ {
1931
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1932
+ source: 'bitgo',
1933
+ type: 'tss',
1934
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1935
+ },
1936
+ ];
1937
+ const baseAddress = '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11';
1938
+ const params = {
1939
+ address: baseAddress,
1940
+ baseAddress: baseAddress,
1941
+ coinSpecific: {
1942
+ salt: '0x0',
1943
+ forwarderVersion: 4,
1944
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1945
+ },
1946
+ keychains,
1947
+ index: 0,
1948
+ walletVersion: 5,
1949
+ };
1950
+ const isWalletAddr = await coin.isWalletAddress(params);
1951
+ isWalletAddr.should.equal(true);
1952
+ });
1953
+ it('should reject base address verification with non-zero index', async function () {
1954
+ const coin = bitgo.coin('hteth');
1955
+ const keychains = [
1956
+ {
1957
+ id: '691f630e0c56098288a9b7fa107db144',
1958
+ source: 'user',
1959
+ type: 'tss',
1960
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1961
+ },
1962
+ {
1963
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1964
+ source: 'backup',
1965
+ type: 'tss',
1966
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1967
+ },
1968
+ {
1969
+ id: '691f630d56735e5eb61b06e353fe7639',
1970
+ source: 'bitgo',
1971
+ type: 'tss',
1972
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1973
+ },
1974
+ ];
1975
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1976
+ const params = {
1977
+ address: baseAddress,
1978
+ baseAddress: baseAddress,
1979
+ coinSpecific: {
1980
+ salt: '0x0',
1981
+ forwarderVersion: 5,
1982
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1983
+ },
1984
+ keychains,
1985
+ index: 5, // Wrong index - should be 0 for base address
1986
+ walletVersion: 6,
1987
+ };
1988
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), /Base address verification requires index 0, but got index 5/);
1989
+ });
1990
+ it('should reject base address verification with wrong address', async function () {
1991
+ const coin = bitgo.coin('hteth');
1992
+ const keychains = [
1993
+ {
1994
+ id: '691f630e0c56098288a9b7fa107db144',
1995
+ source: 'user',
1996
+ type: 'tss',
1997
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1998
+ },
1999
+ {
2000
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
2001
+ source: 'backup',
2002
+ type: 'tss',
2003
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2004
+ },
2005
+ {
2006
+ id: '691f630d56735e5eb61b06e353fe7639',
2007
+ source: 'bitgo',
2008
+ type: 'tss',
2009
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2010
+ },
2011
+ ];
2012
+ const wrongAddress = '0x0000000000000000000000000000000000000001';
2013
+ const actualBaseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
2014
+ const params = {
2015
+ address: wrongAddress,
2016
+ baseAddress: actualBaseAddress,
2017
+ coinSpecific: {
2018
+ salt: '0x0',
2019
+ forwarderVersion: 5,
2020
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2021
+ },
2022
+ keychains,
2023
+ index: 0,
2024
+ walletVersion: 6,
2025
+ };
2026
+ const isWalletAddr = await coin.isWalletAddress(params);
2027
+ isWalletAddr.should.equal(false);
2028
+ });
2029
+ it('should verify base address for wallet version 2 (BIP32) using wallet factory', async function () {
2030
+ const coin = bitgo.coin('hteth');
2031
+ const baseAddress = '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4';
2032
+ const walletSalt = '0x2';
2033
+ const keychains = [
2034
+ {
2035
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
2036
+ source: 'user',
2037
+ type: 'independent',
2038
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
2039
+ },
2040
+ {
2041
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
2042
+ source: 'backup',
2043
+ type: 'independent',
2044
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
2045
+ },
2046
+ {
2047
+ id: '68b9ec587d0ba1c7440de551068c36a7',
2048
+ source: 'bitgo',
2049
+ type: 'independent',
2050
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2051
+ },
2052
+ ];
2053
+ const params = {
2054
+ address: baseAddress,
2055
+ baseAddress: baseAddress,
2056
+ coinSpecific: {
2057
+ salt: walletSalt,
2058
+ forwarderVersion: 2,
2059
+ },
2060
+ keychains: keychains,
2061
+ index: 0,
2062
+ walletVersion: 2,
2063
+ };
2064
+ const isWalletAddr = await coin.isWalletAddress(params);
2065
+ isWalletAddr.should.equal(true);
2066
+ });
2067
+ it('should verify base address for wallet version 1 (BIP32) using wallet factory', async function () {
2068
+ const coin = bitgo.coin('hteth');
2069
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
2070
+ const walletSalt = '0x5';
2071
+ const keychains = [
2072
+ {
2073
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
2074
+ source: 'user',
2075
+ type: 'independent',
2076
+ ethAddress: '0xf45dadce751a317957f2a247ff37cb764b97620d',
2077
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVm...',
2078
+ },
2079
+ {
2080
+ id: '691f638f0b74e73b1f440ea4aceda87e',
2081
+ source: 'backup',
2082
+ type: 'independent',
2083
+ ethAddress: '0x5bdf3ae1d2c2fadeeb70a45872bf4f4252312b55',
2084
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqA...',
2085
+ },
2086
+ {
2087
+ id: '68b9ec587d0ba1c7440de551068c36a7',
2088
+ source: 'bitgo',
2089
+ type: 'independent',
2090
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2091
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79Hok...',
2092
+ },
2093
+ ];
2094
+ const params = {
2095
+ address: baseAddress,
2096
+ baseAddress: baseAddress,
2097
+ coinSpecific: {
2098
+ salt: walletSalt,
2099
+ forwarderVersion: 1,
2100
+ },
2101
+ keychains: keychains,
2102
+ index: 0,
2103
+ walletVersion: 1,
2104
+ };
2105
+ const isWalletAddr = await coin.isWalletAddress(params);
2106
+ isWalletAddr.should.equal(true);
2107
+ });
2108
+ });
2109
+ });
2110
+ });
2111
+ describe('Address Creation', function () {
2112
+ it('should pass walletVersion 6 to isWalletAddress during address creation', async function () {
2113
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
2114
+ const ethCoin = bitgo.coin('hteth');
2115
+ const walletDataV6 = {
2116
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
2117
+ coinSpecific: {
2118
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2119
+ walletVersion: 6,
2120
+ },
2121
+ coin: 'hteth',
2122
+ keys: [
2123
+ '598f606cd8fc24710d2ebad89dce86c2',
2124
+ '598f606cc8e43aef09fcb785221d9dd2',
2125
+ '5935d59cf660764331bafcade1855fd7',
2126
+ ],
2127
+ receiveAddress: {
2128
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2129
+ },
2130
+ };
2131
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
2132
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
2133
+ // Mock keychain requests
2134
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
2135
+ id: '598f606cd8fc24710d2ebad89dce86c2',
2136
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
2137
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2138
+ source: 'user',
2139
+ type: 'tss',
2140
+ });
2141
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
2142
+ id: '598f606cc8e43aef09fcb785221d9dd2',
2143
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
2144
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2145
+ source: 'backup',
2146
+ type: 'tss',
2147
+ });
2148
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
2149
+ id: '5935d59cf660764331bafcade1855fd7',
2150
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
2151
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2152
+ source: 'bitgo',
2153
+ type: 'tss',
2154
+ });
2155
+ // Mock address creation API
2156
+ (0, nock_1.default)(bgUrl)
2157
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
2158
+ .reply(200, {
2159
+ id: '638a48c6c3dba40007a3497fa49a080c',
2160
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
2161
+ chain: 0,
2162
+ index: 0,
2163
+ coin: 'hteth',
2164
+ wallet: ethWalletV6.id(),
2165
+ coinSpecific: {
2166
+ forwarderVersion: 4,
2167
+ salt: '0x0',
2168
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2169
+ },
2170
+ });
2171
+ await ethWalletV6.createAddress({ chain: 0 });
2172
+ isWalletAddressSpy.calledOnce.should.be.true();
2173
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
2174
+ calledParams.should.have.property('walletVersion', 6);
2175
+ });
2176
+ it('should pass walletVersion 5 to isWalletAddress during address creation', async function () {
2177
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
2178
+ const ethCoin = bitgo.coin('hteth');
2179
+ const walletDataV5 = {
2180
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
2181
+ coinSpecific: {
2182
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
2183
+ walletVersion: 5,
2184
+ },
2185
+ coin: 'hteth',
2186
+ keys: [
2187
+ '598f606cd8fc24710d2ebad89dce86c2',
2188
+ '598f606cc8e43aef09fcb785221d9dd2',
2189
+ '5935d59cf660764331bafcade1855fd7',
2190
+ ],
2191
+ receiveAddress: {
2192
+ address: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
2193
+ },
2194
+ };
2195
+ const ethWalletV5 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV5);
2196
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
2197
+ // Mock keychain requests
2198
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
2199
+ id: '598f606cd8fc24710d2ebad89dce86c2',
2200
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
2201
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
2202
+ source: 'user',
2203
+ type: 'tss',
2204
+ });
2205
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
2206
+ id: '598f606cc8e43aef09fcb785221d9dd2',
2207
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
2208
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
2209
+ source: 'backup',
2210
+ type: 'tss',
2211
+ });
2212
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
2213
+ id: '5935d59cf660764331bafcade1855fd7',
2214
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
2215
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
2216
+ source: 'bitgo',
2217
+ type: 'tss',
2218
+ });
2219
+ // Mock address creation API
2220
+ (0, nock_1.default)(bgUrl)
2221
+ .post(`/api/v2/hteth/wallet/${ethWalletV5.id()}/address`)
2222
+ .reply(200, {
2223
+ id: '638a48c6c3dba40007a3497fa49a080c',
2224
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
2225
+ chain: 0,
2226
+ index: 117,
2227
+ coin: 'hteth',
2228
+ wallet: ethWalletV5.id(),
2229
+ coinSpecific: {
2230
+ forwarderVersion: 4,
2231
+ salt: '0x75',
2232
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2233
+ },
2234
+ });
2235
+ await ethWalletV5.createAddress({ chain: 0 });
2236
+ // Verify isWalletAddress was called with walletVersion 5
2237
+ isWalletAddressSpy.calledOnce.should.be.true();
2238
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
2239
+ calledParams.should.have.property('walletVersion', 5);
2240
+ });
2241
+ it('should pass walletVersion 2 to isWalletAddress during address creation', async function () {
2242
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
2243
+ const ethCoin = bitgo.coin('hteth');
2244
+ const walletDataV2 = {
2245
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
2246
+ coinSpecific: {
2247
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
2248
+ walletVersion: 2,
2249
+ },
2250
+ coin: 'hteth',
2251
+ keys: [
2252
+ '598f606cd8fc24710d2ebad89dce86c2',
2253
+ '598f606cc8e43aef09fcb785221d9dd2',
2254
+ '5935d59cf660764331bafcade1855fd7',
2255
+ ],
2256
+ receiveAddress: {
2257
+ address: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
2258
+ },
2259
+ };
2260
+ const ethWalletV2 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV2);
2261
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
2262
+ // Mock keychain requests
2263
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
2264
+ id: '598f606cd8fc24710d2ebad89dce86c2',
2265
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
2266
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
2267
+ source: 'user',
2268
+ type: 'independent',
2269
+ });
2270
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
2271
+ id: '598f606cc8e43aef09fcb785221d9dd2',
2272
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
2273
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
2274
+ source: 'backup',
2275
+ type: 'independent',
2276
+ });
2277
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
2278
+ id: '5935d59cf660764331bafcade1855fd7',
2279
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
2280
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2281
+ source: 'bitgo',
2282
+ type: 'independent',
2283
+ });
2284
+ // Mock address creation API
2285
+ (0, nock_1.default)(bgUrl)
2286
+ .post(`/api/v2/hteth/wallet/${ethWalletV2.id()}/address`)
2287
+ .reply(200, {
2288
+ id: '638a48c6c3dba40007a3497fa49a080c',
2289
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
2290
+ chain: 0,
2291
+ index: 23,
2292
+ coin: 'hteth',
2293
+ wallet: ethWalletV2.id(),
2294
+ coinSpecific: {
2295
+ forwarderVersion: 2,
2296
+ salt: '0x17',
2297
+ },
2298
+ });
2299
+ await ethWalletV2.createAddress({ chain: 0 });
2300
+ // Verify isWalletAddress was called with walletVersion 2
2301
+ isWalletAddressSpy.calledOnce.should.be.true();
2302
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
2303
+ calledParams.should.have.property('walletVersion', 2);
2304
+ });
2305
+ it('should fail v6 address creation if walletVersion was not passed (simulates old bug)', async function () {
2306
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
2307
+ const ethCoin = bitgo.coin('hteth');
2308
+ const walletDataV6 = {
2309
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
2310
+ coinSpecific: {
2311
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2312
+ walletVersion: 6,
2313
+ },
2314
+ coin: 'hteth',
2315
+ keys: [
2316
+ '598f606cd8fc24710d2ebad89dce86c2',
2317
+ '598f606cc8e43aef09fcb785221d9dd2',
2318
+ '5935d59cf660764331bafcade1855fd7',
2319
+ ],
2320
+ receiveAddress: {
2321
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2322
+ },
2323
+ };
2324
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
2325
+ // Stub isWalletAddress to simulate the OLD bug where walletVersion was not passed
2326
+ const originalIsWalletAddress = ethCoin.isWalletAddress.bind(ethCoin);
2327
+ const isWalletAddressStub = sinon_1.default.stub(ethCoin, 'isWalletAddress').callsFake(async (params) => {
2328
+ // Remove walletVersion to simulate the old bug
2329
+ const paramsWithoutWalletVersion = { ...params };
2330
+ delete paramsWithoutWalletVersion.walletVersion;
2331
+ return originalIsWalletAddress(paramsWithoutWalletVersion);
2332
+ });
2333
+ // Mock keychain requests
2334
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
2335
+ id: '598f606cd8fc24710d2ebad89dce86c2',
2336
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
2337
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2338
+ source: 'user',
2339
+ type: 'tss',
2340
+ });
2341
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
2342
+ id: '598f606cc8e43aef09fcb785221d9dd2',
2343
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
2344
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2345
+ source: 'backup',
2346
+ type: 'tss',
2347
+ });
2348
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
2349
+ id: '5935d59cf660764331bafcade1855fd7',
2350
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
2351
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2352
+ source: 'bitgo',
2353
+ type: 'tss',
2354
+ });
2355
+ // Mock address creation API
2356
+ (0, nock_1.default)(bgUrl)
2357
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
2358
+ .reply(200, {
2359
+ id: '638a48c6c3dba40007a3497fa49a080c',
2360
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
2361
+ chain: 0,
2362
+ index: 0,
2363
+ coin: 'hteth',
2364
+ wallet: ethWalletV6.id(),
2365
+ coinSpecific: {
2366
+ forwarderVersion: 4,
2367
+ salt: '0x0',
2368
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2369
+ },
2370
+ });
2371
+ // Without walletVersion, address creation should fail because
2372
+ // the code doesn't know to use TSS verification for v6 wallets
2373
+ await assert_1.default.rejects(async () => ethWalletV6.createAddress({ chain: 0 }), sdk_core_1.UnexpectedAddressError);
2374
+ isWalletAddressStub.restore();
2375
+ });
2376
+ });
2377
+ describe('EVM Cross Chain Recovery', function () {
2378
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2379
+ it('should build a recovery transaction for hot wallet', async function () {
2380
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
2381
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
2382
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
2383
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
2384
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
2385
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
2386
+ const destinationAddress = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
2387
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
2388
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
2389
+ const basecoin = bitgo.coin('hteth');
2390
+ (0, nock_1.default)(baseUrl)
2391
+ .get('/api')
2392
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
2393
+ .reply(200, mockData.getTxListResponse);
2394
+ (0, nock_1.default)(baseUrl)
2395
+ .get('/api')
2396
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
2397
+ .reply(200, mockData.getBalanceResponse);
2398
+ (0, nock_1.default)(baseUrl)
2399
+ .get('/api')
2400
+ .query(mockData.getBalanceRequest(walletContractAddress))
2401
+ .reply(200, mockData.getBalanceResponse);
2402
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2403
+ const spy = sinon_1.default.spy(src_1.TransactionBuilder.prototype, 'coinUsesNonPackedEncodingForTxData');
2404
+ await basecoin.recover({
2405
+ userKey: userKey,
2406
+ backupKey: '',
2407
+ walletPassphrase: walletPassphrase,
2408
+ walletContractAddress: walletContractAddress,
2409
+ bitgoFeeAddress: bitgoFeeAddress,
2410
+ recoveryDestination: destinationAddress,
2411
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2412
+ gasLimit: 500000,
2413
+ bitgoDestinationAddress: bitgoDestinationAddress,
2414
+ intendedChain: 'tarbeth',
2415
+ });
2416
+ (0, assert_1.default)(spy.returned(true));
2417
+ });
2418
+ it('should throw ErrorNoInputToRecover when the multisig wallet has no funds', async function () {
2419
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
2420
+ const basecoin = bitgo.coin('hteth');
2421
+ const nonceStub = sinon_1.default.stub(basecoin, 'getAddressNonce').resolves(0);
2422
+ const isSignerStub = sinon_1.default.stub(basecoin, 'queryIsWalletSigner').resolves(true);
2423
+ const balanceStub = sinon_1.default.stub(basecoin, 'queryAddressBalance');
2424
+ balanceStub.onFirstCall().resolves(new bn_js_1.default('99999999999999999999'));
2425
+ balanceStub.onSecondCall().resolves(new bn_js_1.default('0'));
2426
+ try {
2427
+ await basecoin
2428
+ .recover({
2429
+ userKey: params.userKey,
2430
+ backupKey: params.backupKey,
2431
+ walletPassphrase: params.walletPassphrase,
2432
+ walletContractAddress: params.walletContractAddress,
2433
+ recoveryDestination: params.recoveryDestination,
2434
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2435
+ gasLimit: 500000,
2436
+ intendedChain: params.intendedChain,
2437
+ })
2438
+ .should.be.rejectedWith(sdk_core_1.ErrorNoInputToRecover);
2439
+ }
2440
+ finally {
2441
+ nonceStub.restore();
2442
+ isSignerStub.restore();
2443
+ balanceStub.restore();
2444
+ }
2445
+ });
2446
+ describe('Non-BitGo Recovery for Hot Wallets (MPCv2)', function () {
2447
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2448
+ let bitgo;
2449
+ let basecoin;
2450
+ before(function () {
2451
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2452
+ basecoin = bitgo.coin('hteth');
2453
+ });
2454
+ it('should build a recovery transaction for MPCv2 kind of hot wallets', async function () {
2455
+ (0, nock_1.default)(baseUrl)
2456
+ .get('/api')
2457
+ .query(mockData.getTxListRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
2458
+ .reply(200, mockData.getTxListResponse);
2459
+ (0, nock_1.default)(baseUrl)
2460
+ .get('/api')
2461
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
2462
+ .reply(200, mockData.getBalanceResponse);
2463
+ (0, nock_1.default)(baseUrl)
2464
+ .get('/api')
2465
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().walletContractAddress))
2466
+ .reply(200, mockData.getBalanceResponse);
2467
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2468
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
2469
+ const transaction = await basecoin.recover({
2470
+ userKey: params.userKey,
2471
+ backupKey: params.backupKey,
2472
+ walletPassphrase: params.walletPassphrase,
2473
+ walletContractAddress: params.walletContractAddress,
2474
+ bitgoFeeAddress: params.bitgoFeeAddress,
2475
+ recoveryDestination: params.recoveryDestination,
2476
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2477
+ gasLimit: 500000,
2478
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2479
+ intendedChain: params.intendedChain,
2480
+ });
2481
+ should_1.default.exist(transaction);
2482
+ transaction.should.have.property('txHex');
2483
+ });
2484
+ it('should throw an error for invalid user key', async function () {
2485
+ const params = mockData.getInvalidNonBitGoRecoveryParams();
2486
+ await assert_1.default.rejects(async () => {
2487
+ await basecoin.recover({
2488
+ userKey: params.userKey,
2489
+ backupKey: params.backupKey,
2490
+ walletPassphrase: params.walletPassphrase,
2491
+ walletContractAddress: params.walletContractAddress,
2492
+ bitgoFeeAddress: params.bitgoFeeAddress,
2493
+ recoveryDestination: params.recoveryDestination,
2494
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2495
+ gasLimit: 500000,
2496
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2497
+ intendedChain: params.intendedChain,
2498
+ });
2499
+ }, Error, 'user key is invalid');
2500
+ });
2501
+ });
2502
+ describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
2503
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2504
+ let bitgo;
2505
+ let basecoin;
2506
+ before(function () {
2507
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2508
+ basecoin = bitgo.coin('hteth');
2509
+ });
2510
+ it('should generate an unsigned sweep without derivation seed', async function () {
2511
+ (0, nock_1.default)(baseUrl)
2512
+ .get('/api')
2513
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2514
+ .reply(200, mockData.getTxListResponse);
2515
+ (0, nock_1.default)(baseUrl)
2516
+ .get('/api')
2517
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2518
+ .reply(200, mockData.getBalanceResponse);
2519
+ (0, nock_1.default)(baseUrl)
2520
+ .get('/api')
2521
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2522
+ .reply(200, mockData.getBalanceResponse);
2523
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2524
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2525
+ const sweepResult = await basecoin.recover({
2526
+ userKey: params.commonKeyChain, // Box A Data
2527
+ backupKey: params.commonKeyChain, // Box B Data
2528
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2529
+ recoveryDestination: params.recoveryDestination, // Destination Address
2530
+ gasLimit: 200000, // Gas Limit
2531
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2532
+ walletContractAddress: params.walletContractAddress,
2533
+ isTss: true,
2534
+ replayProtectionOptions: {
2535
+ chain: '42',
2536
+ hardfork: 'london',
2537
+ },
2538
+ });
2539
+ should_1.default.exist(sweepResult);
2540
+ const output = sweepResult;
2541
+ output.should.have.property('txRequests');
2542
+ output.txRequests.should.have.length(1);
2543
+ output.txRequests[0].should.have.property('transactions');
2544
+ output.txRequests[0].transactions.should.have.length(1);
2545
+ output.txRequests[0].should.have.property('walletCoin');
2546
+ output.txRequests[0].transactions.should.have.length(1);
2547
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2548
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2549
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2550
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2551
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2552
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2553
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2554
+ parsedTx.should.have.property('spendAmount');
2555
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2556
+ });
2557
+ it('should throw an error for invalid address', async function () {
2558
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2559
+ params.recoveryDestination = 'invalidAddress';
2560
+ // Ensure userKey and backupKey are the same
2561
+ params.userKey =
2562
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2563
+ params.backupKey =
2564
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2565
+ await assert_1.default.rejects(async () => {
2566
+ await basecoin.recover({
2567
+ recoveryDestination: params.recoveryDestination, // Destination Address
2568
+ gasLimit: 2000, // Gas Limit
2569
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2570
+ userKey: params.userKey, // Provide the userKey
2571
+ backupKey: params.backupKey, // Provide the backupKey
2572
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2573
+ isTss: true,
2574
+ replayProtectionOptions: {
2575
+ chain: '42',
2576
+ hardfork: 'london',
2577
+ },
2578
+ });
2579
+ }, Error, 'Error: invalid address');
2580
+ });
2581
+ });
2582
+ describe('Build Unsigned Consolidation for Self-Custody Cold Wallets (MPCv2)', function () {
2583
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2584
+ let bitgo;
2585
+ let basecoin;
2586
+ before(function () {
2587
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2588
+ basecoin = bitgo.coin('hteth');
2589
+ });
2590
+ it('should generate an unsigned consolidation for wallet v5', async function () {
2591
+ (0, nock_1.default)(baseUrl)
2592
+ .get('/api')
2593
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2594
+ .times(2)
2595
+ .reply(200, mockData.getTxListResponse);
2596
+ (0, nock_1.default)(baseUrl)
2597
+ .get('/api')
2598
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2599
+ .times(2)
2600
+ .reply(200, mockData.getBalanceResponse);
2601
+ (0, nock_1.default)(baseUrl)
2602
+ .get('/api')
2603
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2604
+ .reply(200, mockData.getBalanceResponse);
2605
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2606
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2607
+ const consolidationResult = await basecoin.recoverConsolidations({
2608
+ backupKey: params.commonKeyChain, // Box B Data
2609
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2610
+ recoveryDestination: params.recoveryDestination, // Destination Address
2611
+ gasLimit: 200000, // Gas Limit
2612
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2613
+ walletContractAddress: params.walletContractAddress,
2614
+ isTss: true,
2615
+ replayProtectionOptions: {
2616
+ chain: '42',
2617
+ hardfork: 'london',
2618
+ },
2619
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2620
+ startingScanIndex: 1,
2621
+ endingScanIndex: 2,
2622
+ });
2623
+ should_1.default.exist(consolidationResult);
2624
+ const unsignedBuilConsolidation = consolidationResult;
2625
+ unsignedBuilConsolidation.should.have.property('transactions');
2626
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2627
+ const output = unsignedBuilConsolidation.transactions[0];
2628
+ output.should.have.property('txRequests');
2629
+ output.txRequests[0].should.have.property('transactions');
2630
+ output.txRequests[0].transactions.should.have.length(1);
2631
+ output.txRequests[0].should.have.property('walletCoin');
2632
+ output.txRequests[0].transactions.should.have.length(1);
2633
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2634
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2635
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2636
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2637
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2638
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2639
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2640
+ parsedTx.should.have.property('spendAmount');
2641
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2642
+ });
2643
+ it('should generate an unsigned consolidation for wallet v6', async function () {
2644
+ (0, nock_1.default)(baseUrl)
2645
+ .get('/api')
2646
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2647
+ .times(2)
2648
+ .reply(200, mockData.getTxListResponse);
2649
+ (0, nock_1.default)(baseUrl)
2650
+ .get('/api')
2651
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2652
+ .times(2)
2653
+ .reply(200, mockData.getBalanceResponse);
2654
+ (0, nock_1.default)(baseUrl)
2655
+ .get('/api')
2656
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2657
+ .reply(200, mockData.getBalanceResponse);
2658
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2659
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2660
+ const consolidationResult = await basecoin.recoverConsolidations({
2661
+ userKey: params.commonKeyChain, // Box A Data
2662
+ backupKey: params.commonKeyChain, // Box B Data
2663
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2664
+ recoveryDestination: params.recoveryDestination, // Destination Address
2665
+ gasLimit: 200000, // Gas Limit
2666
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2667
+ isTss: true,
2668
+ walletContractAddress: '123', // Wrong wallet address so that we can skip v5 address generation
2669
+ replayProtectionOptions: {
2670
+ chain: '42',
2671
+ hardfork: 'london',
2672
+ },
2673
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2674
+ startingScanIndex: 1,
2675
+ endingScanIndex: 2,
2676
+ });
2677
+ should_1.default.exist(consolidationResult);
2678
+ const unsignedBuilConsolidation = consolidationResult;
2679
+ unsignedBuilConsolidation.should.have.property('transactions');
2680
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2681
+ const output = unsignedBuilConsolidation.transactions[0];
2682
+ output.should.have.property('txRequests');
2683
+ output.txRequests[0].should.have.property('transactions');
2684
+ output.txRequests[0].transactions.should.have.length(1);
2685
+ output.txRequests[0].should.have.property('walletCoin');
2686
+ output.txRequests[0].transactions.should.have.length(1);
2687
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2688
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2689
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2690
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2691
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2692
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2693
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2694
+ parsedTx.should.have.property('spendAmount');
2695
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2696
+ });
2697
+ it('should throw an error for invalid address', async function () {
2698
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2699
+ params.recoveryDestination = 'invalidAddress';
2700
+ // Ensure userKey and backupKey are the same
2701
+ params.userKey =
2702
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2703
+ params.backupKey =
2704
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2705
+ await assert_1.default.rejects(async () => {
2706
+ await basecoin.recover({
2707
+ recoveryDestination: params.recoveryDestination, // Destination Address
2708
+ gasLimit: 2000, // Gas Limit
2709
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2710
+ userKey: params.userKey, // Provide the userKey
2711
+ backupKey: params.backupKey, // Provide the backupKey
2712
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2713
+ isTss: true,
2714
+ replayProtectionOptions: {
2715
+ chain: '42',
2716
+ hardfork: 'london',
2717
+ },
2718
+ });
2719
+ }, Error, 'Error: invalid address');
2720
+ });
2721
+ });
2722
+ });
2723
+ describe('Recover signer checks', function () {
2724
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2725
+ it('should throw RecoveryKeyMismatchError when the user recovery key is not a wallet signer', async function () {
2726
+ const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
2727
+ const backupXpub = 'xpub661MyMwAqRbcFZX15xpZf4ERCGHiVSJm8r5C4yh1yXV2GrdZCUPYo4WQr6tN9oUywKXsgSHo7Risf9r22GH5joVD2hEEEhqnSCvK8qy11wW';
2728
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
2729
+ (0, nock_1.default)(baseUrl)
2730
+ .get('/api')
2731
+ .query(mockData.getIsSignerCallRequest('0x916da87c3ae51f0fa23a2bab8732d23c21d30f5e'))
2732
+ .reply(200, mockData.getIsSignerFalseResponse);
2733
+ (0, nock_1.default)(baseUrl)
2734
+ .get('/api')
2735
+ .query(mockData.getIsSignerCallRequest(backupKeyAddress))
2736
+ .reply(200, mockData.getIsSignerTrueResponse);
2737
+ const basecoin = bitgo.coin('hteth');
2738
+ await assert_1.default.rejects(async () => await basecoin.recover({
2739
+ userKey: userXpub,
2740
+ backupKey: backupXpub,
2741
+ walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
2742
+ recoveryDestination: '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560',
2743
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2744
+ gasLimit: 500000,
2745
+ }), (err) => err instanceof sdk_core_1.RecoveryKeyMismatchError && err.code === 'recovery_key_mismatch');
2746
+ });
2747
+ it('should recover with a raw xprv userKey for Erc20Token and Erc721Token', async function () {
2748
+ // any registered token works — the explorer is stubbed
2749
+ const erc20Coin = src_1.Erc20Token.createTokenConstructors()[0].coinConstructor(bitgo);
2750
+ const erc721Coin = src_1.Erc721Token.createTokenConstructors()[0].coinConstructor(bitgo);
2751
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
2752
+ const recoveryDestination = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
2753
+ const passphrase = 'test wallet passphrase';
2754
+ const encryptedBackupKey = await bitgo.encrypt({ input: testData.PRIVATE_KEY, password: passphrase });
2755
+ for (const tokenCoin of [erc20Coin, erc721Coin]) {
2756
+ const stub = sandbox.stub(tokenCoin, 'recoveryBlockchainExplorerQuery');
2757
+ stub.callsFake(async (query) => {
2758
+ if (query.action === 'eth_call' && query.data?.startsWith('7df73e27')) {
2759
+ return { result: '0x' + '00'.repeat(31) + '01' };
2760
+ }
2761
+ if (query.action === 'txlist') {
2762
+ return { result: [] };
2763
+ }
2764
+ if (query.action === 'balance') {
2765
+ return { result: '100000000000000000' };
2766
+ }
2767
+ if (query.action === 'tokenbalance') {
2768
+ return { result: '1000' };
2769
+ }
2770
+ if (query.action === 'eth_call' && query.data?.startsWith('a0b7967b')) {
2771
+ return { result: '0x' + '00'.repeat(31) + '01' };
2772
+ }
2773
+ throw new Error(`Unexpected explorer query: ${JSON.stringify(query)}`);
2774
+ });
2775
+ const tx = await tokenCoin.recover({
2776
+ userKey: testData.PRIVATE_KEY,
2777
+ backupKey: encryptedBackupKey,
2778
+ walletPassphrase: passphrase,
2779
+ walletContractAddress,
2780
+ recoveryDestination,
2781
+ });
2782
+ should_1.default.exist(tx);
2783
+ tx.should.have.property('id');
2784
+ tx.should.have.property('tx');
2785
+ stub.restore();
2786
+ }
2787
+ });
2788
+ it('should throw RecoveryKeyMismatchError on signer mismatch for Erc20Token and Erc721Token', async function () {
2789
+ // any registered token works — the explorer is stubbed
2790
+ const erc20Coin = src_1.Erc20Token.createTokenConstructors()[0].coinConstructor(bitgo);
2791
+ const erc721Coin = src_1.Erc721Token.createTokenConstructors()[0].coinConstructor(bitgo);
2792
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
2793
+ const recoveryDestination = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
2794
+ const passphrase = 'test wallet passphrase';
2795
+ const encryptedBackupKey = await bitgo.encrypt({ input: testData.PRIVATE_KEY, password: passphrase });
2796
+ for (const tokenCoin of [erc20Coin, erc721Coin]) {
2797
+ const stub = sandbox.stub(tokenCoin, 'recoveryBlockchainExplorerQuery');
2798
+ stub.callsFake(async (query) => {
2799
+ if (query.action === 'eth_call' && query.data?.startsWith('7df73e27')) {
2800
+ return { result: '0x' + '00'.repeat(32) };
2801
+ }
2802
+ throw new Error(`Unexpected explorer query: ${JSON.stringify(query)}`);
2803
+ });
2804
+ await assert_1.default.rejects(async () => await tokenCoin.recover({
2805
+ userKey: testData.PRIVATE_KEY,
2806
+ backupKey: encryptedBackupKey,
2807
+ walletPassphrase: passphrase,
2808
+ walletContractAddress,
2809
+ recoveryDestination,
2810
+ }), (err) => err instanceof sdk_core_1.RecoveryKeyMismatchError && err.code === 'recovery_key_mismatch');
2811
+ stub.restore();
2812
+ }
2813
+ });
2814
+ });
2815
+ describe('RecoveryBlockchainExplorerQuery', () => {
2816
+ it('should override the token parameter with a custom API key', async function () {
2817
+ const coin = bitgo.coin('teth');
2818
+ const query = {
2819
+ module: 'account',
2820
+ action: 'balance',
2821
+ address: '0x1234567890123456789012345678901234567890',
2822
+ };
2823
+ const customApiKey = 'custom-api-key-for-test';
2824
+ // Mock the environment API token
2825
+ const originalApiToken = sdk_core_1.common.Environments.test.etherscanApiToken;
2826
+ sdk_core_1.common.Environments.test.etherscanApiToken = 'default-environment-api-key';
2827
+ // Mock the request.get function to capture the query parameters
2828
+ const originalGet = superagent_1.default.get;
2829
+ let capturedQuery;
2830
+ superagent_1.default.get = function (url) {
2831
+ return {
2832
+ query: function (params) {
2833
+ capturedQuery = params;
2834
+ return {
2835
+ ok: true,
2836
+ body: { result: '100000000' },
2837
+ };
2838
+ },
2839
+ };
2840
+ };
2841
+ try {
2842
+ // Call with default API key
2843
+ await coin.recoveryBlockchainExplorerQuery(query);
2844
+ capturedQuery.should.have.property('apikey', 'default-environment-api-key');
2845
+ // Call with custom API key
2846
+ await coin.recoveryBlockchainExplorerQuery(query, customApiKey);
2847
+ capturedQuery.should.have.property('apikey', customApiKey);
2848
+ }
2849
+ finally {
2850
+ // Restore original function and API token
2851
+ superagent_1.default.get = originalGet;
2852
+ sdk_core_1.common.Environments.test.etherscanApiToken = originalApiToken;
2853
+ }
2854
+ });
2855
+ it('should throw RecoveryProviderError when the explorer request fails', async function () {
2856
+ const coin = bitgo.coin('teth');
2857
+ const query = {
2858
+ module: 'account',
2859
+ action: 'balance',
2860
+ address: '0x1234567890123456789012345678901234567890',
2861
+ };
2862
+ const originalGet = superagent_1.default.get;
2863
+ superagent_1.default.get = function () {
2864
+ return {
2865
+ query: function () {
2866
+ throw new Error('connection refused');
2867
+ },
2868
+ };
2869
+ };
2870
+ try {
2871
+ await coin.recoveryBlockchainExplorerQuery(query).should.be.rejectedWith(sdk_core_1.RecoveryProviderError);
2872
+ }
2873
+ finally {
2874
+ superagent_1.default.get = originalGet;
2875
+ }
2876
+ });
2877
+ it('should throw RecoveryProviderError when the explorer rate-limits the request', async function () {
2878
+ const coin = bitgo.coin('teth');
2879
+ const query = {
2880
+ module: 'account',
2881
+ action: 'balance',
2882
+ address: '0x1234567890123456789012345678901234567890',
2883
+ };
2884
+ const originalGet = superagent_1.default.get;
2885
+ superagent_1.default.get = function () {
2886
+ return {
2887
+ query: function () {
2888
+ return { ok: true, body: { status: '0', message: 'NOTOK' } };
2889
+ },
2890
+ };
2891
+ };
2892
+ try {
2893
+ await coin.recoveryBlockchainExplorerQuery(query).should.be.rejectedWith(sdk_core_1.RecoveryProviderError);
2894
+ }
2895
+ finally {
2896
+ superagent_1.default.get = originalGet;
2897
+ }
2898
+ });
2899
+ });
2900
+ describe('Audit Key', () => {
2901
+ let coin;
2902
+ before(() => {
2903
+ coin = bitgo.coin('hteth');
2904
+ });
2905
+ describe('MultiSig', () => {
2906
+ const { key } = ethMultiSigBackupKey_1.ethMultiSigBackupKey;
2907
+ it('should return { isValid: true } for valid inputs', () => {
2908
+ coin.assertIsValidKey({
2909
+ encryptedPrv: key,
2910
+ walletPassphrase: 'ZQ8MhxT84m4P',
2911
+ });
2912
+ });
2913
+ it('should throw error if the walletPassphrase is incorrect', async () => {
2914
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2915
+ encryptedPrv: key,
2916
+ walletPassphrase: 'foo',
2917
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2918
+ });
2919
+ it('should throw error if the key is altered', async () => {
2920
+ const alteredKey = key.replace(/[0-9]/g, '0');
2921
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2922
+ encryptedPrv: alteredKey,
2923
+ walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
2924
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2925
+ });
2926
+ });
2927
+ describe('TSS', () => {
2928
+ const { key: keyString, commonKeychain } = ethTssBackupKey_1.ethTssBackupKey;
2929
+ const key = keyString.replace(/\s/g, '');
2930
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
2931
+ const multiSigType = 'tss';
2932
+ it('should not throw for valid inputs', () => {
2933
+ coin.assertIsValidKey({
2934
+ encryptedPrv: key,
2935
+ publicKey: commonKeychain,
2936
+ walletPassphrase,
2937
+ multiSigType,
2938
+ });
2939
+ });
2940
+ it('should throw if the commonKeychain is altered', async () => {
2941
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
2942
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2943
+ encryptedPrv: key,
2944
+ publicKey: alteredCommonKeychain,
2945
+ walletPassphrase,
2946
+ multiSigType,
2947
+ }), { message: 'Invalid common keychain' });
2948
+ });
2949
+ it('should throw error if the walletPassphrase is incorrect', async () => {
2950
+ const incorrectPassphrase = 'foo';
2951
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2952
+ encryptedPrv: key,
2953
+ publicKey: commonKeychain,
2954
+ walletPassphrase: incorrectPassphrase,
2955
+ multiSigType,
2956
+ }), { message: 'failed to decrypt prv: incorrect password' });
2957
+ });
2958
+ it('should throw error if the key is altered', async () => {
2959
+ const alteredKey = key.replace(/[0-9]/g, '0');
2960
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2961
+ encryptedPrv: alteredKey,
2962
+ publicKey: commonKeychain,
2963
+ walletPassphrase,
2964
+ multiSigType,
2965
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2966
+ });
2967
+ });
2968
+ });
2969
+ describe('getSignablePayload', function () {
2970
+ let coin;
2971
+ before(function () {
2972
+ coin = bitgo.coin('teth');
2973
+ });
2974
+ it('should return a 32-byte keccak256 hash for a Legacy transaction', async function () {
2975
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2976
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2977
+ txBuilder.fee({ fee: '10000000000', gasLimit: '7000000' });
2978
+ txBuilder.counter(1);
2979
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
2980
+ const transferBuilder = txBuilder.transfer();
2981
+ transferBuilder
2982
+ .coin('teth')
2983
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
2984
+ .amount('100000')
2985
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
2986
+ .contractSequenceId(1);
2987
+ const tx = await txBuilder.build();
2988
+ const serializedTx = tx.toBroadcastFormat();
2989
+ const payload = await coin.getSignablePayload(serializedTx);
2990
+ assert_1.default.ok(Buffer.isBuffer(payload));
2991
+ assert_1.default.strictEqual(payload.length, 32);
2992
+ });
2993
+ it('should return a 32-byte keccak256 hash for an EIP1559 transaction', async function () {
2994
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2995
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2996
+ txBuilder.fee({
2997
+ fee: '280000000000',
2998
+ gasLimit: '7000000',
2999
+ eip1559: { maxFeePerGas: '7593123', maxPriorityFeePerGas: '150' },
3000
+ });
3001
+ txBuilder.counter(1);
3002
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
3003
+ const transferBuilder = txBuilder.transfer();
3004
+ transferBuilder
3005
+ .coin('teth')
3006
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
3007
+ .amount('100000')
3008
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
3009
+ .contractSequenceId(1);
3010
+ const tx = await txBuilder.build();
3011
+ const serializedTx = tx.toBroadcastFormat();
3012
+ const payload = await coin.getSignablePayload(serializedTx);
3013
+ assert_1.default.ok(Buffer.isBuffer(payload));
3014
+ assert_1.default.strictEqual(payload.length, 32);
3015
+ });
3016
+ });
3017
+ // ---------------------------------------------------------------------------
3018
+ // ERC-7984 token enablement — multisig verifyTransaction (all scenarios)
3019
+ // ---------------------------------------------------------------------------
3020
+ describe('verifyTransaction – ERC-7984 enabletoken (multisig wallet)', function () {
3021
+ // hteth Zama ACL contract (Networks.test.hoodi.zamaAclContractAddress)
3022
+ const ZAMA_ACL_ADDRESS = '0x6d3faf6f86e1ff9f3b0831dda920aba1cbd5bd68';
3023
+ // Simulated wallet base address (what the client sends as the recipient for base-address wallets)
3024
+ const WALLET_BASE_ADDRESS = '0x08e6736e876d772d2fa8f803a076cd6c9f845546';
3025
+ // Simulated forwarder address (what the client sends as recipient for forwarder wallets)
3026
+ const FORWARDER_ADDRESS = '0x1234567890123456789012345678901234567890';
3027
+ const WRONG_ADDRESS = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
3028
+ const makePrebuild = (recipientAddress) => ({
3029
+ recipients: [{ address: recipientAddress, amount: '0' }],
3030
+ nextContractSequenceId: 0,
3031
+ gasPrice: 20000000000,
3032
+ gasLimit: 300000,
3033
+ isBatch: false,
3034
+ coin: 'hteth',
3035
+ walletId: 'fakeWalletId',
3036
+ });
3037
+ // ── Base-address wallet ──────────────────────────────────────────────────
3038
+ it('base-address, single token: txParams → walletBase, txPrebuild → ACL', async function () {
3039
+ const htethCoin = bitgo.coin('hteth');
3040
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3041
+ const result = await htethCoin.verifyTransaction({
3042
+ txParams: {
3043
+ type: 'enabletoken',
3044
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
3045
+ },
3046
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
3047
+ wallet,
3048
+ });
3049
+ result.should.equal(true);
3050
+ });
3051
+ it('base-address, multi-token: multiple txParams recipients (same base address), txPrebuild → ACL multicall', async function () {
3052
+ const htethCoin = bitgo.coin('hteth');
3053
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3054
+ const result = await htethCoin.verifyTransaction({
3055
+ txParams: {
3056
+ type: 'enabletoken',
3057
+ recipients: [
3058
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
3059
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
3060
+ ],
3061
+ },
3062
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
3063
+ wallet,
3064
+ });
3065
+ result.should.equal(true);
3066
+ });
3067
+ // ── Forwarder wallet ─────────────────────────────────────────────────────
3068
+ it('forwarder, single token: txParams → forwarder, txPrebuild → forwarder', async function () {
3069
+ const htethCoin = bitgo.coin('hteth');
3070
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3071
+ const result = await htethCoin.verifyTransaction({
3072
+ txParams: {
3073
+ type: 'enabletoken',
3074
+ recipients: [{ address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
3075
+ },
3076
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
3077
+ wallet,
3078
+ });
3079
+ result.should.equal(true);
3080
+ });
3081
+ it('forwarder, multi-token: multiple txParams recipients (same forwarder), txPrebuild → forwarder', async function () {
3082
+ const htethCoin = bitgo.coin('hteth');
3083
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3084
+ const result = await htethCoin.verifyTransaction({
3085
+ txParams: {
3086
+ type: 'enabletoken',
3087
+ recipients: [
3088
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
3089
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
3090
+ ],
3091
+ },
3092
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
3093
+ wallet,
3094
+ });
3095
+ result.should.equal(true);
3096
+ });
3097
+ // ── Negative cases ───────────────────────────────────────────────────────
3098
+ it('should throw when txPrebuild recipient is neither the ACL contract nor the forwarder from txParams', async function () {
3099
+ const htethCoin = bitgo.coin('hteth');
3100
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3101
+ await htethCoin
3102
+ .verifyTransaction({
3103
+ txParams: {
3104
+ type: 'enabletoken',
3105
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
3106
+ },
3107
+ txPrebuild: makePrebuild(WRONG_ADDRESS),
3108
+ wallet,
3109
+ })
3110
+ .should.be.rejectedWith(/token enablement txPrebuild recipient must be/);
3111
+ });
3112
+ it('should throw when txParams recipients have different addresses', async function () {
3113
+ const htethCoin = bitgo.coin('hteth');
3114
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3115
+ await htethCoin
3116
+ .verifyTransaction({
3117
+ txParams: {
3118
+ type: 'enabletoken',
3119
+ recipients: [
3120
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
3121
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
3122
+ ],
3123
+ },
3124
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
3125
+ wallet,
3126
+ })
3127
+ .should.be.rejectedWith(/must all have the same address/);
3128
+ });
3129
+ it('should throw when a txParams recipient has non-zero amount', async function () {
3130
+ const htethCoin = bitgo.coin('hteth');
3131
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3132
+ await htethCoin
3133
+ .verifyTransaction({
3134
+ txParams: {
3135
+ type: 'enabletoken',
3136
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '100', tokenName: 'hteth:ctest1' }],
3137
+ },
3138
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
3139
+ wallet,
3140
+ })
3141
+ .should.be.rejectedWith(/must all have amount 0/);
3142
+ });
3143
+ it('should throw when txPrebuild recipient has non-zero amount', async function () {
3144
+ const htethCoin = bitgo.coin('hteth');
3145
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
3146
+ await htethCoin
3147
+ .verifyTransaction({
3148
+ txParams: {
3149
+ type: 'enabletoken',
3150
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
3151
+ },
3152
+ txPrebuild: {
3153
+ recipients: [{ address: ZAMA_ACL_ADDRESS, amount: '500' }],
3154
+ nextContractSequenceId: 0,
3155
+ coin: 'hteth',
3156
+ walletId: 'fakeWalletId',
3157
+ },
3158
+ wallet,
3159
+ })
3160
+ .should.be.rejectedWith(/expected amount 0 in txPrebuild/);
3161
+ });
3162
+ });
3163
+ });
3164
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUErRDtBQUUvRCxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLHFEQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsNERBQWlDO0FBQ2pDLG1EQWM4QjtBQUM5QixrREFBdUI7QUFDdkIsaURBQStDO0FBQy9DLG1DQVltQjtBQUNuQixpREFBMEU7QUFDMUUsb0RBQTRCO0FBQzVCLDZDQUEwQztBQUMxQywyREFBNkM7QUFDN0MsMERBQTRDO0FBQzVDLG9EQUE0QjtBQUM1QixvRUFBeUM7QUFDekMsMEVBQXVFO0FBQ3ZFLGdFQUE2RDtBQUU3RCxjQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUV4QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksbUJBQW1CLENBQUM7SUFDeEIsSUFBSSxPQUEyQixDQUFDO0lBRWhDLE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sa0JBQWtCLEdBQUcsNENBQTRDLENBQUM7SUFDeEUsTUFBTSxxQkFBcUIsR0FBRyw0Q0FBNEMsQ0FBQztJQUMzRSxNQUFNLEtBQUssR0FDVCw4TkFBOE4sQ0FBQztJQUNqTyxNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQztJQUNyRixNQUFNLFVBQVUsR0FDZCxvSUFBb0ksQ0FBQztJQUV2SSxNQUFNLGNBQWMsR0FBRyxLQUFLLEVBQUUsSUFBWSxFQUFFLEtBQWEsUUFBUSxFQUFtQixFQUFFO1FBQ3BGLE1BQU0sU0FBUyxHQUFHLElBQUEsdUJBQVUsRUFBQyxPQUFPLENBQXVCLENBQUM7UUFDNUQsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBZSxD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akQsTUFBTTthQUNQLENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxLQUFLO1lBQ3BFLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFVLENBQUM7WUFDL0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxpQkFBTSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRSxZQUFZLEVBQUUsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFcEcsTUFBTSxTQUFTO2lCQUNaLGlCQUFpQixDQUFDO2dCQUNqQixRQUFRLEVBQUU7b0JBQ1IsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLFVBQVUsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxDQUFDO2lCQUNoRjtnQkFDUixVQUFVLEVBQUU7b0JBQ1YsVUFBVSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO29CQUMxRCxzQkFBc0IsRUFBRSxDQUFDO29CQUN6QixJQUFJLEVBQUUsT0FBTztvQkFDYixRQUFRLEVBQUUsY0FBYztpQkFDbEI7Z0JBQ1IsTUFBTTthQUNQLENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsaUNBQWlDLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcblxuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7XG4gIGNvbW1vbixcbiAgRXJyb3JOb0lucHV0VG9SZWNvdmVyLFxuICBnZW5lcmF0ZVJhbmRvbVBhc3N3b3JkLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3IsXG4gIE1QQ1N3ZWVwVHhzLFxuICBSZWNvdmVyeUtleU1pc21hdGNoRXJyb3IsXG4gIFJlY292ZXJ5UHJvdmlkZXJFcnJvcixcbiAgcmVzb2x2ZUVmZmVjdGl2ZVR4UGFyYW1zLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFR4SW50ZW50TWlzbWF0Y2hSZWNpcGllbnRFcnJvcixcbiAgVW5leHBlY3RlZEFkZHJlc3NFcnJvcixcbiAgV2FsbGV0LFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgQk4gZnJvbSAnYm4uanMnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7XG4gIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLFxuICBFcmMyMFRva2VuLFxuICBFcmM3MjFUb2tlbixcbiAgSHRldGgsXG4gIFRldGgsXG4gIFRyYW5zYWN0aW9uQnVpbGRlcixcbiAgVHJhbnNmZXJCdWlsZGVyLFxuICBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyxcbiAgVW5zaWduZWRCdWlsQ29uc29saWRhdGlvbixcbiAgVW5zaWduZWRTd2VlcFR4TVBDdjIsXG4gIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zLFxufSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgY29pbnMsIEVyYzc5ODRDb2luLCBFdGhlcmV1bU5ldHdvcmsgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2V0aCc7XG5pbXBvcnQgKiBhcyBtb2NrRGF0YSBmcm9tICcuLi9maXh0dXJlcy9ldGgnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IEV0aGVyZXVtQWJpIGZyb20gJ2V0aGVyZXVtanMtYWJpJztcbmltcG9ydCB7IGV0aE11bHRpU2lnQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9ldGhNdWx0aVNpZ0JhY2t1cEtleSc7XG5pbXBvcnQgeyBldGhUc3NCYWNrdXBLZXkgfSBmcm9tICcuL2ZpeHR1cmVzL2V0aFRzc0JhY2t1cEtleSc7XG5cbm5vY2suZW5hYmxlTmV0Q29ubmVjdCgpO1xuXG5kZXNjcmliZSgnRVRIOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBob3BUeEJpdGdvU2lnbmF0dXJlO1xuICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuXG4gIGNvbnN0IGFkZHJlc3MxID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gIGNvbnN0IGFkZHJlc3MyID0gJzB4N2U4NWJkYzI3YzA1MGUzOTA1ZWJmNGI4ZTYzNGQ5YWQ2ZWRkMGRlNic7XG4gIGNvbnN0IGhvcENvbnRyYWN0QWRkcmVzcyA9ICcweDQ3Y2U3Y2M4NmVmZWZlZjE5ZjhmYjUxNmIxMTczNWQxODNkYTg2MzUnO1xuICBjb25zdCBob3BEZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHg5YzdlOGNlNjgyNWJENDgyNzhCM0FiNTkyMjhFRTI2ZjhCRTc5MjViJztcbiAgY29uc3QgaG9wVHggPVxuICAgICcweGY4NmI4MDg1MDRhODE3YzhmZjgyNTJmZjk0OWM3ZThjZTY4MjViZDQ4Mjc4YjNhYjU5MjI4ZWUyNmY4YmU3OTI1Yjg3MDM4ZDdlYTRjNjgwMDA4MDFjYTAxMWJjMjJjNjY0NTcwMTMzZGZjYTRmMDhhMGI4ZDAyMzM5Y2Y0NjcwNDZkNmE0MTUyZjA0ZjM2OGQwZWFmOTllYTAxZDZkYzVjZjBjODk3YzhkNGMzZTFkZjUzZDBkMDQyNzg0YzQyNDUzNmE0Y2M1YjgwMjU1MmI3ZDY0ZmVlOGI1JztcbiAgY29uc3QgaG9wVHhpZCA9ICcweDRhZjY1MTQzYmM3N2RhMmI1MGYzNWIzZDEzY2FjYjRkYjE4ZjAyNmJmODRiYzA3NDM1NTBiYzU3YjliNTMzNTEnO1xuICBjb25zdCB1c2VyUmVxU2lnID1cbiAgICAnMHg0MDRkYjMwN2Y2MTQ3ZjBkOGNkMzM4YzM0YzEzOTA2ZWY0NmE2ZmFhN2UwZTExOWQ1MTk0ZWYwNWFlYzE2ZTZmM2Q3MTBmOWI3OTAxNDYwZjk3ZTkyNDA2NmI2MmVmZDc0NDQzYmQzNDQwMmM2ZDQwYjQ5YzIwM2E1NTlmZjJjOCc7XG5cbiAgY29uc3QgYnVpbGREZWZpVHhIZXggPSBhc3luYyAoZGF0YTogc3RyaW5nLCB0bzogc3RyaW5nID0gYWRkcmVzczEpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMCcsIGdhc0xpbWl0OiAnMTAwMDAwJyB9KTtcbiAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICB0eEJ1aWxkZXIuY29udHJhY3QodG8pO1xuICAgIHR4QnVpbGRlci5kYXRhKGRhdGEpO1xuICAgIHJldHVybiAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gIH07XG5cbiAgY29uc3QgZGVmaUNhbGxkYXRhID0gKHNpZ25hdHVyZTogc3RyaW5nLCB2YWx1ZXM6IHN0cmluZ1tdKTogc3RyaW5nID0+IHtcbiAgICBjb25zdCB0eXBlcyA9IHNpZ25hdHVyZS5zbGljZShzaWduYXR1cmUuaW5kZXhPZignKCcpICsgMSwgLTEpLnNwbGl0KCcsJyk7XG4gICAgY29uc3QgbWV0aG9kSWQgPSBFdGhlcmV1bUFiaS5tZXRob2RJRChzaWduYXR1cmUuc3BsaXQoJygnKVswXSwgdHlwZXMpO1xuICAgIHJldHVybiAnMHgnICsgQnVmZmVyLmNvbmNhdChbbWV0aG9kSWQsIEV0aGVyZXVtQWJpLnJhd0VuY29kZSh0eXBlcywgdmFsdWVzKV0pLnRvU3RyaW5nKCdoZXgnKTtcbiAgfTtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvS2V5WHBydiA9XG4gICAgICAneHBydjlzMjFaclFIMTQzSzN0cFdCSFdlMzFzTG9YTlJROUF2UllKZ2l0a0t4UTRBVEZRTXd2cjdoSE5xWVJVblM3UHNqekI3YUsxVnhxSEx1TlFqajFzY2tKMkp3bzJxeG1zdmVqd0VDU3BGTWZDJztcbiAgICBjb25zdCBiaXRnb0tleSA9IGJpcDMyLmZyb21CYXNlNTgoYml0Z29LZXlYcHJ2KTtcbiAgICBpZiAoIWJpdGdvS2V5LnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBjb25zdCBiaXRnb1hwdWIgPSBiaXRnb0tleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgaG9wVHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oc2VjcDI1NmsxLmVjZHNhU2lnbihCdWZmZXIuZnJvbShob3BUeGlkLnNsaWNlKDIpLCAnaGV4JyksIGJpdGdvS2V5LnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoXG4gICAgICAgICdoZXgnXG4gICAgICApO1xuXG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIEVyYzIwVG9rZW4uY3JlYXRlVG9rZW5Db25zdHJ1Y3RvcnMoKS5mb3JFYWNoKCh7IG5hbWUsIGNvaW5Db25zdHJ1Y3RvciB9KSA9PiB7XG4gICAgICBiaXRnby5zYWZlUmVnaXN0ZXIobmFtZSwgY29pbkNvbnN0cnVjdG9yKTtcbiAgICB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RldGgnLCBUZXRoLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2h0ZXRoJywgSHRldGguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGNvbW1vbi5FbnZpcm9ubWVudHNbZW52XS5oc21YcHViID0gYml0Z29YcHViO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFSVAxNTU5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHdpdGggRUlQMTU1OSBmZWUgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgIHBydjogJ3hwcnY5czIxWnJRSDE0M0szaGVreU5qN1RjaVI0WE5ZZTFrTWo2OFcyaXBqSkdOSEVUV1A3bzQyQWpEblNQZ0toZFo0eDhOQkF2YUw3MlJyWGp1WE5kbWtNcUxFUlp6YTczb1l1Z0d0YkxGWEc4ZycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHQmpFNVFHN3BrZjljWkQzM1VVRDZLNDZxN0VMcmJ1RzdGcVhmTE5HaVhZR0hlRW5HQmI1QVdSRW5rMWVBMjhnOEFyWnZVUmJoc2hYV2tUdGRkSFJvNTRmZ3lWdkxkYicsXG4gICAgICAgIHJhd1B1YjogJzAyMzYzNmU2OGI3YjIwNDU3M2FiZGEyNjE2YWZmNmI1ODQ5MTBkZWNlMjU0M2YxY2M2ZDg0MmNhYWM3ZDc0OTc0YicsXG4gICAgICAgIHJhd1BydjogJzc0MzhhNTAwMTBjZTdiMWRmZDg2ZTY4MDQ2Y2M3OGJhMWViZDI0MmQ2ZDg1ZDk5MDRkM2ZjYzA4NzM0YmMxNzInLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhQcmlvcml0eUZlZVBlckdhczogMTAsIG1heEZlZVBlckdhczogMTAgfSxcbiAgICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudDogJzQyJyxcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4YzkzYjEzNjQyZDkzYjQyMThiYjg1ZjY3MzE3ZDZiMzcyODZlODAyOCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZXhwaXJlVGltZTogMTYyNzk0OTIxNCxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IDEyLFxuICAgICAgICAgIGdhc0xpbWl0OiB1bmRlZmluZWQsXG4gICAgICAgICAgZ2FzUHJpY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBob3BUcmFuc2FjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGJhY2t1cEtleU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgc2VxdWVuY2VJZDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogdXNlcktleWNoYWluLnBydixcbiAgICAgIH0gYXMgYW55KTtcblxuICAgICAgKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQuZWlwMTU1OS5tYXhQcmlvcml0eUZlZVBlckdhcy5zaG91bGQuZXF1YWwoMTApO1xuICAgICAgKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKDEwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHdpdGggRUlQMTU1OSBmZWUgcGFyYW1zIGZvciBDQ1InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHNpZ25UcmFuc2FjdGlvbiA9IHNpbm9uLnNweShBYnN0cmFjdEV0aExpa2VOZXdDb2lucy5wcm90b3R5cGUsICdzaWduVHJhbnNhY3Rpb24nKTtcblxuICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICBwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLM2hla3lOajdUY2lSNFhOWWUxa01qNjhXMmlwakpHTkhFVFdQN280MkFqRG5TUGdLaGRaNHg4TkJBdmFMNzJSclhqdVhOZG1rTXFMRVJaemE3M29ZdWdHdGJMRlhHOGcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0JqRTVRRzdwa2Y5Y1pEMzNVVUQ2SzQ2cTdFTHJidUc3RnFYZkxOR2lYWUdIZUVuR0JiNUFXUkVuazFlQTI4ZzhBclp2VVJiaHNoWFdrVHRkZEhSbzU0Zmd5VnZMZGInLFxuICAgICAgICByYXdQdWI6ICcwMjM2MzZlNjhiN2IyMDQ1NzNhYmRhMjYxNmFmZjZiNTg0OTEwZGVjZTI1NDNmMWNjNmQ4NDJjYWFjN2Q3NDk3NGInLFxuICAgICAgICByYXdQcnY6ICc3NDM4YTUwMDEwY2U3YjFkZmQ4NmU2ODA0NmNjNzhiYTFlYmQyNDJkNmQ4NWQ5OTA0ZDNmY2MwODczNGJjMTcyJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcxMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnMTAwMCcsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGtleSA9IHRlc3REYXRhLktFWVBBSVJfUFJWLmdldEtleXMoKS5wcnYgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyXG4gICAgICAgIC5hbW91bnQoJzAnKVxuICAgICAgICAudG8oJzB4MTk2NDUwMzJjN2YxNTMzMzk1ZDQ0YTYyOTQ2MmU3NTEwODRkM2U0YycpXG4gICAgICAgIC5leHBpcmF0aW9uVGltZSgxNTkwMDY2NzI4KVxuICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDUpXG4gICAgICAgIC5rZXkoa2V5KTtcbiAgICAgIHR4QnVpbGRlci5jb250cmFjdChhZGRyZXNzMSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMCwgbWF4RmVlUGVyR2FzOiAxMCB9LFxuICAgICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYW1vdW50OiAnNDInLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnMHhjOTNiMTM2NDJkOTNiNDIxOGJiODVmNjczMTdkNmIzNzI4NmU4MDI4JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBleHBpcmVUaW1lOiAxNjI3OTQ5MjE0LFxuICAgICAgICAgIGNvbnRyYWN0U2VxdWVuY2VJZDogMTIsXG4gICAgICAgICAgZ2FzTGltaXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBnYXNQcmljZTogdW5kZWZpbmVkLFxuICAgICAgICAgIGhvcFRyYW5zYWN0aW9uOiB1bmRlZmluZWQsXG4gICAgICAgICAgYmFja3VwS2V5Tm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzZXF1ZW5jZUlkOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgICB0eEhleDogdHgudG9Ccm9hZGNhc3RGb3JtYXQoKSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiB1c2VyS2V5Y2hhaW4ucHJ2LFxuICAgICAgICBpc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5OiB0cnVlLFxuICAgICAgfSBhcyBhbnkpO1xuXG4gICAgICBhc3NlcnQoKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQudHhIZXgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4RmVlUGVyR2FzLCAxMCk7XG5cbiAgICAgIHNhbmRib3guYXNzZXJ0LmNhbGxlZE9uY2Uoc2lnblRyYW5zYWN0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0OiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIGJhdGNoIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICczNTAwMDAwMDAwMDAwJywgYWRkcmVzczogKGNvaW4/LnN0YXRpY3NDb2luPy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaykuYmF0Y2hlckNvbnRyYWN0QWRkcmVzcyB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IEVOUyBhZGRyZXNzIHJlc29sdXRpb24gY2hhbmdpbmcgcmVjaXBpZW50IGFkZHJlc3MgaW4gY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICdiaXRnb3Rlc3R3YWxsZXQuZXRoJyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogJzB4NDBhNjYzOTYzODEwNDQ5ZDZlNzI1MzM2NTdhNzRmMTEyYzNiOTAxYScgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgaG9wIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAxMDAwMDAwMDAwMDAwMDAwLCBhZGRyZXNzOiBob3BEZXN0aW5hdGlvbkFkZHJlc3MgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICc1MDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wQ29udHJhY3RBZGRyZXNzIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIGNsaWVudCB0eFBhcmFtcyBhcmUgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSBudWxsO1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyBwYXJhbXMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHR4UHJlYnVpbGQgdGhhdCBpcyBib3RoIGJhdGNoIGFuZCBob3AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzI3NzM5MjgxOTYnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4IGNhbm5vdCBiZSBib3RoIGEgYmF0Y2ggYW5kIGhvcCB0cmFuc2FjdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIG9uZSByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBgdGV0aCBkb2Vzbid0IHN1cHBvcnQgc2VuZGluZyB0byBtb3JlIHRoYW4gMSBkZXN0aW5hdGlvbiBhZGRyZXNzIHdpdGhpbiBhIHNpbmdsZSB0cmFuc2FjdGlvbi4gVHJ5IGFnYWluLCB1c2luZyBvbmx5IGEgc2luZ2xlIHJlY2lwaWVudC5gXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGhvcCB0eFByZWJ1aWxkIHRoYXQgZG9lcyBub3Qgc2VuZCB0byBpdHMgaG9wIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcwJyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdyZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGhvcCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGJhdGNoIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIHRvdGFsIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnNTUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IChjb2luPy5zdGF0aWNzQ29pbj8ubmV0d29yayBhcyBFdGhlcmV1bU5ldHdvcmspLmJhdGNoZXJDb250cmFjdEFkZHJlc3MgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdiYXRjaCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IGRvZXMgbm90IHNlbmQgdG8gdGhlIGJhdGNoZXIgY29udHJhY3QgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdyZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGJhdGNoZXIgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzIwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnbm9ybWFsIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0b2tlbiB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXN0Jyk7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHRva2VuOiAndGVzdCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIGNvaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAnYnRjJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2NvaW4gaW4gdHhQcmVidWlsZCBkaWQgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUU1MgVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGV4cGVjdERlZmlSZWplY3Rpb24gPSBhc3luYyAocDogUHJvbWlzZTx1bmtub3duPiwgbWVzc2FnZVBhdHRlcm46IFJlZ0V4cCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgcDtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBlcnIuc2hvdWxkLmJlLmluc3RhbmNlT2YoVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yKTtcbiAgICAgICAgKGVyciBhcyBFcnJvcikubWVzc2FnZS5zaG91bGQubWF0Y2gobWVzc2FnZVBhdHRlcm4pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIHZlcmlmeVRyYW5zYWN0aW9uIHRvIGJlIHJlamVjdGVkLCBidXQgaXQgcmVzb2x2ZWQnKTtcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24gd2hlbiB0eFByZWJ1aWxkIGhhcyBjb25zb2xpZGF0ZUlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gdHhQYXJhbXMgd2l0aG91dCByZWNpcGllbnRzIChhcyBpbiBjb25zb2xpZGF0aW9uIGZsb3cpXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICAvLyB0eFByZWJ1aWxkIHdpdGggY29uc29saWRhdGVJZCAoc2V0IGJ5IHNlcnZlciBkdXJpbmcgY29uc29saWRhdGlvbiBidWlsZClcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgdHJhbnNhY3Rpb24gd2hlbiB0eFBhcmFtcy50eXBlIGlzIGNvbnNvbGlkYXRlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aGVuIHR4UGFyYW1zLnByZWJ1aWxkVHggaGFzIGNvbnNvbGlkYXRlSWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIHByZWJ1aWxkVHg6IHtcbiAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IFRTUyB0cmFuc2FjdGlvbiB3aXRob3V0IHJlY2lwaWVudHMsIGNvbnNvbGlkYXRlSWQsIG9yIHZhbGlkIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHR4UGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgdHJhbnNhY3Rpb24gd2l0aCBhY2NlbGVyYXRpb24gdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnYWNjZWxlcmF0aW9uJyxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdpdGggZmlsbE5vbmNlIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogJ2ZpbGxOb25jZScsXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGRlZmlBcHByb3ZlIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBEZUZpIGRlcG9zaXQgZmxvdyBpcyBpbnRlbnQtYmFzZWQ6IHJlY2lwaWVudHMvY2FsbGRhdGEgYXJlIGJ1aWx0IHNlcnZlci1zaWRlXG4gICAgICAvLyBmcm9tIGRlZmlQYXJhbXMsIHNvIHR4UGFyYW1zIGhhcyBubyByZWNpcGllbnRzIChzZWUgQ0dELTE4MTUpLlxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICdkZWZpQXBwcm92ZScsXG4gICAgICAgIGRlZmlQYXJhbXM6IHsgdmF1bHRJZDogJ2h0ZXRoLXVzZGMtdGVzdCcsIGFtb3VudDogJzEwJyB9LFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFthZGRyZXNzMSwgJzEwJ10pKSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3dyYXBBcHByb3ZlIGNhbGxkYXRhIGFzc2VydGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhaXIgPSBjb2lucy5nZXQoJ2h0ZXRoOmN1c2R0JykgYXMgRXJjNzk4NENvaW47XG4gICAgICBjb25zdCB3cmFwcGVyID0gU3RyaW5nKHBhaXIuY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIGNvbnN0IHVuZGVybHlpbmcgPSBwYWlyLnVuZGVybHlpbmdFcmMyMEFkZHJlc3MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMDAnO1xuXG4gICAgICBjb25zdCB2ZXJpZnlXcmFwQXBwcm92ZSA9IGFzeW5jIChcbiAgICAgICAgZGF0YTogc3RyaW5nLFxuICAgICAgICBvcHRzOiB7IHRvPzogc3RyaW5nOyB3cmFwUGFyYW1zPzogeyB0b2tlbk5hbWU6IHN0cmluZzsgYW1vdW50OiBzdHJpbmcgfSB8IG51bGwgfSA9IHt9XG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBhZGRyZXNzMSB9IH0pO1xuICAgICAgICAvLyBXUCBkZXJpdmVzIHRoZSB1bmRlcmx5aW5nIHRva2VuLCBzcGVuZGVyIGFuZCBjYWxsZGF0YSBmcm9tIHdyYXBQYXJhbXMsIHNvIHRoZXJlIGFyZSBubyByZWNpcGllbnRzLlxuICAgICAgICBjb25zdCB3cmFwUGFyYW1zID1cbiAgICAgICAgICBvcHRzLndyYXBQYXJhbXMgPT09IG51bGwgPyB1bmRlZmluZWQgOiBvcHRzLndyYXBQYXJhbXMgPz8geyB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcsIGFtb3VudCB9O1xuICAgICAgICByZXR1cm4gY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ3dyYXBBcHByb3ZlJywgd3JhcFBhcmFtcyB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhLCBvcHRzLnRvID8/IHVuZGVybHlpbmcpLCBjb2luOiAnaHRldGgnLCB3YWxsZXRJZDogJ3cnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFwcHJvdmUod3JhcHBlciwgYW1vdW50KSBvbiB0aGUgdW5kZXJseWluZyBFUkMtMjAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZlcmlmeVdyYXBBcHByb3ZlKGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pKTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhcHByb3ZlIHdpdGggYSBzcGVuZGVyIG90aGVyIHRoYW4gdGhlIHdyYXBwZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgICAgdmVyaWZ5V3JhcEFwcHJvdmUoZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsIGFtb3VudF0pKSxcbiAgICAgICAgICAvc3BlbmRlciBkb2VzIG5vdCBtYXRjaCB0aGUgd3JhcHBlci9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhcHByb3ZlIHdpdGggYSBtdXRhdGVkIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlXcmFwQXBwcm92ZShkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCAnMTAwMDAwMSddKSksXG4gICAgICAgICAgL2Ftb3VudCBkb2VzIG5vdCBtYXRjaC9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBjYWxsZGF0YSB0aGF0IGlzIG5vdCBhcHByb3ZlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICAgIHZlcmlmeVdyYXBBcHByb3ZlKGRlZmlDYWxsZGF0YSgndHJhbnNmZXIoYWRkcmVzcyx1aW50MjU2KScsIFthZGRyZXNzMiwgYW1vdW50XSkpLFxuICAgICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGFwcHJvdmUgY2FsbGRhdGEgd2l0aCB0cmFpbGluZyBieXRlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlXcmFwQXBwcm92ZShkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCBhbW91bnRdKSArICcwMCcpLFxuICAgICAgICAgIC9leHBlY3RlZCA2OCBieXRlcy9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhcHByb3ZlIHNlbnQgdG8gYSBjb250cmFjdCBvdGhlciB0aGFuIHRoZSB1bmRlcmx5aW5nIEVSQy0yMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlXcmFwQXBwcm92ZShkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCBhbW91bnRdKSwgeyB0bzogYWRkcmVzczIgfSksXG4gICAgICAgICAgL211c3QgdGFyZ2V0IHRoZSB1bmRlcmx5aW5nIEVSQy0yMC9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCB3aGVuIHdyYXBQYXJhbXMgaXMgbWlzc2luZyBvciBuYW1lcyBhbiB1bnJlZ2lzdGVyZWQgcGFpcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pO1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKHZlcmlmeVdyYXBBcHByb3ZlKGRhdGEsIHsgd3JhcFBhcmFtczogbnVsbCB9KSwgL3JlcXVpcmVzIHdyYXBQYXJhbXMvKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlXcmFwQXBwcm92ZShkYXRhLCB7IHdyYXBQYXJhbXM6IHsgdG9rZW5OYW1lOiAnaHRldGgnLCBhbW91bnQgfSB9KSxcbiAgICAgICAgICAvbm90IGEgcmVnaXN0ZXJlZCBFUkMtNzk4NCBzaGllbGQgcGFpci9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhcHByb3ZlIHRoYXQgY2FycmllcyBuYXRpdmUgdmFsdWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAnLCBnYXNMaW1pdDogJzEwMDAwMCcgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QodW5kZXJseWluZyk7XG4gICAgICAgIHR4QnVpbGRlci5kYXRhKGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pKTtcbiAgICAgICAgdHhCdWlsZGVyLnZhbHVlKCcxJyk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICAgIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ3dyYXBBcHByb3ZlJywgd3JhcFBhcmFtczogeyB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcsIGFtb3VudCB9IH0gYXMgYW55LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleCwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICd3JyB9IGFzIGFueSxcbiAgICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICAvbXVzdCBub3QgY2FycnkgbmF0aXZlIHZhbHVlL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgcGVuZGluZ0FwcHJvdmFsIHJlLXNpZ24gd2hlcmUgdHhQYXJhbXMgYXJlIHJlc29sdmVkIGZyb20gdGhlIHBlcnNpc3RlZCBpbnRlbnQgb25seScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBhZGRyZXNzMSB9IH0pO1xuICAgICAgICAvLyByZWNyZWF0ZVR4UmVxdWVzdCgpIC0+IHNpZ25UeFJlcXVlc3QoKSBjYXJyaWVzIG5vIHR4UGFyYW1zOyB0aGUgaW50ZW50IGlzIHRoZSBvbmx5IHNvdXJjZS5cbiAgICAgICAgY29uc3QgdHhSZXF1ZXN0ID0geyBpbnRlbnQ6IHsgaW50ZW50VHlwZTogJ3dyYXBBcHByb3ZlJywgdG9rZW5OYW1lOiAnaHRldGg6Y3VzZHQnLCBhbW91bnQgfSB9IGFzIGFueTtcbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSByZXNvbHZlRWZmZWN0aXZlVHhQYXJhbXModHhSZXF1ZXN0LCB1bmRlZmluZWQpO1xuICAgICAgICBjb25zdCB0eEhleCA9IGF3YWl0IGJ1aWxkRGVmaVR4SGV4KGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pLCB1bmRlcmx5aW5nKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4LCBjb2luOiAnaHRldGgnLCB3YWxsZXRJZDogJ3cnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ211bHRpc2lnIHdyYXBBcHByb3ZlIHZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhaXIgPSBjb2lucy5nZXQoJ2h0ZXRoOmN1c2R0JykgYXMgRXJjNzk4NENvaW47XG4gICAgICBjb25zdCB3cmFwcGVyID0gU3RyaW5nKHBhaXIuY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIGNvbnN0IHVuZGVybHlpbmcgPSBwYWlyLnVuZGVybHlpbmdFcmMyMEFkZHJlc3MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMDAnO1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3QgPSBhZGRyZXNzMjtcblxuICAgICAgLy8gU2VydmVyLWJ1aWx0IG11bHRpc2lnIHNoYXBlOiB0eC50byA9IHdhbGxldCBjb250cmFjdCxcbiAgICAgIC8vIGRhdGEgPSBzZW5kTXVsdGlTaWcodW5kZXJseWluZywgMCwgYXBwcm92ZSh3cmFwcGVyLCBhbW91bnQpLCBleHBpcmVUaW1lLCBzZXF1ZW5jZUlkLCBzaWduYXR1cmUpXG4gICAgICBjb25zdCBzZW5kTXVsdGlTaWdDYWxsZGF0YSA9ICh0b0FkZHJlc3M6IHN0cmluZywgdmFsdWU6IHN0cmluZywgaW5uZXJEYXRhOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50JywgJ2J5dGVzJywgJ3VpbnQnLCAndWludCcsICdieXRlcyddO1xuICAgICAgICBjb25zdCBtZXRob2RJZCA9IEV0aGVyZXVtQWJpLm1ldGhvZElEKCdzZW5kTXVsdGlTaWcnLCB0eXBlcyk7XG4gICAgICAgIGNvbnN0IGVuY29kZWQgPSBFdGhlcmV1bUFiaS5yYXdFbmNvZGUodHlwZXMsIFtcbiAgICAgICAgICB0b0FkZHJlc3MsXG4gICAgICAgICAgbmV3IEJOKHZhbHVlKSxcbiAgICAgICAgICBCdWZmZXIuZnJvbShpbm5lckRhdGEuc2xpY2UoMiksICdoZXgnKSxcbiAgICAgICAgICAxMjM0LFxuICAgICAgICAgIDEsXG4gICAgICAgICAgQnVmZmVyLmFsbG9jKDApLFxuICAgICAgICBdKTtcbiAgICAgICAgcmV0dXJuICcweCcgKyBCdWZmZXIuY29uY2F0KFttZXRob2RJZCwgZW5jb2RlZF0pLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmeU11bHRpc2lnV3JhcEFwcHJvdmUgPSBhc3luYyAoXG4gICAgICAgIGRhdGE6IHN0cmluZyxcbiAgICAgICAgb3B0czoge1xuICAgICAgICAgIHRvPzogc3RyaW5nO1xuICAgICAgICAgIHdyYXBQYXJhbXM/OiB7IHRva2VuTmFtZTogc3RyaW5nOyBhbW91bnQ6IHN0cmluZyB9IHwgbnVsbDtcbiAgICAgICAgICB0eFByZWJ1aWxkUmVjaXBpZW50cz86IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcbiAgICAgICAgfSA9IHt9XG4gICAgICApID0+IHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBhZGRyZXNzMSB9IH0pO1xuICAgICAgICBjb25zdCB3cmFwUGFyYW1zID1cbiAgICAgICAgICBvcHRzLndyYXBQYXJhbXMgPT09IG51bGwgPyB1bmRlZmluZWQgOiBvcHRzLndyYXBQYXJhbXMgPz8geyB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcsIGFtb3VudCB9O1xuICAgICAgICByZXR1cm4gY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ3dyYXBBcHByb3ZlJywgd3JhcFBhcmFtcyB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGF0YSwgb3B0cy50byA/PyB3YWxsZXRDb250cmFjdCksXG4gICAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgICAgd2FsbGV0SWQ6ICd3JyxcbiAgICAgICAgICAgIC4uLihvcHRzLnR4UHJlYnVpbGRSZWNpcGllbnRzID8geyByZWNpcGllbnRzOiBvcHRzLnR4UHJlYnVpbGRSZWNpcGllbnRzIH0gOiB7fSksXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgYXBwcm92ZUNhbGxkYXRhID0gKHNwZW5kZXI6IHN0cmluZywgYXBwcm92ZUFtb3VudDogc3RyaW5nKSA9PlxuICAgICAgICBkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFtzcGVuZGVyLCBhcHByb3ZlQW1vdW50XSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFwcHJvdmUod3JhcHBlciwgYW1vdW50KSB3cmFwcGVkIGluIHNlbmRNdWx0aVNpZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHNlbmRNdWx0aVNpZ0NhbGxkYXRhKHVuZGVybHlpbmcsICcwJywgYXBwcm92ZUNhbGxkYXRhKHdyYXBwZXIsIGFtb3VudCkpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKGRhdGEsIHtcbiAgICAgICAgICB0eFByZWJ1aWxkUmVjaXBpZW50czogW3sgYWRkcmVzczogdW5kZXJseWluZywgYW1vdW50OiAnMCcsIGRhdGE6IGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyLCBhbW91bnQpIH1dLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhcHByb3ZlIHdyYXBwZWQgaW4gc2VuZE11bHRpU2lnIHdpdGhvdXQgcHJlYnVpbGQgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHNlbmRNdWx0aVNpZ0NhbGxkYXRhKHVuZGVybHlpbmcsICcwJywgYXBwcm92ZUNhbGxkYXRhKHdyYXBwZXIsIGFtb3VudCkpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKGRhdGEpO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgc3BlbmRlciBvdGhlciB0aGFuIHRoZSB3cmFwcGVyIGluc2lkZSBzZW5kTXVsdGlTaWcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgICAgdmVyaWZ5TXVsdGlzaWdXcmFwQXBwcm92ZShzZW5kTXVsdGlTaWdDYWxsZGF0YSh1bmRlcmx5aW5nLCAnMCcsIGFwcHJvdmVDYWxsZGF0YShhZGRyZXNzMiwgYW1vdW50KSkpLFxuICAgICAgICAgIC9zcGVuZGVyIGRvZXMgbm90IG1hdGNoIHRoZSB3cmFwcGVyL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbXV0YXRlZCBhbW91bnQgaW5zaWRlIHNlbmRNdWx0aVNpZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKHNlbmRNdWx0aVNpZ0NhbGxkYXRhKHVuZGVybHlpbmcsICcwJywgYXBwcm92ZUNhbGxkYXRhKHdyYXBwZXIsICcxMDAwMDAxJykpKSxcbiAgICAgICAgICAvYW1vdW50IGRvZXMgbm90IG1hdGNoL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlubmVyIGNhbGxkYXRhIHRoYXQgaXMgbm90IGFwcHJvdmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgICAgdmVyaWZ5TXVsdGlzaWdXcmFwQXBwcm92ZShcbiAgICAgICAgICAgIHNlbmRNdWx0aVNpZ0NhbGxkYXRhKHVuZGVybHlpbmcsICcwJywgZGVmaUNhbGxkYXRhKCd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MyLCBhbW91bnRdKSlcbiAgICAgICAgICApLFxuICAgICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgc2VuZE11bHRpU2lnIHRhcmdldCBvdGhlciB0aGFuIHRoZSB1bmRlcmx5aW5nIEVSQy0yMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKHNlbmRNdWx0aVNpZ0NhbGxkYXRhKGFkZHJlc3MyLCAnMCcsIGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyLCBhbW91bnQpKSksXG4gICAgICAgICAgL211c3QgdGFyZ2V0IHRoZSB1bmRlcmx5aW5nIEVSQy0yMC9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBuYXRpdmUgdmFsdWUgaW5zaWRlIHNlbmRNdWx0aVNpZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKHNlbmRNdWx0aVNpZ0NhbGxkYXRhKHVuZGVybHlpbmcsICcxJywgYXBwcm92ZUNhbGxkYXRhKHdyYXBwZXIsIGFtb3VudCkpKSxcbiAgICAgICAgICAvbXVzdCBub3QgY2FycnkgbmF0aXZlIHZhbHVlL1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gd3JhcFBhcmFtcyBpcyBtaXNzaW5nIG9yIG5hbWVzIGFuIHVucmVnaXN0ZXJlZCBwYWlyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBkYXRhID0gc2VuZE11bHRpU2lnQ2FsbGRhdGEodW5kZXJseWluZywgJzAnLCBhcHByb3ZlQ2FsbGRhdGEod3JhcHBlciwgYW1vdW50KSk7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24odmVyaWZ5TXVsdGlzaWdXcmFwQXBwcm92ZShkYXRhLCB7IHdyYXBQYXJhbXM6IG51bGwgfSksIC9yZXF1aXJlcyB3cmFwUGFyYW1zLyk7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgICAgdmVyaWZ5TXVsdGlzaWdXcmFwQXBwcm92ZShkYXRhLCB7IHdyYXBQYXJhbXM6IHsgdG9rZW5OYW1lOiAnaHRldGgnLCBhbW91bnQgfSB9KSxcbiAgICAgICAgICAvbm90IGEgcmVnaXN0ZXJlZCBFUkMtNzk4NCBzaGllbGQgcGFpci9cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgY2xvc2VkIG9uIGEgdHggdGhhdCBpcyBub3Qgc2VuZE11bHRpU2lnLXdyYXBwZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24odmVyaWZ5TXVsdGlzaWdXcmFwQXBwcm92ZShhcHByb3ZlQ2FsbGRhdGEod3JhcHBlciwgYW1vdW50KSksIC9zZW5kTXVsdGlTaWcvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBwcmVidWlsZCByZWNpcGllbnRzIHRoYXQgZG8gbm90IG1pcnJvciB0aGUgc2VuZE11bHRpU2lnIGFyZ3MgaW4gdHhIZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBzZW5kTXVsdGlTaWdDYWxsZGF0YSh1bmRlcmx5aW5nLCAnMCcsIGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyLCBhbW91bnQpKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKGRhdGEsIHtcbiAgICAgICAgICAgIHR4UHJlYnVpbGRSZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBhZGRyZXNzMiwgYW1vdW50OiAnMCcsIGRhdGE6IGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyLCBhbW91bnQpIH1dLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIC9yZWNpcGllbnQgYWRkcmVzcyBkb2VzIG5vdCBtYXRjaCB0aGUgc2VuZE11bHRpU2lnIHRhcmdldC9cbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICB2ZXJpZnlNdWx0aXNpZ1dyYXBBcHByb3ZlKGRhdGEsIHtcbiAgICAgICAgICAgIHR4UHJlYnVpbGRSZWNpcGllbnRzOiBbeyBhZGRyZXNzOiB1bmRlcmx5aW5nLCBhbW91bnQ6ICcwJywgZGF0YTogYXBwcm92ZUNhbGxkYXRhKGFkZHJlc3MyLCBhbW91bnQpIH1dLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIC9yZWNpcGllbnQgZGF0YSBkb2VzIG5vdCBtYXRjaCB0aGUgc2VuZE11bHRpU2lnIGNhbGxkYXRhL1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnd3JhcHBlci1kaXJlY3RlZCBhcHByb3ZlIG11c3QgYmUgZGVjbGFyZWQgd3JhcEFwcHJvdmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYWlyID0gY29pbnMuZ2V0KCdodGV0aDpjdXNkdCcpIGFzIEVyYzc5ODRDb2luO1xuICAgICAgY29uc3Qgd3JhcHBlciA9IFN0cmluZyhwYWlyLmNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICBjb25zdCB1bmRlcmx5aW5nID0gcGFpci51bmRlcmx5aW5nRXJjMjBBZGRyZXNzIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMDAwJztcblxuICAgICAgY29uc3QgdmVyaWZ5QXMgPSBhc3luYyAodHlwZTogc3RyaW5nLCBkYXRhOiBzdHJpbmcsIHRvOiBzdHJpbmcgPSB1bmRlcmx5aW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgICAgcmV0dXJuIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGUsIGRlZmlQYXJhbXM6IHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50IH0sIHdhbGxldCB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhLCB0byksIGNvaW46ICdodGV0aCcsIHdhbGxldElkOiAndycgfSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgWyd0b2tlbkFwcHJvdmFsJywgJ2N1c3RvbVR4JywgJ2RlZmlBcHByb3ZlJ10uZm9yRWFjaCgodHlwZSkgPT4ge1xuICAgICAgICBpdChgc2hvdWxkIHJlamVjdCBhcHByb3ZlKHdyYXBwZXIsIGFtb3VudCkgb24gdGhlIHVuZGVybHlpbmcgcmVsYWJlbGxlZCBhcyAke3R5cGV9YCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgICAgICB2ZXJpZnlBcyh0eXBlLCBkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCBhbW91bnRdKSksXG4gICAgICAgICAgICAvbXVzdCBiZSBkZWNsYXJlZCBhcyBhIHdyYXBBcHByb3ZlIGludGVudC9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG11dGF0ZWQtYW1vdW50IHdyYXBwZXIgYXBwcm92ZSByZWxhYmVsbGVkIGFzIGN1c3RvbVR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICAgIHZlcmlmeUFzKCdjdXN0b21UeCcsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsICc5OTk5OTk5OTk5OTknXSkpLFxuICAgICAgICAgIC9tdXN0IGJlIGRlY2xhcmVkIGFzIGEgd3JhcEFwcHJvdmUgaW50ZW50L1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgd3JhcHBlciBhcHByb3ZlIHdpdGggdHJhaWxpbmcgYnl0ZXMgKGFuIEVSQy0yMCBpZ25vcmVzIHRoZW0pJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICAgIHZlcmlmeUFzKCdjdXN0b21UeCcsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pICsgJzAwJyksXG4gICAgICAgICAgL211c3QgYmUgZGVjbGFyZWQgYXMgYSB3cmFwQXBwcm92ZSBpbnRlbnQvXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBub3QgYWZmZWN0IGFwcHJvdmFscyBvZiB0aGUgdW5kZXJseWluZyB0byBvdGhlciBzcGVuZGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKGF3YWl0IHZlcmlmeUFzKCdjdXN0b21UeCcsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MyLCBhbW91bnRdKSkpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgKGF3YWl0IHZlcmlmeUFzKCd0b2tlbkFwcHJvdmFsJywgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsIGFtb3VudF0pKSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBwYXJzZSB0aGUgdHggYXQgYWxsIHdoZW4gdGhlIGNhbGxkYXRhIGNhcnJpZXMgbm8gYXBwcm92ZSBzZWxlY3RvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBhZGRyZXNzMSB9IH0pO1xuICAgICAgICBjb25zdCB2ZXJpZnlXaXRoID0gYXN5bmMgKGRhdGE6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGNvbnN0IHR4SGV4ID0gYXdhaXQgYnVpbGREZWZpVHhIZXgoZGF0YSwgdW5kZXJseWluZyk7XG4gICAgICAgICAgLy8gZ2V0VHJhbnNhY3Rpb25CdWlsZGVyIGlzIG5vdCBwYXJ0IG9mIHRoZSBjb2luJ3MgcHVibGljIHR5cGUsIHNvIHNweSB0aHJvdWdoIGEgbWluaW1hbCBzdHJ1Y3R1cmFsIHZpZXcuXG4gICAgICAgICAgY29uc3QgYnVpbGRlclNweSA9IHNpbm9uLnNweShcbiAgICAgICAgICAgIGNvaW4gYXMgdW5rbm93biBhcyB7IGdldFRyYW5zYWN0aW9uQnVpbGRlcjogKCkgPT4gdW5rbm93biB9LFxuICAgICAgICAgICAgJ2dldFRyYW5zYWN0aW9uQnVpbGRlcidcbiAgICAgICAgICApO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2N1c3RvbVR4Jywgd2FsbGV0IH0gYXMgYW55LFxuICAgICAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4LCBjb2luOiAnaHRldGgnLCB3YWxsZXRJZDogJ3cnIH0gYXMgYW55LFxuICAgICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRlclNweS5jYWxsQ291bnQ7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGJ1aWxkZXJTcHkucmVzdG9yZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAoYXdhaXQgdmVyaWZ5V2l0aChkZWZpQ2FsbGRhdGEoJ3RyYW5zZmVyKGFkZHJlc3MsdWludDI1NiknLCBbd3JhcHBlciwgYW1vdW50XSkpKS5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIChhd2FpdCB2ZXJpZnlXaXRoKGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MyLCBhbW91bnRdKSkpLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGxlYXZlIG90aGVyIGRlY2xhcmVkIHR5cGVzIHVudG91Y2hlZCBmb3IgdHhzIHRoYXQgYXJlIG5vdCBhIHdyYXBwZXIgYXBwcm92ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gRXZlcnkgdHlwZSBiZWxvdyBza2lwcyB0aGUgd3JhcEFwcHJvdmUgY2hlY2sgYW5kIHJlYWNoZXMgdGhlIGd1YXJkOyBub25lIG9mIHRoZXNlIHR4cyBpcyBhbiBhcHByb3ZlIG9mIGFcbiAgICAgICAgLy8gd3JhcHBlciwgc28gYWxsIG11c3QgdmVyaWZ5IGV4YWN0bHkgYXMgdGhleSBkaWQgYmVmb3JlIHRoZSBndWFyZCBleGlzdGVkLlxuICAgICAgICBjb25zdCBiZW5pZ246IEFycmF5PFtzdHJpbmcsIHN0cmluZywgc3RyaW5nXT4gPSBbXG4gICAgICAgICAgWydjdXN0b21UeCcsIGRlZmlDYWxsZGF0YSgndHJhbnNmZXIoYWRkcmVzcyx1aW50MjU2KScsIFthZGRyZXNzMiwgYW1vdW50XSksIHVuZGVybHlpbmddLFxuICAgICAgICAgIFsnY3VzdG9tVHgnLCBkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFthZGRyZXNzMiwgYW1vdW50XSksIHVuZGVybHlpbmddLFxuICAgICAgICAgIFsnY3VzdG9tVHgnLCBkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCBhbW91bnRdKSwgYWRkcmVzczJdLFxuICAgICAgICAgIFsndG9rZW5BcHByb3ZhbCcsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MyLCBhbW91bnRdKSwgdW5kZXJseWluZ10sXG4gICAgICAgICAgWyd0b2tlbkFwcHJvdmFsJywgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbd3JhcHBlciwgYW1vdW50XSksIGFkZHJlc3MyXSxcbiAgICAgICAgICBbJ2FjY2VsZXJhdGlvbicsIGRlZmlDYWxsZGF0YSgndHJhbnNmZXIoYWRkcmVzcyx1aW50MjU2KScsIFthZGRyZXNzMiwgYW1vdW50XSksIGFkZHJlc3MyXSxcbiAgICAgICAgICBbJ2ZpbGxOb25jZScsICcweCcsIGFkZHJlc3MyXSxcbiAgICAgICAgICBbJ2VuYWJsZXRva2VuJywgZGVmaUNhbGxkYXRhKCd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MyLCBhbW91bnRdKSwgYWRkcmVzczJdLFxuICAgICAgICBdO1xuICAgICAgICBmb3IgKGNvbnN0IFt0eXBlLCBkYXRhLCB0b10gb2YgYmVuaWduKSB7XG4gICAgICAgICAgKGF3YWl0IHZlcmlmeUFzKHR5cGUsIGRhdGEsIHRvKSkuc2hvdWxkLmVxdWFsKHRydWUsIGAke3R5cGV9IHRvICR7dG99IHNob3VsZCBzdGlsbCB2ZXJpZnlgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGFmZmVjdCB0cmFuc2ZlcnMgdG8gdGhlIHVuZGVybHlpbmcgb3IgYXBwcm92ZXMgb2YgdGhlIHdyYXBwZXIgb24gb3RoZXIgY29udHJhY3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAoYXdhaXQgdmVyaWZ5QXMoJ2N1c3RvbVR4JywgZGVmaUNhbGxkYXRhKCd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsIGFtb3VudF0pKSkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICAoXG4gICAgICAgICAgYXdhaXQgdmVyaWZ5QXMoJ2N1c3RvbVR4JywgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbd3JhcHBlciwgYW1vdW50XSksIGFkZHJlc3MyKVxuICAgICAgICApLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN0aWxsIHZlcmlmeSBhIGRlY2xhcmVkIHdyYXBBcHByb3ZlIHRocm91Z2ggdGhlIGZ1bGwgY2hlY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ3dyYXBBcHByb3ZlJywgd3JhcFBhcmFtczogeyB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcsIGFtb3VudCB9IH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkZWZpQ2FsbGRhdGEoJ2FwcHJvdmUoYWRkcmVzcyx1aW50MjU2KScsIFt3cmFwcGVyLCBhbW91bnRdKSwgdW5kZXJseWluZyksXG4gICAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgICAgd2FsbGV0SWQ6ICd3JyxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdtdWx0aXNpZyB3cmFwcGVyLWRpcmVjdGVkIGFwcHJvdmUgbXVzdCBiZSBkZWNsYXJlZCB3cmFwQXBwcm92ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhaXIgPSBjb2lucy5nZXQoJ2h0ZXRoOmN1c2R0JykgYXMgRXJjNzk4NENvaW47XG4gICAgICBjb25zdCB3cmFwcGVyID0gU3RyaW5nKHBhaXIuY29udHJhY3RBZGRyZXNzKTtcbiAgICAgIGNvbnN0IHVuZGVybHlpbmcgPSBwYWlyLnVuZGVybHlpbmdFcmMyMEFkZHJlc3MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYW1vdW50ID0gJzEwMDAwMDAnO1xuICAgICAgY29uc3Qgd2FsbGV0Q29udHJhY3QgPSBhZGRyZXNzMjtcblxuICAgICAgY29uc3Qgc2VuZE11bHRpU2lnQ2FsbGRhdGEgPSAodG9BZGRyZXNzOiBzdHJpbmcsIGlubmVyRGF0YTogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBbJ2FkZHJlc3MnLCAndWludCcsICdieXRlcycsICd1aW50JywgJ3VpbnQnLCAnYnl0ZXMnXTtcbiAgICAgICAgY29uc3QgbWV0aG9kSWQgPSBFdGhlcmV1bUFiaS5tZXRob2RJRCgnc2VuZE11bHRpU2lnJywgdHlwZXMpO1xuICAgICAgICBjb25zdCBlbmNvZGVkID0gRXRoZXJldW1BYmkucmF3RW5jb2RlKHR5cGVzLCBbXG4gICAgICAgICAgdG9BZGRyZXNzLFxuICAgICAgICAgIG5ldyBCTignMCcpLFxuICAgICAgICAgIEJ1ZmZlci5mcm9tKGlubmVyRGF0YS5zbGljZSgyKSwgJ2hleCcpLFxuICAgICAgICAgIDEyMzQsXG4gICAgICAgICAgMSxcbiAgICAgICAgICBCdWZmZXIuYWxsb2MoMCksXG4gICAgICAgIF0pO1xuICAgICAgICByZXR1cm4gJzB4JyArIEJ1ZmZlci5jb25jYXQoW21ldGhvZElkLCBlbmNvZGVkXSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgYXBwcm92ZUNhbGxkYXRhID0gKHNwZW5kZXI6IHN0cmluZykgPT4gZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbc3BlbmRlciwgYW1vdW50XSk7XG5cbiAgICAgIGNvbnN0IHZlcmlmeUFzID0gYXN5bmMgKHR5cGU6IHN0cmluZywgdGFyZ2V0OiBzdHJpbmcsIGlubmVyRGF0YTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFt7IGFkZHJlc3M6IHRhcmdldCwgYW1vdW50OiAnMCcgfV07XG4gICAgICAgIHJldHVybiBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogeyB0eXBlLCByZWNpcGllbnRzIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChzZW5kTXVsdGlTaWdDYWxsZGF0YSh0YXJnZXQsIGlubmVyRGF0YSksIHdhbGxldENvbnRyYWN0KSxcbiAgICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgICB3YWxsZXRJZDogJ3cnLFxuICAgICAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAnb25jaGFpbicsXG4gICAgICAgIH0pO1xuICAgICAgfTtcblxuICAgICAgWyd0cmFuc2ZlcicsICd0b2tlbkFwcHJvdmFsJywgJ2N1c3RvbVR4JywgJ2RlZmlBcHByb3ZlJ10uZm9yRWFjaCgodHlwZSkgPT4ge1xuICAgICAgICBpdChgc2hvdWxkIHJlamVjdCBzZW5kTXVsdGlTaWcoYXBwcm92ZSh3cmFwcGVyLCBhbW91bnQpKSBvbiB0aGUgdW5kZXJseWluZyByZWxhYmVsbGVkIGFzICR7dHlwZX1gLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgICAgIHZlcmlmeUFzKHR5cGUsIHVuZGVybHlpbmcsIGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyKSksXG4gICAgICAgICAgICAvbXVzdCBiZSBkZWNsYXJlZCBhcyBhIHdyYXBBcHByb3ZlIGludGVudC9cbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG11dGF0ZWQtYW1vdW50IHdyYXBwZXIgYXBwcm92ZSBpbnNpZGUgc2VuZE11bHRpU2lnJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICAgIHZlcmlmeUFzKCd0cmFuc2ZlcicsIHVuZGVybHlpbmcsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW3dyYXBwZXIsICc5OTk5OTk5OTk5OTknXSkpLFxuICAgICAgICAgIC9tdXN0IGJlIGRlY2xhcmVkIGFzIGEgd3JhcEFwcHJvdmUgaW50ZW50L1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IGFmZmVjdCBzZW5kTXVsdGlTaWcgYXBwcm92YWxzIG9mIHRoZSB1bmRlcmx5aW5nIHRvIG90aGVyIHNwZW5kZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAoYXdhaXQgdmVyaWZ5QXMoJ3RyYW5zZmVyJywgdW5kZXJseWluZywgYXBwcm92ZUNhbGxkYXRhKGFkZHJlc3MxKSkpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBhZmZlY3QgYSBzZW5kTXVsdGlTaWcgYXBwcm92ZSBvZiB0aGUgd3JhcHBlciBhaW1lZCBhdCBhIG5vbi11bmRlcmx5aW5nIGNvbnRyYWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAoYXdhaXQgdmVyaWZ5QXMoJ3RyYW5zZmVyJywgYWRkcmVzczEsIGFwcHJvdmVDYWxsZGF0YSh3cmFwcGVyKSkpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIG5vdCBhZmZlY3QgYSBwbGFpbiBuYXRpdmUgc2VuZE11bHRpU2lnIHRyYW5zZmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAoYXdhaXQgdmVyaWZ5QXMoJ3RyYW5zZmVyJywgYWRkcmVzczEsICcweCcpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdGlsbCB2ZXJpZnkgYSBkZWNsYXJlZCB3cmFwQXBwcm92ZSBpbnNpZGUgc2VuZE11bHRpU2lnJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IGFkZHJlc3MxIH0gfSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGU6ICd3cmFwQXBwcm92ZScsIHdyYXBQYXJhbXM6IHsgdG9rZW5OYW1lOiAnaHRldGg6Y3VzZHQnLCBhbW91bnQgfSB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoc2VuZE11bHRpU2lnQ2FsbGRhdGEodW5kZXJseWluZywgYXBwcm92ZUNhbGxkYXRhKHdyYXBwZXIpKSwgd2FsbGV0Q29udHJhY3QpLFxuICAgICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICAgIHdhbGxldElkOiAndycsXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ29uY2hhaW4nLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdpdGggZGVmaURlcG9zaXQgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZGVmaURlcG9zaXQnLFxuICAgICAgICBkZWZpUGFyYW1zOiB7IHZhdWx0SWQ6ICdodGV0aC11c2RjLXRlc3QnLCBhbW91bnQ6ICcxMCcsIG9wZXJhdGlvbklkOiAnZmFrZU9wZXJhdGlvbklkJyB9LFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkZWZpQ2FsbGRhdGEoJ2RlcG9zaXQodWludDI1NixhZGRyZXNzKScsIFsnMTAnLCBhZGRyZXNzMV0pKSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgRGVGaSBjYWxsZGF0YSB0aGF0IHJlZGlyZWN0cyBmdW5kcyBvciBncmFudHMgZXhjZXNzIGFwcHJvdmFsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IGFzeW5jICh0eXBlOiBzdHJpbmcsIGRlZmlQYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLCBkYXRhOiBzdHJpbmcpID0+XG4gICAgICAgIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGUsIGRlZmlQYXJhbXMsIHdhbGxldCB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhKSwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcblxuICAgICAgLy8gZGVmaUFwcHJvdmU6IGF0dGFja2VyIGFwcHJvdmUoYXR0YWNrZXIsIE1BWF9VSU5UMjU2KSBkaXNndWlzZWQgYXMgZGVmaUFwcHJvdmVcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeShcbiAgICAgICAgICAnZGVmaUFwcHJvdmUnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsICcxMDAwMDAwMDAwMDAwMDAwMDAwJ10pXG4gICAgICAgICksXG4gICAgICAgIC9hbW91bnQgZG9lcyBub3QgbWF0Y2gvXG4gICAgICApO1xuICAgICAgLy8gZGVmaURlcG9zaXQ6IGZ1bmRzIHJlZGlyZWN0ZWQgdG8gYXR0YWNrZXIgcmVjZWl2ZXJcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeShcbiAgICAgICAgICAnZGVmaURlcG9zaXQnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdkZXBvc2l0KHVpbnQyNTYsYWRkcmVzcyknLCBbJzEwJywgYWRkcmVzczJdKVxuICAgICAgICApLFxuICAgICAgICAvcmVjZWl2ZXIgZG9lcyBub3QgbWF0Y2gvXG4gICAgICApO1xuICAgICAgLy8gZGVmaVdpdGhkcmF3OiByZWNlaXZlciBhbmQgb3duZXIgYm90aCBhdHRhY2tlclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KFxuICAgICAgICAgICdkZWZpV2l0aGRyYXcnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWyc1JywgYWRkcmVzczIsIGFkZHJlc3MyXSlcbiAgICAgICAgKSxcbiAgICAgICAgL3JlY2VpdmVyIGFuZCBvd25lci9cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBEZUZpIGNhbGxkYXRhIHdpdGggd3Jvbmcgc2VsZWN0b3IsIHdyb25nIG93bmVyIGFsb25lLCBvciB3cm9uZyBkZXBvc2l0IGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IGFkZHJlc3MxIH0gfSk7XG4gICAgICBjb25zdCB2ZXJpZnkgPSBhc3luYyAodHlwZTogc3RyaW5nLCBkZWZpUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgZGF0YTogc3RyaW5nKSA9PlxuICAgICAgICBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogeyB0eXBlLCBkZWZpUGFyYW1zLCB3YWxsZXQgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGF0YSksIGNvaW46ICdodGV0aCcsIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBkZWZpUGFyYW1zID0geyB2YXVsdElkOiAndmF1bHQnLCBhbW91bnQ6ICcxMCcgfTtcblxuICAgICAgLy8gZGVmaUFwcHJvdmUgd2l0aCBhIG5vbi1hcHByb3ZlIHNlbGVjdG9yICh0cmFuc2ZlciBkaXNndWlzZWQgYXMgYXBwcm92ZSlcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaUFwcHJvdmUnLCBkZWZpUGFyYW1zLCBkZWZpQ2FsbGRhdGEoJ3RyYW5zZmVyKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsICcxMCddKSksXG4gICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlEZXBvc2l0IHdpdGggYSBub24tZGVwb3NpdCBzZWxlY3RvclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpRGVwb3NpdCcsIGRlZmlQYXJhbXMsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MxLCAnMTAnXSkpLFxuICAgICAgICAvZGVwb3NpdFxcKHVpbnQyNTYsYWRkcmVzc1xcKS9cbiAgICAgICk7XG4gICAgICAvLyBkZWZpV2l0aGRyYXcgd2l0aCBhIG5vbi1yZWRlZW0gc2VsZWN0b3JcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaVdpdGhkcmF3JywgZGVmaVBhcmFtcywgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczEsICcxMCddKSksXG4gICAgICAgIC9yZWRlZW1cXCh1aW50MjU2LGFkZHJlc3MsYWRkcmVzc1xcKS9cbiAgICAgICk7XG4gICAgICAvLyBkZWZpV2l0aGRyYXc6IHJlY2VpdmVyIG9rIGJ1dCBvd25lciBpcyBhdHRhY2tlclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpV2l0aGRyYXcnLCBkZWZpUGFyYW1zLCBkZWZpQ2FsbGRhdGEoJ3JlZGVlbSh1aW50MjU2LGFkZHJlc3MsYWRkcmVzcyknLCBbJzEwJywgYWRkcmVzczEsIGFkZHJlc3MyXSkpLFxuICAgICAgICAvcmVjZWl2ZXIgYW5kIG93bmVyL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlXaXRoZHJhdzogcmVjZWl2ZXIgYW5kIG93bmVyIG9rIGJ1dCBzaGFyZXMgZG8gbm90IG1hdGNoIGRlZmlQYXJhbXMuYW1vdW50XG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoXG4gICAgICAgICAgJ2RlZmlXaXRoZHJhdycsXG4gICAgICAgICAgZGVmaVBhcmFtcyxcbiAgICAgICAgICBkZWZpQ2FsbGRhdGEoJ3JlZGVlbSh1aW50MjU2LGFkZHJlc3MsYWRkcmVzcyknLCBbJzk5OScsIGFkZHJlc3MxLCBhZGRyZXNzMV0pXG4gICAgICAgICksXG4gICAgICAgIC9zaGFyZXMgZG8gbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlEZXBvc2l0OiByZWNlaXZlciBvayBidXQgYW1vdW50IG1pc21hdGNoXG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlEZXBvc2l0JywgZGVmaVBhcmFtcywgZGVmaUNhbGxkYXRhKCdkZXBvc2l0KHVpbnQyNTYsYWRkcmVzcyknLCBbJzk5OScsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvYW1vdW50IGRvZXMgbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBjbG9zZWQgd2hlbiBkZWZpIGludGVudCBwYXJhbWV0ZXJzIGFyZSBtaXNzaW5nIG9yIGNhbGxkYXRhIGlzIHNob3J0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IGFzeW5jICh0eXBlOiBzdHJpbmcsIGRlZmlQYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLCBkYXRhOiBzdHJpbmcpID0+XG4gICAgICAgIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGUsIGRlZmlQYXJhbXMsIHdhbGxldCB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhKSwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcblxuICAgICAgLy8gTWlzc2luZyBkZWZpUGFyYW1zIGZvciBlYWNoIGRlZmkgdHlwZSAtPiBmYWlsIGNsb3NlZFxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpQXBwcm92ZScsIHVuZGVmaW5lZCwgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczEsICcxMCddKSksXG4gICAgICAgIC9taXNzaW5nIHJlcXVpcmVkIGludGVudCBwYXJhbWV0ZXJzL1xuICAgICAgKTtcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaURlcG9zaXQnLCB1bmRlZmluZWQsIGRlZmlDYWxsZGF0YSgnZGVwb3NpdCh1aW50MjU2LGFkZHJlc3MpJywgWycxMCcsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvbWlzc2luZyByZXF1aXJlZCBpbnRlbnQgcGFyYW1ldGVycy9cbiAgICAgICk7XG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlXaXRoZHJhdycsIHVuZGVmaW5lZCwgZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWyc1JywgYWRkcmVzczEsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvbWlzc2luZyByZXF1aXJlZCBpbnRlbnQgcGFyYW1ldGVycy9cbiAgICAgICk7XG4gICAgICAvLyBTaG9ydC9lbXB0eSBjYWxsZGF0YSB3aXRoIG5vIHZhbGlkIHNlbGVjdG9yIHByZWZpeCAtPiBzZWxlY3RvciBtaXNtYXRjaCAoZmFpbCBjbG9zZWQpXG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlBcHByb3ZlJywgeyB2YXVsdElkOiAndmF1bHQnLCBhbW91bnQ6ICcxMCcgfSwgJzB4JyksXG4gICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGRlZmlXaXRoZHJhdyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZGVmaVdpdGhkcmF3JyxcbiAgICAgICAgZGVmaVBhcmFtczogeyB2YXVsdElkOiAnaHRldGgtdXNkYy10ZXN0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWycxMCcsIGFkZHJlc3MxLCBhZGRyZXNzMV0pKSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzcyB2ZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBjb25zb2xpZGF0aW9uIHdoZW4gcmVjaXBpZW50IG1hdGNoZXMgYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcblxuICAgICAgICAvLyBCdWlsZCBhIHJlYWwgdHJhbnNhY3Rpb24gdGhhdCBzZW5kcyB0byB0aGUgYmFzZUFkZHJlc3NcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICAgIGdhc0xpbWl0OiAnMjEwMDAnLFxuICAgICAgICB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdChiYXNlQWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci52YWx1ZSgnMTAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgdHhIZXg6IHR4SGV4LFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pO1xuICAgICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGNvbnNvbGlkYXRpb24gd2hlbiByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgICAgY29uc3Qgd3JvbmdSZWNpcGllbnQgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcblxuICAgICAgICAvLyBCdWlsZCBhIHRyYW5zYWN0aW9uIHRoYXQgc2VuZHMgdG8gYSBESUZGRVJFTlQgYWRkcmVzcyAobm90IGJhc2VBZGRyZXNzKVxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNpbmdsZVNpZ1NlbmQpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgICBmZWU6ICcxMCcsXG4gICAgICAgICAgZ2FzTGltaXQ6ICcyMTAwMCcsXG4gICAgICAgIH0pO1xuICAgICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KHdyb25nUmVjaXBpZW50KTtcbiAgICAgICAgdHhCdWlsZGVyLnZhbHVlKCcxMDAwMDAwMDAwMDAwMDAwMDAwJyk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgICB0eEhleDogdHhIZXgsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ29uc29saWRhdGlvbiB0cmFuc2FjdGlvbiByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB0eEhleCBpcyBtaXNzaW5nIGZvciBjb25zb2xpZGF0aW9uIHZlcmlmaWNhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgLy8gSW50ZW50aW9uYWxseSBtaXNzaW5nIHR4SGV4XG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyB0eEhleCBpbiB0eFByZWJ1aWxkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgRVJDMjAgdG9rZW4gY29uc29saWRhdGlvbiB3aGVuIGNhbGxkYXRhIHJlY2lwaWVudCBtYXRjaGVzIGJhc2UgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4YTBiODY5OTFjNjIxOGIzNmMxZDE5ZDRhMmU5ZWIwY2UzNjA2ZWI0OCc7XG5cbiAgICAgICAgLy8gQnVpbGQgYW4gRVJDMjAgdHJhbnNmZXIoYWRkcmVzcywgdWludDI1NikgdHgg4oCUIG1pbWljcyB3aGF0IHRoZSBzZXJ2ZXIgcmV0dXJuc1xuICAgICAgICAvLyBmb3IgYSB2NiBUU1Mgd2FsbGV0IHRva2VuIGNvbnNvbGlkYXRpb246IHR4SnNvbi50byA9IHRva2VuIGNvbnRyYWN0LFxuICAgICAgICAvLyBhY3R1YWwgcmVjaXBpZW50IGlzIGVuY29kZWQgaW4gdGhlIDB4YTkwNTljYmIgY2FsbGRhdGFcbiAgICAgICAgY29uc3QgbWV0aG9kSWQgPSBFdGhlcmV1bUFiaS5tZXRob2RJRCgndHJhbnNmZXInLCBbJ2FkZHJlc3MnLCAndWludDI1NiddKTtcbiAgICAgICAgY29uc3QgZW5jb2RlZFBhcmFtcyA9IEV0aGVyZXVtQWJpLnJhd0VuY29kZShbJ2FkZHJlc3MnLCAndWludDI1NiddLCBbYmFzZUFkZHJlc3MsICcxMDAwMDAwMCddKTtcbiAgICAgICAgY29uc3QgZXJjMjBUcmFuc2ZlckRhdGEgPSAnMHgnICsgQnVmZmVyLmNvbmNhdChbbWV0aG9kSWQsIGVuY29kZWRQYXJhbXNdKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAnLCBnYXNMaW1pdDogJzYwMDAwJyB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdCh0b2tlbkNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci5kYXRhKGVyYzIwVHJhbnNmZXJEYXRhKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3MgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2NvbnNvbGlkYXRlJywgd2FsbGV0LCB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZScgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogeyBjb25zb2xpZGF0ZUlkOiAnYWJjMTIzJywgdHhIZXgsIGNvaW46ICdodGV0aCcsIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7IGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlIH0sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pO1xuICAgICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IEVSQzIwIHRva2VuIGNvbnNvbGlkYXRpb24gd2hlbiBjYWxsZGF0YSByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgICAgY29uc3Qgd3JvbmdSZWNpcGllbnQgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcbiAgICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJlc3MgPSAnMHhhMGI4Njk5MWM2MjE4YjM2YzFkMTlkNGEyZTllYjBjZTM2MDZlYjQ4JztcblxuICAgICAgICAvLyBCdWlsZCBhbiBFUkMyMCB0cmFuc2ZlciB3aGVyZSBjYWxsZGF0YSByZWNpcGllbnQgaXMgYSBXUk9ORyBhZGRyZXNzXG4gICAgICAgIGNvbnN0IG1ldGhvZElkID0gRXRoZXJldW1BYmkubWV0aG9kSUQoJ3RyYW5zZmVyJywgWydhZGRyZXNzJywgJ3VpbnQyNTYnXSk7XG4gICAgICAgIGNvbnN0IGVuY29kZWRQYXJhbXMgPSBFdGhlcmV1bUFiaS5yYXdFbmNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnXSwgW3dyb25nUmVjaXBpZW50LCAnMTAwMDAwMDAnXSk7XG4gICAgICAgIGNvbnN0IGVyYzIwVHJhbnNmZXJEYXRhID0gJzB4JyArIEJ1ZmZlci5jb25jYXQoW21ldGhvZElkLCBlbmNvZGVkUGFyYW1zXSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZTogJzEwJywgZ2FzTGltaXQ6ICc2MDAwMCcgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QodG9rZW5Db250cmFjdEFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIuZGF0YShlcmMyMFRyYW5zZmVyRGF0YSk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2NvbnNvbGlkYXRlJywgd2FsbGV0LCB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZScgfSBhcyBhbnksXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IGNvbnNvbGlkYXRlSWQ6ICdhYmMxMjMnLCB0eEhleCwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uOiB7IGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlIH0sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHJlY2lwaWVudCBkb2VzIG5vdCBtYXRjaCB3YWxsZXQgYmFzZSBhZGRyZXNzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHdhbGxldCBpcyBtaXNzaW5nIGJhc2VBZGRyZXNzIGZvciBjb25zb2xpZGF0aW9uIHZlcmlmaWNhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG5cbiAgICAgICAgLy8gQnVpbGQgYSByZWFsIHRyYW5zYWN0aW9uXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2luZ2xlU2lnU2VuZCk7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwJyxcbiAgICAgICAgICBnYXNMaW1pdDogJzIxMDAwJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QoYmFzZUFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIudmFsdWUoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIC8vIFdhbGxldCB3aXRob3V0IGJhc2VBZGRyZXNzXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgICB0eXBlOiAnY29uc29saWRhdGUnLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICAgIHR4SGV4OiB0eEhleCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdVbmFibGUgdG8gZGV0ZXJtaW5lIGJhc2UgYWRkcmVzcyBmb3IgY29uc29saWRhdGlvbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGRyZXNzIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnaXNXYWxsZXRBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gYWRkcmVzcyBnZW5lcmF0ZWQgdXNpbmcgZm9yd2FyZGVyIHZlcnNpb24gMScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYxZDNjOWZjZThmNWFhNjkxNTY5YTk5ZWInLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dWYjNQZkN6d2lFWDk0QUIxbkpRdHpWbXNhNVNyaU5yZktaWkFjQXZSZ3hoMUF1Z202czh5b0Q4Z1NrcTJGZFo4WUNkVlhVZ0xqZjlReHZkWUFKSzVVdGhBbXBRc2hVJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYwYjc0ZTczYjFmNDQwZWE0YWNlZGE4N2UnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjQ2cFJIZGEzc1pidVB6emE5QTlNaXFBVTlKUm9kOGh1WXR5VjROWTJvZUpYc2lzN3IyNkwxdm1MbnRmOUJjWkplMW00Q1FOU3ZZV2Z3cGUxaFNwbzZKNHg2WUYxZU4nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhva1lMYzVQWFpNMTlWOFVyYnVMZFZSYUNRTXM0RWVDQWpucW1vWVhxZnl1c1RVNDZXb1pNRHlMcG1Uem9VWDY2WkJ3R0ZqdDFhJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHg2MDY5YTRiYWYyMzYwYmY2N2E2ZDAyYTdmYzQzZDhmMzkxMDAxNmFlJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTEyNTNiY2NlN2Q4N2RiNTIyZmJjZWVjNmU1NWM5Zjc4YzM3NmQ5ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3JyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFuIGFkZHJlc3MgZ2VuZXJhdGVkIHVzaW5nIGZvcndhcmRlciB2ZXJzaW9uIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiM2M4YWFhNzkxMTE4ZDljZTYxNmQzYjIxJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHckN4Q1gzOXpiM1R2WWpUcWZVR3dFVVpIam5yYVJGbTFXZU13OWdmQ0Qxd3djMndVRG1CQloyVGtjY0pNd2Y1ZUJUamE4cjN6NkhNeG9UWkdXNm52eW9KTVFGc2VjdicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiMTk2N2ZkNmQ5ODY3YTIyYTFhNDEzMWEwJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dLaGRlQzRucjF0YThkMjd4VGh0ZkZGSGdieFdNclZiNTk1bWVNUzhpM2ZCTXJUejhFZFFNV0JLSEhLenhhcEdnaGVvTXltVnZSY1FtYUdEeWtSVEJidFhxYml1OXBzJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2tZTGM1UFhaTTE5VjhVcmJ1TGRWUmFDUU1zNEVlQ0FqbnFtb1lYcWZ5dXNUVTQ2V29aTUR5THBtVHpvVVg2NlpCd0dGanQxYScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZjYzNmNlZGRmZmU0MWQxMDY1ODY4NzVjMGU1NmRjOGZlYjYyNjhmNycsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgc2FsdDogJzB4MTcnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMjMsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgd2FsbGV0IHZlcnNpb24gNSBmb3J3YXJkZXIgdmVyc2lvbiA0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZTI0MmQ5M2Y4ZDdhZDA3MDU4ODc0NDk3NjNjOTYnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJkZjhiNjMyM2Q0YjA4ZGYzNjY4NjRhZjY2JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJjMDU5NWI0Y2ZlZTZmOTU3YzFkNjQ1OGY3JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkNjNiNWUyYjhkMWI0ZmJhMzYyNTQ2MDUwODkwMGJmMmEwNDk5YTRkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3NScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHdhbGxldCB2ZXJzaW9uIDYgZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4YTMzZjA5NzVmNTNjZGNmY2MwY2I1NjRkMjVmYjViZTAzYjA2NTFjZicsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gYWN0dWFsIGFkZHJlc3MgZGlmZmVycyBmcm9tIGV4cGVjdGVkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHgyODkwNDU5MWY3MzU5OTRmMDUwODA0ZmRhM2I2MWI4MTNiMTZlMDRjJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb2luU3BlY2lmaWMgZmllbGQgaXMgbm90IGFuIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksXG4gICAgICAgICAgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgdGhlIGRlcml2ZWQgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhlMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4YnZmJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgYmFzZSBhZGRyZXNzIGlzIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksIEludmFsaWRBZGRyZXNzRXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlmIGJhc2UgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTBiNTZlZWFlMWIyODM5MThjYWNhMDJhMTRhZGEyZGYxN2E5OGJ2ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ01QQyB3YWxsZXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICAgJzAzZjljMmZiMmU1YThiNzhhNDRmNWQxZTRmOTA2ZjhlM2Q3YTBlNmI1YzRkM2UyZjFhMGI5YzhkN2U2ZjVhNGIzYzJkMWUwZjllOGQ3YzZiNWE0JyArXG4gICAgICAgICAgJzkzODI3MTYwNTk0ODU3NDYzNzI4MTkwYTBiMGMwZDBlMGYxMDExMTIxMzE0MTUxNjE3MTgxOTFhMWIxYzFkMWUxZic7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7IHB1YjogJ3VzZXJfcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgICB7IHB1YjogJ2JhY2t1cF9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYml0Z29fcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBNUEMgd2FsbGV0IGFkZHJlc3Mgd2l0aCBmb3J3YXJkZXIgdmVyc2lvbiAzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDAxMTUzZjNhZGZlNDU0YTcyNTg5Y2E5ZWY3NGYwMTNjMTllNTQ5NjEnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHgwMTE1M2YzYWRmZTQ1NGE3MjU4OWNhOWVmNzRmMDEzYzE5ZTU0OTYxJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IE1QQyB3YWxsZXQgYWRkcmVzcyB3aXRoIHdyb25nIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggaW52YWxpZCBhZGRyZXNzIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHhpbnZhbGlkJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYga2V5Y2hhaW5zIGFyZSBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDllN2NlOGMyNGQ5Zjc2YTgxNGUyMzYzM2U2MWJlN2NiOGU2ZTJkNWUnLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMgYXMgYW55KSwgRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IGludmFsaWRLZXljaGFpbnMgPSBbeyBwdWI6ICd1c2VyX3B1YicgfSwgeyBwdWI6ICdiYWNrdXBfcHViJyB9LCB7IHB1YjogJ2JpdGdvX3B1YicgfV07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg5ZTdjZThjMjRkOWY3NmE4MTRlMjM2MzNlNjFiZTdjYjhlNmUyZDVlJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWluczogaW52YWxpZEtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBFcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdkZXJpdmVBZGRyZXNzIChNUEMpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBTYW1lIHZlY3RvciBhcyB0aGUgTVBDIGlzV2FsbGV0QWRkcmVzcyB0ZXN0cyBhYm92ZTpcbiAgICAgICAgLy8gY29tbW9uS2V5Y2hhaW4gQCBpbmRleCAwIC0+IDB4MDExNTNmM2FkZmU0NTRhNzI1ODljYTllZjc0ZjAxM2MxOWU1NDk2MVxuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICAgJzAzZjljMmZiMmU1YThiNzhhNDRmNWQxZTRmOTA2ZjhlM2Q3YTBlNmI1YzRkM2UyZjFhMGI5YzhkN2U2ZjVhNGIzYzJkMWUwZjllOGQ3YzZiNWE0JyArXG4gICAgICAgICAgJzkzODI3MTYwNTk0ODU3NDYzNzI4MTkwYTBiMGMwZDBlMGYxMDExMTIxMzE0MTUxNjE3MTgxOTFhMWIxYzFkMWUxZic7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7IHB1YjogJ3VzZXJfcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgICB7IHB1YjogJ2JhY2t1cF9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYml0Z29fcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpdCgnc2hvdWxkIGRlcml2ZSB0aGUgZXhwZWN0ZWQgTVBDIGFkZHJlc3MgZm9yIGEgY29tbW9uS2V5Y2hhaW4gYXQgaW5kZXggMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHsga2V5Y2hhaW5zLCBpbmRleDogMCwgd2FsbGV0VmVyc2lvbjogMyB9KTtcbiAgICAgICAgICByZXN1bHQuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4MDExNTNmM2FkZmU0NTRhNzI1ODljYTllZjc0ZjAxM2MxOWU1NDk2MScpO1xuICAgICAgICAgIHJlc3VsdC5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5kZXJpdmF0aW9uUGF0aCwgJ20vMCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgncm91bmQtdHJpcHMgd2l0aCBpc1dhbGxldEFkZHJlc3MgKGRlcml2ZWQgYWRkcmVzcyB2ZXJpZmllcyBhcyB0cnVlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICAgICAgY29uc3QgZGVyaXZlZCA9IGF3YWl0IGNvaW4uZGVyaXZlQWRkcmVzcyh7IGtleWNoYWlucywgaW5kZXg6IDMsIHdhbGxldFZlcnNpb246IDYgfSk7XG4gICAgICAgICAgY29uc3QgdmVyaWZpZWQgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgICAgICBhZGRyZXNzOiBkZXJpdmVkLmFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogNSB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDMsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyk7XG4gICAgICAgICAgdmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gbmVpdGhlciBNUEMgbm9yIGZvcndhcmRlciBpbnB1dHMgYXJlIHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgICAgICAvLyB3YWxsZXRWZXJzaW9uIDEgd2l0aCBubyBjb2luU3BlY2lmaWMuZm9yd2FyZGVyVmVyc2lvbiBhbmQgbm8gYmFzZUFkZHJlc3MgaXMgYW1iaWd1b3VzXG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmRlcml2ZUFkZHJlc3MoeyBrZXljaGFpbnMsIGluZGV4OiAwLCB3YWxsZXRWZXJzaW9uOiAxIH0pLFxuICAgICAgICAgICAgL2NvdWxkIG5vdCBkZXRlcm1pbmUgYW4gRVRIIGRlcml2YXRpb24gc3RyYXRlZ3kvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBrZXljaGFpbnMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5kZXJpdmVBZGRyZXNzKHsga2V5Y2hhaW5zOiBbXSwgaW5kZXg6IDAsIHdhbGxldFZlcnNpb246IDMgfSksXG4gICAgICAgICAgICAva2V5Y2hhaW5zL1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdkZXJpdmVBZGRyZXNzIChmb3J3YXJkZXIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBTYW1lIHZlY3RvcnMgYXMgdGhlIGZvcndhcmRlciBpc1dhbGxldEFkZHJlc3MgdGVzdHMgYWJvdmUgKGNvaW46IGh0ZXRoKS5cbiAgICAgICAgLy8gc2FsdCA9PSBpbmRleCBmb3IgQml0R28gZm9yd2FyZGVycywgc28gZGVyaXZpbmcgYnkgaW5kZXggcmVwcm9kdWNlcyB0aGUgYWRkcmVzcy5cbiAgICAgICAgaXQoJ2Rlcml2ZXMgdGhlIGV4YWN0IHYxIGZvcndhcmRlciBhZGRyZXNzIGFuZCByb3VuZC10cmlwcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGUxMjUzYmNjZTdkODdkYjUyMmZiY2VlYzZlNTVjOWY3OGMzNzZkOWYnO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvaW4uZGVyaXZlQWRkcmVzcyh7XG4gICAgICAgICAgICBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAxIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzdWx0LmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweDYwNjlhNGJhZjIzNjBiZjY3YTZkMDJhN2ZjNDNkOGYzOTEwMDE2YWUnKTtcblxuICAgICAgICAgIGNvbnN0IHZlcmlmaWVkID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3Moe1xuICAgICAgICAgICAgYWRkcmVzczogcmVzdWx0LmFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBzYWx0OiAnMHg3JywgZm9yd2FyZGVyVmVyc2lvbjogMSB9LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyk7XG4gICAgICAgICAgdmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnZGVyaXZlcyB0aGUgZXhhY3QgdjIgZm9yd2FyZGVyIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHtcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkYzQ4NWRhMDc2ZWQ0YTJiMTk1ODRlOWExZmRiYjk3NGY4OWI2MGY0JyxcbiAgICAgICAgICAgIGluZGV4OiAyMyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDIsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogMiB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3VsdC5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMHhmNjM2Y2VkZGZmZTQxZDEwNjU4Njg3NWMwZTU2ZGM4ZmViNjI2OGY3Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdkZXJpdmVzIHRoZSBleGFjdCB2NCBmb3J3YXJkZXIgYWRkcmVzcyAod2FsbGV0IHY1LCBuZWVkcyBmZWVBZGRyZXNzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGYxZTNkMzA3OThhY2RmM2ExMmZhNWJlYjVmYWQ4ZWZiMjNkNWJlMTEnLFxuICAgICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogNCwgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXN1bHQuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4ZDYzYjVlMmI4ZDFiNGZiYTM2MjU0NjA1MDg5MDBiZjJhMDQ5OWE0ZCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyb3dzIGlmIGJhc2VBZGRyZXNzIGlzIG1pc3NpbmcgZm9yIGEgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5kZXJpdmVBZGRyZXNzKHsgaW5kZXg6IDcsIHdhbGxldFZlcnNpb246IDEsIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAxIH0gfSksXG4gICAgICAgICAgICAvYmFzZUFkZHJlc3MgaXMgcmVxdWlyZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Rocm93cyBpZiBmZWVBZGRyZXNzIGlzIG1pc3NpbmcgZm9yIGEgdjQgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICAgICAgY29pbi5kZXJpdmVBZGRyZXNzKHtcbiAgICAgICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiA0IH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgL2ZlZUFkZHJlc3MgaXMgcmVxdWlyZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Rocm93cyBmb3IgZm9yd2FyZGVyIHZlcnNpb24gMCAobm90IGRlcml2YWJsZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgICAgICBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhlMTI1M2JjY2U3ZDg3ZGI1MjJmYmNlZWM2ZTU1YzlmNzhjMzc2ZDlmJyxcbiAgICAgICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAwIH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgL3ZlcnNpb24gMCBhZGRyZXNzZXMgY2Fubm90IGJlIGRlcml2ZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ0Jhc2UgQWRkcmVzcyBWZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gNiAoVFNTKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZTBjNTYwOTgyODhhOWI3ZmExMDdkYjE0NCcsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBkNTY3MzVlNWViNjFiMDZlMzUzZmU3NjM5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JztcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBiYXNlIGFkZHJlc3MgZm9yIHdhbGxldCB2ZXJzaW9uIDUgKFRTUyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZTI0MmQ5M2Y4ZDdhZDA3MDU4ODc0NDk3NjNjOTYnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZTI0MmRmOGI2MzIzZDRiMDhkZjM2Njg2NGFmNjYnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlMjQyYzA1OTViNGNmZWU2Zjk1N2MxZDY0NThmNycsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMSc7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNCxcbiAgICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYmFzZSBhZGRyZXNzIHZlcmlmaWNhdGlvbiB3aXRoIG5vbi16ZXJvIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGQ1NjczNWU1ZWI2MWIwNmUzNTNmZTc2MzknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDUsXG4gICAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiA1LCAvLyBXcm9uZyBpbmRleCAtIHNob3VsZCBiZSAwIGZvciBiYXNlIGFkZHJlc3NcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLFxuICAgICAgICAgICAgL0Jhc2UgYWRkcmVzcyB2ZXJpZmljYXRpb24gcmVxdWlyZXMgaW5kZXggMCwgYnV0IGdvdCBpbmRleCA1L1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGJhc2UgYWRkcmVzcyB2ZXJpZmljYXRpb24gd2l0aCB3cm9uZyBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGQ1NjczNWU1ZWI2MWIwNmUzNTNmZTc2MzknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxJztcbiAgICAgICAgICBjb25zdCBhY3R1YWxCYXNlQWRkcmVzcyA9ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogd3JvbmdBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGFjdHVhbEJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmFzZSBhZGRyZXNzIGZvciB3YWxsZXQgdmVyc2lvbiAyIChCSVAzMikgdXNpbmcgd2FsbGV0IGZhY3RvcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnO1xuICAgICAgICAgIGNvbnN0IHdhbGxldFNhbHQgPSAnMHgyJztcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlOGM3YjNjOGFhYTc5MTExOGQ5Y2U2MTZkM2IyMScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHg5ZDE2YmI4NjdiNzkyYzVlM2JmNjM2YTAyNzVmMmRiODYwMWJkN2Q0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZThjN2IxOTY3ZmQ2ZDk4NjdhMjJhMWE0MTMxYTAnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHgyZGZjZTVjZmViNWMwM2ZiZTY4MGNkMzlhYzBkMmIyNTM5OWI3ZDIyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogd2FsbGV0U2FsdCxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnM6IGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gMSAoQklQMzIpIHVzaW5nIHdhbGxldCBmYWN0b3J5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhlMTI1M2JjY2U3ZDg3ZGI1MjJmYmNlZWM2ZTU1YzlmNzhjMzc2ZDlmJztcbiAgICAgICAgICBjb25zdCB3YWxsZXRTYWx0ID0gJzB4NSc7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYxZDNjOWZjZThmNWFhNjkxNTY5YTk5ZWInLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4ZjQ1ZGFkY2U3NTFhMzE3OTU3ZjJhMjQ3ZmYzN2NiNzY0Yjk3NjIwZCcsXG4gICAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHVmIzUGZDendpRVg5NEFCMW5KUXR6Vm0uLi4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjM4ZjBiNzRlNzNiMWY0NDBlYTRhY2VkYTg3ZScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweDViZGYzYWUxZDJjMmZhZGVlYjcwYTQ1ODcyYmY0ZjQyNTIzMTJiNTUnLFxuICAgICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjQ2cFJIZGEzc1pidVB6emE5QTlNaXFBLi4uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR3pUbjVleU5HRGtiMThSNDNuSDc5SG9rLi4uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6IHdhbGxldFNhbHQsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zOiBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDEsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBDcmVhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHBhc3Mgd2FsbGV0VmVyc2lvbiA2IHRvIGlzV2FsbGV0QWRkcmVzcyBkdXJpbmcgYWRkcmVzcyBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjYgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFY2ID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVY2KTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1NweSA9IHNpbm9uLnNweShldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJyk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRnNYU2hXOFIzaEpzSE5UWVRVd3pjZWpuTGtZN0tDdGFKYkRxY0drY0JGOTlCckVKU2pOWkhlSHZlaVlVcnNBZHdualVNR3dwZ21FYmlLY1pXUnVWQTlIeG5SYUEzcjMnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjYuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldDogZXRoV2FsbGV0VjYuaWQoKSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRWNi5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSk7XG5cbiAgICAgIGlzV2FsbGV0QWRkcmVzc1NweS5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjb25zdCBjYWxsZWRQYXJhbXMgPSBpc1dhbGxldEFkZHJlc3NTcHkuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBjYWxsZWRQYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFZlcnNpb24nLCA2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyB3YWxsZXRWZXJzaW9uIDUgdG8gaXNXYWxsZXRBZGRyZXNzIGR1cmluZyBhZGRyZXNzIGNyZWF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWNSA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjUgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjUpO1xuICAgICAgY29uc3QgaXNXYWxsZXRBZGRyZXNzU3B5ID0gc2lub24uc3B5KGV0aENvaW4sICdpc1dhbGxldEFkZHJlc3MnKTtcblxuICAgICAgLy8gTW9jayBrZXljaGFpbiByZXF1ZXN0c1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGc1hTaFc4UjNoSnNITlRZVFV3emNlam5Ma1k3S0N0YUpiRHFjR2tjQkY5OUJyRUpTak5aSGVIdmVpWVVyc0Fkd25qVU1Hd3BnbUViaUtjWldSdVZBOUh4blJhQTNyMycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGFkZHJlc3MgY3JlYXRpb24gQVBJXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXRWNS5pZCgpfS9hZGRyZXNzYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGQ2M2I1ZTJiOGQxYjRmYmEzNjI1NDYwNTA4OTAwYmYyYTA0OTlhNGQnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAxMTcsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFY1LmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgc2FsdDogJzB4NzUnLFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFY1LmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCB9KTtcblxuICAgICAgLy8gVmVyaWZ5IGlzV2FsbGV0QWRkcmVzcyB3YXMgY2FsbGVkIHdpdGggd2FsbGV0VmVyc2lvbiA1XG4gICAgICBpc1dhbGxldEFkZHJlc3NTcHkuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgY29uc3QgY2FsbGVkUGFyYW1zID0gaXNXYWxsZXRBZGRyZXNzU3B5LmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgY2FsbGVkUGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRWZXJzaW9uJywgNSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgd2FsbGV0VmVyc2lvbiAyIHRvIGlzV2FsbGV0QWRkcmVzcyBkdXJpbmcgYWRkcmVzcyBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjIgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGM0ODVkYTA3NmVkNGEyYjE5NTg0ZTlhMWZkYmI5NzRmODliNjBmNCcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFYyID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVYyKTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1NweSA9IHNpbm9uLnNweShldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJyk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHckN4Q1gzOXpiM1R2WWpUcWZVR3dFVVpIam5yYVJGbTFXZU13OWdmQ0Qxd3djMndVRG1CQloyVGtjY0pNd2Y1ZUJUamE4cjN6NkhNeG9UWkdXNm52eW9KTVFGc2VjdicsXG4gICAgICAgIGV0aEFkZHJlc3M6ICcweDlkMTZiYjg2N2I3OTJjNWUzYmY2MzZhMDI3NWYyZGI4NjAxYmQ3ZDQnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dLaGRlQzRucjF0YThkMjd4VGh0ZkZGSGdieFdNclZiNTk1bWVNUzhpM2ZCTXJUejhFZFFNV0JLSEhLenhhcEdnaGVvTXltVnZSY1FtYUdEeWtSVEJidFhxYml1OXBzJyxcbiAgICAgICAgZXRoQWRkcmVzczogJzB4MmRmY2U1Y2ZlYjVjMDNmYmU2ODBjZDM5YWMwZDJiMjUzOTliN2QyMicsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2tZTGM1UFhaTTE5VjhVcmJ1TGRWUmFDUU1zNEVlQ0FqbnFtb1lYcWZ5dXNUVTQ2V29aTUR5THBtVHpvVVg2NlpCd0dGanQxYScsXG4gICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjIuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhmNjM2Y2VkZGZmZTQxZDEwNjU4Njg3NWMwZTU2ZGM4ZmViNjI2OGY3JyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMjMsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFYyLmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAyLFxuICAgICAgICAgICAgc2FsdDogJzB4MTcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRWMi5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBpc1dhbGxldEFkZHJlc3Mgd2FzIGNhbGxlZCB3aXRoIHdhbGxldFZlcnNpb24gMlxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3B5LmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGNvbnN0IGNhbGxlZFBhcmFtcyA9IGlzV2FsbGV0QWRkcmVzc1NweS5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIGNhbGxlZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0VmVyc2lvbicsIDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHY2IGFkZHJlc3MgY3JlYXRpb24gaWYgd2FsbGV0VmVyc2lvbiB3YXMgbm90IHBhc3NlZCAoc2ltdWxhdGVzIG9sZCBidWcpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWNiA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjYgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjYpO1xuXG4gICAgICAvLyBTdHViIGlzV2FsbGV0QWRkcmVzcyB0byBzaW11bGF0ZSB0aGUgT0xEIGJ1ZyB3aGVyZSB3YWxsZXRWZXJzaW9uIHdhcyBub3QgcGFzc2VkXG4gICAgICBjb25zdCBvcmlnaW5hbElzV2FsbGV0QWRkcmVzcyA9IGV0aENvaW4uaXNXYWxsZXRBZGRyZXNzLmJpbmQoZXRoQ29pbik7XG4gICAgICBjb25zdCBpc1dhbGxldEFkZHJlc3NTdHViID0gc2lub24uc3R1YihldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJykuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIHdhbGxldFZlcnNpb24gdG8gc2ltdWxhdGUgdGhlIG9sZCBidWdcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aG91dFdhbGxldFZlcnNpb24gPSB7IC4uLnBhcmFtcyB9O1xuICAgICAgICBkZWxldGUgKHBhcmFtc1dpdGhvdXRXYWxsZXRWZXJzaW9uIGFzIGFueSkud2FsbGV0VmVyc2lvbjtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsSXNXYWxsZXRBZGRyZXNzKHBhcmFtc1dpdGhvdXRXYWxsZXRWZXJzaW9uKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIHJlcXVlc3RzXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkN2ApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgYWRkcmVzcyBjcmVhdGlvbiBBUElcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldFY2LmlkKCl9L2FkZHJlc3NgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NScsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFY2LmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgLy8gV2l0aG91dCB3YWxsZXRWZXJzaW9uLCBhZGRyZXNzIGNyZWF0aW9uIHNob3VsZCBmYWlsIGJlY2F1c2VcbiAgICAgIC8vIHRoZSBjb2RlIGRvZXNuJ3Qga25vdyB0byB1c2UgVFNTIHZlcmlmaWNhdGlvbiBmb3IgdjYgd2FsbGV0c1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gZXRoV2FsbGV0VjYuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwIH0pLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcblxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFVk0gQ3Jvc3MgQ2hhaW4gUmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJwK2ZrSHVMYS84az1cIixcImN0XCI6XCJoWUc3cHZsakxJZ0NqWlxcbicgK1xuICAgICAgICAnNTNQQmxDZGU1S1pSbWxVS0tITHRETWsrSEpmdVU0NmhXK3grQzlXc0lBTzRnRlBuVEN2RlZtUTh4N2N6Q3RjTkZ1YjVBTzJvdE9HXFxuJyArXG4gICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNUFEZEUxN2ZlRDhiYWVkM0YzMmI4NEFGMDVCOEYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3Qgc3B5ID0gc2lub24uc3B5KFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUsICdjb2luVXNlc05vblBhY2tlZEVuY29kaW5nRm9yVHhEYXRhJyk7XG4gICAgICBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiAnJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIGJpdGdvRmVlQWRkcmVzczogYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgaW50ZW5kZWRDaGFpbjogJ3RhcmJldGgnLFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQoc3B5LnJldHVybmVkKHRydWUpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgRXJyb3JOb0lucHV0VG9SZWNvdmVyIHdoZW4gdGhlIG11bHRpc2lnIHdhbGxldCBoYXMgbm8gZnVuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgIGNvbnN0IG5vbmNlU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdnZXRBZGRyZXNzTm9uY2UnKS5yZXNvbHZlcygwKTtcbiAgICAgIGNvbnN0IGlzU2lnbmVyU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdxdWVyeUlzV2FsbGV0U2lnbmVyJykucmVzb2x2ZXModHJ1ZSk7XG4gICAgICBjb25zdCBiYWxhbmNlU3R1YiA9IHNpbm9uLnN0dWIoYmFzZWNvaW4sICdxdWVyeUFkZHJlc3NCYWxhbmNlJyk7XG4gICAgICBiYWxhbmNlU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKG5ldyBCTignOTk5OTk5OTk5OTk5OTk5OTk5OTknKSk7XG4gICAgICBiYWxhbmNlU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhuZXcgQk4oJzAnKSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgICBpbnRlbmRlZENoYWluOiBwYXJhbXMuaW50ZW5kZWRDaGFpbixcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKEVycm9yTm9JbnB1dFRvUmVjb3Zlcik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBub25jZVN0dWIucmVzdG9yZSgpO1xuICAgICAgICBpc1NpZ25lclN0dWIucmVzdG9yZSgpO1xuICAgICAgICBiYWxhbmNlU3R1Yi5yZXN0b3JlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTm9uLUJpdEdvIFJlY292ZXJ5IGZvciBIb3QgV2FsbGV0cyAoTVBDdjIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICAgIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICAgICAgbGV0IGJhc2Vjb2luOiBIdGV0aDtcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIE1QQ3YyIGtpbmQgb2YgaG90IHdhbGxldHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCkuYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCkuYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKTtcblxuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IHBhcmFtcy5iaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBwYXJhbXMuYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgaW50ZW5kZWRDaGFpbjogcGFyYW1zLmludGVuZGVkQ2hhaW4sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgdXNlciBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEludmFsaWROb25CaXRHb1JlY292ZXJ5UGFyYW1zKCk7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcGFyYW1zLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBwYXJhbXMuYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IHBhcmFtcy5iaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICAgICAgaW50ZW5kZWRDaGFpbjogcGFyYW1zLmludGVuZGVkQ2hhaW4sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICd1c2VyIGtleSBpcyBpbnZhbGlkJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQnVpbGQgVW5zaWduZWQgU3dlZXAgZm9yIFNlbGYtQ3VzdG9keSBDb2xkIFdhbGxldHMgKE1QQ3YyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgICAgIGxldCBiYXNlY29pbjogSHRldGg7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBzd2VlcCB3aXRob3V0IGRlcml2YXRpb24gc2VlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3Qgc3dlZXBSZXN1bHQgPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEEgRGF0YVxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5leGlzdChzd2VlcFJlc3VsdCk7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IHN3ZWVwUmVzdWx0IGFzIFVuc2lnbmVkU3dlZXBUeE1QQ3YyO1xuICAgICAgICBvdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UmVxdWVzdHMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdpbnZhbGlkQWRkcmVzcyc7XG5cbiAgICAgICAgLy8gRW5zdXJlIHVzZXJLZXkgYW5kIGJhY2t1cEtleSBhcmUgdGhlIHNhbWVcbiAgICAgICAgcGFyYW1zLnVzZXJLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcbiAgICAgICAgcGFyYW1zLmJhY2t1cEtleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiAyMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LCAvLyBQcm92aWRlIHRoZSB1c2VyS2V5XG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSwgLy8gUHJvdmlkZSB0aGUgYmFja3VwS2V5XG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcywgLy8gUHJvdmlkZSB0aGUgd2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgJ0Vycm9yOiBpbnZhbGlkIGFkZHJlc3MnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdCdWlsZCBVbnNpZ25lZCBDb25zb2xpZGF0aW9uIGZvciBTZWxmLUN1c3RvZHkgQ29sZCBXYWxsZXRzIChNUEN2MiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgICAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gICAgICBsZXQgYmFzZWNvaW46IEh0ZXRoO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgY29uc29saWRhdGlvbiBmb3Igd2FsbGV0IHY1JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShcbiAgICAgICAgICAgIG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KFxuICAgICAgICAgICAgICBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9uUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6ICcweDMzYTQyZmFlYTNjNmU4NzAyMTM0N2U1MTcwMGI0OGFhZjQ5YWExZTcnLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5leGlzdChjb25zb2xpZGF0aW9uUmVzdWx0KTtcbiAgICAgICAgY29uc3QgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbiA9IGNvbnNvbGlkYXRpb25SZXN1bHQgYXMgVW5zaWduZWRCdWlsQ29uc29saWRhdGlvbjtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcblxuICAgICAgICBjb25zdCBvdXRwdXQgPSB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9uc1swXSBhcyBNUENTd2VlcFR4cztcbiAgICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzZXJpYWxpemVkVHhIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgICAgY29uc3QgcGFyc2VkVHggPSBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IHNwZW5kQW1vdW50OiBzdHJpbmcgfTtcbiAgICAgICAgcGFyc2VkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NwZW5kQW1vdW50Jyk7XG4gICAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICdvdXRwdXRzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgY29uc29saWRhdGlvbiBmb3Igd2FsbGV0IHY2JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShcbiAgICAgICAgICAgIG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KFxuICAgICAgICAgICAgICBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9uUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEEgRGF0YVxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQiBEYXRhXG4gICAgICAgICAgZGVyaXZhdGlvblNlZWQ6IHBhcmFtcy5kZXJpdmF0aW9uU2VlZCwgLy8gS2V5IERlcml2YXRpb24gU2VlZCAob3B0aW9uYWwpXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICBnYXNMaW1pdDogMjAwMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJzEyMycsIC8vIFdyb25nIHdhbGxldCBhZGRyZXNzIHNvIHRoYXQgd2UgY2FuIHNraXAgdjUgYWRkcmVzcyBnZW5lcmF0aW9uXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JyxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3QoY29uc29saWRhdGlvblJlc3VsdCk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24gPSBjb25zb2xpZGF0aW9uUmVzdWx0IGFzIFVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb247XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnNbMF0gYXMgTVBDU3dlZXBUeHM7XG4gICAgICAgIG91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdpbnZhbGlkQWRkcmVzcyc7XG5cbiAgICAgICAgLy8gRW5zdXJlIHVzZXJLZXkgYW5kIGJhY2t1cEtleSBhcmUgdGhlIHNhbWVcbiAgICAgICAgcGFyYW1zLnVzZXJLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcbiAgICAgICAgcGFyYW1zLmJhY2t1cEtleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiAyMDAwLCAvLyBHYXMgTGltaXRcbiAgICAgICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LCAvLyBQcm92aWRlIHRoZSB1c2VyS2V5XG4gICAgICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSwgLy8gUHJvdmlkZSB0aGUgYmFja3VwS2V5XG4gICAgICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcGFyYW1zLndhbGxldENvbnRyYWN0QWRkcmVzcywgLy8gUHJvdmlkZSB0aGUgd2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgJ0Vycm9yOiBpbnZhbGlkIGFkZHJlc3MnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgc2lnbmVyIGNoZWNrcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgIGl0KCdzaG91bGQgdGhyb3cgUmVjb3ZlcnlLZXlNaXNtYXRjaEVycm9yIHdoZW4gdGhlIHVzZXIgcmVjb3Zlcnkga2V5IGlzIG5vdCBhIHdhbGxldCBzaWduZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRWVUYzg3ODlNSzVQVUdFWWlQRzRGNFYxN24yUmQyTG9UQVRBMVhvQ25KVDVGQVlBU2hReFN4dEZqcG81TkhtY1d3VHAyTGlXR0JNd3BVY0FBM0h5d2h4aXZnWWZxN3EnO1xuICAgICAgY29uc3QgYmFja3VwWHB1YiA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRlpYMTV4cFpmNEVSQ0dIaVZTSm04cjVDNHloMXlYVjJHcmRaQ1VQWW80V1FyNnROOW9VeXdLWHNnU0hvN1Jpc2Y5cjIyR0g1am9WRDJoRUVFaHFuU0N2SzhxeTExd1cnO1xuICAgICAgY29uc3QgYmFja3VwS2V5QWRkcmVzcyA9ICcweDRmMmM0ODMwY2MzN2YyNzg1YzY0NmY4OWRlZDhhOTE5MjE5ZmEwZTknO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldElzU2lnbmVyQ2FsbFJlcXVlc3QoJzB4OTE2ZGE4N2MzYWU1MWYwZmEyM2EyYmFiODczMmQyM2MyMWQzMGY1ZScpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRJc1NpZ25lckZhbHNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldElzU2lnbmVyQ2FsbFJlcXVlc3QoYmFja3VwS2V5QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldElzU2lnbmVyVHJ1ZVJlc3BvbnNlKTtcbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgdXNlcktleTogdXNlclhwdWIsXG4gICAgICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmcsXG4gICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnMHhkNUFEZEUxN2ZlRDhiYWVkM0YzMmI4NEFGMDVCOEYyODE2ZjdiNTYwJyxcbiAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIH0pLFxuICAgICAgICAoZXJyKSA9PiBlcnIgaW5zdGFuY2VvZiBSZWNvdmVyeUtleU1pc21hdGNoRXJyb3IgJiYgZXJyLmNvZGUgPT09ICdyZWNvdmVyeV9rZXlfbWlzbWF0Y2gnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHdpdGggYSByYXcgeHBydiB1c2VyS2V5IGZvciBFcmMyMFRva2VuIGFuZCBFcmM3MjFUb2tlbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGFueSByZWdpc3RlcmVkIHRva2VuIHdvcmtzIOKAlCB0aGUgZXhwbG9yZXIgaXMgc3R1YmJlZFxuICAgICAgY29uc3QgZXJjMjBDb2luID0gRXJjMjBUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9ycygpWzBdLmNvaW5Db25zdHJ1Y3RvcihiaXRnbykgYXMgRXJjMjBUb2tlbjtcbiAgICAgIGNvbnN0IGVyYzcyMUNvaW4gPSBFcmM3MjFUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9ycygpWzBdLmNvaW5Db25zdHJ1Y3RvcihiaXRnbykgYXMgRXJjNzIxVG9rZW47XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgcmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICcweGQ1QURkRTE3ZmVEOGJhZWQzRjMyYjg0QUYwNUI4RjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgcGFzc3BocmFzZSA9ICd0ZXN0IHdhbGxldCBwYXNzcGhyYXNlJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZEJhY2t1cEtleSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogdGVzdERhdGEuUFJJVkFURV9LRVksIHBhc3N3b3JkOiBwYXNzcGhyYXNlIH0pO1xuXG4gICAgICBmb3IgKGNvbnN0IHRva2VuQ29pbiBvZiBbZXJjMjBDb2luLCBlcmM3MjFDb2luXSkge1xuICAgICAgICBjb25zdCBzdHViOiBzaW5vbi5TaW5vblN0dWIgPSBzYW5kYm94LnN0dWIodG9rZW5Db2luLCAncmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeScgYXMgYW55KTtcbiAgICAgICAgc3R1Yi5jYWxsc0Zha2UoYXN5bmMgKHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiB7XG4gICAgICAgICAgaWYgKHF1ZXJ5LmFjdGlvbiA9PT0gJ2V0aF9jYWxsJyAmJiBxdWVyeS5kYXRhPy5zdGFydHNXaXRoKCc3ZGY3M2UyNycpKSB7XG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6ICcweCcgKyAnMDAnLnJlcGVhdCgzMSkgKyAnMDEnIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChxdWVyeS5hY3Rpb24gPT09ICd0eGxpc3QnKSB7XG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6IFtdIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChxdWVyeS5hY3Rpb24gPT09ICdiYWxhbmNlJykge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiAnMTAwMDAwMDAwMDAwMDAwMDAwJyB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocXVlcnkuYWN0aW9uID09PSAndG9rZW5iYWxhbmNlJykge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVzdWx0OiAnMTAwMCcgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHF1ZXJ5LmFjdGlvbiA9PT0gJ2V0aF9jYWxsJyAmJiBxdWVyeS5kYXRhPy5zdGFydHNXaXRoKCdhMGI3OTY3YicpKSB7XG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6ICcweCcgKyAnMDAnLnJlcGVhdCgzMSkgKyAnMDEnIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBleHBsb3JlciBxdWVyeTogJHtKU09OLnN0cmluZ2lmeShxdWVyeSl9YCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdG9rZW5Db2luLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHRlc3REYXRhLlBSSVZBVEVfS0VZLFxuICAgICAgICAgIGJhY2t1cEtleTogZW5jcnlwdGVkQmFja3VwS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhc3NwaHJhc2UsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3QodHgpO1xuICAgICAgICB0eC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgICAgdHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgICAgIHN0dWIucmVzdG9yZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBSZWNvdmVyeUtleU1pc21hdGNoRXJyb3Igb24gc2lnbmVyIG1pc21hdGNoIGZvciBFcmMyMFRva2VuIGFuZCBFcmM3MjFUb2tlbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGFueSByZWdpc3RlcmVkIHRva2VuIHdvcmtzIOKAlCB0aGUgZXhwbG9yZXIgaXMgc3R1YmJlZFxuICAgICAgY29uc3QgZXJjMjBDb2luID0gRXJjMjBUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9ycygpWzBdLmNvaW5Db25zdHJ1Y3RvcihiaXRnbykgYXMgRXJjMjBUb2tlbjtcbiAgICAgIGNvbnN0IGVyYzcyMUNvaW4gPSBFcmM3MjFUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9ycygpWzBdLmNvaW5Db25zdHJ1Y3RvcihiaXRnbykgYXMgRXJjNzIxVG9rZW47XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgcmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICcweGQ1QURkRTE3ZmVEOGJhZWQzRjMyYjg0QUYwNUI4RjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgcGFzc3BocmFzZSA9ICd0ZXN0IHdhbGxldCBwYXNzcGhyYXNlJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZEJhY2t1cEtleSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogdGVzdERhdGEuUFJJVkFURV9LRVksIHBhc3N3b3JkOiBwYXNzcGhyYXNlIH0pO1xuXG4gICAgICBmb3IgKGNvbnN0IHRva2VuQ29pbiBvZiBbZXJjMjBDb2luLCBlcmM3MjFDb2luXSkge1xuICAgICAgICBjb25zdCBzdHViOiBzaW5vbi5TaW5vblN0dWIgPSBzYW5kYm94LnN0dWIodG9rZW5Db2luLCAncmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeScgYXMgYW55KTtcbiAgICAgICAgc3R1Yi5jYWxsc0Zha2UoYXN5bmMgKHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiB7XG4gICAgICAgICAgaWYgKHF1ZXJ5LmFjdGlvbiA9PT0gJ2V0aF9jYWxsJyAmJiBxdWVyeS5kYXRhPy5zdGFydHNXaXRoKCc3ZGY3M2UyNycpKSB7XG4gICAgICAgICAgICByZXR1cm4geyByZXN1bHQ6ICcweCcgKyAnMDAnLnJlcGVhdCgzMikgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGV4cGxvcmVyIHF1ZXJ5OiAke0pTT04uc3RyaW5naWZ5KHF1ZXJ5KX1gKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICAgIGF3YWl0IHRva2VuQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgdXNlcktleTogdGVzdERhdGEuUFJJVkFURV9LRVksXG4gICAgICAgICAgICAgIGJhY2t1cEtleTogZW5jcnlwdGVkQmFja3VwS2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXNzcGhyYXNlLFxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAoZXJyKSA9PiBlcnIgaW5zdGFuY2VvZiBSZWNvdmVyeUtleU1pc21hdGNoRXJyb3IgJiYgZXJyLmNvZGUgPT09ICdyZWNvdmVyeV9rZXlfbWlzbWF0Y2gnXG4gICAgICAgICk7XG4gICAgICAgIHN0dWIucmVzdG9yZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG92ZXJyaWRlIHRoZSB0b2tlbiBwYXJhbWV0ZXIgd2l0aCBhIGN1c3RvbSBBUEkga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICBhY3Rpb246ICdiYWxhbmNlJyxcbiAgICAgICAgYWRkcmVzczogJzB4MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgY3VzdG9tQXBpS2V5ID0gJ2N1c3RvbS1hcGkta2V5LWZvci10ZXN0JztcblxuICAgICAgLy8gTW9jayB0aGUgZW52aXJvbm1lbnQgQVBJIHRva2VuXG4gICAgICBjb25zdCBvcmlnaW5hbEFwaVRva2VuID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkFwaVRva2VuO1xuICAgICAgY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkFwaVRva2VuID0gJ2RlZmF1bHQtZW52aXJvbm1lbnQtYXBpLWtleSc7XG5cbiAgICAgIC8vIE1vY2sgdGhlIHJlcXVlc3QuZ2V0IGZ1bmN0aW9uIHRvIGNhcHR1cmUgdGhlIHF1ZXJ5IHBhcmFtZXRlcnNcbiAgICAgIGNvbnN0IG9yaWdpbmFsR2V0ID0gcmVxdWVzdC5nZXQ7XG4gICAgICBsZXQgY2FwdHVyZWRRdWVyeTtcblxuICAgICAgcmVxdWVzdC5nZXQgPSBmdW5jdGlvbiAodXJsOiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBxdWVyeTogZnVuY3Rpb24gKHBhcmFtczogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgICAgICAgICAgY2FwdHVyZWRRdWVyeSA9IHBhcmFtcztcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgICAgICBib2R5OiB7IHJlc3VsdDogJzEwMDAwMDAwMCcgfSxcbiAgICAgICAgICAgIH0gYXMgYW55O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55O1xuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQ2FsbCB3aXRoIGRlZmF1bHQgQVBJIGtleVxuICAgICAgICBhd2FpdCBjb2luLnJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnkocXVlcnkpO1xuICAgICAgICBjYXB0dXJlZFF1ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhcGlrZXknLCAnZGVmYXVsdC1lbnZpcm9ubWVudC1hcGkta2V5Jyk7XG5cbiAgICAgICAgLy8gQ2FsbCB3aXRoIGN1c3RvbSBBUEkga2V5XG4gICAgICAgIGF3YWl0IGNvaW4ucmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSwgY3VzdG9tQXBpS2V5KTtcbiAgICAgICAgY2FwdHVyZWRRdWVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYXBpa2V5JywgY3VzdG9tQXBpS2V5KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgZnVuY3Rpb24gYW5kIEFQSSB0b2tlblxuICAgICAgICByZXF1ZXN0LmdldCA9IG9yaWdpbmFsR2V0O1xuICAgICAgICBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW4gPSBvcmlnaW5hbEFwaVRva2VuO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBSZWNvdmVyeVByb3ZpZGVyRXJyb3Igd2hlbiB0aGUgZXhwbG9yZXIgcmVxdWVzdCBmYWlscycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgIGFkZHJlc3M6ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsR2V0ID0gcmVxdWVzdC5nZXQ7XG4gICAgICByZXF1ZXN0LmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBxdWVyeTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb25uZWN0aW9uIHJlZnVzZWQnKTtcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIGFueTtcbiAgICAgIH07XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjb2luLnJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnkocXVlcnkpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoUmVjb3ZlcnlQcm92aWRlckVycm9yKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHJlcXVlc3QuZ2V0ID0gb3JpZ2luYWxHZXQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IFJlY292ZXJ5UHJvdmlkZXJFcnJvciB3aGVuIHRoZSBleHBsb3JlciByYXRlLWxpbWl0cyB0aGUgcmVxdWVzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgIGFkZHJlc3M6ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsR2V0ID0gcmVxdWVzdC5nZXQ7XG4gICAgICByZXF1ZXN0LmdldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBxdWVyeTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgb2s6IHRydWUsIGJvZHk6IHsgc3RhdHVzOiAnMCcsIG1lc3NhZ2U6ICdOT1RPSycgfSB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55O1xuICAgICAgfTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNvaW4ucmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChSZWNvdmVyeVByb3ZpZGVyRXJyb3IpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgcmVxdWVzdC5nZXQgPSBvcmlnaW5hbEdldDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0F1ZGl0IEtleScsICgpID0+IHtcbiAgICBsZXQgY29pbjogSHRldGg7XG4gICAgYmVmb3JlKCgpID0+IHtcbiAgICAgIGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ011bHRpU2lnJywgKCkgPT4ge1xuICAgICAgY29uc3QgeyBrZXkgfSA9IGV0aE11bHRpU2lnQmFja3VwS2V5O1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB7IGlzVmFsaWQ6IHRydWUgfSBmb3IgdmFsaWQgaW5wdXRzJywgKCkgPT4ge1xuICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdaUThNaHhUODRtNFAnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSB3YWxsZXRQYXNzcGhyYXNlIGlzIGluY29ycmVjdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZm9vJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjogZGVjcnlwdDogY2lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBhbHRlcmVkS2V5ID0ga2V5LnJlcGxhY2UoL1swLTldL2csICcwJyk7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGFsdGVyZWRLZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdrQW1bRUZRNm89U3hsY0xGRHclLCcsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGRlY3J5cHQ6IGNpcGhlcnRleHQgaXMgbm90IHZhbGlkIEpTT04nIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RTUycsICgpID0+IHtcbiAgICAgIGNvbnN0IHsga2V5OiBrZXlTdHJpbmcsIGNvbW1vbktleWNoYWluIH0gPSBldGhUc3NCYWNrdXBLZXk7XG4gICAgICBjb25zdCBrZXkgPSBrZXlTdHJpbmcucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAna0FtW0VGUTZvPVN4bGNMRkR3JSwnO1xuICAgICAgY29uc3QgbXVsdGlTaWdUeXBlID0gJ3Rzcyc7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IHRocm93IGZvciB2YWxpZCBpbnB1dHMnLCAoKSA9PiB7XG4gICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUgY29tbW9uS2V5Y2hhaW4gaXMgYWx0ZXJlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYWx0ZXJlZENvbW1vbktleWNoYWluID0gZ2VuZXJhdGVSYW5kb21QYXNzd29yZCgxMCk7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ0ludmFsaWQgY29tbW9uIGtleWNoYWluJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluY29ycmVjdFBhc3NwaHJhc2UgPSAnZm9vJztcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBpbmNvcnJlY3RQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGluY29ycmVjdCBwYXNzd29yZCcgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBhbHRlcmVkS2V5ID0ga2V5LnJlcGxhY2UoL1swLTldL2csICcwJyk7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGFsdGVyZWRLZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjogZGVjcnlwdDogY2lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicgfVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRTaWduYWJsZVBheWxvYWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGNvaW46IFRldGg7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSAzMi1ieXRlIGtlY2NhazI1NiBoYXNoIGZvciBhIExlZ2FjeSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAwMDAwMDAwMDAnLCBnYXNMaW1pdDogJzcwMDAwMDAnIH0pO1xuICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QoJzB4OENlNTljMmQxNzAyODQ0RjhFZEVENDUxQUExMDM5NjFiQzM3QjRlOCcpO1xuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyXG4gICAgICAgIC5jb2luKCd0ZXRoJylcbiAgICAgICAgLmV4cGlyYXRpb25UaW1lKE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgMzYwMClcbiAgICAgICAgLmFtb3VudCgnMTAwMDAwJylcbiAgICAgICAgLnRvKCcweGVlYWYwRjA1ZjM3ODkxYWI0YTIxMjA4QjEwNUEwNjg3ZDEyYzVhRjcnKVxuICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBjb2luLmdldFNpZ25hYmxlUGF5bG9hZChzZXJpYWxpemVkVHgpO1xuICAgICAgYXNzZXJ0Lm9rKEJ1ZmZlci5pc0J1ZmZlcihwYXlsb2FkKSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGF5bG9hZC5sZW5ndGgsIDMyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgMzItYnl0ZSBrZWNjYWsyNTYgaGFzaCBmb3IgYW4gRUlQMTU1OSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMjgwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICc3MDAwMDAwJyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6ICc3NTkzMTIzJywgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICcxNTAnIH0sXG4gICAgICB9KTtcbiAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KCcweDhDZTU5YzJkMTcwMjg0NEY4RWRFRDQ1MUFBMTAzOTYxYkMzN0I0ZTgnKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgICAuY29pbigndGV0aCcpXG4gICAgICAgIC5leHBpcmF0aW9uVGltZShNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDM2MDApXG4gICAgICAgIC5hbW91bnQoJzEwMDAwMCcpXG4gICAgICAgIC50bygnMHhlZWFmMEYwNWYzNzg5MWFiNGEyMTIwOEIxMDVBMDY4N2QxMmM1YUY3JylcbiAgICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZCgxKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBzZXJpYWxpemVkVHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgY29pbi5nZXRTaWduYWJsZVBheWxvYWQoc2VyaWFsaXplZFR4KTtcbiAgICAgIGFzc2VydC5vayhCdWZmZXIuaXNCdWZmZXIocGF5bG9hZCkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBheWxvYWQubGVuZ3RoLCAzMik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBFUkMtNzk4NCB0b2tlbiBlbmFibGVtZW50IOKAlCBtdWx0aXNpZyB2ZXJpZnlUcmFuc2FjdGlvbiAoYWxsIHNjZW5hcmlvcylcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIGRlc2NyaWJlKCd2ZXJpZnlUcmFuc2FjdGlvbiDigJMgRVJDLTc5ODQgZW5hYmxldG9rZW4gKG11bHRpc2lnIHdhbGxldCknLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaHRldGggWmFtYSBBQ0wgY29udHJhY3QgKE5ldHdvcmtzLnRlc3QuaG9vZGkuemFtYUFjbENvbnRyYWN0QWRkcmVzcylcbiAgICBjb25zdCBaQU1BX0FDTF9BRERSRVNTID0gJzB4NmQzZmFmNmY4NmUxZmY5ZjNiMDgzMWRkYTkyMGFiYTFjYmQ1YmQ2OCc7XG4gICAgLy8gU2ltdWxhdGVkIHdhbGxldCBiYXNlIGFkZHJlc3MgKHdoYXQgdGhlIGNsaWVudCBzZW5kcyBhcyB0aGUgcmVjaXBpZW50IGZvciBiYXNlLWFkZHJlc3Mgd2FsbGV0cylcbiAgICBjb25zdCBXQUxMRVRfQkFTRV9BRERSRVNTID0gJzB4MDhlNjczNmU4NzZkNzcyZDJmYThmODAzYTA3NmNkNmM5Zjg0NTU0Nic7XG4gICAgLy8gU2ltdWxhdGVkIGZvcndhcmRlciBhZGRyZXNzICh3aGF0IHRoZSBjbGllbnQgc2VuZHMgYXMgcmVjaXBpZW50IGZvciBmb3J3YXJkZXIgd2FsbGV0cylcbiAgICBjb25zdCBGT1JXQVJERVJfQUREUkVTUyA9ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnO1xuICAgIGNvbnN0IFdST05HX0FERFJFU1MgPSAnMHhhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhJztcblxuICAgIGNvbnN0IG1ha2VQcmVidWlsZCA9IChyZWNpcGllbnRBZGRyZXNzOiBzdHJpbmcpID0+ICh7XG4gICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLCBhbW91bnQ6ICcwJyB9XSxcbiAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICBnYXNMaW1pdDogMzAwMDAwLFxuICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgIH0pO1xuXG4gICAgLy8g4pSA4pSAIEJhc2UtYWRkcmVzcyB3YWxsZXQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgICBpdCgnYmFzZS1hZGRyZXNzLCBzaW5nbGUgdG9rZW46IHR4UGFyYW1zIOKGkiB3YWxsZXRCYXNlLCB0eFByZWJ1aWxkIOKGkiBBQ0wnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBodGV0aENvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfV0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoWkFNQV9BQ0xfQUREUkVTUykgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnYmFzZS1hZGRyZXNzLCBtdWx0aS10b2tlbjogbXVsdGlwbGUgdHhQYXJhbXMgcmVjaXBpZW50cyAoc2FtZSBiYXNlIGFkZHJlc3MpLCB0eFByZWJ1aWxkIOKGkiBBQ0wgbXVsdGljYWxsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaHRldGhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHsgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfSxcbiAgICAgICAgICAgIHsgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN1c2R0JyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoWkFNQV9BQ0xfQUREUkVTUykgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICAvLyDilIDilIAgRm9yd2FyZGVyIHdhbGxldCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAgIGl0KCdmb3J3YXJkZXIsIHNpbmdsZSB0b2tlbjogdHhQYXJhbXMg4oaSIGZvcndhcmRlciwgdHhQcmVidWlsZCDihpIgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaHRldGhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IEZPUldBUkRFUl9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9XSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChGT1JXQVJERVJfQUREUkVTUykgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZm9yd2FyZGVyLCBtdWx0aS10b2tlbjogbXVsdGlwbGUgdHhQYXJhbXMgcmVjaXBpZW50cyAoc2FtZSBmb3J3YXJkZXIpLCB0eFByZWJ1aWxkIOKGkiBmb3J3YXJkZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBodGV0aENvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgeyBhZGRyZXNzOiBGT1JXQVJERVJfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfSxcbiAgICAgICAgICAgIHsgYWRkcmVzczogRk9SV0FSREVSX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKEZPUldBUkRFUl9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIC8vIOKUgOKUgCBOZWdhdGl2ZSBjYXNlcyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB0eFByZWJ1aWxkIHJlY2lwaWVudCBpcyBuZWl0aGVyIHRoZSBBQ0wgY29udHJhY3Qgbm9yIHRoZSBmb3J3YXJkZXIgZnJvbSB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGF3YWl0IGh0ZXRoQ29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfV0sXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKFdST05HX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC90b2tlbiBlbmFibGVtZW50IHR4UHJlYnVpbGQgcmVjaXBpZW50IG11c3QgYmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB0eFBhcmFtcyByZWNpcGllbnRzIGhhdmUgZGlmZmVyZW50IGFkZHJlc3NlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGF3YWl0IGh0ZXRoQ29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgICB7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH0sXG4gICAgICAgICAgICAgIHsgYWRkcmVzczogRk9SV0FSREVSX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdXNkdCcgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKFpBTUFfQUNMX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9tdXN0IGFsbCBoYXZlIHRoZSBzYW1lIGFkZHJlc3MvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBhIHR4UGFyYW1zIHJlY2lwaWVudCBoYXMgbm9uLXplcm8gYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgYXdhaXQgaHRldGhDb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcxMDAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH1dLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChaQU1BX0FDTF9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbXVzdCBhbGwgaGF2ZSBhbW91bnQgMC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHR4UHJlYnVpbGQgcmVjaXBpZW50IGhhcyBub24temVybyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBhd2FpdCBodGV0aENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH1dLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFpBTUFfQUNMX0FERFJFU1MsIGFtb3VudDogJzUwMCcgfV0sXG4gICAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9leHBlY3RlZCBhbW91bnQgMCBpbiB0eFByZWJ1aWxkLyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=