{"version":3,"file":"convert-to-jcamp.min.js","sources":["../lib-esm/utils/addInfoData.js","../lib-esm/utils/assert.js","../node_modules/is-any-array/lib-esm/index.js","../lib-esm/utils/checkNumberOrArray.js","../node_modules/ml-spectra-processing/lib-esm/x/utils/getOutputArray.js","../node_modules/ml-spectra-processing/lib-esm/x/xMinMaxValues.js","../node_modules/ml-spectra-processing/lib-esm/x/xCheck.js","../node_modules/ml-spectra-processing/lib-esm/matrix/matrixMinMaxZ.js","../node_modules/ml-spectra-processing/lib-esm/matrix/matrixCheck.js","../lib-esm/utils/getFactorNumber.js","../lib-esm/utils/getBestFactor.js","../lib-esm/utils/checkMatrix.js","../lib-esm/utils/getExtremeValues.js","../lib-esm/utils/rescaleAndEnsureInteger.js","../node_modules/ml-spectra-processing/lib-esm/x/xDivide.js","../lib-esm/utils/vectorEncoder.js","../lib-esm/creatorNtuples.js","../lib-esm/utils/getNumber.js","../lib-esm/utils/peakTableCreator.js","../lib-esm/utils/xyDataCreator.js","../lib-esm/fromJSON.js","../lib-esm/from2DNMRVariables.js","../lib-esm/utils/getBestFactorMatrix.js","../lib-esm/fromVariables.js"],"sourcesContent":["export const addInfoData = (data, keys = Object.keys(data), prefix = '##$') => {\n    let header = '';\n    for (const key of keys) {\n        header +=\n            typeof data[key] === 'object'\n                ? `${prefix}${key}=${JSON.stringify(data[key])}\\n`\n                : `${prefix}${key}=${data[key]}\\n`;\n    }\n    return header;\n};\n//# sourceMappingURL=addInfoData.js.map","export function assertMeasurementXYVariables(variables) {\n    assertVariablesHasX(variables);\n    assertVariablesHasY(variables);\n}\nexport function assertVariablesHasX(variables) {\n    if (!variables.x) {\n        throw new Error('variables has not x');\n    }\n}\nexport function assertVariablesHasY(variables) {\n    if (!variables.y) {\n        throw new Error('variables has not y');\n    }\n}\nexport function variablesHasXY(variables) {\n    return variables.x && variables.y ? true : false;\n}\n//# sourceMappingURL=assert.js.map","const toString = Object.prototype.toString;\n/**\n * Checks if an object is an instance of an Array (array or typed array).\n *\n * @param {any} value - Object to check.\n * @returns {boolean} True if the object is an array.\n */\nexport function isAnyArray(value) {\n    return toString.call(value).endsWith('Array]');\n}\n//# sourceMappingURL=index.js.map","import { isAnyArray } from 'is-any-array';\nexport function checkNumberOrArray(data) {\n    if (!isAnyArray(data) || isAnyArray(data[0])) {\n        throw new Error(`x and y data should be an array of numbers`);\n    }\n}\n//# sourceMappingURL=checkNumberOrArray.js.map","import { isAnyArray } from 'is-any-array';\n/**\n * This function\n * @param output - undefined or a new array\n * @param length - length of the output array\n * @returns\n */\nexport function getOutputArray(output, length) {\n    if (output !== undefined) {\n        if (!isAnyArray(output)) {\n            throw new TypeError('output option must be an array if specified');\n        }\n        if (output.length !== length) {\n            throw new TypeError('the output array does not have the correct length');\n        }\n        return output;\n    }\n    else {\n        return new Float64Array(length);\n    }\n}\n//# sourceMappingURL=getOutputArray.js.map","import { xCheck } from './xCheck';\n/**\n * Return min and max values of an array\n *\n * @param array - array of number\n * @returns - Object with 2 properties, min and max\n */\nexport function xMinMaxValues(array) {\n    xCheck(array);\n    let min = array[0];\n    let max = array[0];\n    for (let value of array) {\n        if (value < min)\n            min = value;\n        if (value > max)\n            max = value;\n    }\n    return { min, max };\n}\n//# sourceMappingURL=xMinMaxValues.js.map","import { isAnyArray } from 'is-any-array';\n/**\n * Checks if input is of type array\n *\n * @param input - input\n */\nexport function xCheck(input) {\n    if (!isAnyArray(input)) {\n        throw new TypeError('input must be an array');\n    }\n    if (input.length === 0) {\n        throw new TypeError('input must not be empty');\n    }\n}\n//# sourceMappingURL=xCheck.js.map","import { matrixCheck } from './matrixCheck';\n/**\n * Get min and max Z\n *\n * @param matrix - matrix [rows][cols].\n */\nexport function matrixMinMaxZ(matrix) {\n    matrixCheck(matrix);\n    const nbRows = matrix.length;\n    const nbColumns = matrix[0].length;\n    let min = matrix[0][0];\n    let max = matrix[0][0];\n    for (let column = 0; column < nbColumns; column++) {\n        for (let row = 0; row < nbRows; row++) {\n            if (matrix[row][column] < min)\n                min = matrix[row][column];\n            if (matrix[row][column] > max)\n                max = matrix[row][column];\n        }\n    }\n    return { min, max };\n}\n//# sourceMappingURL=matrixMinMaxZ.js.map","export function matrixCheck(data) {\n    if (data.length === 0 || data[0].length === 0) {\n        throw new RangeError('matrix should contain data');\n    }\n    const firstLength = data[0].length;\n    for (let i = 1; i < data.length; i++) {\n        if (data[i].length !== firstLength) {\n            throw new RangeError('All rows should has the same length');\n        }\n    }\n}\n//# sourceMappingURL=matrixCheck.js.map","export function getFactorNumber(minMax, maxValue = 2 ** 31 - 1) {\n    let factor;\n    if (minMax.min < 0) {\n        if (minMax.max > 0) {\n            factor = Math.max(-minMax.min, minMax.max) / maxValue;\n        }\n        else {\n            factor = -minMax.min / maxValue;\n        }\n    }\n    else {\n        factor = minMax.max / maxValue;\n    }\n    return factor;\n}\n//# sourceMappingURL=getFactorNumber.js.map","import { xMinMaxValues } from 'ml-spectra-processing';\nimport { getFactorNumber } from './getFactorNumber';\nexport function getBestFactor(array, options = {}) {\n    const { maxValue, factor, minMax } = options;\n    if (factor !== undefined) {\n        return factor;\n    }\n    // is there non integer number ?\n    let onlyInteger = true;\n    for (let y of array) {\n        if (Math.round(y) !== y) {\n            onlyInteger = false;\n            break;\n        }\n    }\n    if (onlyInteger) {\n        return 1;\n    }\n    // we need to rescale the values\n    // need to find the max and min values\n    const extremeValues = minMax || xMinMaxValues(array);\n    return getFactorNumber(extremeValues, maxValue);\n}\n//# sourceMappingURL=getBestFactor.js.map","import { isAnyArray } from 'is-any-array';\nexport function checkMatrix(data) {\n    if (!isAnyArray(data) || !isAnyArray(data[0])) {\n        throw new Error(`2D data should be a matrix`);\n    }\n}\n//# sourceMappingURL=checkMatrix.js.map","import { isAnyArray } from 'is-any-array';\nimport { matrixMinMaxZ, xMinMaxValues, } from 'ml-spectra-processing';\nimport { checkMatrix } from './checkMatrix';\nimport { checkNumberOrArray } from './checkNumberOrArray';\nexport function getExtremeValues(data) {\n    if (isAnyArray(data[0])) {\n        checkMatrix(data);\n        const firstRow = data[0];\n        return {\n            firstLast: {\n                first: firstRow[0],\n                last: data[data.length - 1][data[0].length - 1],\n            },\n            minMax: matrixMinMaxZ(data),\n        };\n    }\n    checkNumberOrArray(data);\n    return {\n        firstLast: {\n            first: data[0],\n            last: data[data.length - 1],\n        },\n        minMax: xMinMaxValues(data),\n    };\n}\n//# sourceMappingURL=getExtremeValues.js.map","import { xDivide } from 'ml-spectra-processing';\nexport function rescaleAndEnsureInteger(data, factor) {\n    if (factor === 1)\n        return data.map((value) => Math.round(value));\n    return xDivide(data, factor);\n}\n//# sourceMappingURL=rescaleAndEnsureInteger.js.map","import { isAnyArray } from 'is-any-array';\nimport { getOutputArray } from '..';\n/**\n * This function divide the first array by the second array or a constant value to each element of the first array\n *\n * @param array1 - first array\n * @param array2 - second array or number\n * @param options - options\n */\nexport function xDivide(array1, array2, options = {}) {\n    let isConstant = false;\n    let constant = 0;\n    if (isAnyArray(array2)) {\n        if (array1.length !== array2.length) {\n            throw new Error('xDivide: size of array1 and array2 must be identical');\n        }\n    }\n    else {\n        isConstant = true;\n        constant = Number(array2);\n    }\n    let array3 = getOutputArray(options.output, array1.length);\n    if (isConstant) {\n        for (let i = 0; i < array1.length; i++) {\n            array3[i] = array1[i] / constant;\n        }\n    }\n    else {\n        for (let i = 0; i < array1.length; i++) {\n            array3[i] = array1[i] / array2[i];\n        }\n    }\n    return array3;\n}\n//# sourceMappingURL=xDivide.js.map","/**\n * class encodes a integer vector as a String in order to store it in a text file.\n * The algorithms used to encode the data are describe in:\n *            http://www.iupac.org/publications/pac/pdf/2001/pdf/7311x1765.pdf\n */\nconst newLine = '\\n';\nconst pseudoDigits = [\n    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],\n    ['@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],\n    ['@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],\n    ['%', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'],\n    ['%', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r'],\n    [' ', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 's'],\n];\nconst SQZ_P = 1;\nconst SQZ_N = 2;\nconst DIF_P = 3;\nconst DIF_N = 4;\nconst DUP = 5;\nconst maxLinelength = 100;\n/**\n * This function encodes the given vector. The xyEncoding format is specified by the\n * xyEncoding option\n * @param xyEncoding: ('FIX','SQZ','DIF','DIFDUP','CVS','PAC') Default 'DIFDUP'\n * @return {string}\n */\nexport function vectorEncoder(data, firstX, intervalX, xyEncoding) {\n    switch (xyEncoding) {\n        case 'FIX':\n            return fixEncoding(data, firstX, intervalX);\n        case 'SQZ':\n            return squeezedEncoding(data, firstX, intervalX);\n        case 'DIF':\n            return differenceEncoding(data, firstX, intervalX);\n        case 'DIFDUP':\n            return differenceDuplicateEncoding(data, firstX, intervalX);\n        case 'CSV':\n            return commaSeparatedValuesEncoding(data, firstX, intervalX);\n        case 'PAC':\n            return packedEncoding(data, firstX, intervalX);\n        default:\n            return differenceEncoding(data, firstX, intervalX);\n    }\n}\n/**\n * @private\n * No data compression used. The data is separated by a comma(',').\n */\nexport function commaSeparatedValuesEncoding(data, firstX, intervalX) {\n    return fixEncoding(data, firstX, intervalX, ',');\n}\n/**\n * @private\n * No data compression used. The data is separated by the specified separator.\n */\nexport function fixEncoding(data, firstX, intervalX, separator = ' ') {\n    let outputData = '';\n    let j = 0;\n    let dataLength = data.length;\n    while (j < dataLength - 7) {\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = 0; i < 8; i++) {\n            outputData += separator + data[j++];\n        }\n        outputData += newLine;\n    }\n    if (j < dataLength) {\n        // We add last numbers\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = j; i < dataLength; i++) {\n            outputData += separator + data[i];\n        }\n    }\n    return outputData;\n}\n/**\n * @private\n * No data compression used. The data is separated by the sign of the number.\n */\nexport function packedEncoding(data, firstX, intervalX) {\n    let outputData = '';\n    let j = 0;\n    let dataLength = data.length;\n    while (j < dataLength - 7) {\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = 0; i < 8; i++) {\n            outputData += data[j] < 0 ? data[j++] : `+${data[j++]}`;\n        }\n        outputData += newLine;\n    }\n    if (j < dataLength) {\n        // We add last numbers\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = j; i < dataLength; i++) {\n            outputData += data[i] < 0 ? data[i] : `+${data[i]}`;\n        }\n    }\n    return outputData;\n}\n/**\n * @private\n * Data compression is possible using the squeezed form (SQZ) in which the delimiter, the leading digit,\n * and sign are replaced by a pseudo-digit from Table 1. For example, the Y-values 30, 32 would be\n * represented as C0C2.\n */\nexport function squeezedEncoding(data, firstX, intervalX) {\n    let outputData = '';\n    // String outputData = new String();\n    let j = 0;\n    let dataLength = data.length;\n    while (j < dataLength - 10) {\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = 0; i < 10; i++) {\n            outputData += squeezedDigit(data[j++].toString());\n        }\n        outputData += newLine;\n    }\n    if (j < dataLength) {\n        // We add last numbers\n        outputData += Math.ceil(firstX + j * intervalX);\n        for (let i = j; i < dataLength; i++) {\n            outputData += squeezedDigit(data[i].toString());\n        }\n    }\n    return outputData;\n}\n/**\n * @private\n * Duplicate suppression xyEncoding\n */\nexport function differenceDuplicateEncoding(data, firstX, intervalX) {\n    let mult = 0;\n    let index = 0;\n    let charCount = 0;\n    // We built a string where we store the encoded data.\n    let encodedData = '';\n    let encodedNumber = '';\n    let temp = '';\n    // We calculate the differences vector\n    let diffData = new Array(data.length - 1);\n    for (let i = 0; i < diffData.length; i++) {\n        diffData[i] = data[i + 1] - data[i];\n    }\n    // We simulate a line carry\n    let numDiff = diffData.length;\n    while (index < numDiff) {\n        if (charCount === 0) {\n            // Start line\n            encodedNumber =\n                Math.ceil(firstX + index * intervalX) +\n                    squeezedDigit(data[index].toString()) +\n                    differenceDigit(diffData[index].toString());\n            encodedData += encodedNumber;\n            charCount += encodedNumber.length;\n        }\n        else {\n            // Try to insert next difference\n            if (diffData[index - 1] === diffData[index]) {\n                mult++;\n            }\n            else {\n                if (mult > 0) {\n                    // Now we know that it can be in line\n                    mult++;\n                    encodedNumber = duplicateDigit(mult.toString());\n                    encodedData += encodedNumber;\n                    charCount += encodedNumber.length;\n                    mult = 0;\n                    index--;\n                }\n                else {\n                    // Check if it fits, otherwise start a new line\n                    encodedNumber = differenceDigit(diffData[index].toString());\n                    if (encodedNumber.length + charCount < maxLinelength) {\n                        encodedData += encodedNumber;\n                        charCount += encodedNumber.length;\n                    }\n                    else {\n                        // start a new line\n                        encodedData += newLine;\n                        temp =\n                            Math.ceil(firstX + index * intervalX) +\n                                squeezedDigit(data[index].toString()) +\n                                encodedNumber;\n                        encodedData += temp; // Each line start with first index number.\n                        charCount = temp.length;\n                    }\n                }\n            }\n        }\n        index++;\n    }\n    if (mult > 0) {\n        encodedData += duplicateDigit((mult + 1).toString());\n    }\n    // We insert the last data from fid. It is done to control of data\n    // The last line start with the number of datas in the fid.\n    encodedData +=\n        newLine +\n            Math.ceil(firstX + index * intervalX) +\n            squeezedDigit(data[index].toString());\n    return encodedData;\n}\n/**\n * @private\n * Differential xyEncoding\n */\nexport function differenceEncoding(data, firstX, intervalX) {\n    let index = 0;\n    let charCount = 0;\n    let i;\n    let encodedData = '';\n    let encodedNumber = '';\n    let temp = '';\n    // We calculate the differences vector\n    let diffData = new Array(data.length - 1);\n    for (i = 0; i < diffData.length; i++) {\n        diffData[i] = data[i + 1] - data[i];\n    }\n    let numDiff = diffData.length;\n    while (index < numDiff) {\n        if (charCount === 0) {\n            // We convert the first number.\n            encodedNumber =\n                Math.ceil(firstX + index * intervalX) +\n                    squeezedDigit(data[index].toString()) +\n                    differenceDigit(diffData[index].toString());\n            encodedData += encodedNumber;\n            charCount += encodedNumber.length;\n        }\n        else {\n            encodedNumber = differenceDigit(diffData[index].toString());\n            if (encodedNumber.length + charCount < maxLinelength) {\n                encodedData += encodedNumber;\n                charCount += encodedNumber.length;\n            }\n            else {\n                encodedData += newLine;\n                temp =\n                    Math.ceil(firstX + index * intervalX) +\n                        squeezedDigit(data[index].toString()) +\n                        encodedNumber;\n                encodedData += temp; // Each line start with first index number.\n                charCount = temp.length;\n            }\n        }\n        index++;\n    }\n    // We insert the last number from data. It is done to control of data\n    encodedData +=\n        newLine +\n            Math.ceil(firstX + index * intervalX) +\n            squeezedDigit(data[index].toString());\n    return encodedData;\n}\n/**\n * @private\n * Convert number to the ZQZ format, using pseudo digits.\n */\nfunction squeezedDigit(num) {\n    let sqzDigits = '';\n    if (num.startsWith('-')) {\n        sqzDigits += pseudoDigits[SQZ_N][num.charCodeAt(1) - 48];\n        if (num.length > 2) {\n            sqzDigits += num.substring(2);\n        }\n    }\n    else {\n        sqzDigits += pseudoDigits[SQZ_P][num.charCodeAt(0) - 48];\n        if (num.length > 1) {\n            sqzDigits += num.substring(1);\n        }\n    }\n    return sqzDigits;\n}\n/**\n * Convert number to the DIF format, using pseudo digits.\n */\nfunction differenceDigit(num) {\n    let diffDigits = '';\n    if (num.startsWith('-')) {\n        diffDigits += pseudoDigits[DIF_N][num.charCodeAt(1) - 48];\n        if (num.length > 2) {\n            diffDigits += num.substring(2);\n        }\n    }\n    else {\n        diffDigits += pseudoDigits[DIF_P][num.charCodeAt(0) - 48];\n        if (num.length > 1) {\n            diffDigits += num.substring(1);\n        }\n    }\n    return diffDigits;\n}\n/**\n * Convert number to the DUP format, using pseudo digits.\n */\nfunction duplicateDigit(num) {\n    let dupDigits = '';\n    dupDigits += pseudoDigits[DUP][num.charCodeAt(0) - 48];\n    if (num.length > 1) {\n        dupDigits += num.substring(1);\n    }\n    return dupDigits;\n}\n//# sourceMappingURL=vectorEncoder.js.map","import { addInfoData } from './utils/addInfoData';\nimport { assertVariablesHasX, assertVariablesHasY, } from './utils/assert';\nimport { checkNumberOrArray } from './utils/checkNumberOrArray';\nimport { getBestFactor } from './utils/getBestFactor';\nimport { getExtremeValues } from './utils/getExtremeValues';\nimport { rescaleAndEnsureInteger } from './utils/rescaleAndEnsureInteger';\nimport { vectorEncoder } from './utils/vectorEncoder';\n/**\n * Parse from a xyxy data array\n * @param variables - Variables to convert to jcamp\n * @param [options={}] - options that allows to add meta data in the jcamp\n * @return JCAMP-DX text file corresponding to the variables\n */\nexport default function creatorNtuples(variables, options) {\n    assertVariablesHasX(variables);\n    const { meta = {}, info = {}, xyEncoding = '', factors = {} } = options;\n    const { title = '', owner = '', origin = '', dataType = '' } = info;\n    const symbol = [];\n    const varName = [];\n    const varType = [];\n    const varDim = [];\n    const units = [];\n    const first = [];\n    const last = [];\n    const min = [];\n    const max = [];\n    const factorArray = [];\n    const keys = Object.keys(variables);\n    for (let i = 0; i < keys.length; i++) {\n        const key = keys[i];\n        let variable = variables[key];\n        if (!variable)\n            continue;\n        let name = variable?.label.replace(/ *\\[.*/, '');\n        let unit = variable?.label.replace(/.*\\[(?<units>.*)\\].*/, '$<units>');\n        const { firstLast, minMax } = getExtremeValues(variable.data);\n        factors[key] = getBestFactor(variable.data, {\n            factor: factors[key],\n            minMax,\n        });\n        const currentFactor = factors[key];\n        factorArray.push(currentFactor);\n        symbol.push(variable.symbol || key);\n        varName.push(name || key);\n        varDim.push(variable.data.length);\n        first.push(firstLast.first);\n        last.push(firstLast.last);\n        max.push(minMax.max);\n        min.push(minMax.min);\n        if (variable.isDependent !== undefined) {\n            varType.push(variable.isDependent ? 'DEPENDENT' : 'INDEPENDENT');\n        }\n        else {\n            varType.push(variable.isDependent !== undefined\n                ? !variable.isDependent\n                : i === 0\n                    ? 'INDEPENDENT'\n                    : 'DEPENDENT');\n        }\n        units.push(variable.units || unit || '');\n    }\n    let header = `##TITLE=${title}\n##JCAMP-DX=6.00\n##DATA TYPE=${dataType}\n##DATA CLASS= NTUPLES\n##ORIGIN=${origin}\n##OWNER=${owner}\\n`;\n    const infoKeys = Object.keys(info).filter((e) => !['title', 'owner', 'origin', 'datatype'].includes(e.toLocaleLowerCase()));\n    header += addInfoData(info, infoKeys, '##');\n    header += addInfoData(meta);\n    header += `##NTUPLES= ${dataType}\n##VAR_NAME=  ${varName.join()}\n##SYMBOL=    ${symbol.join()}\n##VAR_TYPE=  ${varType.join()}\n##VAR_DIM=   ${varDim.join()}\n##UNITS=     ${units.join()}\n##FACTOR=    ${factorArray.join()}\n##FIRST=     ${first.join()}\n##LAST=      ${last.join()}\n##MIN=       ${min.join()}\n##MAX=       ${max.join()}\\n`;\n    if (options.isNMR) {\n        let xData = variables.x.data;\n        checkNumberOrArray(xData);\n        if (options.isPeakData) {\n            assertVariablesHasY(variables);\n            let yData = variables.y.data;\n            checkNumberOrArray(yData);\n            header += `##DATA TABLE= (XY..XY), PEAKS\\n`;\n            for (let point = 0; point < varDim[0]; point++) {\n                header += `${xData[point]}, ${yData[point]}\\n`;\n            }\n        }\n        else if (options.isXYData) {\n            for (const key of ['r', 'i']) {\n                const variable = variables[key];\n                if (variable) {\n                    checkNumberOrArray(variable.data);\n                    header += `##PAGE= N=${key === 'r' ? 1 : 2}\\n`;\n                    header += `##DATA TABLE= (X++(${key === 'r' ? 'R..R' : 'I..I'})), XYDATA\\n`;\n                    header += vectorEncoder(rescaleAndEnsureInteger(variable.data, factors[key]), 0, 1, xyEncoding);\n                    header += '\\n';\n                }\n            }\n        }\n    }\n    else {\n        header += `##PAGE= N=1\\n`;\n        header += `##DATA TABLE= (${symbol.join('')}..${symbol.join('')}), PEAKS\\n`;\n        for (let i = 0; i < variables.x.data.length; i++) {\n            let point = [];\n            for (let key of keys) {\n                let variable = variables[key];\n                if (!variable)\n                    continue;\n                point.push(variable.data[i]);\n            }\n            header += `${point.join('\\t')}\\n`;\n        }\n    }\n    header += `##END NTUPLES= ${dataType}\\n`;\n    header += '##END=\\n##END=';\n    return header;\n}\n//# sourceMappingURL=creatorNtuples.js.map","/**\n * Reconvert number to original value\n * @param number Number used for computation\n * @param factor Multiplying factor\n * @returns Original value\n */\nexport function getNumber(number, factor) {\n    if (factor !== 1)\n        number /= factor;\n    const rounded = Math.round(number);\n    if (rounded !== number && Math.abs(rounded - number) <= Number.EPSILON) {\n        return rounded;\n    }\n    return number;\n}\n//# sourceMappingURL=getNumber.js.map","import { getNumber } from './getNumber';\nexport function peakTableCreator(data, options = {}) {\n    const { xFactor = 1, yFactor = 1 } = options.info || {};\n    let firstX = Number.POSITIVE_INFINITY;\n    let lastX = Number.NEGATIVE_INFINITY;\n    let firstY = Number.POSITIVE_INFINITY;\n    let lastY = Number.NEGATIVE_INFINITY;\n    let lines = [];\n    for (let i = 0; i < data.x.length; i++) {\n        let x = data.x[i];\n        let y = data.y[i];\n        if (firstX > x) {\n            firstX = x;\n        }\n        if (lastX < x) {\n            lastX = x;\n        }\n        if (firstY > y) {\n            firstY = y;\n        }\n        if (lastY < y) {\n            lastY = y;\n        }\n    }\n    lines.push(`##FIRSTX=${firstX}`);\n    lines.push(`##LASTX=${lastX}`);\n    lines.push(`##FIRSTY=${firstY}`);\n    lines.push(`##LASTY=${lastY}`);\n    lines.push(`##XFACTOR=${xFactor}`);\n    lines.push(`##YFACTOR=${yFactor}`);\n    lines.push('##PEAK TABLE=(XY..XY)');\n    for (let i = 0; i < data.x.length; i++) {\n        lines.push(`${getNumber(data.x[i], xFactor)} ${getNumber(data.y[i], yFactor)}`);\n    }\n    return lines;\n}\n//# sourceMappingURL=peakTableCreator.js.map","import { rescaleAndEnsureInteger } from './rescaleAndEnsureInteger';\nimport { vectorEncoder } from './vectorEncoder';\nexport function xyDataCreator(data, options = {}) {\n    const { xyEncoding = 'DIF' } = options;\n    const { xFactor = 1, yFactor = 1 } = options.info || {};\n    let firstX = data.x[0];\n    let lastX = data.x[data.x.length - 1];\n    let firstY = data.y[0];\n    let lastY = data.y[data.y.length - 1];\n    let nbPoints = data.x.length;\n    let deltaX = (lastX - firstX) / (nbPoints - 1);\n    let lines = [];\n    lines.push(`##FIRSTX=${firstX}`);\n    lines.push(`##LASTX=${lastX}`);\n    lines.push(`##FIRSTY=${firstY}`);\n    lines.push(`##LASTY=${lastY}`);\n    lines.push(`##DELTAX=${deltaX}`);\n    lines.push(`##XFACTOR=${xFactor}`);\n    lines.push(`##YFACTOR=${yFactor}`);\n    lines.push('##XYDATA=(X++(Y..Y))');\n    let line = vectorEncoder(rescaleAndEnsureInteger(data.y, yFactor), firstX / xFactor, deltaX / xFactor, xyEncoding);\n    if (line)\n        lines.push(line);\n    return lines;\n}\n//# sourceMappingURL=xyDataCreator.js.map","import { addInfoData } from './utils/addInfoData';\nimport { getBestFactor } from './utils/getBestFactor';\nimport { peakTableCreator } from './utils/peakTableCreator';\nimport { xyDataCreator } from './utils/xyDataCreator';\nconst infoDefaultKeys = [\n    'title',\n    'owner',\n    'origin',\n    'dataType',\n    'xUnits',\n    'yUnits',\n    'xFactor',\n    'yFactor',\n];\n/**\n * Create a jcamp\n * @param data object of array\n * @param [options={meta:{},info:{}} - metadata object\n * @returns JCAMP of the input\n */\nexport function fromJSON(data, options = {}) {\n    const { meta = {}, info = {}, xyEncoding } = options;\n    let { title = '', owner = '', origin = '', dataType = '', xUnits = '', yUnits = '', xFactor, yFactor, } = info;\n    data = { x: data.x, y: data.y };\n    let header = `##TITLE=${title}\n##JCAMP-DX=4.24\n##DATA TYPE=${dataType}\n##ORIGIN=${origin}\n##OWNER=${owner}\n##XUNITS=${xUnits}\n##YUNITS=${yUnits}\\n`;\n    const infoKeys = Object.keys(info).filter((keys) => !infoDefaultKeys.includes(keys));\n    header += addInfoData(info, infoKeys, '##');\n    header += addInfoData(meta);\n    // we leave the header and utf8 fonts ${header.replace(/[^\\t\\n\\x20-\\x7F]/g, '')\n    if (xyEncoding) {\n        xFactor = getBestFactor(data.x, { factor: xFactor });\n        yFactor = getBestFactor(data.y, { factor: yFactor });\n        return `${header}##NPOINTS=${data.x.length}\n${xyDataCreator(data, { info: { xFactor, yFactor }, xyEncoding }).join('\\n')}\n##END=`;\n    }\n    else {\n        if (xFactor === undefined)\n            xFactor = 1;\n        if (yFactor === undefined)\n            yFactor = 1;\n        if (xFactor !== 1) {\n            //@ts-expect-error xFactor is always defined\n            data.x = data.x.map((value) => value / xFactor);\n        }\n        if (yFactor !== 1) {\n            //@ts-expect-error yFactor is always defined\n            data.y = data.y.map((value) => value / yFactor);\n        }\n        return `${header}##NPOINTS=${data.x.length}\n${peakTableCreator(data, { info: { xFactor, yFactor } }).join('\\n')}\n##END=`;\n    }\n}\n//# sourceMappingURL=fromJSON.js.map","import { isAnyArray } from 'is-any-array';\nimport { addInfoData } from './utils/addInfoData';\nimport { checkMatrix } from './utils/checkMatrix';\nimport { checkNumberOrArray } from './utils/checkNumberOrArray';\nimport { getBestFactor } from './utils/getBestFactor';\nimport { getBestFactorMatrix } from './utils/getBestFactorMatrix';\nimport { getExtremeValues } from './utils/getExtremeValues';\nimport { rescaleAndEnsureInteger } from './utils/rescaleAndEnsureInteger';\nimport { vectorEncoder } from './utils/vectorEncoder';\n/**\n * Create a jcamp from variables\n */\nexport function from2DNMRVariables(\n/** object of variables */\nvariables, options = {}) {\n    const { info = {}, meta = {}, xyEncoding = 'DIFDUP' } = options;\n    const { title = '', owner = '', origin = '', dataType = '' } = info;\n    const symbol = [];\n    const varName = [];\n    const varType = [];\n    const varDim = [];\n    const units = [];\n    const first = [];\n    const last = [];\n    const min = [];\n    const max = [];\n    const factor = [];\n    const keys = ['y', 'x', 'z'];\n    for (let i = 0; i < keys.length; i++) {\n        const key = keys[i];\n        let variable = variables[key];\n        if (!variable)\n            throw new Error('variables x, y and z are mandatory');\n        let name = variable?.label.replace(/ *\\[.*/, '');\n        let unit = variable?.label.replace(/.*\\[(?<units>.*)\\].*/, '$<units>');\n        const { firstLast, minMax } = getExtremeValues(variable.data);\n        symbol.push(variable.symbol || key);\n        varName.push(name || key);\n        varDim.push(variable.data.length);\n        first.push(firstLast.first);\n        last.push(firstLast.last);\n        max.push(minMax.max);\n        min.push(minMax.min);\n        //@ts-expect-error it will be included\n        factor.push(variable.factor || calculateFactor(variable.data, minMax));\n        if (variable.isDependent !== undefined) {\n            varType.push(variable.isDependent ? 'DEPENDENT' : 'INDEPENDENT');\n        }\n        else {\n            varType.push(variable.isDependent !== undefined\n                ? !variable.isDependent\n                : i === 0\n                    ? 'INDEPENDENT'\n                    : 'DEPENDENT');\n        }\n        units.push(variable.units || unit || '');\n    }\n    let header = `##TITLE=${title}\n##JCAMP-DX=6.00\n##DATA TYPE=${dataType}\n##DATA CLASS= NTUPLES\n##ORIGIN=${origin}\n##OWNER=${owner}\\n`;\n    const infoKeys = Object.keys(info).filter((e) => !['title', 'owner', 'origin', 'dataType'].includes(e));\n    header += addInfoData(info, infoKeys, '##');\n    header += addInfoData(meta);\n    let xData = variables.x.data;\n    let yData = variables.y.data;\n    checkNumberOrArray(xData);\n    checkNumberOrArray(yData);\n    checkMandatoryParameters(meta);\n    const zData = variables.z?.data || [];\n    checkMatrix(zData);\n    const { direct, indirect, dependent } = getDimensionIndices(symbol);\n    const nuc1 = String(meta.NUC1);\n    const nuc2 = String(meta.NUC2);\n    const nucleus = new Array(3);\n    nucleus[direct] = nuc1;\n    nucleus[indirect] = nuc2;\n    const sfo1 = Number(meta.SFO1);\n    const sfo2 = Number(meta.SFO2);\n    const optionsScaleAndJoin = {\n        indices: { direct, indirect },\n        sfo1,\n        sfo2,\n    };\n    header += `##NTUPLES= ${dataType}\n##VAR_NAME=  ${varName.join()}\n##SYMBOL=    ${symbol.join()}\n##VAR_TYPE=  ${varType.join()}\n##VAR_DIM=   ${varDim.join()}\n##.NUCLEUS=  ${nucleus.join()}\n##UNITS=     ${units.join()}\n##FACTOR=    ${factor.join()}\n##FIRST=     ${scaleAndJoin(first, optionsScaleAndJoin)}\n##LAST=      ${scaleAndJoin(last, optionsScaleAndJoin)}\n##MIN=       ${scaleAndJoin(min, optionsScaleAndJoin)}\n##MAX=       ${scaleAndJoin(max, optionsScaleAndJoin)}\\n`;\n    header += `##VAR_FORM= AFFN, AFFN, ASDF\\n`;\n    header += '##NUM DIM= 2\\n';\n    if (keys[direct] !== 'x') {\n        [yData, xData] = [xData, yData];\n    }\n    const directSymbol = symbol[direct].toUpperCase();\n    const indirectSymbol = symbol[indirect].toUpperCase();\n    const firstY = yData[0] * sfo2;\n    const lastY = yData[yData.length - 1] * sfo2;\n    const firstX = xData[0];\n    const lastX = xData[xData.length - 1];\n    const deltaX = (lastX - firstX) / (xData.length - 1);\n    const deltaY = (lastY - firstY) / (yData.length - 1);\n    let firstData = new Float64Array(3);\n    firstData[direct] = firstX * sfo1;\n    firstData[indirect] = firstY;\n    const yFactor = factor[indirect];\n    const xFactor = factor[direct];\n    const zFactor = factor[dependent];\n    for (let index = 0; index < zData.length; index++) {\n        firstData[dependent] = zData[index][0];\n        header += `##PAGE= ${indirectSymbol}=${(firstY + deltaY * index) / yFactor}\\n`;\n        header += `##FIRST=  ${firstData.join()}\\n`;\n        header += `##DATA TABLE= (${directSymbol}++(Y..Y)), PROFILE\\n`;\n        header += vectorEncoder(rescaleAndEnsureInteger(zData[index], zFactor), firstX / xFactor, deltaX / xFactor, xyEncoding);\n        header += '\\n';\n    }\n    return header;\n}\nfunction scaleAndJoin(variable, options) {\n    const { sfo1, sfo2 } = options;\n    const { direct, indirect } = options.indices;\n    const copy = variable.slice();\n    copy[direct] *= sfo1;\n    copy[indirect] *= sfo2;\n    return copy.join();\n}\nfunction getDimensionIndices(entry) {\n    const symbol = entry.map((e) => e.toUpperCase());\n    const direct = symbol.includes('F2')\n        ? symbol.indexOf('F2')\n        : symbol.indexOf('T2');\n    const indirect = symbol.includes('F1')\n        ? symbol.indexOf('F1')\n        : symbol.indexOf('T1');\n    if (direct === -1 || indirect === -1) {\n        throw new Error('F2/T2 and F1/T1 symbol should be defined for nD NMR SPECTRUM');\n    }\n    return { direct, indirect, dependent: 3 - direct - indirect };\n}\nfunction checkMandatoryParameters(meta) {\n    const list = ['SFO1', 'SFO2', 'NUC1', 'NUC2'];\n    for (const key of list) {\n        if (!meta[key]) {\n            throw new Error(`${key} in options.meta should be defined`);\n        }\n    }\n}\nfunction calculateFactor(data, minMax) {\n    return isAnyArray(data[0])\n        ? getBestFactorMatrix(data, { minMax })\n        : getBestFactor(data, { minMax });\n}\n//# sourceMappingURL=from2DNMRVariables.js.map","import { matrixMinMaxZ } from 'ml-spectra-processing';\nimport { getFactorNumber } from './getFactorNumber';\nexport function getBestFactorMatrix(matrix, options = {}) {\n    const { maxValue, factor, minMax } = options;\n    if (factor !== undefined) {\n        return factor;\n    }\n    // is there non integer number ?\n    let onlyInteger = true;\n    for (let row of matrix) {\n        for (let y of row) {\n            if (Math.round(y) !== y) {\n                onlyInteger = false;\n                break;\n            }\n        }\n    }\n    if (onlyInteger) {\n        return 1;\n    }\n    // we need to rescale the values\n    // need to find the max and min values\n    const extremeValues = minMax || matrixMinMaxZ(matrix);\n    return getFactorNumber(extremeValues, maxValue);\n}\n//# sourceMappingURL=getBestFactorMatrix.js.map","import creatorNtuples from './creatorNtuples';\nimport { fromJSON } from './fromJSON';\nimport { variablesHasXY } from './utils/assert';\nimport { checkNumberOrArray } from './utils/checkNumberOrArray';\n/**\n * Create a jcamp from variables\n */\nexport function fromVariables(\n/** object of variables */\nvariables, options = {}) {\n    const { info = {}, meta = {}, forceNtuples = false } = options;\n    let jcampOptions = {\n        info,\n        meta,\n    };\n    let keys = Object.keys(variables).map((key) => key.toLowerCase());\n    if (!forceNtuples && keys.length === 2 && variablesHasXY(variables)) {\n        let x = variables.x;\n        let xLabel = x.label || 'x';\n        if (variables.x.units) {\n            if (xLabel.includes(variables.x.units)) {\n                jcampOptions.info.xUnits = xLabel;\n            }\n            else {\n                jcampOptions.info.xUnits = `${xLabel} (${variables.x.units})`;\n            }\n        }\n        else {\n            jcampOptions.info.xUnits = xLabel;\n        }\n        let y = variables.y;\n        let yLabel = y.label || 'y';\n        if (variables.y.units) {\n            if (yLabel.includes(variables.y.units)) {\n                jcampOptions.info.xUnits = yLabel;\n            }\n            else {\n                jcampOptions.info.yUnits = `${yLabel} (${variables.y.units})`;\n            }\n        }\n        else {\n            jcampOptions.info.yUnits = yLabel;\n        }\n        const xData = variables.x.data;\n        const yData = variables.y.data;\n        checkNumberOrArray(xData);\n        checkNumberOrArray(yData);\n        return fromJSON({ x: xData, y: yData }, jcampOptions);\n    }\n    else {\n        return creatorNtuples(variables, options);\n    }\n}\n//# sourceMappingURL=fromVariables.js.map"],"names":["addInfoData","data","keys","Object","prefix","header","key","JSON","stringify","variablesHasXY","variables","x","y","toString","prototype","isAnyArray","value","call","endsWith","checkNumberOrArray","Error","getOutputArray","output","length","undefined","TypeError","Float64Array","xMinMaxValues","array","input","xCheck","min","max","matrixMinMaxZ","matrix","RangeError","firstLength","i","matrixCheck","nbRows","nbColumns","column","row","getFactorNumber","minMax","factor","maxValue","arguments","Math","getBestFactor","options","onlyInteger","round","extremeValues","checkMatrix","getExtremeValues","firstLast","first","last","rescaleAndEnsureInteger","map","array1","array2","isConstant","constant","Number","array3","xDivide","newLine","pseudoDigits","vectorEncoder","firstX","intervalX","xyEncoding","fixEncoding","outputData","j","dataLength","ceil","squeezedDigit","squeezedEncoding","differenceEncoding","mult","index","charCount","encodedData","encodedNumber","temp","diffData","Array","numDiff","differenceDigit","duplicateDigit","differenceDuplicateEncoding","commaSeparatedValuesEncoding","packedEncoding","separator","num","sqzDigits","startsWith","charCodeAt","substring","diffDigits","dupDigits","creatorNtuples","assertVariablesHasX","meta","info","factors","title","owner","origin","dataType","symbol","varName","varType","varDim","units","factorArray","variable","name","label","replace","unit","currentFactor","push","isDependent","infoKeys","filter","e","includes","toLocaleLowerCase","join","isNMR","xData","isPeakData","assertVariablesHasY","yData","point","isXYData","getNumber","number","rounded","abs","EPSILON","peakTableCreator","xFactor","yFactor","POSITIVE_INFINITY","lastX","NEGATIVE_INFINITY","firstY","lastY","lines","xyDataCreator","nbPoints","deltaX","line","infoDefaultKeys","fromJSON","xUnits","yUnits","scaleAndJoin","sfo1","sfo2","direct","indirect","indices","copy","slice","getDimensionIndices","entry","toUpperCase","indexOf","dependent","checkMandatoryParameters","list","calculateFactor","getBestFactorMatrix","zData","z","nuc1","String","NUC1","nuc2","NUC2","nucleus","SFO1","SFO2","optionsScaleAndJoin","directSymbol","indirectSymbol","deltaY","firstData","zFactor","forceNtuples","jcampOptions","toLowerCase","xLabel","yLabel"],"mappings":"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"}