@bitgo-beta/sdk-api 1.10.1-beta.15 → 1.10.1-beta.1500

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 (65) hide show
  1. package/dist/package.json +24 -27
  2. package/dist/src/api.d.ts +3 -3
  3. package/dist/src/api.d.ts.map +1 -1
  4. package/dist/src/api.js +39 -33
  5. package/dist/src/bitgoAPI.d.ts +73 -13
  6. package/dist/src/bitgoAPI.d.ts.map +1 -1
  7. package/dist/src/bitgoAPI.js +416 -140
  8. package/dist/src/encrypt.d.ts +4 -4
  9. package/dist/src/encrypt.d.ts.map +1 -1
  10. package/dist/src/encrypt.js +44 -7
  11. package/dist/src/index.js +6 -2
  12. package/dist/src/types.d.ts +77 -42
  13. package/dist/src/types.d.ts.map +1 -1
  14. package/dist/src/types.js +4 -2
  15. package/dist/src/util.d.ts +12 -0
  16. package/dist/src/util.d.ts.map +1 -1
  17. package/dist/src/util.js +57 -4
  18. package/dist/src/v1/blockchain.js +25 -12
  19. package/dist/src/v1/keychains.js +27 -22
  20. package/dist/src/v1/markets.js +10 -5
  21. package/dist/src/v1/pendingapproval.d.ts.map +1 -1
  22. package/dist/src/v1/pendingapproval.js +57 -18
  23. package/dist/src/v1/pendingapprovals.d.ts.map +1 -1
  24. package/dist/src/v1/pendingapprovals.js +41 -7
  25. package/dist/src/v1/signPsbt.d.ts +14 -0
  26. package/dist/src/v1/signPsbt.d.ts.map +1 -0
  27. package/dist/src/v1/signPsbt.js +69 -0
  28. package/dist/src/v1/transactionBuilder.js +144 -92
  29. package/dist/src/v1/travelRule.js +60 -23
  30. package/dist/src/v1/verifyAddress.d.ts +6 -0
  31. package/dist/src/v1/verifyAddress.d.ts.map +1 -0
  32. package/dist/src/v1/verifyAddress.js +50 -0
  33. package/dist/src/v1/wallet.d.ts.map +1 -1
  34. package/dist/src/v1/wallet.js +428 -224
  35. package/dist/src/v1/wallets.js +93 -37
  36. package/dist/test/unit/api.d.ts +2 -0
  37. package/dist/test/unit/api.d.ts.map +1 -0
  38. package/dist/test/unit/api.js +158 -0
  39. package/dist/test/unit/bitgoAPI.d.ts +2 -0
  40. package/dist/test/unit/bitgoAPI.d.ts.map +1 -0
  41. package/dist/test/unit/bitgoAPI.js +477 -0
  42. package/dist/test/unit/encrypt.d.ts +2 -0
  43. package/dist/test/unit/encrypt.d.ts.map +1 -0
  44. package/dist/test/unit/encrypt.js +62 -0
  45. package/dist/test/unit/utils.d.ts +2 -0
  46. package/dist/test/unit/utils.d.ts.map +1 -0
  47. package/dist/test/unit/utils.js +65 -0
  48. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts +4 -0
  49. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts.map +1 -0
  50. package/dist/test/unit/v1/fixtures/accelerate-tx.js +53 -0
  51. package/dist/test/unit/v1/fixtures/index.d.ts +3 -0
  52. package/dist/test/unit/v1/fixtures/index.d.ts.map +1 -0
  53. package/dist/test/unit/v1/fixtures/index.js +24 -0
  54. package/dist/test/unit/v1/signPsbt.d.ts +2 -0
  55. package/dist/test/unit/v1/signPsbt.d.ts.map +1 -0
  56. package/dist/test/unit/v1/signPsbt.js +53 -0
  57. package/dist/test/unit/v1/wallet.d.ts +2 -0
  58. package/dist/test/unit/v1/wallet.d.ts.map +1 -0
  59. package/dist/test/unit/v1/wallet.js +1371 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -0
  61. package/package.json +24 -27
  62. package/.eslintignore +0 -5
  63. package/CHANGELOG.md +0 -262
  64. package/dist/web/main.js +0 -2
  65. package/dist/web/main.js.LICENSE.txt +0 -103
@@ -0,0 +1,1371 @@
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
+ }));
211
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
212
+ // add first signature
213
+ transaction.keychain = userKeypair;
214
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
215
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b600473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
216
+ // add second signature
217
+ transaction.transactionHex = signature1.tx;
218
+ transaction.keychain = backupKeypair;
219
+ transaction.fullLocalSigning = true;
220
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
221
+ // This transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
222
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
223
+ // changed, changing the output amounts and thus the tx hex.
224
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfd0000473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80147304402202ae01f01b5ae0c3fa7d67ac73db81932cb5aca10db16a99063fef45e3f1398cd022055001ba7e163cb350910fc7321ecd7eb6359b321d4c04887484d9c7284b78c4701004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
225
+ });
226
+ it('BCH p2sh', async function () {
227
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
228
+ const unspent = {
229
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
230
+ value: '0.00504422',
231
+ value_int: 504422,
232
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
233
+ n: 1,
234
+ script_pub_key: {
235
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
236
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
237
+ },
238
+ req_sigs: 1,
239
+ type: 'scripthash',
240
+ confirmations: 9,
241
+ id: 61330229,
242
+ };
243
+ _.extend(unspent, p2shAddress);
244
+ unspent.value = unspent.value_int;
245
+ unspent.tx_hash = unspent.txid;
246
+ unspent.tx_output_n = unspent.n;
247
+ unspent.script = unspent.outputScript;
248
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
249
+ const transaction = (await fakeProdWallet.createTransaction({
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
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
263
+ // add first signature
264
+ transaction.keychain = userKeypair;
265
+ transaction.forceBCH = true;
266
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
267
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b60047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
268
+ // add second signature
269
+ transaction.transactionHex = signature1.tx;
270
+ transaction.keychain = backupKeypair;
271
+ transaction.fullLocalSigning = true;
272
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
273
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
274
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
275
+ // changed, changing the output amounts and thus the tx hex.
276
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfe000047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884148304502210082bc546293858459f3895db24c85ccf37505c56f8faf4bb8f78cf40135bc2f2b02203dc1c78d7c7ceaf6b924eca3c39b95e8a227b069a07047581273136b47ca7ac441004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
277
+ });
278
+ it('default segwit', 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
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
301
+ const transaction = (await fakeProdWallet.createTransaction({
302
+ changeAddress: segwitAddress.address,
303
+ unspents: [unspent],
304
+ recipients: {},
305
+ noSplitChange: true,
306
+ forceChangeAtEnd: true,
307
+ feeRate: 10000,
308
+ bitgoFee: {
309
+ amount: 0,
310
+ address: '',
311
+ },
312
+ opReturns: { 'BitGo segwit test': 1000 },
313
+ }));
314
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
315
+ // add first signature
316
+ transaction.keychain = userKeypair;
317
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
318
+ signature1.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f3010000695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
319
+ // add second signature
320
+ transaction.transactionHex = signature1.tx;
321
+ transaction.keychain = backupKeypair;
322
+ transaction.fullLocalSigning = true;
323
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
324
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/d67266f1de905baaee750011fa4b3d88a8e3a1758d5173a659c67709488dde07
325
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
326
+ // changed, changing the output amounts and thus the tx hex.
327
+ signature2.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f30147304402205cf8d2f2be6ce083d35654bdc3fa85d7e71b227d457e9245bb603b21e7b5165102203ea686226db8320e08c26bfb304048b3a9473d0e05797d3658dacb2f09a2b51c0100695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
328
+ });
329
+ it('creates an unsigned tx made of uncompressed public keys of v1 safe wallet', async function () {
330
+ const { address, redeemScript, scriptPubKey } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
331
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
332
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
333
+ id: address,
334
+ private: { safe: { redeemScript } },
335
+ });
336
+ const unspentsToSpend = [
337
+ {
338
+ value: 100000,
339
+ redeemScript,
340
+ script: scriptPubKey,
341
+ tx_hash: 'a55d11dc8b701bd19601fbfe711a1e465fc8f128ec4474e78e1fd087e808e5fe',
342
+ tx_output_n: 0,
343
+ confirmations: 1,
344
+ },
345
+ {
346
+ value: 100000,
347
+ redeemScript,
348
+ script: scriptPubKey,
349
+ tx_hash: '48fb879cec879356045a331937023aed859f5dc5db955a1dc8a5ccf29f49d108',
350
+ tx_output_n: 0,
351
+ confirmations: 1,
352
+ },
353
+ ];
354
+ const recipients = {
355
+ '2MyGxrhLC4kRfuVjLqCVYFtC7DchhgMCiNz': 191340, // purposely set to simulate a sweep transaction
356
+ };
357
+ const scope = (0, nock_1.default)(bgUrlTest)
358
+ .post('/api/v1/billing/address')
359
+ .reply(200, { address: '2N3L9cu9WN2Df7Xvb1Y8owokuDVj5Hdyv4i' });
360
+ const result = await fakeTestV1SafeWallet.createTransaction({
361
+ recipients,
362
+ unspents: unspentsToSpend,
363
+ feeRate: 10000, // 10 sat/byte
364
+ bitgoFee: {
365
+ amount: 0,
366
+ address: '',
367
+ },
368
+ });
369
+ scope.isDone().should.be.true();
370
+ result.estimatedSize.should.equal(866);
371
+ result.fee.should.equal(8660);
372
+ // This should equal to 1 because this is a sweep transaction but due to hardcoded addition of
373
+ // 1 change output in transactionBuilder, it is 2.
374
+ // Because of this the estimated size of the transactions is more than what it actually is in the hex.
375
+ result.txInfo.nOutputs.should.equal(2);
376
+ });
377
+ it('signs an unsigned tx made of uncompressed public keys of v1 safe wallet & verifies signatures', async function () {
378
+ const { address, redeemScript, scriptPubKey, userKeyWIF: userSigningKey, bitgoKeyWIF: bitgoSigningKey, unsignedTxHex, halfSignedTxHex, fullSignedTxHex, } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
379
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
380
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
381
+ id: address,
382
+ private: { safe: { redeemScript } },
383
+ });
384
+ const unspentsToSpend = [
385
+ { value: 100000, redeemScript, script: scriptPubKey },
386
+ { value: 100000, redeemScript, script: scriptPubKey },
387
+ ];
388
+ const halfSignedTx = await fakeTestV1SafeWallet.signTransaction({
389
+ transactionHex: unsignedTxHex,
390
+ signingKey: userSigningKey,
391
+ unspents: unspentsToSpend,
392
+ validate: true,
393
+ });
394
+ halfSignedTx.tx.should.equal(halfSignedTxHex);
395
+ const fullSignedTx = await fakeTestV1SafeWallet.signTransaction({
396
+ transactionHex: halfSignedTxHex,
397
+ signingKey: bitgoSigningKey,
398
+ unspents: unspentsToSpend,
399
+ validate: true,
400
+ fullLocalSigning: true,
401
+ });
402
+ // Upon calling txb.build() instead after getting 2 valid signatures, we get a valid full signed tx that was broadcast
403
+ // and confirmed on testnet here: https://mempool.space/testnet/tx/bde09f1bd5e6661c28d90e4c96291853e21ba15ab42f3e4a30719decb73e791b
404
+ // It's present in the fullSignedTxHexBuildComplete property of the fixture.
405
+ fullSignedTx.tx.should.equal(fullSignedTxHex);
406
+ });
407
+ it('BCH segwit should fail', async function () {
408
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
409
+ const unspent = {
410
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
411
+ value: '0.18750000',
412
+ value_int: 18750000,
413
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
414
+ n: 0,
415
+ script_pub_key: {
416
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
417
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
418
+ },
419
+ req_sigs: 1,
420
+ type: 'scripthash',
421
+ confirmations: 0,
422
+ id: 61331617,
423
+ };
424
+ _.extend(unspent, segwitAddress);
425
+ unspent.value = unspent.value_int;
426
+ unspent.tx_hash = unspent.txid;
427
+ unspent.tx_output_n = unspent.n;
428
+ unspent.script = unspent.outputScript;
429
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
430
+ const transaction = (await fakeProdWallet.createTransaction({
431
+ changeAddress: segwitAddress.address,
432
+ unspents: [unspent],
433
+ recipients: {},
434
+ noSplitChange: true,
435
+ forceChangeAtEnd: true,
436
+ feeRate: 10000,
437
+ bitgoFee: {
438
+ amount: 0,
439
+ address: '',
440
+ },
441
+ opReturns: { 'BitGo segwit test': 1000 },
442
+ }));
443
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
444
+ // add first signature
445
+ transaction.keychain = userKeypair;
446
+ transaction.forceBCH = true;
447
+ (() => fakeProdWallet.signTransaction(transaction)).should.throw('BCH does not support segwit inputs');
448
+ });
449
+ it('mixed p2sh & segwit', async function () {
450
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
451
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
452
+ const p2shUnspent = {
453
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
454
+ value: '2.99996610',
455
+ value_int: 299996610,
456
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
457
+ n: 1,
458
+ script_pub_key: {
459
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
460
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
461
+ },
462
+ req_sigs: 1,
463
+ type: 'scripthash',
464
+ confirmations: 0,
465
+ id: 61331263,
466
+ };
467
+ const segwitUnspent = {
468
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
469
+ value: '1.50000000',
470
+ value_int: 150000000,
471
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
472
+ n: 0,
473
+ script_pub_key: {
474
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
475
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
476
+ },
477
+ req_sigs: 1,
478
+ type: 'scripthash',
479
+ confirmations: 0,
480
+ id: 61330882,
481
+ };
482
+ const addresses = [p2shAddress, segwitAddress];
483
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
484
+ const address = addresses[index];
485
+ _.extend(unspent, address);
486
+ unspent.value = unspent.value_int;
487
+ unspent.tx_hash = unspent.txid;
488
+ unspent.tx_output_n = unspent.n;
489
+ unspent.script = unspent.outputScript;
490
+ return unspent;
491
+ });
492
+ const transaction = (await fakeWallet.createTransaction({
493
+ changeAddress: p2shAddress.address,
494
+ unspents: unspents,
495
+ recipients: {},
496
+ noSplitChange: true,
497
+ forceChangeAtEnd: true,
498
+ feeRate: 10000,
499
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
500
+ bitgoFee: {
501
+ amount: 81760,
502
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
503
+ },
504
+ }));
505
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
506
+ // add first signature
507
+ transaction.keychain = userKeypair;
508
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
509
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b700483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d90100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd6010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
510
+ // add second signature
511
+ transaction.transactionHex = signature1.tx;
512
+ transaction.keychain = backupKeypair;
513
+ transaction.fullLocalSigning = true;
514
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
515
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
516
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
517
+ // changed, changing the output amounts and thus the tx hex.
518
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdff0000483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d9014830450221008254d100401a3a831ed019e1662dbd90b96c6c4072b81ce640d152bc29295c10022013f86c5af5716234999a7bd6e94fc8f428f7697cc3138b3649d0ec4dd8681bc701004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd60147304402207713d671b45989688e2665c2b11ab7e5ea8d57eb14f9da233c095dabe441308d022069521b5aeb071b07a70a7197a0c2bbc40a23ae63a04160cf3627250c4ba4c40f0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
519
+ });
520
+ it('should send to bech32 recipient', async function () {
521
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
522
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
523
+ const p2shUnspent = {
524
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
525
+ value: '2.99996610',
526
+ value_int: 299996610,
527
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
528
+ n: 1,
529
+ script_pub_key: {
530
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
531
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
532
+ },
533
+ req_sigs: 1,
534
+ type: 'scripthash',
535
+ confirmations: 0,
536
+ id: 61331263,
537
+ };
538
+ const segwitUnspent = {
539
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
540
+ value: '1.50000000',
541
+ value_int: 150000000,
542
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
543
+ n: 0,
544
+ script_pub_key: {
545
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
546
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
547
+ },
548
+ req_sigs: 1,
549
+ type: 'scripthash',
550
+ confirmations: 0,
551
+ id: 61330882,
552
+ };
553
+ const addresses = [p2shAddress, segwitAddress];
554
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
555
+ const address = addresses[index];
556
+ _.extend(unspent, address);
557
+ unspent.value = unspent.value_int;
558
+ unspent.tx_hash = unspent.txid;
559
+ unspent.tx_output_n = unspent.n;
560
+ unspent.script = unspent.outputScript;
561
+ return unspent;
562
+ });
563
+ const transaction = (await fakeWallet.createTransaction({
564
+ changeAddress: p2shAddress.address,
565
+ unspents: unspents,
566
+ recipients: { tb1qguzyk4w6kaqtpsczs5aj0w8r7598jq36egm8e98wqph3rwmex68seslgsg: 300000 },
567
+ noSplitChange: true,
568
+ forceChangeAtEnd: true,
569
+ feeRate: 10000,
570
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
571
+ bitgoFee: {
572
+ amount: 81760,
573
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
574
+ },
575
+ }));
576
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
577
+ // add first signature
578
+ transaction.keychain = userKeypair;
579
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
580
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b7004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a2832010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
581
+ // add second signature
582
+ transaction.transactionHex = signature1.tx;
583
+ transaction.keychain = backupKeypair;
584
+ transaction.fullLocalSigning = true;
585
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
586
+ console.log('signature1 ' + JSON.stringify(signature2));
587
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
588
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
589
+ // changed, changing the output amounts and thus the tx hex.
590
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdfe00004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40147304402205a58e602042b8e8a5da509d19ce31050147dd0ffcfbe2bb337c23d4c88f4cc41022075bfa455d1f74e30fbd9c786cd4811a1defe54310f235b4193ce4ffa0e8309a101004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a283201473044022053690234582a6911a28cae9f534c980b7d7918749a7413c1c59327debf16ff0b022056175f5c27a363416b2ce4791aefc3d55545cacbd0527202e869e1127fc2f24d0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
591
+ });
592
+ });
593
+ describe('Send Many', function () {
594
+ it('responds with proper fee and fee rate', async function () {
595
+ const params = {
596
+ recipients: [
597
+ {
598
+ address: '2MutpXVYs8Lyk74pVDn3eAG7xnK4Wc2kjTQ',
599
+ amount: 300000,
600
+ },
601
+ ],
602
+ };
603
+ const unspents = [
604
+ {
605
+ value: 8170,
606
+ },
607
+ {
608
+ value: 800000,
609
+ },
610
+ ];
611
+ const createAndSignResponse = {
612
+ bitgoFee: 0,
613
+ travelInfos: [],
614
+ unspents,
615
+ tx: 'halfsignedhex',
616
+ };
617
+ sinon.stub(fakeWallet, 'createAndSignTransaction').returns(Promise.resolve(createAndSignResponse));
618
+ const getSendTxResponse = () => ({
619
+ status: 'accepted',
620
+ tx: '0100000000010228b5c3e2789d4770fc397ec79fa7255f86235297c5a04def678b481b8b09e81b0100000023220020b3bbe067960be39501f365b8999d53f2a8285d8d9836f61fad020e6a4a9e26fdffffffff1510e90411a86c49f2a52546a32a03febde2bc604741f0e85dc47adec33f515900000000fdfd0000483045022100a44bbf97b155c57703862be69d2b20c4b2ab9e94f402595880bf74402ccc87e202200a4aaf98f939b65c98ca08eb96074c222ecb1fc37e359b1d67a05f1c56dedfc001473044022003f3989a14284f132bbb550118c20256d4ea737704123a29955acc1d03ea6eb7022017223da7edcf73076d89875aa33360aa6a12141807f683c6c1b9a5a0d3ff6019014c695221025789857cc8be110ff4cbf354b52dd0e7e9326c6bfe0aee6c30c1ee69660c3dc02102f58f1b1516d05814ae688ca701856695e27050e3e16d3a2351284d7af84498882102385c7bcec3f38c13e87b558aebf2f20a8928e7ecbe11e7c3a47792bc8e33fe8853aeffffffff02e09304000000000017a9141d0c791cec3af1f37808d42f04593095d6fdea268705bc07000000000017a914d8c720f646c7c56c5467248e47c72dc0b2d30bbc87040047304402201eaa1359fffd3bdec5b48268bd2f15193a299c22b1970356f390883473324651022074186232f02245af9c0977031448c2c99e7b7e2b05b2ba4b32c3227d8ca1494e01483045022100bd61b37051c28533ea0b00dda75b1c4f1dee1b683bb7351b2d8dd720f6dfbe1102203acc4cf9d2dd44b294aa25812e99e7d8eb3730e4ff6f889d3cdcd525195750b8016952210219d093c18c27cb547737b4a49dddac9c3412b10e9f880eb30053c3eba81928542103747118892cac1b4da11526fc4ebeebe168dae0907cefb1a1812541cd46b07602210339f73b6750f8f91efd484b5aa2974321a6cc2776d5bd78b9cfb5fe18e3b2d66253ae005a9e1600',
621
+ hash: 'f8df43c2c650b3bb11277aee4531db99a715fa3b9dfd3d45a8d171342c1bf780',
622
+ instant: false,
623
+ });
624
+ const expectedResult = Object.assign({
625
+ fee: 1285,
626
+ feeRate: 2519.607843137255,
627
+ }, getSendTxResponse());
628
+ sinon.stub(fakeWallet, 'sendTransaction').resolves(getSendTxResponse());
629
+ const result = (await fakeWallet.sendMany(params));
630
+ result.tx.should.equal(expectedResult.tx);
631
+ result.fee.should.equal(expectedResult.fee);
632
+ result.feeRate.should.equal(expectedResult.feeRate);
633
+ });
634
+ });
635
+ describe('Accelerate Transaction (server mocked)', function accelerateTxMockedDescribe() {
636
+ let wallet;
637
+ let bgUrl;
638
+ let explorerUrl;
639
+ let minChangeSize;
640
+ let parentTxId = '6a74b74df4991d93c32d751336c85b5f2d1ee544a2dfbae2e5f4beb4f914e5e0';
641
+ const outputIdx = 0;
642
+ const outputAddress = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
643
+ const unrelatedTxId = '08f5e0b4acb5ab8245229dfe161ce4ca0da1ec983e7a34b09e72f56979a467df';
644
+ const walletId = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
645
+ /**
646
+ * Helper function to get the parent transaction ID from a transaction input
647
+ *
648
+ * This function converts `hash` (which is a Buffer object) to a usable txid string.
649
+ * The issue is that the bytes are stored in reverse order in the buffer, so
650
+ * the simple approach of just comparing the hex strings doesn't work.
651
+ * Instead, the Buffer is copied to a new Buffer object, the new Buffer
652
+ * object is reversed in-place, and then the new Buffer is converted to a
653
+ * hex string. After this, the result is a hex string which is the parent txid
654
+ *
655
+ * @param hash a bitcoinjs-lib transaction object's input hash
656
+ */
657
+ function inputParentTxId({ hash }) {
658
+ return Buffer.from(hash).reverse().toString('hex');
659
+ }
660
+ before(function accelerateTxMockedBefore() {
661
+ nock_1.default.pendingMocks().should.be.empty();
662
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'mock', clientConstants: { constants: {} } });
663
+ // bitgo.initializeTestVars();
664
+ bitgo.setValidate(false);
665
+ wallet = new Wallet(bitgo, { id: walletId, private: { keychains: [userKeypair, backupKeypair, bitgoKey] } });
666
+ wallet.bitgo = bitgo;
667
+ bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
668
+ explorerUrl = sdk_core_1.common.Environments[bitgo.getEnv()].btcExplorerBaseUrl;
669
+ // try to get the min change size from the server, otherwise default to 0.1 BTC
670
+ // TODO: minChangeSize is not currently a constant defined on the client and should be added
671
+ minChangeSize = 1e7;
672
+ });
673
+ after(function accelerateTxMockedAfter() {
674
+ // make sure all nocks are cleared or consumed after the tests are complete
675
+ nock_1.default.pendingMocks().should.be.empty();
676
+ });
677
+ it('arguments', async () => {
678
+ await wallet.accelerateTransaction({ feeRate: 123 }).should.be.rejectedWith(/^Missing parameter: transactionID$/);
679
+ await wallet
680
+ .accelerateTransaction({ transactionID: 123, feeRate: 123 })
681
+ .should.be.rejectedWith(/^Expecting parameter string: transactionID but found number$/);
682
+ await wallet
683
+ .accelerateTransaction({ transactionID: '123' })
684
+ .should.be.rejectedWith(/^Missing parameter: feeRate$/);
685
+ const feeRatesParams = ['123', 0, -10, -Infinity, Infinity, NaN];
686
+ for (const feeRate of feeRatesParams) {
687
+ await wallet
688
+ .accelerateTransaction({ transactionID: '123', feeRate })
689
+ .should.be.rejectedWith(/^Expecting positive finite number for parameter: feeRate$/);
690
+ }
691
+ });
692
+ describe('bad input', function badInputDescribe() {
693
+ after(() => {
694
+ // make sure all nocks are cleared or consumed after the tests are complete
695
+ nock_1.default.pendingMocks().should.be.empty();
696
+ });
697
+ it('non existent transaction ID', async () => {
698
+ (0, nock_1.default)(bgUrl)
699
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
700
+ .reply(404, 'transaction not found on this wallet');
701
+ await wallet
702
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 123 })
703
+ .should.be.rejectedWith(/^404\ntransaction not found on this wallet$/);
704
+ });
705
+ it('confirmed transaction', async () => {
706
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`).reply(200, {
707
+ confirmations: 6,
708
+ });
709
+ await wallet
710
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
711
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ is already confirmed and cannot be accelerated$/);
712
+ });
713
+ it('no outputs to wallet', async () => {
714
+ (0, nock_1.default)(bgUrl)
715
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
716
+ .reply(200, {
717
+ outputs: [
718
+ {
719
+ account: outputAddress,
720
+ value: 1890000,
721
+ vout: 0,
722
+ chain: 0,
723
+ },
724
+ ],
725
+ confirmations: 0,
726
+ });
727
+ await wallet
728
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
729
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ contains no outputs to this wallet, and thus cannot be accelerated$/);
730
+ });
731
+ /*
732
+ * This test covers the case where a failure occurs during the process of
733
+ * converting an output from the parent transaction into an unspent which
734
+ * can be used to chain the child tx to the parent.
735
+ *
736
+ * This should never happen, but it is possible (for example, in the case
737
+ * of an attempted double spend of the output from the parent, or a race
738
+ * between finding the parent output, and retrieving the corresponding unspent).
739
+ */
740
+ it('cannot find correct unspent to use', async () => {
741
+ (0, nock_1.default)(bgUrl)
742
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
743
+ .reply(200, {
744
+ outputs: [
745
+ {
746
+ account: outputAddress,
747
+ value: 50 * 1e4,
748
+ vout: outputIdx,
749
+ isMine: true,
750
+ chain: 0,
751
+ },
752
+ ],
753
+ confirmations: 0,
754
+ hex: parentTxId,
755
+ fee: 10,
756
+ });
757
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
758
+ count: 0,
759
+ unspents: [],
760
+ });
761
+ await wallet
762
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
763
+ .should.be.rejectedWith(/^Could not find unspent output from parent tx to use as child input$/);
764
+ });
765
+ it('Detects when an incorrect tx hex is returned by the external service', async () => {
766
+ (0, nock_1.default)(bgUrl)
767
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
768
+ .reply(200, {
769
+ outputs: [
770
+ {
771
+ account: outputAddress,
772
+ value: 10,
773
+ vout: outputIdx,
774
+ isMine: true,
775
+ chain: 0,
776
+ },
777
+ ],
778
+ confirmations: 0,
779
+ hex: fixtures[parentTxId],
780
+ fee: 10,
781
+ });
782
+ (0, nock_1.default)(bgUrl)
783
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
784
+ .query(true)
785
+ .reply(200, {
786
+ count: 1,
787
+ unspents: [
788
+ {
789
+ tx_hash: parentTxId,
790
+ tx_output_n: outputIdx,
791
+ },
792
+ ],
793
+ });
794
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[unrelatedTxId]);
795
+ await wallet
796
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
797
+ .should.be.rejectedWith(/^Decoded transaction id is [0-9a-f]+, which does not match given txid [0-9a-f]+$/);
798
+ });
799
+ it('cannot cover child fee with one parent output and one wallet unspent', async () => {
800
+ (0, nock_1.default)(bgUrl)
801
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
802
+ .reply(200, {
803
+ outputs: [
804
+ {
805
+ account: outputAddress,
806
+ value: 10,
807
+ vout: outputIdx,
808
+ isMine: true,
809
+ chain: 0,
810
+ },
811
+ ],
812
+ confirmations: 0,
813
+ hex: fixtures[parentTxId],
814
+ fee: 10,
815
+ });
816
+ (0, nock_1.default)(bgUrl)
817
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
818
+ .query(true)
819
+ .reply(200, {
820
+ count: 1,
821
+ unspents: [
822
+ {
823
+ tx_hash: parentTxId,
824
+ tx_output_n: outputIdx,
825
+ },
826
+ ],
827
+ });
828
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
829
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
830
+ count: 0,
831
+ unspents: [],
832
+ });
833
+ await wallet
834
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
835
+ .should.be.rejectedWith(/^Insufficient confirmed unspents available to cover the child fee$/);
836
+ });
837
+ it('cannot lower fee rate', async () => {
838
+ (0, nock_1.default)(bgUrl)
839
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
840
+ .reply(200, {
841
+ outputs: [
842
+ {
843
+ account: outputAddress,
844
+ value: 10,
845
+ vout: outputIdx,
846
+ isMine: true,
847
+ chain: 11,
848
+ },
849
+ ],
850
+ confirmations: 0,
851
+ hex: fixtures[parentTxId],
852
+ fee: 10000, // large fee, and thus fee rate, for parent
853
+ });
854
+ (0, nock_1.default)(bgUrl)
855
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
856
+ .query(true)
857
+ .reply(200, {
858
+ count: 1,
859
+ unspents: [
860
+ {
861
+ tx_hash: parentTxId,
862
+ tx_output_n: outputIdx,
863
+ },
864
+ ],
865
+ });
866
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
867
+ await wallet
868
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
869
+ .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\)$/);
870
+ });
871
+ it('cannot break maximum fee limit for combined transaction', async () => {
872
+ (0, nock_1.default)(bgUrl)
873
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
874
+ .reply(200, {
875
+ outputs: [
876
+ {
877
+ account: outputAddress,
878
+ value: 3e7,
879
+ vout: outputIdx,
880
+ isMine: true,
881
+ chain: 11,
882
+ },
883
+ ],
884
+ confirmations: 0,
885
+ hex: fixtures[parentTxId],
886
+ fee: 1000,
887
+ });
888
+ (0, nock_1.default)(bgUrl)
889
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
890
+ .query(true)
891
+ .reply(200, {
892
+ count: 1,
893
+ unspents: [
894
+ {
895
+ tx_hash: parentTxId,
896
+ tx_output_n: outputIdx,
897
+ },
898
+ ],
899
+ });
900
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
901
+ await wallet
902
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2e6 })
903
+ .should.be.rejectedWith(/^Transaction cannot be accelerated\. Combined fee rate of \d+\.?\d* sat\/kB exceeds maximum fee rate of \d+\.?\d* sat\/kB$/);
904
+ });
905
+ });
906
+ describe('successful tx acceleration', function successfulTxDescribe() {
907
+ const feeRate = 20000;
908
+ beforeEach(() => {
909
+ (0, nock_1.default)(bgUrl).post(`/api/v1/wallet/${wallet.id()}/address/1`).reply(200, {
910
+ address: '2NCYjG8Q56yr8tx9jazNoYnGKxjgB2MQSfY',
911
+ });
912
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, {
913
+ address: '2NFbvo2HK4eXZm1aqDcSDGGqD64FPt7T6d8',
914
+ });
915
+ (0, nock_1.default)(bgUrl).get('/api/v1/tx/fee').query(true).reply(200, {
916
+ feePerKb: 0,
917
+ });
918
+ (0, nock_1.default)(bgUrl)
919
+ .post(`/api/v1/keychain/${userKeypair.xpub}`, {})
920
+ .reply(200, {
921
+ encryptedXprv: bitgo.encrypt({ input: userKeypair.xprv, password: TestBitGo.TEST_WALLET1_PASSCODE }),
922
+ path: userKeypair.path + userKeypair.walletSubPath,
923
+ });
924
+ });
925
+ it('accelerates a stuck tx without additional unspents', async () => {
926
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
927
+ (0, nock_1.default)(bgUrl)
928
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
929
+ .reply(200, {
930
+ fee: 434,
931
+ outputs: [
932
+ {
933
+ vout: 0,
934
+ value: 10348500,
935
+ isMine: true,
936
+ chain: 1,
937
+ },
938
+ {
939
+ vout: 1,
940
+ value: 10000,
941
+ isMine: true,
942
+ chain: 11,
943
+ },
944
+ ],
945
+ });
946
+ (0, nock_1.default)(bgUrl)
947
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
948
+ .query(true)
949
+ .reply(200, {
950
+ unspents: [
951
+ {
952
+ tx_hash: parentTxId,
953
+ tx_output_n: 0,
954
+ value: 10348500,
955
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
956
+ chainPath: '/11/160',
957
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
958
+ },
959
+ ],
960
+ });
961
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
962
+ (0, nock_1.default)(bgUrl)
963
+ .post('/api/v1/tx/send', (body) => {
964
+ return !body.ignoreMaxFeeRate;
965
+ })
966
+ .reply(200, function (_, body) {
967
+ return {
968
+ transaction: body.tx,
969
+ };
970
+ });
971
+ const childTx = await wallet.accelerateTransaction({
972
+ transactionID: parentTxId,
973
+ feeRate,
974
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
975
+ });
976
+ should.exist(childTx);
977
+ childTx.should.have.property('status', 'accepted');
978
+ childTx.should.have.property('tx');
979
+ // assert the following:
980
+ // 0) The child tx has exactly one input
981
+ // 1) The parent tx output is an input
982
+ // 2) The child tx has exactly one output
983
+ // 3) The child tx output meets the minimum change threshold
984
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
985
+ decodedChild.ins.length.should.equal(1);
986
+ decodedChild.outs.length.should.equal(1);
987
+ const childInput = decodedChild.ins[0];
988
+ childInput.should.have.property('index', 0);
989
+ childInput.should.have.property('hash');
990
+ const inputTxId = inputParentTxId(childInput);
991
+ inputTxId.should.equal(parentTxId);
992
+ const childOutput = decodedChild.outs[0];
993
+ childOutput.should.have.property('value');
994
+ childOutput.value.should.be.above(minChangeSize);
995
+ });
996
+ it('accelerates a stuck tx with one additional segwit unspent', async () => {
997
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
998
+ const additionalUnspentTxId = '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87';
999
+ (0, nock_1.default)(bgUrl)
1000
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1001
+ .reply(200, {
1002
+ fee: 1336,
1003
+ outputs: [
1004
+ {
1005
+ vout: 0,
1006
+ value: 10000,
1007
+ isMine: true,
1008
+ chain: 11,
1009
+ },
1010
+ {
1011
+ vout: 1,
1012
+ value: 8664,
1013
+ isMine: true,
1014
+ chain: 1,
1015
+ },
1016
+ ],
1017
+ confirmations: 0,
1018
+ });
1019
+ (0, nock_1.default)(bgUrl)
1020
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1021
+ .query(true)
1022
+ .reply(200, {
1023
+ unspents: [
1024
+ {
1025
+ tx_hash: parentTxId,
1026
+ tx_output_n: 0,
1027
+ value: 10000,
1028
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1029
+ chainPath: '/0/0',
1030
+ },
1031
+ ],
1032
+ });
1033
+ (0, nock_1.default)(bgUrl)
1034
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1035
+ .query(true)
1036
+ .reply(200, {
1037
+ unspents: [
1038
+ {
1039
+ tx_hash: additionalUnspentTxId,
1040
+ tx_output_n: 0,
1041
+ value: 19935526,
1042
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1043
+ chainPath: '/11/155',
1044
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1045
+ },
1046
+ ],
1047
+ });
1048
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1049
+ (0, nock_1.default)(bgUrl)
1050
+ .post('/api/v1/tx/send', (body) => {
1051
+ return !body.ignoreMaxFeeRate;
1052
+ })
1053
+ .reply(200, function (_, body) {
1054
+ return {
1055
+ transaction: body.tx,
1056
+ };
1057
+ });
1058
+ const childTx = await wallet.accelerateTransaction({
1059
+ transactionID: parentTxId,
1060
+ feeRate,
1061
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1062
+ });
1063
+ should.exist(childTx);
1064
+ childTx.should.have.property('status', 'accepted');
1065
+ childTx.should.have.property('tx');
1066
+ // assert the following:
1067
+ // 0) The child tx has exactly two inputs
1068
+ // 1) The parent tx output is an input
1069
+ // 2) The additional unspent output is an input
1070
+ // 3) The child tx has exactly one output
1071
+ // 4) The child tx output meets the minimum change threshold
1072
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1073
+ decodedChild.ins.length.should.equal(2);
1074
+ decodedChild.outs.length.should.equal(1);
1075
+ let inputFromParent = undefined;
1076
+ let additionalInput = undefined;
1077
+ _.forEach(decodedChild.ins, (input) => {
1078
+ input.should.have.property('hash');
1079
+ input.should.have.property('index');
1080
+ const inputTxId = inputParentTxId(input);
1081
+ if (inputTxId === parentTxId) {
1082
+ inputFromParent = input;
1083
+ }
1084
+ else {
1085
+ additionalInput = input;
1086
+ }
1087
+ });
1088
+ should.exist(inputFromParent);
1089
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1090
+ inputFromParentHash.should.equal(parentTxId);
1091
+ inputFromParent.index.should.equal(0);
1092
+ should.exist(additionalInput);
1093
+ const additionalInputHash = inputParentTxId(additionalInput);
1094
+ additionalInputHash.should.equal(additionalUnspentTxId);
1095
+ additionalInput.index.should.equal(0);
1096
+ const childOutput = decodedChild.outs[0];
1097
+ childOutput.should.have.property('value');
1098
+ childOutput.value.should.be.above(minChangeSize);
1099
+ });
1100
+ it('accelerates a stuck tx with one additional P2SH unspent', async () => {
1101
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1102
+ const additionalUnspentTxId = 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58';
1103
+ (0, nock_1.default)(bgUrl)
1104
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1105
+ .reply(200, {
1106
+ fee: 1336,
1107
+ outputs: [
1108
+ {
1109
+ vout: 0,
1110
+ value: 10000,
1111
+ isMine: true,
1112
+ chain: 11,
1113
+ },
1114
+ {
1115
+ vout: 1,
1116
+ value: 8664,
1117
+ isMine: true,
1118
+ chain: 1,
1119
+ },
1120
+ ],
1121
+ confirmations: 0,
1122
+ });
1123
+ (0, nock_1.default)(bgUrl)
1124
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1125
+ .query(true)
1126
+ .reply(200, {
1127
+ unspents: [
1128
+ {
1129
+ tx_hash: parentTxId,
1130
+ tx_output_n: 0,
1131
+ value: 10000,
1132
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1133
+ chainPath: '/0/0',
1134
+ },
1135
+ ],
1136
+ });
1137
+ (0, nock_1.default)(bgUrl)
1138
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1139
+ .query(true)
1140
+ .reply(200, {
1141
+ unspents: [
1142
+ {
1143
+ tx_hash: additionalUnspentTxId,
1144
+ tx_output_n: 1,
1145
+ value: 20000000,
1146
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1147
+ chainPath: '/0/0',
1148
+ },
1149
+ ],
1150
+ });
1151
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1152
+ (0, nock_1.default)(bgUrl)
1153
+ .post('/api/v1/tx/send', (body) => {
1154
+ return !body.ignoreMaxFeeRate;
1155
+ })
1156
+ .reply(200, function (_, body) {
1157
+ return {
1158
+ transaction: body.tx,
1159
+ };
1160
+ });
1161
+ const childTx = await wallet.accelerateTransaction({
1162
+ transactionID: parentTxId,
1163
+ feeRate,
1164
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1165
+ });
1166
+ should.exist(childTx);
1167
+ childTx.should.have.property('status', 'accepted');
1168
+ childTx.should.have.property('tx');
1169
+ // assert the following:
1170
+ // 0) The child tx has exactly two inputs
1171
+ // 1) The parent tx output is an input
1172
+ // 2) The additional unspent output is an input
1173
+ // 3) The child tx has exactly one output
1174
+ // 4) The child tx output meets the minimum change threshold
1175
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1176
+ decodedChild.ins.length.should.equal(2);
1177
+ decodedChild.outs.length.should.equal(1);
1178
+ let inputFromParent = undefined;
1179
+ let additionalInput = undefined;
1180
+ _.forEach(decodedChild.ins, (input) => {
1181
+ input.should.have.property('hash');
1182
+ input.should.have.property('index');
1183
+ const inputHash = inputParentTxId(input);
1184
+ if (inputHash === parentTxId) {
1185
+ inputFromParent = input;
1186
+ }
1187
+ else {
1188
+ additionalInput = input;
1189
+ }
1190
+ });
1191
+ should.exist(inputFromParent);
1192
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1193
+ inputFromParentHash.should.equal(parentTxId);
1194
+ inputFromParent.index.should.equal(0);
1195
+ should.exist(additionalInput);
1196
+ const additionalInputHash = inputParentTxId(additionalInput);
1197
+ additionalInputHash.should.equal(additionalUnspentTxId);
1198
+ additionalInput.index.should.equal(1);
1199
+ const childOutput = decodedChild.outs[0];
1200
+ childOutput.should.have.property('value');
1201
+ childOutput.value.should.be.above(minChangeSize);
1202
+ });
1203
+ it('accelerates a stuck tx with two additional unspents (segwit and P2SH)', async () => {
1204
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1205
+ (0, nock_1.default)(bgUrl)
1206
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1207
+ .reply(200, {
1208
+ fee: 1336,
1209
+ outputs: [
1210
+ {
1211
+ vout: 0,
1212
+ value: 10000,
1213
+ isMine: true,
1214
+ chain: 11,
1215
+ },
1216
+ {
1217
+ vout: 1,
1218
+ value: 8664,
1219
+ isMine: true,
1220
+ chain: 1,
1221
+ },
1222
+ ],
1223
+ confirmations: 0,
1224
+ });
1225
+ (0, nock_1.default)(bgUrl)
1226
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1227
+ .query(true)
1228
+ .reply(200, {
1229
+ unspents: [
1230
+ {
1231
+ tx_hash: parentTxId,
1232
+ tx_output_n: 0,
1233
+ value: 10000,
1234
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1235
+ chainPath: '/0/0',
1236
+ },
1237
+ ],
1238
+ });
1239
+ (0, nock_1.default)(bgUrl)
1240
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1241
+ .query(true)
1242
+ .reply(200, {
1243
+ unspents: [
1244
+ {
1245
+ tx_hash: 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58',
1246
+ tx_output_n: 1,
1247
+ value: 800000,
1248
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1249
+ chainPath: '/0/0',
1250
+ },
1251
+ {
1252
+ tx_hash: '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87',
1253
+ tx_output_n: 0,
1254
+ value: 20006284,
1255
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1256
+ chainPath: '/11/155',
1257
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1258
+ },
1259
+ ],
1260
+ });
1261
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1262
+ (0, nock_1.default)(bgUrl)
1263
+ .post('/api/v1/tx/send', (body) => {
1264
+ return !body.ignoreMaxFeeRate;
1265
+ })
1266
+ .reply(200, function (_, body) {
1267
+ return {
1268
+ transaction: body.tx,
1269
+ };
1270
+ });
1271
+ const childTx = await wallet.accelerateTransaction({
1272
+ transactionID: parentTxId,
1273
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1274
+ feeRate,
1275
+ });
1276
+ should.exist(childTx);
1277
+ childTx.should.have.property('status', 'accepted');
1278
+ childTx.should.have.property('tx');
1279
+ // assert the following:
1280
+ // 0) The child tx has exactly three inputs
1281
+ // 1) The parent tx output is an input
1282
+ // 2) The child tx has exactly one output
1283
+ // 3) The child tx output meets the minimum change threshold
1284
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1285
+ decodedChild.ins.length.should.equal(3);
1286
+ decodedChild.outs.length.should.equal(1);
1287
+ let inputFromParent = undefined;
1288
+ const additionalInputs = [];
1289
+ _.forEach(decodedChild.ins, (input) => {
1290
+ input.should.have.property('hash');
1291
+ input.should.have.property('index');
1292
+ const inputHash = inputParentTxId(input);
1293
+ if (inputHash === parentTxId) {
1294
+ inputFromParent = input;
1295
+ }
1296
+ else {
1297
+ additionalInputs.push(input);
1298
+ }
1299
+ });
1300
+ should.exist(inputFromParent);
1301
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1302
+ inputFromParentHash.should.equal(parentTxId);
1303
+ inputFromParent.index.should.equal(0);
1304
+ additionalInputs.length.should.equal(2);
1305
+ const childOutput = decodedChild.outs[0];
1306
+ childOutput.should.have.property('value');
1307
+ childOutput.value.should.be.above(minChangeSize);
1308
+ });
1309
+ it('correctly uses the ignoreMaxFeeRate parameter only when necessary', async () => {
1310
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
1311
+ (0, nock_1.default)(bgUrl)
1312
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1313
+ .reply(200, {
1314
+ fee: 434,
1315
+ outputs: [
1316
+ {
1317
+ vout: 0,
1318
+ value: 10348500,
1319
+ isMine: true,
1320
+ chain: 0,
1321
+ },
1322
+ {
1323
+ vout: 1,
1324
+ value: 10000,
1325
+ isMine: true,
1326
+ chain: 11,
1327
+ },
1328
+ ],
1329
+ });
1330
+ (0, nock_1.default)(bgUrl)
1331
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1332
+ .query(true)
1333
+ .reply(200, {
1334
+ unspents: [
1335
+ {
1336
+ tx_hash: parentTxId,
1337
+ tx_output_n: 0,
1338
+ value: 10348500,
1339
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
1340
+ chainPath: '/11/160',
1341
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
1342
+ },
1343
+ ],
1344
+ });
1345
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1346
+ (0, nock_1.default)(bgUrl)
1347
+ .post('/api/v1/tx/send', (body) => {
1348
+ // ignore max fee rate must be set for this test
1349
+ return body.ignoreMaxFeeRate;
1350
+ })
1351
+ .reply(200);
1352
+ // monkey patch the bitgo getConstants() function
1353
+ const oldGetConstants = bitgo.__proto__.getConstants;
1354
+ bitgo.__proto__.getConstants = () => ({
1355
+ // child fee rate in this test is 31378 sat/kb
1356
+ // so set the max fee rate just below that limit,
1357
+ // but above the combined fee rate of 20000
1358
+ maxFeeRate: 30000,
1359
+ });
1360
+ await wallet.accelerateTransaction({
1361
+ transactionID: parentTxId,
1362
+ feeRate,
1363
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1364
+ });
1365
+ nock_1.default.pendingMocks().should.be.empty();
1366
+ bitgo.__proto__.getConstants = oldGetConstants;
1367
+ });
1368
+ });
1369
+ });
1370
+ });
1371
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3YxL3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLG1CQUFtQjtBQUNuQixFQUFFO0FBQ0Ysb0RBQW9EO0FBQ3BELEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUYseUNBQXdDO0FBRXhDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ2pELG9EQUFpRDtBQUNqRCwwQ0FBNEI7QUFDNUIsbURBQThDO0FBQzlDLDhEQUFnRDtBQUNoRCwrQ0FBaUM7QUFDakMsZ0RBQXdCO0FBQ3hCLDZDQUErQjtBQUUvQiw0REFBdUQ7QUFFdkQsY0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIsTUFBTSxTQUFTLEdBQUc7SUFDaEIscUJBQXFCLEVBQUUsMEJBQTBCO0NBQ2xELENBQUM7QUFDRixRQUFRLENBQUMsMEJBQTBCLEVBQUU7SUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBQSwyQkFBVyxHQUFFLENBQUM7SUFFL0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxtQkFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLDhCQUE4QjtJQUU5QixNQUFNLFdBQVcsR0FBRztRQUNsQixJQUFJLEVBQUUsaUhBQWlIO1FBQ3ZILElBQUksRUFBRSxpSEFBaUg7UUFDdkgsTUFBTSxFQUFFLG9FQUFvRTtRQUM1RSxNQUFNLEVBQUUsa0VBQWtFO1FBQzFFLElBQUksRUFBRSxHQUFHO1FBQ1QsYUFBYSxFQUFFLE1BQU07S0FDdEIsQ0FBQztJQUNGLE1BQU0sYUFBYSxHQUFHO1FBQ3BCLElBQUksRUFBRSxpSEFBaUg7UUFDdkgsSUFBSSxFQUFFLGlIQUFpSDtRQUN2SCxN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Q2pELDJDQUEyQztvQkFDM0MsVUFBVSxFQUFFLEtBQUs7aUJBQ2xCLENBQUMsQ0FBQztnQkFFSCxNQUFNLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztvQkFDakMsYUFBYSxFQUFFLFVBQVU7b0JBQ3pCLE9BQU87b0JBQ1AsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLHFCQUFxQjtpQkFDbEQsQ0FBQyxDQUFDO2dCQUNILGNBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUVyQyxLQUFhLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxlQUFlLENBQUM7WUFDMUQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvL1xuLy8gVGVzdHMgZm9yIFdhbGxldFxuLy9cbi8vIENvcHlyaWdodCAyMDE0LCBCaXRHbywgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vXG5cbmltcG9ydCB7IGdldEZpeHR1cmUgfSBmcm9tICcuL2ZpeHR1cmVzJztcblxuY29uc3QgV2FsbGV0ID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjL3YxL3dhbGxldCcpO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z29BUEknO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgY29tbW9uIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCBub2NrIGZyb20gJ25vY2snO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuXG5pbXBvcnQgeyBnZXRGaXh0dXJlcyB9IGZyb20gJy4vZml4dHVyZXMvYWNjZWxlcmF0ZS10eCc7XG5cbm5vY2suZGlzYWJsZU5ldENvbm5lY3QoKTtcblxuY29uc3QgVGVzdEJpdEdvID0ge1xuICBURVNUX1dBTExFVDFfUEFTU0NPREU6ICdpVldlQVRqcUxTMWpKU2hyUHBFVHRpMGInLFxufTtcbmRlc2NyaWJlKCdXYWxsZXQgUHJvdG90eXBlIE1ldGhvZHMnLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGZpeHR1cmVzID0gZ2V0Rml4dHVyZXMoKTtcblxuICBsZXQgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgLy8gYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG5cbiAgY29uc3QgdXNlcktleXBhaXIgPSB7XG4gICAgeHBydjogJ3hwcnY5czIxWnJRSDE0M0syZko5MVM0QlJzdXBjWXJFNm1tWTk2ZmNYNUhraG9UcnJ3bXdqZDE2Q244N2NXaW5KakJ5cmZwb2pqeDdlenNKTHg3VEFLTFQ4bThoTTVLYXg5WWNveG5CZUpaM3QyaycsXG4gICAgeHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGOU5jN1RiQm8xclpBYWdpV0VWUFdLYkRLVGhORzh6cWprNzZIQUtMa2FTYlRuNmRLMmRRUGZ1RDd4amljeENaVld2ajY3ZlA1blE5VzdRVVJtb01WQVg4bTZqWnNHcCcsXG4gICAgcmF3UHViOiAnMDJjMTAzYWM3NDQ4MTg3NGI1ZWYwZjM4NWQxMjcyNWU0ZjE0YWVkYzllMDBiYzgxNGNlOTZmNDdmNjJjZTdhZGYyJyxcbiAgICByYXdQcnY6ICc5MzZjNWFmM2Y4YWY4MWY3NWNkYWQxYjA4ZjI5ZTdkOWMwMWU1OThlMmRiMmQ3YmUxOGI5ZTVhODY0NmU4N2M2JyxcbiAgICBwYXRoOiAnbScsXG4gICAgd2FsbGV0U3ViUGF0aDogJy8wLzAnLFxuICB9O1xuICBjb25zdCBiYWNrdXBLZXlwYWlyID0ge1xuICAgIHhwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLNDdzRWtMa3lrZ1ltcTF4RjVaV3JQWWhVWmNtQnBQRk1Rb2p2R1VtRWNyNWpGWFlHZnI4Q3BGZHBUdmhRN0w5Tk4yckx0c0JGalNpeDNCQWp3SmNCajZVM0Q1aHhUUGMnLFxuICAgIHhwdWI6ICd4cHViNjYxTXlNd0FxUmJjR2J3aHJOSHo3cFZXUDNualYyRWhrbWQ1TjFBb05pbkxIYzU0cDI1VkFlUUQ2cTJvVFMzdXVETURuZm5YbnRoYlM5dWZDOEpWWXBObldVNVJuM3BZYU51TENOeXdrdzEnLFxuICAgIHJhd1B1YjogJzAzYmJjYjczOTk3OTc3MDY4ZDllMzY2NjZiYmQ1Y2QzNzU3OWFjYWU4ZTJiZDVjZTlkMGE2ZTVjMTUwYTQyM2JjMycsXG4gICAgcmF3UHJ2OiAnNzdhMTVmMTQ3OTZmNDAwMWQxMDkyYWU4NGY3NjZiZDg2OWU5YmVlNmJmZmFlNjU0N2RlZjUwNDViOTZmYTk0MycsXG4gICAgcGF0aDogJ20nLFxuICAgIHdhbGxldFN1YlBhdGg6ICcvMC8wJyxcbiAgfTtcbiAgY29uc3QgYml0Z29LZXkgPSB7XG4gICAgeHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHUWNWRml3Y3J0YzdjM3ZvcHNYOTZqc0pVWVBjRk1SRWNSVHFBcXNxYnYyWlJ5Q0pBUExtNU5NSEN5ODVFM1p3cFQ0RUFVdzlXR1U3dk1oRzZ6ODNoRGVLWEJXbjZMZicsXG4gICAgcGF0aDogJ20nLFxuICAgIHdhbGxldFN1YlBhdGg6ICcvMC8wJyxcbiAgfTtcblxuICBjb25zdCBmYWtlV2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywge1xuICAgIGlkOiAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnLFxuICAgIHByaXZhdGU6IHsga2V5Y2hhaW5zOiBbdXNlcktleXBhaXIsIGJhY2t1cEtleXBhaXIsIGJpdGdvS2V5XSB9LFxuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgQWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmUoKCkgPT4gbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKSk7XG5cbiAgICBpdCgnZ2VuZXJhdGUgZmlyc3QgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGlkQWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzAnLCBzZWd3aXQ6IGZhbHNlIH0pO1xuICAgICAgaWRBZGRyZXNzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGZha2VXYWxsZXQuaWQoKSk7XG4gICAgICBpZEFkZHJlc3MuY2hhaW4uc2hvdWxkLmVxdWFsKDApO1xuICAgICAgaWRBZGRyZXNzLmluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIGlkQWRkcmVzcy5jaGFpblBhdGguc2hvdWxkLmVxdWFsKCcvMC8wJyk7XG4gICAgICBpZEFkZHJlc3MucGF0aC5zaG91bGQuZXF1YWwoJy8wLzAnKTtcbiAgICAgIGlkQWRkcmVzcy5vdXRwdXRTY3JpcHQuc2hvdWxkLmVxdWFsKCdhOTE0ZDY4MjQ3NmU5YmQ1NDQ1NGE4ODVmOWRmZjFlNjA0ZTk5Y2VmNDNkYzg3Jyk7XG4gICAgICBpZEFkZHJlc3MucmVkZWVtU2NyaXB0LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzUyMjEwMmNkM2M4ZTYwMDZhNDYyNzcwNTAyMWQxZDAxNmQwOTdjMjk0NGQ5ODEwMGE0N2JmMmRhNjdhNWZlMTVhZWViMzQyMTAyZWUxZmE5ZTgxMmU3NzkzNTZhYTNjMzFlYmYzMTdkMGNmZmViYWI5Mjg2NGNmZTM4YmFiMjIzZTA4MjBmOThiYzIxMDI2YmEwNTc1MmJhYTZlYWZkNWM1NjU5ZGE2MmI3ZjBhYzUxZmQyODg2YjY1YzI0MWQwYWZlZjFjNGZkZmExY2JjNTNhZSdcbiAgICAgICk7XG4gICAgICBpZEFkZHJlc3Mud2FsbGV0LnNob3VsZC5lcXVhbChmYWtlV2FsbGV0LmlkKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2dlbmVyYXRlIHNlY29uZCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIHAyc2hBZGRyZXNzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcyTjV5NVJMVnFkWmk3cXA1UG16TWRQUjZZdlF6VXFCUUZXSycpO1xuICAgICAgcDJzaEFkZHJlc3MuY2hhaW4uc2hvdWxkLmVxdWFsKDApO1xuICAgICAgcDJzaEFkZHJlc3MuaW5kZXguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgcDJzaEFkZHJlc3MuY2hhaW5QYXRoLnNob3VsZC5lcXVhbCgnLzAvMScpO1xuICAgICAgcDJzaEFkZHJlc3MucGF0aC5zaG91bGQuZXF1YWwoJy8wLzEnKTtcbiAgICAgIHAyc2hBZGRyZXNzLm91dHB1dFNjcmlwdC5zaG91bGQuZXF1YWwoJ2E5MTQ4YjhiZDNkYTY4ZWYwZjI0NjU1MjMxNDZiZDJkZTMzYzg2YjljODcxODcnKTtcbiAgICAgIHAyc2hBZGRyZXNzLnJlZGVlbVNjcmlwdC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1MjIxMDI3MDllZGI2YTIxOThkMzY0YzQ4NWE3NmI5ODFkMTIwNjVlYWJkZThhYTJkODViZDdlN2EwMzVmN2VjYjM1NzliMjEwMmE3MjRlZmVkNDk5YzA1ZmRiNGRhMWUxMzk3MDA5NTFmYWUwMGMwMDZiMzI4Mzg4OGJkZmQxYjQ2OTc5MjkyMjQyMTAyYjMyYWJlNDRkNjE5ODZmZjU3YjgzNWUzYmQxNjI5M2Q5M2YzMDNkMGQ4ZmIwNDU0ZTJjOWNjZWRhNWM0OTI5ODUzYWUnXG4gICAgICApO1xuICAgICAgcDJzaEFkZHJlc3Mud2FsbGV0LnNob3VsZC5lcXVhbChmYWtlV2FsbGV0LmlkKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2dlbmVyYXRlIGNoYW5nZSBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMS8wJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIHAyc2hBZGRyZXNzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcyTkZqOUpycFpjNU15WW5Db3V5UkV0ek5ZNGVveUtXRGZnUCcpO1xuICAgICAgcDJzaEFkZHJlc3MuY2hhaW4uc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgcDJzaEFkZHJlc3MuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgcDJzaEFkZHJlc3MuY2hhaW5QYXRoLnNob3VsZC5lcXVhbCgnLzEvMCcpO1xuICAgICAgcDJzaEFkZHJlc3MucGF0aC5zaG91bGQuZXF1YWwoJy8xLzAnKTtcbiAgICAgIHAyc2hBZGRyZXNzLm91dHB1dFNjcmlwdC5zaG91bGQuZXF1YWwoJ2E5MTRmNjlhODFmYWQ3NWVhNjVhZDE2NmRhNzY1MTUyOTE2NzlhNGYxYWQ4ODcnKTtcbiAgICAgIHAyc2hBZGRyZXNzLnJlZGVlbVNjcmlwdC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1MjIxMDIwYjRjNGY4OTFhNTUyMGY1YTBiNjgxOGQ4ZDUzOTE5NTUyYTBkNGQ4MDZiNWZhMDVjOTc3MDgwNzlkODM3MzdlMjEwMmM1Y2M0OWJmMDMzMWViMGIwODkwYTdlN2Q4N2Y3ZTllMGRlYTUxNTQzODI4MGRjNzY4MzRjMjFkMTk4ZWZlMDgyMTAzNzBlNTJjZjc0MWViZjQ1MTM3NDlkMDI4ODM5ZDY5Njg5MWViNzg5YmE3YTU4NTkyY2ZiYzg1N2NkYzBhOWRlNzUzYWUnXG4gICAgICApO1xuICAgICAgcDJzaEFkZHJlc3Mud2FsbGV0LnNob3VsZC5lcXVhbChmYWtlV2FsbGV0LmlkKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2dlbmVyYXRlIHNlZ3dpdCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2Vnd2l0QWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8wJywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMk41RVZlZ1JQV25tZWQyUHBxRGdnWlB3N0RjTkRndVJZdjgnKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MuY2hhaW4uc2hvdWxkLmVxdWFsKDEwKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3MuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5jaGFpblBhdGguc2hvdWxkLmVxdWFsKCcvMTAvMCcpO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5wYXRoLnNob3VsZC5lcXVhbCgnLzEwLzAnKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3Mub3V0cHV0U2NyaXB0LnNob3VsZC5lcXVhbCgnYTkxNDgzN2UyYWRjYjZmNjM4NmZlYTNjNWQ0MDMxNmIyODJjY2YzOTEyMWQ4NycpO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5yZWRlZW1TY3JpcHQuc2hvdWxkLmVxdWFsKCcwMDIwYTYyYWZlZTFkMjExYzVhZGI5NzM5ZjgxZWQ0ZTM2MzMwZTZjZGE2NTFjN2JkZDMxNGUzMmNjYzQ2NWVjMjIwMycpO1xuICAgICAgc2Vnd2l0QWRkcmVzcy53aXRuZXNzU2NyaXB0LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzUyMjEwMjdiMzA1MDU3NzdhNGVkODk0N2IwNjlmY2IwMTE2ZTI4Nzk5NWQ5NzI3OGQ4NGRhNGRiNmM2MTMyNzA2NDlkM2QyMTAzNGMzMGU1MWYxZTYxNGNhZDY2NzgxNWM5MWQwNDE0MDRjMTgyMjVkMGIyZjc5ZTJjMGJjYjYzZmQyNjA0MzE2YjIxMDNiNjVkZGZjMDYxNTliNjkxNjkzMzkwNzYxZTc1YTBiOGNjN2E2NWI2ZmYzMDVkMDk0ZjNhZDk3MmYxNzk1M2ZlNTNhZSdcbiAgICAgICk7XG4gICAgICBzZWd3aXRBZGRyZXNzLndhbGxldC5zaG91bGQuZXF1YWwoZmFrZVdhbGxldC5pZCgpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NyZWF0ZSBUcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgYmdVcmwsIGJnVXJsVGVzdDtcbiAgICBsZXQgZmFrZVByb2RXYWxsZXQ7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICAgIGNvbnN0IHByb2RCaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Byb2QnLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAgICAgLy8gcHJvZEJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW3Byb2RCaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgZmFrZVByb2RXYWxsZXQgPSBuZXcgV2FsbGV0KHByb2RCaXRnbywge1xuICAgICAgICBpZDogJzJOQ29TZkhINkxzNENkVFM1UWFoZ0M5azd4OVJmWGVTd1k0JyxcbiAgICAgICAgcHJpdmF0ZTogeyBrZXljaGFpbnM6IFt1c2VyS2V5cGFpciwgYmFja3VwS2V5cGFpciwgYml0Z29LZXldIH0sXG4gICAgICB9KTtcbiAgICAgIGJnVXJsVGVzdCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICB9KTtcblxuICAgIGl0KCdleHRyYSB1bnNwZW50IGZldGNoIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpbGxpbmdBZGRyZXNzID0gJzNKOTh0MVdwRVo3M0NObVF2aWVjcm55aVdybnFSaFdOTHknO1xuICAgICAgY29uc3QgY3VzdG9tVW5zcGVudHNGZXRjaFBhcmFtcyA9IHsgdGVzdDogMTIzIH07XG4gICAgICBjb25zdCBzZW5kQW1vdW50ID0gMWU1O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiBiaWxsaW5nQWRkcmVzcyB9KTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke2Zha2VQcm9kV2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgLnF1ZXJ5KFxuICAgICAgICAgIF8ubWVyZ2UoY3VzdG9tVW5zcGVudHNGZXRjaFBhcmFtcywge1xuICAgICAgICAgICAgc2Vnd2l0OiB0cnVlLFxuICAgICAgICAgICAgdGFyZ2V0OiBzZW5kQW1vdW50LFxuICAgICAgICAgICAgbWluU2l6ZTogMCxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDAsIHsgdW5zcGVudHM6IFtdIH0pO1xuXG4gICAgICBhd2FpdCBmYWtlUHJvZFdhbGxldFxuICAgICAgICAuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHVuc3BlbnRzRmV0Y2hQYXJhbXM6IGN1c3RvbVVuc3BlbnRzRmV0Y2hQYXJhbXMsXG4gICAgICAgICAgcmVjaXBpZW50czogeyBbYmlsbGluZ0FkZHJlc3NdOiBzZW5kQW1vdW50IH0sXG4gICAgICAgICAgZmVlUmF0ZTogMTAwMDAsXG4gICAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICAgIGFkZHJlc3M6ICcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCcwIHVuc3BlbnRzIGF2YWlsYWJsZSBmb3IgdHJhbnNhY3Rpb24gY3JlYXRpb24nKTtcblxuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdkZWZhdWx0IHAyc2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VQcm9kV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xMycsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCB1bnNwZW50OiBhbnkgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTkNFRG1tS05ObnFLdm5XdzdwRTNSTHp1RmU1YUhIVnkxWCddLFxuICAgICAgICB2YWx1ZTogJzAuMDA1MDQ0MjInLFxuICAgICAgICB2YWx1ZV9pbnQ6IDUwNDQyMixcbiAgICAgICAgdHhpZDogJ2I4MTZkZWQ4OWMzZDhkNTAyMWIwMTA5N2Y0YTMxMjlhNmE2OGE1Y2I3Yzg4NmU5Nzk0NWY0MjA1Y2JhNWRlNDQnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDksXG4gICAgICAgIGlkOiA2MTMzMDIyOSxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBwMnNoQWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBwMnNoQWRkcmVzcy5hZGRyZXNzLFxuICAgICAgICB1bnNwZW50czogW3Vuc3BlbnRdLFxuICAgICAgICByZWNpcGllbnRzOiB7fSxcbiAgICAgICAgbm9TcGxpdENoYW5nZTogdHJ1ZSxcbiAgICAgICAgZm9yY2VDaGFuZ2VBdEVuZDogdHJ1ZSxcbiAgICAgICAgZmVlUmF0ZTogMTAwMDAsXG4gICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgIGFkZHJlc3M6ICcnLFxuICAgICAgICB9LFxuICAgICAgICBvcFJldHVybnM6IHsgJ0JpdEdvIHAyc2ggdGVzdCc6IDEwMDAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwMDBmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTQ0ZGVhNWNiMDU0MjVmOTQ5NzZlODg3Y2NiYTU2ODZhOWExMmEzZjQ5NzEwYjAyMTUwOGQzZDljZDhkZTE2YjgwMTAwMDAwMGI2MDA0NzMwNDQwMjIwMjFmYTczZDVmZTYxYWM4OTQyY2Q3MGZmNDUwN2M1NzQ2NzdjZTc0N2RlNWJjNDZjM2RkMmUzOGVjMjQ0OGZjZTAyMjA0NzkwNmQyYzAxNTQzMzdhYjk2MDQxZThmYjU4YzI0M2I5YmNlNWY4ODE4ZmE5OTE2NDNjMTI2MGExODU5YWQ4MDEwMDAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIHNlY29uZCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4ID0gc2lnbmF0dXJlMS50eDtcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gYmFja3VwS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZ1bGxMb2NhbFNpZ25pbmcgPSB0cnVlO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICAvLyBUaGlzIHRyYW5zYWN0aW9uIGhhcyBhY3R1YWxseSB3b3JrZWQ6IGh0dHBzOi8vdGVzdG5ldC5zbWFydGJpdC5jb20uYXUvdHgvYThjY2I5MjgxNjkwMzJkNmUxZjM3YmY4MWRmZDlhYjZkOTAzNjJhNGY4NGU1NzczOTdmYTY5MGFhNzExNTUwY1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZSB0eCBoZXggYmVsb3cgbm8gbG9uZ2VyIGNvcnJlc3BvbmRzIHRvIHRoZSBhYm92ZSB0cmFuc2FjdGlvbiBiZWNhdXNlIG91ciBmZWUgZXN0aW1hdGlvbiBoYXNcbiAgICAgIC8vIGNoYW5nZWQsIGNoYW5naW5nIHRoZSBvdXRwdXQgYW1vdW50cyBhbmQgdGh1cyB0aGUgdHggaGV4LlxuICAgICAgc2lnbmF0dXJlMi50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwZmRmZDAwMDA0NzMwNDQwMjIwMjFmYTczZDVmZTYxYWM4OTQyY2Q3MGZmNDUwN2M1NzQ2NzdjZTc0N2RlNWJjNDZjM2RkMmUzOGVjMjQ0OGZjZTAyMjA0NzkwNmQyYzAxNTQzMzdhYjk2MDQxZThmYjU4YzI0M2I5YmNlNWY4ODE4ZmE5OTE2NDNjMTI2MGExODU5YWQ4MDE0NzMwNDQwMjIwMmFlMDFmMDFiNWFlMGMzZmE3ZDY3YWM3M2RiODE5MzJjYjVhY2ExMGRiMTZhOTkwNjNmZWY0NWUzZjEzOThjZDAyMjA1NTAwMWJhN2UxNjNjYjM1MDkxMGZjNzMyMWVjZDdlYjYzNTliMzIxZDRjMDQ4ODc0ODRkOWM3Mjg0Yjc4YzQ3MDEwMDRjNjk1MjIxMDMxY2QyMjdlNDBhZDYxYjRlMTM3MTA5Y2IyODQ1ZWI2ZjVhNTg0ZWQ1YzY3ZDlkMzEzNWNkYWE1MDQ1YTg0MmVhMjEwM2EyZTdiNTRjN2IyZGEwOTkyNTU1MzUzYjhlMjZjNmFjZmY0MjQ4ZjQzNTFmMDg3ODdiZjNlMmVmYzk0YjY1ODMyMTAyNWMyYTZjZGUzM2MyZDczY2NmMTJlZWNmNjRjNTRmMDhmNzIyYzJmMDczODI0NDk4OTUwNjk1ZTk4ODNiMTQxMjUzYWVmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnQkNIIHAyc2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VQcm9kV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xMycsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCB1bnNwZW50OiBhbnkgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTkNFRG1tS05ObnFLdm5XdzdwRTNSTHp1RmU1YUhIVnkxWCddLFxuICAgICAgICB2YWx1ZTogJzAuMDA1MDQ0MjInLFxuICAgICAgICB2YWx1ZV9pbnQ6IDUwNDQyMixcbiAgICAgICAgdHhpZDogJ2I4MTZkZWQ4OWMzZDhkNTAyMWIwMTA5N2Y0YTMxMjlhNmE2OGE1Y2I3Yzg4NmU5Nzk0NWY0MjA1Y2JhNWRlNDQnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDksXG4gICAgICAgIGlkOiA2MTMzMDIyOSxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBwMnNoQWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBwMnNoQWRkcmVzcy5hZGRyZXNzLFxuICAgICAgICB1bnNwZW50czogW3Vuc3BlbnRdLFxuICAgICAgICByZWNpcGllbnRzOiB7fSxcbiAgICAgICAgbm9TcGxpdENoYW5nZTogdHJ1ZSxcbiAgICAgICAgZm9yY2VDaGFuZ2VBdEVuZDogdHJ1ZSxcbiAgICAgICAgZmVlUmF0ZTogMTAwMDAsXG4gICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgIGFkZHJlc3M6ICcnLFxuICAgICAgICB9LFxuICAgICAgICBvcFJldHVybnM6IHsgJ0JpdEdvIHAyc2ggdGVzdCc6IDEwMDAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwMDBmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mb3JjZUJDSCA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTQ0ZGVhNWNiMDU0MjVmOTQ5NzZlODg3Y2NiYTU2ODZhOWExMmEzZjQ5NzEwYjAyMTUwOGQzZDljZDhkZTE2YjgwMTAwMDAwMGI2MDA0NzMwNDQwMjIwNjIyMWE5N2YwODFkODdlMDJlM2IxNDk4OGE2NDg2MTgxMWE2YThkZTRmMTFmNzRmNWFhZWE0NTk4MWNmNjEyZTAyMjA3N2EwOGE1YmQ3ZDc4MWU3OTgzOGFmYmIxMjZhZjJlNDg4MDJmZWZhZDY2MGFmZGJkODgwNWY1ZTU5OGVkNTg4NDEwMDAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbiBoYXMgYWN0dWFsbHkgd29ya2VkOiBodHRwczovL3Rlc3RuZXQuc21hcnRiaXQuY29tLmF1L3R4L2E4Y2NiOTI4MTY5MDMyZDZlMWYzN2JmODFkZmQ5YWI2ZDkwMzYyYTRmODRlNTc3Mzk3ZmE2OTBhYTcxMTU1MGNcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGUgdHggaGV4IGJlbG93IG5vIGxvbmdlciBjb3JyZXNwb25kcyB0byB0aGUgYWJvdmUgdHJhbnNhY3Rpb24gYmVjYXVzZSBvdXIgZmVlIGVzdGltYXRpb24gaGFzXG4gICAgICAvLyBjaGFuZ2VkLCBjaGFuZ2luZyB0aGUgb3V0cHV0IGFtb3VudHMgYW5kIHRodXMgdGhlIHR4IGhleC5cbiAgICAgIHNpZ25hdHVyZTIudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTQ0ZGVhNWNiMDU0MjVmOTQ5NzZlODg3Y2NiYTU2ODZhOWExMmEzZjQ5NzEwYjAyMTUwOGQzZDljZDhkZTE2YjgwMTAwMDAwMGZkZmUwMDAwNDczMDQ0MDIyMDYyMjFhOTdmMDgxZDg3ZTAyZTNiMTQ5ODhhNjQ4NjE4MTFhNmE4ZGU0ZjExZjc0ZjVhYWVhNDU5ODFjZjYxMmUwMjIwNzdhMDhhNWJkN2Q3ODFlNzk4MzhhZmJiMTI2YWYyZTQ4ODAyZmVmYWQ2NjBhZmRiZDg4MDVmNWU1OThlZDU4ODQxNDgzMDQ1MDIyMTAwODJiYzU0NjI5Mzg1ODQ1OWYzODk1ZGIyNGM4NWNjZjM3NTA1YzU2ZjhmYWY0YmI4Zjc4Y2Y0MDEzNWJjMmYyYjAyMjAzZGMxYzc4ZDdjN2NlYWY2YjkyNGVjYTNjMzliOTVlOGEyMjdiMDY5YTA3MDQ3NTgxMjczMTM2YjQ3Y2E3YWM0NDEwMDRjNjk1MjIxMDMxY2QyMjdlNDBhZDYxYjRlMTM3MTA5Y2IyODQ1ZWI2ZjVhNTg0ZWQ1YzY3ZDlkMzEzNWNkYWE1MDQ1YTg0MmVhMjEwM2EyZTdiNTRjN2IyZGEwOTkyNTU1MzUzYjhlMjZjNmFjZmY0MjQ4ZjQzNTFmMDg3ODdiZjNlMmVmYzk0YjY1ODMyMTAyNWMyYTZjZGUzM2MyZDczY2NmMTJlZWNmNjRjNTRmMDhmNzIyYzJmMDczODI0NDk4OTUwNjk1ZTk4ODNiMTQxMjUzYWVmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDExNmEwZjQyNjk3NDQ3NmYyMDcwMzI3MzY4MjA3NDY1NzM3NDIyYTEwNzAwMDAwMDAwMDAxN2E5MTRkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExODcwMDAwMDAwMCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnZGVmYXVsdCBzZWd3aXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8xMycsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJNeEtrSDh5QjNTOVlXbVRRUmJ2bWJvcllReVFuSDVwZXRQJ10sXG4gICAgICAgIHZhbHVlOiAnMC4xODc1MDAwMCcsXG4gICAgICAgIHZhbHVlX2ludDogMTg3NTAwMDAsXG4gICAgICAgIHR4aWQ6ICc3ZDI4Mjg3OGE4NWRhZWU1ZDQ2ZTA0MzgyN2RhZWQ1NzU5NmQ3NWQxYWE2ZTA0ZmQwYzA5YTM2ZjkxMzA4ODFmJyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzE2MTcsXG4gICAgICB9O1xuICAgICAgXy5leHRlbmQodW5zcGVudCwgc2Vnd2l0QWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBzZWd3aXRBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gc2Vnd2l0IHRlc3QnOiAxMDAwIH0sXG4gICAgICB9KSkgYXMgYW55O1xuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTFmODgzMDkxNmZhMzA5MGNmZDA0NmVhYWQxNzU2ZDU5NTdlZGRhMjczODA0NmVkNGU1YWU1ZGE4NzgyODI4N2QwMDAwMDAwMDAwZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMzZhMTE0MjY5NzQ0NzZmMjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0MGUwZjFlMDEwMDAwMDAwMDE3YTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTEgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgc2lnbmF0dXJlMS50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAwMDEwMTFmODgzMDkxNmZhMzA5MGNmZDA0NmVhYWQxNzU2ZDU5NTdlZGRhMjczODA0NmVkNGU1YWU1ZGE4NzgyODI4N2QwMDAwMDAwMDIzMjIwMDIwNDQwZTg1ODIyOGI3NTM1NDRiNGM1N2UzMDAyOTZiNTU3MTdmODExMDUzODgzZjliZTliNmE3MTJlYWNkOTMxY2ZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTM2YTExNDI2OTc0NDc2ZjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDBlMGYxZTAxMDAwMDAwMDAxN2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcwNTAwNDgzMDQ1MDIyMTAwYmYzYTg5MTRhMWJmZTkyNjYxZjI3Y2EzN2MwZDZiNWMwYjNjNzM1MzYxNGM5NTU2NDY5MjlmMmU3ZWI4OWZmZTAyMjAyZDU1NmIwZmZhYjM3YzEwNGJhZTY3NDA2Y2ExNmY4ODU5Y2ZhMzdjNmE0MGYyMDEzZDg5YWZjZWNkNTU5NGYzMDEwMDAwNjk1MjIxMDMyYzUwNWZjOGExZTRiNTY4MTFiMjczNjZhMzcxZTYxYzlmYWY1NjVkZDJmYWJhZmY3YTcwZWFjMTljMzIxNTdjMjEwMjUxMTYwYjU4M2JkNWRjMGYwZDQ4MDk2NTA1MTMxYzQzNDdhYjY1YjRmMjFlZDU3ZDc2YzM4MTU3NDk5YzAwM2QyMTAyNjc5NzEyZDYyYTI1NjA5MTdjYzQzZmQyY2MzYTFiOWI2MWY1MjhjODhiYzY0OTA1YmFlNmVlMDc5ZTYwNjA5ZjUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbiBoYXMgYWN0dWFsbHkgd29ya2VkOiBodHRwczovL3Rlc3RuZXQuc21hcnRiaXQuY29tLmF1L3R4L2Q2NzI2NmYxZGU5MDViYWFlZTc1MDAxMWZhNGIzZDg4YThlM2ExNzU4ZDUxNzNhNjU5YzY3NzA5NDg4ZGRlMDdcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGUgdHggaGV4IGJlbG93IG5vIGxvbmdlciBjb3JyZXNwb25kcyB0byB0aGUgYWJvdmUgdHJhbnNhY3Rpb24gYmVjYXVzZSBvdXIgZmVlIGVzdGltYXRpb24gaGFzXG4gICAgICAvLyBjaGFuZ2VkLCBjaGFuZ2luZyB0aGUgb3V0cHV0IGFtb3VudHMgYW5kIHRodXMgdGhlIHR4IGhleC5cbiAgICAgIHNpZ25hdHVyZTIudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDExZjg4MzA5MTZmYTMwOTBjZmQwNDZlYWFkMTc1NmQ1OTU3ZWRkYTI3MzgwNDZlZDRlNWFlNWRhODc4MjgyODdkMDAwMDAwMDAyMzIyMDAyMDQ0MGU4NTgyMjhiNzUzNTQ0YjRjNTdlMzAwMjk2YjU1NzE3ZjgxMTA1Mzg4M2Y5YmU5YjZhNzEyZWFjZDkzMWNmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDEzNmExMTQyNjk3NDQ3NmYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQwZTBmMWUwMTAwMDAwMDAwMTdhOTE0MzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YTg3MDUwMDQ4MzA0NTAyMjEwMGJmM2E4OTE0YTFiZmU5MjY2MWYyN2NhMzdjMGQ2YjVjMGIzYzczNTM2MTRjOTU1NjQ2OTI5ZjJlN2ViODlmZmUwMjIwMmQ1NTZiMGZmYWIzN2MxMDRiYWU2NzQwNmNhMTZmODg1OWNmYTM3YzZhNDBmMjAxM2Q4OWFmY2VjZDU1OTRmMzAxNDczMDQ0MDIyMDVjZjhkMmYyYmU2Y2UwODNkMzU2NTRiZGMzZmE4NWQ3ZTcxYjIyN2Q0NTdlOTI0NWJiNjAzYjIxZTdiNTE2NTEwMjIwM2VhNjg2MjI2ZGI4MzIwZTA4YzI2YmZiMzA0MDQ4YjNhOTQ3M2QwZTA1Nzk3ZDM2NThkYWNiMmYwOWEyYjUxYzAxMDA2OTUyMjEwMzJjNTA1ZmM4YTFlNGI1NjgxMWIyNzM2NmEzNzFlNjFjOWZhZjU2NWRkMmZhYmFmZjdhNzBlYWMxOWMzMjE1N2MyMTAyNTExNjBiNTgzYmQ1ZGMwZjBkNDgwOTY1MDUxMzFjNDM0N2FiNjViNGYyMWVkNTdkNzZjMzgxNTc0OTljMDAzZDIxMDI2Nzk3MTJkNjJhMjU2MDkxN2NjNDNmZDJjYzNhMWI5YjYxZjUyOGM4OGJjNjQ5MDViYWU2ZWUwNzllNjA2MDlmNTNhZTAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGFuIHVuc2lnbmVkIHR4IG1hZGUgb2YgdW5jb21wcmVzc2VkIHB1YmxpYyBrZXlzIG9mIHYxIHNhZmUgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyBhZGRyZXNzLCByZWRlZW1TY3JpcHQsIHNjcmlwdFB1YktleSB9ID0gYXdhaXQgZ2V0Rml4dHVyZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgICAgIGAke19fZGlybmFtZX0vZml4dHVyZXMvc2lnbi10cmFuc2FjdGlvbi5qc29uYFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHRlc3RCaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Rlc3QnLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAgICAgY29uc3QgZmFrZVRlc3RWMVNhZmVXYWxsZXQgPSBuZXcgV2FsbGV0KHRlc3RCaXRnbywge1xuICAgICAgICBpZDogYWRkcmVzcyxcbiAgICAgICAgcHJpdmF0ZTogeyBzYWZlOiB7IHJlZGVlbVNjcmlwdCB9IH0sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnRzVG9TcGVuZCA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiAxMDAwMDAsXG4gICAgICAgICAgcmVkZWVtU2NyaXB0LFxuICAgICAgICAgIHNjcmlwdDogc2NyaXB0UHViS2V5LFxuICAgICAgICAgIHR4X2hhc2g6ICdhNTVkMTFkYzhiNzAxYmQxOTYwMWZiZmU3MTFhMWU0NjVmYzhmMTI4ZWM0NDc0ZTc4ZTFmZDA4N2U4MDhlNWZlJyxcbiAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICBjb25maXJtYXRpb25zOiAxLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IDEwMDAwMCxcbiAgICAgICAgICByZWRlZW1TY3JpcHQsXG4gICAgICAgICAgc2NyaXB0OiBzY3JpcHRQdWJLZXksXG4gICAgICAgICAgdHhfaGFzaDogJzQ4ZmI4NzljZWM4NzkzNTYwNDVhMzMxOTM3MDIzYWVkODU5ZjVkYzVkYjk1NWExZGM4YTVjY2YyOWY0OWQxMDgnLFxuICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDEsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IHtcbiAgICAgICAgJzJNeUd4cmhMQzRrUmZ1VmpMcUNWWUZ0QzdEY2hoZ01DaU56JzogMTkxMzQwLCAvLyBwdXJwb3NlbHkgc2V0IHRvIHNpbXVsYXRlIGEgc3dlZXAgdHJhbnNhY3Rpb25cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybFRlc3QpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJOM0w5Y3U5V04yRGY3WHZiMVk4b3dva3VEVmo1SGR5djRpJyB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmFrZVRlc3RWMVNhZmVXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICByZWNpcGllbnRzLFxuICAgICAgICB1bnNwZW50czogdW5zcGVudHNUb1NwZW5kLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCwgLy8gMTAgc2F0L2J5dGVcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgcmVzdWx0LmVzdGltYXRlZFNpemUuc2hvdWxkLmVxdWFsKDg2Nik7XG4gICAgICByZXN1bHQuZmVlLnNob3VsZC5lcXVhbCg4NjYwKTtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIGVxdWFsIHRvIDEgYmVjYXVzZSB0aGlzIGlzIGEgc3dlZXAgdHJhbnNhY3Rpb24gYnV0IGR1ZSB0byBoYXJkY29kZWQgYWRkaXRpb24gb2ZcbiAgICAgIC8vIDEgY2hhbmdlIG91dHB1dCBpbiB0cmFuc2FjdGlvbkJ1aWxkZXIsIGl0IGlzIDIuXG4gICAgICAvLyBCZWNhdXNlIG9mIHRoaXMgdGhlIGVzdGltYXRlZCBzaXplIG9mIHRoZSB0cmFuc2FjdGlvbnMgaXMgbW9yZSB0aGFuIHdoYXQgaXQgYWN0dWFsbHkgaXMgaW4gdGhlIGhleC5cbiAgICAgIHJlc3VsdC50eEluZm8ubk91dHB1dHMuc2hvdWxkLmVxdWFsKDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3NpZ25zIGFuIHVuc2lnbmVkIHR4IG1hZGUgb2YgdW5jb21wcmVzc2VkIHB1YmxpYyBrZXlzIG9mIHYxIHNhZmUgd2FsbGV0ICYgdmVyaWZpZXMgc2lnbmF0dXJlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYWRkcmVzcyxcbiAgICAgICAgcmVkZWVtU2NyaXB0LFxuICAgICAgICBzY3JpcHRQdWJLZXksXG4gICAgICAgIHVzZXJLZXlXSUY6IHVzZXJTaWduaW5nS2V5LFxuICAgICAgICBiaXRnb0tleVdJRjogYml0Z29TaWduaW5nS2V5LFxuICAgICAgICB1bnNpZ25lZFR4SGV4LFxuICAgICAgICBoYWxmU2lnbmVkVHhIZXgsXG4gICAgICAgIGZ1bGxTaWduZWRUeEhleCxcbiAgICAgIH0gPSBhd2FpdCBnZXRGaXh0dXJlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PihgJHtfX2Rpcm5hbWV9L2ZpeHR1cmVzL3NpZ24tdHJhbnNhY3Rpb24uanNvbmApO1xuICAgICAgY29uc3QgdGVzdEJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAndGVzdCcsIGNsaWVudENvbnN0YW50czogeyBjb25zdGFudHM6IHt9IH0gfSk7XG4gICAgICBjb25zdCBmYWtlVGVzdFYxU2FmZVdhbGxldCA9IG5ldyBXYWxsZXQodGVzdEJpdGdvLCB7XG4gICAgICAgIGlkOiBhZGRyZXNzLFxuICAgICAgICBwcml2YXRlOiB7IHNhZmU6IHsgcmVkZWVtU2NyaXB0IH0gfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zcGVudHNUb1NwZW5kID0gW1xuICAgICAgICB7IHZhbHVlOiAxMDAwMDAsIHJlZGVlbVNjcmlwdCwgc2NyaXB0OiBzY3JpcHRQdWJLZXkgfSxcbiAgICAgICAgeyB2YWx1ZTogMTAwMDAwLCByZWRlZW1TY3JpcHQsIHNjcmlwdDogc2NyaXB0UHViS2V5IH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgaGFsZlNpZ25lZFR4ID0gYXdhaXQgZmFrZVRlc3RWMVNhZmVXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHJhbnNhY3Rpb25IZXg6IHVuc2lnbmVkVHhIZXgsXG4gICAgICAgIHNpZ25pbmdLZXk6IHVzZXJTaWduaW5nS2V5LFxuICAgICAgICB1bnNwZW50czogdW5zcGVudHNUb1NwZW5kLFxuICAgICAgICB2YWxpZGF0ZTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgaGFsZlNpZ25lZFR4LnR4LnNob3VsZC5lcXVhbChoYWxmU2lnbmVkVHhIZXgpO1xuXG4gICAgICBjb25zdCBmdWxsU2lnbmVkVHggPSBhd2FpdCBmYWtlVGVzdFYxU2FmZVdhbGxldC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0cmFuc2FjdGlvbkhleDogaGFsZlNpZ25lZFR4SGV4LFxuICAgICAgICBzaWduaW5nS2V5OiBiaXRnb1NpZ25pbmdLZXksXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50c1RvU3BlbmQsXG4gICAgICAgIHZhbGlkYXRlOiB0cnVlLFxuICAgICAgICBmdWxsTG9jYWxTaWduaW5nOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICAvLyBVcG9uIGNhbGxpbmcgdHhiLmJ1aWxkKCkgaW5zdGVhZCBhZnRlciBnZXR0aW5nIDIgdmFsaWQgc2lnbmF0dXJlcywgd2UgZ2V0IGEgdmFsaWQgZnVsbCBzaWduZWQgdHggdGhhdCB3YXMgYnJvYWRjYXN0XG4gICAgICAvLyBhbmQgY29uZmlybWVkIG9uIHRlc3RuZXQgaGVyZTogaHR0cHM6Ly9tZW1wb29sLnNwYWNlL3Rlc3RuZXQvdHgvYmRlMDlmMWJkNWU2NjYxYzI4ZDkwZTRjOTYyOTE4NTNlMjFiYTE1YWI0MmYzZTRhMzA3MTlkZWNiNzNlNzkxYlxuICAgICAgLy8gSXQncyBwcmVzZW50IGluIHRoZSBmdWxsU2lnbmVkVHhIZXhCdWlsZENvbXBsZXRlIHByb3BlcnR5IG9mIHRoZSBmaXh0dXJlLlxuICAgICAgZnVsbFNpZ25lZFR4LnR4LnNob3VsZC5lcXVhbChmdWxsU2lnbmVkVHhIZXgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ0JDSCBzZWd3aXQgc2hvdWxkIGZhaWwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xMC8xMycsIHNlZ3dpdDogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJNeEtrSDh5QjNTOVlXbVRRUmJ2bWJvcllReVFuSDVwZXRQJ10sXG4gICAgICAgIHZhbHVlOiAnMC4xODc1MDAwMCcsXG4gICAgICAgIHZhbHVlX2ludDogMTg3NTAwMDAsXG4gICAgICAgIHR4aWQ6ICc3ZDI4Mjg3OGE4NWRhZWU1ZDQ2ZTA0MzgyN2RhZWQ1NzU5NmQ3NWQxYWE2ZTA0ZmQwYzA5YTM2ZjkxMzA4ODFmJyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzE2MTcsXG4gICAgICB9O1xuICAgICAgXy5leHRlbmQodW5zcGVudCwgc2Vnd2l0QWRkcmVzcyk7XG4gICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICB1bnNwZW50LnR4X2hhc2ggPSB1bnNwZW50LnR4aWQ7XG4gICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHsgYWRkcmVzczogJzJNc3dRamt2TjZvV1lkRTdMMmJySjVjQUFNalBtRzU5b2NvJyB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuY3JlYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICBjaGFuZ2VBZGRyZXNzOiBzZWd3aXRBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gc2Vnd2l0IHRlc3QnOiAxMDAwIH0sXG4gICAgICB9KSkgYXMgYW55O1xuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMTFmODgzMDkxNmZhMzA5MGNmZDA0NmVhYWQxNzU2ZDU5NTdlZGRhMjczODA0NmVkNGU1YWU1ZGE4NzgyODI4N2QwMDAwMDAwMDAwZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMzZhMTE0MjY5NzQ0NzZmMjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0MGUwZjFlMDEwMDAwMDAwMDE3YTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZvcmNlQkNIID0gdHJ1ZTtcbiAgICAgICgoKSA9PiBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKS5zaG91bGQudGhyb3coJ0JDSCBkb2VzIG5vdCBzdXBwb3J0IHNlZ3dpdCBpbnB1dHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdtaXhlZCBwMnNoICYgc2Vnd2l0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xNCcsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzE0Jywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgcDJzaFVuc3BlbnQgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTjUzM2ZxZ3lQWUtWRDg5Mm5CUmFZbUZIYmJUeWtoWVNFdyddLFxuICAgICAgICB2YWx1ZTogJzIuOTk5OTY2MTAnLFxuICAgICAgICB2YWx1ZV9pbnQ6IDI5OTk5NjYxMCxcbiAgICAgICAgdHhpZDogJ2Y2NTRjZTBhNWJlM2YxMmRmN2ZlY2Y0ZWU3NzdiNmQ4NmI1YWE4YzcxMGVmNjk0NmVjMTIxMjA2YjRmODc1N2MnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1MiBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTI2MyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZWd3aXRVbnNwZW50ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk5CdHBYY0RydWYzelJ1dG1GNEFiQ01GTlFIWHNHTlA2a1QnXSxcbiAgICAgICAgdmFsdWU6ICcxLjUwMDAwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxNTAwMDAwMDAsXG4gICAgICAgIHR4aWQ6ICdhNDQwOWMzZjA0MmZhZTY3Yjg5MGFjM2RmNDBlZjBkYjAzNTM5YzY3MzMxZmQ3ZTkyNjA1MTE4OTNiNGY5ZjI0JyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIGNjOGU3Y2JmNDgxMzg5ZDMxODNhNTkwYWNmYTZhYTY2ZWI5N2M4ZTEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTRjYzhlN2NiZjQ4MTM4OWQzMTgzYTU5MGFjZmE2YWE2NmViOTdjOGUxODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzA4ODIsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWRkcmVzc2VzID0gW3Ayc2hBZGRyZXNzLCBzZWd3aXRBZGRyZXNzXTtcbiAgICAgIGNvbnN0IHVuc3BlbnRzID0gW3Ayc2hVbnNwZW50LCBzZWd3aXRVbnNwZW50XS5tYXAoKHVuc3BlbnQ6IGFueSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IGFkZHJlc3Nlc1tpbmRleF07XG4gICAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIGFkZHJlc3MpO1xuICAgICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgICAgdW5zcGVudC50eF9vdXRwdXRfbiA9IHVuc3BlbnQubjtcbiAgICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcbiAgICAgICAgcmV0dXJuIHVuc3BlbnQ7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50cyxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBvcFJldHVybnM6IHsgJ0JpdEdvIG1peGVkIHAyc2ggJiBzZWd3aXQgdGVzdCc6IDQwMDAwMDAwMCB9LFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogODE3NjAsXG4gICAgICAgICAgYWRkcmVzczogJzJORDdqUVI1aXRqR1RiaDNES2dicFpXU1k5dW5nRHJ3Y3diJyxcbiAgICAgICAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwMDBmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDAwZmZmZmZmZmYwMzAwODRkNzE3MDAwMDAwMDAyMDZhMWU0MjY5NzQ0NzZmMjA2ZDY5Nzg2NTY0MjA3MDMyNzM2ODIwMjYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzRiMDhmZjkwMjAwMDAwMDAwMTdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3NjAzZjAxMDAwMDAwMDAwMDE3YTkxNGQ5ZjdiZTQ3OTc1YzAzNmY5NDIyOGIwYmZkNzA3MDE5MTI3NThiYTk4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTEgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgc2lnbmF0dXJlMS50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAwMDEwMjdjNzVmOGI0MDYxMjEyZWM0NjY5ZWYxMGM3YTg1YTZiZDhiNjc3ZTc0ZWNmZmVmNzJkZjFlMzViMGFjZTU0ZjYwMTAwMDAwMGI3MDA0ODMwNDUwMjIxMDBmZmM0NWQ5M2NiYWY0YzFjODUwZTIxZjI3N2M1YjMxMWQzZTM5NTdmMTMzODk1NWNiMTY1ZDcyYTc2OGEwNTRjMDIyMDUyMDIwNTkzYjM2NzgxZWVhMDBhOWY4ZGNiZWI3NjYwOGY5MjBjN2E5MzNhOTA4ODMxOGFiMmY3MGMxMWUxZDkwMTAwMDA0YzY5NTIyMTAzZGE5NWIyOGExM2FhMmQ0YmI0OTBkNzA2MjhlMmU1ZDkxMjQ2MWQzNzVmZWYzODFhYWRkODlkYzEyNTYyMjA3NTIxMDMxMjEyODdhNTEwYzVmMzJlOGJhNzJkMjQ3OWU5MGViNTJiYTQ0YTQ2NzE3M2RmMzM5ZmViMGZmMjE1ZjEwMGUzMjEwMjk3N2NkZmJlZTc2MDY2YWU3MzlkYjcyZDU1MzcxYWQ0OWRjNjcxMmZiOGYyZjNmNjliYjFhNGMyNDIyYjBiMWE1M2FlZmZmZmZmZmYyNDlmNGYzYjg5MTEwNTI2ZTlkNzFmMzM2NzljNTMwM2RiZjAwZWY0M2RhYzkwYjg2N2FlMmYwNDNmOWM0MGE0MDAwMDAwMDAyMzIyMDAyMDhiOTFhYTAzZWIwZjdmMzFlMzkxNzA4ODA4NDE2OGJhNTI4MmE5MTVlN2NkZTBhNWE5MzRiN2VhMDJlYjA1N2JmZmZmZmZmZjAzMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NGIwOGZmOTAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDczMDQ0MDIyMDU4OThiZWU3MTE0NjdjMDlhNWUyMmUxZGNiMWExMWZjZTFhMGQ2ZWExMjlkOTExZjgxM2Y4N2M3ZDQ1ZTA2N2IwMjIwMmY2OWZiMTE4YmJmMGIwNzJlZDI2ZDcyY2Y4MDczZTdhY2Q2NmMyMDU0MTlhNGEwMGY4NmE3YmEwZjZlM2RkNjAxMDAwMDY5NTIyMTAzMDc4MDE4NmMwYmU1ZGYwZDJkNjJjZjU0Y2MyZjNkMmMwOTkxMWUzNzdhYTk1YjVmZTg3NWZhMzUyYWVkMGE1OTIxMDNmMzIzN2VkZDJkODcwMTBlOGZlOWY0M2YzNGU4YzYzZGU2Mzg0MjgzZGU5MDk3OTVkNjJhZjRkZGI0ZDU3OTU0MjEwMmFkMDNkZTU1MDRlZjk0N2U0ZTZlZTJmYTZiMTVkMTUwZDU1M2MyMTI3NWY0OWYyY2UyMzU5ZDlmZGVkYjlhZGU1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgc2Vjb25kIHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXggPSBzaWduYXR1cmUxLnR4O1xuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSBiYWNrdXBLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZnVsbExvY2FsU2lnbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUyID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIC8vIHRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9lMmY2OTZiY2JhOTFhMzc2YzM2YmI1MjVkZjhjMzY3OTM4ZjZlMmZkNjM0NGM5MDU4N2JmMTI4MDIwOTExMjRjXG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwZmRmZjAwMDA0ODMwNDUwMjIxMDBmZmM0NWQ5M2NiYWY0YzFjODUwZTIxZjI3N2M1YjMxMWQzZTM5NTdmMTMzODk1NWNiMTY1ZDcyYTc2OGEwNTRjMDIyMDUyMDIwNTkzYjM2NzgxZWVhMDBhOWY4ZGNiZWI3NjYwOGY5MjBjN2E5MzNhOTA4ODMxOGFiMmY3MGMxMWUxZDkwMTQ4MzA0NTAyMjEwMDgyNTRkMTAwNDAxYTNhODMxZWQwMTllMTY2MmRiZDkwYjk2YzZjNDA3MmI4MWNlNjQwZDE1MmJjMjkyOTVjMTAwMjIwMTNmODZjNWFmNTcxNjIzNDk5OWE3YmQ2ZTk0ZmM4ZjQyOGY3Njk3Y2MzMTM4YjM2NDlkMGVjNGRkODY4MWJjNzAxMDA0YzY5NTIyMTAzZGE5NWIyOGExM2FhMmQ0YmI0OTBkNzA2MjhlMmU1ZDkxMjQ2MWQzNzVmZWYzODFhYWRkODlkYzEyNTYyMjA3NTIxMDMxMjEyODdhNTEwYzVmMzJlOGJhNzJkMjQ3OWU5MGViNTJiYTQ0YTQ2NzE3M2RmMzM5ZmViMGZmMjE1ZjEwMGUzMjEwMjk3N2NkZmJlZTc2MDY2YWU3MzlkYjcyZDU1MzcxYWQ0OWRjNjcxMmZiOGYyZjNmNjliYjFhNGMyNDIyYjBiMWE1M2FlZmZmZmZmZmYyNDlmNGYzYjg5MTEwNTI2ZTlkNzFmMzM2NzljNTMwM2RiZjAwZWY0M2RhYzkwYjg2N2FlMmYwNDNmOWM0MGE0MDAwMDAwMDAyMzIyMDAyMDhiOTFhYTAzZWIwZjdmMzFlMzkxNzA4ODA4NDE2OGJhNTI4MmE5MTVlN2NkZTBhNWE5MzRiN2VhMDJlYjA1N2JmZmZmZmZmZjAzMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NGIwOGZmOTAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDczMDQ0MDIyMDU4OThiZWU3MTE0NjdjMDlhNWUyMmUxZGNiMWExMWZjZTFhMGQ2ZWExMjlkOTExZjgxM2Y4N2M3ZDQ1ZTA2N2IwMjIwMmY2OWZiMTE4YmJmMGIwNzJlZDI2ZDcyY2Y4MDczZTdhY2Q2NmMyMDU0MTlhNGEwMGY4NmE3YmEwZjZlM2RkNjAxNDczMDQ0MDIyMDc3MTNkNjcxYjQ1OTg5Njg4ZTI2NjVjMmIxMWFiN2U1ZWE4ZDU3ZWIxNGY5ZGEyMzNjMDk1ZGFiZTQ0MTMwOGQwMjIwNjk1MjFiNWFlYjA3MWIwN2E3MGE3MTk3YTBjMmJiYzQwYTIzYWU2M2EwNDE2MGNmMzYyNzI1MGM0YmE0YzQwZjAxMDA2OTUyMjEwMzA3ODAxODZjMGJlNWRmMGQyZDYyY2Y1NGNjMmYzZDJjMDk5MTFlMzc3YWE5NWI1ZmU4NzVmYTM1MmFlZDBhNTkyMTAzZjMyMzdlZGQyZDg3MDEwZThmZTlmNDNmMzRlOGM2M2RlNjM4NDI4M2RlOTA5Nzk1ZDYyYWY0ZGRiNGQ1Nzk1NDIxMDJhZDAzZGU1NTA0ZWY5NDdlNGU2ZWUyZmE2YjE1ZDE1MGQ1NTNjMjEyNzVmNDlmMmNlMjM1OWQ5ZmRlZGI5YWRlNTNhZTAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2VuZCB0byBiZWNoMzIgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcDJzaEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMC8xNCcsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzE0Jywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgcDJzaFVuc3BlbnQgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTjUzM2ZxZ3lQWUtWRDg5Mm5CUmFZbUZIYmJUeWtoWVNFdyddLFxuICAgICAgICB2YWx1ZTogJzIuOTk5OTY2MTAnLFxuICAgICAgICB2YWx1ZV9pbnQ6IDI5OTk5NjYxMCxcbiAgICAgICAgdHhpZDogJ2Y2NTRjZTBhNWJlM2YxMmRmN2ZlY2Y0ZWU3NzdiNmQ4NmI1YWE4YzcxMGVmNjk0NmVjMTIxMjA2YjRmODc1N2MnLFxuICAgICAgICBuOiAxLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1MiBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTI2MyxcbiAgICAgIH07XG4gICAgICBjb25zdCBzZWd3aXRVbnNwZW50ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk5CdHBYY0RydWYzelJ1dG1GNEFiQ01GTlFIWHNHTlA2a1QnXSxcbiAgICAgICAgdmFsdWU6ICcxLjUwMDAwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxNTAwMDAwMDAsXG4gICAgICAgIHR4aWQ6ICdhNDQwOWMzZjA0MmZhZTY3Yjg5MGFjM2RmNDBlZjBkYjAzNTM5YzY3MzMxZmQ3ZTkyNjA1MTE4OTNiNGY5ZjI0JyxcbiAgICAgICAgbjogMCxcbiAgICAgICAgc2NyaXB0X3B1Yl9rZXk6IHtcbiAgICAgICAgICBhc206ICdPUF9IQVNIMTYwIGNjOGU3Y2JmNDgxMzg5ZDMxODNhNTkwYWNmYTZhYTY2ZWI5N2M4ZTEgT1BfRVFVQUwnLFxuICAgICAgICAgIGhleDogJ2E5MTRjYzhlN2NiZjQ4MTM4OWQzMTgzYTU5MGFjZmE2YWE2NmViOTdjOGUxODcnLFxuICAgICAgICB9LFxuICAgICAgICByZXFfc2lnczogMSxcbiAgICAgICAgdHlwZTogJ3NjcmlwdGhhc2gnLFxuICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICBpZDogNjEzMzA4ODIsXG4gICAgICB9O1xuICAgICAgY29uc3QgYWRkcmVzc2VzID0gW3Ayc2hBZGRyZXNzLCBzZWd3aXRBZGRyZXNzXTtcbiAgICAgIGNvbnN0IHVuc3BlbnRzID0gW3Ayc2hVbnNwZW50LCBzZWd3aXRVbnNwZW50XS5tYXAoKHVuc3BlbnQ6IGFueSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IGFkZHJlc3Nlc1tpbmRleF07XG4gICAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIGFkZHJlc3MpO1xuICAgICAgICB1bnNwZW50LnZhbHVlID0gdW5zcGVudC52YWx1ZV9pbnQ7XG4gICAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgICAgdW5zcGVudC50eF9vdXRwdXRfbiA9IHVuc3BlbnQubjtcbiAgICAgICAgdW5zcGVudC5zY3JpcHQgPSB1bnNwZW50Lm91dHB1dFNjcmlwdDtcbiAgICAgICAgcmV0dXJuIHVuc3BlbnQ7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgZmFrZVdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50cyxcbiAgICAgICAgcmVjaXBpZW50czogeyB0YjFxZ3V6eWs0dzZrYXF0cHNjenM1YWowdzhyNzU5OGpxMzZlZ204ZTk4d3FwaDNyd21leDY4c2VzbGdzZzogMzAwMDAwIH0sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBvcFJldHVybnM6IHsgJ0JpdEdvIG1peGVkIHAyc2ggJiBzZWd3aXQgdGVzdCc6IDQwMDAwMDAwMCB9LFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogODE3NjAsXG4gICAgICAgICAgYWRkcmVzczogJzJORDdqUVI1aXRqR1RiaDNES2dicFpXU1k5dW5nRHJ3Y3diJyxcbiAgICAgICAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwMDBmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDAwZmZmZmZmZmYwNGUwOTMwNDAwMDAwMDAwMDAyMjAwMjA0NzA0NGI1NWRhYjc0MGIwYzMwMjg1M2IyN2I4ZTNmNTBhNzkwMjNhY2EzNjdjOTRlZTAwNmYxMWJiNzkzNjhmMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDdjZmFmNDAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgZmlyc3Qgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IHVzZXJLZXlwYWlyO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMSA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICBzaWduYXR1cmUxLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwYjcwMDQ4MzA0NTAyMjEwMDg4MDkzNzc2MzRlNjY3ZDZlMTlmMzhhMTM4YTU1YjJiNjM3MDMxMmFmNzZhNWNhM2I3NzZkZjYxZmM3MTk2MTcwMjIwMjFkOTAzNDdiOTA4NWFiNzFhNzZjODQwMGY5ODRlMzIyYzE1NDUxZWNjNjczZGQzN2RlMzA4ODc0MzZkMzdiNDAxMDAwMDRjNjk1MjIxMDNkYTk1YjI4YTEzYWEyZDRiYjQ5MGQ3MDYyOGUyZTVkOTEyNDYxZDM3NWZlZjM4MWFhZGQ4OWRjMTI1NjIyMDc1MjEwMzEyMTI4N2E1MTBjNWYzMmU4YmE3MmQyNDc5ZTkwZWI1MmJhNDRhNDY3MTczZGYzMzlmZWIwZmYyMTVmMTAwZTMyMTAyOTc3Y2RmYmVlNzYwNjZhZTczOWRiNzJkNTUzNzFhZDQ5ZGM2NzEyZmI4ZjJmM2Y2OWJiMWE0YzI0MjJiMGIxYTUzYWVmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDIzMjIwMDIwOGI5MWFhMDNlYjBmN2YzMWUzOTE3MDg4MDg0MTY4YmE1MjgyYTkxNWU3Y2RlMGE1YTkzNGI3ZWEwMmViMDU3YmZmZmZmZmZmMDRlMDkzMDQwMDAwMDAwMDAwMjIwMDIwNDcwNDRiNTVkYWI3NDBiMGMzMDI4NTNiMjdiOGUzZjUwYTc5MDIzYWNhMzY3Yzk0ZWUwMDZmMTFiYjc5MzY4ZjAwODRkNzE3MDAwMDAwMDAyMDZhMWU0MjY5NzQ0NzZmMjA2ZDY5Nzg2NTY0MjA3MDMyNzM2ODIwMjYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQ3Y2ZhZjQwMjAwMDAwMDAwMTdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3NjAzZjAxMDAwMDAwMDAwMDE3YTkxNGQ5ZjdiZTQ3OTc1YzAzNmY5NDIyOGIwYmZkNzA3MDE5MTI3NThiYTk4NzAwMDUwMDQ4MzA0NTAyMjEwMDhiOTVhYzgzZTQ0YzcyN2I3OWZmYmY0NTcxMTcxOTI1ZDA2Zjg4M2EwNWMxMjJiM2IzM2MwNTVmMGJmZmE3MDEwMjIwN2I1ZWUzNDEyZWE4YTVjZWM0YTVjMzg2ZjFiNDY0YWI2OGQ1MzFjNmM2OTcwNzdiYzQ2MmMwNWViNDRhMjgzMjAxMDAwMDY5NTIyMTAzMDc4MDE4NmMwYmU1ZGYwZDJkNjJjZjU0Y2MyZjNkMmMwOTkxMWUzNzdhYTk1YjVmZTg3NWZhMzUyYWVkMGE1OTIxMDNmMzIzN2VkZDJkODcwMTBlOGZlOWY0M2YzNGU4YzYzZGU2Mzg0MjgzZGU5MDk3OTVkNjJhZjRkZGI0ZDU3OTU0MjEwMmFkMDNkZTU1MDRlZjk0N2U0ZTZlZTJmYTZiMTVkMTUwZDU1M2MyMTI3NWY0OWYyY2UyMzU5ZDlmZGVkYjlhZGU1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgc2Vjb25kIHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXggPSBzaWduYXR1cmUxLnR4O1xuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSBiYWNrdXBLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZnVsbExvY2FsU2lnbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUyID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIGNvbnNvbGUubG9nKCdzaWduYXR1cmUxICcgKyBKU09OLnN0cmluZ2lmeShzaWduYXR1cmUyKSk7XG4gICAgICAvLyB0aGlzIHRyYW5zYWN0aW9uIGhhcyBhY3R1YWxseSB3b3JrZWQ6IGh0dHBzOi8vdGVzdG5ldC5zbWFydGJpdC5jb20uYXUvdHgvZTJmNjk2YmNiYTkxYTM3NmMzNmJiNTI1ZGY4YzM2NzkzOGY2ZTJmZDYzNDRjOTA1ODdiZjEyODAyMDkxMTI0Y1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZSB0eCBoZXggYmVsb3cgbm8gbG9uZ2VyIGNvcnJlc3BvbmRzIHRvIHRoZSBhYm92ZSB0cmFuc2FjdGlvbiBiZWNhdXNlIG91ciBmZWUgZXN0aW1hdGlvbiBoYXNcbiAgICAgIC8vIGNoYW5nZWQsIGNoYW5naW5nIHRoZSBvdXRwdXQgYW1vdW50cyBhbmQgdGh1cyB0aGUgdHggaGV4LlxuICAgICAgc2lnbmF0dXJlMi50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAwMDEwMjdjNzVmOGI0MDYxMjEyZWM0NjY5ZWYxMGM3YTg1YTZiZDhiNjc3ZTc0ZWNmZmVmNzJkZjFlMzViMGFjZTU0ZjYwMTAwMDAwMGZkZmUwMDAwNDgzMDQ1MDIyMTAwODgwOTM3NzYzNGU2NjdkNmUxOWYzOGExMzhhNTViMmI2MzcwMzEyYWY3NmE1Y2EzYjc3NmRmNjFmYzcxOTYxNzAyMjAyMWQ5MDM0N2I5MDg1YWI3MWE3NmM4NDAwZjk4NGUzMjJjMTU0NTFlY2M2NzNkZDM3ZGUzMDg4NzQzNmQzN2I0MDE0NzMwNDQwMjIwNWE1OGU2MDIwNDJiOGU4YTVkYTUwOWQxOWNlMzEwNTAxNDdkZDBmZmNmYmUyYmIzMzdjMjNkNGM4OGY0Y2M0MTAyMjA3NWJmYTQ1NWQxZjc0ZTMwZmJkOWM3ODZjZDQ4MTFhMWRlZmU1NDMxMGYyMzViNDE5M2NlNGZmYTBlODMwOWExMDEwMDRjNjk1MjIxMDNkYTk1YjI4YTEzYWEyZDRiYjQ5MGQ3MDYyOGUyZTVkOTEyNDYxZDM3NWZlZjM4MWFhZGQ4OWRjMTI1NjIyMDc1MjEwMzEyMTI4N2E1MTBjNWYzMmU4YmE3MmQyNDc5ZTkwZWI1MmJhNDRhNDY3MTczZGYzMzlmZWIwZmYyMTVmMTAwZTMyMTAyOTc3Y2RmYmVlNzYwNjZhZTczOWRiNzJkNTUzNzFhZDQ5ZGM2NzEyZmI4ZjJmM2Y2OWJiMWE0YzI0MjJiMGIxYTUzYWVmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDIzMjIwMDIwOGI5MWFhMDNlYjBmN2YzMWUzOTE3MDg4MDg0MTY4YmE1MjgyYTkxNWU3Y2RlMGE1YTkzNGI3ZWEwMmViMDU3YmZmZmZmZmZmMDRlMDkzMDQwMDAwMDAwMDAwMjIwMDIwNDcwNDRiNTVkYWI3NDBiMGMzMDI4NTNiMjdiOGUzZjUwYTc5MDIzYWNhMzY3Yzk0ZWUwMDZmMTFiYjc5MzY4ZjAwODRkNzE3MDAwMDAwMDAyMDZhMWU0MjY5NzQ0NzZmMjA2ZDY5Nzg2NTY0MjA3MDMyNzM2ODIwMjYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQ3Y2ZhZjQwMjAwMDAwMDAwMTdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3NjAzZjAxMDAwMDAwMDAwMDE3YTkxNGQ5ZjdiZTQ3OTc1YzAzNmY5NDIyOGIwYmZkNzA3MDE5MTI3NThiYTk4NzAwMDUwMDQ4MzA0NTAyMjEwMDhiOTVhYzgzZTQ0YzcyN2I3OWZmYmY0NTcxMTcxOTI1ZDA2Zjg4M2EwNWMxMjJiM2IzM2MwNTVmMGJmZmE3MDEwMjIwN2I1ZWUzNDEyZWE4YTVjZWM0YTVjMzg2ZjFiNDY0YWI2OGQ1MzFjNmM2OTcwNzdiYzQ2MmMwNWViNDRhMjgzMjAxNDczMDQ0MDIyMDUzNjkwMjM0NTgyYTY5MTFhMjhjYWU5ZjUzNGM5ODBiN2Q3OTE4NzQ5YTc0MTNjMWM1OTMyN2RlYmYxNmZmMGIwMjIwNTYxNzVmNWMyN2EzNjM0MTZiMmNlNDc5MWFlZmMzZDU1NTQ1Y2FjYmQwNTI3MjAyZTg2OWUxMTI3ZmMyZjI0ZDAxMDA2OTUyMjEwMzA3ODAxODZjMGJlNWRmMGQyZDYyY2Y1NGNjMmYzZDJjMDk5MTFlMzc3YWE5NWI1ZmU4NzVmYTM1MmFlZDBhNTkyMTAzZjMyMzdlZGQyZDg3MDEwZThmZTlmNDNmMzRlOGM2M2RlNjM4NDI4M2RlOTA5Nzk1ZDYyYWY0ZGRiNGQ1Nzk1NDIxMDJhZDAzZGU1NTA0ZWY5NDdlNGU2ZWUyZmE2YjE1ZDE1MGQ1NTNjMjEyNzVmNDlmMmNlMjM1OWQ5ZmRlZGI5YWRlNTNhZTAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NlbmQgTWFueScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgncmVzcG9uZHMgd2l0aCBwcm9wZXIgZmVlIGFuZCBmZWUgcmF0ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcyTXV0cFhWWXM4THlrNzRwVkRuM2VBRzd4bks0V2Mya2pUUScsXG4gICAgICAgICAgICBhbW91bnQ6IDMwMDAwMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVuc3BlbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IDgxNzAsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogODAwMDAwLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIGNvbnN0IGNyZWF0ZUFuZFNpZ25SZXNwb25zZSA9IHtcbiAgICAgICAgYml0Z29GZWU6IDAsXG4gICAgICAgIHRyYXZlbEluZm9zOiBbXSxcbiAgICAgICAgdW5zcGVudHMsXG4gICAgICAgIHR4OiAnaGFsZnNpZ25lZGhleCcsXG4gICAgICB9O1xuICAgICAgc2lub24uc3R1YihmYWtlV2FsbGV0LCAnY3JlYXRlQW5kU2lnblRyYW5zYWN0aW9uJykucmV0dXJucyhQcm9taXNlLnJlc29sdmUoY3JlYXRlQW5kU2lnblJlc3BvbnNlKSk7XG4gICAgICBjb25zdCBnZXRTZW5kVHhSZXNwb25zZSA9ICgpID0+ICh7XG4gICAgICAgIHN0YXR1czogJ2FjY2VwdGVkJyxcbiAgICAgICAgdHg6ICcwMTAwMDAwMDAwMDEwMjI4YjVjM2UyNzg5ZDQ3NzBmYzM5N2VjNzlmYTcyNTVmODYyMzUyOTdjNWEwNGRlZjY3OGI0ODFiOGIwOWU4MWIwMTAwMDAwMDIzMjIwMDIwYjNiYmUwNjc5NjBiZTM5NTAxZjM2NWI4OTk5ZDUzZjJhODI4NWQ4ZDk4MzZmNjFmYWQwMjBlNmE0YTllMjZmZGZmZmZmZmZmMTUxMGU5MDQxMWE4NmM0OWYyYTUyNTQ2YTMyYTAzZmViZGUyYmM2MDQ3NDFmMGU4NWRjNDdhZGVjMzNmNTE1OTAwMDAwMDAwZmRmZDAwMDA0ODMwNDUwMjIxMDBhNDRiYmY5N2IxNTVjNTc3MDM4NjJiZTY5ZDJiMjBjNGIyYWI5ZTk0ZjQwMjU5NTg4MGJmNzQ0MDJjY2M4N2UyMDIyMDBhNGFhZjk4ZjkzOWI2NWM5OGNhMDhlYjk2MDc0YzIyMmVjYjFmYzM3ZTM1OWIxZDY3YTA1ZjFjNTZkZWRmYzAwMTQ3MzA0NDAyMjAwM2YzOTg5YTE0Mjg0ZjEzMmJiYjU1MDExOGMyMDI1NmQ0ZWE3Mzc3MDQxMjNhMjk5NTVhY2MxZDAzZWE2ZWI3MDIyMDE3MjIzZGE3ZWRjZjczMDc2ZDg5ODc1YWEzMzM2MGFhNmExMjE0MTgwN2Y2ODNjNmMxYjlhNWEwZDNmZjYwMTkwMTRjNjk1MjIxMDI1Nzg5ODU3Y2M4YmUxMTBmZjRjYmYzNTRiNTJkZDBlN2U5MzI2YzZiZmUwYWVlNmMzMGMxZWU2OTY2MGMzZGMwMjEwMmY1OGYxYjE1MTZkMDU4MTRhZTY4OGNhNzAxODU2Njk1ZTI3MDUwZTNlMTZkM2EyMzUxMjg0ZDdhZjg0NDk4ODgyMTAyMzg1YzdiY2VjM2YzOGMxM2U4N2I1NThhZWJmMmYyMGE4OTI4ZTdlY2JlMTFlN2MzYTQ3NzkyYmM4ZTMzZmU4ODUzYWVmZmZmZmZmZjAyZTA5MzA0MDAwMDAwMDAwMDE3YTkxNDFkMGM3OTFjZWMzYWYxZjM3ODA4ZDQyZjA0NTkzMDk1ZDZmZGVhMjY4NzA1YmMwNzAwMDAwMDAwMDAxN2E5MTRkOGM3MjBmNjQ2YzdjNTZjNTQ2NzI0OGU0N2M3MmRjMGIyZDMwYmJjODcwNDAwNDczMDQ0MDIyMDFlYWExMzU5ZmZmZDNiZGVjNWI0ODI2OGJkMmYxNTE5M2EyOTljMjJiMTk3MDM1NmYzOTA4ODM0NzMzMjQ2NTEwMjIwNzQxODYyMzJmMDIyNDVhZjljMDk3NzAzMTQ0OGMyYzk5ZTdiN2UyYjA1YjJiYTRiMzJjMzIyN2Q4Y2ExNDk0ZTAxNDgzMDQ1MDIyMTAwYmQ2MWIzNzA1MWMyODUzM2VhMGIwMGRkYTc1YjFjNGYxZGVlMWI2ODNiYjczNTFiMmQ4ZGQ3MjBmNmRmYmUxMTAyMjAzYWNjNGNmOWQyZGQ0NGIyOTRhYTI1ODEyZTk5ZTdkOGViMzczMGU0ZmY2Zjg4OWQzY2RjZDUyNTE5NTc1MGI4MDE2OTUyMjEwMjE5ZDA5M2MxOGMyN2NiNTQ3NzM3YjRhNDlkZGRhYzljMzQxMmIxMGU5Zjg4MGViMzAwNTNjM2ViYTgxOTI4NTQyMTAzNzQ3MTE4ODkyY2FjMWI0ZGExMTUyNmZjNGViZWViZTE2OGRhZTA5MDdjZWZiMWExODEyNTQxY2Q0NmIwNzYwMjIxMDMzOWY3M2I2NzUwZjhmOTFlZmQ0ODRiNWFhMjk3NDMyMWE2Y2MyNzc2ZDViZDc4YjljZmI1ZmUxOGUzYjJkNjYyNTNhZTAwNWE5ZTE2MDAnLFxuICAgICAgICBoYXNoOiAnZjhkZjQzYzJjNjUwYjNiYjExMjc3YWVlNDUzMWRiOTlhNzE1ZmEzYjlkZmQzZDQ1YThkMTcxMzQyYzFiZjc4MCcsXG4gICAgICAgIGluc3RhbnQ6IGZhbHNlLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBleHBlY3RlZFJlc3VsdCA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgIHtcbiAgICAgICAgICBmZWU6IDEyODUsXG4gICAgICAgICAgZmVlUmF0ZTogMjUxOS42MDc4NDMxMzcyNTUsXG4gICAgICAgIH0sXG4gICAgICAgIGdldFNlbmRUeFJlc3BvbnNlKClcbiAgICAgICk7XG4gICAgICBzaW5vbi5zdHViKGZha2VXYWxsZXQsICdzZW5kVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyhnZXRTZW5kVHhSZXNwb25zZSgpKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IChhd2FpdCBmYWtlV2FsbGV0LnNlbmRNYW55KHBhcmFtcykpIGFzIGFueTtcbiAgICAgIHJlc3VsdC50eC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRSZXN1bHQudHgpO1xuICAgICAgcmVzdWx0LmZlZS5zaG91bGQuZXF1YWwoZXhwZWN0ZWRSZXN1bHQuZmVlKTtcbiAgICAgIHJlc3VsdC5mZWVSYXRlLnNob3VsZC5lcXVhbChleHBlY3RlZFJlc3VsdC5mZWVSYXRlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FjY2VsZXJhdGUgVHJhbnNhY3Rpb24gKHNlcnZlciBtb2NrZWQpJywgZnVuY3Rpb24gYWNjZWxlcmF0ZVR4TW9ja2VkRGVzY3JpYmUoKSB7XG4gICAgbGV0IHdhbGxldDtcbiAgICBsZXQgYmdVcmw7XG4gICAgbGV0IGV4cGxvcmVyVXJsO1xuICAgIGxldCBtaW5DaGFuZ2VTaXplO1xuXG4gICAgbGV0IHBhcmVudFR4SWQgPSAnNmE3NGI3NGRmNDk5MWQ5M2MzMmQ3NTEzMzZjODViNWYyZDFlZTU0NGEyZGZiYWUyZTVmNGJlYjRmOTE0ZTVlMCc7XG4gICAgY29uc3Qgb3V0cHV0SWR4ID0gMDtcbiAgICBjb25zdCBvdXRwdXRBZGRyZXNzID0gJzJOQ29TZkhINkxzNENkVFM1UWFoZ0M5azd4OVJmWGVTd1k0JztcbiAgICBjb25zdCB1bnJlbGF0ZWRUeElkID0gJzA4ZjVlMGI0YWNiNWFiODI0NTIyOWRmZTE2MWNlNGNhMGRhMWVjOTgzZTdhMzRiMDllNzJmNTY5NzlhNDY3ZGYnO1xuICAgIGNvbnN0IHdhbGxldElkID0gJzJOQ29TZkhINkxzNENkVFM1UWFoZ0M5azd4OVJmWGVTd1k0JztcblxuICAgIC8qKlxuICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIHBhcmVudCB0cmFuc2FjdGlvbiBJRCBmcm9tIGEgdHJhbnNhY3Rpb24gaW5wdXRcbiAgICAgKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gY29udmVydHMgYGhhc2hgICh3aGljaCBpcyBhIEJ1ZmZlciBvYmplY3QpIHRvIGEgdXNhYmxlIHR4aWQgc3RyaW5nLlxuICAgICAqIFRoZSBpc3N1ZSBpcyB0aGF0IHRoZSBieXRlcyBhcmUgc3RvcmVkIGluIHJldmVyc2Ugb3JkZXIgaW4gdGhlIGJ1ZmZlciwgc29cbiAgICAgKiB0aGUgc2ltcGxlIGFwcHJvYWNoIG9mIGp1c3QgY29tcGFyaW5nIHRoZSBoZXggc3RyaW5ncyBkb2Vzbid0IHdvcmsuXG4gICAgICogSW5zdGVhZCwgdGhlIEJ1ZmZlciBpcyBjb3BpZWQgdG8gYSBuZXcgQnVmZmVyIG9iamVjdCwgdGhlIG5ldyBCdWZmZXJcbiAgICAgKiBvYmplY3QgaXMgcmV2ZXJzZWQgaW4tcGxhY2UsIGFuZCB0aGVuIHRoZSBuZXcgQnVmZmVyIGlzIGNvbnZlcnRlZCB0byBhXG4gICAgICogaGV4IHN0cmluZy4gQWZ0ZXIgdGhpcywgdGhlIHJlc3VsdCBpcyBhIGhleCBzdHJpbmcgd2hpY2ggaXMgdGhlIHBhcmVudCB0eGlkXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaGFzaCBhIGJpdGNvaW5qcy1saWIgdHJhbnNhY3Rpb24gb2JqZWN0J3MgaW5wdXQgaGFzaFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlucHV0UGFyZW50VHhJZCh7IGhhc2ggfSk6IHN0cmluZyB7XG4gICAgICByZXR1cm4gKEJ1ZmZlci5mcm9tKGhhc2gpLnJldmVyc2UoKSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gYWNjZWxlcmF0ZVR4TW9ja2VkQmVmb3JlKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcblxuICAgICAgYml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICdtb2NrJywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgICAgIC8vIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgYml0Z28uc2V0VmFsaWRhdGUoZmFsc2UpO1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgeyBpZDogd2FsbGV0SWQsIHByaXZhdGU6IHsga2V5Y2hhaW5zOiBbdXNlcktleXBhaXIsIGJhY2t1cEtleXBhaXIsIGJpdGdvS2V5XSB9IH0pO1xuICAgICAgKHdhbGxldCBhcyBhbnkpLmJpdGdvID0gYml0Z287XG4gICAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgICAgIGV4cGxvcmVyVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0uYnRjRXhwbG9yZXJCYXNlVXJsO1xuXG4gICAgICAvLyB0cnkgdG8gZ2V0IHRoZSBtaW4gY2hhbmdlIHNpemUgZnJvbSB0aGUgc2VydmVyLCBvdGhlcndpc2UgZGVmYXVsdCB0byAwLjEgQlRDXG4gICAgICAvLyBUT0RPOiBtaW5DaGFuZ2VTaXplIGlzIG5vdCBjdXJyZW50bHkgYSBjb25zdGFudCBkZWZpbmVkIG9uIHRoZSBjbGllbnQgYW5kIHNob3VsZCBiZSBhZGRlZFxuICAgICAgbWluQ2hhbmdlU2l6ZSA9IDFlNztcbiAgICB9KTtcblxuICAgIGFmdGVyKGZ1bmN0aW9uIGFjY2VsZXJhdGVUeE1vY2tlZEFmdGVyKCkge1xuICAgICAgLy8gbWFrZSBzdXJlIGFsbCBub2NrcyBhcmUgY2xlYXJlZCBvciBjb25zdW1lZCBhZnRlciB0aGUgdGVzdHMgYXJlIGNvbXBsZXRlXG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FyZ3VtZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyBmZWVSYXRlOiAxMjMgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXk1pc3NpbmcgcGFyYW1ldGVyOiB0cmFuc2FjdGlvbklEJC8pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IDEyMywgZmVlUmF0ZTogMTIzIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eRXhwZWN0aW5nIHBhcmFtZXRlciBzdHJpbmc6IHRyYW5zYWN0aW9uSUQgYnV0IGZvdW5kIG51bWJlciQvKTtcblxuICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiAnMTIzJyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXk1pc3NpbmcgcGFyYW1ldGVyOiBmZWVSYXRlJC8pO1xuXG4gICAgICBjb25zdCBmZWVSYXRlc1BhcmFtcyA9IFsnMTIzJywgMCwgLTEwLCAtSW5maW5pdHksIEluZmluaXR5LCBOYU5dO1xuICAgICAgZm9yIChjb25zdCBmZWVSYXRlIG9mIGZlZVJhdGVzUGFyYW1zKSB7XG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiAnMTIzJywgZmVlUmF0ZSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eRXhwZWN0aW5nIHBvc2l0aXZlIGZpbml0ZSBudW1iZXIgZm9yIHBhcmFtZXRlcjogZmVlUmF0ZSQvKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdiYWQgaW5wdXQnLCBmdW5jdGlvbiBiYWRJbnB1dERlc2NyaWJlKCkge1xuICAgICAgYWZ0ZXIoKCkgPT4ge1xuICAgICAgICAvLyBtYWtlIHN1cmUgYWxsIG5vY2tzIGFyZSBjbGVhcmVkIG9yIGNvbnN1bWVkIGFmdGVyIHRoZSB0ZXN0cyBhcmUgY29tcGxldGVcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnbm9uIGV4aXN0ZW50IHRyYW5zYWN0aW9uIElEJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSg0MDQsICd0cmFuc2FjdGlvbiBub3QgZm91bmQgb24gdGhpcyB3YWxsZXQnKTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMTIzIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL140MDRcXG50cmFuc2FjdGlvbiBub3QgZm91bmQgb24gdGhpcyB3YWxsZXQkLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2NvbmZpcm1lZCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY29uZmlybWF0aW9uczogNixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDIwMDAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXlRyYW5zYWN0aW9uIFswLTlhLWZdKyBpcyBhbHJlYWR5IGNvbmZpcm1lZCBhbmQgY2Fubm90IGJlIGFjY2VsZXJhdGVkJC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdubyBvdXRwdXRzIHRvIHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NvdW50OiBvdXRwdXRBZGRyZXNzLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxODkwMDAwLFxuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL15UcmFuc2FjdGlvbiBbMC05YS1mXSsgY29udGFpbnMgbm8gb3V0cHV0cyB0byB0aGlzIHdhbGxldCwgYW5kIHRodXMgY2Fubm90IGJlIGFjY2VsZXJhdGVkJC9cbiAgICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIC8qXG4gICAgICAgKiBUaGlzIHRlc3QgY292ZXJzIHRoZSBjYXNlIHdoZXJlIGEgZmFpbHVyZSBvY2N1cnMgZHVyaW5nIHRoZSBwcm9jZXNzIG9mXG4gICAgICAgKiBjb252ZXJ0aW5nIGFuIG91dHB1dCBmcm9tIHRoZSBwYXJlbnQgdHJhbnNhY3Rpb24gaW50byBhbiB1bnNwZW50IHdoaWNoXG4gICAgICAgKiBjYW4gYmUgdXNlZCB0byBjaGFpbiB0aGUgY2hpbGQgdHggdG8gdGhlIHBhcmVudC5cbiAgICAgICAqXG4gICAgICAgKiBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBpdCBpcyBwb3NzaWJsZSAoZm9yIGV4YW1wbGUsIGluIHRoZSBjYXNlXG4gICAgICAgKiBvZiBhbiBhdHRlbXB0ZWQgZG91YmxlIHNwZW5kIG9mIHRoZSBvdXRwdXQgZnJvbSB0aGUgcGFyZW50LCBvciBhIHJhY2VcbiAgICAgICAqIGJldHdlZW4gZmluZGluZyB0aGUgcGFyZW50IG91dHB1dCwgYW5kIHJldHJpZXZpbmcgdGhlIGNvcnJlc3BvbmRpbmcgdW5zcGVudCkuXG4gICAgICAgKi9cbiAgICAgIGl0KCdjYW5ub3QgZmluZCBjb3JyZWN0IHVuc3BlbnQgdG8gdXNlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDUwICogMWU0LFxuICAgICAgICAgICAgICAgIHZvdXQ6IG91dHB1dElkeCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICAgIGhleDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgIGZlZTogMTAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvdW50OiAwLFxuICAgICAgICAgIHVuc3BlbnRzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDIwMDAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXkNvdWxkIG5vdCBmaW5kIHVuc3BlbnQgb3V0cHV0IGZyb20gcGFyZW50IHR4IHRvIHVzZSBhcyBjaGlsZCBpbnB1dCQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnRGV0ZWN0cyB3aGVuIGFuIGluY29ycmVjdCB0eCBoZXggaXMgcmV0dXJuZWQgYnkgdGhlIGV4dGVybmFsIHNlcnZpY2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBmaXh0dXJlc1twYXJlbnRUeElkXSxcbiAgICAgICAgICAgIGZlZTogMTAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbdW5yZWxhdGVkVHhJZF0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15EZWNvZGVkIHRyYW5zYWN0aW9uIGlkIGlzIFswLTlhLWZdKywgd2hpY2ggZG9lcyBub3QgbWF0Y2ggZ2l2ZW4gdHhpZCBbMC05YS1mXSskLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2Nhbm5vdCBjb3ZlciBjaGlsZCBmZWUgd2l0aCBvbmUgcGFyZW50IG91dHB1dCBhbmQgb25lIHdhbGxldCB1bnNwZW50JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwLFxuICAgICAgICAgICAgICAgIHZvdXQ6IG91dHB1dElkeCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICAgIGhleDogZml4dHVyZXNbcGFyZW50VHhJZF0sXG4gICAgICAgICAgICBmZWU6IDEwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvdW50OiAxLFxuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IG91dHB1dElkeCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYCkucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY291bnQ6IDAsXG4gICAgICAgICAgdW5zcGVudHM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eSW5zdWZmaWNpZW50IGNvbmZpcm1lZCB1bnNwZW50cyBhdmFpbGFibGUgdG8gY292ZXIgdGhlIGNoaWxkIGZlZSQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY2Fubm90IGxvd2VyIGZlZSByYXRlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwLFxuICAgICAgICAgICAgICAgIHZvdXQ6IG91dHB1dElkeCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgICAgICBoZXg6IGZpeHR1cmVzW3BhcmVudFR4SWRdLFxuICAgICAgICAgICAgZmVlOiAxMDAwMCwgLy8gbGFyZ2UgZmVlLCBhbmQgdGh1cyBmZWUgcmF0ZSwgZm9yIHBhcmVudFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvdW50OiAxLFxuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IG91dHB1dElkeCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL15DYW5ub3QgbG93ZXIgZmVlIHJhdGUhIFxcKFBhcmVudCB0eCBmZWUgcmF0ZSBpcyBcXGQrXFwuP1xcZCogc2F0XFwva0IsIGFuZCByZXF1ZXN0ZWQgZmVlIHJhdGUgd2FzIFxcZCtcXC4/XFxkKiBzYXRcXC9rQlxcKSQvXG4gICAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY2Fubm90IGJyZWFrIG1heGltdW0gZmVlIGxpbWl0IGZvciBjb21iaW5lZCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NvdW50OiBvdXRwdXRBZGRyZXNzLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAzZTcsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICAgIGhleDogZml4dHVyZXNbcGFyZW50VHhJZF0sXG4gICAgICAgICAgICBmZWU6IDEwMDAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyZTYgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAgIC9eVHJhbnNhY3Rpb24gY2Fubm90IGJlIGFjY2VsZXJhdGVkXFwuIENvbWJpbmVkIGZlZSByYXRlIG9mIFxcZCtcXC4/XFxkKiBzYXRcXC9rQiBleGNlZWRzIG1heGltdW0gZmVlIHJhdGUgb2YgXFxkK1xcLj9cXGQqIHNhdFxcL2tCJC9cbiAgICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc3VjY2Vzc2Z1bCB0eCBhY2NlbGVyYXRpb24nLCBmdW5jdGlvbiBzdWNjZXNzZnVsVHhEZXNjcmliZSgpIHtcbiAgICAgIGNvbnN0IGZlZVJhdGUgPSAyMDAwMDtcblxuICAgICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2FkZHJlc3MvMWApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGFkZHJlc3M6ICcyTkNZakc4UTU2eXI4dHg5amF6Tm9ZbkdLeGpnQjJNUVNmWScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJykucmVwbHkoMjAwLCB7XG4gICAgICAgICAgYWRkcmVzczogJzJORmJ2bzJISzRlWFptMWFxRGNTREdHcUQ2NEZQdDdUNmQ4JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YxL3R4L2ZlZScpLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGZlZVBlcktiOiAwLFxuICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YxL2tleWNoYWluLyR7dXNlcktleXBhaXIueHB1Yn1gLCB7fSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHVzZXJLZXlwYWlyLnhwcnYsIHBhc3N3b3JkOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFIH0pLFxuICAgICAgICAgICAgcGF0aDogdXNlcktleXBhaXIucGF0aCArIHVzZXJLZXlwYWlyLndhbGxldFN1YlBhdGgsXG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aG91dCBhZGRpdGlvbmFsIHVuc3BlbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzc1Y2ZjNWE3YjIxNGM0YjczYzkyYzdiMDI2MDhjZGU3MGIyMjY3NjdhOTU3NmY4NGMwNDQwN2U0M2ZkMzg1YmQnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogNDM0LFxuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAzNDg1MDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMzQ4NTAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDogJzAwMjBmN2I1OGQ0NTUzNTFiN2I4ZGRkN2M4OTg2ZDk4MjQ0ZjZhOTVmMDc0NjcyMDA5MTUzNzMyM2I5Njc4MDBmNzQ0JyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMTEvMTYwJyxcbiAgICAgICAgICAgICAgICB3aXRuZXNzU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMjdmMGI0NWJiNDE1NWVhNTMyZTNiNDMxMmZlMGJlODAxNjZmMjk3ZDFlMDc1M2QyZDRhOTExOGMwNzNhZDY1MTQyMTAzMTBhYTlkNjhjOTg4MzE2MjVmMzI5Yjc4MjZiNmMzZTNiNTNlMTY3MzZiMTk5NGI4OTAyNDQyYmRjZDY2NTNkMTIxMDI2ZTBjYTQxNGYyNDg4YjBhYjU3MmI5OWUwYWU1NDQyOTExYWI0ZTA4MjFiMjcwOWQ4ODUxNzVhNTI3ZmQ1NTJiNTNhZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92MS90eC9zZW5kJywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhYm9keS5pZ25vcmVNYXhGZWVSYXRlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgZnVuY3Rpb24gKF8sIGJvZHkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uOiAoYm9keSBhcyBhbnkpLnR4LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjaGlsZFR4ID0gYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCxcbiAgICAgICAgICBmZWVSYXRlLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfUEFTU0NPREUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChjaGlsZFR4KTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3RhdHVzJywgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG5cbiAgICAgICAgLy8gYXNzZXJ0IHRoZSBmb2xsb3dpbmc6XG4gICAgICAgIC8vIDApIFRoZSBjaGlsZCB0eCBoYXMgZXhhY3RseSBvbmUgaW5wdXRcbiAgICAgICAgLy8gMSkgVGhlIHBhcmVudCB0eCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMikgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBvdXRwdXRcbiAgICAgICAgLy8gMykgVGhlIGNoaWxkIHR4IG91dHB1dCBtZWV0cyB0aGUgbWluaW11bSBjaGFuZ2UgdGhyZXNob2xkXG4gICAgICAgIGNvbnN0IGRlY29kZWRDaGlsZCA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KGNoaWxkVHgudHgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICAgIGRlY29kZWRDaGlsZC5pbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLm91dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBjb25zdCBjaGlsZElucHV0ID0gZGVjb2RlZENoaWxkLmluc1swXTtcbiAgICAgICAgY2hpbGRJbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaW5kZXgnLCAwKTtcbiAgICAgICAgY2hpbGRJbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFzaCcpO1xuXG4gICAgICAgIGNvbnN0IGlucHV0VHhJZCA9IGlucHV0UGFyZW50VHhJZChjaGlsZElucHV0KTtcbiAgICAgICAgaW5wdXRUeElkLnNob3VsZC5lcXVhbChwYXJlbnRUeElkKTtcblxuICAgICAgICBjb25zdCBjaGlsZE91dHB1dCA9IGRlY29kZWRDaGlsZC5vdXRzWzBdO1xuICAgICAgICBjaGlsZE91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndmFsdWUnKTtcbiAgICAgICAgY2hpbGRPdXRwdXQudmFsdWUuc2hvdWxkLmJlLmFib3ZlKG1pbkNoYW5nZVNpemUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhY2NlbGVyYXRlcyBhIHN0dWNrIHR4IHdpdGggb25lIGFkZGl0aW9uYWwgc2Vnd2l0IHVuc3BlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHBhcmVudFR4SWQgPSAnODgxNWYyMDJjODY1NGI2YzhiMjk1NzQ5NTQ1YzcxMTg3OGNkODQ1YTE0Y2IxZWE5ODIzOTRkMGMxNDk0NWMzMyc7XG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxVbnNwZW50VHhJZCA9ICcwN2Q2ZWU1N2IwMjRjZTJiNjEwOGY2Nzg0NzQ1NGEwYTc5YTRmY2ZiOThhYjI1NTU1M2EyOTkzYTFhMTcwYjg3JztcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBmZWU6IDEzMzYsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODY2NCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMmNkM2M4ZTYwMDZhNDYyNzcwNTAyMWQxZDAxNmQwOTdjMjk0NGQ5ODEwMGE0N2JmMmRhNjdhNWZlMTVhZWViMzQyMTAyZWUxZmE5ZTgxMmU3NzkzNTZhYTNjMzFlYmYzMTdkMGNmZmViYWI5Mjg2NGNmZTM4YmFiMjIzZTA4MjBmOThiYzIxMDI2YmEwNTc1MmJhYTZlYWZkNWM1NjU5ZGE2MmI3ZjBhYzUxZmQyODg2YjY1YzI0MWQwYWZlZjFjNGZkZmExY2JjNTNhZScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzAvMCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBhZGRpdGlvbmFsVW5zcGVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDE5OTM1NTI2LFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDogJzAwMjBkMzRlZjZkZDM0ZWYyYTRmYmVhNjdjNTQxYzFjNzk2NzQ5YTYwYWZlNGE5N2ZlZThlYzdkZWQxODhiZDc0OWRhJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMTEvMTU1JyxcbiAgICAgICAgICAgICAgICB3aXRuZXNzU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMjIxOWQyYWE4NDE3NjMzZjBiY2UzOTExMzc0YTE2MDRjMWI2NDE2MWY4M2EzYzJlZTQwOWMyN2M0MjM1NWYwOGUyMTAyYzk3MzQ5MjBkYzRkYTA2YzI4OWZlNjkxNzFkZmNkNzVlM2I5YjRmMTkwZDBjYmMzZDVkMGZmM2Y1ZmRlZWFhZTIxMDNjY2Q2OGQ3ZmE4ZGMwZDAyZGQ0NWRhZDE2NTU1N2E0ODU4MmVkYTQ0MzVmYWU3Mzc3YjNjMzFlMDhhZDA2NWM5NTNhZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92MS90eC9zZW5kJywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhYm9keS5pZ25vcmVNYXhGZWVSYXRlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgZnVuY3Rpb24gKF8sIGJvZHkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uOiAoYm9keSBhcyBhbnkpLnR4LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBjaGlsZFR4ID0gYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCxcbiAgICAgICAgICBmZWVSYXRlLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfUEFTU0NPREUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChjaGlsZFR4KTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3RhdHVzJywgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG5cbiAgICAgICAgLy8gYXNzZXJ0IHRoZSBmb2xsb3dpbmc6XG4gICAgICAgIC8vIDApIFRoZSBjaGlsZCB0eCBoYXMgZXhhY3RseSB0d28gaW5wdXRzXG4gICAgICAgIC8vIDEpIFRoZSBwYXJlbnQgdHggb3V0cHV0IGlzIGFuIGlucHV0XG4gICAgICAgIC8vIDIpIFRoZSBhZGRpdGlvbmFsIHVuc3BlbnQgb3V0cHV0IGlzIGFuIGlucHV0XG4gICAgICAgIC8vIDMpIFRoZSBjaGlsZCB0eCBoYXMgZXhhY3RseSBvbmUgb3V0cHV0XG4gICAgICAgIC8vIDQpIFRoZSBjaGlsZCB0eCBvdXRwdXQgbWVldHMgdGhlIG1pbmltdW0gY2hhbmdlIHRocmVzaG9sZFxuICAgICAgICBjb25zdCBkZWNvZGVkQ2hpbGQgPSB1dHhvbGliLmJpdGdvLmNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleChjaGlsZFR4LnR4LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgICBkZWNvZGVkQ2hpbGQuaW5zLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgIGRlY29kZWRDaGlsZC5vdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgbGV0IGlucHV0RnJvbVBhcmVudDogYW55ID0gdW5kZWZpbmVkO1xuICAgICAgICBsZXQgYWRkaXRpb25hbElucHV0OiBhbnkgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgXy5mb3JFYWNoKGRlY29kZWRDaGlsZC5pbnMsIChpbnB1dCkgPT4ge1xuICAgICAgICAgIGlucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYXNoJyk7XG4gICAgICAgICAgaW5wdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2luZGV4Jyk7XG5cbiAgICAgICAgICBjb25zdCBpbnB1dFR4SWQgPSBpbnB1dFBhcmVudFR4SWQoaW5wdXQpO1xuXG4gICAgICAgICAgaWYgKGlucHV0VHhJZCA9PT0gcGFyZW50VHhJZCkge1xuICAgICAgICAgICAgaW5wdXRGcm9tUGFyZW50ID0gaW5wdXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZGl0aW9uYWxJbnB1dCA9IGlucHV0O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGNvbnN0IGlucHV0RnJvbVBhcmVudEhhc2ggPSBpbnB1dFBhcmVudFR4SWQoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50SGFzaC5zaG91bGQuZXF1YWwocGFyZW50VHhJZCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudC5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGFkZGl0aW9uYWxJbnB1dCk7XG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxJbnB1dEhhc2ggPSBpbnB1dFBhcmVudFR4SWQoYWRkaXRpb25hbElucHV0KTtcbiAgICAgICAgYWRkaXRpb25hbElucHV0SGFzaC5zaG91bGQuZXF1YWwoYWRkaXRpb25hbFVuc3BlbnRUeElkKTtcbiAgICAgICAgYWRkaXRpb25hbElucHV0LmluZGV4LnNob3VsZC5lcXVhbCgwKTtcblxuICAgICAgICBjb25zdCBjaGlsZE91dHB1dCA9IGRlY29kZWRDaGlsZC5vdXRzWzBdO1xuICAgICAgICBjaGlsZE91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndmFsdWUnKTtcbiAgICAgICAgY2hpbGRPdXRwdXQudmFsdWUuc2hvdWxkLmJlLmFib3ZlKG1pbkNoYW5nZVNpemUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhY2NlbGVyYXRlcyBhIHN0dWNrIHR4IHdpdGggb25lIGFkZGl0aW9uYWwgUDJTSCB1bnNwZW50JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzg4MTVmMjAyYzg2NTRiNmM4YjI5NTc0OTU0NWM3MTE4NzhjZDg0NWExNGNiMWVhOTgyMzk0ZDBjMTQ5NDVjMzMnO1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsVW5zcGVudFR4SWQgPSAnZTE5MDMxMGYyZjNmNzFhYTg4NDZmMTE2MWNiY2UxNTMzYzI0YTg1N2RkMjRlNDUwMWIxMzFmZWI0MDBhYWQ1OCc7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgZmVlOiAxMzM2LFxuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDg2NjQsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8wLzAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogYWRkaXRpb25hbFVuc3BlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAyMDAwMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IHR3byBpbnB1dHNcbiAgICAgICAgLy8gMSkgVGhlIHBhcmVudCB0eCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMikgVGhlIGFkZGl0aW9uYWwgdW5zcGVudCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMykgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBvdXRwdXRcbiAgICAgICAgLy8gNCkgVGhlIGNoaWxkIHR4IG91dHB1dCBtZWV0cyB0aGUgbWluaW11bSBjaGFuZ2UgdGhyZXNob2xkXG4gICAgICAgIGNvbnN0IGRlY29kZWRDaGlsZCA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KGNoaWxkVHgudHgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICAgIGRlY29kZWRDaGlsZC5pbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLm91dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBsZXQgaW5wdXRGcm9tUGFyZW50OiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBhZGRpdGlvbmFsSW5wdXQ6IGFueSA9IHVuZGVmaW5lZDtcblxuICAgICAgICBfLmZvckVhY2goZGVjb2RlZENoaWxkLmlucywgKGlucHV0KSA9PiB7XG4gICAgICAgICAgaW5wdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhc2gnKTtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaW5kZXgnKTtcblxuICAgICAgICAgIGNvbnN0IGlucHV0SGFzaCA9IGlucHV0UGFyZW50VHhJZChpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaW5wdXRIYXNoID09PSBwYXJlbnRUeElkKSB7XG4gICAgICAgICAgICBpbnB1dEZyb21QYXJlbnQgPSBpbnB1dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkaXRpb25hbElucHV0ID0gaW5wdXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgY29uc3QgaW5wdXRGcm9tUGFyZW50SGFzaCA9IGlucHV0UGFyZW50VHhJZChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnRIYXNoLnNob3VsZC5lcXVhbChwYXJlbnRUeElkKTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50LmluZGV4LnNob3VsZC5lcXVhbCgwKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoYWRkaXRpb25hbElucHV0KTtcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbElucHV0SGFzaCA9IGlucHV0UGFyZW50VHhJZChhZGRpdGlvbmFsSW5wdXQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXRIYXNoLnNob3VsZC5lcXVhbChhZGRpdGlvbmFsVW5zcGVudFR4SWQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXQuaW5kZXguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aCB0d28gYWRkaXRpb25hbCB1bnNwZW50cyAoc2Vnd2l0IGFuZCBQMlNIKScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcGFyZW50VHhJZCA9ICc4ODE1ZjIwMmM4NjU0YjZjOGIyOTU3NDk1NDVjNzExODc4Y2Q4NDVhMTRjYjFlYTk4MjM5NGQwYzE0OTQ1YzMzJztcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBmZWU6IDEzMzYsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODY2NCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMmNkM2M4ZTYwMDZhNDYyNzcwNTAyMWQxZDAxNmQwOTdjMjk0NGQ5ODEwMGE0N2JmMmRhNjdhNWZlMTVhZWViMzQyMTAyZWUxZmE5ZTgxMmU3NzkzNTZhYTNjMzFlYmYzMTdkMGNmZmViYWI5Mjg2NGNmZTM4YmFiMjIzZTA4MjBmOThiYzIxMDI2YmEwNTc1MmJhYTZlYWZkNWM1NjU5ZGE2MmI3ZjBhYzUxZmQyODg2YjY1YzI0MWQwYWZlZjFjNGZkZmExY2JjNTNhZScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzAvMCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiAnZTE5MDMxMGYyZjNmNzFhYTg4NDZmMTE2MWNiY2UxNTMzYzI0YTg1N2RkMjRlNDUwMWIxMzFmZWI0MDBhYWQ1OCcsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDgwMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6ICcwN2Q2ZWU1N2IwMjRjZTJiNjEwOGY2Nzg0NzQ1NGEwYTc5YTRmY2ZiOThhYjI1NTU1M2EyOTkzYTFhMTcwYjg3JyxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMjAwMDYyODQsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OiAnMDAyMGQzNGVmNmRkMzRlZjJhNGZiZWE2N2M1NDFjMWM3OTY3NDlhNjBhZmU0YTk3ZmVlOGVjN2RlZDE4OGJkNzQ5ZGEnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8xMS8xNTUnLFxuICAgICAgICAgICAgICAgIHdpdG5lc3NTY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyMjE5ZDJhYTg0MTc2MzNmMGJjZTM5MTEzNzRhMTYwNGMxYjY0MTYxZjgzYTNjMmVlNDA5YzI3YzQyMzU1ZjA4ZTIxMDJjOTczNDkyMGRjNGRhMDZjMjg5ZmU2OTE3MWRmY2Q3NWUzYjliNGYxOTBkMGNiYzNkNWQwZmYzZjVmZGVlYWFlMjEwM2NjZDY4ZDdmYThkYzBkMDJkZDQ1ZGFkMTY1NTU3YTQ4NTgyZWRhNDQzNWZhZTczNzdiM2MzMWUwOGFkMDY1Yzk1M2FlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfUEFTU0NPREUsXG4gICAgICAgICAgZmVlUmF0ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IHRocmVlIGlucHV0c1xuICAgICAgICAvLyAxKSBUaGUgcGFyZW50IHR4IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAyKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgb25lIG91dHB1dFxuICAgICAgICAvLyAzKSBUaGUgY2hpbGQgdHggb3V0cHV0IG1lZXRzIHRoZSBtaW5pbXVtIGNoYW5nZSB0aHJlc2hvbGRcbiAgICAgICAgY29uc3QgZGVjb2RlZENoaWxkID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXgoY2hpbGRUeC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLmlucy5sZW5ndGguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgICBkZWNvZGVkQ2hpbGQub3V0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGxldCBpbnB1dEZyb21QYXJlbnQ6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbElucHV0czogYW55W10gPSBbXTtcblxuICAgICAgICBfLmZvckVhY2goZGVjb2RlZENoaWxkLmlucywgKGlucHV0KSA9PiB7XG4gICAgICAgICAgaW5wdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhc2gnKTtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaW5kZXgnKTtcblxuICAgICAgICAgIGNvbnN0IGlucHV0SGFzaCA9IGlucHV0UGFyZW50VHhJZChpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaW5wdXRIYXNoID09PSBwYXJlbnRUeElkKSB7XG4gICAgICAgICAgICBpbnB1dEZyb21QYXJlbnQgPSBpbnB1dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkaXRpb25hbElucHV0cy5wdXNoKGlucHV0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBjb25zdCBpbnB1dEZyb21QYXJlbnRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudEhhc2guc2hvdWxkLmVxdWFsKHBhcmVudFR4SWQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnQuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgIGFkZGl0aW9uYWxJbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcblxuICAgICAgICBjb25zdCBjaGlsZE91dHB1dCA9IGRlY29kZWRDaGlsZC5vdXRzWzBdO1xuICAgICAgICBjaGlsZE91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndmFsdWUnKTtcbiAgICAgICAgY2hpbGRPdXRwdXQudmFsdWUuc2hvdWxkLmJlLmFib3ZlKG1pbkNoYW5nZVNpemUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdjb3JyZWN0bHkgdXNlcyB0aGUgaWdub3JlTWF4RmVlUmF0ZSBwYXJhbWV0ZXIgb25seSB3aGVuIG5lY2Vzc2FyeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcGFyZW50VHhJZCA9ICc3NWNmYzVhN2IyMTRjNGI3M2M5MmM3YjAyNjA4Y2RlNzBiMjI2NzY3YTk1NzZmODRjMDQ0MDdlNDNmZDM4NWJkJztcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBmZWU6IDQzNCxcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMzQ4NTAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDM0ODUwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6ICcwMDIwZjdiNThkNDU1MzUxYjdiOGRkZDdjODk4NmQ5ODI0NGY2YTk1ZjA3NDY3MjAwOTE1MzczMjNiOTY3ODAwZjc0NCcsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzExLzE2MCcsXG4gICAgICAgICAgICAgICAgd2l0bmVzc1NjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDI3ZjBiNDViYjQxNTVlYTUzMmUzYjQzMTJmZTBiZTgwMTY2ZjI5N2QxZTA3NTNkMmQ0YTkxMThjMDczYWQ2NTE0MjEwMzEwYWE5ZDY4Yzk4ODMxNjI1ZjMyOWI3ODI2YjZjM2UzYjUzZTE2NzM2YjE5OTRiODkwMjQ0MmJkY2Q2NjUzZDEyMTAyNmUwY2E0MTRmMjQ4OGIwYWI1NzJiOTllMGFlNTQ0MjkxMWFiNGUwODIxYjI3MDlkODg1MTc1YTUyN2ZkNTUyYjUzYWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdHgvc2VuZCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICAvLyBpZ25vcmUgbWF4IGZlZSByYXRlIG11c3QgYmUgc2V0IGZvciB0aGlzIHRlc3RcbiAgICAgICAgICAgIHJldHVybiBib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICAvLyBtb25rZXkgcGF0Y2ggdGhlIGJpdGdvIGdldENvbnN0YW50cygpIGZ1bmN0aW9uXG4gICAgICAgIGNvbnN0IG9sZEdldENvbnN0YW50cyA9IChiaXRnbyBhcyBhbnkpLl9fcHJvdG9fXy5nZXRDb25zdGFudHM7XG4gICAgICAgIChiaXRnbyBhcyBhbnkpLl9fcHJvdG9fXy5nZXRDb25zdGFudHMgPSAoKSA9PiAoe1xuICAgICAgICAgIC8vIGNoaWxkIGZlZSByYXRlIGluIHRoaXMgdGVzdCBpcyAzMTM3OCBzYXQva2JcbiAgICAgICAgICAvLyBzbyBzZXQgdGhlIG1heCBmZWUgcmF0ZSBqdXN0IGJlbG93IHRoYXQgbGltaXQsXG4gICAgICAgICAgLy8gYnV0IGFib3ZlIHRoZSBjb21iaW5lZCBmZWUgcmF0ZSBvZiAyMDAwMFxuICAgICAgICAgIG1heEZlZVJhdGU6IDMwMDAwLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG4gICAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCk7XG5cbiAgICAgICAgKGJpdGdvIGFzIGFueSkuX19wcm90b19fLmdldENvbnN0YW50cyA9IG9sZEdldENvbnN0YW50cztcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19