UNPKG

israeli-bank-scrapers

Version:

Provide scrapers for all major Israeli banks and credit card companies

198 lines (195 loc) 32.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _moment = _interopRequireDefault(require("moment")); var _uuid = require("uuid"); 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"); 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) { 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 }; 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, _uuid.v4)(); 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 }; } } } return transaction; }); const res = await Promise.all(promises); return { transactions: res }; } async function getAccountTransactions(baseUrl, apiSiteUrl, page, accountNumber, startDate, endDate, additionalTransactionInformation = false) { 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 ?? []); } 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)) || []; debug('got %d accounts, fetching txns and balance', 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 accountsInfo) { let balance; const accountNumber = `${account.bankNumber}-${account.branchNumber}-${account.accountNumber}`; const isActiveAccount = account.accountClosingReasonCode === 0; if (isActiveAccount) { balance = await getAccountBalance(apiSiteUrl, page, accountNumber); } else { debug('Skipping balance for a closed account, balance will be undefined'); } const txns = await getAccountTransactions(baseUrl, apiSiteUrl, page, accountNumber, startDateStr, endDateStr, additionalTransactionInformation); 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 { // eslint-disable-next-line class-methods-use-this 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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfdXVpZCIsIl9kZWJ1ZyIsIl9mZXRjaCIsIl9uYXZpZ2F0aW9uIiwiX3dhaXRpbmciLCJfdHJhbnNhY3Rpb25zIiwiX2Jhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImdldERlYnVnIiwiREFURV9GT1JNQVQiLCJjb252ZXJ0VHJhbnNhY3Rpb25zIiwidHhucyIsIm1hcCIsInR4biIsImlzT3V0Ym91bmQiLCJldmVudEFjdGl2aXR5VHlwZUNvZGUiLCJtZW1vIiwiYmVuZWZpY2lhcnlEZXRhaWxzRGF0YSIsInBhcnR5SGVhZGxpbmUiLCJwYXJ0eU5hbWUiLCJtZXNzYWdlSGVhZGxpbmUiLCJtZXNzYWdlRGV0YWlsIiwibWVtb0xpbmVzIiwicHVzaCIsImxlbmd0aCIsImpvaW4iLCJyZXN1bHQiLCJ0eXBlIiwiVHJhbnNhY3Rpb25UeXBlcyIsIk5vcm1hbCIsImlkZW50aWZpZXIiLCJyZWZlcmVuY2VOdW1iZXIiLCJkYXRlIiwibW9tZW50IiwiZXZlbnREYXRlIiwidG9JU09TdHJpbmciLCJwcm9jZXNzZWREYXRlIiwidmFsdWVEYXRlIiwib3JpZ2luYWxBbW91bnQiLCJldmVudEFtb3VudCIsIm9yaWdpbmFsQ3VycmVuY3kiLCJjaGFyZ2VkQW1vdW50IiwiZGVzY3JpcHRpb24iLCJhY3Rpdml0eURlc2NyaXB0aW9uIiwic3RhdHVzIiwic2VyaWFsTnVtYmVyIiwiVHJhbnNhY3Rpb25TdGF0dXNlcyIsIlBlbmRpbmciLCJDb21wbGV0ZWQiLCJnZXRSZXN0Q29udGV4dCIsInBhZ2UiLCJ3YWl0VW50aWwiLCJldmFsdWF0ZSIsIndpbmRvdyIsImJuaHBBcHAiLCJyZXN0Q29udGV4dCIsInNsaWNlIiwiZmV0Y2hQb2FsaW1YU1JGV2l0aGluUGFnZSIsInVybCIsInBhZ2VVdWlkIiwiY29va2llcyIsIlhTUkZDb29raWUiLCJmaW5kIiwiY29va2llIiwibmFtZSIsImhlYWRlcnMiLCJ2YWx1ZSIsInV1aWQiLCJ1dWlkNCIsImZldGNoUG9zdFdpdGhpblBhZ2UiLCJnZXRFeHRyYVNjcmFwIiwidHhuc1Jlc3VsdCIsImJhc2VVcmwiLCJhY2NvdW50TnVtYmVyIiwicHJvbWlzZXMiLCJ0cmFuc2FjdGlvbnMiLCJ0cmFuc2FjdGlvbiIsInBmbURldGFpbHMiLCJleHRyYVRyYW5zYWN0aW9uRGV0YWlscyIsImZldGNoR2V0V2l0aGluUGFnZSIsInRyYW5zYWN0aW9uTnVtYmVyIiwicmVzIiwiUHJvbWlzZSIsImFsbCIsImdldEFjY291bnRUcmFuc2FjdGlvbnMiLCJhcGlTaXRlVXJsIiwic3RhcnREYXRlIiwiZW5kRGF0ZSIsImFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uIiwidHhuc1VybCIsImZpbmFsUmVzdWx0IiwiZ2V0QWNjb3VudEJhbGFuY2UiLCJiYWxhbmNlQW5kQ3JlZGl0TGltaXRVcmwiLCJiYWxhbmNlQW5kQ3JlZGl0TGltaXQiLCJjdXJyZW50QmFsYW5jZSIsImZldGNoQWNjb3VudERhdGEiLCJvcHRpb25zIiwiYWNjb3VudERhdGFVcmwiLCJhY2NvdW50c0luZm8iLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJzdWJ0cmFjdCIsImFkZCIsInRvRGF0ZSIsInN0YXJ0TW9tZW50IiwibWF4Iiwic3RhcnREYXRlU3RyIiwiZm9ybWF0IiwiZW5kRGF0ZVN0ciIsImFjY291bnRzIiwiYWNjb3VudCIsImJhbGFuY2UiLCJiYW5rTnVtYmVyIiwiYnJhbmNoTnVtYmVyIiwiaXNBY3RpdmVBY2NvdW50IiwiYWNjb3VudENsb3NpbmdSZWFzb25Db2RlIiwiYWNjb3VudERhdGEiLCJzdWNjZXNzIiwiZ2V0UG9zc2libGVMb2dpblJlc3VsdHMiLCJ1cmxzIiwiTG9naW5SZXN1bHRzIiwiU3VjY2VzcyIsIkludmFsaWRQYXNzd29yZCIsIkNoYW5nZVBhc3N3b3JkIiwiY3JlYXRlTG9naW5GaWVsZHMiLCJjcmVkZW50aWFscyIsInNlbGVjdG9yIiwidXNlckNvZGUiLCJwYXNzd29yZCIsIkhhcG9hbGltU2NyYXBlciIsIkJhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJnZXRMb2dpbk9wdGlvbnMiLCJsb2dpblVybCIsImZpZWxkcyIsInN1Ym1pdEJ1dHRvblNlbGVjdG9yIiwicG9zdEFjdGlvbiIsIndhaXRGb3JSZWRpcmVjdCIsInBvc3NpYmxlUmVzdWx0cyIsImZldGNoRGF0YSIsIl9kZWZhdWx0IiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JhcGVycy9oYXBvYWxpbS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyB0eXBlIFBhZ2UgfSBmcm9tICdwdXBwZXRlZXInO1xuaW1wb3J0IHsgdjQgYXMgdXVpZDQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7IGdldERlYnVnIH0gZnJvbSAnLi4vaGVscGVycy9kZWJ1Zyc7XG5pbXBvcnQgeyBmZXRjaEdldFdpdGhpblBhZ2UsIGZldGNoUG9zdFdpdGhpblBhZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2ZldGNoJztcbmltcG9ydCB7IHdhaXRGb3JSZWRpcmVjdCB9IGZyb20gJy4uL2hlbHBlcnMvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyB3YWl0VW50aWwgfSBmcm9tICcuLi9oZWxwZXJzL3dhaXRpbmcnO1xuaW1wb3J0IHsgdHlwZSBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25TdGF0dXNlcywgVHJhbnNhY3Rpb25UeXBlcywgdHlwZSBUcmFuc2FjdGlvbnNBY2NvdW50IH0gZnJvbSAnLi4vdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIsIExvZ2luUmVzdWx0cywgdHlwZSBQb3NzaWJsZUxvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQgeyB0eXBlIFNjcmFwZXJPcHRpb25zIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuXG5jb25zdCBkZWJ1ZyA9IGdldERlYnVnKCdoYXBvYWxpbScpO1xuXG5jb25zdCBEQVRFX0ZPUk1BVCA9ICdZWVlZTU1ERCc7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbmFtZXNwYWNlXG5kZWNsYXJlIG5hbWVzcGFjZSB3aW5kb3cge1xuICBjb25zdCBibmhwQXBwOiBhbnk7XG59XG5cbmludGVyZmFjZSBTY3JhcGVkVHJhbnNhY3Rpb24ge1xuICBzZXJpYWxOdW1iZXI/OiBudW1iZXI7XG4gIGFjdGl2aXR5RGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIGV2ZW50QW1vdW50OiBudW1iZXI7XG4gIHZhbHVlRGF0ZT86IHN0cmluZztcbiAgZXZlbnREYXRlPzogc3RyaW5nO1xuICByZWZlcmVuY2VOdW1iZXI/OiBudW1iZXI7XG4gIFNjcmFwZWRUcmFuc2FjdGlvbj86IHN0cmluZztcbiAgZXZlbnRBY3Rpdml0eVR5cGVDb2RlOiBudW1iZXI7XG4gIGN1cnJlbnRCYWxhbmNlOiBudW1iZXI7XG4gIHBmbURldGFpbHM6IHN0cmluZztcbiAgYmVuZWZpY2lhcnlEZXRhaWxzRGF0YT86IHtcbiAgICBwYXJ0eUhlYWRsaW5lPzogc3RyaW5nO1xuICAgIHBhcnR5TmFtZT86IHN0cmluZztcbiAgICBtZXNzYWdlSGVhZGxpbmU/OiBzdHJpbmc7XG4gICAgbWVzc2FnZURldGFpbD86IHN0cmluZztcbiAgfTtcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRQZm1UcmFuc2FjdGlvbiB7XG4gIHRyYW5zYWN0aW9uTnVtYmVyOiBudW1iZXI7XG59XG5cbnR5cGUgRmV0Y2hlZEFjY291bnREYXRhID0ge1xuICBiYW5rTnVtYmVyOiBzdHJpbmc7XG4gIGFjY291bnROdW1iZXI6IHN0cmluZztcbiAgYnJhbmNoTnVtYmVyOiBzdHJpbmc7XG4gIGFjY291bnRDbG9zaW5nUmVhc29uQ29kZTogbnVtYmVyO1xufVtdO1xuXG50eXBlIEZldGNoZWRBY2NvdW50VHJhbnNhY3Rpb25zRGF0YSA9IHtcbiAgdHJhbnNhY3Rpb25zOiBTY3JhcGVkVHJhbnNhY3Rpb25bXTtcbn07XG5cbnR5cGUgQmFsYW5jZUFuZENyZWRpdExpbWl0ID0ge1xuICBjcmVkaXRMaW1pdEFtb3VudDogbnVtYmVyO1xuICBjcmVkaXRMaW1pdERlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNyZWRpdExpbWl0VXRpbGl6YXRpb25BbW91bnQ6IG51bWJlcjtcbiAgY3JlZGl0TGltaXRVdGlsaXphdGlvbkV4aXN0YW5jZUNvZGU6IG51bWJlcjtcbiAgY3JlZGl0TGltaXRVdGlsaXphdGlvblBlcmNlbnQ6IG51bWJlcjtcbiAgY3VycmVudEFjY291bnRMaW1pdHNBbW91bnQ6IG51bWJlcjtcbiAgY3VycmVudEJhbGFuY2U6IG51bWJlcjtcbiAgd2l0aGRyYXdhbEJhbGFuY2U6IG51bWJlcjtcbn07XG5cbmZ1bmN0aW9uIGNvbnZlcnRUcmFuc2FjdGlvbnModHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10pOiBUcmFuc2FjdGlvbltdIHtcbiAgcmV0dXJuIHR4bnMubWFwKHR4biA9PiB7XG4gICAgY29uc3QgaXNPdXRib3VuZCA9IHR4bi5ldmVudEFjdGl2aXR5VHlwZUNvZGUgPT09IDI7XG5cbiAgICBsZXQgbWVtbyA9ICcnO1xuICAgIGlmICh0eG4uYmVuZWZpY2lhcnlEZXRhaWxzRGF0YSkge1xuICAgICAgY29uc3QgeyBwYXJ0eUhlYWRsaW5lLCBwYXJ0eU5hbWUsIG1lc3NhZ2VIZWFkbGluZSwgbWVzc2FnZURldGFpbCB9ID0gdHhuLmJlbmVmaWNpYXJ5RGV0YWlsc0RhdGE7XG4gICAgICBjb25zdCBtZW1vTGluZXM6IHN0cmluZ1tdID0gW107XG4gICAgICBpZiAocGFydHlIZWFkbGluZSkge1xuICAgICAgICBtZW1vTGluZXMucHVzaChwYXJ0eUhlYWRsaW5lKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcnR5TmFtZSkge1xuICAgICAgICBtZW1vTGluZXMucHVzaChgJHtwYXJ0eU5hbWV9LmApO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZUhlYWRsaW5lKSB7XG4gICAgICAgIG1lbW9MaW5lcy5wdXNoKG1lc3NhZ2VIZWFkbGluZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtZXNzYWdlRGV0YWlsKSB7XG4gICAgICAgIG1lbW9MaW5lcy5wdXNoKGAke21lc3NhZ2VEZXRhaWx9LmApO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVtb0xpbmVzLmxlbmd0aCkge1xuICAgICAgICBtZW1vID0gbWVtb0xpbmVzLmpvaW4oJyAnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQ6IFRyYW5zYWN0aW9uID0ge1xuICAgICAgdHlwZTogVHJhbnNhY3Rpb25UeXBlcy5Ob3JtYWwsXG4gICAgICBpZGVudGlmaWVyOiB0eG4ucmVmZXJlbmNlTnVtYmVyLFxuICAgICAgZGF0ZTogbW9tZW50KHR4bi5ldmVudERhdGUsIERBVEVfRk9STUFUKS50b0lTT1N0cmluZygpLFxuICAgICAgcHJvY2Vzc2VkRGF0ZTogbW9tZW50KHR4bi52YWx1ZURhdGUsIERBVEVfRk9STUFUKS50b0lTT1N0cmluZygpLFxuICAgICAgb3JpZ2luYWxBbW91bnQ6IGlzT3V0Ym91bmQgPyAtdHhuLmV2ZW50QW1vdW50IDogdHhuLmV2ZW50QW1vdW50LFxuICAgICAgb3JpZ2luYWxDdXJyZW5jeTogJ0lMUycsXG4gICAgICBjaGFyZ2VkQW1vdW50OiBpc091dGJvdW5kID8gLXR4bi5ldmVudEFtb3VudCA6IHR4bi5ldmVudEFtb3VudCxcbiAgICAgIGRlc2NyaXB0aW9uOiB0eG4uYWN0aXZpdHlEZXNjcmlwdGlvbiB8fCAnJyxcbiAgICAgIHN0YXR1czogdHhuLnNlcmlhbE51bWJlciA9PT0gMCA/IFRyYW5zYWN0aW9uU3RhdHVzZXMuUGVuZGluZyA6IFRyYW5zYWN0aW9uU3RhdHVzZXMuQ29tcGxldGVkLFxuICAgICAgbWVtbyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFJlc3RDb250ZXh0KHBhZ2U6IFBhZ2UpIHtcbiAgYXdhaXQgd2FpdFVudGlsKCgpID0+IHtcbiAgICByZXR1cm4gcGFnZS5ldmFsdWF0ZSgoKSA9PiAhIXdpbmRvdy5ibmhwQXBwKTtcbiAgfSwgJ3dhaXRpbmcgZm9yIGFwcCBkYXRhIGxvYWQnKTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHtcbiAgICByZXR1cm4gd2luZG93LmJuaHBBcHAucmVzdENvbnRleHQ7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuc2xpY2UoMSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoUG9hbGltWFNSRldpdGhpblBhZ2UoXG4gIHBhZ2U6IFBhZ2UsXG4gIHVybDogc3RyaW5nLFxuICBwYWdlVXVpZDogc3RyaW5nLFxuKTogUHJvbWlzZTxGZXRjaGVkQWNjb3VudFRyYW5zYWN0aW9uc0RhdGEgfCBudWxsPiB7XG4gIGNvbnN0IGNvb2tpZXMgPSBhd2FpdCBwYWdlLmNvb2tpZXMoKTtcbiAgY29uc3QgWFNSRkNvb2tpZSA9IGNvb2tpZXMuZmluZChjb29raWUgPT4gY29va2llLm5hbWUgPT09ICdYU1JGLVRPS0VOJyk7XG4gIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgaWYgKFhTUkZDb29raWUgIT0gbnVsbCkge1xuICAgIGhlYWRlcnNbJ1gtWFNSRi1UT0tFTiddID0gWFNSRkNvb2tpZS52YWx1ZTtcbiAgfVxuICBoZWFkZXJzLnBhZ2VVdWlkID0gcGFnZVV1aWQ7XG4gIGhlYWRlcnMudXVpZCA9IHV1aWQ0KCk7XG4gIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL2pzb247Y2hhcnNldD1VVEYtOCc7XG4gIHJldHVybiBmZXRjaFBvc3RXaXRoaW5QYWdlPEZldGNoZWRBY2NvdW50VHJhbnNhY3Rpb25zRGF0YT4ocGFnZSwgdXJsLCBbXSwgaGVhZGVycyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEV4dHJhU2NyYXAoXG4gIHR4bnNSZXN1bHQ6IEZldGNoZWRBY2NvdW50VHJhbnNhY3Rpb25zRGF0YSxcbiAgYmFzZVVybDogc3RyaW5nLFxuICBwYWdlOiBQYWdlLFxuICBhY2NvdW50TnVtYmVyOiBzdHJpbmcsXG4pOiBQcm9taXNlPEZldGNoZWRBY2NvdW50VHJhbnNhY3Rpb25zRGF0YT4ge1xuICBjb25zdCBwcm9taXNlcyA9IHR4bnNSZXN1bHQudHJhbnNhY3Rpb25zLm1hcChhc3luYyAodHJhbnNhY3Rpb246IFNjcmFwZWRUcmFuc2FjdGlvbik6IFByb21pc2U8U2NyYXBlZFRyYW5zYWN0aW9uPiA9PiB7XG4gICAgY29uc3QgeyBwZm1EZXRhaWxzLCBzZXJpYWxOdW1iZXIgfSA9IHRyYW5zYWN0aW9uO1xuICAgIGlmIChzZXJpYWxOdW1iZXIgIT09IDApIHtcbiAgICAgIGNvbnN0IHVybCA9IGAke2Jhc2VVcmx9JHtwZm1EZXRhaWxzfSZhY2NvdW50SWQ9JHthY2NvdW50TnVtYmVyfSZsYW5nPWhlYDtcbiAgICAgIGNvbnN0IGV4dHJhVHJhbnNhY3Rpb25EZXRhaWxzID0gKGF3YWl0IGZldGNoR2V0V2l0aGluUGFnZTxTY3JhcGVkUGZtVHJhbnNhY3Rpb25bXT4ocGFnZSwgdXJsKSkgfHwgW107XG4gICAgICBpZiAoZXh0cmFUcmFuc2FjdGlvbkRldGFpbHMgJiYgZXh0cmFUcmFuc2FjdGlvbkRldGFpbHMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHsgdHJhbnNhY3Rpb25OdW1iZXIgfSA9IGV4dHJhVHJhbnNhY3Rpb25EZXRhaWxzWzBdO1xuICAgICAgICBpZiAodHJhbnNhY3Rpb25OdW1iZXIpIHtcbiAgICAgICAgICByZXR1cm4geyAuLi50cmFuc2FjdGlvbiwgcmVmZXJlbmNlTnVtYmVyOiB0cmFuc2FjdGlvbk51bWJlciB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cmFuc2FjdGlvbjtcbiAgfSk7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgcmV0dXJuIHsgdHJhbnNhY3Rpb25zOiByZXMgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWNjb3VudFRyYW5zYWN0aW9ucyhcbiAgYmFzZVVybDogc3RyaW5nLFxuICBhcGlTaXRlVXJsOiBzdHJpbmcsXG4gIHBhZ2U6IFBhZ2UsXG4gIGFjY291bnROdW1iZXI6IHN0cmluZyxcbiAgc3RhcnREYXRlOiBzdHJpbmcsXG4gIGVuZERhdGU6IHN0cmluZyxcbiAgYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb24gPSBmYWxzZSxcbikge1xuICBjb25zdCB0eG5zVXJsID0gYCR7YXBpU2l0ZVVybH0vY3VycmVudC1hY2NvdW50L3RyYW5zYWN0aW9ucz9hY2NvdW50SWQ9JHthY2NvdW50TnVtYmVyfSZudW1JdGVtc1BlclBhZ2U9MTAwMCZyZXRyaWV2YWxFbmREYXRlPSR7ZW5kRGF0ZX0mcmV0cmlldmFsU3RhcnREYXRlPSR7c3RhcnREYXRlfSZzb3J0Q29kZT0xYDtcbiAgY29uc3QgdHhuc1Jlc3VsdCA9IGF3YWl0IGZldGNoUG9hbGltWFNSRldpdGhpblBhZ2UocGFnZSwgdHhuc1VybCwgJy9jdXJyZW50LWFjY291bnQvdHJhbnNhY3Rpb25zJyk7XG5cbiAgY29uc3QgZmluYWxSZXN1bHQgPVxuICAgIGFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uICYmIHR4bnNSZXN1bHQ/LnRyYW5zYWN0aW9ucy5sZW5ndGhcbiAgICAgID8gYXdhaXQgZ2V0RXh0cmFTY3JhcCh0eG5zUmVzdWx0LCBiYXNlVXJsLCBwYWdlLCBhY2NvdW50TnVtYmVyKVxuICAgICAgOiB0eG5zUmVzdWx0O1xuXG4gIHJldHVybiBjb252ZXJ0VHJhbnNhY3Rpb25zKGZpbmFsUmVzdWx0Py50cmFuc2FjdGlvbnMgPz8gW10pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRBY2NvdW50QmFsYW5jZShhcGlTaXRlVXJsOiBzdHJpbmcsIHBhZ2U6IFBhZ2UsIGFjY291bnROdW1iZXI6IHN0cmluZykge1xuICBjb25zdCBiYWxhbmNlQW5kQ3JlZGl0TGltaXRVcmwgPSBgJHthcGlTaXRlVXJsfS9jdXJyZW50LWFjY291bnQvY29tcG9zaXRlL2JhbGFuY2VBbmRDcmVkaXRMaW1pdD9hY2NvdW50SWQ9JHthY2NvdW50TnVtYmVyfSZ2aWV3PWRldGFpbHMmbGFuZz1oZWA7XG4gIGNvbnN0IGJhbGFuY2VBbmRDcmVkaXRMaW1pdCA9IGF3YWl0IGZldGNoR2V0V2l0aGluUGFnZTxCYWxhbmNlQW5kQ3JlZGl0TGltaXQ+KHBhZ2UsIGJhbGFuY2VBbmRDcmVkaXRMaW1pdFVybCk7XG5cbiAgcmV0dXJuIGJhbGFuY2VBbmRDcmVkaXRMaW1pdD8uY3VycmVudEJhbGFuY2U7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoQWNjb3VudERhdGEocGFnZTogUGFnZSwgYmFzZVVybDogc3RyaW5nLCBvcHRpb25zOiBTY3JhcGVyT3B0aW9ucykge1xuICBjb25zdCByZXN0Q29udGV4dCA9IGF3YWl0IGdldFJlc3RDb250ZXh0KHBhZ2UpO1xuICBjb25zdCBhcGlTaXRlVXJsID0gYCR7YmFzZVVybH0vJHtyZXN0Q29udGV4dH1gO1xuICBjb25zdCBhY2NvdW50RGF0YVVybCA9IGAke2Jhc2VVcmx9L1NlcnZlclNlcnZpY2VzL2dlbmVyYWwvYWNjb3VudHNgO1xuXG4gIGRlYnVnKCdmZXRjaGluZyBhY2NvdW50cyBkYXRhJyk7XG4gIGNvbnN0IGFjY291bnRzSW5mbyA9IChhd2FpdCBmZXRjaEdldFdpdGhpblBhZ2U8RmV0Y2hlZEFjY291bnREYXRhPihwYWdlLCBhY2NvdW50RGF0YVVybCkpIHx8IFtdO1xuICBkZWJ1ZygnZ290ICVkIGFjY291bnRzLCBmZXRjaGluZyB0eG5zIGFuZCBiYWxhbmNlJywgYWNjb3VudHNJbmZvLmxlbmd0aCk7XG5cbiAgY29uc3QgZGVmYXVsdFN0YXJ0TW9tZW50ID0gbW9tZW50KCkuc3VidHJhY3QoMSwgJ3llYXJzJykuYWRkKDEsICdkYXknKTtcbiAgY29uc3Qgc3RhcnREYXRlID0gb3B0aW9ucy5zdGFydERhdGUgfHwgZGVmYXVsdFN0YXJ0TW9tZW50LnRvRGF0ZSgpO1xuICBjb25zdCBzdGFydE1vbWVudCA9IG1vbWVudC5tYXgoZGVmYXVsdFN0YXJ0TW9tZW50LCBtb21lbnQoc3RhcnREYXRlKSk7XG4gIGNvbnN0IHsgYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb24gfSA9IG9wdGlvbnM7XG5cbiAgY29uc3Qgc3RhcnREYXRlU3RyID0gc3RhcnRNb21lbnQuZm9ybWF0KERBVEVfRk9STUFUKTtcbiAgY29uc3QgZW5kRGF0ZVN0ciA9IG1vbWVudCgpLmZvcm1hdChEQVRFX0ZPUk1BVCk7XG5cbiAgY29uc3QgYWNjb3VudHM6IFRyYW5zYWN0aW9uc0FjY291bnRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYWNjb3VudCBvZiBhY2NvdW50c0luZm8pIHtcbiAgICBsZXQgYmFsYW5jZTogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFjY291bnROdW1iZXIgPSBgJHthY2NvdW50LmJhbmtOdW1iZXJ9LSR7YWNjb3VudC5icmFuY2hOdW1iZXJ9LSR7YWNjb3VudC5hY2NvdW50TnVtYmVyfWA7XG5cbiAgICBjb25zdCBpc0FjdGl2ZUFjY291bnQgPSBhY2NvdW50LmFjY291bnRDbG9zaW5nUmVhc29uQ29kZSA9PT0gMDtcbiAgICBpZiAoaXNBY3RpdmVBY2NvdW50KSB7XG4gICAgICBiYWxhbmNlID0gYXdhaXQgZ2V0QWNjb3VudEJhbGFuY2UoYXBpU2l0ZVVybCwgcGFnZSwgYWNjb3VudE51bWJlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlYnVnKCdTa2lwcGluZyBiYWxhbmNlIGZvciBhIGNsb3NlZCBhY2NvdW50LCBiYWxhbmNlIHdpbGwgYmUgdW5kZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgdHhucyA9IGF3YWl0IGdldEFjY291bnRUcmFuc2FjdGlvbnMoXG4gICAgICBiYXNlVXJsLFxuICAgICAgYXBpU2l0ZVVybCxcbiAgICAgIHBhZ2UsXG4gICAgICBhY2NvdW50TnVtYmVyLFxuICAgICAgc3RhcnREYXRlU3RyLFxuICAgICAgZW5kRGF0ZVN0cixcbiAgICAgIGFkZGl0aW9uYWxUcmFuc2FjdGlvbkluZm9ybWF0aW9uLFxuICAgICk7XG5cbiAgICBhY2NvdW50cy5wdXNoKHtcbiAgICAgIGFjY291bnROdW1iZXIsXG4gICAgICBiYWxhbmNlLFxuICAgICAgdHhucyxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGFjY291bnREYXRhID0ge1xuICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgYWNjb3VudHMsXG4gIH07XG4gIGRlYnVnKCdmZXRjaGluZyBlbmRlZCcpO1xuICByZXR1cm4gYWNjb3VudERhdGE7XG59XG5cbmZ1bmN0aW9uIGdldFBvc3NpYmxlTG9naW5SZXN1bHRzKGJhc2VVcmw6IHN0cmluZykge1xuICBjb25zdCB1cmxzOiBQb3NzaWJsZUxvZ2luUmVzdWx0cyA9IHt9O1xuICB1cmxzW0xvZ2luUmVzdWx0cy5TdWNjZXNzXSA9IFtcbiAgICBgJHtiYXNlVXJsfS9wb3J0YWxzZXJ2ZXIvSG9tZVBhZ2VgLFxuICAgIGAke2Jhc2VVcmx9L25nLXBvcnRhbHMtYnQvcmIvaGUvaG9tZXBhZ2VgLFxuICAgIGAke2Jhc2VVcmx9L25nLXBvcnRhbHMvcmIvaGUvaG9tZXBhZ2VgLFxuICBdO1xuICB1cmxzW0xvZ2luUmVzdWx0cy5JbnZhbGlkUGFzc3dvcmRdID0gW1xuICAgIGAke2Jhc2VVcmx9L0FVVEhFTlRJQ0FURS9MT0dPTj9mbG93PUFVVEhFTlRJQ0FURSZzdGF0ZT1MT0dPTiZlcnJvcmNvZGU9MS42JmNhbGxtZT1mYWxzZWAsXG4gIF07XG4gIHVybHNbTG9naW5SZXN1bHRzLkNoYW5nZVBhc3N3b3JkXSA9IFtcbiAgICBgJHtiYXNlVXJsfS9NQ1AvU1RBUlQ/Zmxvdz1NQ1Amc3RhdGU9U1RBUlQmZXhwaXJlZERhdGU9bnVsbGAsXG4gICAgL1xcL0FCT1VUVE9FWFBJUkVcXC9TVEFSVC9pLFxuICBdO1xuICByZXR1cm4gdXJscztcbn1cblxuZnVuY3Rpb24gY3JlYXRlTG9naW5GaWVsZHMoY3JlZGVudGlhbHM6IFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzKSB7XG4gIHJldHVybiBbXG4gICAgeyBzZWxlY3RvcjogJyN1c2VyQ29kZScsIHZhbHVlOiBjcmVkZW50aWFscy51c2VyQ29kZSB9LFxuICAgIHsgc2VsZWN0b3I6ICcjcGFzc3dvcmQnLCB2YWx1ZTogY3JlZGVudGlhbHMucGFzc3dvcmQgfSxcbiAgXTtcbn1cblxudHlwZSBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscyA9IHsgdXNlckNvZGU6IHN0cmluZzsgcGFzc3dvcmQ6IHN0cmluZyB9O1xuXG5jbGFzcyBIYXBvYWxpbVNjcmFwZXIgZXh0ZW5kcyBCYXNlU2NyYXBlcldpdGhCcm93c2VyPFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzPiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzXG4gIGdldCBiYXNlVXJsKCkge1xuICAgIHJldHVybiAnaHR0cHM6Ly9sb2dpbi5iYW5raGFwb2FsaW0uY28uaWwnO1xuICB9XG5cbiAgZ2V0TG9naW5PcHRpb25zKGNyZWRlbnRpYWxzOiBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscykge1xuICAgIHJldHVybiB7XG4gICAgICBsb2dpblVybDogYCR7dGhpcy5iYXNlVXJsfS9jZ2ktYmluL3BvYWx3d3djP3JlcU5hbWU9Z2V0TG9nb25QYWdlYCxcbiAgICAgIGZpZWxkczogY3JlYXRlTG9naW5GaWVsZHMoY3JlZGVudGlhbHMpLFxuICAgICAgc3VibWl0QnV0dG9uU2VsZWN0b3I6ICcubG9naW4tYnRuJyxcbiAgICAgIHBvc3RBY3Rpb246IGFzeW5jICgpID0+IHdhaXRGb3JSZWRpcmVjdCh0aGlzLnBhZ2UpLFxuICAgICAgcG9zc2libGVSZXN1bHRzOiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cyh0aGlzLmJhc2VVcmwpLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKSB7XG4gICAgcmV0dXJuIGZldGNoQWNjb3VudERhdGEodGhpcy5wYWdlLCB0aGlzLmJhc2VVcmwsIHRoaXMub3B0aW9ucyk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSGFwb2FsaW1TY3JhcGVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBQyxLQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxNQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxNQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxXQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxRQUFBLEdBQUFMLE9BQUE7QUFDQSxJQUFBTSxhQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyx1QkFBQSxHQUFBUCxPQUFBO0FBQThHLFNBQUFELHVCQUFBUyxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRzlHLE1BQU1HLEtBQUssR0FBRyxJQUFBQyxlQUFRLEVBQUMsVUFBVSxDQUFDO0FBRWxDLE1BQU1DLFdBQVcsR0FBRyxVQUFVOztBQUU5Qjs7QUFrREEsU0FBU0MsbUJBQW1CQSxDQUFDQyxJQUEwQixFQUFpQjtFQUN0RSxPQUFPQSxJQUFJLENBQUNDLEdBQUcsQ0FBQ0MsR0FBRyxJQUFJO0lBQ3JCLE1BQU1DLFVBQVUsR0FBR0QsR0FBRyxDQUFDRSxxQkFBcUIsS0FBSyxDQUFDO0lBRWxELElBQUlDLElBQUksR0FBRyxFQUFFO0lBQ2IsSUFBSUgsR0FBRyxDQUFDSSxzQkFBc0IsRUFBRTtNQUM5QixNQUFNO1FBQUVDLGFBQWE7UUFBRUMsU0FBUztRQUFFQyxlQUFlO1FBQUVDO01BQWMsQ0FBQyxHQUFHUixHQUFHLENBQUNJLHNCQUFzQjtNQUMvRixNQUFNSyxTQUFtQixHQUFHLEVBQUU7TUFDOUIsSUFBSUosYUFBYSxFQUFFO1FBQ2pCSSxTQUFTLENBQUNDLElB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