UNPKG

emailjs-imap-client

Version:
567 lines (447 loc) 54.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseNAMESPACE = parseNAMESPACE; exports.parseNAMESPACEElement = parseNAMESPACEElement; exports.parseSELECT = parseSELECT; exports.parseENVELOPE = parseENVELOPE; exports.parseBODYSTRUCTURE = parseBODYSTRUCTURE; exports.parseFETCH = parseFETCH; exports.parseSEARCH = parseSEARCH; exports.parseCOPY = parseCOPY; exports.parseAPPEND = parseAPPEND; var _emailjsAddressparser = _interopRequireDefault(require("emailjs-addressparser")); var _emailjsImapHandler = require("emailjs-imap-handler"); var _ramda = require("ramda"); var _emailjsMimeCodec = require("emailjs-mime-codec"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function parseNAMESPACE(response) { if (!response.payload || !response.payload.NAMESPACE || !response.payload.NAMESPACE.length) { return false; } const attributes = [].concat(response.payload.NAMESPACE.pop().attributes || []); if (!attributes.length) { return false; } return { personal: parseNAMESPACEElement(attributes[0]), users: parseNAMESPACEElement(attributes[1]), shared: parseNAMESPACEElement(attributes[2]) }; } /** * Parses a NAMESPACE element * * @param {Object} element * @return {Object} Namespaces element object */ function parseNAMESPACEElement(element) { if (!element) { return false; } element = [].concat(element || []); return element.map(ns => { if (!ns || !ns.length) { return false; } return { prefix: ns[0].value, delimiter: ns[1] && ns[1].value // The delimiter can legally be NIL which maps to null }; }); } /** * Parses SELECT response * * @param {Object} response * @return {Object} Mailbox information object */ function parseSELECT(response) { if (!response || !response.payload) { return; } const mailbox = { readOnly: response.code === 'READ-ONLY' }; const existsResponse = response.payload.EXISTS && response.payload.EXISTS.pop(); const flagsResponse = response.payload.FLAGS && response.payload.FLAGS.pop(); const okResponse = response.payload.OK; if (existsResponse) { mailbox.exists = existsResponse.nr || 0; } if (flagsResponse && flagsResponse.attributes && flagsResponse.attributes.length) { mailbox.flags = flagsResponse.attributes[0].map(flag => (flag.value || '').toString().trim()); } [].concat(okResponse || []).forEach(ok => { switch (ok && ok.code) { case 'PERMANENTFLAGS': mailbox.permanentFlags = [].concat(ok.permanentflags || []); break; case 'UIDVALIDITY': mailbox.uidValidity = Number(ok.uidvalidity) || 0; break; case 'UIDNEXT': mailbox.uidNext = Number(ok.uidnext) || 0; break; case 'HIGHESTMODSEQ': mailbox.highestModseq = ok.highestmodseq || '0'; // keep 64bit uint as a string break; case 'NOMODSEQ': mailbox.noModseq = true; break; } }); return mailbox; } /** * Parses message envelope from FETCH response. All keys in the resulting * object are lowercase. Address fields are all arrays with {name:, address:} * structured values. Unicode strings are automatically decoded. * * @param {Array} value Envelope array * @param {Object} Envelope object */ function parseENVELOPE(value) { const envelope = {}; if (value[0] && value[0].value) { envelope.date = value[0].value; } if (value[1] && value[1].value) { envelope.subject = (0, _emailjsMimeCodec.mimeWordsDecode)(value[1] && value[1].value); } if (value[2] && value[2].length) { envelope.from = processAddresses(value[2]); } if (value[3] && value[3].length) { envelope.sender = processAddresses(value[3]); } if (value[4] && value[4].length) { envelope['reply-to'] = processAddresses(value[4]); } if (value[5] && value[5].length) { envelope.to = processAddresses(value[5]); } if (value[6] && value[6].length) { envelope.cc = processAddresses(value[6]); } if (value[7] && value[7].length) { envelope.bcc = processAddresses(value[7]); } if (value[8] && value[8].value) { envelope['in-reply-to'] = value[8].value; } if (value[9] && value[9].value) { envelope['message-id'] = value[9].value; } return envelope; } /* * ENVELOPE lists addresses as [name-part, source-route, username, hostname] * where source-route is not used anymore and can be ignored. * To get comparable results with other parts of the email.js stack * browserbox feeds the parsed address values from ENVELOPE * to addressparser and uses resulting values instead of the * pre-parsed addresses */ function processAddresses(list = []) { return list.map(addr => { const name = (0, _ramda.pathOr)('', ['0', 'value'], addr).trim(); const address = (0, _ramda.pathOr)('', ['2', 'value'], addr) + '@' + (0, _ramda.pathOr)('', ['3', 'value'], addr); const formatted = name ? encodeAddressName(name) + ' <' + address + '>' : address; const parsed = (0, _emailjsAddressparser.default)(formatted).shift(); // there should be just a single address parsed.name = (0, _emailjsMimeCodec.mimeWordsDecode)(parsed.name); return parsed; }); } /** * If needed, encloses with quotes or mime encodes the name part of an e-mail address * * @param {String} name Name part of an address * @returns {String} Mime word encoded or quoted string */ function encodeAddressName(name) { if (!/^[\w ']*$/.test(name)) { if (/^[\x20-\x7e]*$/.test(name)) { return JSON.stringify(name); } else { return (0, _emailjsMimeCodec.mimeWordEncode)(name, 'Q', 52); } } return name; } /** * Parses message body structure from FETCH response. * * @param {Array} value BODYSTRUCTURE array * @param {Object} Envelope object */ function parseBODYSTRUCTURE(node, path = []) { const curNode = {}; let i = 0; let part = 0; if (path.length) { curNode.part = path.join('.'); } // multipart if (Array.isArray(node[0])) { curNode.childNodes = []; while (Array.isArray(node[i])) { curNode.childNodes.push(parseBODYSTRUCTURE(node[i], path.concat(++part))); i++; } // multipart type curNode.type = 'multipart/' + ((node[i++] || {}).value || '').toString().toLowerCase(); // extension data (not available for BODY requests) // body parameter parenthesized list if (i < node.length - 1) { if (node[i]) { curNode.parameters = attributesToObject(node[i]); } i++; } } else { // content type curNode.type = [((node[i++] || {}).value || '').toString().toLowerCase(), ((node[i++] || {}).value || '').toString().toLowerCase()].join('/'); // body parameter parenthesized list if (node[i]) { curNode.parameters = attributesToObject(node[i]); } i++; // id if (node[i]) { curNode.id = ((node[i] || {}).value || '').toString(); } i++; // description if (node[i]) { curNode.description = ((node[i] || {}).value || '').toString(); } i++; // encoding if (node[i]) { curNode.encoding = ((node[i] || {}).value || '').toString().toLowerCase(); } i++; // size if (node[i]) { curNode.size = Number((node[i] || {}).value || 0) || 0; } i++; if (curNode.type === 'message/rfc822') { // message/rfc adds additional envelope, bodystructure and line count values // envelope if (node[i]) { curNode.envelope = parseENVELOPE([].concat(node[i] || [])); } i++; if (node[i]) { curNode.childNodes = [// rfc822 bodyparts share the same path, difference is between MIME and HEADER // path.MIME returns message/rfc822 header // path.HEADER returns inlined message header parseBODYSTRUCTURE(node[i], path)]; } i++; // line count if (node[i]) { curNode.lineCount = Number((node[i] || {}).value || 0) || 0; } i++; } else if (/^text\//.test(curNode.type)) { // text/* adds additional line count values // line count if (node[i]) { curNode.lineCount = Number((node[i] || {}).value || 0) || 0; } i++; } // extension data (not available for BODY requests) // md5 if (i < node.length - 1) { if (node[i]) { curNode.md5 = ((node[i] || {}).value || '').toString().toLowerCase(); } i++; } } // the following are shared extension values (for both multipart and non-multipart parts) // not available for BODY requests // body disposition if (i < node.length - 1) { if (Array.isArray(node[i]) && node[i].length) { curNode.disposition = ((node[i][0] || {}).value || '').toString().toLowerCase(); if (Array.isArray(node[i][1])) { curNode.dispositionParameters = attributesToObject(node[i][1]); } } i++; } // body language if (i < node.length - 1) { if (node[i]) { curNode.language = [].concat(node[i]).map(val => (0, _ramda.propOr)('', 'value', val).toLowerCase()); } i++; } // body location // NB! defined as a "string list" in RFC3501 but replaced in errata document with "string" // Errata: http://www.rfc-editor.org/errata_search.php?rfc=3501 if (i < node.length - 1) { if (node[i]) { curNode.location = ((node[i] || {}).value || '').toString(); } i++; } return curNode; } function attributesToObject(attrs = [], keyTransform = _ramda.toLower, valueTransform = _emailjsMimeCodec.mimeWordsDecode) { const vals = attrs.map((0, _ramda.prop)('value')); const keys = vals.filter((_, i) => i % 2 === 0).map(keyTransform); const values = vals.filter((_, i) => i % 2 === 1).map(valueTransform); return (0, _ramda.fromPairs)((0, _ramda.zip)(keys, values)); } /** * Parses FETCH response * * @param {Object} response * @return {Object} Message object */ function parseFETCH(response) { if (!response || !response.payload || !response.payload.FETCH || !response.payload.FETCH.length) { return []; } const list = []; const messages = {}; response.payload.FETCH.forEach(item => { const params = [].concat([].concat(item.attributes || [])[0] || []); // ensure the first value is an array let message; let i, len, key; if (messages[item.nr]) { // same sequence number is already used, so merge values instead of creating a new message object message = messages[item.nr]; } else { messages[item.nr] = message = { '#': item.nr }; list.push(message); } for (i = 0, len = params.length; i < len; i++) { if (i % 2 === 0) { key = (0, _emailjsImapHandler.compiler)({ attributes: [params[i]] }).toLowerCase().replace(/<\d+>$/, ''); continue; } message[key] = parseFetchValue(key, params[i]); } }); return list; } /** * Parses a single value from the FETCH response object * * @param {String} key Key name (uppercase) * @param {Mized} value Value for the key * @return {Mixed} Processed value */ function parseFetchValue(key, value) { if (!value) { return null; } if (!Array.isArray(value)) { switch (key) { case 'uid': case 'rfc822.size': return Number(value.value) || 0; case 'modseq': // do not cast 64 bit uint to a number return value.value || '0'; } return value.value; } switch (key) { case 'flags': case 'x-gm-labels': value = [].concat(value).map(flag => flag.value || ''); break; case 'envelope': value = parseENVELOPE([].concat(value || [])); break; case 'bodystructure': value = parseBODYSTRUCTURE([].concat(value || [])); break; case 'modseq': value = (value.shift() || {}).value || '0'; break; } return value; } /** * Binary Search - from npm module binary-search, license CC0 * * @param {Array} haystack Ordered array * @param {any} needle Item to search for in haystack * @param {Function} comparator Function that defines the sort order * @return {Number} Index of needle in haystack or if not found, * -Index-1 is the position where needle could be inserted while still * keeping haystack ordered. */ function binSearch(haystack, needle, comparator = (a, b) => a - b) { var mid, cmp; var low = 0; var high = haystack.length - 1; while (low <= high) { // Note that "(low + high) >>> 1" may overflow, and results in // a typecast to double (which gives the wrong results). mid = low + (high - low >> 1); cmp = +comparator(haystack[mid], needle); if (cmp < 0.0) { // too low low = mid + 1; } else if (cmp > 0.0) { // too high high = mid - 1; } else { // key found return mid; } } // key not found return ~low; } ; /** * Parses SEARCH response. Gathers all untagged SEARCH responses, fetched seq./uid numbers * and compiles these into a sorted array. * * @param {Object} response * @return {Object} Message object * @param {Array} Sorted Seq./UID number list */ function parseSEARCH(response) { const list = []; if (!response || !response.payload || !response.payload.SEARCH || !response.payload.SEARCH.length) { return list; } response.payload.SEARCH.forEach(result => (result.attributes || []).forEach(nr => { nr = Number(nr && nr.value || nr) || 0; const idx = binSearch(list, nr); if (idx < 0) { list.splice(-idx - 1, 0, nr); } })); return list; } ; /** * Parses COPY and UID COPY response. * https://tools.ietf.org/html/rfc4315 * @param {Object} response * @returns {{destSeqSet: string, srcSeqSet: string}} Source and * destination uid sets if available, undefined if not. */ function parseCOPY(response) { const copyuid = response && response.copyuid; if (copyuid) { return { srcSeqSet: copyuid[1], destSeqSet: copyuid[2] }; } } /** * Parses APPEND (upload) response. * https://tools.ietf.org/html/rfc4315 * @param {Object} response * @returns {String} The uid assigned to the uploaded message if available. */ function parseAPPEND(response) { return response && response.appenduid && response.appenduid[1]; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLXBhcnNlci5qcyJdLCJuYW1lcyI6WyJwYXJzZU5BTUVTUEFDRSIsInJlc3BvbnNlIiwicGF5bG9hZCIsIk5BTUVTUEFDRSIsImxlbmd0aCIsImF0dHJpYnV0ZXMiLCJjb25jYXQiLCJwb3AiLCJwZXJzb25hbCIsInBhcnNlTkFNRVNQQUNFRWxlbWVudCIsInVzZXJzIiwic2hhcmVkIiwiZWxlbWVudCIsIm1hcCIsIm5zIiwicHJlZml4IiwidmFsdWUiLCJkZWxpbWl0ZXIiLCJwYXJzZVNFTEVDVCIsIm1haWxib3giLCJyZWFkT25seSIsImNvZGUiLCJleGlzdHNSZXNwb25zZSIsIkVYSVNUUyIsImZsYWdzUmVzcG9uc2UiLCJGTEFHUyIsIm9rUmVzcG9uc2UiLCJPSyIsImV4aXN0cyIsIm5yIiwiZmxhZ3MiLCJmbGFnIiwidG9TdHJpbmciLCJ0cmltIiwiZm9yRWFjaCIsIm9rIiwicGVybWFuZW50RmxhZ3MiLCJwZXJtYW5lbnRmbGFncyIsInVpZFZhbGlkaXR5IiwiTnVtYmVyIiwidWlkdmFsaWRpdHkiLCJ1aWROZXh0IiwidWlkbmV4dCIsImhpZ2hlc3RNb2RzZXEiLCJoaWdoZXN0bW9kc2VxIiwibm9Nb2RzZXEiLCJwYXJzZUVOVkVMT1BFIiwiZW52ZWxvcGUiLCJkYXRlIiwic3ViamVjdCIsImZyb20iLCJwcm9jZXNzQWRkcmVzc2VzIiwic2VuZGVyIiwidG8iLCJjYyIsImJjYyIsImxpc3QiLCJhZGRyIiwibmFtZSIsImFkZHJlc3MiLCJmb3JtYXR0ZWQiLCJlbmNvZGVBZGRyZXNzTmFtZSIsInBhcnNlZCIsInNoaWZ0IiwidGVzdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJwYXJzZUJPRFlTVFJVQ1RVUkUiLCJub2RlIiwicGF0aCIsImN1ck5vZGUiLCJpIiwicGFydCIsImpvaW4iLCJBcnJheSIsImlzQXJyYXkiLCJjaGlsZE5vZGVzIiwicHVzaCIsInR5cGUiLCJ0b0xvd2VyQ2FzZSIsInBhcmFtZXRlcnMiLCJhdHRyaWJ1dGVzVG9PYmplY3QiLCJpZCIsImRlc2NyaXB0aW9uIiwiZW5jb2RpbmciLCJzaXplIiwibGluZUNvdW50IiwibWQ1IiwiZGlzcG9zaXRpb24iLCJkaXNwb3NpdGlvblBhcmFtZXRlcnMiLCJsYW5ndWFnZSIsInZhbCIsImxvY2F0aW9uIiwiYXR0cnMiLCJrZXlUcmFuc2Zvcm0iLCJ0b0xvd2VyIiwidmFsdWVUcmFuc2Zvcm0iLCJtaW1lV29yZHNEZWNvZGUiLCJ2YWxzIiwia2V5cyIsImZpbHRlciIsIl8iLCJ2YWx1ZXMiLCJwYXJzZUZFVENIIiwiRkVUQ0giLCJtZXNzYWdlcyIsIml0ZW0iLCJwYXJhbXMiLCJtZXNzYWdlIiwibGVuIiwia2V5IiwicmVwbGFjZSIsInBhcnNlRmV0Y2hWYWx1ZSIsImJpblNlYXJjaCIsImhheXN0YWNrIiwibmVlZGxlIiwiY29tcGFyYXRvciIsImEiLCJiIiwibWlkIiwiY21wIiwibG93IiwiaGlnaCIsInBhcnNlU0VBUkNIIiwiU0VBUkNIIiwicmVzdWx0IiwiaWR4Iiwic3BsaWNlIiwicGFyc2VDT1BZIiwiY29weXVpZCIsInNyY1NlcVNldCIsImRlc3RTZXFTZXQiLCJwYXJzZUFQUEVORCIsImFwcGVuZHVpZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFRTyxTQUFTQSxjQUFULENBQXlCQyxRQUF6QixFQUFtQztBQUN4QyxNQUFJLENBQUNBLFFBQVEsQ0FBQ0MsT0FBVixJQUFxQixDQUFDRCxRQUFRLENBQUNDLE9BQVQsQ0FBaUJDLFNBQXZDLElBQW9ELENBQUNGLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsU0FBakIsQ0FBMkJDLE1BQXBGLEVBQTRGO0FBQzFGLFdBQU8sS0FBUDtBQUNEOztBQUVELFFBQU1DLFVBQVUsR0FBRyxHQUFHQyxNQUFILENBQVVMLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsU0FBakIsQ0FBMkJJLEdBQTNCLEdBQWlDRixVQUFqQyxJQUErQyxFQUF6RCxDQUFuQjs7QUFDQSxNQUFJ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RSxNQUFBQSxVQUFVLEVBQUVGLE9BQU8sQ0FBQyxDQUFEO0FBRmQsS0FBUDtBQUlEO0FBQ0Y7QUFFRDs7Ozs7Ozs7QUFNTyxTQUFTRyxXQUFULENBQXNCbkksUUFBdEIsRUFBZ0M7QUFDckMsU0FBT0EsUUFBUSxJQUFJQSxRQUFRLENBQUNvSSxTQUFyQixJQUFrQ3BJLFFBQVEsQ0FBQ29JLFNBQVQsQ0FBbUIsQ0FBbkIsQ0FBekM7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXJzZUFkZHJlc3MgZnJvbSAnZW1haWxqcy1hZGRyZXNzcGFyc2VyJ1xuaW1wb3J0IHsgY29tcGlsZXIgfSBmcm9tICdlbWFpbGpzLWltYXAtaGFuZGxlcidcbmltcG9ydCB7IHppcCwgZnJvbVBhaXJzLCBwcm9wLCBwYXRoT3IsIHByb3BPciwgdG9Mb3dlciB9IGZyb20gJ3JhbWRhJ1xuaW1wb3J0IHsgbWltZVdvcmRFbmNvZGUsIG1pbWVXb3Jkc0RlY29kZSB9IGZyb20gJ2VtYWlsanMtbWltZS1jb2RlYydcblxuLyoqXG4gKiBQYXJzZXMgTkFNRVNQQUNFIHJlc3BvbnNlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHJlc3BvbnNlXG4gKiBAcmV0dXJuIHtPYmplY3R9IE5hbWVzcGFjZXMgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU5BTUVTUEFDRSAocmVzcG9uc2UpIHtcbiAgaWYgKCFyZXNwb25zZS5wYXlsb2FkIHx8ICFyZXNwb25zZS5wYXlsb2FkLk5BTUVTUEFDRSB8fCAhcmVzcG9uc2UucGF5bG9hZC5OQU1FU1BBQ0UubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCBhdHRyaWJ1dGVzID0gW10uY29uY2F0KHJlc3BvbnNlLnBheWxvYWQuTkFNRVNQQUNFLnBvcCgpLmF0dHJpYnV0ZXMgfHwgW10pXG4gIGlmICghYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcGVyc29uYWw6IHBhcnNlTkFNRVNQQUNFRWxlbWVudChhdHRyaWJ1dGVzWzBdKSxcbiAgICB1c2VyczogcGFyc2VOQU1FU1BBQ0VFbGVtZW50KGF0dHJpYnV0ZXNbMV0pLFxuICAgIHNoYXJlZDogcGFyc2VOQU1FU1BBQ0VFbGVtZW50KGF0dHJpYnV0ZXNbMl0pXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBOQU1FU1BBQ0UgZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtPYmplY3R9IE5hbWVzcGFjZXMgZWxlbWVudCBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTkFNRVNQQUNFRWxlbWVudCAoZWxlbWVudCkge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGVsZW1lbnQgPSBbXS5jb25jYXQoZWxlbWVudCB8fCBbXSlcbiAgcmV0dXJuIGVsZW1lbnQubWFwKChucykgPT4ge1xuICAgIGlmICghbnMgfHwgIW5zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByZWZpeDogbnNbMF0udmFsdWUsXG4gICAgICBkZWxpbWl0ZXI6IG5zWzFdICYmIG5zWzFdLnZhbHVlIC8vIFRoZSBkZWxpbWl0ZXIgY2FuIGxlZ2FsbHkgYmUgTklMIHdoaWNoIG1hcHMgdG8gbnVsbFxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBQYXJzZXMgU0VMRUNUIHJlc3BvbnNlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHJlc3BvbnNlXG4gKiBAcmV0dXJuIHtPYmplY3R9IE1haWxib3ggaW5mb3JtYXRpb24gb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVNFTEVDVCAocmVzcG9uc2UpIHtcbiAgaWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UucGF5bG9hZCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3QgbWFpbGJveCA9IHtcbiAgICByZWFkT25seTogcmVzcG9uc2UuY29kZSA9PT0gJ1JFQUQtT05MWSdcbiAgfVxuICBjb25zdCBleGlzdHNSZXNwb25zZSA9IHJlc3BvbnNlLnBheWxvYWQuRVhJU1RTICYmIHJlc3BvbnNlLnBheWxvYWQuRVhJU1RTLnBvcCgpXG4gIGNvbnN0IGZsYWdzUmVzcG9uc2UgPSByZXNwb25zZS5wYXlsb2FkLkZMQUdTICYmIHJlc3BvbnNlLnBheWxvYWQuRkxBR1MucG9wKClcbiAgY29uc3Qgb2tSZXNwb25zZSA9IHJlc3BvbnNlLnBheWxvYWQuT0tcblxuICBpZiAoZXhpc3RzUmVzcG9uc2UpIHtcbiAgICBtYWlsYm94LmV4aXN0cyA9IGV4aXN0c1Jlc3BvbnNlLm5yIHx8IDBcbiAgfVxuXG4gIGlmIChmbGFnc1Jlc3BvbnNlICYmIGZsYWdzUmVzcG9uc2UuYXR0cmlidXRlcyAmJiBmbGFnc1Jlc3BvbnNlLmF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgbWFpbGJveC5mbGFncyA9IGZsYWdzUmVzcG9uc2UuYXR0cmlidXRlc1swXS5tYXAoKGZsYWcpID0+IChmbGFnLnZhbHVlIHx8ICcnKS50b1N0cmluZygpLnRyaW0oKSlcbiAgfVxuXG4gIFtdLmNvbmNhdChva1Jlc3BvbnNlIHx8IFtdKS5mb3JFYWNoKChvaykgPT4ge1xuICAgIHN3aXRjaCAob2sgJiYgb2suY29kZSkge1xuICAgICAgY2FzZSAnUEVSTUFORU5URkxBR1MnOlxuICAgICAgICBtYWlsYm94LnBlcm1hbmVudEZsYWdzID0gW10uY29uY2F0KG9rLnBlcm1hbmVudGZsYWdzIHx8IFtdKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnVUlEVkFMSURJVFknOlxuICAgICAgICBtYWlsYm94LnVpZFZhbGlkaXR5ID0gTnVtYmVyKG9rLnVpZHZhbGlkaXR5KSB8fCAwXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdVSURORVhUJzpcbiAgICAgICAgbWFpbGJveC51aWROZXh0ID0gTnVtYmVyKG9rLnVpZG5leHQpIHx8IDBcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ0hJR0hFU1RNT0RTRVEnOlxuICAgICAgICBtYWlsYm94LmhpZ2hlc3RNb2RzZXEgPSBvay5oaWdoZXN0bW9kc2VxIHx8ICcwJyAvLyBrZWVwIDY0Yml0IHVpbnQgYXMgYSBzdHJpbmdcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ05PTU9EU0VRJzpcbiAgICAgICAgbWFpbGJveC5ub01vZHNlcSA9IHRydWVcbiAgICAgICAgYnJlYWtcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIG1haWxib3hcbn1cblxuLyoqXG4gKiBQYXJzZXMgbWVzc2FnZSBlbnZlbG9wZSBmcm9tIEZFVENIIHJlc3BvbnNlLiBBbGwga2V5cyBpbiB0aGUgcmVzdWx0aW5nXG4gKiBvYmplY3QgYXJlIGxvd2VyY2FzZS4gQWRkcmVzcyBmaWVsZHMgYXJlIGFsbCBhcnJheXMgd2l0aCB7bmFtZTosIGFkZHJlc3M6fVxuICogc3RydWN0dXJlZCB2YWx1ZXMuIFVuaWNvZGUgc3RyaW5ncyBhcmUgYXV0b21hdGljYWxseSBkZWNvZGVkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlIEVudmVsb3BlIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gRW52ZWxvcGUgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUVOVkVMT1BFICh2YWx1ZSkge1xuICBjb25zdCBlbnZlbG9wZSA9IHt9XG5cbiAgaWYgKHZhbHVlWzBdICYmIHZhbHVlWzBdLnZhbHVlKSB7XG4gICAgZW52ZWxvcGUuZGF0ZSA9IHZhbHVlWzBdLnZhbHVlXG4gIH1cblxuICBpZiAodmFsdWVbMV0gJiYgdmFsdWVbMV0udmFsdWUpIHtcbiAgICBlbnZlbG9wZS5zdWJqZWN0ID0gbWltZVdvcmRzRGVjb2RlKHZhbHVlWzFdICYmIHZhbHVlWzFdLnZhbHVlKVxuICB9XG5cbiAgaWYgKHZhbHVlWzJdICYmIHZhbHVlWzJdLmxlbmd0aCkge1xuICAgIGVudmVsb3BlLmZyb20gPSBwcm9jZXNzQWRkcmVzc2VzKHZhbHVlWzJdKVxuICB9XG5cbiAgaWYgKHZhbHVlWzNdICYmIHZhbHVlWzNdLmxlbmd0aCkge1xuICAgIGVudmVsb3BlLnNlbmRlciA9IHByb2Nlc3NBZGRyZXNzZXModmFsdWVbM10pXG4gIH1cblxuICBpZiAodmFsdWVbNF0gJiYgdmFsdWVbNF0ubGVuZ3RoKSB7XG4gICAgZW52ZWxvcGVbJ3JlcGx5LXRvJ10gPSBwcm9jZXNzQWRkcmVzc2VzKHZhbHVlWzRdKVxuICB9XG5cbiAgaWYgKHZhbHVlWzVdICYmIHZhbHVlWzVdLmxlbmd0aCkge1xuICAgIGVudmVsb3BlLnRvID0gcHJvY2Vzc0FkZHJlc3Nlcyh2YWx1ZVs1XSlcbiAgfVxuXG4gIGlmICh2YWx1ZVs2XSAmJiB2YWx1ZVs2XS5sZW5ndGgpIHtcbiAgICBlbnZlbG9wZS5jYyA9IHByb2Nlc3NBZGRyZXNzZXModmFsdWVbNl0pXG4gIH1cblxuICBpZiAodmFsdWVbN10gJiYgdmFsdWVbN10ubGVuZ3RoKSB7XG4gICAgZW52ZWxvcGUuYmNjID0gcHJvY2Vzc0FkZHJlc3Nlcyh2YWx1ZVs3XSlcbiAgfVxuXG4gIGlmICh2YWx1ZVs4XSAmJiB2YWx1ZVs4XS52YWx1ZSkge1xuICAgIGVudmVsb3BlWydpbi1yZXBseS10byddID0gdmFsdWVbOF0udmFsdWVcbiAgfVxuXG4gIGlmICh2YWx1ZVs5XSAmJiB2YWx1ZVs5XS52YWx1ZSkge1xuICAgIGVudmVsb3BlWydtZXNzYWdlLWlkJ10gPSB2YWx1ZVs5XS52YWx1ZVxuICB9XG5cbiAgcmV0dXJuIGVudmVsb3BlXG59XG5cbi8qXG4gKiBFTlZFTE9QRSBsaXN0cyBhZGRyZXNzZXMgYXMgW25hbWUtcGFydCwgc291cmNlLXJvdXRlLCB1c2VybmFtZSwgaG9zdG5hbWVdXG4gKiB3aGVyZSBzb3VyY2Utcm91dGUgaXMgbm90IHVzZWQgYW55bW9yZSBhbmQgY2FuIGJlIGlnbm9yZWQuXG4gKiBUbyBnZXQgY29tcGFyYWJsZSByZXN1bHRzIHdpdGggb3RoZXIgcGFydHMgb2YgdGhlIGVtYWlsLmpzIHN0YWNrXG4gKiBicm93c2VyYm94IGZlZWRzIHRoZSBwYXJzZWQgYWRkcmVzcyB2YWx1ZXMgZnJvbSBFTlZFTE9QRVxuICogdG8gYWRkcmVzc3BhcnNlciBhbmQgdXNlcyByZXN1bHRpbmcgdmFsdWVzIGluc3RlYWQgb2YgdGhlXG4gKiBwcmUtcGFyc2VkIGFkZHJlc3Nlc1xuICovXG5mdW5jdGlvbiBwcm9jZXNzQWRkcmVzc2VzIChsaXN0ID0gW10pIHtcbiAgcmV0dXJuIGxpc3QubWFwKChhZGRyKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IChwYXRoT3IoJycsIFsnMCcsICd2YWx1ZSddLCBhZGRyKSkudHJpbSgpXG4gICAgY29uc3QgYWRkcmVzcyA9IChwYXRoT3IoJycsIFsnMicsICd2YWx1ZSddLCBhZGRyKSkgKyAnQCcgKyAocGF0aE9yKCcnLCBbJzMnLCAndmFsdWUnXSwgYWRkcikpXG4gICAgY29uc3QgZm9ybWF0dGVkID0gbmFtZSA/IChlbmNvZGVBZGRyZXNzTmFtZShuYW1lKSArICcgPCcgKyBhZGRyZXNzICsgJz4nKSA6IGFkZHJlc3NcbiAgICBjb25zdCBwYXJzZWQgPSBwYXJzZUFkZHJlc3MoZm9ybWF0dGVkKS5zaGlmdCgpIC8vIHRoZXJlIHNob3VsZCBiZSBqdXN0IGEgc2luZ2xlIGFkZHJlc3NcbiAgICBwYXJzZWQubmFtZSA9IG1pbWVXb3Jkc0RlY29kZShwYXJzZWQubmFtZSlcbiAgICByZXR1cm4gcGFyc2VkXG4gIH0pXG59XG5cbi8qKlxuICogSWYgbmVlZGVkLCBlbmNsb3NlcyB3aXRoIHF1b3RlcyBvciBtaW1lIGVuY29kZXMgdGhlIG5hbWUgcGFydCBvZiBhbiBlLW1haWwgYWRkcmVzc1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIE5hbWUgcGFydCBvZiBhbiBhZGRyZXNzXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBNaW1lIHdvcmQgZW5jb2RlZCBvciBxdW90ZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGVuY29kZUFkZHJlc3NOYW1lIChuYW1lKSB7XG4gIGlmICghL15bXFx3ICddKiQvLnRlc3QobmFtZSkpIHtcbiAgICBpZiAoL15bXFx4MjAtXFx4N2VdKiQvLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShuYW1lKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbWltZVdvcmRFbmNvZGUobmFtZSwgJ1EnLCA1MilcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hbWVcbn1cblxuLyoqXG4gKiBQYXJzZXMgbWVzc2FnZSBib2R5IHN0cnVjdHVyZSBmcm9tIEZFVENIIHJlc3BvbnNlLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlIEJPRFlTVFJVQ1RVUkUgYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSBFbnZlbG9wZSBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQk9EWVNUUlVDVFVSRSAobm9kZSwgcGF0aCA9IFtdKSB7XG4gIGNvbnN0IGN1ck5vZGUgPSB7fVxuICBsZXQgaSA9IDBcbiAgbGV0IHBhcnQgPSAwXG5cbiAgaWYgKHBhdGgubGVuZ3RoKSB7XG4gICAgY3VyTm9kZS5wYXJ0ID0gcGF0aC5qb2luKCcuJylcbiAgfVxuXG4gIC8vIG11bHRpcGFydFxuICBpZiAoQXJyYXkuaXNBcnJheShub2RlWzBdKSkge1xuICAgIGN1ck5vZGUuY2hpbGROb2RlcyA9IFtdXG4gICAgd2hpbGUgKEFycmF5LmlzQXJyYXkobm9kZVtpXSkpIHtcbiAgICAgIGN1ck5vZGUuY2hpbGROb2Rlcy5wdXNoKHBhcnNlQk9EWVNUUlVDVFVSRShub2RlW2ldLCBwYXRoLmNvbmNhdCgrK3BhcnQpKSlcbiAgICAgIGkrK1xuICAgIH1cblxuICAgIC8vIG11bHRpcGFydCB0eXBlXG4gICAgY3VyTm9kZS50eXBlID0gJ211bHRpcGFydC8nICsgKChub2RlW2krK10gfHwge30pLnZhbHVlIHx8ICcnKS50b1N0cmluZygpLnRvTG93ZXJDYXNlKClcblxuICAgIC8vIGV4dGVuc2lvbiBkYXRhIChub3QgYXZhaWxhYmxlIGZvciBCT0RZIHJlcXVlc3RzKVxuXG4gICAgLy8gYm9keSBwYXJhbWV0ZXIgcGFyZW50aGVzaXplZCBsaXN0XG4gICAgaWYgKGkgPCBub2RlLmxlbmd0aCAtIDEpIHtcbiAgICAgIGlmIChub2RlW2ldKSB7XG4gICAgICAgIGN1ck5vZGUucGFyYW1ldGVycyA9IGF0dHJpYnV0ZXNUb09iamVjdChub2RlW2ldKVxuICAgICAgfVxuICAgICAgaSsrXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIGNvbnRlbnQgdHlwZVxuICAgIGN1ck5vZGUudHlwZSA9IFtcbiAgICAgICgobm9kZVtpKytdIHx8IHt9KS52YWx1ZSB8fCAnJykudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpLCAoKG5vZGVbaSsrXSB8fCB7fSkudmFsdWUgfHwgJycpLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKVxuICAgIF0uam9pbignLycpXG5cbiAgICAvLyBib2R5IHBhcmFtZXRlciBwYXJlbnRoZXNpemVkIGxpc3RcbiAgICBpZiAobm9kZVtpXSkge1xuICAgICAgY3VyTm9kZS5wYXJhbWV0ZXJzID0gYXR0cmlidXRlc1RvT2JqZWN0KG5vZGVbaV0pXG4gICAgfVxuICAgIGkrK1xuXG4gICAgLy8gaWRcbiAgICBpZiAobm9kZVtpXSkge1xuICAgICAgY3VyTm9kZS5pZCA9ICgobm9kZVtpXSB8fCB7fSkudmFsdWUgfHwgJycpLnRvU3RyaW5nKClcbiAgICB9XG4gICAgaSsrXG5cbiAgICAvLyBkZXNjcmlwdGlvblxuICAgIGlmIChub2RlW2ldKSB7XG4gICAgICBjdXJOb2RlLmRlc2NyaXB0aW9uID0gKChub2RlW2ldIHx8IHt9KS52YWx1ZSB8fCAnJykudG9TdHJpbmcoKVxuICAgIH1cbiAgICBpKytcblxuICAgIC8vIGVuY29kaW5nXG4gICAgaWYgKG5vZGVbaV0pIHtcbiAgICAgIGN1ck5vZGUuZW5jb2RpbmcgPSAoKG5vZGVbaV0gfHwge30pLnZhbHVlIHx8ICcnKS50b1N0cmluZygpLnRvTG93ZXJDYXNlKClcbiAgICB9XG4gICAgaSsrXG5cbiAgICAvLyBzaXplXG4gICAgaWYgKG5vZGVbaV0pIHtcbiAgICAgIGN1ck5vZGUuc2l6ZSA9IE51bWJlcigobm9kZVtpXSB8fCB7fSkudmFsdWUgfHwgMCkgfHwgMFxuICAgIH1cbiAgICBpKytcblxuICAgIGlmIChjdXJOb2RlLnR5cGUgPT09ICdtZXNzYWdlL3JmYzgyMicpIHtcbiAgICAgIC8vIG1lc3NhZ2UvcmZjIGFkZHMgYWRkaXRpb25hbCBlbnZlbG9wZSwgYm9keXN0cnVjdHVyZSBhbmQgbGluZSBjb3VudCB2YWx1ZXNcblxuICAgICAgLy8gZW52ZWxvcGVcbiAgICAgIGlmIChub2RlW2ldKSB7XG4gICAgICAgIGN1ck5vZGUuZW52ZWxvcGUgPSBwYXJzZUVOVkVMT1BFKFtdLmNvbmNhdChub2RlW2ldIHx8IFtdKSlcbiAgICAgIH1cbiAgICAgIGkrK1xuXG4gICAgICBpZiAobm9kZVtpXSkge1xuICAgICAgICBjdXJOb2RlLmNoaWxkTm9kZXMgPSBbXG4gICAgICAgICAgLy8gcmZjODIyIGJvZHlwYXJ0cyBzaGFyZSB0aGUgc2FtZSBwYXRoLCBkaWZmZXJlbmNlIGlzIGJldHdlZW4gTUlNRSBhbmQgSEVBREVSXG4gICAgICAgICAgLy8gcGF0aC5NSU1FIHJldHVybnMgbWVzc2FnZS9yZmM4MjIgaGVhZGVyXG4gICAgICAgICAgLy8gcGF0aC5IRUFERVIgcmV0dXJucyBpbmxpbmVkIG1lc3NhZ2UgaGVhZGVyXG4gICAgICAgICAgcGFyc2VCT0RZU1RSVUNUVVJFKG5vZGVbaV0sIHBhdGgpXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICAgIGkrK1xuXG4gICAgICAvLyBsaW5lIGNvdW50XG4gICAgICBpZiAobm9kZVtpXSkge1xuICAgICAgICBjdXJOb2RlLmxpbmVDb3VudCA9IE51bWJlcigobm9kZVtpXSB8fCB7fSkudmFsdWUgfHwgMCkgfHwgMFxuICAgICAgfVxuICAgICAgaSsrXG4gICAgfSBlbHNlIGlmICgvXnRleHRcXC8vLnRlc3QoY3VyTm9kZS50eXBlKSkge1xuICAgICAgLy8gdGV4dC8qIGFkZHMgYWRkaXRpb25hbCBsaW5lIGNvdW50IHZhbHVlc1xuXG4gICAgICAvLyBsaW5lIGNvdW50XG4gICAgICBpZiAobm9kZVtpXSkge1xuICAgICAgICBjdXJOb2RlLmxpbmVDb3VudCA9IE51bWJlcigobm9kZVtpXSB8fCB7fSkudmFsdWUgfHwgMCkgfHwgMFxuICAgICAgfVxuICAgICAgaSsrXG4gICAgfVxuXG4gICAgLy8gZXh0ZW5zaW9uIGRhdGEgKG5vdCBhdmFpbGFibGUgZm9yIEJPRFkgcmVxdWVzdHMpXG5cbiAgICAvLyBtZDVcbiAgICBpZiAoaSA8IG5vZGUubGVuZ3RoIC0gMSkge1xuICAgICAgaWYgKG5vZGVbaV0pIHtcbiAgICAgICAgY3VyTm9kZS5tZDUgPSAoKG5vZGVbaV0gfHwge30pLnZhbHVlIHx8ICcnKS50b1N0cmluZygpLnRvTG93ZXJDYXNlKClcbiAgICAgIH1cbiAgICAgIGkrK1xuICAgIH1cbiAgfVxuXG4gIC8vIHRoZSBmb2xsb3dpbmcgYXJlIHNoYXJlZCBleHRlbnNpb24gdmFsdWVzIChmb3IgYm90aCBtdWx0aXBhcnQgYW5kIG5vbi1tdWx0aXBhcnQgcGFydHMpXG4gIC8vIG5vdCBhdmFpbGFibGUgZm9yIEJPRFkgcmVxdWVzdHNcblxuICAvLyBib2R5IGRpc3Bvc2l0aW9uXG4gIGlmIChpIDwgbm9kZS5sZW5ndGggLSAxKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkobm9kZVtpXSkgJiYgbm9kZVtpXS5sZW5ndGgpIHtcbiAgICAgIGN1ck5vZGUuZGlzcG9zaXRpb24gPSAoKG5vZGVbaV1bMF0gfHwge30pLnZhbHVlIHx8ICcnKS50b1N0cmluZygpLnRvTG93ZXJDYXNlKClcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG5vZGVbaV1bMV0pKSB7XG4gICAgICAgIGN1ck5vZGUuZGlzcG9zaXRpb25QYXJhbWV0ZXJzID0gYXR0cmlidXRlc1RvT2JqZWN0KG5vZGVbaV1bMV0pXG4gICAgICB9XG4gICAgfVxuICAgIGkrK1xuICB9XG5cbiAgLy8gYm9keSBsYW5ndWFnZVxuICBpZiAoaSA8IG5vZGUubGVuZ3RoIC0gMSkge1xuICAgIGlmIChub2RlW2ldKSB7XG4gICAgICBjdXJOb2RlLmxhbmd1YWdlID0gW10uY29uY2F0KG5vZGVbaV0pLm1hcCgodmFsKSA9PiBwcm9wT3IoJycsICd2YWx1ZScsIHZhbCkudG9Mb3dlckNhc2UoKSlcbiAgICB9XG4gICAgaSsrXG4gIH1cblxuICAvLyBib2R5IGxvY2F0aW9uXG4gIC8vIE5CISBkZWZpbmVkIGFzIGEgXCJzdHJpbmcgbGlzdFwiIGluIFJGQzM1MDEgYnV0IHJlcGxhY2VkIGluIGVycmF0YSBkb2N1bWVudCB3aXRoIFwic3RyaW5nXCJcbiAgLy8gRXJyYXRhOiBodHRwOi8vd3d3LnJmYy1lZGl0b3Iub3JnL2VycmF0YV9zZWFyY2gucGhwP3JmYz0zNTAxXG4gIGlmIChpIDwgbm9kZS5sZW5ndGggLSAxKSB7XG4gICAgaWYgKG5vZGVbaV0pIHtcbiAgICAgIGN1ck5vZGUubG9jYXRpb24gPSAoKG5vZGVbaV0gfHwge30pLnZhbHVlIHx8ICcnKS50b1N0cmluZygpXG4gICAgfVxuICAgIGkrK1xuICB9XG5cbiAgcmV0dXJuIGN1ck5vZGVcbn1cblxuZnVuY3Rpb24gYXR0cmlidXRlc1RvT2JqZWN0IChhdHRycyA9IFtdLCBrZXlUcmFuc2Zvcm0gPSB0b0xvd2VyLCB2YWx1ZVRyYW5zZm9ybSA9IG1pbWVXb3Jkc0RlY29kZSkge1xuICBjb25zdCB2YWxzID0gYXR0cnMubWFwKHByb3AoJ3ZhbHVlJykpXG4gIGNvbnN0IGtleXMgPSB2YWxzLmZpbHRlcigoXywgaSkgPT4gaSAlIDIgPT09IDApLm1hcChrZXlUcmFuc2Zvcm0pXG4gIGNvbnN0IHZhbHVlcyA9IHZhbHMuZmlsdGVyKChfLCBpKSA9PiBpICUgMiA9PT0gMSkubWFwKHZhbHVlVHJhbnNmb3JtKVxuICByZXR1cm4gZnJvbVBhaXJzKHppcChrZXlzLCB2YWx1ZXMpKVxufVxuXG4vKipcbiAqIFBhcnNlcyBGRVRDSCByZXNwb25zZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSByZXNwb25zZVxuICogQHJldHVybiB7T2JqZWN0fSBNZXNzYWdlIG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VGRVRDSCAocmVzcG9uc2UpIHtcbiAgaWYgKCFyZXNwb25zZSB8fCAhcmVzcG9uc2UucGF5bG9hZCB8fCAhcmVzcG9uc2UucGF5bG9hZC5GRVRDSCB8fCAhcmVzcG9uc2UucGF5bG9hZC5GRVRDSC5sZW5ndGgpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIGNvbnN0IGxpc3QgPSBbXVxuICBjb25zdCBtZXNzYWdlcyA9IHt9XG5cbiAgcmVzcG9uc2UucGF5bG9hZC5GRVRDSC5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgY29uc3QgcGFyYW1zID0gW10uY29uY2F0KFtdLmNvbmNhdChpdGVtLmF0dHJpYnV0ZXMgfHwgW10pWzBdIHx8IFtdKSAvLyBlbnN1cmUgdGhlIGZpcnN0IHZhbHVlIGlzIGFuIGFycmF5XG4gICAgbGV0IG1lc3NhZ2VcbiAgICBsZXQgaSwgbGVuLCBrZXlcblxuICAgIGlmIChtZXNzYWdlc1tpdGVtLm5yXSkge1xuICAgICAgLy8gc2FtZSBzZXF1ZW5jZSBudW1iZXIgaXMgYWxyZWFkeSB1c2VkLCBzbyBtZXJnZSB2YWx1ZXMgaW5zdGVhZCBvZiBjcmVhdGluZyBhIG5ldyBtZXNzYWdlIG9iamVjdFxuICAgICAgbWVzc2FnZSA9IG1lc3NhZ2VzW2l0ZW0ubnJdXG4gICAgfSBlbHNlIHtcbiAgICAgIG1lc3NhZ2VzW2l0ZW0ubnJdID0gbWVzc2FnZSA9IHtcbiAgICAgICAgJyMnOiBpdGVtLm5yXG4gICAgICB9XG4gICAgICBsaXN0LnB1c2gobWVzc2FnZSlcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBsZW4gPSBwYXJhbXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGlmIChpICUgMiA9PT0gMCkge1xuICAgICAgICBrZXkgPSBjb21waWxlcih7XG4gICAgICAgICAgYXR0cmlidXRlczogW3BhcmFtc1tpXV1cbiAgICAgICAgfSkudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC88XFxkKz4kLywgJycpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBtZXNzYWdlW2tleV0gPSBwYXJzZUZldGNoVmFsdWUoa2V5LCBwYXJhbXNbaV0pXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBsaXN0XG59XG5cbi8qKlxuICogUGFyc2VzIGEgc2luZ2xlIHZhbHVlIGZyb20gdGhlIEZFVENIIHJlc3BvbnNlIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgS2V5IG5hbWUgKHVwcGVyY2FzZSlcbiAqIEBwYXJhbSB7TWl6ZWR9IHZhbHVlIFZhbHVlIGZvciB0aGUga2V5XG4gKiBAcmV0dXJuIHtNaXhlZH0gUHJvY2Vzc2VkIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHBhcnNlRmV0Y2hWYWx1ZSAoa2V5LCB2YWx1ZSkge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgY2FzZSAndWlkJzpcbiAgICAgIGNhc2UgJ3JmYzgyMi5zaXplJzpcbiAgICAgICAgcmV0dXJuIE51bWJlcih2YWx1ZS52YWx1ZSkgfHwgMFxuICAgICAgY2FzZSAnbW9kc2VxJzogLy8gZG8gbm90IGNhc3QgNjQg