@bitgo-beta/sdk-coin-xrp 1.3.3-alpha.23 → 1.3.3-alpha.230

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +445 -0
  2. package/dist/src/index.d.ts +4 -2
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +10 -4
  5. package/dist/src/lib/accountSetBuilder.d.ts +18 -0
  6. package/dist/src/lib/accountSetBuilder.d.ts.map +1 -0
  7. package/dist/src/lib/accountSetBuilder.js +63 -0
  8. package/dist/src/lib/constants.d.ts +8 -0
  9. package/dist/src/lib/constants.d.ts.map +1 -0
  10. package/dist/src/lib/constants.js +30 -0
  11. package/dist/src/lib/iface.d.ts +108 -0
  12. package/dist/src/lib/iface.d.ts.map +1 -0
  13. package/dist/src/lib/iface.js +11 -0
  14. package/dist/src/lib/index.d.ts +14 -0
  15. package/dist/src/lib/index.d.ts.map +1 -0
  16. package/dist/src/lib/index.js +43 -0
  17. package/dist/src/lib/keyPair.d.ts +35 -0
  18. package/dist/src/lib/keyPair.d.ts.map +1 -0
  19. package/dist/src/lib/keyPair.js +109 -0
  20. package/dist/src/lib/tokenTransferBuilder.d.ts +29 -0
  21. package/dist/src/lib/tokenTransferBuilder.d.ts.map +1 -0
  22. package/dist/src/lib/tokenTransferBuilder.js +91 -0
  23. package/dist/src/lib/transaction.d.ts +62 -0
  24. package/dist/src/lib/transaction.d.ts.map +1 -0
  25. package/dist/src/lib/transaction.js +371 -0
  26. package/dist/src/lib/transactionBuilder.d.ts +72 -0
  27. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  28. package/dist/src/lib/transactionBuilder.js +253 -0
  29. package/dist/src/lib/transactionBuilderFactory.d.ts +39 -0
  30. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  31. package/dist/src/lib/transactionBuilderFactory.js +97 -0
  32. package/dist/src/lib/transferBuilder.d.ts +28 -0
  33. package/dist/src/lib/transferBuilder.d.ts.map +1 -0
  34. package/dist/src/lib/transferBuilder.js +82 -0
  35. package/dist/src/lib/trustsetBuilder.d.ts +21 -0
  36. package/dist/src/lib/trustsetBuilder.d.ts.map +1 -0
  37. package/dist/src/lib/trustsetBuilder.js +72 -0
  38. package/dist/src/lib/utils.d.ts +69 -0
  39. package/dist/src/lib/utils.d.ts.map +1 -0
  40. package/dist/src/lib/utils.js +268 -0
  41. package/dist/src/lib/walletInitializationBuilder.d.ts +19 -0
  42. package/dist/src/lib/walletInitializationBuilder.d.ts.map +1 -0
  43. package/dist/src/lib/walletInitializationBuilder.js +76 -0
  44. package/dist/src/register.d.ts.map +1 -1
  45. package/dist/src/register.js +5 -1
  46. package/dist/src/ripple.d.ts +112 -2
  47. package/dist/src/ripple.d.ts.map +1 -1
  48. package/dist/src/ripple.js +17 -14
  49. package/dist/src/txrp.d.ts +3 -2
  50. package/dist/src/txrp.d.ts.map +1 -1
  51. package/dist/src/txrp.js +5 -5
  52. package/dist/src/xrp.d.ts +14 -60
  53. package/dist/src/xrp.d.ts.map +1 -1
  54. package/dist/src/xrp.js +260 -144
  55. package/dist/src/xrpToken.d.ts +21 -0
  56. package/dist/src/xrpToken.d.ts.map +1 -0
  57. package/dist/src/xrpToken.js +58 -0
  58. package/dist/tsconfig.tsbuildinfo +1 -8595
  59. package/package.json +11 -11
  60. package/.mocharc.yml +0 -8
package/dist/src/xrp.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -18,118 +22,68 @@ var __importStar = (this && this.__importStar) || function (mod) {
18
22
  __setModuleDefault(result, mod);
19
23
  return result;
20
24
  };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
21
28
  Object.defineProperty(exports, "__esModule", { value: true });
22
29
  exports.Xrp = void 0;
23
30
  /**
24
31
  * @prettier
25
32
  */
26
33
  const bignumber_js_1 = require("bignumber.js");
27
- const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
28
- const crypto_1 = require("crypto");
29
34
  const _ = __importStar(require("lodash"));
30
- const url = __importStar(require("url"));
31
35
  const querystring = __importStar(require("querystring"));
32
- const rippleAddressCodec = __importStar(require("ripple-address-codec"));
36
+ const url = __importStar(require("url"));
37
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
38
+ const statics_1 = require("@bitgo-beta/statics");
33
39
  const rippleBinaryCodec = __importStar(require("ripple-binary-codec"));
34
- const hashes_1 = require("ripple-lib/dist/npm/common/hashes");
35
40
  const rippleKeypairs = __importStar(require("ripple-keypairs"));
36
- const sdk_core_1 = require("@bitgo-beta/sdk-core");
37
- const ripple = require('./ripple');
41
+ const xrpl = __importStar(require("xrpl"));
42
+ const keyPair_1 = require("./lib/keyPair");
43
+ const utils_1 = __importDefault(require("./lib/utils"));
44
+ const ripple_1 = __importDefault(require("./ripple"));
45
+ const lib_1 = require("./lib");
38
46
  class Xrp extends sdk_core_1.BaseCoin {
39
- constructor(bitgo) {
47
+ constructor(bitgo, staticsCoin) {
40
48
  super(bitgo);
49
+ if (!staticsCoin) {
50
+ throw new Error('missing required constructor parameter staticsCoin');
51
+ }
52
+ this._staticsCoin = staticsCoin;
41
53
  }
42
- static createInstance(bitgo) {
43
- return new Xrp(bitgo);
54
+ static createInstance(bitgo, staticsCoin) {
55
+ return new Xrp(bitgo, staticsCoin);
44
56
  }
45
57
  /**
46
58
  * Factor between the coin's base unit and its smallest subdivison
47
59
  */
48
60
  getBaseFactor() {
49
- return 1e6;
61
+ return Math.pow(10, this._staticsCoin.decimalPlaces);
50
62
  }
51
63
  /**
52
64
  * Identifier for the blockchain which supports this coin
53
65
  */
54
66
  getChain() {
55
- return 'xrp';
67
+ return this._staticsCoin.name;
56
68
  }
57
69
  /**
58
70
  * Identifier for the coin family
59
71
  */
60
72
  getFamily() {
61
- return 'xrp';
73
+ return this._staticsCoin.family;
62
74
  }
63
75
  /**
64
76
  * Complete human-readable name of this coin
65
77
  */
66
78
  getFullName() {
67
- return 'Ripple';
68
- }
69
- /**
70
- * Parse an address string into address and destination tag
71
- */
72
- getAddressDetails(address) {
73
- const destinationDetails = url.parse(address);
74
- const destinationAddress = destinationDetails.pathname;
75
- if (!destinationAddress || !rippleAddressCodec.isValidClassicAddress(destinationAddress)) {
76
- throw new sdk_core_1.InvalidAddressError(`destination address "${destinationAddress}" is not valid`);
77
- }
78
- // there are no other properties like destination tags
79
- if (destinationDetails.pathname === address) {
80
- return {
81
- address: address,
82
- destinationTag: undefined,
83
- };
84
- }
85
- if (!destinationDetails.query) {
86
- throw new sdk_core_1.InvalidAddressError('no query params present');
87
- }
88
- const queryDetails = querystring.parse(destinationDetails.query);
89
- if (!queryDetails.dt) {
90
- // if there are more properties, the query details need to contain the destination tag property.
91
- throw new sdk_core_1.InvalidAddressError('destination tag missing');
92
- }
93
- if (Array.isArray(queryDetails.dt)) {
94
- // if queryDetails.dt is an array, that means dt was given multiple times, which is not valid
95
- throw new sdk_core_1.InvalidAddressError(`destination tag can appear at most once, but ${queryDetails.dt.length} destination tags were found`);
96
- }
97
- const parsedTag = parseInt(queryDetails.dt, 10);
98
- if (!Number.isSafeInteger(parsedTag)) {
99
- throw new sdk_core_1.InvalidAddressError('invalid destination tag');
100
- }
101
- if (parsedTag > 0xffffffff || parsedTag < 0) {
102
- throw new sdk_core_1.InvalidAddressError('destination tag out of range');
103
- }
104
- return {
105
- address: destinationAddress,
106
- destinationTag: parsedTag,
107
- };
108
- }
109
- /**
110
- * Construct a full, normalized address from an address and destination tag
111
- */
112
- normalizeAddress({ address, destinationTag }) {
113
- if (!_.isString(address)) {
114
- throw new sdk_core_1.InvalidAddressError('invalid address details');
115
- }
116
- if (_.isInteger(destinationTag)) {
117
- return `${address}?dt=${destinationTag}`;
118
- }
119
- return address;
79
+ return this._staticsCoin.fullName;
120
80
  }
121
81
  /**
122
82
  * Evaluates whether an address string is valid for this coin
123
83
  * @param address
124
84
  */
125
85
  isValidAddress(address) {
126
- try {
127
- const addressDetails = this.getAddressDetails(address);
128
- return address === this.normalizeAddress(addressDetails);
129
- }
130
- catch (e) {
131
- return false;
132
- }
86
+ return utils_1.default.isValidAddress(address);
133
87
  }
134
88
  /**
135
89
  * Return boolean indicating whether input is valid public key for the coin.
@@ -138,12 +92,7 @@ class Xrp extends sdk_core_1.BaseCoin {
138
92
  * @returns {Boolean} is it valid?
139
93
  */
140
94
  isValidPub(pub) {
141
- try {
142
- return utxo_lib_1.bip32.fromBase58(pub).isNeutered();
143
- }
144
- catch (e) {
145
- return false;
146
- }
95
+ return utils_1.default.isValidPublicKey(pub);
147
96
  }
148
97
  /**
149
98
  * Get fee info from server
@@ -151,6 +100,12 @@ class Xrp extends sdk_core_1.BaseCoin {
151
100
  async getFeeInfo() {
152
101
  return this.bitgo.get(this.url('/public/feeinfo')).result();
153
102
  }
103
+ getTokenEnablementConfig() {
104
+ return {
105
+ requiresTokenEnablement: true,
106
+ supportsMultipleTokenEnablements: false,
107
+ };
108
+ }
154
109
  /**
155
110
  * Assemble keychain and half-sign prebuilt transaction
156
111
  * @param params
@@ -158,7 +113,7 @@ class Xrp extends sdk_core_1.BaseCoin {
158
113
  * - prv
159
114
  * @returns Bluebird<HalfSignedTransaction>
160
115
  */
161
- async signTransaction({ txPrebuild, prv }) {
116
+ async signTransaction({ txPrebuild, prv, isLastSignature, }) {
162
117
  if (_.isUndefined(txPrebuild) || !_.isObject(txPrebuild)) {
163
118
  if (!_.isUndefined(txPrebuild) && !_.isObject(txPrebuild)) {
164
119
  throw new Error(`txPrebuild must be an object, got type ${typeof txPrebuild}`);
@@ -171,17 +126,21 @@ class Xrp extends sdk_core_1.BaseCoin {
171
126
  }
172
127
  throw new Error('missing prv parameter to sign transaction');
173
128
  }
174
- const userKey = utxo_lib_1.bip32.fromBase58(prv);
175
- const userPrivateKey = userKey.privateKey;
176
- if (!userPrivateKey) {
177
- throw new Error(`no privateKey`);
129
+ if (!txPrebuild.txHex) {
130
+ throw new Error(`missing txHex in txPrebuild`);
178
131
  }
179
- const userAddress = rippleKeypairs.deriveAddress(userKey.publicKey.toString('hex'));
180
- const rippleLib = ripple();
181
- const halfSigned = rippleLib.signWithPrivateKey(txPrebuild.txHex, userPrivateKey.toString('hex'), {
182
- signAs: userAddress,
132
+ const keyPair = new keyPair_1.KeyPair({ prv });
133
+ const address = keyPair.getAddress();
134
+ const privateKey = keyPair.getPrivateKey().toString('hex');
135
+ const tx = ripple_1.default.signWithPrivateKey(txPrebuild.txHex, privateKey, {
136
+ signAs: address,
183
137
  });
184
- return { halfSigned: { txHex: halfSigned.signedTransaction } };
138
+ // Normally the SDK provides the first signature for an XRP tx, but occasionally it provides the final one as well
139
+ // (recoveries)
140
+ if (isLastSignature) {
141
+ return { txHex: tx.signedTransaction };
142
+ }
143
+ return { halfSigned: { txHex: tx.signedTransaction } };
185
144
  }
186
145
  /**
187
146
  * Ripple requires additional parameters for wallet generation to be sent to the server. The additional parameters are
@@ -196,11 +155,11 @@ class Xrp extends sdk_core_1.BaseCoin {
196
155
  }
197
156
  }
198
157
  else {
199
- const keyPair = utxo_lib_1.ECPair.makeRandom();
200
- if (!keyPair.privateKey) {
158
+ const keyPair = new keyPair_1.KeyPair().getKeys();
159
+ if (!keyPair.prv) {
201
160
  throw new Error('no privateKey');
202
161
  }
203
- walletParams.rootPrivateKey = keyPair.privateKey.toString('hex');
162
+ walletParams.rootPrivateKey = keyPair.prv;
204
163
  }
205
164
  return walletParams;
206
165
  }
@@ -209,26 +168,33 @@ class Xrp extends sdk_core_1.BaseCoin {
209
168
  * @param params
210
169
  */
211
170
  async explainTransaction(params = {}) {
212
- if (!params.txHex) {
171
+ let transaction;
172
+ let txHex = params.txHex || (params.halfSigned && params.halfSigned.txHex);
173
+ if (!txHex) {
213
174
  throw new Error('missing required param txHex');
214
175
  }
215
- let transaction;
216
- let txHex;
217
176
  try {
218
- transaction = rippleBinaryCodec.decode(params.txHex);
219
- txHex = params.txHex;
177
+ transaction = rippleBinaryCodec.decode(txHex);
220
178
  }
221
179
  catch (e) {
222
180
  try {
223
- transaction = JSON.parse(params.txHex);
181
+ transaction = JSON.parse(txHex);
224
182
  txHex = rippleBinaryCodec.encode(transaction);
225
183
  }
226
184
  catch (e) {
227
185
  throw new Error('txHex needs to be either hex or JSON string for XRP');
228
186
  }
229
187
  }
230
- const id = hashes_1.computeBinaryTransactionHash(txHex);
231
- if (transaction.TransactionType == 'AccountSet') {
188
+ let id;
189
+ // hashes ids are different for signed and unsigned tx
190
+ // first we try to get the hash id as if it is signed, will throw if its not
191
+ try {
192
+ id = xrpl.hashes.hashSignedTx(txHex);
193
+ }
194
+ catch (e) {
195
+ id = xrpl.hashes.hashTx(txHex);
196
+ }
197
+ if (transaction.TransactionType === 'AccountSet') {
232
198
  return {
233
199
  displayOrder: ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'accountSet'],
234
200
  id: id,
@@ -238,11 +204,42 @@ class Xrp extends sdk_core_1.BaseCoin {
238
204
  outputs: [],
239
205
  fee: {
240
206
  fee: transaction.Fee,
241
- feeRate: null,
207
+ feeRate: undefined,
242
208
  size: txHex.length / 2,
243
209
  },
244
210
  accountSet: {
245
211
  messageKey: transaction.MessageKey,
212
+ setFlag: transaction.SetFlag,
213
+ },
214
+ };
215
+ }
216
+ else if (transaction.TransactionType === 'TrustSet') {
217
+ return {
218
+ displayOrder: [
219
+ 'id',
220
+ 'outputAmount',
221
+ 'changeAmount',
222
+ 'outputs',
223
+ 'changeOutputs',
224
+ 'fee',
225
+ 'account',
226
+ 'limitAmount',
227
+ ],
228
+ id: id,
229
+ changeOutputs: [],
230
+ outputAmount: 0,
231
+ changeAmount: 0,
232
+ outputs: [],
233
+ fee: {
234
+ fee: transaction.Fee,
235
+ feeRate: undefined,
236
+ size: txHex.length / 2,
237
+ },
238
+ account: transaction.Account,
239
+ limitAmount: {
240
+ currency: transaction.LimitAmount.currency,
241
+ issuer: transaction.LimitAmount.issuer,
242
+ value: transaction.LimitAmount.value,
246
243
  },
247
244
  };
248
245
  }
@@ -261,7 +258,7 @@ class Xrp extends sdk_core_1.BaseCoin {
261
258
  ],
262
259
  fee: {
263
260
  fee: transaction.Fee,
264
- feeRate: null,
261
+ feeRate: undefined,
265
262
  size: txHex.length / 2,
266
263
  },
267
264
  };
@@ -274,6 +271,8 @@ class Xrp extends sdk_core_1.BaseCoin {
274
271
  * @returns {boolean}
275
272
  */
276
273
  async verifyTransaction({ txParams, txPrebuild }) {
274
+ var _a;
275
+ const coinConfig = statics_1.coins.get(this.getChain());
277
276
  const explanation = await this.explainTransaction({
278
277
  txHex: txPrebuild.txHex,
279
278
  });
@@ -287,9 +286,34 @@ class Xrp extends sdk_core_1.BaseCoin {
287
286
  const amount2 = new bignumber_js_1.BigNumber(recipient2.amount);
288
287
  return amount1.toFixed() === amount2.toFixed();
289
288
  };
290
- if (!comparator(output, expectedOutput)) {
289
+ if ((txParams.type === undefined || txParams.type === 'payment') &&
290
+ typeof output.amount !== 'object' &&
291
+ !comparator(output, expectedOutput)) {
291
292
  throw new Error('transaction prebuild does not match expected output');
292
293
  }
294
+ if (txParams.type === 'enabletoken') {
295
+ if (((_a = txParams.recipients) === null || _a === void 0 ? void 0 : _a.length) !== 1) {
296
+ throw new Error('Only one recipient is allowed.');
297
+ }
298
+ const recipient = txParams.recipients[0];
299
+ if (!recipient.tokenName) {
300
+ throw new Error('Recipient must include a token name.');
301
+ }
302
+ const recipientCurrency = utils_1.default.getXrpCurrencyFromTokenName(recipient.tokenName).currency;
303
+ if (coinConfig.isToken) {
304
+ if (recipientCurrency !== coinConfig.currencyCode) {
305
+ throw new Error('Incorrect token name specified in recipients');
306
+ }
307
+ }
308
+ if (!('account' in explanation) || !('limitAmount' in explanation) || !explanation.limitAmount.currency) {
309
+ throw new Error('Explanation is missing required keys (account or limitAmount with currency)');
310
+ }
311
+ const baseAddress = explanation.account;
312
+ const currency = explanation.limitAmount.currency;
313
+ if (recipient.address !== baseAddress || recipientCurrency !== currency) {
314
+ throw new Error('Tx outputs does not match with expected txParams recipients');
315
+ }
316
+ }
293
317
  return true;
294
318
  }
295
319
  /**
@@ -303,8 +327,8 @@ class Xrp extends sdk_core_1.BaseCoin {
303
327
  if (!this.isValidAddress(address)) {
304
328
  throw new sdk_core_1.InvalidAddressError(`address verification failure: address "${address}" is not valid`);
305
329
  }
306
- const addressDetails = this.getAddressDetails(address);
307
- const rootAddressDetails = this.getAddressDetails(rootAddress);
330
+ const addressDetails = utils_1.default.getAddressDetails(address);
331
+ const rootAddressDetails = utils_1.default.getAddressDetails(rootAddress);
308
332
  if (addressDetails.address !== rootAddressDetails.address) {
309
333
  throw new sdk_core_1.UnexpectedAddressError(`address validation failure: ${addressDetails.address} vs. ${rootAddressDetails.address}`);
310
334
  }
@@ -336,25 +360,35 @@ class Xrp extends sdk_core_1.BaseCoin {
336
360
  params: [
337
361
  {
338
362
  account: params.rootAddress,
339
- strict: true,
340
363
  ledger_index: 'current',
341
364
  queue: true,
365
+ strict: true,
342
366
  signer_lists: true,
343
367
  },
344
368
  ],
345
369
  };
370
+ const accountLinesParams = {
371
+ method: 'account_lines',
372
+ params: [
373
+ {
374
+ account: params.rootAddress,
375
+ ledger_index: 'validated',
376
+ },
377
+ ],
378
+ };
346
379
  if (isKrsRecovery) {
347
- sdk_core_1.checkKrsProvider(this, params.krsProvider);
380
+ (0, sdk_core_1.checkKrsProvider)(this, params.krsProvider);
348
381
  }
349
382
  // Validate the destination address
350
383
  if (!this.isValidAddress(params.recoveryDestination)) {
351
384
  throw new Error('Invalid destination address!');
352
385
  }
353
- const keys = sdk_core_1.getBip32Keys(this.bitgo, params, { requireBitGoXpub: false });
354
- const { addressDetails, feeDetails, serverDetails } = await sdk_core_1.promiseProps({
386
+ const keys = (0, sdk_core_1.getBip32Keys)(this.bitgo, params, { requireBitGoXpub: false });
387
+ const { addressDetails, feeDetails, serverDetails, accountLines } = await (0, sdk_core_1.promiseProps)({
355
388
  addressDetails: this.bitgo.post(rippledUrl).send(accountInfoParams),
356
389
  feeDetails: this.bitgo.post(rippledUrl).send({ method: 'fee' }),
357
390
  serverDetails: this.bitgo.post(rippledUrl).send({ method: 'server_info' }),
391
+ accountLines: this.bitgo.post(rippledUrl).send(accountLinesParams),
358
392
  });
359
393
  const openLedgerFee = new bignumber_js_1.BigNumber(feeDetails.body.result.drops.open_ledger_fee);
360
394
  const baseReserve = new bignumber_js_1.BigNumber(serverDetails.body.result.info.validated_ledger.reserve_base_xrp).times(this.getBaseFactor());
@@ -412,7 +446,7 @@ class Xrp extends sdk_core_1.BaseCoin {
412
446
  throw new Error('the destination flag requirement has not been activated');
413
447
  }
414
448
  // recover the funds
415
- const reserve = baseReserve.plus(reserveDelta.times(5));
449
+ const reserve = baseReserve.plus(reserveDelta);
416
450
  const recoverableBalance = balance.minus(reserve);
417
451
  const rawDestination = params.recoveryDestination;
418
452
  const destinationDetails = url.parse(rawDestination);
@@ -430,68 +464,150 @@ class Xrp extends sdk_core_1.BaseCoin {
430
464
  destinationTag = parsedTag;
431
465
  }
432
466
  }
433
- const transaction = {
434
- TransactionType: 'Payment',
435
- Account: params.rootAddress,
436
- Destination: destinationAddress,
437
- DestinationTag: destinationTag,
438
- Amount: recoverableBalance.toFixed(0),
439
- Flags: 2147483648,
440
- LastLedgerSequence: currentLedger + 1000000,
441
- Fee: openLedgerFee.times(3).toFixed(0),
442
- Sequence: sequenceId,
443
- };
444
- const txJSON = JSON.stringify(transaction);
467
+ if (recoverableBalance.toNumber() <= 0) {
468
+ throw new Error(`Quantity of XRP to recover must be greater than 0. Current balance: ${balance.toNumber()}, blockchain reserve: ${reserve.toNumber()}, spendable balance: ${recoverableBalance.toNumber()}`);
469
+ }
470
+ const tokenName = params === null || params === void 0 ? void 0 : params.tokenName;
471
+ if (!!tokenName) {
472
+ const tokenParams = {
473
+ destinationAddress,
474
+ destinationTag,
475
+ recoverableBalance,
476
+ currentLedger,
477
+ openLedgerFee,
478
+ sequenceId,
479
+ accountLines,
480
+ keys,
481
+ isKrsRecovery,
482
+ isUnsignedSweep,
483
+ userAddress,
484
+ backupAddress,
485
+ };
486
+ return this.recoverXrpToken(params, tokenName, tokenParams);
487
+ }
488
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get(this.getChain()));
489
+ const txBuilder = factory.getTransferBuilder();
490
+ txBuilder
491
+ .to(destinationAddress)
492
+ .amount(recoverableBalance.toFixed(0))
493
+ .sender(params.rootAddress)
494
+ .flags(2147483648)
495
+ .lastLedgerSequence(currentLedger + 1000000) // give it 1 million ledgers' time (~1 month, suitable for KRS)
496
+ .fee(openLedgerFee.times(3).toFixed(0)) // the factor three is for the multisigning
497
+ .sequence(sequenceId);
498
+ const tx = await txBuilder.build();
499
+ const serializedTx = tx.toBroadcastFormat();
445
500
  if (isUnsignedSweep) {
446
- return txJSON;
501
+ return {
502
+ txHex: serializedTx,
503
+ coin: this.getChain(),
504
+ };
447
505
  }
448
- const rippleLib = ripple();
449
506
  if (!keys[0].privateKey) {
450
507
  throw new Error(`userKey is not a private key`);
451
508
  }
452
509
  const userKey = keys[0].privateKey.toString('hex');
453
- const userSignature = rippleLib.signWithPrivateKey(txJSON, userKey, { signAs: userAddress });
510
+ const userSignature = ripple_1.default.signWithPrivateKey(serializedTx, userKey, { signAs: userAddress });
454
511
  let signedTransaction;
455
512
  if (isKrsRecovery) {
456
- signedTransaction = userSignature;
513
+ signedTransaction = userSignature.signedTransaction;
457
514
  }
458
515
  else {
459
516
  if (!keys[1].privateKey) {
460
517
  throw new Error(`backupKey is not a private key`);
461
518
  }
462
519
  const backupKey = keys[1].privateKey.toString('hex');
463
- const backupSignature = rippleLib.signWithPrivateKey(txJSON, backupKey, { signAs: backupAddress });
464
- signedTransaction = rippleLib.combine([userSignature.signedTransaction, backupSignature.signedTransaction]);
520
+ const backupSignature = ripple_1.default.signWithPrivateKey(serializedTx, backupKey, { signAs: backupAddress });
521
+ signedTransaction = ripple_1.default.multisign([userSignature.signedTransaction, backupSignature.signedTransaction]);
465
522
  }
466
523
  const transactionExplanation = (await this.explainTransaction({
467
- txHex: signedTransaction.signedTransaction,
524
+ txHex: signedTransaction,
468
525
  }));
469
- transactionExplanation.txHex = signedTransaction.signedTransaction;
526
+ transactionExplanation.txHex = signedTransaction;
470
527
  if (isKrsRecovery) {
471
528
  transactionExplanation.backupKey = params.backupKey;
472
529
  transactionExplanation.coin = this.getChain();
473
530
  }
474
531
  return transactionExplanation;
475
532
  }
476
- initiateRecovery(params) {
477
- throw new Error('deprecated method');
533
+ async recoverXrpToken(params, tokenName, tokenParams) {
534
+ const { currency, issuer } = utils_1.default.getXrpCurrencyFromTokenName(tokenName);
535
+ const lines = tokenParams.accountLines.body.result.lines;
536
+ let amount;
537
+ for (const line of lines) {
538
+ if (line.currency === currency && line.account === issuer) {
539
+ amount = line.balance;
540
+ break;
541
+ }
542
+ }
543
+ if (amount === undefined) {
544
+ throw new Error(`Does not have Trustline with ${issuer}`);
545
+ }
546
+ if (amount === '0') {
547
+ throw new Error(`Does not have funds to recover`);
548
+ }
549
+ const decimalPlaces = statics_1.coins.get(tokenName).decimalPlaces;
550
+ amount = new bignumber_js_1.BigNumber(amount).shiftedBy(decimalPlaces).toFixed();
551
+ const FLAG_VALUE = 2147483648;
552
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get(tokenName));
553
+ const txBuilder = factory.getTokenTransferBuilder();
554
+ txBuilder
555
+ .to(tokenParams.destinationAddress)
556
+ .amount(amount)
557
+ .sender(params.rootAddress)
558
+ .flags(FLAG_VALUE)
559
+ .lastLedgerSequence(tokenParams.currentLedger + 1000000) // give it 1 million ledgers' time (~1 month, suitable for KRS)
560
+ .fee(tokenParams.openLedgerFee.times(3).toFixed(0)) // the factor three is for the multisigning
561
+ .sequence(tokenParams.sequenceId);
562
+ const tx = await txBuilder.build();
563
+ const serializedTx = tx.toBroadcastFormat();
564
+ const { keys, isKrsRecovery, isUnsignedSweep, userAddress, backupAddress } = tokenParams;
565
+ if (isUnsignedSweep) {
566
+ return {
567
+ txHex: serializedTx,
568
+ coin: this.getChain(),
569
+ };
570
+ }
571
+ if (!keys[0].privateKey) {
572
+ throw new Error(`userKey is not a private key`);
573
+ }
574
+ const userKey = keys[0].privateKey.toString('hex');
575
+ const userSignature = ripple_1.default.signWithPrivateKey(serializedTx, userKey, { signAs: userAddress });
576
+ let signedTransaction;
577
+ if (isKrsRecovery) {
578
+ signedTransaction = userSignature.signedTransaction;
579
+ }
580
+ else {
581
+ if (!keys[1].privateKey) {
582
+ throw new Error(`backupKey is not a private key`);
583
+ }
584
+ const backupKey = keys[1].privateKey.toString('hex');
585
+ const backupSignature = ripple_1.default.signWithPrivateKey(serializedTx, backupKey, { signAs: backupAddress });
586
+ signedTransaction = ripple_1.default.multisign([userSignature.signedTransaction, backupSignature.signedTransaction]);
587
+ }
588
+ const transactionExplanation = (await this.explainTransaction({
589
+ txHex: signedTransaction,
590
+ }));
591
+ transactionExplanation.txHex = signedTransaction;
592
+ if (isKrsRecovery) {
593
+ transactionExplanation.backupKey = params.backupKey;
594
+ transactionExplanation.coin = this.getChain();
595
+ }
596
+ return transactionExplanation;
478
597
  }
479
598
  /**
480
599
  * Generate a new keypair for this coin.
481
600
  * @param seed Seed from which the new keypair should be generated, otherwise a random seed is used
482
601
  */
483
602
  generateKeyPair(seed) {
484
- if (!seed) {
485
- // An extended private key has both a normal 256 bit private key and a 256
486
- // bit chain code, both of which must be random. 512 bits is therefore the
487
- // maximum entropy and gives us maximum security against cracking.
488
- seed = crypto_1.randomBytes(512 / 8);
489
- }
490
- const extendedKey = utxo_lib_1.bip32.fromSeed(seed);
491
- const xpub = extendedKey.neutered().toBase58();
603
+ const keyPair = seed ? new keyPair_1.KeyPair({ seed }) : new keyPair_1.KeyPair();
604
+ const keys = keyPair.getExtendedKeys();
605
+ if (!keys.xprv) {
606
+ throw new Error('Missing prv in key generation.');
607
+ }
492
608
  return {
493
- pub: xpub,
494
- prv: extendedKey.toBase58(),
609
+ pub: keys.xpub,
610
+ prv: keys.xprv,
495
611
  };
496
612
  }
497
613
  async parseTransaction(params) {
@@ -499,4 +615,4 @@ class Xrp extends sdk_core_1.BaseCoin {
499
615
  }
500
616
  }
501
617
  exports.Xrp = Xrp;
502
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHJwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3hycC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCwrQ0FBeUM7QUFDekMsbURBQXFEO0FBQ3JELG1DQUFxQztBQUNyQywwQ0FBNEI7QUFDNUIseUNBQTJCO0FBQzNCLHlEQUEyQztBQUUzQyx5RUFBMkQ7QUFDM0QsdUVBQXlEO0FBQ3pELDhEQUFpRjtBQUNqRixnRUFBa0Q7QUFDbEQsbURBaUI4QjtBQUU5QixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUF5RG5DLE1BQWEsR0FBSSxTQUFRLG1CQUFRO0lBQy9CLFlBQXNCLEtBQWdCO1FBQ3BDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNmLENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWdCO1FBQ3BDLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksYUFBYTtRQUNsQixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFRDs7T0FFRztJQUNJLFFBQVE7UUFDYixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7T0FFRztJQUNJLFNBQVM7UUFDZCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVc7UUFDaEIsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksaUJBQWlCLENBQUMsT0FBZTtRQUN0QyxNQUFNLGtCQUFrQixHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDOUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUM7UUFDdkQsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsa0JBQWtCLENBQUMscUJBQXFCLENBQUMsa0JBQWtCLENB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ICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCB7IEJpZ051bWJlciB9IGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgeyBiaXAzMiwgRUNQYWlyIH0gZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0ICogYXMgdXJsIGZyb20gJ3VybCc7XG5pbXBvcnQgKiBhcyBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5cbmltcG9ydCAqIGFzIHJpcHBsZUFkZHJlc3NDb2RlYyBmcm9tICdyaXBwbGUtYWRkcmVzcy1jb2RlYyc7XG5pbXBvcnQgKiBhcyByaXBwbGVCaW5hcnlDb2RlYyBmcm9tICdyaXBwbGUtYmluYXJ5LWNvZGVjJztcbmltcG9ydCB7IGNvbXB1dGVCaW5hcnlUcmFuc2FjdGlvbkhhc2ggfSBmcm9tICdyaXBwbGUtbGliL2Rpc3QvbnBtL2NvbW1vbi9oYXNoZXMnO1xuaW1wb3J0ICogYXMgcmlwcGxlS2V5cGFpcnMgZnJvbSAncmlwcGxlLWtleXBhaXJzJztcbmltcG9ydCB7XG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIGNoZWNrS3JzUHJvdmlkZXIsXG4gIGdldEJpcDMyS2V5cyxcbiAgSW5pdGlhdGVSZWNvdmVyeU9wdGlvbnMgYXMgQmFzZUluaXRpYXRlUmVjb3ZlcnlPcHRpb25zLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBLZXlQYWlyLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIHByb21pc2VQcm9wcyxcbiAgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBhcyBCYXNlU2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbixcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVW5leHBlY3RlZEFkZHJlc3NFcnJvcixcbiAgVmVyaWZ5QWRkcmVzc09wdGlvbnMgYXMgQmFzZVZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcblxuY29uc3QgcmlwcGxlID0gcmVxdWlyZSgnLi9yaXBwbGUnKTtcblxuaW50ZXJmYWNlIEFkZHJlc3Mge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGRlc3RpbmF0aW9uVGFnPzogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgRmVlSW5mbyB7XG4gIGRhdGU6IHN0cmluZztcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIGJhc2VSZXNlcnZlOiBzdHJpbmc7XG4gIGJhc2VGZWU6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBCYXNlU2lnblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4UHJlYnVpbGQ6IFRyYW5zYWN0aW9uUHJlYnVpbGQ7XG4gIHBydjogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4Pzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgVmVyaWZ5QWRkcmVzc09wdGlvbnMgZXh0ZW5kcyBCYXNlVmVyaWZ5QWRkcmVzc09wdGlvbnMge1xuICByb290QWRkcmVzczogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUmVjb3ZlcnlJbmZvIGV4dGVuZHMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIHR4SGV4OiBzdHJpbmc7XG4gIGJhY2t1cEtleT86IHN0cmluZztcbiAgY29pbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbml0aWF0ZVJlY292ZXJ5T3B0aW9ucyBleHRlbmRzIEJhc2VJbml0aWF0ZVJlY292ZXJ5T3B0aW9ucyB7XG4gIGtyc1Byb3ZpZGVyPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJ5T3B0aW9ucyB7XG4gIGJhY2t1cEtleTogc3RyaW5nO1xuICB1c2VyS2V5OiBzdHJpbmc7XG4gIHJvb3RBZGRyZXNzOiBzdHJpbmc7XG4gIHJlY292ZXJ5RGVzdGluYXRpb246IHN0cmluZztcbiAgYml0Z29LZXk/OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZztcbiAga3JzUHJvdmlkZXI/OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBIYWxmU2lnbmVkVHJhbnNhY3Rpb24ge1xuICBoYWxmU2lnbmVkOiB7XG4gICAgdHhIZXg6IHN0cmluZztcbiAgfTtcbn1cblxuaW50ZXJmYWNlIFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMge1xuICByb290UHJpdmF0ZUtleT86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFhycCBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UpIHtcbiAgICBzdXBlcihiaXRnbyk7XG4gIH1cblxuICBzdGF0aWMgY3JlYXRlSW5zdGFuY2UoYml0Z286IEJpdEdvQmFzZSk6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IFhycChiaXRnbyk7XG4gIH1cblxuICAvKipcbiAgICogRmFjdG9yIGJldHdlZW4gdGhlIGNvaW4ncyBiYXNlIHVuaXQgYW5kIGl0cyBzbWFsbGVzdCBzdWJkaXZpc29uXG4gICAqL1xuICBwdWJsaWMgZ2V0QmFzZUZhY3RvcigpOiBudW1iZXIge1xuICAgIHJldHVybiAxZTY7XG4gIH1cblxuICAvKipcbiAgICogSWRlbnRpZmllciBmb3IgdGhlIGJsb2NrY2hhaW4gd2hpY2ggc3VwcG9ydHMgdGhpcyBjb2luXG4gICAqL1xuICBwdWJsaWMgZ2V0Q2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ3hycCc7XG4gIH1cblxuICAvKipcbiAgICogSWRlbnRpZmllciBmb3IgdGhlIGNvaW4gZmFtaWx5XG4gICAqL1xuICBwdWJsaWMgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICd4cnAnO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXBsZXRlIGh1bWFuLXJlYWRhYmxlIG5hbWUgb2YgdGhpcyBjb2luXG4gICAqL1xuICBwdWJsaWMgZ2V0RnVsbE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ1JpcHBsZSc7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgYW4gYWRkcmVzcyBzdHJpbmcgaW50byBhZGRyZXNzIGFuZCBkZXN0aW5hdGlvbiB0YWdcbiAgICovXG4gIHB1YmxpYyBnZXRBZGRyZXNzRGV0YWlscyhhZGRyZXNzOiBzdHJpbmcpOiBBZGRyZXNzIHtcbiAgICBjb25zdCBkZXN0aW5hdGlvbkRldGFpbHMgPSB1cmwucGFyc2UoYWRkcmVzcyk7XG4gICAgY29uc3QgZGVzdGluYXRpb25BZGRyZXNzID0gZGVzdGluYXRpb25EZXRhaWxzLnBhdGhuYW1lO1xuICAgIGlmICghZGVzdGluYXRpb25BZGRyZXNzIHx8ICFyaXBwbGVBZGRyZXNzQ29kZWMuaXNWYWxpZENsYXNzaWNBZGRyZXNzKGRlc3RpbmF0aW9uQWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBkZXN0aW5hdGlvbiBhZGRyZXNzIFwiJHtkZXN0aW5hdGlvbkFkZHJlc3N9XCIgaXMgbm90IHZhbGlkYCk7XG4gICAgfVxuICAgIC8vIHRoZXJlIGFyZSBubyBvdGhlciBwcm9wZXJ0aWVzIGxpa2UgZGVzdGluYXRpb24gdGFnc1xuICAgIGlmIChkZXN0aW5hdGlvbkRldGFpbHMucGF0aG5hbWUgPT09IGFkZHJlc3MpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IGFkZHJlc3MsXG4gICAgICAgIGRlc3RpbmF0aW9uVGFnOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICghZGVzdGluYXRpb25EZXRhaWxzLnF1ZXJ5KSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcignbm8gcXVlcnkgcGFyYW1zIHByZXNlbnQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeURldGFpbHMgPSBxdWVyeXN0cmluZy5wYXJzZShkZXN0aW5hdGlvbkRldGFpbHMucXVlcnkpO1xuICAgIGlmICghcXVlcnlEZXRhaWxzLmR0KSB7XG4gICAgICAvLyBpZiB0aGVyZSBhcmUgbW9yZSBwcm9wZXJ0aWVzLCB0aGUgcXVlcnkgZGV0YWlscyBuZWVkIHRvIGNvbnRhaW4gdGhlIGRlc3RpbmF0aW9uIHRhZyBwcm9wZXJ0eS5cbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKCdkZXN0aW5hdGlvbiB0YWcgbWlzc2luZycpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHF1ZXJ5RGV0YWlscy5kdCkpIHtcbiAgICAgIC8vIGlmIHF1ZXJ5RGV0YWlscy5kdCBpcyBhbiBhcnJheSwgdGhhdCBtZWFucyBkdCB3YXMgZ2l2ZW4gbXVsdGlwbGUgdGltZXMsIHdoaWNoIGlzIG5vdCB2YWxpZFxuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoXG4gICAgICAgIGBkZXN0aW5hdGlvbiB0YWcgY2FuIGFwcGVhciBhdCBtb3N0IG9uY2UsIGJ1dCAke3F1ZXJ5RGV0YWlscy5kdC5sZW5ndGh9IGRlc3RpbmF0aW9uIHRhZ3Mgd2VyZSBmb3VuZGBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFyc2VkVGFnID0gcGFyc2VJbnQocXVlcnlEZXRhaWxzLmR0LCAxMCk7XG4gICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihwYXJzZWRUYWcpKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcignaW52YWxpZCBkZXN0aW5hdGlvbiB0YWcnKTtcbiAgICB9XG5cbiAgICBpZiAocGFyc2VkVGFnID4gMHhmZmZmZmZmZiB8fCBwYXJzZWRUYWcgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcignZGVzdGluYXRpb24gdGFnIG91dCBvZiByYW5nZScpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhZGRyZXNzOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICBkZXN0aW5hdGlvblRhZzogcGFyc2VkVGFnLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IGEgZnVsbCwgbm9ybWFsaXplZCBhZGRyZXNzIGZyb20gYW4gYWRkcmVzcyBhbmQgZGVzdGluYXRpb24gdGFnXG4gICAqL1xuICBwdWJsaWMgbm9ybWFsaXplQWRkcmVzcyh7IGFkZHJlc3MsIGRlc3RpbmF0aW9uVGFnIH06IEFkZHJlc3MpOiBzdHJpbmcge1xuICAgIGlmICghXy5pc1N0cmluZyhhZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoJ2ludmFsaWQgYWRkcmVzcyBkZXRhaWxzJyk7XG4gICAgfVxuICAgIGlmIChfLmlzSW50ZWdlcihkZXN0aW5hdGlvblRhZykpIHtcbiAgICAgIHJldHVybiBgJHthZGRyZXNzfT9kdD0ke2Rlc3RpbmF0aW9uVGFnfWA7XG4gICAgfVxuICAgIHJldHVybiBhZGRyZXNzO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyB3aGV0aGVyIGFuIGFkZHJlc3Mgc3RyaW5nIGlzIHZhbGlkIGZvciB0aGlzIGNvaW5cbiAgICogQHBhcmFtIGFkZHJlc3NcbiAgICovXG4gIHB1YmxpYyBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWRkcmVzc0RldGFpbHMgPSB0aGlzLmdldEFkZHJlc3NEZXRhaWxzKGFkZHJlc3MpO1xuICAgICAgcmV0dXJuIGFkZHJlc3MgPT09IHRoaXMubm9ybWFsaXplQWRkcmVzcyhhZGRyZXNzRGV0YWlscyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwdWIgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIHB1YmxpYyBpc1ZhbGlkUHViKHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHB1YikuaXNOZXV0ZXJlZCgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGZlZSBpbmZvIGZyb20gc2VydmVyXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0RmVlSW5mbygpOiBQcm9taXNlPEZlZUluZm8+IHtcbiAgICByZXR1cm4gdGhpcy5iaXRnby5nZXQodGhpcy51cmwoJy9wdWJsaWMvZmVlaW5mbycpKS5yZXN1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NlbWJsZSBrZXljaGFpbiBhbmQgaGFsZi1zaWduIHByZWJ1aWx0IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogLSB0eFByZWJ1aWxkXG4gICAqIC0gcHJ2XG4gICAqIEByZXR1cm5zIEJsdWViaXJkPEhhbGZTaWduZWRUcmFuc2FjdGlvbj5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzaWduVHJhbnNhY3Rpb24oeyB0eFByZWJ1aWxkLCBwcnYgfTogU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8SGFsZlNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgaWYgKF8uaXNVbmRlZmluZWQodHhQcmVidWlsZCkgfHwgIV8uaXNPYmplY3QodHhQcmVidWlsZCkpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh0eFByZWJ1aWxkKSAmJiAhXy5pc09iamVjdCh0eFByZWJ1aWxkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHR4UHJlYnVpbGQgbXVzdCBiZSBhbiBvYmplY3QsIGdvdCB0eXBlICR7dHlwZW9mIHR4UHJlYnVpbGR9YCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdHhQcmVidWlsZCBwYXJhbWV0ZXInKTtcbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZChwcnYpIHx8ICFfLmlzU3RyaW5nKHBydikpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChwcnYpICYmICFfLmlzU3RyaW5nKHBydikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBwcnYgbXVzdCBiZSBhIHN0cmluZywgZ290IHR5cGUgJHt0eXBlb2YgcHJ2fWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHBydiBwYXJhbWV0ZXIgdG8gc2lnbiB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJLZXkgPSBiaXAzMi5mcm9tQmFzZTU4KHBydik7XG4gICAgY29uc3QgdXNlclByaXZhdGVLZXkgPSB1c2VyS2V5LnByaXZhdGVLZXk7XG4gICAgaWYgKCF1c2VyUHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBwcml2YXRlS2V5YCk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJBZGRyZXNzID0gcmlwcGxlS2V5cGFpcnMuZGVyaXZlQWRkcmVzcyh1c2VyS2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JykpO1xuXG4gICAgY29uc3QgcmlwcGxlTGliID0gcmlwcGxlKCk7XG4gICAgY29uc3QgaGFsZlNpZ25lZCA9IHJpcHBsZUxpYi5zaWduV2l0aFByaXZhdGVLZXkodHhQcmVidWlsZC50eEhleCwgdXNlclByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpLCB7XG4gICAgICBzaWduQXM6IHVzZXJBZGRyZXNzLFxuICAgIH0pO1xuICAgIHJldHVybiB7IGhhbGZTaWduZWQ6IHsgdHhIZXg6IGhhbGZTaWduZWQuc2lnbmVkVHJhbnNhY3Rpb24gfSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJpcHBsZSByZXF1aXJlcyBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgZm9yIHdhbGxldCBnZW5lcmF0aW9uIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlci4gVGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBhcmVcbiAgICogdGhlIHJvb3QgcHVibGljIGtleSwgd2hpY2ggaXMgdGhlIGJhc2lzIG9mIHRoZSByb290IGFkZHJlc3MsIHR3byBzaWduZWQsIGFuZCBvbmUgaGFsZi1zaWduZWQgaW5pdGlhbGl6YXRpb24gdHhzXG4gICAqIEBwYXJhbSB3YWxsZXRQYXJhbXNcbiAgICogLSByb290UHJpdmF0ZUtleTogb3B0aW9uYWwgaGV4LWVuY29kZWQgUmlwcGxlIHByaXZhdGUga2V5XG4gICAqL1xuICBhc3luYyBzdXBwbGVtZW50R2VuZXJhdGVXYWxsZXQoXG4gICAgd2FsbGV0UGFyYW1zOiBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zXG4gICk6IFByb21pc2U8U3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucz4ge1xuICAgIGlmICh3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkpIHtcbiAgICAgIGlmICh3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkubGVuZ3RoICE9PSA2NCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jvb3RQcml2YXRlS2V5IG5lZWRzIHRvIGJlIGEgaGV4YWRlY2ltYWwgcHJpdmF0ZSBrZXkgc3RyaW5nJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBFQ1BhaXIubWFrZVJhbmRvbSgpO1xuICAgICAgaWYgKCFrZXlQYWlyLnByaXZhdGVLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgICB9XG4gICAgICB3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkgPSBrZXlQYWlyLnByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cbiAgICByZXR1cm4gd2FsbGV0UGFyYW1zO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4vcGFyc2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxUcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgaWYgKCFwYXJhbXMudHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBwYXJhbSB0eEhleCcpO1xuICAgIH1cbiAgICBsZXQgdHJhbnNhY3Rpb247XG4gICAgbGV0IHR4SGV4O1xuICAgIHRyeSB7XG4gICAgICB0cmFuc2FjdGlvbiA9IHJpcHBsZUJpbmFyeUNvZGVjLmRlY29kZShwYXJhbXMudHhIZXgpO1xuICAgICAgdHhIZXggPSBwYXJhbXMudHhIZXg7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdHJhbnNhY3Rpb24gPSBKU09OLnBhcnNlKHBhcmFtcy50eEhleCk7XG4gICAgICAgIHR4SGV4ID0gcmlwcGxlQmluYXJ5Q29kZWMuZW5jb2RlKHRyYW5zYWN0aW9uKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0eEhleCBuZWVkcyB0byBiZSBlaXRoZXIgaGV4IG9yIEpTT04gc3RyaW5nIGZvciBYUlAnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaWQgPSBjb21wdXRlQmluYXJ5VHJhbnNhY3Rpb25IYXNoKHR4SGV4KTtcblxuICAgIGlmICh0cmFuc2FjdGlvbi5UcmFuc2FjdGlvblR5cGUgPT0gJ0FjY291bnRTZXQnKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFsnaWQnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZUFtb3VudCcsICdvdXRwdXRzJywgJ2NoYW5nZU91dHB1dHMnLCAnZmVlJywgJ2FjY291bnRTZXQnXSxcbiAgICAgICAgaWQ6IGlkLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAwLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6IDAsXG4gICAgICAgIG91dHB1dHM6IFtdLFxuICAgICAgICBmZWU6IHtcbiAgICAgICAgICBmZWU6IHRyYW5zYWN0aW9uLkZlZSxcbiAgICAgICAgICBmZWVSYXRlOiBudWxsLFxuICAgICAgICAgIHNpemU6IHR4SGV4Lmxlbmd0aCAvIDIsXG4gICAgICAgIH0sXG4gICAgICAgIGFjY291bnRTZXQ6IHtcbiAgICAgICAgICBtZXNzYWdlS2V5OiB0cmFuc2FjdGlvbi5NZXNzYWdlS2V5LFxuICAgICAgICB9LFxuICAgICAgfSBhcyBhbnk7XG4gICAgfVxuXG4gICAgY29uc3QgYWRkcmVzcyA9XG4gICAgICB0cmFuc2FjdGlvbi5EZXN0aW5hdGlvbiArICh0cmFuc2FjdGlvbi5EZXN0aW5hdGlvblRhZyA+PSAwID8gJz9kdD0nICsgdHJhbnNhY3Rpb24uRGVzdGluYXRpb25UYWcgOiAnJyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlQW1vdW50JywgJ291dHB1dHMnLCAnY2hhbmdlT3V0cHV0cycsICdmZWUnXSxcbiAgICAgIGlkOiBpZCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgb3V0cHV0QW1vdW50OiB0cmFuc2FjdGlvbi5BbW91bnQsXG4gICAgICBjaGFuZ2VBbW91bnQ6IDAsXG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogdHJhbnNhY3Rpb24uQW1vdW50LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGZlZToge1xuICAgICAgICBmZWU6IHRyYW5zYWN0aW9uLkZlZSxcbiAgICAgICAgZmVlUmF0ZTogbnVsbCxcbiAgICAgICAgc2l6ZTogdHhIZXgubGVuZ3RoIC8gMixcbiAgICAgIH0sXG4gICAgfSBhcyBhbnk7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHRoYXQgYSB0cmFuc2FjdGlvbiBwcmVidWlsZCBjb21wbGllcyB3aXRoIHRoZSBvcmlnaW5hbCBpbnRlbnRpb25cbiAgICogQHBhcmFtIHR4UGFyYW1zIHBhcmFtcyBvYmplY3QgcGFzc2VkIHRvIHNlbmRcbiAgICogQHBhcmFtIHR4UHJlYnVpbGQgcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHNlcnZlclxuICAgKiBAcGFyYW0gd2FsbGV0XG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgcHVibGljIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQgfTogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgZXhwbGFuYXRpb24gPSBhd2FpdCB0aGlzLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEhleDogdHhQcmVidWlsZC50eEhleCxcbiAgICB9KTtcblxuICAgIGNvbnN0IG91dHB1dCA9IFsuLi5leHBsYW5hdGlvbi5vdXRwdXRzLCAuLi5leHBsYW5hdGlvbi5jaGFuZ2VPdXRwdXRzXVswXTtcbiAgICBjb25zdCBleHBlY3RlZE91dHB1dCA9IHR4UGFyYW1zLnJlY2lwaWVudHMgJiYgdHhQYXJhbXMucmVjaXBpZW50c1swXTtcblxuICAgIGNvbnN0IGNvbXBhcmF0b3IgPSAocmVjaXBpZW50MSwgcmVjaXBpZW50MikgPT4ge1xuICAgICAgaWYgKHJlY2lwaWVudDEuYWRkcmVzcyAhPT0gcmVjaXBpZW50Mi5hZGRyZXNzKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFtb3VudDEgPSBuZXcgQmlnTnVtYmVyKHJlY2lwaWVudDEuYW1vdW50KTtcbiAgICAgIGNvbnN0IGFtb3VudDIgPSBuZXcgQmlnTnVtYmVyKHJlY2lwaWVudDIuYW1vdW50KTtcbiAgICAgIHJldHVybiBhbW91bnQxLnRvRml4ZWQoKSA9PT0gYW1vdW50Mi50b0ZpeGVkKCk7XG4gICAgfTtcblxuICAgIGlmICghY29tcGFyYXRvcihvdXRwdXQsIGV4cGVjdGVkT3V0cHV0KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0cmFuc2FjdGlvbiBwcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBleHBlY3RlZCBvdXRwdXQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhZGRyZXNzIGlzIGEgdmFsaWQgWFJQIGFkZHJlc3MsIGFuZCB0aGVuIG1ha2Ugc3VyZSB0aGUgcm9vdCBhZGRyZXNzZXMgbWF0Y2guXG4gICAqIFRoaXMgcHJldmVudHMgYXR0YWNrcyB3aGVyZSBhbiBhdHRhY2sgbWF5IHN3aXRjaCBvdXQgdGhlIG5ldyBhZGRyZXNzIGZvciBvbmUgb2YgdGhlaXIgb3duXG4gICAqIEBwYXJhbSBhZGRyZXNzIHtTdHJpbmd9IHRoZSBhZGRyZXNzIHRvIHZlcmlmeVxuICAgKiBAcGFyYW0gcm9vdEFkZHJlc3Mge1N0cmluZ30gdGhlIHdhbGxldCdzIHJvb3QgYWRkcmVzc1xuICAgKiBAcmV0dXJuIHRydWUgaWZmIGFkZHJlc3MgaXMgYSB3YWxsZXQgYWRkcmVzcyAoYmFzZWQgb24gcm9vdEFkZHJlc3MpXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgaXNXYWxsZXRBZGRyZXNzKHsgYWRkcmVzcywgcm9vdEFkZHJlc3MgfTogVmVyaWZ5QWRkcmVzc09wdGlvbnMpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBhZGRyZXNzIHZlcmlmaWNhdGlvbiBmYWlsdXJlOiBhZGRyZXNzIFwiJHthZGRyZXNzfVwiIGlzIG5vdCB2YWxpZGApO1xuICAgIH1cblxuICAgIGNvbnN0IGFkZHJlc3NEZXRhaWxzID0gdGhpcy5nZXRBZGRyZXNzRGV0YWlscyhhZGRyZXNzKTtcbiAgICBjb25zdCByb290QWRkcmVzc0RldGFpbHMgPSB0aGlzLmdldEFkZHJlc3NEZXRhaWxzKHJvb3RBZGRyZXNzKTtcblxuICAgIGlmIChhZGRyZXNzRGV0YWlscy5hZGRyZXNzICE9PSByb290QWRkcmVzc0RldGFpbHMuYWRkcmVzcykge1xuICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IoXG4gICAgICAgIGBhZGRyZXNzIHZhbGlkYXRpb24gZmFpbHVyZTogJHthZGRyZXNzRGV0YWlscy5hZGRyZXNzfSB2cy4gJHtyb290QWRkcmVzc0RldGFpbHMuYWRkcmVzc31gXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFVSTCBvZiBhIHdlbGwta25vd24sIHB1YmxpYyBmYWNpbmcgKG5vbi1iaXRnbykgcmlwcGxlZCBpbnN0YW5jZSB3aGljaCBjYW4gYmUgdXNlZCBmb3IgcmVjb3ZlcnlcbiAgICovXG4gIHB1YmxpYyBnZXRSaXBwbGVkVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdodHRwczovL3MxLnJpcHBsZS5jb206NTEyMzQnO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R29cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiAtIHJvb3RBZGRyZXNzOiByb290IFhSUCB3YWxsZXQgYWRkcmVzcyB0byByZWNvdmVyIGZ1bmRzIGZyb21cbiAgICogLSB1c2VyS2V5OiBbZW5jcnlwdGVkXSB4cHJ2XG4gICAqIC0gYmFja3VwS2V5OiBbZW5jcnlwdGVkXSB4cHJ2LCBvciB4cHViIGlmIHRoZSB4cHJ2IGlzIGhlbGQgYnkgYSBLUlMgcHJvdmlkZXJcbiAgICogLSB3YWxsZXRQYXNzcGhyYXNlOiBuZWNlc3NhcnkgaWYgb25lIG9mIHRoZSB4cHJ2cyBpcyBlbmNyeXB0ZWRcbiAgICogLSBiaXRnb0tleTogeHB1YlxuICAgKiAtIGtyc1Byb3ZpZGVyOiBuZWNlc3NhcnkgaWYgYmFja3VwIGtleSBpcyBoZWxkIGJ5IEtSU1xuICAgKiAtIHJlY292ZXJ5RGVzdGluYXRpb246IHRhcmdldCBhZGRyZXNzIHRvIHNlbmQgcmVjb3ZlcmVkIGZ1bmRzIHRvXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgcmVjb3ZlcihwYXJhbXM6IFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8UmVjb3ZlcnlJbmZvIHwgc3RyaW5nPiB7XG4gICAgY29uc3QgcmlwcGxlZFVybCA9IHRoaXMuZ2V0UmlwcGxlZFVybCgpO1xuICAgIGNvbnN0IGlzS3JzUmVjb3ZlcnkgPSBwYXJhbXMuYmFja3VwS2V5LnN0YXJ0c1dpdGgoJ3hwdWInKSAmJiAhcGFyYW1zLnVzZXJLZXkuc3RhcnRzV2l0aCgneHB1YicpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IHBhcmFtcy5iYWNrdXBLZXkuc3RhcnRzV2l0aCgneHB1YicpICYmIHBhcmFtcy51c2VyS2V5LnN0YXJ0c1dpdGgoJ3hwdWInKTtcblxuICAgIGNvbnN0IGFjY291bnRJbmZvUGFyYW1zID0ge1xuICAgICAgbWV0aG9kOiAnYWNjb3VudF9pbmZvJyxcbiAgICAgIHBhcmFtczogW1xuICAgICAgICB7XG4gICAgICAgICAgYWNjb3VudDogcGFyYW1zLnJvb3RBZGRyZXNzLFxuICAgICAgICAgIHN0cmljdDogdHJ1ZSxcbiAgICAgICAgICBsZWRnZXJfaW5kZXg6ICdjdXJyZW50JyxcbiAgICAgICAgICBxdWV1ZTogdHJ1ZSxcbiAgICAgICAgICBzaWduZXJfbGlzdHM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBpZiAoaXNLcnNSZWNvdmVyeSkge1xuICAgICAgY2hlY2tLcnNQcm92aWRlcih0aGlzLCBwYXJhbXMua3JzUHJvdmlkZXIpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5cyA9IGdldEJpcDMyS2V5cyh0aGlzLmJpdGdvLCBwYXJhbXMsIHsgcmVxdWlyZUJpdEdvWHB1YjogZmFsc2UgfSk7XG5cbiAgICBjb25zdCB7IGFkZHJlc3NEZXRhaWxzLCBmZWVEZXRhaWxzLCBzZXJ2ZXJEZXRhaWxzIH0gPSBhd2FpdCBwcm9taXNlUHJvcHMoe1xuICAgICAgYWRkcmVzc0RldGFpbHM6IHRoaXMuYml0Z28ucG9zdChyaXBwbGVkVXJsKS5zZW5kKGFjY291bnRJbmZvUGFyYW1zKSxcbiAgICAgIGZlZURldGFpbHM6IHRoaXMuYml0Z28ucG9zdChyaXBwbGVkVXJsKS5zZW5kKHsgbWV0aG9kOiAnZmVlJyB9KSxcbiAgICAgIHNlcnZlckRldGFpbHM6IHRoaXMuYml0Z28ucG9zdChyaXBwbGVkVXJsKS5zZW5kKHsgbWV0aG9kOiAnc2VydmVyX2luZm8nIH0pLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgb3BlbkxlZGdlckZlZSA9IG5ldyBCaWdOdW1iZXIoZmVlRGV0YWlscy5ib2R5LnJlc3VsdC5kcm9wcy5vcGVuX2xlZGdlcl9mZWUpO1xuICAgIGNvbnN0IGJhc2VSZXNlcnZlID0gbmV3IEJpZ051bWJlcihzZXJ2ZXJEZXRhaWxzLmJvZHkucmVzdWx0LmluZm8udmFsaWRhdGVkX2xlZGdlci5yZXNlcnZlX2Jhc2VfeHJwKS50aW1lcyhcbiAgICAgIHRoaXMuZ2V0QmFzZUZhY3RvcigpXG4gICAgKTtcbiAgICBjb25zdCByZXNlcnZlRGVsdGEgPSBuZXcgQmlnTnVtYmVyKHNlcnZlckRldGFpbHMuYm9keS5yZXN1bHQuaW5mby52YWxpZGF0ZWRfbGVkZ2VyLnJlc2VydmVfaW5jX3hycCkudGltZXMoXG4gICAgICB0aGlzLmdldEJhc2VGYWN0b3IoKVxuICAgICk7XG4gICAgY29uc3QgY3VycmVudExlZGdlciA9IHNlcnZlckRldGFpbHMuYm9keS5yZXN1bHQuaW5mby52YWxpZGF0ZWRfbGVkZ2VyLnNlcTtcbiAgICBjb25zdCBzZXF1ZW5jZUlkID0gYWRkcmVzc0RldGFpbHMuYm9keS5yZXN1bHQuYWNjb3VudF9kYXRhLlNlcXVlbmNlO1xuICAgIGNvbnN0IGJhbGFuY2UgPSBuZXcgQmlnTnVtYmVyKGFkZHJlc3NEZXRhaWxzLmJvZHkucmVzdWx0LmFjY291bnRfZGF0YS5CYWxhbmNlKTtcbiAgICBjb25zdCBzaWduZXJMaXN0cyA9IGFkZHJlc3NEZXRhaWxzLmJvZHkucmVzdWx0LmFjY291bnRfZGF0YS5zaWduZXJfbGlzdHM7XG4gICAgY29uc3QgYWNjb3VudEZsYWdzID0gYWRkcmVzc0RldGFpbHMuYm9keS5yZXN1bHQuYWNjb3VudF9kYXRhLkZsYWdzO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZXJlIGlzIG9ubHkgb25lIHNpZ25lciBsaXN0IHNldFxuICAgIGlmIChzaWduZXJMaXN0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBzZXQgb2Ygc2lnbmVyIGxpc3RzJyk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBzaWduZXJzIGFyZSB1c2VyLCBiYWNrdXAsIGJpdGdvXG4gICAgY29uc3QgdXNlckFkZHJlc3MgPSByaXBwbGVLZXlwYWlycy5kZXJpdmVBZGRyZXNzKGtleXNbMF0ucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgY29uc3QgYmFja3VwQWRkcmVzcyA9IHJpcHBsZUtleXBhaXJzLmRlcml2ZUFkZHJlc3Moa2V5c1sxXS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgIGNvbnN0IHNpZ25lckxpc3QgPSBzaWduZXJMaXN0c1swXTtcbiAgICBpZiAoc2lnbmVyTGlzdC5TaWduZXJRdW9ydW0gIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBtaW5pbXVtIHNpZ25hdHVyZSBjb3VudCcpO1xuICAgIH1cbiAgICBjb25zdCBmb3VuZEFkZHJlc3NlcyA9IHt9O1xuXG4gICAgY29uc3Qgc2lnbmVyRW50cmllcyA9IHNpZ25lckxpc3QuU2lnbmVyRW50cmllcztcbiAgICBpZiAoc2lnbmVyRW50cmllcy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWduZXIgbGlzdCBsZW5ndGgnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCB7IFNpZ25lckVudHJ5IH0gb2Ygc2lnbmVyRW50cmllcykge1xuICAgICAgY29uc3Qgd2VpZ2h0ID0gU2lnbmVyRW50cnkuU2lnbmVyV2VpZ2h0O1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFNpZ25lckVudHJ5LkFjY291bnQ7XG4gICAgICBpZiAod2VpZ2h0ICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWduZXIgd2VpZ2h0Jyk7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIGl0J3MgYSBkdXBlIG9mIGFuIGFkZHJlc3Mgd2UgYWxyZWFkeSBrbm93LCBibG9ja1xuICAgICAgaWYgKGZvdW5kQWRkcmVzc2VzW2FkZHJlc3NdID49IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkdXBsaWNhdGUgc2lnbmVyIGFkZHJlc3MnKTtcbiAgICAgIH1cbiAgICAgIGZvdW5kQWRkcmVzc2VzW2FkZHJlc3NdID0gKGZvdW5kQWRkcmVzc2VzW2FkZHJlc3NdIHx8IDApICsgMTtcbiAgICB9XG5cbiAgICBpZiAoZm91bmRBZGRyZXNzZXNbdXNlckFkZHJlc3NdICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuZXhwZWN0ZWQgaW5jaWRlbmNlIGZyZXF1ZW5jeSBvZiB1c2VyIHNpZ25lciBhZGRyZXNzJyk7XG4gICAgfVxuICAgIGlmIChmb3VuZEFkZHJlc3Nlc1tiYWNrdXBBZGRyZXNzXSAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmV4cGVjdGVkIGluY2lkZW5jZSBmcmVxdWVuY3kgb2YgdXNlciBzaWduZXIgYWRkcmVzcycpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgZmxhZ3MgZGlzYWJsZSB0aGUgbWFzdGVyIGtleSBhbmQgZW5mb3JjZSBkZXN0aW5hdGlvbiB0YWdzXG4gICAgY29uc3QgVVNFUl9LRVlfU0VUVElOR19GTEFHID0gNjU1MzY7XG4gICAgY29uc3QgTUFTVEVSX0tFWV9ERUFDVElWQVRJT05fRkxBRyA9IDEwNDg1NzY7XG4gICAgY29uc3QgUkVRVUlSRV9ERVNUSU5BVElPTl9UQUdfRkxBRyA9IDEzMTA3MjtcbiAgICBpZiAoKGFjY291bnRGbGFncyAmIFVTRVJfS0VZX1NFVFRJTkdfRkxBRykgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYSBjdXN0b20gdXNlciBrZXkgaGFzIGJlZW4gc2V0Jyk7XG4gICAgfVxuICAgIGlmICgoYWNjb3VudEZsYWdzICYgTUFTVEVSX0tFWV9ERUFDVElWQVRJT05fRkxBRykgIT09IE1BU1RFUl9LRVlfREVBQ1RJVkFUSU9OX0ZMQUcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIG1hc3RlciBrZXkgaGFzIG5vdCBiZWVuIGRlYWN0aXZhdGVkJyk7XG4gICAgfVxuICAgIGlmICgoYWNjb3VudEZsYWdzICYgUkVRVUlSRV9ERVNUSU5BVElPTl9UQUdfRkxBRykgIT09IFJFUVVJUkVfREVTVElOQVRJT05fVEFHX0ZMQUcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIGRlc3RpbmF0aW9uIGZsYWcgcmVxdWlyZW1lbnQgaGFzIG5vdCBiZWVuIGFjdGl2YXRlZCcpO1xuICAgIH1cblxuICAgIC8vIHJlY292ZXIgdGhlIGZ1bmRzXG4gICAgY29uc3QgcmVzZXJ2ZSA9IGJhc2VSZXNlcnZlLnBsdXMocmVzZXJ2ZURlbHRhLnRpbWVzKDUpKTtcbiAgICBjb25zdCByZWNvdmVyYWJsZUJhbGFuY2UgPSBiYWxhbmNlLm1pbnVzKHJlc2VydmUpO1xuXG4gICAgY29uc3QgcmF3RGVzdGluYXRpb24gPSBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbjtcbiAgICBjb25zdCBkZXN0aW5hdGlvbkRldGFpbHMgPSB1cmwucGFyc2UocmF3RGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9IGRlc3RpbmF0aW9uRGV0YWlscy5wYXRobmFtZTtcblxuICAgIC8vIHBhcnNlIGRlc3RpbmF0aW9uIHRhZyBmcm9tIHF1ZXJ5XG4gICAgbGV0IGRlc3RpbmF0aW9uVGFnOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgaWYgKGRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSkge1xuICAgICAgY29uc3QgcXVlcnlEZXRhaWxzID0gcXVlcnlzdHJpbmcucGFyc2UoZGVzdGluYXRpb25EZXRhaWxzLnF1ZXJ5KTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHF1ZXJ5RGV0YWlscy5kdCkpIHtcbiAgICAgICAgLy8gaWYgcXVlcnlEZXRhaWxzLmR0IGlzIGFuIGFycmF5LCB0aGF0IG1lYW5zIGR0IHdhcyBnaXZlbiBtdWx0aXBsZSB0aW1lcywgd2hpY2ggaXMgbm90IHZhbGlkXG4gICAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKFxuICAgICAgICAgIGBkZXN0aW5hdGlvbiB0YWcgY2FuIGFwcGVhciBhdCBtb3N0IG9uY2UsIGJ1dCAke3F1ZXJ5RGV0YWlscy5kdC5sZW5ndGh9IGRlc3RpbmF0aW9uIHRhZ3Mgd2VyZSBmb3VuZGBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyc2VkVGFnID0gcGFyc2VJbnQocXVlcnlEZXRhaWxzLmR0IGFzIHN0cmluZywgMTApO1xuICAgICAgaWYgKE51bWJlci5pc0ludGVnZXIocGFyc2VkVGFnKSkge1xuICAgICAgICBkZXN0aW5hdGlvblRhZyA9IHBhcnNlZFRhZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHtcbiAgICAgIFRyYW5zYWN0aW9uVHlwZTogJ1BheW1lbnQnLFxuICAgICAgQWNjb3VudDogcGFyYW1zLnJvb3RBZGRyZXNzLCAvLyBzb3VyY2UgYWRkcmVzc1xuICAgICAgRGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgIERlc3RpbmF0aW9uVGFnOiBkZXN0aW5hdGlvblRhZyxcbiAgICAgIEFtb3VudDogcmVjb3ZlcmFibGVCYWxhbmNlLnRvRml4ZWQoMCksXG4gICAgICBGbGFnczogMjE0NzQ4MzY0OCxcbiAgICAgIExhc3RMZWRnZXJTZXF1ZW5jZTogY3VycmVudExlZGdlciArIDEwMDAwMDAsIC8vIGdpdmUgaXQgMSBtaWxsaW9uIGxlZGdlcnMnIHRpbWUgKH4xIG1vbnRoLCBzdWl0YWJsZSBmb3IgS1JTKVxuICAgICAgRmVlOiBvcGVuTGVkZ2VyRmVlLnRpbWVzKDMpLnRvRml4ZWQoMCksIC8vIHRoZSBmYWN0b3IgdGhyZWUgaXMgZm9yIHRoZSBtdWx0aXNpZ25pbmdcbiAgICAgIFNlcXVlbmNlOiBzZXF1ZW5jZUlkLFxuICAgIH07XG4gICAgY29uc3QgdHhKU09OOiBzdHJpbmcgPSBKU09OLnN0cmluZ2lmeSh0cmFuc2FjdGlvbik7XG5cbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4gdHhKU09OO1xuICAgIH1cbiAgICBjb25zdCByaXBwbGVMaWIgPSByaXBwbGUoKTtcbiAgICBpZiAoIWtleXNbMF0ucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1c2VyS2V5IGlzIG5vdCBhIHByaXZhdGUga2V5YCk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJLZXkgPSBrZXlzWzBdLnByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJTaWduYXR1cmUgPSByaXBwbGVMaWIuc2lnbldpdGhQcml2YXRlS2V5KHR4SlNPTiwgdXNlcktleSwgeyBzaWduQXM6IHVzZXJBZGRyZXNzIH0pO1xuXG4gICAgbGV0IHNpZ25lZFRyYW5zYWN0aW9uO1xuXG4gICAgaWYgKGlzS3JzUmVjb3ZlcnkpIHtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gdXNlclNpZ25hdHVyZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFrZXlzWzFdLnByaXZhdGVLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBiYWNrdXBLZXkgaXMgbm90IGEgcHJpdmF0ZSBrZXlgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJhY2t1cEtleSA9IGtleXNbMV0ucHJpdmF0ZUtleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBiYWNrdXBTaWduYXR1cmUgPSByaXBwbGVMaWIuc2lnbldpdGhQcml2YXRlS2V5KHR4SlNPTiwgYmFja3VwS2V5LCB7IHNpZ25BczogYmFja3VwQWRkcmVzcyB9KTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gcmlwcGxlTGliLmNvbWJpbmUoW3VzZXJTaWduYXR1cmUuc2lnbmVkVHJhbnNhY3Rpb24sIGJhY2t1cFNpZ25hdHVyZS5zaWduZWRUcmFuc2FjdGlvbl0pO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYW5zYWN0aW9uRXhwbGFuYXRpb246IFJlY292ZXJ5SW5mbyA9IChhd2FpdCB0aGlzLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEhleDogc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmVkVHJhbnNhY3Rpb24sXG4gICAgfSkpIGFzIGFueTtcbiAgICB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uLnR4SGV4ID0gc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmVkVHJhbnNhY3Rpb247XG5cbiAgICBpZiAoaXNLcnNSZWNvdmVyeSkge1xuICAgICAgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbi5iYWNrdXBLZXkgPSBwYXJhbXMuYmFja3VwS2V5O1xuICAgICAgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbi5jb2luID0gdGhpcy5nZXRDaGFpbigpO1xuICAgIH1cbiAgICByZXR1cm4gdHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgfVxuXG4gIGluaXRpYXRlUmVjb3ZlcnkocGFyYW1zOiBJbml0aWF0ZVJlY292ZXJ5T3B0aW9ucyk6IG5ldmVyIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlcHJlY2F0ZWQgbWV0aG9kJyk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSBuZXcga2V5cGFpciBmb3IgdGhpcyBjb2luLlxuICAgKiBAcGFyYW0gc2VlZCBTZWVkIGZyb20gd2hpY2ggdGhlIG5ldyBrZXlwYWlyIHNob3VsZCBiZSBnZW5lcmF0ZWQsIG90aGVyd2lzZSBhIHJhbmRvbSBzZWVkIGlzIHVzZWRcbiAgICovXG4gIHB1YmxpYyBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTZcbiAgICAgIC8vIGJpdCBjaGFpbiBjb2RlLCBib3RoIG9mIHdoaWNoIG11c3QgYmUgcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlXG4gICAgICAvLyBtYXhpbXVtIGVudHJvcHkgYW5kIGdpdmVzIHVzIG1heGltdW0gc2VjdXJpdHkgYWdhaW5zdCBjcmFja2luZy5cbiAgICAgIHNlZWQgPSByYW5kb21CeXRlcyg1MTIgLyA4KTtcbiAgICB9XG4gICAgY29uc3QgZXh0ZW5kZWRLZXkgPSBiaXAzMi5mcm9tU2VlZChzZWVkKTtcbiAgICBjb25zdCB4cHViID0gZXh0ZW5kZWRLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IHhwdWIsXG4gICAgICBwcnY6IGV4dGVuZGVkS2V5LnRvQmFzZTU4KCksXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cbiJdfQ==
618
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHJwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3hycC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztHQUVHO0FBQ0gsK0NBQXlDO0FBQ3pDLDBDQUE0QjtBQUM1Qix5REFBMkM7QUFDM0MseUNBQTJCO0FBRTNCLG1EQWE4QjtBQUM5QixpREFBa0Y7QUFDbEYsdUVBQXlEO0FBQ3pELGdFQUFrRDtBQUNsRCwyQ0FBNkI7QUFjN0IsMkNBQXNEO0FBQ3RELHdEQUFnQztBQUNoQyxzREFBOEI7QUFDOUIsK0JBQXlGO0FBRXpGLE1BQWEsR0FBSSxTQUFRLG1CQUFRO0lBRS9CLFlBQXNCLEtBQWdCLEVBQUUsV0FBdUM7UUFDN0UsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2IsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7U0FDdkU7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQixFQUFFLFdBQXVDO1FBQzdFLE9BQU8sSUFBSSxHQUFHLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7T0FFRztJQUNJLGFBQWE7UUFDbEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFRDs7T0FFRztJQUNJLFFBQVE7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNJLFNBQVM7UUFDZCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVc7UUFDaEIsT0FB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Q0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksaUJBQVUsRUFBRSxDQUFDO1FBQ25FLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztTQUNuRDtRQUNELE9BQU87WUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZCxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUk7U0FDZixDQUFDO0lBQ0osQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUErQjtRQUNwRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7Q0FDRjtBQXJwQkQsa0JBcXBCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cbmltcG9ydCB7IEJpZ051bWJlciB9IGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgKiBhcyB1cmwgZnJvbSAndXJsJztcblxuaW1wb3J0IHtcbiAgQmFzZUNvaW4sXG4gIEJpdEdvQmFzZSxcbiAgY2hlY2tLcnNQcm92aWRlcixcbiAgZ2V0QmlwMzJLZXlzLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBLZXlQYWlyLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIHByb21pc2VQcm9wcyxcbiAgVG9rZW5FbmFibGVtZW50Q29uZmlnLFxuICBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEJhc2VDb2luIGFzIFN0YXRpY3NCYXNlQ29pbiwgY29pbnMsIFhycENvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCAqIGFzIHJpcHBsZUJpbmFyeUNvZGVjIGZyb20gJ3JpcHBsZS1iaW5hcnktY29kZWMnO1xuaW1wb3J0ICogYXMgcmlwcGxlS2V5cGFpcnMgZnJvbSAncmlwcGxlLWtleXBhaXJzJztcbmltcG9ydCAqIGFzIHhycGwgZnJvbSAneHJwbCc7XG5cbmltcG9ydCB7XG4gIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIEZlZUluZm8sXG4gIEhhbGZTaWduZWRUcmFuc2FjdGlvbixcbiAgUmVjb3ZlcnlJbmZvLFxuICBSZWNvdmVyeU9wdGlvbnMsXG4gIFJlY292ZXJ5VHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFN1cHBsZW1lbnRHZW5lcmF0ZVdhbGxldE9wdGlvbnMsXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zLFxufSBmcm9tICcuL2xpYi9pZmFjZSc7XG5pbXBvcnQgeyBLZXlQYWlyIGFzIFhycEtleVBhaXIgfSBmcm9tICcuL2xpYi9rZXlQYWlyJztcbmltcG9ydCB1dGlscyBmcm9tICcuL2xpYi91dGlscyc7XG5pbXBvcnQgcmlwcGxlIGZyb20gJy4vcmlwcGxlJztcbmltcG9ydCB7IFRva2VuVHJhbnNmZXJCdWlsZGVyLCBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5LCBUcmFuc2ZlckJ1aWxkZXIgfSBmcm9tICcuL2xpYic7XG5cbmV4cG9ydCBjbGFzcyBYcnAgZXh0ZW5kcyBCYXNlQ29pbiB7XG4gIHByb3RlY3RlZCBfc3RhdGljc0NvaW46IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj47XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG4gICAgaWYgKCFzdGF0aWNzQ29pbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIGNvbnN0cnVjdG9yIHBhcmFtZXRlciBzdGF0aWNzQ29pbicpO1xuICAgIH1cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPik6IEJhc2VDb2luIHtcbiAgICByZXR1cm4gbmV3IFhycChiaXRnbywgc3RhdGljc0NvaW4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZhY3RvciBiZXR3ZWVuIHRoZSBjb2luJ3MgYmFzZSB1bml0IGFuZCBpdHMgc21hbGxlc3Qgc3ViZGl2aXNvblxuICAgKi9cbiAgcHVibGljIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5wb3coMTAsIHRoaXMuX3N0YXRpY3NDb2luLmRlY2ltYWxQbGFjZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIElkZW50aWZpZXIgZm9yIHRoZSBibG9ja2NoYWluIHdoaWNoIHN1cHBvcnRzIHRoaXMgY29pblxuICAgKi9cbiAgcHVibGljIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICAvKipcbiAgICogSWRlbnRpZmllciBmb3IgdGhlIGNvaW4gZmFtaWx5XG4gICAqL1xuICBwdWJsaWMgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZhbWlseTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wbGV0ZSBodW1hbi1yZWFkYWJsZSBuYW1lIG9mIHRoaXMgY29pblxuICAgKi9cbiAgcHVibGljIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZ1bGxOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlcyB3aGV0aGVyIGFuIGFkZHJlc3Mgc3RyaW5nIGlzIHZhbGlkIGZvciB0aGlzIGNvaW5cbiAgICogQHBhcmFtIGFkZHJlc3NcbiAgICovXG4gIHB1YmxpYyBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHB1YmxpYyBrZXkgZm9yIHRoZSBjb2luLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHViIHRoZSBwdWIgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBwdWJsaWMgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGZlZSBpbmZvIGZyb20gc2VydmVyXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0RmVlSW5mbygpOiBQcm9taXNlPEZlZUluZm8+IHtcbiAgICByZXR1cm4gdGhpcy5iaXRnby5nZXQodGhpcy51cmwoJy9wdWJsaWMvZmVlaW5mbycpKS5yZXN1bHQoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUb2tlbkVuYWJsZW1lbnRDb25maWcoKTogVG9rZW5FbmFibGVtZW50Q29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVxdWlyZXNUb2tlbkVuYWJsZW1lbnQ6IHRydWUsXG4gICAgICBzdXBwb3J0c011bHRpcGxlVG9rZW5FbmFibGVtZW50czogZmFsc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NlbWJsZSBrZXljaGFpbiBhbmQgaGFsZi1zaWduIHByZWJ1aWx0IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogLSB0eFByZWJ1aWxkXG4gICAqIC0gcHJ2XG4gICAqIEByZXR1cm5zIEJsdWViaXJkPEhhbGZTaWduZWRUcmFuc2FjdGlvbj5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBzaWduVHJhbnNhY3Rpb24oe1xuICAgIHR4UHJlYnVpbGQsXG4gICAgcHJ2LFxuICAgIGlzTGFzdFNpZ25hdHVyZSxcbiAgfTogU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8SGFsZlNpZ25lZFRyYW5zYWN0aW9uIHwgUmVjb3ZlcnlUcmFuc2FjdGlvbj4ge1xuICAgIGlmIChfLmlzVW5kZWZpbmVkKHR4UHJlYnVpbGQpIHx8ICFfLmlzT2JqZWN0KHR4UHJlYnVpbGQpKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQodHhQcmVidWlsZCkgJiYgIV8uaXNPYmplY3QodHhQcmVidWlsZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0eFByZWJ1aWxkIG11c3QgYmUgYW4gb2JqZWN0LCBnb3QgdHlwZSAke3R5cGVvZiB0eFByZWJ1aWxkfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UHJlYnVpbGQgcGFyYW1ldGVyJyk7XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQocHJ2KSB8fCAhXy5pc1N0cmluZyhwcnYpKSB7XG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQocHJ2KSAmJiAhXy5pc1N0cmluZyhwcnYpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgcHJ2IG11c3QgYmUgYSBzdHJpbmcsIGdvdCB0eXBlICR7dHlwZW9mIHBydn1gKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBwcnYgcGFyYW1ldGVyIHRvIHNpZ24gdHJhbnNhY3Rpb24nKTtcbiAgICB9XG5cbiAgICBpZiAoIXR4UHJlYnVpbGQudHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyB0eEhleCBpbiB0eFByZWJ1aWxkYCk7XG4gICAgfVxuICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgWHJwS2V5UGFpcih7IHBydiB9KTtcbiAgICBjb25zdCBhZGRyZXNzID0ga2V5UGFpci5nZXRBZGRyZXNzKCk7XG4gICAgY29uc3QgcHJpdmF0ZUtleSA9IChrZXlQYWlyLmdldFByaXZhdGVLZXkoKSBhcyBCdWZmZXIpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgIGNvbnN0IHR4ID0gcmlwcGxlLnNpZ25XaXRoUHJpdmF0ZUtleSh0eFByZWJ1aWxkLnR4SGV4LCBwcml2YXRlS2V5LCB7XG4gICAgICBzaWduQXM6IGFkZHJlc3MsXG4gICAgfSk7XG5cbiAgICAvLyBOb3JtYWxseSB0aGUgU0RLIHByb3ZpZGVzIHRoZSBmaXJzdCBzaWduYXR1cmUgZm9yIGFuIFhSUCB0eCwgYnV0IG9jY2FzaW9uYWxseSBpdCBwcm92aWRlcyB0aGUgZmluYWwgb25lIGFzIHdlbGxcbiAgICAvLyAocmVjb3ZlcmllcylcbiAgICBpZiAoaXNMYXN0U2lnbmF0dXJlKSB7XG4gICAgICByZXR1cm4geyB0eEhleDogdHguc2lnbmVkVHJhbnNhY3Rpb24gfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgaGFsZlNpZ25lZDogeyB0eEhleDogdHguc2lnbmVkVHJhbnNhY3Rpb24gfSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJpcHBsZSByZXF1aXJlcyBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgZm9yIHdhbGxldCBnZW5lcmF0aW9uIHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlci4gVGhlIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBhcmVcbiAgICogdGhlIHJvb3QgcHVibGljIGtleSwgd2hpY2ggaXMgdGhlIGJhc2lzIG9mIHRoZSByb290IGFkZHJlc3MsIHR3byBzaWduZWQsIGFuZCBvbmUgaGFsZi1zaWduZWQgaW5pdGlhbGl6YXRpb24gdHhzXG4gICAqIEBwYXJhbSB3YWxsZXRQYXJhbXNcbiAgICogLSByb290UHJpdmF0ZUtleTogb3B0aW9uYWwgaGV4LWVuY29kZWQgUmlwcGxlIHByaXZhdGUga2V5XG4gICAqL1xuICBhc3luYyBzdXBwbGVtZW50R2VuZXJhdGVXYWxsZXQoXG4gICAgd2FsbGV0UGFyYW1zOiBTdXBwbGVtZW50R2VuZXJhdGVXYWxsZXRPcHRpb25zXG4gICk6IFByb21pc2U8U3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0T3B0aW9ucz4ge1xuICAgIGlmICh3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkpIHtcbiAgICAgIGlmICh3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkubGVuZ3RoICE9PSA2NCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jvb3RQcml2YXRlS2V5IG5lZWRzIHRvIGJlIGEgaGV4YWRlY2ltYWwgcHJpdmF0ZSBrZXkgc3RyaW5nJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgWHJwS2V5UGFpcigpLmdldEtleXMoKTtcbiAgICAgIGlmICgha2V5UGFpci5wcnYpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgICB9XG4gICAgICB3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkgPSBrZXlQYWlyLnBydjtcbiAgICB9XG4gICAgcmV0dXJuIHdhbGxldFBhcmFtcztcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluL3BhcnNlIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMgPSB7fSk6IFByb21pc2U8VHJhbnNhY3Rpb25FeHBsYW5hdGlvbj4ge1xuICAgIGxldCB0cmFuc2FjdGlvbjtcbiAgICBsZXQgdHhIZXg6IHN0cmluZyA9IHBhcmFtcy50eEhleCB8fCAoKHBhcmFtcy5oYWxmU2lnbmVkICYmIHBhcmFtcy5oYWxmU2lnbmVkLnR4SGV4KSBhcyBzdHJpbmcpO1xuICAgIGlmICghdHhIZXgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBwYXJhbSB0eEhleCcpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdHJhbnNhY3Rpb24gPSByaXBwbGVCaW5hcnlDb2RlYy5kZWNvZGUodHhIZXgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRyYW5zYWN0aW9uID0gSlNPTi5wYXJzZSh0eEhleCk7XG4gICAgICAgIHR4SGV4ID0gcmlwcGxlQmluYXJ5Q29kZWMuZW5jb2RlKHRyYW5zYWN0aW9uKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0eEhleCBuZWVkcyB0byBiZSBlaXRoZXIgaGV4IG9yIEpTT04gc3RyaW5nIGZvciBYUlAnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGlkOiBzdHJpbmc7XG4gICAgLy8gaGFzaGVzIGlkcyBhcmUgZGlmZmVyZW50IGZvciBzaWduZWQgYW5kIHVuc2lnbmVkIHR4XG4gICAgLy8gZmlyc3Qgd2UgdHJ5IHRvIGdldCB0aGUgaGFzaCBpZCBhcyBpZiBpdCBpcyBzaWduZWQsIHdpbGwgdGhyb3cgaWYgaXRzIG5vdFxuICAgIHRyeSB7XG4gICAgICBpZCA9IHhycGwuaGFzaGVzLmhhc2hTaWduZWRUeCh0eEhleCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWQgPSB4cnBsLmhhc2hlcy5oYXNoVHgodHhIZXgpO1xuICAgIH1cblxuICAgIGlmICh0cmFuc2FjdGlvbi5UcmFuc2FjdGlvblR5cGUgPT09ICdBY2NvdW50U2V0Jykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VBbW91bnQnLCAnb3V0cHV0cycsICdjaGFuZ2VPdXRwdXRzJywgJ2ZlZScsICdhY2NvdW50U2V0J10sXG4gICAgICAgIGlkOiBpZCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIG91dHB1dEFtb3VudDogMCxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAwLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiB0cmFuc2FjdGlvbi5GZWUsXG4gICAgICAgICAgZmVlUmF0ZTogdW5kZWZpbmVkLFxuICAgICAgICAgIHNpemU6IHR4SGV4Lmxlbmd0aCAvIDIsXG4gICAgICAgIH0sXG4gICAgICAgIGFjY291bnRTZXQ6IHtcbiAgICAgICAgICBtZXNzYWdlS2V5OiB0cmFuc2FjdGlvbi5NZXNzYWdlS2V5LFxuICAgICAgICAgIHNldEZsYWc6IHRyYW5zYWN0aW9uLlNldEZsYWcsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAodHJhbnNhY3Rpb24uVHJhbnNhY3Rpb25UeXBlID09PSAnVHJ1c3RTZXQnKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFtcbiAgICAgICAgICAnaWQnLFxuICAgICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAgICdjaGFuZ2VBbW91bnQnLFxuICAgICAgICAgICdvdXRwdXRzJyxcbiAgICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICAgJ2ZlZScsXG4gICAgICAgICAgJ2FjY291bnQnLFxuICAgICAgICAgICdsaW1pdEFtb3VudCcsXG4gICAgICAgIF0sXG4gICAgICAgIGlkOiBpZCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIG91dHB1dEFtb3VudDogMCxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAwLFxuICAgICAgICBvdXRwdXRzOiBbXSxcbiAgICAgICAgZmVlOiB7XG4gICAgICAgICAgZmVlOiB0cmFuc2FjdGlvbi5GZWUsXG4gICAgICAgICAgZmVlUmF0ZTogdW5kZWZpbmVkLFxuICAgICAgICAgIHNpemU6IHR4SGV4Lmxlbmd0aCAvIDIsXG4gICAgICAgIH0sXG4gICAgICAgIGFjY291bnQ6IHRyYW5zYWN0aW9uLkFjY291bnQsXG4gICAgICAgIGxpbWl0QW1vdW50OiB7XG4gICAgICAgICAgY3VycmVuY3k6IHRyYW5zYWN0aW9uLkxpbWl0QW1vdW50LmN1cnJlbmN5LFxuICAgICAgICAgIGlzc3VlcjogdHJhbnNhY3Rpb24uTGltaXRBbW91bnQuaXNzdWVyLFxuICAgICAgICAgIHZhbHVlOiB0cmFuc2FjdGlvbi5MaW1pdEFtb3VudC52YWx1ZSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgYWRkcmVzcyA9XG4gICAgICB0cmFuc2FjdGlvbi5EZXN0aW5hdGlvbiArICh0cmFuc2FjdGlvbi5EZXN0aW5hdGlvblRhZyA+PSAwID8gJz9kdD0nICsgdHJhbnNhY3Rpb24uRGVzdGluYXRpb25UYWcgOiAnJyk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlQW1vdW50JywgJ291dHB1dHMnLCAnY2hhbmdlT3V0cHV0cycsICdmZWUnXSxcbiAgICAgIGlkOiBpZCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgb3V0cHV0QW1vdW50OiB0cmFuc2FjdGlvbi5BbW91bnQsXG4gICAgICBjaGFuZ2VBbW91bnQ6IDAsXG4gICAgICBvdXRwdXRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIGFtb3VudDogdHJhbnNhY3Rpb24uQW1vdW50LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGZlZToge1xuICAgICAgICBmZWU6IHRyYW5zYWN0aW9uLkZlZSxcbiAgICAgICAgZmVlUmF0ZTogdW5kZWZpbmVkLFxuICAgICAgICBzaXplOiB0eEhleC5sZW5ndGggLyAyLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSB0aGF0IGEgdHJhbnNhY3Rpb24gcHJlYnVpbGQgY29tcGxpZXMgd2l0aCB0aGUgb3JpZ2luYWwgaW50ZW50aW9uXG4gICAqIEBwYXJhbSB0eFBhcmFtcyBwYXJhbXMgb2JqZWN0IHBhc3NlZCB0byBzZW5kXG4gICAqIEBwYXJhbSB0eFByZWJ1aWxkIHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBzZXJ2ZXJcbiAgICogQHBhcmFtIHdhbGxldFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHB1YmxpYyBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkIH06IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKSBhcyBYcnBDb2luO1xuICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gYXdhaXQgdGhpcy5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgdHhIZXg6IHR4UHJlYnVpbGQudHhIZXgsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvdXRwdXQgPSBbLi4uZXhwbGFuYXRpb24ub3V0cHV0cywgLi4uZXhwbGFuYXRpb24uY2hhbmdlT3V0cHV0c11bMF07XG4gICAgY29uc3QgZXhwZWN0ZWRPdXRwdXQgPSB0eFBhcmFtcy5yZWNpcGllbnRzICYmIHR4UGFyYW1zLnJlY2lwaWVudHNbMF07XG5cbiAgICBjb25zdCBjb21wYXJhdG9yID0gKHJlY2lwaWVudDEsIHJlY2lwaWVudDIpID0+IHtcbiAgICAgIGlmIChyZWNpcGllbnQxLmFkZHJlc3MgIT09IHJlY2lwaWVudDIuYWRkcmVzcykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBhbW91bnQxID0gbmV3IEJpZ051bWJlcihyZWNpcGllbnQxLmFtb3VudCk7XG4gICAgICBjb25zdCBhbW91bnQyID0gbmV3IEJpZ051bWJlcihyZWNpcGllbnQyLmFtb3VudCk7XG4gICAgICByZXR1cm4gYW1vdW50MS50b0ZpeGVkKCkgPT09IGFtb3VudDIudG9GaXhlZCgpO1xuICAgIH07XG5cbiAgICBpZiAoXG4gICAgICAodHhQYXJhbXMudHlwZSA9PT0gdW5kZWZpbmVkIHx8IHR4UGFyYW1zLnR5cGUgPT09ICdwYXltZW50JykgJiZcbiAgICAgIHR5cGVvZiBvdXRwdXQuYW1vdW50ICE9PSAnb2JqZWN0JyAmJlxuICAgICAgIWNvbXBhcmF0b3Iob3V0cHV0LCBleHBlY3RlZE91dHB1dClcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndHJhbnNhY3Rpb24gcHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgb3V0cHV0Jyk7XG4gICAgfVxuXG4gICAgaWYgKHR4UGFyYW1zLnR5cGUgPT09ICdlbmFibGV0b2tlbicpIHtcbiAgICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzPy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdPbmx5IG9uZSByZWNpcGllbnQgaXMgYWxsb3dlZC4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHR4UGFyYW1zLnJlY2lwaWVudHNbMF07XG4gICAgICBpZiAoIXJlY2lwaWVudC50b2tlbk5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZWNpcGllbnQgbXVzdCBpbmNsdWRlIGEgdG9rZW4gbmFtZS4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY2lwaWVudEN1cnJlbmN5ID0gdXRpbHMuZ2V0WHJwQ3VycmVuY3lGcm9tVG9rZW5OYW1lKHJlY2lwaWVudC50b2tlbk5hbWUpLmN1cnJlbmN5O1xuICAgICAgaWYgKGNvaW5Db25maWcuaXNUb2tlbikge1xuICAgICAgICBpZiAocmVjaXBpZW50Q3VycmVuY3kgIT09IGNvaW5Db25maWcuY3VycmVuY3lDb2RlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvcnJlY3QgdG9rZW4gbmFtZSBzcGVjaWZpZWQgaW4gcmVjaXBpZW50cycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoISgnYWNjb3VudCcgaW4gZXhwbGFuYXRpb24pIHx8ICEoJ2xpbWl0QW1vdW50JyBpbiBleHBsYW5hdGlvbikgfHwgIWV4cGxhbmF0aW9uLmxpbWl0QW1vdW50LmN1cnJlbmN5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwbGFuYXRpb24gaXMgbWlzc2luZyByZXF1aXJlZCBrZXlzIChhY2NvdW50IG9yIGxpbWl0QW1vdW50IHdpdGggY3VycmVuY3kpJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9IGV4cGxhbmF0aW9uLmFjY291bnQ7XG4gICAgICBjb25zdCBjdXJyZW5jeSA9IGV4cGxhbmF0aW9uLmxpbWl0QW1vdW50LmN1cnJlbmN5O1xuXG4gICAgICBpZiAocmVjaXBpZW50LmFkZHJlc3MgIT09IGJhc2VBZGRyZXNzIHx8IHJlY2lwaWVudEN1cnJlbmN5ICE9PSBjdXJyZW5jeSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCB0eFBhcmFtcyByZWNpcGllbnRzJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFkZHJlc3MgaXMgYSB2YWxpZCBYUlAgYWRkcmVzcywgYW5kIHRoZW4gbWFrZSBzdXJlIHRoZSByb290IGFkZHJlc3NlcyBtYXRjaC5cbiAgICogVGhpcyBwcmV2ZW50cyBhdHRhY2tzIHdoZXJlIGFuIGF0dGFjayBtYXkgc3dpdGNoIG91dCB0aGUgbmV3IGFkZHJlc3MgZm9yIG9uZSBvZiB0aGVpciBvd25cbiAgICogQHBhcmFtIGFkZHJlc3Mge1N0cmluZ30gdGhlIGFkZHJlc3MgdG8gdmVyaWZ5XG4gICAqIEBwYXJhbSByb290QWRkcmVzcyB7U3RyaW5nfSB0aGUgd2FsbGV0J3Mgcm9vdCBhZGRyZXNzXG4gICAqIEByZXR1cm4gdHJ1ZSBpZmYgYWRkcmVzcyBpcyBhIHdhbGxldCBhZGRyZXNzIChiYXNlZCBvbiByb290QWRkcmVzcylcbiAgICovXG4gIHB1YmxpYyBhc3luYyBpc1dhbGxldEFkZHJlc3MoeyBhZGRyZXNzLCByb290QWRkcmVzcyB9OiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBZGRyZXNzRXJyb3IoYGFkZHJlc3MgdmVyaWZpY2F0aW9uIGZhaWx1cmU6IGFkZHJlc3MgXCIke2FkZHJlc3N9XCIgaXMgbm90IHZhbGlkYCk7XG4gICAgfVxuXG4gICAgY29uc3QgYWRkcmVzc0RldGFpbHMgPSB1dGlscy5nZXRBZGRyZXNzRGV0YWlscyhhZGRyZXNzKTtcbiAgICBjb25zdCByb290QWRkcmVzc0RldGFpbHMgPSB1dGlscy5nZXRBZGRyZXNzRGV0YWlscyhyb290QWRkcmVzcyk7XG5cbiAgICBpZiAoYWRkcmVzc0RldGFpbHMuYWRkcmVzcyAhPT0gcm9vdEFkZHJlc3NEZXRhaWxzLmFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKFxuICAgICAgICBgYWRkcmVzcyB2YWxpZGF0aW9uIGZhaWx1cmU6ICR7YWRkcmVzc0RldGFpbHMuYWRkcmVzc30gdnMuICR7cm9vdEFkZHJlc3NEZXRhaWxzLmFkZHJlc3N9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVUkwgb2YgYSB3ZWxsLWtub3duLCBwdWJsaWMgZmFjaW5nIChub24tYml0Z28pIHJpcHBsZWQgaW5zdGFuY2Ugd2hpY2ggY2FuIGJlIHVzZWQgZm9yIHJlY292ZXJ5XG4gICAqL1xuICBwdWJsaWMgZ2V0UmlwcGxlZFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiAnaHR0cHM6Ly9zMS5yaXBwbGUuY29tOjUxMjM0JztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICogLSByb290QWRkcmVzczogcm9vdCBYUlAgd2FsbGV0IGFkZHJlc3MgdG8gcmVjb3ZlciBmdW5kcyBmcm9tXG4gICAqIC0gdXNlcktleTogW2VuY3J5cHRlZF0geHBydlxuICAgKiAtIGJhY2t1cEtleTogW2VuY3J5cHRlZF0geHBydiwgb3IgeHB1YiBpZiB0aGUgeHBydiBpcyBoZWxkIGJ5IGEgS1JTIHByb3ZpZGVyXG4gICAqIC0gd2FsbGV0UGFzc3BocmFzZTogbmVjZXNzYXJ5IGlmIG9uZSBvZiB0aGUgeHBydnMgaXMgZW5jcnlwdGVkXG4gICAqIC0gYml0Z29LZXk6IHhwdWJcbiAgICogLSBrcnNQcm92aWRlcjogbmVjZXNzYXJ5IGlmIGJhY2t1cCBrZXkgaXMgaGVsZCBieSBLUlNcbiAgICogLSByZWNvdmVyeURlc3RpbmF0aW9uOiB0YXJnZXQgYWRkcmVzcyB0byBzZW5kIHJlY292ZXJlZCBmdW5kcyB0b1xuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5SW5mbyB8IFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCByaXBwbGVkVXJsID0gdGhpcy5nZXRSaXBwbGVkVXJsKCk7XG4gICAgY29uc3QgaXNLcnNSZWNvdmVyeSA9IHBhcmFtcy5iYWNrdXBLZXkuc3RhcnRzV2l0aCgneHB1YicpICYmICFwYXJhbXMudXNlcktleS5zdGFydHNXaXRoKCd4cHViJyk7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gcGFyYW1zLmJhY2t1cEtleS5zdGFydHNXaXRoKCd4cHViJykgJiYgcGFyYW1zLnVzZXJLZXkuc3RhcnRzV2l0aCgneHB1YicpO1xuXG4gICAgY29uc3QgYWNjb3VudEluZm9QYXJhbXMgPSB7XG4gICAgICBtZXRob2Q6ICdhY2NvdW50X2luZm8nLFxuICAgICAgcGFyYW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhY2NvdW50OiBwYXJhbXMucm9vdEFkZHJlc3MsXG4gICAgICAgICAgbGVkZ2VyX2luZGV4OiAnY3VycmVudCcsXG4gICAgICAgICAgcXVldWU6IHRydWUsXG4gICAgICAgICAgc3RyaWN0OiB0cnVlLFxuICAgICAgICAgIHNpZ25lcl9saXN0czogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGNvbnN0IGFjY291bnRMaW5lc1BhcmFtcyA9IHtcbiAgICAgIG1ldGhvZDogJ2FjY291bnRfbGluZXMnLFxuICAgICAgcGFyYW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhY2NvdW50OiBwYXJhbXMucm9vdEFkZHJlc3MsXG4gICAgICAgICAgbGVkZ2VyX2luZGV4OiAndmFsaWRhdGVkJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGlmIChpc0tyc1JlY292ZXJ5KSB7XG4gICAgICBjaGVja0tyc1Byb3ZpZGVyKHRoaXMsIHBhcmFtcy5rcnNQcm92aWRlcik7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIGRlc3RpbmF0aW9uIGFkZHJlc3NcbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGVzdGluYXRpb24gYWRkcmVzcyEnKTtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gZ2V0QmlwMzJLZXlzKHRoaXMuYml0Z28sIHBhcmFtcywgeyByZXF1aXJlQml0R29YcHViOiBmYWxzZSB9KTtcblxuICAgIGNvbnN0IHsgYWRkcmVzc0RldGFpbHMsIGZlZURldGFpbHMsIHNlcnZlckRldGFpbHMsIGFjY291bnRMaW5lcyB9ID0gYXdhaXQgcHJvbWlzZVByb3BzKHtcbiAgICAgIGFkZHJlc3NEZXRhaWxzOiB0aGlzLmJpdGdvLnBvc3QocmlwcGxlZFVybCkuc2VuZChhY2NvdW50SW5mb1BhcmFtcyksXG4gICAgICBmZWVEZXRhaWxzOiB0aGlzLmJpdGdvLnBvc3QocmlwcGxlZFVybCkuc2VuZCh7IG1ldGhvZDogJ2ZlZScgfSksXG4gICAgICBzZXJ2ZXJEZXRhaWxzOiB0aGlzLmJpdGdvLnBvc3QocmlwcGxlZFVybCkuc2VuZCh7IG1ldGhvZDogJ3NlcnZlcl9pbmZvJyB9KSxcbiAgICAgIGFjY291bnRMaW5lczogdGhpcy5iaXRnby5wb3N0KHJpcHBsZWRVcmwpLnNlbmQoYWNjb3VudExpbmVzUGFyYW1zKSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG9wZW5MZWRnZXJGZWUgPSBuZXcgQmlnTnVtYmVyKGZlZURldGFpbHMuYm9keS5yZXN1bHQuZHJvcHMub3Blbl9sZWRnZXJfZmVlKTtcbiAgICBjb25zdCBiYXNlUmVzZXJ2ZSA9IG5ldyBCaWdOdW1iZXIoc2VydmVyRGV0YWlscy5ib2R5LnJlc3VsdC5pbmZvLnZhbGlkYXRlZF9sZWRnZXIucmVzZXJ2ZV9iYXNlX3hycCkudGltZXMoXG4gICAgICB0aGlzLmdldEJhc2VGYWN0b3IoKVxuICAgICk7XG4gICAgY29uc3QgcmVzZXJ2ZURlbHRhID0gbmV3IEJpZ051bWJlcihzZXJ2ZXJEZXRhaWxzLmJvZHkucmVzdWx0LmluZm8udmFsaWRhdGVkX2xlZGdlci5yZXNlcnZlX2luY194cnApLnRpbWVzKFxuICAgICAgdGhpcy5nZXRCYXNlRmFjdG9yKClcbiAgICApO1xuICAgIGNvbnN0IGN1cnJlbnRMZWRnZXIgPSBzZXJ2ZXJEZXRhaWxzLmJvZHkucmVzdWx0LmluZm8udmFsaWRhdGVkX2xlZGdlci5zZXE7XG4gICAgY29uc3Qgc2VxdWVuY2VJZCA9IGFkZHJlc3NEZXRhaWxzLmJvZHkucmVzdWx0LmFjY291bnRfZGF0YS5TZXF1ZW5jZTtcbiAgICBjb25zdCBiYWxhbmNlID0gbmV3IEJpZ051bWJlcihhZGRyZXNzRGV0YWlscy5ib2R5LnJlc3VsdC5hY2NvdW50X2RhdGEuQmFsYW5jZSk7XG4gICAgY29uc3Qgc2lnbmVyTGlzdHMgPSBhZGRyZXNzRGV0YWlscy5ib2R5LnJlc3VsdC5hY2NvdW50X2RhdGEuc2lnbmVyX2xpc3RzO1xuICAgIGNvbnN0IGFjY291bnRGbGFncyA9IGFkZHJlc3NEZXRhaWxzLmJvZHkucmVzdWx0LmFjY291bnRfZGF0YS5GbGFncztcblxuICAgIC8vIG1ha2Ugc3VyZSB0aGVyZSBpcyBvbmx5IG9uZSBzaWduZXIgbGlzdCBzZXRcbiAgICBpZiAoc2lnbmVyTGlzdHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VuZXhwZWN0ZWQgc2V0IG9mIHNpZ25lciBsaXN0cycpO1xuICAgIH1cblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgc2lnbmVycyBhcmUgdXNlciwgYmFja3VwLCBiaXRnb1xuICAgIGNvbnN0IHVzZXJBZGRyZXNzID0gcmlwcGxlS2V5cGFpcnMuZGVyaXZlQWRkcmVzcyhrZXlzWzBdLnB1YmxpY0tleS50b1N0cmluZygnaGV4JykpO1xuICAgIGNvbnN0IGJhY2t1cEFkZHJlc3MgPSByaXBwbGVLZXlwYWlycy5kZXJpdmVBZGRyZXNzKGtleXNbMV0ucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG5cbiAgICBjb25zdCBzaWduZXJMaXN0ID0gc2lnbmVyTGlzdHNbMF07XG4gICAgaWYgKHNpZ25lckxpc3QuU2lnbmVyUXVvcnVtICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgbWluaW11bSBzaWduYXR1cmUgY291bnQnKTtcbiAgICB9XG4gICAgY29uc3QgZm91bmRBZGRyZXNzZXMgPSB7fTtcblxuICAgIGNvbnN0IHNpZ25lckVudHJpZXMgPSBzaWduZXJMaXN0LlNpZ25lckVudHJpZXM7XG4gICAgaWYgKHNpZ25lckVudHJpZXMubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnbmVyIGxpc3QgbGVuZ3RoJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgeyBTaWduZXJFbnRyeSB9IG9mIHNpZ25lckVudHJpZXMpIHtcbiAgICAgIGNvbnN0IHdlaWdodCA9IFNpZ25lckVudHJ5LlNpZ25lcldlaWdodDtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBTaWduZXJFbnRyeS5BY2NvdW50O1xuICAgICAgaWYgKHdlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgc2lnbmVyIHdlaWdodCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiBpdCdzIGEgZHVwZSBvZiBhbiBhZGRyZXNzIHdlIGFscmVhZHkga25vdywgYmxvY2tcbiAgICAgIGlmIChmb3VuZEFkZHJlc3Nlc1thZGRyZXNzXSA+PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignZHVwbGljYXRlIHNpZ25lciBhZGRyZXNzJyk7XG4gICAgICB9XG4gICAgICBmb3VuZEFkZHJlc3Nlc1thZGRyZXNzXSA9IChmb3VuZEFkZHJlc3Nlc1thZGRyZXNzXSB8fCAwKSArIDE7XG4gICAgfVxuXG4gICAgaWYgKGZvdW5kQWRkcmVzc2VzW3VzZXJBZGRyZXNzXSAhPT0gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmV4cGVjdGVkIGluY2lkZW5jZSBmcmVxdWVuY3kgb2YgdXNlciBzaWduZXIgYWRkcmVzcycpO1xuICAgIH1cbiAgICBpZiAoZm91bmRBZGRyZXNzZXNbYmFja3VwQWRkcmVzc10gIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBpbmNpZGVuY2UgZnJlcXVlbmN5IG9mIHVzZXIgc2lnbmVyIGFkZHJlc3MnKTtcbiAgICB9XG5cbiAgICAvLyBtYWtlIHN1cmUgdGhlIGZsYWdzIGRpc2FibGUgdGhlIG1hc3RlciBrZXkgYW5kIGVuZm9yY2UgZGVzdGluYXRpb24gdGFnc1xuICAgIGNvbnN0IFVTRVJfS0VZX1NFVFRJTkdfRkxBRyA9IDY1NTM2O1xuICAgIGNvbnN0IE1BU1RFUl9LRVlfREVBQ1RJVkFUSU9OX0ZMQUcgPSAxMDQ4NTc2O1xuICAgIGNvbnN0IFJFUVVJUkVfREVTVElOQVRJT05fVEFHX0ZMQUcgPSAxMzEwNzI7XG4gICAgaWYgKChhY2NvdW50RmxhZ3MgJiBVU0VSX0tFWV9TRVRUSU5HX0ZMQUcpICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2EgY3VzdG9tIHVzZXIga2V5IGhhcyBiZWVuIHNldCcpO1xuICAgIH1cbiAgICBpZiAoKGFjY291bnRGbGFncyAmIE1BU1RFUl9LRVlfREVBQ1RJVkFUSU9OX0ZMQUcpICE9PSBNQVNURVJfS0VZX0RFQUNUSVZBVElPTl9GTEFHKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBtYXN0ZXIga2V5IGhhcyBub3QgYmVlbiBkZWFjdGl2YXRlZCcpO1xuICAgIH1cbiAgICBpZiAoKGFjY291bnRGbGFncyAmIFJFUVVJUkVfREVTVElOQVRJT05fVEFHX0ZMQUcpICE9PSBSRVFVSVJFX0RFU1RJTkFUSU9OX1RBR19GTEFHKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBkZXN0aW5hdGlvbiBmbGFnIHJlcXVpcmVtZW50IGhhcyBub3QgYmVlbiBhY3RpdmF0ZWQnKTtcbiAgICB9XG5cbiAgICAvLyByZWNvdmVyIHRoZSBmdW5kc1xuICAgIGNvbnN0IHJlc2VydmUgPSBiYXNlUmVzZXJ2ZS5wbHVzKHJlc2VydmVEZWx0YSk7XG4gICAgY29uc3QgcmVjb3ZlcmFibGVCYWxhbmNlID0gYmFsYW5jZS5taW51cyhyZXNlcnZlKTtcblxuICAgIGNvbnN0IHJhd0Rlc3RpbmF0aW9uID0gcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb247XG4gICAgY29uc3QgZGVzdGluYXRpb25EZXRhaWxzID0gdXJsLnBhcnNlKHJhd0Rlc3RpbmF0aW9uKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSBkZXN0aW5hdGlvbkRldGFpbHMucGF0aG5hbWU7XG5cbiAgICAvLyBwYXJzZSBkZXN0aW5hdGlvbiB0YWcgZnJvbSBxdWVyeVxuICAgIGxldCBkZXN0aW5hdGlvblRhZzogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGlmIChkZXN0aW5hdGlvbkRldGFpbHMucXVlcnkpIHtcbiAgICAgIGNvbnN0IHF1ZXJ5RGV0YWlscyA9IHF1ZXJ5c3RyaW5nLnBhcnNlKGRlc3RpbmF0aW9uRGV0YWlscy5xdWVyeSk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShxdWVyeURldGFpbHMuZHQpKSB7XG4gICAgICAgIC8vIGlmIHF1ZXJ5RGV0YWlscy5kdCBpcyBhbiBhcnJheSwgdGhhdCBtZWFucyBkdCB3YXMgZ2l2ZW4gbXVsdGlwbGUgdGltZXMsIHdoaWNoIGlzIG5vdCB2YWxpZFxuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEFkZHJlc3NFcnJvcihcbiAgICAgICAgICBgZGVzdGluYXRpb24gdGFnIGNhbiBhcHBlYXIgYXQgbW9zdCBvbmNlLCBidXQgJHtxdWVyeURldGFpbHMuZHQubGVuZ3RofSBkZXN0aW5hdGlvbiB0YWdzIHdlcmUgZm91bmRgXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcnNlZFRhZyA9IHBhcnNlSW50KHF1ZXJ5RGV0YWlscy5kdCBhcyBzdHJpbmcsIDEwKTtcbiAgICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKHBhcnNlZFRhZykpIHtcbiAgICAgICAgZGVzdGluYXRpb25UYWcgPSBwYXJzZWRUYWc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHJlY292ZXJhYmxlQmFsYW5jZS50b051bWJlcigpIDw9IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFF1YW50aXR5IG9mIFhSUCB0byByZWNvdmVyIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAuIEN1cnJlbnQgYmFsYW5jZTogJHtiYWxhbmNlLnRvTnVtYmVyKCl9LCBibG9ja2NoYWluIHJlc2VydmU6ICR7cmVzZXJ2ZS50b051bWJlcigpfSwgc3BlbmRhYmxlIGJhbGFuY2U6ICR7cmVjb3ZlcmFibGVCYWxhbmNlLnRvTnVtYmVyKCl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b2tlbk5hbWUgPSBwYXJhbXM/LnRva2VuTmFtZTtcbiAgICBpZiAoISF0b2tlbk5hbWUpIHtcbiAgICAgIGNvbnN0IHRva2VuUGFyYW1zID0ge1xuICAgICAgICBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGRlc3RpbmF0aW9uVGFnLFxuICAgICAgICByZWNvdmVyYWJsZUJhbGFuY2UsXG4gICAgICAgIGN1cnJlbnRMZWRnZXIsXG4gICAgICAgIG9wZW5MZWRnZXJGZWUsXG4gICAgICAgIHNlcXVlbmNlSWQsXG4gICAgICAgIGFjY291bnRMaW5lcyxcbiAgICAgICAga2V5cyxcbiAgICAgICAgaXNLcnNSZWNvdmVyeSxcbiAgICAgICAgaXNVbnNpZ25lZFN3ZWVwLFxuICAgICAgICB1c2VyQWRkcmVzcyxcbiAgICAgICAgYmFja3VwQWRkcmVzcyxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiB0aGlzLnJlY292ZXJYcnBUb2tlbihwYXJhbXMsIHRva2VuTmFtZSwgdG9rZW5QYXJhbXMpO1xuICAgIH1cblxuICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQodGhpcy5nZXRDaGFpbigpKSk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgdHhCdWlsZGVyXG4gICAgICAudG8oZGVzdGluYXRpb25BZGRyZXNzIGFzIHN0cmluZylcbiAgICAgIC5hbW91bnQocmVjb3ZlcmFibGVCYWxhbmNlLnRvRml4ZWQoMCkpXG4gICAgICAuc2VuZGVyKHBhcmFtcy5yb290QWRkcmVzcylcbiAgICAgIC5mbGFncygyMTQ3NDgzNjQ4KVxuICAgICAgLmxhc3RMZWRnZXJTZXF1ZW5jZShjdXJyZW50TGVkZ2VyICsgMTAwMDAwMCkgLy8gZ2l2ZSBpdCAxIG1pbGxpb24gbGVkZ2VycycgdGltZSAofjEgbW9udGgsIHN1aXRhYmxlIGZvciBLUlMpXG4gICAgICAuZmVlKG9wZW5MZWRnZXJGZWUudGltZXMoMykudG9GaXhlZCgwKSkgLy8gdGhlIGZhY3RvciB0aHJlZSBpcyBmb3IgdGhlIG11bHRpc2lnbmluZ1xuICAgICAgLnNlcXVlbmNlKHNlcXVlbmNlSWQpO1xuXG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBzZXJpYWxpemVkVHggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgaWYgKGlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHhIZXg6IHNlcmlhbGl6ZWRUeCxcbiAgICAgICAgY29pbjogdGhpcy5nZXRDaGFpbigpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoIWtleXNbMF0ucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1c2VyS2V5IGlzIG5vdCBhIHByaXZhdGUga2V5YCk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJLZXkgPSBrZXlzWzBdLnByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgIGNvbnN0IHVzZXJTaWduYXR1cmUgPSByaXBwbGUuc2lnbldpdGhQcml2YXRlS2V5KHNlcmlhbGl6ZWRUeCwgdXNlcktleSwgeyBzaWduQXM6IHVzZXJBZGRyZXNzIH0pO1xuXG4gICAgbGV0IHNpZ25lZFRyYW5zYWN0aW9uOiBzdHJpbmc7XG5cbiAgICBpZiAoaXNLcnNSZWNvdmVyeSkge1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24gPSB1c2VyU2lnbmF0dXJlLnNpZ25lZFRyYW5zYWN0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWtleXNbMV0ucHJpdmF0ZUtleSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGJhY2t1cEtleSBpcyBub3QgYSBwcml2YXRlIGtleWApO1xuICAgICAgfVxuICAgICAgY29uc3QgYmFja3VwS2V5ID0ga2V5c1sxXS5wcml2YXRlS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGJhY2t1cFNpZ25hdHVyZSA9IHJpcHBsZS5zaWduV2l0aFByaXZhdGVLZXkoc2VyaWFsaXplZFR4LCBiYWNrdXBLZXksIHsgc2lnbkFzOiBiYWNrdXBBZGRyZXNzIH0pO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24gPSByaXBwbGUubXVsdGlzaWduKFt1c2VyU2lnbmF0dXJlLnNpZ25lZFRyYW5zYWN0aW9uLCBiYWNrdXBTaWduYXR1cmUuc2lnbmVkVHJhbnNhY3Rpb25dKTtcbiAgICB9XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uOiBSZWNvdmVyeUluZm8gPSAoYXdhaXQgdGhpcy5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgdHhIZXg6IHNpZ25lZFRyYW5zYWN0aW9uLFxuICAgIH0pKSBhcyBSZWNvdmVyeUluZm87XG5cbiAgICB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uLnR4SGV4ID0gc2lnbmVkVHJhbnNhY3Rpb247XG5cbiAgICBpZiAoaXNLcnNSZWNvdmVyeSkge1xuICAgICAgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbi5iYWNrdXBLZXkgPSBwYXJhbXMuYmFja3VwS2V5O1xuICAgICAgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbi5jb2luID0gdGhpcy5nZXRDaGFpbigpO1xuICAgIH1cbiAgICByZXR1cm4gdHJhbnNhY3Rpb25FeHBsYW5hdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZWNvdmVyWHJwVG9rZW4ocGFyYW1zLCB0b2tlbk5hbWUsIHRva2VuUGFyYW1zKSB7XG4gICAgY29uc3QgeyBjdXJyZW5jeSwgaXNzdWVyIH0gPSB1dGlscy5nZXRYcnBDdXJyZW5jeUZyb21Ub2tlbk5hbWUodG9rZW5OYW1lKTtcblxuICAgIGNvbnN0IGxpbmVzID0gdG9rZW5QYXJhbXMuYWNjb3VudExpbmVzLmJvZHkucmVzdWx0LmxpbmVzO1xuXG4gICAgbGV0IGFtb3VudDtcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGlmIChsaW5lLmN1cnJlbmN5ID09PSBjdXJyZW5jeSAmJiBsaW5lLmFjY291bnQgPT09IGlzc3Vlcikge1xuICAgICAgICBhbW91bnQgPSBsaW5lLmJhbGFuY2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChhbW91bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEb2VzIG5vdCBoYXZlIFRydXN0bGluZSB3aXRoICR7aXNzdWVyfWApO1xuICAgIH1cbiAgICBpZiAoYW1vdW50ID09PSAnMCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRG9lcyBub3QgaGF2ZSBmdW5kcyB0byByZWNvdmVyYCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVjaW1hbFBsYWNlcyA9IGNvaW5zLmdldCh0b2tlbk5hbWUpLmRlY2ltYWxQbGFjZXM7XG4gICAgYW1vdW50ID0gbmV3IEJpZ051bWJlcihhbW91bnQpLnNoaWZ0ZWRCeShkZWNpbWFsUGxhY2VzKS50b0ZpeGVkKCk7XG5cbiAgICBjb25zdCBGTEFHX1ZBTFVFID0gMjE0NzQ4MzY0ODtcblxuICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQodG9rZW5OYW1lKSk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRUb2tlblRyYW5zZmVyQnVpbGRlcigpIGFzIFRva2VuVHJhbnNmZXJCdWlsZGVyO1xuICAgIHR4QnVpbGRlclxuICAgICAgLnRvKHRva2VuUGFyYW1zLmRlc3RpbmF0aW9uQWRkcmVzcylcbiAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgLnNlbmRlcihwYXJhbXMucm9vdEFkZHJlc3MpXG4gICAgICAuZmxhZ3MoRkxBR19WQUxVRSlcbiAgICAgIC5sYXN0TGVkZ2VyU2VxdWVuY2UodG9rZW5QYXJhbXMuY3VycmVudExlZGdlciArIDEwMDAwMDApIC8vIGdpdmUgaXQgMSBtaWxsaW9uIGxlZGdlcnMnIHRpbWUgKH4xIG1vbnRoLCBzdWl0YWJsZSBmb3IgS1JTKVxuICAgICAgLmZlZSh0b2tlblBhcmFtcy5vcGVuTGVkZ2VyRmVlLnRpbWVzKDMpLnRvRml4ZWQoMCkpIC8vIHRoZSBmYWN0b3IgdGhyZWUgaXMgZm9yIHRoZSBtdWx0aXNpZ25pbmdcbiAgICAgIC5zZXF1ZW5jZSh0b2tlblBhcmFtcy5zZXF1ZW5jZUlkKTtcblxuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFR4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgIGNvbnN0IHsga2V5cywgaXNLcnNSZWNvdmVyeSwgaXNVbnNpZ25lZFN3ZWVwLCB1c2VyQWRkcmVzcywgYmFja3VwQWRkcmVzcyB9ID0gdG9rZW5QYXJhbXM7XG5cbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eEhleDogc2VyaWFsaXplZFR4LFxuICAgICAgICBjb2luOiB0aGlzLmdldENoYWluKCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICgha2V5c1swXS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVzZXJLZXkgaXMgbm90IGEgcHJpdmF0ZSBrZXlgKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyS2V5ID0ga2V5c1swXS5wcml2YXRlS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICBjb25zdCB1c2VyU2lnbmF0dXJlID0gcmlwcGxlLnNpZ25XaXRoUHJpdmF0ZUtleShzZXJpYWxpemVkVHgsIHVzZXJLZXksIHsgc2lnbkFzOiB1c2VyQWRkcmVzcyB9KTtcblxuICAgIGxldCBzaWduZWRUcmFuc2FjdGlvbjogc3RyaW5nO1xuXG4gICAgaWYgKGlzS3JzUmVjb3ZlcnkpIHtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gdXNlclNpZ25hdHVyZS5zaWduZWRUcmFuc2FjdGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFrZXlzWzFdLnByaXZhdGVLZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBiYWNrdXBLZXkgaXMgbm90IGEgcHJpdmF0ZSBrZXlgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJhY2t1cEtleSA9IGtleXNbMV0ucHJpdmF0ZUtleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBiYWNrdXBTaWduYXR1cmUgPSByaXBwbGUuc2lnbldpdGhQcml2YXRlS2V5KHNlcmlhbGl6ZWRUeCwgYmFja3VwS2V5LCB7IHNpZ25BczogYmFja3VwQWRkcmVzcyB9KTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gcmlwcGxlLm11bHRpc2lnbihbdXNlclNpZ25hdHVyZS5zaWduZWRUcmFuc2FjdGlvbiwgYmFja3VwU2lnbmF0dXJlLnNpZ25lZFRyYW5zYWN0aW9uXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbjogUmVjb3ZlcnlJbmZvID0gKGF3YWl0IHRoaXMuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4SGV4OiBzaWduZWRUcmFuc2FjdGlvbixcbiAgICB9KSkgYXMgUmVjb3ZlcnlJbmZvO1xuXG4gICAgdHJhbnNhY3Rpb25FeHBsYW5hdGlvbi50eEhleCA9IHNpZ25lZFRyYW5zYWN0aW9uO1xuXG4gICAgaWYgKGlzS3JzUmVjb3ZlcnkpIHtcbiAgICAgIHRyYW5zYWN0aW9uRXhwbGFuYXRpb24uYmFja3VwS2V5ID0gcGFyYW1zLmJhY2t1cEtleTtcbiAgICAgIHRyYW5zYWN0aW9uRXhwbGFuYXRpb24uY29pbiA9IHRoaXMuZ2V0Q2hhaW4oKTtcbiAgICB9XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uRXhwbGFuYXRpb247XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgYSBuZXcga2V5cGFpciBmb3IgdGhpcyBjb2luLlxuICAgKiBAcGFyYW0gc2VlZCBTZWVkIGZyb20gd2hpY2ggdGhlIG5ldyBrZXlwYWlyIHNob3VsZCBiZSBnZW5lcmF0ZWQsIG90aGVyd2lzZSBhIHJhbmRvbSBzZWVkIGlzIHVzZWRcbiAgICovXG4gIHB1YmxpYyBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIGNvbnN0IGtleVBhaXIgPSBzZWVkID8gbmV3IFhycEtleVBhaXIoeyBzZWVkIH0pIDogbmV3IFhycEtleVBhaXIoKTtcbiAgICBjb25zdCBrZXlzID0ga2V5UGFpci5nZXRFeHRlbmRlZEtleXMoKTtcbiAgICBpZiAoIWtleXMueHBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHBydiBpbiBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHB1Yjoga2V5cy54cHViLFxuICAgICAgcHJ2OiBrZXlzLnhwcnYsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHBhcnNlVHJhbnNhY3Rpb24ocGFyYW1zOiBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8UGFyc2VkVHJhbnNhY3Rpb24+IHtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cbiJdfQ==