@bitgo/sdk-core 36.42.0 → 36.43.0
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/bitgo/trading/iTradingAccount.d.ts +1 -6
- package/dist/src/bitgo/trading/iTradingAccount.d.ts.map +1 -1
- package/dist/src/bitgo/trading/iTradingAccount.js +1 -1
- package/dist/src/bitgo/trading/network/network.d.ts +1 -1
- package/dist/src/bitgo/trading/network/network.d.ts.map +1 -1
- package/dist/src/bitgo/trading/network/network.js +5 -3
- package/dist/src/bitgo/trading/network/types.d.ts +1 -1
- package/dist/src/bitgo/trading/network/types.d.ts.map +1 -1
- package/dist/src/bitgo/trading/network/types.js +1 -1
- package/dist/src/bitgo/trading/tradingAccount.d.ts +1 -13
- package/dist/src/bitgo/trading/tradingAccount.d.ts.map +1 -1
- package/dist/src/bitgo/trading/tradingAccount.js +2 -32
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +4 -0
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +25 -11
- package/dist/src/bitgo/wallet/iWallet.d.ts +0 -1
- package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/iWallet.js +1 -1
- package/dist/src/coins/ofc.d.ts +1 -15
- package/dist/src/coins/ofc.d.ts.map +1 -1
- package/dist/src/coins/ofc.js +1 -8
- package/dist/src/coins/ofcToken.d.ts +3 -5
- package/dist/src/coins/ofcToken.d.ts.map +1 -1
- package/dist/src/coins/ofcToken.js +4 -14
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +2 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +465 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts +5 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.d.ts.map +1 -0
- package/dist/test/unit/bitgo/utils/tss/ecdsa/gpgKeys.js +36 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/test/unit/bitgo/trading/tradingAccount.d.ts +0 -2
- package/dist/test/unit/bitgo/trading/tradingAccount.d.ts.map +0 -1
- package/dist/test/unit/bitgo/trading/tradingAccount.js +0 -113
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts +0 -2
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.d.ts.map +0 -1
- package/dist/test/unit/bitgo/wallet/ofcWalletSignTransaction.js +0 -70
- package/dist/test/unit/coins/ofc.d.ts +0 -2
- package/dist/test/unit/coins/ofc.d.ts.map +0 -1
- package/dist/test/unit/coins/ofc.js +0 -124
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const assert = __importStar(require("assert"));
|
|
40
|
+
const sinon = __importStar(require("sinon"));
|
|
41
|
+
const crypto_1 = require("crypto");
|
|
42
|
+
const keccak_1 = __importDefault(require("keccak"));
|
|
43
|
+
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
|
|
44
|
+
const sjcl = __importStar(require("@bitgo/sjcl"));
|
|
45
|
+
const src_1 = require("../../../../../../src");
|
|
46
|
+
const gpgKeys_1 = require("./gpgKeys");
|
|
47
|
+
describe('ECDSA MPC v2', async () => {
|
|
48
|
+
let userShare;
|
|
49
|
+
let bitgoShare;
|
|
50
|
+
before('generate key shares for testing', async () => {
|
|
51
|
+
const [userDkgSession, backupDkgSession, bitgoDkgSession] = await sdk_lib_mpc_1.DklsUtils.generateDKGKeyShares();
|
|
52
|
+
assert.ok(userDkgSession);
|
|
53
|
+
assert.ok(backupDkgSession);
|
|
54
|
+
assert.ok(bitgoDkgSession);
|
|
55
|
+
userShare = userDkgSession.getKeyShare();
|
|
56
|
+
bitgoShare = bitgoDkgSession.getKeyShare();
|
|
57
|
+
});
|
|
58
|
+
let ecdsaMPCv2Utils;
|
|
59
|
+
before('initialize EcdsaMPCv2Utils', async () => {
|
|
60
|
+
const mockBg = {};
|
|
61
|
+
mockBg.getEnv = sinon.stub().returns('test');
|
|
62
|
+
mockBg.encrypt = sinon.stub().callsFake((params) => {
|
|
63
|
+
const salt = (0, crypto_1.randomBytes)(8);
|
|
64
|
+
const iv = (0, crypto_1.randomBytes)(16);
|
|
65
|
+
return sjcl.encrypt(params.password, params.input, {
|
|
66
|
+
salt: [bytesToWord(salt.subarray(0, 4)), bytesToWord(salt.subarray(4))],
|
|
67
|
+
iv: [
|
|
68
|
+
bytesToWord(iv.subarray(0, 4)),
|
|
69
|
+
bytesToWord(iv.subarray(4, 8)),
|
|
70
|
+
bytesToWord(iv.subarray(8, 12)),
|
|
71
|
+
bytesToWord(iv.subarray(12, 16)),
|
|
72
|
+
],
|
|
73
|
+
adata: params.adata,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
mockBg.decrypt = sinon.stub().callsFake((params) => {
|
|
77
|
+
return sjcl.decrypt(params.password, params.input);
|
|
78
|
+
});
|
|
79
|
+
const mockCoin = {};
|
|
80
|
+
mockCoin.getHashFunction = sinon.stub().callsFake(() => (0, keccak_1.default)('keccak256'));
|
|
81
|
+
ecdsaMPCv2Utils = new src_1.EcdsaMPCv2Utils(mockBg, mockCoin);
|
|
82
|
+
});
|
|
83
|
+
const walletID = '62fe536a6b4cf70007acb48c0e7bb0b0';
|
|
84
|
+
const walletPassphrase = 'testPass';
|
|
85
|
+
it('should sign a message hash using ECDSA MPC v2 offline rounds', async () => {
|
|
86
|
+
const tMessage = 'testMessage';
|
|
87
|
+
const derivationPath = 'm/0';
|
|
88
|
+
// round 1
|
|
89
|
+
const reqMPCv2SigningRound1 = {
|
|
90
|
+
txRequest: {
|
|
91
|
+
txRequestId: '123456',
|
|
92
|
+
apiVersion: 'full',
|
|
93
|
+
walletId: walletID,
|
|
94
|
+
transactions: [
|
|
95
|
+
{
|
|
96
|
+
unsignedTx: {
|
|
97
|
+
derivationPath,
|
|
98
|
+
signableHex: tMessage,
|
|
99
|
+
},
|
|
100
|
+
signatureShares: [],
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
prv: userShare.toString('base64'),
|
|
105
|
+
walletPassphrase,
|
|
106
|
+
};
|
|
107
|
+
const resMPCv2SigningRound1 = await ecdsaMPCv2Utils.createOfflineRound1Share(reqMPCv2SigningRound1);
|
|
108
|
+
resMPCv2SigningRound1.should.have.property('signatureShareRound1');
|
|
109
|
+
resMPCv2SigningRound1.should.have.property('userGpgPubKey');
|
|
110
|
+
resMPCv2SigningRound1.should.have.property('encryptedRound1Session');
|
|
111
|
+
resMPCv2SigningRound1.should.have.property('encryptedUserGpgPrvKey');
|
|
112
|
+
const encryptedRound1Session = resMPCv2SigningRound1.encryptedRound1Session;
|
|
113
|
+
const encryptedUserGpgPrvKey = resMPCv2SigningRound1.encryptedUserGpgPrvKey;
|
|
114
|
+
const hashBuffer = (0, keccak_1.default)('keccak256').update(Buffer.from(tMessage, 'hex')).digest();
|
|
115
|
+
const bitgoSession = new sdk_lib_mpc_1.DklsDsg.Dsg(bitgoShare, 2, derivationPath, hashBuffer);
|
|
116
|
+
const txRequestRound1 = await signBitgoMPCv2Round1(bitgoSession, reqMPCv2SigningRound1.txRequest, resMPCv2SigningRound1.signatureShareRound1, resMPCv2SigningRound1.userGpgPubKey);
|
|
117
|
+
assert.ok(txRequestRound1.transactions &&
|
|
118
|
+
txRequestRound1.transactions.length === 1 &&
|
|
119
|
+
txRequestRound1.transactions[0].signatureShares.length === 2, 'txRequestRound1.transactions is not an array of length 1 with 2 signatureShares');
|
|
120
|
+
// round 2
|
|
121
|
+
const reqMPCv2SigningRound2 = {
|
|
122
|
+
...reqMPCv2SigningRound1,
|
|
123
|
+
txRequest: txRequestRound1,
|
|
124
|
+
encryptedRound1Session,
|
|
125
|
+
encryptedUserGpgPrvKey,
|
|
126
|
+
bitgoPublicGpgKey: gpgKeys_1.bitgoGpgKey.public,
|
|
127
|
+
};
|
|
128
|
+
const resMPCv2SigningRound2 = await ecdsaMPCv2Utils.createOfflineRound2Share(reqMPCv2SigningRound2);
|
|
129
|
+
resMPCv2SigningRound2.should.have.property('signatureShareRound2');
|
|
130
|
+
resMPCv2SigningRound2.should.have.property('encryptedRound2Session');
|
|
131
|
+
const encryptedRound2Session = resMPCv2SigningRound2.encryptedRound2Session;
|
|
132
|
+
const { txRequest: txRequestRound2, bitgoMsg4 } = await signBitgoMPCv2Round2(bitgoSession, reqMPCv2SigningRound2.txRequest, resMPCv2SigningRound2.signatureShareRound2, resMPCv2SigningRound1.userGpgPubKey);
|
|
133
|
+
assert.ok(txRequestRound2.transactions &&
|
|
134
|
+
txRequestRound2.transactions.length === 1 &&
|
|
135
|
+
txRequestRound2.transactions[0].signatureShares.length === 4, 'txRequestRound2.transactions is not an array of length 1 with 4 signatureShares');
|
|
136
|
+
bitgoMsg4.should.have.property('signatureR');
|
|
137
|
+
// round 3
|
|
138
|
+
const reqMPCv2SigningRound3 = {
|
|
139
|
+
...reqMPCv2SigningRound2,
|
|
140
|
+
txRequest: txRequestRound2,
|
|
141
|
+
encryptedRound1Session: null, // not needed for round 3
|
|
142
|
+
encryptedRound2Session,
|
|
143
|
+
};
|
|
144
|
+
const resMPCv2SigningRound3 = await ecdsaMPCv2Utils.createOfflineRound3Share(reqMPCv2SigningRound3);
|
|
145
|
+
resMPCv2SigningRound3.should.have.property('signatureShareRound3');
|
|
146
|
+
const { userMsg4 } = await signBitgoMPCv2Round3(bitgoSession, resMPCv2SigningRound3.signatureShareRound3, resMPCv2SigningRound1.userGpgPubKey);
|
|
147
|
+
// signature generation and validation
|
|
148
|
+
assert.ok(userMsg4.data.msg4.signatureR === bitgoMsg4.signatureR, 'User and BitGo signaturesR do not match');
|
|
149
|
+
const deserializedBitgoMsg4 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
150
|
+
p2pMessages: [],
|
|
151
|
+
broadcastMessages: [bitgoMsg4],
|
|
152
|
+
});
|
|
153
|
+
const deserializedUserMsg4 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
154
|
+
p2pMessages: [],
|
|
155
|
+
broadcastMessages: [
|
|
156
|
+
{
|
|
157
|
+
from: userMsg4.data.msg4.from,
|
|
158
|
+
payload: userMsg4.data.msg4.message,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
});
|
|
162
|
+
const combinedSigUsingUtil = sdk_lib_mpc_1.DklsUtils.combinePartialSignatures([deserializedUserMsg4.broadcastMessages[0].payload, deserializedBitgoMsg4.broadcastMessages[0].payload], Buffer.from(userMsg4.data.msg4.signatureR, 'base64').toString('hex'));
|
|
163
|
+
const convertedSignature = sdk_lib_mpc_1.DklsUtils.verifyAndConvertDklsSignature(Buffer.from(tMessage, 'hex'), combinedSigUsingUtil, sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userShare), derivationPath, (0, keccak_1.default)('keccak256'));
|
|
164
|
+
assert.ok(convertedSignature, 'Signature is not valid');
|
|
165
|
+
assert.ok(convertedSignature.split(':').length === 4, 'Signature is not valid');
|
|
166
|
+
});
|
|
167
|
+
it('should fail to sign using session after round X when session after round Y is expected', async () => {
|
|
168
|
+
const tMessage = 'testMessage';
|
|
169
|
+
const derivationPath = 'm/1/2';
|
|
170
|
+
// round 1
|
|
171
|
+
const reqMPCv2SigningRound1 = {
|
|
172
|
+
txRequest: {
|
|
173
|
+
txRequestId: '123456',
|
|
174
|
+
apiVersion: 'full',
|
|
175
|
+
walletId: walletID,
|
|
176
|
+
transactions: [
|
|
177
|
+
{
|
|
178
|
+
unsignedTx: {
|
|
179
|
+
derivationPath,
|
|
180
|
+
signableHex: tMessage,
|
|
181
|
+
},
|
|
182
|
+
signatureShares: [],
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
prv: userShare.toString('base64'),
|
|
187
|
+
walletPassphrase,
|
|
188
|
+
};
|
|
189
|
+
const resMPCv2SigningRound1 = await ecdsaMPCv2Utils.createOfflineRound1Share(reqMPCv2SigningRound1);
|
|
190
|
+
resMPCv2SigningRound1.should.have.property('signatureShareRound1');
|
|
191
|
+
resMPCv2SigningRound1.should.have.property('userGpgPubKey');
|
|
192
|
+
resMPCv2SigningRound1.should.have.property('encryptedRound1Session');
|
|
193
|
+
resMPCv2SigningRound1.should.have.property('encryptedUserGpgPrvKey');
|
|
194
|
+
const encryptedRound1Session = resMPCv2SigningRound1.encryptedRound1Session;
|
|
195
|
+
const encryptedUserGpgPrvKey = resMPCv2SigningRound1.encryptedUserGpgPrvKey;
|
|
196
|
+
const hashBuffer = (0, keccak_1.default)('keccak256').update(Buffer.from(tMessage, 'hex')).digest();
|
|
197
|
+
const bitgoSession = new sdk_lib_mpc_1.DklsDsg.Dsg(bitgoShare, 2, derivationPath, hashBuffer);
|
|
198
|
+
const txRequestRound1 = await signBitgoMPCv2Round1(bitgoSession, reqMPCv2SigningRound1.txRequest, resMPCv2SigningRound1.signatureShareRound1, resMPCv2SigningRound1.userGpgPubKey);
|
|
199
|
+
assert.ok(txRequestRound1.transactions &&
|
|
200
|
+
txRequestRound1.transactions.length === 1 &&
|
|
201
|
+
txRequestRound1.transactions[0].signatureShares.length === 2, 'txRequestRound1.transactions is not an array of length 1 with 2 signatureShares');
|
|
202
|
+
// round 2
|
|
203
|
+
const reqMPCv2SigningRound2 = {
|
|
204
|
+
...reqMPCv2SigningRound1,
|
|
205
|
+
txRequest: txRequestRound1,
|
|
206
|
+
encryptedRound1Session,
|
|
207
|
+
encryptedUserGpgPrvKey,
|
|
208
|
+
bitgoPublicGpgKey: gpgKeys_1.bitgoGpgKey.public,
|
|
209
|
+
};
|
|
210
|
+
const resMPCv2SigningRound2 = await ecdsaMPCv2Utils.createOfflineRound2Share(reqMPCv2SigningRound2);
|
|
211
|
+
resMPCv2SigningRound2.should.have.property('signatureShareRound2');
|
|
212
|
+
resMPCv2SigningRound2.should.have.property('encryptedRound2Session');
|
|
213
|
+
const { txRequest: txRequestRound2, bitgoMsg4 } = await signBitgoMPCv2Round2(bitgoSession, reqMPCv2SigningRound2.txRequest, resMPCv2SigningRound2.signatureShareRound2, resMPCv2SigningRound1.userGpgPubKey);
|
|
214
|
+
assert.ok(txRequestRound2.transactions &&
|
|
215
|
+
txRequestRound2.transactions.length === 1 &&
|
|
216
|
+
txRequestRound2.transactions[0].signatureShares.length === 4, 'txRequestRound2.transactions is not an array of length 1 with 4 signatureShares');
|
|
217
|
+
bitgoMsg4.should.have.property('signatureR');
|
|
218
|
+
const encryptedRound2Session = resMPCv2SigningRound2.encryptedRound2Session;
|
|
219
|
+
// A bogus round 3 signing request containing encrypted session from round 1 instead of round 2 should fail.
|
|
220
|
+
const bogusReqMPCv2SigningRound3 = {
|
|
221
|
+
...reqMPCv2SigningRound2,
|
|
222
|
+
txRequest: txRequestRound2,
|
|
223
|
+
encryptedRound1Session: null, // not needed for round 3
|
|
224
|
+
encryptedRound2Session: encryptedRound1Session, // instaed of encryptedRound2Session
|
|
225
|
+
};
|
|
226
|
+
await ecdsaMPCv2Utils
|
|
227
|
+
.createOfflineRound3Share(bogusReqMPCv2SigningRound3)
|
|
228
|
+
.should.be.rejectedWith('Adata does not match cyphertext adata');
|
|
229
|
+
// A bogus round 2 signing request containing encrypted session from round 2 instead of round 1 should fail.
|
|
230
|
+
const bogusReqMPCv2SigningRound2 = {
|
|
231
|
+
...reqMPCv2SigningRound2,
|
|
232
|
+
encryptedRound1Session: encryptedRound2Session, // instaed of encryptedRound1Session
|
|
233
|
+
};
|
|
234
|
+
await ecdsaMPCv2Utils
|
|
235
|
+
.createOfflineRound2Share(bogusReqMPCv2SigningRound2)
|
|
236
|
+
.should.be.rejectedWith('Unexpected signature share response. Unable to parse data.');
|
|
237
|
+
});
|
|
238
|
+
it('should fail to sign reusing a session on different message', async () => {
|
|
239
|
+
const tMessage1 = 'testMessage1';
|
|
240
|
+
const tMessage2 = 'testMessage2';
|
|
241
|
+
const derivationPath = 'm/3/4';
|
|
242
|
+
// round 1 of signing tMessage1
|
|
243
|
+
const reqMPCv2SigningMsg1Round1 = {
|
|
244
|
+
txRequest: {
|
|
245
|
+
txRequestId: '123456',
|
|
246
|
+
apiVersion: 'full',
|
|
247
|
+
walletId: walletID,
|
|
248
|
+
transactions: [
|
|
249
|
+
{
|
|
250
|
+
unsignedTx: {
|
|
251
|
+
derivationPath,
|
|
252
|
+
signableHex: tMessage1,
|
|
253
|
+
},
|
|
254
|
+
signatureShares: [],
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
},
|
|
258
|
+
prv: userShare.toString('base64'),
|
|
259
|
+
walletPassphrase,
|
|
260
|
+
};
|
|
261
|
+
const resMPCv2SigningMsg1Round1 = await ecdsaMPCv2Utils.createOfflineRound1Share(reqMPCv2SigningMsg1Round1);
|
|
262
|
+
resMPCv2SigningMsg1Round1.should.have.property('signatureShareRound1');
|
|
263
|
+
resMPCv2SigningMsg1Round1.should.have.property('userGpgPubKey');
|
|
264
|
+
resMPCv2SigningMsg1Round1.should.have.property('encryptedRound1Session');
|
|
265
|
+
resMPCv2SigningMsg1Round1.should.have.property('encryptedUserGpgPrvKey');
|
|
266
|
+
const encryptedMsg1Round1Session = resMPCv2SigningMsg1Round1.encryptedRound1Session;
|
|
267
|
+
const hashBuffer1 = (0, keccak_1.default)('keccak256').update(Buffer.from(tMessage1, 'hex')).digest();
|
|
268
|
+
const bitgoSession1 = new sdk_lib_mpc_1.DklsDsg.Dsg(bitgoShare, 2, derivationPath, hashBuffer1);
|
|
269
|
+
const txRequestMsg1Round1 = await signBitgoMPCv2Round1(bitgoSession1, reqMPCv2SigningMsg1Round1.txRequest, resMPCv2SigningMsg1Round1.signatureShareRound1, resMPCv2SigningMsg1Round1.userGpgPubKey);
|
|
270
|
+
assert.ok(txRequestMsg1Round1.transactions &&
|
|
271
|
+
txRequestMsg1Round1.transactions.length === 1 &&
|
|
272
|
+
txRequestMsg1Round1.transactions[0].signatureShares.length === 2, 'txRequestMsg1Round1.transactions is not an array of length 1 with 2 signatureShares');
|
|
273
|
+
// round 1 of signing tMessage2
|
|
274
|
+
const reqMPCv2SigningMsg2Round1 = {
|
|
275
|
+
...reqMPCv2SigningMsg1Round1,
|
|
276
|
+
txRequest: {
|
|
277
|
+
...reqMPCv2SigningMsg1Round1.txRequest,
|
|
278
|
+
transactions: [
|
|
279
|
+
{
|
|
280
|
+
unsignedTx: {
|
|
281
|
+
derivationPath,
|
|
282
|
+
signableHex: tMessage2,
|
|
283
|
+
},
|
|
284
|
+
signatureShares: [],
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
const resMPCv2SigningMsg2Round1 = await ecdsaMPCv2Utils.createOfflineRound1Share(reqMPCv2SigningMsg2Round1);
|
|
290
|
+
resMPCv2SigningMsg2Round1.should.have.property('signatureShareRound1');
|
|
291
|
+
resMPCv2SigningMsg2Round1.should.have.property('userGpgPubKey');
|
|
292
|
+
resMPCv2SigningMsg2Round1.should.have.property('encryptedRound1Session');
|
|
293
|
+
resMPCv2SigningMsg2Round1.should.have.property('encryptedUserGpgPrvKey');
|
|
294
|
+
const encryptedMsg2UserGpgPrvKey = resMPCv2SigningMsg2Round1.encryptedUserGpgPrvKey;
|
|
295
|
+
const hashBuffer2 = (0, keccak_1.default)('keccak256').update(Buffer.from(tMessage2, 'hex')).digest();
|
|
296
|
+
const bitgoSession2 = new sdk_lib_mpc_1.DklsDsg.Dsg(bitgoShare, 2, derivationPath, hashBuffer2);
|
|
297
|
+
const txRequestMsg2Round1 = await signBitgoMPCv2Round1(bitgoSession2, reqMPCv2SigningMsg2Round1.txRequest, resMPCv2SigningMsg2Round1.signatureShareRound1, resMPCv2SigningMsg2Round1.userGpgPubKey);
|
|
298
|
+
assert.ok(txRequestMsg2Round1.transactions &&
|
|
299
|
+
txRequestMsg2Round1.transactions.length === 1 &&
|
|
300
|
+
txRequestMsg2Round1.transactions[0].signatureShares.length === 2, 'txRequestMsg2Round1.transactions is not an array of length 1 with 2 signatureShares');
|
|
301
|
+
// Attempting to reuse round 1 session from signing tMessage1 for signing tMessage2 should fail at round 2.
|
|
302
|
+
const reqMPCv2SigningMsg2Round2WithMsg1Session = {
|
|
303
|
+
...reqMPCv2SigningMsg2Round1,
|
|
304
|
+
txRequest: txRequestMsg2Round1,
|
|
305
|
+
encryptedRound1Session: encryptedMsg1Round1Session, // instead of resMPCv2SigningMsg2Round1.encryptedRound1Session
|
|
306
|
+
encryptedUserGpgPrvKey: encryptedMsg2UserGpgPrvKey,
|
|
307
|
+
bitgoPublicGpgKey: gpgKeys_1.bitgoGpgKey.public,
|
|
308
|
+
};
|
|
309
|
+
await ecdsaMPCv2Utils
|
|
310
|
+
.createOfflineRound2Share(reqMPCv2SigningMsg2Round2WithMsg1Session)
|
|
311
|
+
.should.be.rejectedWith('Error while creating messages from party 0, round 2: Error: Invalid final_session_id');
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
function bytesToWord(bytes) {
|
|
315
|
+
if (!(bytes instanceof Uint8Array) || bytes.length !== 4) {
|
|
316
|
+
throw new Error('bytes must be a Uint8Array with length 4');
|
|
317
|
+
}
|
|
318
|
+
return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
|
|
319
|
+
}
|
|
320
|
+
function getUserPartyGpgKeyPublic(userPubKey) {
|
|
321
|
+
return {
|
|
322
|
+
partyId: 0,
|
|
323
|
+
gpgKey: userPubKey,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function getBitGoPartyGpgKeyPrv(bitgoPrvKey) {
|
|
327
|
+
return {
|
|
328
|
+
partyId: 2,
|
|
329
|
+
gpgKey: bitgoPrvKey,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
async function signBitgoMPCv2Round1(bitgoSession, txRequest, userShare, userGPGPubKey) {
|
|
333
|
+
assert.ok(txRequest.transactions && txRequest.transactions.length === 1, 'txRequest.transactions is not an array of length 1');
|
|
334
|
+
txRequest.transactions[0].signatureShares.push(userShare);
|
|
335
|
+
// Do the actual signing on BitGo's side based on User's messages
|
|
336
|
+
const signatureShare = JSON.parse(userShare.share);
|
|
337
|
+
const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
338
|
+
p2pMessages: [],
|
|
339
|
+
broadcastMessages: [
|
|
340
|
+
{
|
|
341
|
+
from: signatureShare.data.msg1.from,
|
|
342
|
+
payload: signatureShare.data.msg1.message,
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
});
|
|
346
|
+
const bitgoToUserRound1BroadcastMsg = await bitgoSession.init();
|
|
347
|
+
const bitgoToUserRound2Msg = bitgoSession.handleIncomingMessages({
|
|
348
|
+
p2pMessages: [],
|
|
349
|
+
broadcastMessages: deserializedMessages.broadcastMessages,
|
|
350
|
+
});
|
|
351
|
+
const serializedBitGoToUserRound1And2Msgs = sdk_lib_mpc_1.DklsTypes.serializeMessages({
|
|
352
|
+
p2pMessages: bitgoToUserRound2Msg.p2pMessages,
|
|
353
|
+
broadcastMessages: [bitgoToUserRound1BroadcastMsg],
|
|
354
|
+
});
|
|
355
|
+
const authEncMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(serializedBitGoToUserRound1And2Msgs, [getUserPartyGpgKeyPublic(userGPGPubKey)], [getBitGoPartyGpgKeyPrv(gpgKeys_1.bitgoGpgKey.private)]);
|
|
356
|
+
const bitgoToUserSignatureShare = {
|
|
357
|
+
type: 'round1Output',
|
|
358
|
+
data: {
|
|
359
|
+
msg1: {
|
|
360
|
+
from: authEncMessages.broadcastMessages[0].from,
|
|
361
|
+
signature: authEncMessages.broadcastMessages[0].payload.signature,
|
|
362
|
+
message: authEncMessages.broadcastMessages[0].payload.message,
|
|
363
|
+
},
|
|
364
|
+
msg2: {
|
|
365
|
+
from: authEncMessages.p2pMessages[0].from,
|
|
366
|
+
to: authEncMessages.p2pMessages[0].to,
|
|
367
|
+
encryptedMessage: authEncMessages.p2pMessages[0].payload.encryptedMessage,
|
|
368
|
+
signature: authEncMessages.p2pMessages[0].payload.signature,
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
txRequest.transactions[0].signatureShares.push({
|
|
373
|
+
from: src_1.SignatureShareType.BITGO,
|
|
374
|
+
to: src_1.SignatureShareType.USER,
|
|
375
|
+
share: JSON.stringify(bitgoToUserSignatureShare),
|
|
376
|
+
});
|
|
377
|
+
return txRequest;
|
|
378
|
+
}
|
|
379
|
+
async function signBitgoMPCv2Round2(bitgoSession, txRequest, userShare, userGPGPubKey) {
|
|
380
|
+
assert.ok(txRequest.transactions && txRequest.transactions.length === 1, 'txRequest.transactions is not an array of length 1');
|
|
381
|
+
txRequest.transactions[0].signatureShares.push(userShare);
|
|
382
|
+
// Do the actual signing on BitGo's side based on User's messages
|
|
383
|
+
const parsedSignatureShare = JSON.parse(userShare.share);
|
|
384
|
+
const serializedMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
|
|
385
|
+
p2pMessages: [
|
|
386
|
+
{
|
|
387
|
+
from: parsedSignatureShare.data.msg2.from,
|
|
388
|
+
to: parsedSignatureShare.data.msg2.to,
|
|
389
|
+
payload: {
|
|
390
|
+
encryptedMessage: parsedSignatureShare.data.msg2.encryptedMessage,
|
|
391
|
+
signature: parsedSignatureShare.data.msg2.signature,
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
from: parsedSignatureShare.data.msg3.from,
|
|
396
|
+
to: parsedSignatureShare.data.msg3.to,
|
|
397
|
+
payload: {
|
|
398
|
+
encryptedMessage: parsedSignatureShare.data.msg3.encryptedMessage,
|
|
399
|
+
signature: parsedSignatureShare.data.msg3.signature,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
],
|
|
403
|
+
broadcastMessages: [],
|
|
404
|
+
}, [getUserPartyGpgKeyPublic(userGPGPubKey)], [getBitGoPartyGpgKeyPrv(gpgKeys_1.bitgoGpgKey.private)]);
|
|
405
|
+
const deserializedMessages2 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
406
|
+
p2pMessages: [serializedMessages.p2pMessages[0]],
|
|
407
|
+
broadcastMessages: [],
|
|
408
|
+
});
|
|
409
|
+
const bitgoToUserRound3Msg = bitgoSession.handleIncomingMessages(deserializedMessages2);
|
|
410
|
+
const serializedBitGoToUserRound3Msgs = sdk_lib_mpc_1.DklsTypes.serializeMessages(bitgoToUserRound3Msg);
|
|
411
|
+
const authEncMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(serializedBitGoToUserRound3Msgs, [getUserPartyGpgKeyPublic(userGPGPubKey)], [getBitGoPartyGpgKeyPrv(gpgKeys_1.bitgoGpgKey.private)]);
|
|
412
|
+
const bitgoToUserSignatureShare = {
|
|
413
|
+
type: 'round2Output',
|
|
414
|
+
data: {
|
|
415
|
+
msg3: {
|
|
416
|
+
from: authEncMessages.p2pMessages[0].from,
|
|
417
|
+
to: authEncMessages.p2pMessages[0].to,
|
|
418
|
+
encryptedMessage: authEncMessages.p2pMessages[0].payload.encryptedMessage,
|
|
419
|
+
signature: authEncMessages.p2pMessages[0].payload.signature,
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
};
|
|
423
|
+
// handling user msg3 but not returning bitgo msg4 since its stored on bitgo side only
|
|
424
|
+
const deserializedMessages3 = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
425
|
+
p2pMessages: [serializedMessages.p2pMessages[1]],
|
|
426
|
+
broadcastMessages: [],
|
|
427
|
+
});
|
|
428
|
+
const deserializedBitgoMsg4 = bitgoSession.handleIncomingMessages(deserializedMessages3);
|
|
429
|
+
const serializedBitGoToUserRound4Msgs = sdk_lib_mpc_1.DklsTypes.serializeMessages(deserializedBitgoMsg4);
|
|
430
|
+
txRequest.transactions[0].signatureShares.push({
|
|
431
|
+
from: src_1.SignatureShareType.BITGO,
|
|
432
|
+
to: src_1.SignatureShareType.USER,
|
|
433
|
+
share: JSON.stringify(bitgoToUserSignatureShare),
|
|
434
|
+
});
|
|
435
|
+
return { txRequest, bitgoMsg4: serializedBitGoToUserRound4Msgs.broadcastMessages[0] };
|
|
436
|
+
}
|
|
437
|
+
async function signBitgoMPCv2Round3(bitgoSession, userShare, userGPGPubKey) {
|
|
438
|
+
const parsedSignatureShare = JSON.parse(userShare.share);
|
|
439
|
+
const msg4 = parsedSignatureShare.data.msg4;
|
|
440
|
+
const signatureRAuthMessage = msg4.signatureR && msg4.signatureRSignature
|
|
441
|
+
? { message: msg4.signatureR, signature: msg4.signatureRSignature }
|
|
442
|
+
: undefined;
|
|
443
|
+
const serializedMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
|
|
444
|
+
p2pMessages: [],
|
|
445
|
+
broadcastMessages: [
|
|
446
|
+
{
|
|
447
|
+
from: msg4.from,
|
|
448
|
+
payload: {
|
|
449
|
+
message: msg4.message,
|
|
450
|
+
signature: msg4.signature,
|
|
451
|
+
},
|
|
452
|
+
signatureR: signatureRAuthMessage,
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
}, [getUserPartyGpgKeyPublic(userGPGPubKey)], [getBitGoPartyGpgKeyPrv(gpgKeys_1.bitgoGpgKey.private)]);
|
|
456
|
+
const deserializedMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages({
|
|
457
|
+
p2pMessages: [],
|
|
458
|
+
broadcastMessages: [serializedMessages.broadcastMessages[0]],
|
|
459
|
+
});
|
|
460
|
+
bitgoSession.handleIncomingMessages(deserializedMessages);
|
|
461
|
+
return {
|
|
462
|
+
userMsg4: parsedSignatureShare,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2FNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWNkc2EvZWNkc2FNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyw2Q0FBK0I7QUFDL0IsbUNBQTJDO0FBQzNDLG9EQUFzQztBQVN0QyxvREFBOEU7QUFDOUUsa0RBQW9DO0FBQ3BDLCtDQU8rQjtBQUMvQix1Q0FBd0M7QUFFeEMsUUFBUSxDQUFDLGNBQWMsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNsQyxJQUFJLFNBQWlCLENBQUM7SUFDdEIsSUFBSSxVQUFrQixDQUFDO0lBRXZCLE1BQU0sQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuRCxNQUFNLENBQUMsY0FBYyxFQUFFLGdCQUFnQixFQUFFLGVBQWUsQ0FBQyxHQUFHLE1BQU0sdUJBQVMsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQ25HLE1BQU0sQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFM0IsU0FBUyxHQUFHLGNBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QyxVQUFVLEdBQUcsZUFBZSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxlQUFnQyxDQUFDO0lBRXJDLE1BQU0sQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM5QyxNQUFNLE1BQU0sR0FBRyxFQUFlLENBQUM7UUFDL0IsTUFBTSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0s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SUFBSSxDQUFDLFNBQVM7aUJBQzFCO2dCQUNELFVBQVUsRUFBRSxxQkFBcUI7YUFDbEM7U0FDRjtLQUNGLEVBQ0QsQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUN6QyxDQUFDLHNCQUFzQixDQUFDLHFCQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FDOUMsQ0FBQztJQUNGLE1BQU0sb0JBQW9CLEdBQUcsdUJBQVMsQ0FBQyxtQkFBbUIsQ0FBQztRQUN6RCxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDN0QsQ0FBQyxDQUFDO0lBQ0gsWUFBWSxDQUFDLHNCQUFzQixDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFFMUQsT0FBTztRQUNMLFFBQVEsRUFBRSxvQkFBb0I7S0FDL0IsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IEhhc2gsIHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCBjcmVhdGVLZWNjYWtIYXNoIGZyb20gJ2tlY2Nhayc7XG5pbXBvcnQge1xuICBNUEN2MlBhcnR5RnJvbVN0cmluZ09yTnVtYmVyLFxuICBNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxSW5wdXQsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDFPdXRwdXQsXG4gIE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJJbnB1dCxcbiAgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMk91dHB1dCxcbiAgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kM0lucHV0LFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IERrbHNDb21tcywgRGtsc0RzZywgRGtsc1R5cGVzLCBEa2xzVXRpbHMgfSBmcm9tICdAYml0Z28vc2RrLWxpYi1tcGMnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28vc2pjbCc7XG5pbXBvcnQge1xuICBCaXRHb0Jhc2UsXG4gIEVjZHNhTVBDdjJVdGlscyxcbiAgSUJhc2VDb2luLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgU2lnbmF0dXJlU2hhcmVUeXBlLFxuICBUeFJlcXVlc3QsXG59IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBiaXRnb0dwZ0tleSB9IGZyb20gJy4vZ3BnS2V5cyc7XG5cbmRlc2NyaWJlKCdFQ0RTQSBNUEMgdjInLCBhc3luYyAoKSA9PiB7XG4gIGxldCB1c2VyU2hhcmU6IEJ1ZmZlcjtcbiAgbGV0IGJpdGdvU2hhcmU6IEJ1ZmZlcjtcblxuICBiZWZvcmUoJ2dlbmVyYXRlIGtleSBzaGFyZXMgZm9yIHRlc3RpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgW3VzZXJEa2dTZXNzaW9uLCBiYWNrdXBEa2dTZXNzaW9uLCBiaXRnb0RrZ1Nlc3Npb25dID0gYXdhaXQgRGtsc1V0aWxzLmdlbmVyYXRlREtHS2V5U2hhcmVzKCk7XG4gICAgYXNzZXJ0Lm9rKHVzZXJEa2dTZXNzaW9uKTtcbiAgICBhc3NlcnQub2soYmFja3VwRGtnU2Vzc2lvbik7XG4gICAgYXNzZXJ0Lm9rKGJpdGdvRGtnU2Vzc2lvbik7XG5cbiAgICB1c2VyU2hhcmUgPSB1c2VyRGtnU2Vzc2lvbi5nZXRLZXlTaGFyZSgpO1xuICAgIGJpdGdvU2hhcmUgPSBiaXRnb0RrZ1Nlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgfSk7XG5cbiAgbGV0IGVjZHNhTVBDdjJVdGlsczogRWNkc2FNUEN2MlV0aWxzO1xuXG4gIGJlZm9yZSgnaW5pdGlhbGl6ZSBFY2RzYU1QQ3YyVXRpbHMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbW9ja0JnID0ge30gYXMgQml0R29CYXNlO1xuICAgIG1vY2tCZy5nZXRFbnYgPSBzaW5vbi5zdHViKCkucmV0dXJucygndGVzdCcpO1xuICAgIG1vY2tCZy5lbmNyeXB0ID0gc2lub24uc3R1YigpLmNhbGxzRmFrZSgocGFyYW1zKSA9PiB7XG4gICAgICBjb25zdCBzYWx0ID0gcmFuZG9tQnl0ZXMoOCk7XG4gICAgICBjb25zdCBpdiA9IHJhbmRvbUJ5dGVzKDE2KTtcbiAgICAgIHJldHVybiBzamNsLmVuY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQsIHtcbiAgICAgICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc3ViYXJyYXkoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnN1YmFycmF5KDQpKV0sXG4gICAgICAgIGl2OiBbXG4gICAgICAgICAgYnl0ZXNUb1dvcmQoaXYuc3ViYXJyYXkoMCwgNCkpLFxuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDQsIDgpKSxcbiAgICAgICAgICBieXRlc1RvV29yZChpdi5zdWJhcnJheSg4LCAxMikpLFxuICAgICAgICAgIGJ5dGVzVG9Xb3JkKGl2LnN1YmFycmF5KDEyLCAxNikpLFxuICAgICAgICBdLFxuICAgICAgICBhZGF0YTogcGFyYW1zLmFkYXRhLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgbW9ja0JnLmRlY3J5cHQgPSBzaW5vbi5zdHViKCkuY2FsbHNGYWtlKChwYXJhbXMpID0+IHtcbiAgICAgIHJldHVybiBzamNsLmRlY3J5cHQocGFyYW1zLnBhc3N3b3JkLCBwYXJhbXMuaW5wdXQpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbW9ja0NvaW4gPSB7fSBhcyBJQmFzZUNvaW47XG4gICAgbW9ja0NvaW4uZ2V0SGFzaEZ1bmN0aW9uID0gc2lub24uc3R1YigpLmNhbGxzRmFrZSgoKSA9PiBjcmVhdGVLZWNjYWtIYXNoKCdrZWNjYWsyNTYnKSBhcyBIYXNoKTtcblxuICAgIGVjZHNhTVBDdjJVdGlscyA9IG5ldyBFY2RzYU1QQ3YyVXRpbHMobW9ja0JnLCBtb2NrQ29pbik7XG4gIH0pO1xuXG4gIGNvbnN0IHdhbGxldElEID0gJzYyZmU1MzZhNmI0Y2Y3MDAwN2FjYjQ4YzBlN2JiMGIwJztcbiAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICd0ZXN0UGFzcyc7XG5cbiAgaXQoJ3Nob3VsZCBzaWduIGEgbWVzc2FnZSBoYXNoIHVzaW5nIEVDRFNBIE1QQyB2MiBvZmZsaW5lIHJvdW5kcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0TWVzc2FnZSA9ICd0ZXN0TWVzc2FnZSc7XG4gICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8wJztcblxuICAgIC8vIHJvdW5kIDFcbiAgICBjb25zdCByZXFNUEN2MlNpZ25pbmdSb3VuZDEgPSB7XG4gICAgICB0eFJlcXVlc3Q6IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICcxMjM0NTYnLFxuICAgICAgICBhcGlWZXJzaW9uOiAnZnVsbCcsXG4gICAgICAgIHdhbGxldElkOiB3YWxsZXRJRCxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgICAgICAgICAgc2lnbmFibGVIZXg6IHRNZXNzYWdlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICBwcnY6IHVzZXJTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNNUEN2MlNpZ25pbmdSb3VuZDEgPSBhd2FpdCBlY2RzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHJlcU1QQ3YyU2lnbmluZ1JvdW5kMSBhcyBhbnkpO1xuICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmF0dXJlU2hhcmVSb3VuZDEnKTtcbiAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3VzZXJHcGdQdWJLZXknKTtcbiAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFJvdW5kMVNlc3Npb24nKTtcbiAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFVzZXJHcGdQcnZLZXknKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24gPSByZXNNUEN2MlNpZ25pbmdSb3VuZDEuZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjtcbiAgICBjb25zdCBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5ID0gcmVzTVBDdjJTaWduaW5nUm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXk7XG5cbiAgICBjb25zdCBoYXNoQnVmZmVyID0gY3JlYXRlS2VjY2FrSGFzaCgna2VjY2FrMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHRNZXNzYWdlLCAnaGV4JykpLmRpZ2VzdCgpO1xuICAgIGNvbnN0IGJpdGdvU2Vzc2lvbiA9IG5ldyBEa2xzRHNnLkRzZyhiaXRnb1NoYXJlLCAyLCBkZXJpdmF0aW9uUGF0aCwgaGFzaEJ1ZmZlcik7XG5cbiAgICBjb25zdCB0eFJlcXVlc3RSb3VuZDEgPSBhd2FpdCBzaWduQml0Z29NUEN2MlJvdW5kMShcbiAgICAgIGJpdGdvU2Vzc2lvbixcbiAgICAgIHJlcU1QQ3YyU2lnbmluZ1JvdW5kMS50eFJlcXVlc3QgYXMgYW55LFxuICAgICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnVzZXJHcGdQdWJLZXlcbiAgICApO1xuICAgIGFzc2VydC5vayhcbiAgICAgIHR4UmVxdWVzdFJvdW5kMS50cmFuc2FjdGlvbnMgJiZcbiAgICAgICAgdHhSZXF1ZXN0Um91bmQxLnRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgdHhSZXF1ZXN0Um91bmQxLnRyYW5zYWN0aW9uc1swXS5zaWduYXR1cmVTaGFyZXMubGVuZ3RoID09PSAyLFxuICAgICAgJ3R4UmVxdWVzdFJvdW5kMS50cmFuc2FjdGlvbnMgaXMgbm90IGFuIGFycmF5IG9mIGxlbmd0aCAxIHdpdGggMiBzaWduYXR1cmVTaGFyZXMnXG4gICAgKTtcblxuICAgIC8vIHJvdW5kIDJcbiAgICBjb25zdCByZXFNUEN2MlNpZ25pbmdSb3VuZDIgPSB7XG4gICAgICAuLi5yZXFNUEN2MlNpZ25pbmdSb3VuZDEsXG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMSxcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5LFxuICAgICAgYml0Z29QdWJsaWNHcGdLZXk6IGJpdGdvR3BnS2V5LnB1YmxpYyxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzTVBDdjJTaWduaW5nUm91bmQyID0gYXdhaXQgZWNkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZShyZXFNUEN2MlNpZ25pbmdSb3VuZDIgYXMgYW55KTtcbiAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hdHVyZVNoYXJlUm91bmQyJyk7XG4gICAgcmVzTVBDdjJTaWduaW5nUm91bmQyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uJyk7XG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uID0gcmVzTVBDdjJTaWduaW5nUm91bmQyLmVuY3J5cHRlZFJvdW5kMlNlc3Npb247XG5cbiAgICBjb25zdCB7IHR4UmVxdWVzdDogdHhSZXF1ZXN0Um91bmQyLCBiaXRnb01zZzQgfSA9IGF3YWl0IHNpZ25CaXRnb01QQ3YyUm91bmQyKFxuICAgICAgYml0Z29TZXNzaW9uLFxuICAgICAgcmVxTVBDdjJTaWduaW5nUm91bmQyLnR4UmVxdWVzdCxcbiAgICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMi5zaWduYXR1cmVTaGFyZVJvdW5kMixcbiAgICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMS51c2VyR3BnUHViS2V5XG4gICAgKTtcbiAgICBhc3NlcnQub2soXG4gICAgICB0eFJlcXVlc3RSb3VuZDIudHJhbnNhY3Rpb25zICYmXG4gICAgICAgIHR4UmVxdWVzdFJvdW5kMi50cmFuc2FjdGlvbnMubGVuZ3RoID09PSAxICYmXG4gICAgICAgIHR4UmVxdWVzdFJvdW5kMi50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLmxlbmd0aCA9PT0gNCxcbiAgICAgICd0eFJlcXVlc3RSb3VuZDIudHJhbnNhY3Rpb25zIGlzIG5vdCBhbiBhcnJheSBvZiBsZW5ndGggMSB3aXRoIDQgc2lnbmF0dXJlU2hhcmVzJ1xuICAgICk7XG4gICAgYml0Z29Nc2c0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYXR1cmVSJyk7XG5cbiAgICAvLyByb3VuZCAzXG4gICAgY29uc3QgcmVxTVBDdjJTaWduaW5nUm91bmQzID0ge1xuICAgICAgLi4ucmVxTVBDdjJTaWduaW5nUm91bmQyLFxuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDIsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uOiBudWxsLCAvLyBub3QgbmVlZGVkIGZvciByb3VuZCAzXG4gICAgICBlbmNyeXB0ZWRSb3VuZDJTZXNzaW9uLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNNUEN2MlNpZ25pbmdSb3VuZDMgPSBhd2FpdCBlY2RzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kM1NoYXJlKHJlcU1QQ3YyU2lnbmluZ1JvdW5kMyBhcyBhbnkpO1xuICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmF0dXJlU2hhcmVSb3VuZDMnKTtcblxuICAgIGNvbnN0IHsgdXNlck1zZzQgfSA9IGF3YWl0IHNpZ25CaXRnb01QQ3YyUm91bmQzKFxuICAgICAgYml0Z29TZXNzaW9uLFxuICAgICAgcmVzTVBDdjJTaWduaW5nUm91bmQzLnNpZ25hdHVyZVNoYXJlUm91bmQzLFxuICAgICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnVzZXJHcGdQdWJLZXlcbiAgICApO1xuXG4gICAgLy8gc2lnbmF0dXJlIGdlbmVyYXRpb24gYW5kIHZhbGlkYXRpb25cbiAgICBhc3NlcnQub2sodXNlck1zZzQuZGF0YS5tc2c0LnNpZ25hdHVyZVIgPT09IGJpdGdvTXNnNC5zaWduYXR1cmVSLCAnVXNlciBhbmQgQml0R28gc2lnbmF0dXJlc1IgZG8gbm90IG1hdGNoJyk7XG5cbiAgICBjb25zdCBkZXNlcmlhbGl6ZWRCaXRnb01zZzQgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW2JpdGdvTXNnNF0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBkZXNlcmlhbGl6ZWRVc2VyTXNnNCA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBmcm9tOiB1c2VyTXNnNC5kYXRhLm1zZzQuZnJvbSxcbiAgICAgICAgICBwYXlsb2FkOiB1c2VyTXNnNC5kYXRhLm1zZzQubWVzc2FnZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBjb21iaW5lZFNpZ1VzaW5nVXRpbCA9IERrbHNVdGlscy5jb21iaW5lUGFydGlhbFNpZ25hdHVyZXMoXG4gICAgICBbZGVzZXJpYWxpemVkVXNlck1zZzQuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZCwgZGVzZXJpYWxpemVkQml0Z29Nc2c0LmJyb2FkY2FzdE1lc3NhZ2VzWzBdLnBheWxvYWRdLFxuICAgICAgQnVmZmVyLmZyb20odXNlck1zZzQuZGF0YS5tc2c0LnNpZ25hdHVyZVIsICdiYXNlNjQnKS50b1N0cmluZygnaGV4JylcbiAgICApO1xuXG4gICAgY29uc3QgY29udmVydGVkU2lnbmF0dXJlID0gRGtsc1V0aWxzLnZlcmlmeUFuZENvbnZlcnREa2xzU2lnbmF0dXJlKFxuICAgICAgQnVmZmVyLmZyb20odE1lc3NhZ2UsICdoZXgnKSxcbiAgICAgIGNvbWJpbmVkU2lnVXNpbmdVdGlsLFxuICAgICAgRGtsc1R5cGVzLmdldENvbW1vbktleWNoYWluKHVzZXJTaGFyZSksXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICAgIGNyZWF0ZUtlY2Nha0hhc2goJ2tlY2NhazI1NicpIGFzIEhhc2hcbiAgICApO1xuICAgIGFzc2VydC5vayhjb252ZXJ0ZWRTaWduYXR1cmUsICdTaWduYXR1cmUgaXMgbm90IHZhbGlkJyk7XG4gICAgYXNzZXJ0Lm9rKGNvbnZlcnRlZFNpZ25hdHVyZS5zcGxpdCgnOicpLmxlbmd0aCA9PT0gNCwgJ1NpZ25hdHVyZSBpcyBub3QgdmFsaWQnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBmYWlsIHRvIHNpZ24gdXNpbmcgc2Vzc2lvbiBhZnRlciByb3VuZCBYIHdoZW4gc2Vzc2lvbiBhZnRlciByb3VuZCBZIGlzIGV4cGVjdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHRNZXNzYWdlID0gJ3Rlc3RNZXNzYWdlJztcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzEvMic7XG5cbiAgICAvLyByb3VuZCAxXG4gICAgY29uc3QgcmVxTVBDdjJTaWduaW5nUm91bmQxID0ge1xuICAgICAgdHhSZXF1ZXN0OiB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnMTIzNDU2JyxcbiAgICAgICAgYXBpVmVyc2lvbjogJ2Z1bGwnLFxuICAgICAgICB3YWxsZXRJZDogd2FsbGV0SUQsXG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgICAgICAgICAgIHNpZ25hYmxlSGV4OiB0TWVzc2FnZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaWduYXR1cmVTaGFyZXM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgICAgcHJ2OiB1c2VyU2hhcmUudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzTVBDdjJTaWduaW5nUm91bmQxID0gYXdhaXQgZWNkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZShyZXFNUEN2MlNpZ25pbmdSb3VuZDEgYXMgYW55KTtcbiAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hdHVyZVNoYXJlUm91bmQxJyk7XG4gICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1c2VyR3BnUHViS2V5Jyk7XG4gICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uJyk7XG4gICAgcmVzTVBDdjJTaWduaW5nUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5Jyk7XG5cbiAgICBjb25zdCBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uID0gcmVzTVBDdjJTaWduaW5nUm91bmQxLmVuY3J5cHRlZFJvdW5kMVNlc3Npb247XG4gICAgY29uc3QgZW5jcnlwdGVkVXNlckdwZ1BydktleSA9IHJlc01QQ3YyU2lnbmluZ1JvdW5kMS5lbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5O1xuXG4gICAgY29uc3QgaGFzaEJ1ZmZlciA9IGNyZWF0ZUtlY2Nha0hhc2goJ2tlY2NhazI1NicpLnVwZGF0ZShCdWZmZXIuZnJvbSh0TWVzc2FnZSwgJ2hleCcpKS5kaWdlc3QoKTtcbiAgICBjb25zdCBiaXRnb1Nlc3Npb24gPSBuZXcgRGtsc0RzZy5Ec2coYml0Z29TaGFyZSwgMiwgZGVyaXZhdGlvblBhdGgsIGhhc2hCdWZmZXIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0Um91bmQxID0gYXdhaXQgc2lnbkJpdGdvTVBDdjJSb3VuZDEoXG4gICAgICBiaXRnb1Nlc3Npb24sXG4gICAgICByZXFNUEN2MlNpZ25pbmdSb3VuZDEudHhSZXF1ZXN0IGFzIGFueSxcbiAgICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMS5zaWduYXR1cmVTaGFyZVJvdW5kMSxcbiAgICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMS51c2VyR3BnUHViS2V5XG4gICAgKTtcbiAgICBhc3NlcnQub2soXG4gICAgICB0eFJlcXVlc3RSb3VuZDEudHJhbnNhY3Rpb25zICYmXG4gICAgICAgIHR4UmVxdWVzdFJvdW5kMS50cmFuc2FjdGlvbnMubGVuZ3RoID09PSAxICYmXG4gICAgICAgIHR4UmVxdWVzdFJvdW5kMS50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLmxlbmd0aCA9PT0gMixcbiAgICAgICd0eFJlcXVlc3RSb3VuZDEudHJhbnNhY3Rpb25zIGlzIG5vdCBhbiBhcnJheSBvZiBsZW5ndGggMSB3aXRoIDIgc2lnbmF0dXJlU2hhcmVzJ1xuICAgICk7XG5cbiAgICAvLyByb3VuZCAyXG4gICAgY29uc3QgcmVxTVBDdjJTaWduaW5nUm91bmQyID0ge1xuICAgICAgLi4ucmVxTVBDdjJTaWduaW5nUm91bmQxLFxuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RSb3VuZDEsXG4gICAgICBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uLFxuICAgICAgZW5jcnlwdGVkVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleS5wdWJsaWMsXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc01QQ3YyU2lnbmluZ1JvdW5kMiA9IGF3YWl0IGVjZHNhTVBDdjJVdGlscy5jcmVhdGVPZmZsaW5lUm91bmQyU2hhcmUocmVxTVBDdjJTaWduaW5nUm91bmQyIGFzIGFueSk7XG4gICAgcmVzTVBDdjJTaWduaW5nUm91bmQyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYXR1cmVTaGFyZVJvdW5kMicpO1xuICAgIHJlc01QQ3YyU2lnbmluZ1JvdW5kMi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUm91bmQyU2Vzc2lvbicpO1xuXG4gICAgY29uc3QgeyB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMiwgYml0Z29Nc2c0IH0gPSBhd2FpdCBzaWduQml0Z29NUEN2MlJvdW5kMihcbiAgICAgIGJpdGdvU2Vzc2lvbixcbiAgICAgIHJlcU1QQ3YyU2lnbmluZ1JvdW5kMi50eFJlcXVlc3QsXG4gICAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDIuc2lnbmF0dXJlU2hhcmVSb3VuZDIsXG4gICAgICByZXNNUEN2MlNpZ25pbmdSb3VuZDEudXNlckdwZ1B1YktleVxuICAgICk7XG4gICAgYXNzZXJ0Lm9rKFxuICAgICAgdHhSZXF1ZXN0Um91bmQyLnRyYW5zYWN0aW9ucyAmJlxuICAgICAgICB0eFJlcXVlc3RSb3VuZDIudHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICB0eFJlcXVlc3RSb3VuZDIudHJhbnNhY3Rpb25zWzBdLnNpZ25hdHVyZVNoYXJlcy5sZW5ndGggPT09IDQsXG4gICAgICAndHhSZXF1ZXN0Um91bmQyLnRyYW5zYWN0aW9ucyBpcyBub3QgYW4gYXJyYXkgb2YgbGVuZ3RoIDEgd2l0aCA0IHNpZ25hdHVyZVNoYXJlcydcbiAgICApO1xuICAgIGJpdGdvTXNnNC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmF0dXJlUicpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiA9IHJlc01QQ3YyU2lnbmluZ1JvdW5kMi5lbmNyeXB0ZWRSb3VuZDJTZXNzaW9uO1xuXG4gICAgLy8gQSBib2d1cyByb3VuZCAzIHNpZ25pbmcgcmVxdWVzdCBjb250YWluaW5nIGVuY3J5cHRlZCBzZXNzaW9uIGZyb20gcm91bmQgMSBpbnN0ZWFkIG9mIHJvdW5kIDIgc2hvdWxkIGZhaWwuXG4gICAgY29uc3QgYm9ndXNSZXFNUEN2MlNpZ25pbmdSb3VuZDMgPSB7XG4gICAgICAuLi5yZXFNUEN2MlNpZ25pbmdSb3VuZDIsXG4gICAgICB0eFJlcXVlc3Q6IHR4UmVxdWVzdFJvdW5kMixcbiAgICAgIGVuY3J5cHRlZFJvdW5kMVNlc3Npb246IG51bGwsIC8vIG5vdCBuZWVkZWQgZm9yIHJvdW5kIDNcbiAgICAgIGVuY3J5cHRlZFJvdW5kMlNlc3Npb246IGVuY3J5cHRlZFJvdW5kMVNlc3Npb24sIC8vIGluc3RhZWQgb2YgZW5jcnlwdGVkUm91bmQyU2Vzc2lvblxuICAgIH07XG5cbiAgICBhd2FpdCBlY2RzYU1QQ3YyVXRpbHNcbiAgICAgIC5jcmVhdGVPZmZsaW5lUm91bmQzU2hhcmUoYm9ndXNSZXFNUEN2MlNpZ25pbmdSb3VuZDMgYXMgYW55KVxuICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0FkYXRhIGRvZXMgbm90IG1hdGNoIGN5cGhlcnRleHQgYWRhdGEnKTtcblxuICAgIC8vIEEgYm9ndXMgcm91bmQgMiBzaWduaW5nIHJlcXVlc3QgY29udGFpbmluZyBlbmNyeXB0ZWQgc2Vzc2lvbiBmcm9tIHJvdW5kIDIgaW5zdGVhZCBvZiByb3VuZCAxIHNob3VsZCBmYWlsLlxuICAgIGNvbnN0IGJvZ3VzUmVxTVBDdjJTaWduaW5nUm91bmQyID0ge1xuICAgICAgLi4ucmVxTVBDdjJTaWduaW5nUm91bmQyLFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogZW5jcnlwdGVkUm91bmQyU2Vzc2lvbiwgLy8gaW5zdGFlZCBvZiBlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uXG4gICAgfTtcblxuICAgIGF3YWl0IGVjZHNhTVBDdjJVdGlsc1xuICAgICAgLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZShib2d1c1JlcU1QQ3YyU2lnbmluZ1JvdW5kMiBhcyBhbnkpXG4gICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVW5leHBlY3RlZCBzaWduYXR1cmUgc2hhcmUgcmVzcG9uc2UuIFVuYWJsZSB0byBwYXJzZSBkYXRhLicpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGZhaWwgdG8gc2lnbiByZXVzaW5nIGEgc2Vzc2lvbiBvbiBkaWZmZXJlbnQgbWVzc2FnZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0TWVzc2FnZTEgPSAndGVzdE1lc3NhZ2UxJztcbiAgICBjb25zdCB0TWVzc2FnZTIgPSAndGVzdE1lc3NhZ2UyJztcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzMvNCc7XG5cbiAgICAvLyByb3VuZCAxIG9mIHNpZ25pbmcgdE1lc3NhZ2UxXG4gICAgY29uc3QgcmVxTVBDdjJTaWduaW5nTXNnMVJvdW5kMSA9IHtcbiAgICAgIHR4UmVxdWVzdDoge1xuICAgICAgICB0eFJlcXVlc3RJZDogJzEyMzQ1NicsXG4gICAgICAgIGFwaVZlcnNpb246ICdmdWxsJyxcbiAgICAgICAgd2FsbGV0SWQ6IHdhbGxldElELFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgICAgICBzaWduYWJsZUhleDogdE1lc3NhZ2UxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICBwcnY6IHVzZXJTaGFyZS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgIH07XG5cbiAgICBjb25zdCByZXNNUEN2MlNpZ25pbmdNc2cxUm91bmQxID0gYXdhaXQgZWNkc2FNUEN2MlV0aWxzLmNyZWF0ZU9mZmxpbmVSb3VuZDFTaGFyZShyZXFNUEN2MlNpZ25pbmdNc2cxUm91bmQxIGFzIGFueSk7XG4gICAgcmVzTVBDdjJTaWduaW5nTXNnMVJvdW5kMS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmF0dXJlU2hhcmVSb3VuZDEnKTtcbiAgICByZXNNUEN2MlNpZ25pbmdNc2cxUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1c2VyR3BnUHViS2V5Jyk7XG4gICAgcmVzTVBDdjJTaWduaW5nTXNnMVJvdW5kMS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUm91bmQxU2Vzc2lvbicpO1xuICAgIHJlc01QQ3YyU2lnbmluZ01zZzFSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFVzZXJHcGdQcnZLZXknKTtcblxuICAgIGNvbnN0IGVuY3J5cHRlZE1zZzFSb3VuZDFTZXNzaW9uID0gcmVzTVBDdjJTaWduaW5nTXNnMVJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uO1xuXG4gICAgY29uc3QgaGFzaEJ1ZmZlcjEgPSBjcmVhdGVLZWNjYWtIYXNoKCdrZWNjYWsyNTYnKS51cGRhdGUoQnVmZmVyLmZyb20odE1lc3NhZ2UxLCAnaGV4JykpLmRpZ2VzdCgpO1xuICAgIGNvbnN0IGJpdGdvU2Vzc2lvbjEgPSBuZXcgRGtsc0RzZy5Ec2coYml0Z29TaGFyZSwgMiwgZGVyaXZhdGlvblBhdGgsIGhhc2hCdWZmZXIxKTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdE1zZzFSb3VuZDEgPSBhd2FpdCBzaWduQml0Z29NUEN2MlJvdW5kMShcbiAgICAgIGJpdGdvU2Vzc2lvbjEsXG4gICAgICByZXFNUEN2MlNpZ25pbmdNc2cxUm91bmQxLnR4UmVxdWVzdCBhcyBhbnksXG4gICAgICByZXNNUEN2MlNpZ25pbmdNc2cxUm91bmQxLnNpZ25hdHVyZVNoYXJlUm91bmQxLFxuICAgICAgcmVzTVBDdjJTaWduaW5nTXNnMVJvdW5kMS51c2VyR3BnUHViS2V5XG4gICAgKTtcbiAgICBhc3NlcnQub2soXG4gICAgICB0eFJlcXVlc3RNc2cxUm91bmQxLnRyYW5zYWN0aW9ucyAmJlxuICAgICAgICB0eFJlcXVlc3RNc2cxUm91bmQxLnRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEgJiZcbiAgICAgICAgdHhSZXF1ZXN0TXNnMVJvdW5kMS50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLmxlbmd0aCA9PT0gMixcbiAgICAgICd0eFJlcXVlc3RNc2cxUm91bmQxLnRyYW5zYWN0aW9ucyBpcyBub3QgYW4gYXJyYXkgb2YgbGVuZ3RoIDEgd2l0aCAyIHNpZ25hdHVyZVNoYXJlcydcbiAgICApO1xuXG4gICAgLy8gcm91bmQgMSBvZiBzaWduaW5nIHRNZXNzYWdlMlxuICAgIGNvbnN0IHJlcU1QQ3YyU2lnbmluZ01zZzJSb3VuZDEgPSB7XG4gICAgICAuLi5yZXFNUEN2MlNpZ25pbmdNc2cxUm91bmQxLFxuICAgICAgdHhSZXF1ZXN0OiB7XG4gICAgICAgIC4uLnJlcU1QQ3YyU2lnbmluZ01zZzFSb3VuZDEudHhSZXF1ZXN0LFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgICAgICAgICBzaWduYWJsZUhleDogdE1lc3NhZ2UyLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHJlc01QQ3YyU2lnbmluZ01zZzJSb3VuZDEgPSBhd2FpdCBlY2RzYU1QQ3YyVXRpbHMuY3JlYXRlT2ZmbGluZVJvdW5kMVNoYXJlKHJlcU1QQ3YyU2lnbmluZ01zZzJSb3VuZDEgYXMgYW55KTtcbiAgICByZXNNUEN2MlNpZ25pbmdNc2cyUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYXR1cmVTaGFyZVJvdW5kMScpO1xuICAgIHJlc01QQ3YyU2lnbmluZ01zZzJSb3VuZDEuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3VzZXJHcGdQdWJLZXknKTtcbiAgICByZXNNUEN2MlNpZ25pbmdNc2cyUm91bmQxLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRSb3VuZDFTZXNzaW9uJyk7XG4gICAgcmVzTVBDdjJTaWduaW5nTXNnMlJvdW5kMS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkVXNlckdwZ1BydktleScpO1xuXG4gICAgY29uc3QgZW5jcnlwdGVkTXNnMlVzZXJHcGdQcnZLZXkgPSByZXNNUEN2MlNpZ25pbmdNc2cyUm91bmQxLmVuY3J5cHRlZFVzZXJHcGdQcnZLZXk7XG5cbiAgICBjb25zdCBoYXNoQnVmZmVyMiA9IGNyZWF0ZUtlY2Nha0hhc2goJ2tlY2NhazI1NicpLnVwZGF0ZShCdWZmZXIuZnJvbSh0TWVzc2FnZTIsICdoZXgnKSkuZGlnZXN0KCk7XG4gICAgY29uc3QgYml0Z29TZXNzaW9uMiA9IG5ldyBEa2xzRHNnLkRzZyhiaXRnb1NoYXJlLCAyLCBkZXJpdmF0aW9uUGF0aCwgaGFzaEJ1ZmZlcjIpO1xuXG4gICAgY29uc3QgdHhSZXF1ZXN0TXNnMlJvdW5kMSA9IGF3YWl0IHNpZ25CaXRnb01QQ3YyUm91bmQxKFxuICAgICAgYml0Z29TZXNzaW9uMixcbiAgICAgIHJlcU1QQ3YyU2lnbmluZ01zZzJSb3VuZDEudHhSZXF1ZXN0IGFzIGFueSxcbiAgICAgIHJlc01QQ3YyU2lnbmluZ01zZzJSb3VuZDEuc2lnbmF0dXJlU2hhcmVSb3VuZDEsXG4gICAgICByZXNNUEN2MlNpZ25pbmdNc2cyUm91bmQxLnVzZXJHcGdQdWJLZXlcbiAgICApO1xuICAgIGFzc2VydC5vayhcbiAgICAgIHR4UmVxdWVzdE1zZzJSb3VuZDEudHJhbnNhY3Rpb25zICYmXG4gICAgICAgIHR4UmVxdWVzdE1zZzJSb3VuZDEudHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICB0eFJlcXVlc3RNc2cyUm91bmQxLnRyYW5zYWN0aW9uc1swXS5zaWduYXR1cmVTaGFyZXMubGVuZ3RoID09PSAyLFxuICAgICAgJ3R4UmVxdWVzdE1zZzJSb3VuZDEudHJhbnNhY3Rpb25zIGlzIG5vdCBhbiBhcnJheSBvZiBsZW5ndGggMSB3aXRoIDIgc2lnbmF0dXJlU2hhcmVzJ1xuICAgICk7XG5cbiAgICAvLyBBdHRlbXB0aW5nIHRvIHJldXNlIHJvdW5kIDEgc2Vzc2lvbiBmcm9tIHNpZ25pbmcgdE1lc3NhZ2UxIGZvciBzaWduaW5nIHRNZXNzYWdlMiBzaG91bGQgZmFpbCBhdCByb3VuZCAyLlxuICAgIGNvbnN0IHJlcU1QQ3YyU2lnbmluZ01zZzJSb3VuZDJXaXRoTXNnMVNlc3Npb24gPSB7XG4gICAgICAuLi5yZXFNUEN2MlNpZ25pbmdNc2cyUm91bmQxLFxuICAgICAgdHhSZXF1ZXN0OiB0eFJlcXVlc3RNc2cyUm91bmQxLFxuICAgICAgZW5jcnlwdGVkUm91bmQxU2Vzc2lvbjogZW5jcnlwdGVkTXNnMVJvdW5kMVNlc3Npb24sIC8vIGluc3RlYWQgb2YgcmVzTVBDdjJTaWduaW5nTXNnMlJvdW5kMS5lbmNyeXB0ZWRSb3VuZDFTZXNzaW9uXG4gICAgICBlbmNyeXB0ZWRVc2VyR3BnUHJ2S2V5OiBlbmNyeXB0ZWRNc2cyVXNlckdwZ1BydktleSxcbiAgICAgIGJpdGdvUHVibGljR3BnS2V5OiBiaXRnb0dwZ0tleS5wdWJsaWMsXG4gICAgfTtcblxuICAgIGF3YWl0IGVjZHNhTVBDdjJVdGlsc1xuICAgICAgLmNyZWF0ZU9mZmxpbmVSb3VuZDJTaGFyZShyZXFNUEN2MlNpZ25pbmdNc2cyUm91bmQyV2l0aE1zZzFTZXNzaW9uIGFzIGFueSlcbiAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFcnJvciB3aGlsZSBjcmVhdGluZyBtZXNzYWdlcyBmcm9tIHBhcnR5IDAsIHJvdW5kIDI6IEVycm9yOiBJbnZhbGlkIGZpbmFsX3Nlc3Npb25faWQnKTtcbiAgfSk7XG59KTtcblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmQoYnl0ZXM/OiBVaW50OEFycmF5IHwgbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoIShieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGJ5dGVzLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignYnl0ZXMgbXVzdCBiZSBhIFVpbnQ4QXJyYXkgd2l0aCBsZW5ndGggNCcpO1xuICB9XG5cbiAgcmV0dXJuIGJ5dGVzLnJlZHVjZSgobnVtLCBieXRlKSA9PiBudW0gKiAweDEwMCArIGJ5dGUsIDApO1xufVxuXG5mdW5jdGlvbiBnZXRVc2VyUGFydHlHcGdLZXlQdWJsaWModXNlclB1YktleTogc3RyaW5nKTogRGtsc1R5cGVzLlBhcnR5R3BnS2V5IHtcbiAgcmV0dXJuIHtcbiAgICBwYXJ0eUlkOiAwLFxuICAgIGdwZ0tleTogdXNlclB1YktleSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0Qml0R29QYXJ0eUdwZ0tleVBydihiaXRnb1BydktleTogc3RyaW5nKTogRGtsc1R5cGVzLlBhcnR5R3BnS2V5IHtcbiAgcmV0dXJuIHtcbiAgICBwYXJ0eUlkOiAyLFxuICAgIGdwZ0tleTogYml0Z29QcnZLZXksXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNpZ25CaXRnb01QQ3YyUm91bmQxKFxuICBiaXRnb1Nlc3Npb246IERrbHNEc2cuRHNnLFxuICB0eFJlcXVlc3Q6IFR4UmVxdWVzdCxcbiAgdXNlclNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgdXNlckdQR1B1YktleTogc3RyaW5nXG4pOiBQcm9taXNlPFR4UmVxdWVzdD4ge1xuICBhc3NlcnQub2soXG4gICAgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyAmJiB0eFJlcXVlc3QudHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMSxcbiAgICAndHhSZXF1ZXN0LnRyYW5zYWN0aW9ucyBpcyBub3QgYW4gYXJyYXkgb2YgbGVuZ3RoIDEnXG4gICk7XG4gIHR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLnB1c2godXNlclNoYXJlKTtcbiAgLy8gRG8gdGhlIGFjdHVhbCBzaWduaW5nIG9uIEJpdEdvJ3Mgc2lkZSBiYXNlZCBvbiBVc2VyJ3MgbWVzc2FnZXNcbiAgY29uc3Qgc2lnbmF0dXJlU2hhcmUgPSBKU09OLnBhcnNlKHVzZXJTaGFyZS5zaGFyZSkgYXMgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMUlucHV0O1xuICBjb25zdCBkZXNlcmlhbGl6ZWRNZXNzYWdlcyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW10sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtcbiAgICAgIHtcbiAgICAgICAgZnJvbTogc2lnbmF0dXJlU2hhcmUuZGF0YS5tc2cxLmZyb20sXG4gICAgICAgIHBheWxvYWQ6IHNpZ25hdHVyZVNoYXJlLmRhdGEubXNnMS5tZXNzYWdlLFxuICAgICAgfSxcbiAgICBdLFxuICB9KTtcbiAgY29uc3QgYml0Z29Ub1VzZXJSb3VuZDFCcm9hZGNhc3RNc2cgPSBhd2FpdCBiaXRnb1Nlc3Npb24uaW5pdCgpO1xuICBjb25zdCBiaXRnb1RvVXNlclJvdW5kMk1zZyA9IGJpdGdvU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW10sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IGRlc2VyaWFsaXplZE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLFxuICB9KTtcbiAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyUm91bmQxQW5kMk1zZ3MgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBiaXRnb1RvVXNlclJvdW5kMk1zZy5wMnBNZXNzYWdlcyxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW2JpdGdvVG9Vc2VyUm91bmQxQnJvYWRjYXN0TXNnXSxcbiAgfSk7XG5cbiAgY29uc3QgYXV0aEVuY01lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICBzZXJpYWxpemVkQml0R29Ub1VzZXJSb3VuZDFBbmQyTXNncyxcbiAgICBbZ2V0VXNlclBhcnR5R3BnS2V5UHVibGljKHVzZXJHUEdQdWJLZXkpXSxcbiAgICBbZ2V0Qml0R29QYXJ0eUdwZ0tleVBydihiaXRnb0dwZ0tleS5wcml2YXRlKV1cbiAgKTtcblxuICBjb25zdCBiaXRnb1RvVXNlclNpZ25hdHVyZVNoYXJlOiBNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQxT3V0cHV0ID0ge1xuICAgIHR5cGU6ICdyb3VuZDFPdXRwdXQnLFxuICAgIGRhdGE6IHtcbiAgICAgIG1zZzE6IHtcbiAgICAgICAgZnJvbTogYXV0aEVuY01lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzWzBdLmZyb20gYXMgTVBDdjJQYXJ0eUZyb21TdHJpbmdPck51bWJlcixcbiAgICAgICAgc2lnbmF0dXJlOiBhdXRoRW5jTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgIG1lc3NhZ2U6IGF1dGhFbmNNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlc1swXS5wYXlsb2FkLm1lc3NhZ2UsXG4gICAgICB9LFxuICAgICAgbXNnMjoge1xuICAgICAgICBmcm9tOiBhdXRoRW5jTWVzc2FnZXMucDJwTWVzc2FnZXNbMF0uZnJvbSBhcyBNUEN2MlBhcnR5RnJvbVN0cmluZ09yTnVtYmVyLFxuICAgICAgICB0bzogYXV0aEVuY01lc3NhZ2VzLnAycE1lc3NhZ2VzWzBdLnRvIGFzIE1QQ3YyUGFydHlGcm9tU3RyaW5nT3JOdW1iZXIsXG4gICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IGF1dGhFbmNNZXNzYWdlcy5wMnBNZXNzYWdlc1swXS5wYXlsb2FkLmVuY3J5cHRlZE1lc3NhZ2UsXG4gICAgICAgIHNpZ25hdHVyZTogYXV0aEVuY01lc3NhZ2VzLnAycE1lc3NhZ2VzWzBdLnBheWxvYWQuc2lnbmF0dXJlLFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xuICB0eFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdLnNpZ25hdHVyZVNoYXJlcy5wdXNoKHtcbiAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgIHNoYXJlOiBKU09OLnN0cmluZ2lmeShiaXRnb1RvVXNlclNpZ25hdHVyZVNoYXJlKSxcbiAgfSk7XG4gIHJldHVybiB0eFJlcXVlc3Q7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNpZ25CaXRnb01QQ3YyUm91bmQyKFxuICBiaXRnb1Nlc3Npb246IERrbHNEc2cuRHNnLFxuICB0eFJlcXVlc3Q6IFR4UmVxdWVzdCxcbiAgdXNlclNoYXJlOiBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgdXNlckdQR1B1YktleTogc3RyaW5nXG4pOiBQcm9taXNlPHsgdHhSZXF1ZXN0OiBUeFJlcXVlc3Q7IGJpdGdvTXNnNDogRGtsc1R5cGVzLlNlcmlhbGl6ZWRCcm9hZGNhc3RNZXNzYWdlIH0+IHtcbiAgYXNzZXJ0Lm9rKFxuICAgIHR4UmVxdWVzdC50cmFuc2FjdGlvbnMgJiYgdHhSZXF1ZXN0LnRyYW5zYWN0aW9ucy5sZW5ndGggPT09IDEsXG4gICAgJ3R4UmVxdWVzdC50cmFuc2FjdGlvbnMgaXMgbm90IGFuIGFycmF5IG9mIGxlbmd0aCAxJ1xuICApO1xuICB0eFJlcXVlc3QudHJhbnNhY3Rpb25zWzBdLnNpZ25hdHVyZVNoYXJlcy5wdXNoKHVzZXJTaGFyZSk7XG5cbiAgLy8gRG8gdGhlIGFjdHVhbCBzaWduaW5nIG9uIEJpdEdvJ3Mgc2lkZSBiYXNlZCBvbiBVc2VyJ3MgbWVzc2FnZXNcbiAgY29uc3QgcGFyc2VkU2lnbmF0dXJlU2hhcmUgPSBKU09OLnBhcnNlKHVzZXJTaGFyZS5zaGFyZSkgYXMgTVBDdjJTaWduYXR1cmVTaGFyZVJvdW5kMklucHV0O1xuICBjb25zdCBzZXJpYWxpemVkTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAge1xuICAgICAgcDJwTWVzc2FnZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZyb206IHBhcnNlZFNpZ25hdHVyZVNoYXJlLmRhdGEubXNnMi5mcm9tLFxuICAgICAgICAgIHRvOiBwYXJzZWRTaWduYXR1cmVTaGFyZS5kYXRhLm1zZzIudG8sXG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkTWVzc2FnZTogcGFyc2VkU2lnbmF0dXJlU2hhcmUuZGF0YS5tc2cyLmVuY3J5cHRlZE1lc3NhZ2UsXG4gICAgICAgICAgICBzaWduYXR1cmU6IHBhcnNlZFNpZ25hdHVyZVNoYXJlLmRhdGEubXNnMi5zaWduYXR1cmUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGZyb206IHBhcnNlZFNpZ25hdHVyZVNoYXJlLmRhdGEubXNnMy5mcm9tLFxuICAgICAgICAgIHRvOiBwYXJzZWRTaWduYXR1cmVTaGFyZS5kYXRhLm1zZzMudG8sXG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkTWVzc2FnZTogcGFyc2VkU2lnbmF0dXJlU2hhcmUuZGF0YS5tc2czLmVuY3J5cHRlZE1lc3NhZ2UsXG4gICAgICAgICAgICBzaWduYXR1cmU6IHBhcnNlZFNpZ25hdHVyZVNoYXJlLmRhdGEubXNnMy5zaWduYXR1cmUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgfSxcbiAgICBbZ2V0VXNlclBhcnR5R3BnS2V5UHVibGljKHVzZXJHUEdQdWJLZXkpXSxcbiAgICBbZ2V0Qml0R29QYXJ0eUdwZ0tleVBydihiaXRnb0dwZ0tleS5wcml2YXRlKV1cbiAgKTtcbiAgY29uc3QgZGVzZXJpYWxpemVkTWVzc2FnZXMyID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbc2VyaWFsaXplZE1lc3NhZ2VzLnAycE1lc3NhZ2VzWzBdXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gIH0pO1xuXG4gIGNvbnN0IGJpdGdvVG9Vc2VyUm91bmQzTXNnID0gYml0Z29TZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoZGVzZXJpYWxpemVkTWVzc2FnZXMyKTtcbiAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyUm91bmQzTXNncyA9IERrbHNUeXBlcy5zZXJpYWxpemVNZXNzYWdlcyhiaXRnb1RvVXNlclJvdW5kM01zZyk7XG5cbiAgY29uc3QgYXV0aEVuY01lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICBzZXJpYWxpemVkQml0R29Ub1VzZXJSb3VuZDNNc2dzLFxuICAgIFtnZXRVc2VyUGFydHlHcGdLZXlQdWJsaWModXNlckdQR1B1YktleSldLFxuICAgIFtnZXRCaXRHb1BhcnR5R3BnS2V5UHJ2KGJpdGdvR3BnS2V5LnByaXZhdGUpXVxuICApO1xuXG4gIGNvbnN0IGJpdGdvVG9Vc2VyU2lnbmF0dXJlU2hhcmU6IE1QQ3YyU2lnbmF0dXJlU2hhcmVSb3VuZDJPdXRwdXQgPSB7XG4gICAgdHlwZTogJ3JvdW5kMk91dHB1dCcsXG4gICAgZGF0YToge1xuICAgICAgbXNnMzoge1xuICAgICAgICBmcm9tOiBhdXRoRW5jTWVzc2FnZXMucDJwTWVzc2FnZXNbMF0uZnJvbSBhcyBNUEN2MlBhcnR5RnJvbVN0cmluZ09yTnVtYmVyLFxuICAgICAgICB0bzogYXV0aEVuY01lc3NhZ2VzLnAycE1lc3NhZ2VzWzBdLnRvIGFzIE1QQ3YyUGFydHlGcm9tU3RyaW5nT3JOdW1iZXIsXG4gICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IGF1dGhFbmNNZXNzYWdlcy5wMnBNZXNzYWdlc1swXS5wYXlsb2FkLmVuY3J5cHRlZE1lc3NhZ2UsXG4gICAgICAgIHNpZ25hdHVyZTogYXV0aEVuY01lc3NhZ2VzLnAycE1lc3NhZ2VzWzBdLnBheWxvYWQuc2lnbmF0dXJlLFxuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIC8vIGhhbmRsaW5nIHVzZXIgbXNnMyBidXQgbm90IHJldHVybmluZyBiaXRnbyBtc2c0IHNpbmNlIGl0cyBzdG9yZWQgb24gYml0Z28gc2lkZSBvbmx5XG4gIGNvbnN0IGRlc2VyaWFsaXplZE1lc3NhZ2VzMyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW3NlcmlhbGl6ZWRNZXNzYWdlcy5wMnBNZXNzYWdlc1sxXV0sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICB9KTtcbiAgY29uc3QgZGVzZXJpYWxpemVkQml0Z29Nc2c0ID0gYml0Z29TZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoZGVzZXJpYWxpemVkTWVzc2FnZXMzKTtcbiAgY29uc3Qgc2VyaWFsaXplZEJpdEdvVG9Vc2VyUm91bmQ0TXNncyA9IERrbHNUeXBlcy5zZXJpYWxpemVNZXNzYWdlcyhkZXNlcmlhbGl6ZWRCaXRnb01zZzQpO1xuXG4gIHR4UmVxdWVzdC50cmFuc2FjdGlvbnNbMF0uc2lnbmF0dXJlU2hhcmVzLnB1c2goe1xuICAgIGZyb206IFNpZ25hdHVyZVNoYXJlVHlwZS5CSVRHTyxcbiAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgc2hhcmU6IEpTT04uc3RyaW5naWZ5KGJpdGdvVG9Vc2VyU2lnbmF0dXJlU2hhcmUpLFxuICB9KTtcbiAgcmV0dXJuIHsgdHhSZXF1ZXN0LCBiaXRnb01zZzQ6IHNlcmlhbGl6ZWRCaXRHb1RvVXNlclJvdW5kNE1zZ3MuYnJvYWRjYXN0TWVzc2FnZXNbMF0gfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2lnbkJpdGdvTVBDdjJSb3VuZDMoXG4gIGJpdGdvU2Vzc2lvbjogRGtsc0RzZy5Ec2csXG4gIHVzZXJTaGFyZTogU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gIHVzZXJHUEdQdWJLZXk6IHN0cmluZ1xuKTogUHJvbWlzZTx7IHVzZXJNc2c0OiBNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQgfT4ge1xuICBjb25zdCBwYXJzZWRTaWduYXR1cmVTaGFyZSA9IEpTT04ucGFyc2UodXNlclNoYXJlLnNoYXJlKSBhcyBNUEN2MlNpZ25hdHVyZVNoYXJlUm91bmQzSW5wdXQ7XG4gIGNvbnN0IG1zZzQgPSBwYXJzZWRTaWduYXR1cmVTaGFyZS5kYXRhLm1zZzQ7XG4gIGNvbnN0IHNpZ25hdHVyZVJBdXRoTWVzc2FnZSA9XG4gICAgbXNnNC5zaWduYXR1cmVSICYmIG1zZzQuc2lnbmF0dXJlUlNpZ25hdHVyZVxuICAgICAgPyB7IG1lc3NhZ2U6IG1zZzQuc2lnbmF0dXJlUiwgc2lnbmF0dXJlOiBtc2c0LnNpZ25hdHVyZVJTaWduYXR1cmUgfVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNlcmlhbGl6ZWRNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICB7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW1xuICAgICAgICB7XG4gICAgICAgICAgZnJvbTogbXNnNC5mcm9tLFxuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IG1zZzQubWVzc2FnZSxcbiAgICAgICAgICAgIHNpZ25hdHVyZTogbXNnNC5zaWduYXR1cmUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaWduYXR1cmVSOiBzaWduYXR1cmVSQXV0aE1lc3NhZ2UsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0sXG4gICAgW2dldFVzZXJQYXJ0eUdwZ0tleVB1YmxpYyh1c2VyR1BHUHViS2V5KV0sXG4gICAgW2dldEJpdEdvUGFydHlHcGdLZXlQcnYoYml0Z29HcGdLZXkucHJpdmF0ZSldXG4gICk7XG4gIGNvbnN0IGRlc2VyaWFsaXplZE1lc3NhZ2VzID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW3NlcmlhbGl6ZWRNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlc1swXV0sXG4gIH0pO1xuICBiaXRnb1Nlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhkZXNlcmlhbGl6ZWRNZXNzYWdlcyk7XG5cbiAgcmV0dXJuIHtcbiAgICB1c2VyTXNnNDogcGFyc2VkU2lnbmF0dXJlU2hhcmUsXG4gIH07XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpgKeys.d.ts","sourceRoot":"","sources":["../../../../../../../test/unit/bitgo/utils/tss/ecdsa/gpgKeys.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;CAiCvB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bitgoGpgKey = void 0;
|
|
4
|
+
exports.bitgoGpgKey = {
|
|
5
|
+
private: '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
|
|
6
|
+
'\n' +
|
|
7
|
+
'xXQEZo2rshMFK4EEAAoCAwQC6HQa7PXiX2nnpZr/asCcEbgCOcjsR8gcSI8v\n' +
|
|
8
|
+
'vMADk59KsFweg+kIzCR3UqfMe2uG6JHwOYpvDREHp/hqtA+hAAD/XgjiTu4D\n' +
|
|
9
|
+
'0d9YzSx3ZP8lUAcruvJbyMIIlr26QIeHq5kRQM0FYml0Z2/CjAQQEwgAPgWC\n' +
|
|
10
|
+
'Zo2rsgQLCQcICZA8EZGJCCwPOAMVCAoEFgACAQIZAQKbAwIeARYhBLSGUeOq\n' +
|
|
11
|
+
'bM5ym4aSnjwRkYkILA84AABXoQD+KkO5kWGw8GgWN142t+pGULPLzGo6353r\n' +
|
|
12
|
+
'H8FwgKxe9ikBAKEjJI17aVlozG0RzFVxctBLLVqjYO5tBZQhoQbHHkGdx3gE\n' +
|
|
13
|
+
'Zo2rshIFK4EEAAoCAwTBwmMa+htUmjUoqlKTuQaoWcY0Det+ee/6fV9+vnis\n' +
|
|
14
|
+
'EyphRUFXnA0K0LyGpSnNlqKisSoArwUkZTiWwTbMWjTdAwEIBwABAJmAlxnB\n' +
|
|
15
|
+
'IZ5bw88Duvw0yaRRcgXt5tDP0z23l6cvJWgKEJbCeAQYEwgAKgWCZo2rsgmQ\n' +
|
|
16
|
+
'PBGRiQgsDzgCmwwWIQS0hlHjqmzOcpuGkp48EZGJCCwPOAAA3/4BAIozuxF1\n' +
|
|
17
|
+
'JEoSQXe8YFIFqowwCiVwr2K6NqqRn+mGM1NjAQCYWIsZq+4+UCBIKScVknTG\n' +
|
|
18
|
+
'uu2Utd5ZMyNYZTWCxLk9+g==\n' +
|
|
19
|
+
'=iXOB\n' +
|
|
20
|
+
'-----END PGP PRIVATE KEY BLOCK-----\n',
|
|
21
|
+
public: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
|
|
22
|
+
'\n' +
|
|
23
|
+
'xk8EZo2rshMFK4EEAAoCAwQC6HQa7PXiX2nnpZr/asCcEbgCOcjsR8gcSI8v\n' +
|
|
24
|
+
'vMADk59KsFweg+kIzCR3UqfMe2uG6JHwOYpvDREHp/hqtA+hzQViaXRnb8KM\n' +
|
|
25
|
+
'BBATCAA+BYJmjauyBAsJBwgJkDwRkYkILA84AxUICgQWAAIBAhkBApsDAh4B\n' +
|
|
26
|
+
'FiEEtIZR46psznKbhpKePBGRiQgsDzgAAFehAP4qQ7mRYbDwaBY3Xja36kZQ\n' +
|
|
27
|
+
's8vMajrfnesfwXCArF72KQEAoSMkjXtpWWjMbRHMVXFy0EstWqNg7m0FlCGh\n' +
|
|
28
|
+
'BsceQZ3OUwRmjauyEgUrgQQACgIDBMHCYxr6G1SaNSiqUpO5BqhZxjQN6355\n' +
|
|
29
|
+
'7/p9X36+eKwTKmFFQVecDQrQvIalKc2WoqKxKgCvBSRlOJbBNsxaNN0DAQgH\n' +
|
|
30
|
+
'wngEGBMIACoFgmaNq7IJkDwRkYkILA84ApsMFiEEtIZR46psznKbhpKePBGR\n' +
|
|
31
|
+
'iQgsDzgAAN/+AQCKM7sRdSRKEkF3vGBSBaqMMAolcK9iujaqkZ/phjNTYwEA\n' +
|
|
32
|
+
'mFiLGavuPlAgSCknFZJ0xrrtlLXeWTMjWGU1gsS5Pfo=\n' +
|
|
33
|
+
'=7uRX\n' +
|
|
34
|
+
'-----END PGP PUBLIC KEY BLOCK-----\n',
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3BnS2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Rlc3QvdW5pdC9iaXRnby91dGlscy90c3MvZWNkc2EvZ3BnS2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBYSxRQUFBLFdBQVcsR0FBRztJQUN6QixPQUFPLEVBQ0wseUNBQXlDO1FBQ3pDLElBQUk7UUFDSixnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLDRCQUE0QjtRQUM1QixTQUFTO1FBQ1QsdUNBQXVDO0lBQ3pDLE1BQU0sRUFDSix3Q0FBd0M7UUFDeEMsSUFBSTtRQUNKLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdFQUFnRTtRQUNoRSxnRUFBZ0U7UUFDaEUsZ0VBQWdFO1FBQ2hFLGdEQUFnRDtRQUNoRCxTQUFTO1FBQ1Qsc0NBQXNDO0NBQ3pDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgYml0Z29HcGdLZXkgPSB7XG4gIHByaXZhdGU6XG4gICAgJy0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXG4nICtcbiAgICAnXFxuJyArXG4gICAgJ3hYUUVabzJyc2hNRks0RUVBQW9DQXdRQzZIUWE3UFhpWDJubnBaci9hc0NjRWJnQ09janNSOGdjU0k4dlxcbicgK1xuICAgICd2TUFEazU5S3NGd2VnK2tJekNSM1VxZk1lMnVHNkpId09ZcHZEUkVIcC9ocXRBK2hBQUQvWGdqaVR1NERcXG4nICtcbiAgICAnMGQ5WXpTeDNaUDhsVUFjcnV2SmJ5TUlJbHIyNlFJZUhxNWtSUU0wRlltbDBaMi9DakFRUUV3Z0FQZ1dDXFxuJyArXG4gICAgJ1pvMnJzZ1FMQ1FjSUNaQThFWkdKQ0N3UE9BTVZDQW9FRmdBQ0FRSVpBUUtiQXdJZUFSWWhCTFNHVWVPcVxcbicgK1xuICAgICdiTTV5bTRhU25qd1JrWWtJTEE4NEFBQlhvUUQrS2tPNWtXR3c4R2dXTjE0MnQrcEdVTFBMekdvNjM1M3JcXG4nICtcbiAgICAnSDhGd2dLeGU5aWtCQUtFakpJMTdhVmxvekcwUnpGVnhjdEJMTFZxallPNXRCWlFob1FiSEhrR2R4M2dFXFxuJyArXG4gICAgJ1pvMnJzaElGSzRFRUFBb0NBd1RCd21NYStodFVtalVvcWxLVHVRYW9XY1kwRGV0K2VlLzZmVjkrdm5pc1xcbicgK1xuICAgICdFeXBoUlVGWG5BMEswTHlHcFNuTmxxS2lzU29BcndVa1pUaVd3VGJNV2pUZEF3RUlCd0FCQUptQWx4bkJcXG4nICtcbiAgICAnSVo1Ync4OER1dncweWFSUmNnWHQ1dERQMHoyM2w2Y3ZKV2dLRUpiQ2VBUVlFd2dBS2dXQ1pvMnJzZ21RXFxuJyArXG4gICAgJ1BCR1JpUWdzRHpnQ213d1dJUVMwaGxIanFtek9jcHVHa3A0OEVaR0pDQ3dQT0FBQTMvNEJBSW96dXhGMVxcbicgK1xuICAgICdKRW9TUVhlOFlGSUZxb3d3Q2lWd3IySzZOcXFSbittR00xTmpBUUNZV0lzWnErNCtVQ0JJS1NjVmtuVEdcXG4nICtcbiAgICAndXUyVXRkNVpNeU5ZWlRXQ3hMazkrZz09XFxuJyArXG4gICAgJz1pWE9CXFxuJyArXG4gICAgJy0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tXFxuJyxcbiAgcHVibGljOlxuICAgICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nICtcbiAgICAnXFxuJyArXG4gICAgJ3hrOEVabzJyc2hNRks0RUVBQW9DQXdRQzZIUWE3UFhpWDJubnBaci9hc0NjRWJnQ09janNSOGdjU0k4dlxcbicgK1xuICAgICd2TUFEazU5S3NGd2VnK2tJekNSM1VxZk1lMnVHNkpId09ZcHZEUkVIcC9ocXRBK2h6UVZpYVhSbmI4S01cXG4nICtcbiAgICAnQkJBVENBQStCWUptamF1eUJBc0pCd2dKa0R3UmtZa0lMQTg0QXhVSUNnUVdBQUlCQWhrQkFwc0RBaDRCXFxuJyArXG4gICAgJ0ZpRUV0SVpSNDZwc3puS2JocEtlUEJHUmlRZ3NEemdBQUZlaEFQNHFRN21SWWJEd2FCWTNYamEzNmtaUVxcbicgK1xuICAgICdzOHZNYWpyZm5lc2Z3WENBckY3MktRRUFvU01ralh0cFdXak1iUkhNVlhGeTBFc3RXcU5nN20wRmxDR2hcXG4nICtcbiAgICAnQnNjZVFaM09Vd1JtamF1eUVnVXJnUVFBQ2dJREJNSENZeHI2RzFTYU5TaXFVcE81QnFoWnhqUU42MzU1XFxuJyArXG4gICAgJzcvcDlYMzYrZUt3VEttRkZRVmVjRFFyUXZJYWxLYzJXb3FLeEtnQ3ZCU1JsT0piQk5zeGFOTjBEQVFnSFxcbicgK1xuICAgICd3bmdFR0JNSUFDb0ZnbWFOcTdJSmtEd1JrWWtJTEE4NEFwc01GaUVFdElaUjQ2cHN6bktiaHBLZVBCR1JcXG4nICtcbiAgICAnaVFnc0R6Z0FBTi8rQVFDS003c1JkU1JLRWtGM3ZHQlNCYXFNTUFvbGNLOWl1amFxa1ovcGhqTlRZd0VBXFxuJyArXG4gICAgJ21GaUxHYXZ1UGxBZ1NDa25GWkoweHJydGxMWGVXVE1qV0dVMWdzUzVQZm89XFxuJyArXG4gICAgJz03dVJYXFxuJyArXG4gICAgJy0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxufTtcbiJdfQ==
|