israeli-bank-scrapers 3.6.0 → 3.7.0

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 (58) hide show
  1. package/README.md +42 -0
  2. package/lib/definitions.d.ts +6 -1
  3. package/lib/definitions.js +6 -1
  4. package/lib/helpers/fetch.d.ts +2 -1
  5. package/lib/helpers/fetch.js +26 -9
  6. package/lib/helpers/storage.d.ts +2 -0
  7. package/lib/helpers/storage.js +17 -0
  8. package/lib/index.d.ts +2 -1
  9. package/lib/index.js +47 -3
  10. package/lib/scrapers/amex.d.ts +1 -1
  11. package/lib/scrapers/amex.js +1 -1
  12. package/lib/scrapers/amex.test.js +3 -2
  13. package/lib/scrapers/base-beinleumi-group.d.ts +7 -4
  14. package/lib/scrapers/base-beinleumi-group.js +1 -1
  15. package/lib/scrapers/base-isracard-amex.d.ts +8 -3
  16. package/lib/scrapers/base-isracard-amex.js +13 -11
  17. package/lib/scrapers/base-scraper-with-browser.d.ts +6 -3
  18. package/lib/scrapers/base-scraper-with-browser.js +14 -11
  19. package/lib/scrapers/base-scraper.d.ts +9 -119
  20. package/lib/scrapers/base-scraper.js +34 -50
  21. package/lib/scrapers/beyahad-bishvilha.d.ts +6 -3
  22. package/lib/scrapers/beyahad-bishvilha.js +1 -1
  23. package/lib/scrapers/discount.d.ts +9 -4
  24. package/lib/scrapers/discount.js +4 -4
  25. package/lib/scrapers/discount.test.js +4 -3
  26. package/lib/scrapers/errors.d.ts +16 -0
  27. package/lib/scrapers/errors.js +37 -0
  28. package/lib/scrapers/factory.d.ts +2 -16
  29. package/lib/scrapers/factory.js +6 -1
  30. package/lib/scrapers/hapoalim.d.ts +6 -3
  31. package/lib/scrapers/hapoalim.js +1 -1
  32. package/lib/scrapers/hapoalim.test.js +2 -2
  33. package/lib/scrapers/interface.d.ts +146 -0
  34. package/lib/scrapers/interface.js +2 -0
  35. package/lib/scrapers/isracard.d.ts +1 -1
  36. package/lib/scrapers/isracard.js +1 -1
  37. package/lib/scrapers/isracard.test.js +4 -3
  38. package/lib/scrapers/leumi.d.ts +8 -4
  39. package/lib/scrapers/leumi.js +1 -1
  40. package/lib/scrapers/max.d.ts +6 -3
  41. package/lib/scrapers/max.js +1 -1
  42. package/lib/scrapers/mizrahi.d.ts +7 -3
  43. package/lib/scrapers/mizrahi.js +4 -4
  44. package/lib/scrapers/one-zero-queries.d.ts +2 -0
  45. package/lib/scrapers/one-zero-queries.js +562 -0
  46. package/lib/scrapers/one-zero.d.ts +36 -0
  47. package/lib/scrapers/one-zero.js +304 -0
  48. package/lib/scrapers/one-zero.test.d.ts +1 -0
  49. package/lib/scrapers/one-zero.test.js +67 -0
  50. package/lib/scrapers/otsar-hahayal.d.ts +6 -3
  51. package/lib/scrapers/otsar-hahayal.js +1 -1
  52. package/lib/scrapers/union-bank.d.ts +6 -3
  53. package/lib/scrapers/union-bank.js +1 -1
  54. package/lib/scrapers/visa-cal.d.ts +103 -15
  55. package/lib/scrapers/visa-cal.js +154 -343
  56. package/lib/scrapers/yahav.d.ts +7 -3
  57. package/lib/scrapers/yahav.js +1 -1
  58. package/package.json +1 -1
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
 
3
- require("core-js/modules/es.symbol.description");
3
+ require("core-js/modules/es.array.flat-map");
4
4
 
5
5
  require("core-js/modules/es.array.iterator");
6
6
 
7
- require("core-js/modules/es.promise");
8
-
9
- require("core-js/modules/es.string.replace");
7
+ require("core-js/modules/es.array.unscopables.flat-map");
10
8
 
11
- require("core-js/modules/es.string.trim");
9
+ require("core-js/modules/es.promise");
12
10
 
13
11
  Object.defineProperty(exports, "__esModule", {
14
12
  value: true
@@ -17,40 +15,42 @@ exports.default = void 0;
17
15
 
18
16
  var _moment = _interopRequireDefault(require("moment"));
19
17
 
20
- var _baseScraperWithBrowser = require("./base-scraper-with-browser");
18
+ var _constants = require("../constants");
21
19
 
22
- var _elementsInteractions = require("../helpers/elements-interactions");
20
+ var _debug = require("../helpers/debug");
23
21
 
24
- var _transactions = require("../transactions");
22
+ var _elementsInteractions = require("../helpers/elements-interactions");
25
23
 
26
- var _constants = require("../constants");
24
+ var _fetch = require("../helpers/fetch");
27
25
 
28
- var _waiting = require("../helpers/waiting");
26
+ var _navigation = require("../helpers/navigation");
29
27
 
30
- var _transactions2 = require("../helpers/transactions");
28
+ var _storage = require("../helpers/storage");
31
29
 
32
- var _debug = require("../helpers/debug");
30
+ var _transactions = require("../helpers/transactions");
33
31
 
34
- var _fetch = require("../helpers/fetch");
32
+ var _waiting = require("../helpers/waiting");
35
33
 
36
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
+ var _transactions2 = require("../transactions");
37
35
 
38
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
36
+ var _baseScraperWithBrowser = require("./base-scraper-with-browser");
39
37
 
40
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
38
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
41
39
 
42
40
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
43
41
 
44
42
  const LOGIN_URL = 'https://www.cal-online.co.il/';
45
- const TRANSACTIONS_URL = 'https://services.cal-online.co.il/Card-Holders/Screens/Transactions/Transactions.aspx';
46
- const GET_TX_DETAILS_URL = 'https://services.cal-online.co.il/Card-Holders/SCREENS/Transactions/Transactions.aspx/GetTransDetails';
47
- const GET_TX_DETAILS_HEADER = {
48
- 'Content-Type': 'application/json;charset=UTF-8'
49
- };
50
- const LONG_DATE_FORMAT = 'DD/MM/YYYY';
51
- const DATE_FORMAT = 'DD/MM/YY';
43
+ const TRANSACTIONS_REQUEST_ENDPOINT = 'https://api.cal-online.co.il/Transactions/api/transactionsDetails/getCardTransactionsDetails';
52
44
  const InvalidPasswordMessage = 'שם המשתמש או הסיסמה שהוזנו שגויים';
53
45
  const debug = (0, _debug.getDebug)('visa-cal');
46
+ var trnTypeCode;
47
+
48
+ (function (trnTypeCode) {
49
+ trnTypeCode["regular"] = "5";
50
+ trnTypeCode["credit"] = "6";
51
+ trnTypeCode["installments"] = "8";
52
+ trnTypeCode["standingOrder"] = "9";
53
+ })(trnTypeCode || (trnTypeCode = {}));
54
54
 
55
55
  async function getLoginFrame(page) {
56
56
  let frame = null;
@@ -80,7 +80,7 @@ async function hasInvalidPasswordError(page) {
80
80
  function getPossibleLoginResults() {
81
81
  debug('return possible login results');
82
82
  const urls = {
83
- [_baseScraperWithBrowser.LoginResults.Success]: [/AccountManagement/i],
83
+ [_baseScraperWithBrowser.LoginResults.Success]: [/dashboard/i],
84
84
  [_baseScraperWithBrowser.LoginResults.InvalidPassword]: [async options => {
85
85
  const page = options === null || options === void 0 ? void 0 : options.page;
86
86
 
@@ -107,101 +107,39 @@ function createLoginFields(credentials) {
107
107
  }];
108
108
  }
109
109
 
110
- function getAmountData(amountStr) {
111
- const amountStrCln = amountStr.replace(',', '');
112
- let currency = null;
113
- let amount = null;
114
-
115
- if (amountStrCln.includes(_constants.SHEKEL_CURRENCY_SYMBOL)) {
116
- amount = -parseFloat(amountStrCln.replace(_constants.SHEKEL_CURRENCY_SYMBOL, ''));
117
- currency = _constants.SHEKEL_CURRENCY;
118
- } else if (amountStrCln.includes(_constants.DOLLAR_CURRENCY_SYMBOL)) {
119
- amount = -parseFloat(amountStrCln.replace(_constants.DOLLAR_CURRENCY_SYMBOL, ''));
120
- currency = _constants.DOLLAR_CURRENCY;
121
- } else if (amountStrCln.includes(_constants.EURO_CURRENCY_SYMBOL)) {
122
- amount = -parseFloat(amountStrCln.replace(_constants.EURO_CURRENCY_SYMBOL, ''));
123
- currency = _constants.EURO_CURRENCY;
124
- } else {
125
- const parts = amountStrCln.split(' ');
126
- [currency] = parts;
127
- amount = -parseFloat(parts[1]);
128
- }
129
-
130
- return {
131
- amount,
132
- currency
133
- };
134
- }
135
-
136
- function getTransactionInstallments(memo) {
137
- const parsedMemo = /תשלום (\d+) מתוך (\d+)/.exec(memo || '');
138
-
139
- if (!parsedMemo || parsedMemo.length === 0) {
140
- return null;
141
- }
142
-
143
- return {
144
- number: parseInt(parsedMemo[1], 10),
145
- total: parseInt(parsedMemo[2], 10)
146
- };
110
+ function cardAndTransactionCurrencySymbolIsShekel(transaction) {
111
+ return transaction.debCrdCurrencySymbol === _constants.SHEKEL_CURRENCY_SYMBOL && transaction.trnCurrencySymbol === _constants.SHEKEL_CURRENCY_SYMBOL;
147
112
  }
148
113
 
149
- function getIdentifierAndNumerator(onclickValue) {
150
- if (!onclickValue) {
151
- debug('cannot extract the identifier of a transaction, onclick attribute not found for transaction');
152
- return {};
153
- }
154
-
155
- const expectedStartValue = 'OnMouseClickRow(this, event, "';
114
+ function convertParsedDataToTransactions(parsedData) {
115
+ return parsedData.flatMap(monthData => monthData.result.bankAccounts).flatMap(accounts => accounts.debitDates).flatMap(debitDate => debitDate.transactions).map(transaction => {
116
+ const installments = transaction.curPaymentNum && transaction.numOfPayments && {
117
+ number: transaction.curPaymentNum,
118
+ total: transaction.numOfPayments
119
+ } || undefined;
120
+ const date = (0, _moment.default)(transaction.trnPurchaseDate); // I didn't test `amtBeforeConvAndIndex` with a foreign currency as I don't have such transactions
156
121
 
157
- if (!onclickValue.startsWith(expectedStartValue)) {
158
- debug(`cannot extract the identifier of a transaction, onclick attribute value doesnt start with expected value '${onclickValue}'`);
159
- return {};
160
- }
161
-
162
- const thirdArgument = onclickValue.substring(expectedStartValue.length, onclickValue.length - 2);
163
- const splits = thirdArgument.split('|');
164
-
165
- if (splits.length !== 2) {
166
- debug(`cannot extract the identifier of a transaction, unexpected 3rd argument in onclick value '${onclickValue}'`);
167
- return {};
168
- }
169
-
170
- return {
171
- identifier: splits[1],
172
- numerator: splits[0]
173
- };
174
- }
175
-
176
- function convertTransactions(txns) {
177
- debug(`convert ${txns.length} raw transactions to official Transaction structure`);
178
- return txns.map(txn => {
179
- var _getIdentifierAndNume, _txn$additionalInfo;
122
+ let chargedAmount;
180
123
 
181
- const originalAmountTuple = getAmountData(txn.originalAmount || '');
182
- const chargedAmountTuple = getAmountData(txn.chargedAmount || '');
183
- const installments = getTransactionInstallments(txn.memo);
184
- const txnDate = (0, _moment.default)(txn.date, DATE_FORMAT);
185
- const processedDateFormat = txn.processedDate.length === 8 ? DATE_FORMAT : txn.processedDate.length === 9 || txn.processedDate.length === 10 ? LONG_DATE_FORMAT : null;
124
+ if (cardAndTransactionCurrencySymbolIsShekel(transaction)) {
125
+ chargedAmount = transaction.amtBeforeConvAndIndex * -1;
126
+ } else {
127
+ chargedAmount = transaction.trnAmt * -1;
186
128
 
187
- if (!processedDateFormat) {
188
- throw new Error('invalid processed date');
129
+ if (transaction.trnTypeCode === trnTypeCode.credit) {
130
+ chargedAmount = transaction.trnAmt;
131
+ }
189
132
  }
190
133
 
191
- const txnProcessedDate = (0, _moment.default)(txn.processedDate, processedDateFormat);
192
134
  const result = {
193
- identifier: (_getIdentifierAndNume = getIdentifierAndNumerator(txn.onclick)) === null || _getIdentifierAndNume === void 0 ? void 0 : _getIdentifierAndNume.identifier,
194
- type: installments ? _transactions.TransactionTypes.Installments : _transactions.TransactionTypes.Normal,
195
- status: _transactions.TransactionStatuses.Completed,
196
- date: installments ? txnDate.add(installments.number - 1, 'month').toISOString() : txnDate.toISOString(),
197
- processedDate: txnProcessedDate.toISOString(),
198
- originalAmount: originalAmountTuple.amount,
199
- originalCurrency: originalAmountTuple.currency,
200
- chargedAmount: chargedAmountTuple.amount,
201
- chargedCurrency: chargedAmountTuple.currency,
202
- description: txn.description || '',
203
- memo: txn.memo || '',
204
- category: (_txn$additionalInfo = txn.additionalInfo) === null || _txn$additionalInfo === void 0 ? void 0 : _txn$additionalInfo.category
135
+ chargedAmount,
136
+ description: transaction.merchantName,
137
+ originalAmount: transaction.amtBeforeConvAndIndex,
138
+ originalCurrency: transaction.trnCurrencySymbol,
139
+ processedDate: transaction.debCrdDate,
140
+ status: _transactions2.TransactionStatuses.Completed,
141
+ date: installments ? date.add(installments.number - 1, 'month').toISOString() : date.toISOString(),
142
+ type: [trnTypeCode.regular, trnTypeCode.standingOrder].includes(transaction.trnTypeCode) ? _transactions2.TransactionTypes.Normal : _transactions2.TransactionTypes.Installments
205
143
  };
206
144
 
207
145
  if (installments) {
@@ -212,228 +150,6 @@ function convertTransactions(txns) {
212
150
  });
213
151
  }
214
152
 
215
- async function getAdditionalTxInfo(tx, page) {
216
- var _result$d, _result$d$Data, _result$d$Data$Mercha;
217
-
218
- const {
219
- identifier,
220
- numerator
221
- } = getIdentifierAndNumerator(tx.onclick);
222
-
223
- if (identifier === undefined || numerator === undefined) {
224
- return null;
225
- }
226
-
227
- const result = await (0, _fetch.fetchPostWithinPage)(page, GET_TX_DETAILS_URL, {
228
- Identifier: identifier,
229
- Numerator: numerator
230
- }, GET_TX_DETAILS_HEADER);
231
- return {
232
- category: ((_result$d = result.d) === null || _result$d === void 0 ? void 0 : (_result$d$Data = _result$d.Data) === null || _result$d$Data === void 0 ? void 0 : (_result$d$Data$Mercha = _result$d$Data.MerchantDetails) === null || _result$d$Data$Mercha === void 0 ? void 0 : _result$d$Data$Mercha.SectorName) || undefined
233
- };
234
- }
235
-
236
- async function getAdditionalTxsInfoIfNeeded(txs, scraperOptions, page) {
237
- if (!scraperOptions.additionalTransactionInformation) {
238
- return txs;
239
- }
240
-
241
- const promises = txs.map(async x => _objectSpread({}, x, {
242
- additionalInfo: await getAdditionalTxInfo(x, page)
243
- }));
244
- return Promise.all(promises);
245
- }
246
-
247
- async function fetchTransactionsForAccount(page, startDate, accountNumber, scraperOptions) {
248
- var _scraperOptions$outpu, _scraperOptions$outpu2;
249
-
250
- const startDateValue = startDate.format('MM/YYYY');
251
- const dateSelector = '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_TextBox"]';
252
- const dateHiddenFieldSelector = '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_HiddenField"]';
253
- const buttonSelector = '[id$="FormAreaNoBorder_FormArea_ctlSubmitRequest"]';
254
- const nextPageSelector = '[id$="FormAreaNoBorder_FormArea_ctlGridPager_btnNext"]';
255
- const billingLabelSelector = '[id$=FormAreaNoBorder_FormArea_ctlMainToolBar_lblCaption]';
256
- const secondaryBillingLabelSelector = '[id$=FormAreaNoBorder_FormArea_ctlSecondaryToolBar_lblCaption]';
257
- const noDataSelector = '[id$=FormAreaNoBorder_FormArea_msgboxErrorMessages]';
258
- debug('find the start date index in the dropbox');
259
- const options = await (0, _elementsInteractions.pageEvalAll)(page, '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_OptionList"] li', [], items => {
260
- return items.map(el => el.innerText);
261
- });
262
- const startDateIndex = options.findIndex(option => option === startDateValue);
263
- debug(`scrape ${options.length - startDateIndex} billing cycles`);
264
- const accountTransactions = [];
265
-
266
- for (let currentDateIndex = startDateIndex; currentDateIndex < options.length; currentDateIndex += 1) {
267
- debug('wait for date selector to be found');
268
- await (0, _elementsInteractions.waitUntilElementFound)(page, dateSelector, true);
269
- debug(`set hidden value of the date selector to be the index ${currentDateIndex}`);
270
- await (0, _elementsInteractions.setValue)(page, dateHiddenFieldSelector, `${currentDateIndex}`);
271
- debug('wait a second to workaround navigation issue in headless browser mode');
272
- await page.waitForTimeout(1000);
273
- debug('click on the filter submit button and wait for navigation');
274
- await Promise.all([page.waitForNavigation({
275
- waitUntil: 'domcontentloaded'
276
- }), (0, _elementsInteractions.clickButton)(page, buttonSelector)]);
277
- debug('check if month has no transactions');
278
- const pageHasNoTransactions = await (0, _elementsInteractions.pageEval)(page, noDataSelector, false, element => {
279
- const siteValue = (element.innerText || '').replace(/[^ א-ת]/g, '');
280
- return siteValue === 'לא נמצאו נתונים';
281
- });
282
-
283
- if (pageHasNoTransactions) {
284
- debug('page has no transactions');
285
- } else {
286
- var _settlementDateRegex$;
287
-
288
- debug('find the billing date');
289
- let billingDateLabel = await (0, _elementsInteractions.pageEval)(page, billingLabelSelector, '', element => {
290
- return element.innerText;
291
- });
292
- let settlementDateRegex = /\d{1,2}[/]\d{2}[/]\d{2,4}/;
293
-
294
- if (billingDateLabel === '') {
295
- billingDateLabel = await (0, _elementsInteractions.pageEval)(page, secondaryBillingLabelSelector, '', element => {
296
- return element.innerText;
297
- });
298
- settlementDateRegex = /\d{1,2}[/]\d{2,4}/;
299
- }
300
-
301
- const billingDate = (_settlementDateRegex$ = settlementDateRegex.exec(billingDateLabel)) === null || _settlementDateRegex$ === void 0 ? void 0 : _settlementDateRegex$[0];
302
-
303
- if (!billingDate) {
304
- throw new Error('failed to fetch process date');
305
- }
306
-
307
- debug(`found the billing date for that month ${billingDate}`);
308
- let hasNextPage = false;
309
-
310
- do {
311
- debug('fetch raw transactions from page');
312
- const rawTransactions = await (0, _elementsInteractions.pageEvalAll)(page, '#ctlMainGrid > tbody tr, #ctlSecondaryGrid > tbody tr', [], (items, billingDate) => {
313
- return items.map(el => {
314
- const columns = el.getElementsByTagName('td');
315
- const onclick = el.getAttribute('onclick');
316
-
317
- if (columns.length === 6) {
318
- return {
319
- onclick,
320
- processedDate: columns[0].innerText,
321
- date: columns[1].innerText,
322
- description: columns[2].innerText,
323
- originalAmount: columns[3].innerText,
324
- chargedAmount: columns[4].innerText,
325
- memo: columns[5].innerText
326
- };
327
- }
328
-
329
- if (columns.length === 5) {
330
- return {
331
- onclick,
332
- processedDate: billingDate,
333
- date: columns[0].innerText,
334
- description: columns[1].innerText,
335
- originalAmount: columns[2].innerText,
336
- chargedAmount: columns[3].innerText,
337
- memo: columns[4].innerText
338
- };
339
- }
340
-
341
- return null;
342
- });
343
- }, billingDate);
344
- debug(`fetched ${rawTransactions.length} raw transactions from page`);
345
- const existsTxs = rawTransactions.filter(item => !!item);
346
- const fullScrappedTxs = await getAdditionalTxsInfoIfNeeded(existsTxs, scraperOptions, page);
347
- accountTransactions.push(...convertTransactions(fullScrappedTxs));
348
- debug('check for existence of another page');
349
- hasNextPage = await (0, _elementsInteractions.elementPresentOnPage)(page, nextPageSelector);
350
-
351
- if (hasNextPage) {
352
- debug('has another page, click on button next and wait for page navigation');
353
- await Promise.all([page.waitForNavigation({
354
- waitUntil: 'domcontentloaded'
355
- }), await (0, _elementsInteractions.clickButton)(page, '[id$=FormAreaNoBorder_FormArea_ctlGridPager_btnNext]')]);
356
- }
357
- } while (hasNextPage);
358
- }
359
- }
360
-
361
- debug('filer out old transactions');
362
- const txns = ((_scraperOptions$outpu = (_scraperOptions$outpu2 = scraperOptions.outputData) === null || _scraperOptions$outpu2 === void 0 ? void 0 : _scraperOptions$outpu2.enableTransactionsFilterByDate) !== null && _scraperOptions$outpu !== void 0 ? _scraperOptions$outpu : true) ? (0, _transactions2.filterOldTransactions)(accountTransactions, startDate, scraperOptions.combineInstallments || false) : accountTransactions;
363
- debug(`found ${txns.length} valid transactions out of ${accountTransactions.length} transactions for account ending with ${accountNumber.substring(accountNumber.length - 2)}`);
364
- return {
365
- accountNumber,
366
- txns
367
- };
368
- }
369
-
370
- async function getAccountNumbers(page) {
371
- return (0, _elementsInteractions.pageEvalAll)(page, '[id$=lnkItem]', [], elements => elements.map(e => e.text)).then(res => res.map(text => {
372
- var _$exec$, _$exec;
373
-
374
- return (_$exec$ = (_$exec = /\d+$/.exec(text.trim())) === null || _$exec === void 0 ? void 0 : _$exec[0]) !== null && _$exec$ !== void 0 ? _$exec$ : '';
375
- }));
376
- }
377
-
378
- async function setAccount(page, account) {
379
- await (0, _elementsInteractions.pageEvalAll)(page, '[id$=lnkItem]', null, (elements, account) => {
380
- for (const elem of elements) {
381
- const a = elem;
382
-
383
- if (a.text.includes(account)) {
384
- a.click();
385
- }
386
- }
387
- }, account);
388
- }
389
-
390
- async function fetchTransactions(page, startDate, scraperOptions) {
391
- const accountNumbers = await getAccountNumbers(page);
392
- const accounts = [];
393
-
394
- for (const account of accountNumbers) {
395
- debug(`setting account: ${account}`);
396
- await setAccount(page, account);
397
- await page.waitForTimeout(1000);
398
- accounts.push((await fetchTransactionsForAccount(page, startDate, account, scraperOptions)));
399
- }
400
-
401
- return accounts;
402
- }
403
-
404
- async function fetchFutureDebits(page) {
405
- const futureDebitsSelector = '.homepage-banks-top';
406
- const result = await (0, _elementsInteractions.pageEvalAll)(page, futureDebitsSelector, [], items => {
407
- const debitMountClass = 'amount';
408
- const debitWhenChargeClass = 'when-charge';
409
- const debitBankNumberClass = 'bankDesc';
410
- return items.map(currBankEl => {
411
- const amount = currBankEl.getElementsByClassName(debitMountClass)[0].innerText;
412
- const whenCharge = currBankEl.getElementsByClassName(debitWhenChargeClass)[0].innerText;
413
- const bankNumber = currBankEl.getElementsByClassName(debitBankNumberClass)[0].innerText;
414
- return {
415
- amount,
416
- whenCharge,
417
- bankNumber
418
- };
419
- });
420
- });
421
- const futureDebits = result.map(item => {
422
- var _$exec2, _$exec3;
423
-
424
- const amountData = getAmountData(item.amount);
425
- const chargeDate = (_$exec2 = /\d{1,2}[/]\d{2}[/]\d{2,4}/.exec(item.whenCharge)) === null || _$exec2 === void 0 ? void 0 : _$exec2[0];
426
- const bankAccountNumber = (_$exec3 = /\d+-\d+/.exec(item.bankNumber)) === null || _$exec3 === void 0 ? void 0 : _$exec3[0];
427
- return {
428
- amount: amountData.amount,
429
- amountCurrency: amountData.currency,
430
- chargeDate,
431
- bankAccountNumber
432
- };
433
- });
434
- return futureDebits;
435
- }
436
-
437
153
  class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
438
154
  constructor(...args) {
439
155
  super(...args);
@@ -455,6 +171,48 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
455
171
  });
456
172
  }
457
173
 
174
+ async getCards() {
175
+ const initData = await (0, _storage.getFromSessionStorage)(this.page, 'init');
176
+
177
+ if (!initData) {
178
+ throw new Error('could not find \'init\' data in session storage');
179
+ }
180
+
181
+ return initData === null || initData === void 0 ? void 0 : initData.result.cards.map(({
182
+ cardUniqueId,
183
+ last4Digits
184
+ }) => ({
185
+ cardUniqueId,
186
+ last4Digits
187
+ }));
188
+ }
189
+
190
+ async getAuthorizationHeader() {
191
+ const authModule = await (0, _storage.getFromSessionStorage)(this.page, 'auth-module');
192
+
193
+ if (!authModule) {
194
+ throw new Error('could not find \'auth-module\' in session storage');
195
+ }
196
+
197
+ return `CALAuthScheme ${authModule.auth.calConnectToken}`;
198
+ }
199
+
200
+ async getXSiteId() {
201
+ /*
202
+ I don't know if the constant below will change in the feature.
203
+ If so, use the next code:
204
+ return this.page.evaluate(() => new Ut().xSiteId);
205
+ To get the classname search for 'xSiteId' in the page source
206
+ class Ut {
207
+ constructor(_e, on, yn) {
208
+ this.store = _e,
209
+ this.config = on,
210
+ this.eventBusService = yn,
211
+ this.xSiteId = "09031987-273E-2311-906C-8AF85B17C8D9",
212
+ */
213
+ return Promise.resolve('09031987-273E-2311-906C-8AF85B17C8D9');
214
+ }
215
+
458
216
  getLoginOptions(credentials) {
459
217
  return {
460
218
  loginUrl: `${LOGIN_URL}`,
@@ -463,28 +221,81 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
463
221
  possibleResults: getPossibleLoginResults(),
464
222
  checkReadiness: async () => (0, _elementsInteractions.waitUntilElementFound)(this.page, '#ccLoginDesktopBtn'),
465
223
  preAction: this.openLoginPopup,
224
+ postAction: async () => {
225
+ try {
226
+ await (0, _elementsInteractions.waitUntilElementFound)(this.page, 'button.btn-close');
227
+ const currentUrl = await (0, _navigation.getCurrentUrl)(this.page);
228
+
229
+ if (currentUrl.endsWith('site-tutorial')) {
230
+ await (0, _elementsInteractions.clickButton)(this.page, 'button.btn-close');
231
+ }
232
+ } catch (e) {
233
+ const currentUrl = await (0, _navigation.getCurrentUrl)(this.page);
234
+ if (currentUrl.endsWith('dashboard')) return;
235
+ throw e;
236
+ }
237
+ },
466
238
  userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
467
239
  };
468
240
  }
469
241
 
242
+ isCardTransactionDetails(result) {
243
+ return result.result !== undefined;
244
+ }
245
+
470
246
  async fetchData() {
471
- const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').add(1, 'day');
247
+ const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').subtract(6, 'months').add(1, 'day');
472
248
  const startDate = this.options.startDate || defaultStartMoment.toDate();
473
249
 
474
250
  const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
475
251
 
476
252
  debug(`fetch transactions starting ${startMoment.format()}`);
477
- debug('fetch future debits');
478
- const futureDebits = await fetchFutureDebits(this.page);
479
- debug('navigate to transactions page');
480
- await this.navigateTo(TRANSACTIONS_URL, undefined, 60000);
481
- debug('fetch accounts transactions');
482
- const accounts = await fetchTransactions(this.page, startMoment, this.options);
253
+ const Authorization = await this.getAuthorizationHeader(); // Wait a little before `this.getCards` so that it would exist
254
+
255
+ await new Promise(resolve => setTimeout(resolve, 1000));
256
+ const cards = await this.getCards();
257
+ const xSiteId = await this.getXSiteId();
258
+ const accounts = await Promise.all(cards.map(async card => {
259
+ var _this$options$outputD, _this$options$outputD2;
260
+
261
+ debug(`fetch transactions for card ${card.cardUniqueId}`);
262
+ const nextBillingMonth = (0, _moment.default)().add(1, 'month');
263
+ const months = nextBillingMonth.diff(startMoment, 'months');
264
+ const allMonthsData = [];
265
+
266
+ for (let i = 0; i <= months; i += 1) {
267
+ const month = nextBillingMonth.clone().subtract(i, 'months');
268
+ const monthData = await (0, _fetch.fetchPostWithinPage)(this.page, TRANSACTIONS_REQUEST_ENDPOINT, {
269
+ cardUniqueId: card.cardUniqueId,
270
+ month: month.format('M'),
271
+ year: month.format('YYYY')
272
+ }, {
273
+ Authorization,
274
+ 'X-Site-Id': xSiteId,
275
+ 'Content-Type': 'application/json'
276
+ });
277
+ if ((monthData === null || monthData === void 0 ? void 0 : monthData.statusCode) !== 1) throw new Error(`failed to fetch transactions for card ${card.last4Digits}. Message: ${(monthData === null || monthData === void 0 ? void 0 : monthData.title) || ''}`);
278
+
279
+ if (!this.isCardTransactionDetails(monthData)) {
280
+ throw new Error('monthData is not of type CardTransactionDetails');
281
+ }
282
+
283
+ allMonthsData.push(monthData);
284
+ }
285
+
286
+ const transactions = convertParsedDataToTransactions(allMonthsData);
287
+ debug('filer out old transactions');
288
+ const txns = ((_this$options$outputD = (_this$options$outputD2 = this.options.outputData) === null || _this$options$outputD2 === void 0 ? void 0 : _this$options$outputD2.enableTransactionsFilterByDate) !== null && _this$options$outputD !== void 0 ? _this$options$outputD : true) ? (0, _transactions.filterOldTransactions)(transactions, (0, _moment.default)(startDate), this.options.combineInstallments || false) : transactions;
289
+ return {
290
+ txns,
291
+ accountNumber: card.last4Digits
292
+ };
293
+ }));
483
294
  debug('return the scraped accounts');
295
+ debug(JSON.stringify(accounts, null, 2));
484
296
  return {
485
297
  success: true,
486
- accounts,
487
- futureDebits
298
+ accounts
488
299
  };
489
300
  }
490
301
 
@@ -492,4 +303,4 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
492
303
 
493
304
  var _default = VisaCalScraper;
494
305
  exports.default = _default;
495
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy92aXNhLWNhbC50cyJdLCJuYW1lcyI6WyJMT0dJTl9VUkwiLCJUUkFOU0FDVElPTlNfVVJMIiwiR0VUX1RYX0RFVEFJTFNfVVJMIiwiR0VUX1RYX0RFVEFJTFNfSEVBREVSIiwiTE9OR19EQVRFX0ZPUk1BVCIsIkRBVEVfRk9STUFUIiwiSW52YWxpZFBhc3N3b3JkTWVzc2FnZSIsImRlYnVnIiwiZ2V0TG9naW5GcmFtZSIsInBhZ2UiLCJmcmFtZSIsImZyYW1lcyIsImZpbmQiLCJmIiwidXJsIiwiaW5jbHVkZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIkVycm9yIiwiaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IiLCJlcnJvckZvdW5kIiwiZXJyb3JNZXNzYWdlIiwiaXRlbSIsImlubmVyVGV4dCIsImdldFBvc3NpYmxlTG9naW5SZXN1bHRzIiwidXJscyIsIkxvZ2luUmVzdWx0cyIsIlN1Y2Nlc3MiLCJJbnZhbGlkUGFzc3dvcmQiLCJvcHRpb25zIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidmFsdWUiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiZ2V0QW1vdW50RGF0YSIsImFtb3VudFN0ciIsImFtb3VudFN0ckNsbiIsInJlcGxhY2UiLCJjdXJyZW5jeSIsImFtb3VudCIsIlNIRUtFTF9DVVJSRU5DWV9TWU1CT0wiLCJwYXJzZUZsb2F0IiwiU0hFS0VMX0NVUlJFTkNZIiwiRE9MTEFSX0NVUlJFTkNZX1NZTUJPTCIsIkRPTExBUl9DVVJSRU5DWSIsIkVVUk9fQ1VSUkVOQ1lfU1lNQk9MIiwiRVVST19DVVJSRU5DWSIsInBhcnRzIiwic3BsaXQiLCJnZXRUcmFuc2FjdGlvbkluc3RhbGxtZW50cyIsIm1lbW8iLCJwYXJzZWRNZW1vIiwiZXhlYyIsImxlbmd0aCIsIm51bWJlciIsInBhcnNlSW50IiwidG90YWwiLCJnZXRJZGVudGlmaWVyQW5kTnVtZXJhdG9yIiwib25jbGlja1ZhbHVlIiwiZXhwZWN0ZWRTdGFydFZhbHVlIiwic3RhcnRzV2l0aCIsInRoaXJkQXJndW1lbnQiLCJzdWJzdHJpbmciLCJzcGxpdHMiLCJpZGVudGlmaWVyIiwibnVtZXJhdG9yIiwiY29udmVydFRyYW5zYWN0aW9ucyIsInR4bnMiLCJtYXAiLCJ0eG4iLCJvcmlnaW5hbEFtb3VudFR1cGxlIiwib3JpZ2luYWxBbW91bnQiLCJjaGFyZ2VkQW1vdW50VHVwbGUiLCJjaGFyZ2VkQW1vdW50IiwiaW5zdGFsbG1lbnRzIiwidHhuRGF0ZSIsImRhdGUiLCJwcm9jZXNzZWREYXRlRm9ybWF0IiwicHJvY2Vzc2VkRGF0ZSIsInR4blByb2Nlc3NlZERhdGUiLCJyZXN1bHQiLCJvbmNsaWNrIiwidHlwZSIsIlRyYW5zYWN0aW9uVHlwZXMiLCJJbnN0YWxsbWVudHMiLCJOb3JtYWwiLCJzdGF0dXMiLCJUcmFuc2FjdGlvblN0YXR1c2VzIiwiQ29tcGxldGVkIiwiYWRkIiwidG9JU09TdHJpbmciLCJvcmlnaW5hbEN1cnJlbmN5IiwiY2hhcmdlZEN1cnJlbmN5IiwiZGVzY3JpcHRpb24iLCJjYXRlZ29yeSIsImFkZGl0aW9uYWxJbmZvIiwiZ2V0QWRkaXRpb25hbFR4SW5mbyIsInR4IiwidW5kZWZpbmVkIiwiSWRlbnRpZmllciIsIk51bWVyYXRvciIsImQiLCJEYXRhIiwiTWVyY2hhbnREZXRhaWxzIiwiU2VjdG9yTmFtZSIsImdldEFkZGl0aW9uYWxUeHNJbmZvSWZOZWVkZWQiLCJ0eHMiLCJzY3JhcGVyT3B0aW9ucyIsImFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uIiwicHJvbWlzZXMiLCJ4IiwiYWxsIiwiZmV0Y2hUcmFuc2FjdGlvbnNGb3JBY2NvdW50Iiwic3RhcnREYXRlIiwiYWNjb3VudE51bWJlciIsInN0YXJ0RGF0ZVZhbHVlIiwiZm9ybWF0IiwiZGF0ZVNlbGVjdG9yIiwiZGF0ZUhpZGRlbkZpZWxkU2VsZWN0b3IiLCJidXR0b25TZWxlY3RvciIsIm5leHRQYWdlU2VsZWN0b3IiLCJiaWxsaW5nTGFiZWxTZWxlY3RvciIsInNlY29uZGFyeUJpbGxpbmdMYWJlbFNlbGVjdG9yIiwibm9EYXRhU2VsZWN0b3IiLCJpdGVtcyIsImVsIiwic3RhcnREYXRlSW5kZXgiLCJmaW5kSW5kZXgiLCJvcHRpb24iLCJhY2NvdW50VHJhbnNhY3Rpb25zIiwiY3VycmVudERhdGVJbmRleCIsIndhaXRGb3JUaW1lb3V0Iiwid2FpdEZvck5hdmlnYXRpb24iLCJ3YWl0VW50aWwiLCJwYWdlSGFzTm9UcmFuc2FjdGlvbnMiLCJlbGVtZW50Iiwic2l0ZVZhbHVlIiwiYmlsbGluZ0RhdGVMYWJlbCIsInNldHRsZW1lbnREYXRlUmVnZXgiLCJiaWxsaW5nRGF0ZSIsImhhc05leHRQYWdlIiwicmF3VHJhbnNhY3Rpb25zIiwiY29sdW1ucyIsImdldEVsZW1lbnRzQnlUYWdOYW1lIiwiZ2V0QXR0cmlidXRlIiwiZXhpc3RzVHhzIiwiZmlsdGVyIiwiZnVsbFNjcmFwcGVkVHhzIiwicHVzaCIsIm91dHB1dERhdGEiLCJlbmFibGVUcmFuc2FjdGlvbnNGaWx0ZXJCeURhdGUiLCJjb21iaW5lSW5zdGFsbG1lbnRzIiwiZ2V0QWNjb3VudE51bWJlcnMiLCJlbGVtZW50cyIsImUiLCJ0ZXh0IiwidGhlbiIsInJlcyIsInRyaW0iLCJzZXRBY2NvdW50IiwiYWNjb3VudCIsImVsZW0iLCJhIiwiY2xpY2siLCJmZXRjaFRyYW5zYWN0aW9ucyIsImFjY291bnROdW1iZXJzIiwiYWNjb3VudHMiLCJmZXRjaEZ1dHVyZURlYml0cyIsImZ1dHVyZURlYml0c1NlbGVjdG9yIiwiZGViaXRNb3VudENsYXNzIiwiZGViaXRXaGVuQ2hhcmdlQ2xhc3MiLCJkZWJpdEJhbmtOdW1iZXJDbGFzcyIsImN1cnJCYW5rRWwiLCJnZXRFbGVtZW50c0J5Q2xhc3NOYW1lIiwid2hlbkNoYXJnZSIsImJhbmtOdW1iZXIiLCJmdXR1cmVEZWJpdHMiLCJhbW91bnREYXRhIiwiY2hhcmdlRGF0ZSIsImJhbmtBY2NvdW50TnVtYmVyIiwiYW1vdW50Q3VycmVuY3kiLCJWaXNhQ2FsU2NyYXBlciIsIkJhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJnZXRMb2dpbk9wdGlvbnMiLCJsb2dpblVybCIsImZpZWxkcyIsInN1Ym1pdEJ1dHRvblNlbGVjdG9yIiwicG9zc2libGVSZXN1bHRzIiwiY2hlY2tSZWFkaW5lc3MiLCJwcmVBY3Rpb24iLCJvcGVuTG9naW5Qb3B1cCIsInVzZXJBZ2VudCIsImZldGNoRGF0YSIsImRlZmF1bHRTdGFydE1vbWVudCIsInN1YnRyYWN0IiwidG9EYXRlIiwic3RhcnRNb21lbnQiLCJtb21lbnQiLCJtYXgiLCJuYXZpZ2F0ZVRvIiwic3VjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFFQTs7QUFDQTs7QUFHQTs7QUFRQTs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVBLE1BQU1BLFNBQVMsR0FBRywrQkFBbEI7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyx1RkFBekI7QUFDQSxNQUFNQyxrQkFBa0IsR0FBRyx1R0FBM0I7QUFDQSxNQUFNQyxxQkFBcUIsR0FBRztBQUFFLGtCQUFnQjtBQUFsQixDQUE5QjtBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFlBQXpCO0FBQ0EsTUFBTUMsV0FBVyxHQUFHLFVBQXBCO0FBQ0EsTUFBTUMsc0JBQXNCLEdBQUcsbUNBQS9CO0FBRUEsTUFBTUMsS0FBSyxHQUFHLHFCQUFTLFVBQVQsQ0FBZDs7QUFrQkEsZUFBZUMsYUFBZixDQUE2QkMsSUFBN0IsRUFBeUM7QUFDdkMsTUFBSUMsS0FBbUIsR0FBRyxJQUExQjtBQUNBSCxFQUFBQSxLQUFLLENBQUMsOEJBQUQsQ0FBTDtBQUNBLFFBQU0sd0JBQVUsTUFBTTtBQUNwQkcsSUFBQUEsS0FBSyxHQUFHRCxJQUFJLENBQ1RFLE1BREssR0FFTEMsSUFGSyxDQUVDQyxDQUFELElBQU9BLENBQUMsQ0FBQ0MsR0FBRixHQUFRQyxRQUFSLENBQWlCLFlBQWpCLENBRlAsS0FFMEMsSUFGbEQ7QUFHQSxXQUFPQyxPQUFPLENBQUND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QUFTLEdBQUcsS0FBS3RGLE9BQUwsQ0FBYXNGLFNBQWIsSUFBMEJnRixrQkFBa0IsQ0FBQ0UsTUFBbkIsRUFBNUM7O0FBQ0EsVUFBTUMsV0FBVyxHQUFHQyxnQkFBT0MsR0FBUCxDQUFXTCxrQkFBWCxFQUErQixxQkFBT2hGLFNBQVAsQ0FBL0IsQ0FBcEI7O0FBQ0E1RyxJQUFBQSxLQUFLLENBQUUsK0JBQThCK0wsV0FBVyxDQUFDaEYsTUFBWixFQUFxQixFQUFyRCxDQUFMO0FBRUEvRyxJQUFBQSxLQUFLLENBQUMscUJBQUQsQ0FBTDtBQUNBLFVBQU0ySyxZQUFZLEdBQUcsTUFBTVQsaUJBQWlCLENBQUMsS0FBS2hLLElBQU4sQ0FBNUM7QUFFQUYsSUFBQUEsS0FBSyxDQUFDLCtCQUFELENBQUw7QUFDQSxVQUFNLEtBQUtrTSxVQUFMLENBQWdCeE0sZ0JBQWhCLEVBQWtDbUcsU0FBbEMsRUFBNkMsS0FBN0MsQ0FBTjtBQUVBN0YsSUFBQUEsS0FBSyxDQUFDLDZCQUFELENBQUw7QUFDQSxVQUFNaUssUUFBUSxHQUFHLE1BQU1GLGlCQUFpQixDQUFDLEtBQUs3SixJQUFOLEVBQVk2TCxXQUFaLEVBQXlCLEtBQUt6SyxPQUE5QixDQUF4QztBQUVBdEIsSUFBQUEsS0FBSyxDQUFDLDZCQUFELENBQUw7QUFDQSxXQUFPO0FBQ0xtTSxNQUFBQSxPQUFPLEVBQUUsSUFESjtBQUVMbEMsTUFBQUEsUUFGSztBQUdMVSxNQUFBQTtBQUhLLEtBQVA7QUFLRDs7QUFuRGlEOztlQXNEckNLLGMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbW9tZW50LCB7IE1vbWVudCB9IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBGcmFtZSwgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyBCYXNlU2NyYXBlcldpdGhCcm93c2VyLCBMb2dpbk9wdGlvbnMsIExvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQge1xuICBjbGlja0J1dHRvbiwgZWxlbWVudFByZXNlbnRPblBhZ2UsIHBhZ2VFdmFsLCBwYWdlRXZhbEFsbCwgc2V0VmFsdWUsIHdhaXRVbnRpbEVsZW1lbnRGb3VuZCxcbn0gZnJvbSAnLi4vaGVscGVycy9lbGVtZW50cy1pbnRlcmFjdGlvbnMnO1xuaW1wb3J0IHtcbiAgVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uSW5zdGFsbG1lbnRzLFxuICBUcmFuc2FjdGlvbnNBY2NvdW50LFxuICBUcmFuc2FjdGlvblN0YXR1c2VzLFxuICBUcmFuc2FjdGlvblR5cGVzLFxufSBmcm9tICcuLi90cmFuc2FjdGlvbnMnO1xuaW1wb3J0IHsgU2NyYXBlck9wdGlvbnMsIFNjYXBlclNjcmFwaW5nUmVzdWx0LCBTY3JhcGVyQ3JlZGVudGlhbHMgfSBmcm9tICcuL2Jhc2Utc2NyYXBlcic7XG5pbXBvcnQge1xuICBET0xMQVJfQ1VSUkVOQ1ksIERPTExBUl9DVVJSRU5DWV9TWU1CT0wsIEVVUk9fQ1VSUkVOQ1ksIEVVUk9fQ1VSUkVOQ1lfU1lNQk9MLCBTSEVLRUxfQ1VSUkVOQ1ksIFNIRUtFTF9DVVJSRU5DWV9TWU1CT0wsXG59IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHsgZmlsdGVyT2xkVHJhbnNhY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy90cmFuc2FjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0RGVidWcgfSBmcm9tICcuLi9oZWxwZXJzL2RlYnVnJztcbmltcG9ydCB7IGZldGNoUG9zdFdpdGhpblBhZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2ZldGNoJztcblxuY29uc3QgTE9HSU5fVVJMID0gJ2h0dHBzOi8vd3d3LmNhbC1vbmxpbmUuY28uaWwvJztcbmNvbnN0IFRSQU5TQUNUSU9OU19VUkwgPSAnaHR0cHM6Ly9zZXJ2aWNlcy5jYWwtb25saW5lLmNvLmlsL0NhcmQtSG9sZGVycy9TY3JlZW5zL1RyYW5zYWN0aW9ucy9UcmFuc2FjdGlvbnMuYXNweCc7XG5jb25zdCBHRVRfVFhfREVUQUlMU19VUkwgPSAnaHR0cHM6Ly9zZXJ2aWNlcy5jYWwtb25saW5lLmNvLmlsL0NhcmQtSG9sZGVycy9TQ1JFRU5TL1RyYW5zYWN0aW9ucy9UcmFuc2FjdGlvbnMuYXNweC9HZXRUcmFuc0RldGFpbHMnO1xuY29uc3QgR0VUX1RYX0RFVEFJTFNfSEVBREVSID0geyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD1VVEYtOCcgfTtcbmNvbnN0IExPTkdfREFURV9GT1JNQVQgPSAnREQvTU0vWVlZWSc7XG5jb25zdCBEQVRFX0ZPUk1BVCA9ICdERC9NTS9ZWSc7XG5jb25zdCBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlID0gJ9ep150g15TXntep16rXntepINeQ15Ug15TXodeZ16HXnteUINep15TXldeW16DXlSDXqdeS15XXmdeZ150nO1xuXG5jb25zdCBkZWJ1ZyA9IGdldERlYnVnKCd2aXNhLWNhbCcpO1xuXG5pbnRlcmZhY2UgU2NyYXBlZFRyYW5zYWN0aW9uIHtcbiAgb25jbGljazogc3RyaW5nIHwgbnVsbDtcbiAgZGF0ZTogc3RyaW5nO1xuICBwcm9jZXNzZWREYXRlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIG9yaWdpbmFsQW1vdW50OiBzdHJpbmc7XG4gIGNoYXJnZWRBbW91bnQ6IHN0cmluZztcbiAgbWVtbzogc3RyaW5nO1xuICBhZGRpdGlvbmFsSW5mbz86IFNjcmFwZWRBZGRpdGlvbmFsSW5mbztcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRBZGRpdGlvbmFsSW5mbyB7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xufVxuXG5cbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2luRnJhbWUocGFnZTogUGFnZSkge1xuICBsZXQgZnJhbWU6IEZyYW1lIHwgbnVsbCA9IG51bGw7XG4gIGRlYnVnKCd3YWl0IHVudGlsIGxvZ2luIGZyYW1lIGZvdW5kJyk7XG4gIGF3YWl0IHdhaXRVbnRpbCgoKSA9PiB7XG4gICAgZnJhbWUgPSBwYWdlXG4gICAgICAuZnJhbWVzKClcbiAgICAgIC5maW5kKChmKSA9PiBmLnVybCgpLmluY2x1ZGVzKCdjYWxjb25uZWN0JykpIHx8IG51bGw7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSghIWZyYW1lKTtcbiAgfSwgJ3dhaXQgZm9yIGlmcmFtZSB3aXRoIGxvZ2luIGZvcm0nLCAxMDAwMCwgMTAwMCk7XG5cbiAgaWYgKCFmcmFtZSkge1xuICAgIGRlYnVnKCdmYWlsZWQgdG8gZmluZCBsb2dpbiBmcmFtZSBmb3IgMTAgc2Vjb25kcycpO1xuICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGV4dHJhY3QgbG9naW4gaWZyYW1lJyk7XG4gIH1cblxuICByZXR1cm4gZnJhbWU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhc0ludmFsaWRQYXNzd29yZEVycm9yKHBhZ2U6IFBhZ2UpIHtcbiAgY29uc3QgZnJhbWUgPSBhd2FpdCBnZXRMb2dpbkZyYW1lKHBhZ2UpO1xuICBjb25zdCBlcnJvckZvdW5kID0gYXdhaXQgZWxlbWVudFByZXNlbnRPblBhZ2UoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicpO1xuICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvckZvdW5kID8gYXdhaXQgcGFnZUV2YWwoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicsICcnLCAoaXRlbSkgPT4ge1xuICAgIHJldHVybiAoaXRlbSBhcyBIVE1MRGl2RWxlbWVudCkuaW5uZXJUZXh0O1xuICB9KSA6ICcnO1xuICByZXR1cm4gZXJyb3JNZXNzYWdlID09PSBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlO1xufVxuXG5mdW5jdGlvbiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpIHtcbiAgZGVidWcoJ3JldHVybiBwb3NzaWJsZSBsb2dpbiByZXN1bHRzJyk7XG4gIGNvbnN0IHVybHM6IExvZ2luT3B0aW9uc1sncG9zc2libGVSZXN1bHRzJ10gPSB7XG4gICAgW0xvZ2luUmVzdWx0cy5TdWNjZXNzXTogWy9BY2NvdW50TWFuYWdlbWVudC9pXSxcbiAgICBbTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZF06IFthc3luYyAob3B0aW9ucz86IHsgcGFnZT86IFBhZ2V9KSA9PiB7XG4gICAgICBjb25zdCBwYWdlID0gb3B0aW9ucz8ucGFnZTtcbiAgICAgIGlmICghcGFnZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IocGFnZSk7XG4gICAgfV0sXG4gICAgLy8gW0xvZ2luUmVzdWx0cy5BY2NvdW50QmxvY2tlZF06IFtdLCAvLyBUT0RPIGFkZCB3aGVuIHJlYWNoaW5nIHRoaXMgc2NlbmFyaW9cbiAgICAvLyBbTG9naW5SZXN1bHRzLkNoYW5nZVBhc3N3b3JkXTogW10sIC8vIFRPRE8gYWRkIHdoZW4gcmVhY2hpbmcgdGhpcyBzY2VuYXJpb1xuICB9O1xuICByZXR1cm4gdXJscztcbn1cblxuZnVuY3Rpb24gY3JlYXRlTG9naW5GaWVsZHMoY3JlZGVudGlhbHM6IFNjcmFwZXJDcmVkZW50aWFscykge1xuICBkZWJ1ZygnY3JlYXRlIGxvZ2luIGZpZWxkcyBmb3IgdXNlcm5hbWUgYW5kIHBhc3N3b3JkJyk7XG4gIHJldHVybiBbXG4gICAgeyBzZWxlY3RvcjogJ1tmb3JtY29udHJvbG5hbWU9XCJ1c2VyTmFtZVwiXScsIHZhbHVlOiBjcmVkZW50aWFscy51c2VybmFtZSB9LFxuICAgIHsgc2VsZWN0b3I6ICdbZm9ybWNvbnRyb2xuYW1lPVwicGFzc3dvcmRcIl0nLCB2YWx1ZTogY3JlZGVudGlhbHMucGFzc3dvcmQgfSxcbiAgXTtcbn1cblxuXG5mdW5jdGlvbiBnZXRBbW91bnREYXRhKGFtb3VudFN0cjogc3RyaW5nKSB7XG4gIGNvbnN0IGFtb3VudFN0ckNsbiA9IGFtb3VudFN0ci5yZXBsYWNlKCcsJywgJycpO1xuICBsZXQgY3VycmVuY3k6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBsZXQgYW1vdW50OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgaWYgKGFtb3VudFN0ckNsbi5pbmNsdWRlcyhTSEVLRUxfQ1VSUkVOQ1lfU1lNQk9MKSkge1xuICAgIGFtb3VudCA9IC1wYXJzZUZsb2F0KGFtb3VudFN0ckNsbi5yZXBsYWNlKFNIRUtFTF9DVVJSRU5DWV9TWU1CT0wsICcnKSk7XG4gICAgY3VycmVuY3kgPSBTSEVLRUxfQ1VSUkVOQ1k7XG4gIH0gZWxzZSBpZiAoYW1vdW50U3RyQ2xuLmluY2x1ZGVzKERPTExBUl9DVVJSRU5DWV9TWU1CT0wpKSB7XG4gICAgYW1vdW50ID0gLXBhcnNlRmxvYXQoYW1vdW50U3RyQ2xuLnJlcGxhY2UoRE9MTEFSX0NVUlJFTkNZX1NZTUJPTCwgJycpKTtcbiAgICBjdXJyZW5jeSA9IERPTExBUl9DVVJSRU5DWTtcbiAgfSBlbHNlIGlmIChhbW91bnRTdHJDbG4uaW5jbHVkZXMoRVVST19DVVJSRU5DWV9TWU1CT0wpKSB7XG4gICAgYW1vdW50ID0gLXBhcnNlRmxvYXQoYW1vdW50U3RyQ2xuLnJlcGxhY2UoRVVST19DVVJSRU5DWV9TWU1CT0wsICcnKSk7XG4gICAgY3VycmVuY3kgPSBFVVJPX0NVUlJFTkNZO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IHBhcnRzID0gYW1vdW50U3RyQ2xuLnNwbGl0KCcgJyk7XG4gICAgW2N1cnJlbmN5XSA9IHBhcnRzO1xuICAgIGFtb3VudCA9IC1wYXJzZUZsb2F0KHBhcnRzWzFdKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYW1vdW50LFxuICAgIGN1cnJlbmN5LFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRUcmFuc2FjdGlvbkluc3RhbGxtZW50cyhtZW1vOiBzdHJpbmcpOiBUcmFuc2FjdGlvbkluc3RhbGxtZW50cyB8IG51bGwge1xuICBjb25zdCBwYXJzZWRNZW1vID0gKC/Xqtep15zXldedIChcXGQrKSDXnteq15XXmiAoXFxkKykvKS5leGVjKG1lbW8gfHwgJycpO1xuXG4gIGlmICghcGFyc2VkTWVtbyB8fCBwYXJzZWRNZW1vLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBudW1iZXI6IHBhcnNlSW50KHBhcnNlZE1lbW9bMV0sIDEwKSxcbiAgICB0b3RhbDogcGFyc2VJbnQocGFyc2VkTWVtb1syXSwgMTApLFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRJZGVudGlmaWVyQW5kTnVtZXJhdG9yKG9uY2xpY2tWYWx1ZTogc3RyaW5nIHwgbnVsbCk6IHsgaWRlbnRpZmllcj86IHN0cmluZywgbnVtZXJhdG9yPzogc3RyaW5nIH0ge1xuICBpZiAoIW9uY2xpY2tWYWx1ZSkge1xuICAgIGRlYnVnKCdjYW5ub3QgZXh0cmFjdCB0aGUgaWRlbnRpZmllciBvZiBhIHRyYW5zYWN0aW9uLCBvbmNsaWNrIGF0dHJpYnV0ZSBub3QgZm91bmQgZm9yIHRyYW5zYWN0aW9uJyk7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIGNvbnN0IGV4cGVjdGVkU3RhcnRWYWx1ZSA9ICdPbk1vdXNlQ2xpY2tSb3codGhpcywgZXZlbnQsIFwiJztcbiAgaWYgKCFvbmNsaWNrVmFsdWUuc3RhcnRzV2l0aChleHBlY3RlZFN0YXJ0VmFsdWUpKSB7XG4gICAgZGVidWcoYGNhbm5vdCBleHRyYWN0IHRoZSBpZGVudGlmaWVyIG9mIGEgdHJhbnNhY3Rpb24sIG9uY2xpY2sgYXR0cmlidXRlIHZhbHVlIGRvZXNudCBzdGFydCB3aXRoIGV4cGVjdGVkIHZhbHVlICcke29uY2xpY2tWYWx1ZX0nYCk7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgdGhpcmRBcmd1bWVudCA9IG9uY2xpY2tWYWx1ZS5zdWJzdHJpbmcoZXhwZWN0ZWRTdGFydFZhbHVlLmxlbmd0aCwgb25jbGlja1ZhbHVlLmxlbmd0aCAtIDIpO1xuICBjb25zdCBzcGxpdHMgPSB0aGlyZEFyZ3VtZW50LnNwbGl0KCd8Jyk7XG4gIGlmIChzcGxpdHMubGVuZ3RoICE9PSAyKSB7XG4gICAgZGVidWcoYGNhbm5vdCBleHRyYWN0IHRoZSBpZGVudGlmaWVyIG9mIGEgdHJhbnNhY3Rpb24sIHVuZXhwZWN0ZWQgM3JkIGFyZ3VtZW50IGluIG9uY2xpY2sgdmFsdWUgJyR7b25jbGlja1ZhbHVlfSdgKTtcbiAgICByZXR1cm4ge307XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBpZGVudGlmaWVyOiBzcGxpdHNbMV0sXG4gICAgbnVtZXJhdG9yOiBzcGxpdHNbMF0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2FjdGlvbnModHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10pOiBUcmFuc2FjdGlvbltdIHtcbiAgZGVidWcoYGNvbnZlcnQgJHt0eG5zLmxlbmd0aH0gcmF3IHRyYW5zYWN0aW9ucyB0byBvZmZpY2lhbCBUcmFuc2FjdGlvbiBzdHJ1Y3R1cmVgKTtcbiAgcmV0dXJuIHR4bnMubWFwKCh0eG4pID0+IHtcbiAgICBjb25zdCBvcmlnaW5hbEFtb3VudFR1cGxlID0gZ2V0QW1vdW50RGF0YSh0eG4ub3JpZ2luYWxBbW91bnQgfHwgJycpO1xuICAgIGNvbnN0IGNoYXJnZWRBbW91bnRUdXBsZSA9IGdldEFtb3VudERhdGEodHhuLmNoYXJnZWRBbW91bnQgfHwgJycpO1xuXG4gICAgY29uc3QgaW5zdGFsbG1lbnRzID0gZ2V0VHJhbnNhY3Rpb25JbnN0YWxsbWVudHModHhuLm1lbW8pO1xuICAgIGNvbnN0IHR4bkRhdGUgPSBtb21lbnQodHhuLmRhdGUsIERBVEVfRk9STUFUKTtcbiAgICBjb25zdCBwcm9jZXNzZWREYXRlRm9ybWF0ID1cbiAgICAgIHR4bi5wcm9jZXNzZWREYXRlLmxlbmd0aCA9PT0gOCA/XG4gICAgICAgIERBVEVfRk9STUFUIDpcbiAgICAgICAgdHhuLnByb2Nlc3NlZERhdGUubGVuZ3RoID09PSA5IHx8IHR4bi5wcm9jZXNzZWREYXRlLmxlbmd0aCA9PT0gMTAgP1xuICAgICAgICAgIExPTkdfREFURV9GT1JNQVQgOlxuICAgICAgICAgIG51bGw7XG4gICAgaWYgKCFwcm9jZXNzZWREYXRlRm9ybWF0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcHJvY2Vzc2VkIGRhdGUnKTtcbiAgICB9XG4gICAgY29uc3QgdHhuUHJvY2Vzc2VkRGF0ZSA9IG1vbWVudCh0eG4ucHJvY2Vzc2VkRGF0ZSwgcHJvY2Vzc2VkRGF0ZUZvcm1hdCk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgaWRlbnRpZmllcjogZ2V0SWRlbnRpZmllckFuZE51bWVyYXRvcih0eG4ub25jbGljayk/LmlkZW50aWZpZXIsXG4gICAgICB0eXBlOiBpbnN0YWxsbWVudHMgPyBUcmFuc2FjdGlvblR5cGVzLkluc3RhbGxtZW50cyA6IFRyYW5zYWN0aW9uVHlwZXMuTm9ybWFsLFxuICAgICAgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICAgIGRhdGU6IGluc3RhbGxtZW50cyA/IHR4bkRhdGUuYWRkKGluc3RhbGxtZW50cy5udW1iZXIgLSAxLCAnbW9udGgnKS50b0lTT1N0cmluZygpIDogdHhuRGF0ZS50b0lTT1N0cmluZygpLFxuICAgICAgcHJvY2Vzc2VkRGF0ZTogdHhuUHJvY2Vzc2VkRGF0ZS50b0lTT1N0cmluZygpLFxuICAgICAgb3JpZ2luYWxBbW91bnQ6IG9yaWdpbmFsQW1vdW50VHVwbGUuYW1vdW50LFxuICAgICAgb3JpZ2luYWxDdXJyZW5jeTogb3JpZ2luYWxBbW91bnRUdXBsZS5jdXJyZW5jeSxcbiAgICAgIGNoYXJnZWRBbW91bnQ6IGNoYXJnZWRBbW91bnRUdXBsZS5hbW91bnQsXG4gICAgICBjaGFyZ2VkQ3VycmVuY3k6IGNoYXJnZWRBbW91bnRUdXBsZS5jdXJyZW5jeSxcbiAgICAgIGRlc2NyaXB0aW9uOiB0eG4uZGVzY3JpcHRpb24gfHwgJycsXG4gICAgICBtZW1vOiB0eG4ubWVtbyB8fCAnJyxcbiAgICAgIGNhdGVnb3J5OiB0eG4uYWRkaXRpb25hbEluZm8/LmNhdGVnb3J5LFxuICAgIH07XG5cbiAgICBpZiAoaW5zdGFsbG1lbnRzKSB7XG4gICAgICByZXN1bHQuaW5zdGFsbG1lbnRzID0gaW5zdGFsbG1lbnRzO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBZGRpdGlvbmFsVHhJbmZvKHR4OiBTY3JhcGVkVHJhbnNhY3Rpb24sIHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFNjcmFwZWRBZGRpdGlvbmFsSW5mbyB8IG51bGw+IHtcbiAgY29uc3QgeyBpZGVudGlmaWVyLCBudW1lcmF0b3IgfSA9IGdldElkZW50aWZpZXJBbmROdW1lcmF0b3IodHgub25jbGljayk7XG4gIGlmIChpZGVudGlmaWVyID09PSB1bmRlZmluZWQgfHwgbnVtZXJhdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBmZXRjaFBvc3RXaXRoaW5QYWdlPGFueT4ocGFnZSwgR0VUX1RYX0RFVEFJTFNfVVJMLCB7XG4gICAgSWRlbnRpZmllcjogaWRlbnRpZmllcixcbiAgICBOdW1lcmF0b3I6IG51bWVyYXRvcixcbiAgfSwgR0VUX1RYX0RFVEFJTFNfSEVBREVSKTtcblxuICByZXR1cm4ge1xuICAgIGNhdGVnb3J5OiByZXN1bHQuZD8uRGF0YT8uTWVyY2hhbnREZXRhaWxzPy5TZWN0b3JOYW1lIHx8IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWRkaXRpb25hbFR4c0luZm9JZk5lZWRlZCh0eHM6IFNjcmFwZWRUcmFuc2FjdGlvbltdLCBzY3JhcGVyT3B0aW9uczogU2NyYXBlck9wdGlvbnMsIHBhZ2U6IFBhZ2UpOiBQcm9taXNlPFNjcmFwZWRUcmFuc2FjdGlvbltdPiB7XG4gIGlmICghc2NyYXBlck9wdGlvbnMuYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb24pIHtcbiAgICByZXR1cm4gdHhzO1xuICB9XG4gIGNvbnN0IHByb21pc2VzID0gdHhzLm1hcChhc3luYyAoeCkgPT4gKHtcbiAgICAuLi54LFxuICAgIGFkZGl0aW9uYWxJbmZvOiBhd2FpdCBnZXRBZGRpdGlvbmFsVHhJbmZvKHgsIHBhZ2UpLFxuICB9KSBhcyBTY3JhcGVkVHJhbnNhY3Rpb24pO1xuICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaFRyYW5zYWN0aW9uc0ZvckFjY291bnQocGFnZTogUGFnZSwgc3RhcnREYXRlOiBNb21lbnQsIGFjY291bnROdW1iZXI6IHN0cmluZywgc2NyYXBlck9wdGlvbnM6IFNjcmFwZXJPcHRpb25zKTogUHJvbWlzZTxUcmFuc2FjdGlvbnNBY2NvdW50PiB7XG4gIGNvbnN0IHN0YXJ0RGF0ZVZhbHVlID0gc3RhcnREYXRlLmZvcm1hdCgnTU0vWVlZWScpO1xuICBjb25zdCBkYXRlU2VsZWN0b3IgPSAnW2lkJD1cIkZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY2xuZHJEZWJpdERhdGVTY29wZV9UZXh0Qm94XCJdJztcbiAgY29uc3QgZGF0ZUhpZGRlbkZpZWxkU2VsZWN0b3IgPSAnW2lkJD1cIkZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY2xuZHJEZWJpdERhdGVTY29wZV9IaWRkZW5GaWVsZFwiXSc7XG4gIGNvbnN0IGJ1dHRvblNlbGVjdG9yID0gJ1tpZCQ9XCJGb3JtQXJlYU5vQm9yZGVyX0Zvcm1BcmVhX2N0bFN1Ym1pdFJlcXVlc3RcIl0nO1xuICBjb25zdCBuZXh0UGFnZVNlbGVjdG9yID0gJ1tpZCQ9XCJGb3JtQXJlYU5vQm9yZGVyX0Zvcm1BcmVhX2N0bEdyaWRQYWdlcl9idG5OZXh0XCJdJztcbiAgY29uc3QgYmlsbGluZ0xhYmVsU2VsZWN0b3IgPSAnW2lkJD1Gb3JtQXJlYU5vQm9yZGVyX0Zvcm1BcmVhX2N0bE1haW5Ub29sQmFyX2xibENhcHRpb25dJztcbiAgY29uc3Qgc2Vjb25kYXJ5QmlsbGluZ0xhYmVsU2VsZWN0b3IgPSAnW2lkJD1Gb3JtQXJlYU5vQm9yZGVyX0Zvcm1BcmVhX2N0bFNlY29uZGFyeVRvb2xCYXJfbGJsQ2FwdGlvbl0nO1xuICBjb25zdCBub0RhdGFTZWxlY3RvciA9ICdbaWQkPUZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfbXNnYm94RXJyb3JNZXNzYWdlc10nO1xuXG4gIGRlYnVnKCdmaW5kIHRoZSBzdGFydCBkYXRlIGluZGV4IGluIHRoZSBkcm9wYm94Jyk7XG4gIGNvbnN0IG9wdGlvbnMgPSBhd2FpdCBwYWdlRXZhbEFsbChwYWdlLCAnW2lkJD1cIkZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY2xuZHJEZWJpdERhdGVTY29wZV9PcHRpb25MaXN0XCJdIGxpJywgW10sIChpdGVtcykgPT4ge1xuICAgIHJldHVybiBpdGVtcy5tYXAoKGVsOiBhbnkpID0+IGVsLmlubmVyVGV4dCk7XG4gIH0pO1xuICBjb25zdCBzdGFydERhdGVJbmRleCA9IG9wdGlvbnMuZmluZEluZGV4KChvcHRpb24pID0+IG9wdGlvbiA9PT0gc3RhcnREYXRlVmFsdWUpO1xuXG4gIGRlYnVnKGBzY3JhcGUgJHtvcHRpb25zLmxlbmd0aCAtIHN0YXJ0RGF0ZUluZGV4fSBiaWxsaW5nIGN5Y2xlc2ApO1xuICBjb25zdCBhY2NvdW50VHJhbnNhY3Rpb25zOiBUcmFuc2FjdGlvbltdID0gW107XG4gIGZvciAobGV0IGN1cnJlbnREYXRlSW5kZXggPSBzdGFydERhdGVJbmRleDsgY3VycmVudERhdGVJbmRleCA8IG9wdGlvbnMubGVuZ3RoOyBjdXJyZW50RGF0ZUluZGV4ICs9IDEpIHtcbiAgICBkZWJ1Zygnd2FpdCBmb3IgZGF0ZSBzZWxlY3RvciB0byBiZSBmb3VuZCcpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCBkYXRlU2VsZWN0b3IsIHRydWUpO1xuICAgIGRlYnVnKGBzZXQgaGlkZGVuIHZhbHVlIG9mIHRoZSBkYXRlIHNlbGVjdG9yIHRvIGJlIHRoZSBpbmRleCAke2N1cnJlbnREYXRlSW5kZXh9YCk7XG4gICAgYXdhaXQgc2V0VmFsdWUocGFnZSwgZGF0ZUhpZGRlbkZpZWxkU2VsZWN0b3IsIGAke2N1cnJlbnREYXRlSW5kZXh9YCk7XG4gICAgZGVidWcoJ3dhaXQgYSBzZWNvbmQgdG8gd29ya2Fyb3VuZCBuYXZpZ2F0aW9uIGlzc3VlIGluIGhlYWRsZXNzIGJyb3dzZXIgbW9kZScpO1xuICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTAwMCk7XG4gICAgZGVidWcoJ2NsaWNrIG9uIHRoZSBmaWx0ZXIgc3VibWl0IGJ1dHRvbiBhbmQgd2FpdCBmb3IgbmF2aWdhdGlvbicpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIHBhZ2Uud2FpdEZvck5hdmlnYXRpb24oeyB3YWl0VW50aWw6ICdkb21jb250ZW50bG9hZGVkJyB9KSxcbiAgICAgIGNsaWNrQnV0dG9uKHBhZ2UsIGJ1dHRvblNlbGVjdG9yKSxcbiAgICBdKTtcbiAgICBkZWJ1ZygnY2hlY2sgaWYgbW9udGggaGFzIG5vIHRyYW5zYWN0aW9ucycpO1xuICAgIGNvbnN0IHBhZ2VIYXNOb1RyYW5zYWN0aW9ucyA9IGF3YWl0IHBhZ2VFdmFsKHBhZ2UsIG5vRGF0YVNlbGVjdG9yLCBmYWxzZSwgKChlbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBzaXRlVmFsdWUgPSAoKGVsZW1lbnQgYXMgSFRNTFNwYW5FbGVtZW50KS5pbm5lclRleHQgfHwgJycpLnJlcGxhY2UoL1teINeQLdeqXS9nLCAnJyk7XG4gICAgICByZXR1cm4gc2l0ZVZhbHVlID09PSAn15zXkCDXoNee16bXkNeVINeg16rXldeg15nXnSc7XG4gICAgfSkpO1xuXG4gICAgaWYgKHBhZ2VIYXNOb1RyYW5zYWN0aW9ucykge1xuICAgICAgZGVidWcoJ3BhZ2UgaGFzIG5vIHRyYW5zYWN0aW9ucycpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnZmluZCB0aGUgYmlsbGluZyBkYXRlJyk7XG4gICAgICBsZXQgYmlsbGluZ0RhdGVMYWJlbCA9IGF3YWl0IHBhZ2VFdmFsKHBhZ2UsIGJpbGxpbmdMYWJlbFNlbGVjdG9yLCAnJywgKChlbGVtZW50KSA9PiB7XG4gICAgICAgIHJldHVybiAoZWxlbWVudCBhcyBIVE1MU3BhbkVsZW1lbnQpLmlubmVyVGV4dDtcbiAgICAgIH0pKTtcbiAgICAgIGxldCBzZXR0bGVtZW50RGF0ZVJlZ2V4ID0gL1xcZHsxLDJ9Wy9dXFxkezJ9Wy9dXFxkezIsNH0vO1xuXG4gICAgICBpZiAoYmlsbGluZ0RhdGVMYWJlbCA9PT0gJycpIHtcbiAgICAgICAgYmlsbGluZ0RhdGVMYWJlbCA9IGF3YWl0IHBhZ2VFdmFsKHBhZ2UsIHNlY29uZGFyeUJpbGxpbmdMYWJlbFNlbGVjdG9yLCAnJywgKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIChlbGVtZW50IGFzIEhUTUxTcGFuRWxlbWVudCkuaW5uZXJUZXh0O1xuICAgICAgICB9KSk7XG4gICAgICAgIHNldHRsZW1lbnREYXRlUmVnZXggPSAvXFxkezEsMn1bL11cXGR7Miw0fS87XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJpbGxpbmdEYXRlID0gc2V0dGxlbWVudERhdGVSZWdleC5leGVjKGJpbGxpbmdEYXRlTGFiZWwpPy5bMF07XG5cbiAgICAgIGlmICghYmlsbGluZ0RhdGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gZmV0Y2ggcHJvY2VzcyBkYXRlJyk7XG4gICAgICB9XG5cbiAgICAgIGRlYnVnKGBmb3VuZCB0aGUgYmlsbGluZyBkYXRlIGZvciB0aGF0IG1vbnRoICR7YmlsbGluZ0RhdGV9YCk7XG4gICAgICBsZXQgaGFzTmV4dFBhZ2UgPSBmYWxzZTtcbiAgICAgIGRvIHtcbiAgICAgICAgZGVidWcoJ2ZldGNoIHJhdyB0cmFuc2FjdGlvbnMgZnJvbSBwYWdlJyk7XG4gICAgICAgIGNvbnN0IHJhd1RyYW5zYWN0aW9ucyA9IGF3YWl0IHBhZ2VFdmFsQWxsPChTY3JhcGVkVHJhbnNhY3Rpb24gfCBudWxsKVtdPihwYWdlLCAnI2N0bE1haW5HcmlkID4gdGJvZHkgdHIsICNjdGxTZWNvbmRhcnlHcmlkID4gdGJvZHkgdHInLCBbXSwgKGl0ZW1zLCBiaWxsaW5nRGF0ZSkgPT4ge1xuICAgICAgICAgIHJldHVybiAoaXRlbXMpLm1hcCgoZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbHVtbnMgPSBlbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGQnKTtcbiAgICAgICAgICAgIGNvbnN0IG9uY2xpY2sgPSBlbC5nZXRBdHRyaWJ1dGUoJ29uY2xpY2snKTtcbiAgICAgICAgICAgIGlmIChjb2x1bW5zLmxlbmd0aCA9PT0gNikge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG9uY2xpY2ssXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkRGF0ZTogY29sdW1uc1swXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgZGF0ZTogY29sdW1uc1sxXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGNvbHVtbnNbMl0uaW5uZXJUZXh0LFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQW1vdW50OiBjb2x1bW5zWzNdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBjaGFyZ2VkQW1vdW50OiBjb2x1bW5zWzRdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBtZW1vOiBjb2x1bW5zWzVdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2x1bW5zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG9uY2xpY2ssXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkRGF0ZTogYmlsbGluZ0RhdGUsXG4gICAgICAgICAgICAgICAgZGF0ZTogY29sdW1uc1swXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGNvbHVtbnNbMV0uaW5uZXJUZXh0LFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQW1vdW50OiBjb2x1bW5zWzJdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBjaGFyZ2VkQW1vdW50OiBjb2x1bW5zWzNdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBtZW1vOiBjb2x1bW5zWzRdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBiaWxsaW5nRGF0ZSk7XG4gICAgICAgIGRlYnVnKGBmZXRjaGVkICR7cmF3VHJhbnNhY3Rpb25zLmxlbmd0aH0gcmF3IHRyYW5zYWN0aW9ucyBmcm9tIHBhZ2VgKTtcbiAgICAgICAgY29uc3QgZXhpc3RzVHhzID0gKHJhd1RyYW5zYWN0aW9ucyBhcyBTY3JhcGVkVHJhbnNhY3Rpb25bXSlcbiAgICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiAhIWl0ZW0pO1xuICAgICAgICBjb25zdCBmdWxsU2NyYXBwZWRUeHMgPSBhd2FpdCBnZXRBZGRpdGlvbmFsVHhzSW5mb0lmTmVlZGVkKGV4aXN0c1R4cywgc2NyYXBlck9wdGlvbnMsIHBhZ2UpO1xuXG4gICAgICAgIGFjY291bnRUcmFuc2FjdGlvbnMucHVzaCguLi5jb252ZXJ0VHJhbnNhY3Rpb25zKGZ1bGxTY3JhcHBlZFR4cykpO1xuXG4gICAgICAgIGRlYnVnKCdjaGVjayBmb3IgZXhpc3RlbmNlIG9mIGFub3RoZXIgcGFnZScpO1xuICAgICAgICBoYXNOZXh0UGFnZSA9IGF3YWl0IGVsZW1lbnRQcmVzZW50T25QYWdlKHBhZ2UsIG5leHRQYWdlU2VsZWN0b3IpO1xuICAgICAgICBpZiAoaGFzTmV4dFBhZ2UpIHtcbiAgICAgICAgICBkZWJ1ZygnaGFzIGFub3RoZXIgcGFnZSwgY2xpY2sgb24gYnV0dG9uIG5leHQgYW5kIHdhaXQgZm9yIHBhZ2UgbmF2aWdhdGlvbicpO1xuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHBhZ2Uud2FpdEZvck5hdmlnYXRpb24oeyB3YWl0VW50aWw6ICdkb21jb250ZW50bG9hZGVkJyB9KSxcbiAgICAgICAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKHBhZ2UsICdbaWQkPUZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsR3JpZFBhZ2VyX2J0bk5leHRdJyksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKGhhc05leHRQYWdlKTtcbiAgICB9XG4gIH1cblxuICBkZWJ1ZygnZmlsZXIgb3V0IG9sZCB0cmFuc2FjdGlvbnMnKTtcbiAgY29uc3QgdHhucyA9IChzY3JhcGVyT3B0aW9ucy5vdXRwdXREYXRhPy5lbmFibGVUcmFuc2FjdGlvbnNGaWx0ZXJCeURhdGUgPz8gdHJ1ZSkgP1xuICAgIGZpbHRlck9sZFRyYW5zYWN0aW9ucyhhY2NvdW50VHJhbnNhY3Rpb25zLCBzdGFydERhdGUsIHNjcmFwZXJPcHRpb25zLmNvbWJpbmVJbnN0YWxsbWVudHMgfHwgZmFsc2UpIDpcbiAgICBhY2NvdW50VHJhbnNhY3Rpb25zO1xuICBkZWJ1ZyhgZm91bmQgJHt0eG5zLmxlbmd0aH0gdmFsaWQgdHJhbnNhY3Rpb25zIG91dCBvZiAke2FjY291bnRUcmFuc2FjdGlvbnMubGVuZ3RofSB0cmFuc2FjdGlvbnMgZm9yIGFjY291bnQgZW5kaW5nIHdpdGggJHthY2NvdW50TnVtYmVyLnN1YnN0cmluZyhhY2NvdW50TnVtYmVyLmxlbmd0aCAtIDIpfWApO1xuICByZXR1cm4ge1xuICAgIGFjY291bnROdW1iZXIsXG4gICAgdHhucyxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWNjb3VudE51bWJlcnMocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgcmV0dXJuIHBhZ2VFdmFsQWxsKHBhZ2UsICdbaWQkPWxua0l0ZW1dJywgW10sIChlbGVtZW50cykgPT4gZWxlbWVudHMubWFwKChlKSA9PiAoZSBhcyBIVE1MQW5jaG9yRWxlbWVudCkudGV4dCkpLnRoZW4oKHJlcykgPT4gcmVzLm1hcCgodGV4dCkgPT4gL1xcZCskLy5leGVjKHRleHQudHJpbSgpKT8uWzBdID8/ICcnKSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNldEFjY291bnQocGFnZTogUGFnZSwgYWNjb3VudDogc3RyaW5nKSB7XG4gIGF3YWl0IHBhZ2VFdmFsQWxsKFxuICAgIHBhZ2UsXG4gICAgJ1tpZCQ9bG5rSXRlbV0nLFxuICAgIG51bGwsXG4gICAgKGVsZW1lbnRzLCBhY2NvdW50KSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW0gb2YgZWxlbWVudHMpIHtcbiAgICAgICAgY29uc3QgYSA9IGVsZW0gYXMgSFRNTEFuY2hvckVsZW1lbnQ7XG4gICAgICAgIGlmIChhLnRleHQuaW5jbHVkZXMoYWNjb3VudCkpIHtcbiAgICAgICAgICBhLmNsaWNrKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgIGFjY291bnQsXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoVHJhbnNhY3Rpb25zKHBhZ2U6IFBhZ2UsIHN0YXJ0RGF0ZTogTW9tZW50LCBzY3JhcGVyT3B0aW9uczogU2NyYXBlck9wdGlvbnMpOiBQcm9taXNlPFRyYW5zYWN0aW9uc0FjY291bnRbXT4ge1xuICBjb25zdCBhY2NvdW50TnVtYmVyczogc3RyaW5nW10gPSBhd2FpdCBnZXRBY2NvdW50TnVtYmVycyhwYWdlKTtcbiAgY29uc3QgYWNjb3VudHM6IFRyYW5zYWN0aW9uc0FjY291bnRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYWNjb3VudCBvZiBhY2NvdW50TnVtYmVycykge1xuICAgIGRlYnVnKGBzZXR0aW5nIGFjY291bnQ6ICR7YWNjb3VudH1gKTtcbiAgICBhd2FpdCBzZXRBY2NvdW50KHBhZ2UsIGFjY291bnQpO1xuICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTAwMCk7XG4gICAgYWNjb3VudHMucHVzaChcbiAgICAgIGF3YWl0IGZldGNoVHJhbnNhY3Rpb25zRm9yQWNjb3VudChcbiAgICAgICAgcGFnZSxcbiAgICAgICAgc3RhcnREYXRlLFxuICAgICAgICBhY2NvdW50LFxuICAgICAgICBzY3JhcGVyT3B0aW9ucyxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBhY2NvdW50cztcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hGdXR1cmVEZWJpdHMocGFnZTogUGFnZSkge1xuICBjb25zdCBmdXR1cmVEZWJpdHNTZWxlY3RvciA9ICcuaG9tZXBhZ2UtYmFua3MtdG9wJztcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlRXZhbEFsbChwYWdlLCBmdXR1cmVEZWJpdHNTZWxlY3RvciwgW10sIChpdGVtcykgPT4ge1xuICAgIGNvbnN0IGRlYml0TW91bnRDbGFzcyA9ICdhbW91bnQnO1xuICAgIGNvbnN0IGRlYml0V2hlbkNoYXJnZUNsYXNzID0gJ3doZW4tY2hhcmdlJztcbiAgICBjb25zdCBkZWJpdEJhbmtOdW1iZXJDbGFzcyA9ICdiYW5rRGVzYyc7XG5cbiAgICByZXR1cm4gaXRlbXMubWFwKChjdXJyQmFua0VsOiBhbnkpID0+IHtcbiAgICAgIGNvbnN0IGFtb3VudCA9IGN1cnJCYW5rRWwuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShkZWJpdE1vdW50Q2xhc3MpWzBdLmlubmVyVGV4dDtcbiAgICAgIGNvbnN0IHdoZW5DaGFyZ2UgPSBjdXJyQmFua0VsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoZGViaXRXaGVuQ2hhcmdlQ2xhc3MpWzBdLmlubmVyVGV4dDtcbiAgICAgIGNvbnN0IGJhbmtOdW1iZXIgPSBjdXJyQmFua0VsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoZGViaXRCYW5rTnVtYmVyQ2xhc3MpWzBdLmlubmVyVGV4dDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgd2hlbkNoYXJnZSxcbiAgICAgICAgYmFua051bWJlcixcbiAgICAgIH07XG4gICAgfSk7XG4gIH0pO1xuICBjb25zdCBmdXR1cmVEZWJpdHMgPSByZXN1bHQubWFwKChpdGVtKSA9PiB7XG4gICAgY29uc3QgYW1vdW50RGF0YSA9IGdldEFtb3VudERhdGEoaXRlbS5hbW91bnQpO1xuICAgIGNvbnN0IGNoYXJnZURhdGUgPSAvXFxkezEsMn1bL11cXGR7Mn1bL11cXGR7Miw0fS8uZXhlYyhpdGVtLndoZW5DaGFyZ2UpPy5bMF07XG4gICAgY29uc3QgYmFua0FjY291bnROdW1iZXIgPSAvXFxkKy1cXGQrLy5leGVjKGl0ZW0uYmFua051bWJlcik/LlswXTtcbiAgICByZXR1cm4ge1xuICAgICAgYW1vdW50OiBhbW91bnREYXRhLmFtb3VudCxcbiAgICAgIGFtb3VudEN1cnJlbmN5OiBhbW91bnREYXRhLmN1cnJlbmN5LFxuICAgICAgY2hhcmdlRGF0ZSxcbiAgICAgIGJhbmtBY2NvdW50TnVtYmVyLFxuICAgIH07XG4gIH0pO1xuICByZXR1cm4gZnV0dXJlRGViaXRzO1xufVxuXG5jbGFzcyBWaXNhQ2FsU2NyYXBlciBleHRlbmRzIEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIge1xuICBvcGVuTG9naW5Qb3B1cCA9IGFzeW5jICgpID0+IHtcbiAgICBkZWJ1Zygnb3BlbiBsb2dpbiBwb3B1cCwgd2FpdCB1bnRpbCBsb2dpbiBidXR0b24gYXZhaWxhYmxlJyk7XG4gICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKHRoaXMucGFnZSwgJyNjY0xvZ2luRGVza3RvcEJ0bicsIHRydWUpO1xuICAgIGRlYnVnKCdjbGljayBvbiB0aGUgbG9naW4gYnV0dG9uJyk7XG4gICAgYXdhaXQgY2xpY2tCdXR0b24odGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJyk7XG4gICAgZGVidWcoJ2dldCB0aGUgZnJhbWUgdGhhdCBob2xkcyB0aGUgbG9naW4nKTtcbiAgICBjb25zdCBmcmFtZSA9IGF3YWl0IGdldExvZ2luRnJhbWUodGhpcy5wYWdlKTtcbiAgICBkZWJ1Zygnd2FpdCB1bnRpbCB0aGUgcGFzc3dvcmQgbG9naW4gdGFiIGhlYWRlciBpcyBhdmFpbGFibGUnKTtcbiAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQoZnJhbWUsICcjcmVndWxhci1sb2dpbicpO1xuICAgIGRlYnVnKCduYXZpZ2F0ZSB0byB0aGUgcGFzc3dvcmQgbG9naW4gdGFiJyk7XG4gICAgYXdhaXQgY2xpY2tCdXR0b24oZnJhbWUsICcjcmVndWxhci1sb2dpbicpO1xuICAgIGRlYnVnKCd3YWl0IHVudGlsIHRoZSBwYXNzd29yZCBsb2dpbiB0YWIgaXMgYWN0aXZlJyk7XG4gICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKGZyYW1lLCAncmVndWxhci1sb2dpbicpO1xuXG4gICAgcmV0dXJuIGZyYW1lO1xuICB9O1xuXG4gIGdldExvZ2luT3B0aW9ucyhjcmVkZW50aWFsczogUmVjb3JkPHN0cmluZywgc3RyaW5nPikge1xuICAgIHJldHVybiB7XG4gICAgICBsb2dpblVybDogYCR7TE9HSU5fVVJMfWAsXG4gICAgICBmaWVsZHM6IGNyZWF0ZUxvZ2luRmllbGRzKGNyZWRlbnRpYWxzKSxcbiAgICAgIHN1Ym1pdEJ1dHRvblNlbGVjdG9yOiAnYnV0dG9uW3R5cGU9XCJzdWJtaXRcIl0nLFxuICAgICAgcG9zc2libGVSZXN1bHRzOiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpLFxuICAgICAgY2hlY2tSZWFkaW5lc3M6IGFzeW5jICgpID0+IHdhaXRVbnRpbEVsZW1lbnRGb3VuZCh0aGlzLnBhZ2UsICcjY2NMb2dpbkRlc2t0b3BCdG4nKSxcbiAgICAgIHByZUFjdGlvbjogdGhpcy5vcGVuTG9naW5Qb3B1cCxcbiAgICAgIHVzZXJBZ2VudDogJ01vemlsbGEvNS4wIChYMTE7IExpbnV4IHg4Nl82NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzc4LjAuMzkwNC4xMDggU2FmYXJpLzUzNy4zNicsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoRGF0YSgpOiBQcm9taXNlPFNjYXBlclNjcmFwaW5nUmVzdWx0PiB7XG4gICAgY29uc3QgZGVmYXVsdFN0YXJ0TW9tZW50ID0gbW9tZW50KCkuc3VidHJhY3QoMSwgJ3llYXJzJykuYWRkKDEsICdkYXknKTtcbiAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLm9wdGlvbnMuc3RhcnREYXRlIHx8IGRlZmF1bHRTdGFydE1vbWVudC50b0RhdGUoKTtcbiAgICBjb25zdCBzdGFydE1vbWVudCA9IG1vbWVudC5tYXgoZGVmYXVsdFN0YXJ0TW9tZW50LCBtb21lbnQoc3RhcnREYXRlKSk7XG4gICAgZGVidWcoYGZldGNoIHRyYW5zYWN0aW9ucyBzdGFydGluZyAke3N0YXJ0TW9tZW50LmZvcm1hdCgpfWApO1xuXG4gICAgZGVidWcoJ2ZldGNoIGZ1dHVyZSBkZWJpdHMnKTtcbiAgICBjb25zdCBmdXR1cmVEZWJpdHMgPSBhd2FpdCBmZXRjaEZ1dHVyZURlYml0cyh0aGlzLnBhZ2UpO1xuXG4gICAgZGVidWcoJ25hdmlnYXRlIHRvIHRyYW5zYWN0aW9ucyBwYWdlJyk7XG4gICAgYXdhaXQgdGhpcy5uYXZpZ2F0ZVRvKFRSQU5TQUNUSU9OU19VUkwsIHVuZGVmaW5lZCwgNjAwMDApO1xuXG4gICAgZGVidWcoJ2ZldGNoIGFjY291bnRzIHRyYW5zYWN0aW9ucycpO1xuICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgZmV0Y2hUcmFuc2FjdGlvbnModGhpcy5wYWdlLCBzdGFydE1vbWVudCwgdGhpcy5vcHRpb25zKTtcblxuICAgIGRlYnVnKCdyZXR1cm4gdGhlIHNjcmFwZWQgYWNjb3VudHMnKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIGFjY291bnRzLFxuICAgICAgZnV0dXJlRGViaXRzLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgVmlzYUNhbFNjcmFwZXI7XG4iXX0=
306
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy92aXNhLWNhbC50cyJdLCJuYW1lcyI6WyJMT0dJTl9VUkwiLCJUUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCIsIkludmFsaWRQYXNzd29yZE1lc3NhZ2UiLCJkZWJ1ZyIsInRyblR5cGVDb2RlIiwiZ2V0TG9naW5GcmFtZSIsInBhZ2UiLCJmcmFtZSIsImZyYW1lcyIsImZpbmQiLCJmIiwidXJsIiwiaW5jbHVkZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIkVycm9yIiwiaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IiLCJlcnJvckZvdW5kIiwiZXJyb3JNZXNzYWdlIiwiaXRlbSIsImlubmVyVGV4dCIsImdldFBvc3NpYmxlTG9naW5SZXN1bHRzIiwidXJscyIsIkxvZ2luUmVzdWx0cyIsIlN1Y2Nlc3MiLCJJbnZhbGlkUGFzc3dvcmQiLCJvcHRpb25zIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidmFsdWUiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiY2FyZEFuZFRyYW5zYWN0aW9uQ3VycmVuY3lTeW1ib2xJc1NoZWtlbCIsInRyYW5zYWN0aW9uIiwiZGViQ3JkQ3VycmVuY3lTeW1ib2wiLCJTSEVLRUxfQ1VSUkVOQ1lfU1lNQk9MIiwidHJuQ3VycmVuY3lTeW1ib2wiLCJjb252ZXJ0UGFyc2VkRGF0YVRvVHJhbnNhY3Rpb25zIiwicGFyc2VkRGF0YSIsImZsYXRNYXAiLCJtb250aERhdGEiLCJyZXN1bHQiLCJiYW5rQWNjb3VudHMiLCJhY2NvdW50cyIsImRlYml0RGF0ZXMiLCJkZWJpdERhdGUiLCJ0cmFuc2FjdGlvbnMiLCJtYXAiLCJpbnN0YWxsbWVudHMiLCJjdXJQYXltZW50TnVtIiwibnVtT2ZQYXltZW50cyIsIm51bWJlciIsInRvdGFsIiwidW5kZWZpbmVkIiwiZGF0ZSIsInRyblB1cmNoYXNlRGF0ZSIsImNoYXJnZWRBbW91bnQiLCJhbXRCZWZvcmVDb252QW5kSW5kZXgiLCJ0cm5BbXQiLCJjcmVkaXQiLCJkZXNjcmlwdGlvbiIsIm1lcmNoYW50TmFtZSIsIm9yaWdpbmFsQW1vdW50Iiwib3JpZ2luYWxDdXJyZW5jeSIsInByb2Nlc3NlZERhdGUiLCJkZWJDcmREYXRlIiwic3RhdHVzIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIkNvbXBsZXRlZCIsImFkZCIsInRvSVNPU3RyaW5nIiwidHlwZSIsInJlZ3VsYXIiLCJzdGFuZGluZ09yZGVyIiwiVHJhbnNhY3Rpb25UeXBlcyIsIk5vcm1hbCIsIkluc3RhbGxtZW50cyIsIlZpc2FDYWxTY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImdldENhcmRzIiwiaW5pdERhdGEiLCJjYXJkcyIsImNhcmRVbmlxdWVJZCIsImxhc3Q0RGlnaXRzIiwiZ2V0QXV0aG9yaXphdGlvbkhlYWRlciIsImF1dGhNb2R1bGUiLCJhdXRoIiwiY2FsQ29ubmVjdFRva2VuIiwiZ2V0WFNpdGVJZCIsImdldExvZ2luT3B0aW9ucyIsImxvZ2luVXJsIiwiZmllbGRzIiwic3VibWl0QnV0dG9uU2VsZWN0b3IiLCJwb3NzaWJsZVJlc3VsdHMiLCJjaGVja1JlYWRpbmVzcyIsInByZUFjdGlvbiIsIm9wZW5Mb2dpblBvcHVwIiwicG9zdEFjdGlvbiIsImN1cnJlbnRVcmwiLCJlbmRzV2l0aCIsImUiLCJ1c2VyQWdlbnQiLCJpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMiLCJmZXRjaERhdGEiLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJzdWJ0cmFjdCIsInN0YXJ0RGF0ZSIsInRvRGF0ZSIsInN0YXJ0TW9tZW50IiwibW9tZW50IiwibWF4IiwiZm9ybWF0IiwiQXV0aG9yaXphdGlvbiIsInNldFRpbWVvdXQiLCJ4U2l0ZUlkIiwiYWxsIiwiY2FyZCIsIm5leHRCaWxsaW5nTW9udGgiLCJtb250aHMiLCJkaWZmIiwiYWxsTW9udGhzRGF0YSIsImkiLCJtb250aCIsImNsb25lIiwieWVhciIsInN0YXR1c0NvZGUiLCJ0aXRsZSIsInB1c2giLCJ0eG5zIiwib3V0cHV0RGF0YSIsImVuYWJsZVRyYW5zYWN0aW9uc0ZpbHRlckJ5RGF0ZSIsImNvbWJpbmVJbnN0YWxsbWVudHMiLCJhY2NvdW50TnVtYmVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInN1Y2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUdBOztBQUNBOztBQUNBOztBQUdBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQU1BOzs7Ozs7QUFHQSxNQUFNQSxTQUFTLEdBQUcsK0JBQWxCO0FBQ0EsTUFBTUMsNkJBQTZCLEdBQUcsOEZBQXRDO0FBRUEsTUFBTUMsc0JBQXNCLEdBQUcsbUNBQS9CO0FBRUEsTUFBTUMsS0FBSyxHQUFHLHFCQUFTLFVBQVQsQ0FBZDtJQUVLQyxXOztXQUFBQSxXO0FBQUFBLEVBQUFBLFc7QUFBQUEsRUFBQUEsVztBQUFBQSxFQUFBQSxXO0FBQUFBLEVBQUFBLFc7R0FBQUEsVyxLQUFBQSxXOztBQWlHTCxlQUFlQyxhQUFmLENBQTZCQyxJQUE3QixFQUF5QztBQUN2QyxNQUFJQyxLQUFtQixHQUFHLElBQTFCO0FBQ0FKLEVBQUFBLEtBQUssQ0FBQyw4QkFBRCxDQUFMO0FBQ0EsUUFBTSx3QkFBVSxNQUFNO0FBQ3BCSSxJQUFBQSxLQUFLLEdBQUdELElBQUksQ0FDVEUsTUFESyxHQUVMQyxJQUZLLENBRUNDLENBQUQsSUFBT0EsQ0FBQyxDQUFDQyxHQUFGLEdBQVFDLFFBQVIsQ0FBaUIsWUFBakIsQ0FGUCxLQUUwQyxJQUZsRDtBQUdBLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixDQUFDLENBQUNQLEtBQWxCLENBQVA7QUFDRCxHQUxLLEVBS0gsaUNBTEcsRUFLZ0MsS0FMaEMsRUFLdUMsSUFMdkMsQ0FBTjs7QUFPQSxNQUFJLENBQUNBLEtBQUwsRUFBWTtBQUNWSixJQUFBQSxLQUFLLENBQUMsMkNBQUQsQ0FBTDtBQUNBLFVBQU0sSUFBSVksS0FBSixDQUFVLGdDQUFWLENBQU47QUFDRDs7QUFFRCxTQUFPUixLQUFQO0FB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LFNBQTlCLENBQUwsRUFBK0M7QUFDN0MsZ0JBQU0sSUFBSTFCLEtBQUosQ0FBVSxpREFBVixDQUFOO0FBQ0Q7O0FBRUQwRyxRQUFBQSxhQUFhLENBQUNPLElBQWQsQ0FBbUJ2RixTQUFuQjtBQUNEOztBQUVELFlBQU1NLFlBQVksR0FBR1QsK0JBQStCLENBQUNtRixhQUFELENBQXBEO0FBRUF0SCxNQUFBQSxLQUFLLENBQUMsNEJBQUQsQ0FBTDtBQUNBLFlBQU04SCxJQUFJLEdBQUcsb0RBQUMsS0FBS3ZHLE9BQUwsQ0FBYXdHLFVBQWQsMkRBQUMsdUJBQXlCQyw4QkFBMUIseUVBQTRELElBQTVELElBQ1gseUNBQXNCcEYsWUFBdEIsRUFBb0MscUJBQU80RCxTQUFQLENBQXBDLEVBQXVELEtBQUtqRixPQUFMLENBQWEwRyxtQkFBYixJQUFvQyxLQUEzRixDQURXLEdBRVhyRixZQUZGO0FBSUEsYUFBTztBQUNMa0YsUUFBQUEsSUFESztBQUVMSSxRQUFBQSxhQUFhLEVBQUVoQixJQUFJLENBQUNqQztBQUZmLE9BQVA7QUFJRCxLQXZDRCxDQURxQixDQUF2QjtBQTJDQWpGLElBQUFBLEtBQUssQ0FBQyw2QkFBRCxDQUFMO0FBRUFBLElBQUFBLEtBQUssQ0FBQ21JLElBQUksQ0FBQ0MsU0FBTCxDQUFlM0YsUUFBZixFQUF5QixJQUF6QixFQUErQixDQUEvQixDQUFELENBQUw7QUFDQSxXQUFPO0FBQ0w0RixNQUFBQSxPQUFPLEVBQUUsSUFESjtBQUVMNUYsTUFBQUE7QUFGSyxLQUFQO0FBSUQ7O0FBako2RTs7ZUFvSmpFa0MsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IEZyYW1lLCBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcblxuaW1wb3J0IHsgU0hFS0VMX0NVUlJFTkNZX1NZTUJPTCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBnZXREZWJ1ZyB9IGZyb20gJy4uL2hlbHBlcnMvZGVidWcnO1xuaW1wb3J0IHtcbiAgY2xpY2tCdXR0b24sIGVsZW1lbnRQcmVzZW50T25QYWdlLCBwYWdlRXZhbCwgd2FpdFVudGlsRWxlbWVudEZvdW5kLFxufSBmcm9tICcuLi9oZWxwZXJzL2VsZW1lbnRzLWludGVyYWN0aW9ucyc7XG5pbXBvcnQgeyBmZXRjaFBvc3RXaXRoaW5QYWdlIH0gZnJvbSAnLi4vaGVscGVycy9mZXRjaCc7XG5pbXBvcnQgeyBnZXRDdXJyZW50VXJsIH0gZnJvbSAnLi4vaGVscGVycy9uYXZpZ2F0aW9uJztcbmltcG9ydCB7IGdldEZyb21TZXNzaW9uU3RvcmFnZSB9IGZyb20gJy4uL2hlbHBlcnMvc3RvcmFnZSc7XG5pbXBvcnQgeyBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHtcbiAgVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uU3RhdHVzZXMsXG4gIFRyYW5zYWN0aW9uVHlwZXMsXG4gIFRyYW5zYWN0aW9uc0FjY291bnQsXG59IGZyb20gJy4uL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBCYXNlU2NyYXBlcldpdGhCcm93c2VyLCBMb2dpbk9wdGlvbnMsIExvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQgeyBTY3JhcGVyU2NyYXBpbmdSZXN1bHQgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmNvbnN0IExPR0lOX1VSTCA9ICdodHRwczovL3d3dy5jYWwtb25saW5lLmNvLmlsLyc7XG5jb25zdCBUUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCA9ICdodHRwczovL2FwaS5jYWwtb25saW5lLmNvLmlsL1RyYW5zYWN0aW9ucy9hcGkvdHJhbnNhY3Rpb25zRGV0YWlscy9nZXRDYXJkVHJhbnNhY3Rpb25zRGV0YWlscyc7XG5cbmNvbnN0IEludmFsaWRQYXNzd29yZE1lc3NhZ2UgPSAn16nXnSDXlNee16nXqtee16kg15DXlSDXlNeh15nXodee15Qg16nXlNeV15bXoNeVINep15LXldeZ15nXnSc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ3Zpc2EtY2FsJyk7XG5cbmVudW0gdHJuVHlwZUNvZGUge1xuICByZWd1bGFyID0gJzUnLFxuICBjcmVkaXQgPSAnNicsXG4gIGluc3RhbGxtZW50cyA9ICc4JyxcbiAgc3RhbmRpbmdPcmRlciA9ICc5Jyxcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIGFtdEJlZm9yZUNvbnZBbmRJbmRleDogbnVtYmVyO1xuICBicmFuY2hDb2RlRGVzYzogc3RyaW5nO1xuICBjYXNoQWNjTWFuYWdlck5hbWU6IG51bGw7XG4gIGNhc2hBY2NvdW50TWFuYWdlcjogbnVsbDtcbiAgY2FzaEFjY291bnRUcm5BbXQ6IG51bWJlcjtcbiAgY2hhcmdlRXh0ZXJuYWxUb0NhcmRDb21tZW50OiBzdHJpbmc7XG4gIGNvbW1lbnRzOiBbXTtcbiAgY3VyUGF5bWVudE51bTogbnVtYmVyO1xuICBkZWJDcmRDdXJyZW5jeVN5bWJvbDogQ3VycmVuY3lTeW1ib2w7XG4gIGRlYkNyZERhdGU6IHN0cmluZztcbiAgZGViaXRTcHJlYWRJbmQ6IGJvb2xlYW47XG4gIGRpc2NvdW50QW1vdW50OiB1bmtub3duO1xuICBkaXNjb3VudFJlYXNvbjogdW5rbm93bjtcbiAgaW1tZWRpYXRlQ29tbWVudHM6IFtdO1xuICBpc0ltbWVkaWF0ZUNvbW1lbnRJbmQ6IGJvb2xlYW47XG4gIGlzSW1tZWRpYXRlSEhLSW5kOiBib29sZWFuO1xuICBpc01hcmdhcml0YTogYm9vbGVhbjtcbiAgaXNTcHJlYWRQYXltZW5zdEFicm9hZDogYm9vbGVhbjtcbiAgbGlua2VkQ29tbWVudHM6IFtdO1xuICBtZXJjaGFudEFkZHJlc3M6IHN0cmluZztcbiAgbWVyY2hhbnROYW1lOiBzdHJpbmc7XG4gIG1lcmNoYW50UGhvbmVObzogc3RyaW5nO1xuICBudW1PZlBheW1lbnRzOiBudW1iZXI7XG4gIG9uR29pbmdUcmFuc2FjdGlvbnNDb21tZW50OiBzdHJpbmc7XG4gIHJlZnVuZEluZDogYm9vbGVhbjtcbiAgcm91bmRpbmdBbW91bnQ6IHVua25vd247XG4gIHJvdW5kaW5nUmVhc29uOiB1bmtub3duO1xuICB0b2tlbkluZDogMDtcbiAgdG9rZW5OdW1iZXJQYXJ0NDogJyc7XG4gIHRyYW5zQ2FyZFByZXNlbnRJbmQ6IGJvb2xlYW47XG4gIHRyYW5zVHlwZUNvbW1lbnREZXRhaWxzOiBbXTtcbiAgdHJuQW10OiBudW1iZXI7XG4gIHRybkN1cnJlbmN5U3ltYm9sOiBDdXJyZW5jeVN5bWJvbDtcbiAgdHJuRXhhY1dheTogbnVtYmVyO1xuICB0cm5JbnRJZDogc3RyaW5nO1xuICB0cm5OdW1hcmV0b3I6IG51bWJlcjtcbiAgdHJuUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gIHRyblR5cGU6IHN0cmluZztcbiAgdHJuVHlwZUNvZGU6IHRyblR5cGVDb2RlO1xuICB3YWxsZXRQcm92aWRlckNvZGU6IDA7XG4gIHdhbGxldFByb3ZpZGVyRGVzYzogJyc7XG59XG5pbnRlcmZhY2UgSW5pdFJlc3BvbnNlIHtcbiAgcmVzdWx0OiB7XG4gICAgY2FyZHM6IHtcbiAgICAgIGNhcmRVbmlxdWVJZDogc3RyaW5nO1xuICAgICAgbGFzdDREaWdpdHM6IHN0cmluZztcbiAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gICAgfVtdO1xuICB9O1xufVxudHlwZSBDdXJyZW5jeVN5bWJvbCA9ICfigqonIHwgc3RyaW5nO1xuaW50ZXJmYWNlIENhcmRUcmFuc2FjdGlvbkRldGFpbHNFcnJvciB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHN0YXR1c0NvZGU6IG51bWJlcjtcbn1cbmludGVyZmFjZSBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIGV4dGVuZHMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yIHtcbiAgcmVzdWx0OiB7XG4gICAgYmFua0FjY291bnRzOiB7XG4gICAgICBiYW5rQWNjb3VudE51bTogc3RyaW5nO1xuICAgICAgYmFua05hbWU6IHN0cmluZztcbiAgICAgIGNob2ljZUV4dGVybmFsVHJhbnNhY3Rpb25zOiBhbnk7XG4gICAgICBjdXJyZW50QmFua0FjY291bnRJbmQ6IGJvb2xlYW47XG4gICAgICBkZWJpdERhdGVzOiB7XG4gICAgICAgIGJhc2tldEFtb3VudENvbW1lbnQ6IHVua25vd247XG4gICAgICAgIGNob2ljZUhIS0RlYml0OiBudW1iZXI7XG4gICAgICAgIGRhdGU6IHN0cmluZztcbiAgICAgICAgZGViaXRSZWFzb246IHVua25vd247XG4gICAgICAgIGZpeERlYml0QW1vdW50OiBudW1iZXI7XG4gICAgICAgIGZyb21QdXJjaGFzZURhdGU6IHN0cmluZztcbiAgICAgICAgaXNDaG9pY2VSZXBhaW1lbnQ6IGJvb2xlYW47XG4gICAgICAgIHRvUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gICAgICAgIHRvdGFsQmFza2V0QW1vdW50OiBudW1iZXI7XG4gICAgICAgIHRvdGFsRGViaXRzOiB7XG4gICAgICAgICAgY3VycmVuY3lTeW1ib2w6IEN1cnJlbmN5U3ltYm9sO1xuICAgICAgICAgIGFtb3VudDogbnVtYmVyO1xuICAgICAgICB9W107XG4gICAgICAgIHRyYW5zYWN0aW9uczogU2NyYXBlZFRyYW5zYWN0aW9uW107XG4gICAgICB9W107XG4gICAgICBpbW1pZGlhdGVEZWJpdHM6IHsgdG90YWxEZWJpdHM6IFtdLCBkZWJpdERheXM6IFtdIH07XG4gICAgfVtdO1xuICAgIGJsb2NrZWRDYXJkSW5kOiBib29sZWFuO1xuICB9O1xuICBzdGF0dXNDb2RlOiAxO1xuICBzdGF0dXNEZXNjcmlwdGlvbjogc3RyaW5nO1xuICBzdGF0dXNUaXRsZTogc3RyaW5nO1xufVxuXG5cbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2luRnJhbWUocGFnZTogUGFnZSkge1xuICBsZXQgZnJhbWU6IEZyYW1lIHwgbnVsbCA9IG51bGw7XG4gIGRlYnVnKCd3YWl0IHVudGlsIGxvZ2luIGZyYW1lIGZvdW5kJyk7XG4gIGF3YWl0IHdhaXRVbnRpbCgoKSA9PiB7XG4gICAgZnJhbWUgPSBwYWdlXG4gICAgICAuZnJhbWVzKClcbiAgICAgIC5maW5kKChmKSA9PiBmLnVybCgpLmluY2x1ZGVzKCdjYWxjb25uZWN0JykpIHx8IG51bGw7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSghIWZyYW1lKTtcbiAgfSwgJ3dhaXQgZm9yIGlmcmFtZSB3aXRoIGxvZ2luIGZvcm0nLCAxMDAwMCwgMTAwMCk7XG5cbiAgaWYgKCFmcmFtZSkge1xuICAgIGRlYnVnKCdmYWlsZWQgdG8gZmluZCBsb2dpbiBmcmFtZSBmb3IgMTAgc2Vjb25kcycpO1xuICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGV4dHJhY3QgbG9naW4gaWZyYW1lJyk7XG4gIH1cblxuICByZXR1cm4gZnJhbWU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhc0ludmFsaWRQYXNzd29yZEVycm9yKHBhZ2U6IFBhZ2UpIHtcbiAgY29uc3QgZnJhbWUgPSBhd2FpdCBnZXRMb2dpbkZyYW1lKHBhZ2UpO1xuICBjb25zdCBlcnJvckZvdW5kID0gYXdhaXQgZWxlbWVudFByZXNlbnRPblBhZ2UoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicpO1xuICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvckZvdW5kID8gYXdhaXQgcGFnZUV2YWwoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicsICcnLCAoaXRlbSkgPT4ge1xuICAgIHJldHVybiAoaXRlbSBhcyBIVE1MRGl2RWxlbWVudCkuaW5uZXJUZXh0O1xuICB9KSA6ICcnO1xuICByZXR1cm4gZXJyb3JNZXNzYWdlID09PSBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlO1xufVxuXG5mdW5jdGlvbiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpIHtcbiAgZGVidWcoJ3JldHVybiBwb3NzaWJsZSBsb2dpbiByZXN1bHRzJyk7XG4gIGNvbnN0IHVybHM6IExvZ2luT3B0aW9uc1sncG9zc2libGVSZXN1bHRzJ10gPSB7XG4gICAgW0xvZ2luUmVzdWx0cy5TdWNjZXNzXTogWy9kYXNoYm9hcmQvaV0sXG4gICAgW0xvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmRdOiBbYXN5bmMgKG9wdGlvbnM/OiB7IHBhZ2U/OiBQYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBvcHRpb25zPy5wYWdlO1xuICAgICAgaWYgKCFwYWdlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXNJbnZhbGlkUGFzc3dvcmRFcnJvcihwYWdlKTtcbiAgICB9XSxcbiAgICAvLyBbTG9naW5SZXN1bHRzLkFjY291bnRCbG9ja2VkXTogW10sIC8vIFRPRE8gYWRkIHdoZW4gcmVhY2hpbmcgdGhpcyBzY2VuYXJpb1xuICAgIC8vIFtMb2dpblJlc3VsdHMuQ2hhbmdlUGFzc3dvcmRdOiBbXSwgLy8gVE9ETyBhZGQgd2hlbiByZWFjaGluZyB0aGlzIHNjZW5hcmlvXG4gIH07XG4gIHJldHVybiB1cmxzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpIHtcbiAgZGVidWcoJ2NyZWF0ZSBsb2dpbiBmaWVsZHMgZm9yIHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICByZXR1cm4gW1xuICAgIHsgc2VsZWN0b3I6ICdbZm9ybWNvbnRyb2xuYW1lPVwidXNlck5hbWVcIl0nLCB2YWx1ZTogY3JlZGVudGlhbHMudXNlcm5hbWUgfSxcbiAgICB7IHNlbGVjdG9yOiAnW2Zvcm1jb250cm9sbmFtZT1cInBhc3N3b3JkXCJdJywgdmFsdWU6IGNyZWRlbnRpYWxzLnBhc3N3b3JkIH0sXG4gIF07XG59XG5cbmZ1bmN0aW9uIGNhcmRBbmRUcmFuc2FjdGlvbkN1cnJlbmN5U3ltYm9sSXNTaGVrZWwodHJhbnNhY3Rpb246IFNjcmFwZWRUcmFuc2FjdGlvbikge1xuICByZXR1cm4gdHJhbnNhY3Rpb24uZGViQ3JkQ3VycmVuY3lTeW1ib2wgPT09IFNIRUtFTF9DVVJSRU5DWV9TWU1CT0wgJiZcbiAgICB0cmFuc2FjdGlvbi50cm5DdXJyZW5jeVN5bWJvbCA9PT0gU0hFS0VMX0NVUlJFTkNZX1NZTUJPTDtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRQYXJzZWREYXRhVG9UcmFuc2FjdGlvbnMocGFyc2VkRGF0YTogQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc1tdKTogVHJhbnNhY3Rpb25bXSB7XG4gIHJldHVybiBwYXJzZWREYXRhXG4gICAgLmZsYXRNYXAoKG1vbnRoRGF0YSkgPT4gbW9udGhEYXRhLnJlc3VsdC5iYW5rQWNjb3VudHMpXG4gICAgLmZsYXRNYXAoKGFjY291bnRzKSA9PiBhY2NvdW50cy5kZWJpdERhdGVzKVxuICAgIC5mbGF0TWFwKChkZWJpdERhdGUpID0+IGRlYml0RGF0ZS50cmFuc2FjdGlvbnMpXG4gICAgLm1hcCgodHJhbnNhY3Rpb24pID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbGxtZW50cyA9ICh0cmFuc2FjdGlvbi5jdXJQYXltZW50TnVtICYmIHRyYW5zYWN0aW9uLm51bU9mUGF5bWVudHMgJiZcbiAgICAgIHtcbiAgICAgICAgbnVtYmVyOiB0cmFuc2FjdGlvbi5jdXJQYXltZW50TnVtLFxuICAgICAgICB0b3RhbDogdHJhbnNhY3Rpb24ubnVtT2ZQYXltZW50cyxcbiAgICAgIH0pIHx8XG4gICAgICAgIHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgZGF0ZSA9IG1vbWVudCh0cmFuc2FjdGlvbi50cm5QdXJjaGFzZURhdGUpO1xuXG4gICAgICAvLyBJIGRpZG4ndCB0ZXN0IGBhbXRCZWZvcmVDb252QW5kSW5kZXhgIHdpdGggYSBmb3JlaWduIGN1cnJlbmN5IGFzIEkgZG9uJ3QgaGF2ZSBzdWNoIHRyYW5zYWN0aW9uc1xuICAgICAgbGV0IGNoYXJnZWRBbW91bnQ6IG51bWJlcjtcbiAgICAgIGlmIChjYXJkQW5kVHJhbnNhY3Rpb25DdXJyZW5jeVN5bWJvbElzU2hla2VsKHRyYW5zYWN0aW9uKSkge1xuICAgICAgICBjaGFyZ2VkQW1vdW50ID0gdHJhbnNhY3Rpb24uYW10QmVmb3JlQ29udkFuZEluZGV4ICogKC0xKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJnZWRBbW91bnQgPSB0cmFuc2FjdGlvbi50cm5BbXQgKiAoLTEpO1xuXG4gICAgICAgIGlmICh0cmFuc2FjdGlvbi50cm5UeXBlQ29kZSA9PT0gdHJuVHlwZUNvZGUuY3JlZGl0KSB7XG4gICAgICAgICAgY2hhcmdlZEFtb3VudCA9IHRyYW5zYWN0aW9uLnRybkFtdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgICBjaGFyZ2VkQW1vdW50LFxuICAgICAgICBkZXNjcmlwdGlvbjogdHJhbnNhY3Rpb24ubWVyY2hhbnROYW1lLFxuICAgICAgICBvcmlnaW5hbEFtb3VudDogdHJhbnNhY3Rpb24uYW10QmVmb3JlQ29udkFuZEluZGV4LFxuICAgICAgICBvcmlnaW5hbEN1cnJlbmN5OiB0cmFuc2FjdGlvbi50cm5DdXJyZW5jeVN5bWJvbCxcbiAgICAgICAgcHJvY2Vzc2VkRGF0ZTogdHJhbnNhY3Rpb24uZGViQ3JkRGF0ZSxcbiAgICAgICAgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICAgICAgZGF0ZTogaW5zdGFsbG1lbnRzID9cbiAgICAgICAgICBkYXRlLmFkZChpbnN0YWxsbWVudHMubnVtYmVyIC0gMSwgJ21vbnRoJykudG9JU09TdHJpbmcoKSA6XG4gICAgICAgICAgZGF0ZS50b0lTT1N0cmluZygpLFxuICAgICAgICB0eXBlOiBbdHJuVHlwZUNvZGUucmVndWxhciwgdHJuVHlwZUNvZGUuc3RhbmRpbmdPcmRlcl0uaW5jbHVkZXModHJhbnNhY3Rpb24udHJuVHlwZUNvZGUpID9cbiAgICAgICAgICBUcmFuc2FjdGlvblR5cGVzLk5vcm1hbCA6XG4gICAgICAgICAgVHJhbnNhY3Rpb25UeXBlcy5JbnN0YWxsbWVudHMsXG4gICAgICB9O1xuXG4gICAgICBpZiAoaW5zdGFsbG1lbnRzKSB7XG4gICAgICAgIHJlc3VsdC5pbnN0YWxsbWVudHMgPSBpbnN0YWxsbWVudHM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG59XG5cbnR5cGUgU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMgPSB7IHVzZXJuYW1lOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcgfTtcblxuY2xhc3MgVmlzYUNhbFNjcmFwZXIgZXh0ZW5kcyBCYXNlU2NyYXBlcldpdGhCcm93c2VyPFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzPiB7XG4gIG9wZW5Mb2dpblBvcHVwID0gYXN5bmMgKCkgPT4ge1xuICAgIGRlYnVnKCdvcGVuIGxvZ2luIHBvcHVwLCB3YWl0IHVudGlsIGxvZ2luIGJ1dHRvbiBhdmFpbGFibGUnKTtcbiAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJywgdHJ1ZSk7XG4gICAgZGVidWcoJ2NsaWNrIG9uIHRoZSBsb2dpbiBidXR0b24nKTtcbiAgICBhd2FpdCBjbGlja0J1dHRvbih0aGlzLnBhZ2UsICcjY2NMb2dpbkRlc2t0b3BCdG4nKTtcbiAgICBkZWJ1ZygnZ2V0IHRoZSBmcmFtZSB0aGF0IGhvbGRzIHRoZSBsb2dpbicpO1xuICAgIGNvbnN0IGZyYW1lID0gYXdhaXQgZ2V0TG9naW5GcmFtZSh0aGlzLnBhZ2UpO1xuICAgIGRlYnVnKCd3YWl0IHVudGlsIHRoZSBwYXNzd29yZCBsb2dpbiB0YWIgaGVhZGVyIGlzIGF2YWlsYWJsZScpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZChmcmFtZSwgJyNyZWd1bGFyLWxvZ2luJyk7XG4gICAgZGVidWcoJ25hdmlnYXRlIHRvIHRoZSBwYXNzd29yZCBsb2dpbiB0YWInKTtcbiAgICBhd2FpdCBjbGlja0J1dHRvbihmcmFtZSwgJyNyZWd1bGFyLWxvZ2luJyk7XG4gICAgZGVidWcoJ3dhaXQgdW50aWwgdGhlIHBhc3N3b3JkIGxvZ2luIHRhYiBpcyBhY3RpdmUnKTtcbiAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQoZnJhbWUsICdyZWd1bGFyLWxvZ2luJyk7XG5cbiAgICByZXR1cm4gZnJhbWU7XG4gIH07XG5cbiAgYXN5bmMgZ2V0Q2FyZHMoKSB7XG4gICAgY29uc3QgaW5pdERhdGEgPSBhd2FpdCBnZXRGcm9tU2Vzc2lvblN0b3JhZ2U8SW5pdFJlc3BvbnNlPih0aGlzLnBhZ2UsICdpbml0Jyk7XG4gICAgaWYgKCFpbml0RGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCBcXCdpbml0XFwnIGRhdGEgaW4gc2Vzc2lvbiBzdG9yYWdlJyk7XG4gICAgfVxuICAgIHJldHVybiBpbml0RGF0YT8ucmVzdWx0LmNhcmRzLm1hcCgoeyBjYXJkVW5pcXVlSWQsIGxhc3Q0RGlnaXRzIH0pID0+ICh7IGNhcmRVbmlxdWVJZCwgbGFzdDREaWdpdHMgfSkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QXV0aG9yaXphdGlvbkhlYWRlcigpIHtcbiAgICBjb25zdCBhdXRoTW9kdWxlID0gYXdhaXQgZ2V0RnJvbVNlc3Npb25TdG9yYWdlPHsgYXV0aDogeyBjYWxDb25uZWN0VG9rZW46IHN0cmluZyB9IH0+KHRoaXMucGFnZSwgJ2F1dGgtbW9kdWxlJyk7XG4gICAgaWYgKCFhdXRoTW9kdWxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCBmaW5kIFxcJ2F1dGgtbW9kdWxlXFwnIGluIHNlc3Npb24gc3RvcmFnZScpO1xuICAgIH1cbiAgICByZXR1cm4gYENBTEF1dGhTY2hlbWUgJHthdXRoTW9kdWxlLmF1dGguY2FsQ29ubmVjdFRva2VufWA7XG4gIH1cblxuICBhc3luYyBnZXRYU2l0ZUlkKCkge1xuICAgIC8qXG4gICAgICBJIGRvbid0IGtub3cgaWYgdGhlIGNvbnN0YW50IGJlbG93IHdpbGwgY2hhbmdlIGluIHRoZSBmZWF0dXJlLlxuICAgICAgSWYgc28sIHVzZSB0aGUgbmV4dCBjb2RlOlxuXG4gICAgICByZXR1cm4gdGhpcy5wYWdlLmV2YWx1YXRlKCgpID0+IG5ldyBVdCgpLnhTaXRlSWQpO1xuXG4gICAgICBUbyBnZXQgdGhlIGNsYXNzbmFtZSBzZWFyY2ggZm9yICd4U2l0ZUlkJyBpbiB0aGUgcGFnZSBzb3VyY2VcbiAgICAgIGNsYXNzIFV0IHtcbiAgICAgICAgY29uc3RydWN0b3IoX2UsIG9uLCB5bikge1xuICAgICAgICAgICAgdGhpcy5zdG9yZSA9IF9lLFxuICAgICAgICAgICAgdGhpcy5jb25maWcgPSBvbixcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXNTZXJ2aWNlID0geW4sXG4gICAgICAgICAgICB0aGlzLnhTaXRlSWQgPSBcIjA5MDMxOTg3LTI3M0UtMjMxMS05MDZDLThBRjg1QjE3QzhEOVwiLFxuICAgICovXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgnMDkwMzE5ODctMjczRS0yMzExLTkwNkMtOEFGODVCMTdDOEQ5Jyk7XG4gIH1cblxuICBnZXRMb2dpbk9wdGlvbnMoY3JlZGVudGlhbHM6IFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzKTogTG9naW5PcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9naW5Vcmw6IGAke0xPR0lOX1VSTH1gLFxuICAgICAgZmllbGRzOiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFscyksXG4gICAgICBzdWJtaXRCdXR0b25TZWxlY3RvcjogJ2J1dHRvblt0eXBlPVwic3VibWl0XCJdJyxcbiAgICAgIHBvc3NpYmxlUmVzdWx0czogZ2V0UG9zc2libGVMb2dpblJlc3VsdHMoKSxcbiAgICAgIGNoZWNrUmVhZGluZXNzOiBhc3luYyAoKSA9PiB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJyksXG4gICAgICBwcmVBY3Rpb246IHRoaXMub3BlbkxvZ2luUG9wdXAsXG4gICAgICBwb3N0QWN0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKHRoaXMucGFnZSwgJ2J1dHRvbi5idG4tY2xvc2UnKTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChjdXJyZW50VXJsLmVuZHNXaXRoKCdzaXRlLXR1dG9yaWFsJykpIHtcbiAgICAgICAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKHRoaXMucGFnZSwgJ2J1dHRvbi5idG4tY2xvc2UnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChjdXJyZW50VXJsLmVuZHNXaXRoKCdkYXNoYm9hcmQnKSkgcmV0dXJuO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1c2VyQWdlbnQ6ICdNb3ppbGxhLzUuMCAoWDExOyBMaW51eCB4ODZfNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS83OC4wLjM5MDQuMTA4IFNhZmFyaS81MzcuMzYnLFxuICAgIH07XG4gIH1cblxuICBpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMocmVzdWx0OiBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIHwgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yKTpcbiAgICByZXN1bHQgaXMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscyB7XG4gICAgcmV0dXJuIChyZXN1bHQgYXMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscykucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKTogUHJvbWlzZTxTY3JhcGVyU2NyYXBpbmdSZXN1bHQ+IHtcbiAgICBjb25zdCBkZWZhdWx0U3RhcnRNb21lbnQgPSBtb21lbnQoKS5zdWJ0cmFjdCgxLCAneWVhcnMnKS5zdWJ0cmFjdCg2LCAnbW9udGhzJykuYWRkKDEsICdkYXknKTtcbiAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLm9wdGlvbnMuc3RhcnREYXRlIHx8IGRlZmF1bHRTdGFydE1vbWVudC50b0RhdGUoKTtcbiAgICBjb25zdCBzdGFydE1vbWVudCA9IG1vbWVudC5tYXgoZGVmYXVsdFN0YXJ0TW9tZW50LCBtb21lbnQoc3RhcnREYXRlKSk7XG4gICAgZGVidWcoYGZldGNoIHRyYW5zYWN0aW9ucyBzdGFydGluZyAke3N0YXJ0TW9tZW50LmZvcm1hdCgpfWApO1xuXG4gICAgY29uc3QgQXV0aG9yaXphdGlvbiA9IGF3YWl0IHRoaXMuZ2V0QXV0aG9yaXphdGlvbkhlYWRlcigpO1xuICAgIC8vIFdhaXQgYSBsaXR0bGUgYmVmb3JlIGB0aGlzLmdldENhcmRzYCBzbyB0aGF0IGl0IHdvdWxkIGV4aXN0XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xuICAgIGNvbnN0IGNhcmRzID0gYXdhaXQgdGhpcy5nZXRDYXJkcygpO1xuICAgIGNvbnN0IHhTaXRlSWQgPSBhd2FpdCB0aGlzLmdldFhTaXRlSWQoKTtcblxuXG4gICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGNhcmRzLm1hcChhc3luYyAoY2FyZCkgPT4ge1xuICAgICAgICBkZWJ1ZyhgZmV0Y2ggdHJhbnNhY3Rpb25zIGZvciBjYXJkICR7Y2FyZC5jYXJkVW5pcXVlSWR9YCk7XG5cbiAgICAgICAgY29uc3QgbmV4dEJpbGxpbmdNb250aCA9IG1vbWVudCgpLmFkZCgxLCAnbW9udGgnKTtcbiAgICAgICAgY29uc3QgbW9udGhzID0gbmV4dEJpbGxpbmdNb250aC5kaWZmKHN0YXJ0TW9tZW50LCAnbW9udGhzJyk7XG5cbiAgICAgICAgY29uc3QgYWxsTW9udGhzRGF0YTogKENhcmRUcmFuc2FjdGlvbkRldGFpbHMpW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbW9udGhzOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBtb250aCA9IG5leHRCaWxsaW5nTW9udGguY2xvbmUoKS5zdWJ0cmFjdChpLCAnbW9udGhzJyk7XG4gICAgICAgICAgY29uc3QgbW9udGhEYXRhID0gYXdhaXQgZmV0Y2hQb3N0V2l0aGluUGFnZTxDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIHwgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yPihcbiAgICAgICAgICAgIHRoaXMucGFnZSwgVFJBTlNBQ1RJT05TX1JFUVVFU1RfRU5EUE9JTlQsXG4gICAgICAgICAgICB7IGNhcmRVbmlxdWVJZDogY2FyZC5jYXJkVW5pcXVlSWQsIG1vbnRoOiBtb250aC5mb3JtYXQoJ00nKSwgeWVhcjogbW9udGguZm9ybWF0KCdZWVlZJykgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbixcbiAgICAgICAgICAgICAgJ1gtU2l0ZS1JZCc6IHhTaXRlSWQsXG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAobW9udGhEYXRhPy5zdGF0dXNDb2RlICE9PSAxKSB0aHJvdyBuZXcgRXJyb3IoYGZhaWxlZCB0byBmZXRjaCB0cmFuc2FjdGlvbnMgZm9yIGNhcmQgJHtjYXJkLmxhc3Q0RGlnaXRzfS4gTWVzc2FnZTogJHttb250aERhdGE/LnRpdGxlIHx8ICcnfWApO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLmlzQ2FyZFRyYW5zYWN0aW9uRGV0YWlscyhtb250aERhdGEpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21vbnRoRGF0YSBpcyBub3Qgb2YgdHlwZSBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYWxsTW9udGhzRGF0YS5wdXNoKG1vbnRoRGF0YSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbnMgPSBjb252ZXJ0UGFyc2VkRGF0YVRvVHJhbnNhY3Rpb25zKGFsbE1vbnRoc0RhdGEpO1xuXG4gICAgICAgIGRlYnVnKCdmaWxlciBvdXQgb2xkIHRyYW5zYWN0aW9ucycpO1xuICAgICAgICBjb25zdCB0eG5zID0gKHRoaXMub3B0aW9ucy5vdXRwdXREYXRhPy5lbmFibGVUcmFuc2FjdGlvbnNGaWx0ZXJCeURhdGUgPz8gdHJ1ZSkgP1xuICAgICAgICAgIGZpbHRlck9sZFRyYW5zYWN0aW9ucyh0cmFuc2FjdGlvbnMsIG1vbWVudChzdGFydERhdGUpLCB0aGlzLm9wdGlvbnMuY29tYmluZUluc3RhbGxtZW50cyB8fCBmYWxzZSkgOlxuICAgICAgICAgIHRyYW5zYWN0aW9ucztcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR4bnMsXG4gICAgICAgICAgYWNjb3VudE51bWJlcjogY2FyZC5sYXN0NERpZ2l0cyxcbiAgICAgICAgfSBhcyBUcmFuc2FjdGlvbnNBY2NvdW50O1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGRlYnVnKCdyZXR1cm4gdGhlIHNjcmFwZWQgYWNjb3VudHMnKTtcblxuICAgIGRlYnVnKEpTT04uc3RyaW5naWZ5KGFjY291bnRzLCBudWxsLCAyKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICBhY2NvdW50cyxcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFZpc2FDYWxTY3JhcGVyO1xuIl19