{"version":3,"file":"rxn-parser.min.js","sources":["../node_modules/ensure-string/lib-esm/index.js","../node_modules/isutf8/dist/index.esm.js","../src/index.js"],"sourcesContent":["import isutf8 from 'isutf8';\n/**\n * Ensure that the data is string. If it is an ArrayBuffer it will be converted to string using TextDecoder.\n * @param blob\n * @param options\n * @returns\n */\nexport function ensureString(blob, options = {}) {\n    if (typeof blob === 'string') {\n        return blob;\n    }\n    if (ArrayBuffer.isView(blob) || blob instanceof ArrayBuffer) {\n        const { encoding = guessEncoding(blob) } = options;\n        const decoder = new TextDecoder(encoding);\n        return decoder.decode(blob);\n    }\n    throw new TypeError(`blob must be a string, ArrayBuffer or ArrayBufferView`);\n}\nfunction guessEncoding(blob) {\n    const uint8 = ArrayBuffer.isView(blob)\n        ? new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength)\n        : new Uint8Array(blob);\n    if (uint8.length >= 2) {\n        if (uint8[0] === 0xfe && uint8[1] === 0xff) {\n            return 'utf-16be';\n        }\n        if (uint8[0] === 0xff && uint8[1] === 0xfe) {\n            return 'utf-16le';\n        }\n    }\n    //@ts-expect-error an ArrayBuffer is also ok\n    if (!isutf8(blob))\n        return 'latin1';\n    return 'utf-8';\n}\n//# sourceMappingURL=index.js.map","/*\n    https://tools.ietf.org/html/rfc3629\n\n    UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4\n\n    UTF8-1    = %x00-7F\n\n    UTF8-2    = %xC2-DF UTF8-tail\n\n    UTF8-3    = %xE0 %xA0-BF UTF8-tail\n                %xE1-EC 2( UTF8-tail )\n                %xED %x80-9F UTF8-tail\n                %xEE-EF 2( UTF8-tail )\n\n    UTF8-4    = %xF0 %x90-BF 2( UTF8-tail )\n                %xF1-F3 3( UTF8-tail )\n                %xF4 %x80-8F 2( UTF8-tail )\n\n    UTF8-tail = %x80-BF\n*/\n/**\n * Check if a Node.js Buffer or Uint8Array is UTF-8.\n */\nfunction isUtf8(buf) {\n    if (!buf) {\n        return false;\n    }\n    var i = 0;\n    var len = buf.length;\n    while (i < len) {\n        // UTF8-1 = %x00-7F\n        if (buf[i] <= 0x7F) {\n            i++;\n            continue;\n        }\n        // UTF8-2 = %xC2-DF UTF8-tail\n        if (buf[i] >= 0xC2 && buf[i] <= 0xDF) {\n            // if(buf[i + 1] >= 0x80 && buf[i + 1] <= 0xBF) {\n            if (buf[i + 1] >> 6 === 2) {\n                i += 2;\n                continue;\n            }\n            else {\n                return false;\n            }\n        }\n        // UTF8-3 = %xE0 %xA0-BF UTF8-tail\n        // UTF8-3 = %xED %x80-9F UTF8-tail\n        if (((buf[i] === 0xE0 && buf[i + 1] >= 0xA0 && buf[i + 1] <= 0xBF) ||\n            (buf[i] === 0xED && buf[i + 1] >= 0x80 && buf[i + 1] <= 0x9F)) && buf[i + 2] >> 6 === 2) {\n            i += 3;\n            continue;\n        }\n        // UTF8-3 = %xE1-EC 2( UTF8-tail )\n        // UTF8-3 = %xEE-EF 2( UTF8-tail )\n        if (((buf[i] >= 0xE1 && buf[i] <= 0xEC) ||\n            (buf[i] >= 0xEE && buf[i] <= 0xEF)) &&\n            buf[i + 1] >> 6 === 2 &&\n            buf[i + 2] >> 6 === 2) {\n            i += 3;\n            continue;\n        }\n        // UTF8-4 = %xF0 %x90-BF 2( UTF8-tail )\n        //          %xF1-F3 3( UTF8-tail )\n        //          %xF4 %x80-8F 2( UTF8-tail )\n        if (((buf[i] === 0xF0 && buf[i + 1] >= 0x90 && buf[i + 1] <= 0xBF) ||\n            (buf[i] >= 0xF1 && buf[i] <= 0xF3 && buf[i + 1] >> 6 === 2) ||\n            (buf[i] === 0xF4 && buf[i + 1] >= 0x80 && buf[i + 1] <= 0x8F)) &&\n            buf[i + 2] >> 6 === 2 &&\n            buf[i + 3] >> 6 === 2) {\n            i += 4;\n            continue;\n        }\n        return false;\n    }\n    return true;\n}\n\nexport { isUtf8 as default };\n","import { ensureString } from 'ensure-string';\n\n/**\n * Parse a rxn file and return an object with reagents and products\n * @param {import('cheminfo-types').TextData} rxn\n * @returns\n */\n\nexport default function parse(rxn) {\n  rxn = ensureString(rxn);\n  // we will find the delimiter in order to be much faster and not use regular expression\n  let header = rxn.slice(0, 1000);\n  let crlf = '\\n';\n  if (header.includes('\\r\\n')) {\n    crlf = '\\r\\n';\n  } else if (header.includes('\\r')) {\n    crlf = '\\r';\n  }\n\n  let rxnParts = rxn.split(`${crlf}$MOL${crlf}`);\n\n  let reagents = [];\n  let products = [];\n\n  let result = {};\n  result.reagents = reagents;\n  result.products = products;\n\n  // the first part is expected to contain the number of reagents and products\n\n  // First part should start with $RXN\n  // and the fifth line should contain the number of reagents and products\n  if (rxnParts.length === 0) throw new Error('file looks empty');\n\n  header = rxnParts[0];\n  if (header.indexOf('$RXN') !== 0) {\n    throw new Error('file does not start with $RXN');\n  }\n\n  let lines = header.split(crlf);\n  if (lines.length < 5) throw new Error('incorrect number of lines in header');\n\n  let numberReagents = lines[4].slice(0, 3) >> 0;\n  let numberProducts = lines[4].slice(3, 6) >> 0;\n\n  // hack for JSME\n  let thirdNumber = lines[4].slice(6, 9) >> 0; // for jsme\n\n  if (thirdNumber && rxnParts[1]) {\n    let lines = rxnParts[1].split(crlf);\n    if (lines[0]) {\n      numberReagents = lines[0]\n        .trim()\n        .replace(/>[^>]*$/, '')\n        .split(/[.>]/).length;\n    }\n  }\n\n  if (numberReagents + numberProducts !== rxnParts.length - 1) {\n    throw new Error('not the correct number of molecules');\n  }\n\n  for (let i = 1; i < rxnParts.length; i++) {\n    if (i <= numberReagents) {\n      reagents.push(rxnParts[i]);\n    } else {\n      products.push(rxnParts[i]);\n    }\n  }\n  return result;\n}\n"],"names":["guessEncoding","blob","uint8","ArrayBuffer","isView","Uint8Array","buffer","byteOffset","byteLength","length","buf","i","len","isutf8","rxn","header","options","encoding","TextDecoder","decode","TypeError","ensureString","slice","crlf","includes","rxnParts","split","reagents","products","result","Error","indexOf","lines","numberReagents","numberProducts","trim","replace","push"],"mappings":"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","x_google_ignoreList":[0,1]}