UNPKG

israeli-bank-scrapers-core

Version:

Provide scrapers for all major Israeli banks and credit card companies

282 lines 53.6 kB
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _moment = _interopRequireDefault(require("moment"));
var _constants = require("../constants");
var _elementsInteractions = require("../helpers/elements-interactions");
var _fetch = require("../helpers/fetch");
var _navigation = require("../helpers/navigation");
var _transactions = require("../transactions");
var _baseScraperWithBrowser = require("./base-scraper-with-browser");
var _errors = require("./errors");
var _debug = require("../helpers/debug");
var _transactions2 = require("../helpers/transactions");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug.getDebug)('mizrahi');
const BASE_WEBSITE_URL = 'https://www.mizrahi-tefahot.co.il';
const LOGIN_URL = `${BASE_WEBSITE_URL}/login/index.html#/auth-page-he`;
const BASE_APP_URL = 'https://mto.mizrahi-tefahot.co.il';
const AFTER_LOGIN_BASE_URL = /https:\/\/mto\.mizrahi-tefahot\.co\.il\/OnlineApp\/.*/;
const OSH_PAGE = '/osh/legacy/legacy-Osh-Main';
const TRANSACTIONS_PAGE = '/osh/legacy/root-main-osh-p428New';
const TRANSACTIONS_REQUEST_URLS = [`${BASE_APP_URL}/OnlinePilot/api/SkyOSH/get428Index`, `${BASE_APP_URL}/Online/api/SkyOSH/get428Index`];
const PENDING_TRANSACTIONS_PAGE = '/osh/legacy/legacy-Osh-p420';
const PENDING_TRANSACTIONS_IFRAME = 'p420.aspx';
const MORE_DETAILS_URL = `${BASE_APP_URL}/Online/api/OSH/getMaherBerurimSMF`;
const CHANGE_PASSWORD_URL = /https:\/\/www\.mizrahi-tefahot\.co\.il\/login\/index\.html#\/change-pass/;
const DATE_FORMAT = 'DD/MM/YYYY';
const MAX_ROWS_PER_REQUEST = 10000000000;
const usernameSelector = '#userNumberDesktopHeb';
const passwordSelector = '#passwordDesktopHeb';
const submitButtonSelector = 'button.btn.btn-primary';
const invalidPasswordSelector = 'a[href*="https://sc.mizrahi-tefahot.co.il/SCServices/SC/P010.aspx"]';
const afterLoginSelector = '#dropdownBasic';
const loginSpinnerSelector = 'div.ngx-overlay.loading-foreground';
const accountDropDownItemSelector = '#AccountPicker .item';
const pendingTrxIdentifierId = '#ctl00_ContentPlaceHolder2_panel1';
const checkingAccountTabHebrewName = 'עובר ושב';
const checkingAccountTabEnglishName = 'Checking Account';
const genericDescriptions = ['העברת יומן לבנק זר מסניף זר'];
function createLoginFields(credentials) {
  return [{
    selector: usernameSelector,
    value: credentials.username
  }, {
    selector: passwordSelector,
    value: credentials.password
  }];
}
async function isLoggedIn(options) {
  if (!options?.page) {
    return false;
  }
  const oshXPath = `//a//span[contains(., "${checkingAccountTabHebrewName}") or contains(., "${checkingAccountTabEnglishName}")]`;
  const oshTab = await options.page.$$(`xpath${oshXPath}`);
  return oshTab.length > 0;
}
function getPossibleLoginResults(page) {
  return {
    [_baseScraperWithBrowser.LoginResults.Success]: [AFTER_LOGIN_BASE_URL, isLoggedIn],
    [_baseScraperWithBrowser.LoginResults.InvalidPassword]: [async () => !!(await page.$(invalidPasswordSelector))],
    [_baseScraperWithBrowser.LoginResults.ChangePassword]: [CHANGE_PASSWORD_URL]
  };
}
function getStartMoment(optionsStartDate) {
  const defaultStartMoment = (0, _moment.default)().subtract(1, 'years');
  const startDate = optionsStartDate || defaultStartMoment.toDate();
  return _moment.default.max(defaultStartMoment, (0, _moment.default)(startDate));
}
async function getExtraTransactionDetails(page, item, apiHeaders) {
  try {
    debug('getExtraTransactionDetails for item:', item);
    if (item.MC02ShowDetailsEZ === '1') {
      const tarPeula = (0, _moment.default)(item.MC02PeulaTaaEZ);
      const tarErech = (0, _moment.default)(item.MC02ErehTaaEZ);
      const params = {
        inKodGorem: item.MC02KodGoremEZ,
        inAsmachta: item.MC02AsmahtaMekoritEZ,
        inSchum: item.MC02SchumEZ,
        inNakvanit: item.MC02KodGoremEZ,
        inSugTnua: item.MC02SugTnuaKaspitEZ,
        inAgid: item.MC02AgidEZ,
        inTarPeulaFormatted: tarPeula.format(DATE_FORMAT),
        inTarErechFormatted: (tarErech.year() > 2000 ? tarErech : tarPeula).format(DATE_FORMAT),
        inKodNose: item.MC02SeifMaralEZ,
        inKodTatNose: item.MC02NoseMaralEZ,
        inTransactionNumber: item.TransactionNumber
      };
      const response = await (0, _fetch.fetchPostWithinPage)(page, MORE_DETAILS_URL, params, apiHeaders);
      const details = response?.body.fields?.[0]?.[0]?.Records?.[0].Fields;
      debug('fetch details for', params, 'details:', details);
      if (Array.isArray(details) && details.length > 0) {
        const entries = details.map(record => [record.Label.trim(), record.Value.trim()]);
        return {
          entries: Object.fromEntries(entries),
          memo: entries.filter(([label]) => ['שם', 'מהות', 'חשבון'].some(key => label.startsWith(key))).map(([label, value]) => `${label} ${value}`).join(', ')
        };
      }
    }
  } catch (error) {
    debug('Error fetching extra transaction details:', error);
  }
  return {
    entries: {},
    memo: undefined
  };
}
function createDataFromRequest(request, optionsStartDate) {
  const data = JSON.parse(request.postData() || '{}');
  data.inFromDate = getStartMoment(optionsStartDate).format(DATE_FORMAT);
  data.inToDate = (0, _moment.default)().format(DATE_FORMAT);
  data.table.maxRow = MAX_ROWS_PER_REQUEST;
  return data;
}
function createHeadersFromRequest(request) {
  return {
    mizrahixsrftoken: request.headers().mizrahixsrftoken,
    'Content-Type': request.headers()['content-type']
  };
}
function getTransactionIdentifier(row) {
  if (!row.MC02AsmahtaMekoritEZ) {
    return undefined;
  }
  if (row.TransactionNumber && String(row.TransactionNumber) !== '1') {
    return `${row.MC02AsmahtaMekoritEZ}-${row.TransactionNumber}`;
  }
  return parseInt(row.MC02AsmahtaMekoritEZ, 10);
}
async function convertTransactions(txns, getMoreDetails, pendingIfTodayTransaction = false, options) {
  return Promise.all(txns.map(async row => {
    const moreDetails = await getMoreDetails(row);
    const txnDate = (0, _moment.default)(row.MC02PeulaTaaEZ, _moment.default.HTML5_FMT.DATETIME_LOCAL_SECONDS).toISOString();
    const result = {
      type: _transactions.TransactionTypes.Normal,
      identifier: getTransactionIdentifier(row),
      date: txnDate,
      processedDate: txnDate,
      originalAmount: row.MC02SchumEZ,
      originalCurrency: _constants.SHEKEL_CURRENCY,
      chargedAmount: row.MC02SchumEZ,
      description: row.MC02TnuaTeurEZ,
      memo: moreDetails?.memo,
      status: pendingIfTodayTransaction && row.IsTodayTransaction ? _transactions.TransactionStatuses.Pending : _transactions.TransactionStatuses.Completed
    };
    if (options?.includeRawTransaction) {
      result.rawTransaction = (0, _transactions2.getRawTransaction)({
        ...row,
        additionalInformation: moreDetails.entries
      });
    }
    return result;
  }));
}
async function extractPendingTransactions(page) {
  const pendingTxn = await (0, _elementsInteractions.pageEvalAll)(page, 'tr.rgRow, tr.rgAltRow', [], trs => {
    return trs.map(tr => Array.from(tr.querySelectorAll('td'), td => td.textContent || ''));
  });
  return pendingTxn.map(([dateStr, description, incomeAmountStr, amountStr]) => ({
    date: (0, _moment.default)(dateStr, 'DD/MM/YY').toISOString(),
    amount: parseFloat(amountStr.replaceAll(',', '')),
    description,
    incomeAmountStr // TODO: handle incomeAmountStr once we know the sign of it
  })).filter(txn => txn.date).map(({
    date,
    description,
    amount
  }) => ({
    type: _transactions.TransactionTypes.Normal,
    date,
    processedDate: date,
    originalAmount: amount,
    originalCurrency: _constants.SHEKEL_CURRENCY,
    chargedAmount: amount,
    description,
    status: _transactions.TransactionStatuses.Pending
  }));
}
async function postLogin(page) {
  await Promise.race([(0, _elementsInteractions.waitUntilElementFound)(page, afterLoginSelector), (0, _elementsInteractions.waitUntilElementFound)(page, invalidPasswordSelector), (0, _navigation.waitForUrl)(page, CHANGE_PASSWORD_URL)]);
}
class MizrahiScraper extends _baseScraperWithBrowser.BaseScraperWithBrowser {
  getLoginOptions(credentials) {
    return {
      loginUrl: LOGIN_URL,
      fields: createLoginFields(credentials),
      submitButtonSelector,
      checkReadiness: async () => (0, _elementsInteractions.waitUntilElementDisappear)(this.page, loginSpinnerSelector),
      postAction: async () => postLogin(this.page),
      possibleResults: getPossibleLoginResults(this.page)
    };
  }
  async fetchData() {
    await this.page.$eval('#dropdownBasic, .item', el => el.click());
    const numOfAccounts = (await this.page.$$(accountDropDownItemSelector)).length;
    try {
      const results = [];
      for (let i = 0; i < numOfAccounts; i += 1) {
        if (i > 0) {
          await this.page.$eval('#dropdownBasic, .item', el => el.click());
        }
        await this.page.$eval(`${accountDropDownItemSelector}:nth-child(${i + 1})`, el => el.click());
        results.push(await this.fetchAccount());
      }
      return {
        success: true,
        accounts: results
      };
    } catch (e) {
      return {
        success: false,
        errorType: _errors.ScraperErrorTypes.Generic,
        errorMessage: e.message
      };
    }
  }
  async getPendingTransactions() {
    await this.page.$eval(`a[href*="${PENDING_TRANSACTIONS_PAGE}"]`, el => el.click());
    const frame = await (0, _elementsInteractions.waitUntilIframeFound)(this.page, f => f.url().includes(PENDING_TRANSACTIONS_IFRAME));
    const isPending = await (0, _elementsInteractions.waitUntilElementFound)(frame, pendingTrxIdentifierId).then(() => true).catch(() => false);
    if (!isPending) {
      return [];
    }
    const pendingTxn = await extractPendingTransactions(frame);
    return pendingTxn;
  }
  async fetchAccount() {
    await this.page.waitForSelector(`a[href*="${OSH_PAGE}"]`);
    await this.page.$eval(`a[href*="${OSH_PAGE}"]`, el => el.click());
    await (0, _elementsInteractions.waitUntilElementFound)(this.page, `a[href*="${TRANSACTIONS_PAGE}"]`);
    await this.page.$eval(`a[href*="${TRANSACTIONS_PAGE}"]`, el => el.click());
    const accountNumberElement = await this.page.$('#dropdownBasic b span');
    const accountNumberHandle = await accountNumberElement?.getProperty('title');
    const accountNumber = await accountNumberHandle?.jsonValue();
    if (!accountNumber) {
      throw new Error('Account number not found');
    }
    const [response, apiHeaders] = await Promise.any(TRANSACTIONS_REQUEST_URLS.map(async url => {
      const request = await this.page.waitForRequest(url);
      const data = createDataFromRequest(request, this.options.startDate);
      const headers = createHeadersFromRequest(request);
      return [await (0, _fetch.fetchPostWithinPage)(this.page, url, data, headers), headers];
    }));
    if (!response || response.header.success === false) {
      throw new Error(`Error fetching transaction. Response message: ${response ? response.header.messages[0].text : ''}`);
    }
    const relevantRows = response.body.table.rows.filter(row => row.RecTypeSpecified);
    const oshTxn = await convertTransactions(relevantRows, this.options.additionalTransactionInformation ? row => getExtraTransactionDetails(this.page, row, apiHeaders) : () => Promise.resolve({
      entries: {},
      memo: undefined
    }), this.options.optInFeatures?.includes('mizrahi:pendingIfTodayTransaction'), this.options);
    oshTxn.filter(txn => this.shouldMarkAsPending(txn)).forEach(txn => {
      txn.status = _transactions.TransactionStatuses.Pending;
    });

    // workaround for a bug which the bank's API returns transactions before the requested start date
    const startMoment = getStartMoment(this.options.startDate);
    const oshTxnAfterStartDate = oshTxn.filter(txn => (0, _moment.default)(txn.date).isSameOrAfter(startMoment));
    const pendingTxn = await this.getPendingTransactions();
    const allTxn = oshTxnAfterStartDate.concat(pendingTxn);
    return {
      accountNumber,
      txns: allTxn,
      balance: +response.body.fields?.Yitra
    };
  }
  shouldMarkAsPending(txn) {
    if (this.options.optInFeatures?.includes('mizrahi:pendingIfNoIdentifier') && !txn.identifier) {
      debug(`Marking transaction '${txn.description}' as pending due to no identifier.`);
      return true;
    }
    if (this.options.optInFeatures?.includes('mizrahi:pendingIfHasGenericDescription') && genericDescriptions.includes(txn.description)) {
      debug(`Marking transaction '${txn.description}' as pending due to generic description.`);
      return true;
    }
    return false;
  }
}
var _default = exports.default = MizrahiScraper;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfY29uc3RhbnRzIiwiX2VsZW1lbnRzSW50ZXJhY3Rpb25zIiwiX2ZldGNoIiwiX25hdmlnYXRpb24iLCJfdHJhbnNhY3Rpb25zIiwiX2Jhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJfZXJyb3JzIiwiX2RlYnVnIiwiX3RyYW5zYWN0aW9uczIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImdldERlYnVnIiwiQkFTRV9XRUJTSVRFX1VSTCIsIkxPR0lOX1VSTCIsIkJBU0VfQVBQX1VSTCIsIkFGVEVSX0xPR0lOX0JBU0VfVVJMIiwiT1NIX1BBR0UiLCJUUkFOU0FDVElPTlNfUEFHRSIsIlRSQU5TQUNUSU9OU19SRVFVRVNUX1VSTFMiLCJQRU5ESU5HX1RSQU5TQUNUSU9OU19QQUdFIiwiUEVORElOR19UUkFOU0FDVElPTlNfSUZSQU1FIiwiTU9SRV9ERVRBSUxTX1VSTCIsIkNIQU5HRV9QQVNTV09SRF9VUkwiLCJEQVRFX0ZPUk1BVCIsIk1BWF9ST1dTX1BFUl9SRVFVRVNUIiwidXNlcm5hbWVTZWxlY3RvciIsInBhc3N3b3JkU2VsZWN0b3IiLCJzdWJtaXRCdXR0b25TZWxlY3RvciIsImludmFsaWRQYXNzd29yZFNlbGVjdG9yIiwiYWZ0ZXJMb2dpblNlbGVjdG9yIiwibG9naW5TcGlubmVyU2VsZWN0b3IiLCJhY2NvdW50RHJvcERvd25JdGVtU2VsZWN0b3IiLCJwZW5kaW5nVHJ4SWRlbnRpZmllcklkIiwiY2hlY2tpbmdBY2NvdW50VGFiSGVicmV3TmFtZSIsImNoZWNraW5nQWNjb3VudFRhYkVuZ2xpc2hOYW1lIiwiZ2VuZXJpY0Rlc2NyaXB0aW9ucyIsImNyZWF0ZUxvZ2luRmllbGRzIiwiY3JlZGVudGlhbHMiLCJzZWxlY3RvciIsInZhbHVlIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImlzTG9nZ2VkSW4iLCJvcHRpb25zIiwicGFnZSIsIm9zaFhQYXRoIiwib3NoVGFiIiwiJCQiLCJsZW5ndGgiLCJnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cyIsIkxvZ2luUmVzdWx0cyIsIlN1Y2Nlc3MiLCJJbnZhbGlkUGFzc3dvcmQiLCIkIiwiQ2hhbmdlUGFzc3dvcmQiLCJnZXRTdGFydE1vbWVudCIsIm9wdGlvbnNTdGFydERhdGUiLCJkZWZhdWx0U3RhcnRNb21lbnQiLCJtb21lbnQiLCJzdWJ0cmFjdCIsInN0YXJ0RGF0ZSIsInRvRGF0ZSIsIm1heCIsImdldEV4dHJhVHJhbnNhY3Rpb25EZXRhaWxzIiwiaXRlbSIsImFwaUhlYWRlcnMiLCJNQzAyU2hvd0RldGFpbHNFWiIsInRhclBldWxhIiwiTUMwMlBldWxhVGFhRVoiLCJ0YXJFcmVjaCIsIk1DMDJFcmVoVGFhRVoiLCJwYXJhbXMiLCJpbktvZEdvcmVtIiwiTUMwMktvZEdvcmVtRVoiLCJpbkFzbWFjaHRhIiwiTUMwMkFzbWFodGFNZWtvcml0RVoiLCJpblNjaHVtIiwiTUMwMlNjaHVtRVoiLCJpbk5ha3Zhbml0IiwiaW5TdWdUbnVhIiwiTUMwMlN1Z1RudWFLYXNwaXRFWiIsImluQWdpZCIsIk1DMDJBZ2lkRVoiLCJpblRhclBldWxhRm9ybWF0dGVkIiwiZm9ybWF0IiwiaW5UYXJFcmVjaEZvcm1hdHRlZCIsInllYXIiLCJpbktvZE5vc2UiLCJNQzAyU2VpZk1hcmFsRVoiLCJpbktvZFRhdE5vc2UiLCJNQzAyTm9zZU1hcmFsRVoiLCJpblRyYW5zYWN0aW9uTnVtYmVyIiwiVHJhbnNhY3Rpb25OdW1iZXIiLCJyZXNwb25zZSIsImZldGNoUG9zdFdpdGhpblBhZ2UiLCJkZXRhaWxzIiwiYm9keSIsImZpZWxkcyIsIlJlY29yZHMiLCJGaWVsZHMiLCJBcnJheSIsImlzQXJyYXkiLCJlbnRyaWVzIiwibWFwIiwicmVjb3JkIiwiTGFiZWwiLCJ0cmltIiwiVmFsdWUiLCJPYmplY3QiLCJmcm9tRW50cmllcyIsIm1lbW8iLCJmaWx0ZXIiLCJsYWJlbCIsInNvbWUiLCJrZXkiLCJzdGFydHNXaXRoIiwiam9pbiIsImVycm9yIiwidW5kZWZpbmVkIiwiY3JlYXRlRGF0YUZyb21SZXF1ZXN0IiwicmVxdWVzdCIsImRhdGEiLCJKU09OIiwicGFyc2UiLCJwb3N0RGF0YSIsImluRnJvbURhdGUiLCJpblRvRGF0ZSIsInRhYmxlIiwibWF4Um93IiwiY3JlYXRlSGVhZGVyc0Zyb21SZXF1ZXN0IiwibWl6cmFoaXhzcmZ0b2tlbiIsImhlYWRlcnMiLCJnZXRUcmFuc2FjdGlvbklkZW50aWZpZXIiLCJyb3ciLCJTdHJpbmciLCJwYXJzZUludCIsImNvbnZlcnRUcmFuc2FjdGlvbnMiLCJ0eG5zIiwiZ2V0TW9yZURldGFpbHMiLCJwZW5kaW5nSWZUb2RheVRyYW5zYWN0aW9uIiwiUHJvbWlzZSIsImFsbCIsIm1vcmVEZXRhaWxzIiwidHhuRGF0ZSIsIkhUTUw1X0ZNVCIsIkRBVEVUSU1FX0xPQ0FMX1NFQ09ORFMiLCJ0b0lTT1N0cmluZyIsInJlc3VsdCIsInR5cGUiLCJUcmFuc2FjdGlvblR5cGVzIiwiTm9ybWFsIiwiaWRlbnRpZmllciIsImRhdGUiLCJwcm9jZXNzZWREYXRlIiwib3JpZ2luYWxBbW91bnQiLCJvcmlnaW5hbEN1cnJlbmN5IiwiU0hFS0VMX0NVUlJFTkNZIiwiY2hhcmdlZEFtb3VudCIsImRlc2NyaXB0aW9uIiwiTUMwMlRudWFUZXVyRVoiLCJzdGF0dXMiLCJJc1RvZGF5VHJhbnNhY3Rpb24iLCJUcmFuc2FjdGlvblN0YXR1c2VzIiwiUGVuZGluZyIsIkNvbXBsZXRlZCIsImluY2x1ZGVSYXdUcmFuc2FjdGlvbiIsInJhd1RyYW5zYWN0aW9uIiwiZ2V0UmF3VHJhbnNhY3Rpb24iLCJhZGRpdGlvbmFsSW5mb3JtYXRpb24iLCJleHRyYWN0UGVuZGluZ1RyYW5zYWN0aW9ucyIsInBlbmRpbmdUeG4iLCJwYWdlRXZhbEFsbCIsInRycyIsInRyIiwiZnJvbSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJ0ZCIsInRleHRDb250ZW50IiwiZGF0ZVN0ciIsImluY29tZUFtb3VudFN0ciIsImFtb3VudFN0ciIsImFtb3VudCIsInBhcnNlRmxvYXQiLCJyZXBsYWNlQWxsIiwidHhuIiwicG9zdExvZ2luIiwicmFjZSIsIndhaXRVbnRpbEVsZW1lbnRGb3VuZCIsIndhaXRGb3JVcmwiLCJNaXpyYWhpU2NyYXBlciIsIkJhc2VTY3JhcGVyV2l0aEJyb3dzZXIiLCJnZXRMb2dpbk9wdGlvbnMiLCJsb2dpblVybCIsImNoZWNrUmVhZGluZXNzIiwid2FpdFVudGlsRWxlbWVudERpc2FwcGVhciIsInBvc3RBY3Rpb24iLCJwb3NzaWJsZVJlc3VsdHMiLCJmZXRjaERhdGEiLCIkZXZhbCIsImVsIiwiY2xpY2siLCJudW1PZkFjY291bnRzIiwicmVzdWx0cyIsImkiLCJwdXNoIiwiZmV0Y2hBY2NvdW50Iiwic3VjY2VzcyIsImFjY291bnRzIiwiZXJyb3JUeXBlIiwiU2NyYXBlckVycm9yVHlwZXMiLCJHZW5lcmljIiwiZXJyb3JNZXNzYWdlIiwibWVzc2FnZSIsImdldFBlbmRpbmdUcmFuc2FjdGlvbnMiLCJmcmFtZSIsIndhaXRVbnRpbElmcmFtZUZvdW5kIiwiZiIsInVybCIsImluY2x1ZGVzIiwiaXNQZW5kaW5nIiwidGhlbiIsImNhdGNoIiwid2FpdEZvclNlbGVjdG9yIiwiYWNjb3VudE51bWJlckVsZW1lbnQiLCJhY2NvdW50TnVtYmVySGFuZGxlIiwiZ2V0UHJvcGVydHkiLCJhY2NvdW50TnVtYmVyIiwianNvblZhbHVlIiwiRXJyb3IiLCJhbnkiLCJ3YWl0Rm9yUmVxdWVzdCIsImhlYWRlciIsIm1lc3NhZ2VzIiwidGV4dCIsInJlbGV2YW50Um93cyIsInJvd3MiLCJSZWNUeXBlU3BlY2lmaWVkIiwib3NoVHhuIiwiYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb24iLCJyZXNvbHZlIiwib3B0SW5GZWF0dXJlcyIsInNob3VsZE1hcmtBc1BlbmRpbmciLCJmb3JFYWNoIiwic3RhcnRNb21lbnQiLCJvc2hUeG5BZnRlclN0YXJ0RGF0ZSIsImlzU2FtZU9yQWZ0ZXIiLCJhbGxUeG4iLCJjb25jYXQiLCJiYWxhbmNlIiwiWWl0cmEiLCJfZGVmYXVsdCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NyYXBlcnMvbWl6cmFoaS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyB0eXBlIEZyYW1lLCB0eXBlIEhUVFBSZXF1ZXN0LCB0eXBlIFBhZ2UgfSBmcm9tICdwdXBwZXRlZXItY29yZSc7XG5pbXBvcnQgeyBTSEVLRUxfQ1VSUkVOQ1kgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgcGFnZUV2YWxBbGwsXG4gIHdhaXRVbnRpbEVsZW1lbnREaXNhcHBlYXIsXG4gIHdhaXRVbnRpbEVsZW1lbnRGb3VuZCxcbiAgd2FpdFVudGlsSWZyYW1lRm91bmQsXG59IGZyb20gJy4uL2hlbHBlcnMvZWxlbWVudHMtaW50ZXJhY3Rpb25zJztcbmltcG9ydCB7IGZldGNoUG9zdFdpdGhpblBhZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2ZldGNoJztcbmltcG9ydCB7IHdhaXRGb3JVcmwgfSBmcm9tICcuLi9oZWxwZXJzL25hdmlnYXRpb24nO1xuaW1wb3J0IHsgdHlwZSBUcmFuc2FjdGlvbiwgVHJhbnNhY3Rpb25TdGF0dXNlcywgVHJhbnNhY3Rpb25UeXBlcywgdHlwZSBUcmFuc2FjdGlvbnNBY2NvdW50IH0gZnJvbSAnLi4vdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IEJhc2VTY3JhcGVyV2l0aEJyb3dzZXIsIExvZ2luUmVzdWx0cywgdHlwZSBQb3NzaWJsZUxvZ2luUmVzdWx0cyB9IGZyb20gJy4vYmFzZS1zY3JhcGVyLXdpdGgtYnJvd3Nlcic7XG5pbXBvcnQgeyBTY3JhcGVyRXJyb3JUeXBlcyB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IGdldERlYnVnIH0gZnJvbSAnLi4vaGVscGVycy9kZWJ1Zyc7XG5pbXBvcnQgeyBnZXRSYXdUcmFuc2FjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvdHJhbnNhY3Rpb25zJztcbmltcG9ydCB7IHR5cGUgU2NyYXBlck9wdGlvbnMgfSBmcm9tICcuL2ludGVyZmFjZSc7XG5cbmNvbnN0IGRlYnVnID0gZ2V0RGVidWcoJ21penJhaGknKTtcblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbiB7XG4gIFJlY1R5cGVTcGVjaWZpZWQ6IGJvb2xlYW47XG4gIE1DMDJQZXVsYVRhYUVaOiBzdHJpbmc7XG4gIE1DMDJTY2h1bUVaOiBudW1iZXI7XG4gIE1DMDJBc21haHRhTWVrb3JpdEVaOiBzdHJpbmc7XG4gIE1DMDJUbnVhVGV1ckVaOiBzdHJpbmc7XG4gIElzVG9kYXlUcmFuc2FjdGlvbjogYm9vbGVhbjtcbiAgTUMwMkVyZWhUYWFFWjogc3RyaW5nO1xuICBNQzAyU2hvd0RldGFpbHNFWj86IHN0cmluZztcbiAgTUMwMktvZEdvcmVtRVo6IGFueTtcbiAgTUMwMlN1Z1RudWFLYXNwaXRFWjogYW55O1xuICBNQzAyQWdpZEVaOiBhbnk7XG4gIE1DMDJTZWlmTWFyYWxFWjogYW55O1xuICBNQzAyTm9zZU1hcmFsRVo6IGFueTtcbiAgVHJhbnNhY3Rpb25OdW1iZXI6IGFueTtcbn1cblxuaW50ZXJmYWNlIFNjcmFwZWRUcmFuc2FjdGlvbnNSZXN1bHQge1xuICBoZWFkZXI6IHtcbiAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgIG1lc3NhZ2VzOiB7IHRleHQ6IHN0cmluZyB9W107XG4gIH07XG4gIGJvZHk6IHtcbiAgICBmaWVsZHM6IHtcbiAgICAgIFlpdHJhOiBzdHJpbmc7XG4gICAgfTtcbiAgICB0YWJsZToge1xuICAgICAgcm93czogU2NyYXBlZFRyYW5zYWN0aW9uW107XG4gICAgfTtcbiAgfTtcbn1cblxudHlwZSBNb3JlRGV0YWlsc1Jlc3BvbnNlID0ge1xuICBib2R5OiB7XG4gICAgZmllbGRzOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICBSZWNvcmRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIEZpZWxkczogQXJyYXk8e1xuICAgICAgICAgICAgICAgIExhYmVsOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgVmFsdWU6IHN0cmluZztcbiAgICAgICAgICAgICAgfT47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIF07XG4gIH07XG59O1xuXG50eXBlIE1vcmVEZXRhaWxzID0ge1xuICBlbnRyaWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICBtZW1vOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG59O1xuXG5jb25zdCBCQVNFX1dFQlNJVEVfVVJMID0gJ2h0dHBzOi8vd3d3Lm1penJhaGktdGVmYWhvdC5jby5pbCc7XG5jb25zdCBMT0dJTl9VUkwgPSBgJHtCQVNFX1dFQlNJVEVfVVJMfS9sb2dpbi9pbmRleC5odG1sIy9hdXRoLXBhZ2UtaGVgO1xuY29uc3QgQkFTRV9BUFBfVVJMID0gJ2h0dHBzOi8vbXRvLm1penJhaGktdGVmYWhvdC5jby5pbCc7XG5jb25zdCBBRlRFUl9MT0dJTl9CQVNFX1VSTCA9IC9odHRwczpcXC9cXC9tdG9cXC5taXpyYWhpLXRlZmFob3RcXC5jb1xcLmlsXFwvT25saW5lQXBwXFwvLiovO1xuY29uc3QgT1NIX1BBR0UgPSAnL29zaC9sZWdhY3kvbGVnYWN5LU9zaC1NYWluJztcbmNvbnN0IFRSQU5TQUNUSU9OU19QQUdFID0gJy9vc2gvbGVnYWN5L3Jvb3QtbWFpbi1vc2gtcDQyOE5ldyc7XG5jb25zdCBUUkFOU0FDVElPTlNfUkVRVUVTVF9VUkxTID0gW1xuICBgJHtCQVNFX0FQUF9VUkx9L09ubGluZVBpbG90L2FwaS9Ta3lPU0gvZ2V0NDI4SW5kZXhgLFxuICBgJHtCQVNFX0FQUF9VUkx9L09ubGluZS9hcGkvU2t5T1NIL2dldDQyOEluZGV4YCxcbl07XG5jb25zdCBQRU5ESU5HX1RSQU5TQUNUSU9OU19QQUdFID0gJy9vc2gvbGVnYWN5L2xlZ2FjeS1Pc2gtcDQyMCc7XG5jb25zdCBQRU5ESU5HX1RSQU5TQUNUSU9OU19JRlJBTUUgPSAncDQyMC5hc3B4JztcbmNvbnN0IE1PUkVfREVUQUlMU19VUkwgPSBgJHtCQVNFX0FQUF9VUkx9L09ubGluZS9hcGkvT1NIL2dldE1haGVyQmVydXJpbVNNRmA7XG5jb25zdCBDSEFOR0VfUEFTU1dPUkRfVVJMID0gL2h0dHBzOlxcL1xcL3d3d1xcLm1penJhaGktdGVmYWhvdFxcLmNvXFwuaWxcXC9sb2dpblxcL2luZGV4XFwuaHRtbCNcXC9jaGFuZ2UtcGFzcy87XG5jb25zdCBEQVRFX0ZPUk1BVCA9ICdERC9NTS9ZWVlZJztcbmNvbnN0IE1BWF9ST1dTX1BFUl9SRVFVRVNUID0gMTAwMDAwMDAwMDA7XG5cbmNvbnN0IHVzZXJuYW1lU2VsZWN0b3IgPSAnI3VzZXJOdW1iZXJEZXNrdG9wSGViJztcbmNvbnN0IHBhc3N3b3JkU2VsZWN0b3IgPSAnI3Bhc3N3b3JkRGVza3RvcEhlYic7XG5jb25zdCBzdWJtaXRCdXR0b25TZWxlY3RvciA9ICdidXR0b24uYnRuLmJ0bi1wcmltYXJ5JztcbmNvbnN0IGludmFsaWRQYXNzd29yZFNlbGVjdG9yID0gJ2FbaHJlZio9XCJodHRwczovL3NjLm1penJhaGktdGVmYWhvdC5jby5pbC9TQ1NlcnZpY2VzL1NDL1AwMTAuYXNweFwiXSc7XG5jb25zdCBhZnRlckxvZ2luU2VsZWN0b3IgPSAnI2Ryb3Bkb3duQmFzaWMnO1xuY29uc3QgbG9naW5TcGlubmVyU2VsZWN0b3IgPSAnZGl2Lm5neC1vdmVybGF5LmxvYWRpbmctZm9yZWdyb3VuZCc7XG5jb25zdCBhY2NvdW50RHJvcERvd25JdGVtU2VsZWN0b3IgPSAnI0FjY291bnRQaWNrZXIgLml0ZW0nO1xuY29uc3QgcGVuZGluZ1RyeElkZW50aWZpZXJJZCA9ICcjY3RsMDBfQ29udGVudFBsYWNlSG9sZGVyMl9wYW5lbDEnO1xuY29uc3QgY2hlY2tpbmdBY2NvdW50VGFiSGVicmV3TmFtZSA9ICfXoteV15HXqCDXldep15EnO1xuY29uc3QgY2hlY2tpbmdBY2NvdW50VGFiRW5nbGlzaE5hbWUgPSAnQ2hlY2tpbmcgQWNjb3VudCc7XG5jb25zdCBnZW5lcmljRGVzY3JpcHRpb25zID0gWyfXlNei15HXqNeqINeZ15XXntefINec15HXoNenINeW16gg157Xodeg15nXoyDXlteoJ107XG5cbmZ1bmN0aW9uIGNyZWF0ZUxvZ2luRmllbGRzKGNyZWRlbnRpYWxzOiBTY3JhcGVyU3BlY2lmaWNDcmVkZW50aWFscykge1xuICByZXR1cm4gW1xuICAgIHsgc2VsZWN0b3I6IHVzZXJuYW1lU2VsZWN0b3IsIHZhbHVlOiBjcmVkZW50aWFscy51c2VybmFtZSB9LFxuICAgIHsgc2VsZWN0b3I6IHBhc3N3b3JkU2VsZWN0b3IsIHZhbHVlOiBjcmVkZW50aWFscy5wYXNzd29yZCB9LFxuICBdO1xufVxuXG5hc3luYyBmdW5jdGlvbiBpc0xvZ2dlZEluKG9wdGlvbnM6IHsgcGFnZT86IFBhZ2UgfCB1bmRlZmluZWQgfSB8IHVuZGVmaW5lZCkge1xuICBpZiAoIW9wdGlvbnM/LnBhZ2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3Qgb3NoWFBhdGggPSBgLy9hLy9zcGFuW2NvbnRhaW5zKC4sIFwiJHtjaGVja2luZ0FjY291bnRUYWJIZWJyZXdOYW1lfVwiKSBvciBjb250YWlucyguLCBcIiR7Y2hlY2tpbmdBY2NvdW50VGFiRW5nbGlzaE5hbWV9XCIpXWA7XG4gIGNvbnN0IG9zaFRhYiA9IGF3YWl0IG9wdGlvbnMucGFnZS4kJChgeHBhdGgke29zaFhQYXRofWApO1xuICByZXR1cm4gb3NoVGFiLmxlbmd0aCA+IDA7XG59XG5cbmZ1bmN0aW9uIGdldFBvc3NpYmxlTG9naW5SZXN1bHRzKHBhZ2U6IFBhZ2UpOiBQb3NzaWJsZUxvZ2luUmVzdWx0cyB7XG4gIHJldHVybiB7XG4gICAgW0xvZ2luUmVzdWx0cy5TdWNjZXNzXTogW0FGVEVSX0xPR0lOX0JBU0VfVVJMLCBpc0xvZ2dlZEluXSxcbiAgICBbTG9naW5SZXN1bHRzLkludmFsaWRQYXNzd29yZF06IFthc3luYyAoKSA9PiAhIShhd2FpdCBwYWdlLiQoaW52YWxpZFBhc3N3b3JkU2VsZWN0b3IpKV0sXG4gICAgW0xvZ2luUmVzdWx0cy5DaGFuZ2VQYXNzd29yZF06IFtDSEFOR0VfUEFTU1dPUkRfVVJMXSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhcnRNb21lbnQob3B0aW9uc1N0YXJ0RGF0ZTogRGF0ZSkge1xuICBjb25zdCBkZWZhdWx0U3RhcnRNb21lbnQgPSBtb21lbnQoKS5zdWJ0cmFjdCgxLCAneWVhcnMnKTtcbiAgY29uc3Qgc3RhcnREYXRlID0gb3B0aW9uc1N0YXJ0RGF0ZSB8fCBkZWZhdWx0U3RhcnRNb21lbnQudG9EYXRlKCk7XG4gIHJldHVybiBtb21lbnQubWF4KGRlZmF1bHRTdGFydE1vbWVudCwgbW9tZW50KHN0YXJ0RGF0ZSkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRFeHRyYVRyYW5zYWN0aW9uRGV0YWlscyhcbiAgcGFnZTogUGFnZSxcbiAgaXRlbTogU2NyYXBlZFRyYW5zYWN0aW9uLFxuICBhcGlIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuKTogUHJvbWlzZTxNb3JlRGV0YWlscz4ge1xuICB0cnkge1xuICAgIGRlYnVnKCdnZXRFeHRyYVRyYW5zYWN0aW9uRGV0YWlscyBmb3IgaXRlbTonLCBpdGVtKTtcbiAgICBpZiAoaXRlbS5NQzAyU2hvd0RldGFpbHNFWiA9PT0gJzEnKSB7XG4gICAgICBjb25zdCB0YXJQZXVsYSA9IG1vbWVudChpdGVtLk1DMDJQZXVsYVRhYUVaKTtcbiAgICAgIGNvbnN0IHRhckVyZWNoID0gbW9tZW50KGl0ZW0uTUMwMkVyZWhUYWFFWik7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgaW5Lb2RHb3JlbTogaXRlbS5NQzAyS29kR29yZW1FWixcbiAgICAgICAgaW5Bc21hY2h0YTogaXRlbS5NQzAyQXNtYWh0YU1la29yaXRFWixcbiAgICAgICAgaW5TY2h1bTogaXRlbS5NQzAyU2NodW1FWixcbiAgICAgICAgaW5OYWt2YW5pdDogaXRlbS5NQzAyS29kR29yZW1FWixcbiAgICAgICAgaW5TdWdUbnVhOiBpdGVtLk1DMDJTdWdUbnVhS2FzcGl0RVosXG4gICAgICAgIGluQWdpZDogaXRlbS5NQzAyQWdpZEVaLFxuICAgICAgICBpblRhclBldWxhRm9ybWF0dGVkOiB0YXJQZXVsYS5mb3JtYXQoREFURV9GT1JNQVQpLFxuICAgICAgICBpblRhckVyZWNoRm9ybWF0dGVkOiAodGFyRXJlY2gueWVhcigpID4gMjAwMCA/IHRhckVyZWNoIDogdGFyUGV1bGEpLmZvcm1hdChEQVRFX0ZPUk1BVCksXG4gICAgICAgIGluS29kTm9zZTogaXRlbS5NQzAyU2VpZk1hcmFsRVosXG4gICAgICAgIGluS29kVGF0Tm9zZTogaXRlbS5NQzAyTm9zZU1hcmFsRVosXG4gICAgICAgIGluVHJhbnNhY3Rpb25OdW1iZXI6IGl0ZW0uVHJhbnNhY3Rpb25OdW1iZXIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoUG9zdFdpdGhpblBhZ2U8TW9yZURldGFpbHNSZXNwb25zZT4ocGFnZSwgTU9SRV9ERVRBSUxTX1VSTCwgcGFyYW1zLCBhcGlIZWFkZXJzKTtcbiAgICAgIGNvbnN0IGRldGFpbHMgPSByZXNwb25zZT8uYm9keS5maWVsZHM/LlswXT8uWzBdPy5SZWNvcmRzPy5bMF0uRmllbGRzO1xuICAgICAgZGVidWcoJ2ZldGNoIGRldGFpbHMgZm9yJywgcGFyYW1zLCAnZGV0YWlsczonLCBkZXRhaWxzKTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGRldGFpbHMpICYmIGRldGFpbHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBlbnRyaWVzID0gZGV0YWlscy5tYXAocmVjb3JkID0+IFtyZWNvcmQuTGFiZWwudHJpbSgpLCByZWNvcmQuVmFsdWUudHJpbSgpXSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZW50cmllczogT2JqZWN0LmZyb21FbnRyaWVzKGVudHJpZXMpLFxuICAgICAgICAgIG1lbW86IGVudHJpZXNcbiAgICAgICAgICAgIC5maWx0ZXIoKFtsYWJlbF0pID0+IFsn16nXnScsICfXnteU15XXqicsICfXl9ep15HXldefJ10uc29tZShrZXkgPT4gbGFiZWwuc3RhcnRzV2l0aChrZXkpKSlcbiAgICAgICAgICAgIC5tYXAoKFtsYWJlbCwgdmFsdWVdKSA9PiBgJHtsYWJlbH0gJHt2YWx1ZX1gKVxuICAgICAgICAgICAgLmpvaW4oJywgJyksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGRlYnVnKCdFcnJvciBmZXRjaGluZyBleHRyYSB0cmFuc2FjdGlvbiBkZXRhaWxzOicsIGVycm9yKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZW50cmllczoge30sXG4gICAgbWVtbzogdW5kZWZpbmVkLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVEYXRhRnJvbVJlcXVlc3QocmVxdWVzdDogSFRUUFJlcXVlc3QsIG9wdGlvbnNTdGFydERhdGU6IERhdGUpIHtcbiAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UocmVxdWVzdC5wb3N0RGF0YSgpIHx8ICd7fScpO1xuXG4gIGRhdGEuaW5Gcm9tRGF0ZSA9IGdldFN0YXJ0TW9tZW50KG9wdGlvbnNTdGFydERhdGUpLmZvcm1hdChEQVRFX0ZPUk1BVCk7XG4gIGRhdGEuaW5Ub0RhdGUgPSBtb21lbnQoKS5mb3JtYXQoREFURV9GT1JNQVQpO1xuICBkYXRhLnRhYmxlLm1heFJvdyA9IE1BWF9ST1dTX1BFUl9SRVFVRVNUO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVIZWFkZXJzRnJvbVJlcXVlc3QocmVxdWVzdDogSFRUUFJlcXVlc3QpIHtcbiAgcmV0dXJuIHtcbiAgICBtaXpyYWhpeHNyZnRva2VuOiByZXF1ZXN0LmhlYWRlcnMoKS5taXpyYWhpeHNyZnRva2VuLFxuICAgICdDb250ZW50LVR5cGUnOiByZXF1ZXN0LmhlYWRlcnMoKVsnY29udGVudC10eXBlJ10sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFRyYW5zYWN0aW9uSWRlbnRpZmllcihyb3c6IFNjcmFwZWRUcmFuc2FjdGlvbik6IHN0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGlmICghcm93Lk1DMDJBc21haHRhTWVrb3JpdEVaKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocm93LlRyYW5zYWN0aW9uTnVtYmVyICYmIFN0cmluZyhyb3cuVHJhbnNhY3Rpb25OdW1iZXIpICE9PSAnMScpIHtcbiAgICByZXR1cm4gYCR7cm93Lk1DMDJBc21haHRhTWVrb3JpdEVafS0ke3Jvdy5UcmFuc2FjdGlvbk51bWJlcn1gO1xuICB9XG4gIHJldHVybiBwYXJzZUludChyb3cuTUMwMkFzbWFodGFNZWtvcml0RVosIDEwKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY29udmVydFRyYW5zYWN0aW9ucyhcbiAgdHhuczogU2NyYXBlZFRyYW5zYWN0aW9uW10sXG4gIGdldE1vcmVEZXRhaWxzOiAocm93OiBTY3JhcGVkVHJhbnNhY3Rpb24pID0+IFByb21pc2U8TW9yZURldGFpbHM+LFxuICBwZW5kaW5nSWZUb2RheVRyYW5zYWN0aW9uOiBib29sZWFuID0gZmFsc2UsXG4gIG9wdGlvbnM/OiBTY3JhcGVyT3B0aW9ucyxcbik6IFByb21pc2U8VHJhbnNhY3Rpb25bXT4ge1xuICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgdHhucy5tYXAoYXN5bmMgcm93ID0+IHtcbiAgICAgIGNvbnN0IG1vcmVEZXRhaWxzID0gYXdhaXQgZ2V0TW9yZURldGFpbHMocm93KTtcblxuICAgICAgY29uc3QgdHhuRGF0ZSA9IG1vbWVudChyb3cuTUMwMlBldWxhVGFhRVosIG1vbWVudC5IVE1MNV9GTVQuREFURVRJTUVfTE9DQUxfU0VDT05EUykudG9JU09TdHJpbmcoKTtcblxuICAgICAgY29uc3QgcmVzdWx0OiBUcmFuc2FjdGlvbiA9IHtcbiAgICAgICAgdHlwZTogVHJhbnNhY3Rpb25UeXBlcy5Ob3JtYWwsXG4gICAgICAgIGlkZW50aWZpZXI6IGdldFRyYW5zYWN0aW9uSWRlbnRpZmllcihyb3cpLFxuICAgICAgICBkYXRlOiB0eG5EYXRlLFxuICAgICAgICBwcm9jZXNzZWREYXRlOiB0eG5EYXRlLFxuICAgICAgICBvcmlnaW5hbEFtb3VudDogcm93Lk1DMDJTY2h1bUVaLFxuICAgICAgICBvcmlnaW5hbEN1cnJlbmN5OiBTSEVLRUxfQ1VSUkVOQ1ksXG4gICAgICAgIGNoYXJnZWRBbW91bnQ6IHJvdy5NQzAyU2NodW1FWixcbiAgICAgICAgZGVzY3JpcHRpb246IHJvdy5NQzAyVG51YVRldXJFWixcbiAgICAgICAgbWVtbzogbW9yZURldGFpbHM/Lm1lbW8sXG4gICAgICAgIHN0YXR1czpcbiAgICAgICAgICBwZW5kaW5nSWZUb2RheVRyYW5zYWN0aW9uICYmIHJvdy5Jc1RvZGF5VHJhbnNhY3Rpb25cbiAgICAgICAgICAgID8gVHJhbnNhY3Rpb25TdGF0dXNlcy5QZW5kaW5nXG4gICAgICAgICAgICA6IFRyYW5zYWN0aW9uU3RhdHVzZXMuQ29tcGxldGVkLFxuICAgICAgfTtcblxuICAgICAgaWYgKG9wdGlvbnM/LmluY2x1ZGVSYXdUcmFuc2FjdGlvbikge1xuICAgICAgICByZXN1bHQucmF3VHJhbnNhY3Rpb24gPSBnZXRSYXdUcmFuc2FjdGlvbih7XG4gICAgICAgICAgLi4ucm93LFxuICAgICAgICAgIGFkZGl0aW9uYWxJbmZvcm1hdGlvbjogbW9yZURldGFpbHMuZW50cmllcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSksXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RQZW5kaW5nVHJhbnNhY3Rpb25zKHBhZ2U6IEZyYW1lKTogUHJvbWlzZTxUcmFuc2FjdGlvbltdPiB7XG4gIGNvbnN0IHBlbmRpbmdUeG4gPSBhd2FpdCBwYWdlRXZhbEFsbChwYWdlLCAndHIucmdSb3csIHRyLnJnQWx0Um93JywgW10sIHRycyA9PiB7XG4gICAgcmV0dXJuIHRycy5tYXAodHIgPT4gQXJyYXkuZnJvbSh0ci5xdWVyeVNlbGVjdG9yQWxsKCd0ZCcpLCB0ZCA9PiB0ZC50ZXh0Q29udGVudCB8fCAnJykpO1xuICB9KTtcblxuICByZXR1cm4gcGVuZGluZ1R4blxuICAgIC5tYXAoKFtkYXRlU3RyLCBkZXNjcmlwdGlvbiwgaW5jb21lQW1vdW50U3RyLCBhbW91bnRTdHJdKSA9PiAoe1xuICAgICAgZGF0ZTogbW9tZW50KGRhdGVTdHIsICdERC9NTS9ZWScpLnRvSVNPU3RyaW5nKCksXG4gICAgICBhbW91bnQ6IHBhcnNlRmxvYXQoYW1vdW50U3RyLnJlcGxhY2VBbGwoJywnLCAnJykpLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBpbmNvbWVBbW91bnRTdHIsIC8vIFRPRE86IGhhbmRsZSBpbmNvbWVBbW91bnRTdHIgb25jZSB3ZSBrbm93IHRoZSBzaWduIG9mIGl0XG4gICAgfSkpXG4gICAgLmZpbHRlcih0eG4gPT4gdHhuLmRhdGUpXG4gICAgLm1hcCgoeyBkYXRlLCBkZXNjcmlwdGlvbiwgYW1vdW50IH0pID0+ICh7XG4gICAgICB0eXBlOiBUcmFuc2FjdGlvblR5cGVzLk5vcm1hbCxcbiAgICAgIGRhdGUsXG4gICAgICBwcm9jZXNzZWREYXRlOiBkYXRlLFxuICAgICAgb3JpZ2luYWxBbW91bnQ6IGFtb3VudCxcbiAgICAgIG9yaWdpbmFsQ3VycmVuY3k6IFNIRUtFTF9DVVJSRU5DWSxcbiAgICAgIGNoYXJnZWRBbW91bnQ6IGFtb3VudCxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1c2VzLlBlbmRpbmcsXG4gICAgfSkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwb3N0TG9naW4ocGFnZTogUGFnZSkge1xuICBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgIHdhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCBhZnRlckxvZ2luU2VsZWN0b3IpLFxuICAgIHdhaXRVbnRpbEVsZW1lbnRGb3VuZChwYWdlLCBpbnZhbGlkUGFzc3dvcmRTZWxlY3RvciksXG4gICAgd2FpdEZvclVybChwYWdlLCBDSEFOR0VfUEFTU1dPUkRfVVJMKSxcbiAgXSk7XG59XG5cbnR5cGUgU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMgPSB7IHVzZXJuYW1lOiBzdHJpbmc7IHBhc3N3b3JkOiBzdHJpbmcgfTtcblxuY2xhc3MgTWl6cmFoaVNjcmFwZXIgZXh0ZW5kcyBCYXNlU2NyYXBlcldpdGhCcm93c2VyPFNjcmFwZXJTcGVjaWZpY0NyZWRlbnRpYWxzPiB7XG4gIGdldExvZ2luT3B0aW9ucyhjcmVkZW50aWFsczogU2NyYXBlclNwZWNpZmljQ3JlZGVudGlhbHMpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9naW5Vcmw6IExPR0lOX1VSTCxcbiAgICAgIGZpZWxkczogY3JlYXRlTG9naW5GaWVsZHMoY3JlZGVudGlhbHMpLFxuICAgICAgc3VibWl0QnV0dG9uU2VsZWN0b3IsXG4gICAgICBjaGVja1JlYWRpbmVzczogYXN5bmMgKCkgPT4gd2FpdFVudGlsRWxlbWVudERpc2FwcGVhcih0aGlzLnBhZ2UsIGxvZ2luU3Bpbm5lclNlbGVjdG9yKSxcbiAgICAgIHBvc3RBY3Rpb246IGFzeW5jICgpID0+IHBvc3RMb2dpbih0aGlzLnBhZ2UpLFxuICAgICAgcG9zc2libGVSZXN1bHRzOiBnZXRQb3NzaWJsZUxvZ2luUmVzdWx0cyh0aGlzLnBhZ2UpLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBmZXRjaERhdGEoKSB7XG4gICAgYXdhaXQgdGhpcy5wYWdlLiRldmFsKCcjZHJvcGRvd25CYXNpYywgLml0ZW0nLCBlbCA9PiAoZWwgYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCkpO1xuXG4gICAgY29uc3QgbnVtT2ZBY2NvdW50cyA9IChhd2FpdCB0aGlzLnBhZ2UuJCQoYWNjb3VudERyb3BEb3duSXRlbVNlbGVjdG9yKSkubGVuZ3RoO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdHM6IFRyYW5zYWN0aW9uc0FjY291bnRbXSA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bU9mQWNjb3VudHM7IGkgKz0gMSkge1xuICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnBhZ2UuJGV2YWwoJyNkcm9wZG93bkJhc2ljLCAuaXRlbScsIGVsID0+IChlbCBhcyBIVE1MRWxlbWVudCkuY2xpY2soKSk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLnBhZ2UuJGV2YWwoYCR7YWNjb3VudERyb3BEb3duSXRlbVNlbGVjdG9yfTpudGgtY2hpbGQoJHtpICsgMX0pYCwgZWwgPT4gKGVsIGFzIEhUTUxFbGVtZW50KS5jbGljaygpKTtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGF3YWl0IHRoaXMuZmV0Y2hBY2NvdW50KCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICBhY2NvdW50czogcmVzdWx0cyxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIGVycm9yVHlwZTogU2NyYXBlckVycm9yVHlwZXMuR2VuZXJpYyxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiAoZSBhcyBFcnJvcikubWVzc2FnZSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRQZW5kaW5nVHJhbnNhY3Rpb25zKCk6IFByb21pc2U8VHJhbnNhY3Rpb25bXT4ge1xuICAgIGF3YWl0IHRoaXMucGFnZS4kZXZhbChgYVtocmVmKj1cIiR7UEVORElOR19UUkFOU0FDVElPTlNfUEFHRX1cIl1gLCBlbCA9PiAoZWwgYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCkpO1xuICAgIGNvbnN0IGZyYW1lID0gYXdhaXQgd2FpdFVudGlsSWZyYW1lRm91bmQodGhpcy5wYWdlLCBmID0+IGYudXJsKCkuaW5jbHVkZXMoUEVORElOR19UUkFOU0FDVElPTlNfSUZSQU1FKSk7XG4gICAgY29uc3QgaXNQZW5kaW5nID0gYXdhaXQgd2FpdFVudGlsRWxlbWVudEZvdW5kKGZyYW1lLCBwZW5kaW5nVHJ4SWRlbnRpZmllcklkKVxuICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgIC5jYXRjaCgoKSA9PiBmYWxzZSk7XG4gICAgaWYgKCFpc1BlbmRpbmcpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBwZW5kaW5nVHhuID0gYXdhaXQgZXh0cmFjdFBlbmRpbmdUcmFuc2FjdGlvbnMoZnJhbWUpO1xuICAgIHJldHVybiBwZW5kaW5nVHhuO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaEFjY291bnQoKSB7XG4gICAgYXdhaXQgdGhpcy5wYWdlLndhaXRGb3JTZWxlY3RvcihgYVtocmVmKj1cIiR7T1NIX1BBR0V9XCJdYCk7XG4gICAgYXdhaXQgdGhpcy5wYWdlLiRldmFsKGBhW2hyZWYqPVwiJHtPU0hfUEFHRX1cIl1gLCBlbCA9PiAoZWwgYXMgSFRNTEVsZW1lbnQpLmNsaWNrKCkpO1xuICAgIGF3YWl0IHdhaXRVbnRpbEVsZW1lbnRGb3VuZCh0aGlzLnBhZ2UsIGBhW2hyZWYqPVwiJHtUUkFOU0FDVElPTlNfUEFHRX1cIl1gKTtcbiAgICBhd2FpdCB0aGlzLnBhZ2UuJGV2YWwoYGFbaHJlZio9XCIke1RSQU5TQUNUSU9OU19QQUdFfVwiXWAsIGVsID0+IChlbCBhcyBIVE1MRWxlbWVudCkuY2xpY2soKSk7XG5cbiAgICBjb25zdCBhY2NvdW50TnVtYmVyRWxlbWVudCA9IGF3YWl0IHRoaXMucGFnZS4kKCcjZHJvcGRvd25CYXNpYyBiIHNwYW4nKTtcbiAgICBjb25zdCBhY2NvdW50TnVtYmVySGFuZGxlID0gYXdhaXQgYWNjb3VudE51bWJlckVsZW1lbnQ/LmdldFByb3BlcnR5KCd0aXRsZScpO1xuICAgIGNvbnN0IGFjY291bnROdW1iZXIgPSAoYXdhaXQgYWNjb3VudE51bWJlckhhbmRsZT8uanNvblZhbHVlKCkpIGFzIHN0cmluZztcbiAgICBpZiAoIWFjY291bnROdW1iZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQWNjb3VudCBudW1iZXIgbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3QgW3Jlc3BvbnNlLCBhcGlIZWFkZXJzXSA9IGF3YWl0IFByb21pc2UuYW55KFxuICAgICAgVFJBTlNBQ1RJT05TX1JFUVVFU1RfVVJMUy5tYXAoYXN5bmMgdXJsID0+IHtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IGF3YWl0IHRoaXMucGFnZS53YWl0Rm9yUmVxdWVzdCh1cmwpO1xuICAgICAgICBjb25zdCBkYXRhID0gY3JlYXRlRGF0YUZyb21SZXF1ZXN0KHJlcXVlc3QsIHRoaXMub3B0aW9ucy5zdGFydERhdGUpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gY3JlYXRlSGVhZGVyc0Zyb21SZXF1ZXN0KHJlcXVlc3QpO1xuXG4gICAgICAgIHJldHVybiBbYXdhaXQgZmV0Y2hQb3N0V2l0aGluUGFnZTxTY3JhcGVkVHJhbnNhY3Rpb25zUmVzdWx0Pih0aGlzLnBhZ2UsIHVybCwgZGF0YSwgaGVhZGVycyksIGhlYWRlcnNdIGFzIGNvbnN0O1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGlmICghcmVzcG9uc2UgfHwgcmVzcG9uc2UuaGVhZGVyLnN1Y2Nlc3MgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFcnJvciBmZXRjaGluZyB0cmFuc2FjdGlvbi4gUmVzcG9uc2UgbWVzc2FnZTogJHtyZXNwb25zZSA/IHJlc3BvbnNlLmhlYWRlci5tZXNzYWdlc1swXS50ZXh0IDogJyd9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVsZXZhbnRSb3dzID0gcmVzcG9uc2UuYm9keS50YWJsZS5yb3dzLmZpbHRlcihyb3cgPT4gcm93LlJlY1R5cGVTcGVjaWZpZWQpO1xuICAgIGNvbnN0IG9zaFR4biA9IGF3YWl0IGNvbnZlcnRUcmFuc2FjdGlvbnMoXG4gICAgICByZWxldmFudFJvd3MsXG4gICAgICB0aGlzLm9wdGlvbnMuYWRkaXRpb25hbFRyYW5zYWN0aW9uSW5mb3JtYXRpb25cbiAgICAgICAgPyByb3cgPT4gZ2V0RXh0cmFUcmFuc2FjdGlvbkRldGFpbHModGhpcy5wYWdlLCByb3csIGFwaUhlYWRlcnMpXG4gICAgICAgIDogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgZW50cmllczoge30sIG1lbW86IHVuZGVmaW5lZCB9KSxcbiAgICAgIHRoaXMub3B0aW9ucy5vcHRJbkZlYXR1cmVzPy5pbmNsdWRlcygnbWl6cmFoaTpwZW5kaW5nSWZUb2RheVRyYW5zYWN0aW9uJyksXG4gICAgICB0aGlzLm9wdGlvbnMsXG4gICAgKTtcblxuICAgIG9zaFR4blxuICAgICAgLmZpbHRlcih0eG4gPT4gdGhpcy5zaG91bGRNYXJrQXNQZW5kaW5nKHR4bikpXG4gICAgICAuZm9yRWFjaCh0eG4gPT4ge1xuICAgICAgICB0eG4uc3RhdHVzID0gVHJhbnNhY3Rpb25TdGF0dXNlcy5QZW5kaW5nO1xuICAgICAgfSk7XG5cbiAgICAvLyB3b3JrYXJvdW5kIGZvciBhIGJ1ZyB3aGljaCB0aGUgYmFuaydzIEFQSSByZXR1cm5zIHRyYW5zYWN0aW9ucyBiZWZvcmUgdGhlIHJlcXVlc3RlZCBzdGFydCBkYXRlXG4gICAgY29uc3Qgc3RhcnRNb21lbnQgPSBnZXRTdGFydE1vbWVudCh0aGlzLm9wdGlvbnMuc3RhcnREYXRlKTtcbiAgICBjb25zdCBvc2hUeG5BZnRlclN0YXJ0RGF0ZSA9IG9zaFR4bi5maWx0ZXIodHhuID0+IG1vbWVudCh0eG4uZGF0ZSkuaXNTYW1lT3JBZnRlcihzdGFydE1vbWVudCkpO1xuXG4gICAgY29uc3QgcGVuZGluZ1R4biA9IGF3YWl0IHRoaXMuZ2V0UGVuZGluZ1RyYW5zYWN0aW9ucygpO1xuICAgIGNvbnN0IGFsbFR4biA9IG9zaFR4bkFmdGVyU3RhcnREYXRlLmNvbmNhdChwZW5kaW5nVHhuKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2NvdW50TnVtYmVyLFxuICAgICAgdHhuczogYWxsVHhuLFxuICAgICAgYmFsYW5jZTogK3Jlc3BvbnNlLmJvZHkuZmllbGRzPy5ZaXRyYSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzaG91bGRNYXJrQXNQZW5kaW5nKHR4bjogVHJhbnNhY3Rpb24pOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5vcHRpb25zLm9wdEluRmVhdHVyZXM/LmluY2x1ZGVzKCdtaXpyYWhpOnBlbmRpbmdJZk5vSWRlbnRpZmllcicpICYmICF0eG4uaWRlbnRpZmllcikge1xuICAgICAgZGVidWcoYE1hcmtpbmcgdHJhbnNhY3Rpb24gJyR7dHhuLmRlc2NyaXB0aW9ufScgYXMgcGVuZGluZyBkdWUgdG8gbm8gaWRlbnRpZmllci5gKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMub3B0aW9ucy5vcHRJbkZlYXR1cmVzPy5pbmNsdWRlcygnbWl6cmFoaTpwZW5kaW5nSWZIYXNHZW5lcmljRGVzY3JpcHRpb24nKSAmJlxuICAgICAgZ2VuZXJpY0Rlc2NyaXB0aW9ucy5pbmNsdWRlcyh0eG4uZGVzY3JpcHRpb24pXG4gICAgKSB7XG4gICAgICBkZWJ1ZyhgTWFya2luZyB0cmFuc2FjdGlvbiAnJHt0eG4uZGVzY3JpcHRpb259JyBhcyBwZW5kaW5nIGR1ZSB0byBnZW5lcmljIGRlc2NyaXB0aW9uLmApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1penJhaGlTY3JhcGVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxJQUFBQSxPQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBQyxVQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxxQkFBQSxHQUFBRixPQUFBO0FBTUEsSUFBQUcsTUFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksV0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssYUFBQSxHQUFBTCxPQUFBO0FBQ0Es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