@bitgo-beta/abstract-utxo 1.1.1-beta.32 → 1.1.1-beta.321

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.
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AbstractUtxoCoin = void 0;
3
+ exports.AbstractUtxoCoin = exports.AbstractUtxoCoinWallet = void 0;
4
4
  /**
5
5
  * @prettier
6
6
  */
7
7
  const utxolib = require("@bitgo-beta/utxo-lib");
8
8
  const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
9
+ const assert = require("assert");
9
10
  const bitcoinMessage = require("bitcoinjs-message");
10
11
  const crypto_1 = require("crypto");
11
12
  const debugLib = require("debug");
@@ -19,7 +20,14 @@ const debug = debugLib('bitgo:v2:utxo');
19
20
  const replayProtection_1 = require("./replayProtection");
20
21
  const sign_1 = require("./sign");
21
22
  const config_1 = require("./config");
22
- const { getExternalChainCode, isChainCode, scriptTypeForChain, outputScripts, toOutput, verifySignatureWithUnspent } = utxo_lib_1.bitgo;
23
+ const transaction_1 = require("./transaction");
24
+ const { getExternalChainCode, isChainCode, scriptTypeForChain, outputScripts } = utxo_lib_1.bitgo;
25
+ class AbstractUtxoCoinWallet extends sdk_core_1.Wallet {
26
+ constructor(bitgo, baseCoin, walletData) {
27
+ super(bitgo, baseCoin, walletData);
28
+ }
29
+ }
30
+ exports.AbstractUtxoCoinWallet = AbstractUtxoCoinWallet;
23
31
  class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
24
32
  constructor(bitgo, network, amountType = 'number') {
25
33
  super(bitgo);
@@ -54,64 +62,22 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
54
62
  return utxolib;
55
63
  }
56
64
  /**
57
- * Helper to get the version number for an address
65
+ * Check if an address is valid
66
+ * @param address
67
+ * @param param
58
68
  */
59
- getAddressVersion(address) {
60
- // try decoding as base58 first
61
- try {
62
- const { version } = utxolib.address.fromBase58Check(address, this.network);
63
- return version;
64
- }
65
- catch (e) {
66
- // try next format
67
- }
68
- // if coin does not support script types with bech32 encoding, do not attempt to parse
69
- if (!this.supportsAddressType('p2wsh') && !this.supportsAddressType('p2tr')) {
70
- return;
71
- }
72
- // otherwise, try decoding as bech32
73
- try {
74
- const { version, prefix } = utxolib.address.fromBech32(address);
75
- if (_.isString(this.network.bech32) && prefix === this.network.bech32) {
76
- return version;
77
- }
78
- }
79
- catch (e) {
80
- // ignore errors, just fall through and return undefined
69
+ isValidAddress(address, param) {
70
+ if (typeof param === 'boolean' && param) {
71
+ throw new Error('deprecated');
81
72
  }
82
- }
83
- /**
84
- * Helper to get the bech32 prefix for an address
85
- */
86
- getAddressPrefix(address) {
87
- // otherwise, try decoding as bech32
73
+ const formats = param && param.anyFormat ? undefined : ['default'];
88
74
  try {
89
- const { prefix } = utxolib.address.fromBech32(address);
90
- return prefix;
75
+ utxolib.addressFormat.toOutputScriptTryFormats(address, this.network, formats);
76
+ return true;
91
77
  }
92
78
  catch (e) {
93
- // ignore errors, just fall through and return undefined
94
- }
95
- }
96
- /**
97
- * Check if an address is valid
98
- * @param address
99
- * @param forceAltScriptSupport
100
- */
101
- isValidAddress(address, forceAltScriptSupport = false) {
102
- const validVersions = [this.network.pubKeyHash, this.network.scriptHash];
103
- if (this.altScriptHash && (forceAltScriptSupport || this.supportAltScriptDestination)) {
104
- validVersions.push(this.altScriptHash);
105
- }
106
- const addressVersion = this.getAddressVersion(address);
107
- // the address version needs to be among the valid ones
108
- const addressVersionValid = _.isNumber(addressVersion) && validVersions.includes(addressVersion);
109
- const addressPrefix = this.getAddressPrefix(address);
110
- if (!this.supportsAddressType('p2wsh') || _.isUndefined(addressPrefix)) {
111
- return addressVersionValid;
79
+ return false;
112
80
  }
113
- // address has a potential bech32 prefix, validate that
114
- return (_.isString(this.network.bech32) && this.network.bech32 === addressPrefix && address === address.toLowerCase());
115
81
  }
116
82
  /**
117
83
  * Return boolean indicating whether input is valid public key for the coin.
@@ -146,14 +112,13 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
146
112
  if (_.isUndefined(prebuild.txHex)) {
147
113
  throw new Error('missing required txPrebuild property txHex');
148
114
  }
149
- const transaction = this.createTransactionFromHex(prebuild.txHex);
115
+ const tx = utxo_lib_1.bitgo.isPsbt(prebuild.txHex)
116
+ ? utxo_lib_1.bitgo.createPsbtFromHex(prebuild.txHex, this.network)
117
+ : this.createTransactionFromHex(prebuild.txHex);
150
118
  if (_.isUndefined(prebuild.blockHeight)) {
151
119
  prebuild.blockHeight = (await this.getLatestBlockHeight());
152
120
  }
153
- // Lock transaction to the next block to discourage fee sniping
154
- // See: https://github.com/bitcoin/bitcoin/blob/fb0ac482eee761ec17ed2c11df11e054347a026d/src/wallet/wallet.cpp#L2133
155
- transaction.locktime = prebuild.blockHeight;
156
- return _.extend({}, prebuild, { txHex: transaction.toHex() });
121
+ return _.extend({}, prebuild, { txHex: tx.toHex() });
157
122
  }
158
123
  /**
159
124
  * Find outputs that are within expected outputs but not within actual outputs, including duplicates
@@ -162,7 +127,7 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
162
127
  * @returns {Array}
163
128
  */
164
129
  static findMissingOutputs(expectedOutputs, actualOutputs) {
165
- const keyFunc = ({ address, amount }) => `${address}:${Number(amount)}`;
130
+ const keyFunc = ({ address, amount }) => `${address}:${amount}`;
166
131
  const groupedOutputs = _.groupBy(expectedOutputs, keyFunc);
167
132
  actualOutputs.forEach((output) => {
168
133
  const group = groupedOutputs[keyFunc(output)];
@@ -212,7 +177,7 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
212
177
  throw new Error('keychains are required, but could not be fetched');
213
178
  }
214
179
  const keychainArray = [keychains.user, keychains.backup, keychains.bitgo];
215
- const keySignatures = _.get(wallet, '_wallet.keySignatures');
180
+ const keySignatures = _.get(wallet, '_wallet.keySignatures', {});
216
181
  if (_.isUndefined(txPrebuild.txHex)) {
217
182
  throw new Error('missing required txPrebuild property txHex');
218
183
  }
@@ -234,7 +199,7 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
234
199
  if (customChangeWalletId) {
235
200
  // fetch keychains from custom change wallet for deriving addresses.
236
201
  // These keychains should be signed and this should be verified in verifyTransaction
237
- const customChangeKeySignatures = _.get(wallet, '_wallet.customChangeKeySignatures', {});
202
+ const customChangeKeySignatures = wallet._wallet.customChangeKeySignatures;
238
203
  const customChangeWallet = await this.wallets().get({ id: customChangeWalletId });
239
204
  const customChangeKeys = await fetchKeychains(customChangeWallet);
240
205
  if (!customChangeKeys) {
@@ -373,10 +338,19 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
373
338
  throw new Error('key signature is required');
374
339
  }
375
340
  // verify the signature against the user public key
341
+ assert(userKeychain.pub);
376
342
  const publicKey = utxo_lib_1.bip32.fromBase58(userKeychain.pub).publicKey;
377
- const signingAddress = utxolib.address.toBase58Check(utxolib.crypto.hash160(publicKey), utxolib.networks.bitcoin.pubKeyHash, this.network);
343
+ // Due to interface of `bitcoinMessage`, we need to convert the public key to an address.
344
+ // Note that this address has no relationship to on-chain transactions. We are
345
+ // only interested in the address as a representation of the public key.
346
+ const signingAddress = utxolib.address.toBase58Check(utxolib.crypto.hash160(publicKey), utxolib.networks.bitcoin.pubKeyHash,
347
+ // we do not pass `this.network` here because it would fail for zcash
348
+ // the bitcoinMessage library decodes the address and throws away the first byte
349
+ // because zcash has a two-byte prefix, verify() decodes zcash addresses to an invalid pubkey hash
350
+ utxolib.networks.bitcoin);
378
351
  // BG-5703: use BTC mainnet prefix for all key signature operations
379
352
  // (this means do not pass a prefix parameter, and let it use the default prefix instead)
353
+ assert(keychainToVerify.pub);
380
354
  try {
381
355
  return bitcoinMessage.verify(keychainToVerify.pub, signingAddress, Buffer.from(keySignature, 'hex'));
382
356
  }
@@ -408,7 +382,11 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
408
382
  if (!keySignature) {
409
383
  throw new Error(`missing required custom change ${sdk_core_1.KeyIndices[keyIndex].toLowerCase()} keychain signature`);
410
384
  }
411
- if (!this.verifyKeySignature({ userKeychain, keychainToVerify, keySignature })) {
385
+ if (!this.verifyKeySignature({
386
+ userKeychain: userKeychain,
387
+ keychainToVerify: keychainToVerify,
388
+ keySignature,
389
+ })) {
412
390
  debug('failed to verify custom change %s key signature!', sdk_core_1.KeyIndices[keyIndex].toLowerCase());
413
391
  return false;
414
392
  }
@@ -444,7 +422,12 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
444
422
  * @returns {boolean}
445
423
  */
446
424
  async verifyTransaction(params) {
425
+ var _a;
447
426
  const { txParams, txPrebuild, wallet, verification = { allowPaygoOutput: true }, reqId } = params;
427
+ const isPsbt = txPrebuild.txHex && utxo_lib_1.bitgo.isPsbt(txPrebuild.txHex);
428
+ if (isPsbt && ((_a = txPrebuild.txInfo) === null || _a === void 0 ? void 0 : _a.unspents)) {
429
+ throw new Error('should not have unspents in txInfo for psbt');
430
+ }
448
431
  const disableNetworking = !!verification.disableNetworking;
449
432
  const parsedTransaction = await this.parseTransaction({
450
433
  txParams,
@@ -466,7 +449,16 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
466
449
  // let's verify these keychains
467
450
  const keySignatures = parsedTransaction.keySignatures;
468
451
  if (!_.isEmpty(keySignatures)) {
469
- const verify = (key, pub) => this.verifyKeySignature({ userKeychain: keychains.user, keychainToVerify: key, keySignature: pub });
452
+ const verify = (key, pub) => {
453
+ if (!keychains.user || !keychains.user.pub) {
454
+ throw new Error('missing user keychain');
455
+ }
456
+ return this.verifyKeySignature({
457
+ userKeychain: keychains.user,
458
+ keychainToVerify: key,
459
+ keySignature: pub,
460
+ });
461
+ };
470
462
  const isBackupKeySignatureValid = verify(keychains.backup, keySignatures.backupPub);
471
463
  const isBitgoKeySignatureValid = verify(keychains.bitgo, keySignatures.bitgoPub);
472
464
  if (!isBackupKeySignatureValid || !isBitgoKeySignatureValid) {
@@ -517,37 +509,12 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
517
509
  if (!txPrebuild.txHex) {
518
510
  throw new Error(`txPrebuild.txHex not set`);
519
511
  }
520
- const transaction = this.createTransactionFromHex(txPrebuild.txHex);
521
- const transactionCache = {};
522
- const inputs = await Promise.all(transaction.ins.map(async (currentInput) => {
523
- var _a, _b;
524
- const transactionId = Buffer.from(currentInput.hash).reverse().toString('hex');
525
- const txHex = (_b = (_a = txPrebuild.txInfo) === null || _a === void 0 ? void 0 : _a.txHexes) === null || _b === void 0 ? void 0 : _b[transactionId];
526
- if (txHex) {
527
- const localTx = this.createTransactionFromHex(txHex);
528
- if (localTx.getId() !== transactionId) {
529
- throw new Error('input transaction hex does not match id');
530
- }
531
- const currentOutput = localTx.outs[currentInput.index];
532
- const address = utxolib.address.fromOutputScript(currentOutput.script, this.network);
533
- return {
534
- address,
535
- value: currentOutput.value,
536
- valueString: currentOutput.value.toString(),
537
- };
538
- }
539
- else if (!transactionCache[transactionId]) {
540
- if (disableNetworking) {
541
- throw new Error('attempting to retrieve transaction details externally with networking disabled');
542
- }
543
- if (reqId) {
544
- this.bitgo.setRequestTracer(reqId);
545
- }
546
- transactionCache[transactionId] = await this.bitgo.get(this.url(`/public/tx/${transactionId}`)).result();
547
- }
548
- const transactionDetails = transactionCache[transactionId];
549
- return transactionDetails.outputs[currentInput.index];
550
- }));
512
+ const inputs = isPsbt
513
+ ? transaction_1.getPsbtTxInputs(txPrebuild.txHex, this.network).map((v) => ({
514
+ ...v,
515
+ value: utxo_lib_1.bitgo.toTNumber(v.value, this.amountType),
516
+ }))
517
+ : await transaction_1.getTxInputs({ txPrebuild, bitgo: this.bitgo, coin: this, disableNetworking, reqId });
551
518
  // coins (doge) that can exceed number limits (and thus will use bigint) will have the `valueString` field
552
519
  const inputAmount = inputs.reduce((sum, i) => sum + BigInt(this.amountType === 'bigint' ? i.valueString : i.value), BigInt(0));
553
520
  const outputAmount = allOutputs.reduce((sum, o) => sum + BigInt(o.amount), BigInt(0));
@@ -569,7 +536,7 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
569
536
  * @throws {InvalidAddressDerivationPropertyError}
570
537
  * @throws {UnexpectedAddressError}
571
538
  */
572
- isWalletAddress(params) {
539
+ async isWalletAddress(params) {
573
540
  const { address, addressType, keychains, coinSpecific, chain, index } = params;
574
541
  if (!this.isValidAddress(address)) {
575
542
  throw new sdk_core_1.InvalidAddressError(`invalid address: ${address}`);
@@ -666,6 +633,8 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
666
633
  throw new sdk_core_1.P2wshUnsupportedError();
667
634
  case 'p2tr':
668
635
  throw new sdk_core_1.P2trUnsupportedError();
636
+ case 'p2trMusig2':
637
+ throw new sdk_core_1.P2trMusig2UnsupportedError();
669
638
  default:
670
639
  throw new sdk_core_1.UnsupportedAddressTypeError();
671
640
  }
@@ -701,52 +670,171 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
701
670
  addressType,
702
671
  };
703
672
  }
673
+ /**
674
+ * @returns input psbt added with deterministic MuSig2 nonce for bitgo key for each MuSig2 inputs.
675
+ * @param psbtHex all MuSig2 inputs should contain user MuSig2 nonce
676
+ * @param walletId
677
+ */
678
+ async signPsbt(psbtHex, walletId) {
679
+ const params = { psbt: psbtHex };
680
+ return await this.bitgo
681
+ .post(this.url('/wallet/' + walletId + '/tx/signpsbt'))
682
+ .send(params)
683
+ .result();
684
+ }
704
685
  /**
705
686
  * Assemble keychain and half-sign prebuilt transaction
706
687
  * @param params - {@see SignTransactionOptions}
707
688
  * @returns {Promise<SignedTransaction | HalfSignedUtxoTransaction>}
708
689
  */
709
690
  async signTransaction(params) {
710
- var _a;
691
+ var _a, _b, _c;
711
692
  const txPrebuild = params.txPrebuild;
712
- const userPrv = params.prv;
713
693
  if (_.isUndefined(txPrebuild) || !_.isObject(txPrebuild)) {
714
694
  if (!_.isUndefined(txPrebuild) && !_.isObject(txPrebuild)) {
715
695
  throw new Error(`txPrebuild must be an object, got type ${typeof txPrebuild}`);
716
696
  }
717
697
  throw new Error('missing txPrebuild parameter');
718
698
  }
719
- const transaction = this.createTransactionFromHex(txPrebuild.txHex);
720
- if (transaction.ins.length !== txPrebuild.txInfo.unspents.length) {
721
- throw new Error('length of unspents array should equal to the number of transaction inputs');
722
- }
699
+ let tx = utxo_lib_1.bitgo.isPsbt(txPrebuild.txHex)
700
+ ? utxo_lib_1.bitgo.createPsbtFromHex(txPrebuild.txHex, this.network)
701
+ : this.createTransactionFromHex(txPrebuild.txHex);
702
+ const isTxWithKeyPathSpendInput = tx instanceof utxo_lib_1.bitgo.UtxoPsbt && utxo_lib_1.bitgo.isTransactionWithKeyPathSpendInput(tx);
723
703
  let isLastSignature = false;
724
704
  if (_.isBoolean(params.isLastSignature)) {
705
+ // We can only be the first signature on a transaction with taproot key path spend inputs because
706
+ // we require the secret nonce in the cache of the first signer, which is impossible to retrieve if
707
+ // deserialized from a hex.
708
+ if (params.isLastSignature && isTxWithKeyPathSpendInput) {
709
+ throw new Error('Cannot be last signature on a transaction with key path spend inputs');
710
+ }
725
711
  // if build is called instead of buildIncomplete, no signature placeholders are left in the sig script
726
712
  isLastSignature = params.isLastSignature;
727
713
  }
728
- if (_.isUndefined(userPrv) || !_.isString(userPrv)) {
729
- if (!_.isUndefined(userPrv)) {
730
- throw new Error(`prv must be a string, got type ${typeof userPrv}`);
714
+ const getSignerKeychain = () => {
715
+ const userPrv = params.prv;
716
+ if (_.isUndefined(userPrv) || !_.isString(userPrv)) {
717
+ if (!_.isUndefined(userPrv)) {
718
+ throw new Error(`prv must be a string, got type ${typeof userPrv}`);
719
+ }
720
+ throw new Error('missing prv parameter to sign transaction');
721
+ }
722
+ const signerKeychain = utxo_lib_1.bip32.fromBase58(userPrv, utxolib.networks.bitcoin);
723
+ if (signerKeychain.isNeutered()) {
724
+ throw new Error('expected user private key but received public key');
725
+ }
726
+ debug(`Here is the public key of the xprv you used to sign: ${signerKeychain.neutered().toBase58()}`);
727
+ return signerKeychain;
728
+ };
729
+ let signerKeychain;
730
+ if (tx instanceof utxo_lib_1.bitgo.UtxoPsbt && isTxWithKeyPathSpendInput) {
731
+ switch (params.signingStep) {
732
+ case 'signerNonce':
733
+ signerKeychain = getSignerKeychain();
734
+ tx.setAllInputsMusig2NonceHD(signerKeychain);
735
+ AbstractUtxoCoin.PSBT_CACHE.set(tx.getUnsignedTx().getId(), tx);
736
+ return { txHex: tx.toHex() };
737
+ case 'cosignerNonce':
738
+ assert(txPrebuild.walletId, 'walletId is required for MuSig2 bitgo nonce');
739
+ return { txHex: (await this.signPsbt(tx.toHex(), txPrebuild.walletId)).psbt };
740
+ case 'signerSignature':
741
+ const txId = tx.getUnsignedTx().getId();
742
+ const psbt = AbstractUtxoCoin.PSBT_CACHE.get(txId);
743
+ assert(psbt, `Psbt is missing from txCache (cache size ${AbstractUtxoCoin.PSBT_CACHE.size}).
744
+ This may be due to the request being routed to a different BitGo-Express instance that for signing step 'signerNonce'.`);
745
+ AbstractUtxoCoin.PSBT_CACHE.delete(txId);
746
+ tx = psbt.combine(tx);
747
+ break;
748
+ default:
749
+ // this instance is not an external signer
750
+ assert(txPrebuild.walletId, 'walletId is required for MuSig2 bitgo nonce');
751
+ signerKeychain = getSignerKeychain();
752
+ tx.setAllInputsMusig2NonceHD(signerKeychain);
753
+ const response = await this.signPsbt(tx.toHex(), txPrebuild.walletId);
754
+ tx.combine(utxo_lib_1.bitgo.createPsbtFromHex(response.psbt, this.network));
755
+ break;
756
+ }
757
+ }
758
+ else {
759
+ switch (params.signingStep) {
760
+ case 'signerNonce':
761
+ case 'cosignerNonce':
762
+ /**
763
+ * In certain cases, the caller of this method may not know whether the txHex contains a psbt with taproot key path spend input(s).
764
+ * Instead of throwing error, no-op and return the txHex. So that the caller can call this method in the same sequence.
765
+ */
766
+ return { txHex: tx.toHex() };
731
767
  }
732
- throw new Error('missing prv parameter to sign transaction');
733
768
  }
734
- if (!params.pubs || params.pubs.length !== 3) {
735
- throw new Error(`must provide xpub array`);
769
+ if (signerKeychain === undefined) {
770
+ signerKeychain = getSignerKeychain();
736
771
  }
737
- const signerKeychain = utxo_lib_1.bip32.fromBase58(userPrv, utxolib.networks.bitcoin);
738
- if (signerKeychain.isNeutered()) {
739
- throw new Error('expected user private key but received public key');
772
+ let signedTransaction;
773
+ if (tx instanceof utxo_lib_1.bitgo.UtxoPsbt) {
774
+ signedTransaction = sign_1.signAndVerifyPsbt(tx, signerKeychain, { isLastSignature });
775
+ }
776
+ else {
777
+ if (tx.ins.length !== ((_b = (_a = txPrebuild.txInfo) === null || _a === void 0 ? void 0 : _a.unspents) === null || _b === void 0 ? void 0 : _b.length)) {
778
+ throw new Error('length of unspents array should equal to the number of transaction inputs');
779
+ }
780
+ if (!params.pubs || !sdk_core_1.isTriple(params.pubs)) {
781
+ throw new Error(`must provide xpub array`);
782
+ }
783
+ const keychains = params.pubs.map((pub) => utxo_lib_1.bip32.fromBase58(pub));
784
+ const cosignerPub = (_c = params.cosignerPub) !== null && _c !== void 0 ? _c : params.pubs[2];
785
+ const cosignerKeychain = utxo_lib_1.bip32.fromBase58(cosignerPub);
786
+ const walletSigner = new utxo_lib_1.bitgo.WalletUnspentSigner(keychains, signerKeychain, cosignerKeychain);
787
+ signedTransaction = sign_1.signAndVerifyWalletTransaction(tx, txPrebuild.txInfo.unspents, walletSigner, {
788
+ isLastSignature,
789
+ });
740
790
  }
741
- debug(`Here is the public key of the xprv you used to sign: ${signerKeychain.neutered().toBase58()}`);
742
- const cosignerPub = (_a = params.cosignerPub) !== null && _a !== void 0 ? _a : params.pubs[2];
743
- const keychains = params.pubs.map((pub) => utxo_lib_1.bip32.fromBase58(pub));
744
- const cosignerKeychain = utxo_lib_1.bip32.fromBase58(cosignerPub);
745
- const signedTransaction = sign_1.signAndVerifyWalletTransaction(transaction, txPrebuild.txInfo.unspents, new utxo_lib_1.bitgo.WalletUnspentSigner(keychains, signerKeychain, cosignerKeychain), { isLastSignature });
746
791
  return {
747
792
  txHex: signedTransaction.toBuffer().toString('hex'),
748
793
  };
749
794
  }
795
+ /**
796
+ * Sign a transaction with a custom signing function. Example use case is express external signer
797
+ * @param customSigningFunction custom signing function that returns a single signed transaction
798
+ * @param signTransactionParams parameters for custom signing function. Includes txPrebuild and pubs (for legacy tx only).
799
+ *
800
+ * @returns signed transaction as hex string
801
+ */
802
+ async signWithCustomSigningFunction(customSigningFunction, signTransactionParams) {
803
+ const txHex = signTransactionParams.txPrebuild.txHex;
804
+ assert(txHex, 'missing txHex parameter');
805
+ const tx = utxo_lib_1.bitgo.isPsbt(txHex)
806
+ ? utxo_lib_1.bitgo.createPsbtFromHex(txHex, this.network)
807
+ : this.createTransactionFromHex(txHex);
808
+ const isTxWithKeyPathSpendInput = tx instanceof utxo_lib_1.bitgo.UtxoPsbt && utxo_lib_1.bitgo.isTransactionWithKeyPathSpendInput(tx);
809
+ if (!isTxWithKeyPathSpendInput) {
810
+ return await customSigningFunction({ ...signTransactionParams, coin: this });
811
+ }
812
+ const getTxHex = (v) => {
813
+ if ('txHex' in v) {
814
+ return v.txHex;
815
+ }
816
+ throw new Error('txHex not found in signTransaction result');
817
+ };
818
+ const signerNonceTx = await customSigningFunction({
819
+ ...signTransactionParams,
820
+ signingStep: 'signerNonce',
821
+ coin: this,
822
+ });
823
+ const { pubs } = signTransactionParams;
824
+ assert(pubs === undefined || sdk_core_1.isTriple(pubs));
825
+ const cosignerNonceTx = await this.signTransaction({
826
+ ...signTransactionParams,
827
+ pubs,
828
+ txPrebuild: { ...signTransactionParams.txPrebuild, txHex: getTxHex(signerNonceTx) },
829
+ signingStep: 'cosignerNonce',
830
+ });
831
+ return await customSigningFunction({
832
+ ...signTransactionParams,
833
+ txPrebuild: { ...signTransactionParams.txPrebuild, txHex: getTxHex(cosignerNonceTx) },
834
+ signingStep: 'signerSignature',
835
+ coin: this,
836
+ });
837
+ }
750
838
  /**
751
839
  * @param unspent
752
840
  * @returns {boolean}
@@ -774,89 +862,16 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
774
862
  });
775
863
  }
776
864
  /**
777
- * Decompose a raw transaction into useful information, such as the total amounts,
865
+ * Decompose a raw psbt/transaction into useful information, such as the total amounts,
778
866
  * change amounts, and transaction outputs.
779
867
  * @param params
780
868
  */
781
869
  async explainTransaction(params) {
782
- var _a, _b, _c;
783
- const txHex = _.get(params, 'txHex');
784
- if (!txHex || !_.isString(txHex) || !txHex.match(/^([a-f0-9]{2})+$/i)) {
870
+ const { txHex } = params;
871
+ if (typeof txHex !== 'string' || !txHex.match(/^([a-f0-9]{2})+$/i)) {
785
872
  throw new Error('invalid transaction hex, must be a valid hex string');
786
873
  }
787
- let transaction;
788
- try {
789
- transaction = this.createTransactionFromHex(txHex);
790
- }
791
- catch (e) {
792
- throw new Error('failed to parse transaction hex');
793
- }
794
- const id = transaction.getId();
795
- let spendAmount = utxolib.bitgo.toTNumber(0, this.amountType);
796
- let changeAmount = utxolib.bitgo.toTNumber(0, this.amountType);
797
- const explanation = {
798
- displayOrder: ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs'],
799
- id: id,
800
- outputs: [],
801
- changeOutputs: [],
802
- };
803
- const { changeAddresses = [], unspents = [] } = (_a = params.txInfo) !== null && _a !== void 0 ? _a : {};
804
- transaction.outs.forEach((currentOutput) => {
805
- const currentAddress = utxolib.address.fromOutputScript(currentOutput.script, this.network);
806
- const currentAmount = currentOutput.value;
807
- if (changeAddresses.includes(currentAddress)) {
808
- // this is change
809
- changeAmount += currentAmount;
810
- explanation.changeOutputs.push({
811
- address: currentAddress,
812
- amount: currentAmount.toString(),
813
- });
814
- return;
815
- }
816
- spendAmount += currentAmount;
817
- explanation.outputs.push({
818
- address: currentAddress,
819
- amount: currentAmount.toString(),
820
- });
821
- });
822
- explanation.outputAmount = spendAmount.toString();
823
- explanation.changeAmount = changeAmount.toString();
824
- // add fee info if available
825
- if (params.feeInfo) {
826
- explanation.displayOrder.push('fee');
827
- explanation.fee = params.feeInfo;
828
- }
829
- if (_.isInteger(transaction.locktime) && transaction.locktime > 0) {
830
- explanation.locktime = transaction.locktime;
831
- explanation.displayOrder.push('locktime');
832
- }
833
- const prevOutputs = (_b = params.txInfo) === null || _b === void 0 ? void 0 : _b.unspents.map((u) => toOutput(u, this.network));
834
- // if keys are provided, prepare the keys for input signature checking
835
- const keys = (_c = params.pubs) === null || _c === void 0 ? void 0 : _c.map((xpub) => utxo_lib_1.bip32.fromBase58(xpub));
836
- const walletKeys = keys && keys.length === 3 ? new utxo_lib_1.bitgo.RootWalletKeys(keys) : undefined;
837
- // get the number of signatures per input
838
- const inputSignatureCounts = transaction.ins.map((input, idx) => {
839
- if (unspents.length !== transaction.ins.length) {
840
- return 0;
841
- }
842
- if (!prevOutputs) {
843
- throw new Error(`invalid state`);
844
- }
845
- if (!walletKeys) {
846
- // no pub keys or incorrect number of pub keys
847
- return 0;
848
- }
849
- try {
850
- return verifySignatureWithUnspent(transaction, idx, unspents, walletKeys).filter((v) => v).length;
851
- }
852
- catch (e) {
853
- // some other error occurred and we can't validate the signatures
854
- return 0;
855
- }
856
- });
857
- explanation.inputSignatures = inputSignatureCounts;
858
- explanation.signatures = _.max(inputSignatureCounts);
859
- return explanation;
874
+ return utxolib.bitgo.isPsbt(txHex) ? transaction_1.explainPsbt(params, this.network) : transaction_1.explainTx(params, this);
860
875
  }
861
876
  /**
862
877
  * Create a multisig address of a given type from a list of keychains and a signing threshold
@@ -891,10 +906,11 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
891
906
  * @param params.signed return a half-signed transaction (default=true)
892
907
  * @param params.walletPassphrase the wallet passphrase
893
908
  * @param params.xprv the unencrypted xprv (used instead of wallet passphrase)
909
+ * @param params.apiKey for utxo coins other than [BTC,TBTC] this is a Block Chair api key
894
910
  * @returns {*}
895
911
  */
896
912
  async recoverFromWrongChain(params) {
897
- const { txid, recoveryAddress, wallet, walletPassphrase, xprv } = params;
913
+ const { txid, recoveryAddress, wallet, walletPassphrase, xprv, apiKey } = params;
898
914
  // params.recoveryCoin used to be params.coin, backwards compatibility
899
915
  const recoveryCoin = params.coin || params.recoveryCoin;
900
916
  if (!recoveryCoin) {
@@ -916,6 +932,7 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
916
932
  recoveryAddress,
917
933
  walletPassphrase: signed ? walletPassphrase : undefined,
918
934
  xprv: signed ? xprv : undefined,
935
+ apiKey,
919
936
  });
920
937
  }
921
938
  /**
@@ -955,6 +972,18 @@ class AbstractUtxoCoin extends sdk_core_1.BaseCoin {
955
972
  valuelessTransferAllowed() {
956
973
  return false;
957
974
  }
975
+ getRecoveryProvider(apiToken) {
976
+ return recovery_1.forCoin(this.getChain(), apiToken);
977
+ }
958
978
  }
959
979
  exports.AbstractUtxoCoin = AbstractUtxoCoin;
960
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RVdHhvQ29pbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hYnN0cmFjdFV0eG9Db2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOztHQUVHO0FBQ0gsZ0RBQWdEO0FBQ2hELG1EQUFvRTtBQUNwRSxvREFBb0Q7QUFDcEQsbUNBQXFDO0FBQ3JDLGtDQUFrQztBQUNsQyw0QkFBNEI7QUFDNUIsK0NBQXFDO0FBRXJDLG9FQUFnRjtBQUNoRix5Q0FBcUc7QUFFckcsbURBdUM4QjtBQUM5QiwrQ0FBaUU7QUFFakUsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBR3hDLHlEQUErRDtBQUMvRCxpQ0FBd0Q7QUFDeEQscUNBQXlEO0FBRXpELE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSwwQkFBMEIsRUFBRSxHQUNsSCxnQkFBSyxDQUFDO0FBbUtSLE1BQXNCLGdCQUFpQixTQUFRLG1CQUFRO0lBTXJELFlBQXNCLEtBQWdCLEVBQUUsT0FBd0IsRUFBRSxhQUFrQyxRQUFRO1FBQzFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNiLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQ2IsK0RBQStEO2dCQUM3RCxrRkFBa0YsQ0FDckYsQ0FBQztTQUNIO1FBQ0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLE1BQU0sS0FBSyxpQkFBaUI7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QUFJLEVBQUU7WUFDVCwwRUFBMEU7WUFDMUUsMEVBQTBFO1lBQzFFLGtFQUFrRTtZQUNsRSxJQUFJLEdBQUcsb0JBQVcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDN0I7UUFDRCxNQUFNLFdBQVcsR0FBRyxnQkFBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxPQUFPO1lBQ0wsR0FBRyxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDdEMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUU7U0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsc0JBQXNCLENBQUMsV0FBdUM7UUFDbEUsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsY0FBYyxDQUFDLE1BQTZCO1FBQzFDLE9BQU87SUFDVCxDQUFDO0lBRUQsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQWlDO1FBQ3hELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxLQUFLLENBQUMsd0JBQXdCLENBQzVCLFlBQTZDLEVBQzdDLFNBQTJCO1FBRTNCLE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxzQkFBc0I7UUFDcEIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsd0JBQXdCO1FBQ3RCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGO0FBN25DRCw0Q0E2bkNDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgeyBiaXAzMiwgQklQMzJJbnRlcmZhY2UsIGJpdGdvIH0gZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0ICogYXMgYml0Y29pbk1lc3NhZ2UgZnJvbSAnYml0Y29pbmpzLW1lc3NhZ2UnO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgZGVidWdMaWIgZnJvbSAnZGVidWcnO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuXG5pbXBvcnQgeyBiYWNrdXBLZXlSZWNvdmVyeSwgUmVjb3ZlclBhcmFtcyB9IGZyb20gJy4vcmVjb3ZlcnkvYmFja3VwS2V5UmVjb3ZlcnknO1xuaW1wb3J0IHsgQ3Jvc3NDaGFpblJlY292ZXJ5U2lnbmVkLCBDcm9zc0NoYWluUmVjb3ZlcnlVbnNpZ25lZCwgcmVjb3ZlckNyb3NzQ2hhaW4gfSBmcm9tICcuL3JlY292ZXJ5JztcblxuaW1wb3J0IHtcbiAgQWRkcmVzc0NvaW5TcGVjaWZpYyxcbiAgQWRkcmVzc1R5cGVDaGFpbk1pc21hdGNoRXJyb3IsXG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIEV4dHJhUHJlYnVpbGRQYXJhbXNPcHRpb25zLFxuICBIYWxmU2lnbmVkVXR4b1RyYW5zYWN0aW9uLFxuICBJbnZhbGlkQWRkcmVzc0Rlcml2YXRpb25Qcm9wZXJ0eUVycm9yLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3IsXG4gIElSZXF1ZXN0VHJhY2VyLFxuICBJVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBhcyBCYXNlVHJhbnNhY3Rpb25FeHBsYW5hdGlvbixcbiAgSVdhbGxldCxcbiAgS2V5Y2hhaW4sXG4gIEtleWNoYWluc1RyaXBsZXQsXG4gIEtleUluZGljZXMsXG4gIFAyc2hQMndzaFVuc3VwcG9ydGVkRXJyb3IsXG4gIFAydHJVbnN1cHBvcnRlZEVycm9yLFxuICBQMndzaFVuc3VwcG9ydGVkRXJyb3IsXG4gIFBhcnNlZFRyYW5zYWN0aW9uIGFzIEJhc2VQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMgYXMgQmFzZVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zLFxuICBQcmVjcmVhdGVCaXRHb09wdGlvbnMsXG4gIFByZXNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIHByb21pc2VQcm9wcyxcbiAgUmVxdWVzdFRyYWNlcixcbiAgc2FuaXRpemVMZWdhY3lQYXRoLFxuICBTaWduZWRUcmFuc2FjdGlvbixcbiAgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlU2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25QYXJhbXMgYXMgQmFzZVRyYW5zYWN0aW9uUGFyYW1zLFxuICBUcmFuc2FjdGlvblByZWJ1aWxkIGFzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkLFxuICBUcmFuc2FjdGlvblJlY2lwaWVudCxcbiAgVHJpcGxlLFxuICBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yLFxuICBVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXJyb3IsXG4gIFZlcmlmaWNhdGlvbk9wdGlvbnMsXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zIGFzIEJhc2VWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zIGFzIEJhc2VWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQ3VzdG9tQ2hhbmdlT3B0aW9ucywgcGFyc2VPdXRwdXQgfSBmcm9tICcuL3BhcnNlT3V0cHV0JztcblxuY29uc3QgZGVidWcgPSBkZWJ1Z0xpYignYml0Z286djI6dXR4bycpO1xuXG5pbXBvcnQgU2NyaXB0VHlwZTJPZjMgPSB1dHhvbGliLmJpdGdvLm91dHB1dFNjcmlwdHMuU2NyaXB0VHlwZTJPZjM7XG5pbXBvcnQgeyBpc1JlcGxheVByb3RlY3Rpb25VbnNwZW50IH0gZnJvbSAnLi9yZXBsYXlQcm90ZWN0aW9uJztcbmltcG9ydCB7IHNpZ25BbmRWZXJpZnlXYWxsZXRUcmFuc2FjdGlvbiB9IGZyb20gJy4vc2lnbic7XG5pbXBvcnQgeyBzdXBwb3J0ZWRDcm9zc0NoYWluUmVjb3ZlcmllcyB9IGZyb20gJy4vY29uZmlnJztcblxuY29uc3QgeyBnZXRFeHRlcm5hbENoYWluQ29kZSwgaXNDaGFpbkNvZGUsIHNjcmlwdFR5cGVGb3JDaGFpbiwgb3V0cHV0U2NyaXB0cywgdG9PdXRwdXQsIHZlcmlmeVNpZ25hdHVyZVdpdGhVbnNwZW50IH0gPVxuICBiaXRnbztcbnR5cGUgVW5zcGVudDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiA9IGJpdGdvLlVuc3BlbnQ8VE51bWJlcj47XG50eXBlIFJvb3RXYWxsZXRLZXlzID0gYml0Z28uUm9vdFdhbGxldEtleXM7XG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeUFkZHJlc3NPcHRpb25zIGV4dGVuZHMgQmFzZVZlcmlmeUFkZHJlc3NPcHRpb25zIHtcbiAgY2hhaW46IG51bWJlcjtcbiAgaW5kZXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPdXRwdXQge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGFtb3VudDogc3RyaW5nIHwgbnVtYmVyO1xuICBleHRlcm5hbD86IGJvb2xlYW47XG4gIG5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uRXhwbGFuYXRpb248c3RyaW5nLCBzdHJpbmc+IHtcbiAgbG9ja3RpbWU6IG51bWJlcjtcbiAgb3V0cHV0czogT3V0cHV0W107XG4gIGNoYW5nZU91dHB1dHM6IE91dHB1dFtdO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaW5wdXQgc2lnbmF0dXJlcyBwZXIgaW5wdXQuXG4gICAqL1xuICBpbnB1dFNpZ25hdHVyZXM6IG51bWJlcltdO1xuXG4gIC8qKlxuICAgKiBIaWdoZXN0IGlucHV0IHNpZ25hdHVyZSBjb3VudCBmb3IgdGhlIHRyYW5zYWN0aW9uXG4gICAqL1xuICBzaWduYXR1cmVzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25JbmZvPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+IHtcbiAgLyoqIE1hcHMgdHhpZCB0byB0eGhleC4gUmVxdWlyZWQgZm9yIG9mZmxpbmUgc2lnbmluZy4gKi9cbiAgdHhIZXhlcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGNoYW5nZUFkZHJlc3Nlcz86IHN0cmluZ1tdO1xuICB1bnNwZW50czogVW5zcGVudDxUTnVtYmVyPltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4ge1xuICB0eEhleDogc3RyaW5nO1xuICB0eEluZm8/OiBUcmFuc2FjdGlvbkluZm88VE51bWJlcj47XG4gIGZlZUluZm8/OiBzdHJpbmc7XG4gIHB1YnM/OiBUcmlwbGU8c3RyaW5nPjtcbn1cblxuZXhwb3J0IHR5cGUgVXR4b05ldHdvcmsgPSB1dHhvbGliLk5ldHdvcms7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25QcmVidWlsZDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiBleHRlbmRzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhJbmZvPzogVHJhbnNhY3Rpb25JbmZvPFROdW1iZXI+O1xuICBibG9ja0hlaWdodD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblBhcmFtcyBleHRlbmRzIEJhc2VUcmFuc2FjdGlvblBhcmFtcyB7XG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmc7XG4gIGNoYW5nZUFkZHJlc3M/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4gZXh0ZW5kcyBCYXNlUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFBhcmFtczogVHJhbnNhY3Rpb25QYXJhbXM7XG4gIHR4UHJlYnVpbGQ6IFRyYW5zYWN0aW9uUHJlYnVpbGQ8VE51bWJlcj47XG4gIHdhbGxldDogSVdhbGxldDtcbiAgdmVyaWZpY2F0aW9uPzogVmVyaWZpY2F0aW9uT3B0aW9ucztcbiAgcmVxSWQ/OiBJUmVxdWVzdFRyYWNlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXJzZWRUcmFuc2FjdGlvbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPiBleHRlbmRzIEJhc2VQYXJzZWRUcmFuc2FjdGlvbiB7XG4gIGtleWNoYWluczoge1xuICAgIHVzZXI/OiBLZXljaGFpbjtcbiAgICBiYWNrdXA/OiBLZXljaGFpbjtcbiAgICBiaXRnbz86IEtleWNoYWluO1xuICB9O1xuICBrZXlTaWduYXR1cmVzOiB7XG4gICAgYmFja3VwUHViPzogc3RyaW5nO1xuICAgIGJpdGdvUHViPzogc3RyaW5nO1xuICB9O1xuICBvdXRwdXRzOiBPdXRwdXRbXTtcbiAgbWlzc2luZ091dHB1dHM6IE91dHB1dFtdO1xuICBleHBsaWNpdEV4dGVybmFsT3V0cHV0czogT3V0cHV0W107XG4gIGltcGxpY2l0RXh0ZXJuYWxPdXRwdXRzOiBPdXRwdXRbXTtcbiAgY2hhbmdlT3V0cHV0czogT3V0cHV0W107XG4gIGV4cGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudDogVE51bWJlcjtcbiAgaW1wbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50OiBUTnVtYmVyO1xuICBuZWVkc0N1c3RvbUNoYW5nZUtleVNpZ25hdHVyZVZlcmlmaWNhdGlvbjogYm9vbGVhbjtcbiAgY3VzdG9tQ2hhbmdlPzogQ3VzdG9tQ2hhbmdlT3B0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmF0ZUFkZHJlc3NPcHRpb25zIHtcbiAgYWRkcmVzc1R5cGU/OiBTY3JpcHRUeXBlMk9mMztcbiAga2V5Y2hhaW5zOiB7XG4gICAgcHViOiBzdHJpbmc7XG4gICAgYXNwS2V5SWQ/OiBzdHJpbmc7XG4gIH1bXTtcbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICBjaGFpbj86IG51bWJlcjtcbiAgaW5kZXg/OiBudW1iZXI7XG4gIHNlZ3dpdD86IGJvb2xlYW47XG4gIGJlY2gzMj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkcmVzc0RldGFpbHMge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG4gIGNvaW46IHN0cmluZztcbiAgY29pblNwZWNpZmljOiBBZGRyZXNzQ29pblNwZWNpZmljO1xuICBhZGRyZXNzVHlwZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaWduVHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+IGV4dGVuZHMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICAvKiogVHJhbnNhY3Rpb24gcHJlYnVpbGQgZnJvbSBiaXRnbyBzZXJ2ZXIgKi9cbiAgdHhQcmVidWlsZDoge1xuICAgIHR4SGV4OiBzdHJpbmc7XG4gICAgdHhJbmZvOiBUcmFuc2FjdGlvbkluZm88VE51bWJlcj47XG4gIH07XG4gIC8qKiB4cHJ2IG9mIHVzZXIga2V5IG9yIGJhY2t1cCBrZXkgKi9cbiAgcHJ2OiBzdHJpbmc7XG4gIC8qKiB4cHVicyB0cmlwbGUgZm9yIHdhbGxldCAodXNlciwgYmFja3VwLCBiaXRnbykgKi9cbiAgcHViczogVHJpcGxlPHN0cmluZz47XG4gIC8qKiB4cHViIGZvciBjb3NpZ25lciAoZGVmYXVsdHMgdG8gYml0Z28pICovXG4gIGNvc2lnbmVyUHViPzogc3RyaW5nO1xuICAvKipcbiAgICogV2hlbiB0cnVlLCBjcmVhdGVzIGZ1bGwtc2lnbmVkIHRyYW5zYWN0aW9uIHdpdGhvdXQgcGxhY2Vob2xkZXIgc2lnbmF0dXJlcy5cbiAgICogV2hlbiBmYWxzZSwgY3JlYXRlcyBoYWxmLXNpZ25lZCB0cmFuc2FjdGlvbiB3aXRoIHBsYWNlaG9sZGVyIHNpZ25hdHVyZXMuXG4gICAqL1xuICBpc0xhc3RTaWduYXR1cmU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE11bHRpU2lnQWRkcmVzcyB7XG4gIG91dHB1dFNjcmlwdDogQnVmZmVyO1xuICByZWRlZW1TY3JpcHQ/OiBCdWZmZXI7XG4gIHdpdG5lc3NTY3JpcHQ/OiBCdWZmZXI7XG4gIGFkZHJlc3M6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyRnJvbVdyb25nQ2hhaW5PcHRpb25zIHtcbiAgdHhpZDogc3RyaW5nO1xuICByZWNvdmVyeUFkZHJlc3M6IHN0cmluZztcbiAgd2FsbGV0OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmc7XG4gIHhwcnY/OiBzdHJpbmc7XG4gIC8qKiBAZGVwcmVjYXRlZCAqL1xuICBjb2luPzogQWJzdHJhY3RVdHhvQ29pbjtcbiAgcmVjb3ZlcnlDb2luPzogQWJzdHJhY3RVdHhvQ29pbjtcbiAgc2lnbmVkPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlLZXlTaWduYXR1cmVzT3B0aW9ucyB7XG4gIHVzZXJLZXljaGFpbj86IEtleWNoYWluO1xuICBrZXljaGFpblRvVmVyaWZ5PzogS2V5Y2hhaW47XG4gIGtleVNpZ25hdHVyZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlVc2VyUHVibGljS2V5T3B0aW9ucyB7XG4gIHVzZXJLZXljaGFpbj86IEtleWNoYWluO1xuICBkaXNhYmxlTmV0d29ya2luZzogYm9vbGVhbjtcbiAgdHhQYXJhbXM6IFRyYW5zYWN0aW9uUGFyYW1zO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9uczxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPlxuICBleHRlbmRzIEJhc2VWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkPFROdW1iZXI+O1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RVdHhvQ29pbiBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHVibGljIGFsdFNjcmlwdEhhc2g/OiBudW1iZXI7XG4gIHB1YmxpYyBzdXBwb3J0QWx0U2NyaXB0RGVzdGluYXRpb24/OiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgYW1vdW50VHlwZTogJ251bWJlcicgfCAnYmlnaW50JztcbiAgcHJpdmF0ZSByZWFkb25seSBfbmV0d29yazogdXR4b2xpYi5OZXR3b3JrO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmssIGFtb3VudFR5cGU6ICdudW1iZXInIHwgJ2JpZ2ludCcgPSAnbnVtYmVyJykge1xuICAgIHN1cGVyKGJpdGdvKTtcbiAgICBpZiAoIXV0eG9saWIuaXNWYWxpZE5ldHdvcmsobmV0d29yaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2ludmFsaWQgbmV0d29yazogcGxlYXNlIG1ha2Ugc3VyZSB0byB1c2UgdGhlIHNhbWUgdmVyc2lvbiBvZiAnICtcbiAgICAgICAgICAnQGJpdGdvLWJldGEvdXR4by1saWIgYXMgdGhpcyBsaWJyYXJ5IHdoZW4gaW5pdGlhbGl6aW5nIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MnXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmFtb3VudFR5cGUgPSBhbW91bnRUeXBlO1xuICAgIHRoaXMuX25ldHdvcmsgPSBuZXR3b3JrO1xuICB9XG5cbiAgZ2V0IG5ldHdvcmsoKSB7XG4gICAgcmV0dXJuIHRoaXMuX25ldHdvcms7XG4gIH1cblxuICBzd2VlcFdpdGhTZW5kTWFueSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCAqL1xuICBzdGF0aWMgZ2V0IHZhbGlkQWRkcmVzc1R5cGVzKCk6IFNjcmlwdFR5cGUyT2YzW10ge1xuICAgIHJldHVybiBbLi4ub3V0cHV0U2NyaXB0cy5zY3JpcHRUeXBlczJPZjNdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGZhY3RvciBiZXR3ZWVuIHRoZSBiYXNlIHVuaXQgYW5kIGl0cyBzbWFsbGVzdCBzdWJkaXZpc29uXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldEJhc2VGYWN0b3IoKSB7XG4gICAgcmV0dXJuIDFlODtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZFxuICAgKi9cbiAgZ2V0Q29pbkxpYnJhcnkoKSB7XG4gICAgcmV0dXJuIHV0eG9saWI7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIGdldCB0aGUgdmVyc2lvbiBudW1iZXIgZm9yIGFuIGFkZHJlc3NcbiAgICovXG4gIHByb3RlY3RlZCBnZXRBZGRyZXNzVmVyc2lvbihhZGRyZXNzOiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIC8vIHRyeSBkZWNvZGluZyBhcyBiYXNlNTggZmlyc3RcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyB2ZXJzaW9uIH0gPSB1dHhvbGliLmFkZHJlc3MuZnJvbUJhc2U1OENoZWNrKGFkZHJlc3MsIHRoaXMubmV0d29yayk7XG4gICAgICByZXR1cm4gdmVyc2lvbjtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyB0cnkgbmV4dCBmb3JtYXRcbiAgICB9XG5cbiAgICAvLyBpZiBjb2luIGRvZXMgbm90IHN1cHBvcnQgc2NyaXB0IHR5cGVzIHdpdGggYmVjaDMyIGVuY29kaW5nLCBkbyBub3QgYXR0ZW1wdCB0byBwYXJzZVxuICAgIGlmICghdGhpcy5zdXBwb3J0c0FkZHJlc3NUeXBlKCdwMndzaCcpICYmICF0aGlzLnN1cHBvcnRzQWRkcmVzc1R5cGUoJ3AydHInKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIG90aGVyd2lzZSwgdHJ5IGRlY29kaW5nIGFzIGJlY2gzMlxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IHZlcnNpb24sIHByZWZpeCB9ID0gdXR4b2xpYi5hZGRyZXNzLmZyb21CZWNoMzIoYWRkcmVzcyk7XG4gICAgICBpZiAoXy5pc1N0cmluZyh0aGlzLm5ldHdvcmsuYmVjaDMyKSAmJiBwcmVmaXggPT09IHRoaXMubmV0d29yay5iZWNoMzIpIHtcbiAgICAgICAgcmV0dXJuIHZlcnNpb247XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWdub3JlIGVycm9ycywganVzdCBmYWxsIHRocm91Z2ggYW5kIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIGdldCB0aGUgYmVjaDMyIHByZWZpeCBmb3IgYW4gYWRkcmVzc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldEFkZHJlc3NQcmVmaXgoYWRkcmVzczogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICAvLyBvdGhlcndpc2UsIHRyeSBkZWNvZGluZyBhcyBiZWNoMzJcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBwcmVmaXggfSA9IHV0eG9saWIuYWRkcmVzcy5mcm9tQmVjaDMyKGFkZHJlc3MpO1xuICAgICAgcmV0dXJuIHByZWZpeDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBpZ25vcmUgZXJyb3JzLCBqdXN0IGZhbGwgdGhyb3VnaCBhbmQgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhZGRyZXNzIGlzIHZhbGlkXG4gICAqIEBwYXJhbSBhZGRyZXNzXG4gICAqIEBwYXJhbSBmb3JjZUFsdFNjcmlwdFN1cHBvcnRcbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZywgZm9yY2VBbHRTY3JpcHRTdXBwb3J0ID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICBjb25zdCB2YWxpZFZlcnNpb25zOiBudW1iZXJbXSA9IFt0aGlzLm5ldHdvcmsucHViS2V5SGFzaCwgdGhpcy5uZXR3b3JrLnNjcmlwdEhhc2hdO1xuICAgIGlmICh0aGlzLmFsdFNjcmlwdEhhc2ggJiYgKGZvcmNlQWx0U2NyaXB0U3VwcG9ydCB8fCB0aGlzLnN1cHBvcnRBbHRTY3JpcHREZXN0aW5hdGlvbikpIHtcbiAgICAgIHZhbGlkVmVyc2lvbnMucHVzaCh0aGlzLmFsdFNjcmlwdEhhc2gpO1xuICAgIH1cblxuICAgIGNvbnN0IGFkZHJlc3NWZXJzaW9uID0gdGhpcy5nZXRBZGRyZXNzVmVyc2lvbihhZGRyZXNzKTtcblxuICAgIC8vIHRoZSBhZGRyZXNzIHZlcnNpb24gbmVlZHMgdG8gYmUgYW1vbmcgdGhlIHZhbGlkIG9uZXNcbiAgICBjb25zdCBhZGRyZXNzVmVyc2lvblZhbGlkID0gXy5pc051bWJlcihhZGRyZXNzVmVyc2lvbikgJiYgdmFsaWRWZXJzaW9ucy5pbmNsdWRlcyhhZGRyZXNzVmVyc2lvbik7XG4gICAgY29uc3QgYWRkcmVzc1ByZWZpeCA9IHRoaXMuZ2V0QWRkcmVzc1ByZWZpeChhZGRyZXNzKTtcblxuICAgIGlmICghdGhpcy5zdXBwb3J0c0FkZHJlc3NUeXBlKCdwMndzaCcpIHx8IF8uaXNVbmRlZmluZWQoYWRkcmVzc1ByZWZpeCkpIHtcbiAgICAgIHJldHVybiBhZGRyZXNzVmVyc2lvblZhbGlkO1xuICAgIH1cblxuICAgIC8vIGFkZHJlc3MgaGFzIGEgcG90ZW50aWFsIGJlY2gzMiBwcmVmaXgsIHZhbGlkYXRlIHRoYXRcbiAgICByZXR1cm4gKFxuICAgICAgXy5pc1N0cmluZyh0aGlzLm5ldHdvcmsuYmVjaDMyKSAmJiB0aGlzLm5ldHdvcmsuYmVjaDMyID09PSBhZGRyZXNzUHJlZml4ICYmIGFkZHJlc3MgPT09IGFkZHJlc3MudG9Mb3dlckNhc2UoKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHB1YmxpYyBrZXkgZm9yIHRoZSBjb2luLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHViIHRoZSBwdWIgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBpc1ZhbGlkUHViKHB1Yjogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHB1YikuaXNOZXV0ZXJlZCgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBsYXRlc3QgYmxvY2sgaGVpZ2h0XG4gICAqIEBwYXJhbSByZXFJZFxuICAgKi9cbiAgYXN5bmMgZ2V0TGF0ZXN0QmxvY2tIZWlnaHQocmVxSWQ/OiBSZXF1ZXN0VHJhY2VyKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAocmVxSWQpIHtcbiAgICAgIHRoaXMuYml0Z28uc2V0UmVxdWVzdFRyYWNlcihyZXFJZCk7XG4gICAgfVxuICAgIGNvbnN0IGNoYWluaGVhZCA9IGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMudXJsKCcvcHVibGljL2Jsb2NrL2xhdGVzdCcpKS5yZXN1bHQoKTtcbiAgICByZXR1cm4gKGNoYWluaGVhZCBhcyBhbnkpLmhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gY3VzdG9tIGNvaW4gbG9naWMgYWZ0ZXIgYSB0cmFuc2FjdGlvbiBwcmVidWlsZCBoYXMgYmVlbiByZWNlaXZlZCBmcm9tIEJpdEdvXG4gICAqIEBwYXJhbSBwcmVidWlsZFxuICAgKi9cbiAgYXN5bmMgcG9zdFByb2Nlc3NQcmVidWlsZDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50PihcbiAgICBwcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDxUTnVtYmVyPlxuICApOiBQcm9taXNlPFRyYW5zYWN0aW9uUHJlYnVpbGQ8VE51bWJlcj4+IHtcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChwcmVidWlsZC50eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCB0eFByZWJ1aWxkIHByb3BlcnR5IHR4SGV4Jyk7XG4gICAgfVxuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdGhpcy5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXg8VE51bWJlcj4ocHJlYnVpbGQudHhIZXgpO1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKHByZWJ1aWxkLmJsb2NrSGVpZ2h0KSkge1xuICAgICAgcHJlYnVpbGQuYmxvY2tIZWlnaHQgPSAoYXdhaXQgdGhpcy5nZXRMYXRlc3RCbG9ja0hlaWdodCgpKSBhcyBudW1iZXI7XG4gICAgfVxuICAgIC8vIExvY2sgdHJhbnNhY3Rpb24gdG8gdGhlIG5leHQgYmxvY2sgdG8gZGlzY291cmFnZSBmZWUgc25pcGluZ1xuICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW4vYml0Y29pbi9ibG9iL2ZiMGFjNDgyZWVlNzYxZWMxN2VkMmMxMWRmMTFlMDU0MzQ3YTAyNmQvc3JjL3dhbGxldC93YWxsZXQuY3BwI0wyMTMzXG4gICAgdHJhbnNhY3Rpb24ubG9ja3RpbWUgPSBwcmVidWlsZC5ibG9ja0hlaWdodDtcbiAgICByZXR1cm4gXy5leHRlbmQoe30sIHByZWJ1aWxkLCB7IHR4SGV4OiB0cmFuc2FjdGlvbi50b0hleCgpIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgb3V0cHV0cyB0aGF0IGFyZSB3aXRoaW4gZXhwZWN0ZWQgb3V0cHV0cyBidXQgbm90IHdpdGhpbiBhY3R1YWwgb3V0cHV0cywgaW5jbHVkaW5nIGR1cGxpY2F0ZXNcbiAgICogQHBhcmFtIGV4cGVjdGVkT3V0cHV0c1xuICAgKiBAcGFyYW0gYWN0dWFsT3V0cHV0c1xuICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGZpbmRNaXNzaW5nT3V0cHV0cyhleHBlY3RlZE91dHB1dHM6IE91dHB1dFtdLCBhY3R1YWxPdXRwdXRzOiBPdXRwdXRbXSk6IE91dHB1dFtdIHtcbiAgICBjb25zdCBrZXlGdW5jID0gKHsgYWRkcmVzcywgYW1vdW50IH06IE91dHB1dCk6IHN0cmluZyA9PiBgJHthZGRyZXNzfToke051bWJlcihhbW91bnQpfWA7XG4gICAgY29uc3QgZ3JvdXBlZE91dHB1dHMgPSBfLmdyb3VwQnkoZXhwZWN0ZWRPdXRwdXRzLCBrZXlGdW5jKTtcblxuICAgIGFjdHVhbE91dHB1dHMuZm9yRWFjaCgob3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCBncm91cCA9IGdyb3VwZWRPdXRwdXRzW2tleUZ1bmMob3V0cHV0KV07XG4gICAgICBpZiAoZ3JvdXApIHtcbiAgICAgICAgZ3JvdXAucG9wKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gXy5mbGF0dGVuKF8udmFsdWVzKGdyb3VwZWRPdXRwdXRzKSk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGFuIGFkZHJlc3MnIHR5cGUgYmFzZWQgb24gaXRzIHdpdG5lc3MgYW5kIHJlZGVlbSBzY3JpcHQgcHJlc2VuY2VcbiAgICogQHBhcmFtIGFkZHJlc3NEZXRhaWxzXG4gICAqL1xuICBzdGF0aWMgaW5mZXJBZGRyZXNzVHlwZShhZGRyZXNzRGV0YWlsczogeyBjaGFpbjogbnVtYmVyIH0pOiBTY3JpcHRUeXBlMk9mMyB8IG51bGwge1xuICAgIHJldHVybiBpc0NoYWluQ29kZShhZGRyZXNzRGV0YWlscy5jaGFpbikgPyBzY3JpcHRUeXBlRm9yQ2hhaW4oYWRkcmVzc0RldGFpbHMuY2hhaW4pIDogbnVsbDtcbiAgfVxuXG4gIGNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgICBoZXg6IHN0cmluZ1xuICApOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbjxUTnVtYmVyPiB7XG4gICAgcmV0dXJuIHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KGhleCwgdGhpcy5uZXR3b3JrLCB0aGlzLmFtb3VudFR5cGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgYW5kIGZpbGwgdHJhbnNhY3Rpb24gZGV0YWlscyBzdWNoIGFzIGludGVybmFsL2NoYW5nZSBzcGVuZCwgZXh0ZXJuYWwgc3BlbmQgKGV4cGxpY2l0IHZzLiBpbXBsaWNpdCksIGV0Yy5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gICAgcGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9uczxUTnVtYmVyPlxuICApOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPFROdW1iZXI+PiB7XG4gICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gPSB7fSwgcmVxSWQgfSA9IHBhcmFtcztcblxuICAgIGlmICghXy5pc1VuZGVmaW5lZCh2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmcpICYmICFfLmlzQm9vbGVhbih2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmcpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZlcmlmaWNhdGlvbi5kaXNhYmxlTmV0d29ya2luZyBtdXN0IGJlIGEgYm9vbGVhbicpO1xuICAgIH1cbiAgICBjb25zdCBkaXNhYmxlTmV0d29ya2luZyA9IHZlcmlmaWNhdGlvbi5kaXNhYmxlTmV0d29ya2luZztcblxuICAgIGNvbnN0IGZldGNoS2V5Y2hhaW5zID0gYXN5bmMgKHdhbGxldDogSVdhbGxldCk6IFByb21pc2U8VmVyaWZpY2F0aW9uT3B0aW9uc1sna2V5Y2hhaW5zJ10+ID0+IHtcbiAgICAgIHJldHVybiBwcm9taXNlUHJvcHMoe1xuICAgICAgICB1c2VyOiB0aGlzLmtleWNoYWlucygpLmdldCh7IGlkOiB3YWxsZXQua2V5SWRzKClbS2V5SW5kaWNlcy5VU0VSXSwgcmVxSWQgfSksXG4gICAgICAgIGJhY2t1cDogdGhpcy5rZXljaGFpbnMoKS5nZXQoeyBpZDogd2FsbGV0LmtleUlkcygpW0tleUluZGljZXMuQkFDS1VQXSwgcmVxSWQgfSksXG4gICAgICAgIGJpdGdvOiB0aGlzLmtleWNoYWlucygpLmdldCh7IGlkOiB3YWxsZXQua2V5SWRzKClbS2V5SW5kaWNlcy5CSVRHT10sIHJlcUlkIH0pLFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIG9idGFpbiB0aGUga2V5Y2hhaW5zIGFuZCBrZXkgc2lnbmF0dXJlc1xuICAgIGxldCBrZXljaGFpbnM6IFZlcmlmaWNhdGlvbk9wdGlvbnNbJ2tleWNoYWlucyddIHwgdW5kZWZpbmVkID0gdmVyaWZpY2F0aW9uLmtleWNoYWlucztcbiAgICBpZiAoIWtleWNoYWlucykge1xuICAgICAgaWYgKGRpc2FibGVOZXR3b3JraW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGZldGNoIGtleWNoYWlucyB3aXRob3V0IG5ldHdvcmtpbmcnKTtcbiAgICAgIH1cbiAgICAgIGtleWNoYWlucyA9IGF3YWl0IGZldGNoS2V5Y2hhaW5zKHdhbGxldCk7XG4gICAgfVxuXG4gICAgaWYgKCFrZXljaGFpbnMgfHwgIWtleWNoYWlucy51c2VyIHx8ICFrZXljaGFpbnMuYmFja3VwIHx8ICFrZXljaGFpbnMuYml0Z28pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigna2V5Y2hhaW5zIGFyZSByZXF1aXJlZCwgYnV0IGNvdWxkIG5vdCBiZSBmZXRjaGVkJyk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5Y2hhaW5BcnJheTogVHJpcGxlPEtleWNoYWluPiA9IFtrZXljaGFpbnMudXNlciwga2V5Y2hhaW5zLmJhY2t1cCwga2V5Y2hhaW5zLmJpdGdvXTtcblxuICAgIGNvbnN0IGtleVNpZ25hdHVyZXMgPSBfLmdldCh3YWxsZXQsICdfd2FsbGV0LmtleVNpZ25hdHVyZXMnKTtcblxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHR4UHJlYnVpbGQudHhIZXgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgdHhQcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgIH1cbiAgICAvLyBvYnRhaW4gYWxsIG91dHB1dHNcbiAgICBjb25zdCBleHBsYW5hdGlvbjogVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiA9IGF3YWl0IHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uPFROdW1iZXI+KHtcbiAgICAgIHR4SGV4OiB0eFByZWJ1aWxkLnR4SGV4LFxuICAgICAgdHhJbmZvOiB0eFByZWJ1aWxkLnR4SW5mbyxcbiAgICAgIHB1YnM6IGtleWNoYWluQXJyYXkubWFwKChrKSA9PiBrLnB1YikgYXMgVHJpcGxlPHN0cmluZz4sXG4gICAgfSk7XG5cbiAgICBjb25zdCBhbGxPdXRwdXRzID0gWy4uLmV4cGxhbmF0aW9uLm91dHB1dHMsIC4uLmV4cGxhbmF0aW9uLmNoYW5nZU91dHB1dHNdO1xuXG4gICAgLy8gdmVyaWZ5IHRoYXQgZWFjaCByZWNpcGllbnQgZnJvbSB0eFBhcmFtcyBoYXMgdGhlaXIgb3duIG91dHB1dFxuICAgIGNvbnN0IGV4cGVjdGVkT3V0cHV0cyA9IF8uZ2V0KHR4UGFyYW1zLCAncmVjaXBpZW50cycsIFtdIGFzIFRyYW5zYWN0aW9uUmVjaXBpZW50W10pLm1hcCgob3V0cHV0KSA9PiB7XG4gICAgICByZXR1cm4geyAuLi5vdXRwdXQsIGFkZHJlc3M6IHRoaXMuY2Fub25pY2FsQWRkcmVzcyhvdXRwdXQuYWRkcmVzcykgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IG1pc3NpbmdPdXRwdXRzID0gQWJzdHJhY3RVdHhvQ29pbi5maW5kTWlzc2luZ091dHB1dHMoZXhwZWN0ZWRPdXRwdXRzLCBhbGxPdXRwdXRzKTtcblxuICAgIC8vIGdldCB0aGUga2V5Y2hhaW5zIGZyb20gdGhlIGN1c3RvbSBjaGFuZ2Ugd2FsbGV0IGlmIG5lZWRlZFxuICAgIGxldCBjdXN0b21DaGFuZ2U6IEN1c3RvbUNoYW5nZU9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgeyBjdXN0b21DaGFuZ2VXYWxsZXRJZCA9IHVuZGVmaW5lZCB9ID0gd2FsbGV0LmNvaW5TcGVjaWZpYygpIHx8IHt9O1xuICAgIGlmIChjdXN0b21DaGFuZ2VXYWxsZXRJZCkge1xuICAgICAgLy8gZmV0Y2gga2V5Y2hhaW5zIGZyb20gY3VzdG9tIGNoYW5nZSB3YWxsZXQgZm9yIGRlcml2aW5nIGFkZHJlc3Nlcy5cbiAgICAgIC8vIFRoZXNlIGtleWNoYWlucyBzaG91bGQgYmUgc2lnbmVkIGFuZCB0aGlzIHNob3VsZCBiZSB2ZXJpZmllZCBpbiB2ZXJpZnlUcmFuc2FjdGlvblxuICAgICAgY29uc3QgY3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlcyA9IF8uZ2V0KHdhbGxldCwgJ193YWxsZXQuY3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlcycsIHt9KTtcbiAgICAgIGNvbnN0IGN1c3RvbUNoYW5nZVdhbGxldDogV2FsbGV0ID0gYXdhaXQgdGhpcy53YWxsZXRzKCkuZ2V0KHsgaWQ6IGN1c3RvbUNoYW5nZVdhbGxldElkIH0pO1xuICAgICAgY29uc3QgY3VzdG9tQ2hhbmdlS2V5cyA9IGF3YWl0IGZldGNoS2V5Y2hhaW5zKGN1c3RvbUNoYW5nZVdhbGxldCk7XG5cbiAgICAgIGlmICghY3VzdG9tQ2hhbmdlS2V5cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBmZXRjaCBrZXljaGFpbnMgZm9yIGN1c3RvbSBjaGFuZ2Ugd2FsbGV0Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXN0b21DaGFuZ2VLZXlzLnVzZXIgJiYgY3VzdG9tQ2hhbmdlS2V5cy5iYWNrdXAgJiYgY3VzdG9tQ2hhbmdlS2V5cy5iaXRnbyAmJiBjdXN0b21DaGFuZ2VXYWxsZXQpIHtcbiAgICAgICAgY29uc3QgY3VzdG9tQ2hhbmdlS2V5Y2hhaW5zOiBbS2V5Y2hhaW4sIEtleWNoYWluLCBLZXljaGFpbl0gPSBbXG4gICAgICAgICAgY3VzdG9tQ2hhbmdlS2V5cy51c2VyLFxuICAgICAgICAgIGN1c3RvbUNoYW5nZUtleXMuYmFja3VwLFxuICAgICAgICAgIGN1c3RvbUNoYW5nZUtleXMuYml0Z28sXG4gICAgICAgIF07XG5cbiAgICAgICAgY3VzdG9tQ2hhbmdlID0ge1xuICAgICAgICAgIGtleXM6IGN1c3RvbUNoYW5nZUtleWNoYWlucyxcbiAgICAgICAgICBzaWduYXR1cmVzOiBbXG4gICAgICAgICAgICBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzLnVzZXIsXG4gICAgICAgICAgICBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzLmJhY2t1cCxcbiAgICAgICAgICAgIGN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXMuYml0Z28sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb29wIHRocm91Z2ggYWxsIHRoZSBvdXRwdXRzIGFuZCBjbGFzc2lmeSBlYWNoIG9mIHRoZW0gYXMgZWl0aGVyIGludGVybmFsIHNwZW5kc1xuICAgICAqIG9yIGV4dGVybmFsIHNwZW5kcyBieSBzZXR0aW5nIHRoZSBcImV4dGVybmFsXCIgcHJvcGVydHkgdG8gdHJ1ZSBvciBmYWxzZSBvbiB0aGUgb3V0cHV0IG9iamVjdC5cbiAgICAgKi9cbiAgICBjb25zdCBhbGxPdXRwdXREZXRhaWxzOiBPdXRwdXRbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYWxsT3V0cHV0cy5tYXAoKGN1cnJlbnRPdXRwdXQpID0+IHtcbiAgICAgICAgcmV0dXJuIHBhcnNlT3V0cHV0KHtcbiAgICAgICAgICBjdXJyZW50T3V0cHV0LFxuICAgICAgICAgIGNvaW46IHRoaXMsXG4gICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAga2V5Y2hhaW5BcnJheSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgY3VzdG9tQ2hhbmdlLFxuICAgICAgICAgIHJlcUlkLFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGNvbnN0IG5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uID0gYWxsT3V0cHV0RGV0YWlscy5zb21lKFxuICAgICAgKG91dHB1dCkgPT4gb3V0cHV0Lm5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uXG4gICAgKTtcblxuICAgIGNvbnN0IGNoYW5nZU91dHB1dHMgPSBfLmZpbHRlcihhbGxPdXRwdXREZXRhaWxzLCB7IGV4dGVybmFsOiBmYWxzZSB9KTtcblxuICAgIC8vIHRoZXNlIGFyZSBhbGwgdGhlIG91dHB1dHMgdGhhdCB3ZXJlIG5vdCBvcmlnaW5hbGx5IGV4cGxpY2l0bHkgc3BlY2lmaWVkIGluIHJlY2lwaWVudHNcbiAgICBjb25zdCBpbXBsaWNpdE91dHB1dHMgPSBBYnN0cmFjdFV0eG9Db2luLmZpbmRNaXNzaW5nT3V0cHV0cyhhbGxPdXRwdXREZXRhaWxzLCBleHBlY3RlZE91dHB1dHMpO1xuXG4gICAgY29uc3QgZXhwbGljaXRPdXRwdXRzID0gQWJzdHJhY3RVdHhvQ29pbi5maW5kTWlzc2luZ091dHB1dHMoYWxsT3V0cHV0RGV0YWlscywgaW1wbGljaXRPdXRwdXRzKTtcblxuICAgIC8vIHRoZXNlIGFyZSBhbGwgdGhlIG5vbi13YWxsZXQgb3V0cHV0cyB0aGF0IGhhZCBiZWVuIG9yaWdpbmFsbHkgZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gcmVjaXBpZW50c1xuICAgIGNvbnN0IGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzID0gXy5maWx0ZXIoZXhwbGljaXRPdXRwdXRzLCB7IGV4dGVybmFsOiB0cnVlIH0pO1xuXG4gICAgLy8gdGhpcyBpcyB0aGUgc3VtIG9mIGFsbCB0aGUgb3JpZ2luYWxseSBleHBsaWNpdGx5IHNwZWNpZmllZCBub24td2FsbGV0IG91dHB1dCB2YWx1ZXNcbiAgICBjb25zdCBleHBsaWNpdEV4dGVybmFsU3BlbmRBbW91bnQgPSB1dHhvbGliLmJpdGdvLnRvVE51bWJlcjxUTnVtYmVyPihcbiAgICAgIGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzLnJlZHVjZSgoc3VtOiBiaWdpbnQsIG86IE91dHB1dCkgPT4gc3VtICsgQmlnSW50KG8uYW1vdW50KSwgQmlnSW50KDApKSBhcyBiaWdpbnQsXG4gICAgICB0aGlzLmFtb3VudFR5cGVcbiAgICApO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBpbXBsaWNpdCBleHRlcm5hbCBzcGVuZCBhbW91bnQgcGVydGFpbnMgdG8gdmVyaWZ5aW5nIHRoZSBwYXktYXMteW91LWdvLWZlZSBCaXRHb1xuICAgICAqIGF1dG9tYXRpY2FsbHkgYXBwbGllcyB0byB0cmFuc2FjdGlvbnMgc2VuZGluZyBtb25leSBvdXQgb2YgdGhlIHdhbGxldC4gVGhlIGxvZ2ljIGlzIGZhaXJseSBzdHJhaWdodGZvcndhcmRcbiAgICAgKiBpbiB0aGF0IHdlIGNvbXBhcmUgdGhlIGV4dGVybmFsIHNwZW5kIGFtb3VudCB0aGF0IHdhcyBzcGVjaWZpZWQgZXhwbGljaXRseSBieSB0aGUgdXNlciB0byB0aGUgcG9ydGlvblxuICAgICAqIHRoYXQgd2FzIHNwZWNpZmllZCBpbXBsaWNpdGx5LiBUbyBwcm90ZWN0IGN1c3RvbWVycyBmcm9tIHBlb3BsZSB0YW1wZXJpbmcgd2l0aCB0aGUgdHJhbnNhY3Rpb24gb3V0cHV0cywgd2VcbiAgICAgKiBkZWZpbmUgYSB0aHJlc2hvbGQgZm9yIHRoZSBtYXhpbXVtIHBlcmNlbnRhZ2Ugb2YgdGhlIGltcGxpY2l0IGV4dGVybmFsIHNwZW5kIGluIHJlbGF0aW9uIHRvIHRoZSBleHBsaWNpdFxuICAgICAqIGV4dGVybmFsIHNwZW5kLlxuICAgICAqL1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoYXQgYWxsIHRoZSBleHRyYSBhZGRyZXNzZXMgYXJlIGNoYW5nZSBhZGRyZXNzZXNcbiAgICAvLyBnZXQgYWxsIHRoZSBhZGRpdGlvbmFsIGV4dGVybmFsIG91dHB1dHMgdGhlIHNlcnZlciBhZGRlZCBhbmQgY2FsY3VsYXRlIHRoZWlyIHZhbHVlc1xuICAgIGNvbnN0IGltcGxpY2l0RXh0ZXJuYWxPdXRwdXRzID0gXy5maWx0ZXIoaW1wbGljaXRPdXRwdXRzLCB7IGV4dGVybmFsOiB0cnVlIH0pO1xuICAgIGNvbnN0IGltcGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudCA9IHV0eG9saWIuYml0Z28udG9UTnVtYmVyPFROdW1iZXI+KFxuICAgICAgaW1wbGljaXRFeHRlcm5hbE91dHB1dHMucmVkdWNlKChzdW06IGJpZ2ludCwgbzogT3V0cHV0KSA9PiBzdW0gKyBCaWdJbnQoby5hbW91bnQpLCBCaWdJbnQoMCkpIGFzIGJpZ2ludCxcbiAgICAgIHRoaXMuYW1vdW50VHlwZVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAga2V5Y2hhaW5zLFxuICAgICAga2V5U2lnbmF0dXJlcyxcbiAgICAgIG91dHB1dHM6IGFsbE91dHB1dERldGFpbHMsXG4gICAgICBtaXNzaW5nT3V0cHV0cyxcbiAgICAgIGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzLFxuICAgICAgaW1wbGljaXRFeHRlcm5hbE91dHB1dHMsXG4gICAgICBjaGFuZ2VPdXRwdXRzLFxuICAgICAgZXhwbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50LFxuICAgICAgaW1wbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50LFxuICAgICAgbmVlZHNDdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVWZXJpZmljYXRpb24sXG4gICAgICBjdXN0b21DaGFuZ2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0IHRoZSB3YWxsZXQncyB1c2VyIHByaXZhdGUga2V5IGFuZCB2ZXJpZnkgdGhhdCB0aGUgY2xhaW1lZCBwdWJsaWMga2V5IG1hdGNoZXNcbiAgICogQHBhcmFtIHtWZXJpZnlVc2VyUHVibGljS2V5T3B0aW9uc30gcGFyYW1zXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCB2ZXJpZnlVc2VyUHVibGljS2V5KHBhcmFtczogVmVyaWZ5VXNlclB1YmxpY0tleU9wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwgdHhQYXJhbXMsIGRpc2FibGVOZXR3b3JraW5nIH0gPSBwYXJhbXM7XG4gICAgaWYgKCF1c2VyS2V5Y2hhaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBrZXljaGFpbiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJQdWIgPSB1c2VyS2V5Y2hhaW4ucHViO1xuXG4gICAgLy8gZGVjcnlwdCB0aGUgdXNlciBwcml2YXRlIGtleSBzbyB3ZSBjYW4gdmVyaWZ5IHRoYXQgdGhlIGNsYWltZWQgcHVibGljIGtleSBpcyBhIG1hdGNoXG4gICAgbGV0IHVzZXJQcnYgPSB1c2VyS2V5Y2hhaW4ucHJ2O1xuICAgIGlmIChfLmlzRW1wdHkodXNlclBydikpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnY7XG4gICAgICBpZiAoZW5jcnlwdGVkUHJ2ICYmICFfLmlzRW1wdHkoZW5jcnlwdGVkUHJ2KSkge1xuICAgICAgICAvLyBpZiB0aGUgZGVjcnlwdGlvbiBmYWlscywgaXQgd2lsbCB0aHJvdyBhbiBlcnJvclxuICAgICAgICB1c2VyUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogZW5jcnlwdGVkUHJ2LFxuICAgICAgICAgIHBhc3N3b3JkOiB0eFBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICd1c2VyIHByaXZhdGUga2V5IHVuYXZhaWxhYmxlIGZvciB2ZXJpZmljYXRpb24nO1xuICAgICAgaWYgKGRpc2FibGVOZXR3b3JraW5nKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yTWVzc2FnZSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB1c2VyUHJpdmF0ZUtleSA9IGJpcDMyLmZyb21CYXNlNTgodXNlclBydik7XG4gICAgICBpZiAodXNlclByaXZhdGVLZXkudG9CYXNlNTgoKSA9PT0gdXNlclByaXZhdGVLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBwcml2YXRlIGtleSBpcyBvbmx5IHB1YmxpYycpO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXJQcml2YXRlS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKSAhPT0gdXNlclB1Yikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXIgcHJpdmF0ZSBrZXkgZG9lcyBub3QgbWF0Y2ggcHVibGljIGtleScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSBzaWduYXR1cmVzIHByb2R1Y2VkIGJ5IHRoZSB1c2VyIGtleSBvdmVyIHRoZSBiYWNrdXAgYW5kIGJpdGdvIGtleXMuXG4gICAqXG4gICAqIElmIHNldCwgdGhlc2Ugc2lnbmF0dXJlcyBlbnN1cmUgdGhhdCB0aGUgd2FsbGV0IGtleXMgY2Fubm90IGJlIGNoYW5nZWQgYWZ0ZXIgdGhlIHdhbGxldCBoYXMgYmVlbiBjcmVhdGVkLlxuICAgKiBAcGFyYW0ge1ZlcmlmeUtleVNpZ25hdHVyZXNPcHRpb25zfSBwYXJhbXNcbiAgICogQHJldHVybiB7e2JhY2t1cDogYm9vbGVhbiwgYml0Z286IGJvb2xlYW59fVxuICAgKi9cbiAgcHJvdGVjdGVkIHZlcmlmeUtleVNpZ25hdHVyZShwYXJhbXM6IFZlcmlmeUtleVNpZ25hdHVyZXNPcHRpb25zKTogYm9vbGVhbiB7XG4gICAgLy8gZmlyc3QsIGxldCdzIHZlcmlmeSB0aGUgaW50ZWdyaXR5IG9mIHRoZSB1c2VyIGtleSwgd2hvc2UgcHVibGljIGtleSBpcyB1c2VkIGZvciBzdWJzZXF1ZW50IHZlcmlmaWNhdGlvbnNcbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwga2V5Y2hhaW5Ub1ZlcmlmeSwga2V5U2lnbmF0dXJlIH0gPSBwYXJhbXM7XG4gICAgaWYgKCF1c2VyS2V5Y2hhaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBrZXljaGFpbiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICgha2V5Y2hhaW5Ub1ZlcmlmeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXljaGFpbiB0byB2ZXJpZnkgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleVNpZ25hdHVyZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXkgc2lnbmF0dXJlIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gdmVyaWZ5IHRoZSBzaWduYXR1cmUgYWdhaW5zdCB0aGUgdXNlciBwdWJsaWMga2V5XG4gICAgY29uc3QgcHVibGljS2V5ID0gYmlwMzIuZnJvbUJhc2U1OCh1c2VyS2V5Y2hhaW4ucHViKS5wdWJsaWNLZXk7XG4gICAgY29uc3Qgc2lnbmluZ0FkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MudG9CYXNlNThDaGVjayhcbiAgICAgIHV0eG9saWIuY3J5cHRvLmhhc2gxNjAocHVibGljS2V5KSxcbiAgICAgIHV0eG9saWIubmV0d29ya3MuYml0Y29pbi5wdWJLZXlIYXNoLFxuICAgICAgdGhpcy5uZXR3b3JrXG4gICAgKTtcblxuICAgIC8vIEJHLTU3MDM6IHVzZSBCVEMgbWFpbm5ldCBwcmVmaXggZm9yIGFsbCBrZXkgc2lnbmF0dXJlIG9wZXJhdGlvbnNcbiAgICAvLyAodGhpcyBtZWFucyBkbyBub3QgcGFzcyBhIHByZWZpeCBwYXJhbWV0ZXIsIGFuZCBsZXQgaXQgdXNlIHRoZSBkZWZhdWx0IHByZWZpeCBpbnN0ZWFkKVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYml0Y29pbk1lc3NhZ2UudmVyaWZ5KGtleWNoYWluVG9WZXJpZnkucHViLCBzaWduaW5nQWRkcmVzcywgQnVmZmVyLmZyb20oa2V5U2lnbmF0dXJlLCAnaGV4JykpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRlYnVnKCdlcnJvciB0aHJvd24gZnJvbSBiaXRjb2lubWVzc2FnZSB3aGlsZSB2ZXJpZnlpbmcga2V5IHNpZ25hdHVyZScsIGUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgc2lnbmF0dXJlcyBhZ2FpbnN0IHRoZSB1c2VyIHByaXZhdGUga2V5IG92ZXIgdGhlIGNoYW5nZSB3YWxsZXQgZXh0ZW5kZWQga2V5c1xuICAgKiBAcGFyYW0ge1BhcnNlZFRyYW5zYWN0aW9ufSB0eFxuICAgKiBAcGFyYW0ge0tleWNoYWlufSB1c2VyS2V5Y2hhaW5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZlcmlmeUN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gICAgdHg6IFBhcnNlZFRyYW5zYWN0aW9uPFROdW1iZXI+LFxuICAgIHVzZXJLZXljaGFpbjogS2V5Y2hhaW5cbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0eC5jdXN0b21DaGFuZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncGFyc2VkIHRyYW5zYWN0aW9uIGlzIG1pc3NpbmcgcmVxdWlyZWQgY3VzdG9tIGNoYW5nZSB2ZXJpZmljYXRpb24gZGF0YScpO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0eC5jdXN0b21DaGFuZ2Uua2V5cykgfHwgIUFycmF5LmlzQXJyYXkodHguY3VzdG9tQ2hhbmdlLnNpZ25hdHVyZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1c3RvbUNoYW5nZSBwcm9wZXJ0eSBpcyBtaXNzaW5nIGtleXMgb3Igc2lnbmF0dXJlcycpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5SW5kZXggb2YgW0tleUluZGljZXMuVVNFUiwgS2V5SW5kaWNlcy5CQUNLVVAsIEtleUluZGljZXMuQklUR09dKSB7XG4gICAgICBjb25zdCBrZXljaGFpblRvVmVyaWZ5ID0gdHguY3VzdG9tQ2hhbmdlLmtleXNba2V5SW5kZXhdO1xuICAgICAgY29uc3Qga2V5U2lnbmF0dXJlID0gdHguY3VzdG9tQ2hhbmdlLnNpZ25hdHVyZXNba2V5SW5kZXhdO1xuICAgICAgaWYgKCFrZXljaGFpblRvVmVyaWZ5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyByZXF1aXJlZCBjdXN0b20gY2hhbmdlICR7S2V5SW5kaWNlc1trZXlJbmRleF0udG9Mb3dlckNhc2UoKX0ga2V5Y2hhaW4gcHVibGljIGtleWApO1xuICAgICAgfVxuICAgICAgaWYgKCFrZXlTaWduYXR1cmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIHJlcXVpcmVkIGN1c3RvbSBjaGFuZ2UgJHtLZXlJbmRpY2VzW2tleUluZGV4XS50b0xvd2VyQ2FzZSgpfSBrZXljaGFpbiBzaWduYXR1cmVgKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy52ZXJpZnlLZXlTaWduYXR1cmUoeyB1c2VyS2V5Y2hhaW4sIGtleWNoYWluVG9WZXJpZnksIGtleVNpZ25hdHVyZSB9KSkge1xuICAgICAgICBkZWJ1ZygnZmFpbGVkIHRvIHZlcmlmeSBjdXN0b20gY2hhbmdlICVzIGtleSBzaWduYXR1cmUhJywgS2V5SW5kaWNlc1trZXlJbmRleF0udG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gcGVyY2VudGFnZSBsaW1pdCBmb3IgcGF5LWFzLXlvdS1nbyBvdXRwdXRzXG4gICAqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYXlHb0xpbWl0KGFsbG93UGF5Z29PdXRwdXQ/OiBib29sZWFuKTogbnVtYmVyIHtcbiAgICAvLyBhbGxvd2luZyBwYXlnbyBvdXRwdXRzIG5lZWRzIHRvIGJlIHRoZSBkZWZhdWx0IGJlaGF2aW9yLCBzbyBvbmx5IGRpc2FsbG93IHBheWdvIG91dHB1dHMgaWYgdGhlXG4gICAgLy8gcmVsZXZhbnQgdmVyaWZpY2F0aW9uIG9wdGlvbiBpcyBib3RoIHNldCBhbmQgZmFsc2VcbiAgICBpZiAoIV8uaXNOaWwoYWxsb3dQYXlnb091dHB1dCkgJiYgIWFsbG93UGF5Z29PdXRwdXQpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvLyAxNTAgYmFzaXMgcG9pbnRzIGlzIHRoZSBhYnNvbHV0ZSBwZXJtaXR0ZWQgbWF4aW11bSBpZiBwYXlnbyBvdXRwdXRzIGFyZSBhbGxvd2VkXG4gICAgcmV0dXJuIDAuMDE1O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSB0aGF0IGEgdHJhbnNhY3Rpb24gcHJlYnVpbGQgY29tcGxpZXMgd2l0aCB0aGUgb3JpZ2luYWwgaW50ZW50aW9uXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy50eFBhcmFtcyBwYXJhbXMgb2JqZWN0IHBhc3NlZCB0byBzZW5kXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQcmVidWlsZCBwcmVidWlsZCBvYmplY3QgcmV0dXJuZWQgYnkgc2VydmVyXG4gICAqIEBwYXJhbSBwYXJhbXMudHhQcmVidWlsZC50eEhleCBwcmVidWlsdCB0cmFuc2FjdGlvbidzIHR4SGV4IGZvcm1cbiAgICogQHBhcmFtIHBhcmFtcy53YWxsZXQgV2FsbGV0IG9iamVjdCB0byBvYnRhaW4ga2V5cyB0byB2ZXJpZnkgYWdhaW5zdFxuICAgKiBAcGFyYW0gcGFyYW1zLnZlcmlmaWNhdGlvbiBPYmplY3Qgc3BlY2lmeWluZyBzb21lIHZlcmlmaWNhdGlvbiBwYXJhbWV0ZXJzXG4gICAqIEBwYXJhbSBwYXJhbXMudmVyaWZpY2F0aW9uLmRpc2FibGVOZXR3b3JraW5nIERpc2FsbG93IGZldGNoaW5nIGFueSBkYXRhIGZyb20gdGhlIGludGVybmV0IGZvciB2ZXJpZmljYXRpb24gcHVycG9zZXNcbiAgICogQHBhcmFtIHBhcmFtcy52ZXJpZmljYXRpb24ua2V5Y2hhaW5zIFBhc3Mga2V5Y2hhaW5zIG1hbnVhbGx5IHJhdGhlciB0aGFuIGZldGNoaW5nIHRoZW0gYnkgaWRcbiAgICogQHBhcmFtIHBhcmFtcy52ZXJpZmljYXRpb24uYWRkcmVzc2VzIEFkZHJlc3MgZGV0YWlscyB0byBwYXNzIGluIGZvciBvdXQtb2YtYmFuZCB2ZXJpZmljYXRpb25cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgICBwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9uczxUTnVtYmVyPlxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiA9IHsgYWxsb3dQYXlnb091dHB1dDogdHJ1ZSB9LCByZXFJZCB9ID0gcGFyYW1zO1xuICAgIGNvbnN0IGRpc2FibGVOZXR3b3JraW5nID0gISF2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmc7XG4gICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb246IFBhcnNlZFRyYW5zYWN0aW9uPFROdW1iZXI+ID0gYXdhaXQgdGhpcy5wYXJzZVRyYW5zYWN0aW9uPFROdW1iZXI+KHtcbiAgICAgIHR4UGFyYW1zLFxuICAgICAgdHhQcmVidWlsZCxcbiAgICAgIHdhbGxldCxcbiAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIHJlcUlkLFxuICAgIH0pO1xuXG4gICAgY29uc3Qga2V5Y2hhaW5zID0gcGFyc2VkVHJhbnNhY3Rpb24ua2V5Y2hhaW5zO1xuXG4gICAgLy8gdmVyaWZ5IHRoYXQgdGhlIGNsYWltZWQgdXNlciBwdWJsaWMga2V5IGNvcnJlc3BvbmRzIHRvIHRoZSB3YWxsZXQncyB1c2VyIHByaXZhdGUga2V5XG4gICAgbGV0IHVzZXJQdWJsaWNLZXlWZXJpZmllZCA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAvLyB2ZXJpZnkgdGhlIHVzZXIgcHVibGljIGtleSBtYXRjaGVzIHRoZSBwcml2YXRlIGtleSAtIHRoaXMgd2lsbCB0aHJvdyBpZiB0aGVyZSBpcyBubyBtYXRjaFxuICAgICAgdXNlclB1YmxpY0tleVZlcmlmaWVkID0gdGhpcy52ZXJpZnlVc2VyUHVibGljS2V5KHsgdXNlcktleWNoYWluOiBrZXljaGFpbnMudXNlciwgZGlzYWJsZU5ldHdvcmtpbmcsIHR4UGFyYW1zIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRlYnVnKCdmYWlsZWQgdG8gdmVyaWZ5IHVzZXIgcHVibGljIGtleSEnLCBlKTtcbiAgICB9XG5cbiAgICAvLyBsZXQncyB2ZXJpZnkgdGhlc2Uga2V5Y2hhaW5zXG4gICAgY29uc3Qga2V5U2lnbmF0dXJlcyA9IHBhcnNlZFRyYW5zYWN0aW9uLmtleVNpZ25hdHVyZXM7XG4gICAgaWYgKCFfLmlzRW1wdHkoa2V5U2lnbmF0dXJlcykpIHtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IChrZXksIHB1YikgPT5cbiAgICAgICAgdGhpcy52ZXJpZnlLZXlTaWduYXR1cmUoeyB1c2VyS2V5Y2hhaW46IGtleWNoYWlucy51c2VyLCBrZXljaGFpblRvVmVyaWZ5OiBrZXksIGtleVNpZ25hdHVyZTogcHViIH0pO1xuICAgICAgY29uc3QgaXNCYWNrdXBLZXlTaWduYXR1cmVWYWxpZCA9IHZlcmlmeShrZXljaGFpbnMuYmFja3VwLCBrZXlTaWduYXR1cmVzLmJhY2t1cFB1Yik7XG4gICAgICBjb25zdCBpc0JpdGdvS2V5U2lnbmF0dXJlVmFsaWQgPSB2ZXJpZnkoa2V5Y2hhaW5zLmJpdGdvLCBrZXlTaWduYXR1cmVzLmJpdGdvUHViKTtcbiAgICAgIGlmICghaXNCYWNrdXBLZXlTaWduYXR1cmVWYWxpZCB8fCAhaXNCaXRnb0tleVNpZ25hdHVyZVZhbGlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignc2Vjb25kYXJ5IHB1YmxpYyBrZXkgc2lnbmF0dXJlcyBpbnZhbGlkJyk7XG4gICAgICB9XG4gICAgICBkZWJ1Zygnc3VjY2Vzc2Z1bGx5IHZlcmlmaWVkIGJhY2t1cCBhbmQgYml0Z28ga2V5IHNpZ25hdHVyZXMnKTtcbiAgICB9IGVsc2UgaWYgKCFkaXNhYmxlTmV0d29ya2luZykge1xuICAgICAgLy8gdGhlc2Uga2V5cyB3ZXJlIG9idGFpbmVkIG9ubGluZSBhbmQgdGhlaXIgc2lnbmF0dXJlcyB3ZXJlIG5vdCB2ZXJpZmllZFxuICAgICAgLy8gdGhpcyBjb3VsZCBiZSBkYW5nZXJvdXNcbiAgICAgIGNvbnNvbGUubG9nKCd1bnNpZ25lZCBrZXlzIG9idGFpbmVkIG9ubGluZSBhcmUgYmVpbmcgdXNlZCBmb3IgYWRkcmVzcyB2ZXJpZmljYXRpb24nKTtcbiAgICB9XG5cbiAgICBpZiAocGFyc2VkVHJhbnNhY3Rpb24ubmVlZHNDdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVWZXJpZmljYXRpb24pIHtcbiAgICAgIGlmICgha2V5Y2hhaW5zLnVzZXIgfHwgIXVzZXJQdWJsaWNLZXlWZXJpZmllZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RyYW5zYWN0aW9uIHJlcXVpcmVzIHZlcmlmaWNhdGlvbiBvZiB1c2VyIHB1YmxpYyBrZXksIGJ1dCBpdCB3YXMgdW5hYmxlIHRvIGJlIHZlcmlmaWVkJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzVmVyaWZpZWQgPSB0aGlzLnZlcmlmeUN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXMocGFyc2VkVHJhbnNhY3Rpb24sIGtleWNoYWlucy51c2VyKTtcbiAgICAgIGlmICghY3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlc1ZlcmlmaWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAndHJhbnNhY3Rpb24gcmVxdWlyZXMgdmVyaWZpY2F0aW9uIG9mIGN1c3RvbSBjaGFuZ2Uga2V5IHNpZ25hdHVyZXMsIGJ1dCB0aGV5IHdlcmUgdW5hYmxlIHRvIGJlIHZlcmlmaWVkJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZGVidWcoJ3N1Y2Nlc3NmdWxseSB2ZXJpZmllZCB1c2VyIHB1YmxpYyBrZXkgYW5kIGN1c3RvbSBjaGFuZ2Uga2V5IHNpZ25hdHVyZXMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBtaXNzaW5nT3V0cHV0cyA9IHBhcnNlZFRyYW5zYWN0aW9uLm1pc3NpbmdPdXRwdXRzO1xuICAgIGlmIChtaXNzaW5nT3V0cHV0cy5sZW5ndGggIT09IDApIHtcbiAgICAgIC8vIHRoZXJlIGFyZSBzb21lIG91dHB1dHMgaW4gdGhlIHJlY2lwaWVudHMgbGlzdCB0aGF0IGhhdmUgbm90IG1hZGUgaXQgaW50byB0aGUgYWN0dWFsIHRyYW5zYWN0aW9uXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG91dHB1dHMgbWlzc2luZyBpbiB0cmFuc2FjdGlvbiBwcmVidWlsZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGludGVuZGVkRXh0ZXJuYWxTcGVuZCA9IHBhcnNlZFRyYW5zYWN0aW9uLmV4cGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudDtcblxuICAgIC8vIHRoaXMgaXMgYSBsaW1pdCB3ZSBpbXBvc2UgZm9yIHRoZSB0b3RhbCB2YWx1ZSB0aGF0IGlzIGFtZW5kZWQgdG8gdGhlIHRyYW5zYWN0aW9uIGJleW9uZCB3aGF0IHdhcyBvcmlnaW5hbGx5IGludGVuZGVkXG4gICAgY29uc3QgcGF5QXNZb3VHb0xpbWl0ID0gbmV3IEJpZ051bWJlcih0aGlzLmdldFBheUdvTGltaXQodmVyaWZpY2F0aW9uLmFsbG93UGF5Z29PdXRwdXQpKS5tdWx0aXBsaWVkQnkoXG4gICAgICBpbnRlbmRlZEV4dGVybmFsU3BlbmQudG9TdHJpbmcoKVxuICAgICk7XG5cbiAgICAvKlxuICAgIFNvbWUgZXhwbGFuYXRpb24gZm9yIHdoeSB3ZSdyZSBkb2luZyB3aGF0IHdlJ3JlIGRvaW5nOlxuICAgIFNvbWUgY3VzdG9tZXJzIHdpbGwgaGF2ZSBhbiBvdXRwdXQgdG8gQml0R28ncyBQQVlHbyB3YWxsZXQgYWRkZWQgdG8gdGhlaXIgdHJhbnNhY3Rpb24sIGFuZCB3ZSBuZWVkIHRvIGFjY291bnQgZm9yXG4gICAgaXQgaGVyZS4gVG8gcHJvdGVjdCBzb21lb25lIHRhbXBlcmluZyB3aXRoIHRoZSBvdXRwdXQgdG8gbWFrZSBpdCBzZW5kIG1vcmUgdGhhbiBpdCBzaG91bGQgdG8gQml0R28sIHdlIGRlZmluZSBhXG4gICAgdGhyZXNob2xkIGZvciB0aGUgb3V0cHV0J3MgdmFsdWUgYWJvdmUgd2hpY2ggd2UnbGwgdGhyb3cgYW4gZXJyb3IsIGJlY2F1c2UgdGhlIHBheWdvIG91dHB1dCBzaG91bGQgbmV2ZXIgYmUgdGhhdFxuICAgIGhpZ2guXG4gICAgICovXG5cbiAgICAvLyBtYWtlIHN1cmUgdGhhdCBhbGwgdGhlIGV4dHJhIGFkZHJlc3NlcyBhcmUgY2hhbmdlIGFkZHJlc3Nlc1xuICAgIC8vIGdldCBhbGwgdGhlIGFkZGl0aW9uYWwgZXh0ZXJuYWwgb3V0cHV0cyB0aGUgc2VydmVyIGFkZGVkIGFuZCBjYWxjdWxhdGUgdGhlaXIgdmFsdWVzXG4gICAgY29uc3Qgbm9uQ2hhbmdlQW1vdW50ID0gbmV3IEJpZ051bWJlcihwYXJzZWRUcmFuc2FjdGlvbi5pbXBsaWNpdEV4dGVybmFsU3BlbmRBbW91bnQudG9TdHJpbmcoKSk7XG5cbiAgICBkZWJ1ZyhcbiAgICAgICdJbnRlbmRlZCBzcGVuZCBpcyAlcywgTm9uLWNoYW5nZSBhbW91bnQgaXMgJXMsIHBheWdvIGxpbWl0IGlzICVzJyxcbiAgICAgIGludGVuZGVkRXh0ZXJuYWxTcGVuZC50b1N0cmluZygpLFxuICAgICAgbm9uQ2hhbmdlQW1vdW50LnRvU3RyaW5nKCksXG4gICAgICBwYXlBc1lvdUdvTGltaXQudG9TdHJpbmcoKVxuICAgICk7XG5cbiAgICAvLyB0aGUgYWRkaXRpb25hbCBleHRlcm5hbCBvdXRwdXRzIGNhbiBvbmx5IGJlIEJpdEdvJ3MgcGF5LWFzLXlvdS1nbyBmZWUsIGJ1dCB3ZSBjYW5ub3QgdmVyaWZ5IHRoZSB3YWxsZXQgYWRkcmVzc1xuICAgIGlmIChub25DaGFuZ2VBbW91bnQuZ3QocGF5QXNZb3VHb0xpbWl0KSkge1xuICAgICAgLy8gdGhlcmUgYXJlIHNvbWUgYWRkcmVzc2VzIHRoYXQgYXJlIG91dHNpZGUgdGhlIHNjb3BlIG9mIGludGVuZGVkIHJlY2lwaWVudHMgdGhhdCBhcmUgbm90IGNoYW5nZSBhZGRyZXNzZXNcbiAgICAgIHRocm93IG5ldyBFcnJvcigncHJlYnVpbGQgYXR0ZW1wdHMgdG8gc3BlbmQgdG8gdW5pbnRlbmRlZCBleHRlcm5hbCByZWNpcGllbnRzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgYWxsT3V0cHV0cyA9IHBhcnNlZFRyYW5zYWN0aW9uLm91dHB1dHM7XG4gICAgaWYgKCF0eFByZWJ1aWxkLnR4SGV4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHR4UHJlYnVpbGQudHhIZXggbm90IHNldGApO1xuICAgIH1cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KHR4UHJlYnVpbGQudHhIZXgpO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uQ2FjaGUgPSB7fTtcbiAgICBjb25zdCBpbnB1dHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHRyYW5zYWN0aW9uLmlucy5tYXAoYXN5bmMgKGN1cnJlbnRJbnB1dCkgPT4ge1xuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbklkID0gKEJ1ZmZlci5mcm9tKGN1cnJlbnRJbnB1dC5oYXNoKS5yZXZlcnNlKCkgYXMgQnVmZmVyKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHhQcmVidWlsZC50eEluZm8/LnR4SGV4ZXM/Llt0cmFuc2FjdGlvbklkXTtcbiAgICAgICAgaWYgKHR4SGV4KSB7XG4gICAgICAgICAgY29uc3QgbG9jYWxUeCA9IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KHR4SGV4KTtcbiAgICAgICAgICBpZiAobG9jYWxUeC5nZXRJZCgpICE9PSB0cmFuc2FjdGlvbklkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRyYW5zYWN0aW9uIGhleCBkb2VzIG5vdCBtYXRjaCBpZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBjdXJyZW50T3V0cHV0ID0gbG9jYWxUeC5vdXRzW2N1cnJlbnRJbnB1dC5pbmRleF07XG4gICAgICAgICAgY29uc3QgYWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KGN1cnJlbnRPdXRwdXQuc2NyaXB0LCB0aGlzLm5ldHdvcmspO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgICAgdmFsdWU6IGN1cnJlbnRPdXRwdXQudmFsdWUsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogY3VycmVudE91dHB1dC52YWx1ZS50b1N0cmluZygpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoIXRyYW5zYWN0aW9uQ2FjaGVbdHJhbnNhY3Rpb25JZF0pIHtcbiAgICAgICAgICBpZiAoZGlzYWJsZU5ldHdvcmtpbmcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXR0ZW1wdGluZyB0byByZXRyaWV2ZSB0cmFuc2FjdGlvbiBkZXRhaWxzIGV4dGVybmFsbHkgd2l0aCBuZXR3b3JraW5nIGRpc2FibGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXFJZCkge1xuICAgICAgICAgICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHJhbnNhY3Rpb25DYWNoZVt0cmFuc2FjdGlvbklkXSA9IGF3YWl0IHRoaXMuYml0Z28uZ2V0KHRoaXMudXJsKGAvcHVibGljL3R4LyR7dHJhbnNhY3Rpb25JZH1gKSkucmVzdWx0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb25EZXRhaWxzID0gdHJhbnNhY3Rpb25DYWNoZVt0cmFuc2FjdGlvbklkXTtcbiAgICAgICAgcmV0dXJuIHRyYW5zYWN0aW9uRGV0YWlscy5vdXRwdXRzW2N1cnJlbnRJbnB1dC5pbmRleF07XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBjb2lucyAoZG9nZSkgdGhhdCBjYW4gZXhjZWVkIG51bWJlciBsaW1pdHMgKGFuZCB0aHVzIHdpbGwgdXNlIGJpZ2ludCkgd2lsbCBoYXZlIHRoZSBgdmFsdWVTdHJpbmdgIGZpZWxkXG4gICAgY29uc3QgaW5wdXRBbW91bnQgPSBpbnB1dHMucmVkdWNlKFxuICAgICAgKHN1bTogYmlnaW50LCBpKSA9PiBzdW0gKyBCaWdJbnQodGhpcy5hbW91bnRUeXBlID09PSAnYmlnaW50JyA/IGkudmFsdWVTdHJpbmcgOiBpLnZhbHVlKSxcbiAgICAgIEJpZ0ludCgwKVxuICAgICk7XG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gYWxsT3V0cHV0cy5yZWR1Y2UoKHN1bTogYmlnaW50LCBvOiBPdXRwdXQpID0+IHN1bSArIEJpZ0ludChvLmFtb3VudCksIEJpZ0ludCgwKSk7XG4gICAgY29uc3QgZmVlID0gaW5wdXRBbW91bnQgLSBvdXRwdXRBbW91bnQ7XG5cbiAgICBpZiAoZmVlIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgYXR0ZW1wdGluZyB0byBzcGVuZCAke291dHB1dEFtb3VudH0gc2F0b3NoaXMsIHdoaWNoIGV4Y2VlZHMgdGhlIGlucHV0IGFtb3VudCAoJHtpbnB1dEFtb3VudH0gc2F0b3NoaXMpIGJ5ICR7LWZlZX1gXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2Ugc3VyZSBhbiBhZGRyZXNzIGlzIHZhbGlkIGFuZCB0aHJvdyBhbiBlcnJvciBpZiBpdCdzIG5vdC5cbiAgICogQHBhcmFtIHBhcmFtcy5hZGRyZXNzIFRoZSBhZGRyZXNzIHN0cmluZyBvbiB0aGUgbmV0d29ya1xuICAgKiBAcGFyYW0gcGFyYW1zLmFkZHJlc3NUeXBlXG4gICAqIEBwYXJhbSBwYXJhbXMua2V5Y2hhaW5zIEtleWNoYWluIG9iamVjdHMgd2l0aCB4cHVic1xuICAgKiBAcGFyYW0gcGFyYW1zLmNvaW5TcGVjaWZpYyBDb2luLXNwZWNpZmljIGRldGFpbHMgZm9yIHRoZSBhZGRyZXNzIHN1Y2ggYXMgYSB3aXRuZXNzIHNjcmlwdFxuICAgKiBAcGFyYW0gcGFyYW1zLmNoYWluIERlcml2YXRpb24gY2hhaW5cbiAgICogQHBhcmFtIHBhcmFtcy5pbmRleCBEZXJpdmF0aW9uIGluZGV4XG4gICAqIEB0aHJvd3Mge0ludmFsaWRBZGRyZXNzRXJyb3J9XG4gICAqIEB0aHJvd3Mge0ludmFsaWRBZGRyZXNzRGVyaXZhdGlvblByb3BlcnR5RXJyb3J9XG4gICAqIEB0aHJvd3Mge1VuZXhwZWN0ZWRBZGRyZXNzRXJyb3J9XG4gICAqL1xuICBpc1dhbGxldEFkZHJlc3MocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHsgYWRkcmVzcywgYWRkcmVzc1R5cGUsIGtleWNoYWlucywgY29pblNwZWNpZmljLCBjaGFpbiwgaW5kZXggfSA9IHBhcmFtcztcblxuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgIH1cblxuICAgIGlmICgoXy5pc1VuZGVmaW5lZChjaGFpbikgJiYgXy5pc1VuZGVmaW5lZChpbmRleCkpIHx8ICEoXy5pc0Zpbml0ZShjaGFpbikgJiYgXy5pc0Zpbml0ZShpbmRleCkpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NEZXJpdmF0aW9uUHJvcGVydHlFcnJvcihcbiAgICAgICAgYGFkZHJlc3MgdmFsaWRhdGlvbiBmYWlsdXJlOiBpbnZhbGlkIGNoYWluICgke2NoYWlufSkgb3IgaW5kZXggKCR7aW5kZXh9KWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzT2JqZWN0KGNvaW5TcGVjaWZpYykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc1ZlcmlmaWNhdGlvbk9iamVjdFByb3BlcnR5RXJyb3IoXG4gICAgICAgICdhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogY29pblNwZWNpZmljIGZpZWxkIG11c3QgYmUgYW4gb2JqZWN0J1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleWNoYWlucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucycpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cGVjdGVkQWRkcmVzcyA9IHRoaXMuZ2VuZXJhdGVBZGRyZXNzKHtcbiAgICAgIGFkZHJlc3NUeXBlOiBhZGRyZXNzVHlwZSBhcyBTY3JpcHRUeXBlMk9mMyxcbiAgICAgIGtleWNoYWlucyxcbiAgICAgIHRocmVzaG9sZDogMixcbiAgICAgIGNoYWluLFxuICAgICAgaW5kZXgsXG4gICAgfSk7XG5cbiAgICBpZiAoZXhwZWN0ZWRBZGRyZXNzLmFkZHJlc3MgIT09IGFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKFxuICAgICAgICBgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6IGV4cGVjdGVkICR7ZXhwZWN0ZWRBZGRyZXNzLmFkZHJlc3N9IGJ1dCBnb3QgJHthZGRyZXNzfWBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgY29pbiBzdXBwb3J0cyBhIGJsb2NrIHRhcmdldFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHN1cHBvcnRzQmxvY2tUYXJnZXQoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGFkZHJlc3NUeXBlXG4gICAqIEByZXR1cm5zIHRydWUgaWZmIGNvaW4gc3VwcG9ydHMgc3BlbmRpbmcgZnJvbSB1bnNwZW50VHlwZVxuICAgKi9cbiAgc3VwcG9ydHNBZGRyZXNzVHlwZShhZGRyZXNzVHlwZTogU2NyaXB0VHlwZTJPZjMpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdXR4b2xpYi5iaXRnby5vdXRwdXRTY3JpcHRzLmlzU3VwcG9ydGVkU2NyaXB0VHlwZSh0aGlzLm5ldHdvcmssIGFkZHJlc3NUeXBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gY2hhaW5cbiAgICogQHJldHVybiB0cnVlIGlmZiBjb2luIHN1cHBvcnRzIHNwZW5kaW5nIGZyb20gY2hhaW5cbiAgICovXG4gIHN1cHBvcnRzQWRkcmVzc0NoYWluKGNoYWluOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNDaGFpbkNvZGUoY2hhaW4pICYmIHRoaXMuc3VwcG9ydHNBZGRyZXNzVHlwZSh1dHhvbGliLmJpdGdvLnNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbikpO1xuICB9XG5cbiAga2V5SWRzRm9yU2lnbmluZygpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIFtLZXlJbmRpY2VzLlVTRVIsIEtleUluZGljZXMuQkFDS1VQLCBLZXlJbmRpY2VzLkJJVEdPXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUT0RPKEJHLTExNDg3KTogUmVtb3ZlIGFkZHJlc3NUeXBlLCBzZWd3aXQsIGFuZCBiZWNoMzIgcGFyYW1zIGluIFNES3Y2XG4gICAqIEdlbmVyYXRlIGFuIGFkZHJlc3MgZm9yIGEgd2FsbGV0IGJhc2VkIG9uIGEgc2V0IG9mIGNvbmZpZ3VyYXRpb25zXG4gICAqIEBwYXJhbSBwYXJhbXMuYWRkcmVzc1R5cGUge3N0cmluZ30gICBEZXByZWNhdGVkXG4gICAqIEBwYXJhbSBwYXJhbXMua2V5Y2hhaW5zICAge1tvYmplY3RdfSBBcnJheSBvZiBvYmplY3RzIHdpdGggeHB1YnNcbiAgICogQHBhcmFtIHBhcmFtcy50aHJlc2hvbGQgICB7bnVtYmVyfSAgIE1pbmltdW0gbnVtYmVyIG9mIHNpZ25hdHVyZXNcbiAgICogQHBhcmFtIHBhcmFtcy5jaGFpbiAgICAgICB7bnVtYmVyfSAgIERlcml2YXRpb24gY2hhaW4gKHNlZSBodHRwczovL2dpdGh1Yi5jb20vQml0R28vdW5zcGVudHMvYmxvYi9tYXN0ZXIvc3JjL2NvZGVzLnRzIGZvclxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgY29ycmVzcG9uZGluZyBhZGRyZXNzIHR5cGUgb2YgYSBnaXZlbiBjaGFpbiBjb2RlKVxuICAgKiBAcGFyYW0gcGFyYW1zLmluZGV4ICAgICAgIHtudW1iZXJ9ICAgRGVyaXZhdGlvbiBpbmRleFxuICAgKiBAcGFyYW0gcGFyYW1zLnNlZ3dpdCAgICAgIHtib29sZWFufSAgRGVwcmVjYXRlZFxuICAgKiBAcGFyYW0gcGFyYW1zLmJlY2gzMiAgICAgIHtib29sZWFufSAgRGVwcmVjYXRlZFxuICAgKiBAcmV0dXJucyB7e2NoYWluOiBudW1iZXIsIGluZGV4OiBudW1iZXIsIGNvaW46IG51bWJlciwgY29pblNwZWNpZmljOiB7b3V0cHV0U2NyaXB0LCByZWRlZW1TY3JpcHR9fX1cbiAgICovXG4gIGdlbmVyYXRlQWRkcmVzcyhwYXJhbXM6IEdlbmVyYXRlQWRkcmVzc09wdGlvbnMpOiBBZGRyZXNzRGV0YWlscyB7XG4gICAgY29uc3QgeyBrZXljaGFpbnMsIHRocmVzaG9sZCwgY2hhaW4sIGluZGV4LCBzZWd3aXQgPSBmYWxzZSwgYmVjaDMyID0gZmFsc2UgfSA9IHBhcmFtcztcbiAgICBsZXQgZGVyaXZhdGlvbkNoYWluID0gZ2V0RXh0ZXJuYWxDaGFpbkNvZGUoJ3Ayc2gnKTtcbiAgICBpZiAoXy5pc051bWJlcihjaGFpbikgJiYgXy5pc0ludGVnZXIoY2hhaW4pICYmIGlzQ2hhaW5Db2RlKGNoYWluKSkge1xuICAgICAgZGVyaXZhdGlvbkNoYWluID0gY2hhaW47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY29udmVydEZsYWdzVG9BZGRyZXNzVHlwZSgpOiBTY3JpcHRUeXBlMk9mMyB7XG4gICAgICBpZiAoaXNDaGFpbkNvZGUoY2hhaW4pKSB7XG4gICAgICAgIHJldHVybiB1dHhvbGliLmJpdGdvLnNjcmlwdFR5cGVGb3JDaGFpbihjaGFpbik7XG4gICAgICB9XG4gICAgICBpZiAoXy5pc0Jvb2xlYW4oc2Vnd2l0KSAmJiBzZWd3aXQpIHtcbiAgICAgICAgcmV0dXJuICdwMnNoUDJ3c2gnO1xuICAgICAgfSBlbHNlIGlmIChfLmlzQm9vbGVhbihiZWNoMzIpICYmIGJlY2gzMikge1xuICAgICAgICByZXR1cm4gJ3Ayd3NoJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAncDJzaCc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYWRkcmVzc1R5cGUgPSBwYXJhbXMuYWRkcmVzc1R5cGUgfHwgY29udmVydEZsYWdzVG9BZGRyZXNzVHlwZSgpO1xuXG4gICAgaWYgKGFkZHJlc3NUeXBlICE9PSB1dHhvbGliLmJpdGdvLnNjcmlwdFR5cGVGb3JDaGFpbihkZXJpdmF0aW9uQ2hhaW4pKSB7XG4gICAgICB0aHJvdyBuZXcgQWRkcmVzc1R5cGVDaGFpbk1pc21hdGNoRXJyb3IoYWRkcmVzc1R5cGUsIGRlcml2YXRpb25DaGFpbik7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnN1cHBvcnRzQWRkcmVzc1R5cGUoYWRkcmVzc1R5cGUpKSB7XG4gICAgICBzd2l0Y2ggKGFkZHJlc3NUeXBlKSB7XG4gICAgICAgIGNhc2UgJ3Ayc2gnOlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgaW50ZXJuYWwgZXJyb3I6IHAyc2ggc2hvdWxkIGFsd2F5cyBiZSBzdXBwb3J0ZWRgKTtcbiAgICAgICAgY2FzZSAncDJzaFAyd3NoJzpcbiAgICAgICAgICB0aHJvdyBuZXcgUDJzaFAyd3NoVW5zdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICBjYXNlICdwMndzaCc6XG4gICAgICAgICAgdGhyb3cgbmV3IFAyd3NoVW5zdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICBjYXNlICdwMnRyJzpcbiAgICAgICAgICB0aHJvdyBuZXcgUDJ0clVuc3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUVycm9yKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHNpZ25hdHVyZVRocmVzaG9sZCA9IDI7XG4gICAgaWYgKF8uaXNJbnRlZ2VyKHRocmVzaG9sZCkpIHtcbiAgICAgIHNpZ25hdHVyZVRocmVzaG9sZCA9IHRocmVzaG9sZCBhcyBudW1iZXI7XG4gICAgICBpZiAoc2lnbmF0dXJlVGhyZXNob2xkIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aHJlc2hvbGQgaGFzIHRvIGJlIHBvc2l0aXZlJyk7XG4gICAgICB9XG4gICAgICBpZiAoc2lnbmF0dXJlVGhyZXNob2xkID4ga2V5Y2hhaW5zLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RocmVzaG9sZCBjYW5ub3QgZXhjZWVkIG51bWJlciBvZiBrZXlzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGRlcml2YXRpb25JbmRleCA9IDA7XG4gICAgaWYgKF8uaXNJbnRlZ2VyKGluZGV4KSAmJiAoaW5kZXggYXMgbnVtYmVyKSA+IDApIHtcbiAgICAgIGRlcml2YXRpb25JbmRleCA9IGluZGV4IGFzIG51bWJlcjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXRoID0gJzAvMC8nICsgZGVyaXZhdGlvbkNoYWluICsgJy8nICsgZGVyaXZhdGlvbkluZGV4O1xuICAgIGNvbnN0IGhkTm9kZXMgPSBrZXljaGFpbnMubWFwKCh7IHB1YiB9KSA9PiBiaXAzMi5mcm9tQmFzZTU4KHB1YikpO1xuICAgIGNvbnN0IGRlcml2ZWRLZXlzID0gaGROb2Rlcy5tYXAoKGhkTm9kZSkgPT4gaGROb2RlLmRlcml2ZVBhdGgoc2FuaXRpemVMZWdhY3lQYXRoKHBhdGgpKS5wdWJsaWNLZXkpO1xuXG4gICAgY29uc3QgeyBvdXRwdXRTY3JpcHQsIHJlZGVlbVNjcmlwdCwgd2l0bmVzc1NjcmlwdCwgYWRkcmVzcyB9ID0gdGhpcy5jcmVhdGVNdWx0aVNpZ0FkZHJlc3MoXG4gICAgICBhZGRyZXNzVHlwZSxcbiAgICAgIHNpZ25hdHVyZVRocmVzaG9sZCxcbiAgICAgIGRlcml2ZWRLZXlzXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhZGRyZXNzLFxuICAgICAgY2hhaW46IGRlcml2YXRpb25DaGFpbixcbiAgICAgIGluZGV4OiBkZXJpdmF0aW9uSW5kZXgsXG4gICAgICBjb2luOiB0aGlzLmdldENoYWluKCksXG4gICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgb3V0cHV0U2NyaXB0OiBvdXRwdXRTY3JpcHQudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICByZWRlZW1TY3JpcHQ6IHJlZGVlbVNjcmlwdCAmJiByZWRlZW1TY3JpcHQudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICB3aXRuZXNzU2NyaXB0OiB3aXRuZXNzU2NyaXB0ICYmIHdpdG5lc3NTY3JpcHQudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfSxcbiAgICAgIGFkZHJlc3NUeXBlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXNzZW1ibGUga2V5Y2hhaW4gYW5kIGhhbGYtc2lnbiBwcmVidWlsdCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zIC0ge0BzZWUgU2lnblRyYW5zYWN0aW9uT3B0aW9uc31cbiAgICogQHJldHVybnMge1Byb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24gfCBIYWxmU2lnbmVkVXR4b1RyYW5zYWN0aW9uPn1cbiAgICovXG4gIGFzeW5jIHNpZ25UcmFuc2FjdGlvbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgICBwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlcj5cbiAgKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbiB8IEhhbGZTaWduZWRVdHhvVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0eFByZWJ1aWxkID0gcGFyYW1zLnR4UHJlYnVpbGQ7XG4gICAgY29uc3QgdXNlclBydiA9IHBhcmFtcy5wcnY7XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZCh0eFByZWJ1aWxkKSB8fCAhXy5pc09iamVjdCh0eFByZWJ1aWxkKSkge1xuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHR4UHJlYnVpbGQpICYmICFfLmlzT2JqZWN0KHR4UHJlYnVpbGQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdHhQcmVidWlsZCBtdXN0IGJlIGFuIG9iamVjdCwgZ290IHR5cGUgJHt0eXBlb2YgdHhQcmVidWlsZH1gKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFByZWJ1aWxkIHBhcmFtZXRlcicpO1xuICAgIH1cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KHR4UHJlYnVpbGQudHhIZXgpO1xuXG4gICAgaWYgKHRyYW5zYWN0aW9uLmlucy5sZW5ndGggIT09IHR4UHJlYnVpbGQudHhJbmZvLnVuc3BlbnRzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2YgdW5zcGVudHMgYXJyYXkgc2hvdWxkIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgdHJhbnNhY3Rpb24gaW5wdXRzJyk7XG4gICAgfVxuXG4gICAgbGV0IGlzTGFzdFNpZ25hdHVyZSA9IGZhbHNlO1xuICAgIGlmIChfLmlzQm9vbGVhbihwYXJhbXMuaXNMYXN0U2lnbmF0dXJlKSkge1xuICAgICAgLy8gaWYgYnVpbGQgaXMgY2FsbGVkIGluc3RlYWQgb2YgYnVpbGRJbmNvbXBsZXRlLCBubyBzaWduYXR1cmUgcGxhY2Vob2xkZXJzIGFyZSBsZWZ0IGluIHRoZSBzaWcgc2NyaXB0XG4gICAgICBpc0xhc3RTaWduYXR1cmUgPSBwYXJhbXMuaXNMYXN0U2lnbmF0dXJlO1xuICAgIH1cblxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHVzZXJQcnYpIHx8ICFfLmlzU3RyaW5nKHVzZXJQcnYpKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQodXNlclBydikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcnYgbXVzdCBiZSBhIHN0cmluZywgZ290IHR5cGUgJHt0eXBlb2YgdXNlclBydn1gKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBwcnYgcGFyYW1ldGVyIHRvIHNpZ24gdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmFtcy5wdWJzIHx8IHBhcmFtcy5wdWJzLmxlbmd0aCAhPT0gMykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdXN0IHByb3ZpZGUgeHB1YiBhcnJheWApO1xuICAgIH1cblxuICAgIGNvbnN0IHNpZ25lcktleWNoYWluID0gYmlwMzIuZnJvbUJhc2U1OCh1c2VyUHJ2LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgIGlmIChzaWduZXJLZXljaGFpbi5pc05ldXRlcmVkKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgdXNlciBwcml2YXRlIGtleSBidXQgcmVjZWl2ZWQgcHVibGljIGtleScpO1xuICAgIH1cbiAgICBkZWJ1ZyhgSGVyZSBpcyB0aGUgcHVibGljIGtleSBvZiB0aGUgeHBydiB5b3UgdXNlZCB0byBzaWduOiAke3NpZ25lcktleWNoYWluLm5ldXRlcmVkKCkudG9CYXNlNTgoKX1gKTtcblxuICAgIGNvbnN0IGNvc2lnbmVyUHViID0gcGFyYW1zLmNvc2lnbmVyUHViID8/IHBhcmFtcy5wdWJzWzJdO1xuICAgIGNvbnN0IGtleWNoYWlucyA9IHBhcmFtcy5wdWJzLm1hcCgocHViKSA9PiBiaXAzMi5mcm9tQmFzZTU4KHB1YikpIGFzIFRyaXBsZTxCSVAzMkludGVyZmFjZT47XG4gICAgY29uc3QgY29zaWduZXJLZXljaGFpbiA9IGJpcDMyLmZyb21CYXNlNTgoY29zaWduZXJQdWIpO1xuXG4gICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBzaWduQW5kVmVyaWZ5V2FsbGV0VHJhbnNhY3Rpb24oXG4gICAgICB0cmFuc2FjdGlvbixcbiAgICAgIHR4UHJlYnVpbGQudHhJbmZvLnVuc3BlbnRzLFxuICAgICAgbmV3IGJpdGdvLldhbGxldFVuc3BlbnRTaWduZXI8Um9vdFdhbGxldEtleXM+KGtleWNoYWlucywgc2lnbmVyS2V5Y2hhaW4sIGNvc2lnbmVyS2V5Y2hhaW4pLFxuICAgICAgeyBpc0xhc3RTaWduYXR1cmUgfVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHhIZXg6IHNpZ25lZFRyYW5zYWN0aW9uLnRvQnVmZmVyKCkudG9TdHJpbmcoJ2hleCcpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHVuc3BlbnRcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBpc0JpdEdvVGFpbnRlZFVuc3BlbnQ8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4odW5zcGVudDogVW5zcGVudDxUTnVtYmVyPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1JlcGxheVByb3RlY3Rpb25VbnNwZW50PFROdW1iZXI+KHVuc3BlbnQsIHRoaXMubmV0d29yayk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgLSB1c2UgdXR4b2xpYi5iaXRnby5nZXREZWZhdWx0U2lnSGFzaChuZXR3b3JrKSBpbnN0ZWFkXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgZGVmYXVsdFNpZ0hhc2hUeXBlKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHV0eG9saWIuYml0Z28uZ2V0RGVmYXVsdFNpZ0hhc2godGhpcy5uZXR3b3JrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCAtIHVzZSB1dHhvbGliLmJpdGNvaW4udmVyaWZ5U2lnbmF0dXJlKCkgaW5zdGVhZFxuICAgKi9cbiAgdmVyaWZ5U2lnbmF0dXJlKFxuICAgIHRyYW5zYWN0aW9uOiBhbnksXG4gICAgaW5wdXRJbmRleDogbnVtYmVyLFxuICAgIGFtb3VudDogbnVtYmVyLFxuICAgIHZlcmlmaWNhdGlvblNldHRpbmdzOiB7XG4gICAgICBzaWduYXR1cmVJbmRleD86IG51bWJlcjtcbiAgICAgIHB1YmxpY0tleT86IHN0cmluZztcbiAgICB9ID0ge31cbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKHRyYW5zYWN0aW9uLm5ldHdvcmsgIT09IHRoaXMubmV0d29yaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBuZXR3b3JrIG1pc21hdGNoYCk7XG4gICAgfVxuICAgIHJldHVybiB1dHhvbGliLmJpdGdvLnZlcmlmeVNpZ25hdHVyZSh0cmFuc2FjdGlvbiwgaW5wdXRJbmRleCwgYW1vdW50LCB7XG4gICAgICBzaWduYXR1cmVJbmRleDogdmVyaWZpY2F0aW9uU2V0dGluZ3Muc2lnbmF0dXJlSW5kZXgsXG4gICAgICBwdWJsaWNLZXk6IHZlcmlmaWNhdGlvblNldHRpbmdzLnB1YmxpY0tleSA/IEJ1ZmZlci5mcm9tKHZlcmlmaWNhdGlvblNldHRpbmdzLnB1YmxpY0tleSwgJ2hleCcpIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY29tcG9zZSBhIHJhdyB0cmFuc2FjdGlvbiBpbnRvIHVzZWZ1bCBpbmZvcm1hdGlvbiwgc3VjaCBhcyB0aGUgdG90YWwgYW1vdW50cyxcbiAgICogY2hhbmdlIGFtb3VudHMsIGFuZCB0cmFuc2FjdGlvbiBvdXRwdXRzLlxuICAgKiBAcGFyYW0gcGFyYW1zXG4gICAqL1xuICBhc3luYyBleHBsYWluVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gICAgcGFyYW1zOiBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXI+XG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGNvbnN0IHR4SGV4ID0gXy5nZXQocGFyYW1zLCAndHhIZXgnKTtcbiAgICBpZiAoIXR4SGV4IHx8ICFfLmlzU3RyaW5nKHR4SGV4KSB8fCAhdHhIZXgubWF0Y2goL14oW2EtZjAtOV17Mn0pKyQvaSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB0cmFuc2FjdGlvbiBoZXgsIG11c3QgYmUgYSB2YWxpZCBoZXggc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgbGV0IHRyYW5zYWN0aW9uO1xuICAgIHRyeSB7XG4gICAgICB0cmFuc2FjdGlvbiA9IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KHR4SGV4KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBwYXJzZSB0cmFuc2FjdGlvbiBoZXgnKTtcbiAgICB9XG5cbiAgICBjb25zdCBpZCA9IHRyYW5zYWN0aW9uLmdldElkKCk7XG4gICAgbGV0IHNwZW5kQW1vdW50ID0gdXR4b2xpYi5iaXRnby50b1ROdW1iZXI8VE51bWJlcj4oMCwgdGhpcy5hbW91bnRUeXBlKTtcbiAgICBsZXQgY2hhbmdlQW1vdW50ID0gdXR4b2xpYi5iaXRnby50b1ROdW1iZXI8VE51bWJlcj4oMCwgdGhpcy5hbW91bnRUeXBlKTtcbiAgICBjb25zdCBleHBsYW5hdGlvbiA9IHtcbiAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlQW1vdW50JywgJ291dHB1dHMnLCAnY2hhbmdlT3V0cHV0cyddLFxuICAgICAgaWQ6IGlkLFxuICAgICAgb3V0cHV0czogW10gYXMgT3V0cHV0W10sXG4gICAgICBjaGFuZ2VPdXRwdXRzOiBbXSBhcyBPdXRwdXRbXSxcbiAgICB9IGFzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG5cbiAgICBjb25zdCB7IGNoYW5nZUFkZHJlc3NlcyA9IFtdLCB1bnNwZW50cyA9IFtdIH0gPSBwYXJhbXMudHhJbmZvID8/IHt9O1xuXG4gICAgdHJhbnNhY3Rpb24ub3V0cy5mb3JFYWNoKChjdXJyZW50T3V0cHV0KSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50QWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KGN1cnJlbnRPdXRwdXQuc2NyaXB0LCB0aGlzLm5ldHdvcmspO1xuICAgICAgY29uc3QgY3VycmVudEFtb3VudCA9IGN1cnJlbnRPdXRwdXQudmFsdWU7XG5cbiAgICAgIGlmIChjaGFuZ2VBZGRyZXNzZXMuaW5jbHVkZXMoY3VycmVudEFkZHJlc3MpKSB7XG4gICAgICAgIC8vIHRoaXMgaXMgY2hhbmdlXG4gICAgICAgIGNoYW5nZUFtb3VudCArPSBjdXJyZW50QW1vdW50O1xuICAgICAgICBleHBsYW5hdGlvbi5jaGFuZ2VPdXRwdXRzLnB1c2goe1xuICAgICAgICAgIGFkZHJlc3M6IGN1cnJlbnRBZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogY3VycmVudEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzcGVuZEFtb3VudCArPSBjdXJyZW50QW1vdW50O1xuICAgICAgZXhwbGFuYXRpb24ub3V0cHV0cy5wdXNoKHtcbiAgICAgICAgYWRkcmVzczogY3VycmVudEFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogY3VycmVudEFtb3VudC50b1N0cmluZygpLFxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgZXhwbGFuYXRpb24ub3V0cHV0QW1vdW50ID0gc3BlbmRBbW91bnQudG9TdHJpbmcoKTtcbiAgICBleHBsYW5hdGlvbi5jaGFuZ2VBbW91bnQgPSBjaGFuZ2VBbW91bnQudG9TdHJpbmcoKTtcblxuICAgIC8vIGFkZCBmZWUgaW5mbyBpZiBhdmFpbGFibGVcbiAgICBpZiAocGFyYW1zLmZlZUluZm8pIHtcbiAgICAgIGV4cGxhbmF0aW9uLmRpc3BsYXlPcmRlci5wdXNoKCdmZWUnKTtcbiAgICAgIGV4cGxhbmF0aW9uLmZlZSA9IHBhcmFtcy5mZWVJbmZvO1xuICAgIH1cblxuICAgIGlmIChfLmlzSW50ZWdlcih0cmFuc2FjdGlvbi5sb2NrdGltZSkgJiYgdHJhbnNhY3Rpb24ubG9ja3RpbWUgPiAwKSB7XG4gICAgICBleHBsYW5hdGlvbi5sb2NrdGltZSA9IHRyYW5zYWN0aW9uLmxvY2t0aW1lO1xuICAgICAgZXhwbGFuYXRpb24uZGlzcGxheU9yZGVyLnB1c2goJ2xvY2t0aW1lJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHJldk91dHB1dHMgPSBwYXJhbXMudHhJbmZvPy51bnNwZW50cy5tYXAoKHUpID0+IHRvT3V0cHV0PFROdW1iZXI+KHUsIHRoaXMubmV0d29yaykpO1xuXG4gICAgLy8gaWYga2V5cyBhcmUgcHJvdmlkZWQsIHByZXBhcmUgdGhlIGtleXMgZm9yIGlucHV0IHNpZ25hdHVyZSBjaGVja2luZ1xuICAgIGNvbnN0IGtleXMgPSBwYXJhbXMucHVicz8ubWFwKCh4cHViKSA9PiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpKTtcbiAgICBjb25zdCB3YWxsZXRLZXlzID0ga2V5cyAmJiBrZXlzLmxlbmd0aCA9PT0gMyA/IG5ldyBiaXRnby5Sb290V2FsbGV0S2V5cyhrZXlzIGFzIFRyaXBsZTxCSVAzMkludGVyZmFjZT4pIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gZ2V0IHRoZSBudW1iZXIgb2Ygc2lnbmF0dXJlcyBwZXIgaW5wdXRcbiAgICBjb25zdCBpbnB1dFNpZ25hdHVyZUNvdW50cyA9IHRyYW5zYWN0aW9uLmlucy5tYXAoKGlucHV0LCBpZHgpOiBudW1iZXIgPT4ge1xuICAgICAgaWYgKHVuc3BlbnRzLmxlbmd0aCAhPT0gdHJhbnNhY3Rpb24uaW5zLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFwcmV2T3V0cHV0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgc3RhdGVgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCF3YWxsZXRLZXlzKSB7XG4gICAgICAgIC8vIG5vIHB1YiBrZXlzIG9yIGluY29ycmVjdCBudW1iZXIgb2YgcHViIGtleXNcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB2ZXJpZnlTaWduYXR1cmVXaXRoVW5zcGVudDxUTnVtYmVyPih0cmFuc2FjdGlvbiwgaWR4LCB1bnNwZW50cywgd2FsbGV0S2V5cykuZmlsdGVyKCh2KSA9PiB2KS5sZW5ndGg7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIHNvbWUgb3RoZXIgZXJyb3Igb2NjdXJyZWQgYW5kIHdlIGNhbid0IHZhbGlkYXRlIHRoZSBzaWduYXR1cmVzXG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZXhwbGFuYXRpb24uaW5wdXRTaWduYXR1cmVzID0gaW5wdXRTaWduYXR1cmVDb3VudHM7XG4gICAgZXhwbGFuYXRpb24uc2lnbmF0dXJlcyA9IF8ubWF4KGlucHV0U2lnbmF0dXJlQ291bnRzKSBhcyBudW1iZXI7XG4gICAgcmV0dXJuIGV4cGxhbmF0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG11bHRpc2lnIGFkZHJlc3Mgb2YgYSBnaXZlbiB0eXBlIGZyb20gYSBsaXN0IG9mIGtleWNoYWlucyBhbmQgYSBzaWduaW5nIHRocmVzaG9sZFxuICAgKiBAcGFyYW0gYWRkcmVzc1R5cGVcbiAgICogQHBhcmFtIHNpZ25hdHVyZVRocmVzaG9sZFxuICAgKiBAcGFyYW0ga2V5c1xuICAgKi9cbiAgY3JlYXRlTXVsdGlTaWdBZGRyZXNzKGFkZHJlc3NUeXBlOiBTY3JpcHRUeXBlMk9mMywgc2lnbmF0dXJlVGhyZXNob2xkOiBudW1iZXIsIGtleXM6IEJ1ZmZlcltdKTogTXVsdGlTaWdBZGRyZXNzIHtcbiAgICBjb25zdCB7XG4gICAgICBzY3JpcHRQdWJLZXk6IG91dHB1dFNjcmlwdCxcbiAgICAgIHJlZGVlbVNjcmlwdCxcbiAgICAgIHdpdG5lc3NTY3JpcHQsXG4gICAgfSA9IHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5jcmVhdGVPdXRwdXRTY3JpcHQyb2YzKGtleXMsIGFkZHJlc3NUeXBlKTtcblxuICAgIHJldHVybiB7XG4gICAgICBvdXRwdXRTY3JpcHQsXG4gICAgICByZWRlZW1TY3JpcHQsXG4gICAgICB3aXRuZXNzU2NyaXB0LFxuICAgICAgYWRkcmVzczogdXR4b2xpYi5hZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQob3V0cHV0U2NyaXB0LCB0aGlzLm5ldHdvcmspLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgLSB1c2Uge0BzZWUgYmFja3VwS2V5UmVjb3Zlcnl9XG4gICAqIEJ1aWxkcyBhIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R29cbiAgICogQHBhcmFtIHBhcmFtcyAtIHtAc2VlIGJhY2t1cEtleVJlY292ZXJ5fVxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlcihwYXJhbXM6IFJlY292ZXJQYXJhbXMpOiBSZXR1cm5UeXBlPHR5cGVvZiBiYWNrdXBLZXlSZWNvdmVyeT4ge1xuICAgIHJldHVybiBiYWNrdXBLZXlSZWNvdmVyeSh0aGlzLCB0aGlzLmJpdGdvLCBwYXJhbXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY292ZXIgY29pbiB0aGF0IHdhcyBzZW50IHRvIHdyb25nIGNoYWluXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHBhcmFtIHBhcmFtcy50eGlkIFRoZSB0eGlkIG9mIHRoZSBmYXVsdHkgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtcy5yZWNvdmVyeUFkZHJlc3MgYWRkcmVzcyB0byBzZW5kIHJlY292ZXJlZCBmdW5kcyB0b1xuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldCB0aGUgd2FsbGV0IHRoYXQgcmVjZWl2ZWQgdGhlIGZ1bmRzXG4gICAqIEBwYXJhbSBwYXJhbXMucmVjb3ZlcnlDb2luIHRoZSBjb2luIHR5cGUgb2YgdGhlIHdhbGxldCB0aGF0IHJlY2VpdmVkIHRoZSBmdW5kc1xuICAgKiBAcGFyYW0gcGFyYW1zLnNpZ25lZCByZXR1cm4gYSBoYWxmLXNpZ25lZCB0cmFuc2FjdGlvbiAoZGVmYXVsdD10cnVlKVxuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldFBhc3NwaHJhc2UgdGhlIHdhbGxldCBwYXNzcGhyYXNlXG4gICAqIEBwYXJhbSBwYXJhbXMueHBydiB0aGUgdW5lbmNyeXB0ZWQgeHBydiAodXNlZCBpbnN0ZWFkIG9mIHdhbGxldCBwYXNzcGhyYXNlKVxuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIHJlY292ZXJGcm9tV3JvbmdDaGFpbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgICBwYXJhbXM6IFJlY292ZXJGcm9tV3JvbmdDaGFpbk9wdGlvbnNcbiAgKTogUHJvbWlzZTxDcm9zc0NoYWluUmVjb3ZlcnlTaWduZWQ8VE51bWJlcj4gfCBDcm9zc0NoYWluUmVjb3ZlcnlVbnNpZ25lZDxUTnVtYmVyPj4ge1xuICAgIGNvbnN0IHsgdHhpZCwgcmVjb3ZlcnlBZGRyZXNzLCB3YWxsZXQsIHdhbGxldFBhc3NwaHJhc2UsIHhwcnYgfSA9IHBhcmFtcztcblxuICAgIC8vIHBhcmFtcy5yZWNvdmVyeUNvaW4gdXNlZCB0byBiZSBwYXJhbXMuY29pbiwgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICBjb25zdCByZWNvdmVyeUNvaW4gPSBwYXJhbXMuY29pbiB8fCBwYXJhbXMucmVjb3ZlcnlDb2luO1xuICAgIGlmICghcmVjb3ZlcnlDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgb2JqZWN0IHJlY292ZXJ5Q29pbicpO1xuICAgIH1cbiAgICAvLyBzaWduZWQgc2hvdWxkIGRlZmF1bHQgdG8gdHJ1ZSwgYW5kIG9ubHkgYmUgZGlzYWJsZWQgaWYgZXhwbGljaXRseSBzZXQgdG8gZmFsc2UgKG5vdCB1bmRlZmluZWQpXG4gICAgY29uc3Qgc2lnbmVkID0gcGFyYW1zLnNpZ25lZCAhPT0gZmFsc2U7XG5cbiAgICBjb25zdCBzb3VyY2VDb2luRmFtaWx5ID0gdGhpcy5nZXRGYW1pbHkoKTtcbiAgICBjb25zdCByZWNvdmVyeUNvaW5GYW1pbHkgPSByZWNvdmVyeUNvaW4uZ2V0RmFtaWx5KCk7XG4gICAgY29uc3Qgc3VwcG9ydGVkUmVjb3ZlcnlDb2lucyA9IHN1cHBvcnRlZENyb3NzQ2hhaW5SZWNvdmVyaWVzW3NvdXJjZUNvaW5GYW1pbHldO1xuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc3VwcG9ydGVkUmVjb3ZlcnlDb2lucykgfHwgIXN1cHBvcnRlZFJlY292ZXJ5Q29pbnMuaW5jbHVkZXMocmVjb3ZlcnlDb2luRmFtaWx5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWNvdmVyeSBvZiAke3NvdXJjZUNvaW5GYW1pbHl9IGJhbGFuY2VzIGZyb20gJHtyZWNvdmVyeUNvaW5GYW1pbHl9IHdhbGxldHMgaXMgbm90IHN1cHBvcnRlZC5gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgcmVjb3ZlckNyb3NzQ2hhaW48VE51bWJlcj4odGhpcy5iaXRnbywge1xuICAgICAgc291cmNlQ29pbjogdGhpcyxcbiAgICAgIHJlY292ZXJ5Q29pbixcbiAgICAgIHdhbGxldElkOiB3YWxsZXQsXG4gICAgICB0eGlkLFxuICAgICAgcmVjb3ZlcnlBZGRyZXNzLFxuICAgICAgd2FsbGV0UGFzc3BocmFzZTogc2lnbmVkID8gd2FsbGV0UGFzc3BocmFzZSA6IHVuZGVmaW5lZCxcbiAgICAgIHhwcnY6IHNpZ25lZCA/IHhwcnYgOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYmlwMzIga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiBhbmQgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZDogQnVmZmVyKTogeyBwdWI6IHN0cmluZzsgcHJ2OiBzdHJpbmcgfSB7XG4gICAgaWYgKCFzZWVkKSB7XG4gICAgICAvLyBBbiBleHRlbmRlZCBwcml2YXRlIGtleSBoYXMgYm90aCBhIG5vcm1hbCAyNTYgYml0IHByaXZhdGUga2V5IGFuZCBhIDI1NlxuICAgICAgLy8gYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZSByYW5kb20uIDUxMiBiaXRzIGlzIHRoZXJlZm9yZSB0aGVcbiAgICAgIC8vIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBleHRlbmRlZEtleSA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGV4dGVuZGVkS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogZXh0ZW5kZWRLZXkudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZ2V0RXh0cmFQcmVidWlsZFBhcmFtcyhidWlsZFBhcmFtczogRXh0cmFQcmVidWlsZFBhcmFtc09wdGlvbnMpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHByZUNyZWF0ZUJpdEdvKHBhcmFtczogUHJlY3JlYXRlQml0R29PcHRpb25zKTogdm9pZCB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYXN5bmMgcHJlc2lnblRyYW5zYWN0aW9uKHBhcmFtczogUHJlc2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHBhcmFtcztcbiAgfVxuXG4gIGFzeW5jIHN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldChcbiAgICB3YWxsZXRQYXJhbXM6IFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMsXG4gICAga2V5Y2hhaW5zOiBLZXljaGFpbnNUcmlwbGV0XG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHdhbGxldFBhcmFtcztcbiAgfVxuXG4gIHRyYW5zYWN0aW9uRGF0YUFsbG93ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
980
+ /**
981
+ * Key Value: Unsigned tx id => PSBT
982
+ * It is used to cache PSBTs with taproot key path (MuSig2) inputs during external express signer is activated.
983
+ * Reason: MuSig2 signer secure nonce is cached in the UtxoPsbt object. It will be required during the signing step.
984
+ * For more info, check SignTransactionOptions.signingStep
985
+ *
986
+ * TODO BTC-276: This cache may need to be done with LRU like memory safe caching if memory issues comes up.
987
+ */
988
+ AbstractUtxoCoin.PSBT_CACHE = new Map();
989
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RVdHhvQ29pbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hYnN0cmFjdFV0eG9Db2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOztHQUVHO0FBQ0gsZ0RBQWdEO0FBQ2hELG1EQUFvRTtBQUNwRSxpQ0FBaUM7QUFDakMsb0RBQW9EO0FBQ3BELG1DQUFxQztBQUNyQyxrQ0FBa0M7QUFDbEMsNEJBQTRCO0FBQzVCLCtDQUFxQztBQUVyQyxvRUFBZ0Y7QUFDaEYseUNBTW9CO0FBRXBCLG1EQTJDOEI7QUFDOUIsK0NBQWlFO0FBRWpFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUd4Qyx5REFBK0Q7QUFDL0QsaUNBQTJFO0FBQzNFLHFDQUF5RDtBQUN6RCwrQ0FBcUY7QUEyQnJGLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUUsYUFBYSxFQUFFLEdBQUcsZ0JBQUssQ0FBQztBQXFFdkYsTUFBYSxzQkFBdUIsU0FBUSxpQkFBTTtJQUdoRCxZQUFZLEtBQWdCLEVBQUUsUUFBbUIsRUFBRSxVQUFlO1FBQ2hFLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Q0FDRjtBQU5ELHdEQU1DO0FBcUlELE1BQXNCLGdCQUFpQixTQUFRLG1CQUFRO0lBTXJELFlBQXNCLEtBQWdCLEVBQUUsT0FBd0IsRUFBRSxhQUFrQyxRQUFRO1FBQzFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNiLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQ2IsK0RBQStEO2dCQUM3RCxrRkFBa0YsQ0FDckYsQ0FBQztTQUNIO1FBQ0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFP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USxFQUFFO1NBQzVCLENBQUM7SUFDSixDQUFDO0lBRUQsS0FBSyxDQUFDLHNCQUFzQixDQUFDLFdBQXVDO1FBQ2xFLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELGNBQWMsQ0FBQyxNQUE2QjtRQUMxQyxPQUFPO0lBQ1QsQ0FBQztJQUVELEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFpQztRQUN4RCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSyxDQUFDLHdCQUF3QixDQUM1QixZQUE2QyxFQUM3QyxTQUEyQjtRQUUzQixPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0lBRUQsc0JBQXNCO1FBQ3BCLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHdCQUF3QjtRQUN0QixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFpQjtRQUNuQyxPQUFPLGtCQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzVDLENBQUM7O0FBN29DSCw0Q0E4b0NDO0FBNW5DQzs7Ozs7OztHQU9HO0FBQ3FCLDJCQUFVLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBwcmV0dGllclxuICovXG5pbXBvcnQgKiBhcyB1dHhvbGliIGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCB7IGJpcDMyLCBCSVAzMkludGVyZmFjZSwgYml0Z28gfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIGJpdGNvaW5NZXNzYWdlIGZyb20gJ2JpdGNvaW5qcy1tZXNzYWdlJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGRlYnVnTGliIGZyb20gJ2RlYnVnJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcblxuaW1wb3J0IHsgYmFja3VwS2V5UmVjb3ZlcnksIFJlY292ZXJQYXJhbXMgfSBmcm9tICcuL3JlY292ZXJ5L2JhY2t1cEtleVJlY292ZXJ5JztcbmltcG9ydCB7XG4gIENyb3NzQ2hhaW5SZWNvdmVyeVNpZ25lZCxcbiAgQ3Jvc3NDaGFpblJlY292ZXJ5VW5zaWduZWQsXG4gIGZvckNvaW4sXG4gIHJlY292ZXJDcm9zc0NoYWluLFxuICBSZWNvdmVyeVByb3ZpZGVyLFxufSBmcm9tICcuL3JlY292ZXJ5JztcblxuaW1wb3J0IHtcbiAgQWRkcmVzc0NvaW5TcGVjaWZpYyxcbiAgQWRkcmVzc1R5cGVDaGFpbk1pc21hdGNoRXJyb3IsXG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIEV4dHJhUHJlYnVpbGRQYXJhbXNPcHRpb25zLFxuICBIYWxmU2lnbmVkVXR4b1RyYW5zYWN0aW9uLFxuICBJQmFzZUNvaW4sXG4gIEludmFsaWRBZGRyZXNzRGVyaXZhdGlvblByb3BlcnR5RXJyb3IsXG4gIEludmFsaWRBZGRyZXNzRXJyb3IsXG4gIEludmFsaWRBZGRyZXNzVmVyaWZpY2F0aW9uT2JqZWN0UHJvcGVydHlFcnJvcixcbiAgSVJlcXVlc3RUcmFjZXIsXG4gIGlzVHJpcGxlLFxuICBJVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBhcyBCYXNlVHJhbnNhY3Rpb25FeHBsYW5hdGlvbixcbiAgSVdhbGxldCxcbiAgS2V5Y2hhaW4sXG4gIEtleWNoYWluc1RyaXBsZXQsXG4gIEtleUluZGljZXMsXG4gIFAyc2hQMndzaFVuc3VwcG9ydGVkRXJyb3IsXG4gIFAydHJNdXNpZzJVbnN1cHBvcnRlZEVycm9yLFxuICBQMnRyVW5zdXBwb3J0ZWRFcnJvcixcbiAgUDJ3c2hVbnN1cHBvcnRlZEVycm9yLFxuICBQYXJzZWRUcmFuc2FjdGlvbiBhcyBCYXNlUGFyc2VkVHJhbnNhY3Rpb24sXG4gIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIGFzIEJhc2VQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgUHJlY3JlYXRlQml0R29PcHRpb25zLFxuICBQcmVzaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBwcm9taXNlUHJvcHMsXG4gIFJlcXVlc3RUcmFjZXIsXG4gIHNhbml0aXplTGVnYWN5UGF0aCxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgYXMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uUGFyYW1zIGFzIEJhc2VUcmFuc2FjdGlvblBhcmFtcyxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCBhcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVHJhbnNhY3Rpb25SZWNpcGllbnQsXG4gIFRyaXBsZSxcbiAgVW5leHBlY3RlZEFkZHJlc3NFcnJvcixcbiAgVW5zdXBwb3J0ZWRBZGRyZXNzVHlwZUVycm9yLFxuICBWZXJpZmljYXRpb25PcHRpb25zLFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyBhcyBCYXNlVmVyaWZ5QWRkcmVzc09wdGlvbnMsXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxuICBXYWxsZXQsXG4gIFdhbGxldERhdGEsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEN1c3RvbUNoYW5nZU9wdGlvbnMsIHBhcnNlT3V0cHV0IH0gZnJvbSAnLi9wYXJzZU91dHB1dCc7XG5cbmNvbnN0IGRlYnVnID0gZGVidWdMaWIoJ2JpdGdvOnYyOnV0eG8nKTtcblxuaW1wb3J0IFNjcmlwdFR5cGUyT2YzID0gdXR4b2xpYi5iaXRnby5vdXRwdXRTY3JpcHRzLlNjcmlwdFR5cGUyT2YzO1xuaW1wb3J0IHsgaXNSZXBsYXlQcm90ZWN0aW9uVW5zcGVudCB9IGZyb20gJy4vcmVwbGF5UHJvdGVjdGlvbic7XG5pbXBvcnQgeyBzaWduQW5kVmVyaWZ5UHNidCwgc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uIH0gZnJvbSAnLi9zaWduJztcbmltcG9ydCB7IHN1cHBvcnRlZENyb3NzQ2hhaW5SZWNvdmVyaWVzIH0gZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IHsgZXhwbGFpblBzYnQsIGV4cGxhaW5UeCwgZ2V0UHNidFR4SW5wdXRzLCBnZXRUeElucHV0cyB9IGZyb20gJy4vdHJhbnNhY3Rpb24nO1xuXG50eXBlIFV0eG9DdXN0b21TaWduaW5nRnVuY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4gPSB7XG4gIChwYXJhbXM6IHtcbiAgICBjb2luOiBJQmFzZUNvaW47XG4gICAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDxUTnVtYmVyPjtcbiAgICBwdWJzPzogc3RyaW5nW107XG4gICAgLyoqXG4gICAgICogc2lnbmluZ1N0ZXAgZmxhZyBiZWNvbWVzIGFwcGxpY2FibGUgd2hlbiBib3RoIG9mIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICAgICAqIDEpIFdoZW4gdGhlIGV4dGVybmFsIGV4cHJlc3Mgc2lnbmVyIGlzIGFjdGl2YXRlZFxuICAgICAqIDIpIFdoZW4gdGhlIFBTQlQgaW5jbHVkZXMgYXQgbGVhc3Qgb25lIHRhcHJvb3RLZXlQYXRoU3BlbmQgaW5wdXQuXG4gICAgICpcbiAgICAgKiBUaGUgc2lnbmluZyBwcm9jZXNzIG9mIGEgdGFwcm9vdEtleVBhdGhTcGVuZCBpbnB1dCBpcyBhIDQtc3RlcCBzZXF1ZW5jZTpcbiAgICAgKiBpKSB1c2VyIG5vbmNlIGdlbmVyYXRpb24gLSBzaWduZXJOb25jZSAtIHRoaXMgaXMgdGhlIGZpcnN0IGNhbGwgdG8gZXh0ZXJuYWwgZXhwcmVzcyBzaWduZXIgc2lnblRyYW5zYWN0aW9uXG4gICAgICogaWkpIGJpdGdvIG5vbmNlIGdlbmVyYXRpb24gLSBjb3NpZ25lck5vbmNlIC0gdGhpcyBpcyB0aGUgZmlyc3QgYW5kIG9ubHkgY2FsbCB0byBsb2NhbCBzaWduVHJhbnNhY3Rpb25cbiAgICAgKiBpaWkpIHVzZXIgc2lnbmF0dXJlIC0gc2lnbmVyU2lnbmF0dXJlIC0gdGhpcyBpcyB0aGUgc2Vjb25kIGNhbGwgdG8gZXh0ZXJuYWwgZXhwcmVzcyBzaWduZXIgc2lnblRyYW5zYWN0aW9uXG4gICAgICogaXYpIGJpdGdvIHNpZ25hdHVyZSAtIG5vdCBpbiBzaWduVHJhbnNhY3Rpb24gbWV0aG9k4oCZcyBzY29wZVxuICAgICAqXG4gICAgICogSW4gdGhlIGFic2VuY2Ugb2YgdGhpcyBmbGFnLCB0aGUgYWZvcmVtZW50aW9uZWQgZmlyc3QgdGhyZWUgc2VxdWVuY2UgaXMgZXhlY3V0ZWQgaW4gYSBzaW5nbGUgc2lnblRyYW5zYWN0aW9uIGNhbGwuXG4gICAgICpcbiAgICAgKiBOT1RFOiBXZSBtYWtlIGEgc3Ryb25nIGFzc3VtcHRpb24gdGhhdCB0aGUgZXh0ZXJuYWwgZXhwcmVzcyBzaWduZXIgYW5kIGl0cyBjYWxsZXIgdXNlcyBzdGlja3kgc2Vzc2lvbnMsXG4gICAgICogc2luY2UgUFNCVHMgYXJlIGNhY2hlZCBpbiBzdGVwIDEgdG8gYmUgdXNlZCBpbiBzdGVwIDMgZm9yIE11U2lnMiB1c2VyIHNlY3VyZSBub25jZSBhY2Nlc3MuXG4gICAgICovXG4gICAgc2lnbmluZ1N0ZXA/OiAnc2lnbmVyTm9uY2UnIHwgJ3NpZ25lclNpZ25hdHVyZScgfCAnY29zaWduZXJOb25jZSc7XG4gIH0pOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPjtcbn07XG5cbmNvbnN0IHsgZ2V0RXh0ZXJuYWxDaGFpbkNvZGUsIGlzQ2hhaW5Db2RlLCBzY3JpcHRUeXBlRm9yQ2hhaW4sIG91dHB1dFNjcmlwdHMgfSA9IGJpdGdvO1xudHlwZSBVbnNwZW50PFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+ID0gYml0Z28uVW5zcGVudDxUTnVtYmVyPjtcblxudHlwZSBSb290V2FsbGV0S2V5cyA9IGJpdGdvLlJvb3RXYWxsZXRLZXlzO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmeUFkZHJlc3NPcHRpb25zIGV4dGVuZHMgQmFzZVZlcmlmeUFkZHJlc3NPcHRpb25zIHtcbiAgY2hhaW46IG51bWJlcjtcbiAgaW5kZXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPdXRwdXQge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGFtb3VudDogc3RyaW5nIHwgbnVtYmVyO1xuICBleHRlcm5hbD86IGJvb2xlYW47XG4gIG5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uRXhwbGFuYXRpb248c3RyaW5nLCBzdHJpbmc+IHtcbiAgbG9ja3RpbWU6IG51bWJlcjtcbiAgb3V0cHV0czogT3V0cHV0W107XG4gIGNoYW5nZU91dHB1dHM6IE91dHB1dFtdO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaW5wdXQgc2lnbmF0dXJlcyBwZXIgaW5wdXQuXG4gICAqL1xuICBpbnB1dFNpZ25hdHVyZXM6IG51bWJlcltdO1xuXG4gIC8qKlxuICAgKiBIaWdoZXN0IGlucHV0IHNpZ25hdHVyZSBjb3VudCBmb3IgdGhlIHRyYW5zYWN0aW9uXG4gICAqL1xuICBzaWduYXR1cmVzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25JbmZvPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+IHtcbiAgLyoqIE1hcHMgdHhpZCB0byB0eGhleC4gUmVxdWlyZWQgZm9yIG9mZmxpbmUgc2lnbmluZy4gKi9cbiAgdHhIZXhlcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGNoYW5nZUFkZHJlc3Nlcz86IHN0cmluZ1tdO1xuICAvKiogcHNidCBkb2VzIG5vdCByZXF1aXJlIHVuc3BlbnRzLiAqL1xuICB1bnNwZW50cz86IFVuc3BlbnQ8VE51bWJlcj5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+IHtcbiAgdHhIZXg6IHN0cmluZztcbiAgdHhJbmZvPzogVHJhbnNhY3Rpb25JbmZvPFROdW1iZXI+O1xuICBmZWVJbmZvPzogc3RyaW5nO1xuICBwdWJzPzogVHJpcGxlPHN0cmluZz47XG59XG5cbmV4cG9ydCB0eXBlIFV0eG9OZXR3b3JrID0gdXR4b2xpYi5OZXR3b3JrO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zYWN0aW9uUHJlYnVpbGQ8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4gZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCB7XG4gIHR4SW5mbz86IFRyYW5zYWN0aW9uSW5mbzxUTnVtYmVyPjtcbiAgYmxvY2tIZWlnaHQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25QYXJhbXMgZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb25QYXJhbXMge1xuICB3YWxsZXRQYXNzcGhyYXNlPzogc3RyaW5nO1xuICBjaGFuZ2VBZGRyZXNzPzogc3RyaW5nO1xufVxuXG4vLyBwYXJzZVRyYW5zYWN0aW9ucycgcmV0dXJuIHR5cGUgbWFrZXMgdXNlIG9mIFdhbGxldERhdGEncyB0eXBlIGJ1dCB3aXRoIGN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXMgYXMgcmVxdWlyZWQuXG5leHBvcnQgaW50ZXJmYWNlIEFic3RyYWN0VXR4b0NvaW5XYWxsZXREYXRhIGV4dGVuZHMgV2FsbGV0RGF0YSB7XG4gIGN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXM6IHtcbiAgICB1c2VyOiBzdHJpbmc7XG4gICAgYmFja3VwOiBzdHJpbmc7XG4gICAgYml0Z286IHN0cmluZztcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIEFic3RyYWN0VXR4b0NvaW5XYWxsZXQgZXh0ZW5kcyBXYWxsZXQge1xuICBwdWJsaWMgX3dhbGxldDogQWJzdHJhY3RVdHhvQ29pbldhbGxldERhdGE7XG5cbiAgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSwgYmFzZUNvaW46IElCYXNlQ29pbiwgd2FsbGV0RGF0YTogYW55KSB7XG4gICAgc3VwZXIoYml0Z28sIGJhc2VDb2luLCB3YWxsZXREYXRhKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+IGV4dGVuZHMgQmFzZVBhcnNlVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQYXJhbXM6IFRyYW5zYWN0aW9uUGFyYW1zO1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkPFROdW1iZXI+O1xuICB3YWxsZXQ6IEFic3RyYWN0VXR4b0NvaW5XYWxsZXQ7XG4gIHZlcmlmaWNhdGlvbj86IFZlcmlmaWNhdGlvbk9wdGlvbnM7XG4gIHJlcUlkPzogSVJlcXVlc3RUcmFjZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VkVHJhbnNhY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4gZXh0ZW5kcyBCYXNlUGFyc2VkVHJhbnNhY3Rpb24ge1xuICBrZXljaGFpbnM6IHtcbiAgICB1c2VyPzogS2V5Y2hhaW47XG4gICAgYmFja3VwPzogS2V5Y2hhaW47XG4gICAgYml0Z28/OiBLZXljaGFpbjtcbiAgfTtcbiAga2V5U2lnbmF0dXJlczoge1xuICAgIGJhY2t1cFB1Yj86IHN0cmluZztcbiAgICBiaXRnb1B1Yj86IHN0cmluZztcbiAgfTtcbiAgb3V0cHV0czogT3V0cHV0W107XG4gIG1pc3NpbmdPdXRwdXRzOiBPdXRwdXRbXTtcbiAgZXhwbGljaXRFeHRlcm5hbE91dHB1dHM6IE91dHB1dFtdO1xuICBpbXBsaWNpdEV4dGVybmFsT3V0cHV0czogT3V0cHV0W107XG4gIGNoYW5nZU91dHB1dHM6IE91dHB1dFtdO1xuICBleHBsaWNpdEV4dGVybmFsU3BlbmRBbW91bnQ6IFROdW1iZXI7XG4gIGltcGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudDogVE51bWJlcjtcbiAgbmVlZHNDdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVWZXJpZmljYXRpb246IGJvb2xlYW47XG4gIGN1c3RvbUNoYW5nZT86IEN1c3RvbUNoYW5nZU9wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2VuZXJhdGVBZGRyZXNzT3B0aW9ucyB7XG4gIGFkZHJlc3NUeXBlPzogU2NyaXB0VHlwZTJPZjM7XG4gIGtleWNoYWluczoge1xuICAgIHB1Yjogc3RyaW5nO1xuICAgIGFzcEtleUlkPzogc3RyaW5nO1xuICB9W107XG4gIHRocmVzaG9sZD86IG51bWJlcjtcbiAgY2hhaW4/OiBudW1iZXI7XG4gIGluZGV4PzogbnVtYmVyO1xuICBzZWd3aXQ/OiBib29sZWFuO1xuICBiZWNoMzI/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZHJlc3NEZXRhaWxzIHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjaGFpbjogbnVtYmVyO1xuICBpbmRleDogbnVtYmVyO1xuICBjb2luOiBzdHJpbmc7XG4gIGNvaW5TcGVjaWZpYzogQWRkcmVzc0NvaW5TcGVjaWZpYztcbiAgYWRkcmVzc1R5cGU/OiBzdHJpbmc7XG59XG5cbnR5cGUgVXR4b0Jhc2VTaWduVHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+ID0gQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgJiB7XG4gIC8qKiBUcmFuc2FjdGlvbiBwcmVidWlsZCBmcm9tIGJpdGdvIHNlcnZlciAqL1xuICB0eFByZWJ1aWxkOiB7XG4gICAgLyoqXG4gICAgICogd2FsbGV0SWQgaXMgcmVxdWlyZWQgaW4gZm9sbG93aW5nIDIgc2NlbmFyaW9zLlxuICAgICAqIDEuIEV4dGVybmFsIHNpZ25lciBleHByZXNzIG1vZGUgaXMgdXNlZC5cbiAgICAgKiAyLiBiaXRnbyBNdVNpZzIgbm9uY2UgaXMgcmVxdWVzdGVkXG4gICAgICovXG4gICAgd2FsbGV0SWQ/OiBzdHJpbmc7XG4gICAgdHhIZXg6IHN0cmluZztcbiAgICB0eEluZm8/OiBUcmFuc2FjdGlvbkluZm88VE51bWJlcj47XG4gIH07XG4gIC8qKiB4cHVicyB0cmlwbGUgZm9yIHdhbGxldCAodXNlciwgYmFja3VwLCBiaXRnbykuIFJlcXVpcmVkIG9ubHkgd2hlbiB0eFByZWJ1aWxkLnR4SGV4IGlzIG5vdCBhIFBTQlQgKi9cbiAgcHVicz86IFRyaXBsZTxzdHJpbmc+O1xuICAvKiogeHB1YiBmb3IgY29zaWduZXIgKGRlZmF1bHRzIHRvIGJpdGdvKSAqL1xuICBjb3NpZ25lclB1Yj86IHN0cmluZztcbiAgLyoqXG4gICAqIFdoZW4gdHJ1ZSwgY3JlYXRlcyBmdWxsLXNpZ25lZCB0cmFuc2FjdGlvbiB3aXRob3V0IHBsYWNlaG9sZGVyIHNpZ25hdHVyZXMuXG4gICAqIFdoZW4gZmFsc2UsIGNyZWF0ZXMgaGFsZi1zaWduZWQgdHJhbnNhY3Rpb24gd2l0aCBwbGFjZWhvbGRlciBzaWduYXR1cmVzLlxuICAgKi9cbiAgaXNMYXN0U2lnbmF0dXJlPzogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCB0eXBlIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4gPSBVdHhvQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlcj4gJlxuICAoXG4gICAgfCB7XG4gICAgICAgIHBydjogc3RyaW5nO1xuICAgICAgICBzaWduaW5nU3RlcD86ICdzaWduZXJOb25jZScgfCAnc2lnbmVyU2lnbmF0dXJlJztcbiAgICAgIH1cbiAgICB8IHtcbiAgICAgICAgc2lnbmluZ1N0ZXA6ICdjb3NpZ25lck5vbmNlJztcbiAgICAgIH1cbiAgKTtcblxuZXhwb3J0IGludGVyZmFjZSBNdWx0aVNpZ0FkZHJlc3Mge1xuICBvdXRwdXRTY3JpcHQ6IEJ1ZmZlcjtcbiAgcmVkZWVtU2NyaXB0PzogQnVmZmVyO1xuICB3aXRuZXNzU2NyaXB0PzogQnVmZmVyO1xuICBhZGRyZXNzOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlckZyb21Xcm9uZ0NoYWluT3B0aW9ucyB7XG4gIHR4aWQ6IHN0cmluZztcbiAgcmVjb3ZlcnlBZGRyZXNzOiBzdHJpbmc7XG4gIHdhbGxldDogc3RyaW5nO1xuICB3YWxsZXRQYXNzcGhyYXNlPzogc3RyaW5nO1xuICB4cHJ2Pzogc3RyaW5nO1xuICBhcGlLZXk/OiBzdHJpbmc7XG4gIC8qKiBAZGVwcmVjYXRlZCAqL1xuICBjb2luPzogQWJzdHJhY3RVdHhvQ29pbjtcbiAgcmVjb3ZlcnlDb2luPzogQWJzdHJhY3RVdHhvQ29pbjtcbiAgc2lnbmVkPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlLZXlTaWduYXR1cmVzT3B0aW9ucyB7XG4gIHVzZXJLZXljaGFpbjogeyBwdWI/OiBzdHJpbmcgfTtcbiAga2V5Y2hhaW5Ub1ZlcmlmeTogeyBwdWI/OiBzdHJpbmcgfTtcbiAga2V5U2lnbmF0dXJlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5VXNlclB1YmxpY0tleU9wdGlvbnMge1xuICB1c2VyS2V5Y2hhaW4/OiBLZXljaGFpbjtcbiAgZGlzYWJsZU5ldHdvcmtpbmc6IGJvb2xlYW47XG4gIHR4UGFyYW1zOiBUcmFuc2FjdGlvblBhcmFtcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj5cbiAgZXh0ZW5kcyBCYXNlVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDxUTnVtYmVyPjtcbiAgd2FsbGV0OiBBYnN0cmFjdFV0eG9Db2luV2FsbGV0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25Qc2J0UmVxdWVzdCB7XG4gIHBzYnQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaWduUHNidFJlc3BvbnNlIHtcbiAgcHNidDogc3RyaW5nO1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RVdHhvQ29pbiBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHVibGljIGFsdFNjcmlwdEhhc2g/OiBudW1iZXI7XG4gIHB1YmxpYyBzdXBwb3J0QWx0U2NyaXB0RGVzdGluYXRpb24/OiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgYW1vdW50VHlwZTogJ251bWJlcicgfCAnYmlnaW50JztcbiAgcHJpdmF0ZSByZWFkb25seSBfbmV0d29yazogdXR4b2xpYi5OZXR3b3JrO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmssIGFtb3VudFR5cGU6ICdudW1iZXInIHwgJ2JpZ2ludCcgPSAnbnVtYmVyJykge1xuICAgIHN1cGVyKGJpdGdvKTtcbiAgICBpZiAoIXV0eG9saWIuaXNWYWxpZE5ldHdvcmsobmV0d29yaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ2ludmFsaWQgbmV0d29yazogcGxlYXNlIG1ha2Ugc3VyZSB0byB1c2UgdGhlIHNhbWUgdmVyc2lvbiBvZiAnICtcbiAgICAgICAgICAnQGJpdGdvLWJldGEvdXR4by1saWIgYXMgdGhpcyBsaWJyYXJ5IHdoZW4gaW5pdGlhbGl6aW5nIGFuIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MnXG4gICAgICApO1xuICAgIH1cbiAgICB0aGlzLmFtb3VudFR5cGUgPSBhbW91bnRUeXBlO1xuICAgIHRoaXMuX25ldHdvcmsgPSBuZXR3b3JrO1xuICB9XG5cbiAgLyoqXG4gICAqIEtleSBWYWx1ZTogVW5zaWduZWQgdHggaWQgPT4gUFNCVFxuICAgKiBJdCBpcyB1c2VkIHRvIGNhY2hlIFBTQlRzIHdpdGggdGFwcm9vdCBrZXkgcGF0aCAoTXVTaWcyKSBpbnB1dHMgZHVyaW5nIGV4dGVybmFsIGV4cHJlc3Mgc2lnbmVyIGlzIGFjdGl2YXRlZC5cbiAgICogUmVhc29uOiBNdVNpZzIgc2lnbmVyIHNlY3VyZSBub25jZSBpcyBjYWNoZWQgaW4gdGhlIFV0eG9Qc2J0IG9iamVjdC4gSXQgd2lsbCBiZSByZXF1aXJlZCBkdXJpbmcgdGhlIHNpZ25pbmcgc3RlcC5cbiAgICogRm9yIG1vcmUgaW5mbywgY2hlY2sgU2lnblRyYW5zYWN0aW9uT3B0aW9ucy5zaWduaW5nU3RlcFxuICAgKlxuICAgKiBUT0RPIEJUQy0yNzY6IFRoaXMgY2FjaGUgbWF5IG5lZWQgdG8gYmUgZG9uZSB3aXRoIExSVSBsaWtlIG1lbW9yeSBzYWZlIGNhY2hpbmcgaWYgbWVtb3J5IGlzc3VlcyBjb21lcyB1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFBTQlRfQ0FDSEUgPSBuZXcgTWFwPHN0cmluZywgdXR4b2xpYi5iaXRnby5VdHhvUHNidD4oKTtcblxuICBnZXQgbmV0d29yaygpIHtcbiAgICByZXR1cm4gdGhpcy5fbmV0d29yaztcbiAgfVxuXG4gIHN3ZWVwV2l0aFNlbmRNYW55KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBkZXByZWNhdGVkICovXG4gIHN0YXRpYyBnZXQgdmFsaWRBZGRyZXNzVHlwZXMoKTogU2NyaXB0VHlwZTJPZjNbXSB7XG4gICAgcmV0dXJuIFsuLi5vdXRwdXRTY3JpcHRzLnNjcmlwdFR5cGVzMk9mM107XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZmFjdG9yIGJldHdlZW4gdGhlIGJhc2UgdW5pdCBhbmQgaXRzIHNtYWxsZXN0IHN1YmRpdmlzb25cbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0QmFzZUZhY3RvcigpIHtcbiAgICByZXR1cm4gMWU4O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkXG4gICAqL1xuICBnZXRDb2luTGlicmFyeSgpIHtcbiAgICByZXR1cm4gdXR4b2xpYjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhZGRyZXNzIGlzIHZhbGlkXG4gICAqIEBwYXJhbSBhZGRyZXNzXG4gICAqIEBwYXJhbSBwYXJhbVxuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nLCBwYXJhbT86IHsgYW55Rm9ybWF0OiBib29sZWFuIH0gfCAvKiBsZWdhY3kgcGFyYW1ldGVyICovIGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBpZiAodHlwZW9mIHBhcmFtID09PSAnYm9vbGVhbicgJiYgcGFyYW0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGVwcmVjYXRlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHMgPSBwYXJhbSAmJiBwYXJhbS5hbnlGb3JtYXQgPyB1bmRlZmluZWQgOiBbJ2RlZmF1bHQnIGFzIGNvbnN0XTtcbiAgICB0cnkge1xuICAgICAgdXR4b2xpYi5hZGRyZXNzRm9ybWF0LnRvT3V0cHV0U2NyaXB0VHJ5Rm9ybWF0cyhhZGRyZXNzLCB0aGlzLm5ldHdvcmssIGZvcm1hdHMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwdWIgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRQdWIocHViOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGJpcDMyLmZyb21CYXNlNTgocHViKS5pc05ldXRlcmVkKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGxhdGVzdCBibG9jayBoZWlnaHRcbiAgICogQHBhcmFtIHJlcUlkXG4gICAqL1xuICBhc3luYyBnZXRMYXRlc3RCbG9ja0hlaWdodChyZXFJZD86IFJlcXVlc3RUcmFjZXIpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmIChyZXFJZCkge1xuICAgICAgdGhpcy5iaXRnby5zZXRSZXF1ZXN0VHJhY2VyKHJlcUlkKTtcbiAgICB9XG4gICAgY29uc3QgY2hhaW5oZWFkID0gYXdhaXQgdGhpcy5iaXRnby5nZXQodGhpcy51cmwoJy9wdWJsaWMvYmxvY2svbGF0ZXN0JykpLnJlc3VsdCgpO1xuICAgIHJldHVybiAoY2hhaW5oZWFkIGFzIGFueSkuaGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBjdXN0b20gY29pbiBsb2dpYyBhZnRlciBhIHRyYW5zYWN0aW9uIHByZWJ1aWxkIGhhcyBiZWVuIHJlY2VpdmVkIGZyb20gQml0R29cbiAgICogQHBhcmFtIHByZWJ1aWxkXG4gICAqL1xuICBhc3luYyBwb3N0UHJvY2Vzc1ByZWJ1aWxkPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQ+KFxuICAgIHByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkPFROdW1iZXI+XG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25QcmVidWlsZDxUTnVtYmVyPj4ge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKHByZWJ1aWxkLnR4SGV4KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHR4UHJlYnVpbGQgcHJvcGVydHkgdHhIZXgnKTtcbiAgICB9XG4gICAgY29uc3QgdHggPSBiaXRnby5pc1BzYnQocHJlYnVpbGQudHhIZXgpXG4gICAgICA/IGJpdGdvLmNyZWF0ZVBzYnRGcm9tSGV4KHByZWJ1aWxkLnR4SGV4LCB0aGlzLm5ldHdvcmspXG4gICAgICA6IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KHByZWJ1aWxkLnR4SGV4KTtcbiAgICBpZiAoXy5pc1VuZGVmaW5lZChwcmVidWlsZC5ibG9ja0hlaWdodCkpIHtcbiAgICAgIHByZWJ1aWxkLmJsb2NrSGVpZ2h0ID0gKGF3YWl0IHRoaXMuZ2V0TGF0ZXN0QmxvY2tIZWlnaHQoKSkgYXMgbnVtYmVyO1xuICAgIH1cbiAgICByZXR1cm4gXy5leHRlbmQoe30sIHByZWJ1aWxkLCB7IHR4SGV4OiB0eC50b0hleCgpIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgb3V0cHV0cyB0aGF0IGFyZSB3aXRoaW4gZXhwZWN0ZWQgb3V0cHV0cyBidXQgbm90IHdpdGhpbiBhY3R1YWwgb3V0cHV0cywgaW5jbHVkaW5nIGR1cGxpY2F0ZXNcbiAgICogQHBhcmFtIGV4cGVjdGVkT3V0cHV0c1xuICAgKiBAcGFyYW0gYWN0dWFsT3V0cHV0c1xuICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGZpbmRNaXNzaW5nT3V0cHV0cyhleHBlY3RlZE91dHB1dHM6IE91dHB1dFtdLCBhY3R1YWxPdXRwdXRzOiBPdXRwdXRbXSk6IE91dHB1dFtdIHtcbiAgICBjb25zdCBrZXlGdW5jID0gKHsgYWRkcmVzcywgYW1vdW50IH06IE91dHB1dCk6IHN0cmluZyA9PiBgJHthZGRyZXNzfToke2Ftb3VudH1gO1xuICAgIGNvbnN0IGdyb3VwZWRPdXRwdXRzID0gXy5ncm91cEJ5KGV4cGVjdGVkT3V0cHV0cywga2V5RnVuYyk7XG5cbiAgICBhY3R1YWxPdXRwdXRzLmZvckVhY2goKG91dHB1dCkgPT4ge1xuICAgICAgY29uc3QgZ3JvdXAgPSBncm91cGVkT3V0cHV0c1trZXlGdW5jKG91dHB1dCldO1xuICAgICAgaWYgKGdyb3VwKSB7XG4gICAgICAgIGdyb3VwLnBvcCgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIF8uZmxhdHRlbihfLnZhbHVlcyhncm91cGVkT3V0cHV0cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBhbiBhZGRyZXNzJyB0eXBlIGJhc2VkIG9uIGl0cyB3aXRuZXNzIGFuZCByZWRlZW0gc2NyaXB0IHByZXNlbmNlXG4gICAqIEBwYXJhbSBhZGRyZXNzRGV0YWlsc1xuICAgKi9cbiAgc3RhdGljIGluZmVyQWRkcmVzc1R5cGUoYWRkcmVzc0RldGFpbHM6IHsgY2hhaW46IG51bWJlciB9KTogU2NyaXB0VHlwZTJPZjMgfCBudWxsIHtcbiAgICByZXR1cm4gaXNDaGFpbkNvZGUoYWRkcmVzc0RldGFpbHMuY2hhaW4pID8gc2NyaXB0VHlwZUZvckNoYWluKGFkZHJlc3NEZXRhaWxzLmNoYWluKSA6IG51bGw7XG4gIH1cblxuICBjcmVhdGVUcmFuc2FjdGlvbkZyb21IZXg8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludCA9IG51bWJlcj4oXG4gICAgaGV4OiBzdHJpbmdcbiAgKTogdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb248VE51bWJlcj4ge1xuICAgIHJldHVybiB1dHhvbGliLmJpdGdvLmNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleDxUTnVtYmVyPihoZXgsIHRoaXMubmV0d29yaywgdGhpcy5hbW91bnRUeXBlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IGFuZCBmaWxsIHRyYW5zYWN0aW9uIGRldGFpbHMgc3VjaCBhcyBpbnRlcm5hbC9jaGFuZ2Ugc3BlbmQsIGV4dGVybmFsIHNwZW5kIChleHBsaWNpdCB2cy4gaW1wbGljaXQpLCBldGMuXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICAgIHBhcmFtczogUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnM8VE51bWJlcj5cbiAgKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbjxUTnVtYmVyPj4ge1xuICAgIGNvbnN0IHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uID0ge30sIHJlcUlkIH0gPSBwYXJhbXM7XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQodmVyaWZpY2F0aW9uLmRpc2FibGVOZXR3b3JraW5nKSAmJiAhXy5pc0Jvb2xlYW4odmVyaWZpY2F0aW9uLmRpc2FibGVOZXR3b3JraW5nKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmcgbXVzdCBiZSBhIGJvb2xlYW4nKTtcbiAgICB9XG4gICAgY29uc3QgZGlzYWJsZU5ldHdvcmtpbmcgPSB2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmc7XG5cbiAgICBjb25zdCBmZXRjaEtleWNoYWlucyA9IGFzeW5jICh3YWxsZXQ6IElXYWxsZXQpOiBQcm9taXNlPFZlcmlmaWNhdGlvbk9wdGlvbnNbJ2tleWNoYWlucyddPiA9PiB7XG4gICAgICByZXR1cm4gcHJvbWlzZVByb3BzKHtcbiAgICAgICAgdXNlcjogdGhpcy5rZXljaGFpbnMoKS5nZXQoeyBpZDogd2FsbGV0LmtleUlkcygpW0tleUluZGljZXMuVVNFUl0sIHJlcUlkIH0pLFxuICAgICAgICBiYWNrdXA6IHRoaXMua2V5Y2hhaW5zKCkuZ2V0KHsgaWQ6IHdhbGxldC5rZXlJZHMoKVtLZXlJbmRpY2VzLkJBQ0tVUF0sIHJlcUlkIH0pLFxuICAgICAgICBiaXRnbzogdGhpcy5rZXljaGFpbnMoKS5nZXQoeyBpZDogd2FsbGV0LmtleUlkcygpW0tleUluZGljZXMuQklUR09dLCByZXFJZCB9KSxcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBvYnRhaW4gdGhlIGtleWNoYWlucyBhbmQga2V5IHNpZ25hdHVyZXNcbiAgICBsZXQga2V5Y2hhaW5zOiBWZXJpZmljYXRpb25PcHRpb25zWydrZXljaGFpbnMnXSB8IHVuZGVmaW5lZCA9IHZlcmlmaWNhdGlvbi5rZXljaGFpbnM7XG4gICAgaWYgKCFrZXljaGFpbnMpIHtcbiAgICAgIGlmIChkaXNhYmxlTmV0d29ya2luZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBmZXRjaCBrZXljaGFpbnMgd2l0aG91dCBuZXR3b3JraW5nJyk7XG4gICAgICB9XG4gICAgICBrZXljaGFpbnMgPSBhd2FpdCBmZXRjaEtleWNoYWlucyh3YWxsZXQpO1xuICAgIH1cblxuICAgIGlmICgha2V5Y2hhaW5zIHx8ICFrZXljaGFpbnMudXNlciB8fCAha2V5Y2hhaW5zLmJhY2t1cCB8fCAha2V5Y2hhaW5zLmJpdGdvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2tleWNoYWlucyBhcmUgcmVxdWlyZWQsIGJ1dCBjb3VsZCBub3QgYmUgZmV0Y2hlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGtleWNoYWluQXJyYXk6IFRyaXBsZTxLZXljaGFpbj4gPSBba2V5Y2hhaW5zLnVzZXIsIGtleWNoYWlucy5iYWNrdXAsIGtleWNoYWlucy5iaXRnb107XG5cbiAgICBjb25zdCBrZXlTaWduYXR1cmVzID0gXy5nZXQod2FsbGV0LCAnX3dhbGxldC5rZXlTaWduYXR1cmVzJywge30pO1xuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQodHhQcmVidWlsZC50eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCB0eFByZWJ1aWxkIHByb3BlcnR5IHR4SGV4Jyk7XG4gICAgfVxuICAgIC8vIG9idGFpbiBhbGwgb3V0cHV0c1xuICAgIGNvbnN0IGV4cGxhbmF0aW9uOiBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0gYXdhaXQgdGhpcy5leHBsYWluVHJhbnNhY3Rpb248VE51bWJlcj4oe1xuICAgICAgdHhIZXg6IHR4UHJlYnVpbGQudHhIZXgsXG4gICAgICB0eEluZm86IHR4UHJlYnVpbGQudHhJbmZvLFxuICAgICAgcHViczoga2V5Y2hhaW5BcnJheS5tYXAoKGspID0+IGsucHViKSBhcyBUcmlwbGU8c3RyaW5nPixcbiAgICB9KTtcblxuICAgIGNvbnN0IGFsbE91dHB1dHMgPSBbLi4uZXhwbGFuYXRpb24ub3V0cHV0cywgLi4uZXhwbGFuYXRpb24uY2hhbmdlT3V0cHV0c107XG5cbiAgICAvLyB2ZXJpZnkgdGhhdCBlYWNoIHJlY2lwaWVudCBmcm9tIHR4UGFyYW1zIGhhcyB0aGVpciBvd24gb3V0cHV0XG4gICAgY29uc3QgZXhwZWN0ZWRPdXRwdXRzID0gXy5nZXQodHhQYXJhbXMsICdyZWNpcGllbnRzJywgW10gYXMgVHJhbnNhY3Rpb25SZWNpcGllbnRbXSkubWFwKChvdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiB7IC4uLm91dHB1dCwgYWRkcmVzczogdGhpcy5jYW5vbmljYWxBZGRyZXNzKG91dHB1dC5hZGRyZXNzKSB9O1xuICAgIH0pO1xuXG4gICAgY29uc3QgbWlzc2luZ091dHB1dHMgPSBBYnN0cmFjdFV0eG9Db2luLmZpbmRNaXNzaW5nT3V0cHV0cyhleHBlY3RlZE91dHB1dHMsIGFsbE91dHB1dHMpO1xuXG4gICAgLy8gZ2V0IHRoZSBrZXljaGFpbnMgZnJvbSB0aGUgY3VzdG9tIGNoYW5nZSB3YWxsZXQgaWYgbmVlZGVkXG4gICAgbGV0IGN1c3RvbUNoYW5nZTogQ3VzdG9tQ2hhbmdlT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCB7IGN1c3RvbUNoYW5nZVdhbGxldElkID0gdW5kZWZpbmVkIH0gPSB3YWxsZXQuY29pblNwZWNpZmljKCkgfHwge307XG4gICAgaWYgKGN1c3RvbUNoYW5nZVdhbGxldElkKSB7XG4gICAgICAvLyBmZXRjaCBrZXljaGFpbnMgZnJvbSBjdXN0b20gY2hhbmdlIHdhbGxldCBmb3IgZGVyaXZpbmcgYWRkcmVzc2VzLlxuICAgICAgLy8gVGhlc2Uga2V5Y2hhaW5zIHNob3VsZCBiZSBzaWduZWQgYW5kIHRoaXMgc2hvdWxkIGJlIHZlcmlmaWVkIGluIHZlcmlmeVRyYW5zYWN0aW9uXG4gICAgICBjb25zdCBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzID0gd2FsbGV0Ll93YWxsZXQuY3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlcztcbiAgICAgIGNvbnN0IGN1c3RvbUNoYW5nZVdhbGxldDogV2FsbGV0ID0gYXdhaXQgdGhpcy53YWxsZXRzKCkuZ2V0KHsgaWQ6IGN1c3RvbUNoYW5nZVdhbGxldElkIH0pO1xuICAgICAgY29uc3QgY3VzdG9tQ2hhbmdlS2V5cyA9IGF3YWl0IGZldGNoS2V5Y2hhaW5zKGN1c3RvbUNoYW5nZVdhbGxldCk7XG5cbiAgICAgIGlmICghY3VzdG9tQ2hhbmdlS2V5cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBmZXRjaCBrZXljaGFpbnMgZm9yIGN1c3RvbSBjaGFuZ2Ugd2FsbGV0Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjdXN0b21DaGFuZ2VLZXlzLnVzZXIgJiYgY3VzdG9tQ2hhbmdlS2V5cy5iYWNrdXAgJiYgY3VzdG9tQ2hhbmdlS2V5cy5iaXRnbyAmJiBjdXN0b21DaGFuZ2VXYWxsZXQpIHtcbiAgICAgICAgY29uc3QgY3VzdG9tQ2hhbmdlS2V5Y2hhaW5zOiBbS2V5Y2hhaW4sIEtleWNoYWluLCBLZXljaGFpbl0gPSBbXG4gICAgICAgICAgY3VzdG9tQ2hhbmdlS2V5cy51c2VyLFxuICAgICAgICAgIGN1c3RvbUNoYW5nZUtleXMuYmFja3VwLFxuICAgICAgICAgIGN1c3RvbUNoYW5nZUtleXMuYml0Z28sXG4gICAgICAgIF07XG5cbiAgICAgICAgY3VzdG9tQ2hhbmdlID0ge1xuICAgICAgICAgIGtleXM6IGN1c3RvbUNoYW5nZUtleWNoYWlucyxcbiAgICAgICAgICBzaWduYXR1cmVzOiBbXG4gICAgICAgICAgICBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzLnVzZXIsXG4gICAgICAgICAgICBjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzLmJhY2t1cCxcbiAgICAgICAgICAgIGN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXMuYml0Z28sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb29wIHRocm91Z2ggYWxsIHRoZSBvdXRwdXRzIGFuZCBjbGFzc2lmeSBlYWNoIG9mIHRoZW0gYXMgZWl0aGVyIGludGVybmFsIHNwZW5kc1xuICAgICAqIG9yIGV4dGVybmFsIHNwZW5kcyBieSBzZXR0aW5nIHRoZSBcImV4dGVybmFsXCIgcHJvcGVydHkgdG8gdHJ1ZSBvciBmYWxzZSBvbiB0aGUgb3V0cHV0IG9iamVjdC5cbiAgICAgKi9cbiAgICBjb25zdCBhbGxPdXRwdXREZXRhaWxzOiBPdXRwdXRbXSA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYWxsT3V0cHV0cy5tYXAoKGN1cnJlbnRPdXRwdXQpID0+IHtcbiAgICAgICAgcmV0dXJuIHBhcnNlT3V0cHV0KHtcbiAgICAgICAgICBjdXJyZW50T3V0cHV0LFxuICAgICAgICAgIGNvaW46IHRoaXMsXG4gICAgICAgICAgdHhQcmVidWlsZCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAga2V5Y2hhaW5BcnJheSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgICAgY3VzdG9tQ2hhbmdlLFxuICAgICAgICAgIHJlcUlkLFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGNvbnN0IG5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uID0gYWxsT3V0cHV0RGV0YWlscy5zb21lKFxuICAgICAgKG91dHB1dCkgPT4gb3V0cHV0Lm5lZWRzQ3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlVmVyaWZpY2F0aW9uXG4gICAgKTtcblxuICAgIGNvbnN0IGNoYW5nZU91dHB1dHMgPSBfLmZpbHRlcihhbGxPdXRwdXREZXRhaWxzLCB7IGV4dGVybmFsOiBmYWxzZSB9KTtcblxuICAgIC8vIHRoZXNlIGFyZSBhbGwgdGhlIG91dHB1dHMgdGhhdCB3ZXJlIG5vdCBvcmlnaW5hbGx5IGV4cGxpY2l0bHkgc3BlY2lmaWVkIGluIHJlY2lwaWVudHNcbiAgICBjb25zdCBpbXBsaWNpdE91dHB1dHMgPSBBYnN0cmFjdFV0eG9Db2luLmZpbmRNaXNzaW5nT3V0cHV0cyhhbGxPdXRwdXREZXRhaWxzLCBleHBlY3RlZE91dHB1dHMpO1xuXG4gICAgY29uc3QgZXhwbGljaXRPdXRwdXRzID0gQWJzdHJhY3RVdHhvQ29pbi5maW5kTWlzc2luZ091dHB1dHMoYWxsT3V0cHV0RGV0YWlscywgaW1wbGljaXRPdXRwdXRzKTtcblxuICAgIC8vIHRoZXNlIGFyZSBhbGwgdGhlIG5vbi13YWxsZXQgb3V0cHV0cyB0aGF0IGhhZCBiZWVuIG9yaWdpbmFsbHkgZXhwbGljaXRseSBzcGVjaWZpZWQgaW4gcmVjaXBpZW50c1xuICAgIGNvbnN0IGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzID0gXy5maWx0ZXIoZXhwbGljaXRPdXRwdXRzLCB7IGV4dGVybmFsOiB0cnVlIH0pO1xuXG4gICAgLy8gdGhpcyBpcyB0aGUgc3VtIG9mIGFsbCB0aGUgb3JpZ2luYWxseSBleHBsaWNpdGx5IHNwZWNpZmllZCBub24td2FsbGV0IG91dHB1dCB2YWx1ZXNcbiAgICBjb25zdCBleHBsaWNpdEV4dGVybmFsU3BlbmRBbW91bnQgPSB1dHhvbGliLmJpdGdvLnRvVE51bWJlcjxUTnVtYmVyPihcbiAgICAgIGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzLnJlZHVjZSgoc3VtOiBiaWdpbnQsIG86IE91dHB1dCkgPT4gc3VtICsgQmlnSW50KG8uYW1vdW50KSwgQmlnSW50KDApKSBhcyBiaWdpbnQsXG4gICAgICB0aGlzLmFtb3VudFR5cGVcbiAgICApO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBpbXBsaWNpdCBleHRlcm5hbCBzcGVuZCBhbW91bnQgcGVydGFpbnMgdG8gdmVyaWZ5aW5nIHRoZSBwYXktYXMteW91LWdvLWZlZSBCaXRHb1xuICAgICAqIGF1dG9tYXRpY2FsbHkgYXBwbGllcyB0byB0cmFuc2FjdGlvbnMgc2VuZGluZyBtb25leSBvdXQgb2YgdGhlIHdhbGxldC4gVGhlIGxvZ2ljIGlzIGZhaXJseSBzdHJhaWdodGZvcndhcmRcbiAgICAgKiBpbiB0aGF0IHdlIGNvbXBhcmUgdGhlIGV4dGVybmFsIHNwZW5kIGFtb3VudCB0aGF0IHdhcyBzcGVjaWZpZWQgZXhwbGljaXRseSBieSB0aGUgdXNlciB0byB0aGUgcG9ydGlvblxuICAgICAqIHRoYXQgd2FzIHNwZWNpZmllZCBpbXBsaWNpdGx5LiBUbyBwcm90ZWN0IGN1c3RvbWVycyBmcm9tIHBlb3BsZSB0YW1wZXJpbmcgd2l0aCB0aGUgdHJhbnNhY3Rpb24gb3V0cHV0cywgd2VcbiAgICAgKiBkZWZpbmUgYSB0aHJlc2hvbGQgZm9yIHRoZSBtYXhpbXVtIHBlcmNlbnRhZ2Ugb2YgdGhlIGltcGxpY2l0IGV4dGVybmFsIHNwZW5kIGluIHJlbGF0aW9uIHRvIHRoZSBleHBsaWNpdFxuICAgICAqIGV4dGVybmFsIHNwZW5kLlxuICAgICAqL1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoYXQgYWxsIHRoZSBleHRyYSBhZGRyZXNzZXMgYXJlIGNoYW5nZSBhZGRyZXNzZXNcbiAgICAvLyBnZXQgYWxsIHRoZSBhZGRpdGlvbmFsIGV4dGVybmFsIG91dHB1dHMgdGhlIHNlcnZlciBhZGRlZCBhbmQgY2FsY3VsYXRlIHRoZWlyIHZhbHVlc1xuICAgIGNvbnN0IGltcGxpY2l0RXh0ZXJuYWxPdXRwdXRzID0gXy5maWx0ZXIoaW1wbGljaXRPdXRwdXRzLCB7IGV4dGVybmFsOiB0cnVlIH0pO1xuICAgIGNvbnN0IGltcGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudCA9IHV0eG9saWIuYml0Z28udG9UTnVtYmVyPFROdW1iZXI+KFxuICAgICAgaW1wbGljaXRFeHRlcm5hbE91dHB1dHMucmVkdWNlKChzdW06IGJpZ2ludCwgbzogT3V0cHV0KSA9PiBzdW0gKyBCaWdJbnQoby5hbW91bnQpLCBCaWdJbnQoMCkpIGFzIGJpZ2ludCxcbiAgICAgIHRoaXMuYW1vdW50VHlwZVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAga2V5Y2hhaW5zLFxuICAgICAga2V5U2lnbmF0dXJlcyxcbiAgICAgIG91dHB1dHM6IGFsbE91dHB1dERldGFpbHMsXG4gICAgICBtaXNzaW5nT3V0cHV0cyxcbiAgICAgIGV4cGxpY2l0RXh0ZXJuYWxPdXRwdXRzLFxuICAgICAgaW1wbGljaXRFeHRlcm5hbE91dHB1dHMsXG4gICAgICBjaGFuZ2VPdXRwdXRzLFxuICAgICAgZXhwbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50LFxuICAgICAgaW1wbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50LFxuICAgICAgbmVlZHNDdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVWZXJpZmljYXRpb24sXG4gICAgICBjdXN0b21DaGFuZ2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0IHRoZSB3YWxsZXQncyB1c2VyIHByaXZhdGUga2V5IGFuZCB2ZXJpZnkgdGhhdCB0aGUgY2xhaW1lZCBwdWJsaWMga2V5IG1hdGNoZXNcbiAgICogQHBhcmFtIHtWZXJpZnlVc2VyUHVibGljS2V5T3B0aW9uc30gcGFyYW1zXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG4gIHByb3RlY3RlZCB2ZXJpZnlVc2VyUHVibGljS2V5KHBhcmFtczogVmVyaWZ5VXNlclB1YmxpY0tleU9wdGlvbnMpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwgdHhQYXJhbXMsIGRpc2FibGVOZXR3b3JraW5nIH0gPSBwYXJhbXM7XG4gICAgaWYgKCF1c2VyS2V5Y2hhaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBrZXljaGFpbiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJQdWIgPSB1c2VyS2V5Y2hhaW4ucHViO1xuXG4gICAgLy8gZGVjcnlwdCB0aGUgdXNlciBwcml2YXRlIGtleSBzbyB3ZSBjYW4gdmVyaWZ5IHRoYXQgdGhlIGNsYWltZWQgcHVibGljIGtleSBpcyBhIG1hdGNoXG4gICAgbGV0IHVzZXJQcnYgPSB1c2VyS2V5Y2hhaW4ucHJ2O1xuICAgIGlmIChfLmlzRW1wdHkodXNlclBydikpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnY7XG4gICAgICBpZiAoZW5jcnlwdGVkUHJ2ICYmICFfLmlzRW1wdHkoZW5jcnlwdGVkUHJ2KSkge1xuICAgICAgICAvLyBpZiB0aGUgZGVjcnlwdGlvbiBmYWlscywgaXQgd2lsbCB0aHJvdyBhbiBlcnJvclxuICAgICAgICB1c2VyUHJ2ID0gdGhpcy5iaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogZW5jcnlwdGVkUHJ2LFxuICAgICAgICAgIHBhc3N3b3JkOiB0eFBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICd1c2VyIHByaXZhdGUga2V5IHVuYXZhaWxhYmxlIGZvciB2ZXJpZmljYXRpb24nO1xuICAgICAgaWYgKGRpc2FibGVOZXR3b3JraW5nKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yTWVzc2FnZSk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB1c2VyUHJpdmF0ZUtleSA9IGJpcDMyLmZyb21CYXNlNTgodXNlclBydik7XG4gICAgICBpZiAodXNlclByaXZhdGVLZXkudG9CYXNlNTgoKSA9PT0gdXNlclByaXZhdGVLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBwcml2YXRlIGtleSBpcyBvbmx5IHB1YmxpYycpO1xuICAgICAgfVxuICAgICAgaWYgKHVzZXJQcml2YXRlS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKSAhPT0gdXNlclB1Yikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXIgcHJpdmF0ZSBrZXkgZG9lcyBub3QgbWF0Y2ggcHVibGljIGtleScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSBzaWduYXR1cmVzIHByb2R1Y2VkIGJ5IHRoZSB1c2VyIGtleSBvdmVyIHRoZSBiYWNrdXAgYW5kIGJpdGdvIGtleXMuXG4gICAqXG4gICAqIElmIHNldCwgdGhlc2Ugc2lnbmF0dXJlcyBlbnN1cmUgdGhhdCB0aGUgd2FsbGV0IGtleXMgY2Fubm90IGJlIGNoYW5nZWQgYWZ0ZXIgdGhlIHdhbGxldCBoYXMgYmVlbiBjcmVhdGVkLlxuICAgKiBAcGFyYW0ge1ZlcmlmeUtleVNpZ25hdHVyZXNPcHRpb25zfSBwYXJhbXNcbiAgICogQHJldHVybiB7e2JhY2t1cDogYm9vbGVhbiwgYml0Z286IGJvb2xlYW59fVxuICAgKi9cbiAgcHVibGljIHZlcmlmeUtleVNpZ25hdHVyZShwYXJhbXM6IFZlcmlmeUtleVNpZ25hdHVyZXNPcHRpb25zKTogYm9vbGVhbiB7XG4gICAgLy8gZmlyc3QsIGxldCdzIHZlcmlmeSB0aGUgaW50ZWdyaXR5IG9mIHRoZSB1c2VyIGtleSwgd2hvc2UgcHVibGljIGtleSBpcyB1c2VkIGZvciBzdWJzZXF1ZW50IHZlcmlmaWNhdGlvbnNcbiAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwga2V5Y2hhaW5Ub1ZlcmlmeSwga2V5U2lnbmF0dXJlIH0gPSBwYXJhbXM7XG4gICAgaWYgKCF1c2VyS2V5Y2hhaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndXNlciBrZXljaGFpbiBpcyByZXF1aXJlZCcpO1xuICAgIH1cblxuICAgIGlmICgha2V5Y2hhaW5Ub1ZlcmlmeSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXljaGFpbiB0byB2ZXJpZnkgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleVNpZ25hdHVyZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdrZXkgc2lnbmF0dXJlIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgLy8gdmVyaWZ5IHRoZSBzaWduYXR1cmUgYWdhaW5zdCB0aGUgdXNlciBwdWJsaWMga2V5XG4gICAgYXNzZXJ0KHVzZXJLZXljaGFpbi5wdWIpO1xuICAgIGNvbnN0IHB1YmxpY0tleSA9IGJpcDMyLmZyb21CYXNlNTgodXNlcktleWNoYWluLnB1YikucHVibGljS2V5O1xuICAgIC8vIER1ZSB0byBpbnRlcmZhY2Ugb2YgYGJpdGNvaW5NZXNzYWdlYCwgd2UgbmVlZCB0byBjb252ZXJ0IHRoZSBwdWJsaWMga2V5IHRvIGFuIGFkZHJlc3MuXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgYWRkcmVzcyBoYXMgbm8gcmVsYXRpb25zaGlwIHRvIG9uLWNoYWluIHRyYW5zYWN0aW9ucy4gV2UgYXJlXG4gICAgLy8gb25seSBpbnRlcmVzdGVkIGluIHRoZSBhZGRyZXNzIGFzIGEgcmVwcmVzZW50YXRpb24gb2YgdGhlIHB1YmxpYyBrZXkuXG4gICAgY29uc3Qgc2lnbmluZ0FkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MudG9CYXNlNThDaGVjayhcbiAgICAgIHV0eG9saWIuY3J5cHRvLmhhc2gxNjAocHVibGljS2V5KSxcbiAgICAgIHV0eG9saWIubmV0d29ya3MuYml0Y29pbi5wdWJLZXlIYXNoLFxuICAgICAgLy8gd2UgZG8gbm90IHBhc3MgYHRoaXMubmV0d29ya2AgaGVyZSBiZWNhdXNlIGl0IHdvdWxkIGZhaWwgZm9yIHpjYXNoXG4gICAgICAvLyB0aGUgYml0Y29pbk1lc3NhZ2UgbGlicmFyeSBkZWNvZGVzIHRoZSBhZGRyZXNzIGFuZCB0aHJvd3MgYXdheSB0aGUgZmlyc3QgYnl0ZVxuICAgICAgLy8gYmVjYXVzZSB6Y2FzaCBoYXMgYSB0d28tYnl0ZSBwcmVmaXgsIHZlcmlmeSgpIGRlY29kZXMgemNhc2ggYWRkcmVzc2VzIHRvIGFuIGludmFsaWQgcHVia2V5IGhhc2hcbiAgICAgIHV0eG9saWIubmV0d29ya3MuYml0Y29pblxuICAgICk7XG5cbiAgICAvLyBCRy01NzAzOiB1c2UgQlRDIG1haW5uZXQgcHJlZml4IGZvciBhbGwga2V5IHNpZ25hdHVyZSBvcGVyYXRpb25zXG4gICAgLy8gKHRoaXMgbWVhbnMgZG8gbm90IHBhc3MgYSBwcmVmaXggcGFyYW1ldGVyLCBhbmQgbGV0IGl0IHVzZSB0aGUgZGVmYXVsdCBwcmVmaXggaW5zdGVhZClcbiAgICBhc3NlcnQoa2V5Y2hhaW5Ub1ZlcmlmeS5wdWIpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYml0Y29pbk1lc3NhZ2UudmVyaWZ5KGtleWNoYWluVG9WZXJpZnkucHViLCBzaWduaW5nQWRkcmVzcywgQnVmZmVyLmZyb20oa2V5U2lnbmF0dXJlLCAnaGV4JykpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRlYnVnKCdlcnJvciB0aHJvd24gZnJvbSBiaXRjb2lubWVzc2FnZSB3aGlsZSB2ZXJpZnlpbmcga2V5IHNpZ25hdHVyZScsIGUpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgc2lnbmF0dXJlcyBhZ2FpbnN0IHRoZSB1c2VyIHByaXZhdGUga2V5IG92ZXIgdGhlIGNoYW5nZSB3YWxsZXQgZXh0ZW5kZWQga2V5c1xuICAgKiBAcGFyYW0ge1BhcnNlZFRyYW5zYWN0aW9ufSB0eFxuICAgKiBAcGFyYW0ge0tleWNoYWlufSB1c2VyS2V5Y2hhaW5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZlcmlmeUN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXM8VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gICAgdHg6IFBhcnNlZFRyYW5zYWN0aW9uPFROdW1iZXI+LFxuICAgIHVzZXJLZXljaGFpbjogS2V5Y2hhaW5cbiAgKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0eC5jdXN0b21DaGFuZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigncGFyc2VkIHRyYW5zYWN0aW9uIGlzIG1pc3NpbmcgcmVxdWlyZWQgY3VzdG9tIGNoYW5nZSB2ZXJpZmljYXRpb24gZGF0YScpO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0eC5jdXN0b21DaGFuZ2Uua2V5cykgfHwgIUFycmF5LmlzQXJyYXkodHguY3VzdG9tQ2hhbmdlLnNpZ25hdHVyZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1c3RvbUNoYW5nZSBwcm9wZXJ0eSBpcyBtaXNzaW5nIGtleXMgb3Igc2lnbmF0dXJlcycpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5SW5kZXggb2YgW0tleUluZGljZXMuVVNFUiwgS2V5SW5kaWNlcy5CQUNLVVAsIEtleUluZGljZXMuQklUR09dKSB7XG4gICAgICBjb25zdCBrZXljaGFpblRvVmVyaWZ5ID0gdHguY3VzdG9tQ2hhbmdlLmtleXNba2V5SW5kZXhdO1xuICAgICAgY29uc3Qga2V5U2lnbmF0dXJlID0gdHguY3VzdG9tQ2hhbmdlLnNpZ25hdHVyZXNba2V5SW5kZXhdO1xuICAgICAgaWYgKCFrZXljaGFpblRvVmVyaWZ5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyByZXF1aXJlZCBjdXN0b20gY2hhbmdlICR7S2V5SW5kaWNlc1trZXlJbmRleF0udG9Mb3dlckNhc2UoKX0ga2V5Y2hhaW4gcHVibGljIGtleWApO1xuICAgICAgfVxuICAgICAgaWYgKCFrZXlTaWduYXR1cmUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIHJlcXVpcmVkIGN1c3RvbSBjaGFuZ2UgJHtLZXlJbmRpY2VzW2tleUluZGV4XS50b0xvd2VyQ2FzZSgpfSBrZXljaGFpbiBzaWduYXR1cmVgKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMudmVyaWZ5S2V5U2lnbmF0dXJlKHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHVzZXJLZXljaGFpbiBhcyB7IHB1Yjogc3RyaW5nIH0sXG4gICAgICAgICAga2V5Y2hhaW5Ub1ZlcmlmeToga2V5Y2hhaW5Ub1ZlcmlmeSBhcyB7IHB1Yjogc3RyaW5nIH0sXG4gICAgICAgICAga2V5U2lnbmF0dXJlLFxuICAgICAgICB9KVxuICAgICAgKSB7XG4gICAgICAgIGRlYnVnKCdmYWlsZWQgdG8gdmVyaWZ5IGN1c3RvbSBjaGFuZ2UgJXMga2V5IHNpZ25hdHVyZSEnLCBLZXlJbmRpY2VzW2tleUluZGV4XS50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbWF4aW11bSBwZXJjZW50YWdlIGxpbWl0IGZvciBwYXktYXMteW91LWdvIG91dHB1dHNcbiAgICpcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBheUdvTGltaXQoYWxsb3dQYXlnb091dHB1dD86IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIC8vIGFsbG93aW5nIHBheWdvIG91dHB1dHMgbmVlZHMgdG8gYmUgdGhlIGRlZmF1bHQgYmVoYXZpb3IsIHNvIG9ubHkgZGlzYWxsb3cgcGF5Z28gb3V0cHV0cyBpZiB0aGVcbiAgICAvLyByZWxldmFudCB2ZXJpZmljYXRpb24gb3B0aW9uIGlzIGJvdGggc2V0IGFuZCBmYWxzZVxuICAgIGlmICghXy5pc05pbChhbGxvd1BheWdvT3V0cHV0KSAmJiAhYWxsb3dQYXlnb091dHB1dCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8vIDE1MCBiYXNpcyBwb2ludHMgaXMgdGhlIGFic29sdXRlIHBlcm1pdHRlZCBtYXhpbXVtIGlmIHBheWdvIG91dHB1dHMgYXJlIGFsbG93ZWRcbiAgICByZXR1cm4gMC4wMTU7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHRoYXQgYSB0cmFuc2FjdGlvbiBwcmVidWlsZCBjb21wbGllcyB3aXRoIHRoZSBvcmlnaW5hbCBpbnRlbnRpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UGFyYW1zIHBhcmFtcyBvYmplY3QgcGFzc2VkIHRvIHNlbmRcbiAgICogQHBhcmFtIHBhcmFtcy50eFByZWJ1aWxkIHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBzZXJ2ZXJcbiAgICogQHBhcmFtIHBhcmFtcy50eFByZWJ1aWxkLnR4SGV4IHByZWJ1aWx0IHRyYW5zYWN0aW9uJ3MgdHhIZXggZm9ybVxuICAgKiBAcGFyYW0gcGFyYW1zLndhbGxldCBXYWxsZXQgb2JqZWN0IHRvIG9idGFpbiBrZXlzIHRvIHZlcmlmeSBhZ2FpbnN0XG4gICAqIEBwYXJhbSBwYXJhbXMudmVyaWZpY2F0aW9uIE9iamVjdCBzcGVjaWZ5aW5nIHNvbWUgdmVyaWZpY2F0aW9uIHBhcmFtZXRlcnNcbiAgICogQHBhcmFtIHBhcmFtcy52ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmcgRGlzYWxsb3cgZmV0Y2hpbmcgYW55IGRhdGEgZnJvbSB0aGUgaW50ZXJuZXQgZm9yIHZlcmlmaWNhdGlvbiBwdXJwb3Nlc1xuICAgKiBAcGFyYW0gcGFyYW1zLnZlcmlmaWNhdGlvbi5rZXljaGFpbnMgUGFzcyBrZXljaGFpbnMgbWFudWFsbHkgcmF0aGVyIHRoYW4gZmV0Y2hpbmcgdGhlbSBieSBpZFxuICAgKiBAcGFyYW0gcGFyYW1zLnZlcmlmaWNhdGlvbi5hZGRyZXNzZXMgQWRkcmVzcyBkZXRhaWxzIHRvIHBhc3MgaW4gZm9yIG91dC1vZi1iYW5kIHZlcmlmaWNhdGlvblxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICAgIHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zPFROdW1iZXI+XG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uID0geyBhbGxvd1BheWdvT3V0cHV0OiB0cnVlIH0sIHJlcUlkIH0gPSBwYXJhbXM7XG4gICAgY29uc3QgaXNQc2J0ID0gdHhQcmVidWlsZC50eEhleCAmJiBiaXRnby5pc1BzYnQodHhQcmVidWlsZC50eEhleCk7XG4gICAgaWYgKGlzUHNidCAmJiB0eFByZWJ1aWxkLnR4SW5mbz8udW5zcGVudHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc2hvdWxkIG5vdCBoYXZlIHVuc3BlbnRzIGluIHR4SW5mbyBmb3IgcHNidCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGRpc2FibGVOZXR3b3JraW5nID0gISF2ZXJpZmljYXRpb24uZGlzYWJsZU5ldHdvcmtpbmc7XG4gICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb246IFBhcnNlZFRyYW5zYWN0aW9uPFROdW1iZXI+ID0gYXdhaXQgdGhpcy5wYXJzZVRyYW5zYWN0aW9uPFROdW1iZXI+KHtcbiAgICAgIHR4UGFyYW1zLFxuICAgICAgdHhQcmVidWlsZCxcbiAgICAgIHdhbGxldCxcbiAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIHJlcUlkLFxuICAgIH0pO1xuXG4gICAgY29uc3Qga2V5Y2hhaW5zID0gcGFyc2VkVHJhbnNhY3Rpb24ua2V5Y2hhaW5zO1xuXG4gICAgLy8gdmVyaWZ5IHRoYXQgdGhlIGNsYWltZWQgdXNlciBwdWJsaWMga2V5IGNvcnJlc3BvbmRzIHRvIHRoZSB3YWxsZXQncyB1c2VyIHByaXZhdGUga2V5XG4gICAgbGV0IHVzZXJQdWJsaWNLZXlWZXJpZmllZCA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAvLyB2ZXJpZnkgdGhlIHVzZXIgcHVibGljIGtleSBtYXRjaGVzIHRoZSBwcml2YXRlIGtleSAtIHRoaXMgd2lsbCB0aHJvdyBpZiB0aGVyZSBpcyBubyBtYXRjaFxuICAgICAgdXNlclB1YmxpY0tleVZlcmlmaWVkID0gdGhpcy52ZXJpZnlVc2VyUHVibGljS2V5KHsgdXNlcktleWNoYWluOiBrZXljaGFpbnMudXNlciwgZGlzYWJsZU5ldHdvcmtpbmcsIHR4UGFyYW1zIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGRlYnVnKCdmYWlsZWQgdG8gdmVyaWZ5IHVzZXIgcHVibGljIGtleSEnLCBlKTtcbiAgICB9XG5cbiAgICAvLyBsZXQncyB2ZXJpZnkgdGhlc2Uga2V5Y2hhaW5zXG4gICAgY29uc3Qga2V5U2lnbmF0dXJlcyA9IHBhcnNlZFRyYW5zYWN0aW9uLmtleVNpZ25hdHVyZXM7XG4gICAgaWYgKCFfLmlzRW1wdHkoa2V5U2lnbmF0dXJlcykpIHtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IChrZXksIHB1YikgPT4ge1xuICAgICAgICBpZiAoIWtleWNoYWlucy51c2VyIHx8ICFrZXljaGFpbnMudXNlci5wdWIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUtleVNpZ25hdHVyZSh7XG4gICAgICAgICAgdXNlcktleWNoYWluOiBrZXljaGFpbnMudXNlciBhcyB7IHB1Yjogc3RyaW5nIH0sXG4gICAgICAgICAga2V5Y2hhaW5Ub1ZlcmlmeToga2V5LFxuICAgICAgICAgIGtleVNpZ25hdHVyZTogcHViLFxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBjb25zdCBpc0JhY2t1cEtleVNpZ25hdHVyZVZhbGlkID0gdmVyaWZ5KGtleWNoYWlucy5iYWNrdXAsIGtleVNpZ25hdHVyZXMuYmFja3VwUHViKTtcbiAgICAgIGNvbnN0IGlzQml0Z29LZXlTaWduYXR1cmVWYWxpZCA9IHZlcmlmeShrZXljaGFpbnMuYml0Z28sIGtleVNpZ25hdHVyZXMuYml0Z29QdWIpO1xuICAgICAgaWYgKCFpc0JhY2t1cEtleVNpZ25hdHVyZVZhbGlkIHx8ICFpc0JpdGdvS2V5U2lnbmF0dXJlVmFsaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZWNvbmRhcnkgcHVibGljIGtleSBzaWduYXR1cmVzIGludmFsaWQnKTtcbiAgICAgIH1cbiAgICAgIGRlYnVnKCdzdWNjZXNzZnVsbHkgdmVyaWZpZWQgYmFja3VwIGFuZCBiaXRnbyBrZXkgc2lnbmF0dXJlcycpO1xuICAgIH0gZWxzZSBpZiAoIWRpc2FibGVOZXR3b3JraW5nKSB7XG4gICAgICAvLyB0aGVzZSBrZXlzIHdlcmUgb2J0YWluZWQgb25saW5lIGFuZCB0aGVpciBzaWduYXR1cmVzIHdlcmUgbm90IHZlcmlmaWVkXG4gICAgICAvLyB0aGlzIGNvdWxkIGJlIGRhbmdlcm91c1xuICAgICAgY29uc29sZS5sb2coJ3Vuc2lnbmVkIGtleXMgb2J0YWluZWQgb25saW5lIGFyZSBiZWluZyB1c2VkIGZvciBhZGRyZXNzIHZlcmlmaWNhdGlvbicpO1xuICAgIH1cblxuICAgIGlmIChwYXJzZWRUcmFuc2FjdGlvbi5uZWVkc0N1c3RvbUNoYW5nZUtleVNpZ25hdHVyZVZlcmlmaWNhdGlvbikge1xuICAgICAgaWYgKCFrZXljaGFpbnMudXNlciB8fCAhdXNlclB1YmxpY0tleVZlcmlmaWVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndHJhbnNhY3Rpb24gcmVxdWlyZXMgdmVyaWZpY2F0aW9uIG9mIHVzZXIgcHVibGljIGtleSwgYnV0IGl0IHdhcyB1bmFibGUgdG8gYmUgdmVyaWZpZWQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1c3RvbUNoYW5nZUtleVNpZ25hdHVyZXNWZXJpZmllZCA9IHRoaXMudmVyaWZ5Q3VzdG9tQ2hhbmdlS2V5U2lnbmF0dXJlcyhwYXJzZWRUcmFuc2FjdGlvbiwga2V5Y2hhaW5zLnVzZXIpO1xuICAgICAgaWYgKCFjdXN0b21DaGFuZ2VLZXlTaWduYXR1cmVzVmVyaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICd0cmFuc2FjdGlvbiByZXF1aXJlcyB2ZXJpZmljYXRpb24gb2YgY3VzdG9tIGNoYW5nZSBrZXkgc2lnbmF0dXJlcywgYnV0IHRoZXkgd2VyZSB1bmFibGUgdG8gYmUgdmVyaWZpZWQnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBkZWJ1Zygnc3VjY2Vzc2Z1bGx5IHZlcmlmaWVkIHVzZXIgcHVibGljIGtleSBhbmQgY3VzdG9tIGNoYW5nZSBrZXkgc2lnbmF0dXJlcycpO1xuICAgIH1cblxuICAgIGNvbnN0IG1pc3NpbmdPdXRwdXRzID0gcGFyc2VkVHJhbnNhY3Rpb24ubWlzc2luZ091dHB1dHM7XG4gICAgaWYgKG1pc3NpbmdPdXRwdXRzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgLy8gdGhlcmUgYXJlIHNvbWUgb3V0cHV0cyBpbiB0aGUgcmVjaXBpZW50cyBsaXN0IHRoYXQgaGF2ZSBub3QgbWFkZSBpdCBpbnRvIHRoZSBhY3R1YWwgdHJhbnNhY3Rpb25cbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgb3V0cHV0cyBtaXNzaW5nIGluIHRyYW5zYWN0aW9uIHByZWJ1aWxkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgaW50ZW5kZWRFeHRlcm5hbFNwZW5kID0gcGFyc2VkVHJhbnNhY3Rpb24uZXhwbGljaXRFeHRlcm5hbFNwZW5kQW1vdW50O1xuXG4gICAgLy8gdGhpcyBpcyBhIGxpbWl0IHdlIGltcG9zZSBmb3IgdGhlIHRvdGFsIHZhbHVlIHRoYXQgaXMgYW1lbmRlZCB0byB0aGUgdHJhbnNhY3Rpb24gYmV5b25kIHdoYXQgd2FzIG9yaWdpbmFsbHkgaW50ZW5kZWRcbiAgICBjb25zdCBwYXlBc1lvdUdvTGltaXQgPSBuZXcgQmlnTnVtYmVyKHRoaXMuZ2V0UGF5R29MaW1pdCh2ZXJpZmljYXRpb24uYWxsb3dQYXlnb091dHB1dCkpLm11bHRpcGxpZWRCeShcbiAgICAgIGludGVuZGVkRXh0ZXJuYWxTcGVuZC50b1N0cmluZygpXG4gICAgKTtcblxuICAgIC8qXG4gICAgU29tZSBleHBsYW5hdGlvbiBmb3Igd2h5IHdlJ3JlIGRvaW5nIHdoYXQgd2UncmUgZG9pbmc6XG4gICAgU29tZSBjdXN0b21lcnMgd2lsbCBoYXZlIGFuIG91dHB1dCB0byBCaXRHbydzIFBBWUdvIHdhbGxldCBhZGRlZCB0byB0aGVpciB0cmFuc2FjdGlvbiwgYW5kIHdlIG5lZWQgdG8gYWNjb3VudCBmb3JcbiAgICBpdCBoZXJlLiBUbyBwcm90ZWN0IHNvbWVvbmUgdGFtcGVyaW5nIHdpdGggdGhlIG91dHB1dCB0byBtYWtlIGl0IHNlbmQgbW9yZSB0aGFuIGl0IHNob3VsZCB0byBCaXRHbywgd2UgZGVmaW5lIGFcbiAgICB0aHJlc2hvbGQgZm9yIHRoZSBvdXRwdXQncyB2YWx1ZSBhYm92ZSB3aGljaCB3ZSdsbCB0aHJvdyBhbiBlcnJvciwgYmVjYXVzZSB0aGUgcGF5Z28gb3V0cHV0IHNob3VsZCBuZXZlciBiZSB0aGF0XG4gICAgaGlnaC5cbiAgICAgKi9cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGF0IGFsbCB0aGUgZXh0cmEgYWRkcmVzc2VzIGFyZSBjaGFuZ2UgYWRkcmVzc2VzXG4gICAgLy8gZ2V0IGFsbCB0aGUgYWRkaXRpb25hbCBleHRlcm5hbCBvdXRwdXRzIHRoZSBzZXJ2ZXIgYWRkZWQgYW5kIGNhbGN1bGF0ZSB0aGVpciB2YWx1ZXNcbiAgICBjb25zdCBub25DaGFuZ2VBbW91bnQgPSBuZXcgQmlnTnVtYmVyKHBhcnNlZFRyYW5zYWN0aW9uLmltcGxpY2l0RXh0ZXJuYWxTcGVuZEFtb3VudC50b1N0cmluZygpKTtcblxuICAgIGRlYnVnKFxuICAgICAgJ0ludGVuZGVkIHNwZW5kIGlzICVzLCBOb24tY2hhbmdlIGFtb3VudCBpcyAlcywgcGF5Z28gbGltaXQgaXMgJXMnLFxuICAgICAgaW50ZW5kZWRFeHRlcm5hbFNwZW5kLnRvU3RyaW5nKCksXG4gICAgICBub25DaGFuZ2VBbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIHBheUFzWW91R29MaW1pdC50b1N0cmluZygpXG4gICAgKTtcblxuICAgIC8vIHRoZSBhZGRpdGlvbmFsIGV4dGVybmFsIG91dHB1dHMgY2FuIG9ubHkgYmUgQml0R28ncyBwYXktYXMteW91LWdvIGZlZSwgYnV0IHdlIGNhbm5vdCB2ZXJpZnkgdGhlIHdhbGxldCBhZGRyZXNzXG4gICAgaWYgKG5vbkNoYW5nZUFtb3VudC5ndChwYXlBc1lvdUdvTGltaXQpKSB7XG4gICAgICAvLyB0aGVyZSBhcmUgc29tZSBhZGRyZXNzZXMgdGhhdCBhcmUgb3V0c2lkZSB0aGUgc2NvcGUgb2YgaW50ZW5kZWQgcmVjaXBpZW50cyB0aGF0IGFyZSBub3QgY2hhbmdlIGFkZHJlc3Nlc1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcmVidWlsZCBhdHRlbXB0cyB0byBzcGVuZCB0byB1bmludGVuZGVkIGV4dGVybmFsIHJlY2lwaWVudHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBhbGxPdXRwdXRzID0gcGFyc2VkVHJhbnNhY3Rpb24ub3V0cHV0cztcbiAgICBpZiAoIXR4UHJlYnVpbGQudHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHhQcmVidWlsZC50eEhleCBub3Qgc2V0YCk7XG4gICAgfVxuICAgIGNvbnN0IGlucHV0cyA9IGlzUHNidFxuICAgICAgPyBnZXRQc2J0VHhJbnB1dHModHhQcmVidWlsZC50eEhleCwgdGhpcy5uZXR3b3JrKS5tYXAoKHYpID0+ICh7XG4gICAgICAgICAgLi4udixcbiAgICAgICAgICB2YWx1ZTogYml0Z28udG9UTnVtYmVyKHYudmFsdWUsIHRoaXMuYW1vdW50VHlwZSksXG4gICAgICAgIH0pKVxuICAgICAgOiBhd2FpdCBnZXRUeElucHV0cyh7IHR4UHJlYnVpbGQsIGJpdGdvOiB0aGlzLmJpdGdvLCBjb2luOiB0aGlzLCBkaXNhYmxlTmV0d29ya2luZywgcmVxSWQgfSk7XG4gICAgLy8gY29pbnMgKGRvZ2UpIHRoYXQgY2FuIGV4Y2VlZCBudW1iZXIgbGltaXRzIChhbmQgdGh1cyB3aWxsIHVzZSBiaWdpbnQpIHdpbGwgaGF2ZSB0aGUgYHZhbHVlU3RyaW5nYCBmaWVsZFxuICAgIGNvbnN0IGlucHV0QW1vdW50ID0gaW5wdXRzLnJlZHVjZShcbiAgICAgIChzdW06IGJpZ2ludCwgaSkgPT4gc3VtICsgQmlnSW50KHRoaXMuYW1vdW50VHlwZSA9PT0gJ2JpZ2ludCcgPyBpLnZhbHVlU3RyaW5nIDogaS52YWx1ZSksXG4gICAgICBCaWdJbnQoMClcbiAgICApO1xuICAgIGNvbnN0IG91dHB1dEFtb3VudCA9IGFsbE91dHB1dHMucmVkdWNlKChzdW06IGJpZ2ludCwgbzogT3V0cHV0KSA9PiBzdW0gKyBCaWdJbnQoby5hbW91bnQpLCBCaWdJbnQoMCkpO1xuICAgIGNvbnN0IGZlZSA9IGlucHV0QW1vdW50IC0gb3V0cHV0QW1vdW50O1xuXG4gICAgaWYgKGZlZSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYGF0dGVtcHRpbmcgdG8gc3BlbmQgJHtvdXRwdXRBbW91bnR9IHNhdG9zaGlzLCB3aGljaCBleGNlZWRzIHRoZSBpbnB1dCBhbW91bnQgKCR7aW5wdXRBbW91bnR9IHNhdG9zaGlzKSBieSAkey1mZWV9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIHN1cmUgYW4gYWRkcmVzcyBpcyB2YWxpZCBhbmQgdGhyb3cgYW4gZXJyb3IgaWYgaXQncyBub3QuXG4gICAqIEBwYXJhbSBwYXJhbXMuYWRkcmVzcyBUaGUgYWRkcmVzcyBzdHJpbmcgb24gdGhlIG5ldHdvcmtcbiAgICogQHBhcmFtIHBhcmFtcy5hZGRyZXNzVHlwZVxuICAgKiBAcGFyYW0gcGFyYW1zLmtleWNoYWlucyBLZXljaGFpbiBvYmplY3RzIHdpdGggeHB1YnNcbiAgICogQHBhcmFtIHBhcmFtcy5jb2luU3BlY2lmaWMgQ29pbi1zcGVjaWZpYyBkZXRhaWxzIGZvciB0aGUgYWRkcmVzcyBzdWNoIGFzIGEgd2l0bmVzcyBzY3JpcHRcbiAgICogQHBhcmFtIHBhcmFtcy5jaGFpbiBEZXJpdmF0aW9uIGNoYWluXG4gICAqIEBwYXJhbSBwYXJhbXMuaW5kZXggRGVyaXZhdGlvbiBpbmRleFxuICAgKiBAdGhyb3dzIHtJbnZhbGlkQWRkcmVzc0Vycm9yfVxuICAgKiBAdGhyb3dzIHtJbnZhbGlkQWRkcmVzc0Rlcml2YXRpb25Qcm9wZXJ0eUVycm9yfVxuICAgKiBAdGhyb3dzIHtVbmV4cGVjdGVkQWRkcmVzc0Vycm9yfVxuICAgKi9cbiAgYXN5bmMgaXNXYWxsZXRBZGRyZXNzKHBhcmFtczogVmVyaWZ5QWRkcmVzc09wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCB7IGFkZHJlc3MsIGFkZHJlc3NUeXBlLCBrZXljaGFpbnMsIGNvaW5TcGVjaWZpYywgY2hhaW4sIGluZGV4IH0gPSBwYXJhbXM7XG5cbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9XG5cbiAgICBpZiAoKF8uaXNVbmRlZmluZWQoY2hhaW4pICYmIF8uaXNVbmRlZmluZWQoaW5kZXgpKSB8fCAhKF8uaXNGaW5pdGUoY2hhaW4pICYmIF8uaXNGaW5pdGUoaW5kZXgpKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRGVyaXZhdGlvblByb3BlcnR5RXJyb3IoXG4gICAgICAgIGBhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogaW52YWxpZCBjaGFpbiAoJHtjaGFpbn0pIG9yIGluZGV4ICgke2luZGV4fSlgXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghXy5pc09iamVjdChjb2luU3BlY2lmaWMpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yKFxuICAgICAgICAnYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6IGNvaW5TcGVjaWZpYyBmaWVsZCBtdXN0IGJlIGFuIG9iamVjdCdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFrZXljaGFpbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBwYXJhbSBrZXljaGFpbnMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBleHBlY3RlZEFkZHJlc3MgPSB0aGlzLmdlbmVyYXRlQWRkcmVzcyh7XG4gICAgICBhZGRyZXNzVHlwZTogYWRkcmVzc1R5cGUgYXMgU2NyaXB0VHlwZTJPZjMsXG4gICAgICBrZXljaGFpbnMsXG4gICAgICB0aHJlc2hvbGQ6IDIsXG4gICAgICBjaGFpbixcbiAgICAgIGluZGV4LFxuICAgIH0pO1xuXG4gICAgaWYgKGV4cGVjdGVkQWRkcmVzcy5hZGRyZXNzICE9PSBhZGRyZXNzKSB7XG4gICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEFkZHJlc3NFcnJvcihcbiAgICAgICAgYGFkZHJlc3MgdmFsaWRhdGlvbiBmYWlsdXJlOiBleHBlY3RlZCAke2V4cGVjdGVkQWRkcmVzcy5hZGRyZXNzfSBidXQgZ290ICR7YWRkcmVzc31gXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIGNvaW4gc3VwcG9ydHMgYSBibG9jayB0YXJnZXRcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBzdXBwb3J0c0Jsb2NrVGFyZ2V0KCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSBhZGRyZXNzVHlwZVxuICAgKiBAcmV0dXJucyB0cnVlIGlmZiBjb2luIHN1cHBvcnRzIHNwZW5kaW5nIGZyb20gdW5zcGVudFR5cGVcbiAgICovXG4gIHN1cHBvcnRzQWRkcmVzc1R5cGUoYWRkcmVzc1R5cGU6IFNjcmlwdFR5cGUyT2YzKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5pc1N1cHBvcnRlZFNjcmlwdFR5cGUodGhpcy5uZXR3b3JrLCBhZGRyZXNzVHlwZSk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGNoYWluXG4gICAqIEByZXR1cm4gdHJ1ZSBpZmYgY29pbiBzdXBwb3J0cyBzcGVuZGluZyBmcm9tIGNoYWluXG4gICAqL1xuICBzdXBwb3J0c0FkZHJlc3NDaGFpbihjaGFpbjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzQ2hhaW5Db2RlKGNoYWluKSAmJiB0aGlzLnN1cHBvcnRzQWRkcmVzc1R5cGUodXR4b2xpYi5iaXRnby5zY3JpcHRUeXBlRm9yQ2hhaW4oY2hhaW4pKTtcbiAgfVxuXG4gIGtleUlkc0ZvclNpZ25pbmcoKTogbnVtYmVyW10ge1xuICAgIHJldHVybiBbS2V5SW5kaWNlcy5VU0VSLCBLZXlJbmRpY2VzLkJBQ0tVUCwgS2V5SW5kaWNlcy5CSVRHT107XG4gIH1cblxuICAvKipcbiAgICogVE9ETyhCRy0xMTQ4Nyk6IFJlbW92ZSBhZGRyZXNzVHlwZSwgc2Vnd2l0LCBhbmQgYmVjaDMyIHBhcmFtcyBpbiBTREt2NlxuICAgKiBHZW5lcmF0ZSBhbiBhZGRyZXNzIGZvciBhIHdhbGxldCBiYXNlZCBvbiBhIHNldCBvZiBjb25maWd1cmF0aW9uc1xuICAgKiBAcGFyYW0gcGFyYW1zLmFkZHJlc3NUeXBlIHtzdHJpbmd9ICAgRGVwcmVjYXRlZFxuICAgKiBAcGFyYW0gcGFyYW1zLmtleWNoYWlucyAgIHtbb2JqZWN0XX0gQXJyYXkgb2Ygb2JqZWN0cyB3aXRoIHhwdWJzXG4gICAqIEBwYXJhbSBwYXJhbXMudGhyZXNob2xkICAge251bWJlcn0gICBNaW5pbXVtIG51bWJlciBvZiBzaWduYXR1cmVzXG4gICAqIEBwYXJhbSBwYXJhbXMuY2hhaW4gICAgICAge251bWJlcn0gICBEZXJpdmF0aW9uIGNoYWluIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL0JpdEdvL3Vuc3BlbnRzL2Jsb2IvbWFzdGVyL3NyYy9jb2Rlcy50cyBmb3JcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGNvcnJlc3BvbmRpbmcgYWRkcmVzcyB0eXBlIG9mIGEgZ2l2ZW4gY2hhaW4gY29kZSlcbiAgICogQHBhcmFtIHBhcmFtcy5pbmRleCAgICAgICB7bnVtYmVyfSAgIERlcml2YXRpb24gaW5kZXhcbiAgICogQHBhcmFtIHBhcmFtcy5zZWd3aXQgICAgICB7Ym9vbGVhbn0gIERlcHJlY2F0ZWRcbiAgICogQHBhcmFtIHBhcmFtcy5iZWNoMzIgICAgICB7Ym9vbGVhbn0gIERlcHJlY2F0ZWRcbiAgICogQHJldHVybnMge3tjaGFpbjogbnVtYmVyLCBpbmRleDogbnVtYmVyLCBjb2luOiBudW1iZXIsIGNvaW5TcGVjaWZpYzoge291dHB1dFNjcmlwdCwgcmVkZWVtU2NyaXB0fX19XG4gICAqL1xuICBnZW5lcmF0ZUFkZHJlc3MocGFyYW1zOiBHZW5lcmF0ZUFkZHJlc3NPcHRpb25zKTogQWRkcmVzc0RldGFpbHMge1xuICAgIGNvbnN0IHsga2V5Y2hhaW5zLCB0aHJlc2hvbGQsIGNoYWluLCBpbmRleCwgc2Vnd2l0ID0gZmFsc2UsIGJlY2gzMiA9IGZhbHNlIH0gPSBwYXJhbXM7XG4gICAgbGV0IGRlcml2YXRpb25DaGFpbiA9IGdldEV4dGVybmFsQ2hhaW5Db2RlKCdwMnNoJyk7XG4gICAgaWYgKF8uaXNOdW1iZXIoY2hhaW4pICYmIF8uaXNJbnRlZ2VyKGNoYWluKSAmJiBpc0NoYWluQ29kZShjaGFpbikpIHtcbiAgICAgIGRlcml2YXRpb25DaGFpbiA9IGNoYWluO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbnZlcnRGbGFnc1RvQWRkcmVzc1R5cGUoKTogU2NyaXB0VHlwZTJPZjMge1xuICAgICAgaWYgKGlzQ2hhaW5Db2RlKGNoYWluKSkge1xuICAgICAgICByZXR1cm4gdXR4b2xpYi5iaXRnby5zY3JpcHRUeXBlRm9yQ2hhaW4oY2hhaW4pO1xuICAgICAgfVxuICAgICAgaWYgKF8uaXNCb29sZWFuKHNlZ3dpdCkgJiYgc2Vnd2l0KSB7XG4gICAgICAgIHJldHVybiAncDJzaFAyd3NoJztcbiAgICAgIH0gZWxzZSBpZiAoXy5pc0Jvb2xlYW4oYmVjaDMyKSAmJiBiZWNoMzIpIHtcbiAgICAgICAgcmV0dXJuICdwMndzaCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gJ3Ayc2gnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFkZHJlc3NUeXBlID0gcGFyYW1zLmFkZHJlc3NUeXBlIHx8IGNvbnZlcnRGbGFnc1RvQWRkcmVzc1R5cGUoKTtcblxuICAgIGlmIChhZGRyZXNzVHlwZSAhPT0gdXR4b2xpYi5iaXRnby5zY3JpcHRUeXBlRm9yQ2hhaW4oZGVyaXZhdGlvbkNoYWluKSkge1xuICAgICAgdGhyb3cgbmV3IEFkZHJlc3NUeXBlQ2hhaW5NaXNtYXRjaEVycm9yKGFkZHJlc3NUeXBlLCBkZXJpdmF0aW9uQ2hhaW4pO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zdXBwb3J0c0FkZHJlc3NUeXBlKGFkZHJlc3NUeXBlKSkge1xuICAgICAgc3dpdGNoIChhZGRyZXNzVHlwZSkge1xuICAgICAgICBjYXNlICdwMnNoJzpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludGVybmFsIGVycm9yOiBwMnNoIHNob3VsZCBhbHdheXMgYmUgc3VwcG9ydGVkYCk7XG4gICAgICAgIGNhc2UgJ3Ayc2hQMndzaCc6XG4gICAgICAgICAgdGhyb3cgbmV3IFAyc2hQMndzaFVuc3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgY2FzZSAncDJ3c2gnOlxuICAgICAgICAgIHRocm93IG5ldyBQMndzaFVuc3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgY2FzZSAncDJ0cic6XG4gICAgICAgICAgdGhyb3cgbmV3IFAydHJVbnN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIGNhc2UgJ3AydHJNdXNpZzInOlxuICAgICAgICAgIHRocm93IG5ldyBQMnRyTXVzaWcyVW5zdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEFkZHJlc3NUeXBlRXJyb3IoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgc2lnbmF0dXJlVGhyZXNob2xkID0gMjtcbiAgICBpZiAoXy5pc0ludGVnZXIodGhyZXNob2xkKSkge1xuICAgICAgc2lnbmF0dXJlVGhyZXNob2xkID0gdGhyZXNob2xkIGFzIG51bWJlcjtcbiAgICAgIGlmIChzaWduYXR1cmVUaHJlc2hvbGQgPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RocmVzaG9sZCBoYXMgdG8gYmUgcG9zaXRpdmUnKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduYXR1cmVUaHJlc2hvbGQgPiBrZXljaGFpbnMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndGhyZXNob2xkIGNhbm5vdCBleGNlZWQgbnVtYmVyIG9mIGtleXMnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgZGVyaXZhdGlvbkluZGV4ID0gMDtcbiAgICBpZiAoXy5pc0ludGVnZXIoaW5kZXgpICYmIChpbmRleCBhcyBudW1iZXIpID4gMCkge1xuICAgICAgZGVyaXZhdGlvbkluZGV4ID0gaW5kZXggYXMgbnVtYmVyO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGggPSAnMC8wLycgKyBkZXJpdmF0aW9uQ2hhaW4gKyAnLycgKyBkZXJpdmF0aW9uSW5kZXg7XG4gICAgY29uc3QgaGROb2RlcyA9IGtleWNoYWlucy5tYXAoKHsgcHViIH0pID0+IGJpcDMyLmZyb21CYXNlNTgocHViKSk7XG4gICAgY29uc3QgZGVyaXZlZEtleXMgPSBoZE5vZGVzLm1hcCgoaGROb2RlKSA9PiBoZE5vZGUuZGVyaXZlUGF0aChzYW5pdGl6ZUxlZ2FjeVBhdGgocGF0aCkpLnB1YmxpY0tleSk7XG5cbiAgICBjb25zdCB7IG91dHB1dFNjcmlwdCwgcmVkZWVtU2NyaXB0LCB3aXRuZXNzU2NyaXB0LCBhZGRyZXNzIH0gPSB0aGlzLmNyZWF0ZU11bHRpU2lnQWRkcmVzcyhcbiAgICAgIGFkZHJlc3NUeXBlLFxuICAgICAgc2lnbmF0dXJlVGhyZXNob2xkLFxuICAgICAgZGVyaXZlZEtleXNcbiAgICApO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFkZHJlc3MsXG4gICAgICBjaGFpbjogZGVyaXZhdGlvbkNoYWluLFxuICAgICAgaW5kZXg6IGRlcml2YXRpb25JbmRleCxcbiAgICAgIGNvaW46IHRoaXMuZ2V0Q2hhaW4oKSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICBvdXRwdXRTY3JpcHQ6IG91dHB1dFNjcmlwdC50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHJlZGVlbVNjcmlwdDogcmVkZWVtU2NyaXB0ICYmIHJlZGVlbVNjcmlwdC50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHdpdG5lc3NTY3JpcHQ6IHdpdG5lc3NTY3JpcHQgJiYgd2l0bmVzc1NjcmlwdC50b1N0cmluZygnaGV4JyksXG4gICAgICB9LFxuICAgICAgYWRkcmVzc1R5cGUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyBpbnB1dCBwc2J0IGFkZGVkIHdpdGggZGV0ZXJtaW5pc3RpYyBNdVNpZzIgbm9uY2UgZm9yIGJpdGdvIGtleSBmb3IgZWFjaCBNdVNpZzIgaW5wdXRzLlxuICAgKiBAcGFyYW0gcHNidEhleCBhbGwgTXVTaWcyIGlucHV0cyBzaG91bGQgY29udGFpbiB1c2VyIE11U2lnMiBub25jZVxuICAgKiBAcGFyYW0gd2FsbGV0SWRcbiAgICovXG4gIGFzeW5jIHNpZ25Qc2J0KHBzYnRIZXg6IHN0cmluZywgd2FsbGV0SWQ6IHN0cmluZyk6IFByb21pc2U8U2lnblBzYnRSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhcmFtczogU2lnblBzYnRSZXF1ZXN0ID0geyBwc2J0OiBwc2J0SGV4IH07XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuYml0Z29cbiAgICAgIC5wb3N0KHRoaXMudXJsKCcvd2FsbGV0LycgKyB3YWxsZXRJZCArICcvdHgvc2lnbnBzYnQnKSlcbiAgICAgIC5zZW5kKHBhcmFtcylcbiAgICAgIC5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NlbWJsZSBrZXljaGFpbiBhbmQgaGFsZi1zaWduIHByZWJ1aWx0IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXMgLSB7QHNlZSBTaWduVHJhbnNhY3Rpb25PcHRpb25zfVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbiB8IEhhbGZTaWduZWRVdHhvVHJhbnNhY3Rpb24+fVxuICAgKi9cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICAgIHBhcmFtczogU2lnblRyYW5zYWN0aW9uT3B0aW9uczxUTnVtYmVyPlxuICApOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uIHwgSGFsZlNpZ25lZFV0eG9UcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBwYXJhbXMudHhQcmVidWlsZDtcblxuICAgIGlmIChfLmlzVW5kZWZpbmVkKHR4UHJlYnVpbGQpIHx8ICFfLmlzT2JqZWN0KHR4UHJlYnVpbGQpKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQodHhQcmVidWlsZCkgJiYgIV8uaXNPYmplY3QodHhQcmVidWlsZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eFByZWJ1aWxkIG11c3QgYmUgYW4gb2JqZWN0LCBnb3QgdHlwZSAke3R5cGVvZiB0eFByZWJ1aWxkfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UHJlYnVpbGQgcGFyYW1ldGVyJyk7XG4gICAgfVxuXG4gICAgbGV0IHR4ID0gYml0Z28uaXNQc2J0KHR4UHJlYnVpbGQudHhIZXgpXG4gICAgICA/IGJpdGdvLmNyZWF0ZVBzYnRGcm9tSGV4KHR4UHJlYnVpbGQudHhIZXgsIHRoaXMubmV0d29yaylcbiAgICAgIDogdGhpcy5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXg8VE51bWJlcj4odHhQcmVidWlsZC50eEhleCk7XG5cbiAgICBjb25zdCBpc1R4V2l0aEtleVBhdGhTcGVuZElucHV0ID0gdHggaW5zdGFuY2VvZiBiaXRnby5VdHhvUHNidCAmJiBiaXRnby5pc1RyYW5zYWN0aW9uV2l0aEtleVBhdGhTcGVuZElucHV0KHR4KTtcblxuICAgIGxldCBpc0xhc3RTaWduYXR1cmUgPSBmYWxzZTtcbiAgICBpZiAoXy5pc0Jvb2xlYW4ocGFyYW1zLmlzTGFzdFNpZ25hdHVyZSkpIHtcbiAgICAgIC8vIFdlIGNhbiBvbmx5IGJlIHRoZSBmaXJzdCBzaWduYXR1cmUgb24gYSB0cmFuc2FjdGlvbiB3aXRoIHRhcHJvb3Qga2V5IHBhdGggc3BlbmQgaW5wdXRzIGJlY2F1c2VcbiAgICAgIC8vIHdlIHJlcXVpcmUgdGhlIHNlY3JldCBub25jZSBpbiB0aGUgY2FjaGUgb2YgdGhlIGZpcnN0IHNpZ25lciwgd2hpY2ggaXMgaW1wb3NzaWJsZSB0byByZXRyaWV2ZSBpZlxuICAgICAgLy8gZGVzZXJpYWxpemVkIGZyb20gYSBoZXguXG4gICAgICBpZiAocGFyYW1zLmlzTGFzdFNpZ25hdHVyZSAmJiBpc1R4V2l0aEtleVBhdGhTcGVuZElucHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGJlIGxhc3Qgc2lnbmF0dXJlIG9uIGEgdHJhbnNhY3Rpb24gd2l0aCBrZXkgcGF0aCBzcGVuZCBpbnB1dHMnKTtcbiAgICAgIH1cblxuICAgICAgLy8gaWYgYnVpbGQgaXMgY2FsbGVkIGluc3RlYWQgb2YgYnVpbGRJbmNvbXBsZXRlLCBubyBzaWduYXR1cmUgcGxhY2Vob2xkZXJzIGFyZSBsZWZ0IGluIHRoZSBzaWcgc2NyaXB0XG4gICAgICBpc0xhc3RTaWduYXR1cmUgPSBwYXJhbXMuaXNMYXN0U2lnbmF0dXJlO1xuICAgIH1cblxuICAgIGNvbnN0IGdldFNpZ25lcktleWNoYWluID0gKCk6IHV0eG9saWIuQklQMzJJbnRlcmZhY2UgPT4ge1xuICAgICAgY29uc3QgdXNlclBydiA9IHBhcmFtcy5wcnY7XG4gICAgICBpZiAoXy5pc1VuZGVmaW5lZCh1c2VyUHJ2KSB8fCAhXy5pc1N0cmluZyh1c2VyUHJ2KSkge1xuICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQodXNlclBydikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHBydiBtdXN0IGJlIGEgc3RyaW5nLCBnb3QgdHlwZSAke3R5cGVvZiB1c2VyUHJ2fWApO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBwcnYgcGFyYW1ldGVyIHRvIHNpZ24gdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNpZ25lcktleWNoYWluID0gYmlwMzIuZnJvbUJhc2U1OCh1c2VyUHJ2LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgaWYgKHNpZ25lcktleWNoYWluLmlzTmV1dGVyZWQoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIHVzZXIgcHJpdmF0ZSBrZXkgYnV0IHJlY2VpdmVkIHB1YmxpYyBrZXknKTtcbiAgICAgIH1cbiAgICAgIGRlYnVnKGBIZXJlIGlzIHRoZSBwdWJsaWMga2V5IG9mIHRoZSB4cHJ2IHlvdSB1c2VkIHRvIHNpZ246ICR7c2lnbmVyS2V5Y2hhaW4ubmV1dGVyZWQoKS50b0Jhc2U1OCgpfWApO1xuICAgICAgcmV0dXJuIHNpZ25lcktleWNoYWluO1xuICAgIH07XG5cbiAgICBsZXQgc2lnbmVyS2V5Y2hhaW46IHV0eG9saWIuQklQMzJJbnRlcmZhY2UgfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAodHggaW5zdGFuY2VvZiBiaXRnby5VdHhvUHNidCAmJiBpc1R4V2l0aEtleVBhdGhTcGVuZElucHV0KSB7XG4gICAgICBzd2l0Y2ggKHBhcmFtcy5zaWduaW5nU3RlcCkge1xuICAgICAgICBjYXNlICdzaWduZXJOb25jZSc6XG4gICAgICAgICAgc2lnbmVyS2V5Y2hhaW4gPSBnZXRTaWduZXJLZXljaGFpbigpO1xuICAgICAgICAgIHR4LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQoc2lnbmVyS2V5Y2hhaW4pO1xuICAgICAgICAgIEFic3RyYWN0VXR4b0NvaW4uUFNCVF9DQUNIRS5zZXQodHguZ2V0VW5zaWduZWRUeCgpLmdldElkKCksIHR4KTtcbiAgICAgICAgICByZXR1cm4geyB0eEhleDogdHgudG9IZXgoKSB9O1xuICAgICAgICBjYXNlICdjb3NpZ25lck5vbmNlJzpcbiAgICAgICAgICBhc3NlcnQodHhQcmVidWlsZC53YWxsZXRJZCwgJ3dhbGxldElkIGlzIHJlcXVpcmVkIGZvciBNdVNpZzIgYml0Z28gbm9uY2UnKTtcbiAgICAgICAgICByZXR1cm4geyB0eEhleDogKGF3YWl0IHRoaXMuc2lnblBzYnQodHgudG9IZXgoKSwgdHhQcmVidWlsZC53YWxsZXRJZCkpLnBzYnQgfTtcbiAgICAgICAgY2FzZSAnc2lnbmVyU2lnbmF0dXJlJzpcbiAgICAgICAgICBjb25zdCB0eElkID0gdHguZ2V0VW5zaWduZWRUeCgpLmdldElkKCk7XG4gICAgICAgICAgY29uc3QgcHNidCA9IEFic3RyYWN0VXR4b0NvaW4uUFNCVF9DQUNIRS5nZXQodHhJZCk7XG4gICAgICAgICAgYXNzZXJ0KFxuICAgICAgICAgICAgcHNidCxcbiAgICAgICAgICAgIGBQc2J0IGlzIG1pc3NpbmcgZnJvbSB0eENhY2hlIChjYWNoZSBzaXplICR7QWJzdHJhY3RVdHhvQ29pbi5QU0JUX0NBQ0hFLnNpemV9KS5cbiAgICAgICAgICAgIFRoaXMgbWF5IGJlIGR1ZSB0byB0aGUgcmVxdWVzdCBiZWluZyByb3V0ZWQgdG8gYSBkaWZmZXJlbnQgQml0R28tRXhwcmVzcyBpbnN0YW5jZSB0aGF0IGZvciBzaWduaW5nIHN0ZXAgJ3NpZ25lck5vbmNlJy5gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBBYnN0cmFjdFV0eG9Db2luLlBTQlRfQ0FDSEUuZGVsZXRlKHR4SWQpO1xuICAgICAgICAgIHR4ID0gcHNidC5jb21iaW5lKHR4KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyB0aGlzIGluc3RhbmNlIGlzIG5vdCBhbiBleHRlcm5hbCBzaWduZXJcbiAgICAgICAgICBhc3NlcnQodHhQcmVidWlsZC53YWxsZXRJZCwgJ3dhbGxldElkIGlzIHJlcXVpcmVkIGZvciBNdVNpZzIgYml0Z28gbm9uY2UnKTtcbiAgICAgICAgICBzaWduZXJLZXljaGFpbiA9IGdldFNpZ25lcktleWNoYWluKCk7XG4gICAgICAgICAgdHguc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChzaWduZXJLZXljaGFpbik7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNpZ25Qc2J0KHR4LnRvSGV4KCksIHR4UHJlYnVpbGQud2FsbGV0SWQpO1xuICAgICAgICAgIHR4LmNvbWJpbmUoYml0Z28uY3JlYXRlUHNidEZyb21IZXgocmVzcG9uc2UucHNidCwgdGhpcy5uZXR3b3JrKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAocGFyYW1zLnNpZ25pbmdTdGVwKSB7XG4gICAgICAgIGNhc2UgJ3NpZ25lck5vbmNlJzpcbiAgICAgICAgY2FzZSAnY29zaWduZXJOb25jZSc6XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogSW4gY2VydGFpbiBjYXNlcywgdGhlIGNhbGxlciBvZiB0aGlzIG1ldGhvZCBtYXkgbm90IGtub3cgd2hldGhlciB0aGUgdHhIZXggY29udGFpbnMgYSBwc2J0IHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dChzKS5cbiAgICAgICAgICAgKiBJbnN0ZWFkIG9mIHRocm93aW5nIGVycm9yLCBuby1vcCBhbmQgcmV0dXJuIHRoZSB0eEhleC4gU28gdGhhdCB0aGUgY2FsbGVyIGNhbiBjYWxsIHRoaXMgbWV0aG9kIGluIHRoZSBzYW1lIHNlcXVlbmNlLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHJldHVybiB7IHR4SGV4OiB0eC50b0hleCgpIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNpZ25lcktleWNoYWluID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNpZ25lcktleWNoYWluID0gZ2V0U2lnbmVyS2V5Y2hhaW4oKTtcbiAgICB9XG5cbiAgICBsZXQgc2lnbmVkVHJhbnNhY3Rpb246IGJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+IHwgYml0Z28uVXR4b1BzYnQ7XG4gICAgaWYgKHR4IGluc3RhbmNlb2YgYml0Z28uVXR4b1BzYnQpIHtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gc2lnbkFuZFZlcmlmeVBzYnQodHgsIHNpZ25lcktleWNoYWluLCB7IGlzTGFzdFNpZ25hdHVyZSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR4Lmlucy5sZW5ndGggIT09IHR4UHJlYnVpbGQudHhJbmZvPy51bnNwZW50cz8ubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHVuc3BlbnRzIGFycmF5IHNob3VsZCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHRyYW5zYWN0aW9uIGlucHV0cycpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXBhcmFtcy5wdWJzIHx8ICFpc1RyaXBsZShwYXJhbXMucHVicykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdXN0IHByb3ZpZGUgeHB1YiBhcnJheWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBrZXljaGFpbnMgPSBwYXJhbXMucHVicy5tYXAoKHB1YikgPT4gYmlwMzIuZnJvbUJhc2U1OChwdWIpKSBhcyBUcmlwbGU8QklQMzJJbnRlcmZhY2U+O1xuICAgICAgY29uc3QgY29zaWduZXJQdWIgPSBwYXJhbXMuY29zaWduZXJQdWIgPz8gcGFyYW1zLnB1YnNbMl07XG4gICAgICBjb25zdCBjb3NpZ25lcktleWNoYWluID0gYmlwMzIuZnJvbUJhc2U1OChjb3NpZ25lclB1Yik7XG5cbiAgICAgIGNvbnN0IHdhbGxldFNpZ25lciA9IG5ldyBiaXRnby5XYWxsZXRVbnNwZW50U2lnbmVyPFJvb3RXYWxsZXRLZXlzPihrZXljaGFpbnMsIHNpZ25lcktleWNoYWluLCBjb3NpZ25lcktleWNoYWluKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uKHR4LCB0eFByZWJ1aWxkLnR4SW5mby51bnNwZW50cywgd2FsbGV0U2lnbmVyLCB7XG4gICAgICAgIGlzTGFzdFNpZ25hdHVyZSxcbiAgICAgIH0pIGFzIGJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB0eEhleDogc2lnbmVkVHJhbnNhY3Rpb24udG9CdWZmZXIoKS50b1N0cmluZygnaGV4JyksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIGEgdHJhbnNhY3Rpb24gd2l0aCBhIGN1c3RvbSBzaWduaW5nIGZ1bmN0aW9uLiBFeGFtcGxlIHVzZSBjYXNlIGlzIGV4cHJlc3MgZXh0ZXJuYWwgc2lnbmVyXG4gICAqIEBwYXJhbSBjdXN0b21TaWduaW5nRnVuY3Rpb24gY3VzdG9tIHNpZ25pbmcgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgc2luZ2xlIHNpZ25lZCB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gc2lnblRyYW5zYWN0aW9uUGFyYW1zIHBhcmFtZXRlcnMgZm9yIGN1c3RvbSBzaWduaW5nIGZ1bmN0aW9uLiBJbmNsdWRlcyB0eFByZWJ1aWxkIGFuZCBwdWJzIChmb3IgbGVnYWN5IHR4IG9ubHkpLlxuICAgKlxuICAgKiBAcmV0dXJucyBzaWduZWQgdHJhbnNhY3Rpb24gYXMgaGV4IHN0cmluZ1xuICAgKi9cbiAgYXN5bmMgc2lnbldpdGhDdXN0b21TaWduaW5nRnVuY3Rpb248VE51bWJlciBleHRlbmRzIG51bWJlciB8IGJpZ2ludD4oXG4gICAgY3VzdG9tU2lnbmluZ0Z1bmN0aW9uOiBVdHhvQ3VzdG9tU2lnbmluZ0Z1bmN0aW9uPFROdW1iZXI+LFxuICAgIHNpZ25UcmFuc2FjdGlvblBhcmFtczogeyB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkPFROdW1iZXI+OyBwdWJzPzogc3RyaW5nW10gfVxuICApOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHhIZXggPSBzaWduVHJhbnNhY3Rpb25QYXJhbXMudHhQcmVidWlsZC50eEhleDtcbiAgICBhc3NlcnQodHhIZXgsICdtaXNzaW5nIHR4SGV4IHBhcmFtZXRlcicpO1xuXG4gICAgY29uc3QgdHggPSBiaXRnby5pc1BzYnQodHhIZXgpXG4gICAgICA/IGJpdGdvLmNyZWF0ZVBzYnRGcm9tSGV4KHR4SGV4LCB0aGlzLm5ldHdvcmspXG4gICAgICA6IHRoaXMuY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4PFROdW1iZXI+KHR4SGV4KTtcblxuICAgIGNvbnN0IGlzVHhXaXRoS2V5UGF0aFNwZW5kSW5wdXQgPSB0eCBpbnN0YW5jZW9mIGJpdGdvLlV0eG9Qc2J0ICYmIGJpdGdvLmlzVHJhbnNhY3Rpb25XaXRoS2V5UGF0aFNwZW5kSW5wdXQodHgpO1xuXG4gICAgaWYgKCFpc1R4V2l0aEtleVBhdGhTcGVuZElucHV0KSB7XG4gICAgICByZXR1cm4gYXdhaXQgY3VzdG9tU2lnbmluZ0Z1bmN0aW9uKHsgLi4uc2lnblRyYW5zYWN0aW9uUGFyYW1zLCBjb2luOiB0aGlzIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGdldFR4SGV4ID0gKHY6IFNpZ25lZFRyYW5zYWN0aW9uKTogc3RyaW5nID0+IHtcbiAgICAgIGlmICgndHhIZXgnIGluIHYpIHtcbiAgICAgICAgcmV0dXJuIHYudHhIZXg7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3R4SGV4IG5vdCBmb3VuZCBpbiBzaWduVHJhbnNhY3Rpb24gcmVzdWx0Jyk7XG4gICAgfTtcblxuICAgIGNvbnN0IHNpZ25lck5vbmNlVHggPSBhd2FpdCBjdXN0b21TaWduaW5nRnVuY3Rpb24oe1xuICAgICAgLi4uc2lnblRyYW5zYWN0aW9uUGFyYW1zLFxuICAgICAgc2lnbmluZ1N0ZXA6ICdzaWduZXJOb25jZScsXG4gICAgICBjb2luOiB0aGlzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgeyBwdWJzIH0gPSBzaWduVHJhbnNhY3Rpb25QYXJhbXM7XG4gICAgYXNzZXJ0KHB1YnMgPT09IHVuZGVmaW5lZCB8fCBpc1RyaXBsZShwdWJzKSk7XG5cbiAgICBjb25zdCBjb3NpZ25lck5vbmNlVHggPSBhd2FpdCB0aGlzLnNpZ25UcmFuc2FjdGlvbjxUTnVtYmVyPih7XG4gICAgICAuLi5zaWduVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICBwdWJzLFxuICAgICAgdHhQcmVidWlsZDogeyAuLi5zaWduVHJhbnNhY3Rpb25QYXJhbXMudHhQcmVidWlsZCwgdHhIZXg6IGdldFR4SGV4KHNpZ25lck5vbmNlVHgpIH0sXG4gICAgICBzaWduaW5nU3RlcDogJ2Nvc2lnbmVyTm9uY2UnLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF3YWl0IGN1c3RvbVNpZ25pbmdGdW5jdGlvbih7XG4gICAgICAuLi5zaWduVHJhbnNhY3Rpb25QYXJhbXMsXG4gICAgICB0eFByZWJ1aWxkOiB7IC4uLnNpZ25UcmFuc2FjdGlvblBhcmFtcy50eFByZWJ1aWxkLCB0eEhleDogZ2V0VHhIZXgoY29zaWduZXJOb25jZVR4KSB9LFxuICAgICAgc2lnbmluZ1N0ZXA6ICdzaWduZXJTaWduYXR1cmUnLFxuICAgICAgY29pbjogdGhpcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gdW5zcGVudFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQml0R29UYWludGVkVW5zcGVudDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50Pih1bnNwZW50OiBVbnNwZW50PFROdW1iZXI+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzUmVwbGF5UHJvdGVjdGlvblVuc3BlbnQ8VE51bWJlcj4odW5zcGVudCwgdGhpcy5uZXR3b3JrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCAtIHVzZSB1dHhvbGliLmJpdGdvLmdldERlZmF1bHRTaWdIYXNoKG5ldHdvcmspIGluc3RlYWRcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIGdldCBkZWZhdWx0U2lnSGFzaFR5cGUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdXR4b2xpYi5iaXRnby5nZXREZWZhdWx0U2lnSGFzaCh0aGlzLm5ldHdvcmspO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIC0gdXNlIHV0eG9saWIuYml0Y29pbi52ZXJpZnlTaWduYXR1cmUoKSBpbnN0ZWFkXG4gICAqL1xuICB2ZXJpZnlTaWduYXR1cmUoXG4gICAgdHJhbnNhY3Rpb246IGFueSxcbiAgICBpbnB1dEluZGV4OiBudW1iZXIsXG4gICAgYW1vdW50OiBudW1iZXIsXG4gICAgdmVyaWZpY2F0aW9uU2V0dGluZ3M6IHtcbiAgICAgIHNpZ25hdHVyZUluZGV4PzogbnVtYmVyO1xuICAgICAgcHVibGljS2V5Pzogc3RyaW5nO1xuICAgIH0gPSB7fVxuICApOiBib29sZWFuIHtcbiAgICBpZiAodHJhbnNhY3Rpb24ubmV0d29yayAhPT0gdGhpcy5uZXR3b3JrKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYG5ldHdvcmsgbWlzbWF0Y2hgKTtcbiAgICB9XG4gICAgcmV0dXJuIHV0eG9saWIuYml0Z28udmVyaWZ5U2lnbmF0dXJlKHRyYW5zYWN0aW9uLCBpbnB1dEluZGV4LCBhbW91bnQsIHtcbiAgICAgIHNpZ25hdHVyZUluZGV4OiB2ZXJpZmljYXRpb25TZXR0aW5ncy5zaWduYXR1cmVJbmRleCxcbiAgICAgIHB1YmxpY0tleTogdmVyaWZpY2F0aW9uU2V0dGluZ3MucHVibGljS2V5ID8gQnVmZmVyLmZyb20odmVyaWZpY2F0aW9uU2V0dGluZ3MucHVibGljS2V5LCAnaGV4JykgOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVjb21wb3NlIGEgcmF3IHBzYnQvdHJhbnNhY3Rpb24gaW50byB1c2VmdWwgaW5mb3JtYXRpb24sIHN1Y2ggYXMgdGhlIHRvdGFsIGFtb3VudHMsXG4gICAqIGNoYW5nZSBhbW91bnRzLCBhbmQgdHJhbnNhY3Rpb24gb3V0cHV0cy5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uPFROdW1iZXIgZXh0ZW5kcyBudW1iZXIgfCBiaWdpbnQgPSBudW1iZXI+KFxuICAgIHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9uczxUTnVtYmVyPlxuICApOiBQcm9taXNlPFRyYW5zYWN0aW9uRXhwbGFuYXRpb24+IHtcbiAgICBjb25zdCB7IHR4SGV4IH0gPSBwYXJhbXM7XG4gICAgaWYgKHR5cGVvZiB0eEhleCAhPT0gJ3N0cmluZycgfHwgIXR4SGV4Lm1hdGNoKC9eKFthLWYwLTldezJ9KSskL2kpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgdHJhbnNhY3Rpb24gaGV4LCBtdXN0IGJlIGEgdmFsaWQgaGV4IHN0cmluZycpO1xuICAgIH1cbiAgICByZXR1cm4gdXR4b2xpYi5iaXRnby5pc1BzYnQodHhIZXgpID8gZXhwbGFpblBzYnQocGFyYW1zLCB0aGlzLm5ldHdvcmspIDogZXhwbGFpblR4KHBhcmFtcywgdGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbXVsdGlzaWcgYWRkcmVzcyBvZiBhIGdpdmVuIHR5cGUgZnJvbSBhIGxpc3Qgb2Yga2V5Y2hhaW5zIGFuZCBhIHNpZ25pbmcgdGhyZXNob2xkXG4gICAqIEBwYXJhbSBhZGRyZXNzVHlwZVxuICAgKiBAcGFyYW0gc2lnbmF0dXJlVGhyZXNob2xkXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjcmVhdGVNdWx0aVNpZ0FkZHJlc3MoYWRkcmVzc1R5cGU6IFNjcmlwdFR5cGUyT2YzLCBzaWduYXR1cmVUaHJlc2hvbGQ6IG51bWJlciwga2V5czogQnVmZmVyW10pOiBNdWx0aVNpZ0FkZHJlc3Mge1xuICAgIGNvbnN0IHtcbiAgICAgIHNjcmlwdFB1YktleTogb3V0cHV0U2NyaXB0LFxuICAgICAgcmVkZWVtU2NyaXB0LFxuICAgICAgd2l0bmVzc1NjcmlwdCxcbiAgICB9ID0gdXR4b2xpYi5iaXRnby5vdXRwdXRTY3JpcHRzLmNyZWF0ZU91dHB1dFNjcmlwdDJvZjMoa2V5cywgYWRkcmVzc1R5cGUpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG91dHB1dFNjcmlwdCxcbiAgICAgIHJlZGVlbVNjcmlwdCxcbiAgICAgIHdpdG5lc3NTY3JpcHQsXG4gICAgICBhZGRyZXNzOiB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChvdXRwdXRTY3JpcHQsIHRoaXMubmV0d29yayksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCAtIHVzZSB7QHNlZSBiYWNrdXBLZXlSZWNvdmVyeX1cbiAgICogQnVpbGRzIGEgZnVuZHMgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRHb1xuICAgKiBAcGFyYW0gcGFyYW1zIC0ge0BzZWUgYmFja3VwS2V5UmVjb3Zlcnl9XG4gICAqL1xuICBhc3luYyByZWNvdmVyKHBhcmFtczogUmVjb3ZlclBhcmFtcyk6IFJldHVyblR5cGU8dHlwZW9mIGJhY2t1cEtleVJlY292ZXJ5PiB7XG4gICAgcmV0dXJuIGJhY2t1cEtleVJlY292ZXJ5KHRoaXMsIHRoaXMuYml0Z28sIHBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3ZlciBjb2luIHRoYXQgd2FzIHNlbnQgdG8gd3JvbmcgY2hhaW5cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4aWQgVGhlIHR4aWQgb2YgdGhlIGZhdWx0eSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0gcGFyYW1zLnJlY292ZXJ5QWRkcmVzcyBhZGRyZXNzIHRvIHNlbmQgcmVjb3ZlcmVkIGZ1bmRzIHRvXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0IHRoZSB3YWxsZXQgdGhhdCByZWNlaXZlZCB0aGUgZnVuZHNcbiAgICogQHBhcmFtIHBhcmFtcy5yZWNvdmVyeUNvaW4gdGhlIGNvaW4gdHlwZSBvZiB0aGUgd2FsbGV0IHRoYXQgcmVjZWl2ZWQgdGhlIGZ1bmRzXG4gICAqIEBwYXJhbSBwYXJhbXMuc2lnbmVkIHJldHVybiBhIGhhbGYtc2lnbmVkIHRyYW5zYWN0aW9uIChkZWZhdWx0PXRydWUpXG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSB0aGUgd2FsbGV0IHBhc3NwaHJhc2VcbiAgICogQHBhcmFtIHBhcmFtcy54cHJ2IHRoZSB1bmVuY3J5cHRlZCB4cHJ2ICh1c2VkIGluc3RlYWQgb2Ygd2FsbGV0IHBhc3NwaHJhc2UpXG4gICAqIEBwYXJhbSBwYXJhbXMuYXBpS2V5IGZvciB1dHhvIGNvaW5zIG90aGVyIHRoYW4gW0JUQyxUQlRDXSB0aGlzIGlzIGEgQmxvY2sgQ2hhaXIgYXBpIGtleVxuICAgKiBAcmV0dXJucyB7Kn1cbiAgICovXG4gIGFzeW5jIHJlY292ZXJGcm9tV3JvbmdDaGFpbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50ID0gbnVtYmVyPihcbiAgICBwYXJhbXM6IFJlY292ZXJGcm9tV3JvbmdDaGFpbk9wdGlvbnNcbiAgKTogUHJvbWlzZTxDcm9zc0NoYWluUmVjb3ZlcnlTaWduZWQ8VE51bWJlcj4gfCBDcm9zc0NoYWluUmVjb3ZlcnlVbnNpZ25lZDxUTnVtYmVyPj4ge1xuICAgIGNvbnN0IHsgdHhpZCwgcmVjb3ZlcnlBZGRyZXNzLCB3YWxsZXQsIHdhbGxldFBhc3NwaHJhc2UsIHhwcnYsIGFwaUtleSB9ID0gcGFyYW1zO1xuXG4gICAgLy8gcGFyYW1zLnJlY292ZXJ5Q29pbiB1c2VkIHRvIGJlIHBhcmFtcy5jb2luLCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgIGNvbnN0IHJlY292ZXJ5Q29pbiA9IHBhcmFtcy5jb2luIHx8IHBhcmFtcy5yZWNvdmVyeUNvaW47XG4gICAgaWYgKCFyZWNvdmVyeUNvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBvYmplY3QgcmVjb3ZlcnlDb2luJyk7XG4gICAgfVxuICAgIC8vIHNpZ25lZCBzaG91bGQgZGVmYXVsdCB0byB0cnVlLCBhbmQgb25seSBiZSBkaXNhYmxlZCBpZiBleHBsaWNpdGx5IHNldCB0byBmYWxzZSAobm90IHVuZGVmaW5lZClcbiAgICBjb25zdCBzaWduZWQgPSBwYXJhbXMuc2lnbmVkICE9PSBmYWxzZTtcblxuICAgIGNvbnN0IHNvdXJjZUNvaW5GYW1pbHkgPSB0aGlzLmdldEZhbWlseSgpO1xuICAgIGNvbnN0IHJlY292ZXJ5Q29pbkZhbWlseSA9IHJlY292ZXJ5Q29pbi5nZXRGYW1pbHkoKTtcbiAgICBjb25zdCBzdXBwb3J0ZWRSZWNvdmVyeUNvaW5zID0gc3VwcG9ydGVkQ3Jvc3NDaGFpblJlY292ZXJpZXNbc291cmNlQ29pbkZhbWlseV07XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChzdXBwb3J0ZWRSZWNvdmVyeUNvaW5zKSB8fCAhc3VwcG9ydGVkUmVjb3ZlcnlDb2lucy5pbmNsdWRlcyhyZWNvdmVyeUNvaW5GYW1pbHkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlY292ZXJ5IG9mICR7c291cmNlQ29pbkZhbWlseX0gYmFsYW5jZXMgZnJvbSAke3JlY292ZXJ5Q29pbkZhbWlseX0gd2FsbGV0cyBpcyBub3Qgc3VwcG9ydGVkLmApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCByZWNvdmVyQ3Jvc3NDaGFpbjxUTnVtYmVyPih0aGlzLmJpdGdvLCB7XG4gICAgICBzb3VyY2VDb2luOiB0aGlzLFxuICAgICAgcmVjb3ZlcnlDb2luLFxuICAgICAgd2FsbGV0SWQ6IHdhbGxldCxcbiAgICAgIHR4aWQsXG4gICAgICByZWNvdmVyeUFkZHJlc3MsXG4gICAgICB3YWxsZXRQYXNzcGhyYXNlOiBzaWduZWQgPyB3YWxsZXRQYXNzcGhyYXNlIDogdW5kZWZpbmVkLFxuICAgICAgeHBydjogc2lnbmVkID8geHBydiA6IHVuZGVmaW5lZCxcbiAgICAgIGFwaUtleSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBiaXAzMiBrZXkgcGFpclxuICAgKlxuICAgKiBAcGFyYW0gc2VlZFxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBvYmplY3Qgd2l0aCBnZW5lcmF0ZWQgcHViIGFuZCBwcnZcbiAgICovXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkOiBCdWZmZXIpOiB7IHB1Yjogc3RyaW5nOyBwcnY6IHN0cmluZyB9IHtcbiAgICBpZiAoIXNlZWQpIHtcbiAgICAgIC8vIEFuIGV4dGVuZGVkIHByaXZhdGUga2V5IGhhcyBib3RoIGEgbm9ybWFsIDI1NiBiaXQgcHJpdmF0ZSBrZXkgYW5kIGEgMjU2XG4gICAgICAvLyBiaXQgY2hhaW4gY29kZSwgYm90aCBvZiB3aGljaCBtdXN0IGJlIHJhbmRvbS4gNTEyIGJpdHMgaXMgdGhlcmVmb3JlIHRoZVxuICAgICAgLy8gbWF4aW11bSBlbnRyb3B5IGFuZCBnaXZlcyB1cyBtYXhpbXVtIHNlY3VyaXR5IGFnYWluc3QgY3JhY2tpbmcuXG4gICAgICBzZWVkID0gcmFuZG9tQnl0ZXMoNTEyIC8gOCk7XG4gICAgfVxuICAgIGNvbnN0IGV4dGVuZGVkS2V5ID0gYmlwMzIuZnJvbVNlZWQoc2VlZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHB1YjogZXh0ZW5kZWRLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgICAgcHJ2OiBleHRlbmRlZEtleS50b0Jhc2U1OCgpLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBnZXRFeHRyYVByZWJ1aWxkUGFyYW1zKGJ1aWxkUGFyYW1zOiBFeHRyYVByZWJ1aWxkUGFyYW1zT3B0aW9ucyk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgcHJlQ3JlYXRlQml0R28ocGFyYW1zOiBQcmVjcmVhdGVCaXRHb09wdGlvbnMpOiB2b2lkIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBhc3luYyBwcmVzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBQcmVzaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgYXN5bmMgc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KFxuICAgIHdhbGxldFBhcmFtczogU3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucyxcbiAgICBrZXljaGFpbnM6IEtleWNoYWluc1RyaXBsZXRcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gd2FsbGV0UGFyYW1zO1xuICB9XG5cbiAgdHJhbnNhY3Rpb25EYXRhQWxsb3dlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YWx1ZWxlc3NUcmFuc2ZlckFsbG93ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0UmVjb3ZlcnlQcm92aWRlcihhcGlUb2tlbj86IHN0cmluZyk6IFJlY292ZXJ5UHJvdmlkZXIge1xuICAgIHJldHVybiBmb3JDb2luKHRoaXMuZ2V0Q2hhaW4oKSwgYXBpVG9rZW4pO1xuICB9XG59XG4iXX0=