@bitgo/sdk-coin-ton 3.9.2 → 3.9.4
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.
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +2 -1
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +13 -3
- package/dist/test/resources/ton.d.ts +93 -0
- package/dist/test/resources/ton.d.ts.map +1 -0
- package/dist/test/resources/ton.js +113 -0
- package/dist/test/unit/jettonToken.d.ts +2 -0
- package/dist/test/unit/jettonToken.d.ts.map +1 -0
- package/dist/test/unit/jettonToken.js +341 -0
- package/dist/test/unit/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +55 -0
- package/dist/test/unit/singleNominatorWithdrawBuilder.d.ts +2 -0
- package/dist/test/unit/singleNominatorWithdrawBuilder.d.ts.map +1 -0
- package/dist/test/unit/singleNominatorWithdrawBuilder.js +254 -0
- package/dist/test/unit/tokenTransferBuilder.d.ts +2 -0
- package/dist/test/unit/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/test/unit/tokenTransferBuilder.js +262 -0
- package/dist/test/unit/ton.d.ts +2 -0
- package/dist/test/unit/ton.d.ts.map +1 -0
- package/dist/test/unit/ton.js +668 -0
- package/dist/test/unit/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transferBuilder.js +240 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +11 -8
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -881
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const sdk_test_1 = require("@bitgo/sdk-test");
|
|
40
|
+
const sdk_api_1 = require("@bitgo/sdk-api");
|
|
41
|
+
const src_1 = require("../../src");
|
|
42
|
+
const sinon = __importStar(require("sinon"));
|
|
43
|
+
const assert_1 = __importDefault(require("assert"));
|
|
44
|
+
const testData = __importStar(require("../resources/ton"));
|
|
45
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
46
|
+
const should_1 = __importDefault(require("should"));
|
|
47
|
+
const utils_1 = __importDefault(require("../../src/lib/utils"));
|
|
48
|
+
const tonweb_1 = __importDefault(require("tonweb"));
|
|
49
|
+
describe('TON:', function () {
|
|
50
|
+
let basecoin;
|
|
51
|
+
const bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
52
|
+
bitgo.safeRegister('ton', src_1.Ton.createInstance);
|
|
53
|
+
bitgo.safeRegister('tton', src_1.Tton.createInstance);
|
|
54
|
+
bitgo.initializeTestVars();
|
|
55
|
+
const txPrebuildList = [
|
|
56
|
+
{
|
|
57
|
+
txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
|
|
58
|
+
txInfo: {},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
|
|
62
|
+
txInfo: {},
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
const txPrebuildBounceableList = [
|
|
66
|
+
{
|
|
67
|
+
txHex: Buffer.from(testData.signedSendTransaction.txBounceable, 'base64').toString('hex'),
|
|
68
|
+
txInfo: {},
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.txBounceable, 'base64').toString('hex'),
|
|
72
|
+
txInfo: {},
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
const txParamsList = [
|
|
76
|
+
{
|
|
77
|
+
recipients: [testData.signedSendTransaction.recipient],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
recipients: [testData.signedSingleNominatorWithdrawTransaction.recipient],
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
const txParamsBounceableList = [
|
|
84
|
+
{
|
|
85
|
+
recipients: [testData.signedSendTransaction.recipientBounceable],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
recipients: [testData.signedSingleNominatorWithdrawTransaction.recipientBounceable],
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
it('should return the right info', function () {
|
|
92
|
+
const ton = bitgo.coin('ton');
|
|
93
|
+
const tton = bitgo.coin('tton');
|
|
94
|
+
ton.getChain().should.equal('ton');
|
|
95
|
+
ton.getFamily().should.equal('ton');
|
|
96
|
+
ton.getFullName().should.equal('Ton');
|
|
97
|
+
ton.getBaseFactor().should.equal(1e9);
|
|
98
|
+
tton.getChain().should.equal('tton');
|
|
99
|
+
tton.getFamily().should.equal('ton');
|
|
100
|
+
tton.getFullName().should.equal('Testnet Ton');
|
|
101
|
+
tton.getBaseFactor().should.equal(1e9);
|
|
102
|
+
});
|
|
103
|
+
describe('Verify transaction: ', () => {
|
|
104
|
+
basecoin = bitgo.coin('tton');
|
|
105
|
+
txParamsList.forEach((_, index) => {
|
|
106
|
+
const txParams = txParamsList[index];
|
|
107
|
+
const txPrebuild = txPrebuildList[index];
|
|
108
|
+
const txParamsBounceable = txParamsBounceableList[index];
|
|
109
|
+
const txPrebuildBounceable = txPrebuildBounceableList[index];
|
|
110
|
+
it('should succeed to verify transaction', async function () {
|
|
111
|
+
const verification = {};
|
|
112
|
+
const isTransactionVerified = await basecoin.verifyTransaction({
|
|
113
|
+
txParams,
|
|
114
|
+
txPrebuild,
|
|
115
|
+
verification,
|
|
116
|
+
});
|
|
117
|
+
isTransactionVerified.should.equal(true);
|
|
118
|
+
const isBounceableTransactionVerified = await basecoin.verifyTransaction({
|
|
119
|
+
txParams: txParamsBounceable,
|
|
120
|
+
txPrebuild: txPrebuildBounceable,
|
|
121
|
+
verification: {},
|
|
122
|
+
});
|
|
123
|
+
isBounceableTransactionVerified.should.equal(true);
|
|
124
|
+
});
|
|
125
|
+
it('should succeed to verify transaction when recipients amount are numbers', async function () {
|
|
126
|
+
const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
|
|
127
|
+
txParamsWithNumberAmounts.recipients[0].amount = 20000000;
|
|
128
|
+
const verification = {};
|
|
129
|
+
await basecoin
|
|
130
|
+
.verifyTransaction({
|
|
131
|
+
txParams: txParamsWithNumberAmounts,
|
|
132
|
+
txPrebuild,
|
|
133
|
+
verification,
|
|
134
|
+
})
|
|
135
|
+
.should.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
136
|
+
});
|
|
137
|
+
it('should succeed to verify transaction when recipients amount are strings', async function () {
|
|
138
|
+
const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
|
|
139
|
+
txParamsWithNumberAmounts.recipients[0].amount = '20000000';
|
|
140
|
+
const verification = {};
|
|
141
|
+
await basecoin
|
|
142
|
+
.verifyTransaction({
|
|
143
|
+
txParams: txParamsWithNumberAmounts,
|
|
144
|
+
txPrebuild,
|
|
145
|
+
verification,
|
|
146
|
+
})
|
|
147
|
+
.should.rejectedWith('Tx outputs does not match with expected txParams recipients');
|
|
148
|
+
});
|
|
149
|
+
it('should succeed to verify transaction when recipients amounts are number and amount is same', async function () {
|
|
150
|
+
const verification = {};
|
|
151
|
+
await basecoin
|
|
152
|
+
.verifyTransaction({
|
|
153
|
+
txParams,
|
|
154
|
+
txPrebuild,
|
|
155
|
+
verification,
|
|
156
|
+
})
|
|
157
|
+
.should.resolvedWith(true);
|
|
158
|
+
});
|
|
159
|
+
it('should succeed to verify transaction when recipients amounts are string and amount is same', async function () {
|
|
160
|
+
const verification = {};
|
|
161
|
+
await basecoin
|
|
162
|
+
.verifyTransaction({
|
|
163
|
+
txParams,
|
|
164
|
+
txPrebuild,
|
|
165
|
+
verification,
|
|
166
|
+
})
|
|
167
|
+
.should.resolvedWith(true);
|
|
168
|
+
});
|
|
169
|
+
it('should succeed to verify transaction when recipient address are non bounceable', async function () {
|
|
170
|
+
const txParamsWithNumberAmounts = JSON.parse(JSON.stringify(txParams));
|
|
171
|
+
txParamsWithNumberAmounts.recipients[0].address = new tonweb_1.default.Address(txParamsWithNumberAmounts.recipients[0].address).toString(true, true, false);
|
|
172
|
+
const verification = {};
|
|
173
|
+
const isVerified = await basecoin.verifyTransaction({
|
|
174
|
+
txParams: txParamsWithNumberAmounts,
|
|
175
|
+
txPrebuild,
|
|
176
|
+
verification,
|
|
177
|
+
});
|
|
178
|
+
isVerified.should.equal(true);
|
|
179
|
+
});
|
|
180
|
+
it('should fail to verify transaction with invalid param', async function () {
|
|
181
|
+
const txPrebuild = {};
|
|
182
|
+
await basecoin
|
|
183
|
+
.verifyTransaction({
|
|
184
|
+
txParams,
|
|
185
|
+
txPrebuild,
|
|
186
|
+
})
|
|
187
|
+
.should.rejectedWith('missing required tx prebuild property txHex');
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
it('should succeed to verify transaction with recipient having memo', async function () {
|
|
191
|
+
const txParams = {
|
|
192
|
+
recipients: [testData.signedSendTransactionForMemoId.recipient],
|
|
193
|
+
};
|
|
194
|
+
const txPrebuild = {
|
|
195
|
+
txHex: Buffer.from(testData.signedSendTransactionForMemoId.tx, 'base64').toString('hex'),
|
|
196
|
+
txInfo: {},
|
|
197
|
+
};
|
|
198
|
+
const verification = {};
|
|
199
|
+
const isTransactionVerified = await basecoin.verifyTransaction({
|
|
200
|
+
txParams,
|
|
201
|
+
txPrebuild,
|
|
202
|
+
verification,
|
|
203
|
+
});
|
|
204
|
+
isTransactionVerified.should.equal(true);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
describe('Explain Transaction: ', () => {
|
|
208
|
+
const basecoin = bitgo.coin('tton');
|
|
209
|
+
it('should explain a transfer transaction', async function () {
|
|
210
|
+
const explainedTransaction = (await basecoin.explainTransaction({
|
|
211
|
+
txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
|
|
212
|
+
}));
|
|
213
|
+
explainedTransaction.should.deepEqual({
|
|
214
|
+
displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
|
|
215
|
+
id: 'tuyOkyFUMv_neV_FeNBH24Nd4cML2jUgDP4zjGkuOFI=',
|
|
216
|
+
outputs: [
|
|
217
|
+
{
|
|
218
|
+
address: testData.signedSendTransaction.recipient.address,
|
|
219
|
+
amount: testData.signedSendTransaction.recipient.amount,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
outputAmount: testData.signedSendTransaction.recipient.amount,
|
|
223
|
+
changeOutputs: [],
|
|
224
|
+
changeAmount: '0',
|
|
225
|
+
fee: { fee: 'UNKNOWN' },
|
|
226
|
+
withdrawAmount: undefined,
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
it('should explain a non-bounceable transfer transaction', async function () {
|
|
230
|
+
const explainedTransaction = (await basecoin.explainTransaction({
|
|
231
|
+
txHex: Buffer.from(testData.signedSendTransaction.tx, 'base64').toString('hex'),
|
|
232
|
+
toAddressBounceable: false,
|
|
233
|
+
fromAddressBounceable: false,
|
|
234
|
+
}));
|
|
235
|
+
explainedTransaction.should.deepEqual({
|
|
236
|
+
displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
|
|
237
|
+
id: 'tuyOkyFUMv_neV_FeNBH24Nd4cML2jUgDP4zjGkuOFI=',
|
|
238
|
+
outputs: [
|
|
239
|
+
{
|
|
240
|
+
address: testData.signedSendTransaction.recipientBounceable.address,
|
|
241
|
+
amount: testData.signedSendTransaction.recipientBounceable.amount,
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
outputAmount: testData.signedSendTransaction.recipientBounceable.amount,
|
|
245
|
+
changeOutputs: [],
|
|
246
|
+
changeAmount: '0',
|
|
247
|
+
fee: { fee: 'UNKNOWN' },
|
|
248
|
+
withdrawAmount: undefined,
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
it('should explain a single nominator withdraw transaction', async function () {
|
|
252
|
+
const explainedTransaction = (await basecoin.explainTransaction({
|
|
253
|
+
txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
|
|
254
|
+
}));
|
|
255
|
+
explainedTransaction.should.deepEqual({
|
|
256
|
+
displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
|
|
257
|
+
id: testData.signedSingleNominatorWithdrawTransaction.txId,
|
|
258
|
+
outputs: [
|
|
259
|
+
{
|
|
260
|
+
address: testData.signedSingleNominatorWithdrawTransaction.recipient.address,
|
|
261
|
+
amount: testData.signedSingleNominatorWithdrawTransaction.recipient.amount,
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
outputAmount: testData.signedSingleNominatorWithdrawTransaction.recipient.amount,
|
|
265
|
+
changeOutputs: [],
|
|
266
|
+
changeAmount: '0',
|
|
267
|
+
fee: { fee: 'UNKNOWN' },
|
|
268
|
+
withdrawAmount: '932178112330000',
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
it('should explain a non-bounceable single nominator withdraw transaction', async function () {
|
|
272
|
+
const explainedTransaction = (await basecoin.explainTransaction({
|
|
273
|
+
txHex: Buffer.from(testData.signedSingleNominatorWithdrawTransaction.tx, 'base64').toString('hex'),
|
|
274
|
+
toAddressBounceable: false,
|
|
275
|
+
fromAddressBounceable: false,
|
|
276
|
+
}));
|
|
277
|
+
explainedTransaction.should.deepEqual({
|
|
278
|
+
displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'withdrawAmount'],
|
|
279
|
+
id: testData.signedSingleNominatorWithdrawTransaction.txIdBounceable,
|
|
280
|
+
outputs: [
|
|
281
|
+
{
|
|
282
|
+
address: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.address,
|
|
283
|
+
amount: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.amount,
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
outputAmount: testData.signedSingleNominatorWithdrawTransaction.recipientBounceable.amount,
|
|
287
|
+
changeOutputs: [],
|
|
288
|
+
changeAmount: '0',
|
|
289
|
+
fee: { fee: 'UNKNOWN' },
|
|
290
|
+
withdrawAmount: '932178112330000',
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
it('should fail to explain transaction with missing params', async function () {
|
|
294
|
+
try {
|
|
295
|
+
await basecoin.explainTransaction({});
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
should_1.default.equal(error.message, 'Invalid transaction');
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
it('should fail to explain transaction with invalid params', async function () {
|
|
302
|
+
try {
|
|
303
|
+
await basecoin.explainTransaction({ txHex: 'randomString' });
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
should_1.default.equal(error.message, 'Invalid transaction');
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
describe('Parse Transactions: ', () => {
|
|
311
|
+
const basecoin = bitgo.coin('tton');
|
|
312
|
+
const transactionsList = [testData.signedSendTransaction.tx, testData.signedSingleNominatorWithdrawTransaction.tx];
|
|
313
|
+
const transactionInputsResponseList = [
|
|
314
|
+
[
|
|
315
|
+
{
|
|
316
|
+
address: 'EQCSBjR3fUOL98WTw2F_IT4BrcqjZJWVLWUSz5WQDpaL9Jpl',
|
|
317
|
+
amount: '10000000',
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
[
|
|
321
|
+
{
|
|
322
|
+
address: 'EQAbJug-k-tufWMjEC1RKSM0iiJTDUcYkC7zWANHrkT55Fol',
|
|
323
|
+
amount: '123400000',
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
];
|
|
327
|
+
const transactionInputsResponseBounceableList = [
|
|
328
|
+
[
|
|
329
|
+
{
|
|
330
|
+
address: 'UQCSBjR3fUOL98WTw2F_IT4BrcqjZJWVLWUSz5WQDpaL9Meg',
|
|
331
|
+
amount: '10000000',
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
[
|
|
335
|
+
{
|
|
336
|
+
address: 'UQAbJug-k-tufWMjEC1RKSM0iiJTDUcYkC7zWANHrkT55Afg',
|
|
337
|
+
amount: '123400000',
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
];
|
|
341
|
+
const transactionOutputsResponseList = [
|
|
342
|
+
[
|
|
343
|
+
{
|
|
344
|
+
address: 'EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG',
|
|
345
|
+
amount: '10000000',
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
[
|
|
349
|
+
{
|
|
350
|
+
address: 'EQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBXwtG',
|
|
351
|
+
amount: '123400000',
|
|
352
|
+
},
|
|
353
|
+
],
|
|
354
|
+
];
|
|
355
|
+
const transactionOutputsResponseBounceableList = [
|
|
356
|
+
[
|
|
357
|
+
{
|
|
358
|
+
address: 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD',
|
|
359
|
+
amount: '10000000',
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
[
|
|
363
|
+
{
|
|
364
|
+
address: 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD',
|
|
365
|
+
amount: '123400000',
|
|
366
|
+
},
|
|
367
|
+
],
|
|
368
|
+
];
|
|
369
|
+
transactionsList.forEach((_, index) => {
|
|
370
|
+
const transaction = transactionsList[index];
|
|
371
|
+
const transactionInputsResponse = transactionInputsResponseList[index];
|
|
372
|
+
const transactionInputsResponseBounceable = transactionInputsResponseBounceableList[index];
|
|
373
|
+
const transactionOutputsResponse = transactionOutputsResponseList[index];
|
|
374
|
+
const transactionOutputsResponseBounceable = transactionOutputsResponseBounceableList[index];
|
|
375
|
+
it('should parse a TON transaction', async function () {
|
|
376
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
377
|
+
txHex: Buffer.from(transaction, 'base64').toString('hex'),
|
|
378
|
+
});
|
|
379
|
+
parsedTransaction.should.deepEqual({
|
|
380
|
+
inputs: transactionInputsResponse,
|
|
381
|
+
outputs: transactionOutputsResponse,
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
it('should parse a non-bounceable TON transaction', async function () {
|
|
385
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
386
|
+
txHex: Buffer.from(transaction, 'base64').toString('hex'),
|
|
387
|
+
toAddressBounceable: false,
|
|
388
|
+
fromAddressBounceable: false,
|
|
389
|
+
});
|
|
390
|
+
parsedTransaction.should.deepEqual({
|
|
391
|
+
inputs: transactionInputsResponseBounceable,
|
|
392
|
+
outputs: transactionOutputsResponseBounceable,
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
it('should fail to parse a TON transaction when explainTransaction response is undefined', async function () {
|
|
396
|
+
const stub = sinon.stub(src_1.Ton.prototype, 'explainTransaction');
|
|
397
|
+
stub.resolves(undefined);
|
|
398
|
+
await basecoin.parseTransaction({ txHex: transaction }).should.be.rejectedWith('invalid raw transaction');
|
|
399
|
+
stub.restore();
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
describe('Address Validation', () => {
|
|
404
|
+
const basecoin = bitgo.coin('tton');
|
|
405
|
+
let keychains;
|
|
406
|
+
let commonKeychain;
|
|
407
|
+
before(function () {
|
|
408
|
+
commonKeychain =
|
|
409
|
+
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
|
|
410
|
+
keychains = [
|
|
411
|
+
{
|
|
412
|
+
id: '6424c353eaf78d000766e95949868468',
|
|
413
|
+
source: 'user',
|
|
414
|
+
type: 'tss',
|
|
415
|
+
commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
|
|
416
|
+
encryptedPrv: '{"iv":"cZd5i7L4RxtwrALW2rK7UA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"5zgoH1Bd3Fw=","ct":"9vVlnXFRtrM9FVEo+d2chbGHlM9lFZemueBuAs3BIkPo33Fo7jzwwNK/kIWkEyg+NmEBd5IaqAS157nvvvwzzsmMWlQdUz9qbmXNv3pg987cXFR08exS+4uhwP1YNOjJTRvRNcO9ZqHb46d4fmyJ/yC9/susCge7r/EsbaN5C3afv1dzybuq912FwaQElZLYYp5BICudFOMZ9k0UDMfKM/PMDkH7WexoGHr9GKq/bgCH2B39TZZyHKU6Uy47lXep2s6h0DrMwHOrnmiL3DZjOj88Ynvphlzxuo4eOlD2UHia2+nvIaISYs29Pr0DAvREutchvcBpExj1kWWPv7hQYrv8F0NAdatsbWl3w+xKyfiMKo1USlrwyJviypGtQtXOJyw0XPN0rv2+L5lW8BbjpzHfYYN13fJTedlGTFhhkzVtbbPAKE02kx7zCJcjYaiexdSTsrDLScYNT9/Jhdt27KpsooehwVohLfSKz4vbFfRu2MPZw3/+c/hfiJNgtz6esWbnxGrcE8U2IwPYCaK+Ghk4DcqWNIni59RI5B5kAsQOToII40qPN510uTgxBSPO7q7MHgkxdd4CqBq+ojr9j0P7oao8E5Y+CBDJrojDoCh1oCCDW9vo2dXlVcD8SIbw7U/9AfvEbA4xyE/5md1M7CIwLnWs2Ynv0YtaKoqhdS9x6FmHlMDhN/DKHinrwmowtrTT82fOkpO5g9saSmgU7Qy3gLt8t+VwdEyeFeQUKRSyci8qgqXQaZIg4+aXgaSOnlCFMtmB8ekYxEhTY5uzRfrNgS4s1QeqFBpNtUF+Ydi297pbVXnJoXAN+SVWd80GCx+yI2dpVC89k3rOWK9WeyqlnzuLJWp2RIOB9cdW8GFv/fN+QAJpYeVxOE4+nZDsKnsj8nKcg9t4Dlx1G6gLM1/Vq9YxNLbuzuRC0asUYvdMnoMvszmpm++TxndYisgNYscpZSoz7wvcazJNEPfhPVjEkd6tUUuN4GM35H0DmKCUQNT+a6B6hmHlTZvjxiyGAg5bY59hdjvJ+22QduazlEEC6LI3HrA7uK0TpplWzS1tCIFvTMUhj65DEZmNJ2+ZY9bQ4vsMf+DRR3OOG4t+DMlNfjOd3zNv3QoY95BjfWpryFwPzDq7bCP67JDsoj7j2TY5FRSrRkD77H0Ewlux2cWfjRTwcMHcdQxxuV0OP0aNjGDjybFN"}',
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
id: '6424c353eaf78d000766e96137d4404b',
|
|
420
|
+
source: 'backup',
|
|
421
|
+
type: 'tss',
|
|
422
|
+
commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
|
|
423
|
+
encryptedPrv: '{"iv":"vi0dPef/Rx7kG/pRySQi6Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"9efhQsiEvVs=","ct":"Gw6atvf6gxKzsjtl3xseipO3rAxp1mAz7Yu1ihFsi5/lf2vMZegApgZx+pyILFS9KKLHbNF3U6WgSYdrr2t4vzdLsXkH1WIxfHS+cd2C5N59yADZDnPJBT6pv/IRvaYelP0Ck3nIYQ2hSMm8op+VOWC/SzHeh7slYDqwEHTGan0Wigfvk1yRd7CCJTaEAomnc/4eFi2NY3X3gt/3opy9IAgknnwUFohn96EWpEQ0F6pbzH/Z8VF6gF+DUcrrByAxExUPnHQZiFk3YHU/vVV4FxBU/mVAE8xBsBn5ul5e5SUMPfc7TBuJWv4BByTNg9xDShF/91Yx2nbfUm5d9QmM8lpKgzzQvcK8POAPk87gRCuKnsGh5vNS0UppkHc+ocfzRQlGA6jze7QyyQO0rMj5Ly8kWjwk2vISvKYHYS1NR7VU549UIXo7NXjatunKSc3+IreoRUHIshiaLg6hl+pxCCuc0qQ43V0mdIfCjTN8gkGWLNk8R7tAGPz9jyapQPcPEGHgEz0ATIi6yMNWCsibS2eLiE1uVEJONoM4lk6FPl3Q2CHbW2MeEbqjY8hbaw18mNb2xSBH/Fwpiial+Tvi2imqgnCO4ZpO9bllKftZPcQy0stN+eGBlb5ufyflKkDSiChHYroGjEpmiFicdde48cJszF52uKNnf1q67fA9/S2FAHQab3EXojxH2Gbk+kkV2h/TYKFFZSWC3vi4e8mO+vjMUcR0AdsgPFyEIz0SCGuba3CnTLNdEuZwsauAeHkx2vUTnRgJPVgNeeuXmsVG76Sy2ggJHuals0Hj8U2Xda0qO1RuFfoCWfss9wn6HGRwPPkhSB/8oNguAqmRVGKkd8Zwt3IvrTd9fk0/rFFDJKGz7WyNHkYgUmNiGcItD12v0jx7FZ52EJzl3Av1RyJUQK18+8EYPh3SGiU9dt7VX0aF0uo6JouKhOeldUvMP+AugQz8fUclwTQsbboVg27Yxo0DyATVwThW5a56R6Qf5ZiQJluFuzs5y98rq0S5q046lE6o3vVmJpEdwjeSCJoET5CL4nTgkXyWvhm4eB8u/e66l3o0qbaSx8q9YYmT9EpRcl5TP4ThLBKETYdzVvg4exjQfektMatk5EyUpEIhZPXh5vXpJZesdfO9LJ8zTaHBsBjDPU7cdNgQMbebpataRi8A0el2/IJXl+E+olgAz5zC4i2O1Q=="}',
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
id: '6424c353eaf78d000766e9510b125fba',
|
|
427
|
+
source: 'bitgo',
|
|
428
|
+
type: 'tss',
|
|
429
|
+
commonKeychain: '19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
|
|
430
|
+
verifiedVssProof: true,
|
|
431
|
+
isBitGo: true,
|
|
432
|
+
},
|
|
433
|
+
];
|
|
434
|
+
});
|
|
435
|
+
it('should return true when validating a well formatted address', async function () {
|
|
436
|
+
const address = 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi';
|
|
437
|
+
basecoin.isValidAddress(address).should.equal(true);
|
|
438
|
+
});
|
|
439
|
+
it('should return false when validating an incorrectly formatted', async function () {
|
|
440
|
+
const address = 'wrongaddress';
|
|
441
|
+
basecoin.isValidAddress(address).should.equal(false);
|
|
442
|
+
});
|
|
443
|
+
it('should return true when validating a non-bounceable address format', async function () {
|
|
444
|
+
const address = 'UQA0i8-CdGnF_DhUHHf92R1ONH6sIA9vLZ_WLcCIhfBBX1aD';
|
|
445
|
+
basecoin.isValidAddress(address).should.equal(true);
|
|
446
|
+
});
|
|
447
|
+
it('should return true when validating addresses with memoIds', async function () {
|
|
448
|
+
const address1 = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n?memoId=123';
|
|
449
|
+
const address2 = 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi?memoId=123';
|
|
450
|
+
basecoin.isValidAddress(address1).should.equal(true);
|
|
451
|
+
basecoin.isValidAddress(address2).should.equal(true);
|
|
452
|
+
});
|
|
453
|
+
it('should return true for isWalletAddress with valid address for index 4', async function () {
|
|
454
|
+
const newAddress = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
|
|
455
|
+
const index = 4;
|
|
456
|
+
const params = { commonKeychain, address: newAddress, index, keychains };
|
|
457
|
+
(await basecoin.isWalletAddress(params)).should.equal(true);
|
|
458
|
+
});
|
|
459
|
+
it('should return true for isWalletAddress with valid addressand index', async function () {
|
|
460
|
+
const newAddress = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n?memoId=4';
|
|
461
|
+
const index = 4;
|
|
462
|
+
const params = { commonKeychain, address: newAddress, index, keychains };
|
|
463
|
+
(await basecoin.isWalletAddress(params)).should.equal(true);
|
|
464
|
+
});
|
|
465
|
+
it('should return false for isWalletAddress with valid address for index 5 and address is for a different index', async function () {
|
|
466
|
+
const wrongAddressForIndex5 = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
|
|
467
|
+
const index = 5;
|
|
468
|
+
const params = { commonKeychain, address: wrongAddressForIndex5, index, keychains };
|
|
469
|
+
(await basecoin.isWalletAddress(params)).should.equal(false);
|
|
470
|
+
});
|
|
471
|
+
it('should throw error for isWalletAddress when keychains is missing', async function () {
|
|
472
|
+
const address = 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n';
|
|
473
|
+
const index = 0;
|
|
474
|
+
const params = { commonKeychain, address, index };
|
|
475
|
+
await assert_1.default.rejects(async () => basecoin.isWalletAddress(params));
|
|
476
|
+
});
|
|
477
|
+
it('should throw error for isWalletAddress when new address is invalid', async function () {
|
|
478
|
+
const wrongAddress = 'badAddress';
|
|
479
|
+
const index = 0;
|
|
480
|
+
const params = { commonKeychain, address: wrongAddress, index };
|
|
481
|
+
await assert_1.default.rejects(async () => basecoin.isWalletAddress(params), {
|
|
482
|
+
message: `invalid address: ${wrongAddress}`,
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
describe('util class ', () => {
|
|
487
|
+
let commonKeychain;
|
|
488
|
+
let derivedPublicKey;
|
|
489
|
+
before(async function () {
|
|
490
|
+
commonKeychain =
|
|
491
|
+
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
|
|
492
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
493
|
+
derivedPublicKey = MPC.deriveUnhardened(commonKeychain, 'm/' + 0).slice(0, 64);
|
|
494
|
+
});
|
|
495
|
+
describe('getAddressFromPublicKey', function () {
|
|
496
|
+
it('should derive bounceable address by default', async function () {
|
|
497
|
+
(await utils_1.default.getAddressFromPublicKey(derivedPublicKey)).should.equal('EQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvavQ5');
|
|
498
|
+
(await utils_1.default.getAddressFromPublicKey(derivedPublicKey, true)).should.equal('EQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvavQ5');
|
|
499
|
+
});
|
|
500
|
+
it('should derive non-bounceable address when requested', async function () {
|
|
501
|
+
(await utils_1.default.getAddressFromPublicKey(derivedPublicKey, false)).should.equal('UQDVeyUJOx3AnZGWLtE0l-Vxv7c7uTnD8OXtCFhaO-nvaqn8');
|
|
502
|
+
});
|
|
503
|
+
it('should derive raw address when requested', async function () {
|
|
504
|
+
(await utils_1.default.getAddressFromPublicKey(derivedPublicKey, false, false)).should.equal('0:d57b25093b1dc09d91962ed13497e571bfb73bb939c3f0e5ed08585a3be9ef6a');
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
describe('getAddress', function () {
|
|
508
|
+
it('should return address as per bounceable flag', function () {
|
|
509
|
+
should_1.default.equal(utils_1.default.getAddress('UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi', false), 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi');
|
|
510
|
+
should_1.default.equal(utils_1.default.getAddress('UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi', true), 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n');
|
|
511
|
+
should_1.default.equal(utils_1.default.getAddress('EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n', true), 'EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n');
|
|
512
|
+
should_1.default.equal(utils_1.default.getAddress('EQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFL7n', false), 'UQB0Hyt1bTRfI0WK_ULZyKvrvP0PPtpTQFi_jKXVXX6KFOMi');
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
it('should validate block hash', async function () {
|
|
516
|
+
should_1.default.equal(utils_1.default.isValidBlockId('MPuOvHdu/z+t2l82YpZtiJQk8+FVKmWuKxd6ubn09fI='), true);
|
|
517
|
+
should_1.default.equal(utils_1.default.isValidBlockId('MPuOvHdu/z+t2l82YpZtiJQk8+FVKmWuKxd'), false);
|
|
518
|
+
should_1.default.equal(utils_1.default.isValidBlockId(''), false);
|
|
519
|
+
});
|
|
520
|
+
it('should validate transaction id', async function () {
|
|
521
|
+
should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLbVKBYxDtvpk='), true);
|
|
522
|
+
should_1.default.equal(utils_1.default.isValidTransactionId('3sykx6Rujy7UtBwHQ/X5kLgvKE0SKLA+ABiCKi7sX8o='), true); // No url friendly txid
|
|
523
|
+
should_1.default.equal(utils_1.default.isValidTransactionId('3sykx6Rujy7UtBwHQ_X5kLgvKE0SKLA-ABiCKi7sX8o='), true); // Url friendly txid
|
|
524
|
+
should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLb='), false);
|
|
525
|
+
should_1.default.equal(utils_1.default.isValidTransactionId('wlTdDOAXwJp8ESRfQAEJQIn0Tci_S5oLbVKBYxDtafdsasdadsfvpk='), false);
|
|
526
|
+
should_1.default.equal(utils_1.default.isValidTransactionId(''), false);
|
|
527
|
+
});
|
|
528
|
+
it('should generate transaction id', async function () {
|
|
529
|
+
const id = await utils_1.default.getMessageHashFromData('te6cckECCgEAAkoAA7V2k4Vw1nhxr7XcCBjWcFFHKqGwCglPSRuYAkWjWiTVAIAAAPbLgva0G7ytKw/xeE9a3FHK2RM8fgOpGvTpQRseeMer3efRKsiQAADxPhnaQFZWYrlQADRqbCUIAQIDAgHgBAUAgnIAZ0UIwmknkMaW7QboTcq48FfZ1NT5oMUj2VPOBr3zPoxriab4SfV65i6Hd1J2sFsuTcIWUobcKXMcIys+JWknAhMMwSvWBhmTzwRACAkB4YgA0nCuGs8ONfa7gQMazgoo5VQ2AUEp6SNzAEi0a0SaoBAHHgnPJBQQJ/meoCwzK5/PajBSxuJK2Gkva7NmlALNDs2IMEWi4ZRfIV4VeJpKBhzhKjNlFjuz60g+aeT5cNi4CU1NGLsrey/4AAAAGAAcBgEB3wcAaGIAK2cYdYCtxtBaWJ9hi7N+HVzeMsPQxLHSqYn7bfpOcRyh3NZQAAAAAAAAAAAAAAAAAAAAsWgA0nCuGs8ONfa7gQMazgoo5VQ2AUEp6SNzAEi0a0SaoBEAFbOMOsBW42gtLE+wxdm/Dq5vGWHoYljpVMT9tv0nOI5Q7msoAAYUWGAAAB7ZcF7WhMrMVypAAJ1BnYMTiAAAAAAAAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAG/Jh6EgTBRYQAAAAAAAAgAAAAAAA4E52AP/eAYnVhJkoII4YUrhpLfpDFt6mRKiktbFnqs+QFAWDAAacQ0=\\');
|
|
530
|
+
should_1.default.equal(id, 'TsVgNKT05cde4Q54sC+RFC7nToTrHk9ppGgE5M0jXtE=');
|
|
531
|
+
});
|
|
532
|
+
it('should deserialize a cell to get the address', function () {
|
|
533
|
+
const data1 = 'te6cckEBAQEAJAAAQ4AaFUTgUQ/k2i+DdAooib0wNVREZQ2z+8R9WQvvFNpUJBARyAgK';
|
|
534
|
+
const rawAddress1 = '0:d0aa2702887f26d17c1ba051444de981aaa223286d9fde23eac85f78a6d2a120';
|
|
535
|
+
should_1.default.equal(utils_1.default.getRawWalletAddressFromCell(data1), rawAddress1);
|
|
536
|
+
const data2 = 'te6cckEBAQEAJAAAQ5/75w034qP9T0ZXY3muM5ouvFlNoNPky2YUs+Hcxd8otjDkIOPq';
|
|
537
|
+
const rawAddress2 = '-1:df3869bf151fea7a32bb1bcd719cd175e2ca6d069f265b30a59f0ee62ef945b1';
|
|
538
|
+
should_1.default.equal(utils_1.default.getRawWalletAddressFromCell(data2), rawAddress2);
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
describe('Ton recover - Non-BitGo and Unsigned Sweep Transactions', function () {
|
|
542
|
+
let sandbox;
|
|
543
|
+
beforeEach(() => {
|
|
544
|
+
sandbox = sinon.createSandbox(); // Create a new sandbox for each test
|
|
545
|
+
});
|
|
546
|
+
afterEach(() => {
|
|
547
|
+
sandbox.restore(); // Restore all stubs after each test
|
|
548
|
+
});
|
|
549
|
+
it('should successfully recover funds for non-BitGo recovery', async function () {
|
|
550
|
+
// Define recovery parameters
|
|
551
|
+
const recoveryParams = {
|
|
552
|
+
bitgoKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
|
|
553
|
+
recoveryDestination: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
|
|
554
|
+
apiKey: 'db2554641c61e60a979cc6c0053f2ec91da9b13e71d287768c93c2fb556be53b',
|
|
555
|
+
userKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
|
|
556
|
+
walletPassphrase: 'dummyPassphrase',
|
|
557
|
+
};
|
|
558
|
+
// Mock the expected result for non-BitGo recovery
|
|
559
|
+
const mockResult = {
|
|
560
|
+
serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
|
|
561
|
+
scanIndex: 0,
|
|
562
|
+
coin: 'tton',
|
|
563
|
+
};
|
|
564
|
+
// Stub the recover function to return the mocked result
|
|
565
|
+
const sandbox = sinon.createSandbox();
|
|
566
|
+
sandbox.stub(basecoin, 'recover').resolves(mockResult);
|
|
567
|
+
// Call the recover function
|
|
568
|
+
const result = await basecoin.recover(recoveryParams);
|
|
569
|
+
// Validate the result
|
|
570
|
+
result.serializedTx.should.equal('te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=');
|
|
571
|
+
result.scanIndex.should.equal(0);
|
|
572
|
+
result.coin.should.equal('tton');
|
|
573
|
+
sandbox.restore(); // Restore the stubbed method
|
|
574
|
+
});
|
|
575
|
+
it('should return an unsigned sweep transaction if userKey and backupKey are missing', async function () {
|
|
576
|
+
// Define recovery parameters
|
|
577
|
+
const recoveryParams = {
|
|
578
|
+
bitgoKey: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
|
|
579
|
+
recoveryDestination: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
|
|
580
|
+
apiKey: 'db2554641c61e60a979cc6c0053f2ec91da9b13e71d287768c93c2fb556be53b',
|
|
581
|
+
};
|
|
582
|
+
// Mock the expected result for unsigned sweep transaction
|
|
583
|
+
const mockUnsignedTx = {
|
|
584
|
+
serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
|
|
585
|
+
scanIndex: 0,
|
|
586
|
+
coin: 'tton',
|
|
587
|
+
signableHex: 'dd98eb5a3700c0203237095ca1c0d5288bc0d650a9b59f7b81bac552f76137df',
|
|
588
|
+
derivationPath: 'm/0',
|
|
589
|
+
parsedTx: {
|
|
590
|
+
inputs: [
|
|
591
|
+
{
|
|
592
|
+
address: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
|
|
593
|
+
valueString: '1000000000',
|
|
594
|
+
value: 1000000000,
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
outputs: [
|
|
598
|
+
{
|
|
599
|
+
address: 'UQBL2idCXR4ATdQtaNa4VpofcpSxuxIgHH7_slOZfdOXSadJ',
|
|
600
|
+
valueString: '999000000',
|
|
601
|
+
coinName: 'tton',
|
|
602
|
+
},
|
|
603
|
+
],
|
|
604
|
+
spendAmount: 999000000,
|
|
605
|
+
type: '',
|
|
606
|
+
},
|
|
607
|
+
feeInfo: {
|
|
608
|
+
fee: 1000000,
|
|
609
|
+
feeString: '1000000',
|
|
610
|
+
},
|
|
611
|
+
coinSpecific: {
|
|
612
|
+
commonKeychain: '1baafa0d62174bf0c78f3256318613ffc44b6dd54ab1a63c2185232f92ede9dae1b2818dbeb52a8215fd56f5a5f2a9f94c079ce89e4dc3b1ce6ed6e84ce71857',
|
|
613
|
+
},
|
|
614
|
+
};
|
|
615
|
+
const mockTxRequest = {
|
|
616
|
+
transactions: [
|
|
617
|
+
{
|
|
618
|
+
unsignedTx: mockUnsignedTx,
|
|
619
|
+
signatureShares: [],
|
|
620
|
+
},
|
|
621
|
+
],
|
|
622
|
+
walletCoin: 'ton',
|
|
623
|
+
};
|
|
624
|
+
const mockTxRequests = {
|
|
625
|
+
txRequests: [mockTxRequest],
|
|
626
|
+
};
|
|
627
|
+
// Stub the recover function to return the mocked unsigned sweep transaction
|
|
628
|
+
const sandbox = sinon.createSandbox();
|
|
629
|
+
sandbox.stub(basecoin, 'recover').resolves(mockTxRequests);
|
|
630
|
+
// Call the recover function
|
|
631
|
+
const result = await basecoin.recover(recoveryParams);
|
|
632
|
+
// Validate the result
|
|
633
|
+
result.should.have.property('txRequests');
|
|
634
|
+
result.txRequests[0].should.have.property('transactions');
|
|
635
|
+
result.txRequests[0].transactions[0].should.have.property('unsignedTx');
|
|
636
|
+
result.txRequests[0].transactions[0].unsignedTx.should.equal(mockUnsignedTx);
|
|
637
|
+
});
|
|
638
|
+
it('should take OVC output and generate a signed sweep transaction', async function () {
|
|
639
|
+
// Define the parameters (mock OVC response)
|
|
640
|
+
const params = {
|
|
641
|
+
ovcResponse: {
|
|
642
|
+
serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
|
|
643
|
+
scanIndex: 0,
|
|
644
|
+
lastScanIndex: 0,
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
// Mock the expected result for the signed sweep transaction
|
|
648
|
+
const mockSignedSweepTxn = {
|
|
649
|
+
transactions: [
|
|
650
|
+
{
|
|
651
|
+
serializedTx: 'te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=',
|
|
652
|
+
scanIndex: 0,
|
|
653
|
+
},
|
|
654
|
+
],
|
|
655
|
+
lastScanIndex: 0,
|
|
656
|
+
};
|
|
657
|
+
// Stub the createBroadcastableSweepTransaction function to return the mocked result
|
|
658
|
+
sandbox.stub(basecoin, 'createBroadcastableSweepTransaction').resolves(mockSignedSweepTxn);
|
|
659
|
+
// Call the createBroadcastableSweepTransaction function
|
|
660
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
661
|
+
// Validate the result
|
|
662
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('te6cckEBAgEAqgAB4YgAl7ROhLo8AJuoWtGtcK00PuUpY3YkQDj9/2SnMvunLpIFbl896wlMv7fsUOc+sMHzEl8q3vX5bm6noHginPJKBRznOrO7veIpHIEpiRLbH7/eNdpSsRhvL260JP/fD0vAIU1NGLtABDqAAAAACAAcAQBoQgB/OeiNdLeaL7+O04XuujuChSGrRd7ZnFl2fCd9FXdzAyDOJYCwAAAAAAAAAAAAAAAAAFwXGt8=');
|
|
663
|
+
recoveryTxn.transactions[0].scanIndex.should.equal(0);
|
|
664
|
+
recoveryTxn.lastScanIndex.should.equal(0);
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3Rvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhDQUE0QztBQUM1Qyw0Q0FBMEM7QUFDMUMsbUNBQWtFO0FBQ2xFLDZDQUErQjtBQUMvQixvREFBNEI7QUFDNUIsMkRBQTZDO0FBQzdDLDhDQUF1RTtBQUN2RSxvREFBNEI7QUFDNUIsZ0VBQXdDO0FBQ3hDLG9EQUE0QjtBQUU1QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxRQUFRLENBQUM7SUFDYixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDNUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzlDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUMzQixNQUFNLGNBQWMsR0FBRztRQUNyQjtZQUNFLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUMvRSxNQUFNLEVBQUUsRUFBRTtTQUNYO1FBQ0Q7WUFDRSxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsd0NBQXdDLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDbEcsTUFBTSxFQUFFLEVBQUU7U0FDWDtLQUNGLENBQUM7SUFDRixNQUFNLHdCQUF3QixHQUFHO1FBQy9CO1lBQ0UsS0FBSyxF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QUMsTUFBTSxDQUFDLEtBQUssQ0FDbkQsMFBBQTBQLENBQzNQLENBQUM7WUFDRixXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RELFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBUb24sIFRvblBhcnNlVHJhbnNhY3Rpb25PcHRpb25zLCBUdG9uIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL3Jlc291cmNlcy90b24nO1xuaW1wb3J0IHsgRUREU0FNZXRob2RzLCBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCB1dGlscyBmcm9tICcuLi8uLi9zcmMvbGliL3V0aWxzJztcbmltcG9ydCBUb253ZWIgZnJvbSAndG9ud2ViJztcblxuZGVzY3JpYmUoJ1RPTjonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiYXNlY29pbjtcbiAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gIGJpdGdvLnNhZmVSZWdpc3RlcigndG9uJywgVG9uLmNyZWF0ZUluc3RhbmNlKTtcbiAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0dG9uJywgVHRvbi5jcmVhdGVJbnN0YW5jZSk7XG4gIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICBjb25zdCB0eFByZWJ1aWxkTGlzdCA9IFtcbiAgICB7XG4gICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgdHhJbmZvOiB7fSxcbiAgICB9LFxuICAgIHtcbiAgICAgIHR4SGV4OiBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5zaWduZWRTaW5nbGVOb21pbmF0b3JXaXRoZHJhd1RyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgdHhJbmZvOiB7fSxcbiAgICB9LFxuICBdO1xuICBjb25zdCB0eFByZWJ1aWxkQm91bmNlYWJsZUxpc3QgPSBbXG4gICAge1xuICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbi50eEJvdW5jZWFibGUsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICB0eEluZm86IHt9LFxuICAgIH0sXG4gICAge1xuICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHhCb3VuY2VhYmxlLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgdHhJbmZvOiB7fSxcbiAgICB9LFxuICBdO1xuXG4gIGNvbnN0IHR4UGFyYW1zTGlzdCA9IFtcbiAgICB7XG4gICAgICByZWNpcGllbnRzOiBbdGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnJlY2lwaWVudF0sXG4gICAgfSxcbiAgICB7XG4gICAgICByZWNpcGllbnRzOiBbdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi5yZWNpcGllbnRdLFxuICAgIH0sXG4gIF07XG5cbiAgY29uc3QgdHhQYXJhbXNCb3VuY2VhYmxlTGlzdCA9IFtcbiAgICB7XG4gICAgICByZWNpcGllbnRzOiBbdGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnJlY2lwaWVudEJvdW5jZWFibGVdLFxuICAgIH0sXG4gICAge1xuICAgICAgcmVjaXBpZW50czogW3Rlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZV0sXG4gICAgfSxcbiAgXTtcblxuICBpdCgnc2hvdWxkIHJldHVybiB0aGUgcmlnaHQgaW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0b24gPSBiaXRnby5jb2luKCd0b24nKTtcbiAgICBjb25zdCB0dG9uID0gYml0Z28uY29pbigndHRvbicpO1xuXG4gICAgdG9uLmdldENoYWluKCkuc2hvdWxkLmVxdWFsKCd0b24nKTtcbiAgICB0b24uZ2V0RmFtaWx5KCkuc2hvdWxkLmVxdWFsKCd0b24nKTtcbiAgICB0b24uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1RvbicpO1xuICAgIHRvbi5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlOSk7XG5cbiAgICB0dG9uLmdldENoYWluKCkuc2hvdWxkLmVxdWFsKCd0dG9uJyk7XG4gICAgdHRvbi5nZXRGYW1pbHkoKS5zaG91bGQuZXF1YWwoJ3RvbicpO1xuICAgIHR0b24uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1Rlc3RuZXQgVG9uJyk7XG4gICAgdHRvbi5nZXRCYXNlRmFjdG9yKCkuc2hvdWxkLmVxdWFsKDFlOSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdWZXJpZnkgdHJhbnNhY3Rpb246ICcsICgpID0+IHtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R0b24nKTtcbiAgICB0eFBhcmFtc0xpc3QuZm9yRWFjaCgoXywgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gdHhQYXJhbXNMaXN0W2luZGV4XTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB0eFByZWJ1aWxkTGlzdFtpbmRleF07XG4gICAgICBjb25zdCB0eFBhcmFtc0JvdW5jZWFibGUgPSB0eFBhcmFtc0JvdW5jZWFibGVMaXN0W2luZGV4XTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGRCb3VuY2VhYmxlID0gdHhQcmVidWlsZEJvdW5jZWFibGVMaXN0W2luZGV4XTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgfSBhcyBhbnkpO1xuICAgICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuXG4gICAgICAgIGNvbnN0IGlzQm91bmNlYWJsZVRyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zQm91bmNlYWJsZSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkQm91bmNlYWJsZSxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICB9IGFzIGFueSk7XG4gICAgICAgIGlzQm91bmNlYWJsZVRyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gd2hlbiByZWNpcGllbnRzIGFtb3VudCBhcmUgbnVtYmVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodHhQYXJhbXMpKTtcbiAgICAgICAgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzWzBdLmFtb3VudCA9IDIwMDAwMDAwO1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zV2l0aE51bWJlckFtb3VudHMsXG4gICAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgIH0gYXMgYW55KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdUeCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdHhQYXJhbXMgcmVjaXBpZW50cycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gd2hlbiByZWNpcGllbnRzIGFtb3VudCBhcmUgc3RyaW5ncycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodHhQYXJhbXMpKTtcbiAgICAgICAgdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cy5yZWNpcGllbnRzWzBdLmFtb3VudCA9ICcyMDAwMDAwMCc7XG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aGVuIHJlY2lwaWVudHMgYW1vdW50cyBhcmUgbnVtYmVyIGFuZCBhbW91bnQgaXMgc2FtZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgICB9IGFzIGFueSlcbiAgICAgICAgICAuc2hvdWxkLnJlc29sdmVkV2l0aCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9uIHdoZW4gcmVjaXBpZW50cyBhbW91bnRzIGFyZSBzdHJpbmcgYW5kIGFtb3VudCBpcyBzYW1lJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgIH0gYXMgYW55KVxuICAgICAgICAgIC5zaG91bGQucmVzb2x2ZWRXaXRoKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24gd2hlbiByZWNpcGllbnQgYWRkcmVzcyBhcmUgbm9uIGJvdW5jZWFibGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4UGFyYW1zV2l0aE51bWJlckFtb3VudHMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHR4UGFyYW1zKSk7XG4gICAgICAgIHR4UGFyYW1zV2l0aE51bWJlckFtb3VudHMucmVjaXBpZW50c1swXS5hZGRyZXNzID0gbmV3IFRvbndlYi5BZGRyZXNzKFxuICAgICAgICAgIHR4UGFyYW1zV2l0aE51bWJlckFtb3VudHMucmVjaXBpZW50c1swXS5hZGRyZXNzXG4gICAgICAgICkudG9TdHJpbmcodHJ1ZSwgdHJ1ZSwgZmFsc2UpO1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgICAgY29uc3QgaXNWZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXNXaXRoTnVtYmVyQW1vdW50cyxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgfSBhcyBhbnkpO1xuICAgICAgICBpc1ZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IHRyYW5zYWN0aW9uIHdpdGggaW52YWxpZCBwYXJhbScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHt9O1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgfSBhcyBhbnkpXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgdHggcHJlYnVpbGQgcHJvcGVydHkgdHhIZXgnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aXRoIHJlY2lwaWVudCBoYXZpbmcgbWVtbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbdGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uRm9yTWVtb0lkLnJlY2lwaWVudF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbkZvck1lbW9JZC50eCwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgdHhJbmZvOiB7fSxcbiAgICAgIH07XG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0gYXMgYW55KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dG9uJyk7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfSkpIGFzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd3aXRoZHJhd0Ftb3VudCddLFxuICAgICAgICBpZDogJ3R1eU9reUZVTXZfbmVWX0ZlTkJIMjROZDRjTUwyalVnRFA0empHa3VPRkk9JyxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbi5yZWNpcGllbnQuYWRkcmVzcyxcbiAgICAgICAgICAgIGFtb3VudDogdGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnJlY2lwaWVudC5hbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbm9uLWJvdW5jZWFibGUgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2VuZFRyYW5zYWN0aW9uLnR4LCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB0b0FkZHJlc3NCb3VuY2VhYmxlOiBmYWxzZSxcbiAgICAgICAgZnJvbUFkZHJlc3NCb3VuY2VhYmxlOiBmYWxzZSxcbiAgICAgIH0pKSBhcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VPdXRwdXRzJywgJ2NoYW5nZUFtb3VudCcsICdmZWUnLCAnd2l0aGRyYXdBbW91bnQnXSxcbiAgICAgICAgaWQ6ICd0dXlPa3lGVU12X25lVl9GZU5CSDI0TmQ0Y01MMmpVZ0RQNHpqR2t1T0ZJPScsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hZGRyZXNzLFxuICAgICAgICAgICAgYW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTZW5kVHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hbW91bnQsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgZmVlOiB7IGZlZTogJ1VOS05PV04nIH0sXG4gICAgICAgIHdpdGhkcmF3QW1vdW50OiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpbmdsZSBub21pbmF0b3Igd2l0aGRyYXcgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQnVmZmVyLmZyb20odGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eCwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIH0pKSBhcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VPdXRwdXRzJywgJ2NoYW5nZUFtb3VudCcsICdmZWUnLCAnd2l0aGRyYXdBbW91bnQnXSxcbiAgICAgICAgaWQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHhJZCxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFkZHJlc3MsXG4gICAgICAgICAgICBhbW91bnQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRBbW91bnQ6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6ICc5MzIxNzgxMTIzMzAwMDAnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBub24tYm91bmNlYWJsZSBzaW5nbGUgbm9taW5hdG9yIHdpdGhkcmF3IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24udHgsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHRvQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgICBmcm9tQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgfSkpIGFzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd3aXRoZHJhd0Ftb3VudCddLFxuICAgICAgICBpZDogdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eElkQm91bmNlYWJsZSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRlc3REYXRhLnNpZ25lZFNpbmdsZU5vbWluYXRvcldpdGhkcmF3VHJhbnNhY3Rpb24ucmVjaXBpZW50Qm91bmNlYWJsZS5hZGRyZXNzLFxuICAgICAgICAgICAgYW1vdW50OiB0ZXN0RGF0YS5zaWduZWRTaW5nbGVOb21pbmF0b3JXaXRoZHJhd1RyYW5zYWN0aW9uLnJlY2lwaWVudEJvdW5jZWFibGUuYW1vdW50LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG91dHB1dEFtb3VudDogdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi5yZWNpcGllbnRCb3VuY2VhYmxlLmFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiAnVU5LTk9XTicgfSxcbiAgICAgICAgd2l0aGRyYXdBbW91bnQ6ICc5MzIxNzgxMTIzMzAwMDAnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZXhwbGFpbiB0cmFuc2FjdGlvbiB3aXRoIG1pc3NpbmcgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHt9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2l0aCBpbnZhbGlkIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4SGV4OiAncmFuZG9tU3RyaW5nJyB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGFyc2UgVHJhbnNhY3Rpb25zOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dG9uJyk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbnNMaXN0ID0gW3Rlc3REYXRhLnNpZ25lZFNlbmRUcmFuc2FjdGlvbi50eCwgdGVzdERhdGEuc2lnbmVkU2luZ2xlTm9taW5hdG9yV2l0aGRyYXdUcmFuc2FjdGlvbi50eF07XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlTGlzdCA9IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICdFUUNTQmpSM2ZVT0w5OFdUdzJGX0lUNEJyY3FqWkpXVkxXVVN6NVdRRHBhTDlKcGwnLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnRVFBYkp1Zy1rLXR1ZldNakVDMVJLU00waWlKVERVY1lrQzd6V0FOSHJrVDU1Rm9sJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMjM0MDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICBdO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGVMaXN0ID0gW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ1VRQ1NCalIzZlVPTDk4V1R3MkZfSVQ0QnJjcWpaSldWTFdVU3o1V1FEcGFMOU1lZycsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICdVUUFiSnVnLWstdHVmV01qRUMxUktTTTBpaUpURFVjWWtDN3pXQU5IcmtUNTVBZmcnLFxuICAgICAgICAgIGFtb3VudDogJzEyMzQwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIF07XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbk91dHB1dHNSZXNwb25zZUxpc3QgPSBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnRVFBMGk4LUNkR25GX0RoVUhIZjkyUjFPTkg2c0lBOXZMWl9XTGNDSWhmQkJYd3RHJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ0VRQTBpOC1DZEduRl9EaFVISGY5MlIxT05INnNJQTl2TFpfV0xjQ0loZkJCWHd0RycsXG4gICAgICAgICAgYW1vdW50OiAnMTIzNDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgXTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uT3V0cHV0c1Jlc3BvbnNlQm91bmNlYWJsZUxpc3QgPSBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOiAnVVFBMGk4LUNkR25GX0RoVUhIZjkyUjFPTkg2c0lBOXZMWl9XTGNDSWhmQkJYMWFEJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogJ1VRQTBpOC1DZEduRl9EaFVISGY5MlIxT05INnNJQTl2TFpfV0xjQ0loZkJCWDFhRCcsXG4gICAgICAgICAgYW1vdW50OiAnMTIzNDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgXTtcblxuICAgIHRyYW5zYWN0aW9uc0xpc3QuZm9yRWFjaCgoXywgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb25zTGlzdFtpbmRleF07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlID0gdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGUgPSB0cmFuc2FjdGlvbklucHV0c1Jlc3BvbnNlQm91bmNlYWJsZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2UgPSB0cmFuc2FjdGlvbk91dHB1dHNSZXNwb25zZUxpc3RbaW5kZXhdO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlID0gdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlTGlzdFtpbmRleF07XG5cbiAgICAgIGl0KCdzaG91bGQgcGFyc2UgYSBUT04gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB9KTtcblxuICAgICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgICBpbnB1dHM6IHRyYW5zYWN0aW9uSW5wdXRzUmVzcG9uc2UsXG4gICAgICAgICAgb3V0cHV0czogdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2UsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcGFyc2UgYSBub24tYm91bmNlYWJsZSBUT04gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhIZXg6IEJ1ZmZlci5mcm9tKHRyYW5zYWN0aW9uLCAnYmFzZTY0JykudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIHRvQWRkcmVzc0JvdW5jZWFibGU6IGZhbHNlLFxuICAgICAgICAgIGZyb21BZGRyZXNzQm91bmNlYWJsZTogZmFsc2UsXG4gICAgICAgIH0gYXMgVG9uUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpO1xuXG4gICAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICAgIGlucHV0czogdHJhbnNhY3Rpb25JbnB1dHNSZXNwb25zZUJvdW5jZWFibGUsXG4gICAgICAgICAgb3V0cHV0czogdHJhbnNhY3Rpb25PdXRwdXRzUmVzcG9uc2VCb3VuY2VhYmxlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gcGFyc2UgYSBUT04gdHJhbnNhY3Rpb24gd2hlbiBleHBsYWluVHJhbnNhY3Rpb24gcmVzcG9uc2UgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzdHViID0gc2lub24uc3R1YihUb24ucHJvdG90eXBlLCAnZXhwbGFpblRyYW5zYWN0aW9uJyk7XG4gICAgICAgIHN0dWIucmVzb2x2ZXModW5kZWZpbmVkKTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7IHR4SGV4OiB0cmFuc2FjdGlvbiB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICAgICAgICBzdHViLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBWYWxpZGF0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHRvbicpO1xuICAgIGxldCBrZXljaGFpbnM7XG4gICAgbGV0IGNvbW1vbktleWNoYWluO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbW1vbktleWNoYWluID1cbiAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJztcbiAgICAgIGtleWNoYWlucyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTU5NDk4Njg0NjgnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6XG4gICAgICAgICAgICAne1wiaXZcIjpcImNaZDVpN0w0Unh0d3JBTFcycks3VUE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCI1emdvSDFCZDNGdz1cIixcImN0XCI6XCI5dlZsblhGUnRyTTlGVkVvK2QyY2hiR0hsTTlsRlplbXVlQnVBczNCSWtQbzMzRm83anp3d05LL2tJV2tFeWcrTm1FQmQ1SWFxQVMxNTdudnZ2d3p6c21NV2xRZFV6OXFibVhOdjNwZzk4N2NYRlIwOGV4Uys0dWh3UDFZTk9qSlRSdlJOY085WnFIYjQ2ZDRmbXlKL3lDOS9zdXNDZ2U3ci9Fc2JhTjVDM2FmdjFkenlidXE5MTJGd2FRRWxaTFlZcDVCSUN1ZEZPTVo5azBVRE1mS00vUE1Ea0g3V2V4b0dIcjlHS3EvYmdDSDJCMzlUWlp5SEtVNlV5NDdsWGVwMnM2aDBEck13SE9ybm1pTDNEWmpPajg4WW52cGhsenh1bzRlT2xEMlVIaWEyK252SWFJU1lzMjlQcjBEQXZSRXV0Y2h2Y0JwRXhqMWtXV1B2N2hRWXJ2OEYwTkFkYXRzYldsM3creEt5ZmlNS28xVVNscnd5SnZpeXBHdFF0WE9KeXcwWFBOMHJ2MitMNWxXOEJianB6SGZZWU4xM2ZKVGVkbEdURmhoa3pWdGJiUEFLRTAya3g3ekNKY2pZYWlleGRTVHNyRExTY1lOVDkvSmhkdDI3S3Bzb29laHdWb2hMZlNLejR2YkZmUnUyTVBadzMvK2MvaGZpSk5ndHo2ZXNXYm54R3JjRThVMkl3UFlDYUsrR2hrNERjcVdOSW5pNTlSSTVCNWtBc1FPVG9JSTQwcVBONTEwdVRneEJTUE83cTdNSGdreGRkNENxQnErb2pyOWowUDdvYW84RTVZK0NCREpyb2pEb0NoMW9DQ0RXOXZvMmRYbFZjRDhTSWJ3N1UvOUFmdkViQTR4eUUvNW1kMU03Q0l3TG5XczJZbnYwWXRhS29xaGRTOXg2Rm1IbE1EaE4vREtIaW5yd21vd3RyVFQ4MmZPa3BPNWc5c2FTbWdVN1F5M2dMdDh0K1Z3ZEV5ZUZlUVVLUlN5Y2k4cWdxWFFhWklnNCthWGdhU09ubENGTXRtQjhla1l4RWhUWTV1elJmck5nUzRzMVFlcUZCcE50VUYrWWRpMjk3cGJWWG5Kb1hBTitTVldkODBHQ3greUkyZHBWQzg5azNyT1dLOVdleXFsbnp1TEpXcDJSSU9COWNkVzhHRnYvZk4rUUFKcFllVnhPRTQrblpEc0tuc2o4bktjZzl0NERseDFHNmdMTTEvVnE5WXhOTGJ1enVSQzBhc1VZdmRNbm9NdnN6bXBtKytUeG5kWWlzZ05Zc2NwWlNvejd3dmNhekpORVBmaFBWakVrZDZ0VVV1TjRHTTM1SDBEbUtDVVFOVCthNkI2aG1IbFRadmp4aXlHQWc1Ylk1OWhkanZKKzIyUWR1YXpsRUVDNkxJM0hyQTd1SzBUcHBsV3pTMXRDSUZ2VE1VaGo2NURFWm1OSjIrWlk5YlE0dnNNZitEUlIzT09HNHQrRE1sTmZqT2Qzek52M1FvWTk1QmpmV3ByeUZ3UHpEcTdiQ1A2N0pEc29qN2oyVFk1RlJTclJrRDc3SDBFd2x1eDJjV2ZqUlR3Y01IY2RReHh1VjBPUDBhTmpHRGp5YkZOXCJ9JyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnNjQyNGMzNTNlYWY3OGQwMDA3NjZlOTYxMzdkNDQwNGInLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAnMTliZGZlMmE0YjQ5OGEwNTUxMTM4MTIzNWE4ODkyZDU0MjY3ODA3YzRhM2Y2NTRlMzEwYjkzOGI4YjQyNGZmNGFkZWRiZTkyZjRjMTQ2ZGU2NDFjNjc1MDhhOTYxMzI0Yzg1MDRjZGY4ZTBjMGFjYmI2OGQ2MTA0Y2NjY2Q3ODEnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICAgICAgICd7XCJpdlwiOlwidmkwZFBlZi9SeDdrRy9wUnlTUWk2UT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjllZmhRc2lFdlZzPVwiLFwiY3RcIjpcIkd3NmF0dmY2Z3hLenNqdGwzeHNlaXBPM3JBeHAxbUF6N1l1MWloRnNpNS9sZjJ2TVplZ0FwZ1p4K3B5SUxGUzlLS0xIYk5GM1U2V2dTWWRycjJ0NHZ6ZExzWGtIMVdJeGZIUytjZDJDNU41OXlBRFpEblBKQlQ2cHYvSVJ2YVllbFAwQ2szbklZUTJoU01tOG9wK1ZPV0MvU3pIZWg3c2xZRHF3RUhUR2FuMFdpZ2Z2azF5UmQ3Q0NKVGFFQW9tbmMvNGVGaTJOWTNYM2d0LzNvcHk5SUFna25ud1VGb2huOTZFV3BFUTBGNnBiekgvWjhWRjZnRitEVWNyckJ5QXhFeFVQbkhRWmlGazNZSFUvdlZWNEZ4QlUvbVZBRTh4QnNCbjV1bDVlNVNVTVBmYzdUQnVKV3Y0QkJ5VE5nOXhEU2hGLzkxWXgybmJmVW01ZDlRbU04bHBLZ3p6UXZjSzhQT0FQazg3Z1JDdUtuc0doNXZOUzBVcHBrSGMrb2NmelJRbEdBNmp6ZTdReXlRTzByTWo1THk4a1dqd2sydklTdktZSFlTMU5SN1ZVNTQ5VUlYbzdOWGphdHVuS1NjMytJcmVvUlVISXNoaWFMZzZobCtweENDdWMwcVE0M1YwbWRJZkNqVE44Z2tHV0xOazhSN3RBR1B6OWp5YXBRUGNQRUdIZ0V6MEFUSWk2eU1OV0NzaWJTMmVMaUUxdVZFSk9Ob000bGs2RlBsM1EyQ0hiVzJNZUVicWpZOGhiYXcxOG1OYjJ4U0JIL0Z3cGlpYWwrVHZpMmltcWduQ080WnBPOWJsbEtmdFpQY1F5MHN0TitlR0JsYjV1ZnlmbEtrRFNpQ2hIWXJvR2pFcG1pRmljZGRlNDhjSnN6RjUydUtObmYxcTY3ZkE5L1MyRkFIUWFiM0VYb2p4SDJHYmsra2tWMmgvVFlLRkZaU1dDM3ZpNGU4bU8rdmpNVWNSMEFkc2dQRnlFSXowU0NHdWJhM0NuVExOZEV1WndzYXVBZUhreDJ2VVRuUmdKUFZnTmVldVhtc1ZHNzZTeTJnZ0pIdWFsczBIajhVMlhkYTBxTzFSdUZmb0NXZnNzOXduNkhHUndQUGtoU0IvOG9OZ3VBcW1SVkdLa2Q4Wnd0M0l2clRkOWZrMC9yRkZESktHejdXeU5Ia1lnVW1OaUdjSXREMTJ2MGp4N0ZaNTJFSnpsM0F2MVJ5SlVRSzE4KzhFWVBoM1NHaVU5ZHQ3VlgwYUYwdW82Sm91S2hPZWxkVXZNUCtBdWdRejhmVWNsd1RRc2Jib1ZnMjdZeG8wRHlBVFZ3VGhXNWE1NlI2UWY1WmlRSmx1RnV6czV5OThycTBTNXEwNDZsRTZvM3ZWbUpwRWR3amVTQ0pvRVQ1Q0w0blRna1h5V3ZobTRlQjh1L2U2NmwzbzBxYmFTeDhxOVlZbVQ5RXBSY2w1VFA0VGhMQktFVFlkelZ2ZzRleGpRZmVrdE1hdGs1RXlVcEVJaFpQWGg1dlhwSlplc2RmTzlMSjh6VGFIQnNCakRQVTdjZE5nUU1iZWJwYXRhUmk4QTBlbDIvSUpYbCtFK29sZ0F6NXpDNGkyTzFRPT1cIn0nLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICc2NDI0YzM1M2VhZjc4ZDAwMDc2NmU5NTEwYjEyNWZiYScsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgJzE5YmRmZTJhNGI0OThhMDU1MTEzODEyMzVhODg5MmQ1NDI2NzgwN2M0YTNmNjU0ZTMxMGI5MzhiOGI0MjRmZjRhZGVkYmU5MmY0YzE0NmRlNjQxYzY3NTA4YTk2MTMyNGM4NTA0Y2RmOGUwYzBhY2JiNjhkNjEwNGNjY2NkNzgxJyxcbiAgICAgICAgICB2ZXJpZmllZFZzc1Byb29mOiB0cnVlLFxuICAgICAgICAgIGlzQml0R286IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHZhbGlkYXRpbmcgYSB3ZWxsIGZvcm1hdHRlZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiB2YWxpZGF0aW5nIGFuIGluY29ycmVjdGx5IGZvcm1hdHRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAnd3JvbmdhZGRyZXNzJztcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gdmFsaWRhdGluZyBhIG5vbi1ib3VuY2VhYmxlIGFkZHJlc3MgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdVUUEwaTgtQ2RHbkZfRGhVSEhmOTJSMU9OSDZzSUE5dkxaX1dMY0NJaGZCQlgxYUQnO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHZhbGlkYXRpbmcgYWRkcmVzc2VzIHdpdGggbWVtb0lkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MxID0gJ0VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRkw3bj9tZW1vSWQ9MTIzJztcbiAgICAgIGNvbnN0IGFkZHJlc3MyID0gJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaT9tZW1vSWQ9MTIzJztcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MxKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzMikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgaXNXYWxsZXRBZGRyZXNzIHdpdGggdmFsaWQgYWRkcmVzcyBmb3IgaW5kZXggNCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ld0FkZHJlc3MgPSAnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJztcbiAgICAgIGNvbnN0IGluZGV4ID0gNDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogbmV3QWRkcmVzcywgaW5kZXgsIGtleWNoYWlucyB9O1xuICAgICAgKGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBpc1dhbGxldEFkZHJlc3Mgd2l0aCB2YWxpZCBhZGRyZXNzYW5kIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV3QWRkcmVzcyA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24/bWVtb0lkPTQnO1xuICAgICAgY29uc3QgaW5kZXggPSA0O1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzOiBuZXdBZGRyZXNzLCBpbmRleCwga2V5Y2hhaW5zIH07XG4gICAgICAoYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpc1dhbGxldEFkZHJlc3Mgd2l0aCB2YWxpZCBhZGRyZXNzIGZvciBpbmRleCA1IGFuZCBhZGRyZXNzIGlzIGZvciBhIGRpZmZlcmVudCBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdyb25nQWRkcmVzc0ZvckluZGV4NSA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nO1xuICAgICAgY29uc3QgaW5kZXggPSA1O1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzOiB3cm9uZ0FkZHJlc3NGb3JJbmRleDUsIGluZGV4LCBrZXljaGFpbnMgfTtcbiAgICAgIChhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSkuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGlzV2FsbGV0QWRkcmVzcyB3aGVuIGtleWNoYWlucyBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nO1xuICAgICAgY29uc3QgaW5kZXggPSAwO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7IGNvbW1vbktleWNoYWluLCBhZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaXNXYWxsZXRBZGRyZXNzIHdoZW4gbmV3IGFkZHJlc3MgaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdyb25nQWRkcmVzcyA9ICdiYWRBZGRyZXNzJztcbiAgICAgIGNvbnN0IGluZGV4ID0gMDtcblxuICAgICAgY29uc3QgcGFyYW1zID0geyBjb21tb25LZXljaGFpbiwgYWRkcmVzczogd3JvbmdBZGRyZXNzLCBpbmRleCB9O1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyksIHtcbiAgICAgICAgbWVzc2FnZTogYGludmFsaWQgYWRkcmVzczogJHt3cm9uZ0FkZHJlc3N9YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndXRpbCBjbGFzcyAnLCAoKSA9PiB7XG4gICAgbGV0IGNvbW1vbktleWNoYWluO1xuICAgIGxldCBkZXJpdmVkUHVibGljS2V5O1xuICAgIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICcxOWJkZmUyYTRiNDk4YTA1NTExMzgxMjM1YTg4OTJkNTQyNjc4MDdjNGEzZjY1NGUzMTBiOTM4YjhiNDI0ZmY0YWRlZGJlOTJmNGMxNDZkZTY0MWM2NzUwOGE5NjEzMjRjODUwNGNkZjhlMGMwYWNiYjY4ZDYxMDRjY2NjZDc4MSc7XG4gICAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgICAgZGVyaXZlZFB1YmxpY0tleSA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleWNoYWluLCAnbS8nICsgMCkuc2xpY2UoMCwgNjQpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dldEFkZHJlc3NGcm9tUHVibGljS2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgYm91bmNlYWJsZSBhZGRyZXNzIGJ5IGRlZmF1bHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5KSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdFUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmF2UTUnXG4gICAgICAgICk7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5LCB0cnVlKSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdFUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmF2UTUnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgbm9uLWJvdW5jZWFibGUgYWRkcmVzcyB3aGVuIHJlcXVlc3RlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKGF3YWl0IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGRlcml2ZWRQdWJsaWNLZXksIGZhbHNlKSkuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICdVUURWZXlVSk94M0FuWkdXTHRFMGwtVnh2N2M3dVRuRDhPWHRDRmhhTy1udmFxbjgnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBkZXJpdmUgcmF3IGFkZHJlc3Mgd2hlbiByZXF1ZXN0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIChhd2FpdCB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5LCBmYWxzZSwgZmFsc2UpKS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgJzA6ZDU3YjI1MDkzYjFkYzA5ZDkxOTYyZWQxMzQ5N2U1NzFiZmI3M2JiOTM5YzNmMGU1ZWQwODU4NWEzYmU5ZWY2YSdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dldEFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHJldHVybiBhZGRyZXNzIGFzIHBlciBib3VuY2VhYmxlIGZsYWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgICB1dGlscy5nZXRBZGRyZXNzKCdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknLCBmYWxzZSksXG4gICAgICAgICAgJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaSdcbiAgICAgICAgKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIHV0aWxzLmdldEFkZHJlc3MoJ1VRQjBIeXQxYlRSZkkwV0tfVUxaeUt2cnZQMFBQdHBUUUZpX2pLWFZYWDZLRk9NaScsIHRydWUpLFxuICAgICAgICAgICdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nXG4gICAgICAgICk7XG4gICAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgICB1dGlscy5nZXRBZGRyZXNzKCdFUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZMN24nLCB0cnVlKSxcbiAgICAgICAgICAnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJ1xuICAgICAgICApO1xuICAgICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgICAgdXRpbHMuZ2V0QWRkcmVzcygnRVFCMEh5dDFiVFJmSTBXS19VTFp5S3ZydlAwUFB0cFRRRmlfaktYVlhYNktGTDduJywgZmFsc2UpLFxuICAgICAgICAgICdVUUIwSHl0MWJUUmZJMFdLX1VMWnlLdnJ2UDBQUHRwVFFGaV9qS1hWWFg2S0ZPTWknXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYmxvY2sgaGFzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZCgnTVB1T3ZIZHUveit0Mmw4MllwWnRpSlFrOCtGVkttV3VLeGQ2dWJuMDlmST0nKSwgdHJ1ZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoJ01QdU92SGR1L3ordDJsODJZcFp0aUpRazgrRlZLbVd1S3hkJyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZCgnJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdHJhbnNhY3Rpb24gaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQoJ3dsVGRET0FYd0pwOEVTUmZRQUVKUUluMFRjaV9TNW9MYlZLQll4RHR2cGs9JyksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCczc3lreDZSdWp5N1V0QndIUS9YNWtMZ3ZLRTBTS0xBK0FCaUNLaTdzWDhvPScpLCB0cnVlKTsgLy8gTm8gdXJsIGZyaWVuZGx5IHR4aWRcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVHJhbnNhY3Rpb25JZCgnM3N5a3g2UnVqeTdVdEJ3SFFfWDVrTGd2S0UwU0tMQS1BQmlDS2k3c1g4bz0nKSwgdHJ1ZSk7IC8vIFVybCBmcmllbmRseSB0eGlkXG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQoJ3dsVGRET0FYd0pwOEVTUmZRQUVKUUluMFRjaV9TNW9MYj0nKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCd3bFRkRE9BWHdKcDhFU1JmUUFFSlFJbjBUY2lfUzVvTGJWS0JZeER0YWZkc2FzZGFkc2Z2cGs9JyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVHJhbnNhY3Rpb25JZCgnJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgdHJhbnNhY3Rpb24gaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpZCA9IGF3YWl0IHV0aWxzLmdldE1lc3NhZ2VIYXNoRnJvbURhdGEoXG4gICAgICAgICd0ZTZjY2tFQ0NnRUFBa29BQTdWMms0Vncxbmh4cjdYY0NCaldjRkZIS3FHd0NnbFBTUnVZQWtXaldpVFZBSUFBQVBiTGd2YTBHN3l0S3cveGVFOWEzRkhLMlJNOGZnT3BHdlRwUVJzZWVNZXIzZWZSS3NpUUFBRHhQaG5hUUZaV1lybFFBRFJxYkNVSUFRSURBZ0hnQkFVQWduSUFaMFVJd21rbmtNYVc3UWJvVGNxNDhGZloxTlQ1b01VajJWUE9CcjN6UG94cmlhYjRTZlY2NWk2SGQxSjJzRnN1VGNJV1VvYmNLWE1jSXlzK0pXa25BaE1Nd1N2V0JobVR6d1JBQ0FrQjRZZ0EwbkN1R3M4T05mYTdnUU1hemdvbzVWUTJBVUVwNlNOekFFaTBhMFNhb0JBSEhnblBKQlFRSi9tZW9Dd3pLNS9QYWpCU3h1SksyR2t2YTdObWxBTE5EczJJTUVXaTRaUmZJVjRWZUpwS0JoemhLak5sRmp1ejYwZythZVQ1Y05pNENVMU5HTHNyZXkvNEFBQUFHQUFjQmdFQjN3Y0FhR0lBSzJjWWRZQ3R4dEJhV0o5aGk3TitIVnplTXNQUXhMSFNxWW43YmZwT2NSeWgzTlpRQUFBQUFBQUFBQUFBQUFBQUFBQUFzV2dBMG5DdUdzOE9OZmE3Z1FNYXpnb281VlEyQVVFcDZTTnpBRWkwYTBTYW9CRUFGYk9NT3NCVzQyZ3RMRSt3eGRtL0RxNXZHV0hvWWxqcFZNVDl0djBuT0k1UTdtc29BQVlVV0dBQUFCN1pjRjdXaE1yTVZ5cEFBSjFCbllNVGlBQUFBQUFBQUFBQUVRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQWdBRy9KaDZFZ1RCUllRQUFBQUFBQUFnQUFBQUFBQTRFNTJBUC9lQVluVmhKa29JSTRZVXJocExmcERGdDZtUktpa3RiRm5xcytRRkFXREFBYWNRMD1cXFxcJ1xuICAgICAgKTtcbiAgICAgIHNob3VsZC5lcXVhbChpZCwgJ1RzVmdOS1QwNWNkZTRRNTRzQytSRkM3blRvVHJIazlwcEdnRTVNMGpYdEU9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRlc2VyaWFsaXplIGEgY2VsbCB0byBnZXQgdGhlIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhMSA9ICd0ZTZjY2tFQkFRRUFKQUFBUTRBYUZVVGdVUS9rMmkrRGRBb29pYjB3TlZSRVpRMnorOFI5V1F2dkZOcFVKQkFSeUFnSyc7XG4gICAgICBjb25zdCByYXdBZGRyZXNzMSA9ICcwOmQwYWEyNzAyODg3ZjI2ZDE3YzFiYTA1MTQ0NGRlOTgxYWFhMjIzMjg2ZDlmZGUyM2VhYzg1Zjc4YTZkMmExMjAnO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmdldFJhd1dhbGxldEFkZHJlc3NGcm9tQ2VsbChkYXRhMSksIHJhd0FkZHJlc3MxKTtcblxuICAgICAgY29uc3QgZGF0YTIgPSAndGU2Y2NrRUJBUUVBSkFBQVE1Lzc1dzAzNHFQOVQwWlhZM211TTVvdXZGbE5vTlBreTJZVXMrSGN4ZDhvdGpEa0lPUHEnO1xuICAgICAgY29uc3QgcmF3QWRkcmVzczIgPSAnLTE6ZGYzODY5YmYxNTFmZWE3YTMyYmIxYmNkNzE5Y2QxNzVlMmNhNmQwNjlmMjY1YjMwYTU5ZjBlZTYyZWY5NDViMSc7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuZ2V0UmF3V2FsbGV0QWRkcmVzc0Zyb21DZWxsKGRhdGEyKSwgcmF3QWRkcmVzczIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVG9uIHJlY292ZXIgLSBOb24tQml0R28gYW5kIFVuc2lnbmVkIFN3ZWVwIFRyYW5zYWN0aW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTsgLy8gQ3JlYXRlIGEgbmV3IHNhbmRib3ggZm9yIGVhY2ggdGVzdFxuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIHNhbmRib3gucmVzdG9yZSgpOyAvLyBSZXN0b3JlIGFsbCBzdHVicyBhZnRlciBlYWNoIHRlc3RcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IHJlY292ZXIgZnVuZHMgZm9yIG5vbi1CaXRHbyByZWNvdmVyeScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIERlZmluZSByZWNvdmVyeSBwYXJhbWV0ZXJzXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJzFiYWFmYTBkNjIxNzRiZjBjNzhmMzI1NjMxODYxM2ZmYzQ0YjZkZDU0YWIxYTYzYzIxODUyMzJmOTJlZGU5ZGFlMWIyODE4ZGJlYjUyYTgyMTVmZDU2ZjVhNWYyYTlmOTRjMDc5Y2U4OWU0ZGMzYjFjZTZlZDZlODRjZTcxODU3JyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgIGFwaUtleTogJ2RiMjU1NDY0MWM2MWU2MGE5NzljYzZjMDA1M2YyZWM5MWRhOWIxM2U3MWQyODc3NjhjOTNjMmZiNTU2YmU1M2InLFxuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdkdW1teVBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgLy8gTW9jayB0aGUgZXhwZWN0ZWQgcmVzdWx0IGZvciBub24tQml0R28gcmVjb3ZlcnlcbiAgICAgIGNvbnN0IG1vY2tSZXN1bHQgPSB7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDpcbiAgICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nLFxuICAgICAgICBzY2FuSW5kZXg6IDAsXG4gICAgICAgIGNvaW46ICd0dG9uJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIFN0dWIgdGhlIHJlY292ZXIgZnVuY3Rpb24gdG8gcmV0dXJuIHRoZSBtb2NrZWQgcmVzdWx0XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgc2FuZGJveC5zdHViKGJhc2Vjb2luLCAncmVjb3ZlcicpLnJlc29sdmVzKG1vY2tSZXN1bHQpO1xuXG4gICAgICAvLyBDYWxsIHRoZSByZWNvdmVyIGZ1bmN0aW9uXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgLy8gVmFsaWRhdGUgdGhlIHJlc3VsdFxuICAgICAgcmVzdWx0LnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICd0ZTZjY2tFQkFnRUFxZ0FCNFlnQWw3Uk9oTG84QUp1b1d0R3RjSzAwUHVVcFkzWWtRRGo5LzJTbk12dW5McElGYmw4OTZ3bE12N2ZzVU9jK3NNSHpFbDhxM3ZYNWJtNm5vSGdpblBKS0JSem5Pck83dmVJcEhJRXBpUkxiSDcvZU5kcFNzUmh2TDI2MEpQL2ZEMHZBSVUxTkdMdEFCRHFBQUFBQUNBQWNBUUJvUWdCL09laU5kTGVhTDcrTzA0WHV1anVDaFNHclJkN1puRmwyZkNkOUZYZHpBeURPSllDd0FBQUFBQUFBQUFBQUFBQUFBRndYR3Q4PSdcbiAgICAgICk7XG4gICAgICByZXN1bHQuc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlc3VsdC5jb2luLnNob3VsZC5lcXVhbCgndHRvbicpO1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7IC8vIFJlc3RvcmUgdGhlIHN0dWJiZWQgbWV0aG9kXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhbiB1bnNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbiBpZiB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBEZWZpbmUgcmVjb3ZlcnkgcGFyYW1ldGVyc1xuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdVUUJMMmlkQ1hSNEFUZFF0YU5hNFZwb2ZjcFN4dXhJZ0hIN19zbE9aZmRPWFNhZEonLFxuICAgICAgICBhcGlLZXk6ICdkYjI1NTQ2NDFjNjFlNjBhOTc5Y2M2YzAwNTNmMmVjOTFkYTliMTNlNzFkMjg3NzY4YzkzYzJmYjU1NmJlNTNiJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIE1vY2sgdGhlIGV4cGVjdGVkIHJlc3VsdCBmb3IgdW5zaWduZWQgc3dlZXAgdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IG1vY2tVbnNpZ25lZFR4ID0ge1xuICAgICAgICBzZXJpYWxpemVkVHg6XG4gICAgICAgICAgJ3RlNmNja0VCQWdFQXFnQUI0WWdBbDdST2hMbzhBSnVvV3RHdGNLMDBQdVVwWTNZa1FEajkvMlNuTXZ1bkxwSUZibDg5NndsTXY3ZnNVT2Mrc01IekVsOHEzdlg1Ym02bm9IZ2luUEpLQlJ6bk9yTzd2ZUlwSElFcGlSTGJINy9lTmRwU3NSaHZMMjYwSlAvZkQwdkFJVTFOR0x0QUJEcUFBQUFBQ0FBY0FRQm9RZ0IvT2VpTmRMZWFMNytPMDRYdXVqdUNoU0dyUmQ3Wm5GbDJmQ2Q5RlhkekF5RE9KWUN3QUFBQUFBQUFBQUFBQUFBQUFGd1hHdDg9JyxcbiAgICAgICAgc2NhbkluZGV4OiAwLFxuICAgICAgICBjb2luOiAndHRvbicsXG4gICAgICAgIHNpZ25hYmxlSGV4OiAnZGQ5OGViNWEzNzAwYzAyMDMyMzcwOTVjYTFjMGQ1Mjg4YmMwZDY1MGE5YjU5ZjdiODFiYWM1NTJmNzYxMzdkZicsXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiAnbS8wJyxcbiAgICAgICAgcGFyc2VkVHg6IHtcbiAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnMTAwMDAwMDAwMCcsXG4gICAgICAgICAgICAgIHZhbHVlOiAxMDAwMDAwMDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWRkcmVzczogJ1VRQkwyaWRDWFI0QVRkUXRhTmE0VnBvZmNwU3h1eElnSEg3X3NsT1pmZE9YU2FkSicsXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnOTk5MDAwMDAwJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0dG9uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBzcGVuZEFtb3VudDogOTk5MDAwMDAwLFxuICAgICAgICAgIHR5cGU6ICcnLFxuICAgICAgICB9LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAxMDAwMDAwLFxuICAgICAgICAgIGZlZVN0cmluZzogJzEwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICcxYmFhZmEwZDYyMTc0YmYwYzc4ZjMyNTYzMTg2MTNmZmM0NGI2ZGQ1NGFiMWE2M2MyMTg1MjMyZjkyZWRlOWRhZTFiMjgxOGRiZWI1MmE4MjE1ZmQ1NmY1YTVmMmE5Zjk0YzA3OWNlODllNGRjM2IxY2U2ZWQ2ZTg0Y2U3MTg1NycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrVHhSZXF1ZXN0ID0ge1xuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiBtb2NrVW5zaWduZWRUeCxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0Q29pbjogJ3RvbicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2NrVHhSZXF1ZXN0cyA9IHtcbiAgICAgICAgdHhSZXF1ZXN0czogW21vY2tUeFJlcXVlc3RdLFxuICAgICAgfTtcblxuICAgICAgLy8gU3R1YiB0aGUgcmVjb3ZlciBmdW5jdGlvbiB0byByZXR1cm4gdGhlIG1vY2tlZCB1bnNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvblxuICAgICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgc2FuZGJveC5zdHViKGJhc2Vjb2luLCAncmVjb3ZlcicpLnJlc29sdmVzKG1vY2tUeFJlcXVlc3RzKTtcblxuICAgICAgLy8gQ2FsbCB0aGUgcmVjb3ZlciBmdW5jdGlvblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIC8vIFZhbGlkYXRlIHRoZSByZXN1bHRcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICByZXN1bHQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuZXF1YWwobW9ja1Vuc2lnbmVkVHgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIGEgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIChtb2NrIE9WQyByZXNwb25zZSlcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgb3ZjUmVzcG9uc2U6IHtcbiAgICAgICAgICBzZXJpYWxpemVkVHg6XG4gICAgICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nLFxuICAgICAgICAgIHNjYW5JbmRleDogMCxcbiAgICAgICAgICBsYXN0U2NhbkluZGV4OiAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgLy8gTW9jayB0aGUgZXhwZWN0ZWQgcmVzdWx0IGZvciB0aGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uXG4gICAgICBjb25zdCBtb2NrU2lnbmVkU3dlZXBUeG4gPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlcmlhbGl6ZWRUeDpcbiAgICAgICAgICAgICAgJ3RlNmNja0VCQWdFQXFnQUI0WWdBbDdST2hMbzhBSnVvV3RHdGNLMDBQdVVwWTNZa1FEajkvMlNuTXZ1bkxwSUZibDg5NndsTXY3ZnNVT2Mrc01IekVsOHEzdlg1Ym02bm9IZ2luUEpLQlJ6bk9yTzd2ZUlwSElFcGlSTGJINy9lTmRwU3NSaHZMMjYwSlAvZkQwdkFJVTFOR0x0QUJEcUFBQUFBQ0FBY0FRQm9RZ0IvT2VpTmRMZWFMNytPMDRYdXVqdUNoU0dyUmQ3Wm5GbDJmQ2Q5RlhkekF5RE9KWUN3QUFBQUFBQUFBQUFBQUFBQUFGd1hHdDg9JyxcbiAgICAgICAgICAgIHNjYW5JbmRleDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBsYXN0U2NhbkluZGV4OiAwLFxuICAgICAgfTtcblxuICAgICAgLy8gU3R1YiB0aGUgY3JlYXRlQnJvYWRjYXN0YWJsZVN3ZWVwVHJhbnNhY3Rpb24gZnVuY3Rpb24gdG8gcmV0dXJuIHRoZSBtb2NrZWQgcmVzdWx0XG4gICAgICBzYW5kYm94LnN0dWIoYmFzZWNvaW4sICdjcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbicpLnJlc29sdmVzKG1vY2tTaWduZWRTd2VlcFR4bik7XG5cbiAgICAgIC8vIENhbGwgdGhlIGNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uIGZ1bmN0aW9uXG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG5cbiAgICAgIC8vIFZhbGlkYXRlIHRoZSByZXN1bHRcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAndGU2Y2NrRUJBZ0VBcWdBQjRZZ0FsN1JPaExvOEFKdW9XdEd0Y0swMFB1VXBZM1lrUURqOS8yU25NdnVuTHBJRmJsODk2d2xNdjdmc1VPYytzTUh6RWw4cTN2WDVibTZub0hnaW5QSktCUnpuT3JPN3ZlSXBISUVwaVJMYkg3L2VOZHBTc1JodkwyNjBKUC9mRDB2QUlVMU5HTHRBQkRxQUFBQUFDQUFjQVFCb1FnQi9PZWlOZExlYUw3K08wNFh1dWp1Q2hTR3JSZDdabkZsMmZDZDlGWGR6QXlET0pZQ3dBQUFBQUFBQUFBQUFBQUFBQUZ3WEd0OD0nXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICByZWNvdmVyeVR4bi5sYXN0U2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|