1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const client_common_1 = require("@neo-one/client-common");
|
5 | const node_core_1 = require("@neo-one/node-core");
|
6 | const bn_js_1 = require("bn.js");
|
7 | const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
8 | const ValidatorCache_1 = require("./ValidatorCache");
|
9 | const processOutput = async (blockchain, cache, output, negative) => {
|
10 | let { value } = output;
|
11 | if (negative) {
|
12 | value = value.neg();
|
13 | }
|
14 | const [account] = await Promise.all([
|
15 | cache.getAccount(output.address),
|
16 | cache.updateAccountBalance(output.address, output.asset, value),
|
17 | ]);
|
18 | if (client_common_1.common.uInt256Equal(output.asset, blockchain.settings.governingToken.hash) && account.votes.length > 0) {
|
19 | await Promise.all([
|
20 | Promise.all(account.votes.map(async (publicKey) => cache.updateValidatorVotes(publicKey, value))),
|
21 | cache.updateValidatorsCountVotes(account.votes.length - 1, value),
|
22 | ]);
|
23 | }
|
24 | };
|
25 | const processTransaction = async (blockchain, cache, transaction) => {
|
26 | let allOutputs = await Promise.all(transaction.inputs.map(async (input) => {
|
27 | const output = await blockchain.output.get(input);
|
28 | return { output, negative: true };
|
29 | }));
|
30 | allOutputs = allOutputs.concat(transaction.outputs.map((output) => ({ output, negative: false })));
|
31 | await Promise.all(allOutputs.map(async ({ output, negative }) => processOutput(blockchain, cache, output, negative)));
|
32 | const accountHashes = [...new Set(allOutputs.map(({ output }) => client_common_1.common.uInt160ToHex(output.address)))].map((hash) => client_common_1.common.hexToUInt160(hash));
|
33 | const touchedValidators = await Promise.all(accountHashes.map(async (hash) => {
|
34 | const account = await cache.getAccount(hash);
|
35 | return account.votes;
|
36 | }));
|
37 | const touchedValidatorsSet = [
|
38 | ...new Set(touchedValidators.reduce((acc, votes) => acc.concat(votes.map((vote) => client_common_1.common.ecPointToHex(vote))), [])),
|
39 | ].map((publicKey) => client_common_1.common.hexToECPoint(publicKey));
|
40 | await Promise.all(touchedValidatorsSet.map(async (publicKey) => {
|
41 | const validator = await cache.getValidator(publicKey);
|
42 | if (!validator.registered && validator.votes.eq(node_core_1.utils.ZERO)) {
|
43 | await cache.deleteValidator(publicKey);
|
44 | }
|
45 | }));
|
46 | };
|
47 | exports.getDescriptorChanges = async ({ transactions, getAccount, governingTokenHash, }) => {
|
48 | const accountChanges = {};
|
49 | const validatorVotesChanges = {};
|
50 | const validatorRegisteredChanges = {};
|
51 | const validatorsCountChanges = [];
|
52 | const allDescriptors = transactions.reduce((acc, transaction) => acc.concat(transaction.descriptors), []);
|
53 | const accountDescriptors = allDescriptors.filter((descriptor) => descriptor.type === 0x40);
|
54 | const groupedAccountDescriptors = Object.entries(lodash_1.default.groupBy(accountDescriptors, (descriptor) => client_common_1.common.uInt160ToHex(client_common_1.common.bufferToUInt160(descriptor.key))));
|
55 | await Promise.all(groupedAccountDescriptors.map(async ([hash, descriptors]) => {
|
56 | const account = await getAccount(client_common_1.common.hexToUInt160(hash));
|
57 | const balance = account.getBalance(governingTokenHash);
|
58 | for (const vote of account.votes) {
|
59 | const voteHex = client_common_1.common.ecPointToHex(vote);
|
60 | validatorVotesChanges[voteHex] = (validatorVotesChanges[voteHex] === undefined
|
61 | ? node_core_1.utils.ZERO
|
62 | : validatorVotesChanges[voteHex]).sub(balance);
|
63 | }
|
64 | const descriptor = descriptors[descriptors.length - 1];
|
65 | const reader = new node_core_1.BinaryReader(descriptor.value);
|
66 | const votes = reader.readArray(() => reader.readECPoint());
|
67 | if (votes.length !== account.votes.length) {
|
68 | if (account.votes.length > 0) {
|
69 | validatorsCountChanges[account.votes.length - 1] = (validatorsCountChanges[account.votes.length - 1] === undefined
|
70 | ? node_core_1.utils.ZERO
|
71 | : validatorsCountChanges[account.votes.length - 1]).sub(balance);
|
72 | }
|
73 | if (votes.length > 0) {
|
74 | validatorsCountChanges[votes.length - 1] = (validatorsCountChanges[votes.length - 1] ===
|
75 | undefined
|
76 | ? node_core_1.utils.ZERO
|
77 | : validatorsCountChanges[votes.length - 1]).add(balance);
|
78 | }
|
79 | }
|
80 | accountChanges[hash] = votes;
|
81 | for (const vote of votes) {
|
82 | const voteHex = client_common_1.common.ecPointToHex(vote);
|
83 | validatorVotesChanges[voteHex] = (validatorVotesChanges[voteHex] === undefined
|
84 | ? node_core_1.utils.ZERO
|
85 | : validatorVotesChanges[voteHex]).add(balance);
|
86 | }
|
87 | }));
|
88 | const validatorDescriptors = allDescriptors.filter((descriptor) => descriptor.type === 0x48);
|
89 | for (const descriptor of validatorDescriptors) {
|
90 | const publicKey = client_common_1.common.bufferToECPoint(descriptor.key);
|
91 | validatorRegisteredChanges[client_common_1.common.ecPointToHex(publicKey)] = descriptor.value.some((byte) => byte !== 0);
|
92 | }
|
93 | const validatorChanges = {};
|
94 | for (const [publicKey, votes] of Object.entries(validatorVotesChanges)) {
|
95 | validatorChanges[publicKey] = { votes };
|
96 | }
|
97 | for (const [publicKey, registered] of Object.entries(validatorRegisteredChanges)) {
|
98 | const current = validatorChanges[publicKey] === undefined ? {} : validatorChanges[publicKey];
|
99 | validatorChanges[publicKey] = {
|
100 | registered,
|
101 | votes: current.votes,
|
102 | };
|
103 | }
|
104 | return {
|
105 | accountChanges,
|
106 | validatorChanges,
|
107 | validatorsCountChanges,
|
108 | };
|
109 | };
|
110 | exports.processStateTransaction = async ({ validatorChanges, validatorsCountChanges, tryGetValidatorsCount, addValidatorsCount, updateValidatorsCount, tryGetValidator, addValidator, deleteValidator, updateValidator, }) => {
|
111 | const validatorsCount = await tryGetValidatorsCount();
|
112 | const mutableValidatorsCountVotes = validatorsCount === undefined ? [] : [...validatorsCount.votes];
|
113 | [...validatorsCountChanges.entries()].forEach(([index, value]) => {
|
114 | mutableValidatorsCountVotes[index] = value;
|
115 | });
|
116 | await Promise.all([
|
117 | Promise.all(Object.entries(validatorChanges).map(async ([publicKeyHex, { registered, votes }]) => {
|
118 | const publicKey = client_common_1.common.hexToECPoint(publicKeyHex);
|
119 | const validator = await tryGetValidator({ publicKey });
|
120 | if (validator === undefined) {
|
121 | await addValidator(new node_core_1.Validator({
|
122 | publicKey,
|
123 | registered,
|
124 | votes,
|
125 | }));
|
126 | }
|
127 | else if (((registered !== undefined && !registered) || (registered === undefined && !validator.registered)) &&
|
128 | ((votes !== undefined && votes.eq(node_core_1.utils.ZERO)) || (votes === undefined && validator.votes.eq(node_core_1.utils.ZERO)))) {
|
129 | await deleteValidator({ publicKey: validator.publicKey });
|
130 | }
|
131 | else {
|
132 | await updateValidator(validator, { votes, registered });
|
133 | }
|
134 | })),
|
135 | validatorsCount === undefined
|
136 | ? addValidatorsCount(new node_core_1.ValidatorsCount({
|
137 | votes: mutableValidatorsCountVotes,
|
138 | }))
|
139 | : updateValidatorsCount(validatorsCount, {
|
140 | votes: mutableValidatorsCountVotes,
|
141 | }),
|
142 | ]);
|
143 | };
|
144 | exports.getValidators = async (blockchain, transactions) => {
|
145 | const cache = new ValidatorCache_1.ValidatorCache(blockchain);
|
146 | await Promise.all(transactions.map(async (transaction) => processTransaction(blockchain, cache, transaction)));
|
147 | const { validatorChanges, validatorsCountChanges } = await exports.getDescriptorChanges({
|
148 | transactions: transactions.filter((transaction) => transaction.type === node_core_1.TransactionType.State && transaction instanceof node_core_1.StateTransaction),
|
149 | getAccount: async (hash) => cache.getAccount(hash),
|
150 | governingTokenHash: blockchain.settings.governingToken.hashHex,
|
151 | });
|
152 | await exports.processStateTransaction({
|
153 | validatorChanges,
|
154 | validatorsCountChanges,
|
155 | tryGetValidatorsCount: async () => cache.getValidatorsCount(),
|
156 | addValidatorsCount: async (value) => cache.addValidatorsCount(value),
|
157 | updateValidatorsCount: async (update) => {
|
158 | await cache.updateValidatorsCount(update);
|
159 | },
|
160 | tryGetValidator: async (key) => cache.getValidator(key.publicKey),
|
161 | addValidator: async (validator) => cache.addValidator(validator),
|
162 | deleteValidator: async (key) => cache.deleteValidator(key.publicKey),
|
163 | updateValidator: async (value, update) => cache.updateValidator(value.publicKey, update),
|
164 | });
|
165 | const [validatorsCount, validators] = await Promise.all([cache.getValidatorsCount(), cache.getAllValidators()]);
|
166 | const numValidators = Math.max(node_core_1.utils.weightedAverage(node_core_1.utils
|
167 | .weightedFilter(validatorsCount.votes
|
168 | .map((votes, count) => ({ count, votes: votes === undefined ? node_core_1.utils.ZERO : votes }))
|
169 | .filter(({ votes }) => votes.gt(node_core_1.utils.ZERO)), 0.25, 0.75, ({ count }) => new bn_js_1.BN(count))
|
170 | .map(([{ count }, weight]) => ({ value: count, weight }))), blockchain.settings.standbyValidators.length);
|
171 | const standbyValidatorsSet = new Set(blockchain.settings.standbyValidators.map((publicKey) => client_common_1.common.ecPointToHex(publicKey)));
|
172 | const validatorsPublicKeySet = new Set(lodash_1.default.take(validators
|
173 | .filter((validator) => (validator.registered && validator.votes.gt(node_core_1.utils.ZERO)) ||
|
174 | standbyValidatorsSet.has(client_common_1.common.ecPointToHex(validator.publicKey)))
|
175 | .sort((aValidator, bValidator) => aValidator.votes.eq(bValidator.votes)
|
176 | ? client_common_1.common.ecPointCompare(aValidator.publicKey, bValidator.publicKey)
|
177 | : -aValidator.votes.cmp(bValidator.votes))
|
178 | .map((validator) => client_common_1.common.ecPointToHex(validator.publicKey)), numValidators));
|
179 | const standbyValidatorsArray = [...standbyValidatorsSet];
|
180 | for (let i = 0; i < standbyValidatorsArray.length && validatorsPublicKeySet.size < numValidators; i += 1) {
|
181 | validatorsPublicKeySet.add(standbyValidatorsArray[i]);
|
182 | }
|
183 | const validatorsPublicKeys = [...validatorsPublicKeySet].map((hex) => client_common_1.common.hexToECPoint(hex));
|
184 | return validatorsPublicKeys.sort((aKey, bKey) => client_common_1.common.ecPointCompare(aKey, bKey));
|
185 | };
|
186 |
|
187 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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by1vbmUtbm9kZS1ibG9ja2NoYWluL3NyYy9nZXRWYWxpZGF0b3JzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGUgbm8tb2JqZWN0LW11dGF0aW9uIG5vLWFycmF5LW11dGF0aW9uIG5vLWxvb3Atc3RhdGVtZW50XG5pbXBvcnQgeyBjb21tb24sIEVDUG9pbnQsIFVJbnQxNjAsIFVJbnQyNTZIZXggfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7XG4gIEFjY291bnQsXG4gIEJpbmFyeVJlYWRlcixcbiAgT3V0cHV0LFxuICBTdGF0ZURlc2NyaXB0b3IsXG4gIFN0YXRlVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uLFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIHV0aWxzLFxuICBWYWxpZGF0b3IsXG4gIFZhbGlkYXRvcktleSxcbiAgVmFsaWRhdG9yc0NvdW50LFxuICBWYWxpZGF0b3JzQ291bnRVcGRhdGUsXG4gIFZhbGlkYXRvclVwZGF0ZSxcbn0gZnJvbSAnQG5lby1vbmUvbm9kZS1jb3JlJztcbmltcG9ydCB7IEJOIH0gZnJvbSAnYm4uanMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEJsb2NrY2hhaW4gfSBmcm9tICcuL0Jsb2NrY2hhaW4nO1xuaW1wb3J0IHsgVmFsaWRhdG9yQ2FjaGUgfSBmcm9tICcuL1ZhbGlkYXRvckNhY2hlJztcblxuY29uc3QgcHJvY2Vzc091dHB1dCA9IGFzeW5jIChcbiAgYmxvY2tjaGFpbjogQmxvY2tjaGFpbixcbiAgY2FjaGU6IFZhbGlkYXRvckNhY2hlLFxuICBvdXRwdXQ6IE91dHB1dCxcbiAgbmVnYXRpdmU6IGJvb2xlYW4sXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgbGV0IHsgdmFsdWUgfSA9IG91dHB1dDtcbiAgaWYgKG5lZ2F0aXZlKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5uZWcoKTtcbiAgfVxuICBjb25zdCBbYWNjb3VudF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgY2FjaGUuZ2V0QWNjb3VudChvdXRwdXQuYWRkcmVzcyksXG4gICAgY2FjaGUudXBkYXRlQWNjb3VudEJhbGFuY2Uob3V0cHV0LmFkZHJlc3MsIG91dHB1dC5hc3NldCwgdmFsdWUpLFxuICBdKTtcblxuICBpZiAoY29tbW9uLnVJbnQyNTZFcXVhbChvdXRwdXQuYXNzZXQsIGJsb2NrY2hhaW4uc2V0dGluZ3MuZ292ZXJuaW5nVG9rZW4uaGFzaCkgJiYgYWNjb3VudC52b3Rlcy5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgUHJvbWlzZS5hbGwoYWNjb3VudC52b3Rlcy5tYXAoYXN5bmMgKHB1YmxpY0tleSkgPT4gY2FjaGUudXBkYXRlVmFsaWRhdG9yVm90ZXMocHVibGljS2V5LCB2YWx1ZSkpKSxcblxuICAgICAgY2FjaGUudXBkYXRlVmFsaWRhdG9yc0NvdW50Vm90ZXMoYWNjb3VudC52b3Rlcy5sZW5ndGggLSAxLCB2YWx1ZSksXG4gICAgXSk7XG4gIH1cbn07XG5cbmNvbnN0IHByb2Nlc3NUcmFuc2FjdGlvbiA9IGFzeW5jIChcbiAgYmxvY2tjaGFpbjogQmxvY2tjaGFpbixcbiAgY2FjaGU6IFZhbGlkYXRvckNhY2hlLFxuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24sXG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgbGV0IGFsbE91dHB1dHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICB0cmFuc2FjdGlvbi5pbnB1dHMubWFwKGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0ID0gYXdhaXQgYmxvY2tjaGFpbi5vdXRwdXQuZ2V0KGlucHV0KTtcblxuICAgICAgcmV0dXJuIHsgb3V0cHV0LCBuZWdhdGl2ZTogdHJ1ZSB9O1xuICAgIH0pLFxuICApO1xuXG4gIGFsbE91dHB1dHMgPSBhbGxPdXRwdXRzLmNvbmNhdCh0cmFuc2FjdGlvbi5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiAoeyBvdXRwdXQsIG5lZ2F0aXZlOiBmYWxzZSB9KSkpO1xuXG4gIGF3YWl0IFByb21pc2UuYWxsKGFsbE91dHB1dHMubWFwKGFzeW5jICh7IG91dHB1dCwgbmVnYXRpdmUgfSkgPT4gcHJvY2Vzc091dHB1dChibG9ja2NoYWluLCBjYWNoZSwgb3V0cHV0LCBuZWdhdGl2ZSkpKTtcblxuICBjb25zdCBhY2NvdW50SGFzaGVzID0gWy4uLm5ldyBTZXQoYWxsT3V0cHV0cy5tYXAoKHsgb3V0cHV0IH0pID0+IGNvbW1vbi51SW50MTYwVG9IZXgob3V0cHV0LmFkZHJlc3MpKSldLm1hcCgoaGFzaCkgPT5cbiAgICBjb21tb24uaGV4VG9VSW50MTYwKGhhc2gpLFxuICApO1xuICBjb25zdCB0b3VjaGVkVmFsaWRhdG9ycyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGFjY291bnRIYXNoZXMubWFwKGFzeW5jIChoYXNoKSA9PiB7XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgY2FjaGUuZ2V0QWNjb3VudChoYXNoKTtcblxuICAgICAgcmV0dXJuIGFjY291bnQudm90ZXM7XG4gICAgfSksXG4gICk7XG5cbiAgY29uc3QgdG91Y2hlZFZhbGlkYXRvcnNTZXQgPSBbXG4gICAgLi4ubmV3IFNldChcbiAgICAgIHRvdWNoZWRWYWxpZGF0b3JzLnJlZHVjZTxyZWFkb25seSBzdHJpbmdbXT4oXG4gICAgICAgIChhY2MsIHZvdGVzKSA9PiBhY2MuY29uY2F0KHZvdGVzLm1hcCgodm90ZSkgPT4gY29tbW9uLmVjUG9pbnRUb0hleCh2b3RlKSkpLFxuICAgICAgICBbXSxcbiAgICAgICksXG4gICAgKSxcbiAgXS5tYXAoKHB1YmxpY0tleSkgPT4gY29tbW9uLmhleFRvRUNQb2ludChwdWJsaWNLZXkpKTtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgdG91Y2hlZFZhbGlkYXRvcnNTZXQubWFwKGFzeW5jIChwdWJsaWNLZXkpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGF3YWl0IGNhY2hlLmdldFZhbGlkYXRvcihwdWJsaWNLZXkpO1xuICAgICAgaWYgKCF2YWxpZGF0b3IucmVnaXN0ZXJlZCAmJiB2YWxpZGF0b3Iudm90ZXMuZXEodXRpbHMuWkVSTykpIHtcbiAgICAgICAgYXdhaXQgY2FjaGUuZGVsZXRlVmFsaWRhdG9yKHB1YmxpY0tleSk7XG4gICAgICB9XG4gICAgfSksXG4gICk7XG59O1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZSByZWFkb25seS1rZXl3b3JkIHJlYWRvbmx5LWFycmF5XG5leHBvcnQgaW50ZXJmYWNlIEFjY291bnRDaGFuZ2VzIHtcbiAgW2hhc2g6IHN0cmluZ106IHJlYWRvbmx5IEVDUG9pbnRbXTtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdG9yVm90ZXNDaGFuZ2VzIHtcbiAgW2hhc2g6IHN0cmluZ106IEJOO1xufVxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0b3JSZWdpc3RlcmVkQ2hhbmdlcyB7XG4gIFtoYXNoOiBzdHJpbmddOiBib29sZWFuO1xufVxuaW50ZXJmYWNlIFZhbGlkYXRvckNoYW5nZSB7XG4gIHJlYWRvbmx5IHJlZ2lzdGVyZWQ/OiBib29sZWFuO1xuICByZWFkb25seSB2b3Rlcz86IEJOO1xufVxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0b3JDaGFuZ2VzIHtcbiAgW2hhc2g6IHN0cmluZ106IFZhbGlkYXRvckNoYW5nZTtcbn1cbmV4cG9ydCB0eXBlIFZhbGlkYXRvcnNDb3VudENoYW5nZXMgPSBCTltdO1xuLy8gdHNsaW50OmVuYWJsZSByZWFkb25seS1rZXl3b3JkIHJlYWRvbmx5LWFycmF5XG5cbmV4cG9ydCBjb25zdCBnZXREZXNjcmlwdG9yQ2hhbmdlcyA9IGFzeW5jICh7XG4gIHRyYW5zYWN0aW9ucyxcbiAgZ2V0QWNjb3VudCxcbiAgZ292ZXJuaW5nVG9rZW5IYXNoLFxufToge1xuICByZWFkb25seSB0cmFuc2FjdGlvbnM6IHJlYWRvbmx5IFN0YXRlVHJhbnNhY3Rpb25bXTtcbiAgcmVhZG9ubHkgZ2V0QWNjb3VudDogKGhhc2g6IFVJbnQxNjApID0+IFByb21pc2U8QWNjb3VudD47XG4gIHJlYWRvbmx5IGdvdmVybmluZ1Rva2VuSGFzaDogVUludDI1NkhleDtcbn0pOiBQcm9taXNlPHtcbiAgcmVhZG9ubHkgYWNjb3VudENoYW5nZXM6IEFjY291bnRDaGFuZ2VzO1xuICByZWFkb25seSB2YWxpZGF0b3JDaGFuZ2VzOiBWYWxpZGF0b3JDaGFuZ2VzO1xuICByZWFkb25seSB2YWxpZGF0b3JzQ291bnRDaGFuZ2VzOiBWYWxpZGF0b3JzQ291bnRDaGFuZ2VzO1xufT4gPT4ge1xuICBjb25zdCBhY2NvdW50Q2hhbmdlczogQWNjb3VudENoYW5nZXMgPSB7fTtcbiAgY29uc3QgdmFsaWRhdG9yVm90ZXNDaGFuZ2VzOiBWYWxpZGF0b3JWb3Rlc0NoYW5nZXMgPSB7fTtcbiAgY29uc3QgdmFsaWRhdG9yUmVnaXN0ZXJlZENoYW5nZXM6IFZhbGlkYXRvclJlZ2lzdGVyZWRDaGFuZ2VzID0ge307XG4gIGNvbnN0IHZhbGlkYXRvcnNDb3VudENoYW5nZXM6IFZhbGlkYXRvcnNDb3VudENoYW5nZXMgPSBbXTtcbiAgY29uc3QgYWxsRGVzY3JpcHRvcnMgPSB0cmFuc2FjdGlvbnMucmVkdWNlPHJlYWRvbmx5IFN0YXRlRGVzY3JpcHRvcltdPihcbiAgICAoYWNjLCB0cmFuc2FjdGlvbikgPT4gYWNjLmNvbmNhdCh0cmFuc2FjdGlvbi5kZXNjcmlwdG9ycyksXG4gICAgW10sXG4gICk7XG5cbiAgY29uc3QgYWNjb3VudERlc2NyaXB0b3JzID0gYWxsRGVzY3JpcHRvcnMuZmlsdGVyKChkZXNjcmlwdG9yKSA9PiBkZXNjcmlwdG9yLnR5cGUgPT09IDB4NDApO1xuXG4gIGNvbnN0IGdyb3VwZWRBY2NvdW50RGVzY3JpcHRvcnMgPSBPYmplY3QuZW50cmllcyhcbiAgICBfLmdyb3VwQnkoYWNjb3VudERlc2NyaXB0b3JzLCAoZGVzY3JpcHRvcikgPT4gY29tbW9uLnVJbnQxNjBUb0hleChjb21tb24uYnVmZmVyVG9VSW50MTYwKGRlc2NyaXB0b3Iua2V5KSkpLFxuICApO1xuXG4gIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGdyb3VwZWRBY2NvdW50RGVzY3JpcHRvcnMubWFwKGFzeW5jIChbaGFzaCwgZGVzY3JpcHRvcnNdKSA9PiB7XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgZ2V0QWNjb3VudChjb21tb24uaGV4VG9VSW50MTYwKGhhc2gpKTtcbiAgICAgIGNvbnN0IGJhbGFuY2UgPSBhY2NvdW50LmdldEJhbGFuY2UoZ292ZXJuaW5nVG9rZW5IYXNoKTtcblxuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gICAgICBmb3IgKGNvbnN0IHZvdGUgb2YgYWNjb3VudC52b3Rlcykge1xuICAgICAgICBjb25zdCB2b3RlSGV4ID0gY29tbW9uLmVjUG9pbnRUb0hleCh2b3RlKTtcbiAgICAgICAgdmFsaWRhdG9yVm90ZXNDaGFuZ2VzW3ZvdGVIZXhdID0gKCh2YWxpZGF0b3JWb3Rlc0NoYW5nZXNbdm90ZUhleF0gYXMgQk4gfCB1bmRlZmluZWQpID09PSB1bmRlZmluZWRcbiAgICAgICAgICA/IHV0aWxzLlpFUk9cbiAgICAgICAgICA6IHZhbGlkYXRvclZvdGVzQ2hhbmdlc1t2b3RlSGV4XVxuICAgICAgICApLnN1YihiYWxhbmNlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JzW2Rlc2NyaXB0b3JzLmxlbmd0aCAtIDFdO1xuICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEJpbmFyeVJlYWRlcihkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICAgIGNvbnN0IHZvdGVzID0gcmVhZGVyLnJlYWRBcnJheSgoKSA9PiByZWFkZXIucmVhZEVDUG9pbnQoKSk7XG4gICAgICBpZiAodm90ZXMubGVuZ3RoICE9PSBhY2NvdW50LnZvdGVzLmxlbmd0aCkge1xuICAgICAgICBpZiAoYWNjb3VudC52b3Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFsaWRhdG9yc0NvdW50Q2hhbmdlc1thY2NvdW50LnZvdGVzLmxlbmd0aCAtIDFdID0gKCh2YWxpZGF0b3JzQ291bnRDaGFuZ2VzW2FjY291bnQudm90ZXMubGVuZ3RoIC0gMV0gYXNcbiAgICAgICAgICAgIHwgQk5cbiAgICAgICAgICAgIHwgdW5kZWZpbmVkKSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IHV0aWxzLlpFUk9cbiAgICAgICAgICAgIDogdmFsaWRhdG9yc0NvdW50Q2hhbmdlc1thY2NvdW50LnZvdGVzLmxlbmd0aCAtIDFdXG4gICAgICAgICAgKS5zdWIoYmFsYW5jZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodm90ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHZhbGlkYXRvcnNDb3VudENoYW5nZXNbdm90ZXMubGVuZ3RoIC0gMV0gPSAoKHZhbGlkYXRvcnNDb3VudENoYW5nZXNbdm90ZXMubGVuZ3RoIC0gMV0gYXMgQk4gfCB1bmRlZmluZWQpID09PVxuICAgICAgICAgIHVuZGVmaW5lZFxuICAgICAgICAgICAgPyB1dGlscy5aRVJPXG4gICAgICAgICAgICA6IHZhbGlkYXRvcnNDb3VudENoYW5nZXNbdm90ZXMubGVuZ3RoIC0gMV1cbiAgICAgICAgICApLmFkZChiYWxhbmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBhY2NvdW50Q2hhbmdlc1toYXNoXSA9IHZvdGVzO1xuICAgICAgZm9yIChjb25zdCB2b3RlIG9mIHZvdGVzKSB7XG4gICAgICAgIGNvbnN0IHZvdGVIZXggPSBjb21tb24uZWNQb2ludFRvSGV4KHZvdGUpO1xuICAgICAgICB2YWxpZGF0b3JWb3Rlc0NoYW5nZXNbdm90ZUhleF0gPSAoKHZhbGlkYXRvclZvdGVzQ2hhbmdlc1t2b3RlSGV4XSBhcyBCTiB8IHVuZGVmaW5lZCkgPT09IHVuZGVmaW5lZFxuICAgICAgICAgID8gdXRpbHMuWkVST1xuICAgICAgICAgIDogdmFsaWRhdG9yVm90ZXNDaGFuZ2VzW3ZvdGVIZXhdXG4gICAgICAgICkuYWRkKGJhbGFuY2UpO1xuICAgICAgfVxuICAgIH0pLFxuICApO1xuXG4gIGNvbnN0IHZhbGlkYXRvckRlc2NyaXB0b3JzID0gYWxsRGVzY3JpcHRvcnMuZmlsdGVyKChkZXNjcmlwdG9yKSA9PiBkZXNjcmlwdG9yLnR5cGUgPT09IDB4NDgpO1xuXG4gIGZvciAoY29uc3QgZGVzY3JpcHRvciBvZiB2YWxpZGF0b3JEZXNjcmlwdG9ycykge1xuICAgIGNvbnN0IHB1YmxpY0tleSA9IGNvbW1vbi5idWZmZXJUb0VDUG9pbnQoZGVzY3JpcHRvci5rZXkpO1xuICAgIHZhbGlkYXRvclJlZ2lzdGVyZWRDaGFuZ2VzW2NvbW1vbi5lY1BvaW50VG9IZXgocHVibGljS2V5KV0gPSBkZXNjcmlwdG9yLnZhbHVlLnNvbWUoKGJ5dGUpID0+IGJ5dGUgIT09IDApO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdG9yQ2hhbmdlczogVmFsaWRhdG9yQ2hhbmdlcyA9IHt9O1xuICBmb3IgKGNvbnN0IFtwdWJsaWNLZXksIHZvdGVzXSBvZiBPYmplY3QuZW50cmllcyh2YWxpZGF0b3JWb3Rlc0NoYW5nZXMpKSB7XG4gICAgdmFsaWRhdG9yQ2hhbmdlc1twdWJsaWNLZXldID0geyB2b3RlcyB9O1xuICB9XG5cbiAgZm9yIChjb25zdCBbcHVibGljS2V5LCByZWdpc3RlcmVkXSBvZiBPYmplY3QuZW50cmllcyh2YWxpZGF0b3JSZWdpc3RlcmVkQ2hhbmdlcykpIHtcbiAgICBjb25zdCBjdXJyZW50ID1cbiAgICAgICh2YWxpZGF0b3JDaGFuZ2VzW3B1YmxpY0tleV0gYXMgVmFsaWRhdG9yQ2hhbmdlIHwgdW5kZWZpbmVkKSA9PT0gdW5kZWZpbmVkID8ge30gOiB2YWxpZGF0b3JDaGFuZ2VzW3B1YmxpY0tleV07XG4gICAgdmFsaWRhdG9yQ2hhbmdlc1twdWJsaWNLZXldID0ge1xuICAgICAgcmVnaXN0ZXJlZCxcbiAgICAgIHZvdGVzOiBjdXJyZW50LnZvdGVzLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFjY291bnRDaGFuZ2VzLFxuICAgIHZhbGlkYXRvckNoYW5nZXMsXG4gICAgdmFsaWRhdG9yc0NvdW50Q2hhbmdlcyxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBwcm9jZXNzU3RhdGVUcmFuc2FjdGlvbiA9IGFzeW5jICh7XG4gIHZhbGlkYXRvckNoYW5nZXMsXG4gIHZhbGlkYXRvcnNDb3VudENoYW5nZXMsXG4gIHRyeUdldFZhbGlkYXRvcnNDb3VudCxcbiAgYWRkVmFsaWRhdG9yc0NvdW50LFxuICB1cGRhdGVWYWxpZGF0b3JzQ291bnQsXG4gIHRyeUdldFZhbGlkYXRvcixcbiAgYWRkVmFsaWRhdG9yLFxuICBkZWxldGVWYWxpZGF0b3IsXG4gIHVwZGF0ZVZhbGlkYXRvcixcbn06IHtcbiAgcmVhZG9ubHkgdmFsaWRhdG9yQ2hhbmdlczogVmFsaWRhdG9yQ2hhbmdlcztcbiAgcmVhZG9ubHkgdmFsaWRhdG9yc0NvdW50Q2hhbmdlczogVmFsaWRhdG9yc0NvdW50Q2hhbmdlcztcbiAgcmVhZG9ubHkgdHJ5R2V0VmFsaWRhdG9yc0NvdW50OiAoKSA9PiBQcm9taXNlPFZhbGlkYXRvcnNDb3VudCB8IHVuZGVmaW5lZD47XG4gIHJlYWRvbmx5IGFkZFZhbGlkYXRvcnNDb3VudDogKHZhbGlkYXRvcnNDb3VudDogVmFsaWRhdG9yc0NvdW50KSA9PiBQcm9taXNlPHZvaWQ+O1xuICByZWFkb25seSB1cGRhdGVWYWxpZGF0b3JzQ291bnQ6ICh2YWxpZGF0b3JzQ291bnQ6IFZhbGlkYXRvcnNDb3VudCwgdXBkYXRlOiBWYWxpZGF0b3JzQ291bnRVcGRhdGUpID0+IFByb21pc2U8dm9pZD47XG5cbiAgcmVhZG9ubHkgdHJ5R2V0VmFsaWRhdG9yOiAoa2V5OiBWYWxpZGF0b3JLZXkpID0+IFByb21pc2U8VmFsaWRhdG9yIHwgdW5kZWZpbmVkPjtcbiAgcmVhZG9ubHkgYWRkVmFsaWRhdG9yOiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpID0+IFByb21pc2U8dm9pZD47XG4gIHJlYWRvbmx5IGRlbGV0ZVZhbGlkYXRvcjogKGtleTogVmFsaWRhdG9yS2V5KSA9PiBQcm9taXNlPHZvaWQ+O1xuICByZWFkb25seSB1cGRhdGVWYWxpZGF0b3I6ICh2YWxpZGF0b3I6IFZhbGlkYXRvciwgdXBkYXRlOiBWYWxpZGF0b3JVcGRhdGUpID0+IFByb21pc2U8VmFsaWRhdG9yPjtcbn0pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgY29uc3QgdmFsaWRhdG9yc0NvdW50ID0gYXdhaXQgdHJ5R2V0VmFsaWRhdG9yc0NvdW50KCk7XG4gIGNvbnN0IG11dGFibGVWYWxpZGF0b3JzQ291bnRWb3RlcyA9IHZhbGlkYXRvcnNDb3VudCA9PT0gdW5kZWZpbmVkID8gW10gOiBbLi4udmFsaWRhdG9yc0NvdW50LnZvdGVzXTtcbiAgWy4uLnZhbGlkYXRvcnNDb3VudENoYW5nZXMuZW50cmllcygpXS5mb3JFYWNoKChbaW5kZXgsIHZhbHVlXSkgPT4ge1xuICAgIG11dGFibGVWYWxpZGF0b3JzQ291bnRWb3Rlc1tpbmRleF0gPSB2YWx1ZTtcbiAgfSk7XG5cbiAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgIFByb21pc2UuYWxsKFxuICAgICAgT2JqZWN0LmVudHJpZXModmFsaWRhdG9yQ2hhbmdlcykubWFwKGFzeW5jIChbcHVibGljS2V5SGV4LCB7IHJlZ2lzdGVyZWQsIHZvdGVzIH1dKSA9PiB7XG4gICAgICAgIGNvbnN0IHB1YmxpY0tleSA9IGNvbW1vbi5oZXhUb0VDUG9pbnQocHVibGljS2V5SGV4KTtcbiAgICAgICAgY29uc3QgdmFsaWRhdG9yID0gYXdhaXQgdHJ5R2V0VmFsaWRhdG9yKHsgcHVibGljS2V5IH0pO1xuICAgICAgICBpZiAodmFsaWRhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhd2FpdCBhZGRWYWxpZGF0b3IoXG4gICAgICAgICAgICBuZXcgVmFsaWRhdG9yKHtcbiAgICAgICAgICAgICAgcHVibGljS2V5LFxuICAgICAgICAgICAgICByZWdpc3RlcmVkLFxuICAgICAgICAgICAgICB2b3RlcyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgKChyZWdpc3RlcmVkICE9PSB1bmRlZmluZWQgJiYgIXJlZ2lzdGVyZWQpIHx8IChyZWdpc3RlcmVkID09PSB1bmRlZmluZWQgJiYgIXZhbGlkYXRvci5yZWdpc3RlcmVkKSkgJiZcbiAgICAgICAgICAoKHZvdGVzICE9PSB1bmRlZmluZWQgJiYgdm90ZXMuZXEodXRpbHMuWkVSTykpIHx8ICh2b3RlcyA9PT0gdW5kZWZpbmVkICYmIHZhbGlkYXRvci52b3Rlcy5lcSh1dGlscy5aRVJPKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIGF3YWl0IGRlbGV0ZVZhbGlkYXRvcih7IHB1YmxpY0tleTogdmFsaWRhdG9yLnB1YmxpY0tleSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCB1cGRhdGVWYWxpZGF0b3IodmFsaWRhdG9yLCB7IHZvdGVzLCByZWdpc3RlcmVkIH0pO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICApLFxuICAgIHZhbGlkYXRvcnNDb3VudCA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGFkZFZhbGlkYXRvcnNDb3VudChcbiAgICAgICAgICBuZXcgVmFsaWRhdG9yc0NvdW50KHtcbiAgICAgICAgICAgIHZvdGVzOiBtdXRhYmxlVmFsaWRhdG9yc0NvdW50Vm90ZXMsXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgIDogdXBkYXRlVmFsaWRhdG9yc0NvdW50KHZhbGlkYXRvcnNDb3VudCwge1xuICAgICAgICAgIHZvdGVzOiBtdXRhYmxlVmFsaWRhdG9yc0NvdW50Vm90ZXMsXG4gICAgICAgIH0pLFxuICBdKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRWYWxpZGF0b3JzID0gYXN5bmMgKFxuICBibG9ja2NoYWluOiBCbG9ja2NoYWluLFxuICB0cmFuc2FjdGlvbnM6IHJlYWRvbmx5IFRyYW5zYWN0aW9uW10sXG4pOiBQcm9taXNlPHJlYWRvbmx5IEVDUG9pbnRbXT4gPT4ge1xuICBjb25zdCBjYWNoZSA9IG5ldyBWYWxpZGF0b3JDYWNoZShibG9ja2NoYWluKTtcbiAgYXdhaXQgUHJvbWlzZS5hbGwodHJhbnNhY3Rpb25zLm1hcChhc3luYyAodHJhbnNhY3Rpb24pID0+IHByb2Nlc3NUcmFuc2FjdGlvbihibG9ja2NoYWluLCBjYWNoZSwgdHJhbnNhY3Rpb24pKSk7XG5cbiAgY29uc3QgeyB2YWxpZGF0b3JDaGFuZ2VzLCB2YWxpZGF0b3JzQ291bnRDaGFuZ2VzIH0gPSBhd2FpdCBnZXREZXNjcmlwdG9yQ2hhbmdlcyh7XG4gICAgdHJhbnNhY3Rpb25zOiB0cmFuc2FjdGlvbnMuZmlsdGVyKFxuICAgICAgKHRyYW5zYWN0aW9uKTogdHJhbnNhY3Rpb24gaXMgU3RhdGVUcmFuc2FjdGlvbiA9PlxuICAgICAgICB0cmFuc2FjdGlvbi50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3RhdGUgJiYgdHJhbnNhY3Rpb24gaW5zdGFuY2VvZiBTdGF0ZVRyYW5zYWN0aW9uLFxuICAgICksXG5cbiAgICBnZXRBY2NvdW50OiBhc3luYyAoaGFzaCkgPT4gY2FjaGUuZ2V0QWNjb3VudChoYXNoKSxcbiAgICBnb3Zlcm5pbmdUb2tlbkhhc2g6IGJsb2NrY2hhaW4uc2V0dGluZ3MuZ292ZXJuaW5nVG9rZW4uaGFzaEhleCxcbiAgfSk7XG5cbiAgYXdhaXQgcHJvY2Vzc1N0YXRlVHJhbnNhY3Rpb24oe1xuICAgIHZhbGlkYXRvckNoYW5nZXMsXG4gICAgdmFsaWRhdG9yc0NvdW50Q2hhbmdlcyxcbiAgICB0cnlHZXRWYWxpZGF0b3JzQ291bnQ6IGFzeW5jICgpID0+IGNhY2hlLmdldFZhbGlkYXRvcnNDb3VudCgpLFxuICAgIGFkZFZhbGlkYXRvcnNDb3VudDogYXN5bmMgKHZhbHVlKSA9PiBjYWNoZS5hZGRWYWxpZGF0b3JzQ291bnQodmFsdWUpLFxuICAgIHVwZGF0ZVZhbGlkYXRvcnNDb3VudDogYXN5bmMgKHVwZGF0ZSkgPT4ge1xuICAgICAgYXdhaXQgY2FjaGUudXBkYXRlVmFsaWRhdG9yc0NvdW50KHVwZGF0ZSk7XG4gICAgfSxcbiAgICB0cnlHZXRWYWxpZGF0b3I6IGFzeW5jIChrZXkpID0+IGNhY2hlLmdldFZhbGlkYXRvcihrZXkucHVibGljS2V5KSxcbiAgICBhZGRWYWxpZGF0b3I6IGFzeW5jICh2YWxpZGF0b3IpID0+IGNhY2hlLmFkZFZhbGlkYXRvcih2YWxpZGF0b3IpLFxuICAgIGRlbGV0ZVZhbGlkYXRvcjogYXN5bmMgKGtleSkgPT4gY2FjaGUuZGVsZXRlVmFsaWRhdG9yKGtleS5wdWJsaWNLZXkpLFxuICAgIHVwZGF0ZVZhbGlkYXRvcjogYXN5bmMgKHZhbHVlLCB1cGRhdGUpID0+IGNhY2hlLnVwZGF0ZVZhbGlkYXRvcih2YWx1ZS5wdWJsaWNLZXksIHVwZGF0ZSksXG4gIH0pO1xuXG4gIGNvbnN0IFt2YWxpZGF0b3JzQ291bnQsIHZhbGlkYXRvcnNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW2NhY2hlLmdldFZhbGlkYXRvcnNDb3VudCgpLCBjYWNoZS5nZXRBbGxWYWxpZGF0b3JzKCldKTtcblxuICBjb25zdCBudW1WYWxpZGF0b3JzID0gTWF0aC5tYXgoXG4gICAgdXRpbHMud2VpZ2h0ZWRBdmVyYWdlKFxuICAgICAgdXRpbHNcbiAgICAgICAgLndlaWdodGVkRmlsdGVyKFxuICAgICAgICAgIHZhbGlkYXRvcnNDb3VudC52b3Rlc1xuICAgICAgICAgICAgLm1hcCgodm90ZXMsIGNvdW50KSA9PiAoeyBjb3VudCwgdm90ZXM6IHZvdGVzID09PSB1bmRlZmluZWQgPyB1dGlscy5aRVJPIDogdm90ZXMgfSkpXG4gICAgICAgICAgICAuZmlsdGVyKCh7IHZvdGVzIH0pID0+IHZvdGVzLmd0KHV0aWxzLlpFUk8pKSxcbiAgICAgICAgICAwLjI1LFxuICAgICAgICAgIDAuNzUsXG4gICAgICAgICAgKHsgY291bnQgfSkgPT4gbmV3IEJOKGNvdW50KSxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChbeyBjb3VudCB9LCB3ZWlnaHRdKSA9PiAoeyB2YWx1ZTogY291bnQsIHdlaWdodCB9KSksXG4gICAgKSxcblxuICAgIGJsb2NrY2hhaW4uc2V0dGluZ3Muc3RhbmRieVZhbGlkYXRvcnMubGVuZ3RoLFxuICApO1xuXG4gIGNvbnN0IHN0YW5kYnlWYWxpZGF0b3JzU2V0ID0gbmV3IFNldChcbiAgICBibG9ja2NoYWluLnNldHRpbmdzLnN0YW5kYnlWYWxpZGF0b3JzLm1hcCgocHVibGljS2V5KSA9PiBjb21tb24uZWNQb2ludFRvSGV4KHB1YmxpY0tleSkpLFxuICApO1xuXG4gIGNvbnN0IHZhbGlkYXRvcnNQdWJsaWNLZXlTZXQgPSBuZXcgU2V0KFxuICAgIF8udGFrZShcbiAgICAgIHZhbGlkYXRvcnNcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAodmFsaWRhdG9yKSA9PlxuICAgICAgICAgICAgKHZhbGlkYXRvci5yZWdpc3RlcmVkICYmIHZhbGlkYXRvci52b3Rlcy5ndCh1dGlscy5aRVJPKSkgfHxcbiAgICAgICAgICAgIHN0YW5kYnlWYWxpZGF0b3JzU2V0Lmhhcyhjb21tb24uZWNQb2ludFRvSGV4KHZhbGlkYXRvci5wdWJsaWNLZXkpKSxcbiAgICAgICAgKVxuICAgICAgICAuc29ydCgoYVZhbGlkYXRvciwgYlZhbGlkYXRvcikgPT5cbiAgICAgICAgICBhVmFsaWRhdG9yLnZvdGVzLmVxKGJWYWxpZGF0b3Iudm90ZXMpXG4gICAgICAgICAgICA/IGNvbW1vbi5lY1BvaW50Q29tcGFyZShhVmFsaWRhdG9yLnB1YmxpY0tleSwgYlZhbGlkYXRvci5wdWJsaWNLZXkpXG4gICAgICAgICAgICA6IC1hVmFsaWRhdG9yLnZvdGVzLmNtcChiVmFsaWRhdG9yLnZvdGVzKSxcbiAgICAgICAgKVxuICAgICAgICAubWFwKCh2YWxpZGF0b3IpID0+IGNvbW1vbi5lY1BvaW50VG9IZXgodmFsaWRhdG9yLnB1YmxpY0tleSkpLFxuICAgICAgbnVtVmFsaWRhdG9ycyxcbiAgICApLFxuICApO1xuXG4gIGNvbnN0IHN0YW5kYnlWYWxpZGF0b3JzQXJyYXkgPSBbLi4uc3RhbmRieVZhbGlkYXRvcnNTZXRdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YW5kYnlWYWxpZGF0b3JzQXJyYXkubGVuZ3RoICYmIHZhbGlkYXRvcnNQdWJsaWNLZXlTZXQuc2l6ZSA8IG51bVZhbGlkYXRvcnM7IGkgKz0gMSkge1xuICAgIHZhbGlkYXRvcnNQdWJsaWNLZXlTZXQuYWRkKHN0YW5kYnlWYWxpZGF0b3JzQXJyYXlbaV0pO1xuICB9XG5cbiAgY29uc3QgdmFsaWRhdG9yc1B1YmxpY0tleXMgPSBbLi4udmFsaWRhdG9yc1B1YmxpY0tleVNldF0ubWFwKChoZXgpID0+IGNvbW1vbi5oZXhUb0VDUG9pbnQoaGV4KSk7XG5cbiAgcmV0dXJuIHZhbGlkYXRvcnNQdWJsaWNLZXlzLnNvcnQoKGFLZXksIGJLZXkpID0+IGNvbW1vbi5lY1BvaW50Q29tcGFyZShhS2V5LCBiS2V5KSk7XG59O1xuIl19
|