UNPKG

emailjs-imap-client

Version:
233 lines (202 loc) 22.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildFETCHCommand = buildFETCHCommand; exports.buildXOAuth2Token = buildXOAuth2Token; exports.buildSEARCHCommand = buildSEARCHCommand; exports.buildSTORECommand = buildSTORECommand; var _emailjsImapHandler = require("emailjs-imap-handler"); var _emailjsMimeCodec = require("emailjs-mime-codec"); var _emailjsBase = require("emailjs-base64"); var _common = require("./common"); function buildFETCHCommand(sequence, items, options) { const command = { command: options.byUid ? 'UID FETCH' : 'FETCH', attributes: [{ type: 'SEQUENCE', value: sequence }] }; if (options.valueAsString !== undefined) { command.valueAsString = options.valueAsString; } let query = []; items.forEach(item => { item = item.toUpperCase().trim(); if (/^\w+$/.test(item)) { // alphanum strings can be used directly query.push({ type: 'ATOM', value: item }); } else if (item) { try { // parse the value as a fake command, use only the attributes block const cmd = (0, _emailjsImapHandler.parser)((0, _common.toTypedArray)('* Z ' + item)); query = query.concat(cmd.attributes || []); } catch (e) { // if parse failed, use the original string as one entity query.push({ type: 'ATOM', value: item }); } } }); if (query.length === 1) { query = query.pop(); } command.attributes.push(query); if (options.changedSince) { command.attributes.push([{ type: 'ATOM', value: 'CHANGEDSINCE' }, { type: 'ATOM', value: options.changedSince }]); } return command; } /** * Builds a login token for XOAUTH2 authentication command * * @param {String} user E-mail address of the user * @param {String} token Valid access token for the user * @return {String} Base64 formatted login token */ function buildXOAuth2Token(user = '', token) { const authData = [`user=${user}`, `auth=Bearer ${token}`, '', '']; return (0, _emailjsBase.encode)(authData.join('\x01')); } /** * Compiles a search query into an IMAP command. Queries are composed as objects * where keys are search terms and values are term arguments. Only strings, * numbers and Dates are used. If the value is an array, the members of it * are processed separately (use this for terms that require multiple params). * If the value is a Date, it is converted to the form of "01-Jan-1970". * Subqueries (OR, NOT) are made up of objects * * {unseen: true, header: ["subject", "hello world"]}; * SEARCH UNSEEN HEADER "subject" "hello world" * * @param {Object} query Search query * @param {Object} [options] Option object * @param {Boolean} [options.byUid] If ture, use UID SEARCH instead of SEARCH * @return {Object} IMAP command object */ function buildSEARCHCommand(query = {}, options = {}) { const command = { command: options.byUid ? 'UID SEARCH' : 'SEARCH' }; let isAscii = true; const buildTerm = query => { let list = []; Object.keys(query).forEach(key => { let params = []; const formatDate = date => date.toUTCString().replace(/^\w+, 0?(\d+) (\w+) (\d+).*/, '$1-$2-$3'); const escapeParam = param => { if (typeof param === 'number') { return { type: 'number', value: param }; } else if (typeof param === 'string') { if (/[\u0080-\uFFFF]/.test(param)) { isAscii = false; return { type: 'literal', value: (0, _common.fromTypedArray)((0, _emailjsMimeCodec.encode)(param)) // cast unicode string to pseudo-binary as imap-handler compiles strings as octets }; } return { type: 'string', value: param }; } else if (Object.prototype.toString.call(param) === '[object Date]') { // RFC 3501 allows for dates to be placed in // double-quotes or left without quotes. Some // servers (Yandex), do not like the double quotes, // so we treat the date as an atom. return { type: 'atom', value: formatDate(param) }; } else if (Array.isArray(param)) { return param.map(escapeParam); } else if (typeof param === 'object') { return buildTerm(param); } }; params.push({ type: 'atom', value: key.toUpperCase() }); [].concat(query[key] || []).forEach(param => { switch (key.toLowerCase()) { case 'uid': param = { type: 'sequence', value: param }; break; // The Gmail extension values of X-GM-THRID and // X-GM-MSGID are defined to be unsigned 64-bit integers // and they must not be quoted strings or the server // will report a parse error. case 'x-gm-thrid': case 'x-gm-msgid': param = { type: 'number', value: param }; break; default: param = escapeParam(param); } if (param) { params = params.concat(param || []); } }); list = list.concat(params || []); }); return list; }; command.attributes = buildTerm(query); // If any string input is using 8bit bytes, prepend the optional CHARSET argument if (!isAscii) { command.attributes.unshift({ type: 'atom', value: 'UTF-8' }); command.attributes.unshift({ type: 'atom', value: 'CHARSET' }); } return command; } /** * Creates an IMAP STORE command from the selected arguments */ function buildSTORECommand(sequence, action = '', flags = [], options = {}) { const command = { command: options.byUid ? 'UID STORE' : 'STORE', attributes: [{ type: 'sequence', value: sequence }] }; command.attributes.push({ type: 'atom', value: action.toUpperCase() + (options.silent ? '.SILENT' : '') }); command.attributes.push(flags.map(flag => { return { type: 'atom', value: flag }; })); return command; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLWJ1aWxkZXIuanMiXSwibmFtZXMiOlsiYnVpbGRGRVRDSENvbW1hbmQiLCJzZXF1ZW5jZSIsIml0ZW1zIiwib3B0aW9ucyIsImNvbW1hbmQiLCJieVVpZCIsImF0dHJpYnV0ZXMiLCJ0eXBlIiwidmFsdWUiLCJ2YWx1ZUFzU3RyaW5nIiwidW5kZWZpbmVkIiwicXVlcnkiLCJmb3JFYWNoIiwiaXRlbSIsInRvVXBwZXJDYXNlIiwidHJpbSIsInRlc3QiLCJwdXNoIiwiY21kIiwiY29uY2F0IiwiZSIsImxlbmd0aCIsInBvcCIsImNoYW5nZWRTaW5jZSIsImJ1aWxkWE9BdXRoMlRva2VuIiwidXNlciIsInRva2VuIiwiYXV0aERhdGEiLCJqb2luIiwiYnVpbGRTRUFSQ0hDb21tYW5kIiwiaXNBc2NpaSIsImJ1aWxkVGVybSIsImxpc3QiLCJPYmplY3QiLCJrZXlzIiwia2V5IiwicGFyYW1zIiwiZm9ybWF0RGF0ZSIsImRhdGUiLCJ0b1VUQ1N0cmluZyIsInJlcGxhY2UiLCJlc2NhcGVQYXJhbSIsInBhcmFtIiwicHJvdG90eXBlIiwidG9TdHJpbmciLCJjYWxsIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwidG9Mb3dlckNhc2UiLCJ1bnNoaWZ0IiwiYnVpbGRTVE9SRUNvbW1hbmQiLCJhY3Rpb24iLCJmbGFncyIsInNpbGVudCIsImZsYWciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFhTyxTQUFTQSxpQkFBVCxDQUE0QkMsUUFBNUIsRUFBc0NDLEtBQXRDLEVBQTZDQyxPQUE3QyxFQUFzRDtBQUMzRCxRQUFNQyxPQUFPLEdBQUc7QUFDZEEsSUFBQUEsT0FBTyxFQUFFRCxPQUFPLENBQUNFLEtBQVIsR0FBZ0IsV0FBaEIsR0FBOEIsT0FEekI7QUFFZEMsSUFBQUEsVUFBVSxFQUFFLENBQUM7QUFDWEMsTUFBQUEsSUFBSSxFQUFFLFVBREs7QUFFWEMsTUFBQUEsS0FBSyxFQUFFUDtBQUZJ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b3J0IHsgcGFyc2VyIH0gZnJvbSAnZW1haWxqcy1pbWFwLWhhbmRsZXInXG5pbXBvcnQgeyBlbmNvZGUgfSBmcm9tICdlbWFpbGpzLW1pbWUtY29kZWMnXG5pbXBvcnQgeyBlbmNvZGUgYXMgZW5jb2RlQmFzZTY0IH0gZnJvbSAnZW1haWxqcy1iYXNlNjQnXG5pbXBvcnQge1xuICBmcm9tVHlwZWRBcnJheSxcbiAgdG9UeXBlZEFycmF5XG59IGZyb20gJy4vY29tbW9uJ1xuXG4vKipcbiAqIEJ1aWxkcyBhIEZFVENIIGNvbW1hbmRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VxdWVuY2UgTWVzc2FnZSByYW5nZSBzZWxlY3RvclxuICogQHBhcmFtIHtBcnJheX0gaXRlbXMgTGlzdCBvZiBlbGVtZW50cyB0byBmZXRjaCAoZWcuIGBbJ3VpZCcsICdlbnZlbG9wZSddYCkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0LiBVc2UgYHtieVVpZDp0cnVlfWAgZm9yIGBVSUQgRkVUQ0hgXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBTdHJ1Y3R1cmVkIElNQVAgY29tbWFuZFxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRGRVRDSENvbW1hbmQgKHNlcXVlbmNlLCBpdGVtcywgb3B0aW9ucykge1xuICBjb25zdCBjb21tYW5kID0ge1xuICAgIGNvbW1hbmQ6IG9wdGlvbnMuYnlVaWQgPyAnVUlEIEZFVENIJyA6ICdGRVRDSCcsXG4gICAgYXR0cmlidXRlczogW3tcbiAgICAgIHR5cGU6ICdTRVFVRU5DRScsXG4gICAgICB2YWx1ZTogc2VxdWVuY2VcbiAgICB9XVxuICB9XG5cbiAgaWYgKG9wdGlvbnMudmFsdWVBc1N0cmluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29tbWFuZC52YWx1ZUFzU3RyaW5nID0gb3B0aW9ucy52YWx1ZUFzU3RyaW5nXG4gIH1cblxuICBsZXQgcXVlcnkgPSBbXVxuXG4gIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICBpdGVtID0gaXRlbS50b1VwcGVyQ2FzZSgpLnRyaW0oKVxuXG4gICAgaWYgKC9eXFx3KyQvLnRlc3QoaXRlbSkpIHtcbiAgICAgIC8vIGFscGhhbnVtIHN0cmluZ3MgY2FuIGJlIHVzZWQgZGlyZWN0bHlcbiAgICAgIHF1ZXJ5LnB1c2goe1xuICAgICAgICB0eXBlOiAnQVRPTScsXG4gICAgICAgIHZhbHVlOiBpdGVtXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAoaXRlbSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gcGFyc2UgdGhlIHZhbHVlIGFzIGEgZmFrZSBjb21tYW5kLCB1c2Ugb25seSB0aGUgYXR0cmlidXRlcyBibG9ja1xuICAgICAgICBjb25zdCBjbWQgPSBwYXJzZXIodG9UeXBlZEFycmF5KCcqIFogJyArIGl0ZW0pKVxuICAgICAgICBxdWVyeSA9IHF1ZXJ5LmNvbmNhdChjbWQuYXR0cmlidXRlcyB8fCBbXSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaWYgcGFyc2UgZmFpbGVkLCB1c2UgdGhlIG9yaWdpbmFsIHN0cmluZyBhcyBvbmUgZW50aXR5XG4gICAgICAgIHF1ZXJ5LnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdBVE9NJyxcbiAgICAgICAgICB2YWx1ZTogaXRlbVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgfSlcblxuICBpZiAocXVlcnkubGVuZ3RoID09PSAxKSB7XG4gICAgcXVlcnkgPSBxdWVyeS5wb3AoKVxuICB9XG5cbiAgY29tbWFuZC5hdHRyaWJ1dGVzLnB1c2gocXVlcnkpXG5cbiAgaWYgKG9wdGlvbnMuY2hhbmdlZFNpbmNlKSB7XG4gICAgY29tbWFuZC5hdHRyaWJ1dGVzLnB1c2goW3tcbiAgICAgIHR5cGU6ICdBVE9NJyxcbiAgICAgIHZhbHVlOiAnQ0hBTkdFRFNJTkNFJ1xuICAgIH0sIHtcbiAgICAgIHR5cGU6ICdBVE9NJyxcbiAgICAgIHZhbHVlOiBvcHRpb25zLmNoYW5nZWRTaW5jZVxuICAgIH1dKVxuICB9XG5cbiAgcmV0dXJuIGNvbW1hbmRcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBsb2dpbiB0b2tlbiBmb3IgWE9BVVRIMiBhdXRoZW50aWNhdGlvbiBjb21tYW5kXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVzZXIgRS1tYWlsIGFkZHJlc3Mgb2YgdGhlIHVzZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSB0b2tlbiBWYWxpZCBhY2Nlc3MgdG9rZW4gZm9yIHRoZSB1c2VyXG4gKiBAcmV0dXJuIHtTdHJpbmd9IEJhc2U2NCBmb3JtYXR0ZWQgbG9naW4gdG9rZW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkWE9BdXRoMlRva2VuICh1c2VyID0gJycsIHRva2VuKSB7XG4gIGNvbnN0IGF1dGhEYXRhID0gW1xuICAgIGB1c2VyPSR7dXNlcn1gLFxuICAgIGBhdXRoPUJlYXJlciAke3Rva2VufWAsXG4gICAgJycsXG4gICAgJydcbiAgXVxuICByZXR1cm4gZW5jb2RlQmFzZTY0KGF1dGhEYXRhLmpvaW4oJ1xceDAxJykpXG59XG5cbi8qKlxuICogQ29tcGlsZXMgYSBzZWFyY2ggcXVlcnkgaW50byBhbiBJTUFQIGNvbW1hbmQuIFF1ZXJpZXMgYXJlIGNvbXBvc2VkIGFzIG9iamVjdHNcbiAqIHdoZXJlIGtleXMgYXJlIHNlYXJjaCB0ZXJtcyBhbmQgdmFsdWVzIGFyZSB0ZXJtIGFyZ3VtZW50cy4gT25seSBzdHJpbmdzLFxuICogbnVtYmVycyBhbmQgRGF0ZXMgYXJlIHVzZWQuIElmIHRoZSB2YWx1ZSBpcyBhbiBhcnJheSwgdGhlIG1lbWJlcnMgb2YgaXRcbiAqIGFyZSBwcm9jZXNzZWQgc2VwYXJhdGVseSAodXNlIHRoaXMgZm9yIHRlcm1zIHRoYXQgcmVxdWlyZSBtdWx0aXBsZSBwYXJhbXMpLlxuICogSWYgdGhlIHZhbHVlIGlzIGEgRGF0ZSwgaXQgaXMgY29udmVydGVkIHRvIHRoZSBmb3JtIG9mIFwiMDEtSmFuLTE5NzBcIi5cbiAqIFN1YnF1ZXJpZXMgKE9SLCBOT1QpIGFyZSBtYWRlIHVwIG9mIG9iamVjdHNcbiAqXG4gKiAgICB7dW5zZWVuOiB0cnVlLCBoZWFkZXI6IFtcInN1YmplY3RcIiwgXCJoZWxsbyB3b3JsZFwiXX07XG4gKiAgICBTRUFSQ0ggVU5TRUVOIEhFQURFUiBcInN1YmplY3RcIiBcImhlbGxvIHdvcmxkXCJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcXVlcnkgU2VhcmNoIHF1ZXJ5XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIE9wdGlvbiBvYmplY3RcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuYnlVaWRdIElmIHR1cmUsIHVzZSBVSUQgU0VBUkNIIGluc3RlYWQgb2YgU0VBUkNIXG4gKiBAcmV0dXJuIHtPYmplY3R9IElNQVAgY29tbWFuZCBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU0VBUkNIQ29tbWFuZCAocXVlcnkgPSB7fSwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IGNvbW1hbmQgPSB7XG4gICAgY29tbWFuZDogb3B0aW9ucy5ieVVpZCA/ICdVSUQgU0VBUkNIJyA6ICdTRUFSQ0gnXG4gIH1cblxuICBsZXQgaXNBc2NpaSA9IHRydWVcblxuICBjb25zdCBidWlsZFRlcm0gPSAocXVlcnkpID0+IHtcbiAgICBsZXQgbGlzdCA9IFtdXG5cbiAgICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICBsZXQgcGFyYW1zID0gW11cbiAgICAgIGNvbnN0IGZvcm1hdERhdGUgPSAoZGF0ZSkgPT4gZGF0ZS50b1VUQ1N0cmluZygpLnJlcGxhY2UoL15cXHcrLCAwPyhcXGQrKSAoXFx3KykgKFxcZCspLiovLCAnJDEtJDItJDMnKVxuICAgICAgY29uc3QgZXNjYXBlUGFyYW0gPSAocGFyYW0pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJhbSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICB2YWx1ZTogcGFyYW1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGlmICgvW1xcdTAwODAtXFx1RkZGRl0vLnRlc3QocGFyYW0pKSB7XG4gICAgICAgICAgICBpc0FzY2lpID0gZmFsc2VcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGU6ICdsaXRlcmFsJyxcbiAgICAgICAgICAgICAgdmFsdWU6IGZyb21UeXBlZEFycmF5KGVuY29kZShwYXJhbSkpIC8vIGNhc3QgdW5pY29kZSBzdHJpbmcgdG8gcHNldWRvLWJpbmFyeSBhcyBpbWFwLWhhbmRsZXIgY29tcGlsZXMgc3RyaW5ncyBhcyBvY3RldHNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgdmFsdWU6IHBhcmFtXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwYXJhbSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgICAgICAgIC8vIFJGQyAzNTAxIGFsbG93cyBmb3IgZGF0ZXMgdG8gYmUgcGxhY2VkIGluXG4gICAgICAgICAgLy8gZG91YmxlLXF1b3RlcyBvciBsZWZ0IHdpdGhvdXQgcXVvdGVzLiAgU29tZVxuICAgICAgICAgIC8vIHNlcnZlcnMgKFlhbmRleCksIGRvIG5vdCBsaWtlIHRoZSBkb3VibGUgcXVvdGVzLFxuICAgICAgICAgIC8vIHNvIHdlIHRyZWF0IHRoZSBkYXRlIGFzIGFuIGF0b20uXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdhdG9tJyxcbiAgICAgICAgICAgIHZhbHVlOiBmb3JtYXREYXRlKHBhcmFtKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHBhcmFtKSkge1xuICAgICAgICAgIHJldHVybiBwYXJhbS5tYXAoZXNjYXBlUGFyYW0pXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcmFtID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiBidWlsZFRlcm0ocGFyYW0pXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcGFyYW1zLnB1c2goe1xuICAgICAgICB0eXBlOiAnYXRvbScsXG4gICAgICAgIHZhbHVlOiBrZXkudG9VcHBlckNhc2UoKVxuICAgICAgfSk7XG5cbiAgICAgIFtdLmNvbmNhdChxdWVyeVtrZXldIHx8IFtdKS5mb3JFYWNoKChwYXJhbSkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGtleS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgY2FzZSAndWlkJzpcbiAgICAgICAgICAgIHBhcmFtID0ge1xuICAgICAgICAgICAgICB0eXBlOiAnc2VxdWVuY2UnLFxuICAgICAgICAgICAgICB2YWx1ZTogcGFyYW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgLy8gVGhlIEdtYWlsIGV4dGVuc2lvbiB2YWx1ZXMgb2YgWC1HTS1USFJJRCBhbmRcbiAgICAgICAgICAvLyBYLUdNLU1TR0lEIGFyZSBkZWZpbmVkIHRvIGJlIHVuc2lnbmVkIDY0LWJpdCBpbnRlZ2Vyc1xuICAgICAgICAgIC8vIGFuZCB0aGV5IG11c3Qgbm90IGJlIHF1b3RlZCBzdHJpbmdzIG9yIHRoZSBzZXJ2ZXJcbiAgICAgICAgICAvLyB3aWxsIHJlcG9ydCBhIHBhcnNlIGVycm9yLlxuICAgICAgICAgIGNhc2UgJ3gtZ20tdGhyaWQnOlxuICAgICAgICAgIGNhc2UgJ3gtZ20tbXNnaWQnOlxuICAgICAgICAgICAgcGFyYW0gPSB7XG4gICAgICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICAgICAgICB2YWx1ZTogcGFyYW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHBhcmFtID0gZXNjYXBlUGFyYW0ocGFyYW0pXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmFtKSB7XG4gICAgICAgICAgcGFyYW1zID0gcGFyYW1zLmNvbmNhdChwYXJhbSB8fCBbXSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIGxpc3QgPSBsaXN0LmNvbmNhdChwYXJhbXMgfHwgW10pXG4gICAgfSlcblxuICAgIHJldHVybiBsaXN0XG4gIH1cblxuICBjb21tYW5kLmF0dHJpYnV0ZXMgPSBidWlsZFRlcm0ocXVlcnkpXG5cbiAgLy8gSWYgYW55IHN0cmluZyBpbnB1dCBpcyB1c2luZyA4Yml0IGJ5dGVzLCBwcmVwZW5kIHRoZSBvcHRpb25hbCBDSEFSU0VUIGFyZ3VtZW50XG4gIGlmICghaXNBc2NpaSkge1xuICAgIGNvbW1hbmQuYXR0cmlidXRlcy51bnNoaWZ0KHtcbiAgICAgIHR5cGU6ICdhdG9tJyxcbiAgICAgIHZhbHVlOiAnVVRGLTgnXG4gICAgfSlcbiAgICBjb21tYW5kLmF0dHJpYnV0ZXMudW5zaGlmdCh7XG4gICAgICB0eXBlOiAnYXRvbScsXG4gICAgICB2YWx1ZTogJ0NIQVJTRVQnXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBjb21tYW5kXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBJTUFQIFNUT1JFIGNvbW1hbmQgZnJvbSB0aGUgc2VsZWN0ZWQgYXJndW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFNUT1JFQ29tbWFuZCAoc2VxdWVuY2UsIGFjdGlvbiA9ICcnLCBmbGFncyA9IFtdLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgY29tbWFuZCA9IHtcbiAgICBjb21tYW5kOiBvcHRpb25zLmJ5VWlkID8gJ1VJRCBTVE9SRScgOiAnU1RPUkUnLFxuICAgIGF0dHJpYnV0ZXM6IFt7XG4gICAgICB0eXBlOiAnc2VxdWVuY2UnLFxuICAgICAgdmFsdWU6IHNlcXVlbmNlXG4gICAgfV1cbiAgfVxuXG4gIGNvbW1hbmQuYXR0cmlidXRlcy5wdXNoKHtcbiAgICB0eXBlOiAnYXRvbScsXG4gICAgdmFsdWU6IGFjdGlvbi50b1VwcGVyQ2FzZSgpICsgKG9wdGlvbnMuc2lsZW50ID8gJy5TSUxFTlQnIDogJycpXG4gIH0pXG5cbiAgY29tbWFuZC5hdHRyaWJ1dGVzLnB1c2goZmxhZ3MubWFwKChmbGFnKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdhdG9tJyxcbiAgICAgIHZhbHVlOiBmbGFnXG4gICAgfVxuICB9KSlcblxuICByZXR1cm4gY29tbWFuZFxufVxuIl19