@bitgo-beta/sdk-coin-avaxc 2.2.3-alpha.44 → 2.2.3-alpha.441
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/avaxc.d.ts +46 -17
- package/dist/src/avaxc.d.ts.map +1 -1
- package/dist/src/avaxc.js +221 -86
- package/dist/src/avaxcToken.d.ts +1 -1
- package/dist/src/avaxcToken.d.ts.map +1 -1
- package/dist/src/avaxcToken.js +3 -3
- package/dist/src/iface.d.ts +6 -3
- package/dist/src/iface.d.ts.map +1 -1
- package/dist/src/iface.js +1 -1
- package/dist/src/index.js +6 -2
- package/dist/src/lib/index.js +23 -9
- package/dist/src/lib/keyPair.js +10 -11
- package/dist/src/lib/transactionBuilder.js +2 -2
- package/dist/src/lib/utils.d.ts +2 -1
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +31 -10
- package/dist/test/resources/avaxc.d.ts +122 -0
- package/dist/test/resources/avaxc.d.ts.map +1 -0
- package/dist/test/resources/avaxc.js +137 -0
- package/dist/test/unit/avaxc.d.ts +2 -0
- package/dist/test/unit/avaxc.d.ts.map +1 -0
- package/dist/test/unit/avaxc.js +1104 -0
- package/dist/test/unit/avaxcToken.d.ts +2 -0
- package/dist/test/unit/avaxcToken.d.ts.map +1 -0
- package/dist/test/unit/avaxcToken.js +68 -0
- package/dist/test/unit/getBuilder.d.ts +3 -0
- package/dist/test/unit/getBuilder.d.ts.map +1 -0
- package/dist/test/unit/getBuilder.js +10 -0
- package/dist/test/unit/helpers.d.ts +15 -0
- package/dist/test/unit/helpers.d.ts.map +1 -0
- package/dist/test/unit/helpers.js +54 -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 +135 -0
- package/dist/test/unit/transactionBuilder/transfer.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transfer.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transfer.js +223 -0
- package/dist/test/unit/transactionBuilder/walletInitializationBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/walletInitializationBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/walletInitializationBuilder.js +174 -0
- package/dist/test/unit/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transferBuilder.js +119 -0
- package/dist/test/unit/util.d.ts +2 -0
- package/dist/test/unit/util.d.ts.map +1 -0
- package/dist/test/unit/util.js +235 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +22 -16
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -135
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const sdk_test_1 = require("@bitgo-beta/sdk-test");
|
|
37
|
+
const sdk_api_1 = require("@bitgo-beta/sdk-api");
|
|
38
|
+
const src_1 = require("../../src");
|
|
39
|
+
const getBuilder_1 = require("./getBuilder");
|
|
40
|
+
const secp256k1 = __importStar(require("secp256k1"));
|
|
41
|
+
const secp256k1_1 = require("@bitgo-beta/secp256k1");
|
|
42
|
+
const nock = __importStar(require("nock"));
|
|
43
|
+
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
44
|
+
const sdk_coin_eth_1 = require("@bitgo-beta/sdk-coin-eth");
|
|
45
|
+
const should = __importStar(require("should"));
|
|
46
|
+
const avaxc_1 = require("../resources/avaxc");
|
|
47
|
+
const sdk_coin_avaxp_1 = require("@bitgo-beta/sdk-coin-avaxp");
|
|
48
|
+
const helpers_1 = require("./helpers");
|
|
49
|
+
const sinon = __importStar(require("sinon"));
|
|
50
|
+
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
51
|
+
nock.enableNetConnect();
|
|
52
|
+
describe('Avalanche C-Chain', function () {
|
|
53
|
+
let bitgo;
|
|
54
|
+
let tavaxCoin;
|
|
55
|
+
let avaxCoin;
|
|
56
|
+
let hopTxBitgoSignature;
|
|
57
|
+
let hopExportTxBitgoSignature;
|
|
58
|
+
const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
|
|
59
|
+
const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
|
|
60
|
+
const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
|
|
61
|
+
const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
|
|
62
|
+
const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
|
|
63
|
+
const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
|
|
64
|
+
const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
|
|
65
|
+
const hopExportTx = '0x000000000001000000057fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d50000000000000000000000000000000000000000000000000000000000000000000000011fe3de7886be9e53072d6762e9fa1fc27dddfb0500000000061465b23d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa000000070000000006052340000000000000000000000002000000038b2ce3381003fdf86900280a4ec86b384b5d5c99b7fc1f65220b9a0b2f431578b8bb6ee130bf563af1fab1503135fbd423e442d5e9b73abd5622fe02000000010000000900000001af20066197fa3b72bea3d7cc503c60918c098378b958fbb5da8c6f438d0f4e380e506bb2c38dc88dd97c81e982706c48623937c2fe22b31248ed9fd34951480b0173b4e9ca';
|
|
66
|
+
const hopExportTxId = '0xc4b5ca6e7d8c9c24bb9934afcb5c87e6db472dbe31111b778445f8f9c5352966';
|
|
67
|
+
before(function () {
|
|
68
|
+
const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
|
|
69
|
+
const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
|
|
70
|
+
if (!bitgoKey.privateKey) {
|
|
71
|
+
throw new Error('no privateKey');
|
|
72
|
+
}
|
|
73
|
+
const bitgoXpub = bitgoKey.neutered().toBase58();
|
|
74
|
+
hopTxBitgoSignature =
|
|
75
|
+
'0xaa' +
|
|
76
|
+
Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
|
|
77
|
+
hopExportTxBitgoSignature =
|
|
78
|
+
'0xaa' +
|
|
79
|
+
Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopExportTxId.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
|
|
80
|
+
const env = 'test';
|
|
81
|
+
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
|
|
82
|
+
bitgo.safeRegister('avaxc', src_1.AvaxC.createInstance);
|
|
83
|
+
bitgo.safeRegister('tavaxc', src_1.TavaxC.createInstance);
|
|
84
|
+
bitgo.safeRegister('teth', sdk_coin_eth_1.Eth.createInstance);
|
|
85
|
+
bitgo.safeRegister('tavaxp', sdk_coin_avaxp_1.TavaxP.createInstance);
|
|
86
|
+
sdk_core_1.common.Environments[bitgo.getEnv()].hsmXpub = bitgoXpub;
|
|
87
|
+
bitgo.initializeTestVars();
|
|
88
|
+
});
|
|
89
|
+
beforeEach(() => {
|
|
90
|
+
tavaxCoin = bitgo.coin('tavaxc');
|
|
91
|
+
avaxCoin = bitgo.coin('avaxc');
|
|
92
|
+
});
|
|
93
|
+
after(function () {
|
|
94
|
+
nock.cleanAll();
|
|
95
|
+
});
|
|
96
|
+
describe('Instantiate & Statics', () => {
|
|
97
|
+
it('should instantiate the coin', function () {
|
|
98
|
+
let localBasecoin = bitgo.coin('tavaxc');
|
|
99
|
+
localBasecoin.should.be.an.instanceof(src_1.TavaxC);
|
|
100
|
+
localBasecoin = bitgo.coin('avaxc');
|
|
101
|
+
localBasecoin.should.be.an.instanceof(src_1.AvaxC);
|
|
102
|
+
});
|
|
103
|
+
it('should get hop digest', () => {
|
|
104
|
+
const digest = src_1.AvaxC.getHopDigest(['1', '2', '3']);
|
|
105
|
+
digest.toString('hex').should.equal('231cda5f050c841322b9df536afb633ca062400a8f393bf654a48bdd1dfd825b');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('KeyPair', () => {
|
|
109
|
+
it('should generate tavax keyPair without aguments', () => {
|
|
110
|
+
const kp = tavaxCoin.generateKeyPair();
|
|
111
|
+
kp.should.have.property('prv');
|
|
112
|
+
kp.should.have.property('pub');
|
|
113
|
+
});
|
|
114
|
+
it('should generate avax keyPair without aguments', () => {
|
|
115
|
+
const kp = avaxCoin.generateKeyPair();
|
|
116
|
+
kp.should.have.property('prv');
|
|
117
|
+
kp.should.have.property('pub');
|
|
118
|
+
});
|
|
119
|
+
it('should generate avax keyPair from seed', () => {
|
|
120
|
+
const seed = '4b3b89f6ca897cb729d2146913877f71';
|
|
121
|
+
const tAvaxKeyPair = tavaxCoin.generateKeyPair(Buffer.from(seed, 'hex'));
|
|
122
|
+
const avaxKeyPair = avaxCoin.generateKeyPair(Buffer.from(seed, 'hex'));
|
|
123
|
+
tAvaxKeyPair.should.have.property('prv');
|
|
124
|
+
tAvaxKeyPair.should.have.property('pub');
|
|
125
|
+
tAvaxKeyPair.prv.should.equals('xprv9s21ZrQH143K2MJE1yvV8UhjfLQcaDPPipMYvfYjrPbHLptLsnt1FbbCrCT9E5LCmRrS593YZ1CKgf3rf3C2hYTynZN5au3VvBvLcWh8sV2');
|
|
126
|
+
tAvaxKeyPair.pub.should.equals('xpub661MyMwAqRbcEqNh81TVVceUDNF6yg7F63H9j3xMQj8GDdDVRLCFoPughSdgGs4X1n89iPXFKPMy3f45Y7E63kXGAZKuZ1fhLqsKtkoB3yZ');
|
|
127
|
+
tAvaxKeyPair.should.deepEqual(avaxKeyPair);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('keys validations success cases', () => {
|
|
131
|
+
it('validate valid eth uncompressed public key', () => {
|
|
132
|
+
const uncompressedPublicKey = '043BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E227874E8075353564D83047566EEA6CF5A7313816AF004DDA8CA529DE8C94BC6A';
|
|
133
|
+
tavaxCoin.isValidPub(uncompressedPublicKey).should.be.true();
|
|
134
|
+
avaxCoin.isValidPub(uncompressedPublicKey).should.be.true();
|
|
135
|
+
});
|
|
136
|
+
it('validate valid eth compressed public key', () => {
|
|
137
|
+
const compressedPublicKey = '023BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E2';
|
|
138
|
+
tavaxCoin.isValidPub(compressedPublicKey).should.be.true();
|
|
139
|
+
avaxCoin.isValidPub(compressedPublicKey).should.be.true();
|
|
140
|
+
});
|
|
141
|
+
it('validate valid extended public key', () => {
|
|
142
|
+
const extendedPublicKey = 'xpub661MyMwAqRbcEqNh81TVVceUDNF6yg7F63H9j3xMQj8GDdDVRLCFoPughSdgGs4X1n89iPXFKPMy3f45Y7E63kXGAZKuZ1fhLqsKtkoB3yZ';
|
|
143
|
+
tavaxCoin.isValidPub(extendedPublicKey).should.be.true();
|
|
144
|
+
avaxCoin.isValidPub(extendedPublicKey).should.be.true();
|
|
145
|
+
});
|
|
146
|
+
it('validate valid eth address', () => {
|
|
147
|
+
const address = '0x1374a2046661f914d1687d85dbbceb9ac7910a29';
|
|
148
|
+
tavaxCoin.isValidAddress(address).should.be.true();
|
|
149
|
+
avaxCoin.isValidAddress(address).should.be.true();
|
|
150
|
+
});
|
|
151
|
+
it('should validate an array of p-chain addresses', function () {
|
|
152
|
+
const address = [
|
|
153
|
+
'P-fuji15x3z4rvk8e7vwa6g9lkyg89v5dwknp44858uex',
|
|
154
|
+
'P-avax143q8lsy3y4ke9d6zeltre8u2ateed6uk9ka0nu',
|
|
155
|
+
'NodeID-143q8lsy3y4ke9d6zeltre8u2ateed6uk9ka0nu',
|
|
156
|
+
];
|
|
157
|
+
tavaxCoin.isValidAddress(address).should.be.true();
|
|
158
|
+
avaxCoin.isValidAddress(address).should.be.true();
|
|
159
|
+
});
|
|
160
|
+
it('should validate a p-chain multsig address string', function () {
|
|
161
|
+
const address = 'P-fuji1yzpfsdalhfwkq2ceewgs9wv7k0uft40ydpuj59~P-fuji103cmntssp6qnucejahddy42wcy4qty0uj42822~P-fuji1hdk7ntw0huhqmlhlheme9t7scsy9lhfhw3ywy4';
|
|
162
|
+
tavaxCoin.isValidAddress(address).should.be.true();
|
|
163
|
+
avaxCoin.isValidAddress(address).should.be.true();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
describe('keys validations failure cases', () => {
|
|
167
|
+
it('validate empty eth public key', () => {
|
|
168
|
+
tavaxCoin.isValidPub('').should.be.false();
|
|
169
|
+
avaxCoin.isValidPub('').should.be.false();
|
|
170
|
+
tavaxCoin.isValidPub(undefined).should.be.false();
|
|
171
|
+
avaxCoin.isValidPub(undefined).should.be.false();
|
|
172
|
+
});
|
|
173
|
+
it('validate empty eth address', () => {
|
|
174
|
+
tavaxCoin.isValidAddress(undefined).should.be.false();
|
|
175
|
+
avaxCoin.isValidAddress(undefined).should.be.false();
|
|
176
|
+
});
|
|
177
|
+
it('validate eth uncompressed public key too short', () => {
|
|
178
|
+
const uncompressedPublicKey = '043BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E227874E8075353564D83047566EEA6CF5A7313816AF004DDA8CA529DE8C94BC6A';
|
|
179
|
+
tavaxCoin.isValidPub(uncompressedPublicKey.slice(1)).should.be.false();
|
|
180
|
+
avaxCoin.isValidPub(uncompressedPublicKey.slice(1)).should.be.false();
|
|
181
|
+
});
|
|
182
|
+
it('validate eth compressed public key too short', () => {
|
|
183
|
+
const compressedPublicKey = '023BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E2';
|
|
184
|
+
tavaxCoin.isValidPub(compressedPublicKey.slice(1)).should.be.false();
|
|
185
|
+
avaxCoin.isValidPub(compressedPublicKey.slice(1)).should.be.false();
|
|
186
|
+
});
|
|
187
|
+
it('validate invalid extended private key', () => {
|
|
188
|
+
const extendedPublicKey = 'xpub661MyMwAqRbcEqNh81TVVceUDNF6yg7F63H9j3xMQj8GDdDVRLCFoPughSdgGs4X1n89iPXFKPMy3f45Y7E63kXGAZKuZ1fhLqsKtkoB3yZ';
|
|
189
|
+
tavaxCoin.isValidPub(extendedPublicKey.substr(0, extendedPublicKey.length - 1)).should.be.false();
|
|
190
|
+
avaxCoin.isValidPub(extendedPublicKey.substr(0, extendedPublicKey.length - 1)).should.be.false();
|
|
191
|
+
});
|
|
192
|
+
it('validate eth address too short', () => {
|
|
193
|
+
const address = '0x1374a2046661f914d1687d85dbbceb9ac7910a29';
|
|
194
|
+
tavaxCoin.isValidAddress(address.slice(1)).should.be.false();
|
|
195
|
+
avaxCoin.isValidAddress(address.slice(1)).should.be.false();
|
|
196
|
+
});
|
|
197
|
+
it('validate eth uncompressed public key too long', () => {
|
|
198
|
+
const uncompressedPublicKey = '043BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E227874E8075353564D83047566EEA6CF5A7313816AF004DDA8CA529DE8C94BC6A';
|
|
199
|
+
tavaxCoin.isValidPub(uncompressedPublicKey + '00').should.be.false();
|
|
200
|
+
avaxCoin.isValidPub(uncompressedPublicKey + '00').should.be.false();
|
|
201
|
+
});
|
|
202
|
+
it('validate eth compressed public key too long', () => {
|
|
203
|
+
const compressedPublicKey = '023BE650E2C11F36D201C9173BE37BC028AF495CF78CA05F78FEE192F5D339A9E2';
|
|
204
|
+
tavaxCoin.isValidPub(compressedPublicKey + '00').should.be.false();
|
|
205
|
+
avaxCoin.isValidPub(compressedPublicKey + '00').should.be.false();
|
|
206
|
+
});
|
|
207
|
+
it('validate extended public key too long', () => {
|
|
208
|
+
const extendedPublicKey = 'xpub661MyMwAqRbcEqNh81TVVceUDNF6yg7F63H9j3xMQj8GDdDVRLCFoPughSdgGs4X1n89iPXFKPMy3f45Y7E63kXGAZKuZ1fhLqsKtkoB3yZ';
|
|
209
|
+
tavaxCoin.isValidPub(extendedPublicKey + '00').should.be.false();
|
|
210
|
+
avaxCoin.isValidPub(extendedPublicKey + '00').should.be.false();
|
|
211
|
+
});
|
|
212
|
+
it('validate eth address too long', () => {
|
|
213
|
+
const address = '0x1374a2046661f914d1687d85dbbceb9ac7910a29';
|
|
214
|
+
tavaxCoin.isValidAddress(address + '00').should.be.false();
|
|
215
|
+
avaxCoin.isValidAddress(address + '00').should.be.false();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('Sign Transaction', () => {
|
|
219
|
+
const account_1 = {
|
|
220
|
+
address: '0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7',
|
|
221
|
+
owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
|
|
222
|
+
owner_2: '5ca116d25aec5f765465432cc421ff25ef9ffdc330b10bb3d9ad61e3baad88d7',
|
|
223
|
+
owner_3: '1fae946cc84af8bd74d610a88537e24e19c3349d478d86fc5bb59ba4c88fb9cc',
|
|
224
|
+
};
|
|
225
|
+
const account_2 = {
|
|
226
|
+
address: '0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8',
|
|
227
|
+
owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
|
|
228
|
+
owner_2: '5c7e4efff7304d4dfff6d5f1591844ec6f2adfa6a47e9fece6a3c1a4d755f1e3',
|
|
229
|
+
owner_3: '4421ab25dd91e1a3180d03d57c323a7886dcc313d3b3a4b4256a5791572bf597',
|
|
230
|
+
};
|
|
231
|
+
it('should use recipients from txPrebuild when available including data field', async function () {
|
|
232
|
+
const builder = (0, getBuilder_1.getBuilder)('tavaxc');
|
|
233
|
+
builder.fee({
|
|
234
|
+
fee: '280000000000',
|
|
235
|
+
gasLimit: '7000000',
|
|
236
|
+
});
|
|
237
|
+
builder.counter(1);
|
|
238
|
+
builder.type(sdk_core_1.TransactionType.Send);
|
|
239
|
+
builder.contract(account_1.address);
|
|
240
|
+
builder.transfer().amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
|
|
241
|
+
const unsignedTx = await builder.build();
|
|
242
|
+
const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
|
|
243
|
+
// Test with recipients in txPrebuild including data field
|
|
244
|
+
const customRecipients = [
|
|
245
|
+
{ address: '0x1234567890123456789012345678901234567890', amount: '500', data: '0xa9059cbb' },
|
|
246
|
+
{ address: '0x0987654321098765432109876543210987654321', amount: '300', data: '0x23b872dd' },
|
|
247
|
+
];
|
|
248
|
+
const halfSignedRawTx = await tavaxCoin.signTransaction({
|
|
249
|
+
txPrebuild: {
|
|
250
|
+
txHex: unsignedTxForBroadcasting,
|
|
251
|
+
recipients: customRecipients,
|
|
252
|
+
},
|
|
253
|
+
prv: account_1.owner_2,
|
|
254
|
+
});
|
|
255
|
+
// Should use recipients from txPrebuild, not from transaction outputs
|
|
256
|
+
halfSignedRawTx.halfSigned.recipients.length.should.equals(2);
|
|
257
|
+
halfSignedRawTx.halfSigned.recipients[0].address.should.equals(customRecipients[0].address);
|
|
258
|
+
halfSignedRawTx.halfSigned.recipients[0].amount.should.equals(customRecipients[0].amount);
|
|
259
|
+
halfSignedRawTx.halfSigned.recipients[0].data.should.equals(customRecipients[0].data);
|
|
260
|
+
halfSignedRawTx.halfSigned.recipients[1].address.should.equals(customRecipients[1].address);
|
|
261
|
+
halfSignedRawTx.halfSigned.recipients[1].amount.should.equals(customRecipients[1].amount);
|
|
262
|
+
halfSignedRawTx.halfSigned.recipients[1].data.should.equals(customRecipients[1].data);
|
|
263
|
+
});
|
|
264
|
+
it('should sign an unsigned test tx with eip1559', async function () {
|
|
265
|
+
const builder = (0, getBuilder_1.getBuilder)('tavaxc');
|
|
266
|
+
builder.fee({
|
|
267
|
+
fee: '280000000000',
|
|
268
|
+
gasLimit: '7000000',
|
|
269
|
+
eip1559: {
|
|
270
|
+
maxFeePerGas: '7593123',
|
|
271
|
+
maxPriorityFeePerGas: '150',
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
builder.counter(1);
|
|
275
|
+
builder.type(sdk_core_1.TransactionType.Send);
|
|
276
|
+
builder.contract(account_1.address);
|
|
277
|
+
builder.transfer().amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
|
|
278
|
+
const unsignedTx = await builder.build();
|
|
279
|
+
const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
|
|
280
|
+
const halfSignedRawTx = await tavaxCoin.signTransaction({
|
|
281
|
+
txPrebuild: {
|
|
282
|
+
txHex: unsignedTxForBroadcasting,
|
|
283
|
+
eip1559: {
|
|
284
|
+
maxFeePerGas: '7593123',
|
|
285
|
+
maxPriorityFeePerGas: '150',
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
prv: account_1.owner_2,
|
|
289
|
+
});
|
|
290
|
+
builder.transfer().key(account_1.owner_2);
|
|
291
|
+
const halfSignedTx = await builder.build();
|
|
292
|
+
const halfSignedTxForBroadcasting = halfSignedTx.toBroadcastFormat();
|
|
293
|
+
halfSignedRawTx.halfSigned.txHex.should.equals(halfSignedTxForBroadcasting);
|
|
294
|
+
halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
|
|
295
|
+
halfSignedRawTx.halfSigned.recipients[0].address.toLowerCase().should.equals(account_2.address.toLowerCase());
|
|
296
|
+
halfSignedRawTx.halfSigned.recipients[0].amount.toLowerCase().should.equals('1');
|
|
297
|
+
halfSignedRawTx.halfSigned.eip1559.maxFeePerGas.should.equal('7593123');
|
|
298
|
+
halfSignedRawTx.halfSigned.eip1559.maxPriorityFeePerGas.should.equal('150');
|
|
299
|
+
});
|
|
300
|
+
it('should preserve data field from txPrebuild recipients for contract interactions', async function () {
|
|
301
|
+
const builder = (0, getBuilder_1.getBuilder)('avaxc');
|
|
302
|
+
builder.fee({
|
|
303
|
+
fee: '280000000000',
|
|
304
|
+
gasLimit: '7000000',
|
|
305
|
+
});
|
|
306
|
+
builder.counter(1);
|
|
307
|
+
builder.type(sdk_core_1.TransactionType.Send);
|
|
308
|
+
builder.contract(account_1.address);
|
|
309
|
+
builder.transfer().amount('1').to(account_2.address).expirationTime(10000).contractSequenceId(1);
|
|
310
|
+
const unsignedTx = await builder.build();
|
|
311
|
+
const unsignedTxForBroadcasting = unsignedTx.toBroadcastFormat();
|
|
312
|
+
// Test with complex contract interaction data
|
|
313
|
+
const contractCallData = '0xa9059cbb000000000000000000000000abcdef1234567890abcdef1234567890abcdef120000000000000000000000000000000000000000000000000de0b6b3a7640000';
|
|
314
|
+
const customRecipients = [
|
|
315
|
+
{
|
|
316
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
317
|
+
amount: '0', // Contract call with 0 value
|
|
318
|
+
data: contractCallData,
|
|
319
|
+
},
|
|
320
|
+
];
|
|
321
|
+
const halfSignedRawTx = await avaxCoin.signTransaction({
|
|
322
|
+
txPrebuild: {
|
|
323
|
+
txHex: unsignedTxForBroadcasting,
|
|
324
|
+
recipients: customRecipients,
|
|
325
|
+
},
|
|
326
|
+
prv: account_1.owner_2,
|
|
327
|
+
});
|
|
328
|
+
// Should preserve the contract call data in half-signed transaction
|
|
329
|
+
halfSignedRawTx.halfSigned.recipients.length.should.equals(1);
|
|
330
|
+
halfSignedRawTx.halfSigned.recipients[0].address.should.equals(customRecipients[0].address);
|
|
331
|
+
halfSignedRawTx.halfSigned.recipients[0].amount.should.equals(customRecipients[0].amount);
|
|
332
|
+
halfSignedRawTx.halfSigned.recipients[0].data.should.equals(customRecipients[0].data);
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
describe('Transaction Verification', () => {
|
|
336
|
+
it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
|
|
337
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
338
|
+
const txParams = {
|
|
339
|
+
recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
|
|
340
|
+
wallet: wallet,
|
|
341
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
342
|
+
hop: true,
|
|
343
|
+
};
|
|
344
|
+
const txPrebuild = {
|
|
345
|
+
recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
|
|
346
|
+
nextContractSequenceId: 0,
|
|
347
|
+
gasPrice: 20000000000,
|
|
348
|
+
gasLimit: 500000,
|
|
349
|
+
isBatch: false,
|
|
350
|
+
coin: 'tavaxc',
|
|
351
|
+
walletId: 'fakeWalletId',
|
|
352
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
353
|
+
hopTransaction: {
|
|
354
|
+
tx: hopTx,
|
|
355
|
+
id: hopTxid,
|
|
356
|
+
signature: hopTxBitgoSignature,
|
|
357
|
+
paymentId: '2773928196',
|
|
358
|
+
gasPrice: 20000000000,
|
|
359
|
+
gasLimit: 500000,
|
|
360
|
+
amount: '1000000000000000',
|
|
361
|
+
recipient: hopDestinationAddress,
|
|
362
|
+
nonce: 0,
|
|
363
|
+
userReqSig: userReqSig,
|
|
364
|
+
gasPriceMax: 500000000000,
|
|
365
|
+
},
|
|
366
|
+
};
|
|
367
|
+
const verification = {};
|
|
368
|
+
const isTransactionVerified = await tavaxCoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
|
|
369
|
+
isTransactionVerified.should.equal(true);
|
|
370
|
+
});
|
|
371
|
+
describe('Hop export tx verify', () => {
|
|
372
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
373
|
+
const hopDestinationAddress = 'P-fuji13vkwxwqsq07ls6gq9q9yajrt8p946hye5zq3w3~P-fuji178atz5p3xhaagglygt27nde6h4tz9lsznwq2dh~P-fuji1kl7p7efzpwdqkt6rz4ut3wmwuyct7436q6l9h5';
|
|
374
|
+
const hopAddress = '0x1fe3de7886be9e53072d6762e9fa1fc27dddfb05';
|
|
375
|
+
const importTxFee = 1e6;
|
|
376
|
+
const amount = 100000000000000000;
|
|
377
|
+
const txParams = {
|
|
378
|
+
recipients: [{ amount, address: hopDestinationAddress }],
|
|
379
|
+
wallet: wallet,
|
|
380
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
381
|
+
hop: true,
|
|
382
|
+
type: 'Export',
|
|
383
|
+
};
|
|
384
|
+
const txPrebuild = {
|
|
385
|
+
recipients: [{ amount: '102000050000000000', address: hopAddress }],
|
|
386
|
+
nextContractSequenceId: 0,
|
|
387
|
+
gasPrice: 20000000000,
|
|
388
|
+
gasLimit: 500000,
|
|
389
|
+
isBatch: false,
|
|
390
|
+
coin: 'tavaxc',
|
|
391
|
+
walletId: 'fakeWalletId',
|
|
392
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
393
|
+
hopTransaction: {
|
|
394
|
+
tx: hopExportTx,
|
|
395
|
+
id: hopExportTxId,
|
|
396
|
+
signature: hopExportTxBitgoSignature,
|
|
397
|
+
paymentId: '4933349984',
|
|
398
|
+
gasPrice: '50',
|
|
399
|
+
gasLimit: 1,
|
|
400
|
+
amount: '101000000',
|
|
401
|
+
recipient: hopDestinationAddress,
|
|
402
|
+
nonce: 0,
|
|
403
|
+
userReqSig: '0x06fd0b1f8859a40d9fb2d1a65d54da5d645a1d81bbb8c1c5b037051843ec0d3c22433ec7f50cc97fa041cbf8d9ff5ddf7ed41f72a08fa3f1983fd651a33a4441',
|
|
404
|
+
gasPriceMax: 7187500000,
|
|
405
|
+
type: 'Export',
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
const verification = {};
|
|
409
|
+
before(() => {
|
|
410
|
+
txPrebuild.hopTransaction.signature = hopExportTxBitgoSignature;
|
|
411
|
+
});
|
|
412
|
+
it('should verify successfully', async function () {
|
|
413
|
+
const verifyAvaxcTransactionOptions = { txParams, txPrebuild, wallet, verification };
|
|
414
|
+
const isTransactionVerified = await tavaxCoin.verifyTransaction(verifyAvaxcTransactionOptions);
|
|
415
|
+
isTransactionVerified.should.equal(true);
|
|
416
|
+
});
|
|
417
|
+
it('should fail verify for amount plus 1', async function () {
|
|
418
|
+
const verifyAvaxcTransactionOptions = {
|
|
419
|
+
txParams: { ...txParams, recipients: [{ amount: amount + 1e9, address: hopDestinationAddress }] },
|
|
420
|
+
txPrebuild,
|
|
421
|
+
wallet,
|
|
422
|
+
verification,
|
|
423
|
+
};
|
|
424
|
+
await tavaxCoin
|
|
425
|
+
.verifyTransaction(verifyAvaxcTransactionOptions)
|
|
426
|
+
.should.be.rejectedWith(`Hop amount: ${amount / 1e9 + importTxFee} does not equal original amount: ${amount / 1e9 + importTxFee + 1}`);
|
|
427
|
+
});
|
|
428
|
+
it('should fail verify for changed prebuild hop address', async function () {
|
|
429
|
+
const verifyAvaxcTransactionOptions = {
|
|
430
|
+
txParams,
|
|
431
|
+
txPrebuild: { ...txPrebuild, recipients: [{ address: address2, amount: '102000050000000000' }] },
|
|
432
|
+
wallet,
|
|
433
|
+
verification,
|
|
434
|
+
};
|
|
435
|
+
await tavaxCoin
|
|
436
|
+
.verifyTransaction(verifyAvaxcTransactionOptions)
|
|
437
|
+
.should.be.rejectedWith(`recipient address of txPrebuild does not match hop address`);
|
|
438
|
+
});
|
|
439
|
+
it('should fail verify for changed address', async function () {
|
|
440
|
+
const hopDestinationAddressDiff = 'P-fuji13vkwxwqsq07ls6gq8q9yajrt8p946hye5zq3w3~P-fuji178atz5p3xhabgglygt27nde6h4tz9lsznwq2dh~P-fuji1kl7p7efzpwdqkt6rz4ut3wmwuyct7436q6l9h6';
|
|
441
|
+
const verifyAvaxcTransactionOptions = {
|
|
442
|
+
txParams: { ...txParams, recipients: [{ amount: amount, address: hopDestinationAddressDiff }] },
|
|
443
|
+
txPrebuild,
|
|
444
|
+
wallet,
|
|
445
|
+
verification,
|
|
446
|
+
};
|
|
447
|
+
await tavaxCoin
|
|
448
|
+
.verifyTransaction(verifyAvaxcTransactionOptions)
|
|
449
|
+
.should.be.rejectedWith(`Hop destination: ${hopDestinationAddress} does not equal original recipient: ${hopDestinationAddressDiff}`);
|
|
450
|
+
});
|
|
451
|
+
it('should verify if walletId is used instead of address', async function () {
|
|
452
|
+
const verifyAvaxcTransactionOptions = {
|
|
453
|
+
txParams: { ...txParams, recipients: [{ amount: amount, walletId: 'same wallet' }] },
|
|
454
|
+
txPrebuild,
|
|
455
|
+
wallet,
|
|
456
|
+
verification,
|
|
457
|
+
};
|
|
458
|
+
const isTransactionVerified = await tavaxCoin.verifyTransaction(verifyAvaxcTransactionOptions);
|
|
459
|
+
isTransactionVerified.should.equal(true);
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
it('should reject when client txParams are missing', async function () {
|
|
463
|
+
const coin = bitgo.coin('teth');
|
|
464
|
+
const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
|
|
465
|
+
const txParams = null;
|
|
466
|
+
const txPrebuild = {
|
|
467
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
468
|
+
nextContractSequenceId: 0,
|
|
469
|
+
gasPrice: 20000000000,
|
|
470
|
+
gasLimit: 500000,
|
|
471
|
+
isBatch: false,
|
|
472
|
+
coin: 'tavaxc',
|
|
473
|
+
walletId: 'fakeWalletId',
|
|
474
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
475
|
+
};
|
|
476
|
+
const verification = {};
|
|
477
|
+
await coin
|
|
478
|
+
.verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
|
|
479
|
+
.should.be.rejectedWith('missing params');
|
|
480
|
+
});
|
|
481
|
+
it('should reject txPrebuild that is both batch and hop', async function () {
|
|
482
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
483
|
+
const txParams = {
|
|
484
|
+
recipients: [
|
|
485
|
+
{ amount: '1000000000000', address: address1 },
|
|
486
|
+
{ amount: '2500000000000', address: address2 },
|
|
487
|
+
],
|
|
488
|
+
wallet: wallet,
|
|
489
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
490
|
+
hop: true,
|
|
491
|
+
};
|
|
492
|
+
const txPrebuild = {
|
|
493
|
+
recipients: [{ amount: '3500000000000', address: address1 }],
|
|
494
|
+
nextContractSequenceId: 0,
|
|
495
|
+
gasPrice: 20000000000,
|
|
496
|
+
gasLimit: 500000,
|
|
497
|
+
isBatch: true,
|
|
498
|
+
coin: 'tavaxc',
|
|
499
|
+
walletId: 'fakeWalletId',
|
|
500
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
501
|
+
hopTransaction: {
|
|
502
|
+
tx: hopTx,
|
|
503
|
+
id: hopTxid,
|
|
504
|
+
signature: hopTxBitgoSignature,
|
|
505
|
+
paymentId: '2773928196',
|
|
506
|
+
gasPrice: 20000000000,
|
|
507
|
+
gasLimit: 500000,
|
|
508
|
+
amount: '1000000000000000',
|
|
509
|
+
recipient: hopDestinationAddress,
|
|
510
|
+
nonce: 0,
|
|
511
|
+
userReqSig: userReqSig,
|
|
512
|
+
gasPriceMax: 500000000000,
|
|
513
|
+
},
|
|
514
|
+
};
|
|
515
|
+
const verification = {};
|
|
516
|
+
await tavaxCoin
|
|
517
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
518
|
+
.should.be.rejectedWith('tx cannot be both a batch and hop transaction');
|
|
519
|
+
});
|
|
520
|
+
it('should reject a txPrebuild with more than one recipient', async function () {
|
|
521
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
522
|
+
const txParams = {
|
|
523
|
+
recipients: [
|
|
524
|
+
{ amount: '1000000000000', address: address1 },
|
|
525
|
+
{ amount: '2500000000000', address: address2 },
|
|
526
|
+
],
|
|
527
|
+
wallet: wallet,
|
|
528
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
529
|
+
};
|
|
530
|
+
const txPrebuild = {
|
|
531
|
+
recipients: [
|
|
532
|
+
{ amount: '1000000000000', address: address1 },
|
|
533
|
+
{ amount: '2500000000000', address: address2 },
|
|
534
|
+
],
|
|
535
|
+
nextContractSequenceId: 0,
|
|
536
|
+
gasPrice: 20000000000,
|
|
537
|
+
gasLimit: 500000,
|
|
538
|
+
isBatch: true,
|
|
539
|
+
coin: 'tavaxc',
|
|
540
|
+
walletId: 'fakeWalletId',
|
|
541
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
542
|
+
};
|
|
543
|
+
const verification = {};
|
|
544
|
+
await tavaxCoin
|
|
545
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
546
|
+
.should.be.rejectedWith(`tavaxc doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
|
|
547
|
+
});
|
|
548
|
+
it('should reject a hop txPrebuild that does not send to its hop address', async function () {
|
|
549
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
550
|
+
const txParams = {
|
|
551
|
+
recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
|
|
552
|
+
wallet: wallet,
|
|
553
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
554
|
+
hop: true,
|
|
555
|
+
};
|
|
556
|
+
const txPrebuild = {
|
|
557
|
+
recipients: [{ amount: '5000000000000000', address: address1 }],
|
|
558
|
+
nextContractSequenceId: 0,
|
|
559
|
+
gasPrice: 20000000000,
|
|
560
|
+
gasLimit: 500000,
|
|
561
|
+
isBatch: false,
|
|
562
|
+
coin: 'tavaxc',
|
|
563
|
+
walletId: 'fakeWalletId',
|
|
564
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
565
|
+
hopTransaction: {
|
|
566
|
+
tx: hopTx,
|
|
567
|
+
id: hopTxid,
|
|
568
|
+
signature: hopTxBitgoSignature,
|
|
569
|
+
paymentId: '0',
|
|
570
|
+
gasPrice: 20000000000,
|
|
571
|
+
gasLimit: 500000,
|
|
572
|
+
amount: '1000000000000000',
|
|
573
|
+
recipient: hopDestinationAddress,
|
|
574
|
+
nonce: 0,
|
|
575
|
+
userReqSig: userReqSig,
|
|
576
|
+
gasPriceMax: 500000000000,
|
|
577
|
+
},
|
|
578
|
+
};
|
|
579
|
+
const verification = {};
|
|
580
|
+
await tavaxCoin
|
|
581
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
582
|
+
.should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
|
|
583
|
+
});
|
|
584
|
+
it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
|
|
585
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
586
|
+
const txParams = {
|
|
587
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
588
|
+
wallet: wallet,
|
|
589
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
590
|
+
};
|
|
591
|
+
const txPrebuild = {
|
|
592
|
+
recipients: [{ amount: '2000000000000', address: address1 }],
|
|
593
|
+
nextContractSequenceId: 0,
|
|
594
|
+
gasPrice: 20000000000,
|
|
595
|
+
gasLimit: 500000,
|
|
596
|
+
isBatch: false,
|
|
597
|
+
coin: 'tavaxc',
|
|
598
|
+
walletId: 'fakeWalletId',
|
|
599
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
600
|
+
};
|
|
601
|
+
const verification = {};
|
|
602
|
+
await tavaxCoin
|
|
603
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
604
|
+
.should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
|
|
605
|
+
});
|
|
606
|
+
it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
|
|
607
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
608
|
+
const txParams = {
|
|
609
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
610
|
+
wallet: wallet,
|
|
611
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
612
|
+
};
|
|
613
|
+
const txPrebuild = {
|
|
614
|
+
recipients: [{ amount: '1000000000000', address: address2 }],
|
|
615
|
+
nextContractSequenceId: 0,
|
|
616
|
+
gasPrice: 20000000000,
|
|
617
|
+
gasLimit: 500000,
|
|
618
|
+
isBatch: false,
|
|
619
|
+
coin: 'tavaxc',
|
|
620
|
+
walletId: 'fakeWalletId',
|
|
621
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
622
|
+
};
|
|
623
|
+
const verification = {};
|
|
624
|
+
await tavaxCoin
|
|
625
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
626
|
+
.should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
|
|
627
|
+
});
|
|
628
|
+
it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
|
|
629
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
630
|
+
const txParams = {
|
|
631
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
632
|
+
wallet: wallet,
|
|
633
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
634
|
+
};
|
|
635
|
+
const txPrebuild = {
|
|
636
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
637
|
+
nextContractSequenceId: 0,
|
|
638
|
+
gasPrice: 20000000000,
|
|
639
|
+
gasLimit: 500000,
|
|
640
|
+
isBatch: false,
|
|
641
|
+
coin: 'tavaxc',
|
|
642
|
+
token: 'test',
|
|
643
|
+
walletId: 'fakeWalletId',
|
|
644
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
645
|
+
};
|
|
646
|
+
const verification = {};
|
|
647
|
+
const isTransactionVerified = await tavaxCoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
|
|
648
|
+
isTransactionVerified.should.equal(true);
|
|
649
|
+
});
|
|
650
|
+
it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
|
|
651
|
+
const wallet = new sdk_core_1.Wallet(bitgo, tavaxCoin, {});
|
|
652
|
+
const txParams = {
|
|
653
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
654
|
+
wallet: wallet,
|
|
655
|
+
walletPassphrase: 'fakeWalletPassphrase',
|
|
656
|
+
};
|
|
657
|
+
const txPrebuild = {
|
|
658
|
+
recipients: [{ amount: '1000000000000', address: address1 }],
|
|
659
|
+
nextContractSequenceId: 0,
|
|
660
|
+
gasPrice: 20000000000,
|
|
661
|
+
gasLimit: 500000,
|
|
662
|
+
isBatch: false,
|
|
663
|
+
coin: 'btc',
|
|
664
|
+
walletId: 'fakeWalletId',
|
|
665
|
+
walletContractAddress: 'fakeWalletContractAddress',
|
|
666
|
+
};
|
|
667
|
+
const verification = {};
|
|
668
|
+
await tavaxCoin
|
|
669
|
+
.verifyTransaction({ txParams, txPrebuild, wallet, verification })
|
|
670
|
+
.should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
describe('Hop Transaction Parameters', () => {
|
|
674
|
+
const sandBox = sinon.createSandbox();
|
|
675
|
+
afterEach(function () {
|
|
676
|
+
sandBox.restore();
|
|
677
|
+
});
|
|
678
|
+
it('should create hop transaction parameters with gasPriceMax > 0', async function () {
|
|
679
|
+
const mockFeeEstimate = {
|
|
680
|
+
feeEstimate: '120000',
|
|
681
|
+
gasLimitEstimate: 500000,
|
|
682
|
+
};
|
|
683
|
+
sandBox.stub(tavaxCoin, 'feeEstimate').resolves(mockFeeEstimate);
|
|
684
|
+
const recipients = [
|
|
685
|
+
{
|
|
686
|
+
address: 'P-fuji14xa0q4858ct3kfvpkwnw2dys3m63kt6famckf6~P-fuji1hljye3kesjtpj87m00e8vwkayg6eys6theuxfg~P-fuji1lelqx4cleh3dzk5kplstz6mwrt3duk7d7wwmpp',
|
|
687
|
+
amount: '100000000000000000',
|
|
688
|
+
},
|
|
689
|
+
];
|
|
690
|
+
const result = await tavaxCoin.createHopTransactionParams({
|
|
691
|
+
recipients,
|
|
692
|
+
type: 'Export',
|
|
693
|
+
});
|
|
694
|
+
result.should.have.property('hopParams');
|
|
695
|
+
result.hopParams.should.have.properties(['userReqSig', 'gasPriceMax', 'paymentId', 'gasLimit']);
|
|
696
|
+
result.hopParams.userReqSig.should.equal('0x');
|
|
697
|
+
result.hopParams.gasPriceMax.should.be.above(0);
|
|
698
|
+
result.hopParams.paymentId.should.be.a.String();
|
|
699
|
+
result.hopParams.gasLimit.should.equal(500000);
|
|
700
|
+
});
|
|
701
|
+
});
|
|
702
|
+
describe('Explain Transaction', () => {
|
|
703
|
+
it('should explain a half signed import in C transaction', async () => {
|
|
704
|
+
const testData = avaxc_1.IMPORT_C;
|
|
705
|
+
const txExplain = await tavaxCoin.explainTransaction({ txHex: testData.halfsigntxHex, crossChainType: 'import' });
|
|
706
|
+
txExplain.outputAmount.should.equal((Number(testData.amount) - txExplain.fee?.fee).toString());
|
|
707
|
+
txExplain.type.should.equal(sdk_core_1.TransactionType.Import);
|
|
708
|
+
txExplain.outputs[0].address.should.equal(testData.to);
|
|
709
|
+
txExplain.changeOutputs.should.be.empty();
|
|
710
|
+
should.not.exist(txExplain.memo);
|
|
711
|
+
});
|
|
712
|
+
it('should explain a signed import in C transaction', async () => {
|
|
713
|
+
const testData = avaxc_1.IMPORT_C;
|
|
714
|
+
const txExplain = await tavaxCoin.explainTransaction({ txHex: testData.fullsigntxHex, crossChainType: 'import' });
|
|
715
|
+
txExplain.outputAmount.should.equal((Number(testData.amount) - txExplain.fee?.fee).toString());
|
|
716
|
+
txExplain.type.should.equal(sdk_core_1.TransactionType.Import);
|
|
717
|
+
txExplain.outputs[0].address.should.equal(testData.to);
|
|
718
|
+
txExplain.changeOutputs.should.be.empty();
|
|
719
|
+
should.not.exist(txExplain.memo);
|
|
720
|
+
});
|
|
721
|
+
it('should explain a unsigned export in C transaction', async () => {
|
|
722
|
+
const importInPFee = 1000000;
|
|
723
|
+
const testData = avaxc_1.EXPORT_C;
|
|
724
|
+
const txExplain = await tavaxCoin.explainTransaction({ txHex: testData.unsignedTxHex, crossChainType: 'export' });
|
|
725
|
+
txExplain.outputAmount.should.equal((Number(testData.amount) + importInPFee).toString());
|
|
726
|
+
txExplain.type.should.equal(sdk_core_1.TransactionType.Export);
|
|
727
|
+
txExplain.inputs[0].address.should.equal(testData.cHexAddress);
|
|
728
|
+
txExplain.outputs[0].address.should.equal(testData.pAddresses.slice().sort().join('~'));
|
|
729
|
+
txExplain.fee.fee.should.equal(testData.fee);
|
|
730
|
+
txExplain.changeOutputs.should.be.empty();
|
|
731
|
+
should.not.exist(txExplain.memo);
|
|
732
|
+
});
|
|
733
|
+
it('should explain a signed export in C transaction', async () => {
|
|
734
|
+
const importInPFee = 1000000;
|
|
735
|
+
const testData = avaxc_1.EXPORT_C;
|
|
736
|
+
const txExplain = await tavaxCoin.explainTransaction({ txHex: testData.fullsigntxHex, crossChainType: 'export' });
|
|
737
|
+
txExplain.outputAmount.should.equal((Number(testData.amount) + importInPFee).toString());
|
|
738
|
+
txExplain.type.should.equal(sdk_core_1.TransactionType.Export);
|
|
739
|
+
txExplain.inputs[0].address.should.equal(testData.cHexAddress);
|
|
740
|
+
txExplain.outputs[0].address.should.equal(testData.pAddresses.slice().sort().join('~'));
|
|
741
|
+
txExplain.fee.fee.should.equal(testData.fee);
|
|
742
|
+
txExplain.changeOutputs.should.be.empty();
|
|
743
|
+
should.not.exist(txExplain.memo);
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
// TODO(BG-56136): move to modules/bitgo/test/v2/integration/coins/avaxc.ts
|
|
747
|
+
describe('Recovery', function () {
|
|
748
|
+
// contract address for 'tavaxc:link'
|
|
749
|
+
const tokenContractAddress = '0x0b9d5d9136855f6fec3c0993fee6e9ce8a297846';
|
|
750
|
+
const sequenceIdData = '0xa0b7967b';
|
|
751
|
+
const sandBox = sinon.createSandbox();
|
|
752
|
+
beforeEach(function () {
|
|
753
|
+
const callBack = sandBox.stub(src_1.AvaxC.prototype, 'recoveryBlockchainExplorerQuery');
|
|
754
|
+
callBack
|
|
755
|
+
.withArgs({
|
|
756
|
+
jsonrpc: '2.0',
|
|
757
|
+
method: 'eth_getTransactionCount',
|
|
758
|
+
params: ['0xdfd95d01fc9c2cb744e2852256385bbe6d87b72b', 'latest'],
|
|
759
|
+
id: 1,
|
|
760
|
+
})
|
|
761
|
+
.resolves({ jsonrpc: '2.0', id: 1, result: '0x0' });
|
|
762
|
+
callBack
|
|
763
|
+
.withArgs({
|
|
764
|
+
jsonrpc: '2.0',
|
|
765
|
+
method: 'eth_getTransactionCount',
|
|
766
|
+
params: ['0x29d97ce344599825220a54a4bdf7b8aa7ca14fd1', 'latest'],
|
|
767
|
+
id: 1,
|
|
768
|
+
})
|
|
769
|
+
.resolves({ jsonrpc: '2.0', id: 1, result: '0x7' });
|
|
770
|
+
callBack
|
|
771
|
+
.withArgs({
|
|
772
|
+
jsonrpc: '2.0',
|
|
773
|
+
method: 'eth_getBalance',
|
|
774
|
+
params: ['0xdfd95d01fc9c2cb744e2852256385bbe6d87b72b', 'latest'],
|
|
775
|
+
id: 1,
|
|
776
|
+
})
|
|
777
|
+
.resolves({ jsonrpc: '2.0', id: 1, result: '0x0' });
|
|
778
|
+
callBack
|
|
779
|
+
.withArgs({
|
|
780
|
+
jsonrpc: '2.0',
|
|
781
|
+
method: 'eth_getBalance',
|
|
782
|
+
params: ['0x29d97ce344599825220a54a4bdf7b8aa7ca14fd1', 'latest'],
|
|
783
|
+
id: 1,
|
|
784
|
+
})
|
|
785
|
+
.resolves({ jsonrpc: '2.0', id: 1, result: '0x315f8cb9bc2ec00' });
|
|
786
|
+
callBack
|
|
787
|
+
.withArgs({
|
|
788
|
+
jsonrpc: '2.0',
|
|
789
|
+
method: 'eth_getBalance',
|
|
790
|
+
params: ['0xe0b1fe098050f2745b450de419b5cafc7e826699', 'latest'],
|
|
791
|
+
id: 1,
|
|
792
|
+
})
|
|
793
|
+
.resolves({ jsonrpc: '2.0', id: 1, result: '0x0' });
|
|
794
|
+
callBack
|
|
795
|
+
.withArgs({
|
|
796
|
+
jsonrpc: '2.0',
|
|
797
|
+
method: 'eth_call',
|
|
798
|
+
params: [{ to: '0xe0b1fe098050f2745b450de419b5cafc7e826699', data: '0xa0b7967b' }, 'latest'],
|
|
799
|
+
id: 1,
|
|
800
|
+
})
|
|
801
|
+
.resolves({
|
|
802
|
+
jsonrpc: '2.0',
|
|
803
|
+
id: 1,
|
|
804
|
+
result: '0x000000000000000000000000000000000000000000000000000000000000000f',
|
|
805
|
+
});
|
|
806
|
+
callBack
|
|
807
|
+
.withArgs({
|
|
808
|
+
jsonrpc: '2.0',
|
|
809
|
+
method: 'eth_getTransactionCount',
|
|
810
|
+
params: [avaxc_1.recoveryUsers.hotWalletRecoveryUser.backupKeyAddress, 'latest'],
|
|
811
|
+
id: 1,
|
|
812
|
+
})
|
|
813
|
+
.resolves(avaxc_1.endpointResponses.addressNonceResponse1);
|
|
814
|
+
callBack
|
|
815
|
+
.withArgs({
|
|
816
|
+
jsonrpc: '2.0',
|
|
817
|
+
method: 'eth_getTransactionCount',
|
|
818
|
+
params: [avaxc_1.recoveryUsers.coldWalletRecoveryUser.backupKeyAddress, 'latest'],
|
|
819
|
+
id: 1,
|
|
820
|
+
})
|
|
821
|
+
.resolves(avaxc_1.endpointResponses.addressNonceResponse2);
|
|
822
|
+
callBack
|
|
823
|
+
.withArgs({
|
|
824
|
+
jsonrpc: '2.0',
|
|
825
|
+
method: 'eth_getBalance',
|
|
826
|
+
params: [avaxc_1.recoveryUsers.hotWalletRecoveryUser.backupKeyAddress, 'latest'],
|
|
827
|
+
id: 1,
|
|
828
|
+
})
|
|
829
|
+
.resolves(avaxc_1.endpointResponses.backupAddressBalanceResponse);
|
|
830
|
+
callBack
|
|
831
|
+
.withArgs({
|
|
832
|
+
jsonrpc: '2.0',
|
|
833
|
+
method: 'eth_getBalance',
|
|
834
|
+
params: [avaxc_1.recoveryUsers.coldWalletRecoveryUser.backupKeyAddress, 'latest'],
|
|
835
|
+
id: 1,
|
|
836
|
+
})
|
|
837
|
+
.resolves(avaxc_1.endpointResponses.backupAddressBalanceResponse);
|
|
838
|
+
callBack
|
|
839
|
+
.withArgs({
|
|
840
|
+
jsonrpc: '2.0',
|
|
841
|
+
method: 'eth_call',
|
|
842
|
+
params: [
|
|
843
|
+
{
|
|
844
|
+
to: tokenContractAddress,
|
|
845
|
+
data: sdk_coin_eth_1.optionalDeps.ethUtil.addHexPrefix(sdk_coin_eth_1.optionalDeps.ethAbi
|
|
846
|
+
.simpleEncode('balanceOf(address)', avaxc_1.recoveryUsers.hotWalletRecoveryUser.walletContractAddress)
|
|
847
|
+
.toString('hex')),
|
|
848
|
+
},
|
|
849
|
+
'latest',
|
|
850
|
+
],
|
|
851
|
+
id: 1,
|
|
852
|
+
})
|
|
853
|
+
.resolves(avaxc_1.endpointResponses.addressTokenBalanceResponse);
|
|
854
|
+
callBack
|
|
855
|
+
.withArgs({
|
|
856
|
+
jsonrpc: '2.0',
|
|
857
|
+
method: 'eth_call',
|
|
858
|
+
params: [
|
|
859
|
+
{
|
|
860
|
+
to: tokenContractAddress,
|
|
861
|
+
data: sdk_coin_eth_1.optionalDeps.ethUtil.addHexPrefix(sdk_coin_eth_1.optionalDeps.ethAbi
|
|
862
|
+
.simpleEncode('balanceOf(address)', avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletContractAddress)
|
|
863
|
+
.toString('hex')),
|
|
864
|
+
},
|
|
865
|
+
'latest',
|
|
866
|
+
],
|
|
867
|
+
id: 1,
|
|
868
|
+
})
|
|
869
|
+
.resolves(avaxc_1.endpointResponses.addressTokenBalanceResponse);
|
|
870
|
+
callBack
|
|
871
|
+
.withArgs({
|
|
872
|
+
jsonrpc: '2.0',
|
|
873
|
+
method: 'eth_call',
|
|
874
|
+
params: [{ to: avaxc_1.recoveryUsers.hotWalletRecoveryUser.walletContractAddress, data: sequenceIdData }, 'latest'],
|
|
875
|
+
id: 1,
|
|
876
|
+
})
|
|
877
|
+
.resolves(avaxc_1.endpointResponses.sequenceIdResponse1);
|
|
878
|
+
callBack
|
|
879
|
+
.withArgs({
|
|
880
|
+
jsonrpc: '2.0',
|
|
881
|
+
method: 'eth_call',
|
|
882
|
+
params: [{ to: avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletContractAddress, data: sequenceIdData }, 'latest'],
|
|
883
|
+
id: 1,
|
|
884
|
+
})
|
|
885
|
+
.resolves(avaxc_1.endpointResponses.sequenceIdResponse2);
|
|
886
|
+
});
|
|
887
|
+
afterEach(function () {
|
|
888
|
+
sandBox.restore();
|
|
889
|
+
});
|
|
890
|
+
describe('Non-BitGo', async function () {
|
|
891
|
+
it('should error when the backup key is unfunded (cannot pay gas)', async function () {
|
|
892
|
+
await tavaxCoin
|
|
893
|
+
.recover({
|
|
894
|
+
userKey: '{"iv":"ntd9/urFjryqxd4rzREB2Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
895
|
+
':"ccm","adata":"","cipher":"aes","salt":"LTqZ47b1BwE=","ct":"JSbJIBTkHoKR3L\n' +
|
|
896
|
+
'oT2QTkDx3X1OBIPxiSL6WoMiIrKA+aKTgmutXnWC2GTEIyfbLeajw6D2UZ+U0Y8viv7mgITgSz1\n' +
|
|
897
|
+
'u9Gdj97Btm8WsZ0e+KmsbdB/gYucCZoPUZCFqG4bEkdfZ8ZvDI9XvVv4xPzNb/AoSijosA="}',
|
|
898
|
+
backupKey: '{"iv":"Axs+G9gsZ5PENUHx1YY5cg==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
899
|
+
':"ccm","adata":"","cipher":"aes","salt":"awQshUvFi7Q=","ct":"sWQ0bHmruUTI8C\n' +
|
|
900
|
+
'lwGneHObdNfo3WQ/mrz3p84Fo07HgizvgLd+E3wFA3Z1LRbHozRjfstV/qJMRqrFvEgKOcG+SKd\n' +
|
|
901
|
+
'gx6BbmXWfKhFHEerSYluBgU5OrXMfOkbExnMywEWrCKEvoNL+wyNHoRaMNbbDogo36J8PE="}',
|
|
902
|
+
walletContractAddress: '0x22c1ab44371985e49294d1a40e92c8ad00f5be8e',
|
|
903
|
+
// walletPassphrase: TestBitGo.V2.TEST_RECOVERY_PASSCODE,
|
|
904
|
+
walletPassphrase: 'Ghghjkg!455544llll',
|
|
905
|
+
recoveryDestination: '0x94b51ebb8c3b90404ad262f42c1588bd94242ecb',
|
|
906
|
+
})
|
|
907
|
+
.should.be.rejectedWith('Backup key address 0xdfd95d01fc9c2cb744e2852256385bbe6d87b72b has balance 0 Gwei.This address must have a balance of at least 10000000 Gwei to perform recoveries. Try sending some AVAX to this address then retry.');
|
|
908
|
+
});
|
|
909
|
+
it('should build recovery tx', async function () {
|
|
910
|
+
const recovery = await tavaxCoin.recover({
|
|
911
|
+
userKey: '{"iv":"o27pBl7IP+ibe39xYg/cXg==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
912
|
+
':"ccm","adata":"","cipher":"aes","salt":"992R6padf2I=","ct":"6wkn1PdwtWcCWR\n' +
|
|
913
|
+
'VdOdaiGMCMS5RhurGI9eF4tdgzaMzOpgw56eYRmKTzldj5Vh1Cnz6RoqFlVSfnwR+tFjOyqDn3O\n' +
|
|
914
|
+
'8K3NUD5YlMGoCdfvcrCbPF3tCdKl2DyoLv+ZWPo5sKVjjgUOZgI7pn7iBtXRDvqaWylawY="}',
|
|
915
|
+
backupKey: '{"iv":"mwj9ld8svgRBsWS+5NZQqA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
|
|
916
|
+
':"ccm","adata":"","cipher":"aes","salt":"XuMxbqa/yNg=","ct":"lqLnjsVSBR/4ue\n' +
|
|
917
|
+
'ztYahAvEEV+ltDXLoyIEMCmFMycba+3mPtiAM8HrF/84AzJOjwKyvK1pm+CFuuWCTXssAQxRCuc\n' +
|
|
918
|
+
'HujrBvrKunY4hfIJHJsyBr+l1PNNSUB/aYL1aW/n7tdvwL8fOCNqFqEPBCbxXoOlSgCAUw="}',
|
|
919
|
+
walletContractAddress: '0xe0b1fe098050f2745b450de419b5cafc7e826699',
|
|
920
|
+
walletPassphrase: 'Ghghjkg!455544llll',
|
|
921
|
+
recoveryDestination: '0x94b51ebb8c3b90404ad262f42c1588bd94242ecb',
|
|
922
|
+
gasPrice: '30000000000',
|
|
923
|
+
});
|
|
924
|
+
// id and tx will always be different because of expireTime
|
|
925
|
+
recovery.should.not.be.undefined();
|
|
926
|
+
recovery.should.have.property('id');
|
|
927
|
+
recovery.should.have.property('tx');
|
|
928
|
+
const txBuilder = tavaxCoin.getTransactionBuilder();
|
|
929
|
+
txBuilder.from(recovery.tx);
|
|
930
|
+
const tx = await txBuilder.build();
|
|
931
|
+
tx.toBroadcastFormat().should.not.be.empty();
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
describe('Unsigned Sweep', function () {
|
|
935
|
+
const userXprv = 'xprv9s21ZrQH143K3fZVRfmxvr7YBodF4jSczgKU6RoDUzvKnFiFz2mcuKgw1zYgvTGtLMBPAPonv5GzHnDXQK5Vk8BRHcN76TGgLwcNcFTy4kC';
|
|
936
|
+
const userXpub = 'xpub661MyMwAqRbcG9dxXhJyHz4GjqTjUCAUMuF4tpCq3LTJf43QXa5sT81QsJ5VMdK8vnAK56gi7qy2cZ2dzYQfy7YP7x4uHQpuRViAv9CNbtS';
|
|
937
|
+
const backupXprv = 'xprv9s21ZrQH143K4N6YBjooa6Tx3U7hzM3SvHFA8XP23qYhQ6KPLo2QgXTSasVpiMY4F6gMrstXBHRDso5WE7Gn37yZnW5qTRJZU6FPeXx1B69';
|
|
938
|
+
const backupXpub = 'xpub661MyMwAqRbcGrB1HmLowEQgbVxCPomJHWAkvundcB5gGteXtLLfEKmvSB9dKvRmh3LxpL2yvgqy37Z3ydqvHoViMWa2dwX3huwmmBuip7J';
|
|
939
|
+
const walletContractAddress = '0xe0b1fe098050f2745b450de419b5cafc7e826699';
|
|
940
|
+
const recoveryDestination = '0x94b51ebb8c3b90404ad262f42c1588bd94242ecb';
|
|
941
|
+
const gasPrice = '25000000000';
|
|
942
|
+
it('should build unsigned sweep tx', async function () {
|
|
943
|
+
const recovery = await tavaxCoin.recover({
|
|
944
|
+
userKey: userXpub,
|
|
945
|
+
backupKey: backupXpub,
|
|
946
|
+
walletContractAddress,
|
|
947
|
+
recoveryDestination,
|
|
948
|
+
gasPrice,
|
|
949
|
+
});
|
|
950
|
+
const parsedTx = (0, helpers_1.parseTransaction)(recovery.txHex);
|
|
951
|
+
const decodedSendMultisigCallData = (0, helpers_1.decodeTransaction)(JSON.stringify(helpers_1.walletSimpleABI), parsedTx.data);
|
|
952
|
+
const safeTransferFromCallData = decodedSendMultisigCallData.args[2];
|
|
953
|
+
const safeTransferFromDestination = decodedSendMultisigCallData.args[0];
|
|
954
|
+
safeTransferFromDestination.toLowerCase().should.equal(recoveryDestination);
|
|
955
|
+
safeTransferFromCallData.should.be.equal('0x');
|
|
956
|
+
recovery.should.not.be.undefined();
|
|
957
|
+
recovery.should.have.properties('txHex', 'userKey', 'backupKey');
|
|
958
|
+
recovery.recipients.length.should.equal(1);
|
|
959
|
+
recovery.recipients[0].address.should.equal(recoveryDestination);
|
|
960
|
+
recovery.walletContractAddress.should.equal(walletContractAddress);
|
|
961
|
+
});
|
|
962
|
+
it('should add a second signature', async function () {
|
|
963
|
+
const recovery = await tavaxCoin.recover({
|
|
964
|
+
userKey: userXpub,
|
|
965
|
+
backupKey: backupXpub,
|
|
966
|
+
walletContractAddress,
|
|
967
|
+
recoveryDestination,
|
|
968
|
+
gasPrice,
|
|
969
|
+
});
|
|
970
|
+
const txPrebuild = {
|
|
971
|
+
txHex: recovery.txHex,
|
|
972
|
+
userKey: userXpub,
|
|
973
|
+
backupKey: backupXpub,
|
|
974
|
+
coin: recovery.coin,
|
|
975
|
+
gasPrice: recovery.gasPrice,
|
|
976
|
+
gasLimit: recovery.gasLimit,
|
|
977
|
+
recipients: recovery.recipients,
|
|
978
|
+
walletContractAddress: recovery.walletContractAddress,
|
|
979
|
+
amount: recovery.amount,
|
|
980
|
+
backupKeyNonce: recovery.backupKeyNonce,
|
|
981
|
+
recipient: recovery.recipient,
|
|
982
|
+
expireTime: recovery.expireTime,
|
|
983
|
+
contractSequenceId: recovery.contractSequenceId,
|
|
984
|
+
nextContractSequenceId: recovery.nextContractSequenceId,
|
|
985
|
+
};
|
|
986
|
+
const params = {
|
|
987
|
+
txPrebuild,
|
|
988
|
+
prv: userXprv,
|
|
989
|
+
};
|
|
990
|
+
// sign transaction once
|
|
991
|
+
const halfSigned = await tavaxCoin.signTransaction(params);
|
|
992
|
+
const wrapper = {};
|
|
993
|
+
wrapper.txPrebuild = halfSigned;
|
|
994
|
+
wrapper.isLastSignature = true;
|
|
995
|
+
wrapper.walletContractAddress = walletContractAddress;
|
|
996
|
+
wrapper.prv = backupXprv;
|
|
997
|
+
// sign transaction twice with the "isLastSignature" flag
|
|
998
|
+
const finalSignedTx = await tavaxCoin.signTransaction(wrapper);
|
|
999
|
+
finalSignedTx.should.have.property('txHex');
|
|
1000
|
+
const txBuilder = tavaxCoin.getTransactionBuilder();
|
|
1001
|
+
txBuilder.from(finalSignedTx.txHex);
|
|
1002
|
+
const rebuiltTx = await txBuilder.build();
|
|
1003
|
+
rebuiltTx.signature.length.should.equal(2);
|
|
1004
|
+
rebuiltTx.outputs.length.should.equal(1);
|
|
1005
|
+
rebuiltTx.outputs[0].address.should.equal(txPrebuild.recipient.address);
|
|
1006
|
+
rebuiltTx.outputs[0].value.should.equal(txPrebuild.recipient.amount);
|
|
1007
|
+
});
|
|
1008
|
+
});
|
|
1009
|
+
describe('Token Recovery', async function () {
|
|
1010
|
+
const destAddr = '0xc74b1c0ee90a481b528253042ce3228a8cd6873e';
|
|
1011
|
+
const weiToGwei = 10 ** 9;
|
|
1012
|
+
const gasPrice = 30 * weiToGwei;
|
|
1013
|
+
// contract address for 'tavaxc:link'
|
|
1014
|
+
const tokenContractAddress = '0x0b9d5d9136855f6fec3c0993fee6e9ce8a297846';
|
|
1015
|
+
const tokenName = 'tavaxc:link';
|
|
1016
|
+
it('should build token recovery tx', async function () {
|
|
1017
|
+
const params = {
|
|
1018
|
+
userKey: avaxc_1.recoveryUsers.hotWalletRecoveryUser.userKey,
|
|
1019
|
+
backupKey: avaxc_1.recoveryUsers.hotWalletRecoveryUser.backupKey,
|
|
1020
|
+
recoveryDestination: destAddr,
|
|
1021
|
+
walletPassphrase: avaxc_1.recoveryUsers.hotWalletRecoveryUser.walletPassphrase,
|
|
1022
|
+
walletContractAddress: avaxc_1.recoveryUsers.hotWalletRecoveryUser.walletContractAddress,
|
|
1023
|
+
tokenContractAddress,
|
|
1024
|
+
gasPrice: gasPrice.toString(),
|
|
1025
|
+
};
|
|
1026
|
+
const recoveryTxn = await tavaxCoin.recover(params);
|
|
1027
|
+
recoveryTxn.should.not.be.undefined();
|
|
1028
|
+
recoveryTxn.should.have.property('id');
|
|
1029
|
+
recoveryTxn.should.have.property('tx');
|
|
1030
|
+
const txBuilder = tavaxCoin.getTransactionBuilder();
|
|
1031
|
+
txBuilder.from(recoveryTxn.tx);
|
|
1032
|
+
const tx = await txBuilder.build();
|
|
1033
|
+
tx.toBroadcastFormat().should.not.be.empty();
|
|
1034
|
+
tx.inputs.should.not.be.empty();
|
|
1035
|
+
tx.inputs[0].address.should.equal(avaxc_1.recoveryUsers.hotWalletRecoveryUser.walletContractAddress);
|
|
1036
|
+
tx.inputs[0].value.should.equal(new ethereumjs_util_1.BN(avaxc_1.endpointResponses.addressTokenBalanceResponse.result.slice(2), 16).toString(10));
|
|
1037
|
+
tx.inputs[0].coin?.should.equal(tokenName);
|
|
1038
|
+
tx.outputs.should.not.be.empty();
|
|
1039
|
+
tx.outputs[0].address.should.equal(destAddr);
|
|
1040
|
+
tx.outputs[0].value.should.equal(new ethereumjs_util_1.BN(avaxc_1.endpointResponses.addressTokenBalanceResponse.result.slice(2), 16).toString(10));
|
|
1041
|
+
tx.outputs[0].coin?.should.equal(tokenName);
|
|
1042
|
+
});
|
|
1043
|
+
it('should build unsigned sweep token recovery tx', async function () {
|
|
1044
|
+
const params = {
|
|
1045
|
+
userKey: avaxc_1.recoveryUsers.coldWalletRecoveryUser.userKey,
|
|
1046
|
+
backupKey: avaxc_1.recoveryUsers.coldWalletRecoveryUser.backupKey,
|
|
1047
|
+
recoveryDestination: destAddr,
|
|
1048
|
+
walletPassphrase: avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletPassphrase,
|
|
1049
|
+
walletContractAddress: avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletContractAddress,
|
|
1050
|
+
tokenContractAddress,
|
|
1051
|
+
gasPrice: gasPrice.toString(),
|
|
1052
|
+
};
|
|
1053
|
+
const recoveryTxn = await tavaxCoin.recover(params);
|
|
1054
|
+
recoveryTxn.should.not.be.undefined();
|
|
1055
|
+
recoveryTxn.should.have.property('txHex');
|
|
1056
|
+
recoveryTxn.should.have.property('token');
|
|
1057
|
+
recoveryTxn.token.should.equal('tavaxc:link');
|
|
1058
|
+
const txBuilder = tavaxCoin.getTransactionBuilder();
|
|
1059
|
+
txBuilder.from(recoveryTxn.txHex);
|
|
1060
|
+
const tx = await txBuilder.build();
|
|
1061
|
+
const recoveryAmount = new ethereumjs_util_1.BN(avaxc_1.endpointResponses.addressTokenBalanceResponse.result.slice(2), 16).toString(10);
|
|
1062
|
+
tx.toBroadcastFormat().should.not.be.empty();
|
|
1063
|
+
tx.inputs.should.not.be.empty();
|
|
1064
|
+
tx.inputs[0].address.should.equal(avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletContractAddress);
|
|
1065
|
+
tx.inputs[0].value.should.equal(recoveryAmount);
|
|
1066
|
+
tx.inputs[0].should.have.property('coin');
|
|
1067
|
+
tx.inputs[0].coin?.should.equal(tokenName);
|
|
1068
|
+
tx.outputs.should.not.be.empty();
|
|
1069
|
+
tx.outputs[0].address.should.equal(destAddr);
|
|
1070
|
+
tx.outputs[0].value.should.equal(new ethereumjs_util_1.BN(avaxc_1.endpointResponses.addressTokenBalanceResponse.result.slice(2), 16).toString(10));
|
|
1071
|
+
tx.outputs[0].should.have.property('coin');
|
|
1072
|
+
tx.outputs[0].coin?.should.equal(tokenName);
|
|
1073
|
+
recoveryTxn.should.have.property('userKey');
|
|
1074
|
+
recoveryTxn.userKey.should.equal(avaxc_1.recoveryUsers.coldWalletRecoveryUser.userKey);
|
|
1075
|
+
recoveryTxn.should.have.property('backupKey');
|
|
1076
|
+
recoveryTxn.backupKey.should.equal(avaxc_1.recoveryUsers.coldWalletRecoveryUser.backupKey);
|
|
1077
|
+
recoveryTxn.should.have.property('coin');
|
|
1078
|
+
recoveryTxn.coin.should.equal('tavaxc');
|
|
1079
|
+
recoveryTxn.should.have.property('gasPrice');
|
|
1080
|
+
recoveryTxn.gasPrice.should.equal(gasPrice.toString());
|
|
1081
|
+
recoveryTxn.should.have.property('gasLimit');
|
|
1082
|
+
recoveryTxn.gasLimit.should.equal('500000');
|
|
1083
|
+
recoveryTxn.should.have.property('recipients');
|
|
1084
|
+
recoveryTxn.recipients.length.should.equal(1);
|
|
1085
|
+
recoveryTxn.recipients[0].address.should.equal(destAddr);
|
|
1086
|
+
recoveryTxn.recipients[0].amount.should.equal(recoveryAmount);
|
|
1087
|
+
recoveryTxn.should.have.property('walletContractAddress');
|
|
1088
|
+
recoveryTxn.walletContractAddress.should.equal(avaxc_1.recoveryUsers.coldWalletRecoveryUser.walletContractAddress);
|
|
1089
|
+
recoveryTxn.should.have.property('amount');
|
|
1090
|
+
recoveryTxn.amount.should.equal(recoveryAmount);
|
|
1091
|
+
recoveryTxn.should.have.property('recipient');
|
|
1092
|
+
recoveryTxn.recipient.address.should.equal(destAddr);
|
|
1093
|
+
recoveryTxn.recipient.amount.should.equal(recoveryAmount);
|
|
1094
|
+
recoveryTxn.should.have.property('tokenContractAddress');
|
|
1095
|
+
recoveryTxn.tokenContractAddress.should.equal(tokenContractAddress);
|
|
1096
|
+
recoveryTxn.should.have.property('backupKeyNonce');
|
|
1097
|
+
recoveryTxn.should.have.property('expireTime');
|
|
1098
|
+
recoveryTxn.should.have.property('contractSequenceId');
|
|
1099
|
+
recoveryTxn.should.have.property('nextContractSequenceId');
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
});
|
|
1103
|
+
});
|
|
1104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXZheGMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvYXZheGMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxtREFBK0Q7QUFDL0QsaURBQStDO0FBQy9DLG1DQUE4RDtBQUM5RCw2Q0FBMEM7QUFDMUMscURBQXVDO0FBQ3ZDLHFEQUE4QztBQUM5QywyQ0FBNkI7QUFDN0IsbURBQXVFO0FBQ3ZFLDJEQUE2RDtBQUU3RCwrQ0FBaUM7QUFDakMsOENBQTBGO0FBQzFGLCtEQUFvRDtBQUNwRCx1Q0FBaUY7QUFDakYsNkNBQStCO0FBQy9CLHFEQUFxQztBQUVyQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUV4QixRQUFRLENBQUMsbUJBQW1CLEVBQUU7SUFDNUIsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLG1CQUFtQixDQUFDO0lBQ3hCLElBQUkseUJBQXlCLENBQUM7SUFFOUIsTUFBTSxRQUFRLEdBQUcsNENBQTRDLENBQUM7SUFDOUQsTUFBTSxRQUFRLEdBQUcsNENBQTRDLENBQUM7SUFDOUQsTUFBTSxrQkFBa0IsR0FBRyw0Q0FBNEMsQ0FBQztJQUN4RSxNQUFNLHFCQUFxQixHQUFHLDRDQUE0QyxDQUFDO0lBQzNFLE1BQU0sS0FBSyxHQUNULDhOQUE4TixDQUFDO0lBQ2pPLE1BQU0sT0FBTyxHQUFHLG9FQUFvRSxDQUFDO0lBQ3JGLE1BQU0sVUFBVSxHQUNkLG9JQUFvSSxDQUFDO0lBQ3ZJLE1BQU0sV0FBVyxHQUNmLGtzQkFBa3NCLENBQUM7SUFDcnNCLE1BQU0sYUFBYSxHQUFHLG9FQUFvRSxDQUFDO0lBRTNGLE1BQU0sQ0FBQztRQUNMLE1BQU0sWUFBWSxHQUNoQixpSEFBaUgsQ0FBQztRQUNwSCxNQUFNLFFBQVEsR0FBRyxpQkFBSyxDQUFDLFVBQVUs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QUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztnQkFFcEUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ25ELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDL0MsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUM7Z0JBQ3ZELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzdELENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1hcGknO1xuaW1wb3J0IHsgQXZheEMsIFRhdmF4QywgVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBiaXAzMiB9IGZyb20gJ0BiaXRnby1iZXRhL3NlY3AyNTZrMSc7XG5pbXBvcnQgKiBhcyBub2NrIGZyb20gJ25vY2snO1xuaW1wb3J0IHsgY29tbW9uLCBUcmFuc2FjdGlvblR5cGUsIFdhbGxldCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEV0aCwgb3B0aW9uYWxEZXBzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvaW4tZXRoJztcbmltcG9ydCB7IEF2YXhTaWduVHJhbnNhY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vLi4vc3JjL2lmYWNlJztcbmltcG9ydCAqIGFzIHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHsgRVhQT1JUX0MsIElNUE9SVF9DLCBlbmRwb2ludFJlc3BvbnNlcywgcmVjb3ZlcnlVc2VycyB9IGZyb20gJy4uL3Jlc291cmNlcy9hdmF4Yyc7XG5pbXBvcnQgeyBUYXZheFAgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29pbi1hdmF4cCc7XG5pbXBvcnQgeyBkZWNvZGVUcmFuc2FjdGlvbiwgcGFyc2VUcmFuc2FjdGlvbiwgd2FsbGV0U2ltcGxlQUJJIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IEJOIH0gZnJvbSAnZXRoZXJldW1qcy11dGlsJztcblxubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmRlc2NyaWJlKCdBdmFsYW5jaGUgQy1DaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCB0YXZheENvaW47XG4gIGxldCBhdmF4Q29pbjtcbiAgbGV0IGhvcFR4Qml0Z29TaWduYXR1cmU7XG4gIGxldCBob3BFeHBvcnRUeEJpdGdvU2lnbmF0dXJlO1xuXG4gIGNvbnN0IGFkZHJlc3MxID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gIGNvbnN0IGFkZHJlc3MyID0gJzB4N2U4NWJkYzI3YzA1MGUzOTA1ZWJmNGI4ZTYzNGQ5YWQ2ZWRkMGRlNic7XG4gIGNvbnN0IGhvcENvbnRyYWN0QWRkcmVzcyA9ICcweDQ3Y2U3Y2M4NmVmZWZlZjE5ZjhmYjUxNmIxMTczNWQxODNkYTg2MzUnO1xuICBjb25zdCBob3BEZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHg5YzdlOGNlNjgyNWJENDgyNzhCM0FiNTkyMjhFRTI2ZjhCRTc5MjViJztcbiAgY29uc3QgaG9wVHggPVxuICAgICcweGY4NmI4MDg1MDRhODE3YzhmZjgyNTJmZjk0OWM3ZThjZTY4MjViZDQ4Mjc4YjNhYjU5MjI4ZWUyNmY4YmU3OTI1Yjg3MDM4ZDdlYTRjNjgwMDA4MDFjYTAxMWJjMjJjNjY0NTcwMTMzZGZjYTRmMDhhMGI4ZDAyMzM5Y2Y0NjcwNDZkNmE0MTUyZjA0ZjM2OGQwZWFmOTllYTAxZDZkYzVjZjBjODk3YzhkNGMzZTFkZjUzZDBkMDQyNzg0YzQyNDUzNmE0Y2M1YjgwMjU1MmI3ZDY0ZmVlOGI1JztcbiAgY29uc3QgaG9wVHhpZCA9ICcweDRhZjY1MTQzYmM3N2RhMmI1MGYzNWIzZDEzY2FjYjRkYjE4ZjAyNmJmODRiYzA3NDM1NTBiYzU3YjliNTMzNTEnO1xuICBjb25zdCB1c2VyUmVxU2lnID1cbiAgICAnMHg0MDRkYjMwN2Y2MTQ3ZjBkOGNkMzM4YzM0YzEzOTA2ZWY0NmE2ZmFhN2UwZTExOWQ1MTk0ZWYwNWFlYzE2ZTZmM2Q3MTBmOWI3OTAxNDYwZjk3ZTkyNDA2NmI2MmVmZDc0NDQzYmQzNDQwMmM2ZDQwYjQ5YzIwM2E1NTlmZjJjOCc7XG4gIGNvbnN0IGhvcEV4cG9ydFR4ID1cbiAgICAnMHgwMDAwMDAwMDAwMDEwMDAwMDAwNTdmYzkzZDg1YzZkNjJjNWIyYWMwYjUxOWM4NzAxMGVhNTI5NDAxMmQxZTQwNzAzMGQ2YWNkMDAyMWNhYzEwZDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDExZmUzZGU3ODg2YmU5ZTUzMDcyZDY3NjJlOWZhMWZjMjdkZGRmYjA1MDAwMDAwMDAwNjE0NjViMjNkOWJkYWMwZWQxZDc2MTMzMGNmNjgwZWZkZWIxYTQyMTU5ZWIzODdkNmQyOTUwYzk2ZjdkMjhmNjFiYmUyYWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEzZDliZGFjMGVkMWQ3NjEzMzBjZjY4MGVmZGViMWE0MjE1OWViMzg3ZDZkMjk1MGM5NmY3ZDI4ZjYxYmJlMmFhMDAwMDAwMDcwMDAwMDAwMDA2MDUyMzQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAyMDAwMDAwMDM4YjJjZTMzODEwMDNmZGY4NjkwMDI4MGE0ZWM4NmIzODRiNWQ1Yzk5YjdmYzFmNjUyMjBiOWEwYjJmNDMxNTc4YjhiYjZlZTEzMGJmNTYzYWYxZmFiMTUwMzEzNWZiZDQyM2U0NDJkNWU5YjczYWJkNTYyMmZlMDIwMDAwMDAwMTAwMDAwMDA5MDAwMDAwMDFhZjIwMDY2MTk3ZmEzYjcyYmVhM2Q3Y2M1MDNjNjA5MThjMDk4Mzc4Yjk1OGZiYjVkYThjNmY0MzhkMGY0ZTM4MGU1MDZiYjJjMzhkYzg4ZGQ5N2M4MWU5ODI3MDZjNDg2MjM5MzdjMmZlMjJiMzEyNDhlZDlmZDM0OTUxNDgwYjAxNzNiNGU5Y2EnO1xuICBjb25zdCBob3BFeHBvcnRUeElkID0gJzB4YzRiNWNhNmU3ZDhjOWMyNGJiOTkzNGFmY2I1Yzg3ZTZkYjQ3MmRiZTMxMTExYjc3ODQ0NWY4ZjljNTM1Mjk2Nic7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRnb0tleVhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szdHBXQkhXZTMxc0xvWE5SUTlBdlJZSmdpdGtLeFE0QVRGUU13dnI3aEhOcVlSVW5TN1BzanpCN2FLMVZ4cUhMdU5Ramoxc2NrSjJKd28ycXhtc3ZlandFQ1NwRk1mQyc7XG4gICAgY29uc3QgYml0Z29LZXkgPSBiaXAzMi5mcm9tQmFzZTU4KGJpdGdvS2V5WHBydik7XG4gICAgaWYgKCFiaXRnb0tleS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgY29uc3QgYml0Z29YcHViID0gYml0Z29LZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuXG4gICAgaG9wVHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oc2VjcDI1NmsxLmVjZHNhU2lnbihCdWZmZXIuZnJvbShob3BUeGlkLnNsaWNlKDIpLCAnaGV4JyksIGJpdGdvS2V5LnByaXZhdGVLZXkpLnNpZ25hdHVyZSkudG9TdHJpbmcoXG4gICAgICAgICdoZXgnXG4gICAgICApO1xuXG4gICAgaG9wRXhwb3J0VHhCaXRnb1NpZ25hdHVyZSA9XG4gICAgICAnMHhhYScgK1xuICAgICAgQnVmZmVyLmZyb20oXG4gICAgICAgIHNlY3AyNTZrMS5lY2RzYVNpZ24oQnVmZmVyLmZyb20oaG9wRXhwb3J0VHhJZC5zbGljZSgyKSwgJ2hleCcpLCBiaXRnb0tleS5wcml2YXRlS2V5KS5zaWduYXR1cmVcbiAgICAgICkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgY29uc3QgZW52ID0gJ3Rlc3QnO1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudiB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2F2YXhjJywgQXZheEMuY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGF2YXhjJywgVGF2YXhDLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RldGgnLCBFdGguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGF2YXhwJywgVGF2YXhQLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS5oc21YcHViID0gYml0Z29YcHViO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICB0YXZheENvaW4gPSBiaXRnby5jb2luKCd0YXZheGMnKSBhcyBUYXZheEM7XG4gICAgYXZheENvaW4gPSBiaXRnby5jb2luKCdhdmF4YycpIGFzIEF2YXhDO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnSW5zdGFudGlhdGUgJiBTdGF0aWNzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgaW5zdGFudGlhdGUgdGhlIGNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgbG9jYWxCYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RhdmF4YycpO1xuICAgICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihUYXZheEMpO1xuXG4gICAgICBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbignYXZheGMnKTtcbiAgICAgIGxvY2FsQmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoQXZheEMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgaG9wIGRpZ2VzdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGRpZ2VzdCA9IEF2YXhDLmdldEhvcERpZ2VzdChbJzEnLCAnMicsICczJ10pO1xuICAgICAgZGlnZXN0LnRvU3RyaW5nKCdoZXgnKS5zaG91bGQuZXF1YWwoJzIzMWNkYTVmMDUwYzg0MTMyMmI5ZGY1MzZhZmI2MzNjYTA2MjQwMGE4ZjM5M2JmNjU0YTQ4YmRkMWRmZDgyNWInKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0tleVBhaXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSB0YXZheCBrZXlQYWlyIHdpdGhvdXQgYWd1bWVudHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IHRhdmF4Q29pbi5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgIGtwLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwcnYnKTtcbiAgICAgIGtwLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwdWInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYXZheCBrZXlQYWlyIHdpdGhvdXQgYWd1bWVudHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGF2YXhDb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAga3Auc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BydicpO1xuICAgICAga3Auc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhdmF4IGtleVBhaXIgZnJvbSBzZWVkJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2VlZCA9ICc0YjNiODlmNmNhODk3Y2I3MjlkMjE0NjkxMzg3N2Y3MSc7XG4gICAgICBjb25zdCB0QXZheEtleVBhaXIgPSB0YXZheENvaW4uZ2VuZXJhdGVLZXlQYWlyKEJ1ZmZlci5mcm9tKHNlZWQsICdoZXgnKSk7XG4gICAgICBjb25zdCBhdmF4S2V5UGFpciA9IGF2YXhDb2luLmdlbmVyYXRlS2V5UGFpcihCdWZmZXIuZnJvbShzZWVkLCAnaGV4JykpO1xuICAgICAgdEF2YXhLZXlQYWlyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwcnYnKTtcbiAgICAgIHRBdmF4S2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHViJyk7XG4gICAgICB0QXZheEtleVBhaXIucHJ2LnNob3VsZC5lcXVhbHMoXG4gICAgICAgICd4cHJ2OXMyMVpyUUgxNDNLMk1KRTF5dlY4VWhqZkxRY2FEUFBpcE1ZdmZZanJQYkhMcHRMc250MUZiYkNyQ1Q5RTVMQ21SclM1OTNZWjFDS2dmM3JmM0MyaFlUeW5aTjVhdTNWdkJ2TGNXaDhzVjInXG4gICAgICApO1xuICAgICAgdEF2YXhLZXlQYWlyLnB1YiEuc2hvdWxkLmVxdWFscyhcbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFcU5oODFUVlZjZVVETkY2eWc3RjYzSDlqM3hNUWo4R0RkRFZSTENGb1B1Z2hTZGdHczRYMW44OWlQWEZLUE15M2Y0NVk3RTYza1hHQVpLdVoxZmhMcXNLdGtvQjN5WidcbiAgICAgICk7XG4gICAgICB0QXZheEtleVBhaXIuc2hvdWxkLmRlZXBFcXVhbChhdmF4S2V5UGFpcik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdrZXlzIHZhbGlkYXRpb25zIHN1Y2Nlc3MgY2FzZXMnLCAoKSA9PiB7XG4gICAgaXQoJ3ZhbGlkYXRlIHZhbGlkIGV0aCB1bmNvbXByZXNzZWQgcHVibGljIGtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IHVuY29tcHJlc3NlZFB1YmxpY0tleSA9XG4gICAgICAgICcwNDNCRTY1MEUyQzExRjM2RDIwMUM5MTczQkUzN0JDMDI4QUY0OTVDRjc4Q0EwNUY3OEZFRTE5MkY1RDMzOUE5RTIyNzg3NEU4MDc1MzUzNTY0RDgzMDQ3NTY2RUVBNkNGNUE3MzEzODE2QUYwMDREREE4Q0E1MjlERThDOTRCQzZBJztcbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkUHViKHVuY29tcHJlc3NlZFB1YmxpY0tleSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGF2YXhDb2luLmlzVmFsaWRQdWIodW5jb21wcmVzc2VkUHVibGljS2V5KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIHZhbGlkIGV0aCBjb21wcmVzc2VkIHB1YmxpYyBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb21wcmVzc2VkUHVibGljS2V5ID0gJzAyM0JFNjUwRTJDMTFGMzZEMjAxQzkxNzNCRTM3QkMwMjhBRjQ5NUNGNzhDQTA1Rjc4RkVFMTkyRjVEMzM5QTlFMic7XG4gICAgICB0YXZheENvaW4uaXNWYWxpZFB1Yihjb21wcmVzc2VkUHVibGljS2V5KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgYXZheENvaW4uaXNWYWxpZFB1Yihjb21wcmVzc2VkUHVibGljS2V5KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIHZhbGlkIGV4dGVuZGVkIHB1YmxpYyBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHRlbmRlZFB1YmxpY0tleSA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRXFOaDgxVFZWY2VVRE5GNnlnN0Y2M0g5ajN4TVFqOEdEZERWUkxDRm9QdWdoU2RnR3M0WDFuODlpUFhGS1BNeTNmNDVZN0U2M2tYR0FaS3VaMWZoTHFzS3Rrb0IzeVonO1xuICAgICAgdGF2YXhDb2luLmlzVmFsaWRQdWIoZXh0ZW5kZWRQdWJsaWNLZXkpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkUHViKGV4dGVuZGVkUHVibGljS2V5KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIHZhbGlkIGV0aCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcweDEzNzRhMjA0NjY2MWY5MTRkMTY4N2Q4NWRiYmNlYjlhYzc5MTBhMjknO1xuICAgICAgdGF2YXhDb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhbiBhcnJheSBvZiBwLWNoYWluIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBbXG4gICAgICAgICdQLWZ1amkxNXgzejRydms4ZTd2d2E2Zzlsa3lnODl2NWR3a25wNDQ4NTh1ZXgnLFxuICAgICAgICAnUC1hdmF4MTQzcThsc3kzeTRrZTlkNnplbHRyZTh1MmF0ZWVkNnVrOWthMG51JyxcbiAgICAgICAgJ05vZGVJRC0xNDNxOGxzeTN5NGtlOWQ2emVsdHJlOHUyYXRlZWQ2dWs5a2EwbnUnLFxuICAgICAgXTtcblxuICAgICAgdGF2YXhDb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhIHAtY2hhaW4gbXVsdHNpZyBhZGRyZXNzIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPVxuICAgICAgICAnUC1mdWppMXl6cGZzZGFsaGZ3a3EyY2Vld2dzOXd2N2swdWZ0NDB5ZHB1ajU5flAtZnVqaTEwM2NtbnRzc3A2cW51Y2VqYWhkZHk0MndjeTRxdHkwdWo0MjgyMn5QLWZ1amkxaGRrN250dzBodWhxbWxobGhlbWU5dDdzY3N5OWxoZmh3M3l3eTQnO1xuICAgICAgdGF2YXhDb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgna2V5cyB2YWxpZGF0aW9ucyBmYWlsdXJlIGNhc2VzJywgKCkgPT4ge1xuICAgIGl0KCd2YWxpZGF0ZSBlbXB0eSBldGggcHVibGljIGtleScsICgpID0+IHtcbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkUHViKCcnKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIGF2YXhDb2luLmlzVmFsaWRQdWIoJycpLnNob3VsZC5iZS5mYWxzZSgpO1xuXG4gICAgICB0YXZheENvaW4uaXNWYWxpZFB1Yih1bmRlZmluZWQpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgYXZheENvaW4uaXNWYWxpZFB1Yih1bmRlZmluZWQpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGVtcHR5IGV0aCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgdGF2YXhDb2luLmlzVmFsaWRBZGRyZXNzKHVuZGVmaW5lZCkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkQWRkcmVzcyh1bmRlZmluZWQpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGV0aCB1bmNvbXByZXNzZWQgcHVibGljIGtleSB0b28gc2hvcnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB1bmNvbXByZXNzZWRQdWJsaWNLZXkgPVxuICAgICAgICAnMDQzQkU2NTBFMkMxMUYzNkQyMDFDOTE3M0JFMzdCQzAyOEFGNDk1Q0Y3OENBMDVGNzhGRUUxOTJGNUQzMzlBOUUyMjc4NzRFODA3NTM1MzU2NEQ4MzA0NzU2NkVFQTZDRjVBNzMxMzgxNkFGMDA0RERBOENBNTI5REU4Qzk0QkM2QSc7XG5cbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkUHViKHVuY29tcHJlc3NlZFB1YmxpY0tleS5zbGljZSgxKSkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkUHViKHVuY29tcHJlc3NlZFB1YmxpY0tleS5zbGljZSgxKSkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgndmFsaWRhdGUgZXRoIGNvbXByZXNzZWQgcHVibGljIGtleSB0b28gc2hvcnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb21wcmVzc2VkUHVibGljS2V5ID0gJzAyM0JFNjUwRTJDMTFGMzZEMjAxQzkxNzNCRTM3QkMwMjhBRjQ5NUNGNzhDQTA1Rjc4RkVFMTkyRjVEMzM5QTlFMic7XG5cbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkUHViKGNvbXByZXNzZWRQdWJsaWNLZXkuc2xpY2UoMSkpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgYXZheENvaW4uaXNWYWxpZFB1Yihjb21wcmVzc2VkUHVibGljS2V5LnNsaWNlKDEpKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2YWxpZGF0ZSBpbnZhbGlkIGV4dGVuZGVkIHByaXZhdGUga2V5JywgKCkgPT4ge1xuICAgICAgY29uc3QgZXh0ZW5kZWRQdWJsaWNLZXkgPVxuICAgICAgICAneHB1YjY2MU15TXdBcVJiY0VxTmg4MVRWVmNlVURORjZ5ZzdGNjNIOWozeE1RajhHRGREVlJMQ0ZvUHVnaFNkZ0dzNFgxbjg5aVBYRktQTXkzZjQ1WTdFNjNrWEdBWkt1WjFmaExxc0t0a29CM3laJztcblxuICAgICAgdGF2YXhDb2luLmlzVmFsaWRQdWIoZXh0ZW5kZWRQdWJsaWNLZXkuc3Vic3RyKDAsIGV4dGVuZGVkUHVibGljS2V5Lmxlbmd0aCAtIDEpKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIGF2YXhDb2luLmlzVmFsaWRQdWIoZXh0ZW5kZWRQdWJsaWNLZXkuc3Vic3RyKDAsIGV4dGVuZGVkUHVibGljS2V5Lmxlbmd0aCAtIDEpKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICB9KTtcblxuICAgIGl0KCd2YWxpZGF0ZSBldGggYWRkcmVzcyB0b28gc2hvcnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJzB4MTM3NGEyMDQ2NjYxZjkxNGQxNjg3ZDg1ZGJiY2ViOWFjNzkxMGEyOSc7XG5cbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzLnNsaWNlKDEpKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIGF2YXhDb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3Muc2xpY2UoMSkpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGV0aCB1bmNvbXByZXNzZWQgcHVibGljIGtleSB0b28gbG9uZycsICgpID0+IHtcbiAgICAgIGNvbnN0IHVuY29tcHJlc3NlZFB1YmxpY0tleSA9XG4gICAgICAgICcwNDNCRTY1MEUyQzExRjM2RDIwMUM5MTczQkUzN0JDMDI4QUY0OTVDRjc4Q0EwNUY3OEZFRTE5MkY1RDMzOUE5RTIyNzg3NEU4MDc1MzUzNTY0RDgzMDQ3NTY2RUVBNkNGNUE3MzEzODE2QUYwMDREREE4Q0E1MjlERThDOTRCQzZBJztcblxuICAgICAgdGF2YXhDb2luLmlzVmFsaWRQdWIodW5jb21wcmVzc2VkUHVibGljS2V5ICsgJzAwJykuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICBhdmF4Q29pbi5pc1ZhbGlkUHViKHVuY29tcHJlc3NlZFB1YmxpY0tleSArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGV0aCBjb21wcmVzc2VkIHB1YmxpYyBrZXkgdG9vIGxvbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb21wcmVzc2VkUHVibGljS2V5ID0gJzAyM0JFNjUwRTJDMTFGMzZEMjAxQzkxNzNCRTM3QkMwMjhBRjQ5NUNGNzhDQTA1Rjc4RkVFMTkyRjVEMzM5QTlFMic7XG5cbiAgICAgIHRhdmF4Q29pbi5pc1ZhbGlkUHViKGNvbXByZXNzZWRQdWJsaWNLZXkgKyAnMDAnKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIGF2YXhDb2luLmlzVmFsaWRQdWIoY29tcHJlc3NlZFB1YmxpY0tleSArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGV4dGVuZGVkIHB1YmxpYyBrZXkgdG9vIGxvbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCBleHRlbmRlZFB1YmxpY0tleSA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRXFOaDgxVFZWY2VVRE5GNnlnN0Y2M0g5ajN4TVFqOEdEZERWUkxDRm9QdWdoU2RnR3M0WDFuODlpUFhGS1BNeTNmNDVZN0U2M2tYR0FaS3VaMWZoTHFzS3Rrb0IzeVonO1xuXG4gICAgICB0YXZheENvaW4uaXNWYWxpZFB1YihleHRlbmRlZFB1YmxpY0tleSArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgYXZheENvaW4uaXNWYWxpZFB1YihleHRlbmRlZFB1YmxpY0tleSArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbGlkYXRlIGV0aCBhZGRyZXNzIHRvbyBsb25nJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcweDEzNzRhMjA0NjY2MWY5MTRkMTY4N2Q4NWRiYmNlYjlhYzc5MTBhMjknO1xuXG4gICAgICB0YXZheENvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcyArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgYXZheENvaW4uaXNWYWxpZEFkZHJlc3MoYWRkcmVzcyArICcwMCcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBUcmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBjb25zdCBhY2NvdW50XzEgPSB7XG4gICAgICBhZGRyZXNzOiAnMHhlZWFmMEYwNWYzNzg5MWFiNGEyMTIwOEIxMDVBMDY4N2QxMmM1YUY3JyxcbiAgICAgIG93bmVyXzE6ICc0ZWUwODlhY2VhYmYzZGRiZjc0OGRiNzliMTA2NmMzM2I3ZDNlYTFhYjNlYjdlMzI1MTIxYmJhMmJmZjJmNWNhJyxcbiAgICAgIG93bmVyXzI6ICc1Y2ExMTZkMjVhZWM1Zjc2NTQ2NTQzMmNjNDIxZmYyNWVmOWZmZGMzMzBiMTBiYjNkOWFkNjFlM2JhYWQ4OGQ3JyxcbiAgICAgIG93bmVyXzM6ICcxZmFlOTQ2Y2M4NGFmOGJkNzRkNjEwYTg4NTM3ZTI0ZTE5YzMzNDlkNDc4ZDg2ZmM1YmI1OWJhNGM4OGZiOWNjJyxcbiAgICB9O1xuXG4gICAgY29uc3QgYWNjb3VudF8yID0ge1xuICAgICAgYWRkcmVzczogJzB4OENlNTljMmQxNzAyODQ0RjhFZEVENDUxQUExMDM5NjFiQzM3QjRlOCcsXG4gICAgICBvd25lcl8xOiAnNGVlMDg5YWNlYWJmM2RkYmY3NDhkYjc5YjEwNjZjMzNiN2QzZWExYWIzZWI3ZTMyNTEyMWJiYTJiZmYyZjVjYScsXG4gICAgICBvd25lcl8yOiAnNWM3ZTRlZmZmNzMwNGQ0ZGZmZjZkNWYxNTkxODQ0ZWM2ZjJhZGZhNmE0N2U5ZmVjZTZhM2MxYTRkNzU1ZjFlMycsXG4gICAgICBvd25lcl8zOiAnNDQyMWFiMjVkZDkxZTFhMzE4MGQwM2Q1N2MzMjNhNzg4NmRjYzMxM2QzYjNhNGI0MjU2YTU3OTE1NzJiZjU5NycsXG4gICAgfTtcblxuICAgIGl0KCdzaG91bGQgdXNlIHJlY2lwaWVudHMgZnJvbSB0eFByZWJ1aWxkIHdoZW4gYXZhaWxhYmxlIGluY2x1ZGluZyBkYXRhIGZpZWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGdldEJ1aWxkZXIoJ3RhdmF4YycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMjgwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICc3MDAwMDAwJyxcbiAgICAgIH0pO1xuICAgICAgYnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgYnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIGJ1aWxkZXIuY29udHJhY3QoYWNjb3VudF8xLmFkZHJlc3MpO1xuICAgICAgYnVpbGRlci50cmFuc2ZlcigpLmFtb3VudCgnMScpLnRvKGFjY291bnRfMi5hZGRyZXNzKS5leHBpcmF0aW9uVGltZSgxMDAwMCkuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdW5zaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgLy8gVGVzdCB3aXRoIHJlY2lwaWVudHMgaW4gdHhQcmVidWlsZCBpbmNsdWRpbmcgZGF0YSBmaWVsZFxuICAgICAgY29uc3QgY3VzdG9tUmVjaXBpZW50cyA9IFtcbiAgICAgICAgeyBhZGRyZXNzOiAnMHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJywgYW1vdW50OiAnNTAwJywgZGF0YTogJzB4YTkwNTljYmInIH0sXG4gICAgICAgIHsgYWRkcmVzczogJzB4MDk4NzY1NDMyMTA5ODc2NTQzMjEwOTg3NjU0MzIxMDk4NzY1NDMyMScsIGFtb3VudDogJzMwMCcsIGRhdGE6ICcweDIzYjg3MmRkJyB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFJhd1R4ID0gYXdhaXQgdGF2YXhDb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogdW5zaWduZWRUeEZvckJyb2FkY2FzdGluZyxcbiAgICAgICAgICByZWNpcGllbnRzOiBjdXN0b21SZWNpcGllbnRzLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IGFjY291bnRfMS5vd25lcl8yLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNob3VsZCB1c2UgcmVjaXBpZW50cyBmcm9tIHR4UHJlYnVpbGQsIG5vdCBmcm9tIHRyYW5zYWN0aW9uIG91dHB1dHNcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHMubGVuZ3RoLnNob3VsZC5lcXVhbHMoMik7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFscyhjdXN0b21SZWNpcGllbnRzWzBdLmFkZHJlc3MpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hbW91bnQuc2hvdWxkLmVxdWFscyhjdXN0b21SZWNpcGllbnRzWzBdLmFtb3VudCk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmRhdGEuc2hvdWxkLmVxdWFscyhjdXN0b21SZWNpcGllbnRzWzBdLmRhdGEpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1sxXS5hZGRyZXNzLnNob3VsZC5lcXVhbHMoY3VzdG9tUmVjaXBpZW50c1sxXS5hZGRyZXNzKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMV0uYW1vdW50LnNob3VsZC5lcXVhbHMoY3VzdG9tUmVjaXBpZW50c1sxXS5hbW91bnQpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1sxXS5kYXRhLnNob3VsZC5lcXVhbHMoY3VzdG9tUmVjaXBpZW50c1sxXS5kYXRhKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhbiB1bnNpZ25lZCB0ZXN0IHR4IHdpdGggZWlwMTU1OScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCd0YXZheGMnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICBidWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzI4MDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNzAwMDAwMCcsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6ICc3NTkzMTIzJyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIGJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBidWlsZGVyLmNvbnRyYWN0KGFjY291bnRfMS5hZGRyZXNzKTtcbiAgICAgIGJ1aWxkZXIudHJhbnNmZXIoKS5hbW91bnQoJzEnKS50byhhY2NvdW50XzIuYWRkcmVzcykuZXhwaXJhdGlvblRpbWUoMTAwMDApLmNvbnRyYWN0U2VxdWVuY2VJZCgxKTtcblxuICAgICAgY29uc3QgdW5zaWduZWRUeCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcgPSB1bnNpZ25lZFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IGhhbGZTaWduZWRSYXdUeCA9IGF3YWl0IHRhdmF4Q29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcsXG4gICAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgICAgbWF4RmVlUGVyR2FzOiAnNzU5MzEyMycsXG4gICAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBhY2NvdW50XzEub3duZXJfMixcbiAgICAgIH0pO1xuXG4gICAgICBidWlsZGVyLnRyYW5zZmVyKCkua2V5KGFjY291bnRfMS5vd25lcl8yKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IGhhbGZTaWduZWRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC50eEhleC5zaG91bGQuZXF1YWxzKGhhbGZTaWduZWRUeEZvckJyb2FkY2FzdGluZyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzLmxlbmd0aC5zaG91bGQuZXF1YWxzKDEpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50c1swXS5hZGRyZXNzLnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscyhhY2NvdW50XzIuYWRkcmVzcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uYW1vdW50LnRvTG93ZXJDYXNlKCkuc2hvdWxkLmVxdWFscygnMScpO1xuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKCc3NTkzMTIzJyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5laXAxNTU5Lm1heFByaW9yaXR5RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgnMTUwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByZXNlcnZlIGRhdGEgZmllbGQgZnJvbSB0eFByZWJ1aWxkIHJlY2lwaWVudHMgZm9yIGNvbnRyYWN0IGludGVyYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdhdmF4YycpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIGJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMjgwMDAwMDAwMDAwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICc3MDAwMDAwJyxcbiAgICAgIH0pO1xuICAgICAgYnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgYnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIGJ1aWxkZXIuY29udHJhY3QoYWNjb3VudF8xLmFkZHJlc3MpO1xuICAgICAgYnVpbGRlci50cmFuc2ZlcigpLmFtb3VudCgnMScpLnRvKGFjY291bnRfMi5hZGRyZXNzKS5leHBpcmF0aW9uVGltZSgxMDAwMCkuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuXG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdW5zaWduZWRUeEZvckJyb2FkY2FzdGluZyA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgLy8gVGVzdCB3aXRoIGNvbXBsZXggY29udHJhY3QgaW50ZXJhY3Rpb24gZGF0YVxuICAgICAgY29uc3QgY29udHJhY3RDYWxsRGF0YSA9XG4gICAgICAgICcweGE5MDU5Y2JiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYWJjZGVmMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBkZTBiNmIzYTc2NDAwMDAnO1xuICAgICAgY29uc3QgY3VzdG9tUmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFkZHJlc3M6ICcweDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAnLFxuICAgICAgICAgIGFtb3VudDogJzAnLCAvLyBDb250cmFjdCBjYWxsIHdpdGggMCB2YWx1ZVxuICAgICAgICAgIGRhdGE6IGNvbnRyYWN0Q2FsbERhdGEsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkUmF3VHggPSBhd2FpdCBhdmF4Q29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhGb3JCcm9hZGNhc3RpbmcsXG4gICAgICAgICAgcmVjaXBpZW50czogY3VzdG9tUmVjaXBpZW50cyxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBhY2NvdW50XzEub3duZXJfMixcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTaG91bGQgcHJlc2VydmUgdGhlIGNvbnRyYWN0IGNhbGwgZGF0YSBpbiBoYWxmLXNpZ25lZCB0cmFuc2FjdGlvblxuICAgICAgaGFsZlNpZ25lZFJhd1R4LmhhbGZTaWduZWQucmVjaXBpZW50cy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWxzKGN1c3RvbVJlY2lwaWVudHNbMF0uYWRkcmVzcyk7XG4gICAgICBoYWxmU2lnbmVkUmF3VHguaGFsZlNpZ25lZC5yZWNpcGllbnRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWxzKGN1c3RvbVJlY2lwaWVudHNbMF0uYW1vdW50KTtcbiAgICAgIGhhbGZTaWduZWRSYXdUeC5oYWxmU2lnbmVkLnJlY2lwaWVudHNbMF0uZGF0YS5zaG91bGQuZXF1YWxzKGN1c3RvbVJlY2lwaWVudHNbMF0uZGF0YSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBWZXJpZmljYXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBob3AgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0YXZheENvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogMTAwMDAwMDAwMDAwMDAwMCwgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RhdmF4YycsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgdGF2YXhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdIb3AgZXhwb3J0IHR4IHZlcmlmeScsICgpID0+IHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRhdmF4Q29pbiwge30pO1xuICAgICAgY29uc3QgaG9wRGVzdGluYXRpb25BZGRyZXNzID1cbiAgICAgICAgJ1AtZnVqaTEzdmt3eHdxc3EwN2xzNmdxOXE5eWFqcnQ4cDk0Nmh5ZTV6cTN3M35QLWZ1amkxNzhhdHo1cDN4aGFhZ2dseWd0MjduZGU2aDR0ejlsc3pud3EyZGh+UC1mdWppMWtsN3A3ZWZ6cHdkcWt0NnJ6NHV0M3dtd3V5Y3Q3NDM2cTZsOWg1JztcbiAgICAgIGNvbnN0IGhvcEFkZHJlc3MgPSAnMHgxZmUzZGU3ODg2YmU5ZTUzMDcyZDY3NjJlOWZhMWZjMjdkZGRmYjA1JztcbiAgICAgIGNvbnN0IGltcG9ydFR4RmVlID0gMWU2O1xuICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDAwMDAwMDAwMDAwMDAwO1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudCwgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgICB0eXBlOiAnRXhwb3J0JyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMjAwMDA1MDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcEFkZHJlc3MgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0YXZheGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BFeHBvcnRUeCxcbiAgICAgICAgICBpZDogaG9wRXhwb3J0VHhJZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcEV4cG9ydFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnNDkzMzM0OTk4NCcsXG4gICAgICAgICAgZ2FzUHJpY2U6ICc1MCcsXG4gICAgICAgICAgZ2FzTGltaXQ6IDEsXG4gICAgICAgICAgYW1vdW50OiAnMTAxMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOlxuICAgICAgICAgICAgJzB4MDZmZDBiMWY4ODU5YTQwZDlmYjJkMWE2NWQ1NGRhNWQ2NDVhMWQ4MWJiYjhjMWM1YjAzNzA1MTg0M2VjMGQzYzIyNDMzZWM3ZjUwY2M5N2ZhMDQxY2JmOGQ5ZmY1ZGRmN2VkNDFmNzJhMDhmYTNmMTk4M2ZkNjUxYTMzYTQ0NDEnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA3MTg3NTAwMDAwLFxuICAgICAgICAgIHR5cGU6ICdFeHBvcnQnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICAgIHR4UHJlYnVpbGQuaG9wVHJhbnNhY3Rpb24uc2lnbmF0dXJlID0gaG9wRXhwb3J0VHhCaXRnb1NpZ25hdHVyZTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBzdWNjZXNzZnVsbHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHZlcmlmeUF2YXhjVHJhbnNhY3Rpb25PcHRpb25zID0geyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfTtcbiAgICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgdGF2YXhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHZlcmlmeUF2YXhjVHJhbnNhY3Rpb25PcHRpb25zKTtcbiAgICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IGZvciBhbW91bnQgcGx1cyAxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2ZXJpZnlBdmF4Y1RyYW5zYWN0aW9uT3B0aW9ucyA9IHtcbiAgICAgICAgICB0eFBhcmFtczogeyAuLi50eFBhcmFtcywgcmVjaXBpZW50czogW3sgYW1vdW50OiBhbW91bnQgKyAxZTksIGFkZHJlc3M6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyB9XSB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCB0YXZheENvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24odmVyaWZ5QXZheGNUcmFuc2FjdGlvbk9wdGlvbnMpXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgICBgSG9wIGFtb3VudDogJHthbW91bnQgLyAxZTkgKyBpbXBvcnRUeEZlZX0gZG9lcyBub3QgZXF1YWwgb3JpZ2luYWwgYW1vdW50OiAke1xuICAgICAgICAgICAgICBhbW91bnQgLyAxZTkgKyBpbXBvcnRUeEZlZSArIDFcbiAgICAgICAgICAgIH1gXG4gICAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IGZvciBjaGFuZ2VkIHByZWJ1aWxkIGhvcCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2ZXJpZnlBdmF4Y1RyYW5zYWN0aW9uT3B0aW9ucyA9IHtcbiAgICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IC4uLnR4UHJlYnVpbGQsIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IGFkZHJlc3MyLCBhbW91bnQ6ICcxMDIwMDAwNTAwMDAwMDAwMDAnIH1dIH0sXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgdGF2YXhDb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHZlcmlmeUF2YXhjVHJhbnNhY3Rpb25PcHRpb25zKVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKGByZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGhvcCBhZGRyZXNzYCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHZlcmlmeSBmb3IgY2hhbmdlZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBob3BEZXN0aW5hdGlvbkFkZHJlc3NEaWZmID1cbiAgICAgICAgICAnUC1mdWppMTN2a3d4d3FzcTA3bHM2Z3E4cTl5YWpydDhwOTQ2aHllNXpxM3czflAtZnVqaTE3OGF0ejVwM3hoYWJnZ2x5Z3QyN25kZTZoNHR6OWxzem53cTJkaH5QLWZ1amkxa2w3cDdlZnpwd2Rxa3Q2cno0dXQzd213dXljdDc0MzZxNmw5aDYnO1xuICAgICAgICBjb25zdCB2ZXJpZnlBdmF4Y1RyYW5zYWN0aW9uT3B0aW9ucyA9IHtcbiAgICAgICAgICB0eFBhcmFtczogeyAuLi50eFBhcmFtcywgcmVjaXBpZW50czogW3sgYW1vdW50OiBhbW91bnQsIGFkZHJlc3M6IGhvcERlc3RpbmF0aW9uQWRkcmVzc0RpZmYgfV0gfSxcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IHRhdmF4Q29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih2ZXJpZnlBdmF4Y1RyYW5zYWN0aW9uT3B0aW9ucylcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAgIGBIb3AgZGVzdGluYXRpb246ICR7aG9wRGVzdGluYXRpb25BZGRyZXNzfSBkb2VzIG5vdCBlcXVhbCBvcmlnaW5hbCByZWNpcGllbnQ6ICR7aG9wRGVzdGluYXRpb25BZGRyZXNzRGlmZn1gXG4gICAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBpZiB3YWxsZXRJZCBpcyB1c2VkIGluc3RlYWQgb2YgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdmVyaWZ5QXZheGNUcmFuc2FjdGlvbk9wdGlvbnMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgLi4udHhQYXJhbXMsIHJlY2lwaWVudHM6IFt7IGFtb3VudDogYW1vdW50LCB3YWxsZXRJZDogJ3NhbWUgd2FsbGV0JyB9XSB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgdGF2YXhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHZlcmlmeUF2YXhjVHJhbnNhY3Rpb25PcHRpb25zKTtcbiAgICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBjbGllbnQgdHhQYXJhbXMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG51bGw7XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RhdmF4YycsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCB0eFByZWJ1aWxkIHRoYXQgaXMgYm90aCBiYXRjaCBhbmQgaG9wJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdGF2YXhDb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0YXZheGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMjc3MzkyODE5NicsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IHRhdmF4Q29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3R4IGNhbm5vdCBiZSBib3RoIGEgYmF0Y2ggYW5kIGhvcCB0cmFuc2FjdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIHdpdGggbW9yZSB0aGFuIG9uZSByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0YXZheENvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGF2YXhjJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCB0YXZheENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIGB0YXZheGMgZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBob3AgdHhQcmVidWlsZCB0aGF0IGRvZXMgbm90IHNlbmQgdG8gaXRzIGhvcCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdGF2YXhDb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGF2YXhjJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzAnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCB0YXZheENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdyZWNpcGllbnQgYWRkcmVzcyBvZiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGhvcCBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0YXZheENvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0YXZheGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IHRhdmF4Q29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ25vcm1hbCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdGF2YXhDb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGF2YXhjJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCB0YXZheENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdkZXN0aW5hdGlvbiBhZGRyZXNzIGluIG5vcm1hbCB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoYXQgaW4gdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0b2tlbiB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRhdmF4Q29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RhdmF4YycsXG4gICAgICAgIHRva2VuOiAndGVzdCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgdGF2YXhDb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgY29pbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRhdmF4Q29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ2J0YycsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgdGF2YXhDb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnY29pbiBpbiB0eFByZWJ1aWxkIGRpZCBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0hvcCBUcmFuc2FjdGlvbiBQYXJhbWV0ZXJzJywgKCkgPT4ge1xuICAgIGNvbnN0IHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBob3AgdHJhbnNhY3Rpb24gcGFyYW1ldGVycyB3aXRoIGdhc1ByaWNlTWF4ID4gMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tGZWVFc3RpbWF0ZSA9IHtcbiAgICAgICAgZmVlRXN0aW1hdGU6ICcxMjAwMDAnLFxuICAgICAgICBnYXNMaW1pdEVzdGltYXRlOiA1MDAwMDAsXG4gICAgICB9O1xuICAgICAgc2FuZEJveC5zdHViKHRhdmF4Q29pbiwgJ2ZlZUVzdGltYXRlJykucmVzb2x2ZXMobW9ja0ZlZUVzdGltYXRlKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICAgJ1AtZnVqaTE0eGEwcTQ4NThjdDNrZnZwa3dudzJkeXMzbTYza3Q2ZmFtY2tmNn5QLWZ1amkxaGxqeWUza2VzanRwajg3bTAwZTh2d2theWc2ZXlzNnRoZXV4Zmd+UC1mdWppMWxlbHF4NGNsZWgzZHprNWtwbHN0ejZtd3J0M2R1azdkN3d3bXBwJyxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGF2YXhDb2luLmNyZWF0ZUhvcFRyYW5zYWN0aW9uUGFyYW1zKHtcbiAgICAgICAgcmVjaXBpZW50cyxcbiAgICAgICAgdHlwZTogJ0V4cG9ydCcgYXMga2V5b2YgdHlwZW9mIFRyYW5zYWN0aW9uVHlwZSxcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hvcFBhcmFtcycpO1xuICAgICAgcmVzdWx0LmhvcFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0aWVzKFsndXNlclJlcVNpZycsICdnYXNQcmljZU1heCcsICdwYXltZW50SWQnLCAnZ2FzTGltaXQnXSk7XG4gICAgICByZXN1bHQuaG9wUGFyYW1zLnVzZXJSZXFTaWcuc2hvdWxkLmVxdWFsKCcweCcpO1xuICAgICAgcmVzdWx0LmhvcFBhcmFtcy5nYXNQcmljZU1heC5zaG91bGQuYmUuYWJvdmUoMCk7XG4gICAgICByZXN1bHQuaG9wUGFyYW1zLnBheW1lbnRJZC5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgIHJlc3VsdC5ob3BQYXJhbXMuZ2FzTGltaXQuc2hvdWxkLmVxdWFsKDUwMDAwMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIGhhbGYgc2lnbmVkIGltcG9ydCBpbiBDIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdERhdGEgPSBJTVBPUlRfQztcbiAgICAgIGNvbnN0IHR4RXhwbGFpbiA9IGF3YWl0IHRhdmF4Q29pbi5leHBsYWluVHJhbnNhY3Rpb24oeyB0eEhleDogdGVzdERhdGEuaGFsZnNpZ250eEhleCwgY3Jvc3NDaGFpblR5cGU6ICdpbXBvcnQnIH0pO1xuICAgICAgdHhFeHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoKE51bWJlcih0ZXN0RGF0YS5hbW91bnQpIC0gdHhFeHBsYWluLmZlZT8uZmVlKS50b1N0cmluZygpKTtcbiAgICAgIHR4RXhwbGFpbi50eXBlLnNob3VsZC5lcXVhbChUcmFuc2FjdGlvblR5cGUuSW1wb3J0KTtcbiAgICAgIHR4RXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnRvKTtcbiAgICAgIHR4RXhwbGFpbi5jaGFuZ2VPdXRwdXRzLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdCh0eEV4cGxhaW4ubWVtbyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgaW1wb3J0IGluIEMgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IElNUE9SVF9DO1xuICAgICAgY29uc3QgdHhFeHBsYWluID0gYXdhaXQgdGF2YXhDb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4SGV4OiB0ZXN0RGF0YS5mdWxsc2lnbnR4SGV4LCBjcm9zc0NoYWluVHlwZTogJ2ltcG9ydCcgfSk7XG4gICAgICB0eEV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgoTnVtYmVyKHRlc3REYXRhLmFtb3VudCkgLSB0eEV4cGxhaW4uZmVlPy5mZWUpLnRvU3RyaW5nKCkpO1xuICAgICAgdHhFeHBsYWluLnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5JbXBvcnQpO1xuICAgICAgdHhFeHBsYWluLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEudG8pO1xuICAgICAgdHhFeHBsYWluLmNoYW5nZU91dHB1dHMuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHR4RXhwbGFpbi5tZW1vKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHVuc2lnbmVkIGV4cG9ydCBpbiBDIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaW1wb3J0SW5QRmVlID0gMTAwMDAwMDtcbiAgICAgIGNvbnN0IHRlc3REYXRhID0gRVhQT1JUX0M7XG4gICAgICBjb25zdCB0eEV4cGxhaW4gPSBhd2FpdCB0YXZheENvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHsgdHhIZXg6IHRlc3REYXRhLnVuc2lnbmVkVHhIZXgsIGNyb3NzQ2hhaW5UeXBlOiAnZXhwb3J0JyB9KTtcbiAgICAgIHR4RXhwbGFpbi5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKChOdW1iZXIodGVzdERhdGEuYW1vdW50KSArIGltcG9ydEluUEZlZSkudG9TdHJpbmcoKSk7XG4gICAgICB0eEV4cGxhaW4udHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCk7XG4gICAgICB0eEV4cGxhaW4uaW5wdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLmNIZXhBZGRyZXNzKTtcbiAgICAgIHR4RXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLnBBZGRyZXNzZXMuc2xpY2UoKS5zb3J0KCkuam9pbignficpKTtcbiAgICAgIHR4RXhwbGFpbi5mZWUuZmVlLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5mZWUpO1xuICAgICAgdHhFeHBsYWluLmNoYW5nZU91dHB1dHMuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHR4RXhwbGFpbi5tZW1vKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCBleHBvcnQgaW4gQyB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGltcG9ydEluUEZlZSA9IDEwMDAwMDA7XG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IEVYUE9SVF9DO1xuICAgICAgY29uc3QgdHhFeHBsYWluID0gYXdhaXQgdGF2YXhDb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4SGV4OiB0ZXN0RGF0YS5mdWxsc2lnbnR4SGV4LCBjcm9zc0NoYWluVHlwZTogJ2V4cG9ydCcgfSk7XG4gICAgICB0eEV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgoTnVtYmVyKHRlc3REYXRhLmFtb3VudCkgKyBpbXBvcnRJblBGZWUpLnRvU3RyaW5nKCkpO1xuICAgICAgdHhFeHBsYWluLnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5FeHBvcnQpO1xuICAgICAgdHhFeHBsYWluLmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5jSGV4QWRkcmVzcyk7XG4gICAgICB0eEV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5wQWRkcmVzc2VzLnNsaWNlKCkuc29ydCgpLmpvaW4oJ34nKSk7XG4gICAgICB0eEV4cGxhaW4uZmVlLmZlZS5zaG91bGQuZXF1YWwodGVzdERhdGEuZmVlKTtcbiAgICAgIHR4RXhwbGFpbi5jaGFuZ2VPdXRwdXRzLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdCh0eEV4cGxhaW4ubWVtbyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRPRE8oQkctNTYxMzYpOiBtb3ZlIHRvIG1vZHVsZXMvYml0Z28vdGVzdC92Mi9pbnRlZ3JhdGlvbi9jb2lucy9hdmF4Yy50c1xuICBkZXNjcmliZSgnUmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gY29udHJhY3QgYWRkcmVzcyBmb3IgJ3RhdmF4YzpsaW5rJ1xuICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4MGI5ZDVkOTEzNjg1NWY2ZmVjM2MwOTkzZmVlNmU5Y2U4YTI5Nzg0Nic7XG4gICAgY29uc3Qgc2VxdWVuY2VJZERhdGEgPSAnMHhhMGI3OTY3Yic7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNhbGxCYWNrID0gc2FuZEJveC5zdHViKEF2YXhDLnByb3RvdHlwZSwgJ3JlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnknIGFzIGtleW9mIEF2YXhDKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2dldFRyYW5zYWN0aW9uQ291bnQnLFxuICAgICAgICAgIHBhcmFtczogWycweGRmZDk1ZDAxZmM5YzJjYjc0NGUyODUyMjU2Mzg1YmJlNmQ4N2I3MmInLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh7IGpzb25ycGM6ICcyLjAnLCBpZDogMSwgcmVzdWx0OiAnMHgwJyB9KTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2dldFRyYW5zYWN0aW9uQ291bnQnLFxuICAgICAgICAgIHBhcmFtczogWycweDI5ZDk3Y2UzNDQ1OTk4MjUyMjBhNTRhNGJkZjdiOGFhN2NhMTRmZDEnLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh7IGpzb25ycGM6ICcyLjAnLCBpZDogMSwgcmVzdWx0OiAnMHg3JyB9KTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2dldEJhbGFuY2UnLFxuICAgICAgICAgIHBhcmFtczogWycweGRmZDk1ZDAxZmM5YzJjYjc0NGUyODUyMjU2Mzg1YmJlNmQ4N2I3MmInLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh7IGpzb25ycGM6ICcyLjAnLCBpZDogMSwgcmVzdWx0OiAnMHgwJyB9KTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2dldEJhbGFuY2UnLFxuICAgICAgICAgIHBhcmFtczogWycweDI5ZDk3Y2UzNDQ1OTk4MjUyMjBhNTRhNGJkZjdiOGFhN2NhMTRmZDEnLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh7IGpzb25ycGM6ICcyLjAnLCBpZDogMSwgcmVzdWx0OiAnMHgzMTVmOGNiOWJjMmVjMDAnIH0pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdldGhfZ2V0QmFsYW5jZScsXG4gICAgICAgICAgcGFyYW1zOiBbJzB4ZTBiMWZlMDk4MDUwZjI3NDViNDUwZGU0MTliNWNhZmM3ZTgyNjY5OScsICdsYXRlc3QnXSxcbiAgICAgICAgICBpZDogMSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKHsganNvbnJwYzogJzIuMCcsIGlkOiAxLCByZXN1bHQ6ICcweDAnIH0pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdldGhfY2FsbCcsXG4gICAgICAgICAgcGFyYW1zOiBbeyB0bzogJzB4ZTBiMWZlMDk4MDUwZjI3NDViNDUwZGU0MTliNWNhZmM3ZTgyNjY5OScsIGRhdGE6ICcweGEwYjc5NjdiJyB9LCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgICAgcmVzdWx0OiAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmJyxcbiAgICAgICAgfSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIG1ldGhvZDogJ2V0aF9nZXRUcmFuc2FjdGlvbkNvdW50JyxcbiAgICAgICAgICBwYXJhbXM6IFtyZWNvdmVyeVVzZXJzLmhvdFdhbGxldFJlY292ZXJ5VXNlci5iYWNrdXBLZXlBZGRyZXNzLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5hZGRyZXNzTm9uY2VSZXNwb25zZTEpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgICBqc29ucnBjOiAnMi4wJyxcbiAgICAgICAgICBtZXRob2Q6ICdldGhfZ2V0VHJhbnNhY3Rpb25Db3VudCcsXG4gICAgICAgICAgcGFyYW1zOiBbcmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLmJhY2t1cEtleUFkZHJlc3MsICdsYXRlc3QnXSxcbiAgICAgICAgICBpZDogMSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NOb25jZVJlc3BvbnNlMik7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIG1ldGhvZDogJ2V0aF9nZXRCYWxhbmNlJyxcbiAgICAgICAgICBwYXJhbXM6IFtyZWNvdmVyeVVzZXJzLmhvdFdhbGxldFJlY292ZXJ5VXNlci5iYWNrdXBLZXlBZGRyZXNzLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5iYWNrdXBBZGRyZXNzQmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2dldEJhbGFuY2UnLFxuICAgICAgICAgIHBhcmFtczogW3JlY292ZXJ5VXNlcnMuY29sZFdhbGxldFJlY292ZXJ5VXNlci5iYWNrdXBLZXlBZGRyZXNzLCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5iYWNrdXBBZGRyZXNzQmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2NhbGwnLFxuICAgICAgICAgIHBhcmFtczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0bzogdG9rZW5Db250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgICAgIGRhdGE6IG9wdGlvbmFsRGVwcy5ldGhVdGlsLmFkZEhleFByZWZpeChcbiAgICAgICAgICAgICAgICBvcHRpb25hbERlcHMuZXRoQWJpXG4gICAgICAgICAgICAgICAgICAuc2ltcGxlRW5jb2RlKCdiYWxhbmNlT2YoYWRkcmVzcyknLCByZWNvdmVyeVVzZXJzLmhvdFdhbGxldFJlY292ZXJ5VXNlci53YWxsZXRDb250cmFjdEFkZHJlc3MpXG4gICAgICAgICAgICAgICAgICAudG9TdHJpbmcoJ2hleCcpXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2xhdGVzdCcsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBpZDogMSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NUb2tlbkJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIG1ldGhvZDogJ2V0aF9jYWxsJyxcbiAgICAgICAgICBwYXJhbXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdG86IHRva2VuQ29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgICAgICBkYXRhOiBvcHRpb25hbERlcHMuZXRoVXRpbC5hZGRIZXhQcmVmaXgoXG4gICAgICAgICAgICAgICAgb3B0aW9uYWxEZXBzLmV0aEFiaVxuICAgICAgICAgICAgICAgICAgLnNpbXBsZUVuY29kZSgnYmFsYW5jZU9mKGFkZHJlc3MpJywgcmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcylcbiAgICAgICAgICAgICAgICAgIC50b1N0cmluZygnaGV4JylcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnbGF0ZXN0JyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGlkOiAxLFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc1Rva2VuQmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncyh7XG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZXRoX2NhbGwnLFxuICAgICAgICAgIHBhcmFtczogW3sgdG86IHJlY292ZXJ5VXNlcnMuaG90V2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcywgZGF0YTogc2VxdWVuY2VJZERhdGEgfSwgJ2xhdGVzdCddLFxuICAgICAgICAgIGlkOiAxLFxuICAgICAgICB9KVxuICAgICAgICAucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMuc2VxdWVuY2VJZFJlc3BvbnNlMSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3Moe1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIG1ldGhvZDogJ2V0aF9jYWxsJyxcbiAgICAgICAgICBwYXJhbXM6IFt7IHRvOiByZWNvdmVyeVVzZXJzLmNvbGRXYWxsZXRSZWNvdmVyeVVzZXIud2FsbGV0Q29udHJhY3RBZGRyZXNzLCBkYXRhOiBzZXF1ZW5jZUlkRGF0YSB9LCAnbGF0ZXN0J10sXG4gICAgICAgICAgaWQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5zZXF1ZW5jZUlkUmVzcG9uc2UyKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdOb24tQml0R28nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGVycm9yIHdoZW4gdGhlIGJhY2t1cCBrZXkgaXMgdW5mdW5kZWQgKGNhbm5vdCBwYXkgZ2FzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgdGF2YXhDb2luXG4gICAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAgICAgJ3tcIml2XCI6XCJudGQ5L3VyRmpyeXF4ZDRyelJFQjJRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJMVHFaNDdiMUJ3RT1cIixcImN0XCI6XCJKU2JKSUJUa0hvS1IzTFxcbicgK1xuICAgICAgICAgICAgICAnb1QyUVRrRHgzWDFPQklQeGlTTDZXb01pSXJLQSthS1RnbXV0WG5XQzJHVEVJeWZiTGVhanc2RDJVWitVMFk4dml2N21nSVRnU3oxXFxuJyArXG4gICAgICAgICAgICAgICd1OUdkajk3QnRtOFdzWjBlK0ttc2JkQi9nWXVjQ1pvUFVaQ0ZxRzRiRWtkZlo4WnZESTlYdlZ2NHhQek5iL0FvU2lqb3NBPVwifScsXG4gICAgICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgICAgICd7XCJpdlwiOlwiQXhzK0c5Z3NaNVBFTlVIeDFZWTVjZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiYXdRc2hVdkZpN1E9XCIsXCJjdFwiOlwic1dRMGJIbXJ1VVRJOENcXG4nICtcbiAgICAgICAgICAgICAgJ2x3R25lSE9iZE5mbzNXUS9tcnozcDg0Rm8wN0hnaXp2Z0xkK0Uzd0ZBM1oxTFJiSG96Umpmc3RWL3FKTVJxckZ2RWdLT2NHK1NLZFxcbicgK1xuICAgICAgICAgICAgICAnZ3g2QmJtWFdmS2hGSEVlclNZbHVCZ1U1T3JYTWZPa2JFeG5NeXdFV3JDS0V2b05MK3d5TkhvUmFNTmJiRG9nbzM2SjhQRT1cIn0nLFxuICAgICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHgyMmMxYWI0NDM3MTk4NWU0OTI5NGQxYTQwZTkyYzhhZDAwZjViZThlJyxcbiAgICAgICAgICAgIC8vIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ0doZ2hqa2chNDU1NTQ0bGxsbCcsXG4gICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnMHg5NGI1MWViYjhjM2I5MDQwNGFkMjYyZjQyYzE1ODhiZDk0MjQyZWNiJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweGRmZDk1ZDAxZmM5YzJjYjc0NGUyODUyMjU2Mzg1YmJlNmQ4N2I3MmIgaGFzIGJhbGFuY2UgMCBHd2VpLlRoaXMgYWRkcmVzcyBtdXN0IGhhdmUgYSBiYWxhbmNlIG9mIGF0IGxlYXN0IDEwMDAwMDAwIEd3ZWkgdG8gcGVyZm9ybSByZWNvdmVyaWVzLiBUcnkgc2VuZGluZyBzb21lIEFWQVggdG8gdGhpcyBhZGRyZXNzIHRoZW4gcmV0cnkuJ1xuICAgICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCByZWNvdmVyeSB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCB0YXZheENvaW4ucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwibzI3cEJsN0lQK2liZTM5eFlnL2NYZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIjk5MlI2cGFkZjJJPVwiLFwiY3RcIjpcIjZ3a24xUGR3dFdjQ1dSXFxuJyArXG4gICAgICAgICAgICAnVmRPZGFpR01DTVM1Umh1ckdJOWVGNHRkZ3phTXpPcGd3NTZlWVJtS1R6bGRqNVZoMUNuejZSb3FGbFZTZm53Uit0RmpPeXFEbjNPXFxuJyArXG4gICAgICAgICAgICAnOEszTlVENVlsTUdvQ2RmdmNyQ2JQRjN0Q2RLbDJEeW9MditaV1BvNXNLVmpqZ1VPWmdJN3BuN2lCdFhSRHZxYVd5bGF3WT1cIn0nLFxuICAgICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwibXdqOWxkOHN2Z1JCc1dTKzVOWlFxQT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIlh1TXhicWEveU5nPVwiLFwiY3RcIjpcImxxTG5qc1ZTQlIvNHVlXFxuJyArXG4gICAgICAgICAgICAnenRZYWhBdkVFVitsdERYTG95SUVNQ21GTXljYmErM21QdGlBTThIckYvODRBekpPandLeXZLMXBtK0NGdXVXQ1RYc3NBUXhSQ3VjXFxuJyArXG4gICAgICAgICAgICAnSHVqckJ2ckt1blk0aGZJSkhKc3lCcitsMVBOTlNVQi9hWUwxYVcvbjd0ZHZ3TDhmT0NOcUZxRVBCQ2J4WG9PbFNnQ0FVdz1cIn0nLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJzB4ZTBiMWZlMDk4MDUwZjI3NDViNDUwZGU0MTliNWNhZmM3ZTgyNjY5OScsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ0doZ2hqa2chNDU1NTQ0bGxsbCcsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJzB4OTRiNTFlYmI4YzNiOTA0MDRhZDI2MmY0MmMxNTg4YmQ5NDI0MmVjYicsXG4gICAgICAgICAgZ2FzUHJpY2U6ICczMDAwMDAwMDAwMCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGlkIGFuZCB0eCB3aWxsIGFsd2F5cyBiZSBkaWZmZXJlbnQgYmVjYXVzZSBvZiBleHBpcmVUaW1lXG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gdGF2YXhDb2luLmdldFRyYW5zYWN0aW9uQnVpbGRlcigpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgICAgdHhCdWlsZGVyLmZyb20ocmVjb3ZlcnkudHgpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1Vuc2lnbmVkIFN3ZWVwJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdXNlclhwcnYgPVxuICAgICAgICAneHBydjlzMjFaclFIMTQzSzNmWlZSZm14dnI3WUJvZEY0alNjemdLVTZSb0RVenZLbkZpRnoybWN1S2d3MXpZZ3ZUR3RMTUJQQVBvbnY1R3pIbkRYUUs1Vms4QlJIY043NlRHZ0x3Y05jRlR5NGtDJztcbiAgICAgIGNvbnN0IHVzZXJYcHViID1cbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHOWR4WGhKeUh6NEdqcVRqVUNBVU11RjR0cENxM0xUSmY0M1FYYTVzVDgxUXNKNVZNZEs4dm5BSzU2Z2k3cXkyY1oyZHpZUWZ5N1lQN3g0dUhRcHVSVmlBdjlDTmJ0Uyc7XG4gICAgICBjb25zdCBiYWNrdXBYcHJ2ID1cbiAgICAgICAgJ3hwcnY5czIxWnJRSDE0M0s0TjZZQmpvb2E2VHgzVTdoek0zU3ZIRkE4WFAyM3FZaFE2S1BMbzJRZ1hUU2FzVnBpTVk0RjZnTXJzdFhCSFJEc281V0U3R24zN3lablc1cVRSSlpVNkZQZVh4MUI2OSc7XG4gICAgICBjb25zdCBiYWNrdXBYcHViID1cbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHckIxSG1Mb3dFUWdiVnhDUG9tSkhXQWt2dW5kY0I1Z0d0ZVh0TExmRUttdlNCOWRLdlJtaDNMeHBMMnl2Z3F5MzdaM3lkcXZIb1ZpTVdhMmR3WDNodXdtbUJ1aXA3Sic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSAnMHhlMGIxZmUwOTgwNTBmMjc0NWI0NTBkZTQxOWI1Y2FmYzdlODI2Njk5JztcbiAgICAgIGNvbnN0IHJlY292ZXJ5RGVzdGluYXRpb24gPSAnMHg5NGI1MWViYjhjM2I5MDQwNGFkMjYyZjQyYzE1ODhiZDk0MjQyZWNiJztcbiAgICAgIGNvbnN0IGdhc1ByaWNlID0gJzI1MDAwMDAwMDAwJztcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBzd2VlcCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCB0YXZheENvaW4ucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogdXNlclhwdWIsXG4gICAgICAgICAgYmFja3VwS2V5OiBiYWNrdXBYcHViLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGdhc1ByaWNlLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcGFyc2VkVHggPSBwYXJzZVRyYW5zYWN0aW9uKHJlY292ZXJ5LnR4SGV4KTtcblxuICAgICAgICBjb25zdCBkZWNvZGVkU2VuZE11bHRpc2lnQ2FsbERhdGEgPSBkZWNvZGVUcmFuc2FjdGlvbihKU09OLnN0cmluZ2lmeSh3YWxsZXRTaW1wbGVBQkkpLCBwYXJzZWRUeC5kYXRhKTtcblxuICAgICAgICBjb25zdCBzYWZlVHJhbnNmZXJGcm9tQ2FsbERhdGEgPSBkZWNvZGVkU2VuZE11bHRpc2lnQ2FsbERhdGEuYXJnc1syXTtcbiAgICAgICAgY29uc3Qgc2FmZVRyYW5zZmVyRnJvbURlc3RpbmF0aW9uID0gZGVjb2RlZFNlbmRNdWx0aXNpZ0NhbGxEYXRhLmFyZ3NbMF07XG4gICAgICAgIHNhZmVUcmFuc2ZlckZyb21EZXN0aW5hdGlvbi50b0xvd2VyQ2FzZSgpLnNob3VsZC5lcXVhbChyZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICAgICAgc2FmZVRyYW5zZmVyRnJvbUNhbGxEYXRhLnNob3VsZC5iZS5lcXVhbCgnMHgnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydGllcygndHhIZXgnLCAndXNlcktleScsICdiYWNrdXBLZXknKTtcbiAgICAgICAgcmVjb3ZlcnkucmVjaXBpZW50cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICByZWNvdmVyeS5yZWNpcGllbnRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgICAgICByZWNvdmVyeS53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKHdhbGxldENvbnRyYWN0QWRkcmVzcyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhZGQgYSBzZWNvbmQgc2lnbmF0dXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IHRhdmF4Q29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB1c2VyWHB1YixcbiAgICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cFhwdWIsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgZ2FzUHJpY2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgdHhIZXg6IHJlY292ZXJ5LnR4SGV4LFxuICAgICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICAgIGJhY2t1cEtleTogYmFja3VwWHB1YixcbiAgICAgICAgICBjb2luOiByZWNvdmVyeS5jb2luLFxuICAgICAgICAgIGdhc1ByaWNlOiByZWNvdmVyeS5nYXNQcmljZSxcbiAgICAgICAgICBnYXNMaW1pdDogcmVjb3ZlcnkuZ2FzTGltaXQsXG4gICAgICAgICAgcmVjaXBpZW50czogcmVjb3ZlcnkucmVjaXBpZW50cyxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHJlY292ZXJ5LndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBhbW91bnQ6IHJlY292ZXJ5LmFtb3VudCxcbiAgICAgICAgICBiYWNrdXBLZXlOb25jZTogcmVjb3ZlcnkuYmFja3VwS2V5Tm9uY2UsXG4gICAgICAgICAgcmVjaXBpZW50OiByZWNvdmVyeS5yZWNpcGllbnQsXG4gICAgICAgICAgZXhwaXJlVGltZTogcmVjb3ZlcnkuZXhwaXJlVGltZSxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IHJlY292ZXJ5LmNvbnRyYWN0U2VxdWVuY2VJZCxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiByZWNvdmVyeS5uZXh0Q29udHJhY3RTZXF1ZW5jZUlkLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFByZWJ1aWxkLFxuICAgICAgICAgIHBydjogdXNlclhwcnYsXG4gICAgICAgIH07XG4gICAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gb25jZVxuICAgICAgICBjb25zdCBoYWxmU2lnbmVkID0gYXdhaXQgdGF2YXhDb2luLnNpZ25UcmFuc2FjdGlvbihwYXJhbXMpO1xuXG4gICAgICAgIGNvbnN0IHdyYXBwZXIgPSB7fSBhcyBBdmF4U2lnblRyYW5zYWN0aW9uT3B0aW9ucztcbiAgICAgICAgd3JhcHBlci50eFByZWJ1aWxkID0gaGFsZlNpZ25lZDtcbiAgICAgICAgd3JhcHBlci5pc0xhc3RTaWduYXR1cmUgPSB0cnVlO1xuICAgICAgICB3cmFwcGVyLndhbGxldENvbnRyYWN0QWRkcmVzcyA9IHdhbGxldENvbnRyYWN0QWRkcmVzcztcbiAgICAgICAgd3JhcHBlci5wcnYgPSBiYWNrdXBYcHJ2O1xuXG4gICAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb24gdHdpY2Ugd2l0aCB0aGUgXCJpc0xhc3RTaWduYXR1cmVcIiBmbGFnXG4gICAgICAgIGNvbnN0IGZpbmFsU2lnbmVkVHggPSBhd2FpdCB0YXZheENvaW4uc2lnblRyYW5zYWN0aW9uKHdyYXBwZXIpO1xuICAgICAgICBmaW5hbFNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSB0YXZheENvaW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCkgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIuZnJvbShmaW5hbFNpZ25lZFR4LnR4SGV4KTtcbiAgICAgICAgY29uc3QgcmVidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHJlYnVpbHRUeC5zaWduYXR1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgcmVidWlsdFR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgcmVidWlsdFR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodHhQcmVidWlsZC5yZWNpcGllbnQuYWRkcmVzcyk7XG4gICAgICAgIHJlYnVpbHRUeC5vdXRwdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCh0eFByZWJ1aWxkLnJlY2lwaWVudC5hbW91bnQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVG9rZW4gUmVjb3ZlcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkZXN0QWRkciA9ICcweGM3NGIxYzBlZTkwYTQ4MWI1MjgyNTMwNDJjZTMyMjhhOGNkNjg3M2UnO1xuICAgICAgY29uc3Qgd2VpVG9Hd2VpID0gMTAgKiogOTtcbiAgICAgIGNvbnN0IGdhc1ByaWNlID0gMzAgKiB3ZWlUb0d3ZWk7XG4gICAgICAvLyBjb250cmFjdCBhZGRyZXNzIGZvciAndGF2YXhjOmxpbmsnXG4gICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweDBiOWQ1ZDkxMzY4NTVmNmZlYzNjMDk5M2ZlZTZlOWNlOGEyOTc4NDYnO1xuICAgICAgY29uc3QgdG9rZW5OYW1lID0gJ3RhdmF4YzpsaW5rJztcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB0b2tlbiByZWNvdmVyeSB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIHVzZXJLZXk6IHJlY292ZXJ5VXNlcnMuaG90V2FsbGV0UmVjb3ZlcnlVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiByZWNvdmVyeVVzZXJzLmhvdFdhbGxldFJlY292ZXJ5VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdEFkZHIsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcmVjb3ZlcnlVc2Vycy5ob3RXYWxsZXRSZWNvdmVyeVVzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHJlY292ZXJ5VXNlcnMuaG90V2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBnYXNQcmljZTogZ2FzUHJpY2UudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCB0YXZheENvaW4ucmVjb3ZlcihwYXJhbXMpO1xuXG4gICAgICAgIHJlY292ZXJ5VHhuLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICAgIHJlY292ZXJ5VHhuLnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSB0YXZheENvaW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCkgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIuZnJvbShyZWNvdmVyeVR4bi50eCk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgICB0eC5pbnB1dHMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwocmVjb3ZlcnlVc2Vycy5ob3RXYWxsZXRSZWNvdmVyeVVzZXIud2FsbGV0Q29udHJhY3RBZGRyZXNzKTtcbiAgICAgICAgdHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbChcbiAgICAgICAgICBuZXcgQk4oZW5kcG9pbnRSZXNwb25zZXMuYWRkcmVzc1Rva2VuQmFsYW5jZVJlc3BvbnNlLnJlc3VsdC5zbGljZSgyKSwgMTYpLnRvU3RyaW5nKDEwKVxuICAgICAgICApO1xuICAgICAgICB0eC5pbnB1dHNbMF0uY29pbj8uc2hvdWxkLmVxdWFsKHRva2VuTmFtZSk7XG4gICAgICAgIHR4Lm91dHB1dHMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgICB0eC5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RBZGRyKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoXG4gICAgICAgICAgbmV3IEJOKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NUb2tlbkJhbGFuY2VSZXNwb25zZS5yZXN1bHQuc2xpY2UoMiksIDE2KS50b1N0cmluZygxMClcbiAgICAgICAgKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS5jb2luPy5zaG91bGQuZXF1YWwodG9rZW5OYW1lKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIHVuc2lnbmVkIHN3ZWVwIHRva2VuIHJlY292ZXJ5IHR4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdXNlcktleTogcmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLnVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5OiByZWNvdmVyeVVzZXJzLmNvbGRXYWxsZXRSZWNvdmVyeVVzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHJlY292ZXJ5VXNlcnMuY29sZFdhbGxldFJlY292ZXJ5VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogcmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgICBnYXNQcmljZTogZ2FzUHJpY2UudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCB0YXZheENvaW4ucmVjb3ZlcihwYXJhbXMpO1xuXG4gICAgICAgIHJlY292ZXJ5VHhuLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICAgIHJlY292ZXJ5VHhuLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW4nKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4udG9rZW4uc2hvdWxkLmVxdWFsKCd0YXZheGM6bGluaycpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSB0YXZheENvaW4uZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKCkgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIuZnJvbShyZWNvdmVyeVR4bi50eEhleCk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gbmV3IEJOKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NUb2tlbkJhbGFuY2VSZXNwb25zZS5yZXN1bHQuc2xpY2UoMiksIDE2KS50b1N0cmluZygxMCk7XG4gICAgICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgICB0eC5pbnB1dHMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwocmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcyk7XG4gICAgICAgIHR4LmlucHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwocmVjb3ZlcnlBbW91bnQpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgICAgdHguaW5wdXRzWzBdLmNvaW4/LnNob3VsZC5lcXVhbCh0b2tlbk5hbWUpO1xuICAgICAgICB0eC5vdXRwdXRzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0QWRkcik7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIG5ldyBCTihlbmRwb2ludFJlc3BvbnNlcy5hZGRyZXNzVG9rZW5CYWxhbmNlUmVzcG9uc2UucmVzdWx0LnNsaWNlKDIpLCAxNikudG9TdHJpbmcoMTApXG4gICAgICAgICk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS5jb2luPy5zaG91bGQuZXF1YWwodG9rZW5OYW1lKTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndXNlcktleScpO1xuICAgICAgICByZWNvdmVyeVR4bi51c2VyS2V5LnNob3VsZC5lcXVhbChyZWNvdmVyeVVzZXJzLmNvbGRXYWxsZXRSZWNvdmVyeVVzZXIudXNlcktleSk7XG4gICAgICAgIHJlY292ZXJ5VHhuLnNob3VsZC5oYXZlLnByb3BlcnR5KCdiYWNrdXBLZXknKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4uYmFja3VwS2V5LnNob3VsZC5lcXVhbChyZWNvdmVyeVVzZXJzLmNvbGRXYWxsZXRSZWNvdmVyeVVzZXIuYmFja3VwS2V5KTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgICByZWNvdmVyeVR4bi5jb2luLnNob3VsZC5lcXVhbCgndGF2YXhjJyk7XG5cbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICAgIHJlY292ZXJ5VHhuLmdhc1ByaWNlLnNob3VsZC5lcXVhbChnYXNQcmljZS50b1N0cmluZygpKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICAgIHJlY292ZXJ5VHhuLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG5cbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4ucmVjaXBpZW50cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICByZWNvdmVyeVR4bi5yZWNpcGllbnRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RBZGRyKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4ucmVjaXBpZW50c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICAgIHJlY292ZXJ5VHhuLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwocmVjb3ZlcnlVc2Vycy5jb2xkV2FsbGV0UmVjb3ZlcnlVc2VyLndhbGxldENvbnRyYWN0QWRkcmVzcyk7XG5cbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgICByZWNvdmVyeVR4bi5hbW91bnQuc2hvdWxkLmVxdWFsKHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50Jyk7XG4gICAgICAgIHJlY292ZXJ5VHhuLnJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0QWRkcik7XG4gICAgICAgIHJlY292ZXJ5VHhuLnJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5Db250cmFjdEFkZHJlc3MnKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4udG9rZW5Db250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKHRva2VuQ29udHJhY3RBZGRyZXNzKTtcblxuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYmFja3VwS2V5Tm9uY2UnKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgICAgcmVjb3ZlcnlUeG4uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgICByZWNvdmVyeVR4bi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbmV4dENvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|