utxo-lib 1.1.2 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +16 -19
- package/dist/src/bitgo/PsbtUtil.d.ts +0 -5
- package/dist/src/bitgo/PsbtUtil.d.ts.map +1 -1
- package/dist/src/bitgo/PsbtUtil.js +2 -15
- package/dist/src/bitgo/UtxoPsbt.d.ts +0 -9
- package/dist/src/bitgo/UtxoPsbt.d.ts.map +1 -1
- package/dist/src/bitgo/UtxoPsbt.js +12 -42
- package/dist/src/bitgo/index.d.ts +0 -1
- package/dist/src/bitgo/index.d.ts.map +1 -1
- package/dist/src/bitgo/index.js +2 -3
- package/dist/src/bitgo/parseInput.js +2 -2
- package/dist/src/bitgo/wallet/Psbt.d.ts +0 -14
- package/dist/src/bitgo/wallet/Psbt.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/Psbt.js +3 -71
- package/dist/src/bitgo/wallet/WalletOutput.d.ts +1 -17
- package/dist/src/bitgo/wallet/WalletOutput.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/WalletOutput.js +23 -64
- package/dist/src/bitgo/wallet/chains.d.ts +1 -1
- package/dist/src/bitgo/zcash/ZcashPsbt.d.ts +1 -0
- package/dist/src/bitgo/zcash/ZcashPsbt.d.ts.map +1 -1
- package/dist/src/bitgo/zcash/ZcashPsbt.js +12 -3
- package/dist/src/testutil/keys.d.ts +0 -3
- package/dist/src/testutil/keys.d.ts.map +1 -1
- package/dist/src/testutil/keys.js +2 -17
- package/dist/src/testutil/psbt.d.ts +5 -23
- package/dist/src/testutil/psbt.d.ts.map +1 -1
- package/dist/src/testutil/psbt.js +13 -16
- package/dist/src/testutil/transaction.d.ts +5 -14
- package/dist/src/testutil/transaction.d.ts.map +1 -1
- package/dist/src/testutil/transaction.js +9 -9
- package/package.json +5 -5
- package/dist/src/base_crypto.d.ts +0 -14
- package/dist/src/base_crypto.d.ts.map +0 -1
- package/dist/src/base_crypto.js +0 -215
- package/dist/src/bitgo/legacysafe/index.d.ts +0 -15
- package/dist/src/bitgo/legacysafe/index.d.ts.map +0 -1
- package/dist/src/bitgo/legacysafe/index.js +0 -61
- package/dist/src/musig.d.ts +0 -390
- package/dist/src/musig.d.ts.map +0 -1
- package/dist/src/musig.js +0 -447
package/dist/src/musig.js
DELETED
@@ -1,447 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
/* ! musig-js - MIT License (c) 2022 Brandon Black */
|
3
|
-
// https://github.com/ElementsProject/secp256k1-zkp/blob/master/doc/musig-spec.mediawiki
|
4
|
-
// Roughly based on the secp256k1-zkp implementation
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.MuSigFactory = void 0;
|
7
|
-
const TAGS = {
|
8
|
-
challenge: 'BIP0340/challenge',
|
9
|
-
keyagg_list: 'KeyAgg list',
|
10
|
-
keyagg_coef: 'KeyAgg coefficient',
|
11
|
-
musig_aux: 'MuSig/aux',
|
12
|
-
musig_nonce: 'MuSig/nonce',
|
13
|
-
musig_deterministic_nonce: 'MuSig/deterministic/nonce',
|
14
|
-
musig_noncecoef: 'MuSig/noncecoef',
|
15
|
-
};
|
16
|
-
/**
|
17
|
-
* Compares two 32-byte Uint8Arrays in byte order.
|
18
|
-
* @returns < 0, 0, > 0 if a is < b, === b or > b respectively
|
19
|
-
*/
|
20
|
-
function compare32b(a, b) {
|
21
|
-
if (a.length !== 32 || b.length !== 32)
|
22
|
-
throw new Error('Invalid array');
|
23
|
-
const aD = new DataView(a.buffer, a.byteOffset, a.length);
|
24
|
-
const bD = new DataView(b.buffer, b.byteOffset, b.length);
|
25
|
-
for (let i = 0; i < 8; i++) {
|
26
|
-
const cmp = aD.getUint32(i * 4) - bD.getUint32(i * 4);
|
27
|
-
if (cmp !== 0)
|
28
|
-
return cmp;
|
29
|
-
}
|
30
|
-
return 0;
|
31
|
-
}
|
32
|
-
/**
|
33
|
-
* Compares two 33-byte Uint8Arrays in byte order.
|
34
|
-
* @returns < 0, 0, > 0 if a is < b, === b or > b respectively
|
35
|
-
*/
|
36
|
-
function compare33b(a, b) {
|
37
|
-
if (a.length !== 33 || b.length !== 33)
|
38
|
-
throw new Error('Invalid array');
|
39
|
-
const cmp = a[0] - b[0];
|
40
|
-
if (cmp !== 0)
|
41
|
-
return cmp;
|
42
|
-
return compare32b(a.subarray(1), b.subarray(1));
|
43
|
-
}
|
44
|
-
const makeSessionId = typeof self === 'object' && (self.crypto || self.msCrypto)
|
45
|
-
? () => (self.crypto || self.msCrypto).getRandomValues(new Uint8Array(32)) // Browsers
|
46
|
-
: () => require('crypto').randomBytes(32); // Node
|
47
|
-
const _keyAggCache = new WeakMap();
|
48
|
-
// Caches coefficients associated with an array of public keys
|
49
|
-
const _coefCache = new WeakMap();
|
50
|
-
// Caches secret nonces. We do this internally to help users ensure that they
|
51
|
-
// do not reuse a secret nonce.
|
52
|
-
const _nonceCache = new WeakMap();
|
53
|
-
// Caches signing sessions. We do this internally to help users ensure that
|
54
|
-
// these session values were generated on the signer, and are not accepted from
|
55
|
-
// an untrusted third party.
|
56
|
-
const _sessionCache = new WeakMap();
|
57
|
-
function MuSigFactory(ecc) {
|
58
|
-
const CPOINT_INF = new Uint8Array(33);
|
59
|
-
const SCALAR_0 = new Uint8Array(32);
|
60
|
-
const SCALAR_1 = new Uint8Array(32);
|
61
|
-
SCALAR_1[31] = 1;
|
62
|
-
const SCALAR_MINUS_1 = ecc.scalarNegate(SCALAR_1);
|
63
|
-
function keyAggCoeff(publicKeys, publicKey) {
|
64
|
-
let coefCache = _coefCache.get(publicKeys);
|
65
|
-
if (coefCache === undefined) {
|
66
|
-
coefCache = new Map();
|
67
|
-
_coefCache.set(publicKeys, coefCache);
|
68
|
-
}
|
69
|
-
let coefficient = coefCache.get(publicKey);
|
70
|
-
if (coefficient)
|
71
|
-
return coefficient;
|
72
|
-
coefficient = SCALAR_1;
|
73
|
-
let secondPublicKey;
|
74
|
-
let publicKeyHash;
|
75
|
-
let keyAggCache = _keyAggCache.get(publicKeys);
|
76
|
-
if (keyAggCache === undefined) {
|
77
|
-
// Index of the first occurrence of the second unique public key.
|
78
|
-
const pkIdx2 = publicKeys.findIndex((pk) => compare33b(pk, publicKeys[0]) !== 0);
|
79
|
-
secondPublicKey = publicKeys[pkIdx2]; // undefined if pkIdx2 === -1
|
80
|
-
publicKeyHash = ecc.taggedHash(TAGS.keyagg_list, ...publicKeys);
|
81
|
-
keyAggCache = { publicKeyHash, secondPublicKey };
|
82
|
-
_keyAggCache.set(publicKeys, keyAggCache);
|
83
|
-
}
|
84
|
-
else {
|
85
|
-
({ publicKeyHash, secondPublicKey } = keyAggCache);
|
86
|
-
}
|
87
|
-
if (secondPublicKey === undefined || compare33b(publicKey, secondPublicKey) !== 0) {
|
88
|
-
coefficient = ecc.taggedHash(TAGS.keyagg_coef, publicKeyHash, publicKey);
|
89
|
-
}
|
90
|
-
coefCache.set(publicKey, coefficient);
|
91
|
-
return coefficient;
|
92
|
-
}
|
93
|
-
function addTweak(ctx, t) {
|
94
|
-
const tweak = 'tweak' in t ? t : { tweak: t };
|
95
|
-
if (!ecc.isScalar(tweak.tweak))
|
96
|
-
throw new TypeError('Expected tweak to be a valid scalar with curve order');
|
97
|
-
let { gacc, tacc } = ctx;
|
98
|
-
let aggPublicKey = ctx.aggPublicKey;
|
99
|
-
if (!ecc.hasEvenY(aggPublicKey) && tweak.xOnly) {
|
100
|
-
// g = -1
|
101
|
-
gacc = ecc.scalarNegate(gacc); // g * gacc mod n
|
102
|
-
tacc = ecc.scalarNegate(tacc); // g * tacc mod n
|
103
|
-
aggPublicKey = ecc.pointNegate(aggPublicKey); // g * Q
|
104
|
-
}
|
105
|
-
aggPublicKey = ecc.pointAddTweak(aggPublicKey, tweak.tweak, false); // g * Q + t * G
|
106
|
-
if (aggPublicKey === null)
|
107
|
-
throw new Error('Unexpected point at infinity during tweaking');
|
108
|
-
tacc = ecc.scalarAdd(tweak.tweak, tacc); // t + g * tacc mod n
|
109
|
-
return { aggPublicKey, gacc, tacc };
|
110
|
-
}
|
111
|
-
function keyAgg(publicKeys, ...tweaks) {
|
112
|
-
checkArgs({ publicKeys });
|
113
|
-
const multipliedPublicKeys = publicKeys.map((publicKey) => {
|
114
|
-
const coefficient = keyAggCoeff(publicKeys, publicKey);
|
115
|
-
let multipliedPublicKey;
|
116
|
-
if (compare32b(coefficient, SCALAR_1) === 0) {
|
117
|
-
multipliedPublicKey = publicKey;
|
118
|
-
}
|
119
|
-
else {
|
120
|
-
multipliedPublicKey = ecc.pointMultiplyUnsafe(publicKey, coefficient, false);
|
121
|
-
}
|
122
|
-
if (multipliedPublicKey === null)
|
123
|
-
throw new Error('Point at infinity during aggregation');
|
124
|
-
return multipliedPublicKey;
|
125
|
-
});
|
126
|
-
const aggPublicKey = multipliedPublicKeys.reduce((a, b) => {
|
127
|
-
const next = ecc.pointAdd(a, b, false);
|
128
|
-
if (next === null)
|
129
|
-
throw new Error('Point at infinity during aggregation');
|
130
|
-
return next;
|
131
|
-
});
|
132
|
-
return tweaks.reduce((ctx, tweak) => addTweak(ctx, tweak), {
|
133
|
-
aggPublicKey,
|
134
|
-
gacc: SCALAR_1,
|
135
|
-
tacc: SCALAR_0,
|
136
|
-
});
|
137
|
-
}
|
138
|
-
function getSessionValues(sessionKey) {
|
139
|
-
const sessionValues = _sessionCache.get(sessionKey);
|
140
|
-
if (!sessionValues)
|
141
|
-
throw new Error('Invalid session key, please call `startSigningSession`');
|
142
|
-
return sessionValues;
|
143
|
-
}
|
144
|
-
function nonceAgg(publicNonces) {
|
145
|
-
checkArgs({ publicNonces });
|
146
|
-
const aggNonces = [publicNonces[0].subarray(0, 33), publicNonces[0].subarray(33)];
|
147
|
-
for (let i = 1; i < publicNonces.length; i++) {
|
148
|
-
if (aggNonces[0] !== null)
|
149
|
-
aggNonces[0] = ecc.pointAdd(aggNonces[0], publicNonces[i].subarray(0, 33), false);
|
150
|
-
if (aggNonces[1] !== null)
|
151
|
-
aggNonces[1] = ecc.pointAdd(aggNonces[1], publicNonces[i].subarray(33), false);
|
152
|
-
}
|
153
|
-
const aggNonce = new Uint8Array(66);
|
154
|
-
if (aggNonces[0] !== null)
|
155
|
-
aggNonce.set(ecc.pointCompress(aggNonces[0]), 0);
|
156
|
-
if (aggNonces[1] !== null)
|
157
|
-
aggNonce.set(ecc.pointCompress(aggNonces[1]), 33);
|
158
|
-
return aggNonce;
|
159
|
-
}
|
160
|
-
function startSigningSessionInner(aggNonce, msg, publicKeys, ctx) {
|
161
|
-
const pubKeyX = ecc.pointX(ctx.aggPublicKey);
|
162
|
-
const coefficient = ecc.taggedHash(TAGS.musig_noncecoef, aggNonce, pubKeyX, msg);
|
163
|
-
const aggNonces = [aggNonce.subarray(0, 33), aggNonce.subarray(33)];
|
164
|
-
// This is kinda ugly, but crypto.pointAdd doesn't work on 0-coded infinity
|
165
|
-
let r = null;
|
166
|
-
if (compare33b(aggNonces[1], CPOINT_INF) !== 0 && compare33b(aggNonces[0], CPOINT_INF) !== 0) {
|
167
|
-
r = ecc.pointMultiplyAndAddUnsafe(aggNonces[1], coefficient, aggNonces[0], false);
|
168
|
-
}
|
169
|
-
else if (compare33b(aggNonces[0], CPOINT_INF) !== 0) {
|
170
|
-
r = ecc.pointCompress(aggNonces[0], false);
|
171
|
-
}
|
172
|
-
else if (compare33b(aggNonces[1], CPOINT_INF) !== 0) {
|
173
|
-
r = ecc.pointMultiplyUnsafe(aggNonces[1], coefficient, false);
|
174
|
-
}
|
175
|
-
if (r === null)
|
176
|
-
r = ecc.getPublicKey(SCALAR_1, false);
|
177
|
-
if (r === null)
|
178
|
-
throw new Error('Failed to get G');
|
179
|
-
const challenge = ecc.scalarMod(ecc.taggedHash(TAGS.challenge, ecc.pointX(r), pubKeyX, msg));
|
180
|
-
const key = { publicKey: ctx.aggPublicKey, aggNonce, msg };
|
181
|
-
_sessionCache.set(key, { ...ctx, coefficient, challenge, finalNonce: r, publicKeys });
|
182
|
-
return key;
|
183
|
-
}
|
184
|
-
function partialVerifyInner({ sig, publicKey, publicNonces, sessionKey, }) {
|
185
|
-
const { msg } = sessionKey;
|
186
|
-
const { aggPublicKey, gacc, challenge, coefficient, finalNonce, publicKeys } = getSessionValues(sessionKey);
|
187
|
-
const rePrime = ecc.pointMultiplyAndAddUnsafe(publicNonces[1], coefficient, publicNonces[0], false);
|
188
|
-
if (rePrime === null)
|
189
|
-
throw new Error('Unexpected public nonce at infinity');
|
190
|
-
const re = ecc.hasEvenY(finalNonce) ? rePrime : ecc.pointNegate(rePrime);
|
191
|
-
const a = keyAggCoeff(publicKeys, publicKey);
|
192
|
-
const g = ecc.hasEvenY(aggPublicKey) ? gacc : ecc.scalarNegate(gacc);
|
193
|
-
const ea = ecc.scalarMultiply(challenge, a);
|
194
|
-
const eag = ecc.scalarMultiply(ea, g);
|
195
|
-
const ver = ecc.pointMultiplyAndAddUnsafe(publicKey, eag, re, true);
|
196
|
-
if (ver === null)
|
197
|
-
throw new Error('Unexpected verification point at infinity');
|
198
|
-
const sG = ecc.getPublicKey(sig, true);
|
199
|
-
if (sG === null)
|
200
|
-
throw new Error('Unexpected signature point at infinity');
|
201
|
-
return compare33b(ver, sG) === 0;
|
202
|
-
}
|
203
|
-
function partialSignInner({ secretKey, publicKey, secretNonces, sessionKey, }) {
|
204
|
-
const { msg } = sessionKey;
|
205
|
-
const { aggPublicKey, gacc, challenge, coefficient, finalNonce, publicKeys } = getSessionValues(sessionKey);
|
206
|
-
const [k1, k2] = secretNonces.map((k) => (ecc.hasEvenY(finalNonce) ? k : ecc.scalarNegate(k)));
|
207
|
-
const a = keyAggCoeff(publicKeys, publicKey);
|
208
|
-
const g = ecc.hasEvenY(aggPublicKey) ? gacc : ecc.scalarNegate(gacc);
|
209
|
-
const d = ecc.scalarMultiply(g, secretKey);
|
210
|
-
const bk2 = ecc.scalarMultiply(coefficient, k2);
|
211
|
-
const k1bk2 = ecc.scalarAdd(k1, bk2);
|
212
|
-
const ea = ecc.scalarMultiply(challenge, a);
|
213
|
-
const ead = ecc.scalarMultiply(ea, d);
|
214
|
-
const sig = ecc.scalarAdd(k1bk2, ead);
|
215
|
-
return sig;
|
216
|
-
}
|
217
|
-
function partialSign({ secretKey, publicNonce, sessionKey, verify = true, }) {
|
218
|
-
checkArgs({ publicNonce, secretKey });
|
219
|
-
const secretNonce = _nonceCache.get(publicNonce);
|
220
|
-
if (secretNonce === undefined)
|
221
|
-
throw new Error('No secret nonce found for specified public nonce');
|
222
|
-
_nonceCache.delete(publicNonce);
|
223
|
-
const publicKey = ecc.getPublicKey(secretKey, true);
|
224
|
-
if (publicKey === null)
|
225
|
-
throw new Error('Invalid secret key, no corresponding public key');
|
226
|
-
if (compare33b(publicKey, secretNonce.subarray(64)) !== 0)
|
227
|
-
throw new Error('Secret nonce pubkey mismatch');
|
228
|
-
const secretNonces = [secretNonce.subarray(0, 32), secretNonce.subarray(32, 64)];
|
229
|
-
const sig = partialSignInner({
|
230
|
-
secretKey,
|
231
|
-
publicKey,
|
232
|
-
secretNonces,
|
233
|
-
sessionKey,
|
234
|
-
});
|
235
|
-
if (verify) {
|
236
|
-
const publicNonces = [publicNonce.subarray(0, 33), publicNonce.subarray(33)];
|
237
|
-
const valid = partialVerifyInner({
|
238
|
-
sig,
|
239
|
-
publicKey,
|
240
|
-
publicNonces,
|
241
|
-
sessionKey,
|
242
|
-
});
|
243
|
-
if (!valid)
|
244
|
-
throw new Error('Partial signature failed verification');
|
245
|
-
}
|
246
|
-
return sig;
|
247
|
-
}
|
248
|
-
function deterministicSign({ secretKey, aggOtherNonce, publicKeys, tweaks = [], msg, rand, verify = true, nonceOnly = false, }) {
|
249
|
-
// No need to check msg, its max size is larger than JS typed array limit
|
250
|
-
checkArgs({ rand, secretKey, aggOtherNonce });
|
251
|
-
const publicKey = ecc.getPublicKey(secretKey, true);
|
252
|
-
if (publicKey === null)
|
253
|
-
throw new Error('Secret key has no corresponding public key');
|
254
|
-
let secretKeyPrime;
|
255
|
-
if (rand !== undefined) {
|
256
|
-
secretKeyPrime = ecc.taggedHash(TAGS.musig_aux, rand);
|
257
|
-
for (let i = 0; i < 32; i++) {
|
258
|
-
secretKeyPrime[i] = secretKeyPrime[i] ^ secretKey[i];
|
259
|
-
}
|
260
|
-
}
|
261
|
-
else {
|
262
|
-
secretKeyPrime = secretKey;
|
263
|
-
}
|
264
|
-
const ctx = keyAgg(publicKeys, ...tweaks);
|
265
|
-
const aggPublicKey = ecc.pointX(ctx.aggPublicKey);
|
266
|
-
const mLength = new Uint8Array(8);
|
267
|
-
new DataView(mLength.buffer).setBigUint64(0, BigInt(msg.length));
|
268
|
-
const secretNonce = new Uint8Array(97);
|
269
|
-
const publicNonce = new Uint8Array(66);
|
270
|
-
for (let i = 0; i < 2; i++) {
|
271
|
-
const kH = ecc.taggedHash(TAGS.musig_deterministic_nonce, ...[secretKeyPrime, aggOtherNonce, aggPublicKey, mLength, msg, Uint8Array.of(i)]);
|
272
|
-
const k = ecc.scalarMod(kH);
|
273
|
-
if (compare32b(SCALAR_0, k) === 0)
|
274
|
-
throw new Error('0 secret nonce');
|
275
|
-
const pub = ecc.getPublicKey(k, true);
|
276
|
-
if (pub === null)
|
277
|
-
throw new Error('Secret nonce has no corresponding public nonce');
|
278
|
-
secretNonce.set(k, i * 32);
|
279
|
-
publicNonce.set(pub, i * 33);
|
280
|
-
}
|
281
|
-
secretNonce.set(publicKey, 64);
|
282
|
-
if (nonceOnly)
|
283
|
-
return { publicNonce };
|
284
|
-
_nonceCache.set(publicNonce, secretNonce);
|
285
|
-
const aggNonce = nonceAgg([aggOtherNonce, publicNonce]);
|
286
|
-
const sessionKey = startSigningSessionInner(aggNonce, msg, publicKeys, ctx);
|
287
|
-
const sig = partialSign({
|
288
|
-
secretKey,
|
289
|
-
publicNonce,
|
290
|
-
sessionKey,
|
291
|
-
verify,
|
292
|
-
});
|
293
|
-
return { sig, sessionKey, publicNonce };
|
294
|
-
}
|
295
|
-
// TODO: Improve arg checking now that we have startSigningSession
|
296
|
-
const pubKeyArgs = ['publicKey', 'publicKeys'];
|
297
|
-
const scalarArgs = ['tweak', 'sig', 'sigs', 'tacc', 'gacc'];
|
298
|
-
const otherArgs32b = ['xOnlyPublicKey', 'rand', 'sessionId'];
|
299
|
-
const args32b = ['secretKey', ...scalarArgs, ...otherArgs32b];
|
300
|
-
const pubNonceArgs = ['publicNonce', 'publicNonces', 'aggNonce', 'aggOtherNonce', 'finalNonce'];
|
301
|
-
const otherArgs = ['aggPublicKey', 'secretNonce'];
|
302
|
-
const argLengths = new Map();
|
303
|
-
args32b.forEach((a) => argLengths.set(a, 32));
|
304
|
-
pubKeyArgs.forEach((a) => argLengths.set(a, 33));
|
305
|
-
pubNonceArgs.forEach((a) => argLengths.set(a, 66));
|
306
|
-
argLengths.set('secretNonce', 97);
|
307
|
-
argLengths.set('aggPublicKey', 65);
|
308
|
-
const scalarNames = new Set();
|
309
|
-
scalarArgs.forEach((n) => scalarNames.add(n));
|
310
|
-
function checkArgs(args) {
|
311
|
-
for (let [name, values] of Object.entries(args)) {
|
312
|
-
if (values === undefined)
|
313
|
-
continue;
|
314
|
-
values = Array.isArray(values) ? values : [values];
|
315
|
-
if (values.length === 0)
|
316
|
-
throw new TypeError(`0-length ${name}s not supported`);
|
317
|
-
for (const value of values) {
|
318
|
-
if (argLengths.get(name) !== value.length)
|
319
|
-
throw new TypeError(`Invalid ${name} length (${value.length})`);
|
320
|
-
if (name === 'secretKey') {
|
321
|
-
if (!ecc.isSecret(value))
|
322
|
-
throw new TypeError(`Invalid secretKey`);
|
323
|
-
}
|
324
|
-
else if (name === 'secretNonce') {
|
325
|
-
for (let i = 0; i < 64; i += 32) {
|
326
|
-
if (!ecc.isSecret(value.subarray(i, i + 32)))
|
327
|
-
throw new TypeError(`Invalid secretNonce`);
|
328
|
-
}
|
329
|
-
}
|
330
|
-
else if (scalarNames.has(name)) {
|
331
|
-
for (let i = 0; i < value.length; i += 32) {
|
332
|
-
if (!ecc.isScalar(value.subarray(i, i + 32)))
|
333
|
-
throw new TypeError(`Invalid ${name}`);
|
334
|
-
}
|
335
|
-
}
|
336
|
-
// No need for a public key x-to-curve check. They're liftX'd for use any way.
|
337
|
-
}
|
338
|
-
}
|
339
|
-
}
|
340
|
-
return {
|
341
|
-
getXOnlyPubkey: (ctx) => {
|
342
|
-
if ('aggPublicKey' in ctx)
|
343
|
-
return ecc.pointX(ctx.aggPublicKey);
|
344
|
-
return ecc.pointX(getSessionValues(ctx).aggPublicKey);
|
345
|
-
},
|
346
|
-
getPlainPubkey: (ctx) => {
|
347
|
-
if ('aggPublicKey' in ctx)
|
348
|
-
return ecc.pointCompress(ctx.aggPublicKey);
|
349
|
-
return ecc.pointCompress(getSessionValues(ctx).aggPublicKey);
|
350
|
-
},
|
351
|
-
keySort: (publicKeys) => {
|
352
|
-
checkArgs({ publicKeys });
|
353
|
-
// do not modify the original array
|
354
|
-
return [...publicKeys].sort((a, b) => compare33b(a, b));
|
355
|
-
},
|
356
|
-
keyAgg,
|
357
|
-
addTweaks: (ctx, ...tweaks) => {
|
358
|
-
checkArgs(ctx);
|
359
|
-
return tweaks.reduce((c, tweak) => addTweak(c, tweak), ctx);
|
360
|
-
},
|
361
|
-
nonceGen: ({ sessionId = makeSessionId(), secretKey, publicKey, xOnlyPublicKey, msg, extraInput, }) => {
|
362
|
-
if (extraInput !== undefined && extraInput.length > Math.pow(2, 32) - 1) {
|
363
|
-
throw new TypeError('extraInput is limited to 2^32-1 bytes');
|
364
|
-
}
|
365
|
-
// No need to check msg, its max size is larger than JS typed array limit
|
366
|
-
checkArgs({ sessionId, secretKey, publicKey, xOnlyPublicKey });
|
367
|
-
let rand;
|
368
|
-
if (secretKey !== undefined) {
|
369
|
-
rand = ecc.taggedHash(TAGS.musig_aux, sessionId);
|
370
|
-
for (let i = 0; i < 32; i++) {
|
371
|
-
rand[i] = rand[i] ^ secretKey[i];
|
372
|
-
}
|
373
|
-
}
|
374
|
-
else {
|
375
|
-
rand = sessionId;
|
376
|
-
}
|
377
|
-
if (xOnlyPublicKey === undefined)
|
378
|
-
xOnlyPublicKey = new Uint8Array();
|
379
|
-
const mPrefixed = [Uint8Array.of(0)];
|
380
|
-
if (msg !== undefined) {
|
381
|
-
mPrefixed[0][0] = 1;
|
382
|
-
mPrefixed.push(new Uint8Array(8));
|
383
|
-
new DataView(mPrefixed[1].buffer).setBigUint64(0, BigInt(msg.length));
|
384
|
-
mPrefixed.push(msg);
|
385
|
-
}
|
386
|
-
if (extraInput === undefined)
|
387
|
-
extraInput = new Uint8Array();
|
388
|
-
const eLength = new Uint8Array(4);
|
389
|
-
new DataView(eLength.buffer).setUint32(0, extraInput.length);
|
390
|
-
const secretNonce = new Uint8Array(97);
|
391
|
-
const publicNonce = new Uint8Array(66);
|
392
|
-
for (let i = 0; i < 2; i++) {
|
393
|
-
const kH = ecc.taggedHash(TAGS.musig_nonce, rand, Uint8Array.of(publicKey.length), publicKey, Uint8Array.of(xOnlyPublicKey.length), xOnlyPublicKey, ...mPrefixed, eLength, extraInput, Uint8Array.of(i));
|
394
|
-
const k = ecc.scalarMod(kH);
|
395
|
-
if (compare32b(SCALAR_0, k) === 0)
|
396
|
-
throw new Error('0 secret nonce');
|
397
|
-
const pub = ecc.getPublicKey(k, true);
|
398
|
-
if (pub === null)
|
399
|
-
throw new Error('Secret nonce has no corresponding public nonce');
|
400
|
-
secretNonce.set(k, i * 32);
|
401
|
-
publicNonce.set(pub, i * 33);
|
402
|
-
}
|
403
|
-
secretNonce.set(publicKey, 64);
|
404
|
-
_nonceCache.set(publicNonce, secretNonce);
|
405
|
-
return publicNonce;
|
406
|
-
},
|
407
|
-
addExternalNonce: (publicNonce, secretNonce) => {
|
408
|
-
checkArgs({ publicNonce, secretNonce });
|
409
|
-
_nonceCache.set(publicNonce, secretNonce);
|
410
|
-
},
|
411
|
-
deterministicNonceGen: (args) => deterministicSign({ ...args, nonceOnly: true }),
|
412
|
-
deterministicSign,
|
413
|
-
nonceAgg,
|
414
|
-
startSigningSession: (aggNonce, msg, publicKeys, ...tweaks) => {
|
415
|
-
checkArgs({ aggNonce });
|
416
|
-
const ctx = keyAgg(publicKeys, ...tweaks);
|
417
|
-
return startSigningSessionInner(aggNonce, msg, publicKeys, ctx);
|
418
|
-
},
|
419
|
-
partialSign,
|
420
|
-
partialVerify: ({ sig, publicKey, publicNonce, sessionKey, }) => {
|
421
|
-
checkArgs({ sig, publicKey, publicNonce });
|
422
|
-
const publicNonces = [publicNonce.subarray(0, 33), publicNonce.subarray(33)];
|
423
|
-
const valid = partialVerifyInner({
|
424
|
-
sig,
|
425
|
-
publicKey,
|
426
|
-
publicNonces,
|
427
|
-
sessionKey,
|
428
|
-
});
|
429
|
-
return valid;
|
430
|
-
},
|
431
|
-
signAgg: (sigs, sessionKey) => {
|
432
|
-
checkArgs({ sigs });
|
433
|
-
const { aggPublicKey, tacc, challenge, finalNonce } = getSessionValues(sessionKey);
|
434
|
-
let sPart = ecc.scalarMultiply(challenge, tacc);
|
435
|
-
if (!ecc.hasEvenY(aggPublicKey)) {
|
436
|
-
sPart = ecc.scalarNegate(sPart);
|
437
|
-
}
|
438
|
-
const aggS = sigs.reduce((a, b) => ecc.scalarAdd(a, b), sPart);
|
439
|
-
const sig = new Uint8Array(64);
|
440
|
-
sig.set(ecc.pointX(finalNonce), 0);
|
441
|
-
sig.set(aggS, 32);
|
442
|
-
return sig;
|
443
|
-
},
|
444
|
-
};
|
445
|
-
}
|
446
|
-
exports.MuSigFactory = MuSigFactory;
|
447
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVzaWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbXVzaWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHFEQUFxRDtBQUNyRCx3RkFBd0Y7QUFDeEYsb0RBQW9EOzs7QUFrYnBELE1BQU0sSUFBSSxHQUFHO0lBQ1gsU0FBUyxFQUFFLG1CQUFtQjtJQUM5QixXQUFXLEVBQUUsYUFBYTtJQUMxQixXQUFXLEVBQUUsb0JBQW9CO0lBQ2pDLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFdBQVcsRUFBRSxhQUFhO0lBQzFCLHlCQUF5QixFQUFFLDJCQUEyQjtJQUN0RCxlQUFlLEVBQUUsaUJBQWlCO0NBQzFCLENBQUM7QUFFWDs7O0dBR0c7QUFDSCxTQUFTLFVBQVUsQ0FBQyxDQUFhLEVBQUUsQ0FBYTtJQUM5QyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssRUFBRTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDekUsTUFBTSxFQUFFLEdBQUcsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxNQUFNLEVBQUUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBSSxHQUFHLEtBQUssQ0FBQztZQUFF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QUFZLEVBQUUsQ0FBQyxDQUFDO1FBRTVCLE1BQU0sU0FBUyxHQUE2QixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUM1QyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO2dCQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM3RyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO2dCQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQzNHO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSTtZQUFFLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJO1lBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxD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SSxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQy9CLEtBQUssR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ2pDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9ELE1BQU0sR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQy9CLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQXBoQkQsb0NBb2hCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qICEgbXVzaWctanMgLSBNSVQgTGljZW5zZSAoYykgMjAyMiBCcmFuZG9uIEJsYWNrICovXG4vLyBodHRwczovL2dpdGh1Yi5jb20vRWxlbWVudHNQcm9qZWN0L3NlY3AyNTZrMS16a3AvYmxvYi9tYXN0ZXIvZG9jL211c2lnLXNwZWMubWVkaWF3aWtpXG4vLyBSb3VnaGx5IGJhc2VkIG9uIHRoZSBzZWNwMjU2azEtemtwIGltcGxlbWVudGF0aW9uXG5cbmV4cG9ydCBpbnRlcmZhY2UgTXVTaWcge1xuICAvKipcbiAgICogR2V0cyB0aGUgWC1vbmx5IHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dC5cbiAgICpcbiAgICogQHBhcmFtIGN0eCB0aGUga2V5IGdlbiBjb250ZXh0IG9yIGEgc2lnbmluZyBzZXNzaW9uIGtleVxuICAgKiBAcmV0dXJucyB0aGUgWC1vbmx5IHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dFxuICAgKi9cbiAgZ2V0WE9ubHlQdWJrZXkoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHBsYWluIHB1YmxpYyBrZXkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dC5cbiAgICpcbiAgICogQHBhcmFtIGN0eCB0aGUga2V5IGdlbiBjb250ZXh0IG9yIGEgc2lnbmluZyBzZXNzaW9uIGtleVxuICAgKiBAcmV0dXJucyBwbGFpbiBwdWJsaWMga2V5IGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbnRleHQgaW4gY29tcHJlc3NlZCBERVIgZm9ybWF0XG4gICAqL1xuICBnZXRQbGFpblB1YmtleShjdHg6IEtleUdlbkNvbnRleHQgfCBTZXNzaW9uS2V5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogU29ydHMgY29tcHJlc3NlZCBERVIgZm9ybWF0IHB1YmxpYyBrZXlzIGxleGljb2dyYXBoaWNhbGx5LlxuICAgKlxuICAgKiBAcGFyYW0gcHVibGljS2V5cyBhcnJheSBvZiBjb21wcmVzc2VkIERFUiBlbmNvZGVkIHB1YmxpYyBrZXlzIHRvIGFnZ3JlZ2F0ZVxuICAgKiBAcmV0dXJucyBzb3J0ZWQgcHVibGljIGtleXMgKGluIGEgbmV3IGFycmF5KVxuICAgKi9cbiAga2V5U29ydChwdWJsaWNLZXlzOiBVaW50OEFycmF5W10pOiBVaW50OEFycmF5W107XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIE11U2lnIGtleSBhZ2dyZWdhdGlvbiBvbiAxKyB4LW9ubHkgcHVibGljIGtleXMuXG4gICAqXG4gICAqIEBwYXJhbSBwdWJsaWNLZXlzIGFycmF5IG9mIGNvbXByZXNzZWQgREVSIGVuY29kZWQgcHVibGljIGtleXMgdG8gYWdncmVnYXRlXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEByZXR1cm5zIGFuIG9wYXF1ZSBrZXkgZ2VuIGNvbnRleHQgZm9yIHVzZSB3aXRoIG90aGVyIE11U2lnIG9wZXJhdGlvbnNcbiAgICovXG4gIGtleUFnZyhwdWJsaWNLZXlzOiBVaW50OEFycmF5W10sIC4uLnR3ZWFrczogVHdlYWtbXSk6IEtleUdlbkNvbnRleHQ7XG5cbiAgLyoqXG4gICAqIEFwcGx5IG9uZSBvciBtb3JlIHgtb25seSBvciBvcmRpbmFyeSB0d2Vha3MgdG8gYW4gYWdncmVnYXRlIHB1YmxpYyBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSBjdHggdGhlIGtleSBnZW5lcmF0aW9uIGNvbnRleHQsIGFzIHJldHVybmVkIGZyb20gYGtleUFnZ2AuXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEByZXR1cm5zIGFuIG9wYXF1ZSBrZXkgZ2VuIGNvbnRleHQgZm9yIHVzZSB3aXRoIG90aGVyIE11U2lnIG9wZXJhdGlvbnNcbiAgICovXG4gIGFkZFR3ZWFrcyhjdHg6IEtleUdlbkNvbnRleHQsIC4uLnR3ZWFrczogVHdlYWtbXSk6IEtleUdlbkNvbnRleHQ7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGEgTXVTaWcgbm9uY2UgcGFpciBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgdmFsdWVzLlxuICAgKlxuICAgKiBUaGUgY2FsbGVyIG11c3Qgbm90IHVzZSB0aGUgc2FtZSBzZXNzaW9uSWQgZm9yIG11bHRpcGxlIGNhbGxzIHRvIG5vbmNlR2VuXG4gICAqIHdpdGggb3RoZXIgcGFyYW1ldGVycyBoZWxkIGNvbnN0YW50LlxuICAgKlxuICAgKiBUaGUgc2VjcmV0IG5vbmNlICg5NyBieXRlcykgaXMgY2FjaGVkIGludGVybmFsbHksIGFuZCB3aWxsIGJlIGRlbGV0ZWRcbiAgICogZnJvbSB0aGUgY2FjaGUgcHJpb3IgdG8gdXNlIGluIGEgc2lnbmF0dXJlLiBUaGUgc2VjcmV0IG5vbmNlIHdpbGwgYWxzbyBiZVxuICAgKiBkZWxldGVkIGlmIHRoZSByZXR1cm5lZCBwdWJsaWMgbm9uY2UgaXMgZGVsZXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHNlc3Npb25JZCBpZiBubyBzZWNyZXQga2V5IGlzIHByb3ZpZGVkLCB1bmlmb3JtbHkgMzItYnl0ZXMgb2ZcbiAgICogcmFuZG9tIGRhdGEsIG90aGVyd2lzZSBhIHZhbHVlIGd1YXJhbnRlZWQgbm90IHRvIHJlcGVhdCBmb3IgdGhlIHNlY3JldFxuICAgKiBrZXkuIElmIG5vIHNlc3Npb25JZCBpcyBwcm92aWRlZCBhIHJlYXNvbmFibHkgaGlnaCBxdWFsaXR5IHJhbmRvbSBvbmUgd2lsbFxuICAgKiBiZSBnZW5lcmF0ZWQuXG4gICAqIEBwYXJhbSBzZWNyZXRLZXkgdGhlIHNlY3JldCBrZXkgd2hpY2ggd2lsbCBldmVudHVhbGx5IHNpZ24gd2l0aCB0aGlzIG5vbmNlXG4gICAqIEBwYXJhbSBwdWJsaWNLZXkgdGhlIHB1YmxpYyBrZXkgZm9yIHdoaWNoIHRoaXMgbm9uY2Ugd2lsbCBiZSBzaWduZWQgKHJlcXVpcmVkKVxuICAgKiBAcGFyYW0geE9ubHlQdWJsaWNLZXkgdGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgYWdncmVnYXRlIHB1YmxpYyBrZXkgdGhhdCB0aGlzXG4gICAqIG5vbmNlIHdpbGwgYmUgc2lnbmluZyBhIHBhcnQgb2ZcbiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSB3aGljaCB3aWxsIGV2ZW50dWFsbHkgYmUgc2lnbmVkIHdpdGggdGhpcyBub25jZVxuICAgKiAoYW55IHBvc3NpYmxlIFVpbnQ4QXJyYXkgbGVuZ3RoKVxuICAgKiBAcGFyYW0gZXh0cmFJbnB1dCBhZGRpdGlvbmFsIGlucHV0IHdoaWNoIHdpbGwgY29udHJpYnV0ZSB0byB0aGUgZ2VuZXJhdGVkXG4gICAqIG5vbmNlICgwIDw9IGV4dHJhSW5wdXQubGVuZ3RoIDw9IDJeMzItMSlcbiAgICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIHB1YmxpYyBub25jZSAoNjYgYnl0ZXMpXG4gICAqL1xuICBub25jZUdlbihhcmdzOiB7XG4gICAgc2Vzc2lvbklkPzogVWludDhBcnJheTtcbiAgICBzZWNyZXRLZXk/OiBVaW50OEFycmF5O1xuICAgIHB1YmxpY0tleTogVWludDhBcnJheTtcbiAgICB4T25seVB1YmxpY0tleT86IFVpbnQ4QXJyYXk7XG4gICAgbXNnPzogVWludDhBcnJheTtcbiAgICBleHRyYUlucHV0PzogVWludDhBcnJheTtcbiAgfSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIEFkZCBhbiBleHRlcm5hbGx5IGdlbmVyYXRlZCBub25jZSB0byB0aGUgY2FjaGUuXG4gICAqXG4gICAqIE5PVCBSRUNPTU1FTkRFRCwgYnV0IHVzZWZ1bCBpbiB0ZXN0aW5nIGF0IGxlYXN0LlxuICAgKiBAcGFyYW0gcHVibGljTm9uY2UgNjYtYnl0ZSBwdWJsaWMgbm9uY2UgKDIgcG9pbnRzIGluIGNvbXByZXNzZWQgREVSKVxuICAgKiBAcGFyYW0gc2VjcmV0Tm9uY2UgOTctYnl0ZSBzZWNyZXQgbm9uY2UgKDIgMzItYnl0ZSBzY2FsYXJzLCBhbmQgdGhlIHB1YmxpY1xuICAgKiBrZXkgd2hpY2ggd2lsbCBzaWduIGZvciB0aGlzIG5vbmNlIGluIGNvbXByZXNzZWQgREVSKVxuICAgKi9cbiAgYWRkRXh0ZXJuYWxOb25jZShwdWJsaWNOb25jZTogVWludDhBcnJheSwgc2VjcmV0Tm9uY2U6IFVpbnQ4QXJyYXkpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBDb21iaW5lIHB1YmxpYyBub25jZXMgZnJvbSBhbGwgc2lnbmVycyBpbnRvIGEgc2luZ2xlIGFnZ3JlZ2F0ZSBwdWJsaWMgbm9uY2UuXG4gICAqXG4gICAqIFBlciB0aGUgc3BlYywgdGhpcyBmdW5jdGlvbiBwcmVmZXJzIHRvIHN1Y2NlZWQgd2l0aCBhbiBpbnZhbGlkIG5vbmNlIGF0XG4gICAqIGluZmluaXR5IHRoYW4gdG8gZmFpbCwgdG8gZW5hYmxlIGEgZGlzaG9uZXN0IHNpZ25lciB0byBiZSBkZXRlY3RlZCBsYXRlci5cbiAgICpcbiAgICogVGhpcyBjYW4gYmUgcnVuIGJ5IGFuIHVudHJ1c3RlZCBub2RlIHdpdGhvdXQgYnJlYWtpbmcgdGhlIHNlY3VyaXR5IG9mIHRoZVxuICAgKiBwcm90b2NvbC4gQW4gdW50cnVzdGVkIGFnZ3JlZ2F0b3IgY2FuIGNhdXNlIHRoZSBwcm90b2NvbCB0byBmYWlsLCBidXQgbm90XG4gICAqIGZvcmdlIGEgc2lnbmF0dXJlLlxuICAgKlxuICAgKiBAcGFyYW0gbm9uY2VzIG4tc2lnbmVycyBwdWJsaWMgbm9uY2VzICg2Ni1ieXRlcyBlYWNoKVxuICAgKiBAcmV0dXJuIHRoZSBhZ2dyZWdhdGUgcHVibGljIG5vbmNlICg2Ni1ieXRlcylcbiAgICovXG4gIG5vbmNlQWdnKG5vbmNlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBvcGFxdWUgc2lnbmluZyBzZXNzaW9uIGZvciB1c2VkIGluIHBhcnRpYWwgc2lnbmluZywgcGFydGlhbFxuICAgKiB2ZXJpZmljYXRpb24sIG9yIHNpZ25hdHVyZSBhZ2dyZWdhdGlvbi4gVGhpcyBtYXkgYmUgc2F2ZWQgYnkgYVxuICAgKiBwYXJ0aWNpcGFudCwgYnV0IG1heSBub3QgYmUgcHJvdmlkZWQgYnkgYW4gdW50cnVzdGVkIHBhcnR5LlxuICAgKlxuICAgKiBAcGFyYW0gYWdnTm9uY2UgdGhpcyBzaWduaW5nIHNlc3Npb24ncyBhZ2dyZWdhdGUgbm9uY2VcbiAgICogQHBhcmFtIG1zZyB0aGUgMzItYnl0ZSBtZXNzYWdlIHRvIHNpZ24gZm9yLCBtb3N0IGNvbW1vbmx5IGEgdHJhbnNhY3Rpb24gaGFzaC5cbiAgICogQHBhcmFtIHB1YmxpY0tleXMgYXJyYXkgb2YgY29tcHJlc3NlZCBERVIgZW5jb2RlZCBwdWJsaWMga2V5cyB0byBhZ2dyZWdhdGVcbiAgICogQHBhcmFtIHR3ZWFrcyB0d2Vha3MgKDAgPCB0d2VhayA8IG4pIHRvIGFwcGx5IHRvIHRoZSBhZ2dyZWdhdGUga2V5LFxuICAgKiBhbmQgb3B0aW9uYWxseSBib29sZWFucyB0byBpbmRpY2F0ZSB4LW9ubHkgdHdlYWtpbmdcbiAgICogQHJldHVybiBzZXNzaW9uIGtleSBmb3IgYHBhcnRpYWxTaWduYCwgYHBhcnRpYWxWZXJpZnlgIGFuZCBgc2lnbkFnZ2BcbiAgICovXG4gIHN0YXJ0U2lnbmluZ1Nlc3Npb24oYWdnTm9uY2U6IFVpbnQ4QXJyYXksIG1zZzogVWludDhBcnJheSwgcHVibGljS2V5czogVWludDhBcnJheVtdLCAuLi50d2Vha3M6IFR3ZWFrW10pOiBTZXNzaW9uS2V5O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgTXVTaWcgcGFydGlhbCBzaWduYXR1cmUgZm9yIHRoZSBnaXZlbiB2YWx1ZXMuXG4gICAqXG4gICAqIFZlcmlmaWVzIHRoZSByZXN1bHRpbmcgcGFydGlhbCBzaWduYXR1cmUgYnkgZGVmYXVsdCwgYXMgcmVjb21tZW5kZWQgaW4gdGhlXG4gICAqIHNwZWNpZmljYXRpb24uXG4gICAqXG4gICAqIE5vdGU6IENhbGxpbmcgYHBhcnRpYWxTaWduYCB3aXRoIHRoZSBzYW1lIGBwdWJsaWNOb25jZWAgbW9yZSB0aGFuIG9uY2VcbiAgICogd2lsbCBub3Qgd29yaywgYXMgdGhlIGNvcnJlc3BvbmRpbmcgc2VjcmV0IG5vbmNlIGlzIGRlbGV0ZWQuIEdlbmVyYXRlIGFcbiAgICogbmV3IHB1YmxpYyBub25jZSBhbmQgdHJ5IGFnYWluLlxuICAgKlxuICAgKiBAcGFyYW0gc2VjcmV0S2V5IHNpZ25lcidzIHNlY3JldCBrZXlcbiAgICogQHBhcmFtIHB1YmxpY05vbmNlIHNpZ25lcidzIHB1YmxpYyBub25jZVxuICAgKiBAcGFyYW0gc2Vzc2lvbktleSBzaWduaW5nIHNlc3Npb24ga2V5IChmcm9tIHN0YXJ0U2lnbmluZ1Nlc3Npb24pXG4gICAqIEBwYXJhbSB2ZXJpZnkgaWYgZmFsc2UsIGRvbid0IHZlcmlmeSBwYXJ0aWFsIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuIHJlc3VsdGluZyBzaWduYXR1cmVcbiAgICovXG4gIHBhcnRpYWxTaWduKGFyZ3M6IHtcbiAgICBzZWNyZXRLZXk6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgICB2ZXJpZnk/OiBib29sZWFuO1xuICB9KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogVmVyaWZpZXMgYSBNdVNpZyBwYXJ0aWFsIHNpZ25hdHVyZSBmb3IgdGhlIGdpdmVuIHZhbHVlcy5cbiAgICpcbiAgICogQHBhcmFtIHNpZyB0aGUgMzItYnl0ZSBNdVNpZyBwYXJ0aWFsIHNpZ25hdHVyZSB0byB2ZXJpZnlcbiAgICogQHBhcmFtIG1zZyB0aGUgMzItYnl0ZSBtZXNzYWdlIHRvIHNpZ24gZm9yLCBtb3N0IGNvbW1vbmx5IGEgdHJhbnNhY3Rpb24gaGFzaFxuICAgKiBAcGFyYW0gcHVibGljS2V5IHNpZ25lcidzIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHB1YmxpY05vbmNlIHNpZ25lcidzIHB1YmxpYyBub25jZVxuICAgKiBAcGFyYW0gYWdnTm9uY2UgdGhpcyBzaWduaW5nIHNlc3Npb24ncyBhZ2dyZWdhdGUgbm9uY2VcbiAgICogQHBhcmFtIHNlc3Npb25LZXkgc2lnbmluZyBzZXNzaW9uIGtleSAoZnJvbSBzdGFydFNpZ25pbmdTZXNzaW9uKVxuICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHBhcnRpYWwgc2lnbmF0dXJlIGlzIHZhbGlkLCBvdGhlcndpc2UgZmFsc2VcbiAgICovXG4gIHBhcnRpYWxWZXJpZnkoYXJnczoge1xuICAgIHNpZzogVWludDhBcnJheTtcbiAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgfSk6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFnZ3JlZ2F0ZXMgTXVTaWcgcGFydGlhbCBzaWduYXR1cmVzLiBNYXkgYmUgcnVuIGJ5IGFuIHVudHJ1c3RlZCBwYXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHNpZ3MgYXJyYXkgb2YgMzItYnl0ZXMgTXVTaWcgcGFydGlhbCBzaWduYXR1cmVzLlxuICAgKiBAcGFyYW0gc2Vzc2lvbktleSBzaWduaW5nIHNlc3Npb24ga2V5IChmcm9tIHN0YXJ0U2lnbmluZ1Nlc3Npb24pXG4gICAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBhZ2dyZWdhdGUgc2lnbmF0dXJlLlxuICAgKi9cbiAgc2lnbkFnZyhzaWdzOiBVaW50OEFycmF5W10sIHNlc3Npb25LZXk6IFNlc3Npb25LZXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmlzdGljYWxseSBnZW5lcmF0ZSBub25jZXMgYW5kIHBhcnRpYWxseSBzaWduIGZvciBhIE11U2lnIGtleS5cbiAgICogVGhlIHNlY3VyaXR5IG9mIHRoaXMgbWV0aG9kIGRlcGVuZHMgb24gaXRzIGJlaW5nIHJ1biBhZnRlciBhbGwgb3RoZXJcbiAgICogcGFydGllcyBoYXZlIHByb3ZpZGVkIHRoZWlyIG5vbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIHNlY3JldEtleSBzaWduZXIncyBzZWNyZXQga2V5XG4gICAqIEBwYXJhbSBhZ2dPdGhlck5vbmNlIHRoZSByZXN1bHQgb2YgY2FsbGluZyBgbm9uY2VBZ2dgIG9uIGFsbCBvdGhlciBzaWduaW5nXG4gICAqIHBhcnRpZXMnIG5vbmNlc1xuICAgKiBAcGFyYW0gcHVibGljS2V5cyBhcnJheSBvZiBjb21wcmVzc2VkIERFUiBlbmNvZGVkIHB1YmxpYyBrZXlzIHRvIGFnZ3JlZ2F0ZVxuICAgKiBAcGFyYW0gdHdlYWtzIHR3ZWFrcyAoMCA8IHR3ZWFrIDwgbikgdG8gYXBwbHkgdG8gdGhlIGFnZ3JlZ2F0ZSBrZXksXG4gICAqIGFuZCBvcHRpb25hbGx5IGJvb2xlYW5zIHRvIGluZGljYXRlIHgtb25seSB0d2Vha2luZ1xuICAgKiBAcGFyYW0gbXNnIHRoZSAzMi1ieXRlIG1lc3NhZ2UgdG8gc2lnbiBmb3IsIG1vc3QgY29tbW9ubHkgYSB0cmFuc2FjdGlvbiBoYXNoLlxuICAgKiBAcGFyYW0gcmFuZCBvcHRpb25hbCBhZGRpdGlvbmFsIHJhbmRvbW5lc3MgZm9yIG5vbmNlIGdlbmVyYXRpb25cbiAgICogQHBhcmFtIHZlcmlmeSBpZiBmYWxzZSwgZG9uJ3QgdmVyaWZ5IHBhcnRpYWwgc2lnbmF0dXJlXG4gICAqIEByZXR1cm4gcmVzdWx0aW5nIHNpZ25hdHVyZSwgc2Vzc2lvbiBrZXkgKGZvciBzaWduYXR1cmUgYWdncmVnYXRpb24pLCBhbmRcbiAgICogcHVibGljIG5vbmNlIChmb3IgcGFydGlhbCB2ZXJpZmljYXRpb24pXG4gICAqL1xuICBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICAgIHZlcmlmeT86IGJvb2xlYW47XG4gIH0pOiB7XG4gICAgc2lnOiBVaW50OEFycmF5O1xuICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gICAgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXk7XG4gIH07XG5cbiAgLyoqXG4gICAqIERldGVybWluaXN0aWNhbGx5IGdlbmVyYXRlIG5vbmNlcy4gVGhpcyBpcyBpZGVudGljYWwgdG8gZGV0ZXJtaW5pc3RpY1NpZ24sXG4gICAqIGV4Y2VwdCB0aGF0IGl0IGFib3J0cyBhZnRlciBub25jZSBnZW5lcmF0aW9uIGFuZCBiZWZvcmUgc2lnbmluZywgYW5kXG4gICAqIHJldHVybnMgb25seSB0aGUgcHVibGljIG5vbmNlLiBUaGlzIHNlY3VyaXR5IG9mIHRoaXMgbWV0aG9kIG9mIG5vbmNlXG4gICAqIGdlbmVyYXRpb24gZGVwZW5kcyBvbiBpdHMgYmVpbmcgcnVuIGFmdGVyIGFsbCBvdGhlciBwYXJ0aWVzIGhhdmUgcHJvdmlkZWRcbiAgICogdGhlaXIgbm9uY2VzLlxuICAgKlxuICAgKiBBIHB1YmxpYyBub25jZSBnZW5lcmF0ZWQgaW4gdGhpcyB3YXkgY2Fubm90IGJlIGRpcmVjdGx5IHVzZWQgZm9yIHNpZ25pbmdcbiAgICogKG5vIHNlY3JldCBub25jZSBpcyBzYXZlZCksIGJ1dCBhIG1hdGNoaW5nIHBhcnRpYWwgc2lnbmF0dXJlIGNhbiBiZVxuICAgKiBnZW5lcmF0ZWQgYnkgc3Vic2VxdWVudGx5IGNhbGxpbmcgZGV0ZXJtaW5pc3RpY1NpZ24gd2l0aCB0aGUgc2FtZVxuICAgKiBhcmd1bWVudHMgYXMgdGhlIGNhbGwgdG8gZGV0ZXJtaW5pc3RpY05vbmNlR2VuLlxuICAgKlxuICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgaW4gYSBjYXNlIHdoZXJlIGEgc3RhdGVsZXNzIHNpZ25lciBvbmx5IHdhbnRzIHRvXG4gICAqIHByb3ZpZGUgaXRzIHBhcnRpYWwgc2lnbmF0dXJlIGFmdGVyIHNlZWluZyB2YWxpZCBwYXJ0aWFsIHNpZ25hdHVyZXMgZnJvbVxuICAgKiBvdGhlciBwYXJ0aWVzLlxuICAgKlxuICAgKiBAcGFyYW0gc2VjcmV0S2V5IHNpZ25lcidzIHNlY3JldCBrZXlcbiAgICogQHBhcmFtIGFnZ090aGVyTm9uY2UgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIGBub25jZUFnZ2Agb24gYWxsIG90aGVyIHNpZ25pbmdcbiAgICogcGFydGllcycgbm9uY2VzXG4gICAqIEBwYXJhbSBwdWJsaWNLZXlzIGFycmF5IG9mIGNvbXByZXNzZWQgREVSIGVuY29kZWQgcHVibGljIGtleXMgdG8gYWdncmVnYXRlXG4gICAqIEBwYXJhbSB0d2Vha3MgdHdlYWtzICgwIDwgdHdlYWsgPCBuKSB0byBhcHBseSB0byB0aGUgYWdncmVnYXRlIGtleSxcbiAgICogYW5kIG9wdGlvbmFsbHkgYm9vbGVhbnMgdG8gaW5kaWNhdGUgeC1vbmx5IHR3ZWFraW5nXG4gICAqIEBwYXJhbSBtc2cgdGhlIDMyLWJ5dGUgbWVzc2FnZSB0byBzaWduIGZvciwgbW9zdCBjb21tb25seSBhIHRyYW5zYWN0aW9uIGhhc2guXG4gICAqIEBwYXJhbSByYW5kIG9wdGlvbmFsIGFkZGl0aW9uYWwgcmFuZG9tbmVzcyBmb3Igbm9uY2UgZ2VuZXJhdGlvblxuICAgKiBAcGFyYW0gdmVyaWZ5IGlmIGZhbHNlLCBkb24ndCB2ZXJpZnkgcGFydGlhbCBzaWduYXR1cmVcbiAgICogQHJldHVybiBwdWJsaWMgbm9uY2VcbiAgICovXG4gIGRldGVybWluaXN0aWNOb25jZUdlbihhcmdzOiB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICB9KTogeyBwdWJsaWNOb25jZTogVWludDhBcnJheSB9O1xuICAvLyBUT0RPOiBEaXNjdXNzIHdpdGggSFNNIHRlYW0gdGhlIGdlbmVyYXRpb24gb2YgYWxsIHRoZSBub25jZXMgYW5kIGFueVxuICAvLyBwb3RlbnRpYWwgc2NhbGluZyBjb25jZXJucyAoM3ggdGhlIHRvdGFsIGNvc3Qgb2Ygc2Nobm9yciBzaWduaW5nKVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyeXB0byB7XG4gIC8qKlxuICAgKiBBZGRzIGEgdHdlYWsgdG8gYSBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHAgQSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIHQgQSB0d2VhaywgMCA8IHQgPCBuXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHR3ZWFrZWQgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkLCBudWxsIGlmIHRoZSByZXN1bHRcbiAgICogaXMgdGhlIHBvaW50IGF0IGluZmluaXR5LlxuICAgKi9cbiAgcG9pbnRBZGRUd2VhayhwOiBVaW50OEFycmF5LCB0OiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEFkZHMgdHdvIHBvaW50cy5cbiAgICpcbiAgICogQHBhcmFtIGEgQW4gYWRkZW5kIHBvaW50LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gYiBBbiBhZGRlbmQgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHN1bSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWQsIG51bGwgaWYgdGhlIHJlc3VsdCBpc1xuICAgKiB0aGUgcG9pbnQgYXQgaW5maW5pdHkuXG4gICAqL1xuICBwb2ludEFkZChhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIE11bHRpcGxpZXMgYSBwb2ludCBieSBhIHNjYWxhci5cbiAgICogVGhpcyBmdW5jdGlvbiBtYXkgdXNlIG5vbi1jb25zdGFudCB0aW1lIG9wZXJhdGlvbnMsIGFzIG5vIHNlY3JldFxuICAgKiBpbmZvcm1hdGlvbiBpcyBwcm9jZXNzZWQuXG4gICAqXG4gICAqIEBwYXJhbSBwIEEgcG9pbnQgbXVsdGlwbGljYW5kLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gYSBUaGUgbXVsdGlwbGllciwgMCA8IGEgPCBuXG4gICAqIEBwYXJhbSBjb21wcmVzc2VkIFdoZXRoZXIgdGhlIHJlc3VsdGluZyBwb2ludCBzaG91bGQgYmUgY29tcHJlc3NlZC5cbiAgICogQHJldHVybnMgVGhlIHByb2R1Y3QgcG9pbnQsIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkLCBudWxsIGlmIHRoZSByZXN1bHRcbiAgICogaXMgdGhlIHBvaW50IGF0IGluZmluaXR5LlxuICAgKi9cbiAgcG9pbnRNdWx0aXBseVVuc2FmZShwOiBVaW50OEFycmF5LCBhOiBVaW50OEFycmF5LCBjb21wcmVzc2VkOiBib29sZWFuKTogVWludDhBcnJheSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIE11bHRpcGxpZXMgcG9pbnQgMSBieSBhIHNjYWxhciBhbmQgYWRkcyBpdCB0byBwb2ludCAyLlxuICAgKiBUaGlzIGZ1bmN0aW9uIG1heSB1c2Ugbm9uLWNvbnN0YW50IHRpbWUgb3BlcmF0aW9ucywgYXMgbm8gc2VjcmV0XG4gICAqIGluZm9ybWF0aW9uIGlzIHByb2Nlc3NlZC5cbiAgICpcbiAgICogQHBhcmFtIHAxIHBvaW50IG11bHRpcGxpY2FuZCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIGEgVGhlIG11bHRpcGxpZXIsIDAgPCBhIDwgblxuICAgKiBAcGFyYW0gcDIgcG9pbnQgYWRkZW5kLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcGFyYW0gY29tcHJlc3NlZCBXaGV0aGVyIHRoZSByZXN1bHRpbmcgcG9pbnQgc2hvdWxkIGJlIGNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9kdWN0L3N1bSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWQsIG51bGwgaWYgdGhlXG4gICAqIHJlc3VsdCBpcyB0aGUgcG9pbnQgYXQgaW5maW5pdHkuXG4gICAqL1xuICBwb2ludE11bHRpcGx5QW5kQWRkVW5zYWZlKHAxOiBVaW50OEFycmF5LCBhOiBVaW50OEFycmF5LCBwMjogVWludDhBcnJheSwgY29tcHJlc3NlZDogYm9vbGVhbik6IFVpbnQ4QXJyYXkgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBOZWdhdGVzIGEgcG9pbnQsIGllLiByZXR1cm5zIHRoZSBwb2ludCB3aXRoIHRoZSBvcHBvc2l0ZSBwYXJpdHkuXG4gICAqXG4gICAqIEBwYXJhbSBwIEEgcG9pbnQgdG8gbmVnYXRlLCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcmV0dXJucyBUaGUgbmVnYXRlZCBwb2ludCwgd2l0aCBzYW1lIGNvbXByZXNzaW9uIGFzIGlucHV0LlxuICAgKi9cbiAgcG9pbnROZWdhdGUocDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIENvbXByZXNzZXMgYSBwb2ludC5cbiAgICpcbiAgICogQHBhcmFtIHAgQSBwb2ludCwgY29tcHJlc3NlZCBvciB1bmNvbXByZXNzZWRcbiAgICogQHBhcmFtIGNvbXByZXNzIFtkZWZhdWx0PXRydWVdIGlmIGZhbHNlLCB1bmNvbXByZXNzIHRoZSBwb2ludFxuICAgKiBAcmV0dXJucyBUaGUgcG9pbnQsIGNvbXByZXNzZWQgaWYgY29tcHJlc3MgaXMgdHJ1ZSwgb3IgdW5jb21wcmVzc2VkIGlmIGZhbHNlLlxuICAgKi9cbiAgcG9pbnRDb21wcmVzcyhwOiBVaW50OEFycmF5LCBjb21wcmVzcz86IGJvb2xlYW4pOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBBZGRzIG9uZSB2YWx1ZSB0byBhbm90aGVyLCBtb2Qgbi5cbiAgICpcbiAgICogQHBhcmFtIGEgQW4gYWRkZW5kLCAwIDw9IGEgPCBuXG4gICAqIEBwYXJhbSBiIEFuIGFkZGVuZCwgMCA8PSBiIDwgblxuICAgKiBAcmV0dXJucyBUaGUgc3VtLCAwIDw9IHN1bSA8IG5cbiAgICovXG4gIHNjYWxhckFkZChhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogTXVsdGlwbHkgb25lIHZhbHVlIGJ5IGFub3RoZXIsIG1vZCBuLlxuICAgKlxuICAgKiBAcGFyYW0gYSBUaGUgbXVsdGlwbGljYW5kLCAwIDw9IGEgPCBuXG4gICAqIEBwYXJhbSBiIFRoZSBtdWx0aXBsaWVyLCAwIDw9IGIgPCBuXG4gICAqIEByZXR1cm5zIFRoZSBwcm9kdWN0LCAwIDw9IHByb2R1Y3QgPCBuXG4gICAqL1xuICBzY2FsYXJNdWx0aXBseShhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogTmVnYXRlcyBhIHZhbHVlLCBtb2Qgbi5cbiAgICpcbiAgICogQHBhcmFtIGEgVGhlIHZhbHVlIHRvIG5lZ2F0ZSwgMCA8PSBhIDwgblxuICAgKiBAcmV0dXJucyBUaGUgbmVnYXRlZCB2YWx1ZSwgMCA8PSBuZWdhdGVkIDwgblxuICAgKi9cbiAgc2NhbGFyTmVnYXRlKGE6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gYSBUaGUgdmFsdWUgdG8gcmVkdWNlXG4gICAqIEByZXR1cm5zIGEgbW9kIG5cbiAgICovXG4gIHNjYWxhck1vZChhOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogQHBhcmFtIHMgQSBidWZmZXIgdG8gY2hlY2sgYWdhaW5zdCB0aGUgY3VydmUgb3JkZXJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBzIGlzIGEgMzItYnl0ZSBhcnJheSAwIDw9IHMgPCBuXG4gICAqL1xuICBpc1NjYWxhcihzOiBVaW50OEFycmF5KTogYm9vbGVhbjtcblxuICAvKipcbiAgICogQHBhcmFtIHMgQSBidWZmZXIgdG8gY2hlY2sgYWdhaW5zdCB0aGUgY3VydmUgb3JkZXJcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBzIGlzIGEgMzItYnl0ZSBhcnJheSAwIDwgcyA8IG5cbiAgICovXG4gIGlzU2VjcmV0KHM6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBBIGJ1ZmZlciB0byBjaGVjayBhZ2FpbnN0IHRoZSBjdXJ2ZSBlcXVhdGlvbiwgY29tcHJlc3NlZCBvclxuICAgKiB1bmNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIHRydWUgaWYgcCBpcyBhIHZhbGlkIHBvaW50IG9uIHNlY3AyNTZrMSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBpc1BvaW50KHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBBIGJ1ZmZlciB0byBjaGVjayBhZ2FpbnN0IHRoZSBjdXJ2ZSBlcXVhdGlvbi5cbiAgICogQHJldHVybnMgdHJ1ZSBpZiBwIGlzIHRoZSB4IGNvb3JkaW5hdGUgb2YgYSB2YWxpZCBwb2ludCBvbiBzZWNwMjU2azEsXG4gICAqIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgaXNYT25seVBvaW50KHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBhbiB4IGNvb3JkaW5hdGVcbiAgICogQHJldHVybnMgdGhlIHh5LCB1bmNvbXByZXNzZWQgcG9pbnQgaWYgcCBpcyBvbiB0aGUgY3VydmUsIG90aGVyd2lzZSBudWxsLlxuICAgKi9cbiAgbGlmdFgocDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCB4LW9ubHksIGNvbXByZXNzZWQgb3IgdW5jb21wcmVzc2VkXG4gICAqIEByZXR1cm5zIHRoZSB4IGNvb3JkaW5hdGUgb2YgcFxuICAgKi9cbiAgcG9pbnRYKHA6IFVpbnQ4QXJyYXkpOiBVaW50OEFycmF5O1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gcCBhIHBvaW50LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHAgaGFzIGFuIGV2ZW4geSBjb29yZGluYXRlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIGhhc0V2ZW5ZKHA6IFVpbnQ4QXJyYXkpOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBHZXRzIGEgcHVibGljIGtleSBmb3Igc2VjcmV0IGtleS5cbiAgICpcbiAgICogQHBhcmFtIHMgU2VjcmV0IGtleVxuICAgKiBAcGFyYW0gY29tcHJlc3NlZCBXaGV0aGVyIHRoZSByZXN1bHRpbmcgcG9pbnQgc2hvdWxkIGJlIGNvbXByZXNzZWQuXG4gICAqIEByZXR1cm5zIFRoZSBwdWJsaWMga2V5LCBjb21wcmVzc2VkIG9yIHVuY29tcHJlc3NlZFxuICAgKi9cbiAgZ2V0UHVibGljS2V5KHM6IFVpbnQ4QXJyYXksIGNvbXByZXNzZWQ6IGJvb2xlYW4pOiBVaW50OEFycmF5IHwgbnVsbDtcblxuICAvKipcbiAgICogUGVyZm9ybXMgYSBCSVAzNDAtc3R5bGUgdGFnZ2VkIGhhc2guXG4gICAqXG4gICAqIEBwYXJhbSB0YWdcbiAgICogQHBhcmFtIG1lc3NhZ2VzIEFycmF5IG9mIGRhdGEgdG8gaGFzaC5cbiAgICogQHJldHVybiBUaGUgMzItYnl0ZSBCSVAzNDAtc3R5bGUgdGFnZ2VkIGhhc2guXG4gICAqL1xuICB0YWdnZWRIYXNoKHRhZzogc3RyaW5nLCAuLi5tZXNzYWdlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcblxuICAvKipcbiAgICogU0hBMjU2IGhhc2guXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlcyBBcnJheSBvZiBkYXRhIHRvIGhhc2guXG4gICAqIEByZXR1cm4gVGhlIDMyLWJ5dGUgU0hBMjU2IGRpZ2VzdC5cbiAgICovXG4gIHNoYTI1NiguLi5tZXNzYWdlczogVWludDhBcnJheVtdKTogVWludDhBcnJheTtcbn1cblxuZXhwb3J0IHR5cGUgVHdlYWsgPSBUeXBlZFR3ZWFrIHwgVWludDhBcnJheTtcbmV4cG9ydCBpbnRlcmZhY2UgVHlwZWRUd2VhayB7XG4gIHR3ZWFrOiBVaW50OEFycmF5O1xuICB4T25seT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS2V5R2VuQ29udGV4dCB7XG4gIGFnZ1B1YmxpY0tleTogVWludDhBcnJheTsgLy8gYSBwb2ludCBvbiB0aGUgY3VydmVcbiAgZ2FjYzogVWludDhBcnJheTsgLy8gYWNjdW11bGF0ZWQgbmVnYXRpb24gZmFjdG9yIGZyb20gWC1vbmx5IHR3ZWFraW5nXG4gIHRhY2M6IFVpbnQ4QXJyYXk7IC8vIDMyLWJ5dGUgYWNjdW11bGF0ZWQgdHdlYWsgKG1vZCBuKVxufVxuXG5pbnRlcmZhY2UgU2Vzc2lvblZhbHVlcyBleHRlbmRzIEtleUdlbkNvbnRleHQge1xuICBjb2VmZmljaWVudDogVWludDhBcnJheTsgLy8gMzItYnl0ZSBub25jZSBjb2VmZmljaWVudCAobW9kIG4pXG4gIGZpbmFsTm9uY2U6IFVpbnQ4QXJyYXk7IC8vIGEgcG9pbnQgb24gdGhlIGN1cnZlXG4gIGNoYWxsZW5nZTogVWludDhBcnJheTsgLy8gMzItYnl0ZSBjaGFsbGVuZ2UgKG1vZCBuKVxuICBwdWJsaWNLZXlzOiBVaW50OEFycmF5W107IC8vIGluZGl2aWR1YWwgcHVibGljIGtleXMgaW4gY29tcHJlc3NlZCBERVIgZm9ybWF0XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbktleSB7XG4gIHB1YmxpY0tleTogVWludDhBcnJheTtcbiAgYWdnTm9uY2U6IFVpbnQ4QXJyYXk7XG4gIG1zZzogVWludDhBcnJheTtcbn1cblxuY29uc3QgVEFHUyA9IHtcbiAgY2hhbGxlbmdlOiAnQklQMDM0MC9jaGFsbGVuZ2UnLFxuICBrZXlhZ2dfbGlzdDogJ0tleUFnZyBsaXN0JyxcbiAga2V5YWdnX2NvZWY6ICdLZXlBZ2cgY29lZmZpY2llbnQnLFxuICBtdXNpZ19hdXg6ICdNdVNpZy9hdXgnLFxuICBtdXNpZ19ub25jZTogJ011U2lnL25vbmNlJyxcbiAgbXVzaWdfZGV0ZXJtaW5pc3RpY19ub25jZTogJ011U2lnL2RldGVybWluaXN0aWMvbm9uY2UnLFxuICBtdXNpZ19ub25jZWNvZWY6ICdNdVNpZy9ub25jZWNvZWYnLFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21wYXJlcyB0d28gMzItYnl0ZSBVaW50OEFycmF5cyBpbiBieXRlIG9yZGVyLlxuICogQHJldHVybnMgPCAwLCAwLCA+IDAgaWYgYSBpcyA8IGIsID09PSBiIG9yID4gYiByZXNwZWN0aXZlbHlcbiAqL1xuZnVuY3Rpb24gY29tcGFyZTMyYihhOiBVaW50OEFycmF5LCBiOiBVaW50OEFycmF5KTogbnVtYmVyIHtcbiAgaWYgKGEubGVuZ3RoICE9PSAzMiB8fCBiLmxlbmd0aCAhPT0gMzIpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcnJheScpO1xuICBjb25zdCBhRCA9IG5ldyBEYXRhVmlldyhhLmJ1ZmZlciwgYS5ieXRlT2Zmc2V0LCBhLmxlbmd0aCk7XG4gIGNvbnN0IGJEID0gbmV3IERhdGFWaWV3KGIuYnVmZmVyLCBiLmJ5dGVPZmZzZXQsIGIubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICBjb25zdCBjbXAgPSBhRC5nZXRVaW50MzIoaSAqIDQpIC0gYkQuZ2V0VWludDMyKGkgKiA0KTtcbiAgICBpZiAoY21wICE9PSAwKSByZXR1cm4gY21wO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vKipcbiAqIENvbXBhcmVzIHR3byAzMy1ieXRlIFVpbnQ4QXJyYXlzIGluIGJ5dGUgb3JkZXIuXG4gKiBAcmV0dXJucyA8IDAsIDAsID4gMCBpZiBhIGlzIDwgYiwgPT09IGIgb3IgPiBiIHJlc3BlY3RpdmVseVxuICovXG5mdW5jdGlvbiBjb21wYXJlMzNiKGE6IFVpbnQ4QXJyYXksIGI6IFVpbnQ4QXJyYXkpOiBudW1iZXIge1xuICBpZiAoYS5sZW5ndGggIT09IDMzIHx8IGIubGVuZ3RoICE9PSAzMykgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFycmF5Jyk7XG4gIGNvbnN0IGNtcCA9IGFbMF0gLSBiWzBdO1xuICBpZiAoY21wICE9PSAwKSByZXR1cm4gY21wO1xuICByZXR1cm4gY29tcGFyZTMyYihhLnN1YmFycmF5KDEpLCBiLnN1YmFycmF5KDEpKTtcbn1cblxuZGVjbGFyZSBjb25zdCBzZWxmOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkO1xuY29uc3QgbWFrZVNlc3Npb25JZCA9XG4gIHR5cGVvZiBzZWxmID09PSAnb2JqZWN0JyAmJiAoc2VsZi5jcnlwdG8gfHwgc2VsZi5tc0NyeXB0bylcbiAgICA/ICgpID0+IChzZWxmLmNyeXB0byB8fCBzZWxmLm1zQ3J5cHRvKS5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoMzIpKSAvLyBCcm93c2Vyc1xuICAgIDogKCkgPT4gcmVxdWlyZSgnY3J5cHRvJykucmFuZG9tQnl0ZXMoMzIpOyAvLyBOb2RlXG5cbi8vIENhY2hlcyB2YWx1ZXMgbmVlZGVkIHRvIGNvbXB1dGUga2V5IGFnZyBjb2VmZmljaWVudHMgZm9yIGFuIGFycmF5IG9mIHB1YmxpYyBrZXlzXG5pbnRlcmZhY2UgS2V5QWdnQ2FjaGUge1xuICBwdWJsaWNLZXlIYXNoOiBVaW50OEFycmF5O1xuICBzZWNvbmRQdWJsaWNLZXk/OiBVaW50OEFycmF5O1xufVxuY29uc3QgX2tleUFnZ0NhY2hlID0gbmV3IFdlYWtNYXA8VWludDhBcnJheVtdLCBLZXlBZ2dDYWNoZT4oKTtcblxuLy8gQ2FjaGVzIGNvZWZmaWNpZW50cyBhc3NvY2lhdGVkIHdpdGggYW4gYXJyYXkgb2YgcHVibGljIGtleXNcbmNvbnN0IF9jb2VmQ2FjaGUgPSBuZXcgV2Vha01hcDxVaW50OEFycmF5W10sIE1hcDxVaW50OEFycmF5LCBVaW50OEFycmF5Pj4oKTtcblxuLy8gQ2FjaGVzIHNlY3JldCBub25jZXMuIFdlIGRvIHRoaXMgaW50ZXJuYWxseSB0byBoZWxwIHVzZXJzIGVuc3VyZSB0aGF0IHRoZXlcbi8vIGRvIG5vdCByZXVzZSBhIHNlY3JldCBub25jZS5cbmNvbnN0IF9ub25jZUNhY2hlID0gbmV3IFdlYWtNYXA8VWludDhBcnJheSwgVWludDhBcnJheT4oKTtcblxuLy8gQ2FjaGVzIHNpZ25pbmcgc2Vzc2lvbnMuIFdlIGRvIHRoaXMgaW50ZXJuYWxseSB0byBoZWxwIHVzZXJzIGVuc3VyZSB0aGF0XG4vLyB0aGVzZSBzZXNzaW9uIHZhbHVlcyB3ZXJlIGdlbmVyYXRlZCBvbiB0aGUgc2lnbmVyLCBhbmQgYXJlIG5vdCBhY2NlcHRlZCBmcm9tXG4vLyBhbiB1bnRydXN0ZWQgdGhpcmQgcGFydHkuXG5jb25zdCBfc2Vzc2lvbkNhY2hlID0gbmV3IFdlYWtNYXA8U2Vzc2lvbktleSwgU2Vzc2lvblZhbHVlcz4oKTtcblxuZXhwb3J0IGZ1bmN0aW9uIE11U2lnRmFjdG9yeShlY2M6IENyeXB0byk6IE11U2lnIHtcbiAgY29uc3QgQ1BPSU5UX0lORiA9IG5ldyBVaW50OEFycmF5KDMzKTtcbiAgY29uc3QgU0NBTEFSXzAgPSBuZXcgVWludDhBcnJheSgzMik7XG4gIGNvbnN0IFNDQUxBUl8xID0gbmV3IFVpbnQ4QXJyYXkoMzIpO1xuICBTQ0FMQVJfMVszMV0gPSAxO1xuICBjb25zdCBTQ0FMQVJfTUlOVVNfMSA9IGVjYy5zY2FsYXJOZWdhdGUoU0NBTEFSXzEpO1xuXG4gIGZ1bmN0aW9uIGtleUFnZ0NvZWZmKHB1YmxpY0tleXM6IFVpbnQ4QXJyYXlbXSwgcHVibGljS2V5OiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gICAgbGV0IGNvZWZDYWNoZSA9IF9jb2VmQ2FjaGUuZ2V0KHB1YmxpY0tleXMpO1xuICAgIGlmIChjb2VmQ2FjaGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29lZkNhY2hlID0gbmV3IE1hcDxVaW50OEFycmF5LCBVaW50OEFycmF5PigpO1xuICAgICAgX2NvZWZDYWNoZS5zZXQocHVibGljS2V5cywgY29lZkNhY2hlKTtcbiAgICB9XG4gICAgbGV0IGNvZWZmaWNpZW50ID0gY29lZkNhY2hlLmdldChwdWJsaWNLZXkpO1xuICAgIGlmIChjb2VmZmljaWVudCkgcmV0dXJuIGNvZWZmaWNpZW50O1xuXG4gICAgY29lZmZpY2llbnQgPSBTQ0FMQVJfMTtcbiAgICBsZXQgc2Vjb25kUHVibGljS2V5O1xuICAgIGxldCBwdWJsaWNLZXlIYXNoO1xuICAgIGxldCBrZXlBZ2dDYWNoZSA9IF9rZXlBZ2dDYWNoZS5nZXQocHVibGljS2V5cyk7XG4gICAgaWYgKGtleUFnZ0NhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEluZGV4IG9mIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIHRoZSBzZWNvbmQgdW5pcXVlIHB1YmxpYyBrZXkuXG4gICAgICBjb25zdCBwa0lkeDIgPSBwdWJsaWNLZXlzLmZpbmRJbmRleCgocGspID0+IGNvbXBhcmUzM2IocGssIHB1YmxpY0tleXNbMF0pICE9PSAwKTtcbiAgICAgIHNlY29uZFB1YmxpY0tleSA9IHB1YmxpY0tleXNbcGtJZHgyXTsgLy8gdW5kZWZpbmVkIGlmIHBrSWR4MiA9PT0gLTFcbiAgICAgIHB1YmxpY0tleUhhc2ggPSBlY2MudGFnZ2VkSGFzaChUQUdTLmtleWFnZ19saXN0LCAuLi5wdWJsaWNLZXlzKTtcbiAgICAgIGtleUFnZ0NhY2hlID0geyBwdWJsaWNLZXlIYXNoLCBzZWNvbmRQdWJsaWNLZXkgfTtcbiAgICAgIF9rZXlBZ2dDYWNoZS5zZXQocHVibGljS2V5cywga2V5QWdnQ2FjaGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAoeyBwdWJsaWNLZXlIYXNoLCBzZWNvbmRQdWJsaWNLZXkgfSA9IGtleUFnZ0NhY2hlKTtcbiAgICB9XG4gICAgaWYgKHNlY29uZFB1YmxpY0tleSA9PT0gdW5kZWZpbmVkIHx8IGNvbXBhcmUzM2IocHVibGljS2V5LCBzZWNvbmRQdWJsaWNLZXkpICE9PSAwKSB7XG4gICAgICBjb2VmZmljaWVudCA9IGVjYy50YWdnZWRIYXNoKFRBR1Mua2V5YWdnX2NvZWYsIHB1YmxpY0tleUhhc2gsIHB1YmxpY0tleSk7XG4gICAgfVxuICAgIGNvZWZDYWNoZS5zZXQocHVibGljS2V5LCBjb2VmZmljaWVudCk7XG4gICAgcmV0dXJuIGNvZWZmaWNpZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkVHdlYWsoY3R4OiBLZXlHZW5Db250ZXh0LCB0OiBUd2Vhayk6IEtleUdlbkNvbnRleHQge1xuICAgIGNvbnN0IHR3ZWFrID0gJ3R3ZWFrJyBpbiB0ID8gdCA6IHsgdHdlYWs6IHQgfTtcbiAgICBpZiAoIWVjYy5pc1NjYWxhcih0d2Vhay50d2VhaykpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIHR3ZWFrIHRvIGJlIGEgdmFsaWQgc2NhbGFyIHdpdGggY3VydmUgb3JkZXInKTtcbiAgICBsZXQgeyBnYWNjLCB0YWNjIH0gPSBjdHg7XG4gICAgbGV0IGFnZ1B1YmxpY0tleTogVWludDhBcnJheSB8IG51bGwgPSBjdHguYWdnUHVibGljS2V5O1xuXG4gICAgaWYgKCFlY2MuaGFzRXZlblkoYWdnUHVibGljS2V5KSAmJiB0d2Vhay54T25seSkge1xuICAgICAgLy8gZyA9IC0xXG4gICAgICBnYWNjID0gZWNjLnNjYWxhck5lZ2F0ZShnYWNjKTsgLy8gZyAqIGdhY2MgbW9kIG5cbiAgICAgIHRhY2MgPSBlY2Muc2NhbGFyTmVnYXRlKHRhY2MpOyAvLyBnICogdGFjYyBtb2QgblxuICAgICAgYWdnUHVibGljS2V5ID0gZWNjLnBvaW50TmVnYXRlKGFnZ1B1YmxpY0tleSk7IC8vIGcgKiBRXG4gICAgfVxuICAgIGFnZ1B1YmxpY0tleSA9IGVjYy5wb2ludEFkZFR3ZWFrKGFnZ1B1YmxpY0tleSwgdHdlYWsudHdlYWssIGZhbHNlKTsgLy8gZyAqIFEgKyB0ICogR1xuICAgIGlmIChhZ2dQdWJsaWNLZXkgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBwb2ludCBhdCBpbmZpbml0eSBkdXJpbmcgdHdlYWtpbmcnKTtcbiAgICB0YWNjID0gZWNjLnNjYWxhckFkZCh0d2Vhay50d2VhaywgdGFjYyk7IC8vIHQgKyBnICogdGFjYyBtb2QgblxuXG4gICAgcmV0dXJuIHsgYWdnUHVibGljS2V5LCBnYWNjLCB0YWNjIH07XG4gIH1cblxuICBmdW5jdGlvbiBrZXlBZ2cocHVibGljS2V5czogVWludDhBcnJheVtdLCAuLi50d2Vha3M6IFR3ZWFrW10pOiBLZXlHZW5Db250ZXh0IHtcbiAgICBjaGVja0FyZ3MoeyBwdWJsaWNLZXlzIH0pO1xuICAgIGNvbnN0IG11bHRpcGxpZWRQdWJsaWNLZXlzID0gcHVibGljS2V5cy5tYXAoKHB1YmxpY0tleSkgPT4ge1xuICAgICAgY29uc3QgY29lZmZpY2llbnQgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuICAgICAgbGV0IG11bHRpcGxpZWRQdWJsaWNLZXk6IFVpbnQ4QXJyYXkgfCBudWxsO1xuICAgICAgaWYgKGNvbXBhcmUzMmIoY29lZmZpY2llbnQsIFNDQUxBUl8xKSA9PT0gMCkge1xuICAgICAgICBtdWx0aXBsaWVkUHVibGljS2V5ID0gcHVibGljS2V5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbGllZFB1YmxpY0tleSA9IGVjYy5wb2ludE11bHRpcGx5VW5zYWZlKHB1YmxpY0tleSwgY29lZmZpY2llbnQsIGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChtdWx0aXBsaWVkUHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1BvaW50IGF0IGluZmluaXR5IGR1cmluZyBhZ2dyZWdhdGlvbicpO1xuICAgICAgcmV0dXJuIG11bHRpcGxpZWRQdWJsaWNLZXk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBhZ2dQdWJsaWNLZXkgPSBtdWx0aXBsaWVkUHVibGljS2V5cy5yZWR1Y2UoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IG5leHQgPSBlY2MucG9pbnRBZGQoYSwgYiwgZmFsc2UpO1xuICAgICAgaWYgKG5leHQgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignUG9pbnQgYXQgaW5maW5pdHkgZHVyaW5nIGFnZ3JlZ2F0aW9uJyk7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0d2Vha3MucmVkdWNlKChjdHgsIHR3ZWFrKSA9PiBhZGRUd2VhayhjdHgsIHR3ZWFrKSwge1xuICAgICAgYWdnUHVibGljS2V5LFxuICAgICAgZ2FjYzogU0NBTEFSXzEsXG4gICAgICB0YWNjOiBTQ0FMQVJfMCxcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFNlc3Npb25WYWx1ZXMoc2Vzc2lvbktleTogU2Vzc2lvbktleSk6IFNlc3Npb25WYWx1ZXMge1xuICAgIGNvbnN0IHNlc3Npb25WYWx1ZXMgPSBfc2Vzc2lvbkNhY2hlLmdldChzZXNzaW9uS2V5KTtcbiAgICBpZiAoIXNlc3Npb25WYWx1ZXMpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzZXNzaW9uIGtleSwgcGxlYXNlIGNhbGwgYHN0YXJ0U2lnbmluZ1Nlc3Npb25gJyk7XG4gICAgcmV0dXJuIHNlc3Npb25WYWx1ZXM7XG4gIH1cblxuICBmdW5jdGlvbiBub25jZUFnZyhwdWJsaWNOb25jZXM6IFVpbnQ4QXJyYXlbXSk6IFVpbnQ4QXJyYXkge1xuICAgIGNoZWNrQXJncyh7IHB1YmxpY05vbmNlcyB9KTtcblxuICAgIGNvbnN0IGFnZ05vbmNlczogQXJyYXk8VWludDhBcnJheSB8IG51bGw+ID0gW3B1YmxpY05vbmNlc1swXS5zdWJhcnJheSgwLCAzMyksIHB1YmxpY05vbmNlc1swXS5zdWJhcnJheSgzMyldO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcHVibGljTm9uY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYWdnTm9uY2VzWzBdICE9PSBudWxsKSBhZ2dOb25jZXNbMF0gPSBlY2MucG9pbnRBZGQoYWdnTm9uY2VzWzBdLCBwdWJsaWNOb25jZXNbaV0uc3ViYXJyYXkoMCwgMzMpLCBmYWxzZSk7XG4gICAgICBpZiAoYWdnTm9uY2VzWzFdICE9PSBudWxsKSBhZ2dOb25jZXNbMV0gPSBlY2MucG9pbnRBZGQoYWdnTm9uY2VzWzFdLCBwdWJsaWNOb25jZXNbaV0uc3ViYXJyYXkoMzMpLCBmYWxzZSk7XG4gICAgfVxuICAgIGNvbnN0IGFnZ05vbmNlID0gbmV3IFVpbnQ4QXJyYXkoNjYpO1xuICAgIGlmIChhZ2dOb25jZXNbMF0gIT09IG51bGwpIGFnZ05vbmNlLnNldChlY2MucG9pbnRDb21wcmVzcyhhZ2dOb25jZXNbMF0pLCAwKTtcbiAgICBpZiAoYWdnTm9uY2VzWzFdICE9PSBudWxsKSBhZ2dOb25jZS5zZXQoZWNjLnBvaW50Q29tcHJlc3MoYWdnTm9uY2VzWzFdKSwgMzMpO1xuICAgIHJldHVybiBhZ2dOb25jZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXJ0U2lnbmluZ1Nlc3Npb25Jbm5lcihcbiAgICBhZ2dOb25jZTogVWludDhBcnJheSxcbiAgICBtc2c6IFVpbnQ4QXJyYXksXG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdLFxuICAgIGN0eDogS2V5R2VuQ29udGV4dFxuICApOiBTZXNzaW9uS2V5IHtcbiAgICBjb25zdCBwdWJLZXlYID0gZWNjLnBvaW50WChjdHguYWdnUHVibGljS2V5KTtcblxuICAgIGNvbnN0IGNvZWZmaWNpZW50ID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19ub25jZWNvZWYsIGFnZ05vbmNlLCBwdWJLZXlYLCBtc2cpO1xuXG4gICAgY29uc3QgYWdnTm9uY2VzID0gW2FnZ05vbmNlLnN1YmFycmF5KDAsIDMzKSwgYWdnTm9uY2Uuc3ViYXJyYXkoMzMpXTtcblxuICAgIC8vIFRoaXMgaXMga2luZGEgdWdseSwgYnV0IGNyeXB0by5wb2ludEFkZCBkb2Vzbid0IHdvcmsgb24gMC1jb2RlZCBpbmZpbml0eVxuICAgIGxldCByOiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG4gICAgaWYgKGNvbXBhcmUzM2IoYWdnTm9uY2VzWzFdLCBDUE9JTlRfSU5GKSAhPT0gMCAmJiBjb21wYXJlMzNiKGFnZ05vbmNlc1swXSwgQ1BPSU5UX0lORikgIT09IDApIHtcbiAgICAgIHIgPSBlY2MucG9pbnRNdWx0aXBseUFuZEFkZFVuc2FmZShhZ2dOb25jZXNbMV0sIGNvZWZmaWNpZW50LCBhZ2dOb25jZXNbMF0sIGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKGNvbXBhcmUzM2IoYWdnTm9uY2VzWzBdLCBDUE9JTlRfSU5GKSAhPT0gMCkge1xuICAgICAgciA9IGVjYy5wb2ludENvbXByZXNzKGFnZ05vbmNlc1swXSwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoY29tcGFyZTMzYihhZ2dOb25jZXNbMV0sIENQT0lOVF9JTkYpICE9PSAwKSB7XG4gICAgICByID0gZWNjLnBvaW50TXVsdGlwbHlVbnNhZmUoYWdnTm9uY2VzWzFdLCBjb2VmZmljaWVudCwgZmFsc2UpO1xuICAgIH1cbiAgICBpZiAociA9PT0gbnVsbCkgciA9IGVjYy5nZXRQdWJsaWNLZXkoU0NBTEFSXzEsIGZhbHNlKTtcbiAgICBpZiAociA9PT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gZ2V0IEcnKTtcblxuICAgIGNvbnN0IGNoYWxsZW5nZSA9IGVjYy5zY2FsYXJNb2QoZWNjLnRhZ2dlZEhhc2goVEFHUy5jaGFsbGVuZ2UsIGVjYy5wb2ludFgociksIHB1YktleVgsIG1zZykpO1xuXG4gICAgY29uc3Qga2V5ID0geyBwdWJsaWNLZXk6IGN0eC5hZ2dQdWJsaWNLZXksIGFnZ05vbmNlLCBtc2cgfTtcbiAgICBfc2Vzc2lvbkNhY2hlLnNldChrZXksIHsgLi4uY3R4LCBjb2VmZmljaWVudCwgY2hhbGxlbmdlLCBmaW5hbE5vbmNlOiByLCBwdWJsaWNLZXlzIH0pO1xuICAgIHJldHVybiBrZXk7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJ0aWFsVmVyaWZ5SW5uZXIoe1xuICAgIHNpZyxcbiAgICBwdWJsaWNLZXksXG4gICAgcHVibGljTm9uY2VzLFxuICAgIHNlc3Npb25LZXksXG4gIH06IHtcbiAgICBzaWc6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5OiBVaW50OEFycmF5O1xuICAgIHB1YmxpY05vbmNlczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXldO1xuICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IG1zZyB9ID0gc2Vzc2lvbktleTtcbiAgICBjb25zdCB7IGFnZ1B1YmxpY0tleSwgZ2FjYywgY2hhbGxlbmdlLCBjb2VmZmljaWVudCwgZmluYWxOb25jZSwgcHVibGljS2V5cyB9ID0gZ2V0U2Vzc2lvblZhbHVlcyhzZXNzaW9uS2V5KTtcblxuICAgIGNvbnN0IHJlUHJpbWUgPSBlY2MucG9pbnRNdWx0aXBseUFuZEFkZFVuc2FmZShwdWJsaWNOb25jZXNbMV0sIGNvZWZmaWNpZW50LCBwdWJsaWNOb25jZXNbMF0sIGZhbHNlKTtcbiAgICBpZiAocmVQcmltZSA9PT0gbnVsbCkgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIHB1YmxpYyBub25jZSBhdCBpbmZpbml0eScpO1xuICAgIGNvbnN0IHJlID0gZWNjLmhhc0V2ZW5ZKGZpbmFsTm9uY2UpID8gcmVQcmltZSA6IGVjYy5wb2ludE5lZ2F0ZShyZVByaW1lKTtcblxuICAgIGNvbnN0IGEgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgZyA9IGVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpID8gZ2FjYyA6IGVjYy5zY2FsYXJOZWdhdGUoZ2FjYyk7XG5cbiAgICBjb25zdCBlYSA9IGVjYy5zY2FsYXJNdWx0aXBseShjaGFsbGVuZ2UsIGEpO1xuICAgIGNvbnN0IGVhZyA9IGVjYy5zY2FsYXJNdWx0aXBseShlYSwgZyk7XG4gICAgY29uc3QgdmVyID0gZWNjLnBvaW50TXVsdGlwbHlBbmRBZGRVbnNhZmUocHVibGljS2V5LCBlYWcsIHJlLCB0cnVlKTtcbiAgICBpZiAodmVyID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgdmVyaWZpY2F0aW9uIHBvaW50IGF0IGluZmluaXR5Jyk7XG5cbiAgICBjb25zdCBzRyA9IGVjYy5nZXRQdWJsaWNLZXkoc2lnLCB0cnVlKTtcbiAgICBpZiAoc0cgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBzaWduYXR1cmUgcG9pbnQgYXQgaW5maW5pdHknKTtcblxuICAgIHJldHVybiBjb21wYXJlMzNiKHZlciwgc0cpID09PSAwO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFydGlhbFNpZ25Jbm5lcih7XG4gICAgc2VjcmV0S2V5LFxuICAgIHB1YmxpY0tleSxcbiAgICBzZWNyZXROb25jZXMsXG4gICAgc2Vzc2lvbktleSxcbiAgfToge1xuICAgIHNlY3JldEtleTogVWludDhBcnJheTtcbiAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgc2VjcmV0Tm9uY2VzOiBbVWludDhBcnJheSwgVWludDhBcnJheV07XG4gICAgc2Vzc2lvbktleTogU2Vzc2lvbktleTtcbiAgfSk6IFVpbnQ4QXJyYXkge1xuICAgIGNvbnN0IHsgbXNnIH0gPSBzZXNzaW9uS2V5O1xuICAgIGNvbnN0IHsgYWdnUHVibGljS2V5LCBnYWNjLCBjaGFsbGVuZ2UsIGNvZWZmaWNpZW50LCBmaW5hbE5vbmNlLCBwdWJsaWNLZXlzIH0gPSBnZXRTZXNzaW9uVmFsdWVzKHNlc3Npb25LZXkpO1xuXG4gICAgY29uc3QgW2sxLCBrMl0gPSBzZWNyZXROb25jZXMubWFwKChrKSA9PiAoZWNjLmhhc0V2ZW5ZKGZpbmFsTm9uY2UpID8gayA6IGVjYy5zY2FsYXJOZWdhdGUoaykpKTtcblxuICAgIGNvbnN0IGEgPSBrZXlBZ2dDb2VmZihwdWJsaWNLZXlzLCBwdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgZyA9IGVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpID8gZ2FjYyA6IGVjYy5zY2FsYXJOZWdhdGUoZ2FjYyk7XG4gICAgY29uc3QgZCA9IGVjYy5zY2FsYXJNdWx0aXBseShnLCBzZWNyZXRLZXkpO1xuXG4gICAgY29uc3QgYmsyID0gZWNjLnNjYWxhck11bHRpcGx5KGNvZWZmaWNpZW50LCBrMik7XG4gICAgY29uc3QgazFiazIgPSBlY2Muc2NhbGFyQWRkKGsxLCBiazIpO1xuXG4gICAgY29uc3QgZWEgPSBlY2Muc2NhbGFyTXVsdGlwbHkoY2hhbGxlbmdlLCBhKTtcbiAgICBjb25zdCBlYWQgPSBlY2Muc2NhbGFyTXVsdGlwbHkoZWEsIGQpO1xuXG4gICAgY29uc3Qgc2lnID0gZWNjLnNjYWxhckFkZChrMWJrMiwgZWFkKTtcblxuICAgIHJldHVybiBzaWc7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJ0aWFsU2lnbih7XG4gICAgc2VjcmV0S2V5LFxuICAgIHB1YmxpY05vbmNlLFxuICAgIHNlc3Npb25LZXksXG4gICAgdmVyaWZ5ID0gdHJ1ZSxcbiAgfToge1xuICAgIHNlY3JldEtleTogVWludDhBcnJheTtcbiAgICBwdWJsaWNOb25jZTogVWludDhBcnJheTtcbiAgICBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5O1xuICAgIHZlcmlmeTogYm9vbGVhbjtcbiAgfSk6IFVpbnQ4QXJyYXkge1xuICAgIGNoZWNrQXJncyh7IHB1YmxpY05vbmNlLCBzZWNyZXRLZXkgfSk7XG5cbiAgICBjb25zdCBzZWNyZXROb25jZSA9IF9ub25jZUNhY2hlLmdldChwdWJsaWNOb25jZSk7XG4gICAgaWYgKHNlY3JldE5vbmNlID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcignTm8gc2VjcmV0IG5vbmNlIGZvdW5kIGZvciBzcGVjaWZpZWQgcHVibGljIG5vbmNlJyk7XG4gICAgX25vbmNlQ2FjaGUuZGVsZXRlKHB1YmxpY05vbmNlKTtcblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGVjYy5nZXRQdWJsaWNLZXkoc2VjcmV0S2V5LCB0cnVlKTtcbiAgICBpZiAocHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2VjcmV0IGtleSwgbm8gY29ycmVzcG9uZGluZyBwdWJsaWMga2V5Jyk7XG4gICAgaWYgKGNvbXBhcmUzM2IocHVibGljS2V5LCBzZWNyZXROb25jZS5zdWJhcnJheSg2NCkpICE9PSAwKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBub25jZSBwdWJrZXkgbWlzbWF0Y2gnKTtcbiAgICBjb25zdCBzZWNyZXROb25jZXM6IFtVaW50OEFycmF5LCBVaW50OEFycmF5XSA9IFtzZWNyZXROb25jZS5zdWJhcnJheSgwLCAzMiksIHNlY3JldE5vbmNlLnN1YmFycmF5KDMyLCA2NCldO1xuICAgIGNvbnN0IHNpZyA9IHBhcnRpYWxTaWduSW5uZXIoe1xuICAgICAgc2VjcmV0S2V5LFxuICAgICAgcHVibGljS2V5LFxuICAgICAgc2VjcmV0Tm9uY2VzLFxuICAgICAgc2Vzc2lvbktleSxcbiAgICB9KTtcblxuICAgIGlmICh2ZXJpZnkpIHtcbiAgICAgIGNvbnN0IHB1YmxpY05vbmNlczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXldID0gW3B1YmxpY05vbmNlLnN1YmFycmF5KDAsIDMzKSwgcHVibGljTm9uY2Uuc3ViYXJyYXkoMzMpXTtcbiAgICAgIGNvbnN0IHZhbGlkID0gcGFydGlhbFZlcmlmeUlubmVyKHtcbiAgICAgICAgc2lnLFxuICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIHB1YmxpY05vbmNlcyxcbiAgICAgICAgc2Vzc2lvbktleSxcbiAgICAgIH0pO1xuICAgICAgaWYgKCF2YWxpZCkgdGhyb3cgbmV3IEVycm9yKCdQYXJ0aWFsIHNpZ25hdHVyZSBmYWlsZWQgdmVyaWZpY2F0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiBzaWc7XG4gIH1cblxuICBpbnRlcmZhY2UgRGV0ZXJtaW5pc3RpY1NpZ25BcmdzQmFzZSB7XG4gICAgc2VjcmV0S2V5OiBVaW50OEFycmF5O1xuICAgIGFnZ090aGVyTm9uY2U6IFVpbnQ4QXJyYXk7XG4gICAgcHVibGljS2V5czogVWludDhBcnJheVtdO1xuICAgIHR3ZWFrcz86IFR3ZWFrW107XG4gICAgbXNnOiBVaW50OEFycmF5O1xuICAgIHJhbmQ/OiBVaW50OEFycmF5O1xuICB9XG4gIGludGVyZmFjZSBEZXRlcm1pbmlzdGljU2lnbkFyZ3MgZXh0ZW5kcyBEZXRlcm1pbmlzdGljU2lnbkFyZ3NCYXNlIHtcbiAgICB2ZXJpZnk/OiBib29sZWFuO1xuICAgIG5vbmNlT25seT86IGJvb2xlYW47XG4gIH1cbiAgaW50ZXJmYWNlIERldGVybWluaXN0aWNTaWduQXJnc1NpZ24gZXh0ZW5kcyBEZXRlcm1pbmlzdGljU2lnbkFyZ3NCYXNlIHtcbiAgICB2ZXJpZnk6IGJvb2xlYW47XG4gIH1cbiAgaW50ZXJmYWNlIERldGVybWluaXN0aWNTaWduQXJnc05vbmNlT25seSBleHRlbmRzIERldGVybWluaXN0aWNTaWduQXJnc0Jhc2Uge1xuICAgIG5vbmNlT25seTogdHJ1ZTtcbiAgfVxuICBmdW5jdGlvbiBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiBEZXRlcm1pbmlzdGljU2lnbkFyZ3NTaWduKToge1xuICAgIHNpZzogVWludDhBcnJheTtcbiAgICBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5O1xuICAgIHB1YmxpY05vbmNlOiBVaW50OEFycmF5O1xuICB9O1xuICBmdW5jdGlvbiBkZXRlcm1pbmlzdGljU2lnbihhcmdzOiBEZXRlcm1pbmlzdGljU2lnbkFyZ3NOb25jZU9ubHkpOiB7IHB1YmxpY05vbmNlOiBVaW50OEFycmF5IH07XG4gIGZ1bmN0aW9uIGRldGVybWluaXN0aWNTaWduKHtcbiAgICBzZWNyZXRLZXksXG4gICAgYWdnT3RoZXJOb25jZSxcbiAgICBwdWJsaWNLZXlzLFxuICAgIHR3ZWFrcyA9IFtdLFxuICAgIG1zZyxcbiAgICByYW5kLFxuICAgIHZlcmlmeSA9IHRydWUsXG4gICAgbm9uY2VPbmx5ID0gZmFsc2UsXG4gIH06IERldGVybWluaXN0aWNTaWduQXJncyk6IHtcbiAgICBzaWc/OiBVaW50OEFycmF5O1xuICAgIHNlc3Npb25LZXk/OiBTZXNzaW9uS2V5O1xuICAgIHB1YmxpY05vbmNlOiBVaW50OEFycmF5O1xuICB9IHtcbiAgICAvLyBObyBuZWVkIHRvIGNoZWNrIG1zZywgaXRzIG1heCBzaXplIGlzIGxhcmdlciB0aGFuIEpTIHR5cGVkIGFycmF5IGxpbWl0XG4gICAgY2hlY2tBcmdzKHsgcmFuZCwgc2VjcmV0S2V5LCBhZ2dPdGhlck5vbmNlIH0pO1xuICAgIGNvbnN0IHB1YmxpY0tleSA9IGVjYy5nZXRQdWJsaWNLZXkoc2VjcmV0S2V5LCB0cnVlKTtcbiAgICBpZiAocHVibGljS2V5ID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBrZXkgaGFzIG5vIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleScpO1xuXG4gICAgbGV0IHNlY3JldEtleVByaW1lO1xuICAgIGlmIChyYW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHNlY3JldEtleVByaW1lID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19hdXgsIHJhbmQpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAzMjsgaSsrKSB7XG4gICAgICAgIHNlY3JldEtleVByaW1lW2ldID0gc2VjcmV0S2V5UHJpbWVbaV0gXiBzZWNyZXRLZXlbaV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlY3JldEtleVByaW1lID0gc2VjcmV0S2V5O1xuICAgIH1cbiAgICBjb25zdCBjdHggPSBrZXlBZ2cocHVibGljS2V5cywgLi4udHdlYWtzKTtcbiAgICBjb25zdCBhZ2dQdWJsaWNLZXkgPSBlY2MucG9pbnRYKGN0eC5hZ2dQdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgbUxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDgpO1xuICAgIG5ldyBEYXRhVmlldyhtTGVuZ3RoLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsIEJpZ0ludChtc2cubGVuZ3RoKSk7XG5cbiAgICBjb25zdCBzZWNyZXROb25jZSA9IG5ldyBVaW50OEFycmF5KDk3KTtcbiAgICBjb25zdCBwdWJsaWNOb25jZSA9IG5ldyBVaW50OEFycmF5KDY2KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDI7IGkrKykge1xuICAgICAgY29uc3Qga0ggPSBlY2MudGFnZ2VkSGFzaChcbiAgICAgICAgVEFHUy5tdXNpZ19kZXRlcm1pbmlzdGljX25vbmNlLFxuICAgICAgICAuLi5bc2VjcmV0S2V5UHJpbWUsIGFnZ090aGVyTm9uY2UsIGFnZ1B1YmxpY0tleSwgbUxlbmd0aCwgbXNnLCBVaW50OEFycmF5Lm9mKGkpXVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGsgPSBlY2Muc2NhbGFyTW9kKGtIKTtcbiAgICAgIGlmIChjb21wYXJlMzJiKFNDQUxBUl8wLCBrKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCcwIHNlY3JldCBub25jZScpO1xuICAgICAgY29uc3QgcHViID0gZWNjLmdldFB1YmxpY0tleShrLCB0cnVlKTtcbiAgICAgIGlmIChwdWIgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcignU2VjcmV0IG5vbmNlIGhhcyBubyBjb3JyZXNwb25kaW5nIHB1YmxpYyBub25jZScpO1xuXG4gICAgICBzZWNyZXROb25jZS5zZXQoaywgaSAqIDMyKTtcbiAgICAgIHB1YmxpY05vbmNlLnNldChwdWIsIGkgKiAzMyk7XG4gICAgfVxuICAgIHNlY3JldE5vbmNlLnNldChwdWJsaWNLZXksIDY0KTtcblxuICAgIGlmIChub25jZU9ubHkpIHJldHVybiB7IHB1YmxpY05vbmNlIH07XG5cbiAgICBfbm9uY2VDYWNoZS5zZXQocHVibGljTm9uY2UsIHNlY3JldE5vbmNlKTtcbiAgICBjb25zdCBhZ2dOb25jZSA9IG5vbmNlQWdnKFthZ2dPdGhlck5vbmNlLCBwdWJsaWNOb25jZV0pO1xuICAgIGNvbnN0IHNlc3Npb25LZXkgPSBzdGFydFNpZ25pbmdTZXNzaW9uSW5uZXIoYWdnTm9uY2UsIG1zZywgcHVibGljS2V5cywgY3R4KTtcbiAgICBjb25zdCBzaWcgPSBwYXJ0aWFsU2lnbih7XG4gICAgICBzZWNyZXRLZXksXG4gICAgICBwdWJsaWNOb25jZSxcbiAgICAgIHNlc3Npb25LZXksXG4gICAgICB2ZXJpZnksXG4gICAgfSk7XG5cbiAgICByZXR1cm4geyBzaWcsIHNlc3Npb25LZXksIHB1YmxpY05vbmNlIH07XG4gIH1cblxuICAvLyBUT0RPOiBJbXByb3ZlIGFyZyBjaGVja2luZyBub3cgdGhhdCB3ZSBoYXZlIHN0YXJ0U2lnbmluZ1Nlc3Npb25cbiAgY29uc3QgcHViS2V5QXJncyA9IFsncHVibGljS2V5JywgJ3B1YmxpY0tleXMnXSBhcyBjb25zdDtcbiAgY29uc3Qgc2NhbGFyQXJncyA9IFsndHdlYWsnLCAnc2lnJywgJ3NpZ3MnLCAndGFjYycsICdnYWNjJ10gYXMgY29uc3Q7XG4gIGNvbnN0IG90aGVyQXJnczMyYiA9IFsneE9ubHlQdWJsaWNLZXknLCAncmFuZCcsICdzZXNzaW9uSWQnXSBhcyBjb25zdDtcbiAgY29uc3QgYXJnczMyYiA9IFsnc2VjcmV0S2V5JywgLi4uc2NhbGFyQXJncywgLi4ub3RoZXJBcmdzMzJiXSBhcyBjb25zdDtcbiAgY29uc3QgcHViTm9uY2VBcmdzID0gWydwdWJsaWNOb25jZScsICdwdWJsaWNOb25jZXMnLCAnYWdnTm9uY2UnLCAnYWdnT3RoZXJOb25jZScsICdmaW5hbE5vbmNlJ10gYXMgY29uc3Q7XG4gIGNvbnN0IG90aGVyQXJncyA9IFsnYWdnUHVibGljS2V5JywgJ3NlY3JldE5vbmNlJ10gYXMgY29uc3Q7XG4gIHR5cGUgQXJnTmFtZSA9XG4gICAgfCB0eXBlb2YgcHViS2V5QXJnc1tudW1iZXJdXG4gICAgfCB0eXBlb2YgYXJnczMyYltudW1iZXJdXG4gICAgfCB0eXBlb2YgcHViTm9uY2VBcmdzW251bWJlcl1cbiAgICB8IHR5cGVvZiBvdGhlckFyZ3NbbnVtYmVyXTtcbiAgdHlwZSBBcmdzID0geyBbQSBpbiBBcmdOYW1lXT86IFVpbnQ4QXJyYXkgfCBVaW50OEFycmF5W10gfTtcblxuICBjb25zdCBhcmdMZW5ndGhzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgYXJnczMyYi5mb3JFYWNoKChhKSA9PiBhcmdMZW5ndGhzLnNldChhLCAzMikpO1xuICBwdWJLZXlBcmdzLmZvckVhY2goKGEpID0+IGFyZ0xlbmd0aHMuc2V0KGEsIDMzKSk7XG4gIHB1Yk5vbmNlQXJncy5mb3JFYWNoKChhKSA9PiBhcmdMZW5ndGhzLnNldChhLCA2NikpO1xuICBhcmdMZW5ndGhzLnNldCgnc2VjcmV0Tm9uY2UnLCA5Nyk7XG4gIGFyZ0xlbmd0aHMuc2V0KCdhZ2dQdWJsaWNLZXknLCA2NSk7XG4gIGNvbnN0IHNjYWxhck5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHNjYWxhckFyZ3MuZm9yRWFjaCgobikgPT4gc2NhbGFyTmFtZXMuYWRkKG4pKTtcblxuICBmdW5jdGlvbiBjaGVja0FyZ3MoYXJnczogQXJncyk6IHZvaWQge1xuICAgIGZvciAobGV0IFtuYW1lLCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKGFyZ3MpKSB7XG4gICAgICBpZiAodmFsdWVzID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgdmFsdWVzID0gQXJyYXkuaXNBcnJheSh2YWx1ZXMpID8gdmFsdWVzIDogW3ZhbHVlc107XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcihgMC1sZW5ndGggJHtuYW1lfXMgbm90IHN1cHBvcnRlZGApO1xuICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKGFyZ0xlbmd0aHMuZ2V0KG5hbWUpICE9PSB2YWx1ZS5sZW5ndGgpIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgJHtuYW1lfSBsZW5ndGggKCR7dmFsdWUubGVuZ3RofSlgKTtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdzZWNyZXRLZXknKSB7XG4gICAgICAgICAgaWYgKCFlY2MuaXNTZWNyZXQodmFsdWUpKSB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNlY3JldEtleWApO1xuICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdzZWNyZXROb25jZScpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY0OyBpICs9IDMyKSB7XG4gICAgICAgICAgICBpZiAoIWVjYy5pc1NlY3JldCh2YWx1ZS5zdWJhcnJheShpLCBpICsgMzIpKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzZWNyZXROb25jZWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzY2FsYXJOYW1lcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSArPSAzMikge1xuICAgICAgICAgICAgaWYgKCFlY2MuaXNTY2FsYXIodmFsdWUuc3ViYXJyYXkoaSwgaSArIDMyKSkpIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgJHtuYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBObyBuZWVkIGZvciBhIHB1YmxpYyBrZXkgeC10by1jdXJ2ZSBjaGVjay4gVGhleSdyZSBsaWZ0WCdkIGZvciB1c2UgYW55IHdheS5cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGdldFhPbmx5UHVia2V5OiAoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKCdhZ2dQdWJsaWNLZXknIGluIGN0eCkgcmV0dXJuIGVjYy5wb2ludFgoY3R4LmFnZ1B1YmxpY0tleSk7XG4gICAgICByZXR1cm4gZWNjLnBvaW50WChnZXRTZXNzaW9uVmFsdWVzKGN0eCkuYWdnUHVibGljS2V5KTtcbiAgICB9LFxuICAgIGdldFBsYWluUHVia2V5OiAoY3R4OiBLZXlHZW5Db250ZXh0IHwgU2Vzc2lvbktleSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKCdhZ2dQdWJsaWNLZXknIGluIGN0eCkgcmV0dXJuIGVjYy5wb2ludENvbXByZXNzKGN0eC5hZ2dQdWJsaWNLZXkpO1xuICAgICAgcmV0dXJuIGVjYy5wb2ludENvbXByZXNzKGdldFNlc3Npb25WYWx1ZXMoY3R4KS5hZ2dQdWJsaWNLZXkpO1xuICAgIH0sXG4gICAga2V5U29ydDogKHB1YmxpY0tleXM6IFVpbnQ4QXJyYXlbXSk6IFVpbnQ4QXJyYXlbXSA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBwdWJsaWNLZXlzIH0pO1xuICAgICAgLy8gZG8gbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXJyYXlcbiAgICAgIHJldHVybiBbLi4ucHVibGljS2V5c10uc29ydCgoYSwgYikgPT4gY29tcGFyZTMzYihhLCBiKSk7XG4gICAgfSxcbiAgICBrZXlBZ2csXG4gICAgYWRkVHdlYWtzOiAoY3R4OiBLZXlHZW5Db250ZXh0LCAuLi50d2Vha3M6IFR3ZWFrW10pOiBLZXlHZW5Db250ZXh0ID0+IHtcbiAgICAgIGNoZWNrQXJncyhjdHgpO1xuICAgICAgcmV0dXJuIHR3ZWFrcy5yZWR1Y2UoKGMsIHR3ZWFrKSA9PiBhZGRUd2VhayhjLCB0d2VhayksIGN0eCk7XG4gICAgfSxcblxuICAgIG5vbmNlR2VuOiAoe1xuICAgICAgc2Vzc2lvbklkID0gbWFrZVNlc3Npb25JZCgpLFxuICAgICAgc2VjcmV0S2V5LFxuICAgICAgcHVibGljS2V5LFxuICAgICAgeE9ubHlQdWJsaWNLZXksXG4gICAgICBtc2csXG4gICAgICBleHRyYUlucHV0LFxuICAgIH06IHtcbiAgICAgIHNlc3Npb25JZDogVWludDhBcnJheTtcbiAgICAgIHNlY3JldEtleT86IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgICB4T25seVB1YmxpY0tleT86IFVpbnQ4QXJyYXk7XG4gICAgICBtc2c/OiBVaW50OEFycmF5O1xuICAgICAgZXh0cmFJbnB1dD86IFVpbnQ4QXJyYXk7XG4gICAgfSk6IFVpbnQ4QXJyYXkgPT4ge1xuICAgICAgaWYgKGV4dHJhSW5wdXQgIT09IHVuZGVmaW5lZCAmJiBleHRyYUlucHV0Lmxlbmd0aCA+IE1hdGgucG93KDIsIDMyKSAtIDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZXh0cmFJbnB1dCBpcyBsaW1pdGVkIHRvIDJeMzItMSBieXRlcycpO1xuICAgICAgfVxuICAgICAgLy8gTm8gbmVlZCB0byBjaGVjayBtc2csIGl0cyBtYXggc2l6ZSBpcyBsYXJnZXIgdGhhbiBKUyB0eXBlZCBhcnJheSBsaW1pdFxuICAgICAgY2hlY2tBcmdzKHsgc2Vzc2lvbklkLCBzZWNyZXRLZXksIHB1YmxpY0tleSwgeE9ubHlQdWJsaWNLZXkgfSk7XG4gICAgICBsZXQgcmFuZDogVWludDhBcnJheTtcbiAgICAgIGlmIChzZWNyZXRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByYW5kID0gZWNjLnRhZ2dlZEhhc2goVEFHUy5tdXNpZ19hdXgsIHNlc3Npb25JZCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzI7IGkrKykge1xuICAgICAgICAgIHJhbmRbaV0gPSByYW5kW2ldIF4gc2VjcmV0S2V5W2ldO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5kID0gc2Vzc2lvbklkO1xuICAgICAgfVxuXG4gICAgICBpZiAoeE9ubHlQdWJsaWNLZXkgPT09IHVuZGVmaW5lZCkgeE9ubHlQdWJsaWNLZXkgPSBuZXcgVWludDhBcnJheSgpO1xuXG4gICAgICBjb25zdCBtUHJlZml4ZWQgPSBbVWludDhBcnJheS5vZigwKV07XG4gICAgICBpZiAobXNnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbVByZWZpeGVkWzBdWzBdID0gMTtcbiAgICAgICAgbVByZWZpeGVkLnB1c2gobmV3IFVpbnQ4QXJyYXkoOCkpO1xuICAgICAgICBuZXcgRGF0YVZpZXcobVByZWZpeGVkWzFdLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsIEJpZ0ludChtc2cubGVuZ3RoKSk7XG4gICAgICAgIG1QcmVmaXhlZC5wdXNoKG1zZyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHRyYUlucHV0ID09PSB1bmRlZmluZWQpIGV4dHJhSW5wdXQgPSBuZXcgVWludDhBcnJheSgpO1xuICAgICAgY29uc3QgZUxlbmd0aCA9IG5ldyBVaW50OEFycmF5KDQpO1xuICAgICAgbmV3IERhdGFWaWV3KGVMZW5ndGguYnVmZmVyKS5zZXRVaW50MzIoMCwgZXh0cmFJbnB1dC5sZW5ndGgpO1xuXG4gICAgICBjb25zdCBzZWNyZXROb25jZSA9IG5ldyBVaW50OEFycmF5KDk3KTtcbiAgICAgIGNvbnN0IHB1YmxpY05vbmNlID0gbmV3IFVpbnQ4QXJyYXkoNjYpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyBpKyspIHtcbiAgICAgICAgY29uc3Qga0ggPSBlY2MudGFnZ2VkSGFzaChcbiAgICAgICAgICBUQUdTLm11c2lnX25vbmNlLFxuICAgICAgICAgIHJhbmQsXG4gICAgICAgICAgVWludDhBcnJheS5vZihwdWJsaWNLZXkubGVuZ3RoKSxcbiAgICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgICAgVWludDhBcnJheS5vZih4T25seVB1YmxpY0tleS5sZW5ndGgpLFxuICAgICAgICAgIHhPbmx5UHVibGljS2V5LFxuICAgICAgICAgIC4uLm1QcmVmaXhlZCxcbiAgICAgICAgICBlTGVuZ3RoLFxuICAgICAgICAgIGV4dHJhSW5wdXQsXG4gICAgICAgICAgVWludDhBcnJheS5vZihpKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBrID0gZWNjLnNjYWxhck1vZChrSCk7XG4gICAgICAgIGlmIChjb21wYXJlMzJiKFNDQUxBUl8wLCBrKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKCcwIHNlY3JldCBub25jZScpO1xuICAgICAgICBjb25zdCBwdWIgPSBlY2MuZ2V0UHVibGljS2V5KGssIHRydWUpO1xuICAgICAgICBpZiAocHViID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3JldCBub25jZSBoYXMgbm8gY29ycmVzcG9uZGluZyBwdWJsaWMgbm9uY2UnKTtcblxuICAgICAgICBzZWNyZXROb25jZS5zZXQoaywgaSAqIDMyKTtcbiAgICAgICAgcHVibGljTm9uY2Uuc2V0KHB1YiwgaSAqIDMzKTtcbiAgICAgIH1cbiAgICAgIHNlY3JldE5vbmNlLnNldChwdWJsaWNLZXksIDY0KTtcbiAgICAgIF9ub25jZUNhY2hlLnNldChwdWJsaWNOb25jZSwgc2VjcmV0Tm9uY2UpO1xuICAgICAgcmV0dXJuIHB1YmxpY05vbmNlO1xuICAgIH0sXG5cbiAgICBhZGRFeHRlcm5hbE5vbmNlOiAocHVibGljTm9uY2U6IFVpbnQ4QXJyYXksIHNlY3JldE5vbmNlOiBVaW50OEFycmF5KTogdm9pZCA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBwdWJsaWNOb25jZSwgc2VjcmV0Tm9uY2UgfSk7XG4gICAgICBfbm9uY2VDYWNoZS5zZXQocHVibGljTm9uY2UsIHNlY3JldE5vbmNlKTtcbiAgICB9LFxuXG4gICAgZGV0ZXJtaW5pc3RpY05vbmNlR2VuOiAoYXJnczogRGV0ZXJtaW5pc3RpY1NpZ25BcmdzQmFzZSk6IHsgcHVibGljTm9uY2U6IFVpbnQ4QXJyYXkgfSA9PlxuICAgICAgZGV0ZXJtaW5pc3RpY1NpZ24oeyAuLi5hcmdzLCBub25jZU9ubHk6IHRydWUgfSksXG5cbiAgICBkZXRlcm1pbmlzdGljU2lnbixcblxuICAgIG5vbmNlQWdnLFxuXG4gICAgc3RhcnRTaWduaW5nU2Vzc2lvbjogKFxuICAgICAgYWdnTm9uY2U6IFVpbnQ4QXJyYXksXG4gICAgICBtc2c6IFVpbnQ4QXJyYXksXG4gICAgICBwdWJsaWNLZXlzOiBVaW50OEFycmF5W10sXG4gICAgICAuLi50d2Vha3M6IFR3ZWFrW11cbiAgICApOiBTZXNzaW9uS2V5ID0+IHtcbiAgICAgIGNoZWNrQXJncyh7IGFnZ05vbmNlIH0pO1xuICAgICAgY29uc3QgY3R4ID0ga2V5QWdnKHB1YmxpY0tleXMsIC4uLnR3ZWFrcyk7XG4gICAgICByZXR1cm4gc3RhcnRTaWduaW5nU2Vzc2lvbklubmVyKGFnZ05vbmNlLCBtc2csIHB1YmxpY0tleXMsIGN0eCk7XG4gICAgfSxcblxuICAgIHBhcnRpYWxTaWduLFxuXG4gICAgcGFydGlhbFZlcmlmeTogKHtcbiAgICAgIHNpZyxcbiAgICAgIHB1YmxpY0tleSxcbiAgICAgIHB1YmxpY05vbmNlLFxuICAgICAgc2Vzc2lvbktleSxcbiAgICB9OiB7XG4gICAgICBzaWc6IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNLZXk6IFVpbnQ4QXJyYXk7XG4gICAgICBwdWJsaWNOb25jZTogVWludDhBcnJheTtcbiAgICAgIHNlc3Npb25LZXk6IFNlc3Npb25LZXk7XG4gICAgfSk6IGJvb2xlYW4gPT4ge1xuICAgICAgY2hlY2tBcmdzKHsgc2lnLCBwdWJsaWNLZXksIHB1YmxpY05vbmNlIH0pO1xuXG4gICAgICBjb25zdCBwdWJsaWNOb25jZXM6IFtVaW50OEFycmF5LCBVaW50OEFycmF5XSA9IFtwdWJsaWNOb25jZS5zdWJhcnJheSgwLCAzMyksIHB1YmxpY05vbmNlLnN1YmFycmF5KDMzKV07XG5cbiAgICAgIGNvbnN0IHZhbGlkID0gcGFydGlhbFZlcmlmeUlubmVyKHtcbiAgICAgICAgc2lnLFxuICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgIHB1YmxpY05vbmNlcyxcbiAgICAgICAgc2Vzc2lvbktleSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH0sXG5cbiAgICBzaWduQWdnOiAoc2lnczogVWludDhBcnJheVtdLCBzZXNzaW9uS2V5OiBTZXNzaW9uS2V5KTogVWludDhBcnJheSA9PiB7XG4gICAgICBjaGVja0FyZ3MoeyBzaWdzIH0pO1xuXG4gICAgICBjb25zdCB7IGFnZ1B1YmxpY0tleSwgdGFjYywgY2hhbGxlbmdlLCBmaW5hbE5vbmNlIH0gPSBnZXRTZXNzaW9uVmFsdWVzKHNlc3Npb25LZXkpO1xuICAgICAgbGV0IHNQYXJ0OiBVaW50OEFycmF5ID0gZWNjLnNjYWxhck11bHRpcGx5KGNoYWxsZW5nZSwgdGFjYyk7XG4gICAgICBpZiAoIWVjYy5oYXNFdmVuWShhZ2dQdWJsaWNLZXkpKSB7XG4gICAgICAgIHNQYXJ0ID0gZWNjLnNjYWxhck5lZ2F0ZShzUGFydCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhZ2dTID0gc2lncy5yZWR1Y2UoKGEsIGIpID0+IGVjYy5zY2FsYXJBZGQoYSwgYiksIHNQYXJ0KTtcbiAgICAgIGNvbnN0IHNpZyA9IG5ldyBVaW50OEFycmF5KDY0KTtcbiAgICAgIHNpZy5zZXQoZWNjLnBvaW50WChmaW5hbE5vbmNlKSwgMCk7XG4gICAgICBzaWcuc2V0KGFnZ1MsIDMyKTtcbiAgICAgIHJldHVybiBzaWc7XG4gICAgfSxcbiAgfTtcbn1cbiJdfQ==
|