@bitgo-beta/abstract-substrate 1.0.1-beta.14 → 1.0.1-beta.1400
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/abstractSubstrateCoin.d.ts +77 -4
- package/dist/src/abstractSubstrateCoin.d.ts.map +1 -1
- package/dist/src/abstractSubstrateCoin.js +436 -16
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +16 -1
- package/dist/src/lib/constants.d.ts +7 -0
- package/dist/src/lib/constants.d.ts.map +1 -0
- package/dist/src/lib/constants.js +10 -0
- package/dist/src/lib/errors.d.ts +8 -0
- package/dist/src/lib/errors.d.ts.map +1 -0
- package/dist/src/lib/errors.js +19 -0
- package/dist/src/lib/iface.d.ts +257 -0
- package/dist/src/lib/iface.d.ts.map +1 -0
- package/dist/src/lib/iface.js +87 -0
- package/dist/src/lib/index.d.ts +12 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +61 -0
- package/dist/src/lib/keyPair.d.ts +31 -0
- package/dist/src/lib/keyPair.d.ts.map +1 -0
- package/dist/src/lib/keyPair.js +110 -0
- package/dist/src/lib/nativeTransferBuilder.d.ts +61 -0
- package/dist/src/lib/nativeTransferBuilder.d.ts.map +1 -0
- package/dist/src/lib/nativeTransferBuilder.js +150 -0
- package/dist/src/lib/singletonRegistry.d.ts +8 -0
- package/dist/src/lib/singletonRegistry.d.ts.map +1 -0
- package/dist/src/lib/singletonRegistry.js +20 -0
- package/dist/src/lib/transaction.d.ts +92 -0
- package/dist/src/lib/transaction.d.ts.map +1 -0
- package/dist/src/lib/transaction.js +572 -0
- package/dist/src/lib/transactionBuilder.d.ts +121 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
- package/dist/src/lib/transactionBuilder.js +334 -0
- package/dist/src/lib/transferBuilder.d.ts +6 -0
- package/dist/src/lib/transferBuilder.d.ts.map +1 -0
- package/dist/src/lib/transferBuilder.js +11 -0
- package/dist/src/lib/txnSchema.d.ts +13 -0
- package/dist/src/lib/txnSchema.d.ts.map +1 -0
- package/dist/src/lib/txnSchema.js +74 -0
- package/dist/src/lib/utils.d.ts +152 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/src/lib/utils.js +297 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -6
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -14
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SubstrateCoin = void 0;
|
|
6
|
+
exports.SubstrateCoin = exports.DEFAULT_SCAN_FACTOR = void 0;
|
|
4
7
|
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
8
|
+
const lib_1 = require("./lib");
|
|
9
|
+
const constants_1 = require("./lib/constants");
|
|
10
|
+
const utils_1 = __importDefault(require("./lib/utils"));
|
|
11
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
12
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
13
|
+
exports.DEFAULT_SCAN_FACTOR = 20;
|
|
5
14
|
class SubstrateCoin extends sdk_core_1.BaseCoin {
|
|
6
15
|
constructor(bitgo, staticsCoin) {
|
|
7
16
|
super(bitgo);
|
|
17
|
+
this.MAX_VALIDITY_DURATION = 2400;
|
|
18
|
+
this.SWEEP_TXN_DURATION = 64;
|
|
8
19
|
if (!staticsCoin) {
|
|
9
20
|
throw new Error('missing required constructor parameter staticsCoin');
|
|
10
21
|
}
|
|
11
22
|
this._staticsCoin = staticsCoin;
|
|
12
23
|
}
|
|
13
|
-
static createInstance(bitgo, staticsCoin) {
|
|
14
|
-
return new SubstrateCoin(bitgo, staticsCoin);
|
|
15
|
-
}
|
|
16
24
|
/**
|
|
17
25
|
* Creates an instance of TransactionBuilderFactory for the coin specific sdk
|
|
18
26
|
*/
|
|
@@ -21,7 +29,7 @@ class SubstrateCoin extends sdk_core_1.BaseCoin {
|
|
|
21
29
|
}
|
|
22
30
|
/** @inheritDoc **/
|
|
23
31
|
getBaseFactor() {
|
|
24
|
-
|
|
32
|
+
return Math.pow(10, this._staticsCoin.decimalPlaces);
|
|
25
33
|
}
|
|
26
34
|
/** @inheritDoc **/
|
|
27
35
|
getChain() {
|
|
@@ -39,38 +47,450 @@ class SubstrateCoin extends sdk_core_1.BaseCoin {
|
|
|
39
47
|
supportsTss() {
|
|
40
48
|
return true;
|
|
41
49
|
}
|
|
50
|
+
/** inherited doc */
|
|
51
|
+
getDefaultMultisigType() {
|
|
52
|
+
return sdk_core_1.multisigTypes.tss;
|
|
53
|
+
}
|
|
42
54
|
/** @inheritDoc **/
|
|
43
55
|
getMPCAlgorithm() {
|
|
44
56
|
return 'eddsa';
|
|
45
57
|
}
|
|
46
58
|
/** @inheritDoc **/
|
|
47
59
|
generateKeyPair(seed) {
|
|
48
|
-
|
|
60
|
+
const keyPair = seed ? new lib_1.KeyPair({ seed }) : new lib_1.KeyPair();
|
|
61
|
+
const keys = keyPair.getKeys();
|
|
62
|
+
if (!keys.prv) {
|
|
63
|
+
throw new Error('Missing prv in key generation.');
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
pub: keys.pub,
|
|
67
|
+
prv: keys.prv,
|
|
68
|
+
};
|
|
49
69
|
}
|
|
50
70
|
/** @inheritDoc **/
|
|
51
71
|
isValidPub(pub) {
|
|
52
|
-
|
|
72
|
+
return utils_1.default.isValidPublicKey(pub);
|
|
53
73
|
}
|
|
54
74
|
/** @inheritDoc **/
|
|
55
|
-
isWalletAddress(params) {
|
|
56
|
-
|
|
75
|
+
async isWalletAddress(params) {
|
|
76
|
+
const isValid = await (0, sdk_core_1.verifyEddsaTssWalletAddress)(params, (addr) => this.isValidAddress(addr), (pubKey) => this.getAddressFromPublicKey(pubKey));
|
|
77
|
+
if (!isValid) {
|
|
78
|
+
throw new sdk_core_1.UnexpectedAddressError(`address validation failure: ${params.address} is not a wallet address`);
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
57
81
|
}
|
|
58
82
|
/** @inheritDoc **/
|
|
59
|
-
parseTransaction(params) {
|
|
60
|
-
|
|
83
|
+
async parseTransaction(params) {
|
|
84
|
+
return {};
|
|
61
85
|
}
|
|
62
86
|
/** @inheritDoc **/
|
|
63
|
-
verifyTransaction(params) {
|
|
64
|
-
|
|
87
|
+
async verifyTransaction(params) {
|
|
88
|
+
const { txParams, txPrebuild } = params;
|
|
89
|
+
if (!txParams) {
|
|
90
|
+
throw new Error('missing txParams');
|
|
91
|
+
}
|
|
92
|
+
if (!txPrebuild) {
|
|
93
|
+
throw new Error('missing txPrebuild');
|
|
94
|
+
}
|
|
95
|
+
if (!txPrebuild.txHex) {
|
|
96
|
+
throw new Error('missing txHex in txPrebuild');
|
|
97
|
+
}
|
|
98
|
+
const factory = this.getBuilder();
|
|
99
|
+
// Use the live chain material embedded in the prebuild (if present) so the factory can decode
|
|
100
|
+
// transactions built against a chain spec version newer than the SDK's hardcoded metadata.
|
|
101
|
+
// Without this, the factory falls back to its hardcoded material and misidentifies the call
|
|
102
|
+
// pallet (e.g. reads a Balances transfer as treasury.disbursement after a chain upgrade).
|
|
103
|
+
const prebuildMaterial = txPrebuild
|
|
104
|
+
.coinSpecific?.material;
|
|
105
|
+
if (prebuildMaterial && typeof factory.material === 'function') {
|
|
106
|
+
factory.material(prebuildMaterial);
|
|
107
|
+
}
|
|
108
|
+
// Token enablement (preApproveAsset) transactions have no destination address — they are
|
|
109
|
+
// self-transactions signed by the wallet. Skip transfer recipient validation, consistent
|
|
110
|
+
// with how XRP and Algo handle enabletoken in their verifyTransaction implementations.
|
|
111
|
+
if (txParams.type === 'enabletoken') {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
const txBuilder = factory.from(txPrebuild.txHex);
|
|
115
|
+
const txTo = txBuilder['_to'];
|
|
116
|
+
const txAmount = txBuilder['_amount'];
|
|
117
|
+
const isSweep = txBuilder['_sweepFreeBalance'] === true;
|
|
118
|
+
if (txParams.recipients !== undefined) {
|
|
119
|
+
if (txParams.recipients.length === 0) {
|
|
120
|
+
throw new Error('missing recipients in txParams');
|
|
121
|
+
}
|
|
122
|
+
if (Array.isArray(txParams.recipients) && txParams.recipients.length > 1) {
|
|
123
|
+
throw new Error(`${this.getChain()} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
|
|
124
|
+
}
|
|
125
|
+
if (txParams.recipients[0].address !== txTo) {
|
|
126
|
+
throw new sdk_core_1.TxIntentMismatchRecipientError(`Recipient address ${txParams.recipients[0].address} does not match transaction destination address ${txTo}`, params.reqId, [txParams], txPrebuild.txHex, [{ address: txTo, amount: txAmount }]);
|
|
127
|
+
}
|
|
128
|
+
if (!isSweep && txParams.recipients[0].amount !== txAmount) {
|
|
129
|
+
throw new sdk_core_1.TxIntentMismatchRecipientError(`Recipient amount ${txParams.recipients[0].amount} does not match transaction amount ${txAmount}`, params.reqId, [txParams], txPrebuild.txHex, [{ address: txTo, amount: txAmount }]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
65
133
|
}
|
|
66
134
|
/** @inheritDoc **/
|
|
67
135
|
isValidAddress(address) {
|
|
68
|
-
|
|
136
|
+
return utils_1.default.isValidAddress(address);
|
|
137
|
+
}
|
|
138
|
+
verifySignTransactionParams(params) {
|
|
139
|
+
const prv = params?.prv;
|
|
140
|
+
const txHex = params?.txPrebuild?.txHex;
|
|
141
|
+
if (typeof txHex !== 'string') {
|
|
142
|
+
throw new Error(`txHex must be string, got type ${typeof txHex}`);
|
|
143
|
+
}
|
|
144
|
+
if (typeof prv !== 'string') {
|
|
145
|
+
throw new Error(`prv must be string, got type ${typeof prv}`);
|
|
146
|
+
}
|
|
147
|
+
return { txHex, prv };
|
|
69
148
|
}
|
|
70
149
|
/** @inheritDoc **/
|
|
71
|
-
signTransaction(params) {
|
|
150
|
+
async signTransaction(params) {
|
|
151
|
+
const { txHex, prv } = this.verifySignTransactionParams(params);
|
|
152
|
+
const factory = this.getBuilder();
|
|
153
|
+
const txBuilder = factory.from(txHex);
|
|
154
|
+
const keyPair = new lib_1.KeyPair({ prv: prv });
|
|
155
|
+
const { referenceBlock, blockNumber, transactionVersion, sender } = params.txPrebuild.transaction;
|
|
156
|
+
txBuilder
|
|
157
|
+
.validity({ firstValid: blockNumber, maxDuration: this.getMaxValidityDurationBlocks() })
|
|
158
|
+
.referenceBlock(referenceBlock)
|
|
159
|
+
.version(transactionVersion)
|
|
160
|
+
.sender({ address: sender })
|
|
161
|
+
.sign({ key: keyPair.getKeys().prv });
|
|
162
|
+
const transaction = await txBuilder.build();
|
|
163
|
+
if (!transaction) {
|
|
164
|
+
throw new Error('Invalid transaction');
|
|
165
|
+
}
|
|
166
|
+
const signedTxHex = transaction.toBroadcastFormat();
|
|
167
|
+
return { txHex: signedTxHex };
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Retrieves the address format for the substrate coin.
|
|
171
|
+
*
|
|
172
|
+
* @returns {number} The address format as a number.
|
|
173
|
+
*/
|
|
174
|
+
getAddressFormat() {
|
|
175
|
+
return constants_1.DEFAULT_SUBSTRATE_PREFIX;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Retrieves the maximum validity duration in blocks.
|
|
179
|
+
*
|
|
180
|
+
* This method is intended to be overridden by subclasses to provide the specific
|
|
181
|
+
* maximum validity duration for different types of Substrate-based coins.
|
|
182
|
+
*
|
|
183
|
+
* @returns {number} The maximum validity duration in blocks.
|
|
184
|
+
* @throws {Error} If the method is not implemented by the subclass.
|
|
185
|
+
*/
|
|
186
|
+
getMaxValidityDurationBlocks() {
|
|
187
|
+
throw new Error('Method not implemented.');
|
|
188
|
+
}
|
|
189
|
+
getAddressFromPublicKey(Pubkey) {
|
|
190
|
+
return new lib_1.KeyPair({ pub: Pubkey }).getAddress(this.getAddressFormat());
|
|
191
|
+
}
|
|
192
|
+
async getInitializedNodeAPI() {
|
|
193
|
+
throw new Error('Method not implemented.');
|
|
194
|
+
}
|
|
195
|
+
async getAccountInfo(walletAddr) {
|
|
196
|
+
throw new Error('Method not implemented.');
|
|
197
|
+
}
|
|
198
|
+
async getFee(destAddr, srcAddr, amount) {
|
|
72
199
|
throw new Error('Method not implemented.');
|
|
73
200
|
}
|
|
201
|
+
async getHeaderInfo() {
|
|
202
|
+
throw new Error('Method not implemented.');
|
|
203
|
+
}
|
|
204
|
+
async getMaterial() {
|
|
205
|
+
throw new Error('Method not implemented.');
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Builds a funds recovery transaction without BitGo
|
|
209
|
+
* @param {MPCRecoveryOptions} params parameters needed to construct and
|
|
210
|
+
* (maybe) sign the transaction
|
|
211
|
+
*
|
|
212
|
+
* @returns {MPCTx} the serialized transaction hex string and index
|
|
213
|
+
* of the address being swept
|
|
214
|
+
*/
|
|
215
|
+
async recover(params) {
|
|
216
|
+
if (!params.bitgoKey) {
|
|
217
|
+
throw new Error('Missing bitgoKey');
|
|
218
|
+
}
|
|
219
|
+
if (!params.recoveryDestination || !this.isValidAddress(params.recoveryDestination)) {
|
|
220
|
+
throw new Error('Invalid recovery destination address');
|
|
221
|
+
}
|
|
222
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
223
|
+
const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
|
|
224
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
225
|
+
const index = params.index || 0;
|
|
226
|
+
const currPath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${index}` : `m/${index}`;
|
|
227
|
+
const accountId = MPC.deriveUnhardened(bitgoKey, currPath).slice(0, 64);
|
|
228
|
+
const senderAddr = this.getAddressFromPublicKey(accountId);
|
|
229
|
+
const { nonce, freeBalance } = await this.getAccountInfo(senderAddr);
|
|
230
|
+
const destAddr = params.recoveryDestination;
|
|
231
|
+
const amount = freeBalance;
|
|
232
|
+
const partialFee = await this.getFee(destAddr, senderAddr, amount);
|
|
233
|
+
const value = new bignumber_js_1.default(freeBalance).minus(new bignumber_js_1.default(partialFee));
|
|
234
|
+
if (value.isLessThanOrEqualTo(0)) {
|
|
235
|
+
throw new Error('Did not find address with funds to recover');
|
|
236
|
+
}
|
|
237
|
+
const { headerNumber, headerHash } = await this.getHeaderInfo();
|
|
238
|
+
const material = await this.getMaterial();
|
|
239
|
+
const validityWindow = { firstValid: headerNumber, maxDuration: this.MAX_VALIDITY_DURATION };
|
|
240
|
+
const txBuilder = this.getBuilder().getTransferBuilder().material(material);
|
|
241
|
+
txBuilder
|
|
242
|
+
.sweep(false)
|
|
243
|
+
.to({ address: params.recoveryDestination })
|
|
244
|
+
.sender({ address: senderAddr })
|
|
245
|
+
.validity(validityWindow)
|
|
246
|
+
.referenceBlock(headerHash)
|
|
247
|
+
.sequenceId({ name: 'Nonce', keyword: 'Nonce', value: nonce })
|
|
248
|
+
.fee({ amount: 0, type: 'tip' });
|
|
249
|
+
const unsignedTransaction = (await txBuilder.build());
|
|
250
|
+
let serializedTx = unsignedTransaction.toBroadcastFormat();
|
|
251
|
+
if (!isUnsignedSweep) {
|
|
252
|
+
if (!params.userKey) {
|
|
253
|
+
throw new Error('missing userKey');
|
|
254
|
+
}
|
|
255
|
+
if (!params.backupKey) {
|
|
256
|
+
throw new Error('missing backupKey');
|
|
257
|
+
}
|
|
258
|
+
if (!params.walletPassphrase) {
|
|
259
|
+
throw new Error('missing wallet passphrase');
|
|
260
|
+
}
|
|
261
|
+
const signingMaterial = await this.getEddsaSigningMaterial(params.userKey, params.walletPassphrase);
|
|
262
|
+
await this.addSubstrateRecoverySignature(txBuilder, signingMaterial, params.backupKey.replace(/\s/g, ''), params.walletPassphrase, unsignedTransaction, currPath, bitgoKey, accountId);
|
|
263
|
+
const signedTransaction = await txBuilder.build();
|
|
264
|
+
serializedTx = signedTransaction.toBroadcastFormat();
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const value = new bignumber_js_1.default(freeBalance);
|
|
268
|
+
const walletCoin = this.getChain();
|
|
269
|
+
const inputs = [
|
|
270
|
+
{
|
|
271
|
+
address: unsignedTransaction.inputs[0].address,
|
|
272
|
+
valueString: value.toString(),
|
|
273
|
+
value: value.toNumber(),
|
|
274
|
+
},
|
|
275
|
+
];
|
|
276
|
+
const outputs = [
|
|
277
|
+
{
|
|
278
|
+
address: unsignedTransaction.outputs[0].address,
|
|
279
|
+
valueString: value.toString(),
|
|
280
|
+
coinName: walletCoin,
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
const spendAmount = value.toString();
|
|
284
|
+
const parsedTx = { inputs: inputs, outputs: outputs, spendAmount: spendAmount, type: '' };
|
|
285
|
+
const feeInfo = { fee: 0, feeString: '0' };
|
|
286
|
+
const transaction = {
|
|
287
|
+
serializedTx: serializedTx,
|
|
288
|
+
scanIndex: index,
|
|
289
|
+
coin: walletCoin,
|
|
290
|
+
signableHex: unsignedTransaction.signablePayload.toString('hex'),
|
|
291
|
+
derivationPath: currPath,
|
|
292
|
+
parsedTx: parsedTx,
|
|
293
|
+
feeInfo: feeInfo,
|
|
294
|
+
coinSpecific: { ...validityWindow, commonKeychain: bitgoKey },
|
|
295
|
+
};
|
|
296
|
+
const unsignedTx = { unsignedTx: transaction, signatureShares: [] };
|
|
297
|
+
const transactions = [unsignedTx];
|
|
298
|
+
const txRequest = {
|
|
299
|
+
transactions: transactions,
|
|
300
|
+
walletCoin: walletCoin,
|
|
301
|
+
};
|
|
302
|
+
const txRequests = { txRequests: [txRequest] };
|
|
303
|
+
return txRequests;
|
|
304
|
+
}
|
|
305
|
+
const transaction = { serializedTx: serializedTx, scanIndex: index };
|
|
306
|
+
return transaction;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Builds native TAO recoveries of receive addresses in batch without BitGo.
|
|
310
|
+
* Funds will be recovered to base address first. You need to initiate another sweep txn after that.
|
|
311
|
+
*
|
|
312
|
+
* @param {MPCConsolidationRecoveryOptions} params - options for consolidation recovery.
|
|
313
|
+
* @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
|
|
314
|
+
* @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
|
|
315
|
+
*/
|
|
316
|
+
async recoverConsolidations(params) {
|
|
317
|
+
const isUnsignedSweep = !params.userKey && !params.backupKey && !params.walletPassphrase;
|
|
318
|
+
const startIdx = params.startingScanIndex || 1;
|
|
319
|
+
const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
|
|
320
|
+
if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
|
|
321
|
+
throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
|
|
322
|
+
}
|
|
323
|
+
const bitgoKey = params.bitgoKey.replace(/\s/g, '');
|
|
324
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
325
|
+
const baseIndex = 0;
|
|
326
|
+
const basePath = params.seed ? (0, sdk_lib_mpc_1.getDerivationPath)(params.seed) + `/${baseIndex}` : `m/${baseIndex}`;
|
|
327
|
+
const accountId = MPC.deriveUnhardened(bitgoKey, basePath).slice(0, 64);
|
|
328
|
+
const baseAddress = this.getAddressFromPublicKey(accountId);
|
|
329
|
+
const consolidationTransactions = [];
|
|
330
|
+
let lastScanIndex = startIdx;
|
|
331
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
332
|
+
const recoverParams = {
|
|
333
|
+
userKey: params.userKey,
|
|
334
|
+
backupKey: params.backupKey,
|
|
335
|
+
bitgoKey: params.bitgoKey,
|
|
336
|
+
walletPassphrase: params.walletPassphrase,
|
|
337
|
+
recoveryDestination: baseAddress,
|
|
338
|
+
seed: params.seed,
|
|
339
|
+
index: i,
|
|
340
|
+
};
|
|
341
|
+
let recoveryTransaction;
|
|
342
|
+
try {
|
|
343
|
+
recoveryTransaction = await this.recover(recoverParams);
|
|
344
|
+
}
|
|
345
|
+
catch (e) {
|
|
346
|
+
if (e.message === 'Did not find address with funds to recover') {
|
|
347
|
+
lastScanIndex = i;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
throw e;
|
|
351
|
+
}
|
|
352
|
+
if (isUnsignedSweep) {
|
|
353
|
+
consolidationTransactions.push(recoveryTransaction.txRequests[0]);
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
consolidationTransactions.push(recoveryTransaction);
|
|
357
|
+
}
|
|
358
|
+
lastScanIndex = i;
|
|
359
|
+
}
|
|
360
|
+
if (consolidationTransactions.length == 0) {
|
|
361
|
+
throw new Error('Did not find an address with funds to recover');
|
|
362
|
+
}
|
|
363
|
+
if (isUnsignedSweep) {
|
|
364
|
+
// lastScanIndex will be used to inform user the last address index scanned for available funds (so they can
|
|
365
|
+
// appropriately adjust the scan range on the next iteration of consolidation recoveries). In the case of unsigned
|
|
366
|
+
// sweep consolidations, this lastScanIndex will be provided in the coinSpecific of the last txn made.
|
|
367
|
+
const lastTransactionCoinSpecific = {
|
|
368
|
+
firstValid: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
369
|
+
.firstValid,
|
|
370
|
+
maxDuration: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
371
|
+
.maxDuration,
|
|
372
|
+
commonKeychain: consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific
|
|
373
|
+
.commonKeychain,
|
|
374
|
+
lastScanIndex: lastScanIndex,
|
|
375
|
+
};
|
|
376
|
+
consolidationTransactions[consolidationTransactions.length - 1].transactions[0].unsignedTx.coinSpecific =
|
|
377
|
+
lastTransactionCoinSpecific;
|
|
378
|
+
const consolidationSweepTransactions = { txRequests: consolidationTransactions };
|
|
379
|
+
return consolidationSweepTransactions;
|
|
380
|
+
}
|
|
381
|
+
return { transactions: consolidationTransactions, lastScanIndex };
|
|
382
|
+
}
|
|
383
|
+
async getEddsaSigningMaterial(userKey, walletPassphrase) {
|
|
384
|
+
return (0, sdk_core_1.getEddsaSigningMaterial)(userKey, walletPassphrase, this.bitgo);
|
|
385
|
+
}
|
|
386
|
+
// Protected so tests can stub via instance overrides — direct module function bindings
|
|
387
|
+
// cannot be intercepted by sinon after import.
|
|
388
|
+
async signSubstrateMpcV2Recovery(params) {
|
|
389
|
+
return (0, sdk_core_1.signEddsaMpcV2RecoveryTx)(params);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Adds an MPCv1 or MPCv2 signature to a Substrate transaction builder.
|
|
393
|
+
*
|
|
394
|
+
* Both branches hand off the raw 64-byte Ed25519 signature untouched.
|
|
395
|
+
* Transaction#constructSignedPayload already prepends the 0x00 type-tag
|
|
396
|
+
* (the Substrate MultiSignature enum discriminant for Ed25519) to whatever
|
|
397
|
+
* signature buffer is passed to addSignature, so wrapping the signature
|
|
398
|
+
* here would produce a double discriminant, corrupting the on-wire sig
|
|
399
|
+
* bytes and causing the chain to reject the extrinsic with `1010: Bad
|
|
400
|
+
* signature`.
|
|
401
|
+
*/
|
|
402
|
+
async addSubstrateRecoverySignature(txBuilder, signingMaterial, backupKey, walletPassphrase, unsignedTransaction, currPath, bitgoKey, accountId) {
|
|
403
|
+
const substrateKeyPair = new lib_1.KeyPair({ pub: accountId });
|
|
404
|
+
if (signingMaterial.version === 'v2') {
|
|
405
|
+
const rawSig = await this.signSubstrateMpcV2Recovery({
|
|
406
|
+
message: unsignedTransaction.signablePayload,
|
|
407
|
+
userKey: signingMaterial.encryptedUserKey,
|
|
408
|
+
backupKey,
|
|
409
|
+
walletPassphrase,
|
|
410
|
+
bitgoKey,
|
|
411
|
+
derivationPath: currPath,
|
|
412
|
+
bitgo: this.bitgo,
|
|
413
|
+
});
|
|
414
|
+
txBuilder.addSignature({ pub: substrateKeyPair.getKeys().pub }, rawSig);
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
const userSigningMaterial = JSON.parse(signingMaterial.userPrv);
|
|
418
|
+
const backupPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(this.bitgo, { encryptedPrv: backupKey }, walletPassphrase);
|
|
419
|
+
if (!backupPrv) {
|
|
420
|
+
throw new Error('Error decrypting backup keychain: invalid password or corrupted key');
|
|
421
|
+
}
|
|
422
|
+
const backupSigningMaterial = JSON.parse(backupPrv);
|
|
423
|
+
const signatureHex = await sdk_core_1.EDDSAMethods.getTSSSignature(userSigningMaterial, backupSigningMaterial, currPath, unsignedTransaction);
|
|
424
|
+
txBuilder.addSignature({ pub: substrateKeyPair.getKeys().pub }, signatureHex);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/** inherited doc */
|
|
428
|
+
async createBroadcastableSweepTransaction(params) {
|
|
429
|
+
const req = params.signatureShares;
|
|
430
|
+
const broadcastableTransactions = [];
|
|
431
|
+
let lastScanIndex = 0;
|
|
432
|
+
for (let i = 0; i < req.length; i++) {
|
|
433
|
+
const MPC = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
|
|
434
|
+
const transaction = req[i].txRequest.transactions[0].unsignedTx;
|
|
435
|
+
if (!req[i].ovc || !req[i].ovc[0].eddsaSignature) {
|
|
436
|
+
throw new Error('Missing signature(s)');
|
|
437
|
+
}
|
|
438
|
+
const signature = req[i].ovc[0].eddsaSignature;
|
|
439
|
+
if (!transaction.signableHex) {
|
|
440
|
+
throw new Error('Missing signable hex');
|
|
441
|
+
}
|
|
442
|
+
const messageBuffer = Buffer.from(transaction.signableHex, 'hex');
|
|
443
|
+
const result = MPC.verify(messageBuffer, signature);
|
|
444
|
+
if (!result) {
|
|
445
|
+
throw new Error('Invalid signature');
|
|
446
|
+
}
|
|
447
|
+
const signatureHex = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
|
|
448
|
+
if (!transaction.coinSpecific ||
|
|
449
|
+
!transaction.coinSpecific?.firstValid ||
|
|
450
|
+
!transaction.coinSpecific?.maxDuration) {
|
|
451
|
+
throw new Error('missing validity window');
|
|
452
|
+
}
|
|
453
|
+
const validityWindow = {
|
|
454
|
+
firstValid: transaction.coinSpecific?.firstValid,
|
|
455
|
+
maxDuration: transaction.coinSpecific?.maxDuration,
|
|
456
|
+
};
|
|
457
|
+
const material = await this.getMaterial();
|
|
458
|
+
if (!transaction.coinSpecific?.commonKeychain) {
|
|
459
|
+
throw new Error('Missing common keychain');
|
|
460
|
+
}
|
|
461
|
+
const commonKeychain = transaction.coinSpecific.commonKeychain;
|
|
462
|
+
if (!transaction.derivationPath) {
|
|
463
|
+
throw new Error('Missing derivation path');
|
|
464
|
+
}
|
|
465
|
+
const derivationPath = transaction.derivationPath;
|
|
466
|
+
const accountId = MPC.deriveUnhardened(commonKeychain, derivationPath).slice(0, 64);
|
|
467
|
+
const senderAddr = this.getAddressFromPublicKey(accountId);
|
|
468
|
+
const txnBuilder = this.getBuilder()
|
|
469
|
+
.material(material)
|
|
470
|
+
.from(transaction.serializedTx)
|
|
471
|
+
.sender({ address: senderAddr })
|
|
472
|
+
.validity(validityWindow);
|
|
473
|
+
const substrateKeyPair = new lib_1.KeyPair({ pub: accountId });
|
|
474
|
+
txnBuilder.addSignature({ pub: substrateKeyPair.getKeys().pub }, signatureHex);
|
|
475
|
+
const signedTransaction = await txnBuilder.build();
|
|
476
|
+
const serializedTx = signedTransaction.toBroadcastFormat();
|
|
477
|
+
broadcastableTransactions.push({
|
|
478
|
+
serializedTx: serializedTx,
|
|
479
|
+
scanIndex: transaction.scanIndex,
|
|
480
|
+
});
|
|
481
|
+
if (i === req.length - 1 && transaction.coinSpecific.lastScanIndex) {
|
|
482
|
+
lastScanIndex = transaction.coinSpecific.lastScanIndex;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return { transactions: broadcastableTransactions, lastScanIndex };
|
|
486
|
+
}
|
|
487
|
+
/** inherited doc */
|
|
488
|
+
auditDecryptedKey({ publicKey, prv, multiSigType }) {
|
|
489
|
+
if (multiSigType !== 'tss') {
|
|
490
|
+
throw new Error('Unsupported multiSigType');
|
|
491
|
+
}
|
|
492
|
+
(0, sdk_lib_mpc_1.auditEddsaPrivateKey)(prv, publicKey ?? '');
|
|
493
|
+
}
|
|
74
494
|
}
|
|
75
495
|
exports.SubstrateCoin = SubstrateCoin;
|
|
76
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RTdWJzdHJhdGVDb2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Fic3RyYWN0U3Vic3RyYXRlQ29pbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFXOEI7QUFHOUIsTUFBYSxhQUFjLFNBQVEsbUJBQVE7SUFFekMsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFYixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxhQUFhLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVU7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixhQUFhO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQsbUJBQW1CO0lBQ25CLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixlQUFlO1FBQ2IsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixlQUFlLENBQUMsSUFBYTtRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixVQUFVLENBQUMsR0FBVztRQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixlQUFlLENBQUMsTUFBNEI7UUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsZ0JBQWdCLENBQUMsTUFBK0I7UUFDOUMsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsaUJBQWlCLENBQUMsTUFBZ0M7UUFDaEQsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsY0FBYyxDQUFDLE9BQWU7UUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsZUFBZSxDQUFDLE1BQThCO1FBQzVDLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUF2RkQsc0NBdUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQmFzZUNvaW4sXG4gIEJpdEdvQmFzZSxcbiAgS2V5UGFpcixcbiAgTVBDQWxnb3JpdGhtLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4sIENvaW5GYW1pbHkgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcblxuZXhwb3J0IGNsYXNzIFN1YnN0cmF0ZUNvaW4gZXh0ZW5kcyBCYXNlQ29pbiB7XG4gIHByb3RlY3RlZCByZWFkb25seSBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG5cbiAgICBpZiAoIXN0YXRpY3NDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgY29uc3RydWN0b3IgcGFyYW1ldGVyIHN0YXRpY3NDb2luJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBTdWJzdHJhdGVDb2luKGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IGZvciB0aGUgY29pbiBzcGVjaWZpYyBzZGtcbiAgICovXG4gIGdldEJ1aWxkZXIoKTogYW55IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEJhc2VGYWN0b3IoKTogc3RyaW5nIHwgbnVtYmVyIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4ubmFtZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIHN1cHBvcnRzVHNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRNUENBbGdvcml0aG0oKTogTVBDQWxnb3JpdGhtIHtcbiAgICByZXR1cm4gJ2VkZHNhJztcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2VuZXJhdGVLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZCcpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZCcpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cbn1cbiJdfQ==
|
|
496
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RTdWJzdHJhdGVDb2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Fic3RyYWN0U3Vic3RyYXRlQ29pbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxtREErQjhCO0FBRTlCLCtCQUFpRTtBQUVqRSwrQ0FBMkQ7QUFFM0Qsd0RBQWdDO0FBQ2hDLHlEQUFrRjtBQUNsRixnRUFBcUM7QUFHeEIsUUFBQSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFFdEMsTUFBYSxhQUFjLFNBQVEsbUJBQVE7SUFLekMsWUFBc0IsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFKTiwwQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDN0IsdUJBQWtCLEdBQUcsRUFBRSxDQUFDO1FBSy9CLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVU7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxtQkFBbUI7SUFDbkIsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELG1CQUFtQjtJQUNuQixTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQsbUJBQW1CO0lBQ25CLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxZ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S2V5UGFyYW1zLFxuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBFRERTQU1ldGhvZHMsXG4gIEVERFNBTWV0aG9kVHlwZXMsXG4gIEtleVBhaXIsXG4gIE1QQ0FsZ29yaXRobSxcbiAgTVBDQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDUmVjb3ZlcnlPcHRpb25zLFxuICBNUENTd2VlcFJlY292ZXJ5T3B0aW9ucyxcbiAgTVBDU3dlZXBUeHMsXG4gIE1QQ1R4LFxuICBNUENUeHMsXG4gIE1QQ1Vuc2lnbmVkVHgsXG4gIE11bHRpc2lnVHlwZSxcbiAgbXVsdGlzaWdUeXBlcyxcbiAgUGFyc2VkVHJhbnNhY3Rpb24sXG4gIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zLFxuICBSZWNvdmVyeVR4UmVxdWVzdCxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFRzc1ZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBUcmFuc2FjdGlvblByZWJ1aWxkLFxuICBUeEludGVudE1pc21hdGNoUmVjaXBpZW50RXJyb3IsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxuICBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5LFxuICBnZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCBhcyBzaGFyZWRHZXRFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbiAgc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4LFxuICBFZGRzYVNpZ25pbmdNYXRlcmlhbCxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQ29pbkZhbWlseSwgQmFzZUNvaW4gYXMgU3RhdGljc0Jhc2VDb2luIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBLZXlQYWlyIGFzIFN1YnN0cmF0ZUtleVBhaXIsIFRyYW5zYWN0aW9uIH0gZnJvbSAnLi9saWInO1xuaW1wb3J0IHsgTmF0aXZlVHJhbnNmZXJCdWlsZGVyIH0gZnJvbSAnLi9saWIvbmF0aXZlVHJhbnNmZXJCdWlsZGVyJztcbmltcG9ydCB7IERFRkFVTFRfU1VCU1RSQVRFX1BSRUZJWCB9IGZyb20gJy4vbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBTaWduVHJhbnNhY3Rpb25PcHRpb25zLCBWZXJpZmllZFRyYW5zYWN0aW9uUGFyYW1ldGVycywgTWF0ZXJpYWwgfSBmcm9tICcuL2xpYi9pZmFjZSc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0IHsgYXVkaXRFZGRzYVByaXZhdGVLZXksIGdldERlcml2YXRpb25QYXRoIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0IHsgQXBpUHJvbWlzZSB9IGZyb20gJ0Bwb2xrYWRvdC9hcGknO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TQ0FOX0ZBQ1RPUiA9IDIwO1xuXG5leHBvcnQgY2xhc3MgU3Vic3RyYXRlQ29pbiBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGF0aWNzQ29pbjogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPjtcbiAgcmVhZG9ubHkgTUFYX1ZBTElESVRZX0RVUkFUSU9OID0gMjQwMDtcbiAgcmVhZG9ubHkgU1dFRVBfVFhOX0RVUkFUSU9OID0gNjQ7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSBmb3IgdGhlIGNvaW4gc3BlY2lmaWMgc2RrXG4gICAqL1xuICBnZXRCdWlsZGVyKCk6IGFueSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBnZXRCYXNlRmFjdG9yKCk6IHN0cmluZyB8IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGF0aWNzQ29pbi5kZWNpbWFsUGxhY2VzKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4ubmFtZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIHN1cHBvcnRzVHNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgZ2V0RGVmYXVsdE11bHRpc2lnVHlwZSgpOiBNdWx0aXNpZ1R5cGUge1xuICAgIHJldHVybiBtdWx0aXNpZ1R5cGVzLnRzcztcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgZ2V0TVBDQWxnb3JpdGhtKCk6IE1QQ0FsZ29yaXRobSB7XG4gICAgcmV0dXJuICdlZGRzYSc7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkPzogQnVmZmVyKTogS2V5UGFpciB7XG4gICAgY29uc3Qga2V5UGFpciA9IHNlZWQgPyBuZXcgU3Vic3RyYXRlS2V5UGFpcih7IHNlZWQgfSkgOiBuZXcgU3Vic3RyYXRlS2V5UGFpcigpO1xuICAgIGNvbnN0IGtleXMgPSBrZXlQYWlyLmdldEtleXMoKTtcbiAgICBpZiAoIWtleXMucHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcHJ2IGluIGtleSBnZW5lcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcHViOiBrZXlzLnB1YixcbiAgICAgIHBydjoga2V5cy5wcnYsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqKi9cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFRzc1ZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IHZlcmlmeUVkZHNhVHNzV2FsbGV0QWRkcmVzcyhcbiAgICAgIHBhcmFtcyxcbiAgICAgIChhZGRyKSA9PiB0aGlzLmlzVmFsaWRBZGRyZXNzKGFkZHIpLFxuICAgICAgKHB1YktleSkgPT4gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShwdWJLZXkpXG4gICAgKTtcblxuICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IoYGFkZHJlc3MgdmFsaWRhdGlvbiBmYWlsdXJlOiAke3BhcmFtcy5hZGRyZXNzfSBpcyBub3QgYSB3YWxsZXQgYWRkcmVzc2ApO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICoqL1xuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQgfSA9IHBhcmFtcztcblxuICAgIGlmICghdHhQYXJhbXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFBhcmFtcycpO1xuICAgIH1cbiAgICBpZiAoIXR4UHJlYnVpbGQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFByZWJ1aWxkJyk7XG4gICAgfVxuICAgIGlmICghdHhQcmVidWlsZC50eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4SGV4IGluIHR4UHJlYnVpbGQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBmYWN0b3J5ID0gdGhpcy5nZXRCdWlsZGVyKCk7XG4gICAgLy8gVXNlIHRoZSBsaXZlIGNoYWluIG1hdGVyaWFsIGVtYmVkZGVkIGluIHRoZSBwcmVidWlsZCAoaWYgcHJlc2VudCkgc28gdGhlIGZhY3RvcnkgY2FuIGRlY29kZVxuICAgIC8vIHRyYW5zYWN0aW9ucyBidWlsdCBhZ2FpbnN0IGEgY2hhaW4gc3BlYyB2ZXJzaW9uIG5ld2VyIHRoYW4gdGhlIFNESydzIGhhcmRjb2RlZCBtZXRhZGF0YS5cbiAgICAvLyBXaXRob3V0IHRoaXMsIHRoZSBmYWN0b3J5IGZhbGxzIGJhY2sgdG8gaXRzIGhhcmRjb2RlZCBtYXRlcmlhbCBhbmQgbWlzaWRlbnRpZmllcyB0aGUgY2FsbFxuICAgIC8vIHBhbGxldCAoZS5nLiByZWFkcyBhIEJhbGFuY2VzIHRyYW5zZmVyIGFzIHRyZWFzdXJ5LmRpc2J1cnNlbWVudCBhZnRlciBhIGNoYWluIHVwZ3JhZGUpLlxuICAgIGNvbnN0IHByZWJ1aWxkTWF0ZXJpYWwgPSAodHhQcmVidWlsZCBhcyBUcmFuc2FjdGlvblByZWJ1aWxkICYgeyBjb2luU3BlY2lmaWM/OiB7IG1hdGVyaWFsPzogTWF0ZXJpYWwgfSB9KVxuICAgICAgLmNvaW5TcGVjaWZpYz8ubWF0ZXJpYWw7XG4gICAgaWYgKHByZWJ1aWxkTWF0ZXJpYWwgJiYgdHlwZW9mIGZhY3RvcnkubWF0ZXJpYWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGZhY3RvcnkubWF0ZXJpYWwocHJlYnVpbGRNYXRlcmlhbCk7XG4gICAgfVxuICAgIC8vIFRva2VuIGVuYWJsZW1lbnQgKHByZUFwcHJvdmVBc3NldCkgdHJhbnNhY3Rpb25zIGhhdmUgbm8gZGVzdGluYXRpb24gYWRkcmVzcyDigJQgdGhleSBhcmVcbiAgICAvLyBzZWxmLXRyYW5zYWN0aW9ucyBzaWduZWQgYnkgdGhlIHdhbGxldC4gU2tpcCB0cmFuc2ZlciByZWNpcGllbnQgdmFsaWRhdGlvbiwgY29uc2lzdGVudFxuICAgIC8vIHdpdGggaG93IFhSUCBhbmQgQWxnbyBoYW5kbGUgZW5hYmxldG9rZW4gaW4gdGhlaXIgdmVyaWZ5VHJhbnNhY3Rpb24gaW1wbGVtZW50YXRpb25zLlxuICAgIGlmICh0eFBhcmFtcy50eXBlID09PSAnZW5hYmxldG9rZW4nKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhQcmVidWlsZC50eEhleCkgYXMgdW5rbm93biBhcyBOYXRpdmVUcmFuc2ZlckJ1aWxkZXI7XG4gICAgY29uc3QgdHhUbzogc3RyaW5nID0gdHhCdWlsZGVyWydfdG8nXTtcbiAgICBjb25zdCB0eEFtb3VudDogc3RyaW5nID0gdHhCdWlsZGVyWydfYW1vdW50J107XG4gICAgY29uc3QgaXNTd2VlcDogYm9vbGVhbiA9IHR4QnVpbGRlclsnX3N3ZWVwRnJlZUJhbGFuY2UnXSA9PT0gdHJ1ZTtcblxuICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVjaXBpZW50cyBpbiB0eFBhcmFtcycpO1xuICAgICAgfVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHhQYXJhbXMucmVjaXBpZW50cykgJiYgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgJHt0aGlzLmdldENoYWluKCl9IGRvZXNuJ3Qgc3VwcG9ydCBzZW5kaW5nIHRvIG1vcmUgdGhhbiAxIGRlc3RpbmF0aW9uIGFkZHJlc3Mgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUcnkgYWdhaW4sIHVzaW5nIG9ubHkgYSBzaW5nbGUgcmVjaXBpZW50LmBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzcyAhPT0gdHhUbykge1xuICAgICAgICB0aHJvdyBuZXcgVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yKFxuICAgICAgICAgIGBSZWNpcGllbnQgYWRkcmVzcyAke3R4UGFyYW1zLnJlY2lwaWVudHNbMF0uYWRkcmVzc30gZG9lcyBub3QgbWF0Y2ggdHJhbnNhY3Rpb24gZGVzdGluYXRpb24gYWRkcmVzcyAke3R4VG99YCxcbiAgICAgICAgICBwYXJhbXMucmVxSWQsXG4gICAgICAgICAgW3R4UGFyYW1zXSxcbiAgICAgICAgICB0eFByZWJ1aWxkLnR4SGV4LFxuICAgICAgICAgIFt7IGFkZHJlc3M6IHR4VG8sIGFtb3VudDogdHhBbW91bnQgfV1cbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1N3ZWVwICYmIHR4UGFyYW1zLnJlY2lwaWVudHNbMF0uYW1vdW50ICE9PSB0eEFtb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgVHhJbnRlbnRNaXNtYXRjaFJlY2lwaWVudEVycm9yKFxuICAgICAgICAgIGBSZWNpcGllbnQgYW1vdW50ICR7dHhQYXJhbXMucmVjaXBpZW50c1swXS5hbW91bnR9IGRvZXMgbm90IG1hdGNoIHRyYW5zYWN0aW9uIGFtb3VudCAke3R4QW1vdW50fWAsXG4gICAgICAgICAgcGFyYW1zLnJlcUlkLFxuICAgICAgICAgIFt0eFBhcmFtc10sXG4gICAgICAgICAgdHhQcmVidWlsZC50eEhleCxcbiAgICAgICAgICBbeyBhZGRyZXNzOiB0eFRvLCBhbW91bnQ6IHR4QW1vdW50IH1dXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIHZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBWZXJpZmllZFRyYW5zYWN0aW9uUGFyYW1ldGVycyB7XG4gICAgY29uc3QgcHJ2ID0gcGFyYW1zPy5wcnY7XG4gICAgY29uc3QgdHhIZXggPSBwYXJhbXM/LnR4UHJlYnVpbGQ/LnR4SGV4O1xuXG4gICAgaWYgKHR5cGVvZiB0eEhleCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHhIZXggbXVzdCBiZSBzdHJpbmcsIGdvdCB0eXBlICR7dHlwZW9mIHR4SGV4fWApO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJ2ICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcnYgbXVzdCBiZSBzdHJpbmcsIGdvdCB0eXBlICR7dHlwZW9mIHBydn1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB0eEhleCwgcHJ2IH07XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKiovXG4gIGFzeW5jIHNpZ25UcmFuc2FjdGlvbihwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgeyB0eEhleCwgcHJ2IH0gPSB0aGlzLnZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhIZXgpO1xuICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgU3Vic3RyYXRlS2V5UGFpcih7IHBydjogcHJ2IH0pO1xuICAgIGNvbnN0IHsgcmVmZXJlbmNlQmxvY2ssIGJsb2NrTnVtYmVyLCB0cmFuc2FjdGlvblZlcnNpb24sIHNlbmRlciB9ID0gcGFyYW1zLnR4UHJlYnVpbGQudHJhbnNhY3Rpb247XG5cbiAgICB0eEJ1aWxkZXJcbiAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IGJsb2NrTnVtYmVyLCBtYXhEdXJhdGlvbjogdGhpcy5nZXRNYXhWYWxpZGl0eUR1cmF0aW9uQmxvY2tzKCkgfSlcbiAgICAgIC5yZWZlcmVuY2VCbG9jayhyZWZlcmVuY2VCbG9jaylcbiAgICAgIC52ZXJzaW9uKHRyYW5zYWN0aW9uVmVyc2lvbilcbiAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgIC5zaWduKHsga2V5OiBrZXlQYWlyLmdldEtleXMoKS5wcnYgfSk7XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBpZiAoIXRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgY29uc3Qgc2lnbmVkVHhIZXggPSB0cmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgIHJldHVybiB7IHR4SGV4OiBzaWduZWRUeEhleCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgYWRkcmVzcyBmb3JtYXQgZm9yIHRoZSBzdWJzdHJhdGUgY29pbi5cbiAgICpcbiAgICogQHJldHVybnMge251bWJlcn0gVGhlIGFkZHJlc3MgZm9ybWF0IGFzIGEgbnVtYmVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldEFkZHJlc3NGb3JtYXQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gREVGQVVMVF9TVUJTVFJBVEVfUFJFRklYO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgbWF4aW11bSB2YWxpZGl0eSBkdXJhdGlvbiBpbiBibG9ja3MuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIGludGVuZGVkIHRvIGJlIG92ZXJyaWRkZW4gYnkgc3ViY2xhc3NlcyB0byBwcm92aWRlIHRoZSBzcGVjaWZpY1xuICAgKiBtYXhpbXVtIHZhbGlkaXR5IGR1cmF0aW9uIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgU3Vic3RyYXRlLWJhc2VkIGNvaW5zLlxuICAgKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbWF4aW11bSB2YWxpZGl0eSBkdXJhdGlvbiBpbiBibG9ja3MuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgbWV0aG9kIGlzIG5vdCBpbXBsZW1lbnRlZCBieSB0aGUgc3ViY2xhc3MuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0TWF4VmFsaWRpdHlEdXJhdGlvbkJsb2NrcygpOiBudW1iZXIge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRBZGRyZXNzRnJvbVB1YmxpY0tleShQdWJrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIG5ldyBTdWJzdHJhdGVLZXlQYWlyKHsgcHViOiBQdWJrZXkgfSkuZ2V0QWRkcmVzcyh0aGlzLmdldEFkZHJlc3NGb3JtYXQoKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0SW5pdGlhbGl6ZWROb2RlQVBJKCk6IFByb21pc2U8QXBpUHJvbWlzZT4ge1xuICAgIHRocm93IG5ldyBFcnJvcignTWV0aG9kIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBnZXRBY2NvdW50SW5mbyh3YWxsZXRBZGRyOiBzdHJpbmcpOiBQcm9taXNlPHsgbm9uY2U6IG51bWJlcjsgZnJlZUJhbGFuY2U6IG51bWJlciB9PiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldEZlZShkZXN0QWRkcjogc3RyaW5nLCBzcmNBZGRyOiBzdHJpbmcsIGFtb3VudDogbnVtYmVyKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0SGVhZGVySW5mbygpOiBQcm9taXNlPHsgaGVhZGVyTnVtYmVyOiBudW1iZXI7IGhlYWRlckhhc2g6IHN0cmluZyB9PiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGdldE1hdGVyaWFsKCk6IFByb21pc2U8TWF0ZXJpYWw+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgZnVuZHMgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRHb1xuICAgKiBAcGFyYW0ge01QQ1JlY292ZXJ5T3B0aW9uc30gcGFyYW1zIHBhcmFtZXRlcnMgbmVlZGVkIHRvIGNvbnN0cnVjdCBhbmRcbiAgICogKG1heWJlKSBzaWduIHRoZSB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB7TVBDVHh9IHRoZSBzZXJpYWxpemVkIHRyYW5zYWN0aW9uIGhleCBzdHJpbmcgYW5kIGluZGV4XG4gICAqIG9mIHRoZSBhZGRyZXNzIGJlaW5nIHN3ZXB0XG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogTVBDUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxNUENUeCB8IE1QQ1N3ZWVwVHhzPiB7XG4gICAgaWYgKCFwYXJhbXMuYml0Z29LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBiaXRnb0tleScpO1xuICAgIH1cblxuICAgIGlmICghcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gfHwgIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcmVjb3ZlcnkgZGVzdGluYXRpb24gYWRkcmVzcycpO1xuICAgIH1cblxuICAgIGNvbnN0IGJpdGdvS2V5ID0gcGFyYW1zLmJpdGdvS2V5LnJlcGxhY2UoL1xccy9nLCAnJyk7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gIXBhcmFtcy51c2VyS2V5ICYmICFwYXJhbXMuYmFja3VwS2V5ICYmICFwYXJhbXMud2FsbGV0UGFzc3BocmFzZTtcblxuICAgIGNvbnN0IE1QQyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG5cbiAgICBjb25zdCBpbmRleCA9IHBhcmFtcy5pbmRleCB8fCAwO1xuICAgIGNvbnN0IGN1cnJQYXRoID0gcGFyYW1zLnNlZWQgPyBnZXREZXJpdmF0aW9uUGF0aChwYXJhbXMuc2VlZCkgKyBgLyR7aW5kZXh9YCA6IGBtLyR7aW5kZXh9YDtcbiAgICBjb25zdCBhY2NvdW50SWQgPSBNUEMuZGVyaXZlVW5oYXJkZW5lZChiaXRnb0tleSwgY3VyclBhdGgpLnNsaWNlKDAsIDY0KTtcbiAgICBjb25zdCBzZW5kZXJBZGRyID0gdGhpcy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleShhY2NvdW50SWQpO1xuXG4gICAgY29uc3QgeyBub25jZSwgZnJlZUJhbGFuY2UgfSA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEluZm8oc2VuZGVyQWRkcik7XG4gICAgY29uc3QgZGVzdEFkZHIgPSBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbjtcbiAgICBjb25zdCBhbW91bnQgPSBmcmVlQmFsYW5jZTtcbiAgICBjb25zdCBwYXJ0aWFsRmVlID0gYXdhaXQgdGhpcy5nZXRGZWUoZGVzdEFkZHIsIHNlbmRlckFkZHIsIGFtb3VudCk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBCaWdOdW1iZXIoZnJlZUJhbGFuY2UpLm1pbnVzKG5ldyBCaWdOdW1iZXIocGFydGlhbEZlZSkpO1xuICAgIGlmICh2YWx1ZS5pc0xlc3NUaGFuT3JFcXVhbFRvKDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpZCBub3QgZmluZCBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgaGVhZGVyTnVtYmVyLCBoZWFkZXJIYXNoIH0gPSBhd2FpdCB0aGlzLmdldEhlYWRlckluZm8oKTtcbiAgICBjb25zdCBtYXRlcmlhbCA9IGF3YWl0IHRoaXMuZ2V0TWF0ZXJpYWwoKTtcbiAgICBjb25zdCB2YWxpZGl0eVdpbmRvdyA9IHsgZmlyc3RWYWxpZDogaGVhZGVyTnVtYmVyLCBtYXhEdXJhdGlvbjogdGhpcy5NQVhfVkFMSURJVFlfRFVSQVRJT04gfTtcblxuICAgIGNvbnN0IHR4QnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpLmdldFRyYW5zZmVyQnVpbGRlcigpLm1hdGVyaWFsKG1hdGVyaWFsKTtcbiAgICB0eEJ1aWxkZXJcbiAgICAgIC5zd2VlcChmYWxzZSlcbiAgICAgIC50byh7IGFkZHJlc3M6IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uIH0pXG4gICAgICAuc2VuZGVyKHsgYWRkcmVzczogc2VuZGVyQWRkciB9KVxuICAgICAgLnZhbGlkaXR5KHZhbGlkaXR5V2luZG93KVxuICAgICAgLnJlZmVyZW5jZUJsb2NrKGhlYWRlckhhc2gpXG4gICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdOb25jZScsIHZhbHVlOiBub25jZSB9KVxuICAgICAgLmZlZSh7IGFtb3VudDogMCwgdHlwZTogJ3RpcCcgfSk7XG5cbiAgICBjb25zdCB1bnNpZ25lZFRyYW5zYWN0aW9uID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcblxuICAgIGxldCBzZXJpYWxpemVkVHggPSB1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgaWYgKCFpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIGlmICghcGFyYW1zLnVzZXJLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICAgIH1cbiAgICAgIGlmICghcGFyYW1zLmJhY2t1cEtleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYmFja3VwS2V5Jyk7XG4gICAgICB9XG4gICAgICBpZiAoIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaWduaW5nTWF0ZXJpYWwgPSBhd2FpdCB0aGlzLmdldEVkZHNhU2lnbmluZ01hdGVyaWFsKHBhcmFtcy51c2VyS2V5ISwgcGFyYW1zLndhbGxldFBhc3NwaHJhc2UhKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRkU3Vic3RyYXRlUmVjb3ZlcnlTaWduYXR1cmUoXG4gICAgICAgIHR4QnVpbGRlcixcbiAgICAgICAgc2lnbmluZ01hdGVyaWFsLFxuICAgICAgICBwYXJhbXMuYmFja3VwS2V5IS5yZXBsYWNlKC9cXHMvZywgJycpLFxuICAgICAgICBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSEsXG4gICAgICAgIHVuc2lnbmVkVHJhbnNhY3Rpb24sXG4gICAgICAgIGN1cnJQYXRoLFxuICAgICAgICBiaXRnb0tleSxcbiAgICAgICAgYWNjb3VudElkXG4gICAgICApO1xuICAgICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gbmV3IEJpZ051bWJlcihmcmVlQmFsYW5jZSk7XG4gICAgICBjb25zdCB3YWxsZXRDb2luID0gdGhpcy5nZXRDaGFpbigpO1xuICAgICAgY29uc3QgaW5wdXRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdW5zaWduZWRUcmFuc2FjdGlvbi5pbnB1dHNbMF0uYWRkcmVzcyxcbiAgICAgICAgICB2YWx1ZVN0cmluZzogdmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWUudG9OdW1iZXIoKSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdW5zaWduZWRUcmFuc2FjdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3MsXG4gICAgICAgICAgdmFsdWVTdHJpbmc6IHZhbHVlLnRvU3RyaW5nKCksXG4gICAgICAgICAgY29pbk5hbWU6IHdhbGxldENvaW4sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3Qgc3BlbmRBbW91bnQgPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgY29uc3QgcGFyc2VkVHggPSB7IGlucHV0czogaW5wdXRzLCBvdXRwdXRzOiBvdXRwdXRzLCBzcGVuZEFtb3VudDogc3BlbmRBbW91bnQsIHR5cGU6ICcnIH07XG4gICAgICBjb25zdCBmZWVJbmZvID0geyBmZWU6IDAsIGZlZVN0cmluZzogJzAnIH07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbjogTVBDVHggPSB7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IGluZGV4LFxuICAgICAgICBjb2luOiB3YWxsZXRDb2luLFxuICAgICAgICBzaWduYWJsZUhleDogdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBkZXJpdmF0aW9uUGF0aDogY3VyclBhdGgsXG4gICAgICAgIHBhcnNlZFR4OiBwYXJzZWRUeCxcbiAgICAgICAgZmVlSW5mbzogZmVlSW5mbyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7IC4uLnZhbGlkaXR5V2luZG93LCBjb21tb25LZXljaGFpbjogYml0Z29LZXkgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkVHg6IE1QQ1Vuc2lnbmVkVHggPSB7IHVuc2lnbmVkVHg6IHRyYW5zYWN0aW9uLCBzaWduYXR1cmVTaGFyZXM6IFtdIH07XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbnM6IE1QQ1Vuc2lnbmVkVHhbXSA9IFt1bnNpZ25lZFR4XTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdDogUmVjb3ZlcnlUeFJlcXVlc3QgPSB7XG4gICAgICAgIHRyYW5zYWN0aW9uczogdHJhbnNhY3Rpb25zLFxuICAgICAgICB3YWxsZXRDb2luOiB3YWxsZXRDb2luLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UmVxdWVzdHM6IE1QQ1N3ZWVwVHhzID0geyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0XSB9O1xuICAgICAgcmV0dXJuIHR4UmVxdWVzdHM7XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb246IE1QQ1R4ID0geyBzZXJpYWxpemVkVHg6IHNlcmlhbGl6ZWRUeCwgc2NhbkluZGV4OiBpbmRleCB9O1xuICAgIHJldHVybiB0cmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgbmF0aXZlIFRBTyByZWNvdmVyaWVzIG9mIHJlY2VpdmUgYWRkcmVzc2VzIGluIGJhdGNoIHdpdGhvdXQgQml0R28uXG4gICAqIEZ1bmRzIHdpbGwgYmUgcmVjb3ZlcmVkIHRvIGJhc2UgYWRkcmVzcyBmaXJzdC4gWW91IG5lZWQgdG8gaW5pdGlhdGUgYW5vdGhlciBzd2VlcCB0eG4gYWZ0ZXIgdGhhdC5cbiAgICpcbiAgICogQHBhcmFtIHtNUENDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgLSBvcHRpb25zIGZvciBjb25zb2xpZGF0aW9uIHJlY292ZXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5zdGFydGluZ1NjYW5JbmRleF0gLSByZWNlaXZlIGFkZHJlc3MgaW5kZXggdG8gc3RhcnQgc2Nhbm5pbmcgZnJvbS4gZGVmYXVsdCB0byAxIChpbmNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5lbmRpbmdTY2FuSW5kZXhdIC0gcmVjZWl2ZSBhZGRyZXNzIGluZGV4IHRvIGVuZCBzY2FubmluZyBhdC4gZGVmYXVsdCB0byBzdGFydGluZ1NjYW5JbmRleCArIDIwIChleGNsdXNpdmUpLlxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlckNvbnNvbGlkYXRpb25zKHBhcmFtczogTVBDQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8TVBDVHhzIHwgTVBDU3dlZXBUeHM+IHtcbiAgICBjb25zdCBpc1Vuc2lnbmVkU3dlZXAgPSAhcGFyYW1zLnVzZXJLZXkgJiYgIXBhcmFtcy5iYWNrdXBLZXkgJiYgIXBhcmFtcy53YWxsZXRQYXNzcGhyYXNlO1xuICAgIGNvbnN0IHN0YXJ0SWR4ID0gcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4IHx8IDE7XG4gICAgY29uc3QgZW5kSWR4ID0gcGFyYW1zLmVuZGluZ1NjYW5JbmRleCB8fCBzdGFydElkeCArIERFRkFVTFRfU0NBTl9GQUNUT1I7XG5cbiAgICBpZiAoc3RhcnRJZHggPCAxIHx8IGVuZElkeCA8PSBzdGFydElkeCB8fCBlbmRJZHggLSBzdGFydElkeCA+IDEwICogREVGQVVMVF9TQ0FOX0ZBQ1RPUikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBzdGFydGluZyBvciBlbmRpbmcgaW5kZXggdG8gc2NhbiBmb3IgYWRkcmVzc2VzLiBzdGFydGluZ1NjYW5JbmRleDogJHtzdGFydElkeH0sIGVuZGluZ1NjYW5JbmRleDogJHtlbmRJZHh9LmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYml0Z29LZXkgPSBwYXJhbXMuYml0Z29LZXkucmVwbGFjZSgvXFxzL2csICcnKTtcbiAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgIGNvbnN0IGJhc2VJbmRleCA9IDA7XG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXJhbXMuc2VlZCA/IGdldERlcml2YXRpb25QYXRoKHBhcmFtcy5zZWVkKSArIGAvJHtiYXNlSW5kZXh9YCA6IGBtLyR7YmFzZUluZGV4fWA7XG4gICAgY29uc3QgYWNjb3VudElkID0gTVBDLmRlcml2ZVVuaGFyZGVuZWQoYml0Z29LZXksIGJhc2VQYXRoKS5zbGljZSgwLCA2NCk7XG4gICAgY29uc3QgYmFzZUFkZHJlc3MgPSB0aGlzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KGFjY291bnRJZCk7XG5cbiAgICBjb25zdCBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zOiBhbnlbXSA9IFtdO1xuICAgIGxldCBsYXN0U2NhbkluZGV4ID0gc3RhcnRJZHg7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0SWR4OyBpIDwgZW5kSWR4OyBpKyspIHtcbiAgICAgIGNvbnN0IHJlY292ZXJQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiBwYXJhbXMuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgc2VlZDogcGFyYW1zLnNlZWQsXG4gICAgICAgIGluZGV4OiBpLFxuICAgICAgfTtcblxuICAgICAgbGV0IHJlY292ZXJ5VHJhbnNhY3Rpb247XG4gICAgICB0cnkge1xuICAgICAgICByZWNvdmVyeVRyYW5zYWN0aW9uID0gYXdhaXQgdGhpcy5yZWNvdmVyKHJlY292ZXJQYXJhbXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoZS5tZXNzYWdlID09PSAnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJykge1xuICAgICAgICAgIGxhc3RTY2FuSW5kZXggPSBpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9ucy5wdXNoKChyZWNvdmVyeVRyYW5zYWN0aW9uIGFzIE1QQ1N3ZWVwVHhzKS50eFJlcXVlc3RzWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMucHVzaChyZWNvdmVyeVRyYW5zYWN0aW9uKTtcbiAgICAgIH1cbiAgICAgIGxhc3RTY2FuSW5kZXggPSBpO1xuICAgIH1cblxuICAgIGlmIChjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCA9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpZCBub3QgZmluZCBhbiBhZGRyZXNzIHdpdGggZnVuZHMgdG8gcmVjb3ZlcicpO1xuICAgIH1cblxuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIC8vIGxhc3RTY2FuSW5kZXggd2lsbCBiZSB1c2VkIHRvIGluZm9ybSB1c2VyIHRoZSBsYXN0IGFkZHJlc3MgaW5kZXggc2Nhbm5lZCBmb3IgYXZhaWxhYmxlIGZ1bmRzIChzbyB0aGV5IGNhblxuICAgICAgLy8gYXBwcm9wcmlhdGVseSBhZGp1c3QgdGhlIHNjYW4gcmFuZ2Ugb24gdGhlIG5leHQgaXRlcmF0aW9uIG9mIGNvbnNvbGlkYXRpb24gcmVjb3ZlcmllcykuIEluIHRoZSBjYXNlIG9mIHVuc2lnbmVkXG4gICAgICAvLyBzd2VlcCBjb25zb2xpZGF0aW9ucywgdGhpcyBsYXN0U2NhbkluZGV4IHdpbGwgYmUgcHJvdmlkZWQgaW4gdGhlIGNvaW5TcGVjaWZpYyBvZiB0aGUgbGFzdCB0eG4gbWFkZS5cbiAgICAgIGNvbnN0IGxhc3RUcmFuc2FjdGlvbkNvaW5TcGVjaWZpYyA9IHtcbiAgICAgICAgZmlyc3RWYWxpZDpcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zW2NvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoIC0gMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljXG4gICAgICAgICAgICAuZmlyc3RWYWxpZCxcbiAgICAgICAgbWF4RHVyYXRpb246XG4gICAgICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCAtIDFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpY1xuICAgICAgICAgICAgLm1heER1cmF0aW9uLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zW2NvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMubGVuZ3RoIC0gMV0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguY29pblNwZWNpZmljXG4gICAgICAgICAgICAuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGxhc3RTY2FuSW5kZXg6IGxhc3RTY2FuSW5kZXgsXG4gICAgICB9O1xuICAgICAgY29uc29saWRhdGlvblRyYW5zYWN0aW9uc1tjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLmxlbmd0aCAtIDFdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYyA9XG4gICAgICAgIGxhc3RUcmFuc2FjdGlvbkNvaW5TcGVjaWZpYztcbiAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25Td2VlcFRyYW5zYWN0aW9uczogTVBDU3dlZXBUeHMgPSB7IHR4UmVxdWVzdHM6IGNvbnNvbGlkYXRpb25UcmFuc2FjdGlvbnMgfTtcbiAgICAgIHJldHVybiBjb25zb2xpZGF0aW9uU3dlZXBUcmFuc2FjdGlvbnM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHJhbnNhY3Rpb25zOiBjb25zb2xpZGF0aW9uVHJhbnNhY3Rpb25zLCBsYXN0U2NhbkluZGV4IH07XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0RWRkc2FTaWduaW5nTWF0ZXJpYWwodXNlcktleTogc3RyaW5nLCB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmcpOiBQcm9taXNlPEVkZHNhU2lnbmluZ01hdGVyaWFsPiB7XG4gICAgcmV0dXJuIHNoYXJlZEdldEVkZHNhU2lnbmluZ01hdGVyaWFsKHVzZXJLZXksIHdhbGxldFBhc3NwaHJhc2UsIHRoaXMuYml0Z28pO1xuICB9XG5cbiAgLy8gUHJvdGVjdGVkIHNvIHRlc3RzIGNhbiBzdHViIHZpYSBpbnN0YW5jZSBvdmVycmlkZXMg4oCUIGRpcmVjdCBtb2R1bGUgZnVuY3Rpb24gYmluZGluZ3NcbiAgLy8gY2Fubm90IGJlIGludGVyY2VwdGVkIGJ5IHNpbm9uIGFmdGVyIGltcG9ydC5cbiAgcHJvdGVjdGVkIGFzeW5jIHNpZ25TdWJzdHJhdGVNcGNWMlJlY292ZXJ5KHBhcmFtczogUGFyYW1ldGVyczx0eXBlb2Ygc2lnbkVkZHNhTXBjVjJSZWNvdmVyeVR4PlswXSk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgcmV0dXJuIHNpZ25FZGRzYU1wY1YyUmVjb3ZlcnlUeChwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gTVBDdjEgb3IgTVBDdjIgc2lnbmF0dXJlIHRvIGEgU3Vic3RyYXRlIHRyYW5zYWN0aW9uIGJ1aWxkZXIuXG4gICAqXG4gICAqIEJvdGggYnJhbmNoZXMgaGFuZCBvZmYgdGhlIHJhdyA2NC1ieXRlIEVkMjU1MTkgc2lnbmF0dXJlIHVudG91Y2hlZC5cbiAgICogVHJhbnNhY3Rpb24jY29uc3RydWN0U2lnbmVkUGF5bG9hZCBhbHJlYWR5IHByZXBlbmRzIHRoZSAweDAwIHR5cGUtdGFnXG4gICAqICh0aGUgU3Vic3RyYXRlIE11bHRpU2lnbmF0dXJlIGVudW0gZGlzY3JpbWluYW50IGZvciBFZDI1NTE5KSB0byB3aGF0ZXZlclxuICAgKiBzaWduYXR1cmUgYnVmZmVyIGlzIHBhc3NlZCB0byBhZGRTaWduYXR1cmUsIHNvIHdyYXBwaW5nIHRoZSBzaWduYXR1cmVcbiAgICogaGVyZSB3b3VsZCBwcm9kdWNlIGEgZG91YmxlIGRpc2NyaW1pbmFudCwgY29ycnVwdGluZyB0aGUgb24td2lyZSBzaWdcbiAgICogYnl0ZXMgYW5kIGNhdXNpbmcgdGhlIGNoYWluIHRvIHJlamVjdCB0aGUgZXh0cmluc2ljIHdpdGggYDEwMTA6IEJhZFxuICAgKiBzaWduYXR1cmVgLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGFkZFN1YnN0cmF0ZVJlY292ZXJ5U2lnbmF0dXJlKFxuICAgIHR4QnVpbGRlcjogTmF0aXZlVHJhbnNmZXJCdWlsZGVyLFxuICAgIHNpZ25pbmdNYXRlcmlhbDogRWRkc2FTaWduaW5nTWF0ZXJpYWwsXG4gICAgYmFja3VwS2V5OiBzdHJpbmcsXG4gICAgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nLFxuICAgIHVuc2lnbmVkVHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLFxuICAgIGN1cnJQYXRoOiBzdHJpbmcsXG4gICAgYml0Z29LZXk6IHN0cmluZyxcbiAgICBhY2NvdW50SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdWJzdHJhdGVLZXlQYWlyID0gbmV3IFN1YnN0cmF0ZUtleVBhaXIoeyBwdWI6IGFjY291bnRJZCB9KTtcblxuICAgIGlmIChzaWduaW5nTWF0ZXJpYWwudmVyc2lvbiA9PT0gJ3YyJykge1xuICAgICAgY29uc3QgcmF3U2lnID0gYXdhaXQgdGhpcy5zaWduU3Vic3RyYXRlTXBjVjJSZWNvdmVyeSh7XG4gICAgICAgIG1lc3NhZ2U6IHVuc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmFibGVQYXlsb2FkLFxuICAgICAgICB1c2VyS2V5OiBzaWduaW5nTWF0ZXJpYWwuZW5jcnlwdGVkVXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBiaXRnb0tleSxcbiAgICAgICAgZGVyaXZhdGlvblBhdGg6IGN1cnJQYXRoLFxuICAgICAgICBiaXRnbzogdGhpcy5iaXRnbyxcbiAgICAgIH0pO1xuICAgICAgdHhCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1Yjogc3Vic3RyYXRlS2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHJhd1NpZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHVzZXJTaWduaW5nTWF0ZXJpYWwgPSBKU09OLnBhcnNlKHNpZ25pbmdNYXRlcmlhbC51c2VyUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLlVzZXJTaWduaW5nTWF0ZXJpYWw7XG4gICAgICBjb25zdCBiYWNrdXBQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KHRoaXMuYml0Z28sIHsgZW5jcnlwdGVkUHJ2OiBiYWNrdXBLZXkgfSwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBpZiAoIWJhY2t1cFBydikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIGRlY3J5cHRpbmcgYmFja3VwIGtleWNoYWluOiBpbnZhbGlkIHBhc3N3b3JkIG9yIGNvcnJ1cHRlZCBrZXknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJhY2t1cFNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UoYmFja3VwUHJ2KSBhcyBFRERTQU1ldGhvZFR5cGVzLkJhY2t1cFNpZ25pbmdNYXRlcmlhbDtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlSGV4ID0gYXdhaXQgRUREU0FNZXRob2RzLmdldFRTU1NpZ25hdHVyZShcbiAgICAgICAgdXNlclNpZ25pbmdNYXRlcmlhbCxcbiAgICAgICAgYmFja3VwU2lnbmluZ01hdGVyaWFsLFxuICAgICAgICBjdXJyUGF0aCxcbiAgICAgICAgdW5zaWduZWRUcmFuc2FjdGlvblxuICAgICAgKTtcbiAgICAgIHR4QnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHN1YnN0cmF0ZUtleVBhaXIuZ2V0S2V5cygpLnB1YiB9LCBzaWduYXR1cmVIZXgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGFzeW5jIGNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtczogTVBDU3dlZXBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPE1QQ1R4cz4ge1xuICAgIGNvbnN0IHJlcSA9IHBhcmFtcy5zaWduYXR1cmVTaGFyZXM7XG4gICAgY29uc3QgYnJvYWRjYXN0YWJsZVRyYW5zYWN0aW9uczogTVBDVHhbXSA9IFtdO1xuICAgIGxldCBsYXN0U2NhbkluZGV4ID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVxLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBNUEMgPSBhd2FpdCBFRERTQU1ldGhvZHMuZ2V0SW5pdGlhbGl6ZWRNcGNJbnN0YW5jZSgpO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSByZXFbaV0udHhSZXF1ZXN0LnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4O1xuICAgICAgaWYgKCFyZXFbaV0ub3ZjIHx8ICFyZXFbaV0ub3ZjWzBdLmVkZHNhU2lnbmF0dXJlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYXR1cmUocyknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHJlcVtpXS5vdmNbMF0uZWRkc2FTaWduYXR1cmU7XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLnNpZ25hYmxlSGV4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBzaWduYWJsZSBoZXgnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1lc3NhZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbSh0cmFuc2FjdGlvbi5zaWduYWJsZUhleCEsICdoZXgnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IE1QQy52ZXJpZnkobWVzc2FnZUJ1ZmZlciwgc2lnbmF0dXJlKTtcbiAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduYXR1cmUnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25hdHVyZUhleCA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHNpZ25hdHVyZS5SLCAnaGV4JyksIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5zaWdtYSwgJ2hleCcpXSk7XG4gICAgICBpZiAoXG4gICAgICAgICF0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMgfHxcbiAgICAgICAgIXRyYW5zYWN0aW9uLmNvaW5TcGVjaWZpYz8uZmlyc3RWYWxpZCB8fFxuICAgICAgICAhdHJhbnNhY3Rpb24uY29pblNwZWNpZmljPy5tYXhEdXJhdGlvblxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB2YWxpZGl0eSB3aW5kb3cnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbGlkaXR5V2luZG93ID0ge1xuICAgICAgICBmaXJzdFZhbGlkOiB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/LmZpcnN0VmFsaWQsXG4gICAgICAgIG1heER1cmF0aW9uOiB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/Lm1heER1cmF0aW9uLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG1hdGVyaWFsID0gYXdhaXQgdGhpcy5nZXRNYXRlcmlhbCgpO1xuICAgICAgaWYgKCF0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWM/LmNvbW1vbktleWNoYWluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBjb21tb24ga2V5Y2hhaW4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5jb21tb25LZXljaGFpbiEgYXMgc3RyaW5nO1xuICAgICAgaWYgKCF0cmFuc2FjdGlvbi5kZXJpdmF0aW9uUGF0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgZGVyaXZhdGlvbiBwYXRoJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IHRyYW5zYWN0aW9uLmRlcml2YXRpb25QYXRoIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IGFjY291bnRJZCA9IE1QQy5kZXJpdmVVbmhhcmRlbmVkKGNvbW1vbktleWNoYWluLCBkZXJpdmF0aW9uUGF0aCkuc2xpY2UoMCwgNjQpO1xuICAgICAgY29uc3Qgc2VuZGVyQWRkciA9IHRoaXMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkoYWNjb3VudElkKTtcblxuICAgICAgY29uc3QgdHhuQnVpbGRlciA9IHRoaXMuZ2V0QnVpbGRlcigpXG4gICAgICAgIC5tYXRlcmlhbChtYXRlcmlhbClcbiAgICAgICAgLmZyb20odHJhbnNhY3Rpb24uc2VyaWFsaXplZFR4IGFzIHN0cmluZylcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlckFkZHIgfSlcbiAgICAgICAgLnZhbGlkaXR5KHZhbGlkaXR5V2luZG93KTtcblxuICAgICAgY29uc3Qgc3Vic3RyYXRlS2V5UGFpciA9IG5ldyBTdWJzdHJhdGVLZXlQYWlyKHsgcHViOiBhY2NvdW50SWQgfSk7XG4gICAgICB0eG5CdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1Yjogc3Vic3RyYXRlS2V5UGFpci5nZXRLZXlzKCkucHViIH0sIHNpZ25hdHVyZUhleCk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHR4bkJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMucHVzaCh7XG4gICAgICAgIHNlcmlhbGl6ZWRUeDogc2VyaWFsaXplZFR4LFxuICAgICAgICBzY2FuSW5kZXg6IHRyYW5zYWN0aW9uLnNjYW5JbmRleCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoaSA9PT0gcmVxLmxlbmd0aCAtIDEgJiYgdHJhbnNhY3Rpb24uY29pblNwZWNpZmljIS5sYXN0U2NhbkluZGV4KSB7XG4gICAgICAgIGxhc3RTY2FuSW5kZXggPSB0cmFuc2FjdGlvbi5jb2luU3BlY2lmaWMhLmxhc3RTY2FuSW5kZXggYXMgbnVtYmVyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IGJyb2FkY2FzdGFibGVUcmFuc2FjdGlvbnMsIGxhc3RTY2FuSW5kZXggfTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZWQgZG9jICovXG4gIGF1ZGl0RGVjcnlwdGVkS2V5KHsgcHVibGljS2V5LCBwcnYsIG11bHRpU2lnVHlwZSB9OiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcykge1xuICAgIGlmIChtdWx0aVNpZ1R5cGUgIT09ICd0c3MnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIG11bHRpU2lnVHlwZScpO1xuICAgIH1cbiAgICBhdWRpdEVkZHNhUHJpdmF0ZUtleShwcnYsIHB1YmxpY0tleSA/PyAnJyk7XG4gIH1cbn1cbiJdfQ==
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
|