@bitgo-beta/sdk-lib-mpc 8.2.1-alpha.35 → 8.2.1-alpha.37
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/CHANGELOG.md +16 -0
- package/dist/src/tss/ecdsa/generatePaillierKey.d.ts +6 -0
- package/dist/src/tss/ecdsa/generatePaillierKey.d.ts.map +1 -0
- package/dist/src/tss/ecdsa/generatePaillierKey.js +52 -0
- package/dist/src/tss/ecdsa/index.d.ts +4 -2
- package/dist/src/tss/ecdsa/index.d.ts.map +1 -1
- package/dist/src/tss/ecdsa/index.js +9 -4
- package/dist/src/tss/ecdsa/noSmallFactorsProof.d.ts +24 -0
- package/dist/src/tss/ecdsa/noSmallFactorsProof.d.ts.map +1 -0
- package/dist/src/tss/ecdsa/noSmallFactorsProof.js +157 -0
- package/dist/src/tss/ecdsa/paillierBlumProof.d.ts +16 -0
- package/dist/src/tss/ecdsa/paillierBlumProof.d.ts.map +1 -0
- package/dist/src/tss/ecdsa/paillierBlumProof.js +148 -0
- package/dist/src/tss/ecdsa/{paillierproof.d.ts → paillierProof.d.ts} +1 -1
- package/dist/src/tss/ecdsa/{paillierproof.d.ts.map → paillierProof.d.ts.map} +1 -1
- package/dist/src/tss/ecdsa/{paillierproof.js → paillierProof.js} +1 -1
- package/dist/src/tss/ecdsa/{rangeproof.d.ts → rangeProof.d.ts} +1 -1
- package/dist/src/tss/ecdsa/rangeProof.d.ts.map +1 -0
- package/dist/src/tss/ecdsa/rangeProof.js +404 -0
- package/dist/src/tss/ecdsa/types.d.ts +51 -3
- package/dist/src/tss/ecdsa/types.d.ts.map +1 -1
- package/dist/src/tss/ecdsa/types.js +68 -3
- package/dist/src/util.d.ts +2 -0
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +45 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/dist/src/tss/ecdsa/rangeproof.d.ts.map +0 -1
- package/dist/src/tss/ecdsa/rangeproof.js +0 -450
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.verifyWithCheck = exports.proveWithCheck = exports.verify = exports.prove = exports.verifyNtildeProof = exports.generateNtildeProof = exports.generateNtilde = exports.generateSafePrimes = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Zero Knowledge Range Proofs as described in (Two-party generation of DSA signatures)[1].
|
|
6
|
-
* [1]: https://reitermk.github.io/papers/2004/IJIS.pdf
|
|
7
|
-
*/
|
|
8
|
-
const crypto_1 = require("crypto");
|
|
9
|
-
const bigint_crypto_utils_1 = require("bigint-crypto-utils");
|
|
10
|
-
const bigint_mod_arith_1 = require("bigint-mod-arith");
|
|
11
|
-
const util_1 = require("../../util");
|
|
12
|
-
const openssl_1 = require("../../openssl");
|
|
13
|
-
const index_1 = require("./index");
|
|
14
|
-
// 128 as recommend by https://blog.verichains.io/p/vsa-2022-120-multichain-key-extraction.
|
|
15
|
-
const ITERATIONS = 128;
|
|
16
|
-
async function generateSafePrimes(bitLengths) {
|
|
17
|
-
const openSSL = new openssl_1.OpenSSL();
|
|
18
|
-
await openSSL.init();
|
|
19
|
-
const promises = bitLengths.map((bitlength) => {
|
|
20
|
-
return openSSL.generateSafePrime(bitlength);
|
|
21
|
-
});
|
|
22
|
-
return await Promise.all(promises);
|
|
23
|
-
}
|
|
24
|
-
exports.generateSafePrimes = generateSafePrimes;
|
|
25
|
-
async function generateModulus(bitlength = index_1.minModulusBitLength, retry = 10) {
|
|
26
|
-
if (bitlength < index_1.minModulusBitLength) {
|
|
27
|
-
// https://www.keylength.com/en/6/
|
|
28
|
-
// eslint-disable-next-line no-console
|
|
29
|
-
console.warn('Generating a modulus with less than 3072 is not recommended!');
|
|
30
|
-
}
|
|
31
|
-
const bitlengthP = Math.floor(bitlength / 2);
|
|
32
|
-
const bitlengthQ = bitlength - bitlengthP;
|
|
33
|
-
for (let i = 0; i < retry; i++) {
|
|
34
|
-
const [p, q] = await generateSafePrimes([bitlengthP, bitlengthQ]);
|
|
35
|
-
const n = p * q;
|
|
36
|
-
// For large bit lengths, the probability of generating a modulus with the wrong bit length is very low.
|
|
37
|
-
if (bigint_crypto_utils_1.bitLength(n) !== bitlength) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
return { n, q1: (p - BigInt(1)) / BigInt(2), q2: (q - BigInt(1)) / BigInt(2) };
|
|
41
|
-
}
|
|
42
|
-
throw new Error(`Unable to generate modulus with bit length of ${bitlength} after ${retry} tries. Please try again or reach out to support@bitgo.com`);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Generate "challenge" values for range proofs.
|
|
46
|
-
* @param {number} bitlength The bit length of the modulus to generate. This should
|
|
47
|
-
* be the same as the bit length of the paillier public keys used for MtA.
|
|
48
|
-
* @returns {DeserializedNtilde} The generated Ntilde values.
|
|
49
|
-
*/
|
|
50
|
-
async function generateNtilde(bitlength = index_1.minModulusBitLength) {
|
|
51
|
-
const { n: ntilde, q1, q2 } = await generateModulus(bitlength);
|
|
52
|
-
const [f1, f2] = await Promise.all([util_1.randomPositiveCoPrimeTo(ntilde), util_1.randomPositiveCoPrimeTo(ntilde)]);
|
|
53
|
-
const h1 = bigint_mod_arith_1.modPow(f1, BigInt(2), ntilde);
|
|
54
|
-
const h2 = bigint_mod_arith_1.modPow(h1, f2, ntilde);
|
|
55
|
-
const beta = bigint_mod_arith_1.modInv(f2, q1 * q2);
|
|
56
|
-
const [h1wrtH2Proofs, h2wrtH1Proofs] = await Promise.all([
|
|
57
|
-
generateNtildeProof({
|
|
58
|
-
h1: h1,
|
|
59
|
-
h2: h2,
|
|
60
|
-
ntilde: ntilde,
|
|
61
|
-
}, f2, q1, q2),
|
|
62
|
-
generateNtildeProof({
|
|
63
|
-
h1: h2,
|
|
64
|
-
h2: h1,
|
|
65
|
-
ntilde: ntilde,
|
|
66
|
-
}, beta, q1, q2),
|
|
67
|
-
]);
|
|
68
|
-
return {
|
|
69
|
-
ntilde,
|
|
70
|
-
h1,
|
|
71
|
-
h2,
|
|
72
|
-
ntildeProof: {
|
|
73
|
-
h1WrtH2: {
|
|
74
|
-
alpha: h1wrtH2Proofs.alpha,
|
|
75
|
-
t: h1wrtH2Proofs.t,
|
|
76
|
-
},
|
|
77
|
-
h2WrtH1: {
|
|
78
|
-
alpha: h2wrtH1Proofs.alpha,
|
|
79
|
-
t: h2wrtH1Proofs.t,
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
exports.generateNtilde = generateNtilde;
|
|
85
|
-
/**
|
|
86
|
-
* Generate iterations of Ntilde, h1, h2 discrete log proofs.
|
|
87
|
-
* @param {DeserializedNtilde} ntilde Ntilde, h1, h2 to generate the proofs for.
|
|
88
|
-
* @param {bigint} x Either alpha or beta depending on whether it is a discrete log proof of
|
|
89
|
-
* h1 w.r.t h2 or h2 w.r.t h1.
|
|
90
|
-
* @param {bigint} q1 The Sophie Germain prime associated with the first safe prime p1 used to generate Ntilde.
|
|
91
|
-
* @param {bigint} q2 The Sophie Germain prime associated with the second safe prime p2 used to generate Ntilde.
|
|
92
|
-
* @returns {NtildeProof} The generated Ntilde Proofs.
|
|
93
|
-
*/
|
|
94
|
-
async function generateNtildeProof(ntilde, x, q1, q2) {
|
|
95
|
-
const q1MulQ2 = q1 * q2;
|
|
96
|
-
const a = [];
|
|
97
|
-
const alpha = [];
|
|
98
|
-
let msgToHash = Buffer.concat([
|
|
99
|
-
util_1.bigIntToBufferBE(ntilde.h1),
|
|
100
|
-
util_1.bigIntToBufferBE(ntilde.h2),
|
|
101
|
-
util_1.bigIntToBufferBE(ntilde.ntilde),
|
|
102
|
-
]);
|
|
103
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
104
|
-
a.push(bigint_crypto_utils_1.randBetween(q1MulQ2));
|
|
105
|
-
alpha.push(bigint_mod_arith_1.modPow(ntilde.h1, a[i], ntilde.ntilde));
|
|
106
|
-
msgToHash = Buffer.concat([msgToHash, util_1.bigIntToBufferBE(alpha[i], Math.ceil(bigint_crypto_utils_1.bitLength(ntilde.ntilde) / 8))]);
|
|
107
|
-
}
|
|
108
|
-
const simulatedResponse = crypto_1.createHash('sha256').update(msgToHash).digest();
|
|
109
|
-
const t = [];
|
|
110
|
-
for (let i = 0; i < ITERATIONS; i++) {
|
|
111
|
-
// Get the ith bit from a buffer of bytes.
|
|
112
|
-
const ithBit = (simulatedResponse[Math.floor(i / 8)] >> (7 - (i % 8))) & 1;
|
|
113
|
-
t.push((a[i] + ((BigInt(ithBit) * x) % q1MulQ2)) % q1MulQ2);
|
|
114
|
-
}
|
|
115
|
-
return { alpha, t };
|
|
116
|
-
}
|
|
117
|
-
exports.generateNtildeProof = generateNtildeProof;
|
|
118
|
-
/**
|
|
119
|
-
* Verify discrete log proofs of h1 and h2 mod Ntilde.
|
|
120
|
-
* @param {DeserializedNtilde} ntilde Ntilde, h1, h2 to generate the proofs for.
|
|
121
|
-
* @param {DeserializedNtildeProof} ntildeProof Ntilde Proofs
|
|
122
|
-
* @returns {boolean} true if proof is verified, false otherwise.
|
|
123
|
-
*/
|
|
124
|
-
async function verifyNtildeProof(ntilde, ntildeProof) {
|
|
125
|
-
const h1ModNtilde = ntilde.h1 % ntilde.ntilde;
|
|
126
|
-
const h2ModNtilde = ntilde.h2 % ntilde.ntilde;
|
|
127
|
-
if (h1ModNtilde === BigInt(0) || h2ModNtilde === BigInt(0)) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
if (h1ModNtilde === BigInt(1) || h2ModNtilde === BigInt(1)) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
if (h1ModNtilde === h2ModNtilde) {
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
if (ntildeProof.alpha.length > 256 ||
|
|
137
|
-
ntildeProof.alpha.length !== ITERATIONS ||
|
|
138
|
-
ntildeProof.t.length !== ITERATIONS) {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
let msgToHash = Buffer.concat([
|
|
142
|
-
util_1.bigIntToBufferBE(ntilde.h1),
|
|
143
|
-
util_1.bigIntToBufferBE(ntilde.h2),
|
|
144
|
-
util_1.bigIntToBufferBE(ntilde.ntilde),
|
|
145
|
-
]);
|
|
146
|
-
for (let i = 0; i < ntildeProof.alpha.length; i++) {
|
|
147
|
-
msgToHash = Buffer.concat([
|
|
148
|
-
msgToHash,
|
|
149
|
-
util_1.bigIntToBufferBE(ntildeProof.alpha[i], Math.ceil(bigint_crypto_utils_1.bitLength(ntilde.ntilde) / 8)),
|
|
150
|
-
]);
|
|
151
|
-
}
|
|
152
|
-
const simulatedResponse = crypto_1.createHash('sha256').update(msgToHash).digest();
|
|
153
|
-
for (let i = 0; i < ntildeProof.alpha.length; i++) {
|
|
154
|
-
// Get the ith bit from a buffer of bytes.
|
|
155
|
-
const ithBit = (simulatedResponse[Math.floor(i / 8)] >> (7 - (i % 8))) & 1;
|
|
156
|
-
const h1PowTi = bigint_mod_arith_1.modPow(ntilde.h1, ntildeProof.t[i], ntilde.ntilde);
|
|
157
|
-
const h2PowCi = bigint_mod_arith_1.modPow(ntilde.h2, BigInt(ithBit), ntilde.ntilde);
|
|
158
|
-
const alphaMulh2PowCi = (ntildeProof.alpha[i] * h2PowCi) % ntilde.ntilde;
|
|
159
|
-
if (h1PowTi !== alphaMulh2PowCi) {
|
|
160
|
-
return false;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return true;
|
|
164
|
-
}
|
|
165
|
-
exports.verifyNtildeProof = verifyNtildeProof;
|
|
166
|
-
function rangeProofChallenge(curve, modulusBytes, pk, c, z, u, w) {
|
|
167
|
-
const q = curve.order();
|
|
168
|
-
const hash = crypto_1.createHash('sha256');
|
|
169
|
-
hash.update('\x07\x00\x00\x00\x00\x00\x00\x00');
|
|
170
|
-
hash.update(util_1.bigIntToBufferBE(pk.n, modulusBytes));
|
|
171
|
-
hash.update('$');
|
|
172
|
-
hash.update(util_1.bigIntToBufferBE(pk.g, modulusBytes));
|
|
173
|
-
hash.update('$');
|
|
174
|
-
hash.update(util_1.bigIntToBufferBE(c, 2 * modulusBytes));
|
|
175
|
-
hash.update('$');
|
|
176
|
-
hash.update(util_1.bigIntToBufferBE(z, modulusBytes));
|
|
177
|
-
hash.update('$');
|
|
178
|
-
hash.update(util_1.bigIntToBufferBE(u, 2 * modulusBytes));
|
|
179
|
-
hash.update('$');
|
|
180
|
-
hash.update(util_1.bigIntToBufferBE(w, modulusBytes));
|
|
181
|
-
hash.update('$');
|
|
182
|
-
let nonce, e;
|
|
183
|
-
do {
|
|
184
|
-
nonce = crypto_1.randomBytes(32);
|
|
185
|
-
e = util_1.bigIntFromBufferBE(hash.copy().update(nonce).digest());
|
|
186
|
-
} while (e >= q);
|
|
187
|
-
return { nonce, e };
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Generate a zero-knowledge range proof that an encrypted value is "small".
|
|
191
|
-
* @param {BaseCurve} curve An elliptic curve to use for group operations.
|
|
192
|
-
* @param {number} modulusBits The bit count of the prover's public key.
|
|
193
|
-
* @param {PublicKey} pk The prover's public key.
|
|
194
|
-
* @param {DeserializedNtilde} ntilde The verifier's Ntilde values.
|
|
195
|
-
* @param {bigint} c The ciphertext.
|
|
196
|
-
* @param {bigint} m The plaintext.
|
|
197
|
-
* @param {bigint} r The obfuscation value used to encrypt m.
|
|
198
|
-
* @returns {RangeProof} The generated proof.
|
|
199
|
-
*/
|
|
200
|
-
async function prove(curve, modulusBits, pk, ntilde, c, m, r) {
|
|
201
|
-
const modulusBytes = Math.floor((modulusBits + 7) / 8);
|
|
202
|
-
const q = curve.order();
|
|
203
|
-
const q3 = q ** BigInt(3);
|
|
204
|
-
const qntilde = q * ntilde.ntilde;
|
|
205
|
-
const q3ntilde = q3 * ntilde.ntilde;
|
|
206
|
-
const alpha = bigint_crypto_utils_1.randBetween(q3);
|
|
207
|
-
const beta = await util_1.randomPositiveCoPrimeTo(pk.n);
|
|
208
|
-
const gamma = bigint_crypto_utils_1.randBetween(q3ntilde);
|
|
209
|
-
const rho = bigint_crypto_utils_1.randBetween(qntilde);
|
|
210
|
-
const z = (bigint_mod_arith_1.modPow(ntilde.h1, m, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, rho, ntilde.ntilde)) % ntilde.ntilde;
|
|
211
|
-
const u = (bigint_mod_arith_1.modPow(pk.g, alpha, pk._n2) * bigint_mod_arith_1.modPow(beta, pk.n, pk._n2)) % pk._n2;
|
|
212
|
-
const w = (bigint_mod_arith_1.modPow(ntilde.h1, alpha, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, gamma, ntilde.ntilde)) % ntilde.ntilde;
|
|
213
|
-
const { nonce, e } = rangeProofChallenge(curve, modulusBytes, pk, c, z, u, w);
|
|
214
|
-
const s = (bigint_mod_arith_1.modPow(r, e, pk.n) * beta) % pk.n;
|
|
215
|
-
const s1 = e * m + alpha;
|
|
216
|
-
const s2 = e * rho + gamma;
|
|
217
|
-
return { z, u, w, nonce, s, s1, s2 };
|
|
218
|
-
}
|
|
219
|
-
exports.prove = prove;
|
|
220
|
-
/**
|
|
221
|
-
* Verify a zero-knowledge range proof that an encrypted value is "small".
|
|
222
|
-
* @param {BaseCurve} curve An elliptic curve to use for group operations.
|
|
223
|
-
* @param {number} modulusBits The bit count of the prover's public key.
|
|
224
|
-
* @param {PublicKey} pk The prover's public key.
|
|
225
|
-
* @param {DeserializedNtilde} ntilde The verifier's Ntilde values.
|
|
226
|
-
* @param {RangeProof} proof The range proof.
|
|
227
|
-
* @param {bigint} c The ciphertext.
|
|
228
|
-
* @returns {boolean} True if verification succeeds.
|
|
229
|
-
*/
|
|
230
|
-
function verify(curve, modulusBits, pk, ntilde, proof, c) {
|
|
231
|
-
if (proof.u === BigInt(0) || proof.s === BigInt(0)) {
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
const modulusBytes = Math.floor((modulusBits + 7) / 8);
|
|
235
|
-
const q = curve.order();
|
|
236
|
-
const q3 = q ** BigInt(3);
|
|
237
|
-
if (proof.s1 > q3) {
|
|
238
|
-
return false;
|
|
239
|
-
}
|
|
240
|
-
const hash = crypto_1.createHash('sha256');
|
|
241
|
-
if (proof.nonce) {
|
|
242
|
-
hash.update('\x07\x00\x00\x00\x00\x00\x00\x00');
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
hash.update('\x06\x00\x00\x00\x00\x00\x00\x00');
|
|
246
|
-
}
|
|
247
|
-
hash.update(util_1.bigIntToBufferBE(pk.n, modulusBytes));
|
|
248
|
-
hash.update('$');
|
|
249
|
-
hash.update(util_1.bigIntToBufferBE(pk.g, modulusBytes));
|
|
250
|
-
hash.update('$');
|
|
251
|
-
hash.update(util_1.bigIntToBufferBE(c, 2 * modulusBytes));
|
|
252
|
-
hash.update('$');
|
|
253
|
-
hash.update(util_1.bigIntToBufferBE(proof.z, modulusBytes));
|
|
254
|
-
hash.update('$');
|
|
255
|
-
hash.update(util_1.bigIntToBufferBE(proof.u, 2 * modulusBytes));
|
|
256
|
-
hash.update('$');
|
|
257
|
-
hash.update(util_1.bigIntToBufferBE(proof.w, modulusBytes));
|
|
258
|
-
hash.update('$');
|
|
259
|
-
let e;
|
|
260
|
-
if (proof.nonce) {
|
|
261
|
-
e = util_1.bigIntFromBufferBE(hash.update(proof.nonce).digest());
|
|
262
|
-
if (e >= q) {
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
e = util_1.bigIntFromBufferBE(hash.digest()) % q;
|
|
268
|
-
}
|
|
269
|
-
let products;
|
|
270
|
-
products = (bigint_mod_arith_1.modPow(pk.g, proof.s1, pk._n2) * bigint_mod_arith_1.modPow(proof.s, pk.n, pk._n2) * bigint_mod_arith_1.modPow(c, -e, pk._n2)) % pk._n2;
|
|
271
|
-
if (proof.u !== products) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
products =
|
|
275
|
-
(((bigint_mod_arith_1.modPow(ntilde.h1, proof.s1, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, proof.s2, ntilde.ntilde)) % ntilde.ntilde) *
|
|
276
|
-
bigint_mod_arith_1.modPow(proof.z, -e, ntilde.ntilde)) %
|
|
277
|
-
ntilde.ntilde;
|
|
278
|
-
return proof.w === products;
|
|
279
|
-
}
|
|
280
|
-
exports.verify = verify;
|
|
281
|
-
function rangeProofWithCheckChallenge(curve, modulusBytes, pk, X, c1, c2, u, z, zprm, t, v, w) {
|
|
282
|
-
const q = curve.order();
|
|
283
|
-
const hash = crypto_1.createHash('sha256');
|
|
284
|
-
hash.update('\x0e\x00\x00\x00\x00\x00\x00\x00');
|
|
285
|
-
hash.update(util_1.bigIntToBufferBE(pk.n, modulusBytes));
|
|
286
|
-
hash.update('$');
|
|
287
|
-
hash.update(util_1.bigIntToBufferBE(pk.g, modulusBytes));
|
|
288
|
-
hash.update('$');
|
|
289
|
-
hash.update(util_1.bigIntToBufferBE(X, 33));
|
|
290
|
-
hash.update('$');
|
|
291
|
-
hash.update(util_1.bigIntToBufferBE(c1, 2 * modulusBytes));
|
|
292
|
-
hash.update('$');
|
|
293
|
-
hash.update(util_1.bigIntToBufferBE(c2, 2 * modulusBytes));
|
|
294
|
-
hash.update('$');
|
|
295
|
-
hash.update(util_1.bigIntToBufferBE(u, 33));
|
|
296
|
-
hash.update('$');
|
|
297
|
-
hash.update(util_1.bigIntToBufferBE(z, modulusBytes));
|
|
298
|
-
hash.update('$');
|
|
299
|
-
hash.update(util_1.bigIntToBufferBE(zprm, modulusBytes));
|
|
300
|
-
hash.update('$');
|
|
301
|
-
hash.update(util_1.bigIntToBufferBE(t, modulusBytes));
|
|
302
|
-
hash.update('$');
|
|
303
|
-
hash.update(util_1.bigIntToBufferBE(v, 2 * modulusBytes));
|
|
304
|
-
hash.update('$');
|
|
305
|
-
hash.update(util_1.bigIntToBufferBE(w, modulusBytes));
|
|
306
|
-
hash.update('$');
|
|
307
|
-
let nonce, e;
|
|
308
|
-
do {
|
|
309
|
-
nonce = crypto_1.randomBytes(32);
|
|
310
|
-
e = util_1.bigIntFromBufferBE(hash.copy().update(nonce).digest());
|
|
311
|
-
} while (e >= q);
|
|
312
|
-
return { nonce, e };
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Generate a zero-knowledge range proof that a homomorphically manipulated value is "small".
|
|
316
|
-
* @param {BaseCurve} curve An elliptic curve to use for group operations.
|
|
317
|
-
* @param {number} modulusBits The bit count of the prover's public key.
|
|
318
|
-
* @param {PublicKey} pk The prover's public key.
|
|
319
|
-
* @param {DeserializedNtilde} ntilde The verifier's Ntilde values.
|
|
320
|
-
* @param {bigint} c1 The original ciphertext.
|
|
321
|
-
* @param {bigint} c2 The manipulated ciphertext.
|
|
322
|
-
* @param {bigint} x The plaintext value multiplied by the original plaintext.
|
|
323
|
-
* @param {bigint} y The plaintext value that is added to x.
|
|
324
|
-
* @param {bigint} r The obfuscation value used to encrypt x.
|
|
325
|
-
* @param {bigint} X The curve's base point raised to x.
|
|
326
|
-
* @returns {RangeProofWithCheck} The generated proof.
|
|
327
|
-
*/
|
|
328
|
-
async function proveWithCheck(curve, modulusBits, pk, ntilde, c1, c2, x, y, r, X) {
|
|
329
|
-
const modulusBytes = Math.floor((modulusBits + 7) / 8);
|
|
330
|
-
const q = curve.order();
|
|
331
|
-
const q3 = q ** BigInt(3);
|
|
332
|
-
const q7 = q ** BigInt(7);
|
|
333
|
-
const qntilde = q * ntilde.ntilde;
|
|
334
|
-
const q3ntilde = q3 * ntilde.ntilde;
|
|
335
|
-
const alpha = bigint_crypto_utils_1.randBetween(q3);
|
|
336
|
-
const rho = bigint_crypto_utils_1.randBetween(qntilde);
|
|
337
|
-
const sigma = bigint_crypto_utils_1.randBetween(qntilde);
|
|
338
|
-
const tau = bigint_crypto_utils_1.randBetween(q3ntilde);
|
|
339
|
-
const rhoprm = bigint_crypto_utils_1.randBetween(q3ntilde);
|
|
340
|
-
const beta = await util_1.randomPositiveCoPrimeTo(pk.n);
|
|
341
|
-
const gamma = bigint_crypto_utils_1.randBetween(q7);
|
|
342
|
-
const u = curve.basePointMult(curve.scalarReduce(alpha));
|
|
343
|
-
const z = (bigint_mod_arith_1.modPow(ntilde.h1, x, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, rho, ntilde.ntilde)) % ntilde.ntilde;
|
|
344
|
-
const zprm = (bigint_mod_arith_1.modPow(ntilde.h1, alpha, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, rhoprm, ntilde.ntilde)) % ntilde.ntilde;
|
|
345
|
-
const t = (bigint_mod_arith_1.modPow(ntilde.h1, y, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, sigma, ntilde.ntilde)) % ntilde.ntilde;
|
|
346
|
-
const v = (((bigint_mod_arith_1.modPow(c1, alpha, pk._n2) * bigint_mod_arith_1.modPow(pk.g, gamma, pk._n2)) % pk._n2) * bigint_mod_arith_1.modPow(beta, pk.n, pk._n2)) % pk._n2;
|
|
347
|
-
const w = (bigint_mod_arith_1.modPow(ntilde.h1, gamma, ntilde.ntilde) * bigint_mod_arith_1.modPow(ntilde.h2, tau, ntilde.ntilde)) % ntilde.ntilde;
|
|
348
|
-
const { nonce, e } = rangeProofWithCheckChallenge(curve, modulusBytes, pk, X, c1, c2, u, z, zprm, t, v, w);
|
|
349
|
-
const s = (bigint_mod_arith_1.modPow(r, e, pk.n) * beta) % pk.n;
|
|
350
|
-
const s1 = e * x + alpha;
|
|
351
|
-
const s2 = e * rho + rhoprm;
|
|
352
|
-
const t1 = e * y + gamma;
|
|
353
|
-
const t2 = e * sigma + tau;
|
|
354
|
-
return { z, zprm, t, v, w, nonce, s, s1, s2, t1, t2, u };
|
|
355
|
-
}
|
|
356
|
-
exports.proveWithCheck = proveWithCheck;
|
|
357
|
-
/**
|
|
358
|
-
* Verify a zero-knowledge range proof that a homomorphically manipulated value is "small".
|
|
359
|
-
* @param {BaseCurve} curve An elliptic curve to use for group operations.
|
|
360
|
-
* @param {number} modulusBits The bit count of the prover's public key.
|
|
361
|
-
* @param {PublicKey} pk The prover's public key.
|
|
362
|
-
* @param {DeserializedNtilde} ntilde The verifier's Ntilde values.
|
|
363
|
-
* @param {RangeProofWithCheck} proof The range proof.
|
|
364
|
-
* @param {bigint} c1 The original ciphertext.
|
|
365
|
-
* @param {bigint} c2 The manipulated ciphertext.
|
|
366
|
-
* @param {bigint} X The curve's base point raised to x.
|
|
367
|
-
* @returns {boolean} True if verification succeeds.
|
|
368
|
-
*/
|
|
369
|
-
function verifyWithCheck(curve, modulusBits, pk, ntilde, proof, c1, c2, X) {
|
|
370
|
-
const modulusBytes = Math.floor((modulusBits + 7) / 8);
|
|
371
|
-
const q = curve.order();
|
|
372
|
-
const q3 = q ** BigInt(3);
|
|
373
|
-
const q7 = q ** BigInt(7);
|
|
374
|
-
if (proof.s1 > q3) {
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
if (proof.t1 > q7) {
|
|
378
|
-
return false;
|
|
379
|
-
}
|
|
380
|
-
const hash = crypto_1.createHash('sha256');
|
|
381
|
-
if (proof.nonce) {
|
|
382
|
-
hash.update('\x0e\x00\x00\x00\x00\x00\x00\x00');
|
|
383
|
-
}
|
|
384
|
-
else {
|
|
385
|
-
hash.update('\x0d\x00\x00\x00\x00\x00\x00\x00');
|
|
386
|
-
}
|
|
387
|
-
hash.update(util_1.bigIntToBufferBE(pk.n, modulusBytes));
|
|
388
|
-
hash.update('$');
|
|
389
|
-
hash.update(util_1.bigIntToBufferBE(pk.g, modulusBytes));
|
|
390
|
-
hash.update('$');
|
|
391
|
-
hash.update(util_1.bigIntToBufferBE(X, 33));
|
|
392
|
-
hash.update('$');
|
|
393
|
-
hash.update(util_1.bigIntToBufferBE(c1, 2 * modulusBytes));
|
|
394
|
-
hash.update('$');
|
|
395
|
-
hash.update(util_1.bigIntToBufferBE(c2, 2 * modulusBytes));
|
|
396
|
-
hash.update('$');
|
|
397
|
-
hash.update(util_1.bigIntToBufferBE(proof.u, 33));
|
|
398
|
-
hash.update('$');
|
|
399
|
-
hash.update(util_1.bigIntToBufferBE(proof.z, modulusBytes));
|
|
400
|
-
hash.update('$');
|
|
401
|
-
hash.update(util_1.bigIntToBufferBE(proof.zprm, modulusBytes));
|
|
402
|
-
hash.update('$');
|
|
403
|
-
hash.update(util_1.bigIntToBufferBE(proof.t, modulusBytes));
|
|
404
|
-
hash.update('$');
|
|
405
|
-
hash.update(util_1.bigIntToBufferBE(proof.v, 2 * modulusBytes));
|
|
406
|
-
hash.update('$');
|
|
407
|
-
hash.update(util_1.bigIntToBufferBE(proof.w, modulusBytes));
|
|
408
|
-
hash.update('$');
|
|
409
|
-
let e;
|
|
410
|
-
if (proof.nonce) {
|
|
411
|
-
e = util_1.bigIntFromBufferBE(hash.update(proof.nonce).digest());
|
|
412
|
-
if (e >= q) {
|
|
413
|
-
return false;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
e = util_1.bigIntFromBufferBE(hash.digest()) % q;
|
|
418
|
-
}
|
|
419
|
-
const gS1 = curve.basePointMult(curve.scalarReduce(proof.s1));
|
|
420
|
-
const xEU = curve.pointAdd(curve.pointMultiply(X, e), proof.u);
|
|
421
|
-
if (gS1 !== xEU) {
|
|
422
|
-
return false;
|
|
423
|
-
}
|
|
424
|
-
let left, right;
|
|
425
|
-
const h1ExpS1 = bigint_mod_arith_1.modPow(ntilde.h1, proof.s1, ntilde.ntilde);
|
|
426
|
-
const h2ExpS2 = bigint_mod_arith_1.modPow(ntilde.h2, proof.s2, ntilde.ntilde);
|
|
427
|
-
left = (h1ExpS1 * h2ExpS2) % ntilde.ntilde;
|
|
428
|
-
const zExpE = bigint_mod_arith_1.modPow(proof.z, e, ntilde.ntilde);
|
|
429
|
-
right = (zExpE * proof.zprm) % ntilde.ntilde;
|
|
430
|
-
if (left !== right) {
|
|
431
|
-
return false;
|
|
432
|
-
}
|
|
433
|
-
const h1ExpT1 = bigint_mod_arith_1.modPow(ntilde.h1, proof.t1, ntilde.ntilde);
|
|
434
|
-
const h2ExpT2 = bigint_mod_arith_1.modPow(ntilde.h2, proof.t2, ntilde.ntilde);
|
|
435
|
-
left = (h1ExpT1 * h2ExpT2) % ntilde.ntilde;
|
|
436
|
-
const tExpE = bigint_mod_arith_1.modPow(proof.t, e, ntilde.ntilde);
|
|
437
|
-
right = (tExpE * proof.w) % ntilde.ntilde;
|
|
438
|
-
if (left !== right) {
|
|
439
|
-
return false;
|
|
440
|
-
}
|
|
441
|
-
const c1ExpS1 = bigint_mod_arith_1.modPow(c1, proof.s1, pk._n2);
|
|
442
|
-
const sExpN = bigint_mod_arith_1.modPow(proof.s, pk.n, pk._n2);
|
|
443
|
-
const gammaExpT1 = bigint_mod_arith_1.modPow(pk.g, proof.t1, pk._n2);
|
|
444
|
-
left = (((c1ExpS1 * sExpN) % pk._n2) * gammaExpT1) % pk._n2;
|
|
445
|
-
const c2ExpE = bigint_mod_arith_1.modPow(c2, e, pk._n2);
|
|
446
|
-
right = (c2ExpE * proof.v) % pk._n2;
|
|
447
|
-
return left === right;
|
|
448
|
-
}
|
|
449
|
-
exports.verifyWithCheck = verifyWithCheck;
|
|
450
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZ2Vwcm9vZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90c3MvZWNkc2EvcmFuZ2Vwcm9vZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7O0dBR0c7QUFDSCxtQ0FBaUQ7QUFHakQsNkRBQTZEO0FBQzdELHVEQUFrRDtBQVNsRCxxQ0FBMkY7QUFDM0YsMkNBQXdDO0FBQ3hDLG1DQUE4QztBQUU5QywyRkFBMkY7QUFDM0YsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDO0FBRWhCLEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxVQUFvQjtJQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLGlCQUFPLEVBQUUsQ0FBQztJQUM5QixNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixNQUFNLFFBQVEsR0FBc0IsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQWlCLEVBQUUsRUFBRTtRQUN2RSxPQUFPLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFQRCxnREFPQztBQUVELEtBQUssVUFBVSxlQUFlLENBQUMsU0FBUyxHQUFHLDJCQUFtQixFQUFFLEtBQUssR0FBRyxFQUFFO0lBQ3hFLElBQUksU0FBUyxHQUFHLDJCQUFtQixFQUFFO1FBQ25DLGtDQUFrQztRQUNsQyxzQ0FBc0M7UUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyw4REFBOEQsQ0FBQyxDQUFDO0tBQzlFO0lBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDN0MsTUFBTSxVQUFVLEdBQUcsU0FBUyxHQUFHLFVBQVUsQ0FBQztJQUMxQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQzlCLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEIsd0dBQXdHO1FBQ3hHLElBQUksK0JBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLEVBQUU7WUFDOUIsU0FBUztTQUNWO1FBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNoRjtJQUNELE1BQU0sSUFBSSxLQUFLLENBQ2IsaURBQWlELFNBQVMsVUFBVSxLQUFLLDREQUE0RCxDQUN0SSxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0ksS0FBSyxVQUFVLGNBQWMsQ0FBQyxTQUFTLEdBQUcsMkJBQW1CO0lBQ2xFLE1BQU0sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxNQUFNLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvRCxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLDhCQUF1QixDQUFDLE1BQU0sQ0FBQyxFQUFFLDhCQUF1QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RyxNQUFNLEVBQUUsR0FBRyx5QkFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekMsTUFBTSxFQUFFLEdBQUcseUJBQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sSUFBSSxHQUFHLHlCQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNqQyxNQUFNLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN2RCxtQkFBbUIsQ0FDakI7WUFDRSxFQUFFLEVBQUUsRUFBRTtZQUNOLEVBQUUsRUFBRSxFQUFFO1lBQ04sTUFBTSxFQUFFLE1BQU07U0FDZixFQUNELEVBQUUsRUFDRixFQUFFLEVBQ0YsRUFBRSxDQUNIO1FBQ0QsbUJBQW1CLENBQ2pCO1lBQ0UsRUFBRSxFQUFFLEVBQUU7WUFDTixFQUFFLEVBQUUsRUFBRTtZQUNOLE1BQU0sRUFBRSxNQUFNO1NBQ2YsRUFDRCxJQUFJLEVBQ0osRUFBRSxFQUNGLEVBQUUsQ0FDSDtLQUNGLENBQUMsQ0FBQztJQUNILE9BQU87UUFDTCxNQUFNO1FBQ04sRUFBRTtRQUNGLEVBQUU7UUFDRixXQUFXLEVBQUU7WUFDWCxPQUFPLEVBQUU7Z0JBQ1AsS0FBSyxFQUFFLGFBQWEsQ0FBQyxLQUFLO2dCQUMxQixDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7YUFDbkI7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsS0FBSyxFQUFFLGFBQWEsQ0FBQyxLQUFLO2dCQUMxQixDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7YUFDbkI7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBM0NELHdDQTJDQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0ksS0FBSyxVQUFVLG1CQUFtQixDQUN2QyxNQUEwQixFQUMxQixDQUFTLEVBQ1QsRUFBVSxFQUNWLEVBQVU7SUFFVixNQUFNLE9BQU8sR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLE1BQU0sQ0FBQyxHQUFhLEVBQUUsQ0FBQztJQUN2QixNQUFNLEtBQUssR0FBYSxFQUFFLENBQUM7SUFDM0IsSUFBSSxTQUFTLEdBQVcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNwQyx1QkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzNCLHVCQUFnQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDM0IsdUJBQWdCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztLQUNoQyxDQUFDLENBQUM7SUFDSCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ25DLENBQUMsQ0FBQyxJQUFJLENBQUMsaUNBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUMseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNuRCxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSx1QkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQywrQkFBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM3RztJQUNELE1BQU0saUJBQWlCLEdBQUcsbUJBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDMUUsTUFBTSxDQUFDLEdBQWEsRUFBRSxDQUFDO0lBQ3ZCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDbkMsMENBQTBDO1FBQzFDLE1BQU0sTUFBTSxHQUFHLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0tBQzdEO0lBQ0QsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUN0QixDQUFDO0FBM0JELGtEQTJCQztBQUVEOzs7OztHQUtHO0FBQ0ksS0FBSyxVQUFVLGlCQUFpQixDQUNyQyxNQUEwQixFQUMxQixXQUFvQztJQUVwQyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDOUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzlDLElBQUksV0FBVyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxXQUFXLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQzFELE9BQU8sS0FBSyxDQUFDO0tBQ2Q7SUFDRCxJQUFJLFdBQVcsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksV0FBVyxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRTtRQUMxRCxPQUFPLEtBQUssQ0FBQztLQUNkO0lBQ0QsSUFBSSxXQUFXLEtBQUssV0FBVyxFQUFFO1FBQy9CLE9BQU8sS0FBSyxDQUFDO0tBQ2Q7SUFDRCxJQUNFLFdBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUc7UUFDOUIsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLEtBQUssVUFBVTtRQUN2QyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQ25DO1FBQ0EsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUNELElBQUksU0FBUyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDcEMsdUJBQWdCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUMzQix1QkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzNCLHVCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7S0FDaEMsQ0FBQyxDQUFDO0lBQ0gsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2pELFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ3hCLFNBQVM7WUFDVCx1QkFBZ0IsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsK0JBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDaEYsQ0FBQyxDQUFDO0tBQ0o7SUFDRCxNQUFNLGlCQUFpQixHQUFHLG1CQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQzFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNqRCwwQ0FBMEM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0UsTUFBTSxPQUFPLEdBQUcseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25FLE1BQU0sT0FBTyxHQUFHLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pFLE1BQU0sZUFBZSxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ3pFLElBQUksT0FBTyxLQUFLLGVBQWUsRUFBRTtZQUMvQixPQUFPLEtBQUssQ0FBQztTQUNkO0tBQ0Y7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUE3Q0QsOENBNkNDO0FBRUQsU0FBUyxtQkFBbUIsQ0FDMUIsS0FBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsRUFBYSxFQUNiLENBQVMsRUFDVCxDQUFTLEVBQ1QsQ0FBUyxFQUNULENBQVM7SUFFVCxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDeEIsTUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7SUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUMvQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUMvQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRWpCLElBQUksS0FBYSxFQUFFLENBQVMsQ0FBQztJQUM3QixHQUFHO1FBQ0QsS0FBSyxHQUFHLG9CQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDeEIsQ0FBQyxHQUFHLHlCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztLQUM1RCxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7SUFFakIsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUN0QixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNJLEtBQUssVUFBVSxLQUFLLENBQ3pCLEtBQWdCLEVBQ2hCLFdBQW1CLEVBQ25CLEVBQWEsRUFDYixNQUEwQixFQUMxQixDQUFTLEVBQ1QsQ0FBUyxFQUNULENBQVM7SUFFVCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixNQUFNLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2xDLE1BQU0sUUFBUSxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3BDLE1BQU0sS0FBSyxHQUFHLGlDQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUIsTUFBTSxJQUFJLEdBQUcsTUFBTSw4QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsTUFBTSxLQUFLLEdBQUcsaUNBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwQyxNQUFNLEdBQUcsR0FBRyxpQ0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sQ0FBQyxHQUFHLENBQUMseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3hHLE1BQU0sQ0FBQyxHQUFHLENBQUMseUJBQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcseUJBQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDO0lBQzlFLE1BQU0sQ0FBQyxHQUFHLENBQUMseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcseUJBQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzlHLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDOUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyx5QkFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0MsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDekIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUM7SUFDM0IsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUExQkQsc0JBMEJDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBZ0IsTUFBTSxDQUNwQixLQUFnQixFQUNoQixXQUFtQixFQUNuQixFQUFhLEVBQ2IsTUFBMEIsRUFDMUIsS0FBaUIsRUFDakIsQ0FBUztJQUVULElBQUksS0FBSyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDbEQsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUNELE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdkQsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLE1BQU0sRUFBRSxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsSUFBSSxLQUFLLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUNqQixPQUFPLEtBQUssQ0FBQztLQUNkO0lBQ0QsTUFBTSxJQUFJLEdBQUcsbUJBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsQyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUU7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7S0FDakQ7U0FBTTtRQUNMLElBQUksQ0FBQyxNQUFNLENBQUMsa0NBQWtDLENBQUMsQ0FBQztLQUNqRDtJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ2xELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3JELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQVMsQ0FBQztJQUNkLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRTtRQUNmLENBQUMsR0FBRyx5QkFBa0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNWLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7S0FDRjtTQUFNO1FBQ0wsQ0FBQyxHQUFHLHlCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUMzQztJQUNELElBQUksUUFBZ0IsQ0FBQztJQUNyQixRQUFRLEdBQUcsQ0FBQyx5QkFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcseUJBQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLHlCQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUM7SUFDN0csSUFBSSxLQUFLLENBQUMsQ0FBQyxLQUFLLFFBQVEsRUFBRTtRQUN4QixPQUFPLEtBQUssQ0FBQztLQUNkO0lBQ0QsUUFBUTtRQUNOLENBQUMsQ0FBQyxDQUFDLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyx5QkFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQzFHLHlCQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNoQixPQUFPLEtBQUssQ0FBQyxDQUFDLEtBQUssUUFBUSxDQUFDO0FBQzlCLENBQUM7QUF0REQsd0JBc0RDO0FBRUQsU0FBUyw0QkFBNEIsQ0FDbkMsS0FBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsRUFBYSxFQUNiLENBQVMsRUFDVCxFQUFVLEVBQ1YsRUFBVSxFQUNWLENBQVMsRUFDVCxDQUFTLEVBQ1QsSUFBWSxFQUNaLENBQVMsRUFDVCxDQUFTLEVBQ1QsQ0FBUztJQUVULE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixNQUFNLElBQUksR0FBRyxtQkFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsa0NBQWtDLENBQUMsQ0FBQztJQUNoRCxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ2xELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNyQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3BELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUMvQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQWdCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQy9DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDbkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUFnQixDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQy9DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFakIsSUFBSSxLQUFhLEVBQUUsQ0FBUyxDQUFDO0lBQzdCLEdBQUc7UUFDRCxLQUFLLEdBQUcsb0JBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN4QixDQUFDLEdBQUcseUJBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0tBQzVELFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtJQUVqQixPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ3RCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0ksS0FBSyxVQUFVLGNBQWMsQ0FDbEMsS0FBZ0IsRUFDaEIsV0FBbUIsRUFDbkIsRUFBYSxFQUNiLE1BQTBCLEVBQzFCLEVBQVUsRUFDVixFQUFVLEVBQ1YsQ0FBUyxFQUNULENBQVMsRUFDVCxDQUFTLEVBQ1QsQ0FBUztJQUVULE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdkQsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLE1BQU0sRUFBRSxHQUFHLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQixNQUFNLE9BQU8sR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxNQUFNLFFBQVEsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNwQyxNQUFNLEtBQUssR0FBRyxpQ0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzlCLE1BQU0sR0FBRyxHQUFHLGlDQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsTUFBTSxLQUFLLEdBQUcsaUNBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQyxNQUFNLEdBQUcsR0FBRyxpQ0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sTUFBTSxHQUFHLGlDQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDckMsTUFBTSxJQUFJLEdBQUcsTUFBTSw4QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsTUFBTSxLQUFLLEdBQUcsaUNBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUM5QixNQUFNLENBQUMsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN6RCxNQUFNLENBQUMsR0FBRyxDQUFDLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN4RyxNQUFNLElBQUksR0FBRyxDQUFDLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNsSCxNQUFNLENBQUMsR0FBRyxDQUFDLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLHlCQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUMxRyxNQUFNLENBQUMsR0FDTCxDQUFDLENBQUMsQ0FBQyx5QkFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLHlCQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLHlCQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUMvRyxNQUFNLENBQUMsR0FBRyxD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QUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QyxNQUFNLFVBQVUsR0FBRyx5QkFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbEQsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUM1RCxNQUFNLE1BQU0sR0FBRyx5QkFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3JDLEtBQUssR0FBRyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUNwQyxPQUFPLElBQUksS0FBSyxLQUFLLENBQUM7QUFDeEIsQ0FBQztBQXRGRCwwQ0FzRkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFplcm8gS25vd2xlZGdlIFJhbmdlIFByb29mcyBhcyBkZXNjcmliZWQgaW4gKFR3by1wYXJ0eSBnZW5lcmF0aW9uIG9mIERTQSBzaWduYXR1cmVzKVsxXS5cbiAqIFsxXTogaHR0cHM6Ly9yZWl0ZXJtay5naXRodWIuaW8vcGFwZXJzLzIwMDQvSUpJUy5wZGZcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgQmFzZUN1cnZlIH0gZnJvbSAnLi4vLi4vY3VydmVzJztcbmltcG9ydCB7IFB1YmxpY0tleSB9IGZyb20gJ3BhaWxsaWVyLWJpZ2ludCc7XG5pbXBvcnQgeyBiaXRMZW5ndGgsIHJhbmRCZXR3ZWVuIH0gZnJvbSAnYmlnaW50LWNyeXB0by11dGlscyc7XG5pbXBvcnQgeyBtb2RJbnYsIG1vZFBvdyB9IGZyb20gJ2JpZ2ludC1tb2QtYXJpdGgnO1xuaW1wb3J0IHtcbiAgRGVzZXJpYWxpemVkTnRpbGRlLFxuICBEZXNlcmlhbGl6ZWROdGlsZGVQcm9vZixcbiAgUlNBTW9kdWx1cyxcbiAgUmFuZ2VQcm9vZixcbiAgUmFuZ2VQcm9vZldpdGhDaGVjayxcbiAgRGVzZXJpYWxpemVkTnRpbGRlV2l0aFByb29mcyxcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBiaWdJbnRGcm9tQnVmZmVyQkUsIGJpZ0ludFRvQnVmZmVyQkUsIHJhbmRvbVBvc2l0aXZlQ29QcmltZVRvIH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQgeyBPcGVuU1NMIH0gZnJvbSAnLi4vLi4vb3BlbnNzbCc7XG5pbXBvcnQgeyBtaW5Nb2R1bHVzQml0TGVuZ3RoIH0gZnJvbSAnLi9pbmRleCc7XG5cbi8vIDEyOCBhcyByZWNvbW1lbmQgYnkgaHR0cHM6Ly9ibG9nLnZlcmljaGFpbnMuaW8vcC92c2EtMjAyMi0xMjAtbXVsdGljaGFpbi1rZXktZXh0cmFjdGlvbi5cbmNvbnN0IElURVJBVElPTlMgPSAxMjg7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVNhZmVQcmltZXMoYml0TGVuZ3RoczogbnVtYmVyW10pOiBQcm9taXNlPGJpZ2ludFtdPiB7XG4gIGNvbnN0IG9wZW5TU0wgPSBuZXcgT3BlblNTTCgpO1xuICBhd2FpdCBvcGVuU1NMLmluaXQoKTtcbiAgY29uc3QgcHJvbWlzZXM6IFByb21pc2U8YmlnaW50PltdID0gYml0TGVuZ3Rocy5tYXAoKGJpdGxlbmd0aDogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIG9wZW5TU0wuZ2VuZXJhdGVTYWZlUHJpbWUoYml0bGVuZ3RoKTtcbiAgfSk7XG4gIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTW9kdWx1cyhiaXRsZW5ndGggPSBtaW5Nb2R1bHVzQml0TGVuZ3RoLCByZXRyeSA9IDEwKTogUHJvbWlzZTxSU0FNb2R1bHVzPiB7XG4gIGlmIChiaXRsZW5ndGggPCBtaW5Nb2R1bHVzQml0TGVuZ3RoKSB7XG4gICAgLy8gaHR0cHM6Ly93d3cua2V5bGVuZ3RoLmNvbS9lbi82L1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS53YXJuKCdHZW5lcmF0aW5nIGEgbW9kdWx1cyB3aXRoIGxlc3MgdGhhbiAzMDcyIGlzIG5vdCByZWNvbW1lbmRlZCEnKTtcbiAgfVxuICBjb25zdCBiaXRsZW5ndGhQID0gTWF0aC5mbG9vcihiaXRsZW5ndGggLyAyKTtcbiAgY29uc3QgYml0bGVuZ3RoUSA9IGJpdGxlbmd0aCAtIGJpdGxlbmd0aFA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmV0cnk7IGkrKykge1xuICAgIGNvbnN0IFtwLCBxXSA9IGF3YWl0IGdlbmVyYXRlU2FmZVByaW1lcyhbYml0bGVuZ3RoUCwgYml0bGVuZ3RoUV0pO1xuICAgIGNvbnN0IG4gPSBwICogcTtcbiAgICAvLyBGb3IgbGFyZ2UgYml0IGxlbmd0aHMsIHRoZSBwcm9iYWJpbGl0eSBvZiBnZW5lcmF0aW5nIGEgbW9kdWx1cyB3aXRoIHRoZSB3cm9uZyBiaXQgbGVuZ3RoIGlzIHZlcnkgbG93LlxuICAgIGlmIChiaXRMZW5ndGgobikgIT09IGJpdGxlbmd0aCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHJldHVybiB7IG4sIHExOiAocCAtIEJpZ0ludCgxKSkgLyBCaWdJbnQoMiksIHEyOiAocSAtIEJpZ0ludCgxKSkgLyBCaWdJbnQoMikgfTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYFVuYWJsZSB0byBnZW5lcmF0ZSBtb2R1bHVzIHdpdGggYml0IGxlbmd0aCBvZiAke2JpdGxlbmd0aH0gYWZ0ZXIgJHtyZXRyeX0gdHJpZXMuIFBsZWFzZSB0cnkgYWdhaW4gb3IgcmVhY2ggb3V0IHRvIHN1cHBvcnRAYml0Z28uY29tYFxuICApO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIFwiY2hhbGxlbmdlXCIgdmFsdWVzIGZvciByYW5nZSBwcm9vZnMuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bGVuZ3RoIFRoZSBiaXQgbGVuZ3RoIG9mIHRoZSBtb2R1bHVzIHRvIGdlbmVyYXRlLiBUaGlzIHNob3VsZFxuICogYmUgdGhlIHNhbWUgYXMgdGhlIGJpdCBsZW5ndGggb2YgdGhlIHBhaWxsaWVyIHB1YmxpYyBrZXlzIHVzZWQgZm9yIE10QS5cbiAqIEByZXR1cm5zIHtEZXNlcmlhbGl6ZWROdGlsZGV9IFRoZSBnZW5lcmF0ZWQgTnRpbGRlIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTnRpbGRlKGJpdGxlbmd0aCA9IG1pbk1vZHVsdXNCaXRMZW5ndGgpOiBQcm9taXNlPERlc2VyaWFsaXplZE50aWxkZVdpdGhQcm9vZnM+IHtcbiAgY29uc3QgeyBuOiBudGlsZGUsIHExLCBxMiB9ID0gYXdhaXQgZ2VuZXJhdGVNb2R1bHVzKGJpdGxlbmd0aCk7XG4gIGNvbnN0IFtmMSwgZjJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW3JhbmRvbVBvc2l0aXZlQ29QcmltZVRvKG50aWxkZSksIHJhbmRvbVBvc2l0aXZlQ29QcmltZVRvKG50aWxkZSldKTtcbiAgY29uc3QgaDEgPSBtb2RQb3coZjEsIEJpZ0ludCgyKSwgbnRpbGRlKTtcbiAgY29uc3QgaDIgPSBtb2RQb3coaDEsIGYyLCBudGlsZGUpO1xuICBjb25zdCBiZXRhID0gbW9kSW52KGYyLCBxMSAqIHEyKTtcbiAgY29uc3QgW2gxd3J0SDJQcm9vZnMsIGgyd3J0SDFQcm9vZnNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgIGdlbmVyYXRlTnRpbGRlUHJvb2YoXG4gICAgICB7XG4gICAgICAgIGgxOiBoMSxcbiAgICAgICAgaDI6IGgyLFxuICAgICAgICBudGlsZGU6IG50aWxkZSxcbiAgICAgIH0sXG4gICAgICBmMixcbiAgICAgIHExLFxuICAgICAgcTJcbiAgICApLFxuICAgIGdlbmVyYXRlTnRpbGRlUHJvb2YoXG4gICAgICB7XG4gICAgICAgIGgxOiBoMixcbiAgICAgICAgaDI6IGgxLFxuICAgICAgICBudGlsZGU6IG50aWxkZSxcbiAgICAgIH0sXG4gICAgICBiZXRhLFxuICAgICAgcTEsXG4gICAgICBxMlxuICAgICksXG4gIF0pO1xuICByZXR1cm4ge1xuICAgIG50aWxkZSxcbiAgICBoMSxcbiAgICBoMixcbiAgICBudGlsZGVQcm9vZjoge1xuICAgICAgaDFXcnRIMjoge1xuICAgICAgICBhbHBoYTogaDF3cnRIMlByb29mcy5hbHBoYSxcbiAgICAgICAgdDogaDF3cnRIMlByb29mcy50LFxuICAgICAgfSxcbiAgICAgIGgyV3J0SDE6IHtcbiAgICAgICAgYWxwaGE6IGgyd3J0SDFQcm9vZnMuYWxwaGEsXG4gICAgICAgIHQ6IGgyd3J0SDFQcm9vZnMudCxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBpdGVyYXRpb25zIG9mIE50aWxkZSwgaDEsIGgyIGRpc2NyZXRlIGxvZyBwcm9vZnMuXG4gKiBAcGFyYW0ge0Rlc2VyaWFsaXplZE50aWxkZX0gbnRpbGRlIE50aWxkZSwgaDEsIGgyIHRvIGdlbmVyYXRlIHRoZSBwcm9vZnMgZm9yLlxuICogQHBhcmFtIHtiaWdpbnR9IHggRWl0aGVyIGFscGhhIG9yIGJldGEgZGVwZW5kaW5nIG9uIHdoZXRoZXIgaXQgaXMgYSBkaXNjcmV0ZSBsb2cgcHJvb2Ygb2ZcbiAqIGgxIHcuci50IGgyIG9yIGgyIHcuci50IGgxLlxuICogQHBhcmFtIHtiaWdpbnR9IHExIFRoZSBTb3BoaWUgR2VybWFpbiBwcmltZSBhc3NvY2lhdGVkIHdpdGggdGhlIGZpcnN0IHNhZmUgcHJpbWUgcDEgdXNlZCB0byBnZW5lcmF0ZSBOdGlsZGUuXG4gKiBAcGFyYW0ge2JpZ2ludH0gcTIgVGhlIFNvcGhpZSBHZXJtYWluIHByaW1lIGFzc29jaWF0ZWQgd2l0aCB0aGUgc2Vjb25kIHNhZmUgcHJpbWUgcDIgdXNlZCB0byBnZW5lcmF0ZSBOdGlsZGUuXG4gKiBAcmV0dXJucyB7TnRpbGRlUHJvb2Z9IFRoZSBnZW5lcmF0ZWQgTnRpbGRlIFByb29mcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTnRpbGRlUHJvb2YoXG4gIG50aWxkZTogRGVzZXJpYWxpemVkTnRpbGRlLFxuICB4OiBiaWdpbnQsXG4gIHExOiBiaWdpbnQsXG4gIHEyOiBiaWdpbnRcbik6IFByb21pc2U8RGVzZXJpYWxpemVkTnRpbGRlUHJvb2Y+IHtcbiAgY29uc3QgcTFNdWxRMiA9IHExICogcTI7XG4gIGNvbnN0IGE6IGJpZ2ludFtdID0gW107XG4gIGNvbnN0IGFscGhhOiBiaWdpbnRbXSA9IFtdO1xuICBsZXQgbXNnVG9IYXNoOiBCdWZmZXIgPSBCdWZmZXIuY29uY2F0KFtcbiAgICBiaWdJbnRUb0J1ZmZlckJFKG50aWxkZS5oMSksXG4gICAgYmlnSW50VG9CdWZmZXJCRShudGlsZGUuaDIpLFxuICAgIGJpZ0ludFRvQnVmZmVyQkUobnRpbGRlLm50aWxkZSksXG4gIF0pO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IElURVJBVElPTlM7IGkrKykge1xuICAgIGEucHVzaChyYW5kQmV0d2VlbihxMU11bFEyKSk7XG4gICAgYWxwaGEucHVzaChtb2RQb3cobnRpbGRlLmgxLCBhW2ldLCBudGlsZGUubnRpbGRlKSk7XG4gICAgbXNnVG9IYXNoID0gQnVmZmVyLmNvbmNhdChbbXNnVG9IYXNoLCBiaWdJbnRUb0J1ZmZlckJFKGFscGhhW2ldLCBNYXRoLmNlaWwoYml0TGVuZ3RoKG50aWxkZS5udGlsZGUpIC8gOCkpXSk7XG4gIH1cbiAgY29uc3Qgc2ltdWxhdGVkUmVzcG9uc2UgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUobXNnVG9IYXNoKS5kaWdlc3QoKTtcbiAgY29uc3QgdDogYmlnaW50W10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBJVEVSQVRJT05TOyBpKyspIHtcbiAgICAvLyBHZXQgdGhlIGl0aCBiaXQgZnJvbSBhIGJ1ZmZlciBvZiBieXRlcy5cbiAgICBjb25zdCBpdGhCaXQgPSAoc2ltdWxhdGVkUmVzcG9uc2VbTWF0aC5mbG9vcihpIC8gOCldID4+ICg3IC0gKGkgJSA4KSkpICYgMTtcbiAgICB0LnB1c2goKGFbaV0gKyAoKEJpZ0ludChpdGhCaXQpICogeCkgJSBxMU11bFEyKSkgJSBxMU11bFEyKTtcbiAgfVxuICByZXR1cm4geyBhbHBoYSwgdCB9O1xufVxuXG4vKipcbiAqIFZlcmlmeSBkaXNjcmV0ZSBsb2cgcHJvb2ZzIG9mIGgxIGFuZCBoMiBtb2QgTnRpbGRlLlxuICogQHBhcmFtIHtEZXNlcmlhbGl6ZWROdGlsZGV9IG50aWxkZSBOdGlsZGUsIGgxLCBoMiB0byBnZW5lcmF0ZSB0aGUgcHJvb2ZzIGZvci5cbiAqIEBwYXJhbSB7RGVzZXJpYWxpemVkTnRpbGRlUHJvb2Z9IG50aWxkZVByb29mIE50aWxkZSBQcm9vZnNcbiAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHByb29mIGlzIHZlcmlmaWVkLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2ZXJpZnlOdGlsZGVQcm9vZihcbiAgbnRpbGRlOiBEZXNlcmlhbGl6ZWROdGlsZGUsXG4gIG50aWxkZVByb29mOiBEZXNlcmlhbGl6ZWROdGlsZGVQcm9vZlxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGgxTW9kTnRpbGRlID0gbnRpbGRlLmgxICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgaDJNb2ROdGlsZGUgPSBudGlsZGUuaDIgJSBudGlsZGUubnRpbGRlO1xuICBpZiAoaDFNb2ROdGlsZGUgPT09IEJpZ0ludCgwKSB8fCBoMk1vZE50aWxkZSA9PT0gQmlnSW50KDApKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChoMU1vZE50aWxkZSA9PT0gQmlnSW50KDEpIHx8IGgyTW9kTnRpbGRlID09PSBCaWdJbnQoMSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGgxTW9kTnRpbGRlID09PSBoMk1vZE50aWxkZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoXG4gICAgbnRpbGRlUHJvb2YuYWxwaGEubGVuZ3RoID4gMjU2IHx8XG4gICAgbnRpbGRlUHJvb2YuYWxwaGEubGVuZ3RoICE9PSBJVEVSQVRJT05TIHx8XG4gICAgbnRpbGRlUHJvb2YudC5sZW5ndGggIT09IElURVJBVElPTlNcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGxldCBtc2dUb0hhc2g6IEJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW1xuICAgIGJpZ0ludFRvQnVmZmVyQkUobnRpbGRlLmgxKSxcbiAgICBiaWdJbnRUb0J1ZmZlckJFKG50aWxkZS5oMiksXG4gICAgYmlnSW50VG9CdWZmZXJCRShudGlsZGUubnRpbGRlKSxcbiAgXSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnRpbGRlUHJvb2YuYWxwaGEubGVuZ3RoOyBpKyspIHtcbiAgICBtc2dUb0hhc2ggPSBCdWZmZXIuY29uY2F0KFtcbiAgICAgIG1zZ1RvSGFzaCxcbiAgICAgIGJpZ0ludFRvQnVmZmVyQkUobnRpbGRlUHJvb2YuYWxwaGFbaV0sIE1hdGguY2VpbChiaXRMZW5ndGgobnRpbGRlLm50aWxkZSkgLyA4KSksXG4gICAgXSk7XG4gIH1cbiAgY29uc3Qgc2ltdWxhdGVkUmVzcG9uc2UgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUobXNnVG9IYXNoKS5kaWdlc3QoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudGlsZGVQcm9vZi5hbHBoYS5sZW5ndGg7IGkrKykge1xuICAgIC8vIEdldCB0aGUgaXRoIGJpdCBmcm9tIGEgYnVmZmVyIG9mIGJ5dGVzLlxuICAgIGNvbnN0IGl0aEJpdCA9IChzaW11bGF0ZWRSZXNwb25zZVtNYXRoLmZsb29yKGkgLyA4KV0gPj4gKDcgLSAoaSAlIDgpKSkgJiAxO1xuICAgIGNvbnN0IGgxUG93VGkgPSBtb2RQb3cobnRpbGRlLmgxLCBudGlsZGVQcm9vZi50W2ldLCBudGlsZGUubnRpbGRlKTtcbiAgICBjb25zdCBoMlBvd0NpID0gbW9kUG93KG50aWxkZS5oMiwgQmlnSW50KGl0aEJpdCksIG50aWxkZS5udGlsZGUpO1xuICAgIGNvbnN0IGFscGhhTXVsaDJQb3dDaSA9IChudGlsZGVQcm9vZi5hbHBoYVtpXSAqIGgyUG93Q2kpICUgbnRpbGRlLm50aWxkZTtcbiAgICBpZiAoaDFQb3dUaSAhPT0gYWxwaGFNdWxoMlBvd0NpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByYW5nZVByb29mQ2hhbGxlbmdlKFxuICBjdXJ2ZTogQmFzZUN1cnZlLFxuICBtb2R1bHVzQnl0ZXM6IG51bWJlcixcbiAgcGs6IFB1YmxpY0tleSxcbiAgYzogYmlnaW50LFxuICB6OiBiaWdpbnQsXG4gIHU6IGJpZ2ludCxcbiAgdzogYmlnaW50XG4pOiB7IG5vbmNlOiBCdWZmZXI7IGU6IGJpZ2ludCB9IHtcbiAgY29uc3QgcSA9IGN1cnZlLm9yZGVyKCk7XG4gIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKTtcbiAgaGFzaC51cGRhdGUoJ1xceDA3XFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDAnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5uLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5nLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShjLCAyICogbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUoeiwgbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUodSwgMiAqIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHcsIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuXG4gIGxldCBub25jZTogQnVmZmVyLCBlOiBiaWdpbnQ7XG4gIGRvIHtcbiAgICBub25jZSA9IHJhbmRvbUJ5dGVzKDMyKTtcbiAgICBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGhhc2guY29weSgpLnVwZGF0ZShub25jZSkuZGlnZXN0KCkpO1xuICB9IHdoaWxlIChlID49IHEpO1xuXG4gIHJldHVybiB7IG5vbmNlLCBlIH07XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSB6ZXJvLWtub3dsZWRnZSByYW5nZSBwcm9vZiB0aGF0IGFuIGVuY3J5cHRlZCB2YWx1ZSBpcyBcInNtYWxsXCIuXG4gKiBAcGFyYW0ge0Jhc2VDdXJ2ZX0gY3VydmUgQW4gZWxsaXB0aWMgY3VydmUgdG8gdXNlIGZvciBncm91cCBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtudW1iZXJ9IG1vZHVsdXNCaXRzIFRoZSBiaXQgY291bnQgb2YgdGhlIHByb3ZlcidzIHB1YmxpYyBrZXkuXG4gKiBAcGFyYW0ge1B1YmxpY0tleX0gcGsgVGhlIHByb3ZlcidzIHB1YmxpYyBrZXkuXG4gKiBAcGFyYW0ge0Rlc2VyaWFsaXplZE50aWxkZX0gbnRpbGRlIFRoZSB2ZXJpZmllcidzIE50aWxkZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge2JpZ2ludH0gYyBUaGUgY2lwaGVydGV4dC5cbiAqIEBwYXJhbSB7YmlnaW50fSBtIFRoZSBwbGFpbnRleHQuXG4gKiBAcGFyYW0ge2JpZ2ludH0gciBUaGUgb2JmdXNjYXRpb24gdmFsdWUgdXNlZCB0byBlbmNyeXB0IG0uXG4gKiBAcmV0dXJucyB7UmFuZ2VQcm9vZn0gVGhlIGdlbmVyYXRlZCBwcm9vZi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb3ZlKFxuICBjdXJ2ZTogQmFzZUN1cnZlLFxuICBtb2R1bHVzQml0czogbnVtYmVyLFxuICBwazogUHVibGljS2V5LFxuICBudGlsZGU6IERlc2VyaWFsaXplZE50aWxkZSxcbiAgYzogYmlnaW50LFxuICBtOiBiaWdpbnQsXG4gIHI6IGJpZ2ludFxuKTogUHJvbWlzZTxSYW5nZVByb29mPiB7XG4gIGNvbnN0IG1vZHVsdXNCeXRlcyA9IE1hdGguZmxvb3IoKG1vZHVsdXNCaXRzICsgNykgLyA4KTtcbiAgY29uc3QgcSA9IGN1cnZlLm9yZGVyKCk7XG4gIGNvbnN0IHEzID0gcSAqKiBCaWdJbnQoMyk7XG4gIGNvbnN0IHFudGlsZGUgPSBxICogbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgcTNudGlsZGUgPSBxMyAqIG50aWxkZS5udGlsZGU7XG4gIGNvbnN0IGFscGhhID0gcmFuZEJldHdlZW4ocTMpO1xuICBjb25zdCBiZXRhID0gYXdhaXQgcmFuZG9tUG9zaXRpdmVDb1ByaW1lVG8ocGsubik7XG4gIGNvbnN0IGdhbW1hID0gcmFuZEJldHdlZW4ocTNudGlsZGUpO1xuICBjb25zdCByaG8gPSByYW5kQmV0d2VlbihxbnRpbGRlKTtcbiAgY29uc3QgeiA9IChtb2RQb3cobnRpbGRlLmgxLCBtLCBudGlsZGUubnRpbGRlKSAqIG1vZFBvdyhudGlsZGUuaDIsIHJobywgbnRpbGRlLm50aWxkZSkpICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgdSA9IChtb2RQb3cocGsuZywgYWxwaGEsIHBrLl9uMikgKiBtb2RQb3coYmV0YSwgcGsubiwgcGsuX24yKSkgJSBway5fbjI7XG4gIGNvbnN0IHcgPSAobW9kUG93KG50aWxkZS5oMSwgYWxwaGEsIG50aWxkZS5udGlsZGUpICogbW9kUG93KG50aWxkZS5oMiwgZ2FtbWEsIG50aWxkZS5udGlsZGUpKSAlIG50aWxkZS5udGlsZGU7XG4gIGNvbnN0IHsgbm9uY2UsIGUgfSA9IHJhbmdlUHJvb2ZDaGFsbGVuZ2UoY3VydmUsIG1vZHVsdXNCeXRlcywgcGssIGMsIHosIHUsIHcpO1xuICBjb25zdCBzID0gKG1vZFBvdyhyLCBlLCBway5uKSAqIGJldGEpICUgcGsubjtcbiAgY29uc3QgczEgPSBlICogbSArIGFscGhhO1xuICBjb25zdCBzMiA9IGUgKiByaG8gKyBnYW1tYTtcbiAgcmV0dXJuIHsgeiwgdSwgdywgbm9uY2UsIHMsIHMxLCBzMiB9O1xufVxuXG4vKipcbiAqIFZlcmlmeSBhIHplcm8ta25vd2xlZGdlIHJhbmdlIHByb29mIHRoYXQgYW4gZW5jcnlwdGVkIHZhbHVlIGlzIFwic21hbGxcIi5cbiAqIEBwYXJhbSB7QmFzZUN1cnZlfSBjdXJ2ZSBBbiBlbGxpcHRpYyBjdXJ2ZSB0byB1c2UgZm9yIGdyb3VwIG9wZXJhdGlvbnMuXG4gKiBAcGFyYW0ge251bWJlcn0gbW9kdWx1c0JpdHMgVGhlIGJpdCBjb3VudCBvZiB0aGUgcHJvdmVyJ3MgcHVibGljIGtleS5cbiAqIEBwYXJhbSB7UHVibGljS2V5fSBwayBUaGUgcHJvdmVyJ3MgcHVibGljIGtleS5cbiAqIEBwYXJhbSB7RGVzZXJpYWxpemVkTnRpbGRlfSBudGlsZGUgVGhlIHZlcmlmaWVyJ3MgTnRpbGRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7UmFuZ2VQcm9vZn0gcHJvb2YgVGhlIHJhbmdlIHByb29mLlxuICogQHBhcmFtIHtiaWdpbnR9IGMgVGhlIGNpcGhlcnRleHQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2ZXJpZmljYXRpb24gc3VjY2VlZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnkoXG4gIGN1cnZlOiBCYXNlQ3VydmUsXG4gIG1vZHVsdXNCaXRzOiBudW1iZXIsXG4gIHBrOiBQdWJsaWNLZXksXG4gIG50aWxkZTogRGVzZXJpYWxpemVkTnRpbGRlLFxuICBwcm9vZjogUmFuZ2VQcm9vZixcbiAgYzogYmlnaW50XG4pOiBib29sZWFuIHtcbiAgaWYgKHByb29mLnUgPT09IEJpZ0ludCgwKSB8fCBwcm9vZi5zID09PSBCaWdJbnQoMCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgbW9kdWx1c0J5dGVzID0gTWF0aC5mbG9vcigobW9kdWx1c0JpdHMgKyA3KSAvIDgpO1xuICBjb25zdCBxID0gY3VydmUub3JkZXIoKTtcbiAgY29uc3QgcTMgPSBxICoqIEJpZ0ludCgzKTtcbiAgaWYgKHByb29mLnMxID4gcTMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgaGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpO1xuICBpZiAocHJvb2Yubm9uY2UpIHtcbiAgICBoYXNoLnVwZGF0ZSgnXFx4MDdcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMCcpO1xuICB9IGVsc2Uge1xuICAgIGhhc2gudXBkYXRlKCdcXHgwNlxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwJyk7XG4gIH1cbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5uLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5nLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShjLCAyICogbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YueiwgbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YudSwgMiAqIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHByb29mLncsIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBsZXQgZTogYmlnaW50O1xuICBpZiAocHJvb2Yubm9uY2UpIHtcbiAgICBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGhhc2gudXBkYXRlKHByb29mLm5vbmNlKS5kaWdlc3QoKSk7XG4gICAgaWYgKGUgPj0gcSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGhhc2guZGlnZXN0KCkpICUgcTtcbiAgfVxuICBsZXQgcHJvZHVjdHM6IGJpZ2ludDtcbiAgcHJvZHVjdHMgPSAobW9kUG93KHBrLmcsIHByb29mLnMxLCBway5fbjIpICogbW9kUG93KHByb29mLnMsIHBrLm4sIHBrLl9uMikgKiBtb2RQb3coYywgLWUsIHBrLl9uMikpICUgcGsuX24yO1xuICBpZiAocHJvb2YudSAhPT0gcHJvZHVjdHMpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcHJvZHVjdHMgPVxuICAgICgoKG1vZFBvdyhudGlsZGUuaDEsIHByb29mLnMxLCBudGlsZGUubnRpbGRlKSAqIG1vZFBvdyhudGlsZGUuaDIsIHByb29mLnMyLCBudGlsZGUubnRpbGRlKSkgJSBudGlsZGUubnRpbGRlKSAqXG4gICAgICBtb2RQb3cocHJvb2YueiwgLWUsIG50aWxkZS5udGlsZGUpKSAlXG4gICAgbnRpbGRlLm50aWxkZTtcbiAgcmV0dXJuIHByb29mLncgPT09IHByb2R1Y3RzO1xufVxuXG5mdW5jdGlvbiByYW5nZVByb29mV2l0aENoZWNrQ2hhbGxlbmdlKFxuICBjdXJ2ZTogQmFzZUN1cnZlLFxuICBtb2R1bHVzQnl0ZXM6IG51bWJlcixcbiAgcGs6IFB1YmxpY0tleSxcbiAgWDogYmlnaW50LFxuICBjMTogYmlnaW50LFxuICBjMjogYmlnaW50LFxuICB1OiBiaWdpbnQsXG4gIHo6IGJpZ2ludCxcbiAgenBybTogYmlnaW50LFxuICB0OiBiaWdpbnQsXG4gIHY6IGJpZ2ludCxcbiAgdzogYmlnaW50XG4pOiB7IG5vbmNlOiBCdWZmZXI7IGU6IGJpZ2ludCB9IHtcbiAgY29uc3QgcSA9IGN1cnZlLm9yZGVyKCk7XG4gIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKTtcbiAgaGFzaC51cGRhdGUoJ1xceDBlXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDAnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5uLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShway5nLCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShYLCAzMykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKGMxLCAyICogbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUoYzIsIDIgKiBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRSh1LCAzMykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHosIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHpwcm0sIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHQsIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHYsIDIgKiBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRSh3LCBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcblxuICBsZXQgbm9uY2U6IEJ1ZmZlciwgZTogYmlnaW50O1xuICBkbyB7XG4gICAgbm9uY2UgPSByYW5kb21CeXRlcygzMik7XG4gICAgZSA9IGJpZ0ludEZyb21CdWZmZXJCRShoYXNoLmNvcHkoKS51cGRhdGUobm9uY2UpLmRpZ2VzdCgpKTtcbiAgfSB3aGlsZSAoZSA+PSBxKTtcblxuICByZXR1cm4geyBub25jZSwgZSB9O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgemVyby1rbm93bGVkZ2UgcmFuZ2UgcHJvb2YgdGhhdCBhIGhvbW9tb3JwaGljYWxseSBtYW5pcHVsYXRlZCB2YWx1ZSBpcyBcInNtYWxsXCIuXG4gKiBAcGFyYW0ge0Jhc2VDdXJ2ZX0gY3VydmUgQW4gZWxsaXB0aWMgY3VydmUgdG8gdXNlIGZvciBncm91cCBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtudW1iZXJ9IG1vZHVsdXNCaXRzIFRoZSBiaXQgY291bnQgb2YgdGhlIHByb3ZlcidzIHB1YmxpYyBrZXkuXG4gKiBAcGFyYW0ge1B1YmxpY0tleX0gcGsgVGhlIHByb3ZlcidzIHB1YmxpYyBrZXkuXG4gKiBAcGFyYW0ge0Rlc2VyaWFsaXplZE50aWxkZX0gbnRpbGRlIFRoZSB2ZXJpZmllcidzIE50aWxkZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge2JpZ2ludH0gYzEgVGhlIG9yaWdpbmFsIGNpcGhlcnRleHQuXG4gKiBAcGFyYW0ge2JpZ2ludH0gYzIgVGhlIG1hbmlwdWxhdGVkIGNpcGhlcnRleHQuXG4gKiBAcGFyYW0ge2JpZ2ludH0geCBUaGUgcGxhaW50ZXh0IHZhbHVlIG11bHRpcGxpZWQgYnkgdGhlIG9yaWdpbmFsIHBsYWludGV4dC5cbiAqIEBwYXJhbSB7YmlnaW50fSB5IFRoZSBwbGFpbnRleHQgdmFsdWUgdGhhdCBpcyBhZGRlZCB0byB4LlxuICogQHBhcmFtIHtiaWdpbnR9IHIgVGhlIG9iZnVzY2F0aW9uIHZhbHVlIHVzZWQgdG8gZW5jcnlwdCB4LlxuICogQHBhcmFtIHtiaWdpbnR9IFggVGhlIGN1cnZlJ3MgYmFzZSBwb2ludCByYWlzZWQgdG8geC5cbiAqIEByZXR1cm5zIHtSYW5nZVByb29mV2l0aENoZWNrfSBUaGUgZ2VuZXJhdGVkIHByb29mLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvdmVXaXRoQ2hlY2soXG4gIGN1cnZlOiBCYXNlQ3VydmUsXG4gIG1vZHVsdXNCaXRzOiBudW1iZXIsXG4gIHBrOiBQdWJsaWNLZXksXG4gIG50aWxkZTogRGVzZXJpYWxpemVkTnRpbGRlLFxuICBjMTogYmlnaW50LFxuICBjMjogYmlnaW50LFxuICB4OiBiaWdpbnQsXG4gIHk6IGJpZ2ludCxcbiAgcjogYmlnaW50LFxuICBYOiBiaWdpbnRcbik6IFByb21pc2U8UmFuZ2VQcm9vZldpdGhDaGVjaz4ge1xuICBjb25zdCBtb2R1bHVzQnl0ZXMgPSBNYXRoLmZsb29yKChtb2R1bHVzQml0cyArIDcpIC8gOCk7XG4gIGNvbnN0IHEgPSBjdXJ2ZS5vcmRlcigpO1xuICBjb25zdCBxMyA9IHEgKiogQmlnSW50KDMpO1xuICBjb25zdCBxNyA9IHEgKiogQmlnSW50KDcpO1xuICBjb25zdCBxbnRpbGRlID0gcSAqIG50aWxkZS5udGlsZGU7XG4gIGNvbnN0IHEzbnRpbGRlID0gcTMgKiBudGlsZGUubnRpbGRlO1xuICBjb25zdCBhbHBoYSA9IHJhbmRCZXR3ZWVuKHEzKTtcbiAgY29uc3QgcmhvID0gcmFuZEJldHdlZW4ocW50aWxkZSk7XG4gIGNvbnN0IHNpZ21hID0gcmFuZEJldHdlZW4ocW50aWxkZSk7XG4gIGNvbnN0IHRhdSA9IHJhbmRCZXR3ZWVuKHEzbnRpbGRlKTtcbiAgY29uc3QgcmhvcHJtID0gcmFuZEJldHdlZW4ocTNudGlsZGUpO1xuICBjb25zdCBiZXRhID0gYXdhaXQgcmFuZG9tUG9zaXRpdmVDb1ByaW1lVG8ocGsubik7XG4gIGNvbnN0IGdhbW1hID0gcmFuZEJldHdlZW4ocTcpO1xuICBjb25zdCB1ID0gY3VydmUuYmFzZVBvaW50TXVsdChjdXJ2ZS5zY2FsYXJSZWR1Y2UoYWxwaGEpKTtcbiAgY29uc3QgeiA9IChtb2RQb3cobnRpbGRlLmgxLCB4LCBudGlsZGUubnRpbGRlKSAqIG1vZFBvdyhudGlsZGUuaDIsIHJobywgbnRpbGRlLm50aWxkZSkpICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgenBybSA9IChtb2RQb3cobnRpbGRlLmgxLCBhbHBoYSwgbnRpbGRlLm50aWxkZSkgKiBtb2RQb3cobnRpbGRlLmgyLCByaG9wcm0sIG50aWxkZS5udGlsZGUpKSAlIG50aWxkZS5udGlsZGU7XG4gIGNvbnN0IHQgPSAobW9kUG93KG50aWxkZS5oMSwgeSwgbnRpbGRlLm50aWxkZSkgKiBtb2RQb3cobnRpbGRlLmgyLCBzaWdtYSwgbnRpbGRlLm50aWxkZSkpICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgdiA9XG4gICAgKCgobW9kUG93KGMxLCBhbHBoYSwgcGsuX24yKSAqIG1vZFBvdyhway5nLCBnYW1tYSwgcGsuX24yKSkgJSBway5fbjIpICogbW9kUG93KGJldGEsIHBrLm4sIHBrLl9uMikpICUgcGsuX24yO1xuICBjb25zdCB3ID0gKG1vZFBvdyhudGlsZGUuaDEsIGdhbW1hLCBudGlsZGUubnRpbGRlKSAqIG1vZFBvdyhudGlsZGUuaDIsIHRhdSwgbnRpbGRlLm50aWxkZSkpICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgeyBub25jZSwgZSB9ID0gcmFuZ2VQcm9vZldpdGhDaGVja0NoYWxsZW5nZShjdXJ2ZSwgbW9kdWx1c0J5dGVzLCBwaywgWCwgYzEsIGMyLCB1LCB6LCB6cHJtLCB0LCB2LCB3KTtcbiAgY29uc3QgcyA9IChtb2RQb3cociwgZSwgcGsubikgKiBiZXRhKSAlIHBrLm47XG4gIGNvbnN0IHMxID0gZSAqIHggKyBhbHBoYTtcbiAgY29uc3QgczIgPSBlICogcmhvICsgcmhvcHJtO1xuICBjb25zdCB0MSA9IGUgKiB5ICsgZ2FtbWE7XG4gIGNvbnN0IHQyID0gZSAqIHNpZ21hICsgdGF1O1xuICByZXR1cm4geyB6LCB6cHJtLCB0LCB2LCB3LCBub25jZSwgcywgczEsIHMyLCB0MSwgdDIsIHUgfTtcbn1cblxuLyoqXG4gKiBWZXJpZnkgYSB6ZXJvLWtub3dsZWRnZSByYW5nZSBwcm9vZiB0aGF0IGEgaG9tb21vcnBoaWNhbGx5IG1hbmlwdWxhdGVkIHZhbHVlIGlzIFwic21hbGxcIi5cbiAqIEBwYXJhbSB7QmFzZUN1cnZlfSBjdXJ2ZSBBbiBlbGxpcHRpYyBjdXJ2ZSB0byB1c2UgZm9yIGdyb3VwIG9wZXJhdGlvbnMuXG4gKiBAcGFyYW0ge251bWJlcn0gbW9kdWx1c0JpdHMgVGhlIGJpdCBjb3VudCBvZiB0aGUgcHJvdmVyJ3MgcHVibGljIGtleS5cbiAqIEBwYXJhbSB7UHVibGljS2V5fSBwayBUaGUgcHJvdmVyJ3MgcHVibGljIGtleS5cbiAqIEBwYXJhbSB7RGVzZXJpYWxpemVkTnRpbGRlfSBudGlsZGUgVGhlIHZlcmlmaWVyJ3MgTnRpbGRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7UmFuZ2VQcm9vZldpdGhDaGVja30gcHJvb2YgVGhlIHJhbmdlIHByb29mLlxuICogQHBhcmFtIHtiaWdpbnR9IGMxIFRoZSBvcmlnaW5hbCBjaXBoZXJ0ZXh0LlxuICogQHBhcmFtIHtiaWdpbnR9IGMyIFRoZSBtYW5pcHVsYXRlZCBjaXBoZXJ0ZXh0LlxuICogQHBhcmFtIHtiaWdpbnR9IFggVGhlIGN1cnZlJ3MgYmFzZSBwb2ludCByYWlzZWQgdG8geC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZlcmlmaWNhdGlvbiBzdWNjZWVkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeVdpdGhDaGVjayhcbiAgY3VydmU6IEJhc2VDdXJ2ZSxcbiAgbW9kdWx1c0JpdHM6IG51bWJlcixcbiAgcGs6IFB1YmxpY0tleSxcbiAgbnRpbGRlOiBEZXNlcmlhbGl6ZWROdGlsZGUsXG4gIHByb29mOiBSYW5nZVByb29mV2l0aENoZWNrLFxuICBjMTogYmlnaW50LFxuICBjMjogYmlnaW50LFxuICBYOiBiaWdpbnRcbik6IGJvb2xlYW4ge1xuICBjb25zdCBtb2R1bHVzQnl0ZXMgPSBNYXRoLmZsb29yKChtb2R1bHVzQml0cyArIDcpIC8gOCk7XG4gIGNvbnN0IHEgPSBjdXJ2ZS5vcmRlcigpO1xuICBjb25zdCBxMyA9IHEgKiogQmlnSW50KDMpO1xuICBjb25zdCBxNyA9IHEgKiogQmlnSW50KDcpO1xuICBpZiAocHJvb2YuczEgPiBxMykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAocHJvb2YudDEgPiBxNykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBoYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2Jyk7XG4gIGlmIChwcm9vZi5ub25jZSkge1xuICAgIGhhc2gudXBkYXRlKCdcXHgwZVxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwJyk7XG4gIH0gZWxzZSB7XG4gICAgaGFzaC51cGRhdGUoJ1xceDBkXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDAnKTtcbiAgfVxuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHBrLm4sIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHBrLmcsIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKFgsIDMzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUoYzEsIDIgKiBtb2R1bHVzQnl0ZXMpKTtcbiAgaGFzaC51cGRhdGUoJyQnKTtcbiAgaGFzaC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShjMiwgMiAqIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHByb29mLnUsIDMzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YueiwgbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YuenBybSwgbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YudCwgbW9kdWx1c0J5dGVzKSk7XG4gIGhhc2gudXBkYXRlKCckJyk7XG4gIGhhc2gudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUocHJvb2YudiwgMiAqIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBoYXNoLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckJFKHByb29mLncsIG1vZHVsdXNCeXRlcykpO1xuICBoYXNoLnVwZGF0ZSgnJCcpO1xuICBsZXQgZTogYmlnaW50O1xuICBpZiAocHJvb2Yubm9uY2UpIHtcbiAgICBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGhhc2gudXBkYXRlKHByb29mLm5vbmNlKS5kaWdlc3QoKSk7XG4gICAgaWYgKGUgPj0gcSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGhhc2guZGlnZXN0KCkpICUgcTtcbiAgfVxuICBjb25zdCBnUzEgPSBjdXJ2ZS5iYXNlUG9pbnRNdWx0KGN1cnZlLnNjYWxhclJlZHVjZShwcm9vZi5zMSkpO1xuICBjb25zdCB4RVUgPSBjdXJ2ZS5wb2ludEFkZChjdXJ2ZS5wb2ludE11bHRpcGx5KFgsIGUpLCBwcm9vZi51KTtcbiAgaWYgKGdTMSAhPT0geEVVKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGxldCBsZWZ0OiBiaWdpbnQsIHJpZ2h0OiBiaWdpbnQ7XG4gIGNvbnN0IGgxRXhwUzEgPSBtb2RQb3cobnRpbGRlLmgxLCBwcm9vZi5zMSwgbnRpbGRlLm50aWxkZSk7XG4gIGNvbnN0IGgyRXhwUzIgPSBtb2RQb3cobnRpbGRlLmgyLCBwcm9vZi5zMiwgbnRpbGRlLm50aWxkZSk7XG4gIGxlZnQgPSAoaDFFeHBTMSAqIGgyRXhwUzIpICUgbnRpbGRlLm50aWxkZTtcbiAgY29uc3QgekV4cEUgPSBtb2RQb3cocHJvb2YueiwgZSwgbnRpbGRlLm50aWxkZSk7XG4gIHJpZ2h0ID0gKHpFeHBFICogcHJvb2YuenBybSkgJSBudGlsZGUubnRpbGRlO1xuICBpZiAobGVmdCAhPT0gcmlnaHQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgaDFFeHBUMSA9IG1vZFBvdyhudGlsZGUuaDEsIHByb29mLnQxLCBudGlsZGUubnRpbGRlKTtcbiAgY29uc3QgaDJFeHBUMiA9IG1vZFBvdyhudGlsZGUuaDIsIHByb29mLnQyLCBudGlsZGUubnRpbGRlKTtcbiAgbGVmdCA9IChoMUV4cFQxICogaDJFeHBUMikgJSBudGlsZGUubnRpbGRlO1xuICBjb25zdCB0RXhwRSA9IG1vZFBvdyhwcm9vZi50LCBlLCBudGlsZGUubnRpbGRlKTtcbiAgcmlnaHQgPSAodEV4cEUgKiBwcm9vZi53KSAlIG50aWxkZS5udGlsZGU7XG4gIGlmIChsZWZ0ICE9PSByaWdodCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBjMUV4cFMxID0gbW9kUG93KGMxLCBwcm9vZi5zMSwgcGsuX24yKTtcbiAgY29uc3Qgc0V4cE4gPSBtb2RQb3cocHJvb2YucywgcGsubiwgcGsuX24yKTtcbiAgY29uc3QgZ2FtbWFFeHBUMSA9IG1vZFBvdyhway5nLCBwcm9vZi50MSwgcGsuX24yKTtcbiAgbGVmdCA9ICgoKGMxRXhwUzEgKiBzRXhwTikgJSBway5fbjIpICogZ2FtbWFFeHBUMSkgJSBway5fbjI7XG4gIGNvbnN0IGMyRXhwRSA9IG1vZFBvdyhjMiwgZSwgcGsuX24yKTtcbiAgcmlnaHQgPSAoYzJFeHBFICogcHJvb2YudikgJSBway5fbjI7XG4gIHJldHVybiBsZWZ0ID09PSByaWdodDtcbn1cbiJdfQ==
|