israeli-bank-scrapers 3.6.0 → 3.8.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 +4 -4
- 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 +157 -343
- package/lib/scrapers/yahav.d.ts +7 -3
- package/lib/scrapers/yahav.js +1 -1
- package/package.json +1 -1
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,40 +15,42 @@ exports.default = void 0;
|
|
|
17
15
|
|
|
18
16
|
var _moment = _interopRequireDefault(require("moment"));
|
|
19
17
|
|
|
20
|
-
var
|
|
18
|
+
var _constants = require("../constants");
|
|
21
19
|
|
|
22
|
-
var
|
|
20
|
+
var _debug = require("../helpers/debug");
|
|
23
21
|
|
|
24
|
-
var
|
|
22
|
+
var _elementsInteractions = require("../helpers/elements-interactions");
|
|
25
23
|
|
|
26
|
-
var
|
|
24
|
+
var _fetch = require("../helpers/fetch");
|
|
27
25
|
|
|
28
|
-
var
|
|
26
|
+
var _navigation = require("../helpers/navigation");
|
|
29
27
|
|
|
30
|
-
var
|
|
28
|
+
var _storage = require("../helpers/storage");
|
|
31
29
|
|
|
32
|
-
var
|
|
30
|
+
var _transactions = require("../helpers/transactions");
|
|
33
31
|
|
|
34
|
-
var
|
|
32
|
+
var _waiting = require("../helpers/waiting");
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
var _transactions2 = require("../transactions");
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
|
|
39
37
|
|
|
40
|
-
function
|
|
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
|
|
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]: [/
|
|
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
|
|
111
|
-
|
|
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
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
188
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
processedDate:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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,84 @@ 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
|
-
|
|
247
|
+
var _this$options$futureM;
|
|
248
|
+
|
|
249
|
+
const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').subtract(6, 'months').add(1, 'day');
|
|
472
250
|
const startDate = this.options.startDate || defaultStartMoment.toDate();
|
|
473
251
|
|
|
474
252
|
const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
|
|
475
253
|
|
|
476
254
|
debug(`fetch transactions starting ${startMoment.format()}`);
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
await this.
|
|
481
|
-
|
|
482
|
-
const
|
|
255
|
+
const Authorization = await this.getAuthorizationHeader(); // Wait a little before `this.getCards` so that it would exist
|
|
256
|
+
|
|
257
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
258
|
+
const cards = await this.getCards();
|
|
259
|
+
const xSiteId = await this.getXSiteId();
|
|
260
|
+
const futureMonthsToScrape = (_this$options$futureM = this.options.futureMonthsToScrape) !== null && _this$options$futureM !== void 0 ? _this$options$futureM : 1;
|
|
261
|
+
const accounts = await Promise.all(cards.map(async card => {
|
|
262
|
+
var _this$options$outputD, _this$options$outputD2;
|
|
263
|
+
|
|
264
|
+
debug(`fetch transactions for card ${card.cardUniqueId}`);
|
|
265
|
+
const finalMonthToFetchMoment = (0, _moment.default)().add(futureMonthsToScrape, 'month');
|
|
266
|
+
const months = finalMonthToFetchMoment.diff(startMoment, 'months');
|
|
267
|
+
const allMonthsData = [];
|
|
268
|
+
|
|
269
|
+
for (let i = 0; i <= months; i += 1) {
|
|
270
|
+
const month = finalMonthToFetchMoment.clone().subtract(i, 'months');
|
|
271
|
+
const monthData = await (0, _fetch.fetchPostWithinPage)(this.page, TRANSACTIONS_REQUEST_ENDPOINT, {
|
|
272
|
+
cardUniqueId: card.cardUniqueId,
|
|
273
|
+
month: month.format('M'),
|
|
274
|
+
year: month.format('YYYY')
|
|
275
|
+
}, {
|
|
276
|
+
Authorization,
|
|
277
|
+
'X-Site-Id': xSiteId,
|
|
278
|
+
'Content-Type': 'application/json'
|
|
279
|
+
});
|
|
280
|
+
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) || ''}`);
|
|
281
|
+
|
|
282
|
+
if (!this.isCardTransactionDetails(monthData)) {
|
|
283
|
+
throw new Error('monthData is not of type CardTransactionDetails');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
allMonthsData.push(monthData);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const transactions = convertParsedDataToTransactions(allMonthsData);
|
|
290
|
+
debug('filer out old transactions');
|
|
291
|
+
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;
|
|
292
|
+
return {
|
|
293
|
+
txns,
|
|
294
|
+
accountNumber: card.last4Digits
|
|
295
|
+
};
|
|
296
|
+
}));
|
|
483
297
|
debug('return the scraped accounts');
|
|
298
|
+
debug(JSON.stringify(accounts, null, 2));
|
|
484
299
|
return {
|
|
485
300
|
success: true,
|
|
486
|
-
accounts
|
|
487
|
-
futureDebits
|
|
301
|
+
accounts
|
|
488
302
|
};
|
|
489
303
|
}
|
|
490
304
|
|
|
@@ -492,4 +306,4 @@ class VisaCalScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
|
|
|
492
306
|
|
|
493
307
|
var _default = VisaCalScraper;
|
|
494
308
|
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=
|
|
309
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy92aXNhLWNhbC50cyJdLCJuYW1lcyI6WyJMT0dJTl9VUkwiLCJUUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCIsIkludmFsaWRQYXNzd29yZE1lc3NhZ2UiLCJkZWJ1ZyIsInRyblR5cGVDb2RlIiwiZ2V0TG9naW5GcmFtZSIsInBhZ2UiLCJmcmFtZSIsImZyYW1lcyIsImZpbmQiLCJmIiwidXJsIiwiaW5jbHVkZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIkVycm9yIiwiaGFzSW52YWxpZFBhc3N3b3JkRXJyb3IiLCJlcnJvckZvdW5kIiwiZXJyb3JNZXNzYWdlIiwiaXRlbSIsImlubmVyVGV4dCIsImdldFBvc3NpYmxlTG9naW5SZXN1bHRzIiwidXJscyIsIkxvZ2luUmVzdWx0cyIsIlN1Y2Nlc3MiLCJJbnZhbGlkUGFzc3dvcmQiLCJvcHRpb25zIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidmFsdWUiLCJ1c2VybmFtZSIsInBhc3N3b3JkIiwiY2FyZEFuZFRyYW5zYWN0aW9uQ3VycmVuY3lTeW1ib2xJc1NoZWtlbCIsInRyYW5zYWN0aW9uIiwiZGViQ3JkQ3VycmVuY3lTeW1ib2wiLCJTSEVLRUxfQ1VSUkVOQ1lfU1lNQk9MIiwidHJuQ3VycmVuY3lTeW1ib2wiLCJjb252ZXJ0UGFyc2VkRGF0YVRvVHJhbnNhY3Rpb25zIiwicGFyc2VkRGF0YSIsImZsYXRNYXAiLCJtb250aERhdGEiLCJyZXN1bHQiLCJiYW5rQWNjb3VudHMiLCJhY2NvdW50cyIsImRlYml0RGF0ZXMiLCJkZWJpdERhdGUiLCJ0cmFuc2FjdGlvbnMiLCJtYXAiLCJpbnN0YWxsbWVudHMiLCJjdXJQYXltZW50TnVtIiwibnVtT2ZQYXltZW50cyIsIm51bWJlciIsInRvdGFsIiwidW5kZWZpbmVkIiwiZGF0ZSIsInRyblB1cmNoYXNlRGF0ZSIsImNoYXJnZWRBbW91bnQiLCJhbXRCZWZvcmVDb252QW5kSW5kZXgiLCJ0cm5BbXQiLCJjcmVkaXQiLCJkZXNjcmlwdGlvbiIsIm1lcmNoYW50TmFtZSIsIm9yaWdpbmFsQW1vdW50Iiwib3JpZ2luYWxDdXJyZW5jeSIsInByb2Nlc3NlZERhdGUiLCJkZWJDcmREYXRlIiwic3RhdHVzIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIkNvbXBsZXRlZCIsImFkZCIsInRvSVNPU3RyaW5nIiwidHlwZSIsInJlZ3VsYXIiLCJzdGFuZGluZ09yZGVyIiwiVHJhbnNhY3Rpb25UeXBlcyIsIk5vcm1hbCIsIkluc3RhbGxtZW50cyIsIlZpc2FDYWxTY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImdldENhcmRzIiwiaW5pdERhdGEiLCJjYXJkcyIsImNhcmRVbmlxdWVJZCIsImxhc3Q0RGlnaXRzIiwiZ2V0QXV0aG9yaXphdGlvbkhlYWRlciIsImF1dGhNb2R1bGUiLCJhdXRoIiwiY2FsQ29ubmVjdFRva2VuIiwiZ2V0WFNpdGVJZCIsImdldExvZ2luT3B0aW9ucyIsImxvZ2luVXJsIiwiZmllbGRzIiwic3VibWl0QnV0dG9uU2VsZWN0b3IiLCJwb3NzaWJsZVJlc3VsdHMiLCJjaGVja1JlYWRpbmVzcyIsInByZUFjdGlvbiIsIm9wZW5Mb2dpblBvcHVwIiwicG9zdEFjdGlvbiIsImN1cnJlbnRVcmwiLCJlbmRzV2l0aCIsImUiLCJ1c2VyQWdlbnQiLCJpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMiLCJmZXRjaERhdGEiLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJzdWJ0cmFjdCIsInN0YXJ0RGF0ZSIsInRvRGF0ZSIsInN0YXJ0TW9tZW50IiwibW9tZW50IiwibWF4IiwiZm9ybWF0IiwiQXV0aG9yaXphdGlvbiIsInNldFRpbWVvdXQiLCJ4U2l0ZUlkIiwiZnV0dXJlTW9udGhzVG9TY3JhcGUiLCJhbGwiLCJjYXJkIiwiZmluYWxNb250aFRvRmV0Y2hNb21lbnQiLCJtb250aHMiLCJkaWZmIiwiYWxsTW9udGhzRGF0YSIsImkiLCJtb250aCIsImNsb25lIiwieWVhciIsInN0YXR1c0NvZGUiLCJ0aXRsZSIsInB1c2giLCJ0eG5zIiwib3V0cHV0RGF0YSIsImVuYWJsZVRyYW5zYWN0aW9uc0ZpbHRlckJ5RGF0ZSIsImNvbWJpbmVJbnN0YWxsbWVudHMiLCJhY2NvdW50TnVtYmVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInN1Y2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUdBOztBQUNBOztBQUNBOztBQUdBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQU1BOzs7Ozs7QUFHQSxNQUFNQSxTQUFTLEdBQUcsK0JBQWxCO0FBQ0EsTUFBTUMsNkJBQTZCLEdBQUcsOEZBQXRDO0FBRUEsTUFBTUMsc0JBQXNCLEdBQUcsbUNBQS9CO0FBRUEsTUFBTUMsS0FBSyxHQUFHLHFCQUFTLFVBQVQsQ0FBZDtJQUVLQyxXOztXQUFBQSxXO0FBQUFBLEVBQUFBLFc7QUFBQUEsRUFBQUEsVztBQUFBQSxFQUFBQSxXO0FBQUFBLEVBQUFBLFc7R0FBQUEsVyxLQUFBQSxXOztBQWlHTCxlQUFlQyxhQUFmLENBQTZCQyxJQUE3QixFQUF5QztBQUN2QyxNQUFJQyxLQUFtQixHQUFHLElBQTFCO0FBQ0FKLEVBQUFBLEtBQUssQ0FBQyw4QkFBRCxDQUFMO0FBQ0EsUUFBTSx3QkFBVSxNQUFNO0FBQ3BCSSxJQUFBQSxLQUFLLEdBQUdELElBQUksQ0FDVEUsTUFESyxHQUVMQyxJQUZLLENBRUNDLENBQUQsSUFBT0EsQ0FBQyxDQUFDQyxHQUFGLEdBQVFDLFFBQVIsQ0FBaUIsWUFBakIsQ0FGUCxLQUUwQyxJQUZsRDtBQUdBLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixDQUFDLENBQUNQLEtBQWxCLENBQVA7QUFDRCxHQUxLLEVBS0gsaUNBTEcsRUFLZ0MsS0FMaEMsRUFLdUMsSUFMdkMsQ0FBTjs7QUFPQSxNQUFJLENBQUNBLEtBQUwsRUFBWTtBQUNWSixJQUFBQSxLQUFLLENBQUMsMkNBQUQsQ0FBTDtBQUNBLFVBQU0sSUFBSVksS0FBSixDQUFVLGdDQUFW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QUFULElBQUFBLFNBQVMsV0FBVCxZQUFBQSxTQUFTLENBQUV1RixLQUFYLEtBQW9CLEVBQUcsRUFBeEcsQ0FBTjs7QUFFakMsWUFBSSxDQUFDLEtBQUt6Qix3QkFBTCxDQUE4QjlELFNBQTlCLENBQUwsRUFBK0M7QUFDN0MsZ0JBQU0sSUFBSTFCLEtBQUosQ0FBVSxpREFBVixDQUFOO0FBQ0Q7O0FBRUQyRyxRQUFBQSxhQUFhLENBQUNPLElBQWQsQ0FBbUJ4RixTQUFuQjtBQUNEOztBQUVELFlBQU1NLFlBQVksR0FBR1QsK0JBQStCLENBQUNvRixhQUFELENBQXBEO0FBRUF2SCxNQUFBQSxLQUFLLENBQUMsNEJBQUQsQ0FBTDtBQUNBLFlBQU0rSCxJQUFJLEdBQUcsb0RBQUMsS0FBS3hHLE9BQUwsQ0FBYXlHLFVBQWQsMkRBQUMsdUJBQXlCQyw4QkFBMUIseUVBQTRELElBQTVELElBQ1gseUNBQXNCckYsWUFBdEIsRUFBb0MscUJBQU80RCxTQUFQLENBQXBDLEVBQXVELEtBQUtqRixPQUFMLENBQWEyRyxtQkFBYixJQUFvQyxLQUEzRixDQURXLEdBRVh0RixZQUZGO0FBSUEsYUFBTztBQUNMbUYsUUFBQUEsSUFESztBQUVMSSxRQUFBQSxhQUFhLEVBQUVoQixJQUFJLENBQUNsQztBQUZmLE9BQVA7QUFJRCxLQXZDRCxDQURxQixDQUF2QjtBQTJDQWpGLElBQUFBLEtBQUssQ0FBQyw2QkFBRCxDQUFMO0FBRUFBLElBQUFBLEtBQUssQ0FBQ29JLElBQUksQ0FBQ0MsU0FBTCxDQUFlNUYsUUFBZixFQUF5QixJQUF6QixFQUErQixDQUEvQixDQUFELENBQUw7QUFDQSxXQUFPO0FBQ0w2RixNQUFBQSxPQUFPLEVBQUUsSUFESjtBQUVMN0YsTUFBQUE7QUFGSyxLQUFQO0FBSUQ7O0FBako2RTs7ZUFvSmpFa0MsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IEZyYW1lLCBQYWdlIH0gZnJvbSAncHVwcGV0ZWVyJztcblxuaW1wb3J0IHsgU0hFS0VMX0NVUlJFTkNZX1NZTUJPTCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBnZXREZWJ1ZyB9IGZyb20gJy4uL2hlbHBlcnMvZGVidWcnO1xuaW1wb3J0IHtcbiAgY2xpY2tCdXR0b24sIGVsZW1lbnRQcmVzZW50T25QYWdlLCBwYWdlRXZhbCwgd2FpdFVudGlsRWxlbWVudEZvdW5kLFxufSBmcm9tICcuLi9oZWxwZXJzL2VsZW1lbnRzLWludGVyYWN0aW9ucyc7XG5pbXBvcnQgeyBmZXRjaFBvc3RXaXRoaW5QYWdlIH0gZnJvbSAnLi4vaGVscGVycy9mZXRjaCc7XG5pbXBvcnQgeyBnZXRDdXJyZW50VXJsIH0gZnJvbSAnLi4vaGVscGVycy9uYXZpZ2F0aW9uJztcbmltcG9ydCB7IGdldEZyb21TZXNzaW9uU3RvcmFnZSB9IGZyb20gJy4uL2hlbHBlcnMvc3RvcmFnZSc7XG5pbXBvcnQgeyBmaWx0ZXJPbGRUcmFuc2FjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHtcbiAgVHJhbnNhY3Rpb24sXG4gIFRyYW5zYWN0aW9uU3RhdHVzZXMsXG4gIFRyYW5zYWN0aW9uVHlwZXMsXG4gIFRyYW5zYWN0aW9uc0FjY291bnQsXG59IGZyb20gJy4uL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBCYXNlU2NyYXBlcldpdGhCcm93c2VyLCBMb2dpbk9wdGlvbnMsIExvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQgeyBTY3JhcGVyU2NyYXBpbmdSZXN1bHQgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmNvbnN0IExPR0lOX1VSTCA9ICdodHRwczovL3d3dy5jYWwtb25saW5lLmNvLmlsLyc7XG5jb25zdCBUUkFOU0FDVElPTlNfUkVRVUVTVF9FTkRQT0lOVCA9ICdodHRwczovL2FwaS5jYWwtb25saW5lLmNvLmlsL1RyYW5zYWN0aW9ucy9hcGkvdHJhbnNhY3Rpb25zRGV0YWlscy9nZXRDYXJkVHJhbnNhY3Rpb25zRGV0YWlscyc7XG5cbmNvbnN0IEludmFsaWRQYXNzd29yZE1lc3NhZ2UgPSAn16nXnSDXlNee16nXqtee16kg15DXlSDXlNeh15nXodee15Qg16nXlNeV15bXoNeVINep15LXldeZ15nXnSc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ3Zpc2EtY2FsJyk7XG5cbmVudW0gdHJuVHlwZUNvZGUge1xuICByZWd1bGFyID0gJzUnLFxuICBjcmVkaXQgPSAnNicsXG4gIGluc3RhbGxtZW50cyA9ICc4JyxcbiAgc3RhbmRpbmdPcmRlciA9ICc5Jyxcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIGFtdEJlZm9yZUNvbnZBbmRJbmRleDogbnVtYmVyO1xuICBicmFuY2hDb2RlRGVzYzogc3RyaW5nO1xuICBjYXNoQWNjTWFuYWdlck5hbWU6IG51bGw7XG4gIGNhc2hBY2NvdW50TWFuYWdlcjogbnVsbDtcbiAgY2FzaEFjY291bnRUcm5BbXQ6IG51bWJlcjtcbiAgY2hhcmdlRXh0ZXJuYWxUb0NhcmRDb21tZW50OiBzdHJpbmc7XG4gIGNvbW1lbnRzOiBbXTtcbiAgY3VyUGF5bWVudE51bTogbnVtYmVyO1xuICBkZWJDcmRDdXJyZW5jeVN5bWJvbDogQ3VycmVuY3lTeW1ib2w7XG4gIGRlYkNyZERhdGU6IHN0cmluZztcbiAgZGViaXRTcHJlYWRJbmQ6IGJvb2xlYW47XG4gIGRpc2NvdW50QW1vdW50OiB1bmtub3duO1xuICBkaXNjb3VudFJlYXNvbjogdW5rbm93bjtcbiAgaW1tZWRpYXRlQ29tbWVudHM6IFtdO1xuICBpc0ltbWVkaWF0ZUNvbW1lbnRJbmQ6IGJvb2xlYW47XG4gIGlzSW1tZWRpYXRlSEhLSW5kOiBib29sZWFuO1xuICBpc01hcmdhcml0YTogYm9vbGVhbjtcbiAgaXNTcHJlYWRQYXltZW5zdEFicm9hZDogYm9vbGVhbjtcbiAgbGlua2VkQ29tbWVudHM6IFtdO1xuICBtZXJjaGFudEFkZHJlc3M6IHN0cmluZztcbiAgbWVyY2hhbnROYW1lOiBzdHJpbmc7XG4gIG1lcmNoYW50UGhvbmVObzogc3RyaW5nO1xuICBudW1PZlBheW1lbnRzOiBudW1iZXI7XG4gIG9uR29pbmdUcmFuc2FjdGlvbnNDb21tZW50OiBzdHJpbmc7XG4gIHJlZnVuZEluZDogYm9vbGVhbjtcbiAgcm91bmRpbmdBbW91bnQ6IHVua25vd247XG4gIHJvdW5kaW5nUmVhc29uOiB1bmtub3duO1xuICB0b2tlbkluZDogMDtcbiAgdG9rZW5OdW1iZXJQYXJ0NDogJyc7XG4gIHRyYW5zQ2FyZFByZXNlbnRJbmQ6IGJvb2xlYW47XG4gIHRyYW5zVHlwZUNvbW1lbnREZXRhaWxzOiBbXTtcbiAgdHJuQW10OiBudW1iZXI7XG4gIHRybkN1cnJlbmN5U3ltYm9sOiBDdXJyZW5jeVN5bWJvbDtcbiAgdHJuRXhhY1dheTogbnVtYmVyO1xuICB0cm5JbnRJZDogc3RyaW5nO1xuICB0cm5OdW1hcmV0b3I6IG51bWJlcjtcbiAgdHJuUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gIHRyblR5cGU6IHN0cmluZztcbiAgdHJuVHlwZUNvZGU6IHRyblR5cGVDb2RlO1xuICB3YWxsZXRQcm92aWRlckNvZGU6IDA7XG4gIHdhbGxldFByb3ZpZGVyRGVzYzogJyc7XG59XG5pbnRlcmZhY2UgSW5pdFJlc3BvbnNlIHtcbiAgcmVzdWx0OiB7XG4gICAgY2FyZHM6IHtcbiAgICAgIGNhcmRVbmlxdWVJZDogc3RyaW5nO1xuICAgICAgbGFzdDREaWdpdHM6IHN0cmluZztcbiAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gICAgfVtdO1xuICB9O1xufVxudHlwZSBDdXJyZW5jeVN5bWJvbCA9ICfigqonIHwgc3RyaW5nO1xuaW50ZXJmYWNlIENhcmRUcmFuc2FjdGlvbkRldGFpbHNFcnJvciB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHN0YXR1c0NvZGU6IG51bWJlcjtcbn1cbmludGVyZmFjZSBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIGV4dGVuZHMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yIHtcbiAgcmVzdWx0OiB7XG4gICAgYmFua0FjY291bnRzOiB7XG4gICAgICBiYW5rQWNjb3VudE51bTogc3RyaW5nO1xuICAgICAgYmFua05hbWU6IHN0cmluZztcbiAgICAgIGNob2ljZUV4dGVybmFsVHJhbnNhY3Rpb25zOiBhbnk7XG4gICAgICBjdXJyZW50QmFua0FjY291bnRJbmQ6IGJvb2xlYW47XG4gICAgICBkZWJpdERhdGVzOiB7XG4gICAgICAgIGJhc2tldEFtb3VudENvbW1lbnQ6IHVua25vd247XG4gICAgICAgIGNob2ljZUhIS0RlYml0OiBudW1iZXI7XG4gICAgICAgIGRhdGU6IHN0cmluZztcbiAgICAgICAgZGViaXRSZWFzb246IHVua25vd247XG4gICAgICAgIGZpeERlYml0QW1vdW50OiBudW1iZXI7XG4gICAgICAgIGZyb21QdXJjaGFzZURhdGU6IHN0cmluZztcbiAgICAgICAgaXNDaG9pY2VSZXBhaW1lbnQ6IGJvb2xlYW47XG4gICAgICAgIHRvUHVyY2hhc2VEYXRlOiBzdHJpbmc7XG4gICAgICAgIHRvdGFsQmFza2V0QW1vdW50OiBudW1iZXI7XG4gICAgICAgIHRvdGFsRGViaXRzOiB7XG4gICAgICAgICAgY3VycmVuY3lTeW1ib2w6IEN1cnJlbmN5U3ltYm9sO1xuICAgICAgICAgIGFtb3VudDogbnVtYmVyO1xuICAgICAgICB9W107XG4gICAgICAgIHRyYW5zYWN0aW9uczogU2NyYXBlZFRyYW5zYWN0aW9uW107XG4gICAgICB9W107XG4gICAgICBpbW1pZGlhdGVEZWJpdHM6IHsgdG90YWxEZWJpdHM6IFtdLCBkZWJpdERheXM6IFtdIH07XG4gICAgfVtdO1xuICAgIGJsb2NrZWRDYXJkSW5kOiBib29sZWFuO1xuICB9O1xuICBzdGF0dXNDb2RlOiAxO1xuICBzdGF0dXNEZXNjcmlwdGlvbjogc3RyaW5nO1xuICBzdGF0dXNUaXRsZTogc3RyaW5nO1xufVxuXG5cbmFzeW5jIGZ1bmN0aW9uIGdldExvZ2luRnJhbWUocGFnZTogUGFnZSkge1xuICBsZXQgZnJhbWU6IEZyYW1lIHwgbnVsbCA9IG51bGw7XG4gIGRlYnVnKCd3YWl0IHVudGlsIGxvZ2luIGZyYW1lIGZvdW5kJyk7XG4gIGF3YWl0IHdhaXRVbnRpbCgoKSA9PiB7XG4gICAgZnJhbWUgPSBwYWdlXG4gICAgICAuZnJhbWVzKClcbiAgICAgIC5maW5kKChmKSA9PiBmLnVybCgpLmluY2x1ZGVzKCdjYWxjb25uZWN0JykpIHx8IG51bGw7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSghIWZyYW1lKTtcbiAgfSwgJ3dhaXQgZm9yIGlmcmFtZSB3aXRoIGxvZ2luIGZvcm0nLCAxMDAwMCwgMTAwMCk7XG5cbiAgaWYgKCFmcmFtZSkge1xuICAgIGRlYnVnKCdmYWlsZWQgdG8gZmluZCBsb2dpbiBmcmFtZSBmb3IgMTAgc2Vjb25kcycpO1xuICAgIHRocm93IG5ldyBFcnJvcignZmFpbGVkIHRvIGV4dHJhY3QgbG9naW4gaWZyYW1lJyk7XG4gIH1cblxuICByZXR1cm4gZnJhbWU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhc0ludmFsaWRQYXNzd29yZEVycm9yKHBhZ2U6IFBhZ2UpIHtcbiAgY29uc3QgZnJhbWUgPSBhd2FpdCBnZXRMb2dpbkZyYW1lKHBhZ2UpO1xuICBjb25zdCBlcnJvckZvdW5kID0gYXdhaXQgZWxlbWVudFByZXNlbnRPblBhZ2UoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicpO1xuICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvckZvdW5kID8gYXdhaXQgcGFnZUV2YWwoZnJhbWUsICdkaXYuZ2VuZXJhbC1lcnJvciA+IGRpdicsICcnLCAoaXRlbSkgPT4ge1xuICAgIHJldHVybiAoaXRlbSBhcyBIVE1MRGl2RWxlbWVudCkuaW5uZXJUZXh0O1xuICB9KSA6ICcnO1xuICByZXR1cm4gZXJyb3JNZXNzYWdlID09PSBJbnZhbGlkUGFzc3dvcmRNZXNzYWdlO1xufVxuXG5mdW5jdGlvbiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cygpIHtcbiAgZGVidWcoJ3JldHVybiBwb3NzaWJsZSBsb2dpbiByZXN1bHRzJyk7XG4gIGNvbnN0IHVybHM6IExvZ2luT3B0aW9uc1sncG9zc2libGVSZXN1bHRzJ10gPSB7XG4gICAgW0xvZ2luUmVzdWx0cy5TdWNjZXNzXTogWy9kYXNoYm9hcmQvaV0sXG4gICAgW0xvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmRdOiBbYXN5bmMgKG9wdGlvbnM/OiB7IHBhZ2U/OiBQYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBvcHRpb25zPy5wYWdlO1xuICAgICAgaWYgKCFwYWdlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXNJbnZhbGlkUGFzc3dvcmRFcnJvcihwYWdlKTtcbiAgICB9XSxcbiAgICAvLyBbTG9naW5SZXN1bHRzLkFjY291bnRCbG9ja2VkXTogW10sIC8vIFRPRE8gYWRkIHdoZW4gcmVhY2hpbmcgdGhpcyBzY2VuYXJpb1xuICAgIC8vIFtMb2dpblJlc3VsdHMuQ2hhbmdlUGFzc3dvcmRdOiBbXSwgLy8gVE9ETyBhZGQgd2hlbiByZWFjaGluZyB0aGlzIHNjZW5hcmlvXG4gIH07XG4gIHJldHVybiB1cmxzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpIHtcbiAgZGVidWcoJ2NyZWF0ZSBsb2dpbiBmaWVsZHMgZm9yIHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICByZXR1cm4gW1xuICAgIHsgc2VsZWN0b3I6ICdbZm9ybWNvbnRyb2xuYW1lPVwidXNlck5hbWVcIl0nLCB2YWx1ZTogY3JlZGVudGlhbHMudXNlcm5hbWUgfSxcbiAgICB7IHNlbGVjdG9yOiAnW2Zvcm1jb250cm9sbmFtZT1cInBhc3N3b3JkXCJdJywgdmFsdWU6IGNyZWRlbnRpYWxzLnBhc3N3b3JkIH0sXG4gIF07XG59XG5cbmZ1bmN0aW9uIGNhcmRBbmRUcmFuc2FjdGlvbkN1cnJlbmN5U3ltYm9sSXNTaGVrZWwodHJhbnNhY3Rpb246IFNjcmFwZWRUcmFuc2FjdGlvbikge1xuICByZXR1cm4gdHJhbnNhY3Rpb24uZGViQ3JkQ3VycmVuY3lTeW1ib2wgPT09IFNIRUtFTF9DVVJSRU5DWV9TWU1CT0wgJiZcbiAgICB0cmFuc2FjdGlvbi50cm5DdXJyZW5jeVN5bWJvbCA9PT0gU0hFS0VMX0NVUlJFTkNZX1NZTUJPTDtcbn1cbmZ1bmN0aW9uIGNvbnZlcnRQYXJzZWREYXRhVG9UcmFuc2FjdGlvbnMocGFyc2VkRGF0YTogQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc1tdKTogVHJhbnNhY3Rpb25bXSB7XG4gIHJldHVybiBwYXJzZWREYXRhXG4gICAgLmZsYXRNYXAoKG1vbnRoRGF0YSkgPT4gbW9udGhEYXRhLnJlc3VsdC5iYW5rQWNjb3VudHMpXG4gICAgLmZsYXRNYXAoKGFjY291bnRzKSA9PiBhY2NvdW50cy5kZWJpdERhdGVzKVxuICAgIC5mbGF0TWFwKChkZWJpdERhdGUpID0+IGRlYml0RGF0ZS50cmFuc2FjdGlvbnMpXG4gICAgLm1hcCgodHJhbnNhY3Rpb24pID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbGxtZW50cyA9ICh0cmFuc2FjdGlvbi5jdXJQYXltZW50TnVtICYmIHRyYW5zYWN0aW9uLm51bU9mUGF5bWVudHMgJiZcbiAgICAgIHtcbiAgICAgICAgbnVtYmVyOiB0cmFuc2FjdGlvbi5jdXJQYXltZW50TnVtLFxuICAgICAgICB0b3RhbDogdHJhbnNhY3Rpb24ubnVtT2ZQYXltZW50cyxcbiAgICAgIH0pIHx8XG4gICAgICAgIHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgZGF0ZSA9IG1vbWVudCh0cmFuc2FjdGlvbi50cm5QdXJjaGFzZURhdGUpO1xuXG4gICAgICAvLyBJIGRpZG4ndCB0ZXN0IGBhbXRCZWZvcmVDb252QW5kSW5kZXhgIHdpdGggYSBmb3JlaWduIGN1cnJlbmN5IGFzIEkgZG9uJ3QgaGF2ZSBzdWNoIHRyYW5zYWN0aW9uc1xuICAgICAgbGV0IGNoYXJnZWRBbW91bnQ6IG51bWJlcjtcbiAgICAgIGlmIChjYXJkQW5kVHJhbnNhY3Rpb25DdXJyZW5jeVN5bWJvbElzU2hla2VsKHRyYW5zYWN0aW9uKSkge1xuICAgICAgICBjaGFyZ2VkQW1vdW50ID0gdHJhbnNhY3Rpb24uYW10QmVmb3JlQ29udkFuZEluZGV4ICogKC0xKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYXJnZWRBbW91bnQgPSB0cmFuc2FjdGlvbi50cm5BbXQgKiAoLTEpO1xuXG4gICAgICAgIGlmICh0cmFuc2FjdGlvbi50cm5UeXBlQ29kZSA9PT0gdHJuVHlwZUNvZGUuY3JlZGl0KSB7XG4gICAgICAgICAgY2hhcmdlZEFtb3VudCA9IHRyYW5zYWN0aW9uLnRybkFtdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgICBjaGFyZ2VkQW1vdW50LFxuICAgICAgICBkZXNjcmlwdGlvbjogdHJhbnNhY3Rpb24ubWVyY2hhbnROYW1lLFxuICAgICAgICBvcmlnaW5hbEFtb3VudDogdHJhbnNhY3Rpb24uYW10QmVmb3JlQ29udkFuZEluZGV4LFxuICAgICAgICBvcmlnaW5hbEN1cnJlbmN5OiB0cmFuc2FjdGlvbi50cm5DdXJyZW5jeVN5bWJvbCxcbiAgICAgICAgcHJvY2Vzc2VkRGF0ZTogdHJhbnNhY3Rpb24uZGViQ3JkRGF0ZSxcbiAgICAgICAgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICAgICAgZGF0ZTogaW5zdGFsbG1lbnRzID9cbiAgICAgICAgICBkYXRlLmFkZChpbnN0YWxsbWVudHMubnVtYmVyIC0gMSwgJ21vbnRoJykudG9JU09TdHJpbmcoKSA6XG4gICAgICAgICAgZGF0ZS50b0lTT1N0cmluZygpLFxuICAgICAgICB0eXBlOiBbdHJuVHlwZUNvZGUucmVndWxhciwgdHJuVHlwZUNvZGUuc3RhbmRpbmdPcmRlcl0uaW5jbHVkZXModHJhbnNhY3Rpb24udHJuVHlwZUNvZGUpID9cbiAgICAgICAgICBUcmFuc2FjdGlvblR5cGVzLk5vcm1hbCA6XG4gICAgICAgICAgVHJhbnNhY3Rpb25UeXBlcy5JbnN0YWxsbWVudHMsXG4gICAgICB9O1xuXG4gICAgICBpZiAoaW5zdGFsbG1lbnRzKSB7XG4gICAgICAgIHJlc3VsdC5pbnN0YWxsbWVudHMgPSBpbnN0YWxsbWVudHM7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG59XG5cbnR5cGUgU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMgPSB7IHVzZXJuYW1lOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcgfTtcblxuY2xhc3MgVmlzYUNhbFNjcmFwZXIgZXh0ZW5kcyBCYXNlU2NyYXBlcldpdGhCcm93c2VyPFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzPiB7XG4gIG9wZW5Mb2dpblBvcHVwID0gYXN5bmMgKCkgPT4ge1xuICAgIGRlYnVnKCdvcGVuIGxvZ2luIHBvcHVwLCB3YWl0IHVudGlsIGxvZ2luIGJ1dHRvbiBhdmFpbGFibGUnKTtcbiAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJywgdHJ1ZSk7XG4gICAgZGVidWcoJ2NsaWNrIG9uIHRoZSBsb2dpbiBidXR0b24nKTtcbiAgICBhd2FpdCBjbGlja0J1dHRvbih0aGlzLnBhZ2UsICcjY2NMb2dpbkRlc2t0b3BCdG4nKTtcbiAgICBkZWJ1ZygnZ2V0IHRoZSBmcmFtZSB0aGF0IGhvbGRzIHRoZSBsb2dpbicpO1xuICAgIGNvbnN0IGZyYW1lID0gYXdhaXQgZ2V0TG9naW5GcmFtZSh0aGlzLnBhZ2UpO1xuICAgIGRlYnVnKCd3YWl0IHVudGlsIHRoZSBwYXNzd29yZCBsb2dpbiB0YWIgaGVhZGVyIGlzIGF2YWlsYWJsZScpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZChmcmFtZSwgJyNyZWd1bGFyLWxvZ2luJyk7XG4gICAgZGVidWcoJ25hdmlnYXRlIHRvIHRoZSBwYXNzd29yZCBsb2dpbiB0YWInKTtcbiAgICBhd2FpdCBjbGlja0J1dHRvbihmcmFtZSwgJyNyZWd1bGFyLWxvZ2luJyk7XG4gICAgZGVidWcoJ3dhaXQgdW50aWwgdGhlIHBhc3N3b3JkIGxvZ2luIHRhYiBpcyBhY3RpdmUnKTtcbiAgICBhd2FpdCB3YWl0VW50aWxFbGVtZW50Rm91bmQoZnJhbWUsICdyZWd1bGFyLWxvZ2luJyk7XG5cbiAgICByZXR1cm4gZnJhbWU7XG4gIH07XG5cbiAgYXN5bmMgZ2V0Q2FyZHMoKSB7XG4gICAgY29uc3QgaW5pdERhdGEgPSBhd2FpdCBnZXRGcm9tU2Vzc2lvblN0b3JhZ2U8SW5pdFJlc3BvbnNlPih0aGlzLnBhZ2UsICdpbml0Jyk7XG4gICAgaWYgKCFpbml0RGF0YSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgZmluZCBcXCdpbml0XFwnIGRhdGEgaW4gc2Vzc2lvbiBzdG9yYWdlJyk7XG4gICAgfVxuICAgIHJldHVybiBpbml0RGF0YT8ucmVzdWx0LmNhcmRzLm1hcCgoeyBjYXJkVW5pcXVlSWQsIGxhc3Q0RGlnaXRzIH0pID0+ICh7IGNhcmRVbmlxdWVJZCwgbGFzdDREaWdpdHMgfSkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QXV0aG9yaXphdGlvbkhlYWRlcigpIHtcbiAgICBjb25zdCBhdXRoTW9kdWxlID0gYXdhaXQgZ2V0RnJvbVNlc3Npb25TdG9yYWdlPHsgYXV0aDogeyBjYWxDb25uZWN0VG9rZW46IHN0cmluZyB9IH0+KHRoaXMucGFnZSwgJ2F1dGgtbW9kdWxlJyk7XG4gICAgaWYgKCFhdXRoTW9kdWxlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCBmaW5kIFxcJ2F1dGgtbW9kdWxlXFwnIGluIHNlc3Npb24gc3RvcmFnZScpO1xuICAgIH1cbiAgICByZXR1cm4gYENBTEF1dGhTY2hlbWUgJHthdXRoTW9kdWxlLmF1dGguY2FsQ29ubmVjdFRva2VufWA7XG4gIH1cblxuICBhc3luYyBnZXRYU2l0ZUlkKCkge1xuICAgIC8qXG4gICAgICBJIGRvbid0IGtub3cgaWYgdGhlIGNvbnN0YW50IGJlbG93IHdpbGwgY2hhbmdlIGluIHRoZSBmZWF0dXJlLlxuICAgICAgSWYgc28sIHVzZSB0aGUgbmV4dCBjb2RlOlxuXG4gICAgICByZXR1cm4gdGhpcy5wYWdlLmV2YWx1YXRlKCgpID0+IG5ldyBVdCgpLnhTaXRlSWQpO1xuXG4gICAgICBUbyBnZXQgdGhlIGNsYXNzbmFtZSBzZWFyY2ggZm9yICd4U2l0ZUlkJyBpbiB0aGUgcGFnZSBzb3VyY2VcbiAgICAgIGNsYXNzIFV0IHtcbiAgICAgICAgY29uc3RydWN0b3IoX2UsIG9uLCB5bikge1xuICAgICAgICAgICAgdGhpcy5zdG9yZSA9IF9lLFxuICAgICAgICAgICAgdGhpcy5jb25maWcgPSBvbixcbiAgICAgICAgICAgIHRoaXMuZXZlbnRCdXNTZXJ2aWNlID0geW4sXG4gICAgICAgICAgICB0aGlzLnhTaXRlSWQgPSBcIjA5MDMxOTg3LTI3M0UtMjMxMS05MDZDLThBRjg1QjE3QzhEOVwiLFxuICAgICovXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgnMDkwMzE5ODctMjczRS0yMzExLTkwNkMtOEFGODVCMTdDOEQ5Jyk7XG4gIH1cblxuICBnZXRMb2dpbk9wdGlvbnMoY3JlZGVudGlhbHM6IFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzKTogTG9naW5PcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9naW5Vcmw6IGAke0xPR0lOX1VSTH1gLFxuICAgICAgZmllbGRzOiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFscyksXG4gICAgICBzdWJtaXRCdXR0b25TZWxlY3RvcjogJ2J1dHRvblt0eXBlPVwic3VibWl0XCJdJyxcbiAgICAgIHBvc3NpYmxlUmVzdWx0czogZ2V0UG9zc2libGVMb2dpblJlc3VsdHMoKSxcbiAgICAgIGNoZWNrUmVhZGluZXNzOiBhc3luYyAoKSA9PiB3YWl0VW50aWxFbGVtZW50Rm91bmQodGhpcy5wYWdlLCAnI2NjTG9naW5EZXNrdG9wQnRuJyksXG4gICAgICBwcmVBY3Rpb246IHRoaXMub3BlbkxvZ2luUG9wdXAsXG4gICAgICBwb3N0QWN0aW9uOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKHRoaXMucGFnZSwgJ2J1dHRvbi5idG4tY2xvc2UnKTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChjdXJyZW50VXJsLmVuZHNXaXRoKCdzaXRlLXR1dG9yaWFsJykpIHtcbiAgICAgICAgICAgIGF3YWl0IGNsaWNrQnV0dG9uKHRoaXMucGFnZSwgJ2J1dHRvbi5idG4tY2xvc2UnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zdCBjdXJyZW50VXJsID0gYXdhaXQgZ2V0Q3VycmVudFVybCh0aGlzLnBhZ2UpO1xuICAgICAgICAgIGlmIChjdXJyZW50VXJsLmVuZHNXaXRoKCdkYXNoYm9hcmQnKSkgcmV0dXJuO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB1c2VyQWdlbnQ6ICdNb3ppbGxhLzUuMCAoWDExOyBMaW51eCB4ODZfNjQpIEFwcGxlV2ViS2l0LzUzNy4zNiAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS83OC4wLjM5MDQuMTA4IFNhZmFyaS81MzcuMzYnLFxuICAgIH07XG4gIH1cblxuICBpc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMocmVzdWx0OiBDYXJkVHJhbnNhY3Rpb25EZXRhaWxzIHwgQ2FyZFRyYW5zYWN0aW9uRGV0YWlsc0Vycm9yKTpcbiAgICByZXN1bHQgaXMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscyB7XG4gICAgcmV0dXJuIChyZXN1bHQgYXMgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscykucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKTogUHJvbWlzZTxTY3JhcGVyU2NyYXBpbmdSZXN1bHQ+IHtcbiAgICBjb25zdCBkZWZhdWx0U3RhcnRNb21lbnQgPSBtb21lbnQoKS5zdWJ0cmFjdCgxLCAneWVhcnMnKS5zdWJ0cmFjdCg2LCAnbW9udGhzJykuYWRkKDEsICdkYXknKTtcbiAgICBjb25zdCBzdGFydERhdGUgPSB0aGlzLm9wdGlvbnMuc3RhcnREYXRlIHx8IGRlZmF1bHRTdGFydE1vbWVudC50b0RhdGUoKTtcbiAgICBjb25zdCBzdGFydE1vbWVudCA9IG1vbWVudC5tYXgoZGVmYXVsdFN0YXJ0TW9tZW50LCBtb21lbnQoc3RhcnREYXRlKSk7XG4gICAgZGVidWcoYGZldGNoIHRyYW5zYWN0aW9ucyBzdGFydGluZyAke3N0YXJ0TW9tZW50LmZvcm1hdCgpfWApO1xuXG4gICAgY29uc3QgQXV0aG9yaXphdGlvbiA9IGF3YWl0IHRoaXMuZ2V0QXV0aG9yaXphdGlvbkhlYWRlcigpO1xuICAgIC8vIFdhaXQgYSBsaXR0bGUgYmVmb3JlIGB0aGlzLmdldENhcmRzYCBzbyB0aGF0IGl0IHdvdWxkIGV4aXN0XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xuICAgIGNvbnN0IGNhcmRzID0gYXdhaXQgdGhpcy5nZXRDYXJkcygpO1xuICAgIGNvbnN0IHhTaXRlSWQgPSBhd2FpdCB0aGlzLmdldFhTaXRlSWQoKTtcbiAgICBjb25zdCBmdXR1cmVNb250aHNUb1NjcmFwZSA9IHRoaXMub3B0aW9ucy5mdXR1cmVNb250aHNUb1NjcmFwZSA/PyAxO1xuXG4gICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGNhcmRzLm1hcChhc3luYyAoY2FyZCkgPT4ge1xuICAgICAgICBkZWJ1ZyhgZmV0Y2ggdHJhbnNhY3Rpb25zIGZvciBjYXJkICR7Y2FyZC5jYXJkVW5pcXVlSWR9YCk7XG5cbiAgICAgICAgY29uc3QgZmluYWxNb250aFRvRmV0Y2hNb21lbnQgPSBtb21lbnQoKS5hZGQoZnV0dXJlTW9udGhzVG9TY3JhcGUsICdtb250aCcpO1xuICAgICAgICBjb25zdCBtb250aHMgPSBmaW5hbE1vbnRoVG9GZXRjaE1vbWVudC5kaWZmKHN0YXJ0TW9tZW50LCAnbW9udGhzJyk7XG5cbiAgICAgICAgY29uc3QgYWxsTW9udGhzRGF0YTogKENhcmRUcmFuc2FjdGlvbkRldGFpbHMpW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbW9udGhzOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCBtb250aCA9IGZpbmFsTW9udGhUb0ZldGNoTW9tZW50LmNsb25lKCkuc3VidHJhY3QoaSwgJ21vbnRocycpO1xuICAgICAgICAgIGNvbnN0IG1vbnRoRGF0YSA9IGF3YWl0IGZldGNoUG9zdFdpdGhpblBhZ2U8Q2FyZFRyYW5zYWN0aW9uRGV0YWlscyB8IENhcmRUcmFuc2FjdGlvbkRldGFpbHNFcnJvcj4oXG4gICAgICAgICAgICB0aGlzLnBhZ2UsIFRSQU5TQUNUSU9OU19SRVFVRVNUX0VORFBPSU5ULFxuICAgICAgICAgICAgeyBjYXJkVW5pcXVlSWQ6IGNhcmQuY2FyZFVuaXF1ZUlkLCBtb250aDogbW9udGguZm9ybWF0KCdNJyksIHllYXI6IG1vbnRoLmZvcm1hdCgnWVlZWScpIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEF1dGhvcml6YXRpb24sXG4gICAgICAgICAgICAgICdYLVNpdGUtSWQnOiB4U2l0ZUlkLFxuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKG1vbnRoRGF0YT8uc3RhdHVzQ29kZSAhPT0gMSkgdGhyb3cgbmV3IEVycm9yKGBmYWlsZWQgdG8gZmV0Y2ggdHJhbnNhY3Rpb25zIGZvciBjYXJkICR7Y2FyZC5sYXN0NERpZ2l0c30uIE1lc3NhZ2U6ICR7bW9udGhEYXRhPy50aXRsZSB8fCAnJ31gKTtcblxuICAgICAgICAgIGlmICghdGhpcy5pc0NhcmRUcmFuc2FjdGlvbkRldGFpbHMobW9udGhEYXRhKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtb250aERhdGEgaXMgbm90IG9mIHR5cGUgQ2FyZFRyYW5zYWN0aW9uRGV0YWlscycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFsbE1vbnRoc0RhdGEucHVzaChtb250aERhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb25zID0gY29udmVydFBhcnNlZERhdGFUb1RyYW5zYWN0aW9ucyhhbGxNb250aHNEYXRhKTtcblxuICAgICAgICBkZWJ1ZygnZmlsZXIgb3V0IG9sZCB0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgY29uc3QgdHhucyA9ICh0aGlzLm9wdGlvbnMub3V0cHV0RGF0YT8uZW5hYmxlVHJhbnNhY3Rpb25zRmlsdGVyQnlEYXRlID8/IHRydWUpID9cbiAgICAgICAgICBmaWx0ZXJPbGRUcmFuc2FjdGlvbnModHJhbnNhY3Rpb25zLCBtb21lbnQoc3RhcnREYXRlKSwgdGhpcy5vcHRpb25zLmNvbWJpbmVJbnN0YWxsbWVudHMgfHwgZmFsc2UpIDpcbiAgICAgICAgICB0cmFuc2FjdGlvbnM7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eG5zLFxuICAgICAgICAgIGFjY291bnROdW1iZXI6IGNhcmQubGFzdDREaWdpdHMsXG4gICAgICAgIH0gYXMgVHJhbnNhY3Rpb25zQWNjb3VudDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBkZWJ1ZygncmV0dXJuIHRoZSBzY3JhcGVkIGFjY291bnRzJyk7XG5cbiAgICBkZWJ1ZyhKU09OLnN0cmluZ2lmeShhY2NvdW50cywgbnVsbCwgMikpO1xuICAgIHJldHVybiB7XG4gICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgYWNjb3VudHMsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBWaXNhQ2FsU2NyYXBlcjtcbiJdfQ==
|