@bitgo-beta/sdk-coin-ada 2.3.14-beta.142 → 2.3.14-beta.1421
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/ada.d.ts +12 -13
- package/dist/src/ada.d.ts.map +1 -1
- package/dist/src/ada.js +79 -27
- package/dist/src/adaToken.d.ts +3 -10
- package/dist/src/adaToken.d.ts.map +1 -1
- package/dist/src/adaToken.js +6 -3
- package/dist/src/index.js +6 -2
- package/dist/src/lib/index.d.ts +2 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +29 -9
- package/dist/src/lib/keyPair.js +29 -16
- package/dist/src/lib/messages/cip8/cip8Message.d.ts +25 -0
- package/dist/src/lib/messages/cip8/cip8Message.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/cip8Message.js +140 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts +19 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/cip8MessageBuilder.js +27 -0
- package/dist/src/lib/messages/cip8/index.d.ts +4 -0
- package/dist/src/lib/messages/cip8/index.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/index.js +20 -0
- package/dist/src/lib/messages/cip8/utils.d.ts +24 -0
- package/dist/src/lib/messages/cip8/utils.d.ts.map +1 -0
- package/dist/src/lib/messages/cip8/utils.js +73 -0
- package/dist/src/lib/messages/index.d.ts +3 -0
- package/dist/src/lib/messages/index.d.ts.map +1 -0
- package/dist/src/lib/messages/index.js +19 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
- package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/src/lib/messages/messageBuilderFactory.js +20 -0
- package/dist/src/lib/stakingActivateBuilder.d.ts +1 -1
- package/dist/src/lib/stakingActivateBuilder.d.ts.map +1 -1
- package/dist/src/lib/stakingActivateBuilder.js +30 -10
- package/dist/src/lib/stakingDeactivateBuilder.js +24 -10
- package/dist/src/lib/transaction.d.ts +13 -6
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +49 -16
- package/dist/src/lib/transactionBuilder.d.ts +82 -3
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +416 -22
- package/dist/src/lib/transactionBuilderFactory.d.ts +2 -0
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +7 -1
- package/dist/src/lib/utils.d.ts +23 -0
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +153 -17
- package/dist/src/lib/voteDelegationBuilder.d.ts +24 -0
- package/dist/src/lib/voteDelegationBuilder.d.ts.map +1 -0
- package/dist/src/lib/voteDelegationBuilder.js +84 -0
- package/dist/test/resources/cip8Resources.d.ts +25 -0
- package/dist/test/resources/cip8Resources.d.ts.map +1 -0
- package/dist/test/resources/cip8Resources.js +76 -0
- package/dist/test/resources/index.d.ts +435 -0
- package/dist/test/resources/index.d.ts.map +1 -0
- package/dist/test/resources/index.js +635 -0
- package/dist/test/unit/StakingActivateBuilder.d.ts +2 -0
- package/dist/test/unit/StakingActivateBuilder.d.ts.map +1 -0
- package/dist/test/unit/StakingActivateBuilder.js +213 -0
- package/dist/test/unit/StakingDeactivateBuilder.d.ts +2 -0
- package/dist/test/unit/StakingDeactivateBuilder.d.ts.map +1 -0
- package/dist/test/unit/StakingDeactivateBuilder.js +158 -0
- package/dist/test/unit/ada.d.ts +5 -0
- package/dist/test/unit/ada.d.ts.map +1 -0
- package/dist/test/unit/ada.js +997 -0
- package/dist/test/unit/getBuilderFactory.d.ts +3 -0
- package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/getBuilderFactory.js +10 -0
- package/dist/test/unit/index.d.ts +2 -0
- package/dist/test/unit/index.d.ts.map +1 -0
- package/dist/test/unit/index.js +32 -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 +88 -0
- package/dist/test/unit/messages/cip8/cip8Message.d.ts +2 -0
- package/dist/test/unit/messages/cip8/cip8Message.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/cip8Message.js +131 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts +2 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/cip8MessageBuilder.js +132 -0
- package/dist/test/unit/messages/cip8/utils.d.ts +2 -0
- package/dist/test/unit/messages/cip8/utils.d.ts.map +1 -0
- package/dist/test/unit/messages/cip8/utils.js +127 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
- package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/messages/messageBuilderFactory.js +35 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.d.ts +2 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingClaimRewardsBuilder.js +70 -0
- package/dist/test/unit/stakingPledgeBuilder.d.ts +2 -0
- package/dist/test/unit/stakingPledgeBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingPledgeBuilder.js +141 -0
- package/dist/test/unit/stakingWithdrawBuilder.d.ts +2 -0
- package/dist/test/unit/stakingWithdrawBuilder.d.ts.map +1 -0
- package/dist/test/unit/stakingWithdrawBuilder.js +167 -0
- package/dist/test/unit/tokenWithdrawal.d.ts +2 -0
- package/dist/test/unit/tokenWithdrawal.d.ts.map +1 -0
- package/dist/test/unit/tokenWithdrawal.js +316 -0
- package/dist/test/unit/transaction.d.ts +2 -0
- package/dist/test/unit/transaction.d.ts.map +1 -0
- package/dist/test/unit/transaction.js +100 -0
- package/dist/test/unit/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder.js +454 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +138 -0
- package/dist/test/unit/voteDelegationBuilder.d.ts +2 -0
- package/dist/test/unit/voteDelegationBuilder.d.ts.map +1 -0
- package/dist/test/unit/voteDelegationBuilder.js +96 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +17 -12
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -322
|
@@ -0,0 +1,997 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @prettier
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
const should = require("should");
|
|
43
|
+
const crypto_1 = require("crypto");
|
|
44
|
+
const sinon = __importStar(require("sinon"));
|
|
45
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
46
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
47
|
+
const resources_1 = require("../resources");
|
|
48
|
+
const _ = __importStar(require("lodash"));
|
|
49
|
+
const src_1 = require("../../src");
|
|
50
|
+
const lib_1 = require("../../src/lib");
|
|
51
|
+
const enum_1 = require("../../../sdk-core/src/account-lib/baseCoin/enum");
|
|
52
|
+
const assert_1 = __importDefault(require("assert"));
|
|
53
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
54
|
+
const nock_1 = __importDefault(require("nock"));
|
|
55
|
+
describe('ADA', function () {
|
|
56
|
+
const coinName = 'ada';
|
|
57
|
+
const tcoinName = 't' + coinName;
|
|
58
|
+
let bitgo;
|
|
59
|
+
let basecoin;
|
|
60
|
+
let newTxPrebuild;
|
|
61
|
+
let newTxParams;
|
|
62
|
+
const txPrebuild = {
|
|
63
|
+
txHex: resources_1.rawTx.unsignedTx,
|
|
64
|
+
txInfo: {},
|
|
65
|
+
};
|
|
66
|
+
const txParams = {
|
|
67
|
+
recipients: [
|
|
68
|
+
{
|
|
69
|
+
address: resources_1.rawTx.outputAddress1.address,
|
|
70
|
+
amount: '5000000',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
address: resources_1.rawTx.outputAddress2.address,
|
|
74
|
+
amount: '248329150',
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
const transactionExplanation = {
|
|
79
|
+
displayOrder: ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'type'],
|
|
80
|
+
id: 'f48f6ea0f75f3f942855cc0edf29e81e1e0724e75f5db8a1575b166fb202176c',
|
|
81
|
+
outputs: [
|
|
82
|
+
{
|
|
83
|
+
address: 'addr_test1qqnnvptrc3rec64q2n9jh572ncu5wvdtt8uvg4g3aj96s5dwu9nj70mlahzglm9939uevupsmj8dcdqv25d5n5r8vw8sn7prey',
|
|
84
|
+
amount: '7823121',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
address: 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f',
|
|
88
|
+
amount: '13041729',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
outputAmount: '20864850',
|
|
92
|
+
changeOutputs: [],
|
|
93
|
+
changeAmount: '0',
|
|
94
|
+
fee: { fee: '167173' },
|
|
95
|
+
type: 'Transfer',
|
|
96
|
+
certificates: [],
|
|
97
|
+
withdrawals: [],
|
|
98
|
+
pledgeDetails: undefined,
|
|
99
|
+
};
|
|
100
|
+
before(function () {
|
|
101
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
|
|
102
|
+
bitgo.initializeTestVars();
|
|
103
|
+
bitgo.safeRegister(coinName, src_1.Ada.createInstance);
|
|
104
|
+
bitgo.safeRegister(tcoinName, src_1.Tada.createInstance);
|
|
105
|
+
basecoin = bitgo.coin(tcoinName);
|
|
106
|
+
newTxPrebuild = () => {
|
|
107
|
+
return _.cloneDeep(txPrebuild);
|
|
108
|
+
};
|
|
109
|
+
newTxParams = () => {
|
|
110
|
+
return _.cloneDeep(txParams);
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
it('should instantiate the coin', function () {
|
|
114
|
+
let localBasecoin = bitgo.coin(tcoinName);
|
|
115
|
+
localBasecoin.should.be.an.instanceof(src_1.Tada);
|
|
116
|
+
localBasecoin.getChain().should.equal(tcoinName);
|
|
117
|
+
localBasecoin.getFullName().should.equal('Testnet Ada');
|
|
118
|
+
localBasecoin = bitgo.coin(coinName);
|
|
119
|
+
localBasecoin.should.be.an.instanceof(src_1.Ada);
|
|
120
|
+
localBasecoin.getChain().should.equal(coinName);
|
|
121
|
+
localBasecoin.getFullName().should.equal('Cardano ADA');
|
|
122
|
+
});
|
|
123
|
+
describe('Sign Message', () => {
|
|
124
|
+
it('should be performed', async () => {
|
|
125
|
+
const keyPair = new src_1.KeyPair();
|
|
126
|
+
const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
|
|
127
|
+
const signature = await basecoin.signMessage(keyPair.getKeys(), messageToSign);
|
|
128
|
+
keyPair.verifySignature(messageToSign, Uint8Array.from(signature)).should.equals(false);
|
|
129
|
+
});
|
|
130
|
+
it('should fail with missing private key', async () => {
|
|
131
|
+
const keyPair = new src_1.KeyPair({
|
|
132
|
+
pub: '7788327c695dca4b3e649a0db45bc3e703a2c67428fce360e61800cc4248f4f7',
|
|
133
|
+
}).getKeys();
|
|
134
|
+
const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
|
|
135
|
+
await basecoin.signMessage(keyPair, messageToSign).should.be.rejectedWith('Invalid key pair options');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe('Sign transaction', () => {
|
|
139
|
+
it('should sign transaction', async function () {
|
|
140
|
+
const signed = await basecoin.signTransaction({
|
|
141
|
+
txPrebuild: {
|
|
142
|
+
txHex: resources_1.rawTx.unsignedTx2,
|
|
143
|
+
},
|
|
144
|
+
pubs: [resources_1.publicKeys.pubKey1],
|
|
145
|
+
prv: resources_1.privateKeys.prvKey4,
|
|
146
|
+
});
|
|
147
|
+
signed.txHex.should.equal(resources_1.rawTx.signedTx2);
|
|
148
|
+
});
|
|
149
|
+
it('should fail to sign transaction with an invalid key', async function () {
|
|
150
|
+
try {
|
|
151
|
+
await basecoin.signTransaction({
|
|
152
|
+
txPrebuild: {
|
|
153
|
+
txHex: resources_1.rawTx.unsignedTx2,
|
|
154
|
+
},
|
|
155
|
+
pubs: [resources_1.publicKeys.pubKey1],
|
|
156
|
+
prv: resources_1.privateKeys.prvKey2,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch (e) {
|
|
160
|
+
should.equal(e.message, 'Private key cannot sign the transaction');
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
it('should fail to build transaction with missing params', async function () {
|
|
164
|
+
try {
|
|
165
|
+
await basecoin.signTransaction({
|
|
166
|
+
txPrebuild: {
|
|
167
|
+
txHex: resources_1.rawTx.unsignedTx,
|
|
168
|
+
key: resources_1.enterpriseAccounts.account1.publicKey,
|
|
169
|
+
},
|
|
170
|
+
prv: resources_1.enterpriseAccounts.account1.secretKey,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
should.notEqual(e, null);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
describe('Generate wallet key pair: ', () => {
|
|
179
|
+
it('should generate key pair', () => {
|
|
180
|
+
const kp = basecoin.generateKeyPair();
|
|
181
|
+
basecoin.isValidPub(kp.pub).should.equal(true);
|
|
182
|
+
basecoin.isValidPrv(kp.prv).should.equal(true);
|
|
183
|
+
});
|
|
184
|
+
it('should generate key pair from seed', () => {
|
|
185
|
+
const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
|
|
186
|
+
const kp = basecoin.generateKeyPair(seed);
|
|
187
|
+
basecoin.isValidPub(kp.pub).should.equal(true);
|
|
188
|
+
basecoin.isValidPrv(kp.prv).should.equal(true);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
describe('Verify transaction: ', () => {
|
|
192
|
+
it('should succeed to verify unsigned transaction in hex encoding', async () => {
|
|
193
|
+
const txParams = newTxParams();
|
|
194
|
+
const txPrebuild = newTxPrebuild();
|
|
195
|
+
const verification = {};
|
|
196
|
+
const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
|
|
197
|
+
isTransactionVerified.should.equal(true);
|
|
198
|
+
});
|
|
199
|
+
it('should succeed to verify signed transaction in hex encoding', async () => {
|
|
200
|
+
const txPrebuild = {
|
|
201
|
+
txHex: resources_1.rawTx.signedTx,
|
|
202
|
+
txInfo: {},
|
|
203
|
+
};
|
|
204
|
+
const txParams = newTxParams();
|
|
205
|
+
const verification = {};
|
|
206
|
+
const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
|
|
207
|
+
isTransactionVerified.should.equal(true);
|
|
208
|
+
});
|
|
209
|
+
it('should fail verify transactions when have different recipients', async () => {
|
|
210
|
+
const txPrebuild = newTxPrebuild();
|
|
211
|
+
const txParams = {
|
|
212
|
+
recipients: [
|
|
213
|
+
{
|
|
214
|
+
address: '9f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f0254',
|
|
215
|
+
amount: '1000000000000000000000000',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
address: '9f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f0254',
|
|
219
|
+
amount: '2000000000000000000000000',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
};
|
|
223
|
+
const verification = {};
|
|
224
|
+
await basecoin
|
|
225
|
+
.verifyTransaction({ txParams, txPrebuild, verification })
|
|
226
|
+
.should.be.rejectedWith('cannot find recipient in expected output');
|
|
227
|
+
});
|
|
228
|
+
it('should verify when input `recipients` is absent', async function () {
|
|
229
|
+
const txParams = newTxParams();
|
|
230
|
+
txParams.recipients = undefined;
|
|
231
|
+
const txPrebuild = newTxPrebuild();
|
|
232
|
+
const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild });
|
|
233
|
+
validTransaction.should.equal(true);
|
|
234
|
+
});
|
|
235
|
+
it('should fail verify when txHex is invalid', async function () {
|
|
236
|
+
const txParams = newTxParams();
|
|
237
|
+
txParams.recipients = undefined;
|
|
238
|
+
const txPrebuild = {};
|
|
239
|
+
await basecoin
|
|
240
|
+
.verifyTransaction({ txParams, txPrebuild })
|
|
241
|
+
.should.rejectedWith('missing required tx prebuild property txHex');
|
|
242
|
+
});
|
|
243
|
+
it('should succeed to verify transactions when recipients has extra data', async function () {
|
|
244
|
+
const txPrebuild = newTxPrebuild();
|
|
245
|
+
const txParams = newTxParams();
|
|
246
|
+
txParams.data = 'data';
|
|
247
|
+
const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild });
|
|
248
|
+
validTransaction.should.equal(true);
|
|
249
|
+
});
|
|
250
|
+
it('should verify a valid consolidation transaction', async () => {
|
|
251
|
+
const consolidationTx = {
|
|
252
|
+
txRequestId: '1b5c79c5-ab7c-4f47-912b-de6a95fb0779',
|
|
253
|
+
walletId: '64fa31a94db65a0007c9691b',
|
|
254
|
+
txHex: '84a40081825820db46c7c76ea54fec2ca0a2f94b77a238931a8dce2387c99a12b08dd8aac21c4f000181825839004601fc016ac38580916d3520bc76b659298156008738d347aa93142f4601fc016ac38580916d3520bc76b659298156008738d347aa93142f1a3b984357021a000286a9031a060e37eea0f5f6',
|
|
255
|
+
feeInfo: {
|
|
256
|
+
fee: 165545,
|
|
257
|
+
feeString: '165545',
|
|
258
|
+
},
|
|
259
|
+
txInfo: {
|
|
260
|
+
minerFee: '165545',
|
|
261
|
+
spendAmount: '999834455',
|
|
262
|
+
spendAmounts: [
|
|
263
|
+
{
|
|
264
|
+
coinName: 'tada',
|
|
265
|
+
amountString: '999834455',
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
payGoFee: '0',
|
|
269
|
+
outputs: [
|
|
270
|
+
{
|
|
271
|
+
address: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
|
|
272
|
+
value: 999834455,
|
|
273
|
+
wallet: '64fa31a94db65a0007c9691b',
|
|
274
|
+
wallets: ['64fa31a94db65a0007c9691b'],
|
|
275
|
+
enterprise: '62cc59b727443a0007089033',
|
|
276
|
+
enterprises: ['62cc59b727443a0007089033'],
|
|
277
|
+
valueString: '999834455',
|
|
278
|
+
coinName: 'tada',
|
|
279
|
+
walletType: 'hot',
|
|
280
|
+
walletTypes: ['hot'],
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
inputs: [
|
|
284
|
+
{
|
|
285
|
+
value: 1000000000,
|
|
286
|
+
address: 'addr_test1qqlzxfl7tlgp999x4a7334pchycpkk72pykrsr3mryl3yj6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsvpgl8w',
|
|
287
|
+
valueString: '1000000000',
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
type: '0',
|
|
291
|
+
},
|
|
292
|
+
consolidateId: '68b9fc18558006aab53785615fea7c28',
|
|
293
|
+
coin: 'tada',
|
|
294
|
+
};
|
|
295
|
+
const mockedWallet = {
|
|
296
|
+
coinSpecific: () => {
|
|
297
|
+
return {
|
|
298
|
+
rootAddress: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
|
|
299
|
+
};
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
try {
|
|
303
|
+
const isVerified = await basecoin.verifyTransaction({
|
|
304
|
+
txParams: {},
|
|
305
|
+
txPrebuild: consolidationTx,
|
|
306
|
+
wallet: mockedWallet,
|
|
307
|
+
verification: {
|
|
308
|
+
consolidationToBaseAddress: true,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
isVerified.should.equal(true);
|
|
312
|
+
}
|
|
313
|
+
catch (e) {
|
|
314
|
+
assert_1.default.fail('Transaction should pass verification');
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
it('should fail to sign a spoofed consolidation transaction', async function () {
|
|
318
|
+
// Set up wallet data
|
|
319
|
+
const walletData = {
|
|
320
|
+
id: '5b34252f1bf349930e34020a00000000',
|
|
321
|
+
coin: 'tada',
|
|
322
|
+
keys: [
|
|
323
|
+
'5b3424f91bf349930e34017500000000',
|
|
324
|
+
'5b3424f91bf349930e34017600000000',
|
|
325
|
+
'5b3424f91bf349930e34017700000000',
|
|
326
|
+
],
|
|
327
|
+
coinSpecific: {
|
|
328
|
+
rootAddress: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
|
|
329
|
+
},
|
|
330
|
+
multisigType: 'tss',
|
|
331
|
+
};
|
|
332
|
+
const fakePrv = (0, sdk_api_1.encrypt)('password', 'prv');
|
|
333
|
+
const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
|
|
334
|
+
const bgUrl = sdk_core_1.common.Environments['mock'].uri;
|
|
335
|
+
(0, nock_1.default)(bgUrl)
|
|
336
|
+
.get('/api/v2/tada/key/5b3424f91bf349930e34017500000000')
|
|
337
|
+
.reply(200, [
|
|
338
|
+
{
|
|
339
|
+
encryptedPrv: fakePrv,
|
|
340
|
+
},
|
|
341
|
+
]);
|
|
342
|
+
// Mock the API response for buildAccountConsolidations
|
|
343
|
+
(0, nock_1.default)(bgUrl)
|
|
344
|
+
.post('/api/v2/tada/wallet/5b34252f1bf349930e34020a00000000/consolidateAccount/build')
|
|
345
|
+
.reply(200, [
|
|
346
|
+
{
|
|
347
|
+
txRequestId: '1b5c79c5-ab7c-4f47-912b-de6a95fb0779',
|
|
348
|
+
walletId: '64fa31a94db65a0007c9691b',
|
|
349
|
+
txHex: '84a40081825820db46c7c76ea54fec2ca0a2f94b77a238931a8dce2387c99a12b08dd8aac21c4f01018282581d6033c378cee41b2e15ac848f7f6f1d2f78155ab12d93b713de898d855f1a00989680825839004601fc016ac38580916d3520bc76b659298156008738d347aa93142f4601fc016ac38580916d3520bc76b659298156008738d347aa93142f1b0000000217acebe9021a00028db5031a060e3b41a0f5f6',
|
|
350
|
+
feeInfo: {
|
|
351
|
+
fee: 165545,
|
|
352
|
+
feeString: '165545',
|
|
353
|
+
},
|
|
354
|
+
txInfo: {
|
|
355
|
+
minerFee: '165545',
|
|
356
|
+
spendAmount: '999834455',
|
|
357
|
+
spendAmounts: [
|
|
358
|
+
{
|
|
359
|
+
coinName: 'tada',
|
|
360
|
+
amountString: '999834455',
|
|
361
|
+
},
|
|
362
|
+
],
|
|
363
|
+
payGoFee: '0',
|
|
364
|
+
outputs: [
|
|
365
|
+
{
|
|
366
|
+
address: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
|
|
367
|
+
value: 999834455,
|
|
368
|
+
wallet: '64fa31a94db65a0007c9691b',
|
|
369
|
+
wallets: ['64fa31a94db65a0007c9691b'],
|
|
370
|
+
enterprise: '62cc59b727443a0007089033',
|
|
371
|
+
enterprises: ['62cc59b727443a0007089033'],
|
|
372
|
+
valueString: '999834455',
|
|
373
|
+
coinName: 'tada',
|
|
374
|
+
walletType: 'hot',
|
|
375
|
+
walletTypes: ['hot'],
|
|
376
|
+
},
|
|
377
|
+
],
|
|
378
|
+
inputs: [
|
|
379
|
+
{
|
|
380
|
+
value: 1000000000,
|
|
381
|
+
address: 'addr_test1qqlzxfl7tlgp999x4a7334pchycpkk72pykrsr3mryl3yj6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsvpgl8w',
|
|
382
|
+
valueString: '1000000000',
|
|
383
|
+
},
|
|
384
|
+
],
|
|
385
|
+
type: '0',
|
|
386
|
+
},
|
|
387
|
+
consolidateId: '68b9fc18558006aab53785615fea7c28',
|
|
388
|
+
coin: 'tada',
|
|
389
|
+
},
|
|
390
|
+
]);
|
|
391
|
+
// Call the function to test
|
|
392
|
+
await assert_1.default.rejects(async () => {
|
|
393
|
+
await walletObj.sendAccountConsolidations({
|
|
394
|
+
walletPassphrase: 'password',
|
|
395
|
+
});
|
|
396
|
+
}, {
|
|
397
|
+
message: 'tx outputs does not match with expected address',
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
describe('Explain Transactions:', () => {
|
|
402
|
+
it('should explain an unsigned transfer transaction', async function () {
|
|
403
|
+
const explainedTransaction = await basecoin.explainTransaction({
|
|
404
|
+
txPrebuild: {
|
|
405
|
+
txHex: resources_1.rawTx.unsignedTx2,
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
console.log(explainedTransaction);
|
|
409
|
+
explainedTransaction.should.deepEqual(transactionExplanation);
|
|
410
|
+
});
|
|
411
|
+
it('should fail to explain transaction with missing params', async function () {
|
|
412
|
+
try {
|
|
413
|
+
await basecoin.explainTransaction({
|
|
414
|
+
txPrebuild: {},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
catch (error) {
|
|
418
|
+
should.equal(error.message, 'Invalid transaction');
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
it('should fail to explain transaction with wrong params', async function () {
|
|
422
|
+
try {
|
|
423
|
+
await basecoin.explainTransaction({
|
|
424
|
+
txPrebuild: {
|
|
425
|
+
txHex: 'invalidTxHex',
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
should.equal(error.message, 'Invalid transaction');
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
describe('Parse Raw Transactions', () => {
|
|
435
|
+
it('should parse staking pledge transaction', function () {
|
|
436
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
437
|
+
tx.fromRawTransaction(resources_1.rawTx.unsignedNewPledgeTx);
|
|
438
|
+
should.equal(tx.type, enum_1.TransactionType.StakingPledge);
|
|
439
|
+
});
|
|
440
|
+
it('should parse staking activation tx', function () {
|
|
441
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
442
|
+
tx.fromRawTransaction(resources_1.rawTx.unsignedStakingActiveTx);
|
|
443
|
+
should.equal(tx.type, enum_1.TransactionType.StakingActivate);
|
|
444
|
+
});
|
|
445
|
+
it('should parse staking deactivation tx', function () {
|
|
446
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
447
|
+
tx.fromRawTransaction(resources_1.rawTx.unsignedStakingDeactiveTx);
|
|
448
|
+
should.equal(tx.type, enum_1.TransactionType.StakingDeactivate);
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
describe('Parse Transactions:', () => {
|
|
452
|
+
it('should parse an unsigned transfer transaction', async function () {
|
|
453
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
454
|
+
txPrebuild: {
|
|
455
|
+
txHex: resources_1.rawTx.unsignedTx2,
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
parsedTransaction.should.deepEqual(transactionExplanation);
|
|
459
|
+
});
|
|
460
|
+
it('should parse a signed transfer transaction', async function () {
|
|
461
|
+
const parsedTransaction = await basecoin.parseTransaction({
|
|
462
|
+
txPrebuild: {
|
|
463
|
+
txHex: resources_1.rawTx.signedTx2,
|
|
464
|
+
},
|
|
465
|
+
});
|
|
466
|
+
parsedTransaction.should.deepEqual(transactionExplanation);
|
|
467
|
+
});
|
|
468
|
+
it('should fail parse a signed transfer transaction when explainTransaction response is undefined', async function () {
|
|
469
|
+
const stub = sinon.stub(src_1.Ada.prototype, 'explainTransaction');
|
|
470
|
+
stub.resolves(undefined);
|
|
471
|
+
await basecoin
|
|
472
|
+
.parseTransaction({
|
|
473
|
+
txPrebuild: {
|
|
474
|
+
txHex: resources_1.rawTx.signedTx,
|
|
475
|
+
},
|
|
476
|
+
})
|
|
477
|
+
.should.be.rejectedWith('Invalid transaction');
|
|
478
|
+
stub.restore();
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
describe('Recover Transactions:', () => {
|
|
482
|
+
const destAddr = resources_1.address.address2;
|
|
483
|
+
const sandBox = sinon.createSandbox();
|
|
484
|
+
beforeEach(function () {
|
|
485
|
+
const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
|
|
486
|
+
callBack
|
|
487
|
+
.withArgs('address_info', {
|
|
488
|
+
_addresses: [resources_1.wrwUser.walletAddress0],
|
|
489
|
+
})
|
|
490
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO);
|
|
491
|
+
callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
|
|
492
|
+
});
|
|
493
|
+
afterEach(function () {
|
|
494
|
+
sandBox.restore();
|
|
495
|
+
});
|
|
496
|
+
it('should take OVC output and generate a signed sweep transaction', async function () {
|
|
497
|
+
const params = resources_1.ovcResponse;
|
|
498
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
499
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('84a400818258204bd0f991c1532cffe31d4a10db492b43175ec326765b6b29ceee598df2b61f470001818258390087379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c87379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c1a05f359ff021a00028701031a024972e1a10081825820bbacb13431b99208e6e8cdbf710147feaf06a39d71565e60b411ce9e4fa3f137584001a4ab8236563f69ff309e5786e8f39c629ed57676c692159cb2e0494c9e663355384c13c749d04c17a80ba2a45cc127df480fc64a43199a772f11acd5b14a0ff5f6');
|
|
500
|
+
recoveryTxn.transactions[0].scanIndex.should.equal(0);
|
|
501
|
+
recoveryTxn.lastScanIndex.should.equal(0);
|
|
502
|
+
});
|
|
503
|
+
it('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
|
|
504
|
+
const params = resources_1.ovcResponse2;
|
|
505
|
+
const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
|
|
506
|
+
recoveryTxn.transactions[0].serializedTx.should.equal('84a400818258203e62e5ee8b12012c4b949f9777b72165239bb2146ae8b078b4d1c5ca8d3168e300018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa10081825820500e0d725a5ba3a306da3503dfe57b8a14068a09b61b36ec068fcf8cf5c391de5840c836ce6d3262d5654706ea06721522d3b75f6d545245047a7be7463629d88b3f4264b995f591df52bdffcf09da1e6ab9e88de3714c6e2ec1961786cf1c586a07f5f6');
|
|
507
|
+
recoveryTxn.transactions[0].scanIndex.should.equal(1);
|
|
508
|
+
recoveryTxn.transactions[1].serializedTx.should.equal('84a4008182582029c10acf0e08f9523325c88243565af6b32274992189c1153903c410bed7c2c700018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa1008182582062770b224bd314bc526fbd6a94e9082fb6458c425e6e09bad74004dd897e962358403842544f2ff28be054eb7c7997bc303b1e251eb13a41802c82318e592bb24eaa3197c450e797cc8559f0356cd5cdd1ab5eb80c5173e34e9e1d1737533a89520cf5f6');
|
|
509
|
+
recoveryTxn.transactions[1].scanIndex.should.equal(2);
|
|
510
|
+
recoveryTxn.transactions[2].serializedTx.should.equal('84a40081825820dd140f133d865e1bb5642e708fe685bf7601d71d0c99511e5d552da7f8bd10ff00018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa1008182582053b4bb74aa38add458dafc8153f0aa8266acad59322b877ca9c23c5d3873779d5840e94ce7896957d094c6bafbf2ec10df5ebb0f1d2a27a7e31f2d45c531fb687edd6c4d33f8e9b99c7692b6fac6d8399bd8fd47641baae9bbb69f518d42ad11710af5f6');
|
|
511
|
+
recoveryTxn.transactions[2].scanIndex.should.equal(3);
|
|
512
|
+
recoveryTxn.transactions[3].serializedTx.should.equal('84a4008182582015a1d6db5d3f592aa1cda185b6359ca0e2921c3c51959f64222a6b7d95d3392300018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa10081825820600f86ca22d670f0a990ade4e882c05e654343263494735a31517de0819676735840fe199f8e247a4cfabfeb4f9cb574aa35739a0aa98860ee0a85d720c4ab4fecfac7b4504df310b3e4bea04711f60652d4a8cf5eb41817293b8d29977fe695f704f5f6');
|
|
513
|
+
recoveryTxn.transactions[3].scanIndex.should.equal(4);
|
|
514
|
+
recoveryTxn.lastScanIndex.should.equal(20);
|
|
515
|
+
});
|
|
516
|
+
it('should recover a txn for non-bitgo recoveries', async function () {
|
|
517
|
+
const res = await basecoin.recover({
|
|
518
|
+
userKey: resources_1.wrwUser.userKey,
|
|
519
|
+
backupKey: resources_1.wrwUser.backupKey,
|
|
520
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
521
|
+
walletPassphrase: resources_1.wrwUser.walletPassphrase,
|
|
522
|
+
recoveryDestination: destAddr,
|
|
523
|
+
});
|
|
524
|
+
res.should.not.be.empty();
|
|
525
|
+
res.should.hasOwnProperty('serializedTx');
|
|
526
|
+
sandBox.assert.calledTwice(basecoin.getDataFromNode);
|
|
527
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
528
|
+
tx.fromRawTransaction(res.serializedTx);
|
|
529
|
+
const txJson = tx.toJson();
|
|
530
|
+
const fee = Number(tx.explainTransaction().fee.fee);
|
|
531
|
+
should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
|
|
532
|
+
should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
|
|
533
|
+
should.deepEqual(txJson.outputs[0].address, destAddr);
|
|
534
|
+
should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value);
|
|
535
|
+
});
|
|
536
|
+
it('should recover a txn for unsigned sweep recoveries', async function () {
|
|
537
|
+
const res = await basecoin.recover({
|
|
538
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
539
|
+
recoveryDestination: destAddr,
|
|
540
|
+
});
|
|
541
|
+
res.should.not.be.empty();
|
|
542
|
+
res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
|
|
543
|
+
sandBox.assert.calledTwice(basecoin.getDataFromNode);
|
|
544
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
545
|
+
tx.fromRawTransaction(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
|
|
546
|
+
const txJson = tx.toJson();
|
|
547
|
+
const fee = Number(tx.explainTransaction().fee.fee);
|
|
548
|
+
should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
|
|
549
|
+
should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
|
|
550
|
+
should.deepEqual(txJson.outputs[0].address, destAddr);
|
|
551
|
+
should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value);
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
describe('Recover Transactions Multiple UTXO:', () => {
|
|
555
|
+
const destAddr = resources_1.address.address2;
|
|
556
|
+
const sandBox = sinon.createSandbox();
|
|
557
|
+
beforeEach(function () {
|
|
558
|
+
const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
|
|
559
|
+
callBack
|
|
560
|
+
.withArgs('address_info', {
|
|
561
|
+
_addresses: [resources_1.wrwUser.walletAddress0],
|
|
562
|
+
})
|
|
563
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.TwoUTXO);
|
|
564
|
+
callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
|
|
565
|
+
});
|
|
566
|
+
afterEach(function () {
|
|
567
|
+
sandBox.restore();
|
|
568
|
+
});
|
|
569
|
+
it('should recover a txn for non-bitgo recoveries', async function () {
|
|
570
|
+
const res = await basecoin.recover({
|
|
571
|
+
userKey: resources_1.wrwUser.userKey,
|
|
572
|
+
backupKey: resources_1.wrwUser.backupKey,
|
|
573
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
574
|
+
walletPassphrase: resources_1.wrwUser.walletPassphrase,
|
|
575
|
+
recoveryDestination: destAddr,
|
|
576
|
+
});
|
|
577
|
+
res.should.not.be.empty();
|
|
578
|
+
res.should.hasOwnProperty('serializedTx');
|
|
579
|
+
sandBox.assert.calledTwice(basecoin.getDataFromNode);
|
|
580
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
581
|
+
tx.fromRawTransaction(res.serializedTx);
|
|
582
|
+
const txJson = tx.toJson();
|
|
583
|
+
const fee = Number(tx.explainTransaction().fee.fee);
|
|
584
|
+
should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
|
|
585
|
+
should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
|
|
586
|
+
should.deepEqual(txJson.inputs[1].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
|
|
587
|
+
should.deepEqual(txJson.inputs[1].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
|
|
588
|
+
should.deepEqual(txJson.outputs[0].address, destAddr);
|
|
589
|
+
should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value + resources_1.testnetUTXO.UTXO_2.value);
|
|
590
|
+
});
|
|
591
|
+
it('should recover a txn for unsigned sweep recoveries', async function () {
|
|
592
|
+
const res = await basecoin.recover({
|
|
593
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
594
|
+
recoveryDestination: destAddr,
|
|
595
|
+
});
|
|
596
|
+
res.should.not.be.empty();
|
|
597
|
+
res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
|
|
598
|
+
sandBox.assert.calledTwice(basecoin.getDataFromNode);
|
|
599
|
+
const tx = new lib_1.Transaction(basecoin);
|
|
600
|
+
tx.fromRawTransaction(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
|
|
601
|
+
const txJson = tx.toJson();
|
|
602
|
+
const fee = Number(tx.explainTransaction().fee.fee);
|
|
603
|
+
should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
|
|
604
|
+
should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
|
|
605
|
+
should.deepEqual(txJson.inputs[1].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
|
|
606
|
+
should.deepEqual(txJson.inputs[1].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
|
|
607
|
+
should.deepEqual(txJson.outputs[0].address, destAddr);
|
|
608
|
+
should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value + resources_1.testnetUTXO.UTXO_2.value);
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
describe('Build Consolidation Recoveries:', () => {
|
|
612
|
+
const baseAddr = resources_1.consolidationWrwUser.walletAddress0;
|
|
613
|
+
const sandBox = sinon.createSandbox();
|
|
614
|
+
beforeEach(function () {
|
|
615
|
+
const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
|
|
616
|
+
callBack
|
|
617
|
+
.withArgs('address_info', {
|
|
618
|
+
_addresses: [resources_1.consolidationWrwUser.walletAddress1],
|
|
619
|
+
})
|
|
620
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.ZeroUTXO);
|
|
621
|
+
callBack
|
|
622
|
+
.withArgs('address_info', {
|
|
623
|
+
_addresses: [resources_1.consolidationWrwUser.walletAddress2],
|
|
624
|
+
})
|
|
625
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO);
|
|
626
|
+
callBack
|
|
627
|
+
.withArgs('address_info', {
|
|
628
|
+
_addresses: [resources_1.consolidationWrwUser.walletAddress3],
|
|
629
|
+
})
|
|
630
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO2);
|
|
631
|
+
callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
|
|
632
|
+
});
|
|
633
|
+
afterEach(function () {
|
|
634
|
+
sandBox.restore();
|
|
635
|
+
});
|
|
636
|
+
it('should build signed consolidation recoveries', async function () {
|
|
637
|
+
const res = await basecoin.recoverConsolidations({
|
|
638
|
+
userKey: resources_1.consolidationWrwUser.userKey,
|
|
639
|
+
backupKey: resources_1.consolidationWrwUser.backupKey,
|
|
640
|
+
bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
|
|
641
|
+
walletPassphrase: resources_1.consolidationWrwUser.walletPassphrase,
|
|
642
|
+
startingScanIndex: 1,
|
|
643
|
+
endingScanIndex: 4,
|
|
644
|
+
});
|
|
645
|
+
res.should.not.be.empty();
|
|
646
|
+
res.transactions.length.should.equal(2);
|
|
647
|
+
res.lastScanIndex.should.equal(3);
|
|
648
|
+
const txn1 = res.transactions[0];
|
|
649
|
+
const tx1 = new lib_1.Transaction(basecoin);
|
|
650
|
+
tx1.fromRawTransaction(txn1.serializedTx);
|
|
651
|
+
const txJson1 = tx1.toJson();
|
|
652
|
+
const fee1 = Number(tx1.explainTransaction().fee.fee);
|
|
653
|
+
should.deepEqual(txJson1.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
|
|
654
|
+
should.deepEqual(txJson1.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
|
|
655
|
+
should.deepEqual(txJson1.outputs[0].address, baseAddr);
|
|
656
|
+
should.deepEqual(Number(txJson1.outputs[0].amount) + fee1, resources_1.testnetUTXO.UTXO_1.value);
|
|
657
|
+
const txn2 = res.transactions[1];
|
|
658
|
+
const tx2 = new lib_1.Transaction(basecoin);
|
|
659
|
+
tx2.fromRawTransaction(txn2.serializedTx);
|
|
660
|
+
const txJson2 = tx2.toJson();
|
|
661
|
+
const fee2 = Number(tx2.explainTransaction().fee.fee);
|
|
662
|
+
should.deepEqual(txJson2.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
|
|
663
|
+
should.deepEqual(txJson2.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
|
|
664
|
+
should.deepEqual(txJson2.outputs[0].address, baseAddr);
|
|
665
|
+
should.deepEqual(Number(txJson2.outputs[0].amount) + fee2, resources_1.testnetUTXO.UTXO_2.value);
|
|
666
|
+
});
|
|
667
|
+
it('should skip building consolidate transaction if balance is equal to zero', async function () {
|
|
668
|
+
await basecoin
|
|
669
|
+
.recoverConsolidations({
|
|
670
|
+
userKey: resources_1.consolidationWrwUser.userKey,
|
|
671
|
+
backupKey: resources_1.consolidationWrwUser.backupKey,
|
|
672
|
+
bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
|
|
673
|
+
walletPassphrase: resources_1.consolidationWrwUser.walletPassphrase,
|
|
674
|
+
startingScanIndex: 1,
|
|
675
|
+
endingScanIndex: 2,
|
|
676
|
+
})
|
|
677
|
+
.should.rejectedWith('Did not find an address with funds to recover');
|
|
678
|
+
});
|
|
679
|
+
it('should throw if startingScanIndex is not ge to 1', async () => {
|
|
680
|
+
await basecoin
|
|
681
|
+
.recoverConsolidations({
|
|
682
|
+
userKey: resources_1.consolidationWrwUser.userKey,
|
|
683
|
+
backupKey: resources_1.consolidationWrwUser.backupKey,
|
|
684
|
+
bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
|
|
685
|
+
startingScanIndex: -1,
|
|
686
|
+
})
|
|
687
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
|
|
688
|
+
});
|
|
689
|
+
it('should throw if scan factor is too high', async () => {
|
|
690
|
+
await basecoin
|
|
691
|
+
.recoverConsolidations({
|
|
692
|
+
userKey: resources_1.consolidationWrwUser.userKey,
|
|
693
|
+
backupKey: resources_1.consolidationWrwUser.backupKey,
|
|
694
|
+
bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
|
|
695
|
+
startingScanIndex: 1,
|
|
696
|
+
endingScanIndex: 300,
|
|
697
|
+
})
|
|
698
|
+
.should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
describe('Recover Transactions Failure:', () => {
|
|
702
|
+
const destAddr = resources_1.address.address2;
|
|
703
|
+
const sandBox = sinon.createSandbox();
|
|
704
|
+
afterEach(function () {
|
|
705
|
+
sandBox.restore();
|
|
706
|
+
});
|
|
707
|
+
it('should fail to recover due to not finding an address with funds', async function () {
|
|
708
|
+
const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
|
|
709
|
+
callBack
|
|
710
|
+
.withArgs('address_info', sinon.match.has('_addresses'))
|
|
711
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.ZeroUTXO);
|
|
712
|
+
callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
|
|
713
|
+
await basecoin
|
|
714
|
+
.recover({
|
|
715
|
+
userKey: resources_1.wrwUser.userKey,
|
|
716
|
+
backupKey: resources_1.wrwUser.backupKey,
|
|
717
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
718
|
+
walletPassphrase: resources_1.wrwUser.walletPassphrase,
|
|
719
|
+
recoveryDestination: destAddr,
|
|
720
|
+
})
|
|
721
|
+
.should.rejectedWith('Did not find address with funds to recover');
|
|
722
|
+
sandBox.assert.calledOnce(basecoin.getDataFromNode);
|
|
723
|
+
});
|
|
724
|
+
it('should fail to recover due to not having more than 1 ADA in funds', async function () {
|
|
725
|
+
const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
|
|
726
|
+
callBack
|
|
727
|
+
.withArgs('address_info', sinon.match.has('_addresses'))
|
|
728
|
+
.resolves(resources_1.endpointResponses.addressInfoResponse.OneSmallUTXO);
|
|
729
|
+
callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
|
|
730
|
+
await basecoin
|
|
731
|
+
.recover({
|
|
732
|
+
userKey: resources_1.wrwUser.userKey,
|
|
733
|
+
backupKey: resources_1.wrwUser.backupKey,
|
|
734
|
+
bitgoKey: resources_1.wrwUser.bitgoKey,
|
|
735
|
+
walletPassphrase: resources_1.wrwUser.walletPassphrase,
|
|
736
|
+
recoveryDestination: destAddr,
|
|
737
|
+
})
|
|
738
|
+
.should.rejectedWith('Insufficient funds to recover, minimum required is 1 ADA plus fees, got 9834455 fees: 165545');
|
|
739
|
+
sandBox.assert.calledTwice(basecoin.getDataFromNode);
|
|
740
|
+
});
|
|
741
|
+
});
|
|
742
|
+
describe('Verify wallet address (isWalletAddress):', () => {
|
|
743
|
+
const commonKeychain = 'ed312d0db4615688219c43231eb4b98d5883c0b44bcfef1956290555995ad68ef7c22917b4a8b69183864b83cc7028655cd7a70ef76d6948d809a15050054840';
|
|
744
|
+
it('should verify a valid wallet address at index 0', async function () {
|
|
745
|
+
const keychains = [
|
|
746
|
+
{
|
|
747
|
+
id: '1',
|
|
748
|
+
commonKeychain: commonKeychain,
|
|
749
|
+
type: 'tss',
|
|
750
|
+
source: 'user',
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
id: '2',
|
|
754
|
+
commonKeychain: commonKeychain,
|
|
755
|
+
type: 'tss',
|
|
756
|
+
source: 'backup',
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: '3',
|
|
760
|
+
commonKeychain: commonKeychain,
|
|
761
|
+
type: 'tss',
|
|
762
|
+
source: 'bitgo',
|
|
763
|
+
},
|
|
764
|
+
];
|
|
765
|
+
const address = 'addr_test1qzvmazmpgfhjyppwlsw29zjjwazcsfk62z9zv5vsv24p0wyeh69kzsn0ygzzalqu5299ya693qnd55y2yegeqc42z7uq0ge2pq';
|
|
766
|
+
const isValid = await basecoin.isWalletAddress({
|
|
767
|
+
address,
|
|
768
|
+
keychains,
|
|
769
|
+
index: 0,
|
|
770
|
+
});
|
|
771
|
+
isValid.should.equal(true);
|
|
772
|
+
});
|
|
773
|
+
it('should fail to verify an address with wrong index', async function () {
|
|
774
|
+
const keychains = [
|
|
775
|
+
{
|
|
776
|
+
id: '1',
|
|
777
|
+
commonKeychain: commonKeychain,
|
|
778
|
+
type: 'tss',
|
|
779
|
+
source: 'user',
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
id: '2',
|
|
783
|
+
commonKeychain: commonKeychain,
|
|
784
|
+
type: 'tss',
|
|
785
|
+
source: 'backup',
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
id: '3',
|
|
789
|
+
commonKeychain: commonKeychain,
|
|
790
|
+
type: 'tss',
|
|
791
|
+
source: 'bitgo',
|
|
792
|
+
},
|
|
793
|
+
];
|
|
794
|
+
const isValid = await basecoin.isWalletAddress({
|
|
795
|
+
address: 'addr_test1qzvmazmpgfhjyppwlsw29zjjwazcsfk62z9zv5vsv24p0wyeh69kzsn0ygzzalqu5299ya693qnd55y2yegeqc42z7uq0ge2pq',
|
|
796
|
+
keychains,
|
|
797
|
+
index: 2,
|
|
798
|
+
});
|
|
799
|
+
isValid.should.equal(false);
|
|
800
|
+
});
|
|
801
|
+
it('should fail to verify a random address not from wallet', async function () {
|
|
802
|
+
const keychains = [
|
|
803
|
+
{
|
|
804
|
+
id: '1',
|
|
805
|
+
commonKeychain: commonKeychain,
|
|
806
|
+
type: 'tss',
|
|
807
|
+
source: 'user',
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
id: '2',
|
|
811
|
+
commonKeychain: commonKeychain,
|
|
812
|
+
type: 'tss',
|
|
813
|
+
source: 'backup',
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
id: '3',
|
|
817
|
+
commonKeychain: commonKeychain,
|
|
818
|
+
type: 'tss',
|
|
819
|
+
source: 'bitgo',
|
|
820
|
+
},
|
|
821
|
+
];
|
|
822
|
+
// Use a random valid ADA address not from this wallet
|
|
823
|
+
const randomAddress = 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f';
|
|
824
|
+
const isValid = await basecoin.isWalletAddress({
|
|
825
|
+
address: randomAddress,
|
|
826
|
+
keychains,
|
|
827
|
+
index: 0,
|
|
828
|
+
});
|
|
829
|
+
isValid.should.equal(false);
|
|
830
|
+
});
|
|
831
|
+
it('should throw error for invalid address format', async function () {
|
|
832
|
+
const keychains = [
|
|
833
|
+
{
|
|
834
|
+
id: '1',
|
|
835
|
+
commonKeychain: commonKeychain,
|
|
836
|
+
type: 'tss',
|
|
837
|
+
source: 'user',
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
id: '2',
|
|
841
|
+
commonKeychain: commonKeychain,
|
|
842
|
+
type: 'tss',
|
|
843
|
+
source: 'backup',
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
id: '3',
|
|
847
|
+
commonKeychain: commonKeychain,
|
|
848
|
+
type: 'tss',
|
|
849
|
+
source: 'bitgo',
|
|
850
|
+
},
|
|
851
|
+
];
|
|
852
|
+
const invalidAddress = 'not_a_valid_address';
|
|
853
|
+
await basecoin
|
|
854
|
+
.isWalletAddress({
|
|
855
|
+
address: invalidAddress,
|
|
856
|
+
keychains,
|
|
857
|
+
index: 0,
|
|
858
|
+
})
|
|
859
|
+
.should.be.rejectedWith('Invalid Cardano Address: not_a_valid_address');
|
|
860
|
+
});
|
|
861
|
+
it('should throw error when keychains are missing', async function () {
|
|
862
|
+
const address = 'addr_test1qzvmazmpgfhjyppwlsw29zjjwazcsfk62z9zv5vsv24p0wyeh69kzsn0ygzzalqu5299ya693qnd55y2yegeqc42z7uq0ge2pq';
|
|
863
|
+
await basecoin
|
|
864
|
+
.isWalletAddress({
|
|
865
|
+
address,
|
|
866
|
+
keychains: [],
|
|
867
|
+
index: 0,
|
|
868
|
+
})
|
|
869
|
+
.should.be.rejectedWith('missing required param keychains');
|
|
870
|
+
});
|
|
871
|
+
it('should throw error when commonKeychain is missing', async function () {
|
|
872
|
+
const keychains = [
|
|
873
|
+
{
|
|
874
|
+
id: '1',
|
|
875
|
+
type: 'tss',
|
|
876
|
+
source: 'user',
|
|
877
|
+
// commonKeychain is missing
|
|
878
|
+
},
|
|
879
|
+
];
|
|
880
|
+
const address = 'addr_test1qzvmazmpgfhjyppwlsw29zjjwazcsfk62z9zv5vsv24p0wyeh69kzsn0ygzzalqu5299ya693qnd55y2yegeqc42z7uq0ge2pq';
|
|
881
|
+
await basecoin
|
|
882
|
+
.isWalletAddress({
|
|
883
|
+
address,
|
|
884
|
+
keychains,
|
|
885
|
+
index: 0,
|
|
886
|
+
})
|
|
887
|
+
.should.be.rejectedWith('missing required param commonKeychain');
|
|
888
|
+
});
|
|
889
|
+
it('should throw error when keychains have mismatched commonKeychains', async function () {
|
|
890
|
+
const keychains = [
|
|
891
|
+
{
|
|
892
|
+
id: '1',
|
|
893
|
+
commonKeychain: commonKeychain,
|
|
894
|
+
type: 'tss',
|
|
895
|
+
source: 'user',
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
id: '2',
|
|
899
|
+
commonKeychain: 'differentKeychain1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
|
|
900
|
+
type: 'tss',
|
|
901
|
+
source: 'backup',
|
|
902
|
+
},
|
|
903
|
+
];
|
|
904
|
+
const address = 'addr_test1qzvmazmpgfhjyppwlsw29zjjwazcsfk62z9zv5vsv24p0wyeh69kzsn0ygzzalqu5299ya693qnd55y2yegeqc42z7uq0ge2pq';
|
|
905
|
+
await basecoin
|
|
906
|
+
.isWalletAddress({
|
|
907
|
+
address,
|
|
908
|
+
keychains,
|
|
909
|
+
index: 0,
|
|
910
|
+
})
|
|
911
|
+
.should.be.rejectedWith('all keychains must have the same commonKeychain for MPC coins');
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
describe('Verify token consolidation transaction:', () => {
|
|
915
|
+
it('should fail to verify a spoofed token consolidation transaction with incorrect address', async () => {
|
|
916
|
+
const consolidationTx = {
|
|
917
|
+
txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
|
|
918
|
+
walletId: '63068ed4efa63a000877f02fd4b0fa6d',
|
|
919
|
+
txHex: '84a400818258204bd0f991c1532cffe31d4a10db492b43175ec326765b6b29ceee598df2b61f470001818258390087379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c87379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c1a05f359ff021a00028701031a024972e1a10081825820bbacb13431b99208e6e8cdbf710147feaf06a39d71565e60b411ce9e4fa3f137584001a4ab8236563f69ff309e5786e8f39c629ed57676c692159cb2e0494c9e663355384c13c749d04c17a80ba2a45cc127df480fc64a43199a772f11acd5b14a0ff5f6',
|
|
920
|
+
feeInfo: {
|
|
921
|
+
fee: 10000,
|
|
922
|
+
feeString: '10000',
|
|
923
|
+
},
|
|
924
|
+
txInfo: {
|
|
925
|
+
inputs: [
|
|
926
|
+
{
|
|
927
|
+
address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
|
|
928
|
+
value: 2.0173228e10,
|
|
929
|
+
valueString: '20173228000',
|
|
930
|
+
},
|
|
931
|
+
{
|
|
932
|
+
address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
|
|
933
|
+
value: 10000,
|
|
934
|
+
valueString: '10000',
|
|
935
|
+
},
|
|
936
|
+
],
|
|
937
|
+
minerFee: '10000',
|
|
938
|
+
outputs: [
|
|
939
|
+
{
|
|
940
|
+
address: 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f',
|
|
941
|
+
coinName: 'tada:usdt',
|
|
942
|
+
enterprise: {
|
|
943
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
944
|
+
},
|
|
945
|
+
enterprises: [
|
|
946
|
+
{
|
|
947
|
+
$oid: '5553ba8ae7a5c77006719661',
|
|
948
|
+
},
|
|
949
|
+
],
|
|
950
|
+
value: 2.0173228e10,
|
|
951
|
+
valueString: '20173228000',
|
|
952
|
+
wallet: {
|
|
953
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
954
|
+
},
|
|
955
|
+
walletType: 'hot',
|
|
956
|
+
wallets: [
|
|
957
|
+
{
|
|
958
|
+
$oid: '62f4c3720d92c50008257eb5',
|
|
959
|
+
},
|
|
960
|
+
],
|
|
961
|
+
},
|
|
962
|
+
],
|
|
963
|
+
payGoFee: '0',
|
|
964
|
+
spendAmount: '20173228000',
|
|
965
|
+
spendAmounts: [
|
|
966
|
+
{
|
|
967
|
+
amountString: '20173228000',
|
|
968
|
+
coinName: 'tada:usdt',
|
|
969
|
+
},
|
|
970
|
+
],
|
|
971
|
+
type: 'Send',
|
|
972
|
+
},
|
|
973
|
+
consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
|
|
974
|
+
coin: 'tada',
|
|
975
|
+
};
|
|
976
|
+
// Mock the wallet with a different address than the transaction's output
|
|
977
|
+
const mockedWallet = {
|
|
978
|
+
coinSpecific: () => {
|
|
979
|
+
return {
|
|
980
|
+
rootAddress: 'addr_test1qqnnvptrc3rec64q2n9jh572ncu5wvdtt8uvg4g3aj96s5dwu9nj70mlahzglm9939uevupsmj8dcdqv25d5n5r8vw8sn7prey',
|
|
981
|
+
};
|
|
982
|
+
},
|
|
983
|
+
};
|
|
984
|
+
await basecoin
|
|
985
|
+
.verifyTransaction({
|
|
986
|
+
txParams: {},
|
|
987
|
+
txPrebuild: consolidationTx,
|
|
988
|
+
wallet: mockedWallet,
|
|
989
|
+
verification: {
|
|
990
|
+
consolidationToBaseAddress: true,
|
|
991
|
+
},
|
|
992
|
+
})
|
|
993
|
+
.should.be.rejectedWith('tx outputs does not match with expected address');
|
|
994
|
+
});
|
|
995
|
+
});
|
|
996
|
+
});
|
|
997
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2FkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0dBRUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsaUNBQWtDO0FBQ2xDLG1DQUFxQztBQUNyQyw2Q0FBK0I7QUFDL0IsbURBQStEO0FBQy9ELGlEQUF3RDtBQUN4RCw0Q0FZc0I7QUFDdEIsMENBQTRCO0FBQzVCLG1DQUErQztBQUMvQyx1Q0FBNEM7QUFDNUMsMEVBQWtGO0FBQ2xGLG9EQUE0QjtBQUM1QixtREFBc0Q7QUFDdEQsZ0RBQXdCO0FBRXhCLFFBQVEsQ0FBQyxLQUFLLEVBQUU7SUFDZCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDdkIsTUFBTSxTQUFTLEdBQUcsR0FBRyxHQUFHLFFBQVEsQ0FBQztJQUNqQyxJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLGFBQWEsQ0FBQztJQUNsQixJQUFJLFdBQVcsQ0FBQztJQUVoQixNQUFNLFVBQVUsR0FBRztRQUNqQixLQUFLLEVBQUUsaUJBQUssQ0FBQyxVQUFVO1FBQ3ZCLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQztJQUVGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFO1lBQ1Y7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFLLENBQUMsY0FBYyxDQUFDLE9BQU87Z0JBQ3JDLE1BQU0sRUFBRSxTQUFTO2FBQ2xCO1lBQ0Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFLLENBQUMsY0FBYyxDQUFDLE9BQU87Z0JBQ3JDLE1BQU0sRUFBRSxXQUFXO2FBQ3BCO1NBQ0Y7S0FDRixDQUFDO0lBRUYsTUFBTSxzQkFBc0IsR0FBRztRQUM3QixZQUFZLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUM7UUFDL0YsRUFBRSxFQUFFLGtFQUFrRTtRQUN0RSxPQUFPLEVBQUU7WUFDUDtnQkFDRSxPQUFPLEVBQ0wsOEdBQThHO2dCQUNoSCxNQUFNLEVBQUUsU0FBUzthQUNsQjtZQUNEO2dCQUNFLE9BQU8sRUFBRSxpRUFBaUU7Z0JBQzFFLE1BQU0sRUFBRSxVQUFVO2FBQ25CO1NBQ0Y7UUFDRCxZQUFZLEVBQUUsVUFBVTtRQUN4QixhQUFhLEVBQUUsRUFBRTtRQUNqQixZQUFZLEVBQUUsR0FBRztRQUNqQixHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFO1FBQ3RCLElBQUksRUFBRSxVQUFVO1FBQ2hCLFlBQVksRUFBRSxFQUFFO1FBQ2hCLFdBQVcsRUFBRSxFQUFFO1FBQ2YsYUFBYSxFQUFFLFNBQVM7S0FDekIsQ0FBQztJQUVGLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsU0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNuRCxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqQyxhQUFhLEdBQUcsR0FBRyxFQUFFO1lBQ25CLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUM7UUFDRixXQUFXLEdBQUcsR0FBRyxFQUFFO1lBQ2pCLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUNoQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsVUFBSSxDQUFDLENBQUM7UUFDNUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDakQsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFeEQsYUFBYSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDckMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFHLENBQUMsQ0FBQztRQUMzQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLGFBQU8sRUFBRSxDQUFDO1lBQzlCLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBQSxvQkFBVyxFQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25FLE1BQU0sU0FBUyxHQUFHLE1BQU0sUUFBUSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFDL0UsT0FBTyxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0NBQXNDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDcEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxhQUFPLENBQUM7Z0JBQzFCLEdBQUcsRUFBRSxrRUFBa0U7YUFDeEUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFBLG9CQUFXLEVBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkUsTUFBTSxRQUFRLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3hHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO1FBQ2hDLEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxLQUFLO1lBQ2pDLE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FBQztnQkFDNUMsVUFBVSxFQUFFO29CQUNWLEtBQUssRUFBRSxpQkFBSyxDQUFDLFdBQVc7aUJBQ3pCO2dCQUNELElBQUksRUFBRSxDQUFDLHNCQUFVLENBQUMsT0FBTyxDQUFDO2dCQUMxQixHQUFHLEVBQUUsdUJBQVcsQ0FBQyxPQUFPO2FBQ3pCLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEtBQUs7WUFDN0QsSUFBSSxDQUFDO2dCQUNILE1BQU0sUUFBUSxDQUFDLGVBQWUsQ0FBQztvQkFDN0IsVUFBVSxFQUFFO3dCQUNWLEtBQUssRUFBRSxpQkFBSyxDQUFDLFdBQVc7cUJBQ3pCO29CQUNELElBQUksRUFBRSxDQUFDLHNCQUFVLENBQUMsT0FBTyxDQUFDO29CQUMxQixHQUFHLEVBQUUsdUJBQVcsQ0FBQyxPQUFPO2lCQUN6QixDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUseUNBQXlDLENBQUMsQ0FBQztZQUNyRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0RBQXNELEVBQUUsS0FBSztZQUM5RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDO29CQUM3QixVQUFVLEVBQUU7d0JBQ1YsS0FBSyxFQUFFLGlCQUFLLENBQUMsVUFBVTt3QkFDdkIsR0FBRyxFQUFFLDhCQUFRLENBQUMsUUFBUSxDQUFDLFNBQVM7cUJBQ2pDO29CQUNELEdBQUcsRUFBRSw4QkFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTO2lCQUNqQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7UUFDMUMsRUFBRSxDQUFDLDBCQUEwQixFQUFFLEdBQUcsRUFBRTtZQUNsQyxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDdEMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsRUFBRTtZQUM1QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGtFQUFrRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ3BHLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxFQUFFO1FBQ3BDLEVBQUUsQ0FBQywrREFBK0QsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM3RSxNQUFNLFFBQVEsR0FBRyxXQUFXLEVBQUUsQ0FBQztZQUMvQixNQUFNLFVBQVUsR0FBRyxhQUFhLEVBQUUsQ0FBQztZQUNuQyxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7WUFFeEIsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUN2RyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzNFLE1BQU0sVUFBVSxHQUFHO2dCQUNqQixLQUFLLEVBQUUsaUJBQUssQ0FBQyxRQUFRO2dCQUNyQixNQUFNLEVBQUUsRUFBRTthQUNYLENBQUM7WUFFRixNQUFNLFFBQVEsR0FBRyxXQUFXLEVBQUUsQ0FBQztZQUMvQixNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7WUFFeEIsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztZQUN2RyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdFQUFnRSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlFLE1BQU0sVUFBVSxHQUFHLGFBQWEsRUFBRSxDQUFDO1lBRW5DLE1BQU0sUUFBUSxHQUFHO2dCQUNmLFVBQVUsRUFBRTtvQkFDVjt3QkFDRSxPQUFPLEVBQUUsa0VBQWtFO3dCQUMzRSxNQUFNLEVBQUUsMkJBQTJCO3FCQUNwQztvQkFDRDt3QkFDRSxPQUFPLEVBQUUsa0VBQWtFO3dCQUMzRSxNQUFNLEVBQUUsMkJBQTJCO3FCQUNwQztpQkFDRjthQUNGLENBQUM7WUFFRixNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7WUFFeEIsTUFBTSxRQUFRO2lCQUNYLGlCQUFpQixDQUFDLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsQ0FBQztpQkFDekQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUN4RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLO1lBQ3pELE1BQU0sUUFBUSxHQUFHLFdBQVcsRUFBRSxDQUFDO1lBQy9CLFFBQVEsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1lBQ2hDLE1BQU0sVUFBVSxHQUFHLGFBQWEsRUFBRSxDQUFDO1lBQ25DLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNwRixnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEtBQUs7WUFDbEQsTUFBTSxRQUFRLEdBQUcsV0FBVyxFQUFFLENBQUM7WUFDL0IsUUFBUSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7WUFDaEMsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sUUFBUTtpQkFDWCxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQztpQkFDM0MsTUFBTSxDQUFDLFlBQVksQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNFQUFzRSxFQUFFLEtBQUs7WUFDOUUsTUFBTSxVQUFVLEdBQUcsYUFBYSxFQUFFLENBQUM7WUFDbkMsTUFBTSxRQUFRLEdBQUcsV0FBVyxFQUFFLENBQUM7WUFDL0IsUUFBUSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7WUFFdkIsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ3BGLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDL0QsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFdBQVcsRUFBRSxzQ0FBc0M7Z0JBQ25ELFFBQVEsRUFBRSwwQkFBMEI7Z0JBQ3BDLEtBQUssRUFDSCxzUEFBc1A7Z0JBQ3hQLE9BQU8sRUFBRTtvQkFDUCxHQUFHLEVBQUUsTUFBTTtvQkFDWCxTQUFTLEVBQUUsUUFBUTtpQkFDcEI7Z0JBQ0QsTUFBTSxFQUFFO29CQUNOLFFBQVEsRUFBRSxRQUFRO29CQUNsQixXQUFXLEVBQUUsV0FBVztvQkFDeEIsWUFBWSxFQUFFO3dCQUNaOzRCQUNFLFFBQVEsRUFBRSxNQUFNOzRCQUNoQixZQUFZLEVBQUUsV0FBVzt5QkFDMUI7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFLEdBQUc7b0JBQ2IsT0FBTyxFQUFFO3dCQUNQOzRCQUNFLE9BQU8sRUFDTCw4R0FBOEc7NEJBQ2hILEtBQUssRUFBRSxTQUFTOzRCQUNoQixNQUFNLEVBQUUsMEJBQTBCOzRCQUNsQyxPQUFPLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQzs0QkFDckMsVUFBVSxFQUFFLDBCQUEwQjs0QkFDdEMsV0FBVyxFQUFFLENBQUMsMEJBQTBCLENBQUM7NEJBQ3pDLFdBQVcsRUFBRSxXQUFXOzRCQUN4QixRQUFRLEVBQUUsTUFBTTs0QkFDaEIsVUFBVSxFQUFFLEtBQUs7NEJBQ2pCLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQzt5QkFDckI7cUJBQ0Y7b0JBQ0QsTUFBTSxFQUFFO3dCQUNOOzRCQUNFLEtBQUssRUFBRSxVQUFVOzRCQUNqQixPQUFPLEVBQ0wsOEdBQThHOzRCQUNoSCxXQUFXLEVBQUUsWUFBWTt5QkFDMUI7cUJBQ0Y7b0JBQ0QsSUFBSSxFQUFFLEdBQUc7aUJBQ1Y7Z0JBQ0QsYUFBYSxFQUFFLGtDQUFrQztnQkFDakQsSUFBSSxFQUFFLE1BQU07YUFDYixDQUFDO1lBRUYsTUFBTSxZQUFZLEdBQUc7Z0JBQ25CLFlBQVksRUFBRSxHQUFHLEVBQUU7b0JBQ2pCLE9BQU87d0JBQ0wsV0FBVyxFQUNULDhHQUE4RztxQkFDakgsQ0FBQztnQkFDSixDQUFDO2FBQ0YsQ0FBQztZQUVGLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztvQkFDbEQsUUFBUSxFQUFFLEVBQUU7b0JBQ1osVUFBVSxFQUFFLGVBQWU7b0JBQzNCLE1BQU0sRUFBRSxZQUFZO29CQUNwQixZQUFZLEVBQUU7d0JBQ1osMEJBQTBCLEVBQUUsSUFBSTtxQkFDakM7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLGdCQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEtBQUs7WUFDakUscUJBQXFCO1lBQ3JCLE1BQU0sVUFBVSxHQUFHO2dCQUNqQixFQUFFLEVBQUUsa0NBQWtDO2dCQUN0QyxJQUFJLEVBQUUsTUFBTTtnQkFDWixJQUFJLEVBQUU7b0JBQ0osa0NBQWtDO29CQUNsQyxrQ0FBa0M7b0JBQ2xDLGtDQUFrQztpQkFDbkM7Z0JBQ0QsWUFBWSxFQUFFO29CQUNaLFdBQVcsRUFDVCw4R0FBOEc7aUJBQ2pIO2dCQUNELFlBQVksRUFBRSxLQUFLO2FBQ3BCLENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRyxJQUFBLGlCQUFPLEVBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRTNDLE1BQU0sU0FBUyxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzFELE1BQU0sS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUU5QyxJQUFBLGNBQUksRUFBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLG1EQUFtRCxDQUFDO2lCQUN4RCxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNWO29CQUNFLFlBQVksRUFBRSxPQUFPO2lCQUN0QjthQUNGLENBQUMsQ0FBQztZQUVMLHVEQUF1RDtZQUN2RCxJQUFBLGNBQUksRUFBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUFDLCtFQUErRSxDQUFDO2lCQUNyRixLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNWO29CQUNFLFdBQVcsRUFBRSxzQ0FBc0M7b0JBQ25ELFFBQVEsRUFBRSwwQkFBMEI7b0JBQ3BDLEtBQUssRUFDSCx3VUFBd1U7b0JBQzFVLE9BQU8sRUFBRTt3QkFDUCxHQUFHLEVBQUUsTUFBTTt3QkFDWCxTQUFTLEVBQUUsUUFBUTtxQkFDcEI7b0JBQ0QsTUFBTSxFQUFFO3dCQUNOLFFBQVEsRUFBRSxRQUFRO3dCQUNsQixXQUFXLEVBQUUsV0FBVzt3QkFDeEIsWUFBWSxFQUFFOzRCQUNaO2dDQUNFLFFBQVEsRUFBRSxNQUFNO2dDQUNoQixZQUFZLEVBQUUsV0FBVzs2QkFDMUI7eUJBQ0Y7d0JBQ0QsUUFBUSxFQUFFLEdBQUc7d0JBQ2IsT0FBTyxFQUFFOzRCQUNQO2dDQUNFLE9BQU8sRUFDTCw4R0FBOEc7Z0NBQ2hILEtBQUssRUFBRSxTQUFTO2dDQUNoQixNQUFNLEVBQUUsMEJBQTBCO2dDQUNsQyxPQUFPLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQztnQ0FDckMsVUFBVSxFQUFFLDBCQUEwQjtnQ0FDdEMsV0FBVyxFQUFFLENBQUMsMEJBQTBCLENBQUM7Z0NBQ3pDLFdBQVcsRUFBRSxXQUFXO2dDQUN4QixRQUFRLEVBQUUsTUFBTTtnQ0FDaEIsVUFBVSxFQUFFLEtBQUs7Z0NBQ2pCLFdBQVcsRUFBRSxDQUFDLEtBQUssQ0FBQzs2QkFDckI7eUJBQ0Y7d0JBQ0QsTUFBTSxFQUFFOzRCQUNOO2dDQUNFLEtBQUssRUFBRSxVQUFVO2dDQUNqQixPQUFPLEVBQ0wsOEdBQThHO2dDQUNoSCxXQUFXLEVBQUUsWUFBWTs2QkFDMUI7eUJBQ0Y7d0JBQ0QsSUFBSSxFQUFFLEdBQUc7cUJBQ1Y7b0JBQ0QsYUFBYSxFQUFFLGtDQUFrQztvQkFDakQsSUFBSSxFQUFFLE1BQU07aUJBQ2I7YUFDRixDQUFDLENBQUM7WUFFTCw0QkFBNEI7WUFDNUIsTUFBTSxnQkFBTSxDQUFDLE9BQU8sQ0FDbEIsS0FBSyxJQUFJLEVBQUU7Z0JBQ1QsTUFBTSxTQUFTLENBQUMseUJBQXlCLENBQUM7b0JBQ3hDLGdCQUFnQixFQUFFLFVBQVU7aUJBQzdCLENBQUMsQ0FBQztZQUNMLENBQUMsRUFDRDtnQkFDRSxPQUFPLEVBQUUsaURBQWlEO2FBQzNELENBQ0YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsdUJBQXVCLEVBQUUsR0FBRyxFQUFFO1FBQ3JDLEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLO1lBQ3pELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxRQUFRLENBQUMsa0JBQWtCLENBQUM7Z0JBQzdELFVBQVUsRUFBRTtvQkFDVixLQUFLLEVBQUUsaUJBQUssQ0FBQyxXQUFXO2lCQUN6QjthQUNGLENBQUMsQ0FBQztZQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNsQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0RBQXdELEVBQUUsS0FBSztZQUNoRSxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxRQUFRLENBQUMsa0JBQWtCLENBQUM7b0JBQ2hDLFVBQVUsRUFBRSxFQUFFO2lCQUNmLENBQUMsQ0FBQztZQUNMLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1lBQ3JELENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRSxLQUFLO1lBQzlELElBQUksQ0FBQztnQkFDSCxNQUFNLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQztvQkFDaEMsVUFBVSxFQUFFO3dCQUNWLEtBQUssRUFBRSxjQUFjO3FCQUN0QjtpQkFDRixDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUscUJBQXFCLENBQUMsQ0FBQztZQUNyRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7UUFDdEMsRUFBRSxDQUFDLHlDQUF5QyxFQUFFO1lBQzVDLE1BQU0sRUFBRSxHQUFHLElBQUksaUJBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsaUJBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ2pELE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxzQkFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO1lBQ3ZDLE1BQU0sRUFBRSxHQUFHLElBQUksaUJBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsaUJBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxzQkFBZSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNDQUFzQyxFQUFFO1lBQ3pDLE1BQU0sRUFBRSxHQUFHLElBQUksaUJBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsaUJBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxzQkFBZSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDM0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxHQUFHLEVBQUU7UUFDbkMsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUs7WUFDdkQsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDeEQsVUFBVSxFQUFFO29CQUNWLEtBQUssRUFBRSxpQkFBSyxDQUFDLFdBQVc7aUJBQ3pCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEtBQUs7WUFDcEQsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDeEQsVUFBVSxFQUFFO29CQUNWLEtBQUssRUFBRSxpQkFBSyxDQUFDLFNBQVM7aUJBQ3ZCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtGQUErRixFQUFFLEtBQUs7WUFDdkcsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFHLENBQUMsU0FBUyxFQUFFLG9CQUFvQixDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6QixNQUFNLFFBQVE7aUJBQ1gsZ0JBQWdCLENBQUM7Z0JBQ2hCLFVBQVUsRUFBRTtvQkFDVixLQUFLLEVBQUUsaUJBQUssQ0FBQyxRQUFRO2lCQUN0QjthQUNGLENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7UUFDckMsTUFBTSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXRDLFVBQVUsQ0FBQztZQUNULE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBRyxDQUFDLFNBQVMsRUFBRSxpQkFBOEIsQ0FBQyxDQUFDO1lBQzdFLFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDeEIsVUFBVSxFQUFFLENBQUMsbUJBQU8sQ0FBQyxjQUFjLENBQUM7YUFDckMsQ0FBQztpQkFDRCxRQUFRLENBQUMsNkJBQWlCLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDM0QsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsNkJBQWlCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUM7WUFDUixPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0VBQWdFLEVBQUUsS0FBSztZQUN4RSxNQUFNLE1BQU0sR0FBRyx1QkFBVyxDQUFDO1lBQzNCLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLG1DQUFtQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9FLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ25ELG9jQUFvYyxDQUNyYyxDQUFDO1lBQ0YsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsc0ZBQXNGLEVBQUUsS0FBSztZQUM5RixNQUFNLE1BQU0sR0FBRyx3QkFBWSxDQUFDO1lBQzVCLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLG1DQUFtQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9FLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ25ELG9jQUFvYyxDQUNyYyxDQUFDO1lBQ0YsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNuRCxvY0FBb2MsQ0FDcmMsQ0FBQztZQUNGLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEQsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDbkQsb2NBQW9jLENBQ3JjLENBQUM7WUFDRixXQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RELFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ25ELG9jQUFvYyxDQUNyYyxDQUFDO1lBQ0YsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsS0FBSztZQUN2RCxNQUFNLEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ2pDLE9BQU8sRUFBRSxtQkFBTyxDQUFDLE9BQU87Z0JBQ3hCLFNBQVMsRUFBRSxtQkFBTyxDQUFDLFNBQVM7Z0JBQzVCLFFBQVEsRUFBRSxtQkFBTyxDQUFDLFFBQVE7Z0JBQzFCLGdCQUFnQixFQUFFLG1CQUFPLENBQUMsZ0JBQWdCO2dCQUMxQyxtQkFBbUIsRUFBRSxRQUFRO2FBQzlCLENBQUMsQ0FBQztZQUNILEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMxQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFckQsTUFBTSxFQUFFLEdBQUcsSUFBSSxpQkFBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDeEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5RSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEYsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvREFBb0QsRUFBRSxLQUFLO1lBQzVELE1BQU0sR0FBRyxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFDakMsUUFBUSxFQUFFLG1CQUFPLENBQUMsUUFBUTtnQkFDMUIsbUJBQW1CLEVBQUUsUUFBUTthQUM5QixDQUFDLENBQUM7WUFDSCxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDMUIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDbkYsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBRXJELE1BQU0sRUFBRSxHQUFHLElBQUksaUJBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMzQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLGtCQUFrQixFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixFQUFFLHVCQUFXLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xGLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDdEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxxQ0FBcUMsRUFBRSxHQUFHLEVBQUU7UUFDbkQsTUFBTSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXRDLFVBQVUsQ0FBQztZQUNULE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBRyxDQUFDLFNBQVMsRUFBRSxpQkFBOEIsQ0FBQyxDQUFDO1lBQzdFLFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDeEIsVUFBVSxFQUFFLENBQUMsbUJBQU8sQ0FBQyxjQUFjLENBQUM7YUFDckMsQ0FBQztpQkFDRCxRQUFRLENBQUMsNkJBQWlCLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDM0QsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsNkJBQWlCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUM7WUFDUixPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsS0FBSztZQUN2RCxNQUFNLEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ2pDLE9BQU8sRUFBRSxtQkFBTyxDQUFDLE9BQU87Z0JBQ3hCLFNBQVMsRUFBRSxtQkFBTyxDQUFDLFNBQVM7Z0JBQzVCLFFBQVEsRUFBRSxtQkFBTyxDQUFDLFFBQVE7Z0JBQzFCLGdCQUFnQixFQUFFLG1CQUFPLENBQUMsZ0JBQWdCO2dCQUMxQyxtQkFBbUIsRUFBRSxRQUFRO2FBQzlCLENBQUMsQ0FBQztZQUNILEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMxQixHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMxQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFckQsTUFBTSxFQUFFLEdBQUcsSUFBSSxpQkFBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDeEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDcEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5RSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEYsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM5RSxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbEYsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsdUJBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0RBQW9ELEVBQUUsS0FBSztZQUM1RCxNQUFNLEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ2pDLFFBQVEsRUFBRSxtQkFBTyxDQUFDLFFBQVE7Z0JBQzFCLG1CQUFtQixFQUFFLFFBQVE7YUFDOUIsQ0FBQyxDQUFDO1lBQ0gsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFCLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ25GLE9BQU8sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUVyRCxNQUFNLEVBQUUsR0FBRyxJQUFJLGlCQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNqRixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0IsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwRCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLHVCQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzlFLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLHVCQUFXLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzlFLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxFQUFFLHVCQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUMvQyxNQUFNLFFBQVEsR0FBRyxnQ0FBb0IsQ0FBQyxjQUFjLENBQUM7UUFDckQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXRDLFVBQVUsQ0FBQztZQUNULE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBRyxDQUFDLFNBQVMsRUFBRSxpQkFBOEIsQ0FBQyxDQUFDO1lBQzdFLFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDeEIsVUFBVSxFQUFFLENBQUMsZ0NBQW9CLENBQUMsY0FBYyxDQUFDO2FBQ2xELENBQUM7aUJBQ0QsUUFBUSxDQUFDLDZCQUFpQixDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDeEIsVUFBVSxFQUFFLENBQUMsZ0NBQW9CLENBQUMsY0FBYyxDQUFDO2FBQ2xELENBQUM7aUJBQ0QsUUFBUSxDQUFDLDZCQUFpQixDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzNELFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDeEIsVUFBVSxFQUFFLENBQUMsZ0NBQW9CLENBQUMsY0FBYyxDQUFDO2FBQ2xELENBQUM7aUJBQ0QsUUFBUSxDQUFDLDZCQUFpQixDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLDZCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBRUgsU0FBUyxDQUFDO1lBQ1IsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFLEtBQUs7WUFDdEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLENBQUMscUJBQXFCLENBQUM7Z0JBQy9DLE9BQU8sRUFBRSxnQ0FBb0IsQ0FBQyxPQUFPO2dCQUNyQyxTQUFTLEVBQUUsZ0NBQW9CLENBQUMsU0FBUztnQkFDekMsUUFBUSxFQUFFLGdDQUFvQixDQUFDLFFBQVE7Z0JBQ3ZDLGdCQUFnQixFQUFFLGdDQUFvQixDQUFDLGdCQUFnQjtnQkFDdkQsaUJBQWlCLEVBQUUsQ0FBQztnQkFDcEIsZUFBZSxFQUFFLENBQUM7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzFCLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakMsTUFBTSxHQUFHLEdBQUcsSUFBSSxpQkFBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3RDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDMUMsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvRSxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkYsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN2RCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksRUFBRSx1QkFBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVyRixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksaUJBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0QyxHQUFHLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0UsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixFQUFFLHVCQUFXLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDdkQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLEVBQUUsdUJBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMEVBQTBFLEVBQUUsS0FBSztZQUNsRixNQUFNLFFBQVE7aUJBQ1gscUJBQXFCLENBQUM7Z0JBQ3JCLE9BQU8sRUFBRSxnQ0FBb0IsQ0FBQyxPQUFPO2dCQUNyQyxTQUFTLEVBQUUsZ0NBQW9CLENBQUMsU0FBUztnQkFDekMsUUFBUSxFQUFFLGdDQUFvQixDQUFDLFFBQVE7Z0JBQ3ZDLGdCQUFnQixFQUFFLGdDQUFvQixDQUFDLGdCQUFnQjtnQkFDdkQsaUJBQWlCLEVBQUUsQ0FBQztnQkFDcEIsZUFBZSxFQUFFLENBQUM7YUFDbkIsQ0FBQztpQkFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLCtDQUErQyxDQUFDLENBQUM7UUFDMUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDaEUsTUFBTSxRQUFRO2lCQUNYLHFCQUFxQixDQUFDO2dCQUNyQixPQUFPLEVBQUUsZ0NBQW9CLENBQUMsT0FBTztnQkFDckMsU0FBUyxFQUFFLGdDQUFvQixDQUFDLFNBQVM7Z0JBQ3pDLFFBQVEsRUFBRSxnQ0FBb0IsQ0FBQyxRQUFRO2dCQUN2QyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7YUFDdEIsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FDckIscUdBQXFHLENBQ3RHLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN2RCxNQUFNLFFBQVE7aUJBQ1gscUJBQXFCLENBQUM7Z0JBQ3JCLE9BQU8sRUFBRSxnQ0FBb0IsQ0FBQyxPQUFPO2dCQUNyQyxTQUFTLEVBQUUsZ0NBQW9CLENBQUMsU0FBUztnQkFDekMsUUFBUSxFQUFFLGdDQUFvQixDQUFDLFFBQVE7Z0JBQ3ZDLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3BCLGVBQWUsRUFBRSxHQUFHO2FBQ3JCLENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQ3JCLHFHQUFxRyxDQUN0RyxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7UUFDN0MsTUFBTSxRQUFRLEdBQUcsbUJBQU8sQ0FBQyxRQUFRLENBQUM7UUFDbEMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXRDLFNBQVMsQ0FBQztZQUNSLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpRUFBaUUsRUFBRSxLQUFLO1lBQ3pFLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBRyxDQUFDLFNBQVMsRUFBRSxpQkFBOEIsQ0FBQyxDQUFDO1lBQzdFLFFBQVE7aUJBQ0wsUUFBUSxDQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDdkQsUUFBUSxDQUFDLDZCQUFpQixDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLDZCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3JFLE1BQU0sUUFBUTtpQkFDWCxPQUFPLENBQUM7Z0JBQ1AsT0FBTyxFQUFFLG1CQUFPLENBQUMsT0FBTztnQkFDeEIsU0FBUyxFQUFFLG1CQUFPLENBQUMsU0FBUztnQkFDNUIsUUFBUSxFQUFFLG1CQUFPLENBQUMsUUFBUTtnQkFDMUIsZ0JBQWdCLEVBQUUsbUJBQU8sQ0FBQyxnQkFBZ0I7Z0JBQzFDLG1CQUFtQixFQUFFLFFBQVE7YUFDOUIsQ0FBQztpQkFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7WUFDckUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3RELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1FQUFtRSxFQUFFLEtBQUs7WUFDM0UsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFHLENBQUMsU0FBUyxFQUFFLGlCQUE4QixDQUFDLENBQUM7WUFDN0UsUUFBUTtpQkFDTCxRQUFRLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN2RCxRQUFRLENBQUMsNkJBQWlCLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDaEUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsNkJBQWlCLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDckUsTUFBTSxRQUFRO2lCQUNYLE9BQU8sQ0FBQztnQkFDUCxPQUFPLEVBQUUsbUJBQU8sQ0FBQyxPQUFPO2dCQUN4QixTQUFTLEVBQUUsbUJBQU8sQ0FBQyxTQUFTO2dCQUM1QixRQUFRLEVBQUUsbUJBQU8sQ0FBQyxRQUFRO2dCQUMxQixnQkFBZ0IsRUFBRSxtQkFBTyxDQUFDLGdCQUFnQjtnQkFDMUMsbUJBQW1CLEVBQUUsUUFBUTthQUM5QixDQUFDO2lCQUNELE1BQU0sQ0FBQyxZQUFZLENBQ2xCLDhGQUE4RixDQUMvRixDQUFDO1lBQ0osT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1FBQ3hELE1BQU0sY0FBYyxHQUNsQixrSUFBa0ksQ0FBQztRQUVySSxFQUFFLENBQUMsaURBQWlELEVBQUUsS0FBSztZQUN6RCxNQUFNLFNBQVMsR0FBRztnQkFDaEI7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxNQUFNO2lCQUNmO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsUUFBUTtpQkFDakI7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxPQUFPO2lCQUNoQjthQUNGLENBQUM7WUFFRixNQUFNLE9BQU8sR0FDWCw4R0FBOEcsQ0FBQztZQUNqSCxNQUFNLE9BQU8sR0FBRyxNQUFNLFFBQVEsQ0FBQyxlQUFlLENBQUM7Z0JBQzdDLE9BQU87Z0JBQ1AsU0FBUztnQkFDVCxLQUFLLEVBQUUsQ0FBQzthQUNULENBQUMsQ0FBQztZQUVILE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEtBQUs7WUFDM0QsTUFBTSxTQUFTLEdBQUc7Z0JBQ2hCO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLE1BQWU7aUJBQ3hCO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLFFBQWlCO2lCQUMxQjtnQkFDRDtvQkFDRSxFQUFFLEVBQUUsR0FBRztvQkFDUCxjQUFjLEVBQUUsY0FBYztvQkFDOUIsSUFBSSxFQUFFLEtBQWM7b0JBQ3BCLE1BQU0sRUFBRSxPQUFnQjtpQkFDekI7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPLEdBQUcsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDO2dCQUM3QyxPQUFPLEVBQ0wsOEdBQThHO2dCQUNoSCxTQUFTO2dCQUNULEtBQUssRUFBRSxDQUFDO2FBQ1QsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0RBQXdELEVBQUUsS0FBSztZQUNoRSxNQUFNLFNBQVMsR0FBRztnQkFDaEI7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLElBQUksRUFBRSxLQUFjO29CQUNwQixNQUFNLEVBQUUsTUFBZTtpQkFDeEI7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLElBQUksRUFBRSxLQUFjO29CQUNwQixNQUFNLEVBQUUsUUFBaUI7aUJBQzFCO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLE9BQWdCO2lCQUN6QjthQUNGLENBQUM7WUFFRixzREFBc0Q7WUFDdEQsTUFBTSxhQUFhLEdBQUcsaUVBQWlFLENBQUM7WUFFeEYsTUFBTSxPQUFPLEdBQUcsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDO2dCQUM3QyxPQUFPLEVBQUUsYUFBYTtnQkFDdEIsU0FBUztnQkFDVCxLQUFLLEVBQUUsQ0FBQzthQUNULENBQUMsQ0FBQztZQUVILE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUs7WUFDdkQsTUFBTSxTQUFTLEdBQUc7Z0JBQ2hCO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLE1BQWU7aUJBQ3hCO2dCQUNEO29CQUNFLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxjQUFjO29CQUM5QixJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLFFBQWlCO2lCQUMxQjtnQkFDRDtvQkFDRSxFQUFFLEVBQUUsR0FBRztvQkFDUCxjQUFjLEVBQUUsY0FBYztvQkFDOUIsSUFBSSxFQUFFLEtBQWM7b0JBQ3BCLE1BQU0sRUFBRSxPQUFnQjtpQkFDekI7YUFDRixDQUFDO1lBRUYsTUFBTSxjQUFjLEdBQUcscUJBQXFCLENBQUM7WUFFN0MsTUFBTSxRQUFRO2lCQUNYLGVBQWUsQ0FBQztnQkFDZixPQUFPLEVBQUUsY0FBYztnQkFDdkIsU0FBUztnQkFDVCxLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxLQUFLO1lBQ3ZELE1BQU0sT0FBTyxHQUNYLDhHQUE4RyxDQUFDO1lBRWpILE1BQU0sUUFBUTtpQkFDWCxlQUFlLENBQUM7Z0JBQ2YsT0FBTztnQkFDUCxTQUFTLEVBQUUsRUFBRTtnQkFDYixLQUFLLEVBQUUsQ0FBQzthQUNULENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtREFBbUQsRUFBRSxLQUFLO1lBQzNELE1BQU0sU0FBUyxHQUFHO2dCQUNoQjtvQkFDRSxFQUFFLEVBQUUsR0FBRztvQkFDUCxJQUFJLEVBQUUsS0FBYztvQkFDcEIsTUFBTSxFQUFFLE1BQWU7b0JBQ3ZCLDRCQUE0QjtpQkFDN0I7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPLEdBQ1gsOEdBQThHLENBQUM7WUFFakgsTUFBTSxRQUFRO2lCQUNYLGVBQWUsQ0FBQztnQkFDZixPQUFPO2dCQUNQLFNBQVM7Z0JBQ1QsS0FBSyxFQUFFLENBQUM7YUFDVCxDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUVBQW1FLEVBQUUsS0FBSztZQUMzRSxNQUFNLFNBQVMsR0FBRztnQkFDaEI7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLElBQUksRUFBRSxLQUFjO29CQUNwQixNQUFNLEVBQUUsTUFBZTtpQkFDeEI7Z0JBQ0Q7b0JBQ0UsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLG1GQUFtRjtvQkFDbkcsSUFBSSxFQUFFLEtBQWM7b0JBQ3BCLE1BQU0sRUFBRSxRQUFpQjtpQkFDMUI7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPLEdBQ1gsOEdBQThHLENBQUM7WUFFakgsTUFBTSxRQUFRO2lCQUNYLGVBQWUsQ0FBQztnQkFDZixPQUFPO2dCQUNQLFNBQVM7Z0JBQ1QsS0FBSyxFQUFFLENBQUM7YUFDVCxDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLCtEQUErRCxDQUFDLENBQUM7UUFDN0YsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDdkQsRUFBRSxDQUFDLHdGQUF3RixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ3RHLE1BQU0sZUFBZSxHQUFHO2dCQUN0QixXQUFXLEVBQUUsc0NBQXNDO2dCQUNuRCxRQUFRLEVBQUUsa0NBQWtDO2dCQUM1QyxLQUFLLEVBQ0gsb2NBQW9jO2dCQUN0YyxPQUFPLEVBQUU7b0JBQ1AsR0FBRyxFQUFFLEtBQUs7b0JBQ1YsU0FBUyxFQUFFLE9BQU87aUJBQ25CO2dCQUNELE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUU7d0JBQ047NEJBQ0UsT0FBTyxFQUFFLDhDQUE4Qzs0QkFDdkQsS0FBSyxFQUFFLFlBQVk7NEJBQ25CLFdBQVcsRUFBRSxhQUFhO3lCQUMzQjt3QkFDRDs0QkFDRSxPQUFPLEVBQUUsOENBQThDOzRCQUN2RCxLQUFLLEVBQUUsS0FBSzs0QkFDWixXQUFXLEVBQUUsT0FBTzt5QkFDckI7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLE9BQU8sRUFBRTt3QkFDUDs0QkFDRSxPQUFPLEVBQUUsaUVBQWlFOzRCQUMxRSxRQUFRLEVBQUUsV0FBVzs0QkFDckIsVUFBVSxFQUFFO2dDQUNWLElBQUksRUFBRSwwQkFBMEI7NkJBQ2pDOzRCQUNELFdBQVcsRUFBRTtnQ0FDWDtvQ0FDRSxJQUFJLEVBQUUsMEJBQTBCO2lDQUNqQzs2QkFDRjs0QkFDRCxLQUFLLEVBQUUsWUFBWTs0QkFDbkIsV0FBVyxFQUFFLGFBQWE7NEJBQzFCLE1BQU0sRUFBRTtnQ0FDTixJQUFJLEVBQUUsMEJBQTBCOzZCQUNqQzs0QkFDRCxVQUFVLEVBQUUsS0FBSzs0QkFDakIsT0FBTyxFQUFFO2dDQUNQO29DQUNFLElBQUksRUFBRSwwQkFBMEI7aUNBQ2pDOzZCQUNGO3lCQUNGO3FCQUNGO29CQUNELFFBQVEsRUFBRSxHQUFHO29CQUNiLFdBQVcsRUFBRSxhQUFhO29CQUMxQixZQUFZLEVBQUU7d0JBQ1o7NEJBQ0UsWUFBWSxFQUFFLGFBQWE7NEJBQzNCLFFBQVEsRUFBRSxXQUFXO3lCQUN0QjtxQkFDRjtvQkFDRCxJQUFJLEVBQUUsTUFBTTtpQkFDYjtnQkFDRCxhQUFhLEVBQUUsa0NBQWtDO2dCQUNqRCxJQUFJLEVBQUUsTUFBTTthQUNiLENBQUM7WUFFRix5RUFBeUU7WUFDekUsTUFBTSxZQUFZLEdBQUc7Z0JBQ25CLFlBQVksRUFBRSxHQUFHLEVBQUU7b0JBQ2pCLE9BQU87d0JBQ0wsV0FBVyxFQUNULDhHQUE4RztxQkFDakgsQ0FBQztnQkFDSixDQUFDO2FBQ0YsQ0FBQztZQUVGLE1BQU0sUUFBUTtpQkFDWCxpQkFBaUIsQ0FBQztnQkFDakIsUUFBUSxFQUFFLEVBQUU7Z0JBQ1osVUFBVSxFQUFFLGVBQWU7Z0JBQzNCLE1BQU0sRUFBRSxZQUFZO2dCQUNwQixZQUFZLEVBQUU7b0JBQ1osMEJBQTBCLEVBQUUsSUFBSTtpQkFDakM7YUFDRixDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGlEQUFpRCxDQUFDLENBQUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuXG5pbXBvcnQgc2hvdWxkID0gcmVxdWlyZSgnc2hvdWxkJyk7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvQVBJLCBlbmNyeXB0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQge1xuICBhZGRyZXNzLFxuICBjb25zb2xpZGF0aW9uV3J3VXNlcixcbiAgZW5kcG9pbnRSZXNwb25zZXMsXG4gIGVudGVycHJpc2VBY2NvdW50cyBhcyBhY2NvdW50cyxcbiAgb3ZjUmVzcG9uc2UsXG4gIG92Y1Jlc3BvbnNlMixcbiAgcHJpdmF0ZUtleXMsXG4gIHB1YmxpY0tleXMsXG4gIHJhd1R4LFxuICB0ZXN0bmV0VVRYTyxcbiAgd3J3VXNlcixcbn0gZnJvbSAnLi4vcmVzb3VyY2VzJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEFkYSwgS2V5UGFpciwgVGFkYSB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnLi4vLi4vLi4vc2RrLWNvcmUvc3JjL2FjY291bnQtbGliL2Jhc2VDb2luL2VudW0nO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgY29tbW9uLCBXYWxsZXQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcblxuZGVzY3JpYmUoJ0FEQScsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY29pbk5hbWUgPSAnYWRhJztcbiAgY29uc3QgdGNvaW5OYW1lID0gJ3QnICsgY29pbk5hbWU7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW47XG4gIGxldCBuZXdUeFByZWJ1aWxkO1xuICBsZXQgbmV3VHhQYXJhbXM7XG5cbiAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeCxcbiAgICB0eEluZm86IHt9LFxuICB9O1xuXG4gIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgIHJlY2lwaWVudHM6IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogcmF3VHgub3V0cHV0QWRkcmVzczEuYWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiAnNTAwMDAwMCcsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBhZGRyZXNzOiByYXdUeC5vdXRwdXRBZGRyZXNzMi5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6ICcyNDgzMjkxNTAnLFxuICAgICAgfSxcbiAgICBdLFxuICB9O1xuXG4gIGNvbnN0IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSB7XG4gICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VBbW91bnQnLCAnb3V0cHV0cycsICdjaGFuZ2VPdXRwdXRzJywgJ2ZlZScsICd0eXBlJ10sXG4gICAgaWQ6ICdmNDhmNmVhMGY3NWYzZjk0Mjg1NWNjMGVkZjI5ZTgxZTFlMDcyNGU3NWY1ZGI4YTE1NzViMTY2ZmIyMDIxNzZjJyxcbiAgICBvdXRwdXRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6XG4gICAgICAgICAgJ2FkZHJfdGVzdDFxcW5udnB0cmMzcmVjNjRxMm45amg1NzJuY3U1d3ZkdHQ4dXZnNGczYWo5NnM1ZHd1OW5qNzBtbGFoemdsbTk5Mzl1ZXZ1cHNtajhkY2RxdjI1ZDVuNXI4dnc4c243cHJleScsXG4gICAgICAgIGFtb3VudDogJzc4MjMxMjEnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogJ2FkZHJfdGVzdDF2cjhyYWttNjZyY2Z2NGZjeHF5a2c1bGYweXY3bHN5azltdmFweDM2OWpwdnRjZ2ZjdWs3ZicsXG4gICAgICAgIGFtb3VudDogJzEzMDQxNzI5JyxcbiAgICAgIH0sXG4gICAgXSxcbiAgICBvdXRwdXRBbW91bnQ6ICcyMDg2NDg1MCcsXG4gICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgZmVlOiB7IGZlZTogJzE2NzE3MycgfSxcbiAgICB0eXBlOiAnVHJhbnNmZXInLFxuICAgIGNlcnRpZmljYXRlczogW10sXG4gICAgd2l0aGRyYXdhbHM6IFtdLFxuICAgIHBsZWRnZURldGFpbHM6IHVuZGVmaW5lZCxcbiAgfTtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3Rlcihjb2luTmFtZSwgQWRhLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIodGNvaW5OYW1lLCBUYWRhLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4odGNvaW5OYW1lKTtcbiAgICBuZXdUeFByZWJ1aWxkID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UHJlYnVpbGQpO1xuICAgIH07XG4gICAgbmV3VHhQYXJhbXMgPSAoKSA9PiB7XG4gICAgICByZXR1cm4gXy5jbG9uZURlZXAodHhQYXJhbXMpO1xuICAgIH07XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgaW5zdGFudGlhdGUgdGhlIGNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGxvY2FsQmFzZWNvaW4gPSBiaXRnby5jb2luKHRjb2luTmFtZSk7XG4gICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihUYWRhKTtcbiAgICBsb2NhbEJhc2Vjb2luLmdldENoYWluKCkuc2hvdWxkLmVxdWFsKHRjb2luTmFtZSk7XG4gICAgbG9jYWxCYXNlY29pbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCgnVGVzdG5ldCBBZGEnKTtcblxuICAgIGxvY2FsQmFzZWNvaW4gPSBiaXRnby5jb2luKGNvaW5OYW1lKTtcbiAgICBsb2NhbEJhc2Vjb2luLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEFkYSk7XG4gICAgbG9jYWxCYXNlY29pbi5nZXRDaGFpbigpLnNob3VsZC5lcXVhbChjb2luTmFtZSk7XG4gICAgbG9jYWxCYXNlY29pbi5nZXRGdWxsTmFtZSgpLnNob3VsZC5lcXVhbCgnQ2FyZGFubyBBREEnKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ24gTWVzc2FnZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGJlIHBlcmZvcm1lZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcigpO1xuICAgICAgY29uc3QgbWVzc2FnZVRvU2lnbiA9IEJ1ZmZlci5mcm9tKHJhbmRvbUJ5dGVzKDMyKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2Uoa2V5UGFpci5nZXRLZXlzKCksIG1lc3NhZ2VUb1NpZ24pO1xuICAgICAga2V5UGFpci52ZXJpZnlTaWduYXR1cmUobWVzc2FnZVRvU2lnbiwgVWludDhBcnJheS5mcm9tKHNpZ25hdHVyZSkpLnNob3VsZC5lcXVhbHMoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHdpdGggbWlzc2luZyBwcml2YXRlIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcih7XG4gICAgICAgIHB1YjogJzc3ODgzMjdjNjk1ZGNhNGIzZTY0OWEwZGI0NWJjM2U3MDNhMmM2NzQyOGZjZTM2MGU2MTgwMGNjNDI0OGY0ZjcnLFxuICAgICAgfSkuZ2V0S2V5cygpO1xuICAgICAgY29uc3QgbWVzc2FnZVRvU2lnbiA9IEJ1ZmZlci5mcm9tKHJhbmRvbUJ5dGVzKDMyKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2Uoa2V5UGFpciwgbWVzc2FnZVRvU2lnbikuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBrZXkgcGFpciBvcHRpb25zJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaWduIHRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc2lnbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeDIsXG4gICAgICAgIH0sXG4gICAgICAgIHB1YnM6IFtwdWJsaWNLZXlzLnB1YktleTFdLFxuICAgICAgICBwcnY6IHByaXZhdGVLZXlzLnBydktleTQsXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwocmF3VHguc2lnbmVkVHgyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBzaWduIHRyYW5zYWN0aW9uIHdpdGggYW4gaW52YWxpZCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiByYXdUeC51bnNpZ25lZFR4MixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHB1YnM6IFtwdWJsaWNLZXlzLnB1YktleTFdLFxuICAgICAgICAgIHBydjogcHJpdmF0ZUtleXMucHJ2S2V5MixcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlLm1lc3NhZ2UsICdQcml2YXRlIGtleSBjYW5ub3Qgc2lnbiB0aGUgdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBidWlsZCB0cmFuc2FjdGlvbiB3aXRoIG1pc3NpbmcgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeCxcbiAgICAgICAgICAgIGtleTogYWNjb3VudHMuYWNjb3VudDEucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJ2OiBhY2NvdW50cy5hY2NvdW50MS5zZWNyZXRLZXksXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG91bGQubm90RXF1YWwoZSwgbnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQga2V5IHBhaXI6ICcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyJywgKCkgPT4ge1xuICAgICAgY29uc3Qga3AgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBrZXkgcGFpciBmcm9tIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJzlkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVmVyaWZ5IHRyYW5zYWN0aW9uOiAnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB1bnNpZ25lZCB0cmFuc2FjdGlvbiBpbiBoZXggZW5jb2RpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHZlcmlmaWNhdGlvbiB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHNpZ25lZCB0cmFuc2FjdGlvbiBpbiBoZXggZW5jb2RpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogcmF3VHguc2lnbmVkVHgsXG4gICAgICAgIHR4SW5mbzoge30sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgdHJhbnNhY3Rpb25zIHdoZW4gaGF2ZSBkaWZmZXJlbnQgcmVjaXBpZW50cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBuZXdUeFByZWJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzlmN2IwNjc1ZGI1OWQxOWI0YmQ5YzhjNzJlYWFiYmE3NWE5ODYzZDAyYjMwMTE1YjhiM2MzY2E1YzIwZjAyNTQnLFxuICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnOWY3YjA2NzVkYjU5ZDE5YjRiZDljOGM3MmVhYWJiYTc1YTk4NjNkMDJiMzAxMTViOGIzYzNjYTVjMjBmMDI1NCcsXG4gICAgICAgICAgICBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2Nhbm5vdCBmaW5kIHJlY2lwaWVudCBpbiBleHBlY3RlZCBvdXRwdXQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHdoZW4gaW5wdXQgYHJlY2lwaWVudHNgIGlzIGFic2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQgfSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB2ZXJpZnkgd2hlbiB0eEhleCBpcyBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgdHhQYXJhbXMucmVjaXBpZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7fTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHR4IHByZWJ1aWxkIHByb3BlcnR5IHR4SGV4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHRyYW5zYWN0aW9ucyB3aGVuIHJlY2lwaWVudHMgaGFzIGV4dHJhIGRhdGEnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgdHhQYXJhbXMuZGF0YSA9ICdkYXRhJztcblxuICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQgfSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdmFsaWQgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25UeCA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICcxYjVjNzljNS1hYjdjLTRmNDctOTEyYi1kZTZhOTVmYjA3NzknLFxuICAgICAgICB3YWxsZXRJZDogJzY0ZmEzMWE5NGRiNjVhMDAwN2M5NjkxYicsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICc4NGE0MDA4MTgyNTgyMGRiNDZjN2M3NmVhNTRmZWMyY2EwYTJmOTRiNzdhMjM4OTMxYThkY2UyMzg3Yzk5YTEyYjA4ZGQ4YWFjMjFjNGYwMDAxODE4MjU4MzkwMDQ2MDFmYzAxNmFjMzg1ODA5MTZkMzUyMGJjNzZiNjU5Mjk4MTU2MDA4NzM4ZDM0N2FhOTMxNDJmNDYwMWZjMDE2YWMzODU4MDkxNmQzNTIwYmM3NmI2NTkyOTgxNTYwMDg3MzhkMzQ3YWE5MzE0MmYxYTNiOTg0MzU3MDIxYTAwMDI4NmE5MDMxYTA2MGUzN2VlYTBmNWY2JyxcbiAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgIGZlZTogMTY1NTQ1LFxuICAgICAgICAgIGZlZVN0cmluZzogJzE2NTU0NScsXG4gICAgICAgIH0sXG4gICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgIG1pbmVyRmVlOiAnMTY1NTQ1JyxcbiAgICAgICAgICBzcGVuZEFtb3VudDogJzk5OTgzNDQ1NScsXG4gICAgICAgICAgc3BlbmRBbW91bnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNvaW5OYW1lOiAndGFkYScsXG4gICAgICAgICAgICAgIGFtb3VudFN0cmluZzogJzk5OTgzNDQ1NScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6XG4gICAgICAgICAgICAgICAgJ2FkZHJfdGVzdDFxcHJxcmxxcGR0cGN0cXkzZDU2anAwcmtrZXZqbnEya3F6cm4zNTY4NDJmM2d0NnhxODdxejZrcnNrcWZ6bWY0eXo3OGRkamU5eHE0dnF5ODhyZjUwMjVuenNoc2pkbWcycycsXG4gICAgICAgICAgICAgIHZhbHVlOiA5OTk4MzQ0NTUsXG4gICAgICAgICAgICAgIHdhbGxldDogJzY0ZmEzMWE5NGRiNjVhMDAwN2M5NjkxYicsXG4gICAgICAgICAgICAgIHdhbGxldHM6IFsnNjRmYTMxYTk0ZGI2NWEwMDA3Yzk2OTFiJ10sXG4gICAgICAgICAgICAgIGVudGVycHJpc2U6ICc2MmNjNTliNzI3NDQzYTAwMDcwODkwMzMnLFxuICAgICAgICAgICAgICBlbnRlcnByaXNlczogWyc2MmNjNTliNzI3NDQzYTAwMDcwODkwMzMnXSxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICc5OTk4MzQ0NTUnLFxuICAgICAgICAgICAgICBjb2luTmFtZTogJ3RhZGEnLFxuICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgd2FsbGV0VHlwZXM6IFsnaG90J10sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHZhbHVlOiAxMDAwMDAwMDAwLFxuICAgICAgICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICAgICAgICdhZGRyX3Rlc3QxcXFsenhmbDd0bGdwOTk5eDRhNzMzNHBjaHljcGtrNzJweWtyc3IzbXJ5bDN5ajZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHN2cGdsOHcnLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzEwMDAwMDAwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHR5cGU6ICcwJyxcbiAgICAgICAgfSxcbiAgICAgICAgY29uc29saWRhdGVJZDogJzY4YjlmYzE4NTU4MDA2YWFiNTM3ODU2MTVmZWE3YzI4JyxcbiAgICAgICAgY29pbjogJ3RhZGEnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbW9ja2VkV2FsbGV0ID0ge1xuICAgICAgICBjb2luU3BlY2lmaWM6ICgpID0+IHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcm9vdEFkZHJlc3M6XG4gICAgICAgICAgICAgICdhZGRyX3Rlc3QxcXBycXJscXBkdHBjdHF5M2Q1NmpwMHJra2V2am5xMmtxenJuMzU2ODQyZjNndDZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHNqZG1nMnMnLFxuICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpc1ZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7fSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiBjb25zb2xpZGF0aW9uVHgsXG4gICAgICAgICAgd2FsbGV0OiBtb2NrZWRXYWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7XG4gICAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgaXNWZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGFzc2VydC5mYWlsKCdUcmFuc2FjdGlvbiBzaG91bGQgcGFzcyB2ZXJpZmljYXRpb24nKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBzaWduIGEgc3Bvb2ZlZCBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gU2V0IHVwIHdhbGxldCBkYXRhXG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3RhZGEnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOlxuICAgICAgICAgICAgJ2FkZHJfdGVzdDFxcHJxcmxxcGR0cGN0cXkzZDU2anAwcmtrZXZqbnEya3F6cm4zNTY4NDJmM2d0NnhxODdxejZrcnNrcWZ6bWY0eXo3OGRkamU5eHE0dnF5ODhyZjUwMjVuenNoc2pkbWcycycsXG4gICAgICAgIH0sXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICB9O1xuICAgICAgY29uc3QgZmFrZVBydiA9IGVuY3J5cHQoJ3Bhc3N3b3JkJywgJ3BydicpO1xuXG4gICAgICBjb25zdCB3YWxsZXRPYmogPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbJ21vY2snXS51cmk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvdGFkYS9rZXkvNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnKVxuICAgICAgICAucmVwbHkoMjAwLCBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBmYWtlUHJ2LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuXG4gICAgICAvLyBNb2NrIHRoZSBBUEkgcmVzcG9uc2UgZm9yIGJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb25zXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YWRhL3dhbGxldC81YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMC9jb25zb2xpZGF0ZUFjY291bnQvYnVpbGQnKVxuICAgICAgICAucmVwbHkoMjAwLCBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHhSZXF1ZXN0SWQ6ICcxYjVjNzljNS1hYjdjLTRmNDctOTEyYi1kZTZhOTVmYjA3NzknLFxuICAgICAgICAgICAgd2FsbGV0SWQ6ICc2NGZhMzFhOTRkYjY1YTAwMDdjOTY5MWInLFxuICAgICAgICAgICAgdHhIZXg6XG4gICAgICAgICAgICAgICc4NGE0MDA4MTgyNTgyMGRiNDZjN2M3NmVhNTRmZWMyY2EwYTJmOTRiNzdhMjM4OTMxYThkY2UyMzg3Yzk5YTEyYjA4ZGQ4YWFjMjFjNGYwMTAxODI4MjU4MWQ2MDMzYzM3OGNlZTQxYjJlMTVhYzg0OGY3ZjZmMWQyZjc4MTU1YWIxMmQ5M2I3MTNkZTg5OGQ4NTVmMWEwMDk4OTY4MDgyNTgzOTAwNDYwMWZjMDE2YWMzODU4MDkxNmQzNTIwYmM3NmI2NTkyOTgxNTYwMDg3MzhkMzQ3YWE5MzE0MmY0NjAxZmMwMTZhYzM4NTgwOTE2ZDM1MjBiYzc2YjY1OTI5ODE1NjAwODczOGQzNDdhYTkzMTQyZjFiMDAwMDAwMDIxN2FjZWJlOTAyMWEwMDAyOGRiNTAzMWEwNjBlM2I0MWEwZjVmNicsXG4gICAgICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgICAgIGZlZTogMTY1NTQ1LFxuICAgICAgICAgICAgICBmZWVTdHJpbmc6ICcxNjU1NDUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgICAgICBtaW5lckZlZTogJzE2NTU0NScsXG4gICAgICAgICAgICAgIHNwZW5kQW1vdW50OiAnOTk5ODM0NDU1JyxcbiAgICAgICAgICAgICAgc3BlbmRBbW91bnRzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgY29pbk5hbWU6ICd0YWRhJyxcbiAgICAgICAgICAgICAgICAgIGFtb3VudFN0cmluZzogJzk5OTgzNDQ1NScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGFkZHJlc3M6XG4gICAgICAgICAgICAgICAgICAgICdhZGRyX3Rlc3QxcXBycXJscXBkdHBjdHF5M2Q1NmpwMHJra2V2am5xMmtxenJuMzU2ODQyZjNndDZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHNqZG1nMnMnLFxuICAgICAgICAgICAgICAgICAgdmFsdWU6IDk5OTgzNDQ1NSxcbiAgICAgICAgICAgICAgICAgIHdhbGxldDogJzY0ZmEzMWE5NGRiNjVhMDAwN2M5NjkxYicsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRzOiBbJzY0ZmEzMWE5NGRiNjVhMDAwN2M5NjkxYiddLFxuICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZTogJzYyY2M1OWI3Mjc0NDNhMDAwNzA4OTAzMycsXG4gICAgICAgICAgICAgICAgICBlbnRlcnByaXNlczogWyc2MmNjNTliNzI3NDQzYTAwMDcwODkwMzMnXSxcbiAgICAgICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnOTk5ODM0NDU1JyxcbiAgICAgICAgICAgICAgICAgIGNvaW5OYW1lOiAndGFkYScsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgICAgIHdhbGxldFR5cGVzOiBbJ2hvdCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIGlucHV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMDAwMDAwLFxuICAgICAgICAgICAgICAgICAgYWRkcmVzczpcbiAgICAgICAgICAgICAgICAgICAgJ2FkZHJfdGVzdDFxcWx6eGZsN3RsZ3A5OTl4NGE3MzM0cGNoeWNwa2s3MnB5a3JzcjNtcnlsM3lqNnhxODdxejZrcnNrcWZ6bWY0eXo3OGRkamU5eHE0dnF5ODhyZjUwMjVuenNoc3ZwZ2w4dycsXG4gICAgICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzEwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHR5cGU6ICcwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhiOWZjMTg1NTgwMDZhYWI1Mzc4NTYxNWZlYTdjMjgnLFxuICAgICAgICAgICAgY29pbjogJ3RhZGEnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuXG4gICAgICAvLyBDYWxsIHRoZSBmdW5jdGlvbiB0byB0ZXN0XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHdhbGxldE9iai5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBtZXNzYWdlOiAndHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIGFkZHJlc3MnLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXhwbGFpbiBUcmFuc2FjdGlvbnM6JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW5lZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiByYXdUeC51bnNpZ25lZFR4MixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgY29uc29sZS5sb2coZXhwbGFpbmVkVHJhbnNhY3Rpb24pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBleHBsYWluIHRyYW5zYWN0aW9uIHdpdGggbWlzc2luZyBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2l0aCB3cm9uZyBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiAnaW52YWxpZFR4SGV4JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNob3VsZC5lcXVhbChlcnJvci5tZXNzYWdlLCAnSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUGFyc2UgUmF3IFRyYW5zYWN0aW9ucycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIHN0YWtpbmcgcGxlZGdlIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJhd1R4LnVuc2lnbmVkTmV3UGxlZGdlVHgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nUGxlZGdlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2Ugc3Rha2luZyBhY3RpdmF0aW9uIHR4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJhd1R4LnVuc2lnbmVkU3Rha2luZ0FjdGl2ZVR4KTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2Ugc3Rha2luZyBkZWFjdGl2YXRpb24gdHgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24ocmF3VHgudW5zaWduZWRTdGFraW5nRGVhY3RpdmVUeCk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdEZWFjdGl2YXRlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1BhcnNlIFRyYW5zYWN0aW9uczonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhbiB1bnNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcnNlZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeDIsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYSBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHJhd1R4LnNpZ25lZFR4MixcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBwYXJzZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHRyYW5zYWN0aW9uRXhwbGFuYXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHBhcnNlIGEgc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uIHdoZW4gZXhwbGFpblRyYW5zYWN0aW9uIHJlc3BvbnNlIGlzIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0dWIgPSBzaW5vbi5zdHViKEFkYS5wcm90b3R5cGUsICdleHBsYWluVHJhbnNhY3Rpb24nKTtcbiAgICAgIHN0dWIucmVzb2x2ZXModW5kZWZpbmVkKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5wYXJzZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogcmF3VHguc2lnbmVkVHgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICAgIHN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUcmFuc2FjdGlvbnM6JywgKCkgPT4ge1xuICAgIGNvbnN0IGRlc3RBZGRyID0gYWRkcmVzcy5hZGRyZXNzMjtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihBZGEucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBBZGEpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCB7XG4gICAgICAgICAgX2FkZHJlc3NlczogW3dyd1VzZXIud2FsbGV0QWRkcmVzczBdLFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc0luZm9SZXNwb25zZS5PbmVVVFhPKTtcbiAgICAgIGNhbGxCYWNrLndpdGhBcmdzKCd0aXAnKS5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy50aXBJbmZvUmVzcG9uc2UpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIGEgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gb3ZjUmVzcG9uc2U7XG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzg0YTQwMDgxODI1ODIwNGJkMGY5OTFjMTUzMmNmZmUzMWQ0YTEwZGI0OTJiNDMxNzVlYzMyNjc2NWI2YjI5Y2VlZTU5OGRmMmI2MWY0NzAwMDE4MTgyNTgzOTAwODczNzllYmM1NTMzZWJlNjIxOTYzYzkxNWMzY2JjNWYwODUzN2ZjZGNhNGFmOGY4YWUwOGVkNGM4NzM3OWViYzU1MzNlYmU2MjE5NjNjOTE1YzNjYmM1ZjA4NTM3ZmNkY2E0YWY4ZjhhZTA4ZWQ0YzFhMDVmMzU5ZmYwMjFhMDAwMjg3MDEwMzFhMDI0OTcyZTFhMTAwODE4MjU4MjBiYmFjYjEzNDMxYjk5MjA4ZTZlOGNkYmY3MTAxNDdmZWFmMDZhMzlkNzE1NjVlNjBiNDExY2U5ZTRmYTNmMTM3NTg0MDAxYTRhYjgyMzY1NjNmNjlmZjMwOWU1Nzg2ZThmMzljNjI5ZWQ1NzY3NmM2OTIxNTljYjJlMDQ5NGM5ZTY2MzM1NTM4NGMxM2M3NDlkMDRjMTdhODBiYTJhNDVjYzEyN2RmNDgwZmM2NGE0MzE5OWE3NzJmMTFhY2Q1YjE0YTBmZjVmNidcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0YWtlIGNvbnNvbGlkYXRpb24gT1ZDIG91dHB1dCBhbmQgZ2VuZXJhdGUgbXVsdGlwbGUgc2lnbmVkIHN3ZWVwIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG92Y1Jlc3BvbnNlMjtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHhuID0gYXdhaXQgYmFzZWNvaW4uY3JlYXRlQnJvYWRjYXN0YWJsZVN3ZWVwVHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnODRhNDAwODE4MjU4MjAzZTYyZTVlZThiMTIwMTJjNGI5NDlmOTc3N2I3MjE2NTIzOWJiMjE0NmFlOGIwNzhiNGQxYzVjYThkMzE2OGUzMDAwMTgxODI1ODM5MDBiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNGJhZjU1ZWJjZjlhZGExYjhlY2IxNjQwODgwZmJhNTRkMjgxNzY5MGYxMmIzYTEwNmFmZDA4MDA0MWEwMDk2MGY3ZjAyMWEwMDAyODcwMTAzMWEwMjUwZjdlYWExMDA4MTgyNTgyMDUwMGUwZDcyNWE1YmEzYTMwNmRhMzUwM2RmZTU3YjhhMTQwNjhhMDliNjFiMzZlYzA2OGZjZjhjZjVjMzkxZGU1ODQwYzgzNmNlNmQzMjYyZDU2NTQ3MDZlYTA2NzIxNTIyZDNiNzVmNmQ1NDUyNDUwNDdhN2JlNzQ2MzYyOWQ4OGIzZjQyNjRiOTk1ZjU5MWRmNTJiZGZmY2YwOWRhMWU2YWI5ZTg4ZGUzNzE0YzZlMmVjMTk2MTc4NmNmMWM1ODZhMDdmNWY2J1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1swXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc4NGE0MDA4MTgyNTgyMDI5YzEwYWNmMGUwOGY5NTIzMzI1Yzg4MjQzNTY1YWY2YjMyMjc0OTkyMTg5YzExNTM5MDNjNDEwYmVkN2MyYzcwMDAxODE4MjU4MzkwMGJhZjU1ZWJjZjlhZGExYjhlY2IxNjQwODgwZmJhNTRkMjgxNzY5MGYxMmIzYTEwNmFmZDA4MDA0YmFmNTVlYmNmOWFkYTFiOGVjYjE2NDA4ODBmYmE1NGQyODE3NjkwZjEyYjNhMTA2YWZkMDgwMDQxYTAwOTYwZjdmMDIxYTAwMDI4NzAxMDMxYTAyNTBmN2VhYTEwMDgxODI1ODIwNjI3NzBiMjI0YmQzMTRiYzUyNmZiZDZhOTRlOTA4MmZiNjQ1OGM0MjVlNmUwOWJhZDc0MDA0ZGQ4OTdlOTYyMzU4NDAzODQyNTQ0ZjJmZjI4YmUwNTRlYjdjNzk5N2JjMzAzYjFlMjUxZWIxM2E0MTgwMmM4MjMxOGU1OTJiYjI0ZWFhMzE5N2M0NTBlNzk3Y2M4NTU5ZjAzNTZjZDVjZGQxYWI1ZWI4MGM1MTczZTM0ZTllMWQxNzM3NTMzYTg5NTIwY2Y1ZjYnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzFdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMl0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzg0YTQwMDgxODI1ODIwZGQxNDBmMTMzZDg2NWUxYmI1NjQyZTcwOGZlNjg1YmY3NjAxZDcxZDBjOTk1MTFlNWQ1NTJkYTdmOGJkMTBmZjAwMDE4MTgyNTgzOTAwYmFmNTVlYmNmOWFkYTFiOGVjYjE2NDA4ODBmYmE1NGQyODE3NjkwZjEyYjNhMTA2YWZkMDgwMDRiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNDFhMDA5NjBmN2YwMjFhMDAwMjg3MDEwMzFhMDI1MGY3ZWFhMTAwODE4MjU4MjA1M2I0YmI3NGFhMzhhZGQ0NThkYWZjODE1M2YwYWE4MjY2YWNhZDU5MzIyYjg3N2NhOWMyM2M1ZDM4NzM3NzlkNTg0MGU5NGNlNzg5Njk1N2QwOTRjNmJhZmJmMmVjMTBkZjVlYmIwZjFkMmEyN2E3ZTMxZjJkNDVjNTMxZmI2ODdlZGQ2YzRkMzNmOGU5Yjk5Yzc2OTJiNmZhYzZkODM5OWJkOGZkNDc2NDFiYWFlOWJiYjY5ZjUxOGQ0MmFkMTE3MTBhZjVmNidcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMl0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgzKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1szXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnODRhNDAwODE4MjU4MjAxNWExZDZkYjVkM2Y1OTJhYTFjZGExODViNjM1OWNhMGUyOTIxYzNjNTE5NTlmNjQyMjJhNmI3ZDk1ZDMzOTIzMDAwMTgxODI1ODM5MDBiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNGJhZjU1ZWJjZjlhZGExYjhlY2IxNjQwODgwZmJhNTRkMjgxNzY5MGYxMmIzYTEwNmFmZDA4MDA0MWEwMDk2MGY3ZjAyMWEwMDAyODcwMTAzMWEwMjUwZjdlYWExMDA4MTgyNTgyMDYwMGY4NmNhMjJkNjcwZjBhOTkwYWRlNGU4ODJjMDVlNjU0MzQzMjYzNDk0NzM1YTMxNTE3ZGUwODE5Njc2NzM1ODQwZmUxOTlmOGUyNDdhNGNmYWJmZWI0ZjljYjU3NGFhMzU3MzlhMGFhOTg4NjBlZTBhODVkNzIwYzRhYjRmZWNmYWM3YjQ1MDRkZjMxMGIzZTRiZWEwNDcxMWY2MDY1MmQ0YThjZjVlYjQxODE3MjkzYjhkMjk5NzdmZTY5NWY3MDRmNWY2J1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1szXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDQpO1xuICAgICAgcmVjb3ZlcnlUeG4ubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciBub24tYml0Z28gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB3cndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogd3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUd2ljZShiYXNlY29pbi5nZXREYXRhRnJvbU5vZGUpO1xuXG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24ocmVzLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIGNvbnN0IGZlZSA9IE51bWJlcih0eC5leHBsYWluVHJhbnNhY3Rpb24oKS5mZWUuZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1swXS50cmFuc2FjdGlvbl9pZCwgdGVzdG5ldFVUWE8uVVRYT18xLnR4X2hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2luZGV4LCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaW5kZXgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ub3V0cHV0c1swXS5hZGRyZXNzLCBkZXN0QWRkcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKE51bWJlcih0eEpzb24ub3V0cHV0c1swXS5hbW91bnQpICsgZmVlLCB0ZXN0bmV0VVRYTy5VVFhPXzEudmFsdWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciB1bnNpZ25lZCBzd2VlcCByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUd2ljZShiYXNlY29pbi5nZXREYXRhRnJvbU5vZGUpO1xuXG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24ocmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgZmVlID0gTnVtYmVyKHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpLmZlZS5mZWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2lkLCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5vdXRwdXRzWzBdLmFkZHJlc3MsIGRlc3RBZGRyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwoTnVtYmVyKHR4SnNvbi5vdXRwdXRzWzBdLmFtb3VudCkgKyBmZWUsIHRlc3RuZXRVVFhPLlVUWE9fMS52YWx1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9ucyBNdWx0aXBsZSBVVFhPOicsICgpID0+IHtcbiAgICBjb25zdCBkZXN0QWRkciA9IGFkZHJlc3MuYWRkcmVzczI7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY2FsbEJhY2sgPSBzYW5kQm94LnN0dWIoQWRhLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgQWRhKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncygnYWRkcmVzc19pbmZvJywge1xuICAgICAgICAgIF9hZGRyZXNzZXM6IFt3cndVc2VyLndhbGxldEFkZHJlc3MwXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuVHdvVVRYTyk7XG4gICAgICBjYWxsQmFjay53aXRoQXJncygndGlwJykucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMudGlwSW5mb1Jlc3BvbnNlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3Igbm9uLWJpdGdvIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogd3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHdyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcblxuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJlcy5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBjb25zdCBmZWUgPSBOdW1iZXIodHguZXhwbGFpblRyYW5zYWN0aW9uKCkuZmVlLmZlZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1swXS50cmFuc2FjdGlvbl9pbmRleCwgdGVzdG5ldFVUWE8uVVRYT18xLnR4X2luZGV4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1sxXS50cmFuc2FjdGlvbl9pZCwgdGVzdG5ldFVUWE8uVVRYT18yLnR4X2hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzFdLnRyYW5zYWN0aW9uX2luZGV4LCB0ZXN0bmV0VVRYTy5VVFhPXzIudHhfaW5kZXgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ub3V0cHV0c1swXS5hZGRyZXNzLCBkZXN0QWRkcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKE51bWJlcih0eEpzb24ub3V0cHV0c1swXS5hbW91bnQpICsgZmVlLCB0ZXN0bmV0VVRYTy5VVFhPXzEudmFsdWUgKyB0ZXN0bmV0VVRYTy5VVFhPXzIudmFsdWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIGEgdHhuIGZvciB1bnNpZ25lZCBzd2VlcCByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUd2ljZShiYXNlY29pbi5nZXREYXRhRnJvbU5vZGUpO1xuXG4gICAgICBjb25zdCB0eCA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eC5mcm9tUmF3VHJhbnNhY3Rpb24ocmVzLnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgZmVlID0gTnVtYmVyKHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpLmZlZS5mZWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2lkLCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMV0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMi50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1sxXS50cmFuc2FjdGlvbl9pbmRleCwgdGVzdG5ldFVUWE8uVVRYT18yLnR4X2luZGV4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLm91dHB1dHNbMF0uYWRkcmVzcywgZGVzdEFkZHIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChOdW1iZXIodHhKc29uLm91dHB1dHNbMF0uYW1vdW50KSArIGZlZSwgdGVzdG5ldFVUWE8uVVRYT18xLnZhbHVlICsgdGVzdG5ldFVUWE8uVVRYT18yLnZhbHVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0J1aWxkIENvbnNvbGlkYXRpb24gUmVjb3ZlcmllczonLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZUFkZHIgPSBjb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMDtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihBZGEucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBBZGEpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCB7XG4gICAgICAgICAgX2FkZHJlc3NlczogW2NvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MxXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuWmVyb1VUWE8pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCB7XG4gICAgICAgICAgX2FkZHJlc3NlczogW2NvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MyXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuT25lVVRYTyk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3MoJ2FkZHJlc3NfaW5mbycsIHtcbiAgICAgICAgICBfYWRkcmVzc2VzOiBbY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczNdLFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc0luZm9SZXNwb25zZS5PbmVVVFhPMik7XG4gICAgICBjYWxsQmFjay53aXRoQXJncygndGlwJykucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMudGlwSW5mb1Jlc3BvbnNlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgc2lnbmVkIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgIHVzZXJLZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGNvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDQsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHJhbnNhY3Rpb25zLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICByZXMubGFzdFNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICBjb25zdCB0eG4xID0gcmVzLnRyYW5zYWN0aW9uc1swXTtcbiAgICAgIGNvbnN0IHR4MSA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eDEuZnJvbVJhd1RyYW5zYWN0aW9uKHR4bjEuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbjEgPSB0eDEudG9Kc29uKCk7XG4gICAgICBjb25zdCBmZWUxID0gTnVtYmVyKHR4MS5leHBsYWluVHJhbnNhY3Rpb24oKS5mZWUuZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5pbnB1dHNbMF0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMS5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEub3V0cHV0c1swXS5hZGRyZXNzLCBiYXNlQWRkcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKE51bWJlcih0eEpzb24xLm91dHB1dHNbMF0uYW1vdW50KSArIGZlZTEsIHRlc3RuZXRVVFhPLlVUWE9fMS52YWx1ZSk7XG5cbiAgICAgIGNvbnN0IHR4bjIgPSByZXMudHJhbnNhY3Rpb25zWzFdO1xuICAgICAgY29uc3QgdHgyID0gbmV3IFRyYW5zYWN0aW9uKGJhc2Vjb2luKTtcbiAgICAgIHR4Mi5mcm9tUmF3VHJhbnNhY3Rpb24odHhuMi5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdHhKc29uMiA9IHR4Mi50b0pzb24oKTtcbiAgICAgIGNvbnN0IGZlZTIgPSBOdW1iZXIodHgyLmV4cGxhaW5UcmFuc2FjdGlvbigpLmZlZS5mZWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmlucHV0c1swXS50cmFuc2FjdGlvbl9pZCwgdGVzdG5ldFVUWE8uVVRYT18yLnR4X2hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24yLmlucHV0c1swXS50cmFuc2FjdGlvbl9pbmRleCwgdGVzdG5ldFVUWE8uVVRYT18yLnR4X2luZGV4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5vdXRwdXRzWzBdLmFkZHJlc3MsIGJhc2VBZGRyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwoTnVtYmVyKHR4SnNvbjIub3V0cHV0c1swXS5hbW91bnQpICsgZmVlMiwgdGVzdG5ldFVUWE8uVVRYT18yLnZhbHVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2tpcCBidWlsZGluZyBjb25zb2xpZGF0ZSB0cmFuc2FjdGlvbiBpZiBiYWxhbmNlIGlzIGVxdWFsIHRvIHplcm8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBjb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ0RpZCBub3QgZmluZCBhbiBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBzdGFydGluZ1NjYW5JbmRleCBpcyBub3QgZ2UgdG8gMScsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICAgIHVzZXJLZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAtMSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IC0xLCBlbmRpbmdTY2FuSW5kZXg6IDE5LidcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgc2NhbiBmYWN0b3IgaXMgdG9vIGhpZ2gnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDMwMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6IDEsIGVuZGluZ1NjYW5JbmRleDogMzAwLidcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgVHJhbnNhY3Rpb25zIEZhaWx1cmU6JywgKCkgPT4ge1xuICAgIGNvbnN0IGRlc3RBZGRyID0gYWRkcmVzcy5hZGRyZXNzMjtcbiAgICBjb25zdCBzYW5kQm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRCb3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHJlY292ZXIgZHVlIHRvIG5vdCBmaW5kaW5nIGFuIGFkZHJlc3Mgd2l0aCBmdW5kcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNhbGxCYWNrID0gc2FuZEJveC5zdHViKEFkYS5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIEFkYSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3MoJ2FkZHJlc3NfaW5mbycsIHNpbm9uLm1hdGNoLmhhcygnX2FkZHJlc3NlcycpKVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc0luZm9SZXNwb25zZS5aZXJvVVRYTyk7XG4gICAgICBjYWxsQmFjay53aXRoQXJncygndGlwJykucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMudGlwSW5mb1Jlc3BvbnNlKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB3cndVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdEFkZHIsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdEaWQgbm90IGZpbmQgYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byByZWNvdmVyIGR1ZSB0byBub3QgaGF2aW5nIG1vcmUgdGhhbiAxIEFEQSBpbiBmdW5kcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNhbGxCYWNrID0gc2FuZEJveC5zdHViKEFkYS5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIEFkYSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3MoJ2FkZHJlc3NfaW5mbycsIHNpbm9uLm1hdGNoLmhhcygnX2FkZHJlc3NlcycpKVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc0luZm9SZXNwb25zZS5PbmVTbWFsbFVUWE8pO1xuICAgICAgY2FsbEJhY2sud2l0aEFyZ3MoJ3RpcCcpLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLnRpcEluZm9SZXNwb25zZSk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogd3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogd3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnSW5zdWZmaWNpZW50IGZ1bmRzIHRvIHJlY292ZXIsIG1pbmltdW0gcmVxdWlyZWQgaXMgMSBBREEgcGx1cyBmZWVzLCBnb3QgOTgzNDQ1NSBmZWVzOiAxNjU1NDUnXG4gICAgICAgICk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRUd2ljZShiYXNlY29pbi5nZXREYXRhRnJvbU5vZGUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVmVyaWZ5IHdhbGxldCBhZGRyZXNzIChpc1dhbGxldEFkZHJlc3MpOicsICgpID0+IHtcbiAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAnZWQzMTJkMGRiNDYxNTY4ODIxOWM0MzIzMWViNGI5OGQ1ODgzYzBiNDRiY2ZlZjE5NTYyOTA1NTU5OTVhZDY4ZWY3YzIyOTE3YjRhOGI2OTE4Mzg2NGI4M2NjNzAyODY1NWNkN2E3MGVmNzZkNjk0OGQ4MDlhMTUwNTAwNTQ4NDAnO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB2YWxpZCB3YWxsZXQgYWRkcmVzcyBhdCBpbmRleCAwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgYWRkcmVzcyA9XG4gICAgICAgICdhZGRyX3Rlc3QxcXp2bWF6bXBnZmhqeXBwd2xzdzI5empqd2F6Y3NmazYyejl6djV2c3YyNHAwd3llaDY5a3pzbjB5Z3p6YWxxdTUyOTl5YTY5M3FuZDU1eTJ5ZWdlcWM0Mno3dXEwZ2UycHEnO1xuICAgICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgIGFkZHJlc3MsXG4gICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgaW5kZXg6IDAsXG4gICAgICB9KTtcblxuICAgICAgaXNWYWxpZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGFuIGFkZHJlc3Mgd2l0aCB3cm9uZyBpbmRleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInIGFzIGNvbnN0LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyBhcyBjb25zdCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyBhcyBjb25zdCxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IGlzVmFsaWQgPSBhd2FpdCBiYXNlY29pbi5pc1dhbGxldEFkZHJlc3Moe1xuICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICdhZGRyX3Rlc3QxcXp2bWF6bXBnZmhqeXBwd2xzdzI5empqd2F6Y3NmazYyejl6djV2c3YyNHAwd3llaDY5a3pzbjB5Z3p6YWxxdTUyOTl5YTY5M3FuZDU1eTJ5ZWdlcWM0Mno3dXEwZ2UycHEnLFxuICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgIGluZGV4OiAyLFxuICAgICAgfSk7XG5cbiAgICAgIGlzVmFsaWQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgYSByYW5kb20gYWRkcmVzcyBub3QgZnJvbSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyBhcyBjb25zdCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcgYXMgY29uc3QsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycgYXMgY29uc3QsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICAvLyBVc2UgYSByYW5kb20gdmFsaWQgQURBIGFkZHJlc3Mgbm90IGZyb20gdGhpcyB3YWxsZXRcbiAgICAgIGNvbnN0IHJhbmRvbUFkZHJlc3MgPSAnYWRkcl90ZXN0MXZyOHJha202NnJjZnY0ZmN4cXlrZzVsZjB5djdsc3lrOW12YXB4MzY5anB2dGNnZmN1azdmJztcblxuICAgICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IGJhc2Vjb2luLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgIGFkZHJlc3M6IHJhbmRvbUFkZHJlc3MsXG4gICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgaW5kZXg6IDAsXG4gICAgICB9KTtcblxuICAgICAgaXNWYWxpZC5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInIGFzIGNvbnN0LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyBhcyBjb25zdCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyBhcyBjb25zdCxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IGludmFsaWRBZGRyZXNzID0gJ25vdF9hX3ZhbGlkX2FkZHJlc3MnO1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuaXNXYWxsZXRBZGRyZXNzKHtcbiAgICAgICAgICBhZGRyZXNzOiBpbnZhbGlkQWRkcmVzcyxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIENhcmRhbm8gQWRkcmVzczogbm90X2FfdmFsaWRfYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGtleWNoYWlucyBhcmUgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPVxuICAgICAgICAnYWRkcl90ZXN0MXF6dm1hem1wZ2ZoanlwcHdsc3cyOXpqandhemNzZms2Mno5enY1dnN2MjRwMHd5ZWg2OWt6c24weWd6emFscXU1Mjk5eWE2OTNxbmQ1NXkyeWVnZXFjNDJ6N3VxMGdlMnBxJztcblxuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgICAgYWRkcmVzcyxcbiAgICAgICAgICBrZXljaGFpbnM6IFtdLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBrZXljaGFpbnMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyBhcyBjb25zdCxcbiAgICAgICAgICAvLyBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBhZGRyZXNzID1cbiAgICAgICAgJ2FkZHJfdGVzdDFxenZtYXptcGdmaGp5cHB3bHN3Mjl6amp3YXpjc2ZrNjJ6OXp2NXZzdjI0cDB3eWVoNjlrenNuMHlnenphbHF1NTI5OXlhNjkzcW5kNTV5MnllZ2VxYzQyejd1cTBnZTJwcSc7XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5pc1dhbGxldEFkZHJlc3Moe1xuICAgICAgICAgIGFkZHJlc3MsXG4gICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBjb21tb25LZXljaGFpbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGtleWNoYWlucyBoYXZlIG1pc21hdGNoZWQgY29tbW9uS2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgICAgc291cmNlOiAndXNlcicgYXMgY29uc3QsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAnZGlmZmVyZW50S2V5Y2hhaW4xMjM0NTY3ODkwYWJjZGVmMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3ODkwYWJjZGVmJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnIGFzIGNvbnN0LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgYWRkcmVzcyA9XG4gICAgICAgICdhZGRyX3Rlc3QxcXp2bWF6bXBnZmhqeXBwd2xzdzI5empqd2F6Y3NmazYyejl6djV2c3YyNHAwd3llaDY5a3pzbjB5Z3p6YWxxdTUyOTl5YTY5M3FuZDU1eTJ5ZWdlcWM0Mno3dXEwZ2UycHEnO1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuaXNXYWxsZXRBZGRyZXNzKHtcbiAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2FsbCBrZXljaGFpbnMgbXVzdCBoYXZlIHRoZSBzYW1lIGNvbW1vbktleWNoYWluIGZvciBNUEMgY29pbnMnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0b2tlbiBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgc3Bvb2ZlZCB0b2tlbiBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHdpdGggaW5jb3JyZWN0IGFkZHJlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmZkNGIwZmE2ZCcsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICc4NGE0MDA4MTgyNTgyMDRiZDBmOTkxYzE1MzJjZmZlMzFkNGExMGRiNDkyYjQzMTc1ZWMzMjY3NjViNmIyOWNlZWU1OThkZjJiNjFmNDcwMDAxODE4MjU4MzkwMDg3Mzc5ZWJjNTUzM2ViZTYyMTk2M2M5MTVjM2NiYzVmMDg1MzdmY2RjYTRhZjhmOGFlMDhlZDRjODczNzllYmM1NTMzZWJlNjIxOTYzYzkxNWMzY2JjNWYwODUzN2ZjZGNhNGFmOGY4YWUwOGVkNGMxYTA1ZjM1OWZmMDIxYTAwMDI4NzAxMDMxYTAyNDk3MmUxYTEwMDgxODI1ODIwYmJhY2IxMzQzMWI5OTIwOGU2ZThjZGJmNzEwMTQ3ZmVhZjA2YTM5ZDcxNTY1ZTYwYjQxMWNlOWU0ZmEzZjEzNzU4NDAwMWE0YWI4MjM2NTYzZjY5ZmYzMDllNTc4NmU4ZjM5YzYyOWVkNTc2NzZjNjkyMTU5Y2IyZTA0OTRjOWU2NjMzNTUzODRjMTNjNzQ5ZDA0YzE3YTgwYmEyYTQ1Y2MxMjdkZjQ4MGZjNjRhNDMxOTlhNzcyZjExYWNkNWIxNGEwZmY1ZjYnLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAxMDAwMCxcbiAgICAgICAgICBmZWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgIGlucHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnOGlMYTI2S1NiZHBCVXpOSzd1WXE4RnZ5dXlBNWg0azRlckRIc0RjUGJIdXMnLFxuICAgICAgICAgICAgICB2YWx1ZTogMi4wMTczMjI4ZTEwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICc4UDJrWDdUeWg5ZVMzUktkYUJocWJFdFFHQVg1OERYekw3bWhEUUFCR1gyZCcsXG4gICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgbWluZXJGZWU6ICcxMDAwMCcsXG4gICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnYWRkcl90ZXN0MXZyOHJha202NnJjZnY0ZmN4cXlrZzVsZjB5djdsc3lrOW12YXB4MzY5anB2dGNnZmN1azdmJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0YWRhOnVzZHQnLFxuICAgICAgICAgICAgICBlbnRlcnByaXNlOiB7XG4gICAgICAgICAgICAgICAgJG9pZDogJzU1NTNiYThhZTdhNWM3NzAwNjcxOTY2MScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVudGVycHJpc2VzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgJG9pZDogJzU1NTNiYThhZTdhNWM3NzAwNjcxOTY2MScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgdmFsdWU6IDIuMDE3MzIyOGUxMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICAgIHdhbGxldDoge1xuICAgICAgICAgICAgICAgICRvaWQ6ICc2MmY0YzM3MjBkOTJjNTAwMDgyNTdlYjUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgd2FsbGV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICRvaWQ6ICc2MmY0YzM3MjBkOTJjNTAwMDgyNTdlYjUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICBzcGVuZEFtb3VudDogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICBzcGVuZEFtb3VudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYW1vdW50U3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgICBjb2luTmFtZTogJ3RhZGE6dXNkdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICB9LFxuICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjcxMmQ3ZmRhNmRlNDkwNmQ2NThjMDRhZWJiZjhmOWInLFxuICAgICAgICBjb2luOiAndGFkYScsXG4gICAgICB9O1xuXG4gICAgICAvLyBNb2NrIHRoZSB3YWxsZXQgd2l0aCBhIGRpZmZlcmVudCBhZGRyZXNzIHRoYW4gdGhlIHRyYW5zYWN0aW9uJ3Mgb3V0cHV0XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByb290QWRkcmVzczpcbiAgICAgICAgICAgICAgJ2FkZHJfdGVzdDFxcW5udnB0cmMzcmVjNjRxMm45amg1NzJuY3U1d3ZkdHQ4dXZnNGczYWo5NnM1ZHd1OW5qNzBtbGFoemdsbTk5Mzl1ZXZ1cHNtajhkY2RxdjI1ZDVuNXI4dnc4c243cHJleScsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IGNvbnNvbGlkYXRpb25UeCxcbiAgICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0eCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgYWRkcmVzcycpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|