@bitgo-beta/sdk-coin-trx 1.2.3-alpha.31 → 1.2.3-alpha.310

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/trx.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.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
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,31 +15,46 @@ 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 (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
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
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.Trx = exports.NodeTypes = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
36
+ exports.Trx = exports.NodeTypes = exports.DEFAULT_SCAN_FACTOR = exports.RECOVER_TRANSACTION_EXPIRY = exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = exports.SAFE_TRON_TRANSACTION_FEE = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
23
37
  /**
24
38
  * @prettier
25
39
  */
26
40
  const secp256k1 = __importStar(require("secp256k1"));
27
41
  const crypto_1 = require("crypto");
28
- const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
42
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
29
43
  const request = __importStar(require("superagent"));
30
44
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
31
45
  const lib_1 = require("./lib");
32
46
  const builder_1 = require("./lib/builder");
47
+ const lodash_1 = require("lodash");
33
48
  exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = 1e6;
49
+ exports.SAFE_TRON_TRANSACTION_FEE = 2.1 * 1e6; // TRON foundation recommends 2.1 TRX as fees for guaranteed transaction
50
+ exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = 100 * 1e6; // TRON foundation recommends 100 TRX as fees for guaranteed transaction
51
+ exports.RECOVER_TRANSACTION_EXPIRY = 86400000; // 24 hour
52
+ exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
34
53
  var NodeTypes;
35
54
  (function (NodeTypes) {
36
55
  NodeTypes[NodeTypes["Full"] = 0] = "Full";
37
56
  NodeTypes[NodeTypes["Solidity"] = 1] = "Solidity";
38
- })(NodeTypes = exports.NodeTypes || (exports.NodeTypes = {}));
57
+ })(NodeTypes || (exports.NodeTypes = NodeTypes = {}));
39
58
  class Trx extends sdk_core_1.BaseCoin {
40
59
  constructor(bitgo, staticsCoin) {
41
60
  super(bitgo);
@@ -60,6 +79,14 @@ class Trx extends sdk_core_1.BaseCoin {
60
79
  transactionDataAllowed() {
61
80
  return true;
62
81
  }
82
+ /** {@inheritDoc } **/
83
+ supportsMultisig() {
84
+ return true;
85
+ }
86
+ /** inherited doc */
87
+ getDefaultMultisigType() {
88
+ return sdk_core_1.multisigTypes.onchain;
89
+ }
63
90
  static createInstance(bitgo, staticsCoin) {
64
91
  return new Trx(bitgo, staticsCoin);
65
92
  }
@@ -75,21 +102,21 @@ class Trx extends sdk_core_1.BaseCoin {
75
102
  return true;
76
103
  }
77
104
  /**
78
- * Checks if this is a valid base58 or hex address
105
+ * Checks if this is a valid base58
79
106
  * @param address
80
107
  */
81
108
  isValidAddress(address) {
82
109
  if (!address) {
83
110
  return false;
84
111
  }
85
- return this.isValidHexAddress(address) || lib_1.Utils.isBase58Address(address);
112
+ return lib_1.Utils.isBase58Address(address);
86
113
  }
87
114
  /**
88
115
  * Checks if this is a valid hex address
89
116
  * @param address hex address
90
117
  */
91
118
  isValidHexAddress(address) {
92
- return address.length === 42 && /^(0x)?([0-9a-f]{2})+$/i.test(address);
119
+ return /^41[0-9a-f]{40}$/i.test(address);
93
120
  }
94
121
  /**
95
122
  * Generate ed25519 key pair
@@ -102,9 +129,9 @@ class Trx extends sdk_core_1.BaseCoin {
102
129
  if (!seed) {
103
130
  // An extended private key has both a normal 256 bit private key and a 256 bit chain code, both of which must be
104
131
  // random. 512 bits is therefore the maximum entropy and gives us maximum security against cracking.
105
- seed = crypto_1.randomBytes(512 / 8);
132
+ seed = (0, crypto_1.randomBytes)(512 / 8);
106
133
  }
107
- const hd = utxo_lib_1.bip32.fromSeed(seed);
134
+ const hd = secp256k1_1.bip32.fromSeed(seed);
108
135
  return {
109
136
  pub: hd.neutered().toBase58(),
110
137
  prv: hd.toBase58(),
@@ -112,7 +139,7 @@ class Trx extends sdk_core_1.BaseCoin {
112
139
  }
113
140
  isValidXpub(xpub) {
114
141
  try {
115
- return utxo_lib_1.bip32.fromBase58(xpub).isNeutered();
142
+ return secp256k1_1.bip32.fromBase58(xpub).isNeutered();
116
143
  }
117
144
  catch (e) {
118
145
  return false;
@@ -141,7 +168,7 @@ class Trx extends sdk_core_1.BaseCoin {
141
168
  * @returns {string} derived private key
142
169
  */
143
170
  deriveKeyWithPath({ key, path }) {
144
- const keychain = utxo_lib_1.bip32.fromBase58(key);
171
+ const keychain = secp256k1_1.bip32.fromBase58(key);
145
172
  const derivedKeyNode = keychain.derivePath(path);
146
173
  return derivedKeyNode.toBase58();
147
174
  }
@@ -151,14 +178,12 @@ class Trx extends sdk_core_1.BaseCoin {
151
178
  * @param params
152
179
  * @param params.txPrebuild {Object} prebuild object returned by platform
153
180
  * @param params.prv {String} user prv
154
- * @param params.wallet.addressVersion {String} this is the version of the Algorand multisig address generation format
155
181
  * @returns Bluebird<SignedTransaction>
156
182
  */
157
183
  async signTransaction(params) {
158
- var _a, _b;
159
- const txBuilder = builder_1.getBuilder(this.getChain()).from(params.txPrebuild.txHex);
184
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(params.txPrebuild.txHex);
160
185
  let key;
161
- const { chain, index } = (_b = (_a = params.txPrebuild) === null || _a === void 0 ? void 0 : _a.addressInfo) !== null && _b !== void 0 ? _b : { chain: 0, index: 0 };
186
+ const { chain, index } = params.txPrebuild?.addressInfo ?? { chain: 0, index: 0 };
162
187
  if (chain === 0 && index === 0) {
163
188
  key = params.prv;
164
189
  }
@@ -186,7 +211,7 @@ class Trx extends sdk_core_1.BaseCoin {
186
211
  */
187
212
  isValidXprv(prv) {
188
213
  try {
189
- return !utxo_lib_1.bip32.fromBase58(prv).isNeutered();
214
+ return !secp256k1_1.bip32.fromBase58(prv).isNeutered();
190
215
  }
191
216
  catch {
192
217
  return false;
@@ -216,11 +241,10 @@ class Trx extends sdk_core_1.BaseCoin {
216
241
  * @param message
217
242
  */
218
243
  async signMessage(key, message) {
219
- var _a;
220
244
  const toSign = this.toHexString(message);
221
245
  let prv = key.prv;
222
246
  if (this.isValidXprv(prv)) {
223
- prv = (_a = utxo_lib_1.bip32.fromBase58(prv).privateKey) === null || _a === void 0 ? void 0 : _a.toString('hex');
247
+ prv = secp256k1_1.bip32.fromBase58(prv).privateKey?.toString('hex');
224
248
  }
225
249
  if (!prv) {
226
250
  throw new Error('no privateKey');
@@ -238,7 +262,7 @@ class Trx extends sdk_core_1.BaseCoin {
238
262
  if (!this.isValidXpub(xpub)) {
239
263
  throw new Error('invalid xpub');
240
264
  }
241
- const publicKey = utxo_lib_1.bip32.fromBase58(xpub, utxo_lib_1.networks.bitcoin).publicKey;
265
+ const publicKey = secp256k1_1.bip32.fromBase58(xpub).publicKey;
242
266
  return Buffer.from(secp256k1.publicKeyConvert(publicKey, false /* compressed */)).toString('hex');
243
267
  }
244
268
  /**
@@ -259,29 +283,29 @@ class Trx extends sdk_core_1.BaseCoin {
259
283
  if (!this.isValidXprv(xprv)) {
260
284
  throw new Error('invalid xprv');
261
285
  }
262
- const hdNode = utxo_lib_1.bip32.fromBase58(xprv, utxo_lib_1.networks.bitcoin);
286
+ const hdNode = secp256k1_1.bip32.fromBase58(xprv);
263
287
  if (!hdNode.privateKey) {
264
288
  throw new Error('no privateKey');
265
289
  }
266
290
  return hdNode.privateKey.toString('hex');
267
291
  }
292
+ getNodeUrl(node) {
293
+ switch (node) {
294
+ case NodeTypes.Full:
295
+ return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
296
+ case NodeTypes.Solidity:
297
+ return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
298
+ default:
299
+ throw new Error('node type not found');
300
+ }
301
+ }
268
302
  /**
269
303
  * Make a query to Trongrid for information such as balance, token balance, solidity calls
270
304
  * @param query {Object} key-value pairs of parameters to append after /api
271
305
  * @returns {Object} response from Trongrid
272
306
  */
273
307
  async recoveryPost(query) {
274
- let nodeUri = '';
275
- switch (query.node) {
276
- case NodeTypes.Full:
277
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
278
- break;
279
- case NodeTypes.Solidity:
280
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
281
- break;
282
- default:
283
- throw new Error('node type not found');
284
- }
308
+ const nodeUri = this.getNodeUrl(query.node);
285
309
  const response = await request
286
310
  .post(nodeUri + query.path)
287
311
  .type('json')
@@ -298,17 +322,7 @@ class Trx extends sdk_core_1.BaseCoin {
298
322
  * @returns {Object} response from Trongrid
299
323
  */
300
324
  async recoveryGet(query) {
301
- let nodeUri = '';
302
- switch (query.node) {
303
- case NodeTypes.Full:
304
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
305
- break;
306
- case NodeTypes.Solidity:
307
- nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
308
- break;
309
- default:
310
- throw new Error('node type not found');
311
- }
325
+ const nodeUri = this.getNodeUrl(query.node);
312
326
  const response = await request
313
327
  .get(nodeUri + query.path)
314
328
  .type('json')
@@ -389,134 +403,291 @@ class Trx extends sdk_core_1.BaseCoin {
389
403
  }
390
404
  });
391
405
  }
406
+ /**
407
+ * Format for offline vault signing
408
+ * @param {BaseTransaction} tx
409
+ * @param {number} fee
410
+ * @param {number} recoveryAmount
411
+ * @returns {RecoveryTransaction}
412
+ */
413
+ formatForOfflineVault(tx, fee, recoveryAmount, addressInfo) {
414
+ const txJSON = tx.toJson();
415
+ const format = {
416
+ txHex: JSON.stringify(txJSON),
417
+ recoveryAmount,
418
+ feeInfo: {
419
+ fee: `${fee}`,
420
+ },
421
+ tx: txJSON, // Leaving it as txJSON for backwards compatibility
422
+ coin: this.getChain(),
423
+ };
424
+ return addressInfo ? { ...format, addressInfo } : format;
425
+ }
392
426
  /**
393
427
  * Builds a funds recovery transaction without BitGo.
394
428
  * We need to do three queries during this:
395
429
  * 1) Node query - how much money is in the account
396
430
  * 2) Build transaction - build our transaction for the amount
397
431
  * 3) Send signed build - send our signed build to a public node
432
+ *
433
+ * Note 1: for base address recoveries, fund will be recovered to recovery destination if base address balance is
434
+ * more than 2.1 TRX for native TRX recovery and 100 TRX for token recover. For receive addresses, fund will be
435
+ * recovered to base address first then swept to base address(decided as the universal pattern in team meeting).
436
+ *
437
+ * Note 2: the function supports token sweep from base address.
438
+ * TODO: support token sweep from receive address.
439
+ *
398
440
  * @param params
399
441
  */
400
442
  async recover(params) {
401
- const isKrsRecovery = sdk_core_1.getIsKrsRecovery(params);
402
- const isUnsignedSweep = sdk_core_1.getIsUnsignedSweep(params);
443
+ const isKrsRecovery = (0, sdk_core_1.getIsKrsRecovery)(params);
444
+ const isUnsignedSweep = (0, sdk_core_1.getIsUnsignedSweep)(params);
403
445
  if (!this.isValidAddress(params.recoveryDestination)) {
404
446
  throw new Error('Invalid destination address!');
405
447
  }
448
+ let startIdx = params.startingScanIndex;
449
+ if ((0, lodash_1.isUndefined)(startIdx)) {
450
+ startIdx = 1;
451
+ }
452
+ else if (!(0, lodash_1.isInteger)(startIdx) || startIdx < 0) {
453
+ throw new Error('Invalid starting index to scan for addresses');
454
+ }
455
+ let numIteration = params.scan;
456
+ if ((0, lodash_1.isUndefined)(numIteration)) {
457
+ numIteration = 20;
458
+ }
459
+ else if (!(0, lodash_1.isInteger)(numIteration) || numIteration <= 0) {
460
+ throw new Error('Invalid scanning factor');
461
+ }
406
462
  // get our user, backup keys
407
- const keys = sdk_core_1.getBip32Keys(this.bitgo, params, { requireBitGoXpub: false });
463
+ const keys = (0, sdk_core_1.getBip32Keys)(this.bitgo, params, { requireBitGoXpub: false });
408
464
  // we need to decode our bitgoKey to a base58 address
409
465
  const bitgoHexAddr = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
410
- const recoveryAddressHex = lib_1.Utils.getHexAddressFromBase58Address(params.recoveryDestination);
411
- // call the node to get our account balance
412
- const account = await this.getAccountBalancesFromNode(lib_1.Utils.getBase58AddressFromHex(bitgoHexAddr));
413
- const recoveryAmount = account.data[0].balance;
414
- const userXPub = keys[0].neutered().toBase58();
415
- const userXPrv = keys[0].toBase58();
416
- const backupXPub = keys[1].neutered().toBase58();
417
- // first construct token txns
418
- const tokenTxns = [];
419
- for (const token of account.data[0].trc20) {
420
- // mainnet tokens
421
- if (token.TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8) {
422
- const amount = token.TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8;
423
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8');
424
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
425
- .transaction);
426
- }
427
- else if (token.TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t) {
428
- const amount = token.TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t;
429
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t');
430
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
431
- .transaction);
432
- // testnet tokens
466
+ let recoveryFromAddrHex = bitgoHexAddr;
467
+ let recoveryToAddressHex = lib_1.Utils.getHexAddressFromBase58Address(params.recoveryDestination);
468
+ // call the node to get our account balance for base address
469
+ let account = await this.getAccountBalancesFromNode(lib_1.Utils.getBase58AddressFromHex(recoveryFromAddrHex));
470
+ let recoveryAmount = account.data[0].balance;
471
+ let userXPrv = keys[0].toBase58();
472
+ let isReceiveAddress = false;
473
+ let addressInfo;
474
+ const tokenContractAddr = params.tokenContractAddress;
475
+ // check for possible token recovery, recover the token provide by user
476
+ if (tokenContractAddr) {
477
+ let rawTokenTxn;
478
+ for (const token of account.data[0].trc20) {
479
+ if (token[tokenContractAddr]) {
480
+ const amount = token[tokenContractAddr];
481
+ const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(tokenContractAddr);
482
+ rawTokenTxn = (await this.getTriggerSmartContractTransaction(recoveryToAddressHex, recoveryFromAddrHex, amount, tokenContractAddrHex)).transaction;
483
+ recoveryAmount = parseInt(amount, 10);
484
+ break;
485
+ }
433
486
  }
434
- else if (token.TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id) {
435
- const amount = token.TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id;
436
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id');
437
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
438
- .transaction);
487
+ // build and sign token txns
488
+ if (rawTokenTxn) {
489
+ // Check there is sufficient of the native asset to cover fees
490
+ const trxBalance = account.data[0].balance;
491
+ if (trxBalance < exports.SAFE_TRON_TOKEN_TRANSACTION_FEE) {
492
+ throw new Error(`Amount of funds to recover ${trxBalance} is less than ${exports.SAFE_TRON_TOKEN_TRANSACTION_FEE} and wouldn't be able to fund a trc20 send`);
493
+ }
494
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
495
+ // Default expiry is 1 minute which is too short for recovery purposes
496
+ // extend the expiry to 1 day
497
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
498
+ // this tx should be enough to drop into a node
499
+ if (isUnsignedSweep) {
500
+ return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
501
+ }
502
+ const userPrv = this.xprvToCompressedPrv(userXPrv);
503
+ txBuilder.sign({ key: userPrv });
504
+ // krs recoveries don't get signed
505
+ if (!isKrsRecovery && !isReceiveAddress) {
506
+ const backupXPrv = keys[1].toBase58();
507
+ const backupPrv = this.xprvToCompressedPrv(backupXPrv);
508
+ txBuilder.sign({ key: backupPrv });
509
+ }
510
+ return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
439
511
  }
440
- else if (token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs) {
441
- const amount = token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs;
442
- const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs');
443
- tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
444
- .transaction);
512
+ else {
513
+ throw Error('Not found token to recover, please check token balance');
445
514
  }
446
515
  }
447
- // construct the tx -
448
- // there's an assumption here being made about fees: for a wallet that hasn't been used in awhile, the implication is
449
- // it has maximum bandwidth. thus, a recovery should cost the minimum amount (1e6 sun or 1 Tron)
450
- if (exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE > recoveryAmount) {
451
- throw new Error('Amount of funds to recover wouldnt be able to fund a send');
452
- }
453
- const keyHexAddresses = [
454
- this.pubToHexAddress(this.xpubToUncompressedPub(userXPub)),
455
- this.pubToHexAddress(this.xpubToUncompressedPub(backupXPub)),
456
- bitgoHexAddr,
457
- ];
458
- // run checks to ensure this is a valid tx - permissions match our signer keys
459
- const ownerKeys = [];
460
- for (const key of account.data[0].owner_permission.keys) {
461
- const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
462
- const weight = key.weight;
463
- ownerKeys.push({ address, weight });
464
- }
465
- const activePermissionKeys = [];
466
- for (const key of account.data[0].active_permission[0].keys) {
467
- const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
468
- const weight = key.weight;
469
- activePermissionKeys.push({ address, weight });
470
- }
471
- this.checkPermissions(ownerKeys, keyHexAddresses);
472
- this.checkPermissions(activePermissionKeys, keyHexAddresses);
473
- // build and sign token txns
474
- const finalTokenTxs = [];
475
- for (const tokenTxn of tokenTxns) {
476
- const txBuilder = builder_1.getBuilder(this.getChain()).from(tokenTxn);
477
- // this tx should be enough to drop into a node
478
- if (isUnsignedSweep) {
479
- finalTokenTxs.push((await txBuilder.build()).toJson());
480
- continue;
516
+ // let us recover the native Tron
517
+ if (recoveryAmount > exports.SAFE_TRON_TRANSACTION_FEE) {
518
+ const userXPub = keys[0].neutered().toBase58();
519
+ const backupXPub = keys[1].neutered().toBase58();
520
+ // check multisig permissions
521
+ const keyHexAddresses = [
522
+ this.pubToHexAddress(this.xpubToUncompressedPub(userXPub)),
523
+ this.pubToHexAddress(this.xpubToUncompressedPub(backupXPub)),
524
+ bitgoHexAddr,
525
+ ];
526
+ // run checks to ensure this is a valid tx - permissions match our signer keys
527
+ const ownerKeys = [];
528
+ for (const key of account.data[0].owner_permission.keys) {
529
+ const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
530
+ const weight = key.weight;
531
+ ownerKeys.push({ address, weight });
532
+ }
533
+ const activePermissionKeys = [];
534
+ for (const key of account.data[0].active_permission[0].keys) {
535
+ const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
536
+ const weight = key.weight;
537
+ activePermissionKeys.push({ address, weight });
481
538
  }
482
- const userPrv = this.xprvToCompressedPrv(userXPrv);
483
- txBuilder.sign({ key: userPrv });
484
- // krs recoveries don't get signed
485
- if (!isKrsRecovery) {
486
- const backupXPrv = keys[1].toBase58();
487
- const backupPrv = this.xprvToCompressedPrv(backupXPrv);
488
- txBuilder.sign({ key: backupPrv });
539
+ this.checkPermissions(ownerKeys, keyHexAddresses);
540
+ this.checkPermissions(activePermissionKeys, keyHexAddresses);
541
+ }
542
+ else {
543
+ // Check receive addresses for funds
544
+ // Check for first derived wallet with funds
545
+ // Receive addresses are derived from the user key
546
+ for (let i = startIdx; i < numIteration + startIdx; i++) {
547
+ const derivationPath = `0/0/0/${i}`;
548
+ const userKey = keys[0].derivePath(derivationPath);
549
+ const xpub = userKey.neutered();
550
+ const receiveAddress = this.pubToHexAddress(this.xpubToUncompressedPub(xpub.toBase58()));
551
+ const address = lib_1.Utils.getBase58AddressFromHex(receiveAddress);
552
+ // call the node to get our account balance
553
+ const accountInfo = await this.getAccountBalancesFromNode(address);
554
+ if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
555
+ account = accountInfo;
556
+ recoveryAmount = accountInfo.data[0].balance;
557
+ userXPrv = userKey.toBase58(); // assign derived userXPrx
558
+ isReceiveAddress = true;
559
+ recoveryFromAddrHex = receiveAddress;
560
+ recoveryToAddressHex = bitgoHexAddr;
561
+ addressInfo = {
562
+ address,
563
+ chain: 0,
564
+ index: i,
565
+ };
566
+ break;
567
+ }
489
568
  }
490
- finalTokenTxs.push((await txBuilder.build()).toJson());
491
569
  }
492
- // tokens must be recovered before the native asset, so that there is sufficient of the native asset to cover fees
493
- if (finalTokenTxs.length > 0) {
494
- return {
495
- tokenTxs: finalTokenTxs,
496
- };
570
+ // a sweep potentially needs to pay for multi-sig transfer, destination account activation and bandwidth
571
+ // TRON foundation recommends 2.1 TRX for guaranteed confirmation
572
+ if (!recoveryAmount || exports.SAFE_TRON_TRANSACTION_FEE >= recoveryAmount) {
573
+ throw new Error(`Amount of funds to recover ${recoveryAmount} is less than ${exports.SAFE_TRON_TRANSACTION_FEE} and wouldn't be able to fund a send`);
497
574
  }
498
- const recoveryAmountMinusFees = recoveryAmount - exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE;
499
- const buildTx = await this.getBuildTransaction(recoveryAddressHex, bitgoHexAddr, recoveryAmountMinusFees);
575
+ const recoveryAmountMinusFees = recoveryAmount - exports.SAFE_TRON_TRANSACTION_FEE;
576
+ const buildTx = await this.getBuildTransaction(recoveryToAddressHex, recoveryFromAddrHex, recoveryAmountMinusFees);
500
577
  // construct our tx
501
- const txBuilder = builder_1.getBuilder(this.getChain()).from(buildTx);
578
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
579
+ // Default expiry is 1 minute which is too short for recovery purposes
580
+ // extend the expiry to 1 day
581
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
582
+ const tx = await txBuilder.build();
502
583
  // this tx should be enough to drop into a node
503
584
  if (isUnsignedSweep) {
504
- return {
505
- tx: (await txBuilder.build()).toJson(),
506
- recoveryAmount: recoveryAmountMinusFees,
507
- };
585
+ return this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
508
586
  }
509
587
  const userPrv = this.xprvToCompressedPrv(userXPrv);
510
588
  txBuilder.sign({ key: userPrv });
511
589
  // krs recoveries don't get signed
512
- if (!isKrsRecovery) {
590
+ if (!isKrsRecovery && !isReceiveAddress) {
513
591
  const backupXPrv = keys[1].toBase58();
514
592
  const backupPrv = this.xprvToCompressedPrv(backupXPrv);
515
593
  txBuilder.sign({ key: backupPrv });
516
594
  }
595
+ const txSigned = await txBuilder.build();
596
+ return this.formatForOfflineVault(txSigned, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
597
+ }
598
+ /**
599
+ * Builds native TRX recoveries of receive addresses in batch without BitGo.
600
+ * Funds will be recovered to base address first. You need to initiate another sweep txn after that.
601
+ * Note: there will be another recoverTokenConsolidations function to support token recover from receive addresses.
602
+ *
603
+ * @param {ConsolidationRecoveryOptions} params - options for consolidation recovery.
604
+ * @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
605
+ * @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
606
+ */
607
+ async recoverConsolidations(params) {
608
+ const isUnsignedConsolidations = (0, sdk_core_1.getIsUnsignedSweep)(params);
609
+ const startIdx = params.startingScanIndex || 1;
610
+ const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
611
+ if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
612
+ throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
613
+ }
614
+ const keys = (0, sdk_core_1.getBip32Keys)(this.bitgo, params, { requireBitGoXpub: false });
615
+ const baseAddrHex = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
616
+ const txnsBatch = [];
617
+ for (let i = startIdx; i < endIdx; i++) {
618
+ const derivationPath = `0/0/0/${i}`;
619
+ const userKey = keys[0].derivePath(derivationPath);
620
+ const userKeyXPub = userKey.neutered();
621
+ const receiveAddressHex = this.pubToHexAddress(this.xpubToUncompressedPub(userKeyXPub.toBase58()));
622
+ const receiveAddress = lib_1.Utils.getBase58AddressFromHex(receiveAddressHex);
623
+ // call the node to get our account balance
624
+ const accountInfo = await this.getAccountBalancesFromNode(receiveAddress);
625
+ if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
626
+ let recoveryAmount = 0;
627
+ // Tokens must be consolidate before the native asset. First construct token txns
628
+ let rawTokenTxn;
629
+ // check for possible token recovery, recover the token provide by user
630
+ if (params.tokenContractAddress) {
631
+ if (accountInfo.data[0].balance > exports.SAFE_TRON_TOKEN_TRANSACTION_FEE && accountInfo.data[0].trc20[0]) {
632
+ const tokenDataArray = accountInfo.data[0].trc20;
633
+ for (const tokenData of tokenDataArray) {
634
+ const contractAddress = Object.keys(tokenData);
635
+ if (params.tokenContractAddress === contractAddress[0]) {
636
+ const amount = tokenData[contractAddress[0]];
637
+ const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(contractAddress[0]);
638
+ rawTokenTxn = (await this.getTriggerSmartContractTransaction(baseAddrHex, receiveAddressHex, amount, tokenContractAddrHex)).transaction;
639
+ recoveryAmount = parseInt(amount, 10);
640
+ break;
641
+ }
642
+ }
643
+ }
644
+ // build and sign token txns
645
+ if (rawTokenTxn) {
646
+ const addressInfo = {
647
+ address: receiveAddress,
648
+ chain: 0,
649
+ index: i,
650
+ };
651
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
652
+ // Default expiry is 1 minute which is too short for recovery purposes
653
+ // extend the expiry to 1 day
654
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
655
+ // this tx should be enough to drop into a node
656
+ if (!isUnsignedConsolidations) {
657
+ const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
658
+ // receive address only needs to be signed by user key
659
+ txBuilder.sign({ key: userPrv });
660
+ }
661
+ const tx = await txBuilder.build();
662
+ txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount, addressInfo));
663
+ }
664
+ }
665
+ else {
666
+ const addressBalance = accountInfo.data[0].balance;
667
+ const addressInfo = {
668
+ address: receiveAddress,
669
+ chain: 0,
670
+ index: i,
671
+ };
672
+ const recoveryAmount = addressBalance - exports.SAFE_TRON_TRANSACTION_FEE;
673
+ const buildTx = await this.getBuildTransaction(baseAddrHex, receiveAddressHex, recoveryAmount);
674
+ // construct our tx
675
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
676
+ // Default expiry is 1 minute which is too short for recovery purposes
677
+ // extend the expiry to 1 day
678
+ txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
679
+ if (!isUnsignedConsolidations) {
680
+ const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
681
+ // receive address only needs to be signed by user key
682
+ txBuilder.sign({ key: userPrv });
683
+ }
684
+ const tx = await txBuilder.build();
685
+ txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmount, addressInfo));
686
+ }
687
+ }
688
+ }
517
689
  return {
518
- tx: (await txBuilder.build()).toJson(),
519
- recoveryAmount: recoveryAmountMinusFees,
690
+ transactions: txnsBatch,
520
691
  };
521
692
  }
522
693
  /**
@@ -528,7 +699,7 @@ class Trx extends sdk_core_1.BaseCoin {
528
699
  if (!txHex || !params.feeInfo) {
529
700
  throw new Error('missing explain tx parameters');
530
701
  }
531
- const txBuilder = builder_1.getBuilder(this.getChain()).from(txHex);
702
+ const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(txHex);
532
703
  const tx = await txBuilder.build();
533
704
  const outputs = [
534
705
  {
@@ -551,8 +722,8 @@ class Trx extends sdk_core_1.BaseCoin {
551
722
  id: tx.id,
552
723
  outputs,
553
724
  outputAmount: outputs[0].amount,
554
- changeOutputs: [],
555
- changeAmount: '0',
725
+ changeOutputs: [], // account based does not use change outputs
726
+ changeAmount: '0', // account base does not make change
556
727
  fee: params.feeInfo,
557
728
  timestamp: tx.validFrom,
558
729
  expiration: tx.validTo,
@@ -560,4 +731,4 @@ class Trx extends sdk_core_1.BaseCoin {
560
731
  }
561
732
  }
562
733
  exports.Trx = Trx;
563
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCxxREFBdUM7QUFDdkMsbUNBQXFDO0FBRXJDLG1EQUF1RDtBQUN2RCxvREFBc0M7QUFDdEMsbURBbUI4QjtBQUM5QiwrQkFBeUQ7QUFDekQsMkNBQTJDO0FBRzlCLFFBQUEsaUNBQWlDLEdBQUcsR0FBRyxDQUFDO0FBc0RyRCxJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIseUNBQUksQ0FBQTtJQUNKLGlEQUFRLENBQUE7QUFDVixDQUFDLEVBSFcsU0FBUyxHQUFULGlCQUFTLEtBQVQsaUJBQVMsUUFHcEI7QUFTRCxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUcvQixZQUFZLEtBQWdCLEVBQUUsV0FBdUM7UUFDbkUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7U0FDdkU7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztJQUNwQyxDQUFDO0lBRUQsYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLHNCQUFzQjtRQUNwQixPQUFPLElBQUksQ0FBQztJ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NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBDb2luRmFtaWx5LCBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGJpcDMyLCBuZXR3b3JrcyB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBjb21tb24sXG4gIGdldEJpcDMyS2V5cyxcbiAgZ2V0SXNLcnNSZWNvdmVyeSxcbiAgZ2V0SXNVbnNpZ25lZFN3ZWVwLFxuICBLZXlQYWlyLFxuICBNZXRob2ROb3RJbXBsZW1lbnRlZEVycm9yLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUcmFuc2FjdGlvbkZlZSxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCBhcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVHJhbnNhY3Rpb25SZWNpcGllbnQgYXMgUmVjaXBpZW50LFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBJbnRlcmZhY2UsIFV0aWxzLCBXcmFwcGVkQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2xpYi9idWlsZGVyJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uUmVjZWlwdCB9IGZyb20gJy4vbGliL2lmYWNlJztcblxuZXhwb3J0IGNvbnN0IE1JTklNVU1fVFJPTl9NU0lHX1RSQU5TQUNUSU9OX0ZFRSA9IDFlNjtcblxuZXhwb3J0IGludGVyZmFjZSBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeEluZm8ge1xuICByZWNpcGllbnRzOiBSZWNpcGllbnRbXTtcbiAgZnJvbTogc3RyaW5nO1xuICB0eGlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkcmVzc0luZm8ge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgZXhwaXJhdGlvbjogbnVtYmVyO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uUHJlYnVpbGQge1xuICB0eEhleDogc3RyaW5nO1xuICB0eEluZm86IFR4SW5mbztcbiAgYWRkcmVzc0luZm8/OiBBZGRyZXNzSW5mbztcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4Pzogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgfTtcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nOyAvLyBCb3ggQVxuICBiYWNrdXBLZXk6IHN0cmluZzsgLy8gQm94IEJcbiAgYml0Z29LZXk6IHN0cmluZzsgLy8gQm94IEMgLSB0aGlzIGlzIGJpdGdvJ3MgeHB1YiBhbmQgd2lsbCBiZSB1c2VkIHRvIGRlcml2ZSB0aGVpciByb290IGFkZHJlc3NcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogc3RyaW5nOyAvLyBiYXNlNTggYWRkcmVzc1xuICBrcnNQcm92aWRlcj86IHN0cmluZztcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeVRyYW5zYWN0aW9uIHtcbiAgdHg/OiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICByZWNvdmVyeUFtb3VudD86IG51bWJlcjtcbiAgdG9rZW5UeHM/OiBUcmFuc2FjdGlvblJlY2VpcHRbXTtcbn1cblxuZXhwb3J0IGVudW0gTm9kZVR5cGVzIHtcbiAgRnVsbCxcbiAgU29saWRpdHksXG59XG5cbi8qKlxuICogVGhpcyBzdHJ1Y3R1cmUgaXMgbm90IGEgY29tcGxldGUgbW9kZWwgb2YgdGhlIEFjY291bnRSZXNwb25zZSBmcm9tIGEgbm9kZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2NvdW50UmVzcG9uc2Uge1xuICBkYXRhOiBbSW50ZXJmYWNlLkFjY291bnRJbmZvXTtcbn1cblxuZXhwb3J0IGNsYXNzIFRyeCBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGF0aWNzQ29pbjogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPjtcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG5cbiAgICBpZiAoIXN0YXRpY3NDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgY29uc3RydWN0b3IgcGFyYW1ldGVyIHN0YXRpY3NDb2luJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgfVxuXG4gIGdldENoYWluKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5uYW1lO1xuICB9XG5cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICBnZXRGdWxsTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZnVsbE5hbWU7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCkge1xuICAgIHJldHVybiBNYXRoLnBvdygxMCwgdGhpcy5fc3RhdGljc0NvaW4uZGVjaW1hbFBsYWNlcyk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdHJhbnNhY3Rpb25EYXRhQWxsb3dlZCgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUcngoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGJhc2U1OCBvciBoZXggYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFhZGRyZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzVmFsaWRIZXhBZGRyZXNzKGFkZHJlc3MpIHx8IFV0aWxzLmlzQmFzZTU4QWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGhleCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzIGhleCBhZGRyZXNzXG4gICAqL1xuICBpc1ZhbGlkSGV4QWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYWRkcmVzcy5sZW5ndGggPT09IDQyICYmIC9eKDB4KT8oWzAtOWEtZl17Mn0pKyQvaS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIC8vIFRPRE86IG1vdmUgdGhpcyBhbmQgYWRkcmVzcyBjcmVhdGlvbiBsb2dpYyB0byBhY2NvdW50LWxpYlxuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTYgYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZVxuICAgICAgLy8gcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBoZCA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGhkLm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogaGQudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFhwdWIoeHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHViKHB1YikpIHtcbiAgICAgIC8vIHhwdWJzIGNhbiBiZSBjb252ZXJ0ZWQgaW50byByZWd1bGFyIHB1YnMsIHNvIHRlY2huaWNhbGx5IGl0IGlzIGEgdmFsaWQgcHViXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14wNFthLXpBLVowLTldezEyOH0kJykudGVzdChwdWIpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdGhyb3cgbmV3IE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IoKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlIGEgdXNlciBrZXkgdXNpbmcgdGhlIGNoYWluIHBhdGggb2YgdGhlIGFkZHJlc3NcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gcGF0aFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBkZXJpdmVkIHByaXZhdGUga2V5XG4gICAqL1xuICBkZXJpdmVLZXlXaXRoUGF0aCh7IGtleSwgcGF0aCB9OiB7IGtleTogc3RyaW5nOyBwYXRoOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qga2V5Y2hhaW4gPSBiaXAzMi5mcm9tQmFzZTU4KGtleSk7XG4gICAgY29uc3QgZGVyaXZlZEtleU5vZGUgPSBrZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpO1xuICAgIHJldHVybiBkZXJpdmVkS2V5Tm9kZS50b0Jhc2U1OCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge09iamVjdH0gcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHBsYXRmb3JtXG4gICAqIEBwYXJhbSBwYXJhbXMucHJ2IHtTdHJpbmd9IHVzZXIgcHJ2XG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0LmFkZHJlc3NWZXJzaW9uIHtTdHJpbmd9IHRoaXMgaXMgdGhlIHZlcnNpb24gb2YgdGhlIEFsZ29yYW5kIG11bHRpc2lnIGFkZHJlc3MgZ2VuZXJhdGlvbiBmb3JtYXRcbiAgICogQHJldHVybnMgQmx1ZWJpcmQ8U2lnbmVkVHJhbnNhY3Rpb24+XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShwYXJhbXMudHhQcmVidWlsZC50eEhleCk7XG5cbiAgICBsZXQga2V5O1xuICAgIGNvbnN0IHsgY2hhaW4sIGluZGV4IH0gPSBwYXJhbXMudHhQcmVidWlsZD8uYWRkcmVzc0luZm8gPz8geyBjaGFpbjogMCwgaW5kZXg6IDAgfTtcbiAgICBpZiAoY2hhaW4gPT09IDAgJiYgaW5kZXggPT09IDApIHtcbiAgICAgIGtleSA9IHBhcmFtcy5wcnY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8ke2NoYWlufS8ke2luZGV4fWA7XG4gICAgICBrZXkgPSB0aGlzLmRlcml2ZUtleVdpdGhQYXRoKHsga2V5OiBwYXJhbXMucHJ2LCBwYXRoOiBkZXJpdmF0aW9uUGF0aCB9KTtcbiAgICB9XG4gICAgdHhCdWlsZGVyLnNpZ24oeyBrZXkgfSk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHRyYW5zYWN0aW9uLnRvSnNvbigpKSxcbiAgICB9O1xuICAgIGlmICh0cmFuc2FjdGlvbi50b0pzb24oKS5zaWduYXR1cmUubGVuZ3RoID49IDIpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gICAgLy8gSGFsZiBzaWduZWQgdHJhbnNhY3Rpb25cbiAgICByZXR1cm4ge1xuICAgICAgaGFsZlNpZ25lZDogcmVzcG9uc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgc2VlZCBmb3IgdGhlIGNvaW5cbiAgICpcbiAgICogQHBhcmFtIHBydiAtIHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgaXNWYWxpZFhwcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICFiaXAzMi5mcm9tQmFzZTU4KHBydikuaXNOZXV0ZXJlZCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgbWVzc2FnZSB0byBzdHJpbmcgaW4gaGV4YWRlY2ltYWwgZm9ybWF0LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSB7QnVmZmVyfFN0cmluZ30gbWVzc2FnZSB0byBzaWduXG4gICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgYXMgYSBoZXhhZGVjaW1hbCBzdHJpbmdcbiAgICovXG4gIHRvSGV4U3RyaW5nKG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG1lc3NhZ2UpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoJ2hleCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbWVzc2FnZWQgcGFzc2VkIHRvIHNpZ25NZXNzYWdlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNpZ24gbWVzc2FnZSB3aXRoIHByaXZhdGUga2V5XG4gICAqXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICovXG4gIGFzeW5jIHNpZ25NZXNzYWdlKGtleTogS2V5UGFpciwgbWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCB0b1NpZ24gPSB0aGlzLnRvSGV4U3RyaW5nKG1lc3NhZ2UpO1xuXG4gICAgbGV0IHBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0ga2V5LnBydjtcbiAgICBpZiAodGhpcy5pc1ZhbGlkWHBydihwcnYpKSB7XG4gICAgICBwcnYgPSBiaXAzMi5mcm9tQmFzZTU4KHBydikucHJpdmF0ZUtleT8udG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cblxuICAgIGlmICghcHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgbGV0IHNpZyA9IFV0aWxzLnNpZ25TdHJpbmcodG9TaWduLCBwcnYsIHRydWUpO1xuXG4gICAgLy8gcmVtb3ZlIHRoZSBwcmVjZWRpbmcgMHhcbiAgICBzaWcgPSBzaWcucmVwbGFjZSgvXjB4LywgJycpO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNpZywgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGFuIHhwdWIgdG8gYSB1bmNvbXByZXNzZWQgcHViXG4gICAqIEBwYXJhbSB4cHViXG4gICAqL1xuICB4cHViVG9VbmNvbXByZXNzZWRQdWIoeHB1Yjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZFhwdWIoeHB1YikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB4cHViJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGljS2V5ID0gYmlwMzIuZnJvbUJhc2U1OCh4cHViLCBuZXR3b3Jrcy5iaXRjb2luKS5wdWJsaWNLZXk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5wdWJsaWNLZXlDb252ZXJ0KHB1YmxpY0tleSwgZmFsc2UgLyogY29tcHJlc3NlZCAqLykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RpZnkgcHJlYnVpbGQgYmVmb3JlIHNlbmRpbmcgaXQgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGJ1aWxkUGFyYW1zIFRoZSB3aGl0ZWxpc3RlZCBwYXJhbWV0ZXJzIGZvciB0aGlzIHByZWJ1aWxkXG4gICAqL1xuICBhc3luYyBnZXRFeHRyYVByZWJ1aWxkUGFyYW1zKGJ1aWxkUGFyYW1zOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmIChidWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmRhdGEgJiYgYnVpbGRQYXJhbXMuZmVlTGltaXQpIHtcbiAgICAgIGJ1aWxkUGFyYW1zLnJlY2lwaWVudHNbMF0uZmVlTGltaXQgPSBidWlsZFBhcmFtcy5mZWVMaW1pdDtcbiAgICB9XG4gIH1cblxuICBwdWJUb0hleEFkZHJlc3MocHViOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJ5dGVBcnJheUFkZHIgPSBVdGlscy5nZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhwdWIpO1xuICAgIGNvbnN0IHJhd0FkZHJlc3MgPSBVdGlscy5nZXRSYXdBZGRyZXNzRnJvbVB1YktleShieXRlQXJyYXlBZGRyKTtcbiAgICByZXR1cm4gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CeXRlQXJyYXkocmF3QWRkcmVzcyk7XG4gIH1cblxuICB4cHJ2VG9Db21wcmVzc2VkUHJ2KHhwcnY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRYcHJ2KHhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgeHBydicpO1xuICAgIH1cblxuICAgIGNvbnN0IGhkTm9kZSA9IGJpcDMyLmZyb21CYXNlNTgoeHBydiwgbmV0d29ya3MuYml0Y29pbik7XG4gICAgaWYgKCFoZE5vZGUucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIHJldHVybiBoZE5vZGUucHJpdmF0ZUtleS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5UG9zdChxdWVyeTogeyBwYXRoOiBzdHJpbmc7IGpzb25PYmo6IGFueTsgbm9kZTogTm9kZVR5cGVzIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBub2RlVXJpID0gJyc7XG4gICAgc3dpdGNoIChxdWVyeS5ub2RlKSB7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5GdWxsOlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuZnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5Tb2xpZGl0eTpcbiAgICAgICAgbm9kZVVyaSA9IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0udHJvbk5vZGVzLnNvbGlkaXR5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSB0eXBlIG5vdCBmb3VuZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFxuICAgICAgLnBvc3Qobm9kZVVyaSArIHF1ZXJ5LnBhdGgpXG4gICAgICAudHlwZSgnanNvbicpXG4gICAgICAuc2VuZChxdWVyeS5qc29uT2JqKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWNoIFRyb24gbm9kZScpO1xuICAgIH1cblxuICAgIC8vIHVuZm9ydHVuYXRlbHksIGl0IGRvZXNuJ3QgbG9vayBsaWtlIG1vc3QgVFJPTiBub2RlcyByZXR1cm4gdmFsaWQganNvbiBhcyBib2R5XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcG9uc2UudGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5R2V0KHF1ZXJ5OiB7IHBhdGg6IHN0cmluZzsganNvbk9iajogYW55OyBub2RlOiBOb2RlVHlwZXMgfSk6IFByb21pc2U8YW55PiB7XG4gICAgbGV0IG5vZGVVcmkgPSAnJztcbiAgICBzd2l0Y2ggKHF1ZXJ5Lm5vZGUpIHtcbiAgICAgIGNhc2UgTm9kZVR5cGVzLkZ1bGw6XG4gICAgICAgIG5vZGVVcmkgPSBjb21tb24uRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLnRyb25Ob2Rlcy5mdWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTm9kZVR5cGVzLlNvbGlkaXR5OlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuc29saWRpdHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIHR5cGUgbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAuZ2V0KG5vZGVVcmkgKyBxdWVyeS5wYXRoKVxuICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgLnNlbmQocXVlcnkuanNvbk9iaik7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFjaCBUcm9uIG5vZGUnKTtcbiAgICB9XG5cbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBtb3N0IFRST04gbm9kZXMgcmV0dXJuIHZhbGlkIGpzb24gYXMgYm9keVxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJ5IG91ciBleHBsb3JlciBmb3IgdGhlIGJhbGFuY2Ugb2YgYW4gYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyB7U3RyaW5nfSB0aGUgYWRkcmVzcyBlbmNvZGVkIGluIGhleFxuICAgKiBAcmV0dXJucyB7QmlnTnVtYmVyfSBhZGRyZXNzIGJhbGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxBY2NvdW50UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeUdldCh7XG4gICAgICBwYXRoOiAnL3YxL2FjY291bnRzLycgKyBhZGRyZXNzLFxuICAgICAganNvbk9iajoge30sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb3VyIGJ1aWxkIHRyYW5zYWN0aW9uIGZyb20gYSBub2RlLlxuICAgKiBAcGFyYW0gdG9BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGZyb21BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRCdWlsZFRyYW5zYWN0aW9uKFxuICAgIHRvQWRkcjogc3RyaW5nLFxuICAgIGZyb21BZGRyOiBzdHJpbmcsXG4gICAgYW1vdW50OiBudW1iZXJcbiAgKTogUHJvbWlzZTxJbnRlcmZhY2UuVHJhbnNhY3Rpb25SZWNlaXB0PiB7XG4gICAgLy8gb3VyIGFkZHJlc3NlcyBzaG91bGQgYmUgYmFzZTU4LCB3ZSdsbCBoYXZlIHRvIGVuY29kZSB0byBoZXhcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvY3JlYXRldHJhbnNhY3Rpb24nLFxuICAgICAganNvbk9iajoge1xuICAgICAgICB0b19hZGRyZXNzOiB0b0FkZHIsXG4gICAgICAgIG93bmVyX2FkZHJlc3M6IGZyb21BZGRyLFxuICAgICAgICBhbW91bnQsXG4gICAgICB9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogc3RyaW5nLFxuICAgIGNvbnRyYWN0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyB0cmFuc2FjdGlvbjogSW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdCB9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25TZWxlY3RvciA9ICd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJztcbiAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50MjU2J107XG4gICAgY29uc3QgdmFsdWVzID0gW3RvQWRkciwgYW1vdW50XTtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBVdGlscy5lbmNvZGVEYXRhUGFyYW1zKHR5cGVzLCB2YWx1ZXMsICcnKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvdHJpZ2dlcnNtYXJ0Y29udHJhY3QnLFxuICAgICAganNvbk9iajoge1xuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgY29udHJhY3RfYWRkcmVzczogY29udHJhY3RBZGRyLFxuICAgICAgICBmdW5jdGlvbl9zZWxlY3RvcjogZnVuY3Rpb25TZWxlY3RvcixcbiAgICAgICAgcGFyYW1ldGVyOiBwYXJhbWV0ZXIsXG4gICAgICAgIGZlZV9saW1pdDogMTAwMDAwMDAwLFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBhbnkga2V5cyBpbiB0aGUgb3duZXJLZXlzIGNvbGxlY3Rpb24gZG9uJ3QgbWF0Y2ggdGhlIGtleXMgYXJyYXkgd2UgcGFzc1xuICAgKiBAcGFyYW0gb3duZXJLZXlzXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjaGVja1Blcm1pc3Npb25zKG93bmVyS2V5czogeyBhZGRyZXNzOiBzdHJpbmc7IHdlaWdodDogbnVtYmVyIH1bXSwga2V5czogc3RyaW5nW10pIHtcbiAgICBrZXlzID0ga2V5cy5tYXAoKGspID0+IGsudG9VcHBlckNhc2UoKSk7XG5cbiAgICBvd25lcktleXMubWFwKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGhleEtleSA9IGtleS5hZGRyZXNzLnRvVXBwZXJDYXNlKCk7XG4gICAgICBpZiAoIWtleXMuaW5jbHVkZXMoaGV4S2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHB1YiBhZGRyZXNzICR7aGV4S2V5fSBub3QgZm91bmQgaW4gYWNjb3VudGApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LndlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ293bmVyIHBlcm1pc3Npb24gaXMgaW52YWxpZCBmb3IgdGhpcyBzdHJ1Y3R1cmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvLlxuICAgKiBXZSBuZWVkIHRvIGRvIHRocmVlIHF1ZXJpZXMgZHVyaW5nIHRoaXM6XG4gICAqIDEpIE5vZGUgcXVlcnkgLSBob3cgbXVjaCBtb25leSBpcyBpbiB0aGUgYWNjb3VudFxuICAgKiAyKSBCdWlsZCB0cmFuc2FjdGlvbiAtIGJ1aWxkIG91ciB0cmFuc2FjdGlvbiBmb3IgdGhlIGFtb3VudFxuICAgKiAzKSBTZW5kIHNpZ25lZCBidWlsZCAtIHNlbmQgb3VyIHNpZ25lZCBidWlsZCB0byBhIHB1YmxpYyBub2RlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpc0tyc1JlY292ZXJ5ID0gZ2V0SXNLcnNSZWNvdmVyeShwYXJhbXMpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IGdldElzVW5zaWduZWRTd2VlcChwYXJhbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgLy8gZ2V0IG91ciB1c2VyLCBiYWNrdXAga2V5c1xuICAgIGNvbnN0IGtleXMgPSBnZXRCaXAzMktleXModGhpcy5iaXRnbywgcGFyYW1zLCB7IHJlcXVpcmVCaXRHb1hwdWI6IGZhbHNlIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBkZWNvZGUgb3VyIGJpdGdvS2V5IHRvIGEgYmFzZTU4IGFkZHJlc3NcbiAgICBjb25zdCBiaXRnb0hleEFkZHIgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1YihwYXJhbXMuYml0Z29LZXkpKTtcbiAgICBjb25zdCByZWNvdmVyeUFkZHJlc3NIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuXG4gICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZVxuICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlc0Zyb21Ob2RlKFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KGJpdGdvSGV4QWRkcikpO1xuICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG5cbiAgICBjb25zdCB1c2VyWFB1YiA9IGtleXNbMF0ubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IHVzZXJYUHJ2ID0ga2V5c1swXS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IGJhY2t1cFhQdWIgPSBrZXlzWzFdLm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcblxuICAgIC8vIGZpcnN0IGNvbnN0cnVjdCB0b2tlbiB0eG5zXG4gICAgY29uc3QgdG9rZW5UeG5zOiBhbnkgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRva2VuIG9mIGFjY291bnQuZGF0YVswXS50cmMyMCkge1xuICAgICAgLy8gbWFpbm5ldCB0b2tlbnNcbiAgICAgIGlmICh0b2tlbi5URWt4aVRlaG56U21TZTJYcXJCajR3MzJSVU45NjZyZHo4KSB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuLlRFa3hpVGVobnpTbVNlMlhxckJqNHczMlJVTjk2NnJkejg7XG4gICAgICAgIGNvbnN0IGNvbnRyYWN0QWRkciA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcygnVEVreGlUZWhuelNtU2UyWHFyQmo0dzMyUlVOOTY2cmR6OCcpO1xuICAgICAgICB0b2tlblR4bnMucHVzaChcbiAgICAgICAgICAoYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKHJlY292ZXJ5QWRkcmVzc0hleCwgYml0Z29IZXhBZGRyLCBhbW91bnQsIGNvbnRyYWN0QWRkcikpXG4gICAgICAgICAgICAudHJhbnNhY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFI3TkhxamVLUXhHVENpOHE4Wlk0cEw4b3RTemdqTGo2dCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UUjdOSHFqZUtReEdUQ2k4cThaWTRwTDhvdFN6Z2pMajZ0O1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RSN05IcWplS1F4R1RDaThxOFpZNHBMOG90U3pnakxqNnQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gdGVzdG5ldCB0b2tlbnNcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFNkWndOcXBIb2Z6UDZCc0JLR1FVV2RCZUpwaExtRjZpZCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UU2Rad05xcEhvZnpQNkJzQktHUVVXZEJlSnBoTG1GNmlkO1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RTZFp3TnFwSG9melA2QnNCS0dRVVdkQmVKcGhMbUY2aWQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHRva2VuLlRHM1hYeUV4QmtQcDluemRhakRac296RXU0QmthU0pvenMpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gdG9rZW4uVEczWFh5RXhCa1BwOW56ZGFqRFpzb3pFdTRCa2FTSm96cztcbiAgICAgICAgY29uc3QgY29udHJhY3RBZGRyID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKCdURzNYWHlFeEJrUHA5bnpkYWpEWnNvekV1NEJrYVNKb3pzJyk7XG4gICAgICAgIHRva2VuVHhucy5wdXNoKFxuICAgICAgICAgIChhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIGFtb3VudCwgY29udHJhY3RBZGRyKSlcbiAgICAgICAgICAgIC50cmFuc2FjdGlvblxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHR4IC1cbiAgICAvLyB0aGVyZSdzIGFuIGFzc3VtcHRpb24gaGVyZSBiZWluZyBtYWRlIGFib3V0IGZlZXM6IGZvciBhIHdhbGxldCB0aGF0IGhhc24ndCBiZWVuIHVzZWQgaW4gYXdoaWxlLCB0aGUgaW1wbGljYXRpb24gaXNcbiAgICAvLyBpdCBoYXMgbWF4aW11bSBiYW5kd2lkdGguIHRodXMsIGEgcmVjb3Zlcnkgc2hvdWxkIGNvc3QgdGhlIG1pbmltdW0gYW1vdW50ICgxZTYgc3VuIG9yIDEgVHJvbilcbiAgICBpZiAoTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFID4gcmVjb3ZlcnlBbW91bnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgd291bGRudCBiZSBhYmxlIHRvIGZ1bmQgYSBzZW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5SGV4QWRkcmVzc2VzID0gW1xuICAgICAgdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIodXNlclhQdWIpKSxcbiAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJhY2t1cFhQdWIpKSxcbiAgICAgIGJpdGdvSGV4QWRkcixcbiAgICBdO1xuXG4gICAgLy8gcnVuIGNoZWNrcyB0byBlbnN1cmUgdGhpcyBpcyBhIHZhbGlkIHR4IC0gcGVybWlzc2lvbnMgbWF0Y2ggb3VyIHNpZ25lciBrZXlzXG4gICAgY29uc3Qgb3duZXJLZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLm93bmVyX3Blcm1pc3Npb24ua2V5cykge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyhrZXkuYWRkcmVzcyk7XG4gICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgb3duZXJLZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZVBlcm1pc3Npb25LZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLmFjdGl2ZV9wZXJtaXNzaW9uWzBdLmtleXMpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5LndlaWdodDtcbiAgICAgIGFjdGl2ZVBlcm1pc3Npb25LZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgdGhpcy5jaGVja1Blcm1pc3Npb25zKGFjdGl2ZVBlcm1pc3Npb25LZXlzLCBrZXlIZXhBZGRyZXNzZXMpO1xuXG4gICAgLy8gYnVpbGQgYW5kIHNpZ24gdG9rZW4gdHhuc1xuICAgIGNvbnN0IGZpbmFsVG9rZW5UeHM6IGFueSA9IFtdO1xuICAgIGZvciAoY29uc3QgdG9rZW5UeG4gb2YgdG9rZW5UeG5zKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0b2tlblR4bik7XG5cbiAgICAgIC8vIHRoaXMgdHggc2hvdWxkIGJlIGVub3VnaCB0byBkcm9wIGludG8gYSBub2RlXG4gICAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICAgIGZpbmFsVG9rZW5UeHMucHVzaCgoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXJQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYodXNlclhQcnYpO1xuXG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgICAgaWYgKCFpc0tyc1JlY292ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogYmFja3VwUHJ2IH0pO1xuICAgICAgfVxuICAgICAgZmluYWxUb2tlblR4cy5wdXNoKChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCkpO1xuICAgIH1cblxuICAgIC8vIHRva2VucyBtdXN0IGJlIHJlY292ZXJlZCBiZWZvcmUgdGhlIG5hdGl2ZSBhc3NldCwgc28gdGhhdCB0aGVyZSBpcyBzdWZmaWNpZW50IG9mIHRoZSBuYXRpdmUgYXNzZXQgdG8gY292ZXIgZmVlc1xuICAgIGlmIChmaW5hbFRva2VuVHhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRva2VuVHhzOiBmaW5hbFRva2VuVHhzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZWNvdmVyeUFtb3VudE1pbnVzRmVlcyA9IHJlY292ZXJ5QW1vdW50IC0gTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFO1xuICAgIGNvbnN0IGJ1aWxkVHggPSBhd2FpdCB0aGlzLmdldEJ1aWxkVHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzKTtcblxuICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuXG4gICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eDogKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0pzb24oKSxcbiAgICAgICAgcmVjb3ZlcnlBbW91bnQ6IHJlY292ZXJ5QW1vdW50TWludXNGZWVzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJYUHJ2KTtcblxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuXG4gICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgIGlmICghaXNLcnNSZWNvdmVyeSkge1xuICAgICAgY29uc3QgYmFja3VwWFBydiA9IGtleXNbMV0udG9CYXNlNTgoKTtcbiAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGJhY2t1cFBydiB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHg6IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCksXG4gICAgICByZWNvdmVyeUFtb3VudDogcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgVHJvbiB0cmFuc2FjdGlvbiBmcm9tIHR4SGV4XG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgY29uc3QgdHhIZXggPSBwYXJhbXMudHhIZXggfHwgKHBhcmFtcy5oYWxmU2lnbmVkICYmIHBhcmFtcy5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICBpZiAoIXR4SGV4IHx8ICFwYXJhbXMuZmVlSW5mbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH1cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAge1xuICAgICAgICBhbW91bnQ6IHR4Lm91dHB1dHNbMF0udmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgYWRkcmVzczogdHgub3V0cHV0c1swXS5hZGRyZXNzLCAvLyBTaG91bGQgdHVybiBpdCBpbnRvIGEgcmVhZGFibGUgZm9ybWF0LCBha2EgYmFzZTU4XG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAnaWQnLFxuICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICdvdXRwdXRzJyxcbiAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICdmZWUnLFxuICAgICAgJ3RpbWVzdGFtcCcsXG4gICAgICAnZXhwaXJhdGlvbicsXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICBpZDogdHguaWQsXG4gICAgICBvdXRwdXRzLFxuICAgICAgb3V0cHV0QW1vdW50OiBvdXRwdXRzWzBdLmFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLCAvLyBhY2NvdW50IGJhc2VkIGRvZXMgbm90IHVzZSBjaGFuZ2Ugb3V0cHV0c1xuICAgICAgY2hhbmdlQW1vdW50OiAnMCcsIC8vIGFjY291bnQgYmFzZSBkb2VzIG5vdCBtYWtlIGNoYW5nZVxuICAgICAgZmVlOiBwYXJhbXMuZmVlSW5mbyxcbiAgICAgIHRpbWVzdGFtcDogdHgudmFsaWRGcm9tLFxuICAgICAgZXhwaXJhdGlvbjogdHgudmFsaWRUbyxcbiAgICB9O1xuICB9XG59XG4iXX0=
734
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7R0FFRztBQUNILHFEQUF1QztBQUN2QyxtQ0FBcUM7QUFFckMscURBQThDO0FBQzlDLG9EQUFzQztBQUN0QyxtREFzQjhCO0FBQzlCLCtCQUF5RDtBQUN6RCwyQ0FBMkM7QUFFM0MsbUNBQWdEO0FBRW5DLFFBQUEsaUNBQWlDLEdBQUcsR0FBRyxDQUFDO0FBQ3hDLFFBQUEseUJBQXlCLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLHdFQUF3RTtBQUMvRyxRQUFBLCtCQUErQixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyx3RUFBd0U7QUFDckgsUUFBQSwwQkFBMEIsR0FBRyxRQUFRLENBQUMsQ0FBQyxVQUFVO0FBQ2pELFFBQUEsbUJBQW1CLEdBQUcsRUFBRSxDQUFDLENBQUMsd0RBQXdEO0FBOEUvRixJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIseUNBQUksQ0FBQTtJQUNKLGlEQUFRLENBQUE7QUFDVixDQUFDLEVBSFcsU0FBUyx5QkFBVCxTQUFTLFFBR3BCO0FBU0QsTUFBYSxHQUFJLFNBQVEsbUJBQVE7SUFHL0IsWUFBWSxLQUFnQixFQUFFLFdBQXVDO1FBQ25FLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUViLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsV0FBVyxDQUFDO0lBQ2xDLENBQUM7SUFFRCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztJQUNoQyxDQUFDO0lBRUQsU0FBUztRQUNQLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxN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LFlBQVk7WUFDWixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUU7WUFDVCxPQUFPO1lBQ1AsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNO1lBQy9CLGFBQWEsRUFBRSxFQUFFLEVBQUUsNENBQTRDO1lBQy9ELFlBQVksRUFBRSxHQUFHLEVBQUUsb0NBQW9DO1lBQ3ZELEdBQUcsRUFBRSxNQUFNLENBQUMsT0FBTztZQUNuQixTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVM7WUFDdkIsVUFBVSxFQUFFLEVBQUUsQ0FBQyxPQUFPO1NBQ3ZCLENBQUM7SUFDSixDQUFDO0NBQ0Y7QUFyeEJELGtCQXF4QkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICovXG5pbXBvcnQgKiBhcyBzZWNwMjU2azEgZnJvbSAnc2VjcDI1NmsxJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IENvaW5GYW1pbHksIEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7XG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIGNvbW1vbixcbiAgZ2V0QmlwMzJLZXlzLFxuICBnZXRJc0tyc1JlY292ZXJ5LFxuICBnZXRJc1Vuc2lnbmVkU3dlZXAsXG4gIEtleVBhaXIsXG4gIE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIFRyYW5zYWN0aW9uRmVlLFxuICBUcmFuc2FjdGlvblByZWJ1aWxkIGFzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkLFxuICBUcmFuc2FjdGlvblJlY2lwaWVudCBhcyBSZWNpcGllbnQsXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIEJhc2VUcmFuc2FjdGlvbixcbiAgTXVsdGlzaWdUeXBlLFxuICBtdWx0aXNpZ1R5cGVzLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBJbnRlcmZhY2UsIFV0aWxzLCBXcmFwcGVkQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2xpYi9idWlsZGVyJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uUmVjZWlwdCB9IGZyb20gJy4vbGliL2lmYWNlJztcbmltcG9ydCB7IGlzSW50ZWdlciwgaXNVbmRlZmluZWQgfSBmcm9tICdsb2Rhc2gnO1xuXG5leHBvcnQgY29uc3QgTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFID0gMWU2O1xuZXhwb3J0IGNvbnN0IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUgPSAyLjEgKiAxZTY7IC8vIFRST04gZm91bmRhdGlvbiByZWNvbW1lbmRzIDIuMSBUUlggYXMgZmVlcyBmb3IgZ3VhcmFudGVlZCB0cmFuc2FjdGlvblxuZXhwb3J0IGNvbnN0IFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUgPSAxMDAgKiAxZTY7IC8vIFRST04gZm91bmRhdGlvbiByZWNvbW1lbmRzIDEwMCBUUlggYXMgZmVlcyBmb3IgZ3VhcmFudGVlZCB0cmFuc2FjdGlvblxuZXhwb3J0IGNvbnN0IFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZID0gODY0MDAwMDA7IC8vIDI0IGhvdXJcbmV4cG9ydCBjb25zdCBERUZBVUxUX1NDQU5fRkFDVE9SID0gMjA7IC8vIGRlZmF1bHQgbnVtYmVyIG9mIHJlY2VpdmUgYWRkcmVzc2VzIHRvIHNjYW4gZm9yIGZ1bmRzXG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBTaWduVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcHJ2OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHhJbmZvIHtcbiAgcmVjaXBpZW50czogUmVjaXBpZW50W107XG4gIGZyb206IHN0cmluZztcbiAgdHhpZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZHJlc3NJbmZvIHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjaGFpbjogbnVtYmVyO1xuICBpbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIGV4cGlyYXRpb246IG51bWJlcjtcbiAgdGltZXN0YW1wOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25QcmVidWlsZCBleHRlbmRzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgdHhJbmZvOiBUeEluZm87XG4gIGFkZHJlc3NJbmZvPzogQWRkcmVzc0luZm87XG4gIGZlZUluZm86IFRyYW5zYWN0aW9uRmVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEhleD86IHN0cmluZzsgLy8gdHhIZXggaXMgcG9vcmx5IG5hbWVkIGhlcmU7IGl0IGlzIGp1c3QgYSB3cmFwcGVkIEpTT04gb2JqZWN0XG4gIGhhbGZTaWduZWQ/OiB7XG4gICAgdHhIZXg6IHN0cmluZzsgLy8gdHhIZXggaXMgcG9vcmx5IG5hbWVkIGhlcmU7IGl0IGlzIGp1c3QgYSB3cmFwcGVkIEpTT04gb2JqZWN0XG4gIH07XG4gIGZlZUluZm86IFRyYW5zYWN0aW9uRmVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJ5T3B0aW9ucyB7XG4gIHVzZXJLZXk6IHN0cmluZzsgLy8gQm94IEFcbiAgYmFja3VwS2V5OiBzdHJpbmc7IC8vIEJveCBCXG4gIGJpdGdvS2V5OiBzdHJpbmc7IC8vIEJveCBDIC0gdGhpcyBpcyBiaXRnbydzIHhwdWIgYW5kIHdpbGwgYmUgdXNlZCB0byBkZXJpdmUgdGhlaXIgcm9vdCBhZGRyZXNzXG4gIHJlY292ZXJ5RGVzdGluYXRpb246IHN0cmluZzsgLy8gYmFzZTU4IGFkZHJlc3NcbiAga3JzUHJvdmlkZXI/OiBzdHJpbmc7XG4gIHRva2VuQ29udHJhY3RBZGRyZXNzPzogc3RyaW5nO1xuICB3YWxsZXRQYXNzcGhyYXNlPzogc3RyaW5nO1xuICBzdGFydGluZ1NjYW5JbmRleD86IG51bWJlcjtcbiAgc2Nhbj86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nO1xuICBiYWNrdXBLZXk6IHN0cmluZztcbiAgYml0Z29LZXk6IHN0cmluZztcbiAgdG9rZW5Db250cmFjdEFkZHJlc3M/OiBzdHJpbmc7XG4gIHN0YXJ0aW5nU2NhbkluZGV4PzogbnVtYmVyOyAvLyBkZWZhdWx0IHRvIDEgKGluY2x1c2l2ZSlcbiAgZW5kaW5nU2NhbkluZGV4PzogbnVtYmVyOyAvLyBkZWZhdWx0IHRvIHN0YXJ0aW5nU2NhbkluZGV4ICsgMjAgKGV4Y2x1c2l2ZSlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25zb2xpZGF0aW9uUmVjb3ZlcnlCYXRjaCB7XG4gIHRyYW5zYWN0aW9uczogUmVjb3ZlcnlUcmFuc2FjdGlvbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZlZUluZm8ge1xuICBmZWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeVRyYW5zYWN0aW9uIHtcbiAgdHhIZXg/OiBzdHJpbmc7XG4gIGZlZUluZm8/OiBGZWVJbmZvO1xuICBjb2luPzogc3RyaW5nO1xuICB0eD86IFRyYW5zYWN0aW9uUHJlYnVpbGQ7XG4gIHJlY292ZXJ5QW1vdW50PzogbnVtYmVyO1xuICB0b2tlblR4cz86IFRyYW5zYWN0aW9uUmVjZWlwdFtdO1xuICBhZGRyZXNzSW5mbz86IEFkZHJlc3NJbmZvO1xufVxuXG5leHBvcnQgZW51bSBOb2RlVHlwZXMge1xuICBGdWxsLFxuICBTb2xpZGl0eSxcbn1cblxuLyoqXG4gKiBUaGlzIHN0cnVjdHVyZSBpcyBub3QgYSBjb21wbGV0ZSBtb2RlbCBvZiB0aGUgQWNjb3VudFJlc3BvbnNlIGZyb20gYSBub2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjY291bnRSZXNwb25zZSB7XG4gIGRhdGE6IFtJbnRlcmZhY2UuQWNjb3VudEluZm9dO1xufVxuXG5leHBvcnQgY2xhc3MgVHJ4IGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuXG4gIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgZ2V0Q2hhaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICBnZXRGYW1pbHkoKTogQ29pbkZhbWlseSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZhbWlseTtcbiAgfVxuXG4gIGdldEZ1bGxOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mdWxsTmFtZTtcbiAgfVxuXG4gIGdldEJhc2VGYWN0b3IoKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGF0aWNzQ29pbi5kZWNpbWFsUGxhY2VzKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB0cmFuc2FjdGlvbkRhdGFBbGxvd2VkKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIHtAaW5oZXJpdERvYyB9ICoqL1xuICBzdXBwb3J0c011bHRpc2lnKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgZ2V0RGVmYXVsdE11bHRpc2lnVHlwZSgpOiBNdWx0aXNpZ1R5cGUge1xuICAgIHJldHVybiBtdWx0aXNpZ1R5cGVzLm9uY2hhaW47XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSwgc3RhdGljc0NvaW4/OiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+KTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgVHJ4KGJpdGdvLCBzdGF0aWNzQ29pbik7XG4gIH1cblxuICAvKipcbiAgICogRmxhZyBmb3Igc2VuZGluZyB2YWx1ZSBvZiAwXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG9rYXkgdG8gc2VuZCAwIHZhbHVlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIHZhbHVlbGVzc1RyYW5zZmVyQWxsb3dlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBhbGxvd3NBY2NvdW50Q29uc29saWRhdGlvbnMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoaXMgaXMgYSB2YWxpZCBiYXNlNThcbiAgICogQHBhcmFtIGFkZHJlc3NcbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghYWRkcmVzcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBVdGlscy5pc0Jhc2U1OEFkZHJlc3MoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoaXMgaXMgYSB2YWxpZCBoZXggYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyBoZXggYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEhleEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIC9eNDFbMC05YS1mXXs0MH0kL2kudGVzdChhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBlZDI1NTE5IGtleSBwYWlyXG4gICAqXG4gICAqIEBwYXJhbSBzZWVkXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IG9iamVjdCB3aXRoIGdlbmVyYXRlZCBwdWIsIHBydlxuICAgKi9cbiAgZ2VuZXJhdGVLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICAvLyBUT0RPOiBtb3ZlIHRoaXMgYW5kIGFkZHJlc3MgY3JlYXRpb24gbG9naWMgdG8gYWNjb3VudC1saWJcbiAgICBpZiAoIXNlZWQpIHtcbiAgICAgIC8vIEFuIGV4dGVuZGVkIHByaXZhdGUga2V5IGhhcyBib3RoIGEgbm9ybWFsIDI1NiBiaXQgcHJpdmF0ZSBrZXkgYW5kIGEgMjU2IGJpdCBjaGFpbiBjb2RlLCBib3RoIG9mIHdoaWNoIG11c3QgYmVcbiAgICAgIC8vIHJhbmRvbS4gNTEyIGJpdHMgaXMgdGhlcmVmb3JlIHRoZSBtYXhpbXVtIGVudHJvcHkgYW5kIGdpdmVzIHVzIG1heGltdW0gc2VjdXJpdHkgYWdhaW5zdCBjcmFja2luZy5cbiAgICAgIHNlZWQgPSByYW5kb21CeXRlcyg1MTIgLyA4KTtcbiAgICB9XG4gICAgY29uc3QgaGQgPSBiaXAzMi5mcm9tU2VlZChzZWVkKTtcbiAgICByZXR1cm4ge1xuICAgICAgcHViOiBoZC5uZXV0ZXJlZCgpLnRvQmFzZTU4KCksXG4gICAgICBwcnY6IGhkLnRvQmFzZTU4KCksXG4gICAgfTtcbiAgfVxuXG4gIGlzVmFsaWRYcHViKHhwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYmlwMzIuZnJvbUJhc2U1OCh4cHViKS5pc05ldXRlcmVkKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlzVmFsaWRQdWIocHViOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5pc1ZhbGlkWHB1YihwdWIpKSB7XG4gICAgICAvLyB4cHVicyBjYW4gYmUgY29udmVydGVkIGludG8gcmVndWxhciBwdWJzLCBzbyB0ZWNobmljYWxseSBpdCBpcyBhIHZhbGlkIHB1YlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUmVnRXhwKCdeMDRbYS16QS1aMC05XXsxMjh9JCcpLnRlc3QocHViKTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBhc3luYyBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRocm93IG5ldyBNZXRob2ROb3RJbXBsZW1lbnRlZEVycm9yKCk7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERlcml2ZSBhIHVzZXIga2V5IHVzaW5nIHRoZSBjaGFpbiBwYXRoIG9mIHRoZSBhZGRyZXNzXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHBhcmFtIHBhdGhcbiAgICogQHJldHVybnMge3N0cmluZ30gZGVyaXZlZCBwcml2YXRlIGtleVxuICAgKi9cbiAgZGVyaXZlS2V5V2l0aFBhdGgoeyBrZXksIHBhdGggfTogeyBrZXk6IHN0cmluZzsgcGF0aDogc3RyaW5nIH0pOiBzdHJpbmcge1xuICAgIGNvbnN0IGtleWNoYWluID0gYmlwMzIuZnJvbUJhc2U1OChrZXkpO1xuICAgIGNvbnN0IGRlcml2ZWRLZXlOb2RlID0ga2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKTtcbiAgICByZXR1cm4gZGVyaXZlZEtleU5vZGUudG9CYXNlNTgoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NlbWJsZSBrZXljaGFpbiBhbmQgaGFsZi1zaWduIHByZWJ1aWx0IHRyYW5zYWN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy50eFByZWJ1aWxkIHtPYmplY3R9IHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBwbGF0Zm9ybVxuICAgKiBAcGFyYW0gcGFyYW1zLnBydiB7U3RyaW5nfSB1c2VyIHBydlxuICAgKiBAcmV0dXJucyBCbHVlYmlyZDxTaWduZWRUcmFuc2FjdGlvbj5cbiAgICovXG4gIGFzeW5jIHNpZ25UcmFuc2FjdGlvbihwYXJhbXM6IFRyb25TaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIodGhpcy5nZXRDaGFpbigpKS5mcm9tKHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4KTtcblxuICAgIGxldCBrZXk7XG4gICAgY29uc3QgeyBjaGFpbiwgaW5kZXggfSA9IHBhcmFtcy50eFByZWJ1aWxkPy5hZGRyZXNzSW5mbyA/PyB7IGNoYWluOiAwLCBpbmRleDogMCB9O1xuICAgIGlmIChjaGFpbiA9PT0gMCAmJiBpbmRleCA9PT0gMCkge1xuICAgICAga2V5ID0gcGFyYW1zLnBydjtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBgMC8wLyR7Y2hhaW59LyR7aW5kZXh9YDtcbiAgICAgIGtleSA9IHRoaXMuZGVyaXZlS2V5V2l0aFBhdGgoeyBrZXk6IHBhcmFtcy5wcnYsIHBhdGg6IGRlcml2YXRpb25QYXRoIH0pO1xuICAgIH1cbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleSB9KTtcblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICB0eEhleDogSlNPTi5zdHJpbmdpZnkodHJhbnNhY3Rpb24udG9Kc29uKCkpLFxuICAgIH07XG4gICAgaWYgKHRyYW5zYWN0aW9uLnRvSnNvbigpLnNpZ25hdHVyZS5sZW5ndGggPj0gMikge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgIH1cbiAgICAvLyBIYWxmIHNpZ25lZCB0cmFuc2FjdGlvblxuICAgIHJldHVybiB7XG4gICAgICBoYWxmU2lnbmVkOiByZXNwb25zZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciBpbnB1dCBpcyB2YWxpZCBzZWVkIGZvciB0aGUgY29pblxuICAgKlxuICAgKiBAcGFyYW0gcHJ2IC0gdGhlIHBydiB0byBiZSBjaGVja2VkXG4gICAqL1xuICBpc1ZhbGlkWHBydihwcnY6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gIWJpcDMyLmZyb21CYXNlNTgocHJ2KS5pc05ldXRlcmVkKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBtZXNzYWdlIHRvIHN0cmluZyBpbiBoZXhhZGVjaW1hbCBmb3JtYXQuXG4gICAqXG4gICAqIEBwYXJhbSBtZXNzYWdlIHtCdWZmZXJ8U3RyaW5nfSBtZXNzYWdlIHRvIHNpZ25cbiAgICogQHJldHVybiB0aGUgbWVzc2FnZSBhcyBhIGhleGFkZWNpbWFsIHN0cmluZ1xuICAgKi9cbiAgdG9IZXhTdHJpbmcobWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogc3RyaW5nIHtcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20obWVzc2FnZSkudG9TdHJpbmcoJ2hleCcpO1xuICAgIH0gZWxzZSBpZiAoQnVmZmVyLmlzQnVmZmVyKG1lc3NhZ2UpKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZS50b1N0cmluZygnaGV4Jyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtZXNzYWdlZCBwYXNzZWQgdG8gc2lnbk1lc3NhZ2UnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2lnbiBtZXNzYWdlIHdpdGggcHJpdmF0ZSBrZXlcbiAgICpcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKi9cbiAgYXN5bmMgc2lnbk1lc3NhZ2Uoa2V5OiBLZXlQYWlyLCBtZXNzYWdlOiBzdHJpbmcgfCBCdWZmZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGNvbnN0IHRvU2lnbiA9IHRoaXMudG9IZXhTdHJpbmcobWVzc2FnZSk7XG5cbiAgICBsZXQgcHJ2OiBzdHJpbmcgfCB1bmRlZmluZWQgPSBrZXkucHJ2O1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHJ2KHBydikpIHtcbiAgICAgIHBydiA9IGJpcDMyLmZyb21CYXNlNTgocHJ2KS5wcml2YXRlS2V5Py50b1N0cmluZygnaGV4Jyk7XG4gICAgfVxuXG4gICAgaWYgKCFwcnYpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICBsZXQgc2lnID0gVXRpbHMuc2lnblN0cmluZyh0b1NpZ24sIHBydiwgdHJ1ZSk7XG5cbiAgICAvLyByZW1vdmUgdGhlIHByZWNlZGluZyAweFxuICAgIHNpZyA9IHNpZy5yZXBsYWNlKC9eMHgvLCAnJyk7XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20oc2lnLCAnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYW4geHB1YiB0byBhIHVuY29tcHJlc3NlZCBwdWJcbiAgICogQHBhcmFtIHhwdWJcbiAgICovXG4gIHhwdWJUb1VuY29tcHJlc3NlZFB1Yih4cHViOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkWHB1Yih4cHViKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHhwdWInKTtcbiAgICB9XG5cbiAgICBjb25zdCBwdWJsaWNLZXkgPSBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLnB1YmxpY0tleTtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oc2VjcDI1NmsxLnB1YmxpY0tleUNvbnZlcnQocHVibGljS2V5LCBmYWxzZSAvKiBjb21wcmVzc2VkICovKSkudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vZGlmeSBwcmVidWlsZCBiZWZvcmUgc2VuZGluZyBpdCB0byB0aGUgc2VydmVyLlxuICAgKiBAcGFyYW0gYnVpbGRQYXJhbXMgVGhlIHdoaXRlbGlzdGVkIHBhcmFtZXRlcnMgZm9yIHRoaXMgcHJlYnVpbGRcbiAgICovXG4gIGFzeW5jIGdldEV4dHJhUHJlYnVpbGRQYXJhbXMoYnVpbGRQYXJhbXM6IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKGJ1aWxkUGFyYW1zLnJlY2lwaWVudHNbMF0uZGF0YSAmJiBidWlsZFBhcmFtcy5mZWVMaW1pdCkge1xuICAgICAgYnVpbGRQYXJhbXMucmVjaXBpZW50c1swXS5mZWVMaW1pdCA9IGJ1aWxkUGFyYW1zLmZlZUxpbWl0O1xuICAgIH1cbiAgfVxuXG4gIHB1YlRvSGV4QWRkcmVzcyhwdWI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgYnl0ZUFycmF5QWRkciA9IFV0aWxzLmdldEJ5dGVBcnJheUZyb21IZXhBZGRyZXNzKHB1Yik7XG4gICAgY29uc3QgcmF3QWRkcmVzcyA9IFV0aWxzLmdldFJhd0FkZHJlc3NGcm9tUHViS2V5KGJ5dGVBcnJheUFkZHIpO1xuICAgIHJldHVybiBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJ5dGVBcnJheShyYXdBZGRyZXNzKTtcbiAgfVxuXG4gIHhwcnZUb0NvbXByZXNzZWRQcnYoeHBydjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZFhwcnYoeHBydikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB4cHJ2Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgaGROb2RlID0gYmlwMzIuZnJvbUJhc2U1OCh4cHJ2KTtcbiAgICBpZiAoIWhkTm9kZS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgcmV0dXJuIGhkTm9kZS5wcml2YXRlS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Tm9kZVVybChub2RlOiBOb2RlVHlwZXMpOiBzdHJpbmcge1xuICAgIHN3aXRjaCAobm9kZSkge1xuICAgICAgY2FzZSBOb2RlVHlwZXMuRnVsbDpcbiAgICAgICAgcmV0dXJuIGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0udHJvbk5vZGVzLmZ1bGw7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5Tb2xpZGl0eTpcbiAgICAgICAgcmV0dXJuIGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0udHJvbk5vZGVzLnNvbGlkaXR5O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIHR5cGUgbm90IGZvdW5kJyk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBNYWtlIGEgcXVlcnkgdG8gVHJvbmdyaWQgZm9yIGluZm9ybWF0aW9uIHN1Y2ggYXMgYmFsYW5jZSwgdG9rZW4gYmFsYW5jZSwgc29saWRpdHkgY2FsbHNcbiAgICogQHBhcmFtIHF1ZXJ5IHtPYmplY3R9IGtleS12YWx1ZSBwYWlycyBvZiBwYXJhbWV0ZXJzIHRvIGFwcGVuZCBhZnRlciAvYXBpXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IHJlc3BvbnNlIGZyb20gVHJvbmdyaWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVjb3ZlcnlQb3N0KHF1ZXJ5OiB7IHBhdGg6IHN0cmluZzsganNvbk9iajogYW55OyBub2RlOiBOb2RlVHlwZXMgfSk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3Qgbm9kZVVyaSA9IHRoaXMuZ2V0Tm9kZVVybChxdWVyeS5ub2RlKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFxuICAgICAgLnBvc3Qobm9kZVVyaSArIHF1ZXJ5LnBhdGgpXG4gICAgICAudHlwZSgnanNvbicpXG4gICAgICAuc2VuZChxdWVyeS5qc29uT2JqKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWNoIFRyb24gbm9kZScpO1xuICAgIH1cblxuICAgIC8vIHVuZm9ydHVuYXRlbHksIGl0IGRvZXNuJ3QgbG9vayBsaWtlIG1vc3QgVFJPTiBub2RlcyByZXR1cm4gdmFsaWQganNvbiBhcyBib2R5XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcG9uc2UudGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5R2V0KHF1ZXJ5OiB7IHBhdGg6IHN0cmluZzsganNvbk9iajogYW55OyBub2RlOiBOb2RlVHlwZXMgfSk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3Qgbm9kZVVyaSA9IHRoaXMuZ2V0Tm9kZVVybChxdWVyeS5ub2RlKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFxuICAgICAgLmdldChub2RlVXJpICsgcXVlcnkucGF0aClcbiAgICAgIC50eXBlKCdqc29uJylcbiAgICAgIC5zZW5kKHF1ZXJ5Lmpzb25PYmopO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhY2ggVHJvbiBub2RlJyk7XG4gICAgfVxuXG4gICAgLy8gdW5mb3J0dW5hdGVseSwgaXQgZG9lc24ndCBsb29rIGxpa2UgbW9zdCBUUk9OIG5vZGVzIHJldHVybiB2YWxpZCBqc29uIGFzIGJvZHlcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZXNwb25zZS50ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBRdWVyeSBvdXIgZXhwbG9yZXIgZm9yIHRoZSBiYWxhbmNlIG9mIGFuIGFkZHJlc3NcbiAgICogQHBhcmFtIGFkZHJlc3Mge1N0cmluZ30gdGhlIGFkZHJlc3MgZW5jb2RlZCBpbiBoZXhcbiAgICogQHJldHVybnMge0JpZ051bWJlcn0gYWRkcmVzcyBiYWxhbmNlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldEFjY291bnRCYWxhbmNlc0Zyb21Ob2RlKGFkZHJlc3M6IHN0cmluZyk6IFByb21pc2U8QWNjb3VudFJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmVjb3ZlcnlHZXQoe1xuICAgICAgcGF0aDogJy92MS9hY2NvdW50cy8nICsgYWRkcmVzcyxcbiAgICAgIGpzb25PYmo6IHt9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QnVpbGRUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogbnVtYmVyXG4gICk6IFByb21pc2U8SW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdD4ge1xuICAgIC8vIG91ciBhZGRyZXNzZXMgc2hvdWxkIGJlIGJhc2U1OCwgd2UnbGwgaGF2ZSB0byBlbmNvZGUgdG8gaGV4XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmVjb3ZlcnlQb3N0KHtcbiAgICAgIHBhdGg6ICcvd2FsbGV0L2NyZWF0ZXRyYW5zYWN0aW9uJyxcbiAgICAgIGpzb25PYmo6IHtcbiAgICAgICAgdG9fYWRkcmVzczogdG9BZGRyLFxuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgYW1vdW50LFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBvdXIgYnVpbGQgdHJhbnNhY3Rpb24gZnJvbSBhIG5vZGUuXG4gICAqIEBwYXJhbSB0b0FkZHIgaGV4LWVuY29kZWQgYWRkcmVzc1xuICAgKiBAcGFyYW0gZnJvbUFkZHIgaGV4LWVuY29kZWQgYWRkcmVzc1xuICAgKiBAcGFyYW0gYW1vdW50XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24oXG4gICAgdG9BZGRyOiBzdHJpbmcsXG4gICAgZnJvbUFkZHI6IHN0cmluZyxcbiAgICBhbW91bnQ6IHN0cmluZyxcbiAgICBjb250cmFjdEFkZHI6IHN0cmluZ1xuICApOiBQcm9taXNlPHsgdHJhbnNhY3Rpb246IEludGVyZmFjZS5UcmFuc2FjdGlvblJlY2VpcHQgfT4ge1xuICAgIGNvbnN0IGZ1bmN0aW9uU2VsZWN0b3IgPSAndHJhbnNmZXIoYWRkcmVzcyx1aW50MjU2KSc7XG4gICAgY29uc3QgdHlwZXMgPSBbJ2FkZHJlc3MnLCAndWludDI1NiddO1xuICAgIGNvbnN0IHZhbHVlcyA9IFt0b0FkZHIsIGFtb3VudF07XG4gICAgY29uc3QgcGFyYW1ldGVyID0gVXRpbHMuZW5jb2RlRGF0YVBhcmFtcyh0eXBlcywgdmFsdWVzLCAnJyk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmVjb3ZlcnlQb3N0KHtcbiAgICAgIHBhdGg6ICcvd2FsbGV0L3RyaWdnZXJzbWFydGNvbnRyYWN0JyxcbiAgICAgIGpzb25PYmo6IHtcbiAgICAgICAgb3duZXJfYWRkcmVzczogZnJvbUFkZHIsXG4gICAgICAgIGNvbnRyYWN0X2FkZHJlc3M6IGNvbnRyYWN0QWRkcixcbiAgICAgICAgZnVuY3Rpb25fc2VsZWN0b3I6IGZ1bmN0aW9uU2VsZWN0b3IsXG4gICAgICAgIHBhcmFtZXRlcjogcGFyYW1ldGVyLFxuICAgICAgICBmZWVfbGltaXQ6IDEwMDAwMDAwMCxcbiAgICAgIH0sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaHJvd3MgYW4gZXJyb3IgaWYgYW55IGtleXMgaW4gdGhlIG93bmVyS2V5cyBjb2xsZWN0aW9uIGRvbid0IG1hdGNoIHRoZSBrZXlzIGFycmF5IHdlIHBhc3NcbiAgICogQHBhcmFtIG93bmVyS2V5c1xuICAgKiBAcGFyYW0ga2V5c1xuICAgKi9cbiAgY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXM6IHsgYWRkcmVzczogc3RyaW5nOyB3ZWlnaHQ6IG51bWJlciB9W10sIGtleXM6IHN0cmluZ1tdKSB7XG4gICAga2V5cyA9IGtleXMubWFwKChrKSA9PiBrLnRvVXBwZXJDYXNlKCkpO1xuXG4gICAgb3duZXJLZXlzLm1hcCgoa2V5KSA9PiB7XG4gICAgICBjb25zdCBoZXhLZXkgPSBrZXkuYWRkcmVzcy50b1VwcGVyQ2FzZSgpO1xuICAgICAgaWYgKCFrZXlzLmluY2x1ZGVzKGhleEtleSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwdWIgYWRkcmVzcyAke2hleEtleX0gbm90IGZvdW5kIGluIGFjY291bnRgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGtleS53ZWlnaHQgIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdvd25lciBwZXJtaXNzaW9uIGlzIGludmFsaWQgZm9yIHRoaXMgc3RydWN0dXJlJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IGZvciBvZmZsaW5lIHZhdWx0IHNpZ25pbmdcbiAgICogQHBhcmFtIHtCYXNlVHJhbnNhY3Rpb259IHR4XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBmZWVcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlY292ZXJ5QW1vdW50XG4gICAqIEByZXR1cm5zIHtSZWNvdmVyeVRyYW5zYWN0aW9ufVxuICAgKi9cbiAgZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KFxuICAgIHR4OiBCYXNlVHJhbnNhY3Rpb24sXG4gICAgZmVlOiBudW1iZXIsXG4gICAgcmVjb3ZlcnlBbW91bnQ6IG51bWJlcixcbiAgICBhZGRyZXNzSW5mbz86IEFkZHJlc3NJbmZvXG4gICk6IFJlY292ZXJ5VHJhbnNhY3Rpb24ge1xuICAgIGNvbnN0IHR4SlNPTiA9IHR4LnRvSnNvbigpO1xuICAgIGNvbnN0IGZvcm1hdCA9IHtcbiAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh0eEpTT04pLFxuICAgICAgcmVjb3ZlcnlBbW91bnQsXG4gICAgICBmZWVJbmZvOiB7XG4gICAgICAgIGZlZTogYCR7ZmVlfWAsXG4gICAgICB9LFxuICAgICAgdHg6IHR4SlNPTiwgLy8gTGVhdmluZyBpdCBhcyB0eEpTT04gZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgICBjb2luOiB0aGlzLmdldENoYWluKCksXG4gICAgfTtcbiAgICByZXR1cm4gYWRkcmVzc0luZm8gPyB7IC4uLmZvcm1hdCwgYWRkcmVzc0luZm8gfSA6IGZvcm1hdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvLlxuICAgKiBXZSBuZWVkIHRvIGRvIHRocmVlIHF1ZXJpZXMgZHVyaW5nIHRoaXM6XG4gICAqIDEpIE5vZGUgcXVlcnkgLSBob3cgbXVjaCBtb25leSBpcyBpbiB0aGUgYWNjb3VudFxuICAgKiAyKSBCdWlsZCB0cmFuc2FjdGlvbiAtIGJ1aWxkIG91ciB0cmFuc2FjdGlvbiBmb3IgdGhlIGFtb3VudFxuICAgKiAzKSBTZW5kIHNpZ25lZCBidWlsZCAtIHNlbmQgb3VyIHNpZ25lZCBidWlsZCB0byBhIHB1YmxpYyBub2RlXG4gICAqXG4gICAqIE5vdGUgMTogZm9yIGJhc2UgYWRkcmVzcyByZWNvdmVyaWVzLCBmdW5kIHdpbGwgYmUgcmVjb3ZlcmVkIHRvIHJlY292ZXJ5IGRlc3RpbmF0aW9uIGlmIGJhc2UgYWRkcmVzcyBiYWxhbmNlIGlzXG4gICAqIG1vcmUgdGhhbiAyLjEgVFJYIGZvciBuYXRpdmUgVFJYIHJlY292ZXJ5IGFuZCAxMDAgVFJYIGZvciB0b2tlbiByZWNvdmVyLiBGb3IgcmVjZWl2ZSBhZGRyZXNzZXMsIGZ1bmQgd2lsbCBiZVxuICAgKiByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0IHRoZW4gc3dlcHQgdG8gYmFzZSBhZGRyZXNzKGRlY2lkZWQgYXMgdGhlIHVuaXZlcnNhbCBwYXR0ZXJuIGluIHRlYW0gbWVldGluZykuXG4gICAqXG4gICAqIE5vdGUgMjogdGhlIGZ1bmN0aW9uIHN1cHBvcnRzIHRva2VuIHN3ZWVwIGZyb20gYmFzZSBhZGRyZXNzLlxuICAgKiBUT0RPOiBzdXBwb3J0IHRva2VuIHN3ZWVwIGZyb20gcmVjZWl2ZSBhZGRyZXNzLlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogUmVjb3ZlcnlPcHRpb25zKTogUHJvbWlzZTxSZWNvdmVyeVRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgaXNLcnNSZWNvdmVyeSA9IGdldElzS3JzUmVjb3ZlcnkocGFyYW1zKTtcbiAgICBjb25zdCBpc1Vuc2lnbmVkU3dlZXAgPSBnZXRJc1Vuc2lnbmVkU3dlZXAocGFyYW1zKTtcblxuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBkZXN0aW5hdGlvbiBhZGRyZXNzIScpO1xuICAgIH1cblxuICAgIGxldCBzdGFydElkeCA9IHBhcmFtcy5zdGFydGluZ1NjYW5JbmRleDtcbiAgICBpZiAoaXNVbmRlZmluZWQoc3RhcnRJZHgpKSB7XG4gICAgICBzdGFydElkeCA9IDE7XG4gICAgfSBlbHNlIGlmICghaXNJbnRlZ2VyKHN0YXJ0SWR4KSB8fCBzdGFydElkeCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdGFydGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMnKTtcbiAgICB9XG4gICAgbGV0IG51bUl0ZXJhdGlvbiA9IHBhcmFtcy5zY2FuO1xuICAgIGlmIChpc1VuZGVmaW5lZChudW1JdGVyYXRpb24pKSB7XG4gICAgICBudW1JdGVyYXRpb24gPSAyMDtcbiAgICB9IGVsc2UgaWYgKCFpc0ludGVnZXIobnVtSXRlcmF0aW9uKSB8fCBudW1JdGVyYXRpb24gPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNjYW5uaW5nIGZhY3RvcicpO1xuICAgIH1cblxuICAgIC8vIGdldCBvdXIgdXNlciwgYmFja3VwIGtleXNcbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKHRoaXMuYml0Z28sIHBhcmFtcywgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9KTtcblxuICAgIC8vIHdlIG5lZWQgdG8gZGVjb2RlIG91ciBiaXRnb0tleSB0byBhIGJhc2U1OCBhZGRyZXNzXG4gICAgY29uc3QgYml0Z29IZXhBZGRyID0gdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIocGFyYW1zLmJpdGdvS2V5KSk7XG4gICAgbGV0IHJlY292ZXJ5RnJvbUFkZHJIZXggPSBiaXRnb0hleEFkZHI7XG4gICAgbGV0IHJlY292ZXJ5VG9BZGRyZXNzSGV4ID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcblxuICAgIC8vIGNhbGwgdGhlIG5vZGUgdG8gZ2V0IG91ciBhY2NvdW50IGJhbGFuY2UgZm9yIGJhc2UgYWRkcmVzc1xuICAgIGxldCBhY2NvdW50ID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZXNGcm9tTm9kZShVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUhleChyZWNvdmVyeUZyb21BZGRySGV4KSk7XG4gICAgbGV0IHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG5cbiAgICBsZXQgdXNlclhQcnYgPSBrZXlzWzBdLnRvQmFzZTU4KCk7XG4gICAgbGV0IGlzUmVjZWl2ZUFkZHJlc3MgPSBmYWxzZTtcbiAgICBsZXQgYWRkcmVzc0luZm86IEFkZHJlc3NJbmZvIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyID0gcGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzO1xuICAgIC8vIGNoZWNrIGZvciBwb3NzaWJsZSB0b2tlbiByZWNvdmVyeSwgcmVjb3ZlciB0aGUgdG9rZW4gcHJvdmlkZSBieSB1c2VyXG4gICAgaWYgKHRva2VuQ29udHJhY3RBZGRyKSB7XG4gICAgICBsZXQgcmF3VG9rZW5UeG46IGFueSB8IHVuZGVmaW5lZDtcbiAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgYWNjb3VudC5kYXRhWzBdLnRyYzIwKSB7XG4gICAgICAgIGlmICh0b2tlblt0b2tlbkNvbnRyYWN0QWRkcl0pIHtcbiAgICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlblt0b2tlbkNvbnRyYWN0QWRkcl07XG4gICAgICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3ModG9rZW5Db250cmFjdEFkZHIpO1xuICAgICAgICAgIHJhd1Rva2VuVHhuID0gKFxuICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKFxuICAgICAgICAgICAgICByZWNvdmVyeVRvQWRkcmVzc0hleCxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlGcm9tQWRkckhleCxcbiAgICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkckhleFxuICAgICAgICAgICAgKVxuICAgICAgICAgICkudHJhbnNhY3Rpb247XG4gICAgICAgICAgcmVjb3ZlcnlBbW91bnQgPSBwYXJzZUludChhbW91bnQsIDEwKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBidWlsZCBhbmQgc2lnbiB0b2tlbiB0eG5zXG4gICAgICBpZiAocmF3VG9rZW5UeG4pIHtcbiAgICAgICAgLy8gQ2hlY2sgdGhlcmUgaXMgc3VmZmljaWVudCBvZiB0aGUgbmF0aXZlIGFzc2V0IHRvIGNvdmVyIGZlZXNcbiAgICAgICAgY29uc3QgdHJ4QmFsYW5jZSA9IGFjY291bnQuZGF0YVswXS5iYWxhbmNlO1xuICAgICAgICBpZiAodHJ4QmFsYW5jZSA8IFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgJHt0cnhCYWxhbmNlfSBpcyBsZXNzIHRoYW4gJHtTQUZFX1RST05fVE9LRU5fVFJBTlNBQ1RJT05fRkVFfSBhbmQgd291bGRuJ3QgYmUgYWJsZSB0byBmdW5kIGEgdHJjMjAgc2VuZGBcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocmF3VG9rZW5UeG4pO1xuICAgICAgICAvLyBEZWZhdWx0IGV4cGlyeSBpcyAxIG1pbnV0ZSB3aGljaCBpcyB0b28gc2hvcnQgZm9yIHJlY292ZXJ5IHB1cnBvc2VzXG4gICAgICAgIC8vIGV4dGVuZCB0aGUgZXhwaXJ5IHRvIDEgZGF5XG4gICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcbiAgICAgICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICAgICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSwgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdXNlclBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydih1c2VyWFBydik7XG5cbiAgICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHVzZXJQcnYgfSk7XG5cbiAgICAgICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgICAgICBpZiAoIWlzS3JzUmVjb3ZlcnkgJiYgIWlzUmVjZWl2ZUFkZHJlc3MpIHtcbiAgICAgICAgICBjb25zdCBiYWNrdXBYUHJ2ID0ga2V5c1sxXS50b0Jhc2U1OCgpO1xuICAgICAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBiYWNrdXBQcnYgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KGF3YWl0IHR4QnVpbGRlci5idWlsZCgpLCBTQUZFX1RST05fVE9LRU5fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBFcnJvcignTm90IGZvdW5kIHRva2VuIHRvIHJlY292ZXIsIHBsZWFzZSBjaGVjayB0b2tlbiBiYWxhbmNlJyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGxldCB1cyByZWNvdmVyIHRoZSBuYXRpdmUgVHJvblxuICAgIGlmIChyZWNvdmVyeUFtb3VudCA+IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgIGNvbnN0IHVzZXJYUHViID0ga2V5c1swXS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG4gICAgICBjb25zdCBiYWNrdXBYUHViID0ga2V5c1sxXS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCk7XG5cbiAgICAgIC8vIGNoZWNrIG11bHRpc2lnIHBlcm1pc3Npb25zXG4gICAgICBjb25zdCBrZXlIZXhBZGRyZXNzZXMgPSBbXG4gICAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKHVzZXJYUHViKSksXG4gICAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJhY2t1cFhQdWIpKSxcbiAgICAgICAgYml0Z29IZXhBZGRyLFxuICAgICAgXTtcbiAgICAgIC8vIHJ1biBjaGVja3MgdG8gZW5zdXJlIHRoaXMgaXMgYSB2YWxpZCB0eCAtIHBlcm1pc3Npb25zIG1hdGNoIG91ciBzaWduZXIga2V5c1xuICAgICAgY29uc3Qgb3duZXJLZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBhY2NvdW50LmRhdGFbMF0ub3duZXJfcGVybWlzc2lvbi5rZXlzKSB7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgICBvd25lcktleXMucHVzaCh7IGFkZHJlc3MsIHdlaWdodCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjdGl2ZVBlcm1pc3Npb25LZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBhY2NvdW50LmRhdGFbMF0uYWN0aXZlX3Blcm1pc3Npb25bMF0ua2V5cykge1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKGtleS5hZGRyZXNzKTtcbiAgICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5LndlaWdodDtcbiAgICAgICAgYWN0aXZlUGVybWlzc2lvbktleXMucHVzaCh7IGFkZHJlc3MsIHdlaWdodCB9KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgICB0aGlzLmNoZWNrUGVybWlzc2lvbnMoYWN0aXZlUGVybWlzc2lvbktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENoZWNrIHJlY2VpdmUgYWRkcmVzc2VzIGZvciBmdW5kc1xuICAgICAgLy8gQ2hlY2sgZm9yIGZpcnN0IGRlcml2ZWQgd2FsbGV0IHdpdGggZnVuZHNcbiAgICAgIC8vIFJlY2VpdmUgYWRkcmVzc2VzIGFyZSBkZXJpdmVkIGZyb20gdGhlIHVzZXIga2V5XG4gICAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCBudW1JdGVyYXRpb24gKyBzdGFydElkeDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8wLyR7aX1gO1xuICAgICAgICBjb25zdCB1c2VyS2V5ID0ga2V5c1swXS5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoKTtcbiAgICAgICAgY29uc3QgeHB1YiA9IHVzZXJLZXkubmV1dGVyZWQoKTtcbiAgICAgICAgY29uc3QgcmVjZWl2ZUFkZHJlc3MgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1Yih4cHViLnRvQmFzZTU4KCkpKTtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHJlY2VpdmVBZGRyZXNzKTtcbiAgICAgICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZVxuICAgICAgICBjb25zdCBhY2NvdW50SW5mbyA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzcyk7XG5cbiAgICAgICAgaWYgKGFjY291bnRJbmZvLmRhdGFbMF0gJiYgYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlID4gU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSkge1xuICAgICAgICAgIGFjY291bnQgPSBhY2NvdW50SW5mbztcbiAgICAgICAgICByZWNvdmVyeUFtb3VudCA9IGFjY291bnRJbmZvLmRhdGFbMF0uYmFsYW5jZTtcbiAgICAgICAgICB1c2VyWFBydiA9IHVzZXJLZXkudG9CYXNlNTgoKTsgLy8gYXNzaWduIGRlcml2ZWQgdXNlclhQcnhcbiAgICAgICAgICBpc1JlY2VpdmVBZGRyZXNzID0gdHJ1ZTtcbiAgICAgICAgICByZWNvdmVyeUZyb21BZGRySGV4ID0gcmVjZWl2ZUFkZHJlc3M7XG4gICAgICAgICAgcmVjb3ZlcnlUb0FkZHJlc3NIZXggPSBiaXRnb0hleEFkZHI7XG4gICAgICAgICAgYWRkcmVzc0luZm8gPSB7XG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYSBzd2VlcCBwb3RlbnRpYWxseSBuZWVkcyB0byBwYXkgZm9yIG11bHRpLXNpZyB0cmFuc2ZlciwgZGVzdGluYXRpb24gYWNjb3VudCBhY3RpdmF0aW9uIGFuZCBiYW5kd2lkdGhcbiAgICAvLyBUUk9OIGZvdW5kYXRpb24gcmVjb21tZW5kcyAyLjEgVFJYIGZvciBndWFyYW50ZWVkIGNvbmZpcm1hdGlvblxuICAgIGlmICghcmVjb3ZlcnlBbW91bnQgfHwgU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSA+PSByZWNvdmVyeUFtb3VudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgJHtyZWNvdmVyeUFtb3VudH0gaXMgbGVzcyB0aGFuICR7U0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRX0gYW5kIHdvdWxkbid0IGJlIGFibGUgdG8gZnVuZCBhIHNlbmRgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50TWludXNGZWVzID0gcmVjb3ZlcnlBbW91bnQgLSBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFO1xuICAgIGNvbnN0IGJ1aWxkVHggPSBhd2FpdCB0aGlzLmdldEJ1aWxkVHJhbnNhY3Rpb24ocmVjb3ZlcnlUb0FkZHJlc3NIZXgsIHJlY292ZXJ5RnJvbUFkZHJIZXgsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzKTtcblxuICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuICAgIC8vIERlZmF1bHQgZXhwaXJ5IGlzIDEgbWludXRlIHdoaWNoIGlzIHRvbyBzaG9ydCBmb3IgcmVjb3ZlcnkgcHVycG9zZXNcbiAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuXG4gICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRGb3JPZmZsaW5lVmF1bHQodHgsIFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzLCBhZGRyZXNzSW5mbyk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlclBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydih1c2VyWFBydik7XG5cbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgIC8vIGtycyByZWNvdmVyaWVzIGRvbid0IGdldCBzaWduZWRcbiAgICBpZiAoIWlzS3JzUmVjb3ZlcnkgJiYgIWlzUmVjZWl2ZUFkZHJlc3MpIHtcbiAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICBjb25zdCBiYWNrdXBQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYoYmFja3VwWFBydik7XG5cbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBiYWNrdXBQcnYgfSk7XG4gICAgfVxuICAgIGNvbnN0IHR4U2lnbmVkID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KHR4U2lnbmVkLCBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudE1pbnVzRmVlcywgYWRkcmVzc0luZm8pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBuYXRpdmUgVFJYIHJlY292ZXJpZXMgb2YgcmVjZWl2ZSBhZGRyZXNzZXMgaW4gYmF0Y2ggd2l0aG91dCBCaXRHby5cbiAgICogRnVuZHMgd2lsbCBiZSByZWNvdmVyZWQgdG8gYmFzZSBhZGRyZXNzIGZpcnN0LiBZb3UgbmVlZCB0byBpbml0aWF0ZSBhbm90aGVyIHN3ZWVwIHR4biBhZnRlciB0aGF0LlxuICAgKiBOb3RlOiB0aGVyZSB3aWxsIGJlIGFub3RoZXIgcmVjb3ZlclRva2VuQ29uc29saWRhdGlvbnMgZnVuY3Rpb24gdG8gc3VwcG9ydCB0b2tlbiByZWNvdmVyIGZyb20gcmVjZWl2ZSBhZGRyZXNzZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7Q29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9uc30gcGFyYW1zIC0gb3B0aW9ucyBmb3IgY29uc29saWRhdGlvbiByZWNvdmVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXhdIC0gcmVjZWl2ZSBhZGRyZXNzIGluZGV4IHRvIHN0YXJ0IHNjYW5uaW5nIGZyb20uIGRlZmF1bHQgdG8gMSAoaW5jbHVzaXZlKS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuZW5kaW5nU2NhbkluZGV4XSAtIHJlY2VpdmUgYWRkcmVzcyBpbmRleCB0byBlbmQgc2Nhbm5pbmcgYXQuIGRlZmF1bHQgdG8gc3RhcnRpbmdTY2FuSW5kZXggKyAyMCAoZXhjbHVzaXZlKS5cbiAgICovXG4gIGFzeW5jIHJlY292ZXJDb25zb2xpZGF0aW9ucyhwYXJhbXM6IENvbnNvbGlkYXRpb25SZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPENvbnNvbGlkYXRpb25SZWNvdmVyeUJhdGNoPiB7XG4gICAgY29uc3QgaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zID0gZ2V0SXNVbnNpZ25lZFN3ZWVwKHBhcmFtcyk7XG4gICAgY29uc3Qgc3RhcnRJZHggPSBwYXJhbXMuc3RhcnRpbmdTY2FuSW5kZXggfHwgMTtcbiAgICBjb25zdCBlbmRJZHggPSBwYXJhbXMuZW5kaW5nU2NhbkluZGV4IHx8IHN0YXJ0SWR4ICsgREVGQVVMVF9TQ0FOX0ZBQ1RPUjtcblxuICAgIGlmIChzdGFydElkeCA8IDEgfHwgZW5kSWR4IDw9IHN0YXJ0SWR4IHx8IGVuZElkeCAtIHN0YXJ0SWR4ID4gMTAgKiBERUZBVUxUX1NDQU5fRkFDVE9SKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAke3N0YXJ0SWR4fSwgZW5kaW5nU2NhbkluZGV4OiAke2VuZElkeH0uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKHRoaXMuYml0Z28sIHBhcmFtcywgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9KTtcbiAgICBjb25zdCBiYXNlQWRkckhleCA9IHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKHBhcmFtcy5iaXRnb0tleSkpO1xuXG4gICAgY29uc3QgdHhuc0JhdGNoOiBSZWNvdmVyeVRyYW5zYWN0aW9uW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gc3RhcnRJZHg7IGkgPCBlbmRJZHg7IGkrKykge1xuICAgICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBgMC8wLzAvJHtpfWA7XG4gICAgICBjb25zdCB1c2VyS2V5ID0ga2V5c1swXS5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoKTtcbiAgICAgIGNvbnN0IHVzZXJLZXlYUHViID0gdXNlcktleS5uZXV0ZXJlZCgpO1xuICAgICAgY29uc3QgcmVjZWl2ZUFkZHJlc3NIZXggPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1Yih1c2VyS2V5WFB1Yi50b0Jhc2U1OCgpKSk7XG4gICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHJlY2VpdmVBZGRyZXNzSGV4KTtcbiAgICAgIC8vIGNhbGwgdGhlIG5vZGUgdG8gZ2V0IG91ciBhY2NvdW50IGJhbGFuY2VcbiAgICAgIGNvbnN0IGFjY291bnRJbmZvID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZXNGcm9tTm9kZShyZWNlaXZlQWRkcmVzcyk7XG5cbiAgICAgIGlmIChhY2NvdW50SW5mby5kYXRhWzBdICYmIGFjY291bnRJbmZvLmRhdGFbMF0uYmFsYW5jZSA+IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUpIHtcbiAgICAgICAgbGV0IHJlY292ZXJ5QW1vdW50ID0gMDtcbiAgICAgICAgLy8gVG9rZW5zIG11c3QgYmUgY29uc29saWRhdGUgYmVmb3JlIHRoZSBuYXRpdmUgYXNzZXQuIEZpcnN0IGNvbnN0cnVjdCB0b2tlbiB0eG5zXG4gICAgICAgIGxldCByYXdUb2tlblR4bjogYW55IHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIGNoZWNrIGZvciBwb3NzaWJsZSB0b2tlbiByZWNvdmVyeSwgcmVjb3ZlciB0aGUgdG9rZW4gcHJvdmlkZSBieSB1c2VyXG4gICAgICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MpIHtcbiAgICAgICAgICBpZiAoYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlID4gU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSAmJiBhY2NvdW50SW5mby5kYXRhWzBdLnRyYzIwWzBdKSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbkRhdGFBcnJheSA9IGFjY291bnRJbmZvLmRhdGFbMF0udHJjMjA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRva2VuRGF0YSBvZiB0b2tlbkRhdGFBcnJheSkge1xuICAgICAgICAgICAgICBjb25zdCBjb250cmFjdEFkZHJlc3MgPSBPYmplY3Qua2V5cyh0b2tlbkRhdGEpIGFzIEFycmF5PHN0cmluZz47XG4gICAgICAgICAgICAgIGlmIChwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3MgPT09IGNvbnRyYWN0QWRkcmVzc1swXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuRGF0YVtjb250cmFjdEFkZHJlc3NbMF1dO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRySGV4ID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKGNvbnRyYWN0QWRkcmVzc1swXSk7XG4gICAgICAgICAgICAgICAgcmF3VG9rZW5UeG4gPSAoXG4gICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24oXG4gICAgICAgICAgICAgICAgICAgIGJhc2VBZGRySGV4LFxuICAgICAgICAgICAgICAgICAgICByZWNlaXZlQWRkcmVzc0hleCxcbiAgICAgICAgICAgICAgICAgICAgYW1vdW50LFxuICAgICAgICAgICAgICAgICAgICB0b2tlbkNvbnRyYWN0QWRkckhleFxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICkudHJhbnNhY3Rpb247XG4gICAgICAgICAgICAgICAgcmVjb3ZlcnlBbW91bnQgPSBwYXJzZUludChhbW91bnQsIDEwKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBidWlsZCBhbmQgc2lnbiB0b2tlbiB0eG5zXG4gICAgICAgICAgaWYgKHJhd1Rva2VuVHhuKSB7XG4gICAgICAgICAgICBjb25zdCBhZGRyZXNzSW5mbyA9IHtcbiAgICAgICAgICAgICAgYWRkcmVzczogcmVjZWl2ZUFkZHJlc3MsXG4gICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShyYXdUb2tlblR4bik7XG4gICAgICAgICAgICAvLyBEZWZhdWx0IGV4cGlyeSBpcyAxIG1pbnV0ZSB3aGljaCBpcyB0b28gc2hvcnQgZm9yIHJlY292ZXJ5IHB1cnBvc2VzXG4gICAgICAgICAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgICAgICAgICAgdHhCdWlsZGVyLmV4dGVuZFZhbGlkVG8oUkVDT1ZFUl9UUkFOU0FDVElPTl9FWFBJUlkpO1xuICAgICAgICAgICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICAgICAgICAgIGlmICghaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHVzZXJQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYodXNlcktleS50b0Jhc2U1OCgpKTtcbiAgICAgICAgICAgICAgLy8gcmVjZWl2ZSBhZGRyZXNzIG9ubHkgbmVlZHMgdG8gYmUgc2lnbmVkIGJ5IHVzZXIga2V5XG4gICAgICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgICAgIHR4bnNCYXRjaC5wdXNoKFxuICAgICAgICAgICAgICB0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdCh0eCwgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnQsIGFkZHJlc3NJbmZvKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc0JhbGFuY2UgPSBhY2NvdW50SW5mby5kYXRhWzBdLmJhbGFuY2U7XG4gICAgICAgICAgY29uc3QgYWRkcmVzc0luZm8gPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiByZWNlaXZlQWRkcmVzcyxcbiAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IGFkZHJlc3NCYWxhbmNlIC0gU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRTtcbiAgICAgICAgICBjb25zdCBidWlsZFR4ID0gYXdhaXQgdGhpcy5nZXRCdWlsZFRyYW5zYWN0aW9uKGJhc2VBZGRySGV4LCByZWNlaXZlQWRkcmVzc0hleCwgcmVjb3ZlcnlBbW91bnQpO1xuICAgICAgICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuICAgICAgICAgIC8vIERlZmF1bHQgZXhwaXJ5IGlzIDEgbWludXRlIHdoaWNoIGlzIHRvbyBzaG9ydCBmb3IgcmVjb3ZlcnkgcHVycG9zZXNcbiAgICAgICAgICAvLyBleHRlbmQgdGhlIGV4cGlyeSB0byAxIGRheVxuICAgICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcblxuICAgICAgICAgIGlmICghaXNVbnNpZ25lZENvbnNvbGlkYXRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJLZXkudG9CYXNlNTgoKSk7XG4gICAgICAgICAgICAvLyByZWNlaXZlIGFkZHJlc3Mgb25seSBuZWVkcyB0byBiZSBzaWduZWQgYnkgdXNlciBrZXlcbiAgICAgICAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICAgIHR4bnNCYXRjaC5wdXNoKHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KHR4LCBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudCwgYWRkcmVzc0luZm8pKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0cmFuc2FjdGlvbnM6IHR4bnNCYXRjaCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4gYSBUcm9uIHRyYW5zYWN0aW9uIGZyb20gdHhIZXhcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8VHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24+IHtcbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcy50eEhleCB8fCAocGFyYW1zLmhhbGZTaWduZWQgJiYgcGFyYW1zLmhhbGZTaWduZWQudHhIZXgpO1xuICAgIGlmICghdHhIZXggfHwgIXBhcmFtcy5mZWVJbmZvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgZXhwbGFpbiB0eCBwYXJhbWV0ZXJzJyk7XG4gICAgfVxuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIodGhpcy5nZXRDaGFpbigpKS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IG91dHB1dHMgPSBbXG4gICAgICB7XG4gICAgICAgIGFtb3VudDogdHgub3V0cHV0c1swXS52YWx1ZS50b1N0cmluZygpLFxuICAgICAgICBhZGRyZXNzOiB0eC5vdXRwdXRzWzBdLmFkZHJlc3MsIC8vIFNob3VsZCB0dXJuIGl0IGludG8gYSByZWFkYWJsZSBmb3JtYXQsIGFrYSBiYXNlNThcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGNvbnN0IGRpc3BsYXlPcmRlciA9IFtcbiAgICAgICdpZCcsXG4gICAgICAnb3V0cHV0QW1vdW50JyxcbiAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgJ291dHB1dHMnLFxuICAgICAgJ2NoYW5nZU91dHB1dHMnLFxuICAgICAgJ2ZlZScsXG4gICAgICAndGltZXN0YW1wJyxcbiAgICAgICdleHBpcmF0aW9uJyxcbiAgICBdO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXlPcmRlcixcbiAgICAgIGlkOiB0eC5pZCxcbiAgICAgIG91dHB1dHMsXG4gICAgICBvdXRwdXRBbW91bnQ6IG91dHB1dHNbMF0uYW1vdW50LFxuICAgICAgY2hhbmdlT3V0cHV0czogW10sIC8vIGFjY291bnQgYmFzZWQgZG9lcyBub3QgdXNlIGNoYW5nZSBvdXRwdXRzXG4gICAgICBjaGFuZ2VBbW91bnQ6ICcwJywgLy8gYWNjb3VudCBiYXNlIGRvZXMgbm90IG1ha2UgY2hhbmdlXG4gICAgICBmZWU6IHBhcmFtcy5mZWVJbmZvLFxuICAgICAgdGltZXN0YW1wOiB0eC52YWxpZEZyb20sXG4gICAgICBleHBpcmF0aW9uOiB0eC52YWxpZFRvLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==