israeli-bank-scrapers 3.4.1 → 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.
- package/README.md +42 -0
- package/lib/definitions.d.ts +6 -1
- package/lib/definitions.js +6 -1
- package/lib/helpers/fetch.d.ts +2 -1
- package/lib/helpers/fetch.js +26 -9
- package/lib/helpers/storage.d.ts +2 -0
- package/lib/helpers/storage.js +17 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +47 -3
- package/lib/scrapers/amex.d.ts +1 -1
- package/lib/scrapers/amex.js +1 -1
- package/lib/scrapers/amex.test.js +3 -2
- package/lib/scrapers/base-beinleumi-group.d.ts +7 -4
- package/lib/scrapers/base-beinleumi-group.js +1 -1
- package/lib/scrapers/base-isracard-amex.d.ts +8 -3
- package/lib/scrapers/base-isracard-amex.js +13 -11
- package/lib/scrapers/base-scraper-with-browser.d.ts +6 -3
- package/lib/scrapers/base-scraper-with-browser.js +14 -11
- package/lib/scrapers/base-scraper.d.ts +9 -119
- package/lib/scrapers/base-scraper.js +34 -50
- package/lib/scrapers/beyahad-bishvilha.d.ts +6 -3
- package/lib/scrapers/beyahad-bishvilha.js +1 -1
- package/lib/scrapers/discount.d.ts +9 -4
- package/lib/scrapers/discount.js +4 -4
- package/lib/scrapers/discount.test.js +4 -3
- package/lib/scrapers/errors.d.ts +16 -0
- package/lib/scrapers/errors.js +37 -0
- package/lib/scrapers/factory.d.ts +2 -16
- package/lib/scrapers/factory.js +6 -1
- package/lib/scrapers/hapoalim.d.ts +6 -3
- package/lib/scrapers/hapoalim.js +1 -1
- package/lib/scrapers/hapoalim.test.js +2 -2
- package/lib/scrapers/interface.d.ts +146 -0
- package/lib/scrapers/interface.js +2 -0
- package/lib/scrapers/isracard.d.ts +1 -1
- package/lib/scrapers/isracard.js +1 -1
- package/lib/scrapers/isracard.test.js +4 -3
- package/lib/scrapers/leumi.d.ts +8 -4
- package/lib/scrapers/leumi.js +1 -1
- package/lib/scrapers/max.d.ts +6 -3
- package/lib/scrapers/max.js +1 -1
- package/lib/scrapers/mizrahi.d.ts +7 -3
- package/lib/scrapers/mizrahi.js +11 -9
- package/lib/scrapers/one-zero-queries.d.ts +2 -0
- package/lib/scrapers/one-zero-queries.js +562 -0
- package/lib/scrapers/one-zero.d.ts +36 -0
- package/lib/scrapers/one-zero.js +304 -0
- package/lib/scrapers/one-zero.test.d.ts +1 -0
- package/lib/scrapers/one-zero.test.js +67 -0
- package/lib/scrapers/otsar-hahayal.d.ts +6 -3
- package/lib/scrapers/otsar-hahayal.js +1 -1
- package/lib/scrapers/union-bank.d.ts +6 -3
- package/lib/scrapers/union-bank.js +1 -1
- package/lib/scrapers/visa-cal.d.ts +103 -15
- package/lib/scrapers/visa-cal.js +154 -265
- package/lib/scrapers/yahav.d.ts +7 -3
- package/lib/scrapers/yahav.js +1 -1
- package/package.json +2 -2
package/lib/scrapers/visa-cal.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
require("core-js/modules/es.
|
|
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.
|
|
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.
|
|
9
|
+
require("core-js/modules/es.promise");
|
|
12
10
|
|
|
13
11
|
Object.defineProperty(exports, "__esModule", {
|
|
14
12
|
value: true
|
|
@@ -17,30 +15,42 @@ exports.default = void 0;
|
|
|
17
15
|
|
|
18
16
|
var _moment = _interopRequireDefault(require("moment"));
|
|
19
17
|
|
|
20
|
-
var
|
|
18
|
+
var _constants = require("../constants");
|
|
19
|
+
|
|
20
|
+
var _debug = require("../helpers/debug");
|
|
21
21
|
|
|
22
22
|
var _elementsInteractions = require("../helpers/elements-interactions");
|
|
23
23
|
|
|
24
|
-
var
|
|
24
|
+
var _fetch = require("../helpers/fetch");
|
|
25
25
|
|
|
26
|
-
var
|
|
26
|
+
var _navigation = require("../helpers/navigation");
|
|
27
|
+
|
|
28
|
+
var _storage = require("../helpers/storage");
|
|
29
|
+
|
|
30
|
+
var _transactions = require("../helpers/transactions");
|
|
27
31
|
|
|
28
32
|
var _waiting = require("../helpers/waiting");
|
|
29
33
|
|
|
30
|
-
var _transactions2 = require("../
|
|
34
|
+
var _transactions2 = require("../transactions");
|
|
31
35
|
|
|
32
|
-
var
|
|
36
|
+
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
|
|
33
37
|
|
|
34
38
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
39
|
|
|
36
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; }
|
|
37
41
|
|
|
38
42
|
const LOGIN_URL = 'https://www.cal-online.co.il/';
|
|
39
|
-
const
|
|
40
|
-
const LONG_DATE_FORMAT = 'DD/MM/YYYY';
|
|
41
|
-
const DATE_FORMAT = 'DD/MM/YY';
|
|
43
|
+
const TRANSACTIONS_REQUEST_ENDPOINT = 'https://api.cal-online.co.il/Transactions/api/transactionsDetails/getCardTransactionsDetails';
|
|
42
44
|
const InvalidPasswordMessage = 'שם המשתמש או הסיסמה שהוזנו שגויים';
|
|
43
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 = {}));
|
|
44
54
|
|
|
45
55
|
async function getLoginFrame(page) {
|
|
46
56
|
let frame = null;
|
|
@@ -70,7 +80,7 @@ async function hasInvalidPasswordError(page) {
|
|
|
70
80
|
function getPossibleLoginResults() {
|
|
71
81
|
debug('return possible login results');
|
|
72
82
|
const urls = {
|
|
73
|
-
[_baseScraperWithBrowser.LoginResults.Success]: [/
|
|
83
|
+
[_baseScraperWithBrowser.LoginResults.Success]: [/dashboard/i],
|
|
74
84
|
[_baseScraperWithBrowser.LoginResults.InvalidPassword]: [async options => {
|
|
75
85
|
const page = options === null || options === void 0 ? void 0 : options.page;
|
|
76
86
|
|
|
@@ -97,70 +107,39 @@ function createLoginFields(credentials) {
|
|
|
97
107
|
}];
|
|
98
108
|
}
|
|
99
109
|
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
let currency = null;
|
|
103
|
-
let amount = null;
|
|
104
|
-
|
|
105
|
-
if (amountStrCln.includes(_constants.SHEKEL_CURRENCY_SYMBOL)) {
|
|
106
|
-
amount = -parseFloat(amountStrCln.replace(_constants.SHEKEL_CURRENCY_SYMBOL, ''));
|
|
107
|
-
currency = _constants.SHEKEL_CURRENCY;
|
|
108
|
-
} else if (amountStrCln.includes(_constants.DOLLAR_CURRENCY_SYMBOL)) {
|
|
109
|
-
amount = -parseFloat(amountStrCln.replace(_constants.DOLLAR_CURRENCY_SYMBOL, ''));
|
|
110
|
-
currency = _constants.DOLLAR_CURRENCY;
|
|
111
|
-
} else if (amountStrCln.includes(_constants.EURO_CURRENCY_SYMBOL)) {
|
|
112
|
-
amount = -parseFloat(amountStrCln.replace(_constants.EURO_CURRENCY_SYMBOL, ''));
|
|
113
|
-
currency = _constants.EURO_CURRENCY;
|
|
114
|
-
} else {
|
|
115
|
-
const parts = amountStrCln.split(' ');
|
|
116
|
-
[currency] = parts;
|
|
117
|
-
amount = -parseFloat(parts[1]);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
amount,
|
|
122
|
-
currency
|
|
123
|
-
};
|
|
110
|
+
function cardAndTransactionCurrencySymbolIsShekel(transaction) {
|
|
111
|
+
return transaction.debCrdCurrencySymbol === _constants.SHEKEL_CURRENCY_SYMBOL && transaction.trnCurrencySymbol === _constants.SHEKEL_CURRENCY_SYMBOL;
|
|
124
112
|
}
|
|
125
113
|
|
|
126
|
-
function
|
|
127
|
-
|
|
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
|
|
128
121
|
|
|
129
|
-
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
122
|
+
let chargedAmount;
|
|
132
123
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
124
|
+
if (cardAndTransactionCurrencySymbolIsShekel(transaction)) {
|
|
125
|
+
chargedAmount = transaction.amtBeforeConvAndIndex * -1;
|
|
126
|
+
} else {
|
|
127
|
+
chargedAmount = transaction.trnAmt * -1;
|
|
138
128
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const originalAmountTuple = getAmountData(txn.originalAmount || '');
|
|
143
|
-
const chargedAmountTuple = getAmountData(txn.chargedAmount || '');
|
|
144
|
-
const installments = getTransactionInstallments(txn.memo);
|
|
145
|
-
const txnDate = (0, _moment.default)(txn.date, DATE_FORMAT);
|
|
146
|
-
const processedDateFormat = txn.processedDate.length === 8 ? DATE_FORMAT : txn.processedDate.length === 9 || txn.processedDate.length === 10 ? LONG_DATE_FORMAT : null;
|
|
147
|
-
|
|
148
|
-
if (!processedDateFormat) {
|
|
149
|
-
throw new Error('invalid processed date');
|
|
129
|
+
if (transaction.trnTypeCode === trnTypeCode.credit) {
|
|
130
|
+
chargedAmount = transaction.trnAmt;
|
|
131
|
+
}
|
|
150
132
|
}
|
|
151
133
|
|
|
152
|
-
const txnProcessedDate = (0, _moment.default)(txn.processedDate, processedDateFormat);
|
|
153
134
|
const result = {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
description: txn.description || '',
|
|
163
|
-
memo: txn.memo || ''
|
|
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
|
|
164
143
|
};
|
|
165
144
|
|
|
166
145
|
if (installments) {
|
|
@@ -171,191 +150,6 @@ function convertTransactions(txns) {
|
|
|
171
150
|
});
|
|
172
151
|
}
|
|
173
152
|
|
|
174
|
-
async function fetchTransactionsForAccount(page, startDate, accountNumber, scraperOptions) {
|
|
175
|
-
var _scraperOptions$outpu, _scraperOptions$outpu2;
|
|
176
|
-
|
|
177
|
-
const startDateValue = startDate.format('MM/YYYY');
|
|
178
|
-
const dateSelector = '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_TextBox"]';
|
|
179
|
-
const dateHiddenFieldSelector = '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_HiddenField"]';
|
|
180
|
-
const buttonSelector = '[id$="FormAreaNoBorder_FormArea_ctlSubmitRequest"]';
|
|
181
|
-
const nextPageSelector = '[id$="FormAreaNoBorder_FormArea_ctlGridPager_btnNext"]';
|
|
182
|
-
const billingLabelSelector = '[id$=FormAreaNoBorder_FormArea_ctlMainToolBar_lblCaption]';
|
|
183
|
-
const secondaryBillingLabelSelector = '[id$=FormAreaNoBorder_FormArea_ctlSecondaryToolBar_lblCaption]';
|
|
184
|
-
const noDataSelector = '[id$=FormAreaNoBorder_FormArea_msgboxErrorMessages]';
|
|
185
|
-
debug('find the start date index in the dropbox');
|
|
186
|
-
const options = await (0, _elementsInteractions.pageEvalAll)(page, '[id$="FormAreaNoBorder_FormArea_clndrDebitDateScope_OptionList"] li', [], items => {
|
|
187
|
-
return items.map(el => el.innerText);
|
|
188
|
-
});
|
|
189
|
-
const startDateIndex = options.findIndex(option => option === startDateValue);
|
|
190
|
-
debug(`scrape ${options.length - startDateIndex} billing cycles`);
|
|
191
|
-
const accountTransactions = [];
|
|
192
|
-
|
|
193
|
-
for (let currentDateIndex = startDateIndex; currentDateIndex < options.length; currentDateIndex += 1) {
|
|
194
|
-
debug('wait for date selector to be found');
|
|
195
|
-
await (0, _elementsInteractions.waitUntilElementFound)(page, dateSelector, true);
|
|
196
|
-
debug(`set hidden value of the date selector to be the index ${currentDateIndex}`);
|
|
197
|
-
await (0, _elementsInteractions.setValue)(page, dateHiddenFieldSelector, `${currentDateIndex}`);
|
|
198
|
-
debug('wait a second to workaround navigation issue in headless browser mode');
|
|
199
|
-
await page.waitForTimeout(1000);
|
|
200
|
-
debug('click on the filter submit button and wait for navigation');
|
|
201
|
-
await Promise.all([page.waitForNavigation({
|
|
202
|
-
waitUntil: 'domcontentloaded'
|
|
203
|
-
}), (0, _elementsInteractions.clickButton)(page, buttonSelector)]);
|
|
204
|
-
debug('check if month has no transactions');
|
|
205
|
-
const pageHasNoTransactions = await (0, _elementsInteractions.pageEval)(page, noDataSelector, false, element => {
|
|
206
|
-
const siteValue = (element.innerText || '').replace(/[^ א-ת]/g, '');
|
|
207
|
-
return siteValue === 'לא נמצאו נתונים';
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
if (pageHasNoTransactions) {
|
|
211
|
-
debug('page has no transactions');
|
|
212
|
-
} else {
|
|
213
|
-
var _settlementDateRegex$;
|
|
214
|
-
|
|
215
|
-
debug('find the billing date');
|
|
216
|
-
let billingDateLabel = await (0, _elementsInteractions.pageEval)(page, billingLabelSelector, '', element => {
|
|
217
|
-
return element.innerText;
|
|
218
|
-
});
|
|
219
|
-
let settlementDateRegex = /\d{1,2}[/]\d{2}[/]\d{2,4}/;
|
|
220
|
-
|
|
221
|
-
if (billingDateLabel === '') {
|
|
222
|
-
billingDateLabel = await (0, _elementsInteractions.pageEval)(page, secondaryBillingLabelSelector, '', element => {
|
|
223
|
-
return element.innerText;
|
|
224
|
-
});
|
|
225
|
-
settlementDateRegex = /\d{1,2}[/]\d{2,4}/;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const billingDate = (_settlementDateRegex$ = settlementDateRegex.exec(billingDateLabel)) === null || _settlementDateRegex$ === void 0 ? void 0 : _settlementDateRegex$[0];
|
|
229
|
-
|
|
230
|
-
if (!billingDate) {
|
|
231
|
-
throw new Error('failed to fetch process date');
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
debug(`found the billing date for that month ${billingDate}`);
|
|
235
|
-
let hasNextPage = false;
|
|
236
|
-
|
|
237
|
-
do {
|
|
238
|
-
debug('fetch raw transactions from page');
|
|
239
|
-
const rawTransactions = await (0, _elementsInteractions.pageEvalAll)(page, '#ctlMainGrid > tbody tr, #ctlSecondaryGrid > tbody tr', [], (items, billingDate) => {
|
|
240
|
-
return items.map(el => {
|
|
241
|
-
const columns = el.getElementsByTagName('td');
|
|
242
|
-
|
|
243
|
-
if (columns.length === 6) {
|
|
244
|
-
return {
|
|
245
|
-
processedDate: columns[0].innerText,
|
|
246
|
-
date: columns[1].innerText,
|
|
247
|
-
description: columns[2].innerText,
|
|
248
|
-
originalAmount: columns[3].innerText,
|
|
249
|
-
chargedAmount: columns[4].innerText,
|
|
250
|
-
memo: columns[5].innerText
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (columns.length === 5) {
|
|
255
|
-
return {
|
|
256
|
-
processedDate: billingDate,
|
|
257
|
-
date: columns[0].innerText,
|
|
258
|
-
description: columns[1].innerText,
|
|
259
|
-
originalAmount: columns[2].innerText,
|
|
260
|
-
chargedAmount: columns[3].innerText,
|
|
261
|
-
memo: columns[4].innerText
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return null;
|
|
266
|
-
});
|
|
267
|
-
}, billingDate);
|
|
268
|
-
debug(`fetched ${rawTransactions.length} raw transactions from page`);
|
|
269
|
-
accountTransactions.push(...convertTransactions(rawTransactions.filter(item => !!item)));
|
|
270
|
-
debug('check for existance of another page');
|
|
271
|
-
hasNextPage = await (0, _elementsInteractions.elementPresentOnPage)(page, nextPageSelector);
|
|
272
|
-
|
|
273
|
-
if (hasNextPage) {
|
|
274
|
-
debug('has another page, click on button next and wait for page navigation');
|
|
275
|
-
await Promise.all([page.waitForNavigation({
|
|
276
|
-
waitUntil: 'domcontentloaded'
|
|
277
|
-
}), await (0, _elementsInteractions.clickButton)(page, '[id$=FormAreaNoBorder_FormArea_ctlGridPager_btnNext]')]);
|
|
278
|
-
}
|
|
279
|
-
} while (hasNextPage);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
debug('filer out old transactions');
|
|
284
|
-
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;
|
|
285
|
-
debug(`found ${txns.length} valid transactions out of ${accountTransactions.length} transactions for account ending with ${accountNumber.substring(accountNumber.length - 2)}`);
|
|
286
|
-
return {
|
|
287
|
-
accountNumber,
|
|
288
|
-
txns
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async function getAccountNumbers(page) {
|
|
293
|
-
return (0, _elementsInteractions.pageEvalAll)(page, '[id$=lnkItem]', [], elements => elements.map(e => e.text)).then(res => res.map(text => {
|
|
294
|
-
var _$exec$, _$exec;
|
|
295
|
-
|
|
296
|
-
return (_$exec$ = (_$exec = /\d+$/.exec(text.trim())) === null || _$exec === void 0 ? void 0 : _$exec[0]) !== null && _$exec$ !== void 0 ? _$exec$ : '';
|
|
297
|
-
}));
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
async function setAccount(page, account) {
|
|
301
|
-
await (0, _elementsInteractions.pageEvalAll)(page, '[id$=lnkItem]', null, (elements, account) => {
|
|
302
|
-
for (const elem of elements) {
|
|
303
|
-
const a = elem;
|
|
304
|
-
|
|
305
|
-
if (a.text.includes(account)) {
|
|
306
|
-
a.click();
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}, account);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
async function fetchTransactions(page, startDate, scraperOptions) {
|
|
313
|
-
const accountNumbers = await getAccountNumbers(page);
|
|
314
|
-
const accounts = [];
|
|
315
|
-
|
|
316
|
-
for (const account of accountNumbers) {
|
|
317
|
-
debug(`setting account: ${account}`);
|
|
318
|
-
await setAccount(page, account);
|
|
319
|
-
await page.waitForTimeout(1000);
|
|
320
|
-
accounts.push((await fetchTransactionsForAccount(page, startDate, account, scraperOptions)));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
return accounts;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
async function fetchFutureDebits(page) {
|
|
327
|
-
const futureDebitsSelector = '.homepage-banks-top';
|
|
328
|
-
const result = await (0, _elementsInteractions.pageEvalAll)(page, futureDebitsSelector, [], items => {
|
|
329
|
-
const debitMountClass = 'amount';
|
|
330
|
-
const debitWhenChargeClass = 'when-charge';
|
|
331
|
-
const debitBankNumberClass = 'bankDesc';
|
|
332
|
-
return items.map(currBankEl => {
|
|
333
|
-
const amount = currBankEl.getElementsByClassName(debitMountClass)[0].innerText;
|
|
334
|
-
const whenCharge = currBankEl.getElementsByClassName(debitWhenChargeClass)[0].innerText;
|
|
335
|
-
const bankNumber = currBankEl.getElementsByClassName(debitBankNumberClass)[0].innerText;
|
|
336
|
-
return {
|
|
337
|
-
amount,
|
|
338
|
-
whenCharge,
|
|
339
|
-
bankNumber
|
|
340
|
-
};
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
const futureDebits = result.map(item => {
|
|
344
|
-
var _$exec2, _$exec3;
|
|
345
|
-
|
|
346
|
-
const amountData = getAmountData(item.amount);
|
|
347
|
-
const chargeDate = (_$exec2 = /\d{1,2}[/]\d{2}[/]\d{2,4}/.exec(item.whenCharge)) === null || _$exec2 === void 0 ? void 0 : _$exec2[0];
|
|
348
|
-
const bankAccountNumber = (_$exec3 = /\d+-\d+/.exec(item.bankNumber)) === null || _$exec3 === void 0 ? void 0 : _$exec3[0];
|
|
349
|
-
return {
|
|
350
|
-
amount: amountData.amount,
|
|
351
|
-
amountCurrency: amountData.currency,
|
|
352
|
-
chargeDate,
|
|
353
|
-
bankAccountNumber
|
|
354
|
-
};
|
|
355
|
-
});
|
|
356
|
-
return futureDebits;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
153
|
class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
|
|
360
154
|
constructor(...args) {
|
|
361
155
|
super(...args);
|
|
@@ -377,6 +171,48 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
|
|
|
377
171
|
});
|
|
378
172
|
}
|
|
379
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
|
+
|
|
380
216
|
getLoginOptions(credentials) {
|
|
381
217
|
return {
|
|
382
218
|
loginUrl: `${LOGIN_URL}`,
|
|
@@ -385,28 +221,81 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
|
|
|
385
221
|
possibleResults: getPossibleLoginResults(),
|
|
386
222
|
checkReadiness: async () => (0, _elementsInteractions.waitUntilElementFound)(this.page, '#ccLoginDesktopBtn'),
|
|
387
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
|
+
},
|
|
388
238
|
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
|
|
389
239
|
};
|
|
390
240
|
}
|
|
391
241
|
|
|
242
|
+
isCardTransactionDetails(result) {
|
|
243
|
+
return result.result !== undefined;
|
|
244
|
+
}
|
|
245
|
+
|
|
392
246
|
async fetchData() {
|
|
393
|
-
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');
|
|
394
248
|
const startDate = this.options.startDate || defaultStartMoment.toDate();
|
|
395
249
|
|
|
396
250
|
const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
|
|
397
251
|
|
|
398
252
|
debug(`fetch transactions starting ${startMoment.format()}`);
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
await this.
|
|
403
|
-
|
|
404
|
-
const accounts = await
|
|
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
|
+
}));
|
|
405
294
|
debug('return the scraped accounts');
|
|
295
|
+
debug(JSON.stringify(accounts, null, 2));
|
|
406
296
|
return {
|
|
407
297
|
success: true,
|
|
408
|
-
accounts
|
|
409
|
-
futureDebits
|
|
298
|
+
accounts
|
|
410
299
|
};
|
|
411
300
|
}
|
|
412
301
|
|
|
@@ -414,4 +303,4 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
|
|
|
414
303
|
|
|
415
304
|
var _default = VisaCalScraper;
|
|
416
305
|
exports.default = _default;
|
|
417
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy92aXNhLWNhbC50cyJdLCJuYW1lcyI6WyJMT0dJTl9VUkwiLCJUUkFOU0FDVElPTlNfVVJMIiwiTE9OR19EQVRFX0ZPUk1BVCIsIkRBVEVfRk9STUFUIiwiSW52YWxpZFBhc3N3b3JkTWVzc2FnZSIsImRlYnVnIiwiZ2V0TG9naW5GcmFtZSIsInBhZ2UiLCJmcmFtZSIsImZyYW1lcyIsImZpbmQiLCJmIiwidXJsIiwiaW5jbHVkZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIkVycm9yIiwiaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IiLCJlcnJvckZvdW5kIiwiZXJyb3JNZXNzYWdlIiwiaXRlbSIsImlubmVyVGV4dCIsImdldFBvc3NpYmxlTG9naW5SZXN1bHRzIiwidXJscyIsIkxvZ2luUmVzdWx0cyIsIlN1Y2Nlc3MiLCJJbnZhbGlkUGFzc3dvcmQiLCJvcHRpb25zIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidmFsdWUiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiZ2V0QW1vdW50RGF0YSIsImFtb3VudFN0ciIsImFtb3VudFN0ckNsbiIsInJlcGxhY2UiLCJjdXJyZW5jeSIsImFtb3VudCIsIlNIRUtFTF9DVVJSRU5DWV9TWU1CT0wiLCJwYXJzZUZsb2F0IiwiU0hFS0VMX0NVUlJFTkNZIiwiRE9MTEFSX0NVUlJFTkNZX1NZTUJPTCIsIkRPTExBUl9DVVJSRU5DWSIsIkVVUk9fQ1VSUkVOQ1lfU1lNQk9MIiwiRVVST19DVVJSRU5DWSIsInBhcnRzIiwic3BsaXQiLCJnZXRUcmFuc2FjdGlvbkluc3RhbGxtZW50cyIsIm1lbW8iLCJwYXJzZWRNZW1vIiwiZXhlYyIsImxlbmd0aCIsIm51bWJlciIsInBhcnNlSW50IiwidG90YWwiLCJjb252ZXJ0VHJhbnNhY3Rpb25zIiwidHhucyIsIm1hcCIsInR4biIsIm9yaWdpbmFsQW1vdW50VHVwbGUiLCJvcmlnaW5hbEFtb3VudCIsImNoYXJnZWRBbW91bnRUdXBsZSIsImNoYXJnZWRBbW91bnQiLCJpbnN0YWxsbWVudHMiLCJ0eG5EYXRlIiwiZGF0ZSIsInByb2Nlc3NlZERhdGVGb3JtYXQiLCJwcm9jZXNzZWREYXRlIiwidHhuUHJvY2Vzc2VkRGF0ZSIsInJlc3VsdCIsInR5cGUiLCJUcmFuc2FjdGlvblR5cGVzIiwiSW5zdGFsbG1lbnRzIiwiTm9ybWFsIiwic3RhdHVzIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIkNvbXBsZXRlZCIsImFkZCIsInRvSVNPU3RyaW5nIiwib3JpZ2luYWxDdXJyZW5jeSIsImNoYXJnZWRDdXJyZW5jeSIsImRlc2NyaXB0aW9uIiwiZmV0Y2hUcmFuc2FjdGlvbnNGb3JBY2NvdW50Iiwic3RhcnREYXRlIiwiYWNjb3VudE51bWJlciIsInNjcmFwZXJPcHRpb25zIiwic3RhcnREYXRlVmFsdWUiLCJmb3JtYXQiLCJkYXRlU2VsZWN0b3IiLCJkYXRlSGlkZGVuRmllbGRTZWxlY3RvciIsImJ1dHRvblNlbGVjdG9yIiwibmV4dFBhZ2VTZWxlY3RvciIsImJpbGxpbmdMYWJlbFNlbGVjdG9yIiwic2Vjb25kYXJ5QmlsbGluZ0xhYmVsU2VsZWN0b3IiLCJub0RhdGFTZWxlY3RvciIsIml0ZW1zIiwiZWwiLCJzdGFydERhdGVJbmRleCIsImZpbmRJbmRleCIsIm9wdGlvbiIsImFjY291bnRUcmFuc2FjdGlvbnMiLCJjdXJyZW50RGF0ZUluZGV4Iiwid2FpdEZvclRpbWVvdXQiLCJhbGwiLCJ3YWl0Rm9yTmF2aWdhdGlvbiIsIndhaXRVbnRpbCIsInBhZ2VIYXNOb1RyYW5zYWN0aW9ucyIsImVsZW1lbnQiLCJzaXRlVmFsdWUiLCJiaWxsaW5nRGF0ZUxhYmVsIiwic2V0dGxlbWVudERhdGVSZWdleCIsImJpbGxpbmdEYXRlIiwiaGFzTmV4dFBhZ2UiLCJyYXdUcmFuc2FjdGlvbnMiLCJjb2x1bW5zIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJwdXNoIiwiZmlsdGVyIiwib3V0cHV0RGF0YSIsImVuYWJsZVRyYW5zYWN0aW9uc0ZpbHRlckJ5RGF0ZSIsImNvbWJpbmVJbnN0YWxsbWVudHMiLCJzdWJzdHJpbmciLCJnZXRBY2NvdW50TnVtYmVycyIsImVsZW1lbnRzIiwiZSIsInRleHQiLCJ0aGVuIiwicmVzIiwidHJpbSIsInNldEFjY291bnQiLCJhY2NvdW50IiwiZWxlbSIsImEiLCJjbGljayIsImZldGNoVHJhbnNhY3Rpb25zIiwiYWNjb3VudE51bWJlcnMiLCJhY2NvdW50cyIsImZldGNoRnV0dXJlRGViaXRzIiwiZnV0dXJlRGViaXRzU2VsZWN0b3IiLCJkZWJpdE1vdW50Q2xhc3MiLCJkZWJpdFdoZW5DaGFyZ2VDbGFzcyIsImRlYml0QmFua051bWJlckNsYXNzIiwiY3VyckJhbmtFbCIsImdldEVsZW1lbnRzQnlDbGFzc05hbWUiLCJ3aGVuQ2hhcmdlIiwiYmFua051bWJlciIsImZ1dHVyZURlYml0cyIsImFtb3VudERhdGEiLCJjaGFyZ2VEYXRlIiwiYmFua0FjY291bnROdW1iZXIiLCJhbW91bnRDdXJyZW5jeSIsIlZpc2FDYWxTY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImdldExvZ2luT3B0aW9ucyIsImxvZ2luVXJsIiwiZmllbGRzIiwic3VibWl0QnV0dG9uU2VsZWN0b3IiLCJwb3NzaWJsZVJlc3VsdHMiLCJjaGVja1JlYWRpbmVzcyIsInByZUFjdGlvbiIsIm9wZW5Mb2dpblBvcHVwIiwidXNlckFnZW50IiwiZmV0Y2hEYXRhIiwiZGVmYXVsdFN0YXJ0TW9tZW50Iiwic3VidHJhY3QiLCJ0b0RhdGUiLCJzdGFydE1vbWVudCIsIm1vbWVudCIsIm1heCIsIm5hdmlnYXRlVG8iLCJ1bmRlZmluZWQiLCJzdWNjZXNzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUVBOztBQUNBOztBQUdBOztBQVFBOztBQUdBOztBQUNBOztBQUNBOzs7Ozs7QUFFQSxNQUFNQSxTQUFTLEdBQUcsK0JBQWxCO0FBQ0EsTUFBTUMsZ0JBQWdCLEdBQUcsdUZBQXpCO0FBQ0EsTUFBTUMs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THdLLE1BQUFBLE9BQU8sRUFBRSxJQURKO0FBRUxuQyxNQUFBQSxRQUZLO0FBR0xVLE1BQUFBO0FBSEssS0FBUDtBQUtEOztBQW5EaUQ7O2VBc0RyQ0ssYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQsIHsgTW9tZW50IH0gZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IEZyYW1lLCBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcbmltcG9ydCB7IEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIsIExvZ2luT3B0aW9ucywgTG9naW5SZXN1bHRzIH0gZnJvbSAnLi9iYXNlLXNjcmFwZXItd2l0aC1icm93c2VyJztcbmltcG9ydCB7XG4gIGNsaWNrQnV0dG9uLCBlbGVtZW50UHJlc2VudE9uUGFnZSwgcGFnZUV2YWwsIHBhZ2VFdmFsQWxsLCBzZXRWYWx1ZSwgd2FpdFVudGlsRWxlbWVudEZvdW5kLFxufSBmcm9tICcuLi9oZWxwZXJzL2VsZW1lbnRzLWludGVyYWN0aW9ucyc7XG5pbXBvcnQge1xuICBUcmFuc2FjdGlvbixcbiAgVHJhbnNhY3Rpb25JbnN0YWxsbWVudHMsXG4gIFRyYW5zYWN0aW9uc0FjY291bnQsXG4gIFRyYW5zYWN0aW9uU3RhdHVzZXMsXG4gIFRyYW5zYWN0aW9uVHlwZXMsXG59IGZyb20gJy4uL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBTY3JhcGVyT3B0aW9ucywgU2NhcGVyU2NyYXBpbmdSZXN1bHQsIFNjcmFwZXJDcmVkZW50aWFscyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyJztcbmltcG9ydCB7XG4gIERPTExBUl9DVVJSRU5DWSwgRE9MTEFSX0NVUlJFTkNZX1NZTUJPTCwgRVVST19DVVJSRU5DWSwgRVVST19DVVJSRU5DWV9TWU1CT0wsIFNIRUtFTF9DVVJSRU5DWSwgU0hFS0VMX0NVUlJFTkNZX1NZTUJPTCxcbn0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IHdhaXRVbnRpbCB9IGZyb20gJy4uL2hlbHBlcnMvd2FpdGluZyc7XG5pbXBvcnQgeyBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBnZXREZWJ1ZyB9IGZyb20gJy4uL2hlbHBlcnMvZGVidWcnO1xuXG5jb25zdCBMT0dJTl9VUkwgPSAnaHR0cHM6Ly93d3cuY2FsLW9ubGluZS5jby5pbC8nO1xuY29uc3QgVFJBTlNBQ1RJT05TX1VSTCA9ICdodHRwczovL3NlcnZpY2VzLmNhbC1vbmxpbmUuY28uaWwvQ2FyZC1Ib2xkZXJzL1NjcmVlbnMvVHJhbnNhY3Rpb25zL1RyYW5zYWN0aW9ucy5hc3B4JztcbmNvbnN0IExPTkdfREFURV9GT1JNQVQgPSAnREQvTU0vWVlZWSc7XG5jb25zdCBEQVRFX0ZPUk1BVCA9ICdERC9NTS9ZWSc7XG5jb25zdCBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlID0gJ9ep150g15TXntep16rXntepINeQ15Ug15TXodeZ16HXnteUINep15TXldeW16DXlSDXqdeS15XXmdeZ150nO1xuXG5jb25zdCBkZWJ1ZyA9IGdldERlYnVnKCd2aXNhLWNhbCcpO1xuXG5pbnRlcmZhY2UgU2NyYXBlZFRyYW5zYWN0aW9uIHtcbiAgZGF0ZTogc3RyaW5nO1xuICBwcm9jZXNzZWREYXRlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIG9yaWdpbmFsQW1vdW50OiBzdHJpbmc7XG4gIGNoYXJnZWRBbW91bnQ6IHN0cmluZztcbiAgbWVtbzogc3RyaW5nO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRMb2dpbkZyYW1lKHBhZ2U6IFBhZ2UpIHtcbiAgbGV0IGZyYW1lOiBGcmFtZSB8IG51bGwgPSBudWxsO1xuICBkZWJ1Zygnd2FpdCB1bnRpbCBsb2dpbiBmcmFtZSBmb3VuZCcpO1xuICBhd2FpdCB3YWl0VW50aWwoKCkgPT4ge1xuICAgIGZyYW1lID0gcGFnZVxuICAgICAgLmZyYW1lcygpXG4gICAgICAuZmluZCgoZikgPT4gZi51cmwoKS5pbmNsdWRlcygnY2FsY29ubmVjdCcpKSB8fCBudWxsO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoISFmcmFtZSk7XG4gIH0sICd3YWl0IGZvciBpZnJhbWUgd2l0aCBsb2dpbiBmb3JtJywgMTAwMDAsIDEwMDApO1xuXG4gIGlmICghZnJhbWUpIHtcbiAgICBkZWJ1ZygnZmFpbGVkIHRvIGZpbmQgbG9naW4gZnJhbWUgZm9yIDEwIHNlY29uZHMnKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBleHRyYWN0IGxvZ2luIGlmcmFtZScpO1xuICB9XG5cbiAgcmV0dXJuIGZyYW1lO1xufVxuXG5hc3luYyBmdW5jdGlvbiBoYXNJbnZhbGlkUGFzc3dvcmRFcnJvcihwYWdlOiBQYWdlKSB7XG4gIGNvbnN0IGZyYW1lID0gYXdhaXQgZ2V0TG9naW5GcmFtZShwYWdlKTtcbiAgY29uc3QgZXJyb3JGb3VuZCA9IGF3YWl0IGVsZW1lbnRQcmVzZW50T25QYWdlKGZyYW1lLCAnZGl2LmdlbmVyYWwtZXJyb3IgPiBkaXYnKTtcbiAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3JGb3VuZCA/IGF3YWl0IHBhZ2VFdmFsKGZyYW1lLCAnZGl2LmdlbmVyYWwtZXJyb3IgPiBkaXYnLCAnJywgKGl0ZW0pID0+IHtcbiAgICByZXR1cm4gKGl0ZW0gYXMgSFRNTERpdkVsZW1lbnQpLmlubmVyVGV4dDtcbiAgfSkgOiAnJztcbiAgcmV0dXJuIGVycm9yTWVzc2FnZSA9PT0gSW52YWxpZFBhc3N3b3JkTWVzc2FnZTtcbn1cblxuZnVuY3Rpb24gZ2V0UG9zc2libGVMb2dpblJlc3VsdHMoKSB7XG4gIGRlYnVnKCdyZXR1cm4gcG9zc2libGUgbG9naW4gcmVzdWx0cycpO1xuICBjb25zdCB1cmxzOiBMb2dpbk9wdGlvbnNbJ3Bvc3NpYmxlUmVzdWx0cyddID0ge1xuICAgIFtMb2dpblJlc3VsdHMuU3VjY2Vzc106IFsvQWNjb3VudE1hbmFnZW1lbnQvaV0sXG4gICAgW0xvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmRdOiBbYXN5bmMgKG9wdGlvbnM/OiB7IHBhZ2U/OiBQYWdlfSkgPT4ge1xuICAgICAgY29uc3QgcGFnZSA9IG9wdGlvbnM/LnBhZ2U7XG4gICAgICBpZiAoIXBhZ2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0ludmFsaWRQYXNzd29yZEVycm9yKHBhZ2UpO1xuICAgIH1dLFxuICAgIC8vIFtMb2dpblJlc3VsdHMuQWNjb3VudEJsb2NrZWRdOiBbXSwgLy8gVE9ETyBhZGQgd2hlbiByZWFjaGluZyB0aGlzIHNjZW5hcmlvXG4gICAgLy8gW0xvZ2luUmVzdWx0cy5DaGFuZ2VQYXNzd29yZF06IFtdLCAvLyBUT0RPIGFkZCB3aGVuIHJlYWNoaW5nIHRoaXMgc2NlbmFyaW9cbiAgfTtcbiAgcmV0dXJuIHVybHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxvZ2luRmllbGRzKGNyZWRlbnRpYWxzOiBTY3JhcGVyQ3JlZGVudGlhbHMpIHtcbiAgZGVidWcoJ2NyZWF0ZSBsb2dpbiBmaWVsZHMgZm9yIHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICByZXR1cm4gW1xuICAgIHsgc2VsZWN0b3I6ICdbZm9ybWNvbnRyb2xuYW1lPVwidXNlck5hbWVcIl0nLCB2YWx1ZTogY3JlZGVudGlhbHMudXNlcm5hbWUgfSxcbiAgICB7IHNlbGVjdG9yOiAnW2Zvcm1jb250cm9sbmFtZT1cInBhc3N3b3JkXCJdJywgdmFsdWU6IGNyZWRlbnRpYWxzLnBhc3N3b3JkIH0sXG4gIF07XG59XG5cblxuZnVuY3Rpb24gZ2V0QW1vdW50RGF0YShhbW91bnRTdHI6IHN0cmluZykge1xuICBjb25zdCBhbW91bnRTdHJDbG4gPSBhbW91bnRTdHIucmVwbGFjZSgnLCcsICcnKTtcbiAgbGV0IGN1cnJlbmN5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgbGV0IGFtb3VudDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGlmIChhbW91bnRTdHJDbG4uaW5jbHVkZXMoU0hFS0VMX0NVUlJFTkNZX1NZTUJPTCkpIHtcbiAgICBhbW91bnQgPSAtcGFyc2VGbG9hdChhbW91bnRTdHJDbG4ucmVwbGFjZShTSEVLRUxfQ1VSUkVOQ1lfU1lNQk9MLCAnJykpO1xuICAgIGN1cnJlbmN5ID0gU0hFS0VMX0NVUlJFTkNZO1xuICB9IGVsc2UgaWYgKGFtb3VudFN0ckNsbi5pbmNsdWRlcyhET0xMQVJfQ1VSUkVOQ1lfU1lNQk9MKSkge1xuICAgIGFtb3VudCA9IC1wYXJzZUZsb2F0KGFtb3VudFN0ckNsbi5yZXBsYWNlKERPTExBUl9DVVJSRU5DWV9TWU1CT0wsICcnKSk7XG4gICAgY3VycmVuY3kgPSBET0xMQVJfQ1VSUkVOQ1k7XG4gIH0gZWxzZSBpZiAoYW1vdW50U3RyQ2xuLmluY2x1ZGVzKEVVUk9fQ1VSUkVOQ1lfU1lNQk9MKSkge1xuICAgIGFtb3VudCA9IC1wYXJzZUZsb2F0KGFtb3VudFN0ckNsbi5yZXBsYWNlKEVVUk9fQ1VSUkVOQ1lfU1lNQk9MLCAnJykpO1xuICAgIGN1cnJlbmN5ID0gRVVST19DVVJSRU5DWTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwYXJ0cyA9IGFtb3VudFN0ckNsbi5zcGxpdCgnICcpO1xuICAgIFtjdXJyZW5jeV0gPSBwYXJ0cztcbiAgICBhbW91bnQgPSAtcGFyc2VGbG9hdChwYXJ0c1sxXSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGFtb3VudCxcbiAgICBjdXJyZW5jeSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0VHJhbnNhY3Rpb25JbnN0YWxsbWVudHMobWVtbzogc3RyaW5nKTogVHJhbnNhY3Rpb25JbnN0YWxsbWVudHMgfCBudWxsIHtcbiAgY29uc3QgcGFyc2VkTWVtbyA9ICgv16rXqdec15XXnSAoXFxkKykg157XqteV15ogKFxcZCspLykuZXhlYyhtZW1vIHx8ICcnKTtcblxuICBpZiAoIXBhcnNlZE1lbW8gfHwgcGFyc2VkTWVtby5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbnVtYmVyOiBwYXJzZUludChwYXJzZWRNZW1vWzFdLCAxMCksXG4gICAgdG90YWw6IHBhcnNlSW50KHBhcnNlZE1lbW9bMl0sIDEwKSxcbiAgfTtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2FjdGlvbnModHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10pOiBUcmFuc2FjdGlvbltdIHtcbiAgZGVidWcoYGNvbnZlcnQgJHt0eG5zLmxlbmd0aH0gcmF3IHRyYW5zYWN0aW9ucyB0byBvZmZpY2lhbCBUcmFuc2FjdGlvbiBzdHJ1Y3R1cmVgKTtcbiAgcmV0dXJuIHR4bnMubWFwKCh0eG4pID0+IHtcbiAgICBjb25zdCBvcmlnaW5hbEFtb3VudFR1cGxlID0gZ2V0QW1vdW50RGF0YSh0eG4ub3JpZ2luYWxBbW91bnQgfHwgJycpO1xuICAgIGNvbnN0IGNoYXJnZWRBbW91bnRUdXBsZSA9IGdldEFtb3VudERhdGEodHhuLmNoYXJnZWRBbW91bnQgfHwgJycpO1xuXG4gICAgY29uc3QgaW5zdGFsbG1lbnRzID0gZ2V0VHJhbnNhY3Rpb25JbnN0YWxsbWVudHModHhuLm1lbW8pO1xuICAgIGNvbnN0IHR4bkRhdGUgPSBtb21lbnQodHhuLmRhdGUsIERBVEVfRk9STUFUKTtcbiAgICBjb25zdCBwcm9jZXNzZWREYXRlRm9ybWF0ID1cbiAgICAgIHR4bi5wcm9jZXNzZWREYXRlLmxlbmd0aCA9PT0gOCA/XG4gICAgICAgIERBVEVfRk9STUFUIDpcbiAgICAgICAgdHhuLnByb2Nlc3NlZERhdGUubGVuZ3RoID09PSA5IHx8IHR4bi5wcm9jZXNzZWREYXRlLmxlbmd0aCA9PT0gMTAgP1xuICAgICAgICAgIExPTkdfREFURV9GT1JNQVQgOlxuICAgICAgICAgIG51bGw7XG4gICAgaWYgKCFwcm9jZXNzZWREYXRlRm9ybWF0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcHJvY2Vzc2VkIGRhdGUnKTtcbiAgICB9XG4gICAgY29uc3QgdHhuUHJvY2Vzc2VkRGF0ZSA9IG1vbWVudCh0eG4ucHJvY2Vzc2VkRGF0ZSwgcHJvY2Vzc2VkRGF0ZUZvcm1hdCk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgdHlwZTogaW5zdGFsbG1lbnRzID8gVHJhbnNhY3Rpb25UeXBlcy5JbnN0YWxsbWVudHMgOiBUcmFuc2FjdGlvblR5cGVzLk5vcm1hbCxcbiAgICAgIHN0YXR1czogVHJhbnNhY3Rpb25TdGF0dXNlcy5Db21wbGV0ZWQsXG4gICAgICBkYXRlOiBpbnN0YWxsbWVudHMgPyB0eG5EYXRlLmFkZChpbnN0YWxsbWVudHMubnVtYmVyIC0gMSwgJ21vbnRoJykudG9JU09TdHJpbmcoKSA6IHR4bkRhdGUudG9JU09TdHJpbmcoKSxcbiAgICAgIHByb2Nlc3NlZERhdGU6IHR4blByb2Nlc3NlZERhdGUudG9JU09TdHJpbmcoKSxcbiAgICAgIG9yaWdpbmFsQW1vdW50OiBvcmlnaW5hbEFtb3VudFR1cGxlLmFtb3VudCxcbiAgICAgIG9yaWdpbmFsQ3VycmVuY3k6IG9yaWdpbmFsQW1vdW50VHVwbGUuY3VycmVuY3ksXG4gICAgICBjaGFyZ2VkQW1vdW50OiBjaGFyZ2VkQW1vdW50VHVwbGUuYW1vdW50LFxuICAgICAgY2hhcmdlZEN1cnJlbmN5OiBjaGFyZ2VkQW1vdW50VHVwbGUuY3VycmVuY3ksXG4gICAgICBkZXNjcmlwdGlvbjogdHhuLmRlc2NyaXB0aW9uIHx8ICcnLFxuICAgICAgbWVtbzogdHhuLm1lbW8gfHwgJycsXG4gICAgfTtcblxuICAgIGlmIChpbnN0YWxsbWVudHMpIHtcbiAgICAgIHJlc3VsdC5pbnN0YWxsbWVudHMgPSBpbnN0YWxsbWVudHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoVHJhbnNhY3Rpb25zRm9yQWNjb3VudChwYWdlOiBQYWdlLCBzdGFydERhdGU6IE1vbWVudCwgYWNjb3VudE51bWJlcjogc3RyaW5nLCBzY3JhcGVyT3B0aW9uczogU2NyYXBlck9wdGlvbnMpOiBQcm9taXNlPFRyYW5zYWN0aW9uc0FjY291bnQ+IHtcbiAgY29uc3Qgc3RhcnREYXRlVmFsdWUgPSBzdGFydERhdGUuZm9ybWF0KCdNTS9ZWVlZJyk7XG4gIGNvbnN0IGRhdGVTZWxlY3RvciA9ICdbaWQkPVwiRm9ybUFyZWFOb0JvcmRlcl9Gb3JtQXJlYV9jbG5kckRlYml0RGF0ZVNjb3BlX1RleHRCb3hcIl0nO1xuICBjb25zdCBkYXRlSGlkZGVuRmllbGRTZWxlY3RvciA9ICdbaWQkPVwiRm9ybUFyZWFOb0JvcmRlcl9Gb3JtQXJlYV9jbG5kckRlYml0RGF0ZVNjb3BlX0hpZGRlbkZpZWxkXCJdJztcbiAgY29uc3QgYnV0dG9uU2VsZWN0b3IgPSAnW2lkJD1cIkZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsU3VibWl0UmVxdWVzdFwiXSc7XG4gIGNvbnN0IG5leHRQYWdlU2VsZWN0b3IgPSAnW2lkJD1cIkZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsR3JpZFBhZ2VyX2J0bk5leHRcIl0nO1xuICBjb25zdCBiaWxsaW5nTGFiZWxTZWxlY3RvciA9ICdbaWQkPUZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsTWFpblRvb2xCYXJfbGJsQ2FwdGlvbl0nO1xuICBjb25zdCBzZWNvbmRhcnlCaWxsaW5nTGFiZWxTZWxlY3RvciA9ICdbaWQkPUZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsU2Vjb25kYXJ5VG9vbEJhcl9sYmxDYXB0aW9uXSc7XG4gIGNvbnN0IG5vRGF0YVNlbGVjdG9yID0gJ1tpZCQ9Rm9ybUFyZWFOb0JvcmRlcl9Gb3JtQXJlYV9tc2dib3hFcnJvck1lc3NhZ2VzXSc7XG5cbiAgZGVidWcoJ2ZpbmQgdGhlIHN0YXJ0IGRhdGUgaW5kZXggaW4gdGhlIGRyb3Bib3gnKTtcbiAgY29uc3Qgb3B0aW9ucyA9IGF3YWl0IHBhZ2VFdmFsQWxsKHBhZ2UsICdbaWQkPVwiRm9ybUFyZWFOb0JvcmRlcl9Gb3JtQXJlYV9jbG5kckRlYml0RGF0ZVNjb3BlX09wdGlvbkxpc3RcIl0gbGknLCBbXSwgKGl0ZW1zKSA9PiB7XG4gICAgcmV0dXJuIGl0ZW1zLm1hcCgoZWw6IGFueSkgPT4gZWwuaW5uZXJUZXh0KTtcbiAgfSk7XG4gIGNvbnN0IHN0YXJ0RGF0ZUluZGV4ID0gb3B0aW9ucy5maW5kSW5kZXgoKG9wdGlvbikgPT4gb3B0aW9uID09PSBzdGFydERhdGVWYWx1ZSk7XG5cbiAgZGVidWcoYHNjcmFwZSAke29wdGlvbnMubGVuZ3RoIC0gc3RhcnREYXRlSW5kZXh9IGJpbGxpbmcgY3ljbGVzYCk7XG4gIGNvbnN0IGFjY291bnRUcmFuc2FjdGlvbnM6IFRyYW5zYWN0aW9uW10gPSBbXTtcbiAgZm9yIChsZXQgY3VycmVudERhdGVJbmRleCA9IHN0YXJ0RGF0ZUluZGV4OyBjdXJyZW50RGF0ZUluZGV4IDwgb3B0aW9ucy5sZW5ndGg7IGN1cnJlbnREYXRlSW5kZXggKz0gMSkge1xuICAgIGRlYnVnKCd3YWl0IGZvciBkYXRlIHNlbGVjdG9yIHRvIGJlIGZvdW5kJyk7XG4gICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKHBhZ2UsIGRhdGVTZWxlY3RvciwgdHJ1ZSk7XG4gICAgZGVidWcoYHNldCBoaWRkZW4gdmFsdWUgb2YgdGhlIGRhdGUgc2VsZWN0b3IgdG8gYmUgdGhlIGluZGV4ICR7Y3VycmVudERhdGVJbmRleH1gKTtcbiAgICBhd2FpdCBzZXRWYWx1ZShwYWdlLCBkYXRlSGlkZGVuRmllbGRTZWxlY3RvciwgYCR7Y3VycmVudERhdGVJbmRleH1gKTtcbiAgICBkZWJ1Zygnd2FpdCBhIHNlY29uZCB0byB3b3JrYXJvdW5kIG5hdmlnYXRpb24gaXNzdWUgaW4gaGVhZGxlc3MgYnJvd3NlciBtb2RlJyk7XG4gICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgxMDAwKTtcbiAgICBkZWJ1ZygnY2xpY2sgb24gdGhlIGZpbHRlciBzdWJtaXQgYnV0dG9uIGFuZCB3YWl0IGZvciBuYXZpZ2F0aW9uJyk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgcGFnZS53YWl0Rm9yTmF2aWdhdGlvbih7IHdhaXRVbnRpbDogJ2RvbWNvbnRlbnRsb2FkZWQnIH0pLFxuICAgICAgY2xpY2tCdXR0b24ocGFnZSwgYnV0dG9uU2VsZWN0b3IpLFxuICAgIF0pO1xuICAgIGRlYnVnKCdjaGVjayBpZiBtb250aCBoYXMgbm8gdHJhbnNhY3Rpb25zJyk7XG4gICAgY29uc3QgcGFnZUhhc05vVHJhbnNhY3Rpb25zID0gYXdhaXQgcGFnZUV2YWwocGFnZSwgbm9EYXRhU2VsZWN0b3IsIGZhbHNlLCAoKGVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHNpdGVWYWx1ZSA9ICgoZWxlbWVudCBhcyBIVE1MU3BhbkVsZW1lbnQpLmlubmVyVGV4dCB8fCAnJykucmVwbGFjZSgvW14g15At16pdL2csICcnKTtcbiAgICAgIHJldHVybiBzaXRlVmFsdWUgPT09ICfXnNeQINeg157XpteQ15Ug16DXqteV16DXmdedJztcbiAgICB9KSk7XG5cbiAgICBpZiAocGFnZUhhc05vVHJhbnNhY3Rpb25zKSB7XG4gICAgICBkZWJ1ZygncGFnZSBoYXMgbm8gdHJhbnNhY3Rpb25zJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdmaW5kIHRoZSBiaWxsaW5nIGRhdGUnKTtcbiAgICAgIGxldCBiaWxsaW5nRGF0ZUxhYmVsID0gYXdhaXQgcGFnZUV2YWwocGFnZSwgYmlsbGluZ0xhYmVsU2VsZWN0b3IsICcnLCAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgcmV0dXJuIChlbGVtZW50IGFzIEhUTUxTcGFuRWxlbWVudCkuaW5uZXJUZXh0O1xuICAgICAgfSkpO1xuICAgICAgbGV0IHNldHRsZW1lbnREYXRlUmVnZXggPSAvXFxkezEsMn1bL11cXGR7Mn1bL11cXGR7Miw0fS87XG5cbiAgICAgIGlmIChiaWxsaW5nRGF0ZUxhYmVsID09PSAnJykge1xuICAgICAgICBiaWxsaW5nRGF0ZUxhYmVsID0gYXdhaXQgcGFnZUV2YWwocGFnZSwgc2Vjb25kYXJ5QmlsbGluZ0xhYmVsU2VsZWN0b3IsICcnLCAoKGVsZW1lbnQpID0+IHtcbiAgICAgICAgICByZXR1cm4gKGVsZW1lbnQgYXMgSFRNTFNwYW5FbGVtZW50KS5pbm5lclRleHQ7XG4gICAgICAgIH0pKTtcbiAgICAgICAgc2V0dGxlbWVudERhdGVSZWdleCA9IC9cXGR7MSwyfVsvXVxcZHsyLDR9LztcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmlsbGluZ0RhdGUgPSBzZXR0bGVtZW50RGF0ZVJlZ2V4LmV4ZWMoYmlsbGluZ0RhdGVMYWJlbCk/LlswXTtcblxuICAgICAgaWYgKCFiaWxsaW5nRGF0ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byBmZXRjaCBwcm9jZXNzIGRhdGUnKTtcbiAgICAgIH1cblxuICAgICAgZGVidWcoYGZvdW5kIHRoZSBiaWxsaW5nIGRhdGUgZm9yIHRoYXQgbW9udGggJHtiaWxsaW5nRGF0ZX1gKTtcbiAgICAgIGxldCBoYXNOZXh0UGFnZSA9IGZhbHNlO1xuICAgICAgZG8ge1xuICAgICAgICBkZWJ1ZygnZmV0Y2ggcmF3IHRyYW5zYWN0aW9ucyBmcm9tIHBhZ2UnKTtcbiAgICAgICAgY29uc3QgcmF3VHJhbnNhY3Rpb25zID0gYXdhaXQgcGFnZUV2YWxBbGw8KFNjcmFwZWRUcmFuc2FjdGlvbiB8IG51bGwpW10+KHBhZ2UsICcjY3RsTWFpbkdyaWQgPiB0Ym9keSB0ciwgI2N0bFNlY29uZGFyeUdyaWQgPiB0Ym9keSB0cicsIFtdLCAoaXRlbXMsIGJpbGxpbmdEYXRlKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIChpdGVtcykubWFwKChlbCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29sdW1ucyA9IGVsLmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0ZCcpO1xuICAgICAgICAgICAgaWYgKGNvbHVtbnMubGVuZ3RoID09PSA2KSB7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzc2VkRGF0ZTogY29sdW1uc1swXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgZGF0ZTogY29sdW1uc1sxXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGNvbHVtbnNbMl0uaW5uZXJUZXh0LFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsQW1vdW50OiBjb2x1bW5zWzNdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBjaGFyZ2VkQW1vdW50OiBjb2x1bW5zWzRdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBtZW1vOiBjb2x1bW5zWzVdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjb2x1bW5zLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHByb2Nlc3NlZERhdGU6IGJpbGxpbmdEYXRlLFxuICAgICAgICAgICAgICAgIGRhdGU6IGNvbHVtbnNbMF0uaW5uZXJUZXh0LFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBjb2x1bW5zWzFdLmlubmVyVGV4dCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbEFtb3VudDogY29sdW1uc1syXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgY2hhcmdlZEFtb3VudDogY29sdW1uc1szXS5pbm5lclRleHQsXG4gICAgICAgICAgICAgICAgbWVtbzogY29sdW1uc1s0XS5pbm5lclRleHQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSwgYmlsbGluZ0RhdGUpO1xuICAgICAgICBkZWJ1ZyhgZmV0Y2hlZCAke3Jhd1RyYW5zYWN0aW9ucy5sZW5ndGh9IHJhdyB0cmFuc2FjdGlvbnMgZnJvbSBwYWdlYCk7XG4gICAgICAgIGFjY291bnRUcmFuc2FjdGlvbnMucHVzaCguLi5jb252ZXJ0VHJhbnNhY3Rpb25zKChyYXdUcmFuc2FjdGlvbnMgYXMgU2NyYXBlZFRyYW5zYWN0aW9uW10pXG4gICAgICAgICAgLmZpbHRlcigoaXRlbSkgPT4gISFpdGVtKSkpO1xuXG4gICAgICAgIGRlYnVnKCdjaGVjayBmb3IgZXhpc3RhbmNlIG9mIGFub3RoZXIgcGFnZScpO1xuICAgICAgICBoYXNOZXh0UGFnZSA9IGF3YWl0IGVsZW1lbnRQcmVzZW50T25QYWdlKHBhZ2UsIG5leHRQYWdlU2VsZWN0b3IpO1xuICAgICAgICBpZiAoaGFzTmV4dFBhZ2UpIHtcbiAgICAgICAgICBkZWJ1ZygnaGFzIGFub3RoZXIgcGFnZSwgY2xpY2sgb24gYnV0dG9uIG5leHQgYW5kIHdhaXQgZm9yIHBhZ2UgbmF2aWdhdGlvbicpO1xuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHBhZ2Uud2FpdEZvck5hdmlnYXRpb24oeyB3YWl0VW50aWw6ICdkb21jb250ZW50bG9hZGVkJyB9KSxcbiAgICAgICAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKHBhZ2UsICdbaWQkPUZvcm1BcmVhTm9Cb3JkZXJfRm9ybUFyZWFfY3RsR3JpZFBhZ2VyX2J0bk5leHRdJyksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKGhhc05leHRQYWdlKTtcbiAgICB9XG4gIH1cblxuICBkZWJ1ZygnZmlsZXIgb3V0IG9sZCB0cmFuc2FjdGlvbnMnKTtcbiAgY29uc3QgdHhucyA9IChzY3JhcGVyT3B0aW9ucy5vdXRwdXREYXRhPy5lbmFibGVUcmFuc2FjdGlvbnNGaWx0ZXJCeURhdGUgPz8gdHJ1ZSkgP1xuICAgIGZpbHRlck9sZFRyYW5zYWN0aW9ucyhhY2NvdW50VHJhbnNhY3Rpb25zLCBzdGFydERhdGUsIHNjcmFwZXJPcHRpb25zLmNvbWJpbmVJbnN0YWxsbWVudHMgfHwgZmFsc2UpIDpcbiAgICBhY2NvdW50VHJhbnNhY3Rpb25zO1xuICBkZWJ1ZyhgZm91bmQgJHt0eG5zLmxlbmd0aH0gdmFsaWQgdHJhbnNhY3Rpb25zIG91dCBvZiAke2FjY291bnRUcmFuc2FjdGlvbnMubGVuZ3RofSB0cmFuc2FjdGlvbnMgZm9yIGFjY291bnQgZW5kaW5nIHdpdGggJHthY2NvdW50TnVtYmVyLnN1YnN0cmluZyhhY2NvdW50TnVtYmVyLmxlbmd0aCAtIDIpfWApO1xuICByZXR1cm4ge1xuICAgIGFjY291bnROdW1iZXIsXG4gICAgdHhucyxcbiAgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWNjb3VudE51bWJlcnMocGFnZTogUGFnZSk6IFByb21pc2U8c3RyaW5nW10+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
|