@bitgo-beta/sdk-api 1.10.1-beta.189 → 1.10.1-beta.1891

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 (79) hide show
  1. package/dist/package.json +20 -27
  2. package/dist/src/api.d.ts +8 -5
  3. package/dist/src/api.d.ts.map +1 -1
  4. package/dist/src/api.js +130 -71
  5. package/dist/src/bitgoAPI.d.ts +97 -24
  6. package/dist/src/bitgoAPI.d.ts.map +1 -1
  7. package/dist/src/bitgoAPI.js +667 -328
  8. package/dist/src/encrypt.d.ts +16 -6
  9. package/dist/src/encrypt.d.ts.map +1 -1
  10. package/dist/src/encrypt.js +92 -14
  11. package/dist/src/encryptV2.d.ts +68 -0
  12. package/dist/src/encryptV2.d.ts.map +1 -0
  13. package/dist/src/encryptV2.js +202 -0
  14. package/dist/src/encryptionSession.d.ts +34 -0
  15. package/dist/src/encryptionSession.d.ts.map +1 -0
  16. package/dist/src/encryptionSession.js +95 -0
  17. package/dist/src/index.d.ts +2 -0
  18. package/dist/src/index.d.ts.map +1 -1
  19. package/dist/src/index.js +8 -2
  20. package/dist/src/types.d.ts +64 -44
  21. package/dist/src/types.d.ts.map +1 -1
  22. package/dist/src/types.js +4 -2
  23. package/dist/src/util.d.ts +12 -0
  24. package/dist/src/util.d.ts.map +1 -1
  25. package/dist/src/util.js +57 -4
  26. package/dist/src/v1/blockchain.js +25 -12
  27. package/dist/src/v1/keychains.js +39 -26
  28. package/dist/src/v1/markets.js +10 -5
  29. package/dist/src/v1/pendingapproval.d.ts.map +1 -1
  30. package/dist/src/v1/pendingapproval.js +57 -18
  31. package/dist/src/v1/pendingapprovals.d.ts.map +1 -1
  32. package/dist/src/v1/pendingapprovals.js +41 -7
  33. package/dist/src/v1/signPsbt.d.ts +14 -0
  34. package/dist/src/v1/signPsbt.d.ts.map +1 -0
  35. package/dist/src/v1/signPsbt.js +69 -0
  36. package/dist/src/v1/transactionBuilder.js +221 -91
  37. package/dist/src/v1/travelRule.js +125 -66
  38. package/dist/src/v1/verifyAddress.d.ts +6 -0
  39. package/dist/src/v1/verifyAddress.d.ts.map +1 -0
  40. package/dist/src/v1/verifyAddress.js +50 -0
  41. package/dist/src/v1/wallet.d.ts.map +1 -1
  42. package/dist/src/v1/wallet.js +501 -230
  43. package/dist/src/v1/wallets.js +118 -53
  44. package/dist/test/unit/api.d.ts +2 -0
  45. package/dist/test/unit/api.d.ts.map +1 -0
  46. package/dist/test/unit/api.js +307 -0
  47. package/dist/test/unit/bitgoAPI.d.ts +2 -0
  48. package/dist/test/unit/bitgoAPI.d.ts.map +1 -0
  49. package/dist/test/unit/bitgoAPI.js +1001 -0
  50. package/dist/test/unit/encrypt.d.ts +2 -0
  51. package/dist/test/unit/encrypt.d.ts.map +1 -0
  52. package/dist/test/unit/encrypt.js +355 -0
  53. package/dist/test/unit/hmacStrategy.d.ts +2 -0
  54. package/dist/test/unit/hmacStrategy.d.ts.map +1 -0
  55. package/dist/test/unit/hmacStrategy.js +136 -0
  56. package/dist/test/unit/utils.d.ts +2 -0
  57. package/dist/test/unit/utils.d.ts.map +1 -0
  58. package/dist/test/unit/utils.js +65 -0
  59. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts +4 -0
  60. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts.map +1 -0
  61. package/dist/test/unit/v1/fixtures/accelerate-tx.js +53 -0
  62. package/dist/test/unit/v1/fixtures/index.d.ts +3 -0
  63. package/dist/test/unit/v1/fixtures/index.d.ts.map +1 -0
  64. package/dist/test/unit/v1/fixtures/index.js +24 -0
  65. package/dist/test/unit/v1/signPsbt.d.ts +2 -0
  66. package/dist/test/unit/v1/signPsbt.d.ts.map +1 -0
  67. package/dist/test/unit/v1/signPsbt.js +53 -0
  68. package/dist/test/unit/v1/travelRule.d.ts +2 -0
  69. package/dist/test/unit/v1/travelRule.d.ts.map +1 -0
  70. package/dist/test/unit/v1/travelRule.js +125 -0
  71. package/dist/test/unit/v1/wallet.d.ts +2 -0
  72. package/dist/test/unit/v1/wallet.d.ts.map +1 -0
  73. package/dist/test/unit/v1/wallet.js +1658 -0
  74. package/dist/tsconfig.tsbuildinfo +1 -0
  75. package/package.json +20 -27
  76. package/.eslintignore +0 -5
  77. package/CHANGELOG.md +0 -571
  78. package/dist/web/main.js +0 -2
  79. package/dist/web/main.js.LICENSE.txt +0 -110
@@ -0,0 +1,1658 @@
1
+ "use strict";
2
+ //
3
+ // Tests for Wallet
4
+ //
5
+ // Copyright 2014, BitGo, Inc. All Rights Reserved.
6
+ //
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ var __importDefault = (this && this.__importDefault) || function (mod) {
41
+ return (mod && mod.__esModule) ? mod : { "default": mod };
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ const fixtures_1 = require("./fixtures");
45
+ const Wallet = require('../../../src/v1/wallet');
46
+ const bitgoAPI_1 = require("../../../src/bitgoAPI");
47
+ const _ = __importStar(require("lodash"));
48
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
49
+ const utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
50
+ const should = __importStar(require("should"));
51
+ const nock_1 = __importDefault(require("nock"));
52
+ const sinon = __importStar(require("sinon"));
53
+ const accelerate_tx_1 = require("./fixtures/accelerate-tx");
54
+ nock_1.default.disableNetConnect();
55
+ const TestBitGo = {
56
+ TEST_WALLET1_PASSCODE: 'iVWeATjqLS1jJShrPpETti0b',
57
+ };
58
+ describe('Wallet Prototype Methods', function () {
59
+ const fixtures = (0, accelerate_tx_1.getFixtures)();
60
+ let bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
61
+ // bitgo.initializeTestVars();
62
+ const userKeypair = {
63
+ xprv: 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k',
64
+ xpub: 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp',
65
+ rawPub: '02c103ac74481874b5ef0f385d12725e4f14aedc9e00bc814ce96f47f62ce7adf2',
66
+ rawPrv: '936c5af3f8af81f75cdad1b08f29e7d9c01e598e2db2d7be18b9e5a8646e87c6',
67
+ path: 'm',
68
+ walletSubPath: '/0/0',
69
+ };
70
+ const backupKeypair = {
71
+ xprv: 'xprv9s21ZrQH143K47sEkLkykgYmq1xF5ZWrPYhUZcmBpPFMQojvGUmEcr5jFXYGfr8CpFdpTvhQ7L9NN2rLtsBFjSix3BAjwJcBj6U3D5hxTPc',
72
+ xpub: 'xpub661MyMwAqRbcGbwhrNHz7pVWP3njV2Ehkmd5N1AoNinLHc54p25VAeQD6q2oTS3uuDMDnfnXnthbS9ufC8JVYpNnWU5Rn3pYaNuLCNywkw1',
73
+ rawPub: '03bbcb73997977068d9e36666bbd5cd37579acae8e2bd5ce9d0a6e5c150a423bc3',
74
+ rawPrv: '77a15f14796f4001d1092ae84f766bd869e9bee6bffae6547def5045b96fa943',
75
+ path: 'm',
76
+ walletSubPath: '/0/0',
77
+ };
78
+ const bitgoKey = {
79
+ xpub: 'xpub661MyMwAqRbcGQcVFiwcrtc7c3vopsX96jsJUYPcFMREcRTqAqsqbv2ZRyCJAPLm5NMHCy85E3ZwpT4EAUw9WGU7vMhG6z83hDeKXBWn6Lf',
80
+ path: 'm',
81
+ walletSubPath: '/0/0',
82
+ };
83
+ const fakeWallet = new Wallet(bitgo, {
84
+ id: '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4',
85
+ private: { keychains: [userKeypair, backupKeypair, bitgoKey] },
86
+ });
87
+ describe('Generate Address', function () {
88
+ before(() => nock_1.default.pendingMocks().should.be.empty());
89
+ it('generate first address', function () {
90
+ const idAddress = fakeWallet.generateAddress({ path: '/0/0', segwit: false });
91
+ idAddress.address.should.equal(fakeWallet.id());
92
+ idAddress.chain.should.equal(0);
93
+ idAddress.index.should.equal(0);
94
+ idAddress.chainPath.should.equal('/0/0');
95
+ idAddress.path.should.equal('/0/0');
96
+ idAddress.outputScript.should.equal('a914d682476e9bd54454a885f9dff1e604e99cef43dc87');
97
+ idAddress.redeemScript.should.equal('522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae');
98
+ idAddress.wallet.should.equal(fakeWallet.id());
99
+ });
100
+ it('generate second address', function () {
101
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/1', segwit: false });
102
+ p2shAddress.address.should.equal('2N5y5RLVqdZi7qp5PmzMdPR6YvQzUqBQFWK');
103
+ p2shAddress.chain.should.equal(0);
104
+ p2shAddress.index.should.equal(1);
105
+ p2shAddress.chainPath.should.equal('/0/1');
106
+ p2shAddress.path.should.equal('/0/1');
107
+ p2shAddress.outputScript.should.equal('a9148b8bd3da68ef0f2465523146bd2de33c86b9c87187');
108
+ p2shAddress.redeemScript.should.equal('522102709edb6a2198d364c485a76b981d12065eabde8aa2d85bd7e7a035f7ecb3579b2102a724efed499c05fdb4da1e139700951fae00c006b3283888bdfd1b46979292242102b32abe44d61986ff57b835e3bd16293d93f303d0d8fb0454e2c9cceda5c4929853ae');
109
+ p2shAddress.wallet.should.equal(fakeWallet.id());
110
+ });
111
+ it('generate change address', function () {
112
+ const p2shAddress = fakeWallet.generateAddress({ path: '/1/0', segwit: false });
113
+ p2shAddress.address.should.equal('2NFj9JrpZc5MyYnCouyREtzNY4eoyKWDfgP');
114
+ p2shAddress.chain.should.equal(1);
115
+ p2shAddress.index.should.equal(0);
116
+ p2shAddress.chainPath.should.equal('/1/0');
117
+ p2shAddress.path.should.equal('/1/0');
118
+ p2shAddress.outputScript.should.equal('a914f69a81fad75ea65ad166da76515291679a4f1ad887');
119
+ p2shAddress.redeemScript.should.equal('5221020b4c4f891a5520f5a0b6818d8d53919552a0d4d806b5fa05c97708079d83737e2102c5cc49bf0331eb0b0890a7e7d87f7e9e0dea515438280dc76834c21d198efe08210370e52cf741ebf4513749d028839d696891eb789ba7a58592cfbc857cdc0a9de753ae');
120
+ p2shAddress.wallet.should.equal(fakeWallet.id());
121
+ });
122
+ it('generate segwit address', function () {
123
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/0', segwit: true });
124
+ segwitAddress.address.should.equal('2N5EVegRPWnmed2PpqDggZPw7DcNDguRYv8');
125
+ segwitAddress.chain.should.equal(10);
126
+ segwitAddress.index.should.equal(0);
127
+ segwitAddress.chainPath.should.equal('/10/0');
128
+ segwitAddress.path.should.equal('/10/0');
129
+ segwitAddress.outputScript.should.equal('a914837e2adcb6f6386fea3c5d40316b282ccf39121d87');
130
+ segwitAddress.redeemScript.should.equal('0020a62afee1d211c5adb9739f81ed4e36330e6cda651c7bdd314e32ccc465ec2203');
131
+ segwitAddress.witnessScript.should.equal('5221027b30505777a4ed8947b069fcb0116e287995d97278d84da4db6c613270649d3d21034c30e51f1e614cad667815c91d041404c18225d0b2f79e2c0bcb63fd2604316b2103b65ddfc06159b691693390761e75a0b8cc7a65b6ff305d094f3ad972f17953fe53ae');
132
+ segwitAddress.wallet.should.equal(fakeWallet.id());
133
+ });
134
+ });
135
+ describe('Create Transaction', function () {
136
+ let bgUrl, bgUrlTest;
137
+ let fakeProdWallet;
138
+ before(function () {
139
+ nock_1.default.pendingMocks().should.be.empty();
140
+ const prodBitgo = new bitgoAPI_1.BitGoAPI({ env: 'prod', clientConstants: { constants: {} } });
141
+ // prodBitgo.initializeTestVars();
142
+ bgUrl = sdk_core_1.common.Environments[prodBitgo.getEnv()].uri;
143
+ fakeProdWallet = new Wallet(prodBitgo, {
144
+ id: '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4',
145
+ private: { keychains: [userKeypair, backupKeypair, bitgoKey] },
146
+ });
147
+ bgUrlTest = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
148
+ });
149
+ it('extra unspent fetch params', async function () {
150
+ const billingAddress = '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy';
151
+ const customUnspentsFetchParams = { test: 123 };
152
+ const sendAmount = 1e5;
153
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: billingAddress });
154
+ const scope = (0, nock_1.default)(bgUrl)
155
+ .get(`/api/v1/wallet/${fakeProdWallet.id()}/unspents`)
156
+ .query(_.merge(customUnspentsFetchParams, {
157
+ segwit: true,
158
+ target: sendAmount,
159
+ minSize: 0,
160
+ }))
161
+ .reply(200, { unspents: [] });
162
+ await fakeProdWallet
163
+ .createTransaction({
164
+ unspentsFetchParams: customUnspentsFetchParams,
165
+ recipients: { [billingAddress]: sendAmount },
166
+ feeRate: 10000,
167
+ bitgoFee: {
168
+ amount: 0,
169
+ address: '',
170
+ },
171
+ })
172
+ .should.be.rejectedWith('0 unspents available for transaction creation');
173
+ scope.isDone().should.be.true();
174
+ });
175
+ it('default p2sh', async function () {
176
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
177
+ const unspent = {
178
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
179
+ value: '0.00504422',
180
+ value_int: 504422,
181
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
182
+ n: 1,
183
+ script_pub_key: {
184
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
185
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
186
+ },
187
+ req_sigs: 1,
188
+ type: 'scripthash',
189
+ confirmations: 9,
190
+ id: 61330229,
191
+ };
192
+ _.extend(unspent, p2shAddress);
193
+ unspent.value = unspent.value_int;
194
+ unspent.tx_hash = unspent.txid;
195
+ unspent.tx_output_n = unspent.n;
196
+ unspent.script = unspent.outputScript;
197
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
198
+ const transaction = (await fakeProdWallet.createTransaction({
199
+ changeAddress: p2shAddress.address,
200
+ unspents: [unspent],
201
+ recipients: {},
202
+ noSplitChange: true,
203
+ forceChangeAtEnd: true,
204
+ feeRate: 10000,
205
+ bitgoFee: {
206
+ amount: 0,
207
+ address: '',
208
+ },
209
+ opReturns: { 'BitGo p2sh test': 1000 },
210
+ usePsbt: false,
211
+ }));
212
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
213
+ // add first signature
214
+ transaction.keychain = userKeypair;
215
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
216
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b600473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
217
+ // add second signature
218
+ transaction.transactionHex = signature1.tx;
219
+ transaction.keychain = backupKeypair;
220
+ transaction.fullLocalSigning = true;
221
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
222
+ // This transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
223
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
224
+ // changed, changing the output amounts and thus the tx hex.
225
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfd0000473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80147304402202ae01f01b5ae0c3fa7d67ac73db81932cb5aca10db16a99063fef45e3f1398cd022055001ba7e163cb350910fc7321ecd7eb6359b321d4c04887484d9c7284b78c4701004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
226
+ });
227
+ it('p2sh PSBT produces same unsigned tx as legacy', async function () {
228
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
229
+ const unspent = {
230
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
231
+ value: '0.00504422',
232
+ value_int: 504422,
233
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
234
+ n: 1,
235
+ script_pub_key: {
236
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
237
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
238
+ },
239
+ req_sigs: 1,
240
+ type: 'scripthash',
241
+ confirmations: 9,
242
+ id: 61330229,
243
+ };
244
+ _.extend(unspent, p2shAddress);
245
+ unspent.value = unspent.value_int;
246
+ unspent.tx_hash = unspent.txid;
247
+ unspent.tx_output_n = unspent.n;
248
+ unspent.script = unspent.outputScript;
249
+ const txParams = {
250
+ changeAddress: p2shAddress.address,
251
+ unspents: [unspent],
252
+ recipients: {},
253
+ noSplitChange: true,
254
+ forceChangeAtEnd: true,
255
+ feeRate: 10000,
256
+ bitgoFee: {
257
+ amount: 0,
258
+ address: '',
259
+ },
260
+ opReturns: { 'BitGo p2sh test': 1000 },
261
+ };
262
+ // Create legacy transaction
263
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
264
+ const legacyTx = (await fakeProdWallet.createTransaction({ ...txParams, usePsbt: false }));
265
+ // Create PSBT transaction (explicitly)
266
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
267
+ const psbtTx = (await fakeProdWallet.createTransaction({ ...txParams, usePsbt: true }));
268
+ // Extract unsigned tx from PSBT and compare
269
+ const psbt = utxolib.bitgo.createPsbtFromHex(psbtTx.transactionHex, utxolib.networks.bitcoin);
270
+ const unsignedTxFromPsbt = psbt.getUnsignedTx().toHex();
271
+ // The unsigned transaction hex should be identical
272
+ legacyTx.transactionHex.should.equal(unsignedTxFromPsbt);
273
+ // Fees should also match
274
+ legacyTx.fee.should.equal(psbtTx.fee);
275
+ // Clean up nock mocks to avoid interference with other tests
276
+ nock_1.default.cleanAll();
277
+ });
278
+ it('segwit PSBT produces same unsigned tx as legacy', async function () {
279
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
280
+ const unspent = {
281
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
282
+ value: '0.18750000',
283
+ value_int: 18750000,
284
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
285
+ n: 0,
286
+ script_pub_key: {
287
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
288
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
289
+ },
290
+ req_sigs: 1,
291
+ type: 'scripthash',
292
+ confirmations: 0,
293
+ id: 61331617,
294
+ };
295
+ _.extend(unspent, segwitAddress);
296
+ unspent.value = unspent.value_int;
297
+ unspent.tx_hash = unspent.txid;
298
+ unspent.tx_output_n = unspent.n;
299
+ unspent.script = unspent.outputScript;
300
+ const txParams = {
301
+ changeAddress: segwitAddress.address,
302
+ unspents: [unspent],
303
+ recipients: {},
304
+ noSplitChange: true,
305
+ forceChangeAtEnd: true,
306
+ feeRate: 10000,
307
+ bitgoFee: {
308
+ amount: 0,
309
+ address: '',
310
+ },
311
+ opReturns: { 'BitGo segwit test': 1000 },
312
+ };
313
+ // Create legacy transaction
314
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
315
+ const legacyTx = (await fakeProdWallet.createTransaction({ ...txParams, usePsbt: false }));
316
+ // Create PSBT transaction (explicitly)
317
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
318
+ const psbtTx = (await fakeProdWallet.createTransaction({ ...txParams, usePsbt: true }));
319
+ // Extract unsigned tx from PSBT and compare
320
+ const psbt = utxolib.bitgo.createPsbtFromHex(psbtTx.transactionHex, utxolib.networks.bitcoin);
321
+ const unsignedTxFromPsbt = psbt.getUnsignedTx().toHex();
322
+ // The unsigned transaction hex should be identical
323
+ legacyTx.transactionHex.should.equal(unsignedTxFromPsbt);
324
+ // Fees should also match
325
+ legacyTx.fee.should.equal(psbtTx.fee);
326
+ // Clean up nock mocks to avoid interference with other tests
327
+ nock_1.default.cleanAll();
328
+ });
329
+ it('p2sh with PSBT format', async function () {
330
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
331
+ const unspent = {
332
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
333
+ value: '0.00504422',
334
+ value_int: 504422,
335
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
336
+ n: 1,
337
+ script_pub_key: {
338
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
339
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
340
+ },
341
+ req_sigs: 1,
342
+ type: 'scripthash',
343
+ confirmations: 9,
344
+ id: 61330229,
345
+ };
346
+ _.extend(unspent, p2shAddress);
347
+ unspent.value = unspent.value_int;
348
+ unspent.tx_hash = unspent.txid;
349
+ unspent.tx_output_n = unspent.n;
350
+ unspent.script = unspent.outputScript;
351
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
352
+ const transaction = (await fakeProdWallet.createTransaction({
353
+ changeAddress: p2shAddress.address,
354
+ unspents: [unspent],
355
+ recipients: {},
356
+ noSplitChange: true,
357
+ forceChangeAtEnd: true,
358
+ feeRate: 10000,
359
+ bitgoFee: {
360
+ amount: 0,
361
+ address: '',
362
+ },
363
+ opReturns: { 'BitGo p2sh test': 1000 },
364
+ usePsbt: true, // Explicitly request PSBT format
365
+ }));
366
+ // Verify PSBT format is returned in transactionHex
367
+ should.exist(transaction.transactionHex);
368
+ should.ok(utxolib.bitgo.isPsbt(transaction.transactionHex));
369
+ should.not.exist(transaction.unspents);
370
+ // Parse and validate the PSBT
371
+ const psbt = utxolib.bitgo.createPsbtFromHex(transaction.transactionHex, utxolib.networks.bitcoin);
372
+ psbt.data.inputs.length.should.equal(1);
373
+ psbt.data.outputs.length.should.equal(2); // OP_RETURN + change
374
+ // Verify input has required PSBT metadata
375
+ const input = psbt.data.inputs[0];
376
+ should.exist(input.witnessUtxo);
377
+ should.exist(input.redeemScript);
378
+ should.exist(input.bip32Derivation);
379
+ input.bip32Derivation.length.should.equal(3); // user, backup, bitgo
380
+ // Verify globalXpubs are set
381
+ should.exist(psbt.data.globalMap.globalXpub);
382
+ psbt.data.globalMap.globalXpub.length.should.equal(3);
383
+ // Sign with user key - auto-detects PSBT in transactionHex
384
+ const signedResult = (await fakeProdWallet.signTransaction({
385
+ transactionHex: transaction.transactionHex,
386
+ keychain: userKeypair,
387
+ }));
388
+ should.exist(signedResult.tx);
389
+ // Parse signed PSBT and verify signature
390
+ const signedPsbt = utxolib.bitgo.createPsbtFromHex(signedResult.tx, utxolib.networks.bitcoin);
391
+ should.ok(signedPsbt.validateSignaturesOfInputHD(0, utxolib.bip32.fromBase58(userKeypair.xpub)));
392
+ });
393
+ it('segwit with PSBT format', async function () {
394
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
395
+ const unspent = {
396
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
397
+ value: '0.18750000',
398
+ value_int: 18750000,
399
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
400
+ n: 0,
401
+ script_pub_key: {
402
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
403
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
404
+ },
405
+ req_sigs: 1,
406
+ type: 'scripthash',
407
+ confirmations: 0,
408
+ id: 61331617,
409
+ };
410
+ _.extend(unspent, segwitAddress);
411
+ unspent.value = unspent.value_int;
412
+ unspent.tx_hash = unspent.txid;
413
+ unspent.tx_output_n = unspent.n;
414
+ unspent.script = unspent.outputScript;
415
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
416
+ const transaction = (await fakeProdWallet.createTransaction({
417
+ changeAddress: segwitAddress.address,
418
+ unspents: [unspent],
419
+ recipients: {},
420
+ noSplitChange: true,
421
+ forceChangeAtEnd: true,
422
+ feeRate: 10000,
423
+ bitgoFee: {
424
+ amount: 0,
425
+ address: '',
426
+ },
427
+ opReturns: { 'BitGo segwit test': 1000 },
428
+ usePsbt: true, // Explicitly request PSBT format
429
+ }));
430
+ // Verify PSBT format is returned in transactionHex
431
+ should.exist(transaction.transactionHex);
432
+ should.ok(utxolib.bitgo.isPsbt(transaction.transactionHex));
433
+ // Parse and validate the PSBT
434
+ const psbt = utxolib.bitgo.createPsbtFromHex(transaction.transactionHex, utxolib.networks.bitcoin);
435
+ psbt.data.inputs.length.should.equal(1);
436
+ // Verify input has segwit PSBT metadata
437
+ const input = psbt.data.inputs[0];
438
+ should.exist(input.witnessUtxo);
439
+ should.exist(input.witnessScript);
440
+ should.exist(input.redeemScript);
441
+ should.exist(input.bip32Derivation);
442
+ // Sign with user key - auto-detects PSBT in transactionHex
443
+ const signedResult = (await fakeProdWallet.signTransaction({
444
+ transactionHex: transaction.transactionHex,
445
+ keychain: userKeypair,
446
+ }));
447
+ should.exist(signedResult.tx);
448
+ // Parse signed PSBT and verify signature
449
+ const signedPsbt = utxolib.bitgo.createPsbtFromHex(signedResult.tx, utxolib.networks.bitcoin);
450
+ should.ok(signedPsbt.validateSignaturesOfInputHD(0, utxolib.bip32.fromBase58(userKeypair.xpub)));
451
+ });
452
+ it('BCH p2sh', async function () {
453
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
454
+ const unspent = {
455
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
456
+ value: '0.00504422',
457
+ value_int: 504422,
458
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
459
+ n: 1,
460
+ script_pub_key: {
461
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
462
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
463
+ },
464
+ req_sigs: 1,
465
+ type: 'scripthash',
466
+ confirmations: 9,
467
+ id: 61330229,
468
+ };
469
+ _.extend(unspent, p2shAddress);
470
+ unspent.value = unspent.value_int;
471
+ unspent.tx_hash = unspent.txid;
472
+ unspent.tx_output_n = unspent.n;
473
+ unspent.script = unspent.outputScript;
474
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
475
+ const transaction = (await fakeProdWallet.createTransaction({
476
+ changeAddress: p2shAddress.address,
477
+ unspents: [unspent],
478
+ recipients: {},
479
+ noSplitChange: true,
480
+ forceChangeAtEnd: true,
481
+ feeRate: 10000,
482
+ bitgoFee: {
483
+ amount: 0,
484
+ address: '',
485
+ },
486
+ opReturns: { 'BitGo p2sh test': 1000 },
487
+ usePsbt: false,
488
+ }));
489
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
490
+ // add first signature
491
+ transaction.keychain = userKeypair;
492
+ transaction.forceBCH = true;
493
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
494
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b60047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
495
+ // add second signature
496
+ transaction.transactionHex = signature1.tx;
497
+ transaction.keychain = backupKeypair;
498
+ transaction.fullLocalSigning = true;
499
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
500
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
501
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
502
+ // changed, changing the output amounts and thus the tx hex.
503
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfe000047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884148304502210082bc546293858459f3895db24c85ccf37505c56f8faf4bb8f78cf40135bc2f2b02203dc1c78d7c7ceaf6b924eca3c39b95e8a227b069a07047581273136b47ca7ac441004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
504
+ });
505
+ it('default segwit', async function () {
506
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
507
+ const unspent = {
508
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
509
+ value: '0.18750000',
510
+ value_int: 18750000,
511
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
512
+ n: 0,
513
+ script_pub_key: {
514
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
515
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
516
+ },
517
+ req_sigs: 1,
518
+ type: 'scripthash',
519
+ confirmations: 0,
520
+ id: 61331617,
521
+ };
522
+ _.extend(unspent, segwitAddress);
523
+ unspent.value = unspent.value_int;
524
+ unspent.tx_hash = unspent.txid;
525
+ unspent.tx_output_n = unspent.n;
526
+ unspent.script = unspent.outputScript;
527
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
528
+ const transaction = (await fakeProdWallet.createTransaction({
529
+ changeAddress: segwitAddress.address,
530
+ unspents: [unspent],
531
+ recipients: {},
532
+ noSplitChange: true,
533
+ forceChangeAtEnd: true,
534
+ feeRate: 10000,
535
+ bitgoFee: {
536
+ amount: 0,
537
+ address: '',
538
+ },
539
+ opReturns: { 'BitGo segwit test': 1000 },
540
+ usePsbt: false,
541
+ }));
542
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
543
+ // add first signature
544
+ transaction.keychain = userKeypair;
545
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
546
+ signature1.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f3010000695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
547
+ // add second signature
548
+ transaction.transactionHex = signature1.tx;
549
+ transaction.keychain = backupKeypair;
550
+ transaction.fullLocalSigning = true;
551
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
552
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/d67266f1de905baaee750011fa4b3d88a8e3a1758d5173a659c67709488dde07
553
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
554
+ // changed, changing the output amounts and thus the tx hex.
555
+ signature2.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f30147304402205cf8d2f2be6ce083d35654bdc3fa85d7e71b227d457e9245bb603b21e7b5165102203ea686226db8320e08c26bfb304048b3a9473d0e05797d3658dacb2f09a2b51c0100695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
556
+ });
557
+ it('creates an unsigned tx made of uncompressed public keys of v1 safe wallet', async function () {
558
+ const { address, redeemScript, scriptPubKey } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
559
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
560
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
561
+ id: address,
562
+ private: { safe: { redeemScript } },
563
+ });
564
+ const unspentsToSpend = [
565
+ {
566
+ value: 100000,
567
+ redeemScript,
568
+ script: scriptPubKey,
569
+ tx_hash: 'a55d11dc8b701bd19601fbfe711a1e465fc8f128ec4474e78e1fd087e808e5fe',
570
+ tx_output_n: 0,
571
+ confirmations: 1,
572
+ },
573
+ {
574
+ value: 100000,
575
+ redeemScript,
576
+ script: scriptPubKey,
577
+ tx_hash: '48fb879cec879356045a331937023aed859f5dc5db955a1dc8a5ccf29f49d108',
578
+ tx_output_n: 0,
579
+ confirmations: 1,
580
+ },
581
+ ];
582
+ const recipients = {
583
+ '2MyGxrhLC4kRfuVjLqCVYFtC7DchhgMCiNz': 191340, // purposely set to simulate a sweep transaction
584
+ };
585
+ const scope = (0, nock_1.default)(bgUrlTest)
586
+ .post('/api/v1/billing/address')
587
+ .reply(200, { address: '2N3L9cu9WN2Df7Xvb1Y8owokuDVj5Hdyv4i' });
588
+ const result = await fakeTestV1SafeWallet.createTransaction({
589
+ recipients,
590
+ unspents: unspentsToSpend,
591
+ feeRate: 10000, // 10 sat/byte
592
+ bitgoFee: {
593
+ amount: 0,
594
+ address: '',
595
+ },
596
+ usePsbt: false,
597
+ });
598
+ scope.isDone().should.be.true();
599
+ result.estimatedSize.should.equal(866);
600
+ result.fee.should.equal(8660);
601
+ // This should equal to 1 because this is a sweep transaction but due to hardcoded addition of
602
+ // 1 change output in transactionBuilder, it is 2.
603
+ // Because of this the estimated size of the transactions is more than what it actually is in the hex.
604
+ result.txInfo.nOutputs.should.equal(2);
605
+ });
606
+ it('signs an unsigned tx made of uncompressed public keys of v1 safe wallet & verifies signatures', async function () {
607
+ const { address, redeemScript, scriptPubKey, userKeyWIF: userSigningKey, bitgoKeyWIF: bitgoSigningKey, unsignedTxHex, halfSignedTxHex, fullSignedTxHex, } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
608
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
609
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
610
+ id: address,
611
+ private: { safe: { redeemScript } },
612
+ });
613
+ const unspentsToSpend = [
614
+ { value: 100000, redeemScript, script: scriptPubKey },
615
+ { value: 100000, redeemScript, script: scriptPubKey },
616
+ ];
617
+ const halfSignedTx = await fakeTestV1SafeWallet.signTransaction({
618
+ transactionHex: unsignedTxHex,
619
+ signingKey: userSigningKey,
620
+ unspents: unspentsToSpend,
621
+ validate: true,
622
+ });
623
+ halfSignedTx.tx.should.equal(halfSignedTxHex);
624
+ const fullSignedTx = await fakeTestV1SafeWallet.signTransaction({
625
+ transactionHex: halfSignedTxHex,
626
+ signingKey: bitgoSigningKey,
627
+ unspents: unspentsToSpend,
628
+ validate: true,
629
+ fullLocalSigning: true,
630
+ });
631
+ // Upon calling txb.build() instead after getting 2 valid signatures, we get a valid full signed tx that was broadcast
632
+ // and confirmed on testnet here: https://mempool.space/testnet/tx/bde09f1bd5e6661c28d90e4c96291853e21ba15ab42f3e4a30719decb73e791b
633
+ // It's present in the fullSignedTxHexBuildComplete property of the fixture.
634
+ fullSignedTx.tx.should.equal(fullSignedTxHex);
635
+ });
636
+ it('BCH segwit should fail', async function () {
637
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
638
+ const unspent = {
639
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
640
+ value: '0.18750000',
641
+ value_int: 18750000,
642
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
643
+ n: 0,
644
+ script_pub_key: {
645
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
646
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
647
+ },
648
+ req_sigs: 1,
649
+ type: 'scripthash',
650
+ confirmations: 0,
651
+ id: 61331617,
652
+ };
653
+ _.extend(unspent, segwitAddress);
654
+ unspent.value = unspent.value_int;
655
+ unspent.tx_hash = unspent.txid;
656
+ unspent.tx_output_n = unspent.n;
657
+ unspent.script = unspent.outputScript;
658
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
659
+ const transaction = (await fakeProdWallet.createTransaction({
660
+ changeAddress: segwitAddress.address,
661
+ unspents: [unspent],
662
+ recipients: {},
663
+ noSplitChange: true,
664
+ forceChangeAtEnd: true,
665
+ feeRate: 10000,
666
+ bitgoFee: {
667
+ amount: 0,
668
+ address: '',
669
+ },
670
+ opReturns: { 'BitGo segwit test': 1000 },
671
+ usePsbt: false,
672
+ }));
673
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
674
+ // add first signature
675
+ transaction.keychain = userKeypair;
676
+ transaction.forceBCH = true;
677
+ (() => fakeProdWallet.signTransaction(transaction)).should.throw('BCH does not support segwit inputs');
678
+ });
679
+ it('mixed p2sh & segwit', async function () {
680
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
681
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
682
+ const p2shUnspent = {
683
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
684
+ value: '2.99996610',
685
+ value_int: 299996610,
686
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
687
+ n: 1,
688
+ script_pub_key: {
689
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
690
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
691
+ },
692
+ req_sigs: 1,
693
+ type: 'scripthash',
694
+ confirmations: 0,
695
+ id: 61331263,
696
+ };
697
+ const segwitUnspent = {
698
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
699
+ value: '1.50000000',
700
+ value_int: 150000000,
701
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
702
+ n: 0,
703
+ script_pub_key: {
704
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
705
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
706
+ },
707
+ req_sigs: 1,
708
+ type: 'scripthash',
709
+ confirmations: 0,
710
+ id: 61330882,
711
+ };
712
+ const addresses = [p2shAddress, segwitAddress];
713
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
714
+ const address = addresses[index];
715
+ _.extend(unspent, address);
716
+ unspent.value = unspent.value_int;
717
+ unspent.tx_hash = unspent.txid;
718
+ unspent.tx_output_n = unspent.n;
719
+ unspent.script = unspent.outputScript;
720
+ return unspent;
721
+ });
722
+ const transaction = (await fakeWallet.createTransaction({
723
+ changeAddress: p2shAddress.address,
724
+ unspents: unspents,
725
+ recipients: {},
726
+ noSplitChange: true,
727
+ forceChangeAtEnd: true,
728
+ feeRate: 10000,
729
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
730
+ bitgoFee: {
731
+ amount: 81760,
732
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
733
+ },
734
+ usePsbt: false,
735
+ }));
736
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
737
+ // add first signature
738
+ transaction.keychain = userKeypair;
739
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
740
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b700483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d90100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd6010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
741
+ // add second signature
742
+ transaction.transactionHex = signature1.tx;
743
+ transaction.keychain = backupKeypair;
744
+ transaction.fullLocalSigning = true;
745
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
746
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
747
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
748
+ // changed, changing the output amounts and thus the tx hex.
749
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdff0000483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d9014830450221008254d100401a3a831ed019e1662dbd90b96c6c4072b81ce640d152bc29295c10022013f86c5af5716234999a7bd6e94fc8f428f7697cc3138b3649d0ec4dd8681bc701004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd60147304402207713d671b45989688e2665c2b11ab7e5ea8d57eb14f9da233c095dabe441308d022069521b5aeb071b07a70a7197a0c2bbc40a23ae63a04160cf3627250c4ba4c40f0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
750
+ });
751
+ it('should send to bech32 recipient', async function () {
752
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
753
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
754
+ const p2shUnspent = {
755
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
756
+ value: '2.99996610',
757
+ value_int: 299996610,
758
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
759
+ n: 1,
760
+ script_pub_key: {
761
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
762
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
763
+ },
764
+ req_sigs: 1,
765
+ type: 'scripthash',
766
+ confirmations: 0,
767
+ id: 61331263,
768
+ };
769
+ const segwitUnspent = {
770
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
771
+ value: '1.50000000',
772
+ value_int: 150000000,
773
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
774
+ n: 0,
775
+ script_pub_key: {
776
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
777
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
778
+ },
779
+ req_sigs: 1,
780
+ type: 'scripthash',
781
+ confirmations: 0,
782
+ id: 61330882,
783
+ };
784
+ const addresses = [p2shAddress, segwitAddress];
785
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
786
+ const address = addresses[index];
787
+ _.extend(unspent, address);
788
+ unspent.value = unspent.value_int;
789
+ unspent.tx_hash = unspent.txid;
790
+ unspent.tx_output_n = unspent.n;
791
+ unspent.script = unspent.outputScript;
792
+ return unspent;
793
+ });
794
+ const transaction = (await fakeWallet.createTransaction({
795
+ changeAddress: p2shAddress.address,
796
+ unspents: unspents,
797
+ recipients: { tb1qguzyk4w6kaqtpsczs5aj0w8r7598jq36egm8e98wqph3rwmex68seslgsg: 300000 },
798
+ noSplitChange: true,
799
+ forceChangeAtEnd: true,
800
+ feeRate: 10000,
801
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
802
+ bitgoFee: {
803
+ amount: 81760,
804
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
805
+ },
806
+ usePsbt: false,
807
+ }));
808
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
809
+ // add first signature
810
+ transaction.keychain = userKeypair;
811
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
812
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b7004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a2832010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
813
+ // add second signature
814
+ transaction.transactionHex = signature1.tx;
815
+ transaction.keychain = backupKeypair;
816
+ transaction.fullLocalSigning = true;
817
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
818
+ console.log('signature1 ' + JSON.stringify(signature2));
819
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
820
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
821
+ // changed, changing the output amounts and thus the tx hex.
822
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdfe00004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40147304402205a58e602042b8e8a5da509d19ce31050147dd0ffcfbe2bb337c23d4c88f4cc41022075bfa455d1f74e30fbd9c786cd4811a1defe54310f235b4193ce4ffa0e8309a101004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a283201473044022053690234582a6911a28cae9f534c980b7d7918749a7413c1c59327debf16ff0b022056175f5c27a363416b2ce4791aefc3d55545cacbd0527202e869e1127fc2f24d0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
823
+ });
824
+ });
825
+ describe('Send Many', function () {
826
+ it('responds with proper fee and fee rate', async function () {
827
+ const params = {
828
+ recipients: [
829
+ {
830
+ address: '2MutpXVYs8Lyk74pVDn3eAG7xnK4Wc2kjTQ',
831
+ amount: 300000,
832
+ },
833
+ ],
834
+ };
835
+ const unspents = [
836
+ {
837
+ value: 8170,
838
+ },
839
+ {
840
+ value: 800000,
841
+ },
842
+ ];
843
+ const createAndSignResponse = {
844
+ bitgoFee: 0,
845
+ travelInfos: [],
846
+ unspents,
847
+ tx: 'halfsignedhex',
848
+ };
849
+ sinon.stub(fakeWallet, 'createAndSignTransaction').returns(Promise.resolve(createAndSignResponse));
850
+ const getSendTxResponse = () => ({
851
+ status: 'accepted',
852
+ tx: '0100000000010228b5c3e2789d4770fc397ec79fa7255f86235297c5a04def678b481b8b09e81b0100000023220020b3bbe067960be39501f365b8999d53f2a8285d8d9836f61fad020e6a4a9e26fdffffffff1510e90411a86c49f2a52546a32a03febde2bc604741f0e85dc47adec33f515900000000fdfd0000483045022100a44bbf97b155c57703862be69d2b20c4b2ab9e94f402595880bf74402ccc87e202200a4aaf98f939b65c98ca08eb96074c222ecb1fc37e359b1d67a05f1c56dedfc001473044022003f3989a14284f132bbb550118c20256d4ea737704123a29955acc1d03ea6eb7022017223da7edcf73076d89875aa33360aa6a12141807f683c6c1b9a5a0d3ff6019014c695221025789857cc8be110ff4cbf354b52dd0e7e9326c6bfe0aee6c30c1ee69660c3dc02102f58f1b1516d05814ae688ca701856695e27050e3e16d3a2351284d7af84498882102385c7bcec3f38c13e87b558aebf2f20a8928e7ecbe11e7c3a47792bc8e33fe8853aeffffffff02e09304000000000017a9141d0c791cec3af1f37808d42f04593095d6fdea268705bc07000000000017a914d8c720f646c7c56c5467248e47c72dc0b2d30bbc87040047304402201eaa1359fffd3bdec5b48268bd2f15193a299c22b1970356f390883473324651022074186232f02245af9c0977031448c2c99e7b7e2b05b2ba4b32c3227d8ca1494e01483045022100bd61b37051c28533ea0b00dda75b1c4f1dee1b683bb7351b2d8dd720f6dfbe1102203acc4cf9d2dd44b294aa25812e99e7d8eb3730e4ff6f889d3cdcd525195750b8016952210219d093c18c27cb547737b4a49dddac9c3412b10e9f880eb30053c3eba81928542103747118892cac1b4da11526fc4ebeebe168dae0907cefb1a1812541cd46b07602210339f73b6750f8f91efd484b5aa2974321a6cc2776d5bd78b9cfb5fe18e3b2d66253ae005a9e1600',
853
+ hash: 'f8df43c2c650b3bb11277aee4531db99a715fa3b9dfd3d45a8d171342c1bf780',
854
+ instant: false,
855
+ });
856
+ const expectedResult = Object.assign({
857
+ fee: 1285,
858
+ feeRate: 2519.607843137255,
859
+ }, getSendTxResponse());
860
+ sinon.stub(fakeWallet, 'sendTransaction').resolves(getSendTxResponse());
861
+ const result = (await fakeWallet.sendMany(params));
862
+ result.tx.should.equal(expectedResult.tx);
863
+ result.fee.should.equal(expectedResult.fee);
864
+ result.feeRate.should.equal(expectedResult.feeRate);
865
+ });
866
+ });
867
+ describe('Accelerate Transaction (server mocked)', function accelerateTxMockedDescribe() {
868
+ let wallet;
869
+ let bgUrl;
870
+ let explorerUrl;
871
+ let minChangeSize;
872
+ let parentTxId = '6a74b74df4991d93c32d751336c85b5f2d1ee544a2dfbae2e5f4beb4f914e5e0';
873
+ const outputIdx = 0;
874
+ const outputAddress = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
875
+ const unrelatedTxId = '08f5e0b4acb5ab8245229dfe161ce4ca0da1ec983e7a34b09e72f56979a467df';
876
+ const walletId = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
877
+ /**
878
+ * Helper function to get the parent transaction ID from a transaction input
879
+ *
880
+ * This function converts `hash` (which is a Buffer object) to a usable txid string.
881
+ * The issue is that the bytes are stored in reverse order in the buffer, so
882
+ * the simple approach of just comparing the hex strings doesn't work.
883
+ * Instead, the Buffer is copied to a new Buffer object, the new Buffer
884
+ * object is reversed in-place, and then the new Buffer is converted to a
885
+ * hex string. After this, the result is a hex string which is the parent txid
886
+ *
887
+ * @param hash a bitcoinjs-lib transaction object's input hash
888
+ */
889
+ function inputParentTxId({ hash }) {
890
+ return Buffer.from(hash).reverse().toString('hex');
891
+ }
892
+ before(function accelerateTxMockedBefore() {
893
+ nock_1.default.pendingMocks().should.be.empty();
894
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'mock', clientConstants: { constants: {} } });
895
+ // bitgo.initializeTestVars();
896
+ bitgo.setValidate(false);
897
+ wallet = new Wallet(bitgo, { id: walletId, private: { keychains: [userKeypair, backupKeypair, bitgoKey] } });
898
+ wallet.bitgo = bitgo;
899
+ bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
900
+ explorerUrl = sdk_core_1.common.Environments[bitgo.getEnv()].btcExplorerBaseUrl;
901
+ // try to get the min change size from the server, otherwise default to 0.1 BTC
902
+ // TODO: minChangeSize is not currently a constant defined on the client and should be added
903
+ minChangeSize = 1e7;
904
+ });
905
+ after(function accelerateTxMockedAfter() {
906
+ // make sure all nocks are cleared or consumed after the tests are complete
907
+ nock_1.default.pendingMocks().should.be.empty();
908
+ });
909
+ it('arguments', async () => {
910
+ await wallet.accelerateTransaction({ feeRate: 123 }).should.be.rejectedWith(/^Missing parameter: transactionID$/);
911
+ await wallet
912
+ .accelerateTransaction({ transactionID: 123, feeRate: 123 })
913
+ .should.be.rejectedWith(/^Expecting parameter string: transactionID but found number$/);
914
+ await wallet
915
+ .accelerateTransaction({ transactionID: '123' })
916
+ .should.be.rejectedWith(/^Missing parameter: feeRate$/);
917
+ const feeRatesParams = ['123', 0, -10, -Infinity, Infinity, NaN];
918
+ for (const feeRate of feeRatesParams) {
919
+ await wallet
920
+ .accelerateTransaction({ transactionID: '123', feeRate })
921
+ .should.be.rejectedWith(/^Expecting positive finite number for parameter: feeRate$/);
922
+ }
923
+ });
924
+ describe('bad input', function badInputDescribe() {
925
+ after(() => {
926
+ // make sure all nocks are cleared or consumed after the tests are complete
927
+ nock_1.default.pendingMocks().should.be.empty();
928
+ });
929
+ it('non existent transaction ID', async () => {
930
+ (0, nock_1.default)(bgUrl)
931
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
932
+ .reply(404, 'transaction not found on this wallet');
933
+ await wallet
934
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 123 })
935
+ .should.be.rejectedWith(/^404\ntransaction not found on this wallet$/);
936
+ });
937
+ it('confirmed transaction', async () => {
938
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`).reply(200, {
939
+ confirmations: 6,
940
+ });
941
+ await wallet
942
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
943
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ is already confirmed and cannot be accelerated$/);
944
+ });
945
+ it('no outputs to wallet', async () => {
946
+ (0, nock_1.default)(bgUrl)
947
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
948
+ .reply(200, {
949
+ outputs: [
950
+ {
951
+ account: outputAddress,
952
+ value: 1890000,
953
+ vout: 0,
954
+ chain: 0,
955
+ },
956
+ ],
957
+ confirmations: 0,
958
+ });
959
+ await wallet
960
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
961
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ contains no outputs to this wallet, and thus cannot be accelerated$/);
962
+ });
963
+ /*
964
+ * This test covers the case where a failure occurs during the process of
965
+ * converting an output from the parent transaction into an unspent which
966
+ * can be used to chain the child tx to the parent.
967
+ *
968
+ * This should never happen, but it is possible (for example, in the case
969
+ * of an attempted double spend of the output from the parent, or a race
970
+ * between finding the parent output, and retrieving the corresponding unspent).
971
+ */
972
+ it('cannot find correct unspent to use', async () => {
973
+ (0, nock_1.default)(bgUrl)
974
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
975
+ .reply(200, {
976
+ outputs: [
977
+ {
978
+ account: outputAddress,
979
+ value: 50 * 1e4,
980
+ vout: outputIdx,
981
+ isMine: true,
982
+ chain: 0,
983
+ },
984
+ ],
985
+ confirmations: 0,
986
+ hex: parentTxId,
987
+ fee: 10,
988
+ });
989
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
990
+ count: 0,
991
+ unspents: [],
992
+ });
993
+ await wallet
994
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
995
+ .should.be.rejectedWith(/^Could not find unspent output from parent tx to use as child input$/);
996
+ });
997
+ it('Detects when an incorrect tx hex is returned by the external service', async () => {
998
+ (0, nock_1.default)(bgUrl)
999
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1000
+ .reply(200, {
1001
+ outputs: [
1002
+ {
1003
+ account: outputAddress,
1004
+ value: 10,
1005
+ vout: outputIdx,
1006
+ isMine: true,
1007
+ chain: 0,
1008
+ },
1009
+ ],
1010
+ confirmations: 0,
1011
+ hex: fixtures[parentTxId],
1012
+ fee: 10,
1013
+ });
1014
+ (0, nock_1.default)(bgUrl)
1015
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1016
+ .query(true)
1017
+ .reply(200, {
1018
+ count: 1,
1019
+ unspents: [
1020
+ {
1021
+ tx_hash: parentTxId,
1022
+ tx_output_n: outputIdx,
1023
+ },
1024
+ ],
1025
+ });
1026
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[unrelatedTxId]);
1027
+ await wallet
1028
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
1029
+ .should.be.rejectedWith(/^Decoded transaction id is [0-9a-f]+, which does not match given txid [0-9a-f]+$/);
1030
+ });
1031
+ it('cannot cover child fee with one parent output and one wallet unspent', async () => {
1032
+ (0, nock_1.default)(bgUrl)
1033
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1034
+ .reply(200, {
1035
+ outputs: [
1036
+ {
1037
+ account: outputAddress,
1038
+ value: 10,
1039
+ vout: outputIdx,
1040
+ isMine: true,
1041
+ chain: 0,
1042
+ },
1043
+ ],
1044
+ confirmations: 0,
1045
+ hex: fixtures[parentTxId],
1046
+ fee: 10,
1047
+ });
1048
+ (0, nock_1.default)(bgUrl)
1049
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1050
+ .query(true)
1051
+ .reply(200, {
1052
+ count: 1,
1053
+ unspents: [
1054
+ {
1055
+ tx_hash: parentTxId,
1056
+ tx_output_n: outputIdx,
1057
+ },
1058
+ ],
1059
+ });
1060
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1061
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
1062
+ count: 0,
1063
+ unspents: [],
1064
+ });
1065
+ await wallet
1066
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
1067
+ .should.be.rejectedWith(/^Insufficient confirmed unspents available to cover the child fee$/);
1068
+ });
1069
+ it('cannot lower fee rate', async () => {
1070
+ (0, nock_1.default)(bgUrl)
1071
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1072
+ .reply(200, {
1073
+ outputs: [
1074
+ {
1075
+ account: outputAddress,
1076
+ value: 10,
1077
+ vout: outputIdx,
1078
+ isMine: true,
1079
+ chain: 11,
1080
+ },
1081
+ ],
1082
+ confirmations: 0,
1083
+ hex: fixtures[parentTxId],
1084
+ fee: 10000, // large fee, and thus fee rate, for parent
1085
+ });
1086
+ (0, nock_1.default)(bgUrl)
1087
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1088
+ .query(true)
1089
+ .reply(200, {
1090
+ count: 1,
1091
+ unspents: [
1092
+ {
1093
+ tx_hash: parentTxId,
1094
+ tx_output_n: outputIdx,
1095
+ },
1096
+ ],
1097
+ });
1098
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1099
+ await wallet
1100
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
1101
+ .should.be.rejectedWith(/^Cannot lower fee rate! \(Parent tx fee rate is \d+\.?\d* sat\/kB, and requested fee rate was \d+\.?\d* sat\/kB\)$/);
1102
+ });
1103
+ it('cannot break maximum fee limit for combined transaction', async () => {
1104
+ (0, nock_1.default)(bgUrl)
1105
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1106
+ .reply(200, {
1107
+ outputs: [
1108
+ {
1109
+ account: outputAddress,
1110
+ value: 3e7,
1111
+ vout: outputIdx,
1112
+ isMine: true,
1113
+ chain: 11,
1114
+ },
1115
+ ],
1116
+ confirmations: 0,
1117
+ hex: fixtures[parentTxId],
1118
+ fee: 1000,
1119
+ });
1120
+ (0, nock_1.default)(bgUrl)
1121
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1122
+ .query(true)
1123
+ .reply(200, {
1124
+ count: 1,
1125
+ unspents: [
1126
+ {
1127
+ tx_hash: parentTxId,
1128
+ tx_output_n: outputIdx,
1129
+ },
1130
+ ],
1131
+ });
1132
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1133
+ await wallet
1134
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2e6 })
1135
+ .should.be.rejectedWith(/^Transaction cannot be accelerated\. Combined fee rate of \d+\.?\d* sat\/kB exceeds maximum fee rate of \d+\.?\d* sat\/kB$/);
1136
+ });
1137
+ });
1138
+ describe('successful tx acceleration', function successfulTxDescribe() {
1139
+ const feeRate = 20000;
1140
+ beforeEach(async () => {
1141
+ (0, nock_1.default)(bgUrl).post(`/api/v1/wallet/${wallet.id()}/address/1`).reply(200, {
1142
+ address: '2NCYjG8Q56yr8tx9jazNoYnGKxjgB2MQSfY',
1143
+ });
1144
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, {
1145
+ address: '2NFbvo2HK4eXZm1aqDcSDGGqD64FPt7T6d8',
1146
+ });
1147
+ (0, nock_1.default)(bgUrl).get('/api/v1/tx/fee').query(true).reply(200, {
1148
+ feePerKb: 0,
1149
+ });
1150
+ (0, nock_1.default)(bgUrl)
1151
+ .post(`/api/v1/keychain/${userKeypair.xpub}`, {})
1152
+ .reply(200, {
1153
+ encryptedXprv: await bitgo.encrypt({ input: userKeypair.xprv, password: TestBitGo.TEST_WALLET1_PASSCODE }),
1154
+ path: userKeypair.path + userKeypair.walletSubPath,
1155
+ });
1156
+ });
1157
+ it('accelerates a stuck tx without additional unspents', async () => {
1158
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
1159
+ (0, nock_1.default)(bgUrl)
1160
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1161
+ .reply(200, {
1162
+ fee: 434,
1163
+ outputs: [
1164
+ {
1165
+ vout: 0,
1166
+ value: 10348500,
1167
+ isMine: true,
1168
+ chain: 1,
1169
+ },
1170
+ {
1171
+ vout: 1,
1172
+ value: 10000,
1173
+ isMine: true,
1174
+ chain: 11,
1175
+ },
1176
+ ],
1177
+ });
1178
+ (0, nock_1.default)(bgUrl)
1179
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1180
+ .query(true)
1181
+ .reply(200, {
1182
+ unspents: [
1183
+ {
1184
+ tx_hash: parentTxId,
1185
+ tx_output_n: 0,
1186
+ value: 10348500,
1187
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
1188
+ chainPath: '/11/160',
1189
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
1190
+ },
1191
+ ],
1192
+ });
1193
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1194
+ (0, nock_1.default)(bgUrl)
1195
+ .post('/api/v1/tx/send', (body) => {
1196
+ return !body.ignoreMaxFeeRate;
1197
+ })
1198
+ .reply(200, function (_, body) {
1199
+ return {
1200
+ transaction: body.tx,
1201
+ };
1202
+ });
1203
+ const childTx = await wallet.accelerateTransaction({
1204
+ transactionID: parentTxId,
1205
+ feeRate,
1206
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1207
+ });
1208
+ should.exist(childTx);
1209
+ childTx.should.have.property('status', 'accepted');
1210
+ childTx.should.have.property('tx');
1211
+ // assert the following:
1212
+ // 0) The child tx has exactly one input
1213
+ // 1) The parent tx output is an input
1214
+ // 2) The child tx has exactly one output
1215
+ // 3) The child tx output meets the minimum change threshold
1216
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1217
+ decodedChild.ins.length.should.equal(1);
1218
+ decodedChild.outs.length.should.equal(1);
1219
+ const childInput = decodedChild.ins[0];
1220
+ childInput.should.have.property('index', 0);
1221
+ childInput.should.have.property('hash');
1222
+ const inputTxId = inputParentTxId(childInput);
1223
+ inputTxId.should.equal(parentTxId);
1224
+ const childOutput = decodedChild.outs[0];
1225
+ childOutput.should.have.property('value');
1226
+ childOutput.value.should.be.above(minChangeSize);
1227
+ });
1228
+ it('accelerates a stuck tx with one additional segwit unspent', async () => {
1229
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1230
+ const additionalUnspentTxId = '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87';
1231
+ (0, nock_1.default)(bgUrl)
1232
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1233
+ .reply(200, {
1234
+ fee: 1336,
1235
+ outputs: [
1236
+ {
1237
+ vout: 0,
1238
+ value: 10000,
1239
+ isMine: true,
1240
+ chain: 11,
1241
+ },
1242
+ {
1243
+ vout: 1,
1244
+ value: 8664,
1245
+ isMine: true,
1246
+ chain: 1,
1247
+ },
1248
+ ],
1249
+ confirmations: 0,
1250
+ });
1251
+ (0, nock_1.default)(bgUrl)
1252
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1253
+ .query(true)
1254
+ .reply(200, {
1255
+ unspents: [
1256
+ {
1257
+ tx_hash: parentTxId,
1258
+ tx_output_n: 0,
1259
+ value: 10000,
1260
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1261
+ chainPath: '/0/0',
1262
+ },
1263
+ ],
1264
+ });
1265
+ (0, nock_1.default)(bgUrl)
1266
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1267
+ .query(true)
1268
+ .reply(200, {
1269
+ unspents: [
1270
+ {
1271
+ tx_hash: additionalUnspentTxId,
1272
+ tx_output_n: 0,
1273
+ value: 19935526,
1274
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1275
+ chainPath: '/11/155',
1276
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1277
+ },
1278
+ ],
1279
+ });
1280
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1281
+ (0, nock_1.default)(bgUrl)
1282
+ .post('/api/v1/tx/send', (body) => {
1283
+ return !body.ignoreMaxFeeRate;
1284
+ })
1285
+ .reply(200, function (_, body) {
1286
+ return {
1287
+ transaction: body.tx,
1288
+ };
1289
+ });
1290
+ const childTx = await wallet.accelerateTransaction({
1291
+ transactionID: parentTxId,
1292
+ feeRate,
1293
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1294
+ });
1295
+ should.exist(childTx);
1296
+ childTx.should.have.property('status', 'accepted');
1297
+ childTx.should.have.property('tx');
1298
+ // assert the following:
1299
+ // 0) The child tx has exactly two inputs
1300
+ // 1) The parent tx output is an input
1301
+ // 2) The additional unspent output is an input
1302
+ // 3) The child tx has exactly one output
1303
+ // 4) The child tx output meets the minimum change threshold
1304
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1305
+ decodedChild.ins.length.should.equal(2);
1306
+ decodedChild.outs.length.should.equal(1);
1307
+ let inputFromParent = undefined;
1308
+ let additionalInput = undefined;
1309
+ _.forEach(decodedChild.ins, (input) => {
1310
+ input.should.have.property('hash');
1311
+ input.should.have.property('index');
1312
+ const inputTxId = inputParentTxId(input);
1313
+ if (inputTxId === parentTxId) {
1314
+ inputFromParent = input;
1315
+ }
1316
+ else {
1317
+ additionalInput = input;
1318
+ }
1319
+ });
1320
+ should.exist(inputFromParent);
1321
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1322
+ inputFromParentHash.should.equal(parentTxId);
1323
+ inputFromParent.index.should.equal(0);
1324
+ should.exist(additionalInput);
1325
+ const additionalInputHash = inputParentTxId(additionalInput);
1326
+ additionalInputHash.should.equal(additionalUnspentTxId);
1327
+ additionalInput.index.should.equal(0);
1328
+ const childOutput = decodedChild.outs[0];
1329
+ childOutput.should.have.property('value');
1330
+ childOutput.value.should.be.above(minChangeSize);
1331
+ });
1332
+ it('accelerates a stuck tx with one additional P2SH unspent', async () => {
1333
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1334
+ const additionalUnspentTxId = 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58';
1335
+ (0, nock_1.default)(bgUrl)
1336
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1337
+ .reply(200, {
1338
+ fee: 1336,
1339
+ outputs: [
1340
+ {
1341
+ vout: 0,
1342
+ value: 10000,
1343
+ isMine: true,
1344
+ chain: 11,
1345
+ },
1346
+ {
1347
+ vout: 1,
1348
+ value: 8664,
1349
+ isMine: true,
1350
+ chain: 1,
1351
+ },
1352
+ ],
1353
+ confirmations: 0,
1354
+ });
1355
+ (0, nock_1.default)(bgUrl)
1356
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1357
+ .query(true)
1358
+ .reply(200, {
1359
+ unspents: [
1360
+ {
1361
+ tx_hash: parentTxId,
1362
+ tx_output_n: 0,
1363
+ value: 10000,
1364
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1365
+ chainPath: '/0/0',
1366
+ },
1367
+ ],
1368
+ });
1369
+ (0, nock_1.default)(bgUrl)
1370
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1371
+ .query(true)
1372
+ .reply(200, {
1373
+ unspents: [
1374
+ {
1375
+ tx_hash: additionalUnspentTxId,
1376
+ tx_output_n: 1,
1377
+ value: 20000000,
1378
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1379
+ chainPath: '/0/0',
1380
+ },
1381
+ ],
1382
+ });
1383
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1384
+ (0, nock_1.default)(bgUrl)
1385
+ .post('/api/v1/tx/send', (body) => {
1386
+ return !body.ignoreMaxFeeRate;
1387
+ })
1388
+ .reply(200, function (_, body) {
1389
+ return {
1390
+ transaction: body.tx,
1391
+ };
1392
+ });
1393
+ const childTx = await wallet.accelerateTransaction({
1394
+ transactionID: parentTxId,
1395
+ feeRate,
1396
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1397
+ });
1398
+ should.exist(childTx);
1399
+ childTx.should.have.property('status', 'accepted');
1400
+ childTx.should.have.property('tx');
1401
+ // assert the following:
1402
+ // 0) The child tx has exactly two inputs
1403
+ // 1) The parent tx output is an input
1404
+ // 2) The additional unspent output is an input
1405
+ // 3) The child tx has exactly one output
1406
+ // 4) The child tx output meets the minimum change threshold
1407
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1408
+ decodedChild.ins.length.should.equal(2);
1409
+ decodedChild.outs.length.should.equal(1);
1410
+ let inputFromParent = undefined;
1411
+ let additionalInput = undefined;
1412
+ _.forEach(decodedChild.ins, (input) => {
1413
+ input.should.have.property('hash');
1414
+ input.should.have.property('index');
1415
+ const inputHash = inputParentTxId(input);
1416
+ if (inputHash === parentTxId) {
1417
+ inputFromParent = input;
1418
+ }
1419
+ else {
1420
+ additionalInput = input;
1421
+ }
1422
+ });
1423
+ should.exist(inputFromParent);
1424
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1425
+ inputFromParentHash.should.equal(parentTxId);
1426
+ inputFromParent.index.should.equal(0);
1427
+ should.exist(additionalInput);
1428
+ const additionalInputHash = inputParentTxId(additionalInput);
1429
+ additionalInputHash.should.equal(additionalUnspentTxId);
1430
+ additionalInput.index.should.equal(1);
1431
+ const childOutput = decodedChild.outs[0];
1432
+ childOutput.should.have.property('value');
1433
+ childOutput.value.should.be.above(minChangeSize);
1434
+ });
1435
+ it('accelerates a stuck tx with two additional unspents (segwit and P2SH)', async () => {
1436
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1437
+ (0, nock_1.default)(bgUrl)
1438
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1439
+ .reply(200, {
1440
+ fee: 1336,
1441
+ outputs: [
1442
+ {
1443
+ vout: 0,
1444
+ value: 10000,
1445
+ isMine: true,
1446
+ chain: 11,
1447
+ },
1448
+ {
1449
+ vout: 1,
1450
+ value: 8664,
1451
+ isMine: true,
1452
+ chain: 1,
1453
+ },
1454
+ ],
1455
+ confirmations: 0,
1456
+ });
1457
+ (0, nock_1.default)(bgUrl)
1458
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1459
+ .query(true)
1460
+ .reply(200, {
1461
+ unspents: [
1462
+ {
1463
+ tx_hash: parentTxId,
1464
+ tx_output_n: 0,
1465
+ value: 10000,
1466
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1467
+ chainPath: '/0/0',
1468
+ },
1469
+ ],
1470
+ });
1471
+ (0, nock_1.default)(bgUrl)
1472
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1473
+ .query(true)
1474
+ .reply(200, {
1475
+ unspents: [
1476
+ {
1477
+ tx_hash: 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58',
1478
+ tx_output_n: 1,
1479
+ value: 800000,
1480
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1481
+ chainPath: '/0/0',
1482
+ },
1483
+ {
1484
+ tx_hash: '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87',
1485
+ tx_output_n: 0,
1486
+ value: 20006284,
1487
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1488
+ chainPath: '/11/155',
1489
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1490
+ },
1491
+ ],
1492
+ });
1493
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1494
+ (0, nock_1.default)(bgUrl)
1495
+ .post('/api/v1/tx/send', (body) => {
1496
+ return !body.ignoreMaxFeeRate;
1497
+ })
1498
+ .reply(200, function (_, body) {
1499
+ return {
1500
+ transaction: body.tx,
1501
+ };
1502
+ });
1503
+ const childTx = await wallet.accelerateTransaction({
1504
+ transactionID: parentTxId,
1505
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1506
+ feeRate,
1507
+ });
1508
+ should.exist(childTx);
1509
+ childTx.should.have.property('status', 'accepted');
1510
+ childTx.should.have.property('tx');
1511
+ // assert the following:
1512
+ // 0) The child tx has exactly three inputs
1513
+ // 1) The parent tx output is an input
1514
+ // 2) The child tx has exactly one output
1515
+ // 3) The child tx output meets the minimum change threshold
1516
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1517
+ decodedChild.ins.length.should.equal(3);
1518
+ decodedChild.outs.length.should.equal(1);
1519
+ let inputFromParent = undefined;
1520
+ const additionalInputs = [];
1521
+ _.forEach(decodedChild.ins, (input) => {
1522
+ input.should.have.property('hash');
1523
+ input.should.have.property('index');
1524
+ const inputHash = inputParentTxId(input);
1525
+ if (inputHash === parentTxId) {
1526
+ inputFromParent = input;
1527
+ }
1528
+ else {
1529
+ additionalInputs.push(input);
1530
+ }
1531
+ });
1532
+ should.exist(inputFromParent);
1533
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1534
+ inputFromParentHash.should.equal(parentTxId);
1535
+ inputFromParent.index.should.equal(0);
1536
+ additionalInputs.length.should.equal(2);
1537
+ const childOutput = decodedChild.outs[0];
1538
+ childOutput.should.have.property('value');
1539
+ childOutput.value.should.be.above(minChangeSize);
1540
+ });
1541
+ it('correctly uses the ignoreMaxFeeRate parameter only when necessary', async () => {
1542
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
1543
+ (0, nock_1.default)(bgUrl)
1544
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1545
+ .reply(200, {
1546
+ fee: 434,
1547
+ outputs: [
1548
+ {
1549
+ vout: 0,
1550
+ value: 10348500,
1551
+ isMine: true,
1552
+ chain: 0,
1553
+ },
1554
+ {
1555
+ vout: 1,
1556
+ value: 10000,
1557
+ isMine: true,
1558
+ chain: 11,
1559
+ },
1560
+ ],
1561
+ });
1562
+ (0, nock_1.default)(bgUrl)
1563
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1564
+ .query(true)
1565
+ .reply(200, {
1566
+ unspents: [
1567
+ {
1568
+ tx_hash: parentTxId,
1569
+ tx_output_n: 0,
1570
+ value: 10348500,
1571
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
1572
+ chainPath: '/11/160',
1573
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
1574
+ },
1575
+ ],
1576
+ });
1577
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1578
+ (0, nock_1.default)(bgUrl)
1579
+ .post('/api/v1/tx/send', (body) => {
1580
+ // ignore max fee rate must be set for this test
1581
+ return body.ignoreMaxFeeRate;
1582
+ })
1583
+ .reply(200);
1584
+ // monkey patch the bitgo getConstants() function
1585
+ const oldGetConstants = bitgo.__proto__.getConstants;
1586
+ bitgo.__proto__.getConstants = () => ({
1587
+ // child fee rate in this test is 31378 sat/kb
1588
+ // so set the max fee rate just below that limit,
1589
+ // but above the combined fee rate of 20000
1590
+ maxFeeRate: 30000,
1591
+ });
1592
+ await wallet.accelerateTransaction({
1593
+ transactionID: parentTxId,
1594
+ feeRate,
1595
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1596
+ });
1597
+ nock_1.default.pendingMocks().should.be.empty();
1598
+ bitgo.__proto__.getConstants = oldGetConstants;
1599
+ });
1600
+ });
1601
+ });
1602
+ describe('getBitGoFee', function () {
1603
+ let bgUrl;
1604
+ let wallet;
1605
+ before(function () {
1606
+ nock_1.default.pendingMocks().should.be.empty();
1607
+ const prodBitgo = new bitgoAPI_1.BitGoAPI({ env: 'prod', clientConstants: { constants: {} } });
1608
+ bgUrl = sdk_core_1.common.Environments[prodBitgo.getEnv()].uri;
1609
+ wallet = new Wallet(prodBitgo, {
1610
+ id: '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4',
1611
+ private: { keychains: [userKeypair, backupKeypair, bitgoKey] },
1612
+ });
1613
+ });
1614
+ afterEach(function () {
1615
+ nock_1.default.cleanAll();
1616
+ });
1617
+ it('sends amount and instant without recipients when recipients array is empty', async function () {
1618
+ const scope = (0, nock_1.default)(bgUrl)
1619
+ .get(`/api/v1/wallet/${wallet.id()}/billing/fee`)
1620
+ .query({ amount: '100000', instant: 'false' })
1621
+ .reply(200, { fee: 1000 });
1622
+ const result = await wallet.getBitGoFee({ amount: 100000, instant: false });
1623
+ result.fee.should.equal(1000);
1624
+ scope.isDone().should.be.true();
1625
+ });
1626
+ it('sends recipients[] query params when recipients are provided', async function () {
1627
+ const addr1 = '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy';
1628
+ const addr2 = '3FZbgi29cpjq2GjdwV8eyHuJJnkLtktZc5';
1629
+ const scope = (0, nock_1.default)(bgUrl)
1630
+ .get(`/api/v1/wallet/${wallet.id()}/billing/fee`)
1631
+ .query((query) => {
1632
+ const recipientsParam = query['recipients[]'];
1633
+ const recipientsList = Array.isArray(recipientsParam) ? recipientsParam : [recipientsParam];
1634
+ return query.amount === '100000' && recipientsList.includes(addr1) && recipientsList.includes(addr2);
1635
+ })
1636
+ .reply(200, { fee: 0 });
1637
+ const result = await wallet.getBitGoFee({ amount: 100000, recipients: [addr1, addr2] });
1638
+ result.fee.should.equal(0);
1639
+ scope.isDone().should.be.true();
1640
+ });
1641
+ it('omits recipients[] when recipients array is empty', async function () {
1642
+ const scope = (0, nock_1.default)(bgUrl)
1643
+ .get(`/api/v1/wallet/${wallet.id()}/billing/fee`)
1644
+ .query((query) => query.amount === '200000' && !('recipients[]' in query))
1645
+ .reply(200, { fee: 500 });
1646
+ const result = await wallet.getBitGoFee({ amount: 200000, recipients: [] });
1647
+ result.fee.should.equal(500);
1648
+ scope.isDone().should.be.true();
1649
+ });
1650
+ it('throws when amount is not a number', function () {
1651
+ (() => wallet.getBitGoFee({ amount: 'bad' })).should.throw('invalid amount argument');
1652
+ });
1653
+ it('throws when instant is not a boolean', function () {
1654
+ (() => wallet.getBitGoFee({ amount: 100, instant: 'yes' })).should.throw('invalid instant argument');
1655
+ });
1656
+ });
1657
+ });
1658
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3YxL3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLG1CQUFtQjtBQUNuQixFQUFFO0FBQ0Ysb0RBQW9EO0FBQ3BELEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUYseUNBQXdDO0FBRXhDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ2pELG9EQUFpRDtBQUNqRCwwQ0FBNEI7QUFDNUIsbURBQThDO0FBQzlDLDhEQUFnRDtBQUNoRCwrQ0FBaUM7QUFDakMsZ0RBQXdCO0FBQ3hCLDZDQUErQjtBQUUvQiw0REFBdUQ7QUFFdkQsY0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIsTUFBTSxTQUFTLEdBQUc7SUFDaEIscUJBQXFCLEVBQUUsMEJBQTBCO0NBQ2xELENBQUM7QUFDRixRQUFRLENBQUMsMEJBQTBCLEVBQUU7SUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBQSwyQkFBVyxHQUFFLENBQUM7SUFFL0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxtQkFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLDhCQUE4QjtJQUU5QixNQUFNLFdBQVcsR0FBRztRQUNsQixJQUFJLEVBQUUsaUhBQWlIO1FBQ3ZILElBQUksRUFBRSxpSEFBaUg7UUFDdkgsTUFBTSxFQUFFLG9FQUFvRTtRQUM1RSxNQUFNLEVBQUUsa0VBQWtFO1FBQzFFLElBQUksRUFBRSxHQUFHO1FBQ1QsYUFBYSxFQUFFLE1BQU07S0FDdEIsQ0FBQztJQUNGLE1BQU0sYUFBYSxHQUFHO1FBQ3BCLElBQUksRUFBRSxpSEFBaUg7UUFDdkgsSUFBSSxFQUFFLGlIQUFpSDtRQUN2SCxN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O1FBQ3hGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFO1lBQ3pDLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDdkcsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3RzIGZvciBXYWxsZXRcbi8vXG4vLyBDb3B5cmlnaHQgMjAxNCwgQml0R28sIEluYy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4vL1xuXG5pbXBvcnQgeyBnZXRGaXh0dXJlIH0gZnJvbSAnLi9maXh0dXJlcyc7XG5cbmNvbnN0IFdhbGxldCA9IHJlcXVpcmUoJy4uLy4uLy4uL3NyYy92MS93YWxsZXQnKTtcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvQVBJJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGNvbW1vbiB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IHsgZ2V0Rml4dHVyZXMgfSBmcm9tICcuL2ZpeHR1cmVzL2FjY2VsZXJhdGUtdHgnO1xuXG5ub2NrLmRpc2FibGVOZXRDb25uZWN0KCk7XG5cbmNvbnN0IFRlc3RCaXRHbyA9IHtcbiAgVEVTVF9XQUxMRVQxX1BBU1NDT0RFOiAnaVZXZUFUanFMUzFqSlNoclBwRVR0aTBiJyxcbn07XG5kZXNjcmliZSgnV2FsbGV0IFByb3RvdHlwZSBNZXRob2RzJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBmaXh0dXJlcyA9IGdldEZpeHR1cmVzKCk7XG5cbiAgbGV0IGJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAndGVzdCcsIGNsaWVudENvbnN0YW50czogeyBjb25zdGFudHM6IHt9IH0gfSk7XG4gIC8vIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gIGNvbnN0IHVzZXJLZXlwYWlyID0ge1xuICAgIHhwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLMmZKOTFTNEJSc3VwY1lyRTZtbVk5NmZjWDVIa2hvVHJyd213amQxNkNuODdjV2luSmpCeXJmcG9qang3ZXpzSkx4N1RBS0xUOG04aE01S2F4OVljb3huQmVKWjN0MmsnLFxuICAgIHhwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjlOYzdUYkJvMXJaQWFnaVdFVlBXS2JES1RoTkc4enFqazc2SEFLTGthU2JUbjZkSzJkUVBmdUQ3eGppY3hDWlZXdmo2N2ZQNW5ROVc3UVVSbW9NVkFYOG02alpzR3AnLFxuICAgIHJhd1B1YjogJzAyYzEwM2FjNzQ0ODE4NzRiNWVmMGYzODVkMTI3MjVlNGYxNGFlZGM5ZTAwYmM4MTRjZTk2ZjQ3ZjYyY2U3YWRmMicsXG4gICAgcmF3UHJ2OiAnOTM2YzVhZjNmOGFmODFmNzVjZGFkMWIwOGYyOWU3ZDljMDFlNTk4ZTJkYjJkN2JlMThiOWU1YTg2NDZlODdjNicsXG4gICAgcGF0aDogJ20nLFxuICAgIHdhbGxldFN1YlBhdGg6ICcvMC8wJyxcbiAgfTtcbiAgY29uc3QgYmFja3VwS2V5cGFpciA9IHtcbiAgICB4cHJ2OiAneHBydjlzMjFaclFIMTQzSzQ3c0VrTGt5a2dZbXExeEY1WldyUFloVVpjbUJwUEZNUW9qdkdVbUVjcjVqRlhZR2ZyOENwRmRwVHZoUTdMOU5OMnJMdHNCRmpTaXgzQkFqd0pjQmo2VTNENWh4VFBjJyxcbiAgICB4cHViOiAneHB1YjY2MU15TXdBcVJiY0did2hyTkh6N3BWV1AzbmpWMkVoa21kNU4xQW9OaW5MSGM1NHAyNVZBZVFENnEyb1RTM3V1RE1EbmZuWG50aGJTOXVmQzhKVllwTm5XVTVSbjNwWWFOdUxDTnl3a3cxJyxcbiAgICByYXdQdWI6ICcwM2JiY2I3Mzk5Nzk3NzA2OGQ5ZTM2NjY2YmJkNWNkMzc1NzlhY2FlOGUyYmQ1Y2U5ZDBhNmU1YzE1MGE0MjNiYzMnLFxuICAgIHJhd1BydjogJzc3YTE1ZjE0Nzk2ZjQwMDFkMTA5MmFlODRmNzY2YmQ4NjllOWJlZTZiZmZhZTY1NDdkZWY1MDQ1Yjk2ZmE5NDMnLFxuICAgIHBhdGg6ICdtJyxcbiAgICB3YWxsZXRTdWJQYXRoOiAnLzAvMCcsXG4gIH07XG4gIGNvbnN0IGJpdGdvS2V5ID0ge1xuICAgIHhwdWI6ICd4cHViNjYxTXlNd0FxUmJjR1FjVkZpd2NydGM3YzN2b3BzWDk2anNKVVlQY0ZNUkVjUlRxQXFzcWJ2MlpSeUNKQVBMbTVOTUhDeTg1RTNad3BUNEVBVXc5V0dVN3ZNaEc2ejgzaERlS1hCV242TGYnLFxuICAgIHBhdGg6ICdtJyxcbiAgICB3YWxsZXRTdWJQYXRoOiAnLzAvMCcsXG4gIH07XG5cbiAgY29uc3QgZmFrZVdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHtcbiAgICBpZDogJzJOQ29TZkhINkxzNENkVFM1UWFoZ0M5azd4OVJmWGVTd1k0JyxcbiAgICBwcml2YXRlOiB7IGtleWNoYWluczogW3VzZXJLZXlwYWlyLCBiYWNrdXBLZXlwYWlyLCBiaXRnb0tleV0gfSxcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIEFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlKCgpID0+IG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCkpO1xuXG4gICAgaXQoJ2dlbmVyYXRlIGZpcnN0IGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpZEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8wJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGlkQWRkcmVzcy5hZGRyZXNzLnNob3VsZC5lcXVhbChmYWtlV2FsbGV0LmlkKCkpO1xuICAgICAgaWRBZGRyZXNzLmNoYWluLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIGlkQWRkcmVzcy5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBpZEFkZHJlc3MuY2hhaW5QYXRoLnNob3VsZC5lcXVhbCgnLzAvMCcpO1xuICAgICAgaWRBZGRyZXNzLnBhdGguc2hvdWxkLmVxdWFsKCcvMC8wJyk7XG4gICAgICBpZEFkZHJlc3Mub3V0cHV0U2NyaXB0LnNob3VsZC5lcXVhbCgnYTkxNGQ2ODI0NzZlOWJkNTQ0NTRhODg1ZjlkZmYxZTYwNGU5OWNlZjQzZGM4NycpO1xuICAgICAgaWRBZGRyZXNzLnJlZGVlbVNjcmlwdC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnXG4gICAgICApO1xuICAgICAgaWRBZGRyZXNzLndhbGxldC5zaG91bGQuZXF1YWwoZmFrZVdhbGxldC5pZCgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdnZW5lcmF0ZSBzZWNvbmQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzAvMScsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBwMnNoQWRkcmVzcy5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMk41eTVSTFZxZFppN3FwNVBtek1kUFI2WXZRelVxQlFGV0snKTtcbiAgICAgIHAyc2hBZGRyZXNzLmNoYWluLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHAyc2hBZGRyZXNzLmluZGV4LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHAyc2hBZGRyZXNzLmNoYWluUGF0aC5zaG91bGQuZXF1YWwoJy8wLzEnKTtcbiAgICAgIHAyc2hBZGRyZXNzLnBhdGguc2hvdWxkLmVxdWFsKCcvMC8xJyk7XG4gICAgICBwMnNoQWRkcmVzcy5vdXRwdXRTY3JpcHQuc2hvdWxkLmVxdWFsKCdhOTE0OGI4YmQzZGE2OGVmMGYyNDY1NTIzMTQ2YmQyZGUzM2M4NmI5Yzg3MTg3Jyk7XG4gICAgICBwMnNoQWRkcmVzcy5yZWRlZW1TY3JpcHQuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNTIyMTAyNzA5ZWRiNmEyMTk4ZDM2NGM0ODVhNzZiOTgxZDEyMDY1ZWFiZGU4YWEyZDg1YmQ3ZTdhMDM1ZjdlY2IzNTc5YjIxMDJhNzI0ZWZlZDQ5OWMwNWZkYjRkYTFlMTM5NzAwOTUxZmFlMDBjMDA2YjMyODM4ODhiZGZkMWI0Njk3OTI5MjI0MjEwMmIzMmFiZTQ0ZDYxOTg2ZmY1N2I4MzVlM2JkMTYyOTNkOTNmMzAzZDBkOGZiMDQ1NGUyYzljY2VkYTVjNDkyOTg1M2FlJ1xuICAgICAgKTtcbiAgICAgIHAyc2hBZGRyZXNzLndhbGxldC5zaG91bGQuZXF1YWwoZmFrZVdhbGxldC5pZCgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdnZW5lcmF0ZSBjaGFuZ2UgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEvMCcsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBwMnNoQWRkcmVzcy5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMk5GajlKcnBaYzVNeVluQ291eVJFdHpOWTRlb3lLV0RmZ1AnKTtcbiAgICAgIHAyc2hBZGRyZXNzLmNoYWluLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHAyc2hBZGRyZXNzLmluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHAyc2hBZGRyZXNzLmNoYWluUGF0aC5zaG91bGQuZXF1YWwoJy8xLzAnKTtcbiAgICAgIHAyc2hBZGRyZXNzLnBhdGguc2hvdWxkLmVxdWFsKCcvMS8wJyk7XG4gICAgICBwMnNoQWRkcmVzcy5vdXRwdXRTY3JpcHQuc2hvdWxkLmVxdWFsKCdhOTE0ZjY5YTgxZmFkNzVlYTY1YWQxNjZkYTc2NTE1MjkxNjc5YTRmMWFkODg3Jyk7XG4gICAgICBwMnNoQWRkcmVzcy5yZWRlZW1TY3JpcHQuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNTIyMTAyMGI0YzRmODkxYTU1MjBmNWEwYjY4MThkOGQ1MzkxOTU1MmEwZDRkODA2YjVmYTA1Yzk3NzA4MDc5ZDgzNzM3ZTIxMDJjNWNjNDliZjAzMzFlYjBiMDg5MGE3ZTdkODdmN2U5ZTBkZWE1MTU0MzgyODBkYzc2ODM0YzIxZDE5OGVmZTA4MjEwMzcwZTUyY2Y3NDFlYmY0NTEzNzQ5ZDAyODgzOWQ2OTY4OTFlYjc4OWJhN2E1ODU5MmNmYmM4NTdjZGMwYTlkZTc1M2FlJ1xuICAgICAgKTtcbiAgICAgIHAyc2hBZGRyZXNzLndhbGxldC5zaG91bGQuZXF1YWwoZmFrZVdhbGxldC5pZCgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdnZW5lcmF0ZSBzZWd3aXQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMTAvMCcsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzJONUVWZWdSUFdubWVkMlBwcURnZ1pQdzdEY05EZ3VSWXY4Jyk7XG4gICAgICBzZWd3aXRBZGRyZXNzLmNoYWluLnNob3VsZC5lcXVhbCgxMCk7XG4gICAgICBzZWd3aXRBZGRyZXNzLmluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MuY2hhaW5QYXRoLnNob3VsZC5lcXVhbCgnLzEwLzAnKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MucGF0aC5zaG91bGQuZXF1YWwoJy8xMC8wJyk7XG4gICAgICBzZWd3aXRBZGRyZXNzLm91dHB1dFNjcmlwdC5zaG91bGQuZXF1YWwoJ2E5MTQ4MzdlMmFkY2I2ZjYzODZmZWEzYzVkNDAzMTZiMjgyY2NmMzkxMjFkODcnKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MucmVkZWVtU2NyaXB0LnNob3VsZC5lcXVhbCgnMDAyMGE2MmFmZWUxZDIxMWM1YWRiOTczOWY4MWVkNGUzNjMzMGU2Y2RhNjUxYzdiZGQzMTRlMzJjY2M0NjVlYzIyMDMnKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3Mud2l0bmVzc1NjcmlwdC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1MjIxMDI3YjMwNTA1Nzc3YTRlZDg5NDdiMDY5ZmNiMDExNmUyODc5OTVkOTcyNzhkODRkYTRkYjZjNjEzMjcwNjQ5ZDNkMjEwMzRjMzBlNTFmMWU2MTRjYWQ2Njc4MTVjOTFkMDQxNDA0YzE4MjI1ZDBiMmY3OWUyYzBiY2I2M2ZkMjYwNDMxNmIyMTAzYjY1ZGRmYzA2MTU5YjY5MTY5MzM5MDc2MWU3NWEwYjhjYzdhNjViNmZmMzA1ZDA5NGYzYWQ5NzJmMTc5NTNmZTUzYWUnXG4gICAgICApO1xuICAgICAgc2Vnd2l0QWRkcmVzcy53YWxsZXQuc2hvdWxkLmVxdWFsKGZha2VXYWxsZXQuaWQoKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdDcmVhdGUgVHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJnVXJsLCBiZ1VybFRlc3Q7XG4gICAgbGV0IGZha2VQcm9kV2FsbGV0O1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgICBjb25zdCBwcm9kQml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdwcm9kJywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgICAgIC8vIHByb2RCaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1twcm9kQml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGZha2VQcm9kV2FsbGV0ID0gbmV3IFdhbGxldChwcm9kQml0Z28sIHtcbiAgICAgICAgaWQ6ICcyTkNvU2ZISDZMczRDZFRTNVFhaGdDOWs3eDlSZlhlU3dZNCcsXG4gICAgICAgIHByaXZhdGU6IHsga2V5Y2hhaW5zOiBbdXNlcktleXBhaXIsIGJhY2t1cEtleXBhaXIsIGJpdGdvS2V5XSB9LFxuICAgICAgfSk7XG4gICAgICBiZ1VybFRlc3QgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgfSk7XG5cbiAgICBpdCgnZXh0cmEgdW5zcGVudCBmZXRjaCBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaWxsaW5nQWRkcmVzcyA9ICczSjk4dDFXcEVaNzNDTm1RdmllY3JueWlXcm5xUmhXTkx5JztcbiAgICAgIGNvbnN0IGN1c3RvbVVuc3BlbnRzRmV0Y2hQYXJhbXMgPSB7IHRlc3Q6IDEyMyB9O1xuICAgICAgY29uc3Qgc2VuZEFtb3VudCA9IDFlNTtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogYmlsbGluZ0FkZHJlc3MgfSk7XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHtmYWtlUHJvZFdhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgIC5xdWVyeShcbiAgICAgICAgICBfLm1lcmdlKGN1c3RvbVVuc3BlbnRzRmV0Y2hQYXJhbXMsIHtcbiAgICAgICAgICAgIHNlZ3dpdDogdHJ1ZSxcbiAgICAgICAgICAgIHRhcmdldDogc2VuZEFtb3VudCxcbiAgICAgICAgICAgIG1pblNpemU6IDAsXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHVuc3BlbnRzOiBbXSB9KTtcblxuICAgICAgYXdhaXQgZmFrZVByb2RXYWxsZXRcbiAgICAgICAgLmNyZWF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB1bnNwZW50c0ZldGNoUGFyYW1zOiBjdXN0b21VbnNwZW50c0ZldGNoUGFyYW1zLFxuICAgICAgICAgIHJlY2lwaWVudHM6IHsgW2JpbGxpbmdBZGRyZXNzXTogc2VuZEFtb3VudCB9LFxuICAgICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnMCB1bnNwZW50cyBhdmFpbGFibGUgZm9yIHRyYW5zYWN0aW9uIGNyZWF0aW9uJyk7XG5cbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGVmYXVsdCBwMnNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlUHJvZFdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzAvMTMnLCBzZWd3aXQ6IGZhbHNlIH0pO1xuICAgICAgY29uc3QgdW5zcGVudDogYW55ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk5DRURtbUtOTm5xS3ZuV3c3cEUzUkx6dUZlNWFISFZ5MVgnXSxcbiAgICAgICAgdmFsdWU6ICcwLjAwNTA0NDIyJyxcbiAgICAgICAgdmFsdWVfaW50OiA1MDQ0MjIsXG4gICAgICAgIHR4aWQ6ICdiODE2ZGVkODljM2Q4ZDUwMjFiMDEwOTdmNGEzMTI5YTZhNjhhNWNiN2M4ODZlOTc5NDVmNDIwNWNiYTVkZTQ0JyxcbiAgICAgICAgbjogMSxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiA5LFxuICAgICAgICBpZDogNjEzMzAyMjksXG4gICAgICB9O1xuICAgICAgXy5leHRlbmQodW5zcGVudCwgcDJzaEFkZHJlc3MpO1xuICAgICAgdW5zcGVudC52YWx1ZSA9IHVuc3BlbnQudmFsdWVfaW50O1xuICAgICAgdW5zcGVudC50eF9oYXNoID0gdW5zcGVudC50eGlkO1xuICAgICAgdW5zcGVudC50eF9vdXRwdXRfbiA9IHVuc3BlbnQubjtcbiAgICAgIHVuc3BlbnQuc2NyaXB0ID0gdW5zcGVudC5vdXRwdXRTY3JpcHQ7XG5cbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJykucmVwbHkoMjAwLCB7IGFkZHJlc3M6ICcyTXN3UWprdk42b1dZZEU3TDJicko1Y0FBTWpQbUc1OW9jbycgfSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LmNyZWF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgY2hhbmdlQWRkcmVzczogcDJzaEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBwMnNoIHRlc3QnOiAxMDAwIH0sXG4gICAgICAgIHVzZVBzYnQ6IGZhbHNlLFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDE0NGRlYTVjYjA1NDI1Zjk0OTc2ZTg4N2NjYmE1Njg2YTlhMTJhM2Y0OTcxMGIwMjE1MDhkM2Q5Y2Q4ZGUxNmI4MDEwMDAwMDAwMGZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTEgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgc2lnbmF0dXJlMS50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwYjYwMDQ3MzA0NDAyMjAyMWZhNzNkNWZlNjFhYzg5NDJjZDcwZmY0NTA3YzU3NDY3N2NlNzQ3ZGU1YmM0NmMzZGQyZTM4ZWMyNDQ4ZmNlMDIyMDQ3OTA2ZDJjMDE1NDMzN2FiOTYwNDFlOGZiNThjMjQzYjliY2U1Zjg4MThmYTk5MTY0M2MxMjYwYTE4NTlhZDgwMTAwMDA0YzY5NTIyMTAzMWNkMjI3ZTQwYWQ2MWI0ZTEzNzEwOWNiMjg0NWViNmY1YTU4NGVkNWM2N2Q5ZDMxMzVjZGFhNTA0NWE4NDJlYTIxMDNhMmU3YjU0YzdiMmRhMDk5MjU1NTM1M2I4ZTI2YzZhY2ZmNDI0OGY0MzUxZjA4Nzg3YmYzZTJlZmM5NGI2NTgzMjEwMjVjMmE2Y2RlMzNjMmQ3M2NjZjEyZWVjZjY0YzU0ZjA4ZjcyMmMyZjA3MzgyNDQ5ODk1MDY5NWU5ODgzYjE0MTI1M2FlZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMTZhMGY0MjY5NzQ0NzZmMjA3MDMyNzM2ODIwNzQ2NTczNzQyMmExMDcwMDAwMDAwMDAwMTdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgc2Vjb25kIHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXggPSBzaWduYXR1cmUxLnR4O1xuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSBiYWNrdXBLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZnVsbExvY2FsU2lnbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUyID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIC8vIFRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9hOGNjYjkyODE2OTAzMmQ2ZTFmMzdiZjgxZGZkOWFiNmQ5MDM2MmE0Zjg0ZTU3NzM5N2ZhNjkwYWE3MTE1NTBjXG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDE0NGRlYTVjYjA1NDI1Zjk0OTc2ZTg4N2NjYmE1Njg2YTlhMTJhM2Y0OTcxMGIwMjE1MDhkM2Q5Y2Q4ZGUxNmI4MDEwMDAwMDBmZGZkMDAwMDQ3MzA0NDAyMjAyMWZhNzNkNWZlNjFhYzg5NDJjZDcwZmY0NTA3YzU3NDY3N2NlNzQ3ZGU1YmM0NmMzZGQyZTM4ZWMyNDQ4ZmNlMDIyMDQ3OTA2ZDJjMDE1NDMzN2FiOTYwNDFlOGZiNThjMjQzYjliY2U1Zjg4MThmYTk5MTY0M2MxMjYwYTE4NTlhZDgwMTQ3MzA0NDAyMjAyYWUwMWYwMWI1YWUwYzNmYTdkNjdhYzczZGI4MTkzMmNiNWFjYTEwZGIxNmE5OTA2M2ZlZjQ1ZTNmMTM5OGNkMDIyMDU1MDAxYmE3ZTE2M2NiMzUwOTEwZmM3MzIxZWNkN2ViNjM1OWIzMjFkNGMwNDg4NzQ4NGQ5YzcyODRiNzhjNDcwMTAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdwMnNoIFBTQlQgcHJvZHVjZXMgc2FtZSB1bnNpZ25lZCB0eCBhcyBsZWdhY3knLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VQcm9kV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xMycsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCB1bnNwZW50OiBhbnkgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTkNFRG1tS05ObnFLdm5XdzdwRTNSTHp1RmU1YUhIVnkxWCddLFxuICAgICAgICB2YWx1ZTogJzAuMDA1MDQ0MjInLFxuICAgICAgICB2YWx1ZV9pbnQ6IDUwNDQyMixcbiAgICAgICAgdHhpZDogJ2I4MTZkZWQ4OWMzZDhkNTAyMWIwMTA5N2Y0YTMxMjlhNmE2OGE1Y2I3Yzg4NmU5Nzk0NWY0MjA1Y2JhNWRlNDQnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDksXG4gICAgICAgIGlkOiA2MTMzMDIyOSxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBwMnNoQWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gcDJzaCB0ZXN0JzogMTAwMCB9LFxuICAgICAgfTtcblxuICAgICAgLy8gQ3JlYXRlIGxlZ2FjeSB0cmFuc2FjdGlvblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcbiAgICAgIGNvbnN0IGxlZ2FjeVR4ID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LmNyZWF0ZVRyYW5zYWN0aW9uKHsgLi4udHhQYXJhbXMsIHVzZVBzYnQ6IGZhbHNlIH0pKSBhcyBhbnk7XG5cbiAgICAgIC8vIENyZWF0ZSBQU0JUIHRyYW5zYWN0aW9uIChleHBsaWNpdGx5KVxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcbiAgICAgIGNvbnN0IHBzYnRUeCA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7IC4uLnR4UGFyYW1zLCB1c2VQc2J0OiB0cnVlIH0pKSBhcyBhbnk7XG5cbiAgICAgIC8vIEV4dHJhY3QgdW5zaWduZWQgdHggZnJvbSBQU0JUIGFuZCBjb21wYXJlXG4gICAgICBjb25zdCBwc2J0ID0gdXR4b2xpYi5iaXRnby5jcmVhdGVQc2J0RnJvbUhleChwc2J0VHgudHJhbnNhY3Rpb25IZXgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICBjb25zdCB1bnNpZ25lZFR4RnJvbVBzYnQgPSBwc2J0LmdldFVuc2lnbmVkVHgoKS50b0hleCgpO1xuXG4gICAgICAvLyBUaGUgdW5zaWduZWQgdHJhbnNhY3Rpb24gaGV4IHNob3VsZCBiZSBpZGVudGljYWxcbiAgICAgIGxlZ2FjeVR4LnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbCh1bnNpZ25lZFR4RnJvbVBzYnQpO1xuXG4gICAgICAvLyBGZWVzIHNob3VsZCBhbHNvIG1hdGNoXG4gICAgICBsZWdhY3lUeC5mZWUuc2hvdWxkLmVxdWFsKHBzYnRUeC5mZWUpO1xuXG4gICAgICAvLyBDbGVhbiB1cCBub2NrIG1vY2tzIHRvIGF2b2lkIGludGVyZmVyZW5jZSB3aXRoIG90aGVyIHRlc3RzXG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2Vnd2l0IFBTQlQgcHJvZHVjZXMgc2FtZSB1bnNpZ25lZCB0eCBhcyBsZWdhY3knLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8xMycsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJNeEtrSDh5QjNTOVlXbVRRUmJ2bWJvcllReVFuSDVwZXRQJ10sXG4gICAgICAgIHZhbHVlOiAnMC4xODc1MDAwMCcsXG4gICAgICAgIHZhbHVlX2ludDogMTg3NTAwMDAsXG4gICAgICAgIHR4aWQ6ICc3ZDI4Mjg3OGE4NWRhZWU1ZDQ2ZTA0MzgyN2RhZWQ1NzU5NmQ3NWQxYWE2ZTA0ZmQwYzA5YTM2ZjkxMzA4ODFmJyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzE2MTcsXG4gICAgICB9O1xuICAgICAgXy5leHRlbmQodW5zcGVudCwgc2Vnd2l0QWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHNlZ3dpdEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBzZWd3aXQgdGVzdCc6IDEwMDAgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIENyZWF0ZSBsZWdhY3kgdHJhbnNhY3Rpb25cbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJykucmVwbHkoMjAwLCB7IGFkZHJlc3M6ICcyTXN3UWprdk42b1dZZEU3TDJicko1Y0FBTWpQbUc1OW9jbycgfSk7XG4gICAgICBjb25zdCBsZWdhY3lUeCA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7IC4uLnR4UGFyYW1zLCB1c2VQc2J0OiBmYWxzZSB9KSkgYXMgYW55O1xuXG4gICAgICAvLyBDcmVhdGUgUFNCVCB0cmFuc2FjdGlvbiAoZXhwbGljaXRseSlcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJykucmVwbHkoMjAwLCB7IGFkZHJlc3M6ICcyTXN3UWprdk42b1dZZEU3TDJicko1Y0FBTWpQbUc1OW9jbycgfSk7XG4gICAgICBjb25zdCBwc2J0VHggPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oeyAuLi50eFBhcmFtcywgdXNlUHNidDogdHJ1ZSB9KSkgYXMgYW55O1xuXG4gICAgICAvLyBFeHRyYWN0IHVuc2lnbmVkIHR4IGZyb20gUFNCVCBhbmQgY29tcGFyZVxuICAgICAgY29uc3QgcHNidCA9IHV0eG9saWIuYml0Z28uY3JlYXRlUHNidEZyb21IZXgocHNidFR4LnRyYW5zYWN0aW9uSGV4LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgY29uc3QgdW5zaWduZWRUeEZyb21Qc2J0ID0gcHNidC5nZXRVbnNpZ25lZFR4KCkudG9IZXgoKTtcblxuICAgICAgLy8gVGhlIHVuc2lnbmVkIHRyYW5zYWN0aW9uIGhleCBzaG91bGQgYmUgaWRlbnRpY2FsXG4gICAgICBsZWdhY3lUeC50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwodW5zaWduZWRUeEZyb21Qc2J0KTtcblxuICAgICAgLy8gRmVlcyBzaG91bGQgYWxzbyBtYXRjaFxuICAgICAgbGVnYWN5VHguZmVlLnNob3VsZC5lcXVhbChwc2J0VHguZmVlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgbm9jayBtb2NrcyB0byBhdm9pZCBpbnRlcmZlcmVuY2Ugd2l0aCBvdGhlciB0ZXN0c1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Ayc2ggd2l0aCBQU0JUIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzEzJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJOQ0VEbW1LTk5ucUt2bld3N3BFM1JMenVGZTVhSEhWeTFYJ10sXG4gICAgICAgIHZhbHVlOiAnMC4wMDUwNDQyMicsXG4gICAgICAgIHZhbHVlX2ludDogNTA0NDIyLFxuICAgICAgICB0eGlkOiAnYjgxNmRlZDg5YzNkOGQ1MDIxYjAxMDk3ZjRhMzEyOWE2YTY4YTVjYjdjODg2ZTk3OTQ1ZjQyMDVjYmE1ZGU0NCcsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCBkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogOSxcbiAgICAgICAgaWQ6IDYxMzMwMjI5LFxuICAgICAgfTtcbiAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIHAyc2hBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gcDJzaCB0ZXN0JzogMTAwMCB9LFxuICAgICAgICB1c2VQc2J0OiB0cnVlLCAvLyBFeHBsaWNpdGx5IHJlcXVlc3QgUFNCVCBmb3JtYXRcbiAgICAgIH0pKSBhcyBhbnk7XG5cbiAgICAgIC8vIFZlcmlmeSBQU0JUIGZvcm1hdCBpcyByZXR1cm5lZCBpbiB0cmFuc2FjdGlvbkhleFxuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4KTtcbiAgICAgIHNob3VsZC5vayh1dHhvbGliLmJpdGdvLmlzUHNidCh0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCkpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdCh0cmFuc2FjdGlvbi51bnNwZW50cyk7XG5cbiAgICAgIC8vIFBhcnNlIGFuZCB2YWxpZGF0ZSB0aGUgUFNCVFxuICAgICAgY29uc3QgcHNidCA9IHV0eG9saWIuYml0Z28uY3JlYXRlUHNidEZyb21IZXgodHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBwc2J0LmRhdGEub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpOyAvLyBPUF9SRVRVUk4gKyBjaGFuZ2VcblxuICAgICAgLy8gVmVyaWZ5IGlucHV0IGhhcyByZXF1aXJlZCBQU0JUIG1ldGFkYXRhXG4gICAgICBjb25zdCBpbnB1dCA9IHBzYnQuZGF0YS5pbnB1dHNbMF07XG4gICAgICBzaG91bGQuZXhpc3QoaW5wdXQud2l0bmVzc1V0eG8pO1xuICAgICAgc2hvdWxkLmV4aXN0KGlucHV0LnJlZGVlbVNjcmlwdCk7XG4gICAgICBzaG91bGQuZXhpc3QoaW5wdXQuYmlwMzJEZXJpdmF0aW9uKTtcbiAgICAgIGlucHV0LmJpcDMyRGVyaXZhdGlvbiEubGVuZ3RoLnNob3VsZC5lcXVhbCgzKTsgLy8gdXNlciwgYmFja3VwLCBiaXRnb1xuXG4gICAgICAvLyBWZXJpZnkgZ2xvYmFsWHB1YnMgYXJlIHNldFxuICAgICAgc2hvdWxkLmV4aXN0KHBzYnQuZGF0YS5nbG9iYWxNYXAuZ2xvYmFsWHB1Yik7XG4gICAgICBwc2J0LmRhdGEuZ2xvYmFsTWFwLmdsb2JhbFhwdWIhLmxlbmd0aC5zaG91bGQuZXF1YWwoMyk7XG5cbiAgICAgIC8vIFNpZ24gd2l0aCB1c2VyIGtleSAtIGF1dG8tZGV0ZWN0cyBQU0JUIGluIHRyYW5zYWN0aW9uSGV4XG4gICAgICBjb25zdCBzaWduZWRSZXN1bHQgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHJhbnNhY3Rpb25IZXg6IHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LFxuICAgICAgICBrZXljaGFpbjogdXNlcktleXBhaXIsXG4gICAgICB9KSkgYXMgYW55O1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc2lnbmVkUmVzdWx0LnR4KTtcblxuICAgICAgLy8gUGFyc2Ugc2lnbmVkIFBTQlQgYW5kIHZlcmlmeSBzaWduYXR1cmVcbiAgICAgIGNvbnN0IHNpZ25lZFBzYnQgPSB1dHhvbGliLmJpdGdvLmNyZWF0ZVBzYnRGcm9tSGV4KHNpZ25lZFJlc3VsdC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgIHNob3VsZC5vayhzaWduZWRQc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mSW5wdXRIRCgwLCB1dHhvbGliLmJpcDMyLmZyb21CYXNlNTgodXNlcktleXBhaXIueHB1YikpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZWd3aXQgd2l0aCBQU0JUIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlUHJvZFdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzEzJywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgdW5zcGVudDogYW55ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk14S2tIOHlCM1M5WVdtVFFSYnZtYm9yWVF5UW5INXBldFAnXSxcbiAgICAgICAgdmFsdWU6ICcwLjE4NzUwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxODc1MDAwMCxcbiAgICAgICAgdHhpZDogJzdkMjgyODc4YTg1ZGFlZTVkNDZlMDQzODI3ZGFlZDU3NTk2ZDc1ZDFhYTZlMDRmZDBjMDlhMzZmOTEzMDg4MWYnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgMzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTYxNyxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBzZWd3aXRBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHNlZ3dpdEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBzZWd3aXQgdGVzdCc6IDEwMDAgfSxcbiAgICAgICAgdXNlUHNidDogdHJ1ZSwgLy8gRXhwbGljaXRseSByZXF1ZXN0IFBTQlQgZm9ybWF0XG4gICAgICB9KSkgYXMgYW55O1xuXG4gICAgICAvLyBWZXJpZnkgUFNCVCBmb3JtYXQgaXMgcmV0dXJuZWQgaW4gdHJhbnNhY3Rpb25IZXhcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCk7XG4gICAgICBzaG91bGQub2sodXR4b2xpYi5iaXRnby5pc1BzYnQodHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXgpKTtcblxuICAgICAgLy8gUGFyc2UgYW5kIHZhbGlkYXRlIHRoZSBQU0JUXG4gICAgICBjb25zdCBwc2J0ID0gdXR4b2xpYi5iaXRnby5jcmVhdGVQc2J0RnJvbUhleCh0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgIHBzYnQuZGF0YS5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgLy8gVmVyaWZ5IGlucHV0IGhhcyBzZWd3aXQgUFNCVCBtZXRhZGF0YVxuICAgICAgY29uc3QgaW5wdXQgPSBwc2J0LmRhdGEuaW5wdXRzWzBdO1xuICAgICAgc2hvdWxkLmV4aXN0KGlucHV0LndpdG5lc3NVdHhvKTtcbiAgICAgIHNob3VsZC5leGlzdChpbnB1dC53aXRuZXNzU2NyaXB0KTtcbiAgICAgIHNob3VsZC5leGlzdChpbnB1dC5yZWRlZW1TY3JpcHQpO1xuICAgICAgc2hvdWxkLmV4aXN0KGlucHV0LmJpcDMyRGVyaXZhdGlvbik7XG5cbiAgICAgIC8vIFNpZ24gd2l0aCB1c2VyIGtleSAtIGF1dG8tZGV0ZWN0cyBQU0JUIGluIHRyYW5zYWN0aW9uSGV4XG4gICAgICBjb25zdCBzaWduZWRSZXN1bHQgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHJhbnNhY3Rpb25IZXg6IHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LFxuICAgICAgICBrZXljaGFpbjogdXNlcktleXBhaXIsXG4gICAgICB9KSkgYXMgYW55O1xuXG4gICAgICBzaG91bGQuZXhpc3Qoc2lnbmVkUmVzdWx0LnR4KTtcblxuICAgICAgLy8gUGFyc2Ugc2lnbmVkIFBTQlQgYW5kIHZlcmlmeSBzaWduYXR1cmVcbiAgICAgIGNvbnN0IHNpZ25lZFBzYnQgPSB1dHhvbGliLmJpdGdvLmNyZWF0ZVBzYnRGcm9tSGV4KHNpZ25lZFJlc3VsdC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgIHNob3VsZC5vayhzaWduZWRQc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mSW5wdXRIRCgwLCB1dHhvbGliLmJpcDMyLmZyb21CYXNlNTgodXNlcktleXBhaXIueHB1YikpKTtcbiAgICB9KTtcblxuICAgIGl0KCdCQ0ggcDJzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzEzJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJOQ0VEbW1LTk5ucUt2bld3N3BFM1JMenVGZTVhSEhWeTFYJ10sXG4gICAgICAgIHZhbHVlOiAnMC4wMDUwNDQyMicsXG4gICAgICAgIHZhbHVlX2ludDogNTA0NDIyLFxuICAgICAgICB0eGlkOiAnYjgxNmRlZDg5YzNkOGQ1MDIxYjAxMDk3ZjRhMzEyOWE2YTY4YTVjYjdjODg2ZTk3OTQ1ZjQyMDVjYmE1ZGU0NCcsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCBkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogOSxcbiAgICAgICAgaWQ6IDYxMzMwMjI5LFxuICAgICAgfTtcbiAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIHAyc2hBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gcDJzaCB0ZXN0JzogMTAwMCB9LFxuICAgICAgICB1c2VQc2J0OiBmYWxzZSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwMDBmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mb3JjZUJDSCA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTQ0ZGVhNWNiMDU0MjVmOTQ5NzZlODg3Y2NiYTU2ODZhOWExMmEzZjQ5NzEwYjAyMTUwOGQzZDljZDhkZTE2YjgwMTAwMDAwMGI2MDA0NzMwNDQwMjIwNjIyMWE5N2YwODFkODdlMDJlM2IxNDk4OGE2NDg2MTgxMWE2YThkZTRmMTFmNzRmNWFhZWE0NTk4MWNmNjEyZTAyMjA3N2EwOGE1YmQ3ZDc4MWU3OTgzOGFmYmIxMjZhZjJlNDg4MDJmZWZhZDY2MGFmZGJkODgwNWY1ZTU5OGVkNTg4NDEwMDAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbiBoYXMgYWN0dWFsbHkgd29ya2VkOiBodHRwczovL3Rlc3RuZXQuc21hcnRiaXQuY29tLmF1L3R4L2E4Y2NiOTI4MTY5MDMyZDZlMWYzN2JmODFkZmQ5YWI2ZDkwMzYyYTRmODRlNTc3Mzk3ZmE2OTBhYTcxMTU1MGNcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGUgdHggaGV4IGJlbG93IG5vIGxvbmdlciBjb3JyZXNwb25kcyB0byB0aGUgYWJvdmUgdHJhbnNhY3Rpb24gYmVjYXVzZSBvdXIgZmVlIGVzdGltYXRpb24gaGFzXG4gICAgICAvLyBjaGFuZ2VkLCBjaGFuZ2luZyB0aGUgb3V0cHV0IGFtb3VudHMgYW5kIHRodXMgdGhlIHR4IGhleC5cbiAgICAgIHNpZ25hdHVyZTIudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTQ0ZGVhNWNiMDU0MjVmOTQ5NzZlODg3Y2NiYTU2ODZhOWExMmEzZjQ5NzEwYjAyMTUwOGQzZDljZDhkZTE2YjgwMTAwMDAwMGZkZmUwMDAwNDczMDQ0MDIyMDYyMjFhOTdmMDgxZDg3ZTAyZTNiMTQ5ODhhNjQ4NjE4MTFhNmE4ZGU0ZjExZjc0ZjVhYWVhNDU5ODFjZjYxMmUwMjIwNzdhMDhhNWJkN2Q3ODFlNzk4MzhhZmJiMTI2YWYyZTQ4ODAyZmVmYWQ2NjBhZmRiZDg4MDVmNWU1OThlZDU4ODQxNDgzMDQ1MDIyMTAwODJiYzU0NjI5Mzg1ODQ1OWYzODk1ZGIyNGM4NWNjZjM3NTA1YzU2ZjhmYWY0YmI4Zjc4Y2Y0MDEzNWJjMmYyYjAyMjAzZGMxYzc4ZDdjN2NlYWY2YjkyNGVjYTNjMzliOTVlOGEyMjdiMDY5YTA3MDQ3NTgxMjczMTM2YjQ3Y2E3YWM0NDEwMDRjNjk1MjIxMDMxY2QyMjdlNDBhZDYxYjRlMTM3MTA5Y2IyODQ1ZWI2ZjVhNTg0ZWQ1YzY3ZDlkMzEzNWNkYWE1MDQ1YTg0MmVhMjEwM2EyZTdiNTRjN2IyZGEwOTkyNTU1MzUzYjhlMjZjNmFjZmY0MjQ4ZjQzNTFmMDg3ODdiZjNlMmVmYzk0YjY1ODMyMTAyNWMyYTZjZGUzM2MyZDczY2NmMTJlZWNmNjRjNTRmMDhmNzIyYzJmMDczODI0NDk4OTUwNjk1ZTk4ODNiMTQxMjUzYWVmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGVmYXVsdCBzZWd3aXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8xMycsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJNeEtrSDh5QjNTOVlXbVRRUmJ2bWJvcllReVFuSDVwZXRQJ10sXG4gICAgICAgIHZhbHVlOiAnMC4xODc1MDAwMCcsXG4gICAgICAgIHZhbHVlX2ludDogMTg3NTAwMDAsXG4gICAgICAgIHR4aWQ6ICc3ZDI4Mjg3OGE4NWRhZWU1ZDQ2ZTA0MzgyN2RhZWQ1NzU5NmQ3NWQxYWE2ZTA0ZmQwYzA5YTM2ZjkxMzA4ODFmJyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzE2MTcsXG4gICAgICB9O1xuICAgICAgXy5leHRlbmQodW5zcGVudCwgc2Vnd2l0QWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBzZWd3aXRBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gc2Vnd2l0IHRlc3QnOiAxMDAwIH0sXG4gICAgICAgIHVzZVBzYnQ6IGZhbHNlLFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDExZjg4MzA5MTZmYTMwOTBjZmQwNDZlYWFkMTc1NmQ1OTU3ZWRkYTI3MzgwNDZlZDRlNWFlNWRhODc4MjgyODdkMDAwMDAwMDAwMGZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTM2YTExNDI2OTc0NDc2ZjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDBlMGYxZTAxMDAwMDAwMDAxN2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDExZjg4MzA5MTZmYTMwOTBjZmQwNDZlYWFkMTc1NmQ1OTU3ZWRkYTI3MzgwNDZlZDRlNWFlNWRhODc4MjgyODdkMDAwMDAwMDAyMzIyMDAyMDQ0MGU4NTgyMjhiNzUzNTQ0YjRjNTdlMzAwMjk2YjU1NzE3ZjgxMTA1Mzg4M2Y5YmU5YjZhNzEyZWFjZDkzMWNmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDEzNmExMTQyNjk3NDQ3NmYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQwZTBmMWUwMTAwMDAwMDAwMTdhOTE0MzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YTg3MDUwMDQ4MzA0NTAyMjEwMGJmM2E4OTE0YTFiZmU5MjY2MWYyN2NhMzdjMGQ2YjVjMGIzYzczNTM2MTRjOTU1NjQ2OTI5ZjJlN2ViODlmZmUwMjIwMmQ1NTZiMGZmYWIzN2MxMDRiYWU2NzQwNmNhMTZmODg1OWNmYTM3YzZhNDBmMjAxM2Q4OWFmY2VjZDU1OTRmMzAxMDAwMDY5NTIyMTAzMmM1MDVmYzhhMWU0YjU2ODExYjI3MzY2YTM3MWU2MWM5ZmFmNTY1ZGQyZmFiYWZmN2E3MGVhYzE5YzMyMTU3YzIxMDI1MTE2MGI1ODNiZDVkYzBmMGQ0ODA5NjUwNTEzMWM0MzQ3YWI2NWI0ZjIxZWQ1N2Q3NmMzODE1NzQ5OWMwMDNkMjEwMjY3OTcxMmQ2MmEyNTYwOTE3Y2M0M2ZkMmNjM2ExYjliNjFmNTI4Yzg4YmM2NDkwNWJhZTZlZTA3OWU2MDYwOWY1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgc2Vjb25kIHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXggPSBzaWduYXR1cmUxLnR4O1xuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSBiYWNrdXBLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZnVsbExvY2FsU2lnbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUyID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIC8vIHRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9kNjcyNjZmMWRlOTA1YmFhZWU3NTAwMTFmYTRiM2Q4OGE4ZTNhMTc1OGQ1MTczYTY1OWM2NzcwOTQ4OGRkZTA3XG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAxMWY4ODMwOTE2ZmEzMDkwY2ZkMDQ2ZWFhZDE3NTZkNTk1N2VkZGEyNzM4MDQ2ZWQ0ZTVhZTVkYTg3ODI4Mjg3ZDAwMDAwMDAwMjMyMjAwMjA0NDBlODU4MjI4Yjc1MzU0NGI0YzU3ZTMwMDI5NmI1NTcxN2Y4MTEwNTM4ODNmOWJlOWI2YTcxMmVhY2Q5MzFjZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMzZhMTE0MjY5NzQ0NzZmMjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0MGUwZjFlMDEwMDAwMDAwMDE3YTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NzA1MDA0ODMwNDUwMjIxMDBiZjNhODkxNGExYmZlOTI2NjFmMjdjYTM3YzBkNmI1YzBiM2M3MzUzNjE0Yzk1NTY0NjkyOWYyZTdlYjg5ZmZlMDIyMDJkNTU2YjBmZmFiMzdjMTA0YmFlNjc0MDZjYTE2Zjg4NTljZmEzN2M2YTQwZjIwMTNkODlhZmNlY2Q1NTk0ZjMwMTQ3MzA0NDAyMjA1Y2Y4ZDJmMmJlNmNlMDgzZDM1NjU0YmRjM2ZhODVkN2U3MWIyMjdkNDU3ZTkyNDViYjYwM2IyMWU3YjUxNjUxMDIyMDNlYTY4NjIyNmRiODMyMGUwOGMyNmJmYjMwNDA0OGIzYTk0NzNkMGUwNTc5N2QzNjU4ZGFjYjJmMDlhMmI1MWMwMTAwNjk1MjIxMDMyYzUwNWZjOGExZTRiNTY4MTFiMjczNjZhMzcxZTYxYzlmYWY1NjVkZDJmYWJhZmY3YTcwZWFjMTljMzIxNTdjMjEwMjUxMTYwYjU4M2JkNWRjMGYwZDQ4MDk2NTA1MTMxYzQzNDdhYjY1YjRmMjFlZDU3ZDc2YzM4MTU3NDk5YzAwM2QyMTAyNjc5NzEyZDYyYTI1NjA5MTdjYzQzZmQyY2MzYTFiOWI2MWY1MjhjODhiYzY0OTA1YmFlNmVlMDc5ZTYwNjA5ZjUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhbiB1bnNpZ25lZCB0eCBtYWRlIG9mIHVuY29tcHJlc3NlZCBwdWJsaWMga2V5cyBvZiB2MSBzYWZlIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHsgYWRkcmVzcywgcmVkZWVtU2NyaXB0LCBzY3JpcHRQdWJLZXkgfSA9IGF3YWl0IGdldEZpeHR1cmU8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxuICAgICAgICBgJHtfX2Rpcm5hbWV9L2ZpeHR1cmVzL3NpZ24tdHJhbnNhY3Rpb24uanNvbmBcbiAgICAgICk7XG4gICAgICBjb25zdCB0ZXN0Qml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgICAgIGNvbnN0IGZha2VUZXN0VjFTYWZlV2FsbGV0ID0gbmV3IFdhbGxldCh0ZXN0Qml0Z28sIHtcbiAgICAgICAgaWQ6IGFkZHJlc3MsXG4gICAgICAgIHByaXZhdGU6IHsgc2FmZTogeyByZWRlZW1TY3JpcHQgfSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1bnNwZW50c1RvU3BlbmQgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogMTAwMDAwLFxuICAgICAgICAgIHJlZGVlbVNjcmlwdCxcbiAgICAgICAgICBzY3JpcHQ6IHNjcmlwdFB1YktleSxcbiAgICAgICAgICB0eF9oYXNoOiAnYTU1ZDExZGM4YjcwMWJkMTk2MDFmYmZlNzExYTFlNDY1ZmM4ZjEyOGVjNDQ3NGU3OGUxZmQwODdlODA4ZTVmZScsXG4gICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgY29uZmlybWF0aW9uczogMSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxMDAwMDAsXG4gICAgICAgICAgcmVkZWVtU2NyaXB0LFxuICAgICAgICAgIHNjcmlwdDogc2NyaXB0UHViS2V5LFxuICAgICAgICAgIHR4X2hhc2g6ICc0OGZiODc5Y2VjODc5MzU2MDQ1YTMzMTkzNzAyM2FlZDg1OWY1ZGM1ZGI5NTVhMWRjOGE1Y2NmMjlmNDlkMTA4JyxcbiAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICBjb25maXJtYXRpb25zOiAxLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSB7XG4gICAgICAgICcyTXlHeHJoTEM0a1JmdVZqTHFDVllGdEM3RGNoaGdNQ2lOeic6IDE5MTM0MCwgLy8gcHVycG9zZWx5IHNldCB0byBzaW11bGF0ZSBhIHN3ZWVwIHRyYW5zYWN0aW9uXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmxUZXN0KVxuICAgICAgICAucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGFkZHJlc3M6ICcyTjNMOWN1OVdOMkRmN1h2YjFZOG93b2t1RFZqNUhkeXY0aScgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZha2VUZXN0VjFTYWZlV2FsbGV0LmNyZWF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgdW5zcGVudHM6IHVuc3BlbnRzVG9TcGVuZCxcbiAgICAgICAgZmVlUmF0ZTogMTAwMDAsIC8vIDEwIHNhdC9ieXRlXG4gICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgIGFkZHJlc3M6ICcnLFxuICAgICAgICB9LFxuICAgICAgICB1c2VQc2J0OiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICByZXN1bHQuZXN0aW1hdGVkU2l6ZS5zaG91bGQuZXF1YWwoODY2KTtcbiAgICAgIHJlc3VsdC5mZWUuc2hvdWxkLmVxdWFsKDg2NjApO1xuICAgICAgLy8gVGhpcyBzaG91bGQgZXF1YWwgdG8gMSBiZWNhdXNlIHRoaXMgaXMgYSBzd2VlcCB0cmFuc2FjdGlvbiBidXQgZHVlIHRvIGhhcmRjb2RlZCBhZGRpdGlvbiBvZlxuICAgICAgLy8gMSBjaGFuZ2Ugb3V0cHV0IGluIHRyYW5zYWN0aW9uQnVpbGRlciwgaXQgaXMgMi5cbiAgICAgIC8vIEJlY2F1c2Ugb2YgdGhpcyB0aGUgZXN0aW1hdGVkIHNpemUgb2YgdGhlIHRyYW5zYWN0aW9ucyBpcyBtb3JlIHRoYW4gd2hhdCBpdCBhY3R1YWxseSBpcyBpbiB0aGUgaGV4LlxuICAgICAgcmVzdWx0LnR4SW5mby5uT3V0cHV0cy5zaG91bGQuZXF1YWwoMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnbnMgYW4gdW5zaWduZWQgdHggbWFkZSBvZiB1bmNvbXByZXNzZWQgcHVibGljIGtleXMgb2YgdjEgc2FmZSB3YWxsZXQgJiB2ZXJpZmllcyBzaWduYXR1cmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBhZGRyZXNzLFxuICAgICAgICByZWRlZW1TY3JpcHQsXG4gICAgICAgIHNjcmlwdFB1YktleSxcbiAgICAgICAgdXNlcktleVdJRjogdXNlclNpZ25pbmdLZXksXG4gICAgICAgIGJpdGdvS2V5V0lGOiBiaXRnb1NpZ25pbmdLZXksXG4gICAgICAgIHVuc2lnbmVkVHhIZXgsXG4gICAgICAgIGhhbGZTaWduZWRUeEhleCxcbiAgICAgICAgZnVsbFNpZ25lZFR4SGV4LFxuICAgICAgfSA9IGF3YWl0IGdldEZpeHR1cmU8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KGAke19fZGlybmFtZX0vZml4dHVyZXMvc2lnbi10cmFuc2FjdGlvbi5qc29uYCk7XG4gICAgICBjb25zdCB0ZXN0Qml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgICAgIGNvbnN0IGZha2VUZXN0VjFTYWZlV2FsbGV0ID0gbmV3IFdhbGxldCh0ZXN0Qml0Z28sIHtcbiAgICAgICAgaWQ6IGFkZHJlc3MsXG4gICAgICAgIHByaXZhdGU6IHsgc2FmZTogeyByZWRlZW1TY3JpcHQgfSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1bnNwZW50c1RvU3BlbmQgPSBbXG4gICAgICAgIHsgdmFsdWU6IDEwMDAwMCwgcmVkZWVtU2NyaXB0LCBzY3JpcHQ6IHNjcmlwdFB1YktleSB9LFxuICAgICAgICB7IHZhbHVlOiAxMDAwMDAsIHJlZGVlbVNjcmlwdCwgc2NyaXB0OiBzY3JpcHRQdWJLZXkgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHggPSBhd2FpdCBmYWtlVGVzdFYxU2FmZVdhbGxldC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0cmFuc2FjdGlvbkhleDogdW5zaWduZWRUeEhleCxcbiAgICAgICAgc2lnbmluZ0tleTogdXNlclNpZ25pbmdLZXksXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50c1RvU3BlbmQsXG4gICAgICAgIHZhbGlkYXRlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBoYWxmU2lnbmVkVHgudHguc2hvdWxkLmVxdWFsKGhhbGZTaWduZWRUeEhleCk7XG5cbiAgICAgIGNvbnN0IGZ1bGxTaWduZWRUeCA9IGF3YWl0IGZha2VUZXN0VjFTYWZlV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHRyYW5zYWN0aW9uSGV4OiBoYWxmU2lnbmVkVHhIZXgsXG4gICAgICAgIHNpZ25pbmdLZXk6IGJpdGdvU2lnbmluZ0tleSxcbiAgICAgICAgdW5zcGVudHM6IHVuc3BlbnRzVG9TcGVuZCxcbiAgICAgICAgdmFsaWRhdGU6IHRydWUsXG4gICAgICAgIGZ1bGxMb2NhbFNpZ25pbmc6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIC8vIFVwb24gY2FsbGluZyB0eGIuYnVpbGQoKSBpbnN0ZWFkIGFmdGVyIGdldHRpbmcgMiB2YWxpZCBzaWduYXR1cmVzLCB3ZSBnZXQgYSB2YWxpZCBmdWxsIHNpZ25lZCB0eCB0aGF0IHdhcyBicm9hZGNhc3RcbiAgICAgIC8vIGFuZCBjb25maXJtZWQgb24gdGVzdG5ldCBoZXJlOiBodHRwczovL21lbXBvb2wuc3BhY2UvdGVzdG5ldC90eC9iZGUwOWYxYmQ1ZTY2NjFjMjhkOTBlNGM5NjI5MTg1M2UyMWJhMTVhYjQyZjNlNGEzMDcxOWRlY2I3M2U3OTFiXG4gICAgICAvLyBJdCdzIHByZXNlbnQgaW4gdGhlIGZ1bGxTaWduZWRUeEhleEJ1aWxkQ29tcGxldGUgcHJvcGVydHkgb2YgdGhlIGZpeHR1cmUuXG4gICAgICBmdWxsU2lnbmVkVHgudHguc2hvdWxkLmVxdWFsKGZ1bGxTaWduZWRUeEhleCk7XG4gICAgfSk7XG5cbiAgICBpdCgnQkNIIHNlZ3dpdCBzaG91bGQgZmFpbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlUHJvZFdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzEzJywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgdW5zcGVudDogYW55ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk14S2tIOHlCM1M5WVdtVFFSYnZtYm9yWVF5UW5INXBldFAnXSxcbiAgICAgICAgdmFsdWU6ICcwLjE4NzUwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxODc1MDAwMCxcbiAgICAgICAgdHhpZDogJzdkMjgyODc4YTg1ZGFlZTVkNDZlMDQzODI3ZGFlZDU3NTk2ZDc1ZDFhYTZlMDRmZDBjMDlhMzZmOTEzMDg4MWYnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgMzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTYxNyxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBzZWd3aXRBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHNlZ3dpdEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBzZWd3aXQgdGVzdCc6IDEwMDAgfSxcbiAgICAgICAgdXNlUHNidDogZmFsc2UsXG4gICAgICB9KSkgYXMgYW55O1xuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTFmODgzMDkxNmZhMzA5MGNmZDA0NmVhYWQxNzU2ZDU5NTdlZGRhMjczODA0NmVkNGU1YWU1ZGE4NzgyODI4N2QwMDAwMDAwMDAwZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMzZhMTE0MjY5NzQ0NzZmMjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0MGUwZjFlMDEwMDAwMDAwMDE3YTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZvcmNlQkNIID0gdHJ1ZTtcbiAgICAgICgoKSA9PiBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKS5zaG91bGQudGhyb3coJ0JDSCBkb2VzIG5vdCBzdXBwb3J0IHNlZ3dpdCBpbnB1dHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdtaXhlZCBwMnNoICYgc2Vnd2l0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xNCcsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzE0Jywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgcDJzaFVuc3BlbnQgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTjUzM2ZxZ3lQWUtWRDg5Mm5CUmFZbUZIYmJUeWtoWVNFdyddLFxuICAgICAgICB2YWx1ZTogJzIuOTk5OTY2MTAnLFxuICAgICAgICB2YWx1ZV9pbnQ6IDI5OTk5NjYxMCxcbiAgICAgICAgdHhpZDogJ2Y2NTRjZTBhNWJlM2YxMmRmN2ZlY2Y0ZWU3NzdiNmQ4NmI1YWE4YzcxMGVmNjk0NmVjMTIxMjA2YjRmODc1N2MnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1MiBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTI2MyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZWd3aXRVbnNwZW50ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk5CdHBYY0RydWYzelJ1dG1GNEFiQ01GTlFIWHNHTlA2a1QnXSxcbiAgICAgICAgdmFsdWU6ICcxLjUwMDAwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxNTAwMDAwMDAsXG4gICAgICAgIHR4aWQ6ICdhNDQwOWMzZjA0MmZhZTY3Yjg5MGFjM2RmNDBlZjBkYjAzNTM5YzY3MzMxZmQ3ZTkyNjA1MTE4OTNiNGY5ZjI0JyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIGNjOGU3Y2JmNDgxMzg5ZDMxODNhNTkwYWNmYTZhYTY2ZWI5N2M4ZTEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTRjYzhlN2NiZjQ4MTM4OWQzMTgzYTU5MGFjZmE2YWE2NmViOTdjOGUxODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzA4ODIsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWRkcmVzc2VzID0gW3Ayc2hBZGRyZXNzLCBzZWd3aXRBZGRyZXNzXTtcbiAgICAgIGNvbnN0IHVuc3BlbnRzID0gW3Ayc2hVbnNwZW50LCBzZWd3aXRVbnNwZW50XS5tYXAoKHVuc3BlbnQ6IGFueSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IGFkZHJlc3Nlc1tpbmRleF07XG4gICAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIGFkZHJlc3MpO1xuICAgICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgICAgdW5zcGVudC50eF9vdXRwdXRfbiA9IHVuc3BlbnQubjtcbiAgICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcbiAgICAgICAgcmV0dXJuIHVuc3BlbnQ7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50cyxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBvcFJldHVybnM6IHsgJ0JpdEdvIG1peGVkIHAyc2ggJiBzZWd3aXQgdGVzdCc6IDQwMDAwMDAwMCB9LFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogODE3NjAsXG4gICAgICAgICAgYWRkcmVzczogJzJORDdqUVI1aXRqR1RiaDNES2dicFpXU1k5dW5nRHJ3Y3diJyxcbiAgICAgICAgfSxcbiAgICAgICAgdXNlUHNidDogZmFsc2UsXG4gICAgICB9KSkgYXMgYW55O1xuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMjdjNzVmOGI0MDYxMjEyZWM0NjY5ZWYxMGM3YTg1YTZiZDhiNjc3ZTc0ZWNmZmVmNzJkZjFlMzViMGFjZTU0ZjYwMTAwMDAwMDAwZmZmZmZmZmYyNDlmNGYzYjg5MTEwNTI2ZTlkNzFmMzM2NzljNTMwM2RiZjAwZWY0M2RhYzkwYjg2N2FlMmYwNDNmOWM0MGE0MDAwMDAwMDAwMGZmZmZmZmZmMDMwMDg0ZDcxNzAwMDAwMDAwMjA2YTFlNDI2OTc0NDc2ZjIwNmQ2OTc4NjU2NDIwNzAzMjczNjgyMDI2MjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0YjA4ZmY5MDIwMDAwMDAwMDE3YTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NzYwM2YwMTAwMDAwMDAwMDAxN2E5MTRkOWY3YmU0Nzk3NWMwMzZmOTQyMjhiMGJmZDcwNzAxOTEyNzU4YmE5ODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDBiNzAwNDgzMDQ1MDIyMTAwZmZjNDVkOTNjYmFmNGMxYzg1MGUyMWYyNzdjNWIzMTFkM2UzOTU3ZjEzMzg5NTVjYjE2NWQ3MmE3NjhhMDU0YzAyMjA1MjAyMDU5M2IzNjc4MWVlYTAwYTlmOGRjYmViNzY2MDhmOTIwYzdhOTMzYTkwODgzMThhYjJmNzBjMTFlMWQ5MDEwMDAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwMzAwODRkNzE3MDAwMDAwMDAyMDZhMWU0MjY5NzQ0NzZmMjA2ZDY5Nzg2NTY0MjA3MDMyNzM2ODIwMjYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzRiMDhmZjkwMjAwMDAwMDAwMTdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3NjAzZjAxMDAwMDAwMDAwMDE3YTkxNGQ5ZjdiZTQ3OTc1YzAzNmY5NDIyOGIwYmZkNzA3MDE5MTI3NThiYTk4NzAwMDUwMDQ3MzA0NDAyMjA1ODk4YmVlNzExNDY3YzA5YTVlMjJlMWRjYjFhMTFmY2UxYTBkNmVhMTI5ZDkxMWY4MTNmODdjN2Q0NWUwNjdiMDIyMDJmNjlmYjExOGJiZjBiMDcyZWQyNmQ3MmNmODA3M2U3YWNkNjZjMjA1NDE5YTRhMDBmODZhN2JhMGY2ZTNkZDYwMTAwMDA2OTUyMjEwMzA3ODAxODZjMGJlNWRmMGQyZDYyY2Y1NGNjMmYzZDJjMDk5MTFlMzc3YWE5NWI1ZmU4NzVmYTM1MmFlZDBhNTkyMTAzZjMyMzdlZGQyZDg3MDEwZThmZTlmNDNmMzRlOGM2M2RlNjM4NDI4M2RlOTA5Nzk1ZDYyYWY0ZGRiNGQ1Nzk1NDIxMDJhZDAzZGU1NTA0ZWY5NDdlNGU2ZWUyZmE2YjE1ZDE1MGQ1NTNjMjEyNzVmNDlmMmNlMjM1OWQ5ZmRlZGI5YWRlNTNhZTAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIHNlY29uZCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4ID0gc2lnbmF0dXJlMS50eDtcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gYmFja3VwS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZ1bGxMb2NhbFNpZ25pbmcgPSB0cnVlO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICAvLyB0aGlzIHRyYW5zYWN0aW9uIGhhcyBhY3R1YWxseSB3b3JrZWQ6IGh0dHBzOi8vdGVzdG5ldC5zbWFydGJpdC5jb20uYXUvdHgvZTJmNjk2YmNiYTkxYTM3NmMzNmJiNTI1ZGY4YzM2NzkzOGY2ZTJmZDYzNDRjOTA1ODdiZjEyODAyMDkxMTI0Y1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZSB0eCBoZXggYmVsb3cgbm8gbG9uZ2VyIGNvcnJlc3BvbmRzIHRvIHRoZSBhYm92ZSB0cmFuc2FjdGlvbiBiZWNhdXNlIG91ciBmZWUgZXN0aW1hdGlvbiBoYXNcbiAgICAgIC8vIGNoYW5nZWQsIGNoYW5naW5nIHRoZSBvdXRwdXQgYW1vdW50cyBhbmQgdGh1cyB0aGUgdHggaGV4LlxuICAgICAgc2lnbmF0dXJlMi50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAwMDEwMjdjNzVmOGI0MDYxMjEyZWM0NjY5ZWYxMGM3YTg1YTZiZDhiNjc3ZTc0ZWNmZmVmNzJkZjFlMzViMGFjZTU0ZjYwMTAwMDAwMGZkZmYwMDAwNDgzMDQ1MDIyMTAwZmZjNDVkOTNjYmFmNGMxYzg1MGUyMWYyNzdjNWIzMTFkM2UzOTU3ZjEzMzg5NTVjYjE2NWQ3MmE3NjhhMDU0YzAyMjA1MjAyMDU5M2IzNjc4MWVlYTAwYTlmOGRjYmViNzY2MDhmOTIwYzdhOTMzYTkwODgzMThhYjJmNzBjMTFlMWQ5MDE0ODMwNDUwMjIxMDA4MjU0ZDEwMDQwMWEzYTgzMWVkMDE5ZTE2NjJkYmQ5MGI5NmM2YzQwNzJiODFjZTY0MGQxNTJiYzI5Mjk1YzEwMDIyMDEzZjg2YzVhZjU3MTYyMzQ5OTlhN2JkNmU5NGZjOGY0MjhmNzY5N2NjMzEzOGIzNjQ5ZDBlYzRkZDg2ODFiYzcwMTAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwMzAwODRkNzE3MDAwMDAwMDAyMDZhMWU0MjY5NzQ0NzZmMjA2ZDY5Nzg2NTY0MjA3MDMyNzM2ODIwMjYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzRiMDhmZjkwMjAwMDAwMDAwMTdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3NjAzZjAxMDAwMDAwMDAwMDE3YTkxNGQ5ZjdiZTQ3OTc1YzAzNmY5NDIyOGIwYmZkNzA3MDE5MTI3NThiYTk4NzAwMDUwMDQ3MzA0NDAyMjA1ODk4YmVlNzExNDY3YzA5YTVlMjJlMWRjYjFhMTFmY2UxYTBkNmVhMTI5ZDkxMWY4MTNmODdjN2Q0NWUwNjdiMDIyMDJmNjlmYjExOGJiZjBiMDcyZWQyNmQ3MmNmODA3M2U3YWNkNjZjMjA1NDE5YTRhMDBmODZhN2JhMGY2ZTNkZDYwMTQ3MzA0NDAyMjA3NzEzZDY3MWI0NTk4OTY4OGUyNjY1YzJiMTFhYjdlNWVhOGQ1N2ViMTRmOWRhMjMzYzA5NWRhYmU0NDEzMDhkMDIyMDY5NTIxYjVhZWIwNzFiMDdhNzBhNzE5N2EwYzJiYmM0MGEyM2FlNjNhMDQxNjBjZjM2MjcyNTBjNGJhNGM0MGYwMTAwNjk1MjIxMDMwNzgwMTg2YzBiZTVkZjBkMmQ2MmNmNTRjYzJmM2QyYzA5OTExZTM3N2FhOTViNWZlODc1ZmEzNTJhZWQwYTU5MjEwM2YzMjM3ZWRkMmQ4NzAxMGU4ZmU5ZjQzZjM0ZThjNjNkZTYzODQyODNkZTkwOTc5NWQ2MmFmNGRkYjRkNTc5NTQyMTAyYWQwM2RlNTUwNGVmOTQ3ZTRlNmVlMmZhNmIxNWQxNTBkNTUzYzIxMjc1ZjQ5ZjJjZTIzNTlkOWZkZWRiOWFkZTUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNlbmQgdG8gYmVjaDMyIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzAvMTQnLCBzZWd3aXQ6IGZhbHNlIH0pO1xuICAgICAgY29uc3Qgc2Vnd2l0QWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8xNCcsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IHAyc2hVbnNwZW50ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk41MzNmcWd5UFlLVkQ4OTJuQlJhWW1GSGJiVHlraFlTRXcnXSxcbiAgICAgICAgdmFsdWU6ICcyLjk5OTk2NjEwJyxcbiAgICAgICAgdmFsdWVfaW50OiAyOTk5OTY2MTAsXG4gICAgICAgIHR4aWQ6ICdmNjU0Y2UwYTViZTNmMTJkZjdmZWNmNGVlNzc3YjZkODZiNWFhOGM3MTBlZjY5NDZlYzEyMTIwNmI0Zjg3NTdjJyxcbiAgICAgICAgbjogMSxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTIgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzEyNjMsXG4gICAgICB9O1xuICAgICAgY29uc3Qgc2Vnd2l0VW5zcGVudCA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJOQnRwWGNEcnVmM3pSdXRtRjRBYkNNRk5RSFhzR05QNmtUJ10sXG4gICAgICAgIHZhbHVlOiAnMS41MDAwMDAwMCcsXG4gICAgICAgIHZhbHVlX2ludDogMTUwMDAwMDAwLFxuICAgICAgICB0eGlkOiAnYTQ0MDljM2YwNDJmYWU2N2I4OTBhYzNkZjQwZWYwZGIwMzUzOWM2NzMzMWZkN2U5MjYwNTExODkzYjRmOWYyNCcsXG4gICAgICAgIG46IDAsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCBjYzhlN2NiZjQ4MTM4OWQzMTgzYTU5MGFjZmE2YWE2NmViOTdjOGUxIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0Y2M4ZTdjYmY0ODEzODlkMzE4M2E1OTBhY2ZhNmFhNjZlYjk3YzhlMTg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgaWQ6IDYxMzMwODgyLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGFkZHJlc3NlcyA9IFtwMnNoQWRkcmVzcywgc2Vnd2l0QWRkcmVzc107XG4gICAgICBjb25zdCB1bnNwZW50cyA9IFtwMnNoVW5zcGVudCwgc2Vnd2l0VW5zcGVudF0ubWFwKCh1bnNwZW50OiBhbnksIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSBhZGRyZXNzZXNbaW5kZXhdO1xuICAgICAgICBfLmV4dGVuZCh1bnNwZW50LCBhZGRyZXNzKTtcbiAgICAgICAgdW5zcGVudC52YWx1ZSA9IHVuc3BlbnQudmFsdWVfaW50O1xuICAgICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICAgIHVuc3BlbnQuc2NyaXB0ID0gdW5zcGVudC5vdXRwdXRTY3JpcHQ7XG4gICAgICAgIHJldHVybiB1bnNwZW50O1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gKGF3YWl0IGZha2VXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBwMnNoQWRkcmVzcy5hZGRyZXNzLFxuICAgICAgICB1bnNwZW50czogdW5zcGVudHMsXG4gICAgICAgIHJlY2lwaWVudHM6IHsgdGIxcWd1enlrNHc2a2FxdHBzY3pzNWFqMHc4cjc1OThqcTM2ZWdtOGU5OHdxcGgzcndtZXg2OHNlc2xnc2c6IDMwMDAwMCB9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBtaXhlZCBwMnNoICYgc2Vnd2l0IHRlc3QnOiA0MDAwMDAwMDAgfSxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDgxNzYwLFxuICAgICAgICAgIGFkZHJlc3M6ICcyTkQ3alFSNWl0akdUYmgzREtnYnBaV1NZOXVuZ0Ryd2N3YicsXG4gICAgICAgIH0sXG4gICAgICAgIHVzZVBzYnQ6IGZhbHNlLFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDAwMGZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMDBmZmZmZmZmZjA0ZTA5MzA0MDAwMDAwMDAwMDIyMDAyMDQ3MDQ0YjU1ZGFiNzQwYjBjMzAyODUzYjI3YjhlM2Y1MGE3OTAyM2FjYTM2N2M5NGVlMDA2ZjExYmI3OTM2OGYwMDg0ZDcxNzAwMDAwMDAwMjA2YTFlNDI2OTc0NDc2ZjIwNmQ2OTc4NjU2NDIwNzAzMjczNjgyMDI2MjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0N2NmYWY0MDIwMDAwMDAwMDE3YTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NzYwM2YwMTAwMDAwMDAwMDAxN2E5MTRkOWY3YmU0Nzk3NWMwMzZmOTQyMjhiMGJmZDcwNzAxOTEyNzU4YmE5ODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDBiNzAwNDgzMDQ1MDIyMTAwODgwOTM3NzYzNGU2NjdkNmUxOWYzOGExMzhhNTViMmI2MzcwMzEyYWY3NmE1Y2EzYjc3NmRmNjFmYzcxOTYxNzAyMjAyMWQ5MDM0N2I5MDg1YWI3MWE3NmM4NDAwZjk4NGUzMjJjMTU0NTFlY2M2NzNkZDM3ZGUzMDg4NzQzNmQzN2I0MDEwMDAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwNGUwOTMwNDAwMDAwMDAwMDAyMjAwMjA0NzA0NGI1NWRhYjc0MGIwYzMwMjg1M2IyN2I4ZTNmNTBhNzkwMjNhY2EzNjdjOTRlZTAwNmYxMWJiNzkzNjhmMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDdjZmFmNDAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDgzMDQ1MDIyMTAwOGI5NWFjODNlNDRjNzI3Yjc5ZmZiZjQ1NzExNzE5MjVkMDZmODgzYTA1YzEyMmIzYjMzYzA1NWYwYmZmYTcwMTAyMjA3YjVlZTM0MTJlYThhNWNlYzRhNWMzODZmMWI0NjRhYjY4ZDUzMWM2YzY5NzA3N2JjNDYyYzA1ZWI0NGEyODMyMDEwMDAwNjk1MjIxMDMwNzgwMTg2YzBiZTVkZjBkMmQ2MmNmNTRjYzJmM2QyYzA5OTExZTM3N2FhOTViNWZlODc1ZmEzNTJhZWQwYTU5MjEwM2YzMjM3ZWRkMmQ4NzAxMGU4ZmU5ZjQzZjM0ZThjNjNkZTYzODQyODNkZTkwOTc5NWQ2MmFmNGRkYjRkNTc5NTQyMTAyYWQwM2RlNTUwNGVmOTQ3ZTRlNmVlMmZhNmIxNWQxNTBkNTUzYzIxMjc1ZjQ5ZjJjZTIzNTlkOWZkZWRiOWFkZTUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgY29uc29sZS5sb2coJ3NpZ25hdHVyZTEgJyArIEpTT04uc3RyaW5naWZ5KHNpZ25hdHVyZTIpKTtcbiAgICAgIC8vIHRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9lMmY2OTZiY2JhOTFhMzc2YzM2YmI1MjVkZjhjMzY3OTM4ZjZlMmZkNjM0NGM5MDU4N2JmMTI4MDIwOTExMjRjXG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwZmRmZTAwMDA0ODMwNDUwMjIxMDA4ODA5Mzc3NjM0ZTY2N2Q2ZTE5ZjM4YTEzOGE1NWIyYjYzNzAzMTJhZjc2YTVjYTNiNzc2ZGY2MWZjNzE5NjE3MDIyMDIxZDkwMzQ3YjkwODVhYjcxYTc2Yzg0MDBmOTg0ZTMyMmMxNTQ1MWVjYzY3M2RkMzdkZTMwODg3NDM2ZDM3YjQwMTQ3MzA0NDAyMjA1YTU4ZTYwMjA0MmI4ZThhNWRhNTA5ZDE5Y2UzMTA1MDE0N2RkMGZmY2ZiZTJiYjMzN2MyM2Q0Yzg4ZjRjYzQxMDIyMDc1YmZhNDU1ZDFmNzRlMzBmYmQ5Yzc4NmNkNDgxMWExZGVmZTU0MzEwZjIzNWI0MTkzY2U0ZmZhMGU4MzA5YTEwMTAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwNGUwOTMwNDAwMDAwMDAwMDAyMjAwMjA0NzA0NGI1NWRhYjc0MGIwYzMwMjg1M2IyN2I4ZTNmNTBhNzkwMjNhY2EzNjdjOTRlZTAwNmYxMWJiNzkzNjhmMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDdjZmFmNDAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDgzMDQ1MDIyMTAwOGI5NWFjODNlNDRjNzI3Yjc5ZmZiZjQ1NzExNzE5MjVkMDZmODgzYTA1YzEyMmIzYjMzYzA1NWYwYmZmYTcwMTAyMjA3YjVlZTM0MTJlYThhNWNlYzRhNWMzODZmMWI0NjRhYjY4ZDUzMWM2YzY5NzA3N2JjNDYyYzA1ZWI0NGEyODMyMDE0NzMwNDQwMjIwNTM2OTAyMzQ1ODJhNjkxMWEyOGNhZTlmNTM0Yzk4MGI3ZDc5MTg3NDlhNzQxM2MxYzU5MzI3ZGViZjE2ZmYwYjAyMjA1NjE3NWY1YzI3YTM2MzQxNmIyY2U0NzkxYWVmYzNkNTU1NDVjYWNiZDA1MjcyMDJlODY5ZTExMjdmYzJmMjRkMDEwMDY5NTIyMTAzMDc4MDE4NmMwYmU1ZGYwZDJkNjJjZjU0Y2MyZjNkMmMwOTkxMWUzNzdhYTk1YjVmZTg3NWZhMzUyYWVkMGE1OTIxMDNmMzIzN2VkZDJkODcwMTBlOGZlOWY0M2YzNGU4YzYzZGU2Mzg0MjgzZGU5MDk3OTVkNjJhZjRkZGI0ZDU3OTU0MjEwMmFkMDNkZTU1MDRlZjk0N2U0ZTZlZTJmYTZiMTVkMTUwZDU1M2MyMTI3NWY0OWYyY2UyMzU5ZDlmZGVkYjlhZGU1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2VuZCBNYW55JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXNwb25kcyB3aXRoIHByb3BlciBmZWUgYW5kIGZlZSByYXRlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJNdXRwWFZZczhMeWs3NHBWRG4zZUFHN3huSzRXYzJralRRJyxcbiAgICAgICAgICAgIGFtb3VudDogMzAwMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdW5zcGVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogODE3MCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiA4MDAwMDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgY3JlYXRlQW5kU2lnblJlc3BvbnNlID0ge1xuICAgICAgICBiaXRnb0ZlZTogMCxcbiAgICAgICAgdHJhdmVsSW5mb3M6IFtdLFxuICAgICAgICB1bnNwZW50cyxcbiAgICAgICAgdHg6ICdoYWxmc2lnbmVkaGV4JyxcbiAgICAgIH07XG4gICAgICBzaW5vbi5zdHViKGZha2VXYWxsZXQsICdjcmVhdGVBbmRTaWduVHJhbnNhY3Rpb24nKS5yZXR1cm5zKFByb21pc2UucmVzb2x2ZShjcmVhdGVBbmRTaWduUmVzcG9uc2UpKTtcbiAgICAgIGNvbnN0IGdldFNlbmRUeFJlc3BvbnNlID0gKCkgPT4gKHtcbiAgICAgICAgc3RhdHVzOiAnYWNjZXB0ZWQnLFxuICAgICAgICB0eDogJzAxMDAwMDAwMDAwMTAyMjhiNWMzZTI3ODlkNDc3MGZjMzk3ZWM3OWZhNzI1NWY4NjIzNTI5N2M1YTA0ZGVmNjc4YjQ4MWI4YjA5ZTgxYjAxMDAwMDAwMjMyMjAwMjBiM2JiZTA2Nzk2MGJlMzk1MDFmMzY1Yjg5OTlkNTNmMmE4Mjg1ZDhkOTgzNmY2MWZhZDAyMGU2YTRhOWUyNmZkZmZmZmZmZmYxNTEwZTkwNDExYTg2YzQ5ZjJhNTI1NDZhMzJhMDNmZWJkZTJiYzYwNDc0MWYwZTg1ZGM0N2FkZWMzM2Y1MTU5MDAwMDAwMDBmZGZkMDAwMDQ4MzA0NTAyMjEwMGE0NGJiZjk3YjE1NWM1NzcwMzg2MmJlNjlkMmIyMGM0YjJhYjllOTRmNDAyNTk1ODgwYmY3NDQwMmNjYzg3ZTIwMjIwMGE0YWFmOThmOTM5YjY1Yzk4Y2EwOGViOTYwNzRjMjIyZWNiMWZjMzdlMzU5YjFkNjdhMDVmMWM1NmRlZGZjMDAxNDczMDQ0MDIyMDAzZjM5ODlhMTQyODRmMTMyYmJiNTUwMTE4YzIwMjU2ZDRlYTczNzcwNDEyM2EyOTk1NWFjYzFkMDNlYTZlYjcwMjIwMTcyMjNkYTdlZGNmNzMwNzZkODk4NzVhYTMzMzYwYWE2YTEyMTQxODA3ZjY4M2M2YzFiOWE1YTBkM2ZmNjAxOTAxNGM2OTUyMjEwMjU3ODk4NTdjYzhiZTExMGZmNGNiZjM1NGI1MmRkMGU3ZTkzMjZjNmJmZTBhZWU2YzMwYzFlZTY5NjYwYzNkYzAyMTAyZjU4ZjFiMTUxNmQwNTgxNGFlNjg4Y2E3MDE4NTY2OTVlMjcwNTBlM2UxNmQzYTIzNTEyODRkN2FmODQ0OTg4ODIxMDIzODVjN2JjZWMzZjM4YzEzZTg3YjU1OGFlYmYyZjIwYTg5MjhlN2VjYmUxMWU3YzNhNDc3OTJiYzhlMzNmZTg4NTNhZWZmZmZmZmZmMDJlMDkzMDQwMDAwMDAwMDAwMTdhOTE0MWQwYzc5MWNlYzNhZjFmMzc4MDhkNDJmMDQ1OTMwOTVkNmZkZWEyNjg3MDViYzA3MDAwMDAwMDAwMDE3YTkxNGQ4YzcyMGY2NDZjN2M1NmM1NDY3MjQ4ZTQ3YzcyZGMwYjJkMzBiYmM4NzA0MDA0NzMwNDQwMjIwMWVhYTEzNTlmZmZkM2JkZWM1YjQ4MjY4YmQyZjE1MTkzYTI5OWMyMmIxOTcwMzU2ZjM5MDg4MzQ3MzMyNDY1MTAyMjA3NDE4NjIzMmYwMjI0NWFmOWMwOTc3MDMxNDQ4YzJjOTllN2I3ZTJiMDViMmJhNGIzMmMzMjI3ZDhjYTE0OTRlMDE0ODMwNDUwMjIxMDBiZDYxYjM3MDUxYzI4NTMzZWEwYjAwZGRhNzViMWM0ZjFkZWUxYjY4M2JiNzM1MWIyZDhkZDcyMGY2ZGZiZTExMDIyMDNhY2M0Y2Y5ZDJkZDQ0YjI5NGFhMjU4MTJlOTllN2Q4ZWIzNzMwZTRmZjZmODg5ZDNjZGNkNTI1MTk1NzUwYjgwMTY5NTIyMTAyMTlkMDkzYzE4YzI3Y2I1NDc3MzdiNGE0OWRkZGFjOWMzNDEyYjEwZTlmODgwZWIzMDA1M2MzZWJhODE5Mjg1NDIxMDM3NDcxMTg4OTJjYWMxYjRkYTExNTI2ZmM0ZWJlZWJlMTY4ZGFlMDkwN2NlZmIxYTE4MTI1NDFjZDQ2YjA3NjAyMjEwMzM5ZjczYjY3NTBmOGY5MWVmZDQ4NGI1YWEyOTc0MzIxYTZjYzI3NzZkNWJkNzhiOWNmYjVmZTE4ZTNiMmQ2NjI1M2FlMDA1YTllMTYwMCcsXG4gICAgICAgIGhhc2g6ICdmOGRmNDNjMmM2NTBiM2JiMTEyNzdhZWU0NTMxZGI5OWE3MTVmYTNiOWRmZDNkNDVhOGQxNzEzNDJjMWJmNzgwJyxcbiAgICAgICAgaW5zdGFudDogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAge1xuICAgICAgICAgIGZlZTogMTI4NSxcbiAgICAgICAgICBmZWVSYXRlOiAyNTE5LjYwNzg0MzEzNzI1NSxcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0U2VuZFR4UmVzcG9uc2UoKVxuICAgICAgKTtcbiAgICAgIHNpbm9uLnN0dWIoZmFrZVdhbGxldCwgJ3NlbmRUcmFuc2FjdGlvbicpLnJlc29sdmVzKGdldFNlbmRUeFJlc3BvbnNlKCkpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IGZha2VXYWxsZXQuc2VuZE1hbnkocGFyYW1zKSkgYXMgYW55O1xuICAgICAgcmVzdWx0LnR4LnNob3VsZC5lcXVhbChleHBlY3RlZFJlc3VsdC50eCk7XG4gICAgICByZXN1bHQuZmVlLnNob3VsZC5lcXVhbChleHBlY3RlZFJlc3VsdC5mZWUpO1xuICAgICAgcmVzdWx0LmZlZVJhdGUuc2hvdWxkLmVxdWFsKGV4cGVjdGVkUmVzdWx0LmZlZVJhdGUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWNjZWxlcmF0ZSBUcmFuc2FjdGlvbiAoc2VydmVyIG1vY2tlZCknLCBmdW5jdGlvbiBhY2NlbGVyYXRlVHhNb2NrZWREZXNjcmliZSgpIHtcbiAgICBsZXQgd2FsbGV0O1xuICAgIGxldCBiZ1VybDtcbiAgICBsZXQgZXhwbG9yZXJVcmw7XG4gICAgbGV0IG1pbkNoYW5nZVNpemU7XG5cbiAgICBsZXQgcGFyZW50VHhJZCA9ICc2YTc0Yjc0ZGY0OTkxZDkzYzMyZDc1MTMzNmM4NWI1ZjJkMWVlNTQ0YTJkZmJhZTJlNWY0YmViNGY5MTRlNWUwJztcbiAgICBjb25zdCBvdXRwdXRJZHggPSAwO1xuICAgIGNvbnN0IG91dHB1dEFkZHJlc3MgPSAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnO1xuICAgIGNvbnN0IHVucmVsYXRlZFR4SWQgPSAnMDhmNWUwYjRhY2I1YWI4MjQ1MjI5ZGZlMTYxY2U0Y2EwZGExZWM5ODNlN2EzNGIwOWU3MmY1Njk3OWE0NjdkZic7XG4gICAgY29uc3Qgd2FsbGV0SWQgPSAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnO1xuXG4gICAgLyoqXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgcGFyZW50IHRyYW5zYWN0aW9uIElEIGZyb20gYSB0cmFuc2FjdGlvbiBpbnB1dFxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBjb252ZXJ0cyBgaGFzaGAgKHdoaWNoIGlzIGEgQnVmZmVyIG9iamVjdCkgdG8gYSB1c2FibGUgdHhpZCBzdHJpbmcuXG4gICAgICogVGhlIGlzc3VlIGlzIHRoYXQgdGhlIGJ5dGVzIGFyZSBzdG9yZWQgaW4gcmV2ZXJzZSBvcmRlciBpbiB0aGUgYnVmZmVyLCBzb1xuICAgICAqIHRoZSBzaW1wbGUgYXBwcm9hY2ggb2YganVzdCBjb21wYXJpbmcgdGhlIGhleCBzdHJpbmdzIGRvZXNuJ3Qgd29yay5cbiAgICAgKiBJbnN0ZWFkLCB0aGUgQnVmZmVyIGlzIGNvcGllZCB0byBhIG5ldyBCdWZmZXIgb2JqZWN0LCB0aGUgbmV3IEJ1ZmZlclxuICAgICAqIG9iamVjdCBpcyByZXZlcnNlZCBpbi1wbGFjZSwgYW5kIHRoZW4gdGhlIG5ldyBCdWZmZXIgaXMgY29udmVydGVkIHRvIGFcbiAgICAgKiBoZXggc3RyaW5nLiBBZnRlciB0aGlzLCB0aGUgcmVzdWx0IGlzIGEgaGV4IHN0cmluZyB3aGljaCBpcyB0aGUgcGFyZW50IHR4aWRcbiAgICAgKlxuICAgICAqIEBwYXJhbSBoYXNoIGEgYml0Y29pbmpzLWxpYiB0cmFuc2FjdGlvbiBvYmplY3QncyBpbnB1dCBoYXNoXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5wdXRQYXJlbnRUeElkKHsgaGFzaCB9KTogc3RyaW5nIHtcbiAgICAgIHJldHVybiAoQnVmZmVyLmZyb20oaGFzaCkucmV2ZXJzZSgpIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cblxuICAgIGJlZm9yZShmdW5jdGlvbiBhY2NlbGVyYXRlVHhNb2NrZWRCZWZvcmUoKSB7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuXG4gICAgICBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ21vY2snLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAgICAgLy8gYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBiaXRnby5zZXRWYWxpZGF0ZShmYWxzZSk7XG4gICAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB7IGlkOiB3YWxsZXRJZCwgcHJpdmF0ZTogeyBrZXljaGFpbnM6IFt1c2VyS2V5cGFpciwgYmFja3VwS2V5cGFpciwgYml0Z29LZXldIH0gfSk7XG4gICAgICAod2FsbGV0IGFzIGFueSkuYml0Z28gPSBiaXRnbztcbiAgICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgZXhwbG9yZXJVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS5idGNFeHBsb3JlckJhc2VVcmw7XG5cbiAgICAgIC8vIHRyeSB0byBnZXQgdGhlIG1pbiBjaGFuZ2Ugc2l6ZSBmcm9tIHRoZSBzZXJ2ZXIsIG90aGVyd2lzZSBkZWZhdWx0IHRvIDAuMSBCVENcbiAgICAgIC8vIFRPRE86IG1pbkNoYW5nZVNpemUgaXMgbm90IGN1cnJlbnRseSBhIGNvbnN0YW50IGRlZmluZWQgb24gdGhlIGNsaWVudCBhbmQgc2hvdWxkIGJlIGFkZGVkXG4gICAgICBtaW5DaGFuZ2VTaXplID0gMWU3O1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoZnVuY3Rpb24gYWNjZWxlcmF0ZVR4TW9ja2VkQWZ0ZXIoKSB7XG4gICAgICAvLyBtYWtlIHN1cmUgYWxsIG5vY2tzIGFyZSBjbGVhcmVkIG9yIGNvbnN1bWVkIGFmdGVyIHRoZSB0ZXN0cyBhcmUgY29tcGxldGVcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYXJndW1lbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGZlZVJhdGU6IDEyMyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eTWlzc2luZyBwYXJhbWV0ZXI6IHRyYW5zYWN0aW9uSUQkLyk7XG5cbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogMTIzLCBmZWVSYXRlOiAxMjMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15FeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdHJhbnNhY3Rpb25JRCBidXQgZm91bmQgbnVtYmVyJC8pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6ICcxMjMnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eTWlzc2luZyBwYXJhbWV0ZXI6IGZlZVJhdGUkLyk7XG5cbiAgICAgIGNvbnN0IGZlZVJhdGVzUGFyYW1zID0gWycxMjMnLCAwLCAtMTAsIC1JbmZpbml0eSwgSW5maW5pdHksIE5hTl07XG4gICAgICBmb3IgKGNvbnN0IGZlZVJhdGUgb2YgZmVlUmF0ZXNQYXJhbXMpIHtcbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6ICcxMjMnLCBmZWVSYXRlIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15FeHBlY3RpbmcgcG9zaXRpdmUgZmluaXRlIG51bWJlciBmb3IgcGFyYW1ldGVyOiBmZWVSYXRlJC8pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2JhZCBpbnB1dCcsIGZ1bmN0aW9uIGJhZElucHV0RGVzY3JpYmUoKSB7XG4gICAgICBhZnRlcigoKSA9PiB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSBhbGwgbm9ja3MgYXJlIGNsZWFyZWQgb3IgY29uc3VtZWQgYWZ0ZXIgdGhlIHRlc3RzIGFyZSBjb21wbGV0ZVxuICAgICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdub24gZXhpc3RlbnQgdHJhbnNhY3Rpb24gSUQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDQwNCwgJ3RyYW5zYWN0aW9uIG5vdCBmb3VuZCBvbiB0aGlzIHdhbGxldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAxMjMgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXjQwNFxcbnRyYW5zYWN0aW9uIG5vdCBmb3VuZCBvbiB0aGlzIHdhbGxldCQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY29uZmlybWVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb25maXJtYXRpb25zOiA2LFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eVHJhbnNhY3Rpb24gWzAtOWEtZl0rIGlzIGFscmVhZHkgY29uZmlybWVkIGFuZCBjYW5ub3QgYmUgYWNjZWxlcmF0ZWQkLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ25vIG91dHB1dHMgdG8gd2FsbGV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDE4OTAwMDAsXG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgICAvXlRyYW5zYWN0aW9uIFswLTlhLWZdKyBjb250YWlucyBubyBvdXRwdXRzIHRvIHRoaXMgd2FsbGV0LCBhbmQgdGh1cyBjYW5ub3QgYmUgYWNjZWxlcmF0ZWQkL1xuICAgICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgLypcbiAgICAgICAqIFRoaXMgdGVzdCBjb3ZlcnMgdGhlIGNhc2Ugd2hlcmUgYSBmYWlsdXJlIG9jY3VycyBkdXJpbmcgdGhlIHByb2Nlc3Mgb2ZcbiAgICAgICAqIGNvbnZlcnRpbmcgYW4gb3V0cHV0IGZyb20gdGhlIHBhcmVudCB0cmFuc2FjdGlvbiBpbnRvIGFuIHVuc3BlbnQgd2hpY2hcbiAgICAgICAqIGNhbiBiZSB1c2VkIHRvIGNoYWluIHRoZSBjaGlsZCB0eCB0byB0aGUgcGFyZW50LlxuICAgICAgICpcbiAgICAgICAqIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGl0IGlzIHBvc3NpYmxlIChmb3IgZXhhbXBsZSwgaW4gdGhlIGNhc2VcbiAgICAgICAqIG9mIGFuIGF0dGVtcHRlZCBkb3VibGUgc3BlbmQgb2YgdGhlIG91dHB1dCBmcm9tIHRoZSBwYXJlbnQsIG9yIGEgcmFjZVxuICAgICAgICogYmV0d2VlbiBmaW5kaW5nIHRoZSBwYXJlbnQgb3V0cHV0LCBhbmQgcmV0cmlldmluZyB0aGUgY29ycmVzcG9uZGluZyB1bnNwZW50KS5cbiAgICAgICAqL1xuICAgICAgaXQoJ2Nhbm5vdCBmaW5kIGNvcnJlY3QgdW5zcGVudCB0byB1c2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogNTAgKiAxZTQsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgZmVlOiAxMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYCkucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY291bnQ6IDAsXG4gICAgICAgICAgdW5zcGVudHM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eQ291bGQgbm90IGZpbmQgdW5zcGVudCBvdXRwdXQgZnJvbSBwYXJlbnQgdHggdG8gdXNlIGFzIGNoaWxkIGlucHV0JC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdEZXRlY3RzIHdoZW4gYW4gaW5jb3JyZWN0IHR4IGhleCBpcyByZXR1cm5lZCBieSB0aGUgZXh0ZXJuYWwgc2VydmljZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NvdW50OiBvdXRwdXRBZGRyZXNzLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMCxcbiAgICAgICAgICAgICAgICB2b3V0OiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgICAgICBoZXg6IGZpeHR1cmVzW3BhcmVudFR4SWRdLFxuICAgICAgICAgICAgZmVlOiAxMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb3VudDogMSxcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1t1bnJlbGF0ZWRUeElkXSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDIwMDAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXkRlY29kZWQgdHJhbnNhY3Rpb24gaWQgaXMgWzAtOWEtZl0rLCB3aGljaCBkb2VzIG5vdCBtYXRjaCBnaXZlbiB0eGlkIFswLTlhLWZdKyQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY2Fubm90IGNvdmVyIGNoaWxkIGZlZSB3aXRoIG9uZSBwYXJlbnQgb3V0cHV0IGFuZCBvbmUgd2FsbGV0IHVuc3BlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBmaXh0dXJlc1twYXJlbnRUeElkXSxcbiAgICAgICAgICAgIGZlZTogMTAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICB1bnNwZW50czogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15JbnN1ZmZpY2llbnQgY29uZmlybWVkIHVuc3BlbnRzIGF2YWlsYWJsZSB0byBjb3ZlciB0aGUgY2hpbGQgZmVlJC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdjYW5ub3QgbG93ZXIgZmVlIHJhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICAgIGhleDogZml4dHVyZXNbcGFyZW50VHhJZF0sXG4gICAgICAgICAgICBmZWU6IDEwMDAwLCAvLyBsYXJnZSBmZWUsIGFuZCB0aHVzIGZlZSByYXRlLCBmb3IgcGFyZW50XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgICAvXkNhbm5vdCBsb3dlciBmZWUgcmF0ZSEgXFwoUGFyZW50IHR4IGZlZSByYXRlIGlzIFxcZCtcXC4/XFxkKiBzYXRcXC9rQiwgYW5kIHJlcXVlc3RlZCBmZWUgcmF0ZSB3YXMgXFxkK1xcLj9cXGQqIHNhdFxcL2tCXFwpJC9cbiAgICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdjYW5ub3QgYnJlYWsgbWF4aW11bSBmZWUgbGltaXQgZm9yIGNvbWJpbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDNlNyxcbiAgICAgICAgICAgICAgICB2b3V0OiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBmaXh0dXJlc1twYXJlbnRUeElkXSxcbiAgICAgICAgICAgIGZlZTogMTAwMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb3VudDogMSxcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDJlNiB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL15UcmFuc2FjdGlvbiBjYW5ub3QgYmUgYWNjZWxlcmF0ZWRcXC4gQ29tYmluZWQgZmVlIHJhdGUgb2YgXFxkK1xcLj9cXGQqIHNhdFxcL2tCIGV4Y2VlZHMgbWF4aW11bSBmZWUgcmF0ZSBvZiBcXGQrXFwuP1xcZCogc2F0XFwva0IkL1xuICAgICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzdWNjZXNzZnVsIHR4IGFjY2VsZXJhdGlvbicsIGZ1bmN0aW9uIHN1Y2Nlc3NmdWxUeERlc2NyaWJlKCkge1xuICAgICAgY29uc3QgZmVlUmF0ZSA9IDIwMDAwO1xuXG4gICAgICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vYWRkcmVzcy8xYCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgYWRkcmVzczogJzJOQ1lqRzhRNTZ5cjh0eDlqYXpOb1luR0t4amdCMk1RU2ZZJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBhZGRyZXNzOiAnMk5GYnZvMkhLNGVYWm0xYXFEY1NER0dxRDY0RlB0N1Q2ZDgnLFxuICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdHgvZmVlJykucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgZmVlUGVyS2I6IDAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjEva2V5Y2hhaW4vJHt1c2VyS2V5cGFpci54cHVifWAsIHt9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogdXNlcktleXBhaXIueHBydiwgcGFzc3dvcmQ6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfUEFTU0NPREUgfSksXG4gICAgICAgICAgICBwYXRoOiB1c2VyS2V5cGFpci5wYXRoICsgdXNlcktleXBhaXIud2FsbGV0U3ViUGF0aCxcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYWNjZWxlcmF0ZXMgYSBzdHVjayB0eCB3aXRob3V0IGFkZGl0aW9uYWwgdW5zcGVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHBhcmVudFR4SWQgPSAnNzVjZmM1YTdiMjE0YzRiNzNjOTJjN2IwMjYwOGNkZTcwYjIyNjc2N2E5NTc2Zjg0YzA0NDA3ZTQzZmQzODViZCc7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgZmVlOiA0MzQsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDM0ODUwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAzNDg1MDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OiAnMDAyMGY3YjU4ZDQ1NTM1MWI3YjhkZGQ3Yzg5ODZkOTgyNDRmNmE5NWYwNzQ2NzIwMDkxNTM3MzIzYjk2NzgwMGY3NDQnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8xMS8xNjAnLFxuICAgICAgICAgICAgICAgIHdpdG5lc3NTY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyN2YwYjQ1YmI0MTU1ZWE1MzJlM2I0MzEyZmUwYmU4MDE2NmYyOTdkMWUwNzUzZDJkNGE5MTE4YzA3M2FkNjUxNDIxMDMxMGFhOWQ2OGM5ODgzMTYyNWYzMjliNzgyNmI2YzNlM2I1M2UxNjczNmIxOTk0Yjg5MDI0NDJiZGNkNjY1M2QxMjEwMjZlMGNhNDE0ZjI0ODhiMGFiNTcyYjk5ZTBhZTU0NDI5MTFhYjRlMDgyMWIyNzA5ZDg4NTE3NWE1MjdmZDU1MmI1M2FlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBpbnB1dFxuICAgICAgICAvLyAxKSBUaGUgcGFyZW50IHR4IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAyKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgb25lIG91dHB1dFxuICAgICAgICAvLyAzKSBUaGUgY2hpbGQgdHggb3V0cHV0IG1lZXRzIHRoZSBtaW5pbXVtIGNoYW5nZSB0aHJlc2hvbGRcbiAgICAgICAgY29uc3QgZGVjb2RlZENoaWxkID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXgoY2hpbGRUeC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLmlucy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBkZWNvZGVkQ2hpbGQub3V0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkSW5wdXQgPSBkZWNvZGVkQ2hpbGQuaW5zWzBdO1xuICAgICAgICBjaGlsZElucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcsIDApO1xuICAgICAgICBjaGlsZElucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYXNoJyk7XG5cbiAgICAgICAgY29uc3QgaW5wdXRUeElkID0gaW5wdXRQYXJlbnRUeElkKGNoaWxkSW5wdXQpO1xuICAgICAgICBpbnB1dFR4SWQuc2hvdWxkLmVxdWFsKHBhcmVudFR4SWQpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aCBvbmUgYWRkaXRpb25hbCBzZWd3aXQgdW5zcGVudCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcGFyZW50VHhJZCA9ICc4ODE1ZjIwMmM4NjU0YjZjOGIyOTU3NDk1NDVjNzExODc4Y2Q4NDVhMTRjYjFlYTk4MjM5NGQwYzE0OTQ1YzMzJztcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbFVuc3BlbnRUeElkID0gJzA3ZDZlZTU3YjAyNGNlMmI2MTA4ZjY3ODQ3NDU0YTBhNzlhNGZjZmI5OGFiMjU1NTUzYTI5OTNhMWExNzBiODcnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogMTMzNixcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiA4NjY0LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IGFkZGl0aW9uYWxVbnNwZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTk5MzU1MjYsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OiAnMDAyMGQzNGVmNmRkMzRlZjJhNGZiZWE2N2M1NDFjMWM3OTY3NDlhNjBhZmU0YTk3ZmVlOGVjN2RlZDE4OGJkNzQ5ZGEnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8xMS8xNTUnLFxuICAgICAgICAgICAgICAgIHdpdG5lc3NTY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyMjE5ZDJhYTg0MTc2MzNmMGJjZTM5MTEzNzRhMTYwNGMxYjY0MTYxZjgzYTNjMmVlNDA5YzI3YzQyMzU1ZjA4ZTIxMDJjOTczNDkyMGRjNGRhMDZjMjg5ZmU2OTE3MWRmY2Q3NWUzYjliNGYxOTBkMGNiYzNkNWQwZmYzZjVmZGVlYWFlMjEwM2NjZDY4ZDdmYThkYzBkMDJkZDQ1ZGFkMTY1NTU3YTQ4NTgyZWRhNDQzNWZhZTczNzdiM2MzMWUwOGFkMDY1Yzk1M2FlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IHR3byBpbnB1dHNcbiAgICAgICAgLy8gMSkgVGhlIHBhcmVudCB0eCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMikgVGhlIGFkZGl0aW9uYWwgdW5zcGVudCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMykgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBvdXRwdXRcbiAgICAgICAgLy8gNCkgVGhlIGNoaWxkIHR4IG91dHB1dCBtZWV0cyB0aGUgbWluaW11bSBjaGFuZ2UgdGhyZXNob2xkXG4gICAgICAgIGNvbnN0IGRlY29kZWRDaGlsZCA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KGNoaWxkVHgudHgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICAgIGRlY29kZWRDaGlsZC5pbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLm91dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBsZXQgaW5wdXRGcm9tUGFyZW50OiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBhZGRpdGlvbmFsSW5wdXQ6IGFueSA9IHVuZGVmaW5lZDtcblxuICAgICAgICBfLmZvckVhY2goZGVjb2RlZENoaWxkLmlucywgKGlucHV0KSA9PiB7XG4gICAgICAgICAgaW5wdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhc2gnKTtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaW5kZXgnKTtcblxuICAgICAgICAgIGNvbnN0IGlucHV0VHhJZCA9IGlucHV0UGFyZW50VHhJZChpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaW5wdXRUeElkID09PSBwYXJlbnRUeElkKSB7XG4gICAgICAgICAgICBpbnB1dEZyb21QYXJlbnQgPSBpbnB1dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkaXRpb25hbElucHV0ID0gaW5wdXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgY29uc3QgaW5wdXRGcm9tUGFyZW50SGFzaCA9IGlucHV0UGFyZW50VHhJZChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnRIYXNoLnNob3VsZC5lcXVhbChwYXJlbnRUeElkKTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50LmluZGV4LnNob3VsZC5lcXVhbCgwKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoYWRkaXRpb25hbElucHV0KTtcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbElucHV0SGFzaCA9IGlucHV0UGFyZW50VHhJZChhZGRpdGlvbmFsSW5wdXQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXRIYXNoLnNob3VsZC5lcXVhbChhZGRpdGlvbmFsVW5zcGVudFR4SWQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXQuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aCBvbmUgYWRkaXRpb25hbCBQMlNIIHVuc3BlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHBhcmVudFR4SWQgPSAnODgxNWYyMDJjODY1NGI2YzhiMjk1NzQ5NTQ1YzcxMTg3OGNkODQ1YTE0Y2IxZWE5ODIzOTRkMGMxNDk0NWMzMyc7XG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxVbnNwZW50VHhJZCA9ICdlMTkwMzEwZjJmM2Y3MWFhODg0NmYxMTYxY2JjZTE1MzNjMjRhODU3ZGQyNGU0NTAxYjEzMWZlYjQwMGFhZDU4JztcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBmZWU6IDEzMzYsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODY2NCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMmNkM2M4ZTYwMDZhNDYyNzcwNTAyMWQxZDAxNmQwOTdjMjk0NGQ5ODEwMGE0N2JmMmRhNjdhNWZlMTVhZWViMzQyMTAyZWUxZmE5ZTgxMmU3NzkzNTZhYTNjMzFlYmYzMTdkMGNmZmViYWI5Mjg2NGNmZTM4YmFiMjIzZTA4MjBmOThiYzIxMDI2YmEwNTc1MmJhYTZlYWZkNWM1NjU5ZGE2MmI3ZjBhYzUxZmQyODg2YjY1YzI0MWQwYWZlZjFjNGZkZmExY2JjNTNhZScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzAvMCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBhZGRpdGlvbmFsVW5zcGVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDIwMDAwMDAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8wLzAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdHgvc2VuZCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gIWJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIGZ1bmN0aW9uIChfLCBib2R5KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogKGJvZHkgYXMgYW55KS50eCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRUeCA9IGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgZmVlUmF0ZSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoY2hpbGRUeCk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXR1cycsICdhY2NlcHRlZCcpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICAgIC8vIGFzc2VydCB0aGUgZm9sbG93aW5nOlxuICAgICAgICAvLyAwKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgdHdvIGlucHV0c1xuICAgICAgICAvLyAxKSBUaGUgcGFyZW50IHR4IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAyKSBUaGUgYWRkaXRpb25hbCB1bnNwZW50IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAzKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgb25lIG91dHB1dFxuICAgICAgICAvLyA0KSBUaGUgY2hpbGQgdHggb3V0cHV0IG1lZXRzIHRoZSBtaW5pbXVtIGNoYW5nZSB0aHJlc2hvbGRcbiAgICAgICAgY29uc3QgZGVjb2RlZENoaWxkID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXgoY2hpbGRUeC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLmlucy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICBkZWNvZGVkQ2hpbGQub3V0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGxldCBpbnB1dEZyb21QYXJlbnQ6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGFkZGl0aW9uYWxJbnB1dDogYW55ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIF8uZm9yRWFjaChkZWNvZGVkQ2hpbGQuaW5zLCAoaW5wdXQpID0+IHtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFzaCcpO1xuICAgICAgICAgIGlucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcpO1xuXG4gICAgICAgICAgY29uc3QgaW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0KTtcblxuICAgICAgICAgIGlmIChpbnB1dEhhc2ggPT09IHBhcmVudFR4SWQpIHtcbiAgICAgICAgICAgIGlucHV0RnJvbVBhcmVudCA9IGlucHV0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsSW5wdXQgPSBpbnB1dDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBjb25zdCBpbnB1dEZyb21QYXJlbnRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudEhhc2guc2hvdWxkLmVxdWFsKHBhcmVudFR4SWQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnQuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChhZGRpdGlvbmFsSW5wdXQpO1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsSW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGFkZGl0aW9uYWxJbnB1dCk7XG4gICAgICAgIGFkZGl0aW9uYWxJbnB1dEhhc2guc2hvdWxkLmVxdWFsKGFkZGl0aW9uYWxVbnNwZW50VHhJZCk7XG4gICAgICAgIGFkZGl0aW9uYWxJbnB1dC5pbmRleC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRPdXRwdXQgPSBkZWNvZGVkQ2hpbGQub3V0c1swXTtcbiAgICAgICAgY2hpbGRPdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3ZhbHVlJyk7XG4gICAgICAgIGNoaWxkT3V0cHV0LnZhbHVlLnNob3VsZC5iZS5hYm92ZShtaW5DaGFuZ2VTaXplKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYWNjZWxlcmF0ZXMgYSBzdHVjayB0eCB3aXRoIHR3byBhZGRpdGlvbmFsIHVuc3BlbnRzIChzZWd3aXQgYW5kIFAyU0gpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzg4MTVmMjAyYzg2NTRiNmM4YjI5NTc0OTU0NWM3MTE4NzhjZDg0NWExNGNiMWVhOTgyMzk0ZDBjMTQ5NDVjMzMnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogMTMzNixcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiA4NjY0LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6ICdlMTkwMzEwZjJmM2Y3MWFhODg0NmYxMTYxY2JjZTE1MzNjMjRhODU3ZGQyNGU0NTAxYjEzMWZlYjQwMGFhZDU4JyxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODAwMDAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8wLzAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogJzA3ZDZlZTU3YjAyNGNlMmI2MTA4ZjY3ODQ3NDU0YTBhNzlhNGZjZmI5OGFiMjU1NTUzYTI5OTNhMWExNzBiODcnLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAyMDAwNjI4NCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6ICcwMDIwZDM0ZWY2ZGQzNGVmMmE0ZmJlYTY3YzU0MWMxYzc5Njc0OWE2MGFmZTRhOTdmZWU4ZWM3ZGVkMTg4YmQ3NDlkYScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzExLzE1NScsXG4gICAgICAgICAgICAgICAgd2l0bmVzc1NjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDIyMTlkMmFhODQxNzYzM2YwYmNlMzkxMTM3NGExNjA0YzFiNjQxNjFmODNhM2MyZWU0MDljMjdjNDIzNTVmMDhlMjEwMmM5NzM0OTIwZGM0ZGEwNmMyODlmZTY5MTcxZGZjZDc1ZTNiOWI0ZjE5MGQwY2JjM2Q1ZDBmZjNmNWZkZWVhYWUyMTAzY2NkNjhkN2ZhOGRjMGQwMmRkNDVkYWQxNjU1NTdhNDg1ODJlZGE0NDM1ZmFlNzM3N2IzYzMxZTA4YWQwNjVjOTUzYWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdHgvc2VuZCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gIWJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIGZ1bmN0aW9uIChfLCBib2R5KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogKGJvZHkgYXMgYW55KS50eCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRUeCA9IGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgICBmZWVSYXRlLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoY2hpbGRUeCk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXR1cycsICdhY2NlcHRlZCcpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICAgIC8vIGFzc2VydCB0aGUgZm9sbG93aW5nOlxuICAgICAgICAvLyAwKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgdGhyZWUgaW5wdXRzXG4gICAgICAgIC8vIDEpIFRoZSBwYXJlbnQgdHggb3V0cHV0IGlzIGFuIGlucHV0XG4gICAgICAgIC8vIDIpIFRoZSBjaGlsZCB0eCBoYXMgZXhhY3RseSBvbmUgb3V0cHV0XG4gICAgICAgIC8vIDMpIFRoZSBjaGlsZCB0eCBvdXRwdXQgbWVldHMgdGhlIG1pbmltdW0gY2hhbmdlIHRocmVzaG9sZFxuICAgICAgICBjb25zdCBkZWNvZGVkQ2hpbGQgPSB1dHhvbGliLmJpdGdvLmNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleChjaGlsZFR4LnR4LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgICBkZWNvZGVkQ2hpbGQuaW5zLmxlbmd0aC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAgIGRlY29kZWRDaGlsZC5vdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgbGV0IGlucHV0RnJvbVBhcmVudDogYW55ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsSW5wdXRzOiBhbnlbXSA9IFtdO1xuXG4gICAgICAgIF8uZm9yRWFjaChkZWNvZGVkQ2hpbGQuaW5zLCAoaW5wdXQpID0+IHtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFzaCcpO1xuICAgICAgICAgIGlucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcpO1xuXG4gICAgICAgICAgY29uc3QgaW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0KTtcblxuICAgICAgICAgIGlmIChpbnB1dEhhc2ggPT09IHBhcmVudFR4SWQpIHtcbiAgICAgICAgICAgIGlucHV0RnJvbVBhcmVudCA9IGlucHV0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsSW5wdXRzLnB1c2goaW5wdXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGNvbnN0IGlucHV0RnJvbVBhcmVudEhhc2ggPSBpbnB1dFBhcmVudFR4SWQoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50SGFzaC5zaG91bGQuZXF1YWwocGFyZW50VHhJZCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudC5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG5cbiAgICAgICAgYWRkaXRpb25hbElucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2NvcnJlY3RseSB1c2VzIHRoZSBpZ25vcmVNYXhGZWVSYXRlIHBhcmFtZXRlciBvbmx5IHdoZW4gbmVjZXNzYXJ5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzc1Y2ZjNWE3YjIxNGM0YjczYzkyYzdiMDI2MDhjZGU3MGIyMjY3NjdhOTU3NmY4NGMwNDQwN2U0M2ZkMzg1YmQnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogNDM0LFxuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAzNDg1MDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMzQ4NTAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDogJzAwMjBmN2I1OGQ0NTUzNTFiN2I4ZGRkN2M4OTg2ZDk4MjQ0ZjZhOTVmMDc0NjcyMDA5MTUzNzMyM2I5Njc4MDBmNzQ0JyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMTEvMTYwJyxcbiAgICAgICAgICAgICAgICB3aXRuZXNzU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMjdmMGI0NWJiNDE1NWVhNTMyZTNiNDMxMmZlMGJlODAxNjZmMjk3ZDFlMDc1M2QyZDRhOTExOGMwNzNhZDY1MTQyMTAzMTBhYTlkNjhjOTg4MzE2MjVmMzI5Yjc4MjZiNmMzZTNiNTNlMTY3MzZiMTk5NGI4OTAyNDQyYmRjZDY2NTNkMTIxMDI2ZTBjYTQxNGYyNDg4YjBhYjU3MmI5OWUwYWU1NDQyOTExYWI0ZTA4MjFiMjcwOWQ4ODUxNzVhNTI3ZmQ1NTJiNTNhZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92MS90eC9zZW5kJywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBtYXggZmVlIHJhdGUgbXVzdCBiZSBzZXQgZm9yIHRoaXMgdGVzdFxuICAgICAgICAgICAgcmV0dXJuIGJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIC8vIG1vbmtleSBwYXRjaCB0aGUgYml0Z28gZ2V0Q29uc3RhbnRzKCkgZnVuY3Rpb25cbiAgICAgICAgY29uc3Qgb2xkR2V0Q29uc3RhbnRzID0gKGJpdGdvIGFzIGFueSkuX19wcm90b19fLmdldENvbnN0YW50cztcbiAgICAgICAgKGJpdGdvIGFzIGFueSkuX19wcm90b19fLmdldENvbnN0YW50cyA9ICgpID0+ICh7XG4gICAgICAgICAgLy8gY2hpbGQgZmVlIHJhdGUgaW4gdGhpcyB0ZXN0IGlzIDMxMzc4IHNhdC9rYlxuICAgICAgICAgIC8vIHNvIHNldCB0aGUgbWF4IGZlZSByYXRlIGp1c3QgYmVsb3cgdGhhdCBsaW1pdCxcbiAgICAgICAgICAvLyBidXQgYWJvdmUgdGhlIGNvbWJpbmVkIGZlZSByYXRlIG9mIDIwMDAwXG4gICAgICAgICAgbWF4RmVlUmF0ZTogMzAwMDAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgZmVlUmF0ZSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICB9KTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcblxuICAgICAgICAoYml0Z28gYXMgYW55KS5fX3Byb3RvX18uZ2V0Q29uc3RhbnRzID0gb2xkR2V0Q29uc3RhbnRzO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRCaXRHb0ZlZScsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmdVcmw6IHN0cmluZztcbiAgICBsZXQgd2FsbGV0OiBhbnk7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICAgIGNvbnN0IHByb2RCaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Byb2QnLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAgICAgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW3Byb2RCaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChwcm9kQml0Z28sIHtcbiAgICAgICAgaWQ6ICcyTkNvU2ZISDZMczRDZFRTNVFhaGdDOWs3eDlSZlhlU3dZNCcsXG4gICAgICAgIHByaXZhdGU6IHsga2V5Y2hhaW5zOiBbdXNlcktleXBhaXIsIGJhY2t1cEtleXBhaXIsIGJpdGdvS2V5XSB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NlbmRzIGFtb3VudCBhbmQgaW5zdGFudCB3aXRob3V0IHJlY2lwaWVudHMgd2hlbiByZWNpcGllbnRzIGFycmF5IGlzIGVtcHR5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS9iaWxsaW5nL2ZlZWApXG4gICAgICAgIC5xdWVyeSh7IGFtb3VudDogJzEwMDAwMCcsIGluc3RhbnQ6ICdmYWxzZScgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBmZWU6IDEwMDAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5nZXRCaXRHb0ZlZSh7IGFtb3VudDogMTAwMDAwLCBpbnN0YW50OiBmYWxzZSB9KTtcbiAgICAgIHJlc3VsdC5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzZW5kcyByZWNpcGllbnRzW10gcXVlcnkgcGFyYW1zIHdoZW4gcmVjaXBpZW50cyBhcmUgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyMSA9ICczSjk4dDFXcEVaNzNDTm1RdmllY3JueWlXcm5xUmhXTkx5JztcbiAgICAgIGNvbnN0IGFkZHIyID0gJzNGWmJnaTI5Y3BqcTJHamR3VjhleUh1Skpua0x0a3RaYzUnO1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2JpbGxpbmcvZmVlYClcbiAgICAgICAgLnF1ZXJ5KChxdWVyeSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlY2lwaWVudHNQYXJhbSA9IHF1ZXJ5WydyZWNpcGllbnRzW10nXTtcbiAgICAgICAgICBjb25zdCByZWNpcGllbnRzTGlzdCA9IEFycmF5LmlzQXJyYXkocmVjaXBpZW50c1BhcmFtKSA/IHJlY2lwaWVudHNQYXJhbSA6IFtyZWNpcGllbnRzUGFyYW1dO1xuICAgICAgICAgIHJldHVybiBxdWVyeS5hbW91bnQgPT09ICcxMDAwMDAnICYmIHJlY2lwaWVudHNMaXN0LmluY2x1ZGVzKGFkZHIxKSAmJiByZWNpcGllbnRzTGlzdC5pbmNsdWRlcyhhZGRyMik7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgZmVlOiAwIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuZ2V0Qml0R29GZWUoeyBhbW91bnQ6IDEwMDAwMCwgcmVjaXBpZW50czogW2FkZHIxLCBhZGRyMl0gfSk7XG4gICAgICByZXN1bHQuZmVlLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnb21pdHMgcmVjaXBpZW50c1tdIHdoZW4gcmVjaXBpZW50cyBhcnJheSBpcyBlbXB0eScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vYmlsbGluZy9mZWVgKVxuICAgICAgICAucXVlcnkoKHF1ZXJ5KSA9PiBxdWVyeS5hbW91bnQgPT09ICcyMDAwMDAnICYmICEoJ3JlY2lwaWVudHNbXScgaW4gcXVlcnkpKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGZlZTogNTAwIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuZ2V0Qml0R29GZWUoeyBhbW91bnQ6IDIwMDAwMCwgcmVjaXBpZW50czogW10gfSk7XG4gICAgICByZXN1bHQuZmVlLnNob3VsZC5lcXVhbCg1MDApO1xuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiBhbW91bnQgaXMgbm90IGEgbnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgKCgpID0+IHdhbGxldC5nZXRCaXRHb0ZlZSh7IGFtb3VudDogJ2JhZCcgfSkpLnNob3VsZC50aHJvdygnaW52YWxpZCBhbW91bnQgYXJndW1lbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiBpbnN0YW50IGlzIG5vdCBhIGJvb2xlYW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAoKCkgPT4gd2FsbGV0LmdldEJpdEdvRmVlKHsgYW1vdW50OiAxMDAsIGluc3RhbnQ6ICd5ZXMnIH0pKS5zaG91bGQudGhyb3coJ2ludmFsaWQgaW5zdGFudCBhcmd1bWVudCcpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19