israeli-bank-scrapers
Version:
Provide scrapers for all major Israeli banks and credit card companies
198 lines (195 loc) • 33.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _moment = _interopRequireDefault(require("moment"));
var _crypto = require("crypto");
var _debug = require("../helpers/debug");
var _fetch = require("../helpers/fetch");
var _navigation = require("../helpers/navigation");
var _waiting = require("../helpers/waiting");
var _transactions = require("../transactions");
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
var _transactions2 = require("../helpers/transactions");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug.getDebug)('hapoalim');
const DATE_FORMAT = 'YYYYMMDD';
// eslint-disable-next-line @typescript-eslint/no-namespace
function convertTransactions(txns, options) {
return txns.map(txn => {
const isOutbound = txn.eventActivityTypeCode === 2;
let memo = '';
if (txn.beneficiaryDetailsData) {
const {
partyHeadline,
partyName,
messageHeadline,
messageDetail
} = txn.beneficiaryDetailsData;
const memoLines = [];
if (partyHeadline) {
memoLines.push(partyHeadline);
}
if (partyName) {
memoLines.push(`${partyName}.`);
}
if (messageHeadline) {
memoLines.push(messageHeadline);
}
if (messageDetail) {
memoLines.push(`${messageDetail}.`);
}
if (memoLines.length) {
memo = memoLines.join(' ');
}
}
const result = {
type: _transactions.TransactionTypes.Normal,
identifier: txn.referenceNumber,
date: (0, _moment.default)(txn.eventDate, DATE_FORMAT).toISOString(),
processedDate: (0, _moment.default)(txn.valueDate, DATE_FORMAT).toISOString(),
originalAmount: isOutbound ? -txn.eventAmount : txn.eventAmount,
originalCurrency: 'ILS',
chargedAmount: isOutbound ? -txn.eventAmount : txn.eventAmount,
description: txn.activityDescription || '',
status: txn.serialNumber === 0 ? _transactions.TransactionStatuses.Pending : _transactions.TransactionStatuses.Completed,
memo
};
if (options?.includeRawTransaction) {
result.rawTransaction = (0, _transactions2.getRawTransaction)(txn);
}
return result;
});
}
async function getRestContext(page) {
await (0, _waiting.waitUntil)(() => {
return page.evaluate(() => !!window.bnhpApp);
}, 'waiting for app data load');
const result = await page.evaluate(() => {
return window.bnhpApp.restContext;
});
return result.slice(1);
}
async function fetchPoalimXSRFWithinPage(page, url, pageUuid) {
const cookies = await page.cookies();
const XSRFCookie = cookies.find(cookie => cookie.name === 'XSRF-TOKEN');
const headers = {};
if (XSRFCookie != null) {
headers['X-XSRF-TOKEN'] = XSRFCookie.value;
}
headers.pageUuid = pageUuid;
headers.uuid = (0, _crypto.randomUUID)();
headers['Content-Type'] = 'application/json;charset=UTF-8';
return (0, _fetch.fetchPostWithinPage)(page, url, [], headers);
}
async function getExtraScrap(txnsResult, baseUrl, page, accountNumber) {
const promises = txnsResult.transactions.map(async transaction => {
const {
pfmDetails,
serialNumber
} = transaction;
if (serialNumber !== 0) {
const url = `${baseUrl}${pfmDetails}&accountId=${accountNumber}&lang=he`;
const extraTransactionDetails = (await (0, _fetch.fetchGetWithinPage)(page, url)) || [];
if (extraTransactionDetails && extraTransactionDetails.length) {
const {
transactionNumber
} = extraTransactionDetails[0];
if (transactionNumber) {
return {
...transaction,
referenceNumber: transactionNumber,
additionalInformation: extraTransactionDetails
};
}
}
}
return transaction;
});
const res = await Promise.all(promises);
return {
transactions: res
};
}
async function getAccountTransactions(baseUrl, apiSiteUrl, page, accountNumber, startDate, endDate, additionalTransactionInformation = false, options) {
const txnsUrl = `${apiSiteUrl}/current-account/transactions?accountId=${accountNumber}&numItemsPerPage=1000&retrievalEndDate=${endDate}&retrievalStartDate=${startDate}&sortCode=1`;
const txnsResult = await fetchPoalimXSRFWithinPage(page, txnsUrl, '/current-account/transactions');
const finalResult = additionalTransactionInformation && txnsResult?.transactions.length ? await getExtraScrap(txnsResult, baseUrl, page, accountNumber) : txnsResult;
return convertTransactions(finalResult?.transactions ?? [], options);
}
async function getAccountBalance(apiSiteUrl, page, accountNumber) {
const balanceAndCreditLimitUrl = `${apiSiteUrl}/current-account/composite/balanceAndCreditLimit?accountId=${accountNumber}&view=details&lang=he`;
const balanceAndCreditLimit = await (0, _fetch.fetchGetWithinPage)(page, balanceAndCreditLimitUrl);
return balanceAndCreditLimit?.currentBalance;
}
async function fetchAccountData(page, baseUrl, options) {
const restContext = await getRestContext(page);
const apiSiteUrl = `${baseUrl}/${restContext}`;
const accountDataUrl = `${baseUrl}/ServerServices/general/accounts`;
debug('fetching accounts data');
const accountsInfo = (await (0, _fetch.fetchGetWithinPage)(page, accountDataUrl)) || [];
const openAccountsInfo = accountsInfo.filter(account => account.accountClosingReasonCode === 0);
debug('got %d open accounts from %d total accounts, fetching txns and balance', openAccountsInfo.length, accountsInfo.length);
const defaultStartMoment = (0, _moment.default)().subtract(1, 'years').add(1, 'day');
const startDate = options.startDate || defaultStartMoment.toDate();
const startMoment = _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
const {
additionalTransactionInformation
} = options;
const startDateStr = startMoment.format(DATE_FORMAT);
const endDateStr = (0, _moment.default)().format(DATE_FORMAT);
const accounts = [];
for (const account of openAccountsInfo) {
debug('getting information for account %s', account.accountNumber);
const accountNumber = `${account.bankNumber}-${account.branchNumber}-${account.accountNumber}`;
const balance = await getAccountBalance(apiSiteUrl, page, accountNumber);
const txns = await getAccountTransactions(baseUrl, apiSiteUrl, page, accountNumber, startDateStr, endDateStr, additionalTransactionInformation, options);
accounts.push({
accountNumber,
balance,
txns
});
}
const accountData = {
success: true,
accounts
};
debug('fetching ended');
return accountData;
}
function getPossibleLoginResults(baseUrl) {
const urls = {};
urls[_baseScraperWithBrowser.LoginResults.Success] = [`${baseUrl}/portalserver/HomePage`, `${baseUrl}/ng-portals-bt/rb/he/homepage`, `${baseUrl}/ng-portals/rb/he/homepage`];
urls[_baseScraperWithBrowser.LoginResults.InvalidPassword] = [`${baseUrl}/AUTHENTICATE/LOGON?flow=AUTHENTICATE&state=LOGON&errorcode=1.6&callme=false`];
urls[_baseScraperWithBrowser.LoginResults.ChangePassword] = [`${baseUrl}/MCP/START?flow=MCP&state=START&expiredDate=null`, /\/ABOUTTOEXPIRE\/START/i];
return urls;
}
function createLoginFields(credentials) {
return [{
selector: '#userCode',
value: credentials.userCode
}, {
selector: '#password',
value: credentials.password
}];
}
class HapoalimScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
get baseUrl() {
return 'https://login.bankhapoalim.co.il';
}
getLoginOptions(credentials) {
return {
loginUrl: `${this.baseUrl}/cgi-bin/poalwwwc?reqName=getLogonPage`,
fields: createLoginFields(credentials),
submitButtonSelector: '.login-btn',
postAction: async () => (0, _navigation.waitForRedirect)(this.page),
possibleResults: getPossibleLoginResults(this.baseUrl)
};
}
async fetchData() {
return fetchAccountData(this.page, this.baseUrl, this.options);
}
}
var _default = exports.default = HapoalimScraper;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfY3J5cHRvIiwiX2RlYnVnIiwiX2ZldGNoIiwiX25hdmlnYXRpb24iLCJfd2FpdGluZyIsIl90cmFuc2FjdGlvbnMiLCJfYmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsIl90cmFuc2FjdGlvbnMyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiZGVidWciLCJnZXREZWJ1ZyIsIkRBVEVfRk9STUFUIiwiY29udmVydFRyYW5zYWN0aW9ucyIsInR4bnMiLCJvcHRpb25zIiwibWFwIiwidHhuIiwiaXNPdXRib3VuZCIsImV2ZW50QWN0aXZpdHlUeXBlQ29kZSIsIm1lbW8iLCJiZW5lZmljaWFyeURldGFpbHNEYXRhIiwicGFydHlIZWFkbGluZSIsInBhcnR5TmFtZSIsIm1lc3NhZ2VIZWFkbGluZSIsIm1lc3NhZ2VEZXRhaWwiLCJtZW1vTGluZXMiLCJwdXNoIiwibGVuZ3RoIiwiam9pbiIsInJlc3VsdCIsInR5cGUiLCJUcmFuc2FjdGlvblR5cGVzIiwiTm9ybWFsIiwiaWRlbnRpZmllciIsInJlZmVyZW5jZU51bWJlciIsImRhdGUiLCJtb21lbnQiLCJldmVudERhdGUiLCJ0b0lTT1N0cmluZyIsInByb2Nlc3NlZERhdGUiLCJ2YWx1ZURhdGUiLCJvcmlnaW5hbEFtb3VudCIsImV2ZW50QW1vdW50Iiwib3JpZ2luYWxDdXJyZW5jeSIsImNoYXJnZWRBbW91bnQiLCJkZXNjcmlwdGlvbiIsImFjdGl2aXR5RGVzY3JpcHRpb24iLCJzdGF0dXMiLCJzZXJpYWxOdW1iZXIiLCJUcmFuc2FjdGlvblN0YXR1c2VzIiwiUGVuZGluZyIsIkNvbXBsZXRlZCIsImluY2x1ZGVSYXdUcmFuc2FjdGlvbiIsInJhd1RyYW5zYWN0aW9uIiwiZ2V0UmF3VHJhbnNhY3Rpb24iLCJnZXRSZXN0Q29udGV4dCIsInBhZ2UiLCJ3YWl0VW50aWwiLCJldmFsdWF0ZSIsIndpbmRvdyIsImJuaHBBcHAiLCJyZXN0Q29udGV4dCIsInNsaWNlIiwiZmV0Y2hQb2FsaW1YU1JGV2l0aGluUGFnZSIsInVybCIsInBhZ2VVdWlkIiwiY29va2llcyIsIlhTUkZDb29raWUiLCJmaW5kIiwiY29va2llIiwibmFtZSIsImhlYWRlcnMiLCJ2YWx1ZSIsInV1aWQiLCJyYW5kb21VVUlEIiwiZmV0Y2hQb3N0V2l0aGluUGFnZSIsImdldEV4dHJhU2NyYXAiLCJ0eG5zUmVzdWx0IiwiYmFzZVVybCIsImFjY291bnROdW1iZXIiLCJwcm9taXNlcyIsInRyYW5zYWN0aW9ucyIsInRyYW5zYWN0aW9uIiwicGZtRGV0YWlscyIsImV4dHJhVHJhbnNhY3Rpb25EZXRhaWxzIiwiZmV0Y2hHZXRXaXRoaW5QYWdlIiwidHJhbnNhY3Rpb25OdW1iZXIiLCJhZGRpdGlvbmFsSW5mb3JtYXRpb24iLCJyZXMiLCJQcm9taXNlIiwiYWxsIiwiZ2V0QWNjb3VudFRyYW5zYWN0aW9ucyIsImFwaVNpdGVVcmwiLCJzdGFydERhdGUiLCJlbmREYXRlIiwiYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb24iLCJ0eG5zVXJsIiwiZmluYWxSZXN1bHQiLCJnZXRBY2NvdW50QmFsYW5jZSIsImJhbGFuY2VBbmRDcmVkaXRMaW1pdFVybCIsImJhbGFuY2VBbmRDcmVkaXRMaW1pdCIsImN1cnJlbnRCYWxhbmNlIiwiZmV0Y2hBY2NvdW50RGF0YSIsImFjY291bnREYXRhVXJsIiwiYWNjb3VudHNJbmZvIiwib3BlbkFjY291bnRzSW5mbyIsImZpbHRlciIsImFjY291bnQiLCJhY2NvdW50Q2xvc2luZ1JlYXNvbkNvZGUiLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJzdWJ0cmFjdCIsImFkZCIsInRvRGF0ZSIsInN0YXJ0TW9tZW50IiwibWF4Iiwic3RhcnREYXRlU3RyIiwiZm9ybWF0IiwiZW5kRGF0ZVN0ciIsImFjY291bnRzIiwiYmFua051bWJlciIsImJyYW5jaE51bWJlciIsImJhbGFuY2UiLCJhY2NvdW50RGF0YSIsInN1Y2Nlc3MiLCJnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cyIsInVybHMiLCJMb2dpblJlc3VsdHMiLCJTdWNjZXNzIiwiSW52YWxpZFBhc3N3b3JkIiwiQ2hhbmdlUGFzc3dvcmQiLCJjcmVhdGVMb2dpbkZpZWxkcyIsImNyZWRlbnRpYWxzIiwic2VsZWN0b3IiLCJ1c2VyQ29kZSIsInBhc3N3b3JkIiwiSGFwb2FsaW1TY3JhcGVyIiwiQmFzZVNjcmFwZXJXaXRoQnJvd3NlciIsImdldExvZ2luT3B0aW9ucyIsImxvZ2luVXJsIiwiZmllbGRzIiwic3VibWl0QnV0dG9uU2VsZWN0b3IiLCJwb3N0QWN0aW9uIiwid2FpdEZvclJlZGlyZWN0IiwicG9zc2libGVSZXN1bHRzIiwiZmV0Y2hEYXRhIiwiX2RlZmF1bHQiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmFwZXJzL2hhcG9hbGltLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IHR5cGUgUGFnZSB9IGZyb20gJ3B1cHBldGVlcic7XG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGdldERlYnVnIH0gZnJvbSAnLi4vaGVscGVycy9kZWJ1Zyc7XG5pbXBvcnQgeyBmZXRjaEdldFdpdGhpblBhZ2UsIGZldGNoUG9zdFdpdGhpblBhZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2ZldGNoJztcbmltcG9ydCB7IHdhaXRGb3JSZWRpcmVjdCB9IGZyb20gJy4uL2hlbHBlcnMvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHsgdHlwZSBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25TdGF0dXNlcywgVHJhbnNhY3Rpb25UeXBlcywgdHlwZSBUcmFuc2FjdGlvbnNBY2NvdW50IH0gZnJvbSAnLi4vdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIsIExvZ2luUmVzdWx0cywgdHlwZSBQb3NzaWJsZUxvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQgeyB0eXBlIFNjcmFwZXJPcHRpb25zIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgZ2V0UmF3VHJhbnNhY3Rpb24gfSBmcm9tICcuLi9oZWxwZXJzL3RyYW5zYWN0aW9ucyc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ2hhcG9hbGltJyk7XG5cbmNvbnN0IERBVEVfRk9STUFUID0gJ1lZWVlNTUREJztcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2VcbmRlY2xhcmUgbmFtZXNwYWNlIHdpbmRvdyB7XG4gIGNvbnN0IGJuaHBBcHA6IGFueTtcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIHNlcmlhbE51bWJlcj86IG51bWJlcjtcbiAgYWN0aXZpdHlEZXNjcmlwdGlvbj86IHN0cmluZztcbiAgZXZlbnRBbW91bnQ6IG51bWJlcjtcbiAgdmFsdWVEYXRlPzogc3RyaW5nO1xuICBldmVudERhdGU/OiBzdHJpbmc7XG4gIHJlZmVyZW5jZU51bWJlcj86IG51bWJlcjtcbiAgU2NyYXBlZFRyYW5zYWN0aW9uPzogc3RyaW5nO1xuICBldmVudEFjdGl2aXR5VHlwZUNvZGU6IG51bWJlcjtcbiAgY3VycmVudEJhbGFuY2U6IG51bWJlcjtcbiAgcGZtRGV0YWlsczogc3RyaW5nO1xuICBiZW5lZmljaWFyeURldGFpbHNEYXRhPzoge1xuICAgIHBhcnR5SGVhZGxpbmU/OiBzdHJpbmc7XG4gICAgcGFydHlOYW1lPzogc3RyaW5nO1xuICAgIG1lc3NhZ2VIZWFkbGluZT86IHN0cmluZztcbiAgICBtZXNzYWdlRGV0YWlsPzogc3RyaW5nO1xuICB9O1xuICBhZGRpdGlvbmFsSW5mb3JtYXRpb24/OiB1bmtub3duO1xufVxuXG5pbnRlcmZhY2UgU2NyYXBlZFBmbVRyYW5zYWN0aW9uIHtcbiAgdHJhbnNhY3Rpb25OdW1iZXI6IG51bWJlcjtcbn1cblxudHlwZSBGZXRjaGVkQWNjb3VudERhdGEgPSB7XG4gIGJhbmtOdW1iZXI6IHN0cmluZztcbiAgYWNjb3VudE51bWJlcjogc3RyaW5nO1xuICBicmFuY2hOdW1iZXI6IHN0cmluZztcbiAgYWNjb3VudENsb3NpbmdSZWFzb25Db2RlOiBudW1iZXI7XG59W107XG5cbnR5cGUgRmV0Y2hlZEFjY291bnRUcmFuc2FjdGlvbnNEYXRhID0ge1xuICB0cmFuc2FjdGlvbnM6IFNjcmFwZWRUcmFuc2FjdGlvbltdO1xufTtcblxudHlwZSBCYWxhbmNlQW5kQ3JlZGl0TGltaXQgPSB7XG4gIGNyZWRpdExpbWl0QW1vdW50OiBudW1iZXI7XG4gIGNyZWRpdExpbWl0RGVzY3JpcHRpb246IHN0cmluZztcbiAgY3JlZGl0TGltaXRVdGlsaXphdGlvbkFtb3VudDogbnVtYmVyO1xuICBjcmVkaXRMaW1pdFV0aWxpemF0aW9uRXhpc3RhbmNlQ29kZTogbnVtYmVyO1xuICBjcmVkaXRMaW1pdFV0aWxpemF0aW9uUGVyY2VudDogbnVtYmVyO1xuICBjdXJyZW50QWNjb3VudExpbWl0c0Ftb3VudDogbnVtYmVyO1xuICBjdXJyZW50QmFsYW5jZTogbnVtYmVyO1xuICB3aXRoZHJhd2FsQmFsYW5jZTogbnVtYmVyO1xufTtcblxuZnVuY3Rpb24gY29udmVydFRyYW5zYWN0aW9ucyh0eG5zOiBTY3JhcGVkVHJhbnNhY3Rpb25bXSwgb3B0aW9ucz86IFNjcmFwZXJPcHRpb25zKTogVHJhbnNhY3Rpb25bXSB7XG4gIHJldHVybiB0eG5zLm1hcCh0eG4gPT4ge1xuICAgIGNvbnN0IGlzT3V0Ym91bmQgPSB0eG4uZXZlbnRBY3Rpdml0eVR5cGVDb2RlID09PSAyO1xuXG4gICAgbGV0IG1lbW8gPSAnJztcbiAgICBpZiAodHhuLmJlbmVmaWNpYXJ5RGV0YWlsc0RhdGEpIHtcbiAgICAgIGNvbnN0IHsgcGFydHlIZWFkbGluZSwgcGFydHlOYW1lLCBtZXNzYWdlSGVhZGxpbmUsIG1lc3NhZ2VEZXRhaWwgfSA9IHR4bi5iZW5lZmljaWFyeURldGFpbHNEYXRhO1xuICAgICAgY29uc3QgbWVtb0xpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgaWYgKHBhcnR5SGVhZGxpbmUpIHtcbiAgICAgICAgbWVtb0xpbmVzLnB1c2gocGFydHlIZWFkbGluZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJ0eU5hbWUpIHtcbiAgICAgICAgbWVtb0xpbmVzLnB1c2goYCR7cGFydHlOYW1lfS5gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lc3NhZ2VIZWFkbGluZSkge1xuICAgICAgICBtZW1vTGluZXMucHVzaChtZXNzYWdlSGVhZGxpbmUpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZURldGFpbCkge1xuICAgICAgICBtZW1vTGluZXMucHVzaChgJHttZXNzYWdlRGV0YWlsfS5gKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lbW9MaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgbWVtbyA9IG1lbW9MaW5lcy5qb2luKCcgJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiBUcmFuc2FjdGlvbiA9IHtcbiAgICAgIHR5cGU6IFRyYW5zYWN0aW9uVHlwZXMuTm9ybWFsLFxuICAgICAgaWRlbnRpZmllcjogdHhuLnJlZmVyZW5jZU51bWJlcixcbiAgICAgIGRhdGU6IG1vbWVudCh0eG4uZXZlbnREYXRlLCBEQVRFX0ZPUk1BVCkudG9JU09TdHJpbmcoKSxcbiAgICAgIHByb2Nlc3NlZERhdGU6IG1vbWVudCh0eG4udmFsdWVEYXRlLCBEQVRFX0ZPUk1BVCkudG9JU09TdHJpbmcoKSxcbiAgICAgIG9yaWdpbmFsQW1vdW50OiBpc091dGJvdW5kID8gLXR4bi5ldmVudEFtb3VudCA6IHR4bi5ldmVudEFtb3VudCxcbiAgICAgIG9yaWdpbmFsQ3VycmVuY3k6ICdJTFMnLFxuICAgICAgY2hhcmdlZEFtb3VudDogaXNPdXRib3VuZCA/IC10eG4uZXZlbnRBbW91bnQgOiB0eG4uZXZlbnRBbW91bnQsXG4gICAgICBkZXNjcmlwdGlvbjogdHhuLmFjdGl2aXR5RGVzY3JpcHRpb24gfHwgJycsXG4gICAgICBzdGF0dXM6IHR4bi5zZXJpYWxOdW1iZXIgPT09IDAgPyBUcmFuc2FjdGlvblN0YXR1c2VzLlBlbmRpbmcgOiBUcmFuc2FjdGlvblN0YXR1c2VzLkNvbXBsZXRlZCxcbiAgICAgIG1lbW8sXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zPy5pbmNsdWRlUmF3VHJhbnNhY3Rpb24pIHtcbiAgICAgIHJlc3VsdC5yYXdUcmFuc2FjdGlvbiA9IGdldFJhd1RyYW5zYWN0aW9uKHR4bik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFJlc3RDb250ZXh0KHBhZ2U6IFBhZ2UpIHtcbiAgYXdhaXQgd2FpdFVudGlsKCgpID0+IHtcbiAgICByZXR1cm4gcGFnZS5ldmFsdWF0ZSgoKSA9PiAhIXdpbmRvdy5ibmhwQXBwKTtcbiAgfSwgJ3dhaXRpbmcgZm9yIGFwcCBkYXRhIGxvYWQnKTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICByZXR1cm4gd2luZG93LmJuaHBBcHAucmVzdENvbnRleHQ7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuc2xpY2UoMSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoUG9hbGltWFNSRldpdGhpblBhZ2UoXG4gIHBhZ2U6IFBhZ2UsXG4gIHVybDogc3RyaW5nLFxuICBwYWdlVXVpZDogc3RyaW5nLFxuKTogUHJvbWlzZTxGZXRjaGVkQWNjb3VudFRyYW5zYWN0aW9uc0RhdGEgfCBudWxsPiB7XG4gIGNvbnN0IGNvb2tpZXMgPSBhd2FpdCBwYWdlLmNvb2tpZXMoKTtcbiAgY29uc3QgWFNSRkNvb2tpZSA9IGNvb2tpZXMuZmluZChjb29raWUgPT4gY29va2llLm5hbWUgPT09ICdYU1JGLVRPS0VOJyk7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgaWYgKFhTUkZDb29raWUgIT0gbnVsbCkge1xuICAgIGhlYWRlcnNbJ1gtWFNSRi1UT0tFTiddID0gWFNSRkNvb2tpZS52YWx1ZTtcbiAgfVxuICBoZWFkZXJzLnBhZ2VVdWlkID0gcGFnZVV1aWQ7XG4gIGhlYWRlcnMudXVpZCA9IHJhbmRvbVVVSUQoKTtcbiAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PVVURi04JztcbiAgcmV0dXJuIGZldGNoUG9zdFdpdGhpblBhZ2U8RmV0Y2hlZEFjY291bnRUcmFuc2FjdGlvbnNEYXRhPihwYWdlLCB1cmwsIFtdLCBoZWFkZXJzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0RXh0cmFTY3JhcChcbiAgdHhuc1Jlc3VsdDogRmV0Y2hlZEFjY291bnRUcmFuc2FjdGlvbnNEYXRhLFxuICBiYXNlVXJsOiBzdHJpbmcsXG4gIHBhZ2U6IFBhZ2UsXG4gIGFjY291bnROdW1iZXI6IHN0cmluZyxcbik6IFByb21pc2U8RmV0Y2hlZEFjY291bnRUcmFuc2FjdGlvbnNEYXRhPiB7XG4gIGNvbnN0IHByb21pc2VzID0gdHhuc1Jlc3VsdC50cmFuc2FjdGlvbnMubWFwKGFzeW5jICh0cmFuc2FjdGlvbjogU2NyYXBlZFRyYW5zYWN0aW9uKTogUHJvbWlzZTxTY3JhcGVkVHJhbnNhY3Rpb24+ID0+IHtcbiAgICBjb25zdCB7IHBmbURldGFpbHMsIHNlcmlhbE51bWJlciB9ID0gdHJhbnNhY3Rpb247XG4gICAgaWYgKHNlcmlhbE51bWJlciAhPT0gMCkge1xuICAgICAgY29uc3QgdXJsID0gYCR7YmFzZVVybH0ke3BmbURldGFpbHN9JmFjY291bnRJZD0ke2FjY291bnROdW1iZXJ9Jmxhbmc9aGVgO1xuICAgICAgY29uc3QgZXh0cmFUcmFuc2FjdGlvbkRldGFpbHMgPSAoYXdhaXQgZmV0Y2hHZXRXaXRoaW5QYWdlPFNjcmFwZWRQZm1UcmFuc2FjdGlvbltdPihwYWdlLCB1cmwpKSB8fCBbXTtcbiAgICAgIGlmIChleHRyYVRyYW5zYWN0aW9uRGV0YWlscyAmJiBleHRyYVRyYW5zYWN0aW9uRGV0YWlscy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgeyB0cmFuc2FjdGlvbk51bWJlciB9ID0gZXh0cmFUcmFuc2FjdGlvbkRldGFpbHNbMF07XG4gICAgICAgIGlmICh0cmFuc2FjdGlvbk51bWJlcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi50cmFuc2FjdGlvbixcbiAgICAgICAgICAgIHJlZmVyZW5jZU51bWJlcjogdHJhbnNhY3Rpb25OdW1iZXIsXG4gICAgICAgICAgICBhZGRpdGlvbmFsSW5mb3JtYXRpb246IGV4dHJhVHJhbnNhY3Rpb25EZXRhaWxzLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uO1xuICB9KTtcbiAgY29uc3QgcmVzID0gYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICByZXR1cm4geyB0cmFuc2FjdGlvbnM6IHJlcyB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBY2NvdW50VHJhbnNhY3Rpb25zKFxuICBiYXNlVXJsOiBzdHJpbmcsXG4gIGFwaVNpdGVVcmw6IHN0cmluZyxcbiAgcGFnZTogUGFnZSxcbiAgYWNjb3VudE51bWJlcjogc3RyaW5nLFxuICBzdGFydERhdGU6IHN0cmluZyxcbiAgZW5kRGF0ZTogc3RyaW5nLFxuICBhZGRpdGlvbmFsVHJhbnNhY3Rpb25JbmZvcm1hdGlvbiA9IGZhbHNlLFxuICBvcHRpb25zPzogU2NyYXBlck9wdGlvbnMsXG4pIHtcbiAgY29uc3QgdHhuc1VybCA9IGAke2FwaVNpdGVVcmx9L2N1cnJlbnQtYWNjb3VudC90cmFuc2FjdGlvbnM/YWNjb3VudElkPSR7YWNjb3VudE51bWJlcn0mbnVtSXRlbXNQZXJQYWdlPTEwMDAmcmV0cmlldmFsRW5kRGF0ZT0ke2VuZERhdGV9JnJldHJpZXZhbFN0YXJ0RGF0ZT0ke3N0YXJ0RGF0ZX0mc29ydENvZGU9MWA7XG4gIGNvbnN0IHR4bnNSZXN1bHQgPSBhd2FpdCBmZXRjaFBvYWxpbVhTUkZXaXRoaW5QYWdlKHBhZ2UsIHR4bnNVcmwsICcvY3VycmVudC1hY2NvdW50L3RyYW5zYWN0aW9ucycpO1xuXG4gIGNvbnN0IGZpbmFsUmVzdWx0ID1cbiAgICBhZGRpdGlvbmFsVHJhbnNhY3Rpb25JbmZvcm1hdGlvbiAmJiB0eG5zUmVzdWx0Py50cmFuc2FjdGlvbnMubGVuZ3RoXG4gICAgICA/IGF3YWl0IGdldEV4dHJhU2NyYXAodHhuc1Jlc3VsdCwgYmFzZVVybCwgcGFnZSwgYWNjb3VudE51bWJlcilcbiAgICAgIDogdHhuc1Jlc3VsdDtcblxuICByZXR1cm4gY29udmVydFRyYW5zYWN0aW9ucyhmaW5hbFJlc3VsdD8udHJhbnNhY3Rpb25zID8/IFtdLCBvcHRpb25zKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWNjb3VudEJhbGFuY2UoYXBpU2l0ZVVybDogc3RyaW5nLCBwYWdlOiBQYWdlLCBhY2NvdW50TnVtYmVyOiBzdHJpbmcpIHtcbiAgY29uc3QgYmFsYW5jZUFuZENyZWRpdExpbWl0VXJsID0gYCR7YXBpU2l0ZVVybH0vY3VycmVudC1hY2NvdW50L2NvbXBvc2l0ZS9iYWxhbmNlQW5kQ3JlZGl0TGltaXQ/YWNjb3VudElkPSR7YWNjb3VudE51bWJlcn0mdmlldz1kZXRhaWxzJmxhbmc9aGVgO1xuICBjb25zdCBiYWxhbmNlQW5kQ3JlZGl0TGltaXQgPSBhd2FpdCBmZXRjaEdldFdpdGhpblBhZ2U8QmFsYW5jZUFuZENyZWRpdExpbWl0PihwYWdlLCBiYWxhbmNlQW5kQ3JlZGl0TGltaXRVcmwpO1xuXG4gIHJldHVybiBiYWxhbmNlQW5kQ3JlZGl0TGltaXQ/LmN1cnJlbnRCYWxhbmNlO1xufVxuXG5hc3luYyBmdW5jdGlvbiBmZXRjaEFjY291bnREYXRhKHBhZ2U6IFBhZ2UsIGJhc2VVcmw6IHN0cmluZywgb3B0aW9uczogU2NyYXBlck9wdGlvbnMpIHtcbiAgY29uc3QgcmVzdENvbnRleHQgPSBhd2FpdCBnZXRSZXN0Q29udGV4dChwYWdlKTtcbiAgY29uc3QgYXBpU2l0ZVVybCA9IGAke2Jhc2VVcmx9LyR7cmVzdENvbnRleHR9YDtcbiAgY29uc3QgYWNjb3VudERhdGFVcmwgPSBgJHtiYXNlVXJsfS9TZXJ2ZXJTZXJ2aWNlcy9nZW5lcmFsL2FjY291bnRzYDtcblxuICBkZWJ1ZygnZmV0Y2hpbmcgYWNjb3VudHMgZGF0YScpO1xuICBjb25zdCBhY2NvdW50c0luZm8gPSAoYXdhaXQgZmV0Y2hHZXRXaXRoaW5QYWdlPEZldGNoZWRBY2NvdW50RGF0YT4ocGFnZSwgYWNjb3VudERhdGFVcmwpKSB8fCBbXTtcbiAgY29uc3Qgb3BlbkFjY291bnRzSW5mbyA9IGFjY291bnRzSW5mby5maWx0ZXIoYWNjb3VudCA9PiBhY2NvdW50LmFjY291bnRDbG9zaW5nUmVhc29uQ29kZSA9PT0gMCk7XG4gIGRlYnVnKFxuICAgICdnb3QgJWQgb3BlbiBhY2NvdW50cyBmcm9tICVkIHRvdGFsIGFjY291bnRzLCBmZXRjaGluZyB0eG5zIGFuZCBiYWxhbmNlJyxcbiAgICBvcGVuQWNjb3VudHNJbmZvLmxlbmd0aCxcbiAgICBhY2NvdW50c0luZm8ubGVuZ3RoLFxuICApO1xuXG4gIGNvbnN0IGRlZmF1bHRTdGFydE1vbWVudCA9IG1vbWVudCgpLnN1YnRyYWN0KDEsICd5ZWFycycpLmFkZCgxLCAnZGF5Jyk7XG4gIGNvbnN0IHN0YXJ0RGF0ZSA9IG9wdGlvbnMuc3RhcnREYXRlIHx8IGRlZmF1bHRTdGFydE1vbWVudC50b0RhdGUoKTtcbiAgY29uc3Qgc3RhcnRNb21lbnQgPSBtb21lbnQubWF4KGRlZmF1bHRTdGFydE1vbWVudCwgbW9tZW50KHN0YXJ0RGF0ZSkpO1xuICBjb25zdCB7IGFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uIH0gPSBvcHRpb25zO1xuXG4gIGNvbnN0IHN0YXJ0RGF0ZVN0ciA9IHN0YXJ0TW9tZW50LmZvcm1hdChEQVRFX0ZPUk1BVCk7XG4gIGNvbnN0IGVuZERhdGVTdHIgPSBtb21lbnQoKS5mb3JtYXQoREFURV9GT1JNQVQpO1xuXG4gIGNvbnN0IGFjY291bnRzOiBUcmFuc2FjdGlvbnNBY2NvdW50W10gPSBbXTtcblxuICBmb3IgKGNvbnN0IGFjY291bnQgb2Ygb3BlbkFjY291bnRzSW5mbykge1xuICAgIGRlYnVnKCdnZXR0aW5nIGluZm9ybWF0aW9uIGZvciBhY2NvdW50ICVzJywgYWNjb3VudC5hY2NvdW50TnVtYmVyKTtcbiAgICBjb25zdCBhY2NvdW50TnVtYmVyID0gYCR7YWNjb3VudC5iYW5rTnVtYmVyfS0ke2FjY291bnQuYnJhbmNoTnVtYmVyfS0ke2FjY291bnQuYWNjb3VudE51bWJlcn1gO1xuXG4gICAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGdldEFjY291bnRCYWxhbmNlKGFwaVNpdGVVcmwsIHBhZ2UsIGFjY291bnROdW1iZXIpO1xuICAgIGNvbnN0IHR4bnMgPSBhd2FpdCBnZXRBY2NvdW50VHJhbnNhY3Rpb25zKFxuICAgICAgYmFzZVVybCxcbiAgICAgIGFwaVNpdGVVcmwsXG4gICAgICBwYWdlLFxuICAgICAgYWNjb3VudE51bWJlcixcbiAgICAgIHN0YXJ0RGF0ZVN0cixcbiAgICAgIGVuZERhdGVTdHIsXG4gICAgICBhZGRpdGlvbmFsVHJhbnNhY3Rpb25JbmZvcm1hdGlvbixcbiAgICAgIG9wdGlvbnMsXG4gICAgKTtcblxuICAgIGFjY291bnRzLnB1c2goe1xuICAgICAgYWNjb3VudE51bWJlcixcbiAgICAgIGJhbGFuY2UsXG4gICAgICB0eG5zLFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgYWNjb3VudERhdGEgPSB7XG4gICAgc3VjY2VzczogdHJ1ZSxcbiAgICBhY2NvdW50cyxcbiAgfTtcbiAgZGVidWcoJ2ZldGNoaW5nIGVuZGVkJyk7XG4gIHJldHVybiBhY2NvdW50RGF0YTtcbn1cblxuZnVuY3Rpb24gZ2V0UG9zc2libGVMb2dpblJlc3VsdHMoYmFzZVVybDogc3RyaW5nKSB7XG4gIGNvbnN0IHVybHM6IFBvc3NpYmxlTG9naW5SZXN1bHRzID0ge307XG4gIHVybHNbTG9naW5SZXN1bHRzLlN1Y2Nlc3NdID0gW1xuICAgIGAke2Jhc2VVcmx9L3BvcnRhbHNlcnZlci9Ib21lUGFnZWAsXG4gICAgYCR7YmFzZVVybH0vbmctcG9ydGFscy1idC9yYi9oZS9ob21lcGFnZWAsXG4gICAgYCR7YmFzZVVybH0vbmctcG9ydGFscy9yYi9oZS9ob21lcGFnZWAsXG4gIF07XG4gIHVybHNbTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZF0gPSBbXG4gICAgYCR7YmFzZVVybH0vQVVUSEVOVElDQVRFL0xPR09OP2Zsb3c9QVVUSEVOVElDQVRFJnN0YXRlPUxPR09OJmVycm9yY29kZT0xLjYmY2FsbG1lPWZhbHNlYCxcbiAgXTtcbiAgdXJsc1tMb2dpblJlc3VsdHMuQ2hhbmdlUGFzc3dvcmRdID0gW1xuICAgIGAke2Jhc2VVcmx9L01DUC9TVEFSVD9mbG93PU1DUCZzdGF0ZT1TVEFSVCZleHBpcmVkRGF0ZT1udWxsYCxcbiAgICAvXFwvQUJPVVRUT0VYUElSRVxcL1NUQVJUL2ksXG4gIF07XG4gIHJldHVybiB1cmxzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpIHtcbiAgcmV0dXJuIFtcbiAgICB7IHNlbGVjdG9yOiAnI3VzZXJDb2RlJywgdmFsdWU6IGNyZWRlbnRpYWxzLnVzZXJDb2RlIH0sXG4gICAgeyBzZWxlY3RvcjogJyNwYXNzd29yZCcsIHZhbHVlOiBjcmVkZW50aWFscy5wYXNzd29yZCB9LFxuICBdO1xufVxuXG50eXBlIFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzID0geyB1c2VyQ29kZTogc3RyaW5nOyBwYXNzd29yZDogc3RyaW5nIH07XG5cbmNsYXNzIEhhcG9hbGltU2NyYXBlciBleHRlbmRzIEJhc2VTY3JhcGVyV2l0aEJyb3dzZXI8U2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHM+IHtcbiAgZ2V0IGJhc2VVcmwoKSB7XG4gICAgcmV0dXJuICdodHRwczovL2xvZ2luLmJhbmtoYXBvYWxpbS5jby5pbCc7XG4gIH1cblxuICBnZXRMb2dpbk9wdGlvbnMoY3JlZGVudGlhbHM6IFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxvZ2luVXJsOiBgJHt0aGlzLmJhc2VVcmx9L2NnaS1iaW4vcG9hbHd3d2M/cmVxTmFtZT1nZXRMb2dvblBhZ2VgLFxuICAgICAgZmllbGRzOiBjcmVhdGVMb2dpbkZpZWxkcyhjcmVkZW50aWFscyksXG4gICAgICBzdWJtaXRCdXR0b25TZWxlY3RvcjogJy5sb2dpbi1idG4nLFxuICAgICAgcG9zdEFjdGlvbjogYXN5bmMgKCkgPT4gd2FpdEZvclJlZGlyZWN0KHRoaXMucGFnZSksXG4gICAgICBwb3NzaWJsZVJlc3VsdHM6IGdldFBvc3NpYmxlTG9naW5SZXN1bHRzKHRoaXMuYmFzZVVybCksXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZldGNoRGF0YSgpIHtcbiAgICByZXR1cm4gZmV0Y2hBY2NvdW50RGF0YSh0aGlzLnBhZ2UsIHRoaXMuYmFzZVVybCwgdGhpcy5vcHRpb25zKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBIYXBvYWxpbVNjcmFwZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLElBQUFBLE9BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUVBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLE1BQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLE1BQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFdBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFFBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLGFBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLHVCQUFBLEdBQUFQLE9BQUE7QUFFQSxJQUFBUSxjQUFBLEdBQUFSLE9BQUE7QUFBNEQsU0FBQUQsdUJBQUFVLENBQUEs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