emailjs-imap-client
Version:
JavaScript IMAP client
567 lines (447 loc) • 54.1 kB
JavaScript
"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