@bitgo-beta/sdk-coin-sui 3.0.3-beta.182 → 3.0.3-beta.1821
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/dist/src/lib/compareTransactionBlocks.js +2 -3
- package/dist/src/lib/constants.d.ts +9 -2
- package/dist/src/lib/constants.d.ts.map +1 -1
- package/dist/src/lib/constants.js +18 -2
- package/dist/src/lib/customTransaction.js +3 -3
- package/dist/src/lib/customTransactionBuilder.js +5 -5
- package/dist/src/lib/iface.d.ts +80 -12
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +34 -5
- package/dist/src/lib/index.d.ts +6 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +36 -10
- package/dist/src/lib/keyPair.js +24 -10
- package/dist/src/lib/mystenlab/builder/Inputs.d.ts +64 -11
- package/dist/src/lib/mystenlab/builder/Inputs.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/Inputs.js +63 -19
- package/dist/src/lib/mystenlab/builder/TransactionBlock.d.ts +88 -355
- package/dist/src/lib/mystenlab/builder/TransactionBlock.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/TransactionBlock.js +44 -25
- package/dist/src/lib/mystenlab/builder/TransactionDataBlock.d.ts +152 -77
- package/dist/src/lib/mystenlab/builder/TransactionDataBlock.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/TransactionDataBlock.js +54 -44
- package/dist/src/lib/mystenlab/builder/Transactions.d.ts +133 -188
- package/dist/src/lib/mystenlab/builder/Transactions.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/Transactions.js +52 -53
- package/dist/src/lib/mystenlab/builder/bcs.d.ts +1 -1
- package/dist/src/lib/mystenlab/builder/bcs.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/bcs.js +2 -2
- package/dist/src/lib/mystenlab/builder/index.js +6 -2
- package/dist/src/lib/mystenlab/builder/serializer.js +6 -8
- package/dist/src/lib/mystenlab/builder/utils.d.ts +1 -1
- package/dist/src/lib/mystenlab/builder/utils.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/builder/utils.js +4 -4
- package/dist/src/lib/mystenlab/cryptography/hash.js +3 -4
- package/dist/src/lib/mystenlab/framework/framework.d.ts +6 -6
- package/dist/src/lib/mystenlab/framework/framework.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/framework/framework.js +22 -25
- package/dist/src/lib/mystenlab/framework/index.js +6 -2
- package/dist/src/lib/mystenlab/framework/sui-system-state.js +2 -2
- package/dist/src/lib/mystenlab/txn-data-serializers/type-tag-serializer.js +2 -2
- package/dist/src/lib/mystenlab/types/coin.d.ts +13 -11
- package/dist/src/lib/mystenlab/types/coin.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/coin.js +20 -19
- package/dist/src/lib/mystenlab/types/common.d.ts +8 -8
- package/dist/src/lib/mystenlab/types/common.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/common.js +22 -22
- package/dist/src/lib/mystenlab/types/events.d.ts +15 -15
- package/dist/src/lib/mystenlab/types/events.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/events.js +17 -17
- package/dist/src/lib/mystenlab/types/index.js +6 -2
- package/dist/src/lib/mystenlab/types/normalized.d.ts +21 -21
- package/dist/src/lib/mystenlab/types/normalized.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/normalized.js +41 -41
- package/dist/src/lib/mystenlab/types/objects.d.ts +51 -51
- package/dist/src/lib/mystenlab/types/objects.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/objects.js +96 -106
- package/dist/src/lib/mystenlab/types/option.d.ts +1 -1
- package/dist/src/lib/mystenlab/types/option.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/option.js +2 -3
- package/dist/src/lib/mystenlab/types/sui-bcs.d.ts +55 -29
- package/dist/src/lib/mystenlab/types/sui-bcs.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/sui-bcs.js +29 -5
- package/dist/src/lib/mystenlab/types/transactions.d.ts +625 -625
- package/dist/src/lib/mystenlab/types/transactions.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/transactions.js +178 -194
- package/dist/src/lib/mystenlab/types/validator.d.ts +13 -13
- package/dist/src/lib/mystenlab/types/validator.d.ts.map +1 -1
- package/dist/src/lib/mystenlab/types/validator.js +124 -124
- package/dist/src/lib/resources/walrusConfig.d.ts +22 -0
- package/dist/src/lib/resources/walrusConfig.d.ts.map +1 -0
- package/dist/src/lib/resources/walrusConfig.js +37 -0
- package/dist/src/lib/rpcClient.d.ts +5 -0
- package/dist/src/lib/rpcClient.d.ts.map +1 -0
- package/dist/src/lib/rpcClient.js +74 -0
- package/dist/src/lib/stakingBuilder.d.ts.map +1 -1
- package/dist/src/lib/stakingBuilder.js +23 -7
- package/dist/src/lib/stakingTransaction.d.ts +0 -1
- package/dist/src/lib/stakingTransaction.d.ts.map +1 -1
- package/dist/src/lib/stakingTransaction.js +26 -15
- package/dist/src/lib/tokenTransferBuilder.d.ts +66 -0
- package/dist/src/lib/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/src/lib/tokenTransferBuilder.js +202 -0
- package/dist/src/lib/tokenTransferTransaction.d.ts +59 -0
- package/dist/src/lib/tokenTransferTransaction.d.ts.map +1 -0
- package/dist/src/lib/tokenTransferTransaction.js +272 -0
- package/dist/src/lib/transaction.d.ts +21 -4
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +129 -17
- package/dist/src/lib/transactionBuilder.d.ts +13 -4
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +34 -4
- package/dist/src/lib/transactionBuilderFactory.d.ts +11 -2
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +32 -1
- package/dist/src/lib/transferBuilder.d.ts +58 -1
- package/dist/src/lib/transferBuilder.d.ts.map +1 -1
- package/dist/src/lib/transferBuilder.js +310 -24
- package/dist/src/lib/transferTransaction.d.ts +6 -1
- package/dist/src/lib/transferTransaction.d.ts.map +1 -1
- package/dist/src/lib/transferTransaction.js +129 -12
- package/dist/src/lib/unstakingBuilder.js +6 -6
- package/dist/src/lib/unstakingTransaction.d.ts +0 -1
- package/dist/src/lib/unstakingTransaction.d.ts.map +1 -1
- package/dist/src/lib/unstakingTransaction.js +31 -17
- package/dist/src/lib/utils.d.ts +24 -3
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +254 -21
- package/dist/src/lib/walrusStakingBuilder.d.ts +66 -0
- package/dist/src/lib/walrusStakingBuilder.d.ts.map +1 -0
- package/dist/src/lib/walrusStakingBuilder.js +200 -0
- package/dist/src/lib/walrusStakingTransaction.d.ts +52 -0
- package/dist/src/lib/walrusStakingTransaction.d.ts.map +1 -0
- package/dist/src/lib/walrusStakingTransaction.js +269 -0
- package/dist/src/lib/walrusWithdrawStakeBuilder.d.ts +36 -0
- package/dist/src/lib/walrusWithdrawStakeBuilder.d.ts.map +1 -0
- package/dist/src/lib/walrusWithdrawStakeBuilder.js +173 -0
- package/dist/src/lib/walrusWithdrawStakeTransaction.d.ts +21 -0
- package/dist/src/lib/walrusWithdrawStakeTransaction.d.ts.map +1 -0
- package/dist/src/lib/walrusWithdrawStakeTransaction.js +190 -0
- package/dist/src/register.d.ts.map +1 -1
- package/dist/src/register.js +5 -1
- package/dist/src/sui.d.ts +46 -8
- package/dist/src/sui.d.ts.map +1 -1
- package/dist/src/sui.js +525 -37
- package/dist/src/suiToken.d.ts +22 -0
- package/dist/src/suiToken.d.ts.map +1 -0
- package/dist/src/suiToken.js +61 -0
- package/dist/src/tsui.js +1 -1
- package/dist/test/integration/index.d.ts +1 -0
- package/dist/test/integration/index.d.ts.map +1 -0
- package/dist/test/integration/index.js +1 -0
- package/dist/test/local_fullnode/RpcClient.d.ts +60 -0
- package/dist/test/local_fullnode/RpcClient.d.ts.map +1 -0
- package/dist/test/local_fullnode/RpcClient.js +111 -0
- package/dist/test/local_fullnode/faucet.d.ts +6 -0
- package/dist/test/local_fullnode/faucet.d.ts.map +1 -0
- package/dist/test/local_fullnode/faucet.js +17 -0
- package/dist/test/local_fullnode/transactions.d.ts +2 -0
- package/dist/test/local_fullnode/transactions.d.ts.map +1 -0
- package/dist/test/local_fullnode/transactions.js +190 -0
- package/dist/test/resources/sui.d.ts +458 -0
- package/dist/test/resources/sui.d.ts.map +1 -0
- package/dist/test/resources/sui.js +632 -0
- package/dist/test/unit/compareTransactionBlocks.d.ts +2 -0
- package/dist/test/unit/compareTransactionBlocks.d.ts.map +1 -0
- package/dist/test/unit/compareTransactionBlocks.js +64 -0
- package/dist/test/unit/getBuilderFactory.d.ts +3 -0
- package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
- package/dist/test/unit/getBuilderFactory.js +10 -0
- package/dist/test/unit/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +72 -0
- package/dist/test/unit/sui.d.ts +2 -0
- package/dist/test/unit/sui.d.ts.map +1 -0
- package/dist/test/unit/sui.js +2423 -0
- package/dist/test/unit/suiToken.d.ts +2 -0
- package/dist/test/unit/suiToken.d.ts.map +1 -0
- package/dist/test/unit/suiToken.js +39 -0
- package/dist/test/unit/transactionBuilder/customTransactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/customTransactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/customTransactionBuilder.js +106 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/stakingBuilder.js +152 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +255 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transactionBuilder.js +639 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/transferBuilder.js +1055 -0
- package/dist/test/unit/transactionBuilder/unstakingBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/unstakingBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/unstakingBuilder.js +115 -0
- package/dist/test/unit/transactionBuilder/walrusStakingBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/walrusStakingBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/walrusStakingBuilder.js +162 -0
- package/dist/test/unit/transactionBuilder/walrusWithdrawBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/walrusWithdrawBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/walrusWithdrawBuilder.js +181 -0
- package/dist/test/unit/transferTransaction.d.ts +2 -0
- package/dist/test/unit/transferTransaction.d.ts.map +1 -0
- package/dist/test/unit/transferTransaction.js +94 -0
- package/dist/test/unit/utils.d.ts +2 -0
- package/dist/test/unit/utils.d.ts.map +1 -0
- package/dist/test/unit/utils.js +186 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +16 -12
- package/.eslintignore +0 -6
- package/.mocharc.yml +0 -7
- package/CHANGELOG.md +0 -420
package/dist/src/sui.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -11,25 +15,38 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
11
15
|
}) : function(o, v) {
|
|
12
16
|
o["default"] = v;
|
|
13
17
|
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
21
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
37
|
};
|
|
24
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
39
|
exports.Sui = void 0;
|
|
40
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
26
41
|
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
27
42
|
const statics_1 = require("@bitgo-beta/statics");
|
|
28
43
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
29
44
|
const lib_1 = require("./lib");
|
|
30
45
|
const utils_1 = __importDefault(require("./lib/utils"));
|
|
31
46
|
const _ = __importStar(require("lodash"));
|
|
32
|
-
const
|
|
47
|
+
const iface_1 = require("./lib/iface");
|
|
48
|
+
const constants_1 = require("./lib/constants");
|
|
49
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
33
50
|
class Sui extends sdk_core_1.BaseCoin {
|
|
34
51
|
constructor(bitgo, staticsCoin) {
|
|
35
52
|
super(bitgo);
|
|
@@ -56,10 +73,17 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
56
73
|
getFullName() {
|
|
57
74
|
return 'Sui';
|
|
58
75
|
}
|
|
76
|
+
getNetwork() {
|
|
77
|
+
return this._staticsCoin.network;
|
|
78
|
+
}
|
|
59
79
|
/** @inheritDoc */
|
|
60
80
|
supportsTss() {
|
|
61
81
|
return true;
|
|
62
82
|
}
|
|
83
|
+
/** inherited doc */
|
|
84
|
+
getDefaultMultisigType() {
|
|
85
|
+
return sdk_core_1.multisigTypes.tss;
|
|
86
|
+
}
|
|
63
87
|
getMPCAlgorithm() {
|
|
64
88
|
return 'eddsa';
|
|
65
89
|
}
|
|
@@ -67,11 +91,10 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
67
91
|
return true;
|
|
68
92
|
}
|
|
69
93
|
async verifyTransaction(params) {
|
|
70
|
-
var _a;
|
|
71
94
|
let totalAmount = new bignumber_js_1.default(0);
|
|
72
95
|
const coinConfig = statics_1.coins.get(this.getChain());
|
|
73
|
-
const { txPrebuild: txPrebuild, txParams: txParams } = params;
|
|
74
|
-
const transaction = new
|
|
96
|
+
const { txPrebuild: txPrebuild, txParams: txParams, verification, wallet } = params;
|
|
97
|
+
const transaction = new lib_1.TransferTransaction(coinConfig);
|
|
75
98
|
const rawTx = txPrebuild.txHex;
|
|
76
99
|
if (!rawTx) {
|
|
77
100
|
throw new Error('missing required tx prebuild property txHex');
|
|
@@ -79,7 +102,7 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
79
102
|
transaction.fromRawTransaction(Buffer.from(rawTx, 'hex').toString('base64'));
|
|
80
103
|
const explainedTx = transaction.explainTransaction();
|
|
81
104
|
if (txParams.recipients && txParams.recipients.length > 0) {
|
|
82
|
-
const filteredRecipients =
|
|
105
|
+
const filteredRecipients = txParams.recipients?.map((recipient) => {
|
|
83
106
|
const filteredRecipient = _.pick(recipient, ['address', 'amount']);
|
|
84
107
|
filteredRecipient.amount = new bignumber_js_1.default(filteredRecipient.amount).toFixed();
|
|
85
108
|
return filteredRecipient;
|
|
@@ -99,47 +122,42 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
99
122
|
throw new Error('Tx total amount does not match with expected total amount field');
|
|
100
123
|
}
|
|
101
124
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
if (!keychains) {
|
|
110
|
-
throw new Error('missing required param keychains');
|
|
111
|
-
}
|
|
112
|
-
for (const keychain of keychains) {
|
|
113
|
-
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
114
|
-
const commonKeychain = keychain.commonKeychain;
|
|
115
|
-
const derivationPath = 'm/' + index;
|
|
116
|
-
const derivedPublicKey = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
|
|
117
|
-
const expectedAddress = this.getAddressFromPublicKey(derivedPublicKey);
|
|
118
|
-
if (newAddress !== expectedAddress) {
|
|
119
|
-
return false;
|
|
125
|
+
if (verification?.consolidationToBaseAddress) {
|
|
126
|
+
const baseAddress = wallet.coinSpecific()?.baseAddress || wallet.coinSpecific()?.rootAddress;
|
|
127
|
+
for (const output of explainedTx.outputs) {
|
|
128
|
+
if (output.address !== baseAddress) {
|
|
129
|
+
throw new Error('Consolidation transaction output address does not match wallet base address');
|
|
130
|
+
}
|
|
120
131
|
}
|
|
121
132
|
}
|
|
122
133
|
return true;
|
|
123
134
|
}
|
|
135
|
+
async isWalletAddress(params) {
|
|
136
|
+
return (0, sdk_core_1.verifyEddsaTssWalletAddress)(params, (address) => this.isValidAddress(address), (publicKey) => this.getAddressFromPublicKey(publicKey));
|
|
137
|
+
}
|
|
124
138
|
async parseTransaction(params) {
|
|
125
139
|
const transactionExplanation = await this.explainTransaction({ txHex: params.txHex });
|
|
126
140
|
if (!transactionExplanation) {
|
|
127
141
|
throw new Error('Invalid transaction');
|
|
128
142
|
}
|
|
143
|
+
let fee = new bignumber_js_1.default(0);
|
|
129
144
|
const suiTransaction = transactionExplanation;
|
|
130
145
|
if (suiTransaction.outputs.length <= 0) {
|
|
131
146
|
return {
|
|
132
147
|
inputs: [],
|
|
133
148
|
outputs: [],
|
|
149
|
+
fee,
|
|
134
150
|
};
|
|
135
151
|
}
|
|
136
152
|
const senderAddress = suiTransaction.outputs[0].address;
|
|
137
|
-
|
|
153
|
+
if (suiTransaction.fee.fee !== '') {
|
|
154
|
+
fee = new bignumber_js_1.default(suiTransaction.fee.fee);
|
|
155
|
+
}
|
|
138
156
|
// assume 1 sender, who is also the fee payer
|
|
139
157
|
const inputs = [
|
|
140
158
|
{
|
|
141
159
|
address: senderAddress,
|
|
142
|
-
amount: new bignumber_js_1.default(suiTransaction.outputAmount).plus(
|
|
160
|
+
amount: new bignumber_js_1.default(suiTransaction.outputAmount).plus(fee).toFixed(),
|
|
143
161
|
},
|
|
144
162
|
];
|
|
145
163
|
const outputs = suiTransaction.outputs.map((output) => {
|
|
@@ -151,6 +169,7 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
151
169
|
return {
|
|
152
170
|
inputs,
|
|
153
171
|
outputs,
|
|
172
|
+
fee,
|
|
154
173
|
};
|
|
155
174
|
}
|
|
156
175
|
generateKeyPair(seed) {
|
|
@@ -164,16 +183,16 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
164
183
|
prv: keys.prv,
|
|
165
184
|
};
|
|
166
185
|
}
|
|
167
|
-
isValidPub(
|
|
186
|
+
isValidPub(_) {
|
|
168
187
|
throw new Error('Method not implemented.');
|
|
169
188
|
}
|
|
170
|
-
isValidPrv(
|
|
189
|
+
isValidPrv(_) {
|
|
171
190
|
throw new Error('Method not implemented.');
|
|
172
191
|
}
|
|
173
192
|
isValidAddress(address) {
|
|
174
193
|
return utils_1.default.isValidAddress(address);
|
|
175
194
|
}
|
|
176
|
-
signTransaction(
|
|
195
|
+
signTransaction(_) {
|
|
177
196
|
throw new Error('Method not implemented.');
|
|
178
197
|
}
|
|
179
198
|
/**
|
|
@@ -205,6 +224,475 @@ class Sui extends sdk_core_1.BaseCoin {
|
|
|
205
224
|
const rebuiltTransaction = await factory.from(serializedTx).build();
|
|
206
225
|
return rebuiltTransaction.signablePayload;
|
|
207
226
|
}
|
|
227
|
+
getPublicNodeUrl() {
|
|
228
|
+
return sdk_core_1.Environments[this.bitgo.getEnv()].suiNodeUrl;
|
|
229
|
+
}
|
|
230
|
+
async getBalance(owner, coinType) {
|
|
231
|
+
const url = this.getPublicNodeUrl();
|
|
232
|
+
return await utils_1.default.getBalance(url, owner, coinType);
|
|
233
|
+
}
|
|
234
|
+
async getInputCoins(owner, coinType) {
|
|
235
|
+
const url = this.getPublicNodeUrl();
|
|
236
|
+
return await utils_1.default.getInputCoins(url, owner, coinType);
|
|
237
|
+
}
|
|
238
|
+
async getFeeEstimate(txHex) {
|
|
239
|
+
const url = this.getPublicNodeUrl();
|
|
240
|
+
return await utils_1.default.getFeeEstimate(url, txHex);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Builds funds recovery transaction(s) without BitGo
|
|
244
|
+
*
|
|
245
|
+
* @param {MPCRecoveryOptions} params parameters needed to construct and
|
|
246
|
+
* (maybe) sign the transaction
|
|
247
|
+
*
|
|
248
|
+
* @returns {MPCTx | MPCSweepTxs} array of the serialized transaction hex strings and indices
|
|
249
|
+
* of the addresses being swept
|
|
250
|
+
*/
|
|
251
|
+
async recover(params) {
|
|
252
|
+
if (!params.bitgoKey) {
|
|
253
|
+
throw new Error('missing bitgoKey');
|
|
254
|
+
}
|
|
255
|
+
if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
|
|
256
|
+
throw new Error('invalid recoveryDestination');
|
|
257
|
+
}
|
|
258
|
+
const startIdx = utils_1.default.validateNonNegativeNumber(0, 'Invalid starting index to scan for addresses', params.startingScanIndex);
|
|
259
|
+
const numIterations = utils_1.default.validateNonNegativeNumber(20, 'Invalid scanning factor', params.scan);
|
|
260
|
+
const endIdx = startIdx + numIterations;
|
|
261
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
262
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
263
|
+
for (let idx = startIdx; idx < endIdx; idx++) {
|
|
264
|
+
const derivationPath = (params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) : 'm') + `/${idx}`;
|
|
265
|
+
const derivedPublicKey = MPC.deriveUnhardened(bitgoKey, derivationPath).slice(0, 64);
|
|
266
|
+
const senderAddress = this.getAddressFromPublicKey(derivedPublicKey);
|
|
267
|
+
let availableBalance = new bignumber_js_1.default(0);
|
|
268
|
+
let fundsInAddressBalance = new bignumber_js_1.default(0);
|
|
269
|
+
try {
|
|
270
|
+
const balanceInfo = await this.getBalance(senderAddress);
|
|
271
|
+
availableBalance = new bignumber_js_1.default(balanceInfo.totalBalance);
|
|
272
|
+
fundsInAddressBalance = new bignumber_js_1.default(balanceInfo.fundsInAddressBalance);
|
|
273
|
+
}
|
|
274
|
+
catch (e) {
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (availableBalance.minus(constants_1.MAX_GAS_BUDGET).toNumber() <= 0) {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
// check for possible token recovery, recover the token provide by user
|
|
281
|
+
if (params.tokenContractAddress) {
|
|
282
|
+
const token = utils_1.default.getSuiTokenFromAddress(params.tokenContractAddress, this.getNetwork());
|
|
283
|
+
if (!token) {
|
|
284
|
+
throw new Error(`Sui Token Package ID not supported.`);
|
|
285
|
+
}
|
|
286
|
+
const coinType = `${token.packageId}::${token.module}::${token.symbol}`;
|
|
287
|
+
try {
|
|
288
|
+
const tokenBalanceInfo = await this.getBalance(senderAddress, coinType);
|
|
289
|
+
const availableTokenBalance = new bignumber_js_1.default(tokenBalanceInfo.totalBalance);
|
|
290
|
+
if (availableTokenBalance.toNumber() <= 0) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch (e) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
return this.recoverSuiToken(params, token, senderAddress, derivationPath, derivedPublicKey, idx, bitgoKey);
|
|
298
|
+
}
|
|
299
|
+
let inputCoins = await this.getInputCoins(senderAddress);
|
|
300
|
+
inputCoins = inputCoins.sort((a, b) => {
|
|
301
|
+
return b.balance.minus(a.balance).toNumber();
|
|
302
|
+
});
|
|
303
|
+
if (inputCoins.length > constants_1.MAX_OBJECT_LIMIT) {
|
|
304
|
+
inputCoins = inputCoins.slice(0, constants_1.MAX_OBJECT_LIMIT);
|
|
305
|
+
}
|
|
306
|
+
// Include funds held in the address balance system (not in coin objects).
|
|
307
|
+
// When gasData.payment is non-empty, Path 2c merges the address balance into GasCoin.
|
|
308
|
+
// When gasData.payment is empty (address-balance only), Path 2b uses withdrawal+redeem_funds.
|
|
309
|
+
const coinObjectsBalance = inputCoins.reduce((acc, obj) => acc.plus(obj.balance), new bignumber_js_1.default(0));
|
|
310
|
+
let netAmount = coinObjectsBalance.plus(fundsInAddressBalance).minus(constants_1.MAX_GAS_BUDGET);
|
|
311
|
+
const recipients = [
|
|
312
|
+
{
|
|
313
|
+
address: params.recoveryDestination,
|
|
314
|
+
amount: netAmount.toString(),
|
|
315
|
+
},
|
|
316
|
+
];
|
|
317
|
+
// Case 2 self-funded: all balance is in address balance, no coin objects.
|
|
318
|
+
// gasData.payment must be [] and a ValidDuring expiration is required to
|
|
319
|
+
// prevent replay attacks when there are no gas coin objects to anchor uniqueness.
|
|
320
|
+
let validDuringExpiration;
|
|
321
|
+
if (fundsInAddressBalance.gt(0) && coinObjectsBalance.eq(0)) {
|
|
322
|
+
const { epoch, chainId } = await utils_1.default.getChainContext(this.getPublicNodeUrl());
|
|
323
|
+
const nonce = crypto_1.default.randomBytes(4).readUInt32BE(0);
|
|
324
|
+
validDuringExpiration = {
|
|
325
|
+
ValidDuring: {
|
|
326
|
+
minEpoch: { Some: epoch },
|
|
327
|
+
maxEpoch: { Some: epoch + 1 },
|
|
328
|
+
minTimestamp: { None: null },
|
|
329
|
+
maxTimestamp: { None: null },
|
|
330
|
+
chain: chainId,
|
|
331
|
+
nonce,
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
// first build the unsigned txn
|
|
336
|
+
const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
|
|
337
|
+
const txBuilder = factory
|
|
338
|
+
.getTransferBuilder()
|
|
339
|
+
.type(iface_1.SuiTransactionType.Transfer)
|
|
340
|
+
.sender(senderAddress)
|
|
341
|
+
.send(recipients)
|
|
342
|
+
.fundsInAddressBalance(fundsInAddressBalance.toString())
|
|
343
|
+
.gasData({
|
|
344
|
+
owner: senderAddress,
|
|
345
|
+
price: constants_1.DEFAULT_GAS_PRICE,
|
|
346
|
+
budget: constants_1.MAX_GAS_BUDGET,
|
|
347
|
+
payment: inputCoins,
|
|
348
|
+
});
|
|
349
|
+
if (validDuringExpiration) {
|
|
350
|
+
txBuilder.expiration(validDuringExpiration);
|
|
351
|
+
}
|
|
352
|
+
const tempTx = (await txBuilder.build());
|
|
353
|
+
const feeEstimate = await this.getFeeEstimate(tempTx.toBroadcastFormat());
|
|
354
|
+
const gasBudget = Math.trunc(feeEstimate.toNumber() * constants_1.DEFAULT_GAS_OVERHEAD);
|
|
355
|
+
netAmount = netAmount.plus(constants_1.MAX_GAS_BUDGET).minus(gasBudget);
|
|
356
|
+
recipients[0].amount = netAmount.toString();
|
|
357
|
+
txBuilder.send(recipients);
|
|
358
|
+
txBuilder.gasData({
|
|
359
|
+
owner: senderAddress,
|
|
360
|
+
price: constants_1.DEFAULT_GAS_PRICE,
|
|
361
|
+
budget: gasBudget,
|
|
362
|
+
payment: inputCoins,
|
|
363
|
+
});
|
|
364
|
+
const isUnsignedSweep = !params.walletPassphrase;
|
|
365
|
+
if (isUnsignedSweep) {
|
|
366
|
+
return this.buildUnsignedSweepTransaction(txBuilder, senderAddress, bitgoKey, idx, derivationPath);
|
|
367
|
+
}
|
|
368
|
+
await this.signRecoveryTransaction(txBuilder, params, derivationPath, derivedPublicKey, false);
|
|
369
|
+
const tx = (await txBuilder.build());
|
|
370
|
+
return {
|
|
371
|
+
transactions: [
|
|
372
|
+
{
|
|
373
|
+
scanIndex: idx,
|
|
374
|
+
recoveryAmount: netAmount.toString(),
|
|
375
|
+
serializedTx: tx.toBroadcastFormat(),
|
|
376
|
+
signature: Buffer.from(tx.serializedSig).toString('base64'),
|
|
377
|
+
coin: this.getChain(),
|
|
378
|
+
},
|
|
379
|
+
],
|
|
380
|
+
lastScanIndex: idx,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
throw new Error(`Did not find an address with sufficient funds to recover. Please start the next scan at address index ${endIdx}. If it is token transaction, please keep sufficient Sui balance in the address for the transaction fee.`);
|
|
384
|
+
}
|
|
385
|
+
async recoverSuiToken(params, token, senderAddress, derivationPath, derivedPublicKey, idx, bitgoKey) {
|
|
386
|
+
const coinType = `${token.packageId}::${token.module}::${token.symbol}`;
|
|
387
|
+
let tokenObjects = await this.getInputCoins(senderAddress, coinType);
|
|
388
|
+
tokenObjects = tokenObjects.sort((a, b) => {
|
|
389
|
+
return b.balance.minus(a.balance).toNumber();
|
|
390
|
+
});
|
|
391
|
+
if (tokenObjects.length > constants_1.TOKEN_OBJECT_LIMIT) {
|
|
392
|
+
tokenObjects = tokenObjects.slice(0, constants_1.TOKEN_OBJECT_LIMIT);
|
|
393
|
+
}
|
|
394
|
+
const coinObjectsBalance = tokenObjects.reduce((acc, obj) => acc.plus(obj.balance), new bignumber_js_1.default(0));
|
|
395
|
+
const tokenBalanceInfo = await this.getBalance(senderAddress, coinType);
|
|
396
|
+
const tokenFundsInAddressBalance = new bignumber_js_1.default(tokenBalanceInfo.fundsInAddressBalance);
|
|
397
|
+
const netAmount = coinObjectsBalance.plus(tokenFundsInAddressBalance);
|
|
398
|
+
const recipients = [
|
|
399
|
+
{
|
|
400
|
+
address: params.recoveryDestination,
|
|
401
|
+
amount: netAmount.toString(),
|
|
402
|
+
},
|
|
403
|
+
];
|
|
404
|
+
const gasAmount = new bignumber_js_1.default(constants_1.MAX_GAS_BUDGET);
|
|
405
|
+
let gasObjects = await this.getInputCoins(senderAddress);
|
|
406
|
+
gasObjects = utils_1.default.selectObjectsInDescOrderOfBalance(gasObjects, gasAmount);
|
|
407
|
+
if (gasObjects.length >= constants_1.MAX_GAS_OBJECTS) {
|
|
408
|
+
gasObjects = gasObjects.slice(0, constants_1.MAX_GAS_OBJECTS - 1);
|
|
409
|
+
}
|
|
410
|
+
// first build the unsigned txn
|
|
411
|
+
const factory = new lib_1.TransactionBuilderFactory(token);
|
|
412
|
+
const txBuilder = factory
|
|
413
|
+
.getTokenTransferBuilder()
|
|
414
|
+
.type(iface_1.SuiTransactionType.TokenTransfer)
|
|
415
|
+
.sender(senderAddress)
|
|
416
|
+
.send(recipients)
|
|
417
|
+
.fundsInAddressBalance(tokenFundsInAddressBalance.toString())
|
|
418
|
+
.gasData({
|
|
419
|
+
owner: senderAddress,
|
|
420
|
+
price: constants_1.DEFAULT_GAS_PRICE,
|
|
421
|
+
budget: constants_1.MAX_GAS_BUDGET,
|
|
422
|
+
payment: gasObjects,
|
|
423
|
+
});
|
|
424
|
+
if (tokenObjects.length > 0) {
|
|
425
|
+
txBuilder.inputObjects(tokenObjects);
|
|
426
|
+
}
|
|
427
|
+
const tempTx = (await txBuilder.build());
|
|
428
|
+
const feeEstimate = await this.getFeeEstimate(tempTx.toBroadcastFormat());
|
|
429
|
+
const gasBudget = Math.trunc(feeEstimate.toNumber() * constants_1.DEFAULT_GAS_OVERHEAD);
|
|
430
|
+
txBuilder.gasData({
|
|
431
|
+
owner: senderAddress,
|
|
432
|
+
price: constants_1.DEFAULT_GAS_PRICE,
|
|
433
|
+
budget: gasBudget,
|
|
434
|
+
payment: gasObjects,
|
|
435
|
+
});
|
|
436
|
+
const isUnsignedSweep = !params.walletPassphrase;
|
|
437
|
+
if (isUnsignedSweep) {
|
|
438
|
+
return this.buildUnsignedSweepTransaction(txBuilder, senderAddress, bitgoKey, idx, derivationPath, token);
|
|
439
|
+
}
|
|
440
|
+
await this.signRecoveryTransaction(txBuilder, params, derivationPath, derivedPublicKey, true);
|
|
441
|
+
const tx = (await txBuilder.build());
|
|
442
|
+
return {
|
|
443
|
+
transactions: [
|
|
444
|
+
{
|
|
445
|
+
scanIndex: idx,
|
|
446
|
+
recoveryAmount: netAmount.toString(),
|
|
447
|
+
serializedTx: tx.toBroadcastFormat(),
|
|
448
|
+
signature: Buffer.from(tx.serializedSig).toString('base64'),
|
|
449
|
+
coin: token.name,
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
lastScanIndex: idx,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
async buildUnsignedSweepTransaction(txBuilder, senderAddress, bitgoKey, index, derivationPath, token) {
|
|
456
|
+
const isTokenTransaction = !!token;
|
|
457
|
+
const unsignedTransaction = isTokenTransaction
|
|
458
|
+
? (await txBuilder.build())
|
|
459
|
+
: (await txBuilder.build());
|
|
460
|
+
const serializedTx = unsignedTransaction.toBroadcastFormat();
|
|
461
|
+
const serializedTxHex = Buffer.from(serializedTx, 'base64').toString('hex');
|
|
462
|
+
const parsedTx = await this.parseTransaction({ txHex: serializedTxHex });
|
|
463
|
+
const walletCoin = isTokenTransaction ? token.name : this.getChain();
|
|
464
|
+
const output = parsedTx.outputs[0];
|
|
465
|
+
const inputs = [
|
|
466
|
+
{
|
|
467
|
+
address: senderAddress,
|
|
468
|
+
valueString: output.amount,
|
|
469
|
+
value: new bignumber_js_1.default(output.amount),
|
|
470
|
+
},
|
|
471
|
+
];
|
|
472
|
+
const outputs = [
|
|
473
|
+
{
|
|
474
|
+
address: output.address,
|
|
475
|
+
valueString: output.amount,
|
|
476
|
+
coinName: walletCoin,
|
|
477
|
+
},
|
|
478
|
+
];
|
|
479
|
+
const spendAmount = output.amount;
|
|
480
|
+
const completedParsedTx = {
|
|
481
|
+
inputs: inputs,
|
|
482
|
+
outputs: outputs,
|
|
483
|
+
spendAmount: spendAmount,
|
|
484
|
+
type: isTokenTransaction ? iface_1.SuiTransactionType.TokenTransfer : iface_1.SuiTransactionType.Transfer,
|
|
485
|
+
};
|
|
486
|
+
const fee = parsedTx.fee;
|
|
487
|
+
const feeInfo = { fee: fee.toNumber(), feeString: fee.toString() };
|
|
488
|
+
const coinSpecific = { commonKeychain: bitgoKey };
|
|
489
|
+
const transaction = {
|
|
490
|
+
serializedTx: serializedTxHex,
|
|
491
|
+
scanIndex: index,
|
|
492
|
+
coin: walletCoin,
|
|
493
|
+
signableHex: unsignedTransaction.signablePayload.toString('hex'),
|
|
494
|
+
derivationPath,
|
|
495
|
+
parsedTx: completedParsedTx,
|
|
496
|
+
feeInfo: feeInfo,
|
|
497
|
+
coinSpecific: coinSpecific,
|
|
498
|
+
};
|
|
499
|
+
const unsignedTx = { unsignedTx: transaction, signatureShares: [] };
|
|
500
|
+
const transactions = [unsignedTx];
|
|
501
|
+
const txRequest = {
|
|
502
|
+
transactions: transactions,
|
|
503
|
+
walletCoin: walletCoin,
|
|
504
|
+
};
|
|
505
|
+
return { txRequests: [txRequest] };
|
|
506
|
+
}
|
|
507
|
+
async signRecoveryTransaction(txBuilder, params, derivationPath, derivedPublicKey, isTokenTransaction) {
|
|
508
|
+
// TODO(BG-51092): This looks like a common part which can be extracted out too
|
|
509
|
+
const unsignedTx = isTokenTransaction
|
|
510
|
+
? (await txBuilder.build())
|
|
511
|
+
: (await txBuilder.build());
|
|
512
|
+
if (!params.userKey) {
|
|
513
|
+
throw new Error('missing userKey');
|
|
514
|
+
}
|
|
515
|
+
if (!params.backupKey) {
|
|
516
|
+
throw new Error('missing backupKey');
|
|
517
|
+
}
|
|
518
|
+
if (!params.walletPassphrase) {
|
|
519
|
+
throw new Error('missing wallet passphrase');
|
|
520
|
+
}
|
|
521
|
+
// Clean up whitespace from entered values
|
|
522
|
+
const userKey = params.userKey.replace(/\s/g, '');
|
|
523
|
+
const backupKey = params.backupKey.replace(/\s/g, '');
|
|
524
|
+
// Decrypt private keys from KeyCard values
|
|
525
|
+
let userPrv;
|
|
526
|
+
try {
|
|
527
|
+
userPrv = await this.bitgo.decryptAsync({
|
|
528
|
+
input: userKey,
|
|
529
|
+
password: params.walletPassphrase,
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
catch (e) {
|
|
533
|
+
throw new Error(`Error decrypting user keychain: ${e.message}`);
|
|
534
|
+
}
|
|
535
|
+
/** TODO BG-52419 Implement Codec for parsing */
|
|
536
|
+
const userSigningMaterial = JSON.parse(userPrv);
|
|
537
|
+
let backupPrv;
|
|
538
|
+
try {
|
|
539
|
+
backupPrv = await this.bitgo.decryptAsync({
|
|
540
|
+
input: backupKey,
|
|
541
|
+
password: params.walletPassphrase,
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
catch (e) {
|
|
545
|
+
throw new Error(`Error decrypting backup keychain: ${e.message}`);
|
|
546
|
+
}
|
|
547
|
+
const backupSigningMaterial = JSON.parse(backupPrv);
|
|
548
|
+
/* ********************** END ***********************************/
|
|
549
|
+
// add signature
|
|
550
|
+
const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, derivationPath, unsignedTx);
|
|
551
|
+
txBuilder.addSignature({ pub: derivedPublicKey }, signatureHex);
|
|
552
|
+
}
|
|
553
|
+
async broadcastTransaction({ transactions, }) {
|
|
554
|
+
const txIds = [];
|
|
555
|
+
const url = this.getPublicNodeUrl();
|
|
556
|
+
let digest = '';
|
|
557
|
+
if (!!transactions) {
|
|
558
|
+
for (const txn of transactions) {
|
|
559
|
+
try {
|
|
560
|
+
digest = await utils_1.default.executeTransactionBlock(url, txn.serializedTx, [txn.signature]);
|
|
561
|
+
}
|
|
562
|
+
catch (e) {
|
|
563
|
+
throw new Error(`Failed to broadcast transaction, error: ${e.message}`);
|
|
564
|
+
}
|
|
565
|
+
txIds.push(digest);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return { txIds };
|
|
569
|
+
}
|
|
570
|
+
/** inherited doc */
|
|
571
|
+
async createBroadcastableSweepTransaction(params) {
|
|
572
|
+
const req = params.signatureShares;
|
|
573
|
+
const broadcastableTransactions = [];
|
|
574
|
+
let lastScanIndex = 0;
|
|
575
|
+
for (let i = 0; i < req.length; i++) {
|
|
576
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
577
|
+
const transaction = req[i].txRequest.transactions[0].unsignedTx;
|
|
578
|
+
if (!req[i].ovc || !req[i].ovc[0].eddsaSignature) {
|
|
579
|
+
throw new Error('Missing signature(s)');
|
|
580
|
+
}
|
|
581
|
+
const signature = req[i].ovc[0].eddsaSignature;
|
|
582
|
+
if (!transaction.signableHex) {
|
|
583
|
+
throw new Error('Missing signable hex');
|
|
584
|
+
}
|
|
585
|
+
const messageBuffer = Buffer.from(transaction.signableHex, 'hex');
|
|
586
|
+
const result = MPC.verify(messageBuffer, signature);
|
|
587
|
+
if (!result) {
|
|
588
|
+
throw new Error('Invalid signature');
|
|
589
|
+
}
|
|
590
|
+
const signatureHex = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
|
|
591
|
+
const serializedTxBase64 = Buffer.from(transaction.serializedTx, 'hex').toString('base64');
|
|
592
|
+
const txBuilder = this.getBuilder().from(serializedTxBase64);
|
|
593
|
+
if (!transaction.coinSpecific?.commonKeychain) {
|
|
594
|
+
throw new Error('Missing common keychain');
|
|
595
|
+
}
|
|
596
|
+
const commonKeychain = transaction.coinSpecific.commonKeychain;
|
|
597
|
+
if (!transaction.derivationPath) {
|
|
598
|
+
throw new Error('Missing derivation path');
|
|
599
|
+
}
|
|
600
|
+
const derivationPath = transaction.derivationPath;
|
|
601
|
+
const derivedPublicKey = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
|
|
602
|
+
// add combined signature from ovc
|
|
603
|
+
txBuilder.addSignature({ pub: derivedPublicKey }, signatureHex);
|
|
604
|
+
const signedTransaction = (await txBuilder.build());
|
|
605
|
+
const serializedTx = signedTransaction.toBroadcastFormat();
|
|
606
|
+
const outputAmount = signedTransaction.explainTransaction().outputAmount;
|
|
607
|
+
broadcastableTransactions.push({
|
|
608
|
+
serializedTx: serializedTx,
|
|
609
|
+
scanIndex: transaction.scanIndex,
|
|
610
|
+
signature: Buffer.from(signedTransaction.serializedSig).toString('base64'),
|
|
611
|
+
recoveryAmount: outputAmount.toString(),
|
|
612
|
+
});
|
|
613
|
+
if (i === req.length - 1 && transaction.coinSpecific.lastScanIndex) {
|
|
614
|
+
lastScanIndex = transaction.coinSpecific.lastScanIndex;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return { transactions: broadcastableTransactions, lastScanIndex };
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Builds native SUI recoveries of receive addresses in batch without BitGo.
|
|
621
|
+
* Funds will be recovered to base address first. You need to initiate another sweep txn after that.
|
|
622
|
+
*
|
|
623
|
+
* @param {MPCConsolidationRecoveryOptions} params - options for consolidation recovery.
|
|
624
|
+
* @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
|
|
625
|
+
* @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
|
|
626
|
+
*/
|
|
627
|
+
async recoverConsolidations(params) {
|
|
628
|
+
const isUnsignedSweep = !params.walletPassphrase;
|
|
629
|
+
const startIdx = utils_1.default.validateNonNegativeNumber(1, 'Invalid starting index to scan for addresses', params.startingScanIndex);
|
|
630
|
+
const endIdx = utils_1.default.validateNonNegativeNumber(startIdx + constants_1.DEFAULT_SCAN_FACTOR, 'Invalid ending index to scan for addresses', params.endingScanIndex);
|
|
631
|
+
if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * constants_1.DEFAULT_SCAN_FACTOR) {
|
|
632
|
+
throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
|
|
633
|
+
}
|
|
634
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
635
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
636
|
+
const derivationPath = (params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) : 'm') + '/0';
|
|
637
|
+
const derivedPublicKey = MPC.deriveUnhardened(bitgoKey, derivationPath).slice(0, 64);
|
|
638
|
+
const baseAddress = this.getAddressFromPublicKey(derivedPublicKey);
|
|
639
|
+
const consolidationTransactions = [];
|
|
640
|
+
let lastScanIndex = startIdx;
|
|
641
|
+
for (let idx = startIdx; idx < endIdx; idx++) {
|
|
642
|
+
const recoverParams = {
|
|
643
|
+
userKey: params.userKey,
|
|
644
|
+
backupKey: params.backupKey,
|
|
645
|
+
bitgoKey: params.bitgoKey,
|
|
646
|
+
walletPassphrase: params.walletPassphrase,
|
|
647
|
+
seed: params.seed,
|
|
648
|
+
tokenContractAddress: params.tokenContractAddress,
|
|
649
|
+
recoveryDestination: baseAddress,
|
|
650
|
+
startingScanIndex: idx,
|
|
651
|
+
scan: 1,
|
|
652
|
+
};
|
|
653
|
+
let recoveryTransaction;
|
|
654
|
+
try {
|
|
655
|
+
recoveryTransaction = await this.recover(recoverParams);
|
|
656
|
+
}
|
|
657
|
+
catch (e) {
|
|
658
|
+
if (e.message.startsWith('Did not find an address with sufficient funds to recover.')) {
|
|
659
|
+
lastScanIndex = idx;
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
throw e;
|
|
663
|
+
}
|
|
664
|
+
if (isUnsignedSweep) {
|
|
665
|
+
consolidationTransactions.push(recoveryTransaction.txRequests[0]);
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
consolidationTransactions.push(recoveryTransaction.transactions[0]);
|
|
669
|
+
}
|
|
670
|
+
lastScanIndex = idx;
|
|
671
|
+
}
|
|
672
|
+
if (consolidationTransactions.length === 0) {
|
|
673
|
+
throw new Error(`Did not find an address with sufficient funds to recover. Please start the next scan at address index ${lastScanIndex + 1}.`);
|
|
674
|
+
}
|
|
675
|
+
if (isUnsignedSweep) {
|
|
676
|
+
// lastScanIndex will be used to inform user the last address index scanned for available funds (so they can
|
|
677
|
+
// appropriately adjust the scan range on the next iteration of consolidation recoveries). In the case of unsigned
|
|
678
|
+
// sweep consolidations, this lastScanIndex will be provided in the coinSpecific of the last txn made.
|
|
679
|
+
consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific.lastScanIndex = lastScanIndex;
|
|
680
|
+
return { txRequests: consolidationTransactions };
|
|
681
|
+
}
|
|
682
|
+
return { transactions: consolidationTransactions, lastScanIndex };
|
|
683
|
+
}
|
|
684
|
+
/** inherited doc */
|
|
685
|
+
setCoinSpecificFieldsInIntent(intent, params) {
|
|
686
|
+
intent.unspents = params.unspents;
|
|
687
|
+
intent.fundsInAddressBalance = params.fundsInAddressBalance;
|
|
688
|
+
}
|
|
689
|
+
/** inherited doc */
|
|
690
|
+
auditDecryptedKey({ publicKey, prv, multiSigType }) {
|
|
691
|
+
if (multiSigType !== 'tss') {
|
|
692
|
+
throw new Error('Unsupported multiSigType');
|
|
693
|
+
}
|
|
694
|
+
(0, sdk_lib_mpc_1.auditEddsaPrivateKey)(prv, publicKey ?? '');
|
|
695
|
+
}
|
|
208
696
|
}
|
|
209
697
|
exports.Sui = Sui;
|
|
210
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N1aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsbURBZThCO0FBQzlCLGlEQUF5RTtBQUN6RSxnRUFBcUM7QUFDckMsK0JBQXlFO0FBQ3pFLHdEQUFnQztBQUNoQywwQ0FBNEI7QUFDNUIsbUVBQWdFO0FBMkJoRSxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUUvQixZQUFzQixLQUFnQixFQUFFLFdBQXVDO1FBQzdFLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1NBQ3ZFO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7SUFDbEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxhQUFhO1FBQ2xCLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVNLFFBQVE7UUFDYixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTSxTQUFTO1FBQ2QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU0sV0FBVztRQUNoQixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGVBQWU7UUFDYixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsMkJBQTJCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFnQzs7UUFDdEQsSUFBSSxXQUFXLEdBQUcsSUFBSSxzQkFB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Q2xCLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFvQjtRQUMzQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEUsT0FBTyxrQkFBa0IsQ0FBQyxlQUFlLENBQUM7SUFDNUMsQ0FBQztDQUNGO0FBck5ELGtCQXFOQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJhc2VDb2luLFxuICBCYXNlVHJhbnNhY3Rpb24sXG4gIEJpdEdvQmFzZSxcbiAgRUREU0FNZXRob2RzLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBLZXlQYWlyLFxuICBNUENBbGdvcml0aG0sXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUc3NWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4sIGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5LCBLZXlQYWlyIGFzIFN1aUtleVBhaXIgfSBmcm9tICcuL2xpYic7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgVHJhbnNmZXJUcmFuc2FjdGlvbiB9IGZyb20gJy4vbGliL3RyYW5zZmVyVHJhbnNhY3Rpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEhleDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN1aVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIGV4dGVuZHMgQmFzZVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhIZXg6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFRyYW5zYWN0aW9uT3V0cHV0IHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBhbW91bnQ6IHN0cmluZztcbn1cblxudHlwZSBUcmFuc2FjdGlvbklucHV0ID0gVHJhbnNhY3Rpb25PdXRwdXQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VpUGFyc2VkVHJhbnNhY3Rpb24gZXh0ZW5kcyBQYXJzZWRUcmFuc2FjdGlvbiB7XG4gIC8vIHRvdGFsIGFzc2V0cyBiZWluZyBtb3ZlZCwgaW5jbHVkaW5nIGZlZXNcbiAgaW5wdXRzOiBUcmFuc2FjdGlvbklucHV0W107XG5cbiAgLy8gd2hlcmUgYXNzZXRzIGFyZSBtb3ZlZCB0b1xuICBvdXRwdXRzOiBUcmFuc2FjdGlvbk91dHB1dFtdO1xufVxuXG5leHBvcnQgdHlwZSBTdWlUcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0gVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcblxuZXhwb3J0IGNsYXNzIFN1aSBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGF0aWNzQ29pbjogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPjtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IFN1aShiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhY3RvciBiZXR3ZWVuIHRoZSBjb2luJ3MgYmFzZSB1bml0IGFuZCBpdHMgc21hbGxlc3Qgc3ViZGl2aXNvblxuICAgKi9cbiAgcHVibGljIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gMWU5O1xuICB9XG5cbiAgcHVibGljIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdzdWknO1xuICB9XG5cbiAgcHVibGljIGdldEZhbWlseSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnc3VpJztcbiAgfVxuXG4gIHB1YmxpYyBnZXRGdWxsTmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnU3VpJztcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBzdXBwb3J0c1RzcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGdldE1QQ0FsZ29yaXRobSgpOiBNUENBbGdvcml0aG0ge1xuICAgIHJldHVybiAnZWRkc2EnO1xuICB9XG5cbiAgYWxsb3dzQWNjb3VudENvbnNvbGlkYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zOiBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgdG90YWxBbW91bnQgPSBuZXcgQmlnTnVtYmVyKDApO1xuICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKTtcbiAgICBjb25zdCB7IHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQsIHR4UGFyYW1zOiB0eFBhcmFtcyB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zZmVyVHJhbnNhY3Rpb24oY29pbkNvbmZpZyk7XG4gICAgY29uc3QgcmF3VHggPSB0eFByZWJ1aWxkLnR4SGV4O1xuICAgIGlmICghcmF3VHgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCB0eCBwcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgIH1cblxuICAgIHRyYW5zYWN0aW9uLmZyb21SYXdUcmFuc2FjdGlvbihCdWZmZXIuZnJvbShyYXdUeCwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgY29uc3QgZXhwbGFpbmVkVHggPSB0cmFuc2FjdGlvbi5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzICYmIHR4UGFyYW1zLnJlY2lwaWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZmlsdGVyZWRSZWNpcGllbnRzID0gdHhQYXJhbXMucmVjaXBpZW50cz8ubWFwKChyZWNpcGllbnQpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyZWRSZWNpcGllbnQgPSBfLnBpY2socmVjaXBpZW50LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pO1xuICAgICAgICBmaWx0ZXJlZFJlY2lwaWVudC5hbW91bnQgPSBuZXcgQmlnTnVtYmVyKGZpbHRlcmVkUmVjaXBpZW50LmFtb3VudCkudG9GaXhlZCgpO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWRSZWNpcGllbnQ7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkT3V0cHV0cyA9IGV4cGxhaW5lZFR4Lm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyZWRPdXRwdXQgPSBfLnBpY2sob3V0cHV0LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pO1xuICAgICAgICBmaWx0ZXJlZE91dHB1dC5hbW91bnQgPSBuZXcgQmlnTnVtYmVyKGZpbHRlcmVkT3V0cHV0LmFtb3VudCkudG9GaXhlZCgpO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWRPdXRwdXQ7XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFfLmlzRXF1YWwoZmlsdGVyZWRPdXRwdXRzLCBmaWx0ZXJlZFJlY2lwaWVudHMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcmVjaXBpZW50cyBvZiB0eFBhcmFtcy5yZWNpcGllbnRzKSB7XG4gICAgICAgIHRvdGFsQW1vdW50ID0gdG90YWxBbW91bnQucGx1cyhyZWNpcGllbnRzLmFtb3VudCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRvdGFsQW1vdW50LmlzRXF1YWxUbyhleHBsYWluZWRUeC5vdXRwdXRBbW91bnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggdG90YWwgYW1vdW50IGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdG90YWwgYW1vdW50IGZpZWxkJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgYXN5bmMgaXNXYWxsZXRBZGRyZXNzKHBhcmFtczogVHNzVmVyaWZ5QWRkcmVzc09wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IGtleWNoYWlucywgYWRkcmVzczogbmV3QWRkcmVzcywgaW5kZXggfSA9IHBhcmFtcztcblxuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhuZXdBZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHtuZXdBZGRyZXNzfWApO1xuICAgIH1cblxuICAgIGlmICgha2V5Y2hhaW5zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0ga2V5Y2hhaW5zJyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBrZXljaGFpbiBvZiBrZXljaGFpbnMpIHtcbiAgICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9IGtleWNoYWluLmNvbW1vbktleWNoYWluIGFzIHN0cmluZztcblxuICAgICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSAnbS8nICsgaW5kZXg7XG4gICAgICBjb25zdCBkZXJpdmVkUHVibGljS2V5ID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoY29tbW9uS2V5Y2hhaW4sIGRlcml2YXRpb25QYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSB0aGlzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGRlcml2ZWRQdWJsaWNLZXkpO1xuXG4gICAgICBpZiAobmV3QWRkcmVzcyAhPT0gZXhwZWN0ZWRBZGRyZXNzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBTdWlQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U3VpUGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uID0gYXdhaXQgdGhpcy5leHBsYWluVHJhbnNhY3Rpb24oeyB0eEhleDogcGFyYW1zLnR4SGV4IH0pO1xuXG4gICAgaWYgKCF0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdWlUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gYXMgU3VpVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgICBpZiAoc3VpVHJhbnNhY3Rpb24ub3V0cHV0cy5sZW5ndGggPD0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaW5wdXRzOiBbXSxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBzdWlUcmFuc2FjdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3M7XG4gICAgY29uc3QgZmVlQW1vdW50ID0gbmV3IEJpZ051bWJlcihzdWlUcmFuc2FjdGlvbi5mZWUuZmVlID09PSAnJyA/ICcwJyA6IHN1aVRyYW5zYWN0aW9uLmZlZS5mZWUpO1xuXG4gICAgLy8gYXNzdW1lIDEgc2VuZGVyLCB3aG8gaXMgYWxzbyB0aGUgZmVlIHBheWVyXG4gICAgY29uc3QgaW5wdXRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG5ldyBCaWdOdW1iZXIoc3VpVHJhbnNhY3Rpb24ub3V0cHV0QW1vdW50KS5wbHVzKGZlZUFtb3VudCkudG9GaXhlZCgpLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgY29uc3Qgb3V0cHV0czogVHJhbnNhY3Rpb25PdXRwdXRbXSA9IHN1aVRyYW5zYWN0aW9uLm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IG91dHB1dC5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG5ldyBCaWdOdW1iZXIob3V0cHV0LmFtb3VudCkudG9GaXhlZCgpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzLFxuICAgIH07XG4gIH1cblxuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIGNvbnN0IGtleVBhaXIgPSBzZWVkID8gbmV3IFN1aUtleVBhaXIoeyBzZWVkIH0pIDogbmV3IFN1aUtleVBhaXIoKTtcbiAgICBjb25zdCBrZXlzID0ga2V5UGFpci5nZXRLZXlzKCk7XG4gICAgaWYgKCFrZXlzLnBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHBydiBpbiBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHB1Yjoga2V5cy5wdWIsXG4gICAgICBwcnY6IGtleXMucHJ2LFxuICAgIH07XG4gIH1cblxuICBpc1ZhbGlkUHViKHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgaXNWYWxpZFBydihwcnY6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIHNpZ25UcmFuc2FjdGlvbihwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4gYSBTdWkgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U3VpVHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBsZXQgcmVidWlsdFRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb247XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25CdWlsZGVyID0gZmFjdG9yeS5mcm9tKEJ1ZmZlci5mcm9tKHBhcmFtcy50eEhleCwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICByZWJ1aWx0VHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2FjdGlvbkJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiByZWJ1aWx0VHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoZGVyaXZlZFB1YmxpY0tleTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETyhCRy01OTAxNikgcmVwbGFjZSB3aXRoIGFjY291bnQgbGliIGltcGxlbWVudGF0aW9uXG4gICAgcmV0dXJuIHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGRlcml2ZWRQdWJsaWNLZXkpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFzeW5jIGdldFNpZ25hYmxlUGF5bG9hZChzZXJpYWxpemVkVHg6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuICAgIGNvbnN0IHJlYnVpbHRUcmFuc2FjdGlvbiA9IGF3YWl0IGZhY3RvcnkuZnJvbShzZXJpYWxpemVkVHgpLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG4gIH1cbn1cbiJdfQ==
|
|
698
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N1aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsbURBZ0M4QjtBQUM5QixpREFBK0Y7QUFDL0YsZ0VBQXFDO0FBQ3JDLCtCQU1lO0FBQ2Ysd0RBQWdDO0FBQ2hDLDBDQUE0QjtBQUM1Qix1Q0FBZ0Y7QUFFaEYsK0NBUXlCO0FBQ3pCLHlEQUFrRjtBQTZCbEYsTUFBYSxHQUFJLFNBQVEsbUJBQVE7SUFFL0IsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFYixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRU0sUUFBUTtRQUNiLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVNLFNBQVM7UUFDZCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTSxXQUFXO1FBQ2hCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDO0lBQ25DLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixzQkFBc0I7UUFDcEIsT0FBTyx3QkFBYSxDQUFDLEdBQUcsQ0FBQztJQUMzQixDQUFDO0lBRUQsZUFBZTtRQUNiLE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFRCwyQkFBMkI7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE1BQWdDO1FBQ3RELElBQUksV0FBVyxHQUFHLElBQUksc0JBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLFVBQVUsR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUNwRixNQUFNLFdBQVcsR0FBRyxJQUFJLHlCQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFDL0IsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFFRCxXQUFXLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDN0UsTUFBTSxXQUFXLEdBQUcsV0FBVyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFckQsSUFBSSxRQUFRLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFELE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtnQkFDaEUsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUNuRSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsSUFBSSxzQkFBUyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM3RSxPQUFPLGlCQUFpQixDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDekQsTUFBTSxjQUFjLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztnQkFDN0QsY0FBYyxDQUFDLE1BQU0sR0FBRyxJQUFJLHNCQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN2RSxPQUFPLGNBQWMsQ0FBQztZQUN4QixDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztZQUNqRixDQUFDO1lBQ0QsS0FBSyxNQUFNLFVBQVUsSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQzdDLFdBQVcsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ3JELE1BQU0sSUFBSSxLQUFLLENBQUMsaUVBQWlFLENBQUMsQ0FBQztZQUNyRixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksWUFBWSxFQUFFLDBCQUEwQixFQUFFLENBQUM7WUFDN0MsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFlBQVksRUFBRSxFQUFFLFdBQVcsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUUsV0FBVyxDQUFDO1lBRTdGLEtBQUssTUFBTSxNQUFNLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN6QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssV0FBVyxFQUFFLENBQUM7b0JBQ25DLE1BQU0sSUFBSSxLQUFLLENBQUMsNkVBQTZFLENBQUMsQ0FBQztnQkFDakcsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUErQjtRQUNuRCxPQUFPLElBQUEsc0NBQTJCLEVBQ2hDLE1BQU0sRUFDTixDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFDekMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FDdkQsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBa0M7UUFDdkQsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUV0RixJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELElBQUksR0FBRyxHQUFHLElBQUksc0JBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzQixNQUFNLGNBQWMsR0FBRyxzQkFBbUQsQ0FBQztRQUMzRSxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE9BQU87Z0JBQ0wsTUFBTSxFQUFFLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsR0FBRzthQUNKLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDeEQsSUFBSSxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUNsQyxHQUFHLEdBQUcsSUFBSSxzQkFBUyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELDZDQUE2QztRQUM3QyxNQUFNLE1BQU0sR0FBRztZQUNiO2dCQUNFLE9BQU8sRUFBRSxhQUFhO2dCQUN0QixNQUFNLEVBQUUsSUFBSSxzQkFBUyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFO2FBQ3ZFO1NBQ0YsQ0FBQztRQUVGLE1BQU0sT0FBTyxHQUF3QixjQUFjLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3pFLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixNQUFNLEVBQUUsSUFBSSxzQkFBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUU7YUFDL0MsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTztZQUNMLE1BQU07WUFDTixPQUFPO1lBQ1AsR0FBRztTQUNKLENBQUM7SUFDSixDQUFDO0lBRUQsZUFBZSxDQUFDLElBQWE7UUFDM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLGFBQVUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksYUFBVSxFQUFFLENBQUM7UUFDbkUsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUNELE9BQU87WUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7WUFDYixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7U0FDZCxDQUFDO0lBQ0osQ0FBQztJQUVELFVBQVUsQ0FBQyxDQUFTO1FBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsVUFBVSxDQUFDLENBQVM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxjQUFjLENBQUMsT0FBZTtRQUM1QixPQUFPLGVBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELGVBQWUsQ0FBQyxDQUF5QjtRQUN2QyxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFpQztRQUN4RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEMsSUFBSSxrQkFBbUMsQ0FBQztRQUV4QyxJQUFJLENBQUM7WUFDSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzdGLGtCQUFrQixHQUFHLE1BQU0sa0JBQWtCLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEQsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE1BQU0sSUFBSSxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsT0FBTyxrQkFBa0IsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ2pELENBQUM7SUFFTyxVQUFVO1FBQ2hCLE9BQU8sSUFBSSwrQkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVPLHVCQUF1QixDQUFDLGdCQUF3QjtRQUN0RCx5REFBeUQ7UUFDekQsT0FBTyxlQUFLLENBQUMsdUJBQXVCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxZQUFvQjtRQUMzQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbEMsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEUsT0FBTyxrQkFBa0IsQ0FBQyxlQUFlLENBQUM7SUFDNUMsQ0FBQztJQUVTLGdCQUFnQjtRQUN4QixPQUFPLHVCQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUN0RCxDQUFDO0lBRVMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFhLEVBQUUsUUFBaUI7UUFDekQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDcEMsT0FBTyxNQUFNLGVBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRVMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFhLEVBQUUsUUFBaUI7UUFDNUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDcEMsT0FBTyxNQUFNLGVBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRVMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFhO1FBQzFDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sTUFBTSxlQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQTBCO1FBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO1lBQ3BGLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsZUFBSyxDQUFDLHlCQUF5QixDQUM5QyxDQUFDLEVBQ0QsOENBQThDLEVBQzlDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FDekIsQ0FBQztRQUNGLE1BQU0sYUFBYSxHQUFHLGVBQUssQ0FBQyx5QkFBeUIsQ0FBQyxFQUFFLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xHLE1BQU0sTUFBTSxHQUFHLFFBQVEsR0FBRyxhQUFhLENBQUM7UUFDeEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sR0FBRyxHQUFHLE1BQU0sdUJBQVksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1FBRTNELEtBQUssSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUM3QyxNQUFNLGNBQWMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUEsK0JBQWlCLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQ3hGLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxjQUFjLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3JGLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3JFLElBQUksZ0JBQWdCLEdBQUcsSUFBSSxzQkFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLElBQUkscUJBQXFCLEdBQUcsSUFBSSxzQkFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLElBQUksQ0FBQztnQkFDSCxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3pELGdCQUFnQixHQUFHLElBQUksc0JBQVMsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQzNELHFCQUFxQixHQUFHLElBQUksc0JBQVMsQ0FBQyxXQUFXLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUMzRSxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxTQUFTO1lBQ1gsQ0FBQztZQUNELElBQUksZ0JBQWdCLENBQUMsS0FBSyxDQUFDLDBCQUFjLENBQUMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDM0QsU0FBUztZQUNYLENBQUM7WUFFRCx1RUFBdUU7WUFDdkUsSUFBSSxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztnQkFDaEMsTUFBTSxLQUFLLEdBQUcsZUFBSyxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxvQkFBcUIsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQVksQ0FBQztnQkFDdkcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztnQkFDekQsQ0FBQztnQkFDRCxNQUFNLFFBQVEsR0FBRyxHQUFHLEtBQUssQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3hFLElBQUksQ0FBQztvQkFDSCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7b0JBQ3hFLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxzQkFBUyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUMzRSxJQUFJLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO3dCQUMxQyxTQUFTO29CQUNYLENBQUM7Z0JBQ0gsQ0FBQztnQkFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUNYLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM3RyxDQUFDO1lBRUQsSUFBSSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3pELFVBQVUsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUNwQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUMvQyxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyw0QkFBZ0IsRUFBRSxDQUFDO2dCQUN6QyxVQUFVLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsNEJBQWdCLENBQUMsQ0FBQztZQUNyRCxDQUFDO1lBQ0QsMEVBQTBFO1lBQzFFLHNGQUFzRjtZQUN0Riw4RkFBOEY7WUFDOUYsTUFBTSxrQkFBa0IsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxzQkFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsSUFBSSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsS0FBSyxDQUFDLDBCQUFjLENBQUMsQ0FBQztZQUVyRixNQUFNLFVBQVUsR0FBRztnQkFDakI7b0JBQ0UsT0FBTyxFQUFFLE1BQU0sQ0FBQyxtQkFBbUI7b0JBQ25DLE1BQU0sRUFBRSxTQUFTLENBQUMsUUFBUSxFQUFFO2lCQUM3QjthQUNGLENBQUM7WUFFRiwwRUFBMEU7WUFDMUUseUVBQXlFO1lBQ3pFLGtGQUFrRjtZQUNsRixJQUFJLHFCQUF5RSxDQUFDO1lBQzlFLElBQUkscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM1RCxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sZUFBSyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixNQUFNLEtBQUssR0FBRyxnQkFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELHFCQUFxQixHQUFHO29CQUN0QixXQUFXLEVBQUU7d0JBQ1gsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTt3QkFDekIsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUU7d0JBQzdCLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUU7d0JBQzVCLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUU7d0JBQzVCLEtBQUssRUFBRSxPQUFPO3dCQUNkLEtBQUs7cUJBQ047aUJBQ0YsQ0FBQztZQUNKLENBQUM7WUFFRCwrQkFBK0I7WUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxlQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUUsTUFBTSxTQUFTLEdBQUcsT0FBTztpQkFDdEIsa0JBQWtCLEVBQUU7aUJBQ3BCLElBQUksQ0FBQywwQkFBa0IsQ0FBQyxRQUFRLENBQUM7aUJBQ2pDLE1BQU0sQ0FBQyxhQUFhLENBQUM7aUJBQ3JCLElBQUksQ0FBQyxVQUFVLENBQUM7aUJBQ2hCLHFCQUFxQixDQUFDLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxDQUFDO2lCQUN2RCxPQUFPLENBQUM7Z0JBQ1AsS0FBSyxFQUFFLGFBQWE7Z0JBQ3BCLEtBQUssRUFBRSw2QkFBaUI7Z0JBQ3hCLE1BQU0sRUFBRSwwQkFBYztnQkFDdEIsT0FBTyxFQUFFLFVBQVU7YUFDcEIsQ0FBQyxDQUFDO1lBRUwsSUFBSSxxQkFBcUIsRUFBRSxDQUFDO2dCQUMxQixTQUFTLENBQUMsVUFBVSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUVELE1BQU0sTUFBTSxHQUFHLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQXdCLENBQUM7WUFDaEUsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7WUFDMUUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEdBQUcsZ0NBQW9CLENBQUMsQ0FBQztZQUU1RSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQywwQkFBYyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVELFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDM0IsU0FBUyxDQUFDLE9BQU8sQ0FBQztnQkFDaEIsS0FBSyxFQUFFLGFBQWE7Z0JBQ3BCLEtBQUssRUFBRSw2QkFBaUI7Z0JBQ3hCLE1BQU0sRUFBRSxTQUFTO2dCQUNqQixPQUFPLEVBQUUsVUFBVTthQUNwQixDQUFDLENBQUM7WUFFSCxNQUFNLGVBQWUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztZQUNqRCxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixPQUFPLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFDckcsQ0FBQztZQUVELE1BQU0sSUFBSSxDQUFDLHVCQUF1QixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9GLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQXdCLENBQUM7WUFDNUQsT0FBTztnQkFDTCxZQUFZLEVBQUU7b0JBQ1o7d0JBQ0UsU0FBUyxFQUFFLEdBQUc7d0JBQ2QsY0FBYyxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUU7d0JBQ3BDLFlBQVksRUFBRSxFQUFFLENBQUMsaUJBQWlCLEVBQUU7d0JBQ3BDLFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO3dCQUMzRCxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtxQkFDdEI7aUJBQ0Y7Z0JBQ0QsYUFBYSxFQUFFLEdBQUc7YUFDbkIsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLElBQUksS0FBSyxDQUNiLHlHQUF5RyxNQUFNLDBHQUEwRyxDQUMxTixDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxlQUFlLENBQzNCLE1BQTBCLEVBQzFCLEtBQWMsRUFDZCxhQUFxQixFQUNyQixjQUFzQixFQUN0QixnQkFBd0IsRUFDeEIsR0FBVyxFQUNYLFFBQWdCO1FBRWhCLE1BQU0sUUFBUSxHQUFHLEdBQUcsS0FBSyxDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN4RSxJQUFJLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JFLFlBQVksR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3hDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLDhCQUFrQixFQUFFLENBQUM7WUFDN0MsWUFBWSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLDhCQUFrQixDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUNELE1BQU0sa0JBQWtCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksc0JBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4RSxNQUFNLDBCQUEwQixHQUFHLElBQUksc0JBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3pGLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sVUFBVSxHQUFHO1lBQ2pCO2dCQUNFLE9BQU8sRUFBRSxNQUFNLENBQUMsbUJBQW1CO2dCQUNuQyxNQUFNLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRTthQUM3QjtTQUNGLENBQUM7UUFFRixNQUFNLFNBQVMsR0FBRyxJQUFJLHNCQUFTLENBQUMsMEJBQWMsQ0FBQyxDQUFDO1FBQ2hELElBQUksVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN6RCxVQUFVLEdBQUcsZUFBSyxDQUFDLGlDQUFpQyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM1RSxJQUFJLFVBQVUsQ0FBQyxNQUFNLElBQUksMkJBQWUsRUFBRSxDQUFDO1lBQ3pDLFVBQVUsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSwyQkFBZSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFFRCwrQkFBK0I7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyRCxNQUFNLFNBQVMsR0FBRyxPQUFPO2FBQ3RCLHVCQUF1QixFQUFFO2FBQ3pCLElBQUksQ0FBQywwQkFBa0IsQ0FBQyxhQUFhLENBQUM7YUFDdEMsTUFBTSxDQUFDLGFBQWEsQ0FBQzthQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDO2FBQ2hCLHFCQUFxQixDQUFDLDBCQUEwQixDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQzVELE9BQU8sQ0FBQztZQUNQLEtBQUssRUFBRSxhQUFhO1lBQ3BCLEtBQUssRUFBRSw2QkFBaUI7WUFDeEIsTUFBTSxFQUFFLDBCQUFjO1lBQ3RCLE9BQU8sRUFBRSxVQUFVO1NBQ3BCLENBQUMsQ0FBQztRQUVMLElBQUksWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QixTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUE2QixDQUFDO1FBQ3JFLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBQzFFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxHQUFHLGdDQUFvQixDQUFDLENBQUM7UUFFNUUsU0FBUyxDQUFDLE9BQU8sQ0FBQztZQUNoQixLQUFLLEVBQUUsYUFBYTtZQUNwQixLQUFLLEVBQUUsNkJBQWlCO1lBQ3hCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLE9BQU8sRUFBRSxVQUFVO1NBQ3BCLENBQUMsQ0FBQztRQUVILE1BQU0sZUFBZSxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBQ2pELElBQUksZUFBZSxFQUFFLENBQUM7WUFDcEIsT0FBTyxJQUFJLENBQUMsNkJBQTZCLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RyxDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUYsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBNkIsQ0FBQztRQUNqRSxPQUFPO1lBQ0wsWUFBWSxFQUFFO2dCQUNaO29CQUNFLFNBQVMsRUFBRSxHQUFHO29CQUNkLGNBQWMsRUFBRSxTQUFTLENBQUMsUUFBUSxFQUFFO29CQUNwQyxZQUFZLEVBQUUsRUFBRSxDQUFDLGlCQUFpQixFQUFFO29CQUNwQyxTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztvQkFDM0QsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO2lCQUNqQjthQUNGO1lBQ0QsYUFBYSxFQUFFLEdBQUc7U0FDbkIsQ0FBQztJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMsNkJBQTZCLENBQ3pDLFNBQTZCLEVBQzdCLGFBQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLEtBQWEsRUFDYixjQUFzQixFQUN0QixLQUFlO1FBRWYsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ25DLE1BQU0sbUJBQW1CLEdBQUcsa0JBQWtCO1lBQzVDLENBQUMsQ0FBRSxDQUFDLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUE4QjtZQUN6RCxDQUFDLENBQUUsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBeUIsQ0FBQztRQUN2RCxNQUFNLFlBQVksR0FBRyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzdELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RSxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sVUFBVSxHQUFHLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckUsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRztZQUNiO2dCQUNFLE9BQU8sRUFBRSxhQUFhO2dCQUN0QixXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU07Z0JBQzFCLEtBQUssRUFBRSxJQUFJLHNCQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUNwQztTQUNGLENBQUM7UUFDRixNQUFNLE9BQU8sR0FBRztZQUNkO2dCQUNFLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztnQkFDdkIsV0FBVyxFQUFFLE1BQU0sQ0FBQyxNQUFNO2dCQUMxQixRQUFRLEVBQUUsVUFBVTthQUNyQjtTQUNGLENBQUM7UUFDRixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ2xDLE1BQU0saUJBQWlCLEdBQUc7WUFDeEIsTUFBTSxFQUFFLE1BQU07WUFDZCxPQUFPLEVBQUUsT0FBTztZQUNoQixXQUFXLEVBQUUsV0FBVztZQUN4QixJQUFJLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLDBCQUFrQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsMEJBQWtCLENBQUMsUUFBUTtTQUMxRixDQUFDO1FBQ0YsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUN6QixNQUFNLE9BQU8sR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO1FBQ25FLE1BQU0sWUFBWSxHQUFHLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxDQUFDO1FBQ2xELE1BQU0sV0FBVyxHQUFVO1lBQ3pCLFlBQVksRUFBRSxlQUFlO1lBQzdCLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLElBQUksRUFBRSxVQUFVO1lBQ2hCLFdBQVcsRUFBRSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUNoRSxjQUFjO1lBQ2QsUUFBUSxFQUFFLGlCQUFpQjtZQUMzQixPQUFPLEVBQUUsT0FBTztZQUNoQixZQUFZLEVBQUUsWUFBWTtTQUMzQixDQUFDO1FBQ0YsTUFBTSxVQUFVLEdBQWtCLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDbkYsTUFBTSxZQUFZLEdBQW9CLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbkQsTUFBTSxTQUFTLEdBQXNCO1lBQ25DLFlBQVksRUFBRSxZQUFZO1lBQzFCLFVBQVUsRUFBRSxVQUFVO1NBQ3ZCLENBQUM7UUFDRixPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRU8sS0FBSyxDQUFDLHVCQUF1QixDQUNuQyxTQUE2QixFQUM3QixNQUEwQixFQUMxQixjQUFzQixFQUN0QixnQkFBd0IsRUFDeEIsa0JBQTJCO1FBRTNCLCtFQUErRTtRQUMvRSxNQUFNLFVBQVUsR0FBRyxrQkFBa0I7WUFDbkMsQ0FBQyxDQUFFLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQThCO1lBQ3pELENBQUMsQ0FBRSxDQUFDLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUF5QixDQUFDO1FBQ3ZELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBRUQsMENBQTBDO1FBQzFDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNsRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFdEQsMkNBQTJDO1FBQzNDLElBQUksT0FBZSxDQUFDO1FBQ3BCLElBQUksQ0FBQztZQUNILE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDO2dCQUN0QyxLQUFLLEVBQUUsT0FBTztnQkFDZCxRQUFRLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjthQUNsQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7UUFDRCxnREFBZ0Q7UUFDaEQsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBeUMsQ0FBQztRQUV4RixJQUFJLFNBQWlCLENBQUM7UUFDdEIsSUFBSSxDQUFDO1lBQ0gsU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUM7Z0JBQ3hDLEtBQUssRUFBRSxTQUFTO2dCQUNoQixRQUFRLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjthQUNsQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUEyQyxDQUFDO1FBQzlGLGtFQUFrRTtRQUVsRSxnQkFBZ0I7UUFDaEIsTUFBTSxZQUFZLEdBQUcsTUFBTSx1QkFBWSxDQUFDLGVBQWUsQ0FDckQsbUJBQW1CLEVBQ25CLHFCQUFxQixFQUNyQixjQUFjLEVBQ2QsVUFBVSxDQUNYLENBQUM7UUFDRixTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxFQUN6QixZQUFZLEdBQ29CO1FBQ2hDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztRQUMzQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNwQyxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbkIsS0FBSyxNQUFNLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDO29CQUNILE1BQU0sR0FBRyxNQUFNLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUN4RixDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQzFFLENBQUM7Z0JBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxNQUErQjtRQUN2RSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDO1FBQ25DLE1BQU0seUJBQXlCLEdBQVksRUFBRSxDQUFDO1FBQzlDLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztRQUV0QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sR0FBRyxHQUFHLE1BQU0sdUJBQVksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO1lBQzNELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztZQUNoRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUMxQyxDQUFDO1lBQ0QsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUM7WUFDL0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQzFDLENBQUM7WUFDRCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUN2QyxDQUFDO1lBQ0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNHLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMzRixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLENBQUM7Z0JBQzlDLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUM3QyxDQUFDO1lBQ0QsTUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLFlBQWEsQ0FBQyxjQUF5QixDQUFDO1lBQzNFLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUM3QyxDQUFDO1lBQ0QsTUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLGNBQXdCLENBQUM7WUFDNUQsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFM0Ysa0NBQWtDO1lBQ2xDLFNBQVMsQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNoRSxNQUFNLGlCQUFpQixHQUFHLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQXdCLENBQUM7WUFDM0UsTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzRCxNQUFNLFlBQVksR0FBRyxpQkFBaUIsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLFlBQVksQ0FBQztZQUV6RSx5QkFBeUIsQ0FBQyxJQUFJLENBQUM7Z0JBQzdCLFlBQVksRUFBRSxZQUFZO2dCQUMxQixTQUFTLEVBQUUsV0FBVyxDQUFDLFNBQVM7Z0JBQ2hDLFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7Z0JBQzFFLGNBQWMsRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFO2FBQ3hDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxZQUFhLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3BFLGFBQWEsR0FBRyxXQUFXLENBQUMsWUFBYSxDQUFDLGFBQXVCLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEVBQUUsWUFBWSxFQUFFLHlCQUF5QixFQUFFLGFBQWEsRUFBRSxDQUFDO0lBQ3BFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQixDQUFDLE1BQXVDO1FBQ2pFLE1BQU0sZUFBZSxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBQ2pELE1BQU0sUUFBUSxHQUFHLGVBQUssQ0FBQyx5QkFBeUIsQ0FDOUMsQ0FBQyxFQUNELDhDQUE4QyxFQUM5QyxNQUFNLENBQUMsaUJBQWlCLENBQ3pCLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxlQUFLLENBQUMseUJBQXlCLENBQzVDLFFBQVEsR0FBRywrQkFBbUIsRUFDOUIsNENBQTRDLEVBQzVDLE1BQU0sQ0FBQyxlQUFlLENBQ3ZCLENBQUM7UUFFRixJQUFJLFFBQVEsR0FBRyxDQUFDLElBQUksTUFBTSxJQUFJLFFBQVEsSUFBSSxNQUFNLEdBQUcsUUFBUSxHQUFHLEVBQUUsR0FBRywrQkFBbUIsRUFBRSxDQUFDO1lBQ3ZGLE1BQU0sSUFBSSxLQUFLLENBQ2IsOEVBQThFLFFBQVEsc0JBQXNCLE1BQU0sR0FBRyxDQUN0SCxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwRCxNQUFNLEdBQUcsR0FBRyxNQUFNLHVCQUFZLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUMzRCxNQUFNLGNBQWMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUEsK0JBQWlCLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDbkYsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLGNBQWMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDckYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFbkUsTUFBTSx5QkFBeUIsR0FBVSxFQUFFLENBQUM7UUFDNUMsSUFBSSxhQUFhLEdBQUcsUUFBUSxDQUFDO1FBQzdCLEtBQUssSUFBSSxHQUFHLEdBQUcsUUFBUSxFQUFFLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztZQUM3QyxNQUFNLGFBQWEsR0FBRztnQkFDcEIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7Z0JBQzNCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDekIsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLGdCQUFnQjtnQkFDekMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixvQkFBb0IsRUFBRSxNQUFNLENBQUMsb0JBQW9CO2dCQUNqRCxtQkFBbUIsRUFBRSxXQUFXO2dCQUNoQyxpQkFBaUIsRUFBRSxHQUFHO2dCQUN0QixJQUFJLEVBQUUsQ0FBQzthQUNSLENBQUM7WUFFRixJQUFJLG1CQUF5QyxDQUFDO1lBQzlDLElBQUksQ0FBQztnQkFDSCxtQkFBbUIsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDMUQsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1gsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQywyREFBMkQsQ0FBQyxFQUFFLENBQUM7b0JBQ3RGLGFBQWEsR0FBRyxHQUFHLENBQUM7b0JBQ3BCLFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7WUFFRCxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQix5QkFBeUIsQ0FBQyxJQUFJLENBQUUsbUJBQW1DLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckYsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHlCQUF5QixDQUFDLElBQUksQ0FBRSxtQkFBOEIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRixDQUFDO1lBQ0QsYUFBYSxHQUFHLEdBQUcsQ0FBQztRQUN0QixDQUFDO1FBRUQsSUFBSSx5QkFBeUIsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FDYix5R0FDRSxhQUFhLEdBQUcsQ0FDbEIsR0FBRyxDQUNKLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQiw0R0FBNEc7WUFDNUcsa0hBQWtIO1lBQ2xILHNHQUFzRztZQUN0Ryx5QkFBeUIsQ0FDdkIseUJBQXlCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FDckMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1lBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUseUJBQXlCLEVBQUUsQ0FBQztRQUNuRCxDQUFDO1FBRUQsT0FBTyxFQUFFLFlBQVksRUFBRSx5QkFBeUIsRUFBRSxhQUFhLEVBQUUsQ0FBQztJQUNwRSxDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLDZCQUE2QixDQUFDLE1BQXVCLEVBQUUsTUFBNEM7UUFDakcsTUFBTSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxxQkFBcUIsR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUM7SUFDOUQsQ0FBQztJQUVELG9CQUFvQjtJQUNwQixpQkFBaUIsQ0FBQyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUEyQjtRQUN6RSxJQUFJLFlBQVksS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELElBQUEsa0NBQW9CLEVBQUMsR0FBRyxFQUFFLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUEvd0JELGtCQSt3QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQge1xuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25PcHRpb25zLFxuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXN1bHQsXG4gIEJhc2VDb2luLFxuICBCYXNlVHJhbnNhY3Rpb24sXG4gIEJpdEdvQmFzZSxcbiAgRUREU0FNZXRob2RzLFxuICBFRERTQU1ldGhvZFR5cGVzLFxuICBFbnZpcm9ubWVudHMsXG4gIEtleVBhaXIsXG4gIE1QQ0FsZ29yaXRobSxcbiAgTVBDUmVjb3ZlcnlPcHRpb25zLFxuICBNUENDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zLFxuICBNUENTd2VlcFJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDU3dlZXBUeHMsXG4gIE1QQ1R4LFxuICBNUENUeHMsXG4gIE1QQ1Vuc2lnbmVkVHgsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFJlY292ZXJ5VHhSZXF1ZXN0LFxuICBTaWduZWRUcmFuc2FjdGlvbixcbiAgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbixcbiAgVHNzVmVyaWZ5QWRkcmVzc09wdGlvbnMsXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgUG9wdWxhdGVkSW50ZW50LFxuICBQcmVidWlsZFRyYW5zYWN0aW9uV2l0aEludGVudE9wdGlvbnMsXG4gIE11bHRpc2lnVHlwZSxcbiAgbXVsdGlzaWdUeXBlcyxcbiAgQXVkaXREZWNyeXB0ZWRLZXlQYXJhbXMsXG4gIHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQmFzZUNvaW4gYXMgU3RhdGljc0Jhc2VDb2luLCBCYXNlTmV0d29yaywgY29pbnMsIFN1aUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7XG4gIEtleVBhaXIgYXMgU3VpS2V5UGFpcixcbiAgVG9rZW5UcmFuc2ZlclRyYW5zYWN0aW9uLFxuICBUcmFuc2FjdGlvbkJ1aWxkZXIsXG4gIFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnksXG4gIFRyYW5zZmVyVHJhbnNhY3Rpb24sXG59IGZyb20gJy4vbGliJztcbmltcG9ydCB1dGlscyBmcm9tICcuL2xpYi91dGlscyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBTdWlCYWxhbmNlSW5mbywgU3VpT2JqZWN0SW5mbywgU3VpVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnLi9saWIvaWZhY2UnO1xuaW1wb3J0IHsgVmFsaWREdXJpbmdFeHBpcmF0aW9uIH0gZnJvbSAnLi9saWIvbXlzdGVubGFiL3R5cGVzL3N1aS1iY3MnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9HQVNfT1ZFUkhFQUQsXG4gIERFRkFVTFRfR0FTX1BSSUNFLFxuICBERUZBVUxUX1NDQU5fRkFDVE9SLFxuICBNQVhfR0FTX0JVREdFVCxcbiAgTUFYX0dBU19PQkpFQ1RTLFxuICBNQVhfT0JKRUNUX0xJTUlULFxuICBUT0tFTl9PQkpFQ1RfTElNSVQsXG59IGZyb20gJy4vbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBhdWRpdEVkZHNhUHJpdmF0ZUtleSwgZ2V0RGVyaXZhdGlvblBhdGggfSBmcm9tICdAYml0Z28tYmV0YS9zZGstbGliLW1wYyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VpUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEhleDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgVHJhbnNhY3Rpb25PdXRwdXQge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGFtb3VudDogc3RyaW5nO1xufVxuXG50eXBlIFRyYW5zYWN0aW9uSW5wdXQgPSBUcmFuc2FjdGlvbk91dHB1dDtcblxuZXhwb3J0IGludGVyZmFjZSBTdWlQYXJzZWRUcmFuc2FjdGlvbiBleHRlbmRzIFBhcnNlZFRyYW5zYWN0aW9uIHtcbiAgLy8gdG90YWwgYXNzZXRzIGJlaW5nIG1vdmVkLCBpbmNsdWRpbmcgZmVlc1xuICBpbnB1dHM6IFRyYW5zYWN0aW9uSW5wdXRbXTtcblxuICAvLyB3aGVyZSBhc3NldHMgYXJlIG1vdmVkIHRvXG4gIG91dHB1dHM6IFRyYW5zYWN0aW9uT3V0cHV0W107XG5cbiAgZmVlOiBCaWdOdW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIFN1aVRyYW5zYWN0aW9uRXhwbGFuYXRpb24gPSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uO1xuXG5leHBvcnQgY2xhc3MgU3VpIGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KSB7XG4gICAgc3VwZXIoYml0Z28pO1xuXG4gICAgaWYgKCFzdGF0aWNzQ29pbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBzdGF0aWNzQ29pbicpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRpY3NDb2luID0gc3RhdGljc0NvaW47XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgU3VpKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICAvKipcbiAgICogRmFjdG9yIGJldHdlZW4gdGhlIGNvaW4ncyBiYXNlIHVuaXQgYW5kIGl0cyBzbWFsbGVzdCBzdWJkaXZpc29uXG4gICAqL1xuICBwdWJsaWMgZ2V0QmFzZUZhY3RvcigpOiBudW1iZXIge1xuICAgIHJldHVybiAxZTk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ3N1aSc7XG4gIH1cblxuICBwdWJsaWMgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdzdWknO1xuICB9XG5cbiAgcHVibGljIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdTdWknO1xuICB9XG5cbiAgZ2V0TmV0d29yaygpOiBCYXNlTmV0d29yayB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5ldHdvcms7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNUc3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogaW5oZXJpdGVkIGRvYyAqL1xuICBnZXREZWZhdWx0TXVsdGlzaWdUeXBlKCk6IE11bHRpc2lnVHlwZSB7XG4gICAgcmV0dXJuIG11bHRpc2lnVHlwZXMudHNzO1xuICB9XG5cbiAgZ2V0TVBDQWxnb3JpdGhtKCk6IE1QQ0FsZ29yaXRobSB7XG4gICAgcmV0dXJuICdlZGRzYSc7XG4gIH1cblxuICBhbGxvd3NBY2NvdW50Q29uc29saWRhdGlvbnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxldCB0b3RhbEFtb3VudCA9IG5ldyBCaWdOdW1iZXIoMCk7XG4gICAgY29uc3QgY29pbkNvbmZpZyA9IGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpO1xuICAgIGNvbnN0IHsgdHhQcmVidWlsZDogdHhQcmVidWlsZCwgdHhQYXJhbXM6IHR4UGFyYW1zLCB2ZXJpZmljYXRpb24sIHdhbGxldCB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gbmV3IFRyYW5zZmVyVHJhbnNhY3Rpb24oY29pbkNvbmZpZyk7XG4gICAgY29uc3QgcmF3VHggPSB0eFByZWJ1aWxkLnR4SGV4O1xuICAgIGlmICghcmF3VHgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCB0eCBwcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgIH1cblxuICAgIHRyYW5zYWN0aW9uLmZyb21SYXdUcmFuc2FjdGlvbihCdWZmZXIuZnJvbShyYXdUeCwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgY29uc3QgZXhwbGFpbmVkVHggPSB0cmFuc2FjdGlvbi5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzICYmIHR4UGFyYW1zLnJlY2lwaWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZmlsdGVyZWRSZWNpcGllbnRzID0gdHhQYXJhbXMucmVjaXBpZW50cz8ubWFwKChyZWNpcGllbnQpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyZWRSZWNpcGllbnQgPSBfLnBpY2socmVjaXBpZW50LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pO1xuICAgICAgICBmaWx0ZXJlZFJlY2lwaWVudC5hbW91bnQgPSBuZXcgQmlnTnVtYmVyKGZpbHRlcmVkUmVjaXBpZW50LmFtb3VudCkudG9GaXhlZCgpO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWRSZWNpcGllbnQ7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkT3V0cHV0cyA9IGV4cGxhaW5lZFR4Lm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyZWRPdXRwdXQgPSBfLnBpY2sob3V0cHV0LCBbJ2FkZHJlc3MnLCAnYW1vdW50J10pO1xuICAgICAgICBmaWx0ZXJlZE91dHB1dC5hbW91bnQgPSBuZXcgQmlnTnVtYmVyKGZpbHRlcmVkT3V0cHV0LmFtb3VudCkudG9GaXhlZCgpO1xuICAgICAgICByZXR1cm4gZmlsdGVyZWRPdXRwdXQ7XG4gICAgICB9KTtcblxuICAgICAgaWYgKCFfLmlzRXF1YWwoZmlsdGVyZWRPdXRwdXRzLCBmaWx0ZXJlZFJlY2lwaWVudHMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggb3V0cHV0cyBkb2VzIG5vdCBtYXRjaCB3aXRoIGV4cGVjdGVkIHR4UGFyYW1zIHJlY2lwaWVudHMnKTtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcmVjaXBpZW50cyBvZiB0eFBhcmFtcy5yZWNpcGllbnRzKSB7XG4gICAgICAgIHRvdGFsQW1vdW50ID0gdG90YWxBbW91bnQucGx1cyhyZWNpcGllbnRzLmFtb3VudCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRvdGFsQW1vdW50LmlzRXF1YWxUbyhleHBsYWluZWRUeC5vdXRwdXRBbW91bnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVHggdG90YWwgYW1vdW50IGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgdG90YWwgYW1vdW50IGZpZWxkJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZlcmlmaWNhdGlvbj8uY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3MpIHtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gd2FsbGV0LmNvaW5TcGVjaWZpYygpPy5iYXNlQWRkcmVzcyB8fCB3YWxsZXQuY29pblNwZWNpZmljKCk/LnJvb3RBZGRyZXNzO1xuXG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBleHBsYWluZWRUeC5vdXRwdXRzKSB7XG4gICAgICAgIGlmIChvdXRwdXQuYWRkcmVzcyAhPT0gYmFzZUFkZHJlc3MpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24gb3V0cHV0IGFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBUc3NWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB2ZXJpZnlFZGRzYVRzc1dhbGxldEFkZHJlc3MoXG4gICAgICBwYXJhbXMsXG4gICAgICAoYWRkcmVzcykgPT4gdGhpcy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSxcbiAgICAgIChwdWJsaWNLZXkpID0+IHRoaXMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHVibGljS2V5KVxuICAgICk7XG4gIH1cblxuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogU3VpUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFN1aVBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbiA9IGF3YWl0IHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uKHsgdHhIZXg6IHBhcmFtcy50eEhleCB9KTtcblxuICAgIGlmICghdHJhbnNhY3Rpb25FeHBsYW5hdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgbGV0IGZlZSA9IG5ldyBCaWdOdW1iZXIoMCk7XG5cbiAgICBjb25zdCBzdWlUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uRXhwbGFuYXRpb24gYXMgU3VpVHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgICBpZiAoc3VpVHJhbnNhY3Rpb24ub3V0cHV0cy5sZW5ndGggPD0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaW5wdXRzOiBbXSxcbiAgICAgICAgb3V0cHV0czogW10sXG4gICAgICAgIGZlZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc2VuZGVyQWRkcmVzcyA9IHN1aVRyYW5zYWN0aW9uLm91dHB1dHNbMF0uYWRkcmVzcztcbiAgICBpZiAoc3VpVHJhbnNhY3Rpb24uZmVlLmZlZSAhPT0gJycpIHtcbiAgICAgIGZlZSA9IG5ldyBCaWdOdW1iZXIoc3VpVHJhbnNhY3Rpb24uZmVlLmZlZSk7XG4gICAgfVxuXG4gICAgLy8gYXNzdW1lIDEgc2VuZGVyLCB3aG8gaXMgYWxzbyB0aGUgZmVlIHBheWVyXG4gICAgY29uc3QgaW5wdXRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG5ldyBCaWdOdW1iZXIoc3VpVHJhbnNhY3Rpb24ub3V0cHV0QW1vdW50KS5wbHVzKGZlZSkudG9GaXhlZCgpLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgY29uc3Qgb3V0cHV0czogVHJhbnNhY3Rpb25PdXRwdXRbXSA9IHN1aVRyYW5zYWN0aW9uLm91dHB1dHMubWFwKChvdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IG91dHB1dC5hZGRyZXNzLFxuICAgICAgICBhbW91bnQ6IG5ldyBCaWdOdW1iZXIob3V0cHV0LmFtb3VudCkudG9GaXhlZCgpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBpbnB1dHMsXG4gICAgICBvdXRwdXRzLFxuICAgICAgZmVlLFxuICAgIH07XG4gIH1cblxuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIGNvbnN0IGtleVBhaXIgPSBzZWVkID8gbmV3IFN1aUtleVBhaXIoeyBzZWVkIH0pIDogbmV3IFN1aUtleVBhaXIoKTtcbiAgICBjb25zdCBrZXlzID0ga2V5UGFpci5nZXRLZXlzKCk7XG4gICAgaWYgKCFrZXlzLnBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHBydiBpbiBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHB1Yjoga2V5cy5wdWIsXG4gICAgICBwcnY6IGtleXMucHJ2LFxuICAgIH07XG4gIH1cblxuICBpc1ZhbGlkUHViKF86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIGlzVmFsaWRQcnYoXzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpO1xuICB9XG5cbiAgc2lnblRyYW5zYWN0aW9uKF86IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4gYSBTdWkgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U3VpVHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBsZXQgcmVidWlsdFRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb247XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25CdWlsZGVyID0gZmFjdG9yeS5mcm9tKEJ1ZmZlci5mcm9tKHBhcmFtcy50eEhleCwgJ2hleCcpLnRvU3RyaW5nKCdiYXNlNjQnKSk7XG4gICAgICByZWJ1aWx0VHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2FjdGlvbkJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIHJldHVybiByZWJ1aWx0VHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gIH1cblxuICBwcml2YXRlIGdldEJ1aWxkZXIoKTogVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoZGVyaXZlZFB1YmxpY0tleTogc3RyaW5nKSB7XG4gICAgLy8gVE9ETyhCRy01OTAxNikgcmVwbGFjZSB3aXRoIGFjY291bnQgbGliIGltcGxlbWVudGF0aW9uXG4gICAgcmV0dXJuIHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGRlcml2ZWRQdWJsaWNLZXkpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFzeW5jIGdldFNpZ25hYmxlUGF5bG9hZChzZXJpYWxpemVkVHg6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuICAgIGNvbnN0IHJlYnVpbHRUcmFuc2FjdGlvbiA9IGF3YWl0IGZhY3RvcnkuZnJvbShzZXJpYWxpemVkVHgpLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0UHVibGljTm9kZVVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBFbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0uc3VpTm9kZVVybDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRCYWxhbmNlKG93bmVyOiBzdHJpbmcsIGNvaW5UeXBlPzogc3RyaW5nKTogUHJvbWlzZTxTdWlCYWxhbmNlSW5mbz4ge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0UHVibGljTm9kZVVybCgpO1xuICAgIHJldHVybiBhd2FpdCB1dGlscy5nZXRCYWxhbmNlKHVybCwgb3duZXIsIGNvaW5UeXBlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRJbnB1dENvaW5zKG93bmVyOiBzdHJpbmcsIGNvaW5UeXBlPzogc3RyaW5nKTogUHJvbWlzZTxTdWlPYmplY3RJbmZvW10+IHtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmdldFB1YmxpY05vZGVVcmwoKTtcbiAgICByZXR1cm4gYXdhaXQgdXRpbHMuZ2V0SW5wdXRDb2lucyh1cmwsIG93bmVyLCBjb2luVHlwZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RmVlRXN0aW1hdGUodHhIZXg6IHN0cmluZyk6IFByb21pc2U8QmlnTnVtYmVyPiB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQdWJsaWNOb2RlVXJsKCk7XG4gICAgcmV0dXJuIGF3YWl0IHV0aWxzLmdldEZlZUVzdGltYXRlKHVybCwgdHhIZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbihzKSB3aXRob3V0IEJpdEdvXG4gICAqXG4gICAqIEBwYXJhbSB7TVBDUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgcGFyYW1ldGVycyBuZWVkZWQgdG8gY29uc3RydWN0IGFuZFxuICAgKiAobWF5YmUpIHNpZ24gdGhlIHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHtNUENUeCB8IE1QQ1N3ZWVwVHhzfSBhcnJheSBvZiB0aGUgc2VyaWFsaXplZCB0cmFuc2FjdGlvbiBoZXggc3RyaW5ncyBhbmQgaW5kaWNlc1xuICAgKiBvZiB0aGUgYWRkcmVzc2VzIGJlaW5nIHN3ZXB0XG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogTVBDUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeHMgfCBNUENTd2VlcFR4cz4ge1xuICAgIGlmICghcGFyYW1zLmJpdGdvS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYml0Z29LZXknKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiB8fCAhdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCByZWNvdmVyeURlc3RpbmF0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRJZHggPSB1dGlscy52YWxpZGF0ZU5vbk5lZ2F0aXZlTnVtYmVyKFxuICAgICAgMCxcbiAgICAgICdJbnZhbGlkIHN0YXJ0aW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3NlcycsXG4gICAgICBwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXhcbiAgICApO1xuICAgIGNvbnN0IG51bUl0ZXJhdGlvbnMgPSB1dGlscy52YWxpZGF0ZU5vbk5lZ2F0aXZlTnVtYmVyKDIwLCAnSW52YWxpZCBzY2FubmluZyBmYWN0b3InLCBwYXJhbXMuc2Nhbik7XG4gICAgY29uc3QgZW5kSWR4ID0gc3RhcnRJZHggKyBudW1JdGVyYXRpb25zO1xuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgTVBDID0gYXdhaXQgRUREU0FNZXRob2RzLmdldEluaXRpYWxpemVkTXBjSW5zdGFuY2UoKTtcblxuICAgIGZvciAobGV0IGlkeCA9IHN0YXJ0SWR4OyBpZHggPCBlbmRJZHg7IGlkeCsrKSB7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IChwYXJhbXMuc2VlZCA/IGdldERlcml2YXRpb25QYXRoKHBhcmFtcy5zZWVkKSA6ICdtJykgKyBgLyR7aWR4fWA7XG4gICAgICBjb25zdCBkZXJpdmVkUHVibGljS2V5ID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGRlcml2YXRpb25QYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgICBjb25zdCBzZW5kZXJBZGRyZXNzID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5KTtcbiAgICAgIGxldCBhdmFpbGFibGVCYWxhbmNlID0gbmV3IEJpZ051bWJlcigwKTtcbiAgICAgIGxldCBmdW5kc0luQWRkcmVzc0JhbGFuY2UgPSBuZXcgQmlnTnVtYmVyKDApO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYmFsYW5jZUluZm8gPSBhd2FpdCB0aGlzLmdldEJhbGFuY2Uoc2VuZGVyQWRkcmVzcyk7XG4gICAgICAgIGF2YWlsYWJsZUJhbGFuY2UgPSBuZXcgQmlnTnVtYmVyKGJhbGFuY2VJbmZvLnRvdGFsQmFsYW5jZSk7XG4gICAgICAgIGZ1bmRzSW5BZGRyZXNzQmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIoYmFsYW5jZUluZm8uZnVuZHNJbkFkZHJlc3NCYWxhbmNlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoYXZhaWxhYmxlQmFsYW5jZS5taW51cyhNQVhfR0FTX0JVREdFVCkudG9OdW1iZXIoKSA8PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBjaGVjayBmb3IgcG9zc2libGUgdG9rZW4gcmVjb3ZlcnksIHJlY292ZXIgdGhlIHRva2VuIHByb3ZpZGUgYnkgdXNlclxuICAgICAgaWYgKHBhcmFtcy50b2tlbkNvbnRyYWN0QWRkcmVzcykge1xuICAgICAgICBjb25zdCB0b2tlbiA9IHV0aWxzLmdldFN1aVRva2VuRnJvbUFkZHJlc3MocGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzISwgdGhpcy5nZXROZXR3b3JrKCkpIGFzIFN1aUNvaW47XG4gICAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN1aSBUb2tlbiBQYWNrYWdlIElEIG5vdCBzdXBwb3J0ZWQuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29pblR5cGUgPSBgJHt0b2tlbi5wYWNrYWdlSWR9Ojoke3Rva2VuLm1vZHVsZX06OiR7dG9rZW4uc3ltYm9sfWA7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgdG9rZW5CYWxhbmNlSW5mbyA9IGF3YWl0IHRoaXMuZ2V0QmFsYW5jZShzZW5kZXJBZGRyZXNzLCBjb2luVHlwZSk7XG4gICAgICAgICAgY29uc3QgYXZhaWxhYmxlVG9rZW5CYWxhbmNlID0gbmV3IEJpZ051bWJlcih0b2tlbkJhbGFuY2VJbmZvLnRvdGFsQmFsYW5jZSk7XG4gICAgICAgICAgaWYgKGF2YWlsYWJsZVRva2VuQmFsYW5jZS50b051bWJlcigpIDw9IDApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlY292ZXJTdWlUb2tlbihwYXJhbXMsIHRva2VuLCBzZW5kZXJBZGRyZXNzLCBkZXJpdmF0aW9uUGF0aCwgZGVyaXZlZFB1YmxpY0tleSwgaWR4LCBiaXRnb0tleSk7XG4gICAgICB9XG5cbiAgICAgIGxldCBpbnB1dENvaW5zID0gYXdhaXQgdGhpcy5nZXRJbnB1dENvaW5zKHNlbmRlckFkZHJlc3MpO1xuICAgICAgaW5wdXRDb2lucyA9IGlucHV0Q29pbnMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICByZXR1cm4gYi5iYWxhbmNlLm1pbnVzKGEuYmFsYW5jZSkudG9OdW1iZXIoKTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGlucHV0Q29pbnMubGVuZ3RoID4gTUFYX09CSkVDVF9MSU1JVCkge1xuICAgICAgICBpbnB1dENvaW5zID0gaW5wdXRDb2lucy5zbGljZSgwLCBNQVhfT0JKRUNUX0xJTUlUKTtcbiAgICAgIH1cbiAgICAgIC8vIEluY2x1ZGUgZnVuZHMgaGVsZCBpbiB0aGUgYWRkcmVzcyBiYWxhbmNlIHN5c3RlbSAobm90IGluIGNvaW4gb2JqZWN0cykuXG4gICAgICAvLyBXaGVuIGdhc0RhdGEucGF5bWVudCBpcyBub24tZW1wdHksIFBhdGggMmMgbWVyZ2VzIHRoZSBhZGRyZXNzIGJhbGFuY2UgaW50byBHYXNDb2luLlxuICAgICAgLy8gV2hlbiBnYXNEYXRhLnBheW1lbnQgaXMgZW1wdHkgKGFkZHJlc3MtYmFsYW5jZSBvbmx5KSwgUGF0aCAyYiB1c2VzIHdpdGhkcmF3YWwrcmVkZWVtX2Z1bmRzLlxuICAgICAgY29uc3QgY29pbk9iamVjdHNCYWxhbmNlID0gaW5wdXRDb2lucy5yZWR1Y2UoKGFjYywgb2JqKSA9PiBhY2MucGx1cyhvYmouYmFsYW5jZSksIG5ldyBCaWdOdW1iZXIoMCkpO1xuICAgICAgbGV0IG5ldEFtb3VudCA9IGNvaW5PYmplY3RzQmFsYW5jZS5wbHVzKGZ1bmRzSW5BZGRyZXNzQmFsYW5jZSkubWludXMoTUFYX0dBU19CVURHRVQpO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgYW1vdW50OiBuZXRBbW91bnQudG9TdHJpbmcoKSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIC8vIENhc2UgMiBzZWxmLWZ1bmRlZDogYWxsIGJhbGFuY2UgaXMgaW4gYWRkcmVzcyBiYWxhbmNlLCBubyBjb2luIG9iamVjdHMuXG4gICAgICAvLyBnYXNEYXRhLnBheW1lbnQgbXVzdCBiZSBbXSBhbmQgYSBWYWxpZER1cmluZyBleHBpcmF0aW9uIGlzIHJlcXVpcmVkIHRvXG4gICAgICAvLyBwcmV2ZW50IHJlcGxheSBhdHRhY2tzIHdoZW4gdGhlcmUgYXJlIG5vIGdhcyBjb2luIG9iamVjdHMgdG8gYW5jaG9yIHVuaXF1ZW5lc3MuXG4gICAgICBsZXQgdmFsaWREdXJpbmdFeHBpcmF0aW9uOiB7IFZhbGlkRHVyaW5nOiBWYWxpZER1cmluZ0V4cGlyYXRpb24gfSB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChmdW5kc0luQWRkcmVzc0JhbGFuY2UuZ3QoMCkgJiYgY29pbk9iamVjdHNCYWxhbmNlLmVxKDApKSB7XG4gICAgICAgIGNvbnN0IHsgZXBvY2gsIGNoYWluSWQgfSA9IGF3YWl0IHV0aWxzLmdldENoYWluQ29udGV4dCh0aGlzLmdldFB1YmxpY05vZGVVcmwoKSk7XG4gICAgICAgIGNvbnN0IG5vbmNlID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDQpLnJlYWRVSW50MzJCRSgwKTtcbiAgICAgICAgdmFsaWREdXJpbmdFeHBpcmF0aW9uID0ge1xuICAgICAgICAgIFZhbGlkRHVyaW5nOiB7XG4gICAgICAgICAgICBtaW5FcG9jaDogeyBTb21lOiBlcG9jaCB9LFxuICAgICAgICAgICAgbWF4RXBvY2g6IHsgU29tZTogZXBvY2ggKyAxIH0sXG4gICAgICAgICAgICBtaW5UaW1lc3RhbXA6IHsgTm9uZTogbnVsbCB9LFxuICAgICAgICAgICAgbWF4VGltZXN0YW1wOiB7IE5vbmU6IG51bGwgfSxcbiAgICAgICAgICAgIGNoYWluOiBjaGFpbklkLFxuICAgICAgICAgICAgbm9uY2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gZmlyc3QgYnVpbGQgdGhlIHVuc2lnbmVkIHR4blxuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldENoYWluKCkpKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC50eXBlKFN1aVRyYW5zYWN0aW9uVHlwZS5UcmFuc2ZlcilcbiAgICAgICAgLnNlbmRlcihzZW5kZXJBZGRyZXNzKVxuICAgICAgICAuc2VuZChyZWNpcGllbnRzKVxuICAgICAgICAuZnVuZHNJbkFkZHJlc3NCYWxhbmNlKGZ1bmRzSW5BZGRyZXNzQmFsYW5jZS50b1N0cmluZygpKVxuICAgICAgICAuZ2FzRGF0YSh7XG4gICAgICAgICAgb3duZXI6IHNlbmRlckFkZHJlc3MsXG4gICAgICAgICAgcHJpY2U6IERFRkFVTFRfR0FTX1BSSUNFLFxuICAgICAgICAgIGJ1ZGdldDogTUFYX0dBU19CVURHRVQsXG4gICAgICAgICAgcGF5bWVudDogaW5wdXRDb2lucyxcbiAgICAgICAgfSk7XG5cbiAgICAgIGlmICh2YWxpZER1cmluZ0V4cGlyYXRpb24pIHtcbiAgICAgICAgdHhCdWlsZGVyLmV4cGlyYXRpb24odmFsaWREdXJpbmdFeHBpcmF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGVtcFR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmVlRXN0aW1hdGUgPSBhd2FpdCB0aGlzLmdldEZlZUVzdGltYXRlKHRlbXBUeC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIGNvbnN0IGdhc0J1ZGdldCA9IE1hdGgudHJ1bmMoZmVlRXN0aW1hdGUudG9OdW1iZXIoKSAqIERFRkFVTFRfR0FTX09WRVJIRUFEKTtcblxuICAgICAgbmV0QW1vdW50ID0gbmV0QW1vdW50LnBsdXMoTUFYX0dBU19CVURHRVQpLm1pbnVzKGdhc0J1ZGdldCk7XG4gICAgICByZWNpcGllbnRzWzBdLmFtb3VudCA9IG5ldEFtb3VudC50b1N0cmluZygpO1xuICAgICAgdHhCdWlsZGVyLnNlbmQocmVjaXBpZW50cyk7XG4gICAgICB0eEJ1aWxkZXIuZ2FzRGF0YSh7XG4gICAgICAgIG93bmVyOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICBwcmljZTogREVGQVVMVF9HQVNfUFJJQ0UsXG4gICAgICAgIGJ1ZGdldDogZ2FzQnVkZ2V0LFxuICAgICAgICBwYXltZW50OiBpbnB1dENvaW5zLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9ICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcbiAgICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRVbnNpZ25lZFN3ZWVwVHJhbnNhY3Rpb24odHhCdWlsZGVyLCBzZW5kZXJBZGRyZXNzLCBiaXRnb0tleSwgaWR4LCBkZXJpdmF0aW9uUGF0aCk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuc2lnblJlY292ZXJ5VHJhbnNhY3Rpb24odHhCdWlsZGVyLCBwYXJhbXMsIGRlcml2YXRpb25QYXRoLCBkZXJpdmVkUHVibGljS2V5LCBmYWxzZSk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNjYW5JbmRleDogaWR4LFxuICAgICAgICAgICAgcmVjb3ZlcnlBbW91bnQ6IG5ldEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgICAgc2VyaWFsaXplZFR4OiB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICAgICAgc2lnbmF0dXJlOiBCdWZmZXIuZnJvbSh0eC5zZXJpYWxpemVkU2lnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgICAgICBjb2luOiB0aGlzLmdldENoYWluKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbGFzdFNjYW5JbmRleDogaWR4LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBzdWZmaWNpZW50IGZ1bmRzIHRvIHJlY292ZXIuIFBsZWFzZSBzdGFydCB0aGUgbmV4dCBzY2FuIGF0IGFkZHJlc3MgaW5kZXggJHtlbmRJZHh9LiBJZiBpdCBpcyB0b2tlbiB0cmFuc2FjdGlvbiwgcGxlYXNlIGtlZXAgc3VmZmljaWVudCBTdWkgYmFsYW5jZSBpbiB0aGUgYWRkcmVzcyBmb3IgdGhlIHRyYW5zYWN0aW9uIGZlZS5gXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVjb3ZlclN1aVRva2VuKFxuICAgIHBhcmFtczogTVBDUmVjb3ZlcnlPcHRpb25zLFxuICAgIHRva2VuOiBTdWlDb2luLFxuICAgIHNlbmRlckFkZHJlc3M6IHN0cmluZyxcbiAgICBkZXJpdmF0aW9uUGF0aDogc3RyaW5nLFxuICAgIGRlcml2ZWRQdWJsaWNLZXk6IHN0cmluZyxcbiAgICBpZHg6IG51bWJlcixcbiAgICBiaXRnb0tleTogc3RyaW5nXG4gICk6IFByb21pc2U8TVBDVHhzIHwgTVBDU3dlZXBUeHM+IHtcbiAgICBjb25zdCBjb2luVHlwZSA9IGAke3Rva2VuLnBhY2thZ2VJZH06OiR7dG9rZW4ubW9kdWxlfTo6JHt0b2tlbi5zeW1ib2x9YDtcbiAgICBsZXQgdG9rZW5PYmplY3RzID0gYXdhaXQgdGhpcy5nZXRJbnB1dENvaW5zKHNlbmRlckFkZHJlc3MsIGNvaW5UeXBlKTtcbiAgICB0b2tlbk9iamVjdHMgPSB0b2tlbk9iamVjdHMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgcmV0dXJuIGIuYmFsYW5jZS5taW51cyhhLmJhbGFuY2UpLnRvTnVtYmVyKCk7XG4gICAgfSk7XG4gICAgaWYgKHRva2VuT2JqZWN0cy5sZW5ndGggPiBUT0tFTl9PQkpFQ1RfTElNSVQpIHtcbiAgICAgIHRva2VuT2JqZWN0cyA9IHRva2VuT2JqZWN0cy5zbGljZSgwLCBUT0tFTl9PQkpFQ1RfTElNSVQpO1xuICAgIH1cbiAgICBjb25zdCBjb2luT2JqZWN0c0JhbGFuY2UgPSB0b2tlbk9iamVjdHMucmVkdWNlKChhY2MsIG9iaikgPT4gYWNjLnBsdXMob2JqLmJhbGFuY2UpLCBuZXcgQmlnTnVtYmVyKDApKTtcbiAgICBjb25zdCB0b2tlbkJhbGFuY2VJbmZvID0gYXdhaXQgdGhpcy5nZXRCYWxhbmNlKHNlbmRlckFkZHJlc3MsIGNvaW5UeXBlKTtcbiAgICBjb25zdCB0b2tlbkZ1bmRzSW5BZGRyZXNzQmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIodG9rZW5CYWxhbmNlSW5mby5mdW5kc0luQWRkcmVzc0JhbGFuY2UpO1xuICAgIGNvbnN0IG5ldEFtb3VudCA9IGNvaW5PYmplY3RzQmFsYW5jZS5wbHVzKHRva2VuRnVuZHNJbkFkZHJlc3NCYWxhbmNlKTtcbiAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgYW1vdW50OiBuZXRBbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IGdhc0Ftb3VudCA9IG5ldyBCaWdOdW1iZXIoTUFYX0dBU19CVURHRVQpO1xuICAgIGxldCBnYXNPYmplY3RzID0gYXdhaXQgdGhpcy5nZXRJbnB1dENvaW5zKHNlbmRlckFkZHJlc3MpO1xuICAgIGdhc09iamVjdHMgPSB1dGlscy5zZWxlY3RPYmplY3RzSW5EZXNjT3JkZXJPZkJhbGFuY2UoZ2FzT2JqZWN0cywgZ2FzQW1vdW50KTtcbiAgICBpZiAoZ2FzT2JqZWN0cy5sZW5ndGggPj0gTUFYX0dBU19PQkpFQ1RTKSB7XG4gICAgICBnYXNPYmplY3RzID0gZ2FzT2JqZWN0cy5zbGljZSgwLCBNQVhfR0FTX09CSkVDVFMgLSAxKTtcbiAgICB9XG5cbiAgICAvLyBmaXJzdCBidWlsZCB0aGUgdW5zaWduZWQgdHhuXG4gICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KHRva2VuKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAuZ2V0VG9rZW5UcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgLnR5cGUoU3VpVHJhbnNhY3Rpb25UeXBlLlRva2VuVHJhbnNmZXIpXG4gICAgICAuc2VuZGVyKHNlbmRlckFkZHJlc3MpXG4gICAgICAuc2VuZChyZWNpcGllbnRzKVxuICAgICAgLmZ1bmRzSW5BZGRyZXNzQmFsYW5jZSh0b2tlbkZ1bmRzSW5BZGRyZXNzQmFsYW5jZS50b1N0cmluZygpKVxuICAgICAgLmdhc0RhdGEoe1xuICAgICAgICBvd25lcjogc2VuZGVyQWRkcmVzcyxcbiAgICAgICAgcHJpY2U6IERFRkFVTFRfR0FTX1BSSUNFLFxuICAgICAgICBidWRnZXQ6IE1BWF9HQVNfQlVER0VULFxuICAgICAgICBwYXltZW50OiBnYXNPYmplY3RzLFxuICAgICAgfSk7XG5cbiAgICBpZiAodG9rZW5PYmplY3RzLmxlbmd0aCA+IDApIHtcbiAgICAgIHR4QnVpbGRlci5pbnB1dE9iamVjdHModG9rZW5PYmplY3RzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wVHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRva2VuVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICBjb25zdCBmZWVFc3RpbWF0ZSA9IGF3YWl0IHRoaXMuZ2V0RmVlRXN0aW1hdGUodGVtcFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpO1xuICAgIGNvbnN0IGdhc0J1ZGdldCA9IE1hdGgudHJ1bmMoZmVlRXN0aW1hdGUudG9OdW1iZXIoKSAqIERFRkFVTFRfR0FTX09WRVJIRUFEKTtcblxuICAgIHR4QnVpbGRlci5nYXNEYXRhKHtcbiAgICAgIG93bmVyOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgcHJpY2U6IERFRkFVTFRfR0FTX1BSSUNFLFxuICAgICAgYnVkZ2V0OiBnYXNCdWRnZXQsXG4gICAgICBwYXltZW50OiBnYXNPYmplY3RzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlO1xuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIHJldHVybiB0aGlzLmJ1aWxkVW5zaWduZWRTd2VlcFRyYW5zYWN0aW9uKHR4QnVpbGRlciwgc2VuZGVyQWRkcmVzcywgYml0Z29LZXksIGlkeCwgZGVyaXZhdGlvblBhdGgsIHRva2VuKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnNpZ25SZWNvdmVyeVRyYW5zYWN0aW9uKHR4QnVpbGRlciwgcGFyYW1zLCBkZXJpdmF0aW9uUGF0aCwgZGVyaXZlZFB1YmxpY0tleSwgdHJ1ZSk7XG4gICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRva2VuVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBzY2FuSW5kZXg6IGlkeCxcbiAgICAgICAgICByZWNvdmVyeUFtb3VudDogbmV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgc2VyaWFsaXplZFR4OiB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICAgIHNpZ25hdHVyZTogQnVmZmVyLmZyb20odHguc2VyaWFsaXplZFNpZykudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgICAgIGNvaW46IHRva2VuLm5hbWUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgbGFzdFNjYW5JbmRleDogaWR4LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJ1aWxkVW5zaWduZWRTd2VlcFRyYW5zYWN0aW9uKFxuICAgIHR4QnVpbGRlcjogVHJhbnNhY3Rpb25CdWlsZGVyLFxuICAgIHNlbmRlckFkZHJlc3M6IHN0cmluZyxcbiAgICBiaXRnb0tleTogc3RyaW5nLFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgZGVyaXZhdGlvblBhdGg6IHN0cmluZyxcbiAgICB0b2tlbj86IFN1aUNvaW5cbiAgKTogUHJvbWlzZTxNUENTd2VlcFR4cz4ge1xuICAgIGNvbnN0IGlzVG9rZW5UcmFuc2FjdGlvbiA9ICEhdG9rZW47XG4gICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGlzVG9rZW5UcmFuc2FjdGlvblxuICAgICAgPyAoKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUb2tlblRyYW5zZmVyVHJhbnNhY3Rpb24pXG4gICAgICA6ICgoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb24pO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHVuc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICBjb25zdCBzZXJpYWxpemVkVHhIZXggPSBCdWZmZXIuZnJvbShzZXJpYWxpemVkVHgsICdiYXNlNjQnKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgcGFyc2VkVHggPSBhd2FpdCB0aGlzLnBhcnNlVHJhbnNhY3Rpb24oeyB0eEhleDogc2VyaWFsaXplZFR4SGV4IH0pO1xuICAgIGNvbnN0IHdhbGxldENvaW4gPSBpc1Rva2VuVHJhbnNhY3Rpb24gPyB0b2tlbi5uYW1lIDogdGhpcy5nZXRDaGFpbigpO1xuICAgIGNvbnN0IG91dHB1dCA9IHBhcnNlZFR4Lm91dHB1dHNbMF07XG4gICAgY29uc3QgaW5wdXRzID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiBzZW5kZXJBZGRyZXNzLFxuICAgICAgICB2YWx1ZVN0cmluZzogb3V0cHV0LmFtb3VudCxcbiAgICAgICAgdmFsdWU6IG5ldyBCaWdOdW1iZXIob3V0cHV0LmFtb3VudCksXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3Qgb3V0cHV0cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogb3V0cHV0LmFkZHJlc3MsXG4gICAgICAgIHZhbHVlU3RyaW5nOiBvdXRwdXQuYW1vdW50LFxuICAgICAgICBjb2luTmFtZTogd2FsbGV0Q29pbixcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCBzcGVuZEFtb3VudCA9IG91dHB1dC5hbW91bnQ7XG4gICAgY29uc3QgY29tcGxldGVkUGFyc2VkVHggPSB7XG4gICAgICBpbnB1dHM6IGlucHV0cyxcbiAgICAgIG91dHB1dHM6IG91dHB1dHMsXG4gICAgICBzcGVuZEFtb3VudDogc3BlbmRBbW91bnQsXG4gICAgICB0eXBlOiBpc1Rva2VuVHJhbnNhY3Rpb24gPyBTdWlUcmFuc2FjdGlvblR5cGUuVG9rZW5UcmFuc2ZlciA6IFN1aVRyYW5zYWN0aW9uVHlwZS5UcmFuc2ZlcixcbiAgICB9O1xuICAgIGNvbnN0IGZlZSA9IHBhcnNlZFR4LmZlZTtcbiAgICBjb25zdCBmZWVJbmZvID0geyBmZWU6IGZlZS50b051bWJlcigpLCBmZWVTdHJpbmc6IGZlZS50b1N0cmluZygpIH07XG4gICAgY29uc3QgY29pblNwZWNpZmljID0geyBjb21tb25LZXljaGFpbjogYml0Z29LZXkgfTtcbiAgICBjb25zdCB0cmFuc2FjdGlvbjogTVBDVHggPSB7XG4gICAgICBzZXJpYWxpemVkVHg6IHNlcmlhbGl6ZWRUeEhleCxcbiAgICAgIHNjYW5JbmRleDogaW5kZXgsXG4gICAgICBjb2luOiB3YWxsZXRDb2luLFxuICAgICAgc2lnbmFibGVIZXg6IHVuc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmFibGVQYXlsb2FkLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgcGFyc2VkVHg6IGNvbXBsZXRlZFBhcnNlZFR4LFxuICAgICAgZmVlSW5mbzogZmVlSW5mbyxcbiAgICAgIGNvaW5TcGVjaWZpYzogY29pblNwZWNpZmljLFxuICAgIH07XG4gICAgY29uc3QgdW5zaWduZWRUeDogTVBDVW5zaWduZWRUeCA9IHsgdW5zaWduZWRUeDogdHJhbnNhY3Rpb24sIHNpZ25hdHVyZVNoYXJlczogW10gfTtcbiAgICBjb25zdCB0cmFuc2FjdGlvbnM6IE1QQ1Vuc2lnbmVkVHhbXSA9IFt1bnNpZ25lZFR4XTtcbiAgICBjb25zdCB0eFJlcXVlc3Q6IFJlY292ZXJ5VHhSZXF1ZXN0ID0ge1xuICAgICAgdHJhbnNhY3Rpb25zOiB0cmFuc2FjdGlvbnMsXG4gICAgICB3YWxsZXRDb2luOiB3YWxsZXRDb2luLFxuICAgIH07XG4gICAgcmV0dXJuIHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2lnblJlY292ZXJ5VHJhbnNhY3Rpb24oXG4gICAgdHhCdWlsZGVyOiBUcmFuc2FjdGlvbkJ1aWxkZXIsXG4gICAgcGFyYW1zOiBNUENSZWNvdmVyeU9wdGlvbnMsXG4gICAgZGVyaXZhdGlvblBhdGg6IHN0cmluZyxcbiAgICBkZXJpdmVkUHVibGljS2V5OiBzdHJpbmcsXG4gICAgaXNUb2tlblRyYW5zYWN0aW9uOiBib29sZWFuXG4gICkge1xuICAgIC8vIFRPRE8oQkctNTEwOTIpOiBUaGlzIGxvb2tzIGxpa2UgYSBjb21tb24gcGFydCB3aGljaCBjYW4gYmUgZXh0cmFjdGVkIG91dCB0b29cbiAgICBjb25zdCB1bnNpZ25lZFR4ID0gaXNUb2tlblRyYW5zYWN0aW9uXG4gICAgICA/ICgoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRva2VuVHJhbnNmZXJUcmFuc2FjdGlvbilcbiAgICAgIDogKChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbik7XG4gICAgaWYgKCFwYXJhbXMudXNlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuYmFja3VwS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYmFja3VwS2V5Jyk7XG4gICAgfVxuICAgIGlmICghcGFyYW1zLndhbGxldFBhc3NwaHJhc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgIH1cblxuICAgIC8vIENsZWFuIHVwIHdoaXRlc3BhY2UgZnJvbSBlbnRlcmVkIHZhbHVlc1xuICAgIGNvbnN0IHVzZXJLZXkgPSBwYXJhbXMudXNlcktleS5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9IHBhcmFtcy5iYWNrdXBLZXkucmVwbGFjZSgvXFxzL2csICcnKTtcblxuICAgIC8vIERlY3J5cHQgcHJpdmF0ZSBrZXlzIGZyb20gS2V5Q2FyZCB2YWx1ZXNcbiAgICBsZXQgdXNlclBydjogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICB1c2VyUHJ2ID0gYXdhaXQgdGhpcy5iaXRnby5kZWNyeXB0QXN5bmMoe1xuICAgICAgICBpbnB1dDogdXNlcktleSxcbiAgICAgICAgcGFzc3dvcmQ6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciBkZWNyeXB0aW5nIHVzZXIga2V5Y2hhaW46ICR7ZS5tZXNzYWdlfWApO1xuICAgIH1cbiAgICAvKiogVE9ETyBCRy01MjQxOSBJbXBsZW1lbnQgQ29kZWMgZm9yIHBhcnNpbmcgKi9cbiAgICBjb25zdCB1c2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZSh1c2VyUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLlVzZXJTaWduaW5nTWF0ZXJpYWw7XG5cbiAgICBsZXQgYmFja3VwUHJ2OiBzdHJpbmc7XG4gICAgdHJ5IHtcbiAgICAgIGJhY2t1cFBydiA9IGF3YWl0IHRoaXMuYml0Z28uZGVjcnlwdEFzeW5jKHtcbiAgICAgICAgaW5wdXQ6IGJhY2t1cEtleSxcbiAgICAgICAgcGFzc3dvcmQ6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFcnJvciBkZWNyeXB0aW5nIGJhY2t1cCBrZXljaGFpbjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICAgIGNvbnN0IGJhY2t1cFNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UoYmFja3VwUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLkJhY2t1cFNpZ25pbmdNYXRlcmlhbDtcbiAgICAvKiAqKioqKioqKioqKioqKioqKioqKioqIEVORCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIC8vIGFkZCBzaWduYXR1cmVcbiAgICBjb25zdCBzaWduYXR1cmVIZXggPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0VFNTU2lnbmF0dXJlKFxuICAgICAgdXNlclNpZ25pbmdNYXRlcmlhbCxcbiAgICAgIGJhY2t1cFNpZ25pbmdNYXRlcmlhbCxcbiAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgdW5zaWduZWRUeFxuICAgICk7XG4gICAgdHhCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1YjogZGVyaXZlZFB1YmxpY0tleSB9LCBzaWduYXR1cmVIZXgpO1xuICB9XG5cbiAgYXN5bmMgYnJvYWRjYXN0VHJhbnNhY3Rpb24oe1xuICAgIHRyYW5zYWN0aW9ucyxcbiAgfTogQmFzZUJyb2FkY2FzdFRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8QmFzZUJyb2FkY2FzdFRyYW5zYWN0aW9uUmVzdWx0PiB7XG4gICAgY29uc3QgdHhJZHM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQdWJsaWNOb2RlVXJsKCk7XG4gICAgbGV0IGRpZ2VzdCA9ICcnO1xuICAgIGlmICghIXRyYW5zYWN0aW9ucykge1xuICAgICAgZm9yIChjb25zdCB0eG4gb2YgdHJhbnNhY3Rpb25zKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGlnZXN0ID0gYXdhaXQgdXRpbHMuZXhlY3V0ZVRyYW5zYWN0aW9uQmxvY2sodXJsLCB0eG4uc2VyaWFsaXplZFR4LCBbdHhuLnNpZ25hdHVyZSFdKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGJyb2FkY2FzdCB0cmFuc2FjdGlvbiwgZXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICB9XG4gICAgICAgIHR4SWRzLnB1c2goZGlnZXN0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgdHhJZHMgfTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGFzeW5jIGNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtczogTVBDU3dlZXBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPE1QQ1R4cz4ge1xuICAgIGNvbnN0IHJlcSA9IHBhcmFtcy5zaWduYXR1cmVTaGFyZXM7XG4gICAgY29uc3QgYnJvYWRjYXN0YWJsZVRyYW5zYWN0aW9uczogTVBDVHhbXSA9IFtdO1xuICAgIGxldCBsYXN0U2NhbkluZGV4ID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVxLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSByZXFbaV0udHhSZXF1ZXN0LnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgaWYgKCFyZXFbaV0ub3ZjIHx8ICFyZXFbaV0ub3ZjWzBdLmVkZHNhU2lnbmF0dXJlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYXR1cmUocyknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHJlcVtpXS5vdmNbMF0uZWRkc2FTaWduYXR1cmU7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLnNpZ25hYmxlSGV4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYWJsZSBoZXgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi5zaWduYWJsZUhleCEsICdoZXgnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IE1QQy52ZXJpZnkobWVzc2FnZUJ1ZmZlciwgc2lnbmF0dXJlKTtcbiAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZUhleCA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHNpZ25hdHVyZS5SLCAnaGV4JyksIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5zaWdtYSwgJ2hleCcpXSk7XG4gICAgICBjb25zdCBzZXJpYWxpemVkVHhCYXNlNjQgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi5zZXJpYWxpemVkVHgsICdoZXgnKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSB0aGlzLmdldEJ1aWxkZXIoKS5mcm9tKHNlcmlhbGl6ZWRUeEJhc2U2NCk7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8uY29tbW9uS2V5Y2hhaW4pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGNvbW1vbiBrZXljaGFpbicpO1xuICAgICAgfVxuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmNvbW1vbktleWNoYWluISBhcyBzdHJpbmc7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmRlcml2YXRpb25QYXRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBkZXJpdmF0aW9uIHBhdGgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gdHJhbnNhY3Rpb24uZGVyaXZhdGlvblBhdGggYXMgc3RyaW5nO1xuICAgICAgY29uc3QgZGVyaXZlZFB1YmxpY0tleSA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleWNoYWluLCBkZXJpdmF0aW9uUGF0aCkuc2xpY2UoMCwgNjQpO1xuXG4gICAgICAvLyBhZGQgY29tYmluZWQgc2lnbmF0dXJlIGZyb20gb3ZjXG4gICAgICB0eEJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBkZXJpdmVkUHVibGljS2V5IH0sIHNpZ25hdHVyZUhleCk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBvdXRwdXRBbW91bnQgPSBzaWduZWRUcmFuc2FjdGlvbi5leHBsYWluVHJhbnNhY3Rpb24oKS5vdXRwdXRBbW91bnQ7XG5cbiAgICAgIGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMucHVzaCh7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IHRyYW5zYWN0aW9uLnNjYW5JbmRleCxcbiAgICAgICAgc2lnbmF0dXJlOiBCdWZmZXIuZnJvbShzaWduZWRUcmFuc2FjdGlvbi5zZXJpYWxpemVkU2lnKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgICAgIHJlY292ZXJ5QW1vdW50OiBvdXRwdXRBbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaSA9PT0gcmVxLmxlbmd0aCAtIDEgJiYgdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5sYXN0U2NhbkluZGV4KSB7XG4gICAgICAgIGxhc3RTY2FuSW5kZXggPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmxhc3RTY2FuSW5kZXggYXMgbnVtYmVyO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHRyYW5zYWN0aW9uczogYnJvYWRjYXN0YWJsZVRyYW5zYWN0aW9ucywgbGFzdFNjYW5JbmRleCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBuYXRpdmUgU1VJIHJlY292ZXJpZXMgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgaW4gYmF0Y2ggd2l0aG91dCBCaXRHby5cbiAgICogRnVuZHMgd2lsbCBiZSByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0LiBZb3UgbmVlZCB0byBpbml0aWF0ZSBhbm90aGVyIHN3ZWVwIHR4biBhZnRlciB0aGF0LlxuICAgKlxuICAgKiBAcGFyYW0ge01QQ0NvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnN9IHBhcmFtcyAtIG9wdGlvbnMgZm9yIGNvbnNvbGlkYXRpb24gcmVjb3ZlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBzdGFydCBzY2FubmluZyBmcm9tLiBkZWZhdWx0IHRvIDEgKGluY2x1c2l2ZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLmVuZGluZ1NjYW5JbmRleF0gLSByZWNlaXZlIGFkZHJlc3MgaW5kZXggdG8gZW5kIHNjYW5uaW5nIGF0LiBkZWZhdWx0IHRvIHN0YXJ0aW5nU2NhbkluZGV4ICsgMjAgKGV4Y2x1c2l2ZSkuXG4gICAqL1xuICBhc3luYyByZWNvdmVyQ29uc29saWRhdGlvbnMocGFyYW1zOiBNUENDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeHMgfCBNUENTd2VlcFR4cz4ge1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9ICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcbiAgICBjb25zdCBzdGFydElkeCA9IHV0aWxzLnZhbGlkYXRlTm9uTmVnYXRpdmVOdW1iZXIoXG4gICAgICAxLFxuICAgICAgJ0ludmFsaWQgc3RhcnRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzJyxcbiAgICAgIHBhcmFtcy5zdGFydGluZ1NjYW5JbmRleFxuICAgICk7XG4gICAgY29uc3QgZW5kSWR4ID0gdXRpbHMudmFsaWRhdGVOb25OZWdhdGl2ZU51bWJlcihcbiAgICAgIHN0YXJ0SWR4ICsgREVGQVVMVF9TQ0FOX0ZBQ1RPUixcbiAgICAgICdJbnZhbGlkIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMnLFxuICAgICAgcGFyYW1zLmVuZGluZ1NjYW5JbmRleFxuICAgICk7XG5cbiAgICBpZiAoc3RhcnRJZHggPCAxIHx8IGVuZElkeCA8PSBzdGFydElkeCB8fCBlbmRJZHggLSBzdGFydElkeCA+IDEwICogREVGQVVMVF9TQ0FOX0ZBQ1RPUikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogJHtzdGFydElkeH0sIGVuZGluZ1NjYW5JbmRleDogJHtlbmRJZHh9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXkgPSBwYXJhbXMuYml0Z29LZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gKHBhcmFtcy5zZWVkID8gZ2V0RGVyaXZhdGlvblBhdGgocGFyYW1zLnNlZWQpIDogJ20nKSArICcvMCc7XG4gICAgY29uc3QgZGVyaXZlZFB1YmxpY0tleSA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGJpdGdvS2V5LCBkZXJpdmF0aW9uUGF0aCkuc2xpY2UoMCwgNjQpO1xuICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShkZXJpdmVkUHVibGljS2V5KTtcblxuICAgIGNvbnN0IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnM6IGFueVtdID0gW107XG4gICAgbGV0IGxhc3RTY2FuSW5kZXggPSBzdGFydElkeDtcbiAgICBmb3IgKGxldCBpZHggPSBzdGFydElkeDsgaWR4IDwgZW5kSWR4OyBpZHgrKykge1xuICAgICAgY29uc3QgcmVjb3ZlclBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHBhcmFtcy5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcGFyYW1zLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHNlZWQ6IHBhcmFtcy5zZWVkLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogcGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IGlkeCxcbiAgICAgICAgc2NhbjogMSxcbiAgICAgIH07XG5cbiAgICAgIGxldCByZWNvdmVyeVRyYW5zYWN0aW9uOiBNUENUeHMgfCBNUENTd2VlcFR4cztcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlY292ZXJ5VHJhbnNhY3Rpb24gPSBhd2FpdCB0aGlzLnJlY292ZXIocmVjb3ZlclBhcmFtcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlLm1lc3NhZ2Uuc3RhcnRzV2l0aCgnRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBzdWZmaWNpZW50IGZ1bmRzIHRvIHJlY292ZXIuJykpIHtcbiAgICAgICAgICBsYXN0U2NhbkluZGV4ID0gaWR4O1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5wdXNoKChyZWNvdmVyeVRyYW5zYWN0aW9uIGFzIE1QQ1N3ZWVwVHhzKS50eFJlcXVlc3RzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMucHVzaCgocmVjb3ZlcnlUcmFuc2FjdGlvbiBhcyBNUENUeHMpLnRyYW5zYWN0aW9uc1swXSk7XG4gICAgICB9XG4gICAgICBsYXN0U2NhbkluZGV4ID0gaWR4O1xuICAgIH1cblxuICAgIGlmIChjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRGlkIG5vdCBmaW5kIGFuIGFkZHJlc3Mgd2l0aCBzdWZmaWNpZW50IGZ1bmRzIHRvIHJlY292ZXIuIFBsZWFzZSBzdGFydCB0aGUgbmV4dCBzY2FuIGF0IGFkZHJlc3MgaW5kZXggJHtcbiAgICAgICAgICBsYXN0U2NhbkluZGV4ICsgMVxuICAgICAgICB9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgLy8gbGFzdFNjYW5JbmRleCB3aWxsIGJlIHVzZWQgdG8gaW5mb3JtIHVzZXIgdGhlIGxhc3QgYWRkcmVzcyBpbmRleCBzY2FubmVkIGZvciBhdmFpbGFibGUgZnVuZHMgKHNvIHRoZXkgY2FuXG4gICAgICAvLyBhcHByb3ByaWF0ZWx5IGFkanVzdCB0aGUgc2NhbiByYW5nZSBvbiB0aGUgbmV4dCBpdGVyYXRpb24gb2YgY29uc29saWRhdGlvbiByZWNvdmVyaWVzKS4gSW4gdGhlIGNhc2Ugb2YgdW5zaWduZWRcbiAgICAgIC8vIHN3ZWVwIGNvbnNvbGlkYXRpb25zLCB0aGlzIGxhc3RTY2FuSW5kZXggd2lsbCBiZSBwcm92aWRlZCBpbiB0aGUgY29pblNwZWNpZmljIG9mIHRoZSBsYXN0IHR4biBtYWRlLlxuICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5sZW5ndGggLSAxXG4gICAgICBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5sYXN0U2NhbkluZGV4ID0gbGFzdFNjYW5JbmRleDtcbiAgICAgIHJldHVybiB7IHR4UmVxdWVzdHM6IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMsIGxhc3RTY2FuSW5kZXggfTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIHNldENvaW5TcGVjaWZpY0ZpZWxkc0luSW50ZW50KGludGVudDogUG9wdWxhdGVkSW50ZW50LCBwYXJhbXM6IFByZWJ1aWxkVHJhbnNhY3Rpb25XaXRoSW50ZW50T3B0aW9ucyk6IHZvaWQge1xuICAgIGludGVudC51bnNwZW50cyA9IHBhcmFtcy51bnNwZW50cztcbiAgICBpbnRlbnQuZnVuZHNJbkFkZHJlc3NCYWxhbmNlID0gcGFyYW1zLmZ1bmRzSW5BZGRyZXNzQmFsYW5jZTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGF1ZGl0RGVjcnlwdGVkS2V5KHsgcHVibGljS2V5LCBwcnYsIG11bHRpU2lnVHlwZSB9OiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcykge1xuICAgIGlmIChtdWx0aVNpZ1R5cGUgIT09ICd0c3MnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIG11bHRpU2lnVHlwZScpO1xuICAgIH1cblxuICAgIGF1ZGl0RWRkc2FQcml2YXRlS2V5KHBydiwgcHVibGljS2V5ID8/ICcnKTtcbiAgfVxufVxuIl19
|