{"version":3,"file":"netcdfjs.min.js","sources":["../node_modules/iobuffer/lib-esm/text.browser.js","../node_modules/iobuffer/lib-esm/IOBuffer.js","../src/utils.js","../src/types.js","../src/header.js","../src/toString.js","../src/index.js","../src/data.js"],"sourcesContent":["// eslint-disable-next-line import/no-unassigned-import\nimport './text-encoding-polyfill';\nexport function decode(bytes, encoding = 'utf8') {\n    const decoder = new TextDecoder(encoding);\n    return decoder.decode(bytes);\n}\nconst encoder = new TextEncoder();\nexport function encode(str) {\n    return encoder.encode(str);\n}\n//# sourceMappingURL=text.browser.js.map","import { decode, encode } from './text';\nconst defaultByteLength = 1024 * 8;\nexport class IOBuffer {\n    /**\n     * @param data - The data to construct the IOBuffer with.\n     * If data is a number, it will be the new buffer's length<br>\n     * If data is `undefined`, the buffer will be initialized with a default length of 8Kb<br>\n     * If data is an ArrayBuffer, SharedArrayBuffer, an ArrayBufferView (Typed Array), an IOBuffer instance,\n     * or a Node.js Buffer, a view will be created over the underlying ArrayBuffer.\n     * @param options\n     */\n    constructor(data = defaultByteLength, options = {}) {\n        let dataIsGiven = false;\n        if (typeof data === 'number') {\n            data = new ArrayBuffer(data);\n        }\n        else {\n            dataIsGiven = true;\n            this.lastWrittenByte = data.byteLength;\n        }\n        const offset = options.offset ? options.offset >>> 0 : 0;\n        const byteLength = data.byteLength - offset;\n        let dvOffset = offset;\n        if (ArrayBuffer.isView(data) || data instanceof IOBuffer) {\n            if (data.byteLength !== data.buffer.byteLength) {\n                dvOffset = data.byteOffset + offset;\n            }\n            data = data.buffer;\n        }\n        if (dataIsGiven) {\n            this.lastWrittenByte = byteLength;\n        }\n        else {\n            this.lastWrittenByte = 0;\n        }\n        this.buffer = data;\n        this.length = byteLength;\n        this.byteLength = byteLength;\n        this.byteOffset = dvOffset;\n        this.offset = 0;\n        this.littleEndian = true;\n        this._data = new DataView(this.buffer, dvOffset, byteLength);\n        this._mark = 0;\n        this._marks = [];\n    }\n    /**\n     * Checks if the memory allocated to the buffer is sufficient to store more\n     * bytes after the offset.\n     * @param byteLength - The needed memory in bytes.\n     * @returns `true` if there is sufficient space and `false` otherwise.\n     */\n    available(byteLength = 1) {\n        return this.offset + byteLength <= this.length;\n    }\n    /**\n     * Check if little-endian mode is used for reading and writing multi-byte\n     * values.\n     * @returns `true` if little-endian mode is used, `false` otherwise.\n     */\n    isLittleEndian() {\n        return this.littleEndian;\n    }\n    /**\n     * Set little-endian mode for reading and writing multi-byte values.\n     */\n    setLittleEndian() {\n        this.littleEndian = true;\n        return this;\n    }\n    /**\n     * Check if big-endian mode is used for reading and writing multi-byte values.\n     * @returns `true` if big-endian mode is used, `false` otherwise.\n     */\n    isBigEndian() {\n        return !this.littleEndian;\n    }\n    /**\n     * Switches to big-endian mode for reading and writing multi-byte values.\n     */\n    setBigEndian() {\n        this.littleEndian = false;\n        return this;\n    }\n    /**\n     * Move the pointer n bytes forward.\n     * @param n - Number of bytes to skip.\n     */\n    skip(n = 1) {\n        this.offset += n;\n        return this;\n    }\n    /**\n     * Move the pointer n bytes backward.\n     * @param n - Number of bytes to move back.\n     */\n    back(n = 1) {\n        this.offset -= n;\n        return this;\n    }\n    /**\n     * Move the pointer to the given offset.\n     * @param offset\n     */\n    seek(offset) {\n        this.offset = offset;\n        return this;\n    }\n    /**\n     * Store the current pointer offset.\n     * @see {@link IOBuffer#reset}\n     */\n    mark() {\n        this._mark = this.offset;\n        return this;\n    }\n    /**\n     * Move the pointer back to the last pointer offset set by mark.\n     * @see {@link IOBuffer#mark}\n     */\n    reset() {\n        this.offset = this._mark;\n        return this;\n    }\n    /**\n     * Push the current pointer offset to the mark stack.\n     * @see {@link IOBuffer#popMark}\n     */\n    pushMark() {\n        this._marks.push(this.offset);\n        return this;\n    }\n    /**\n     * Pop the last pointer offset from the mark stack, and set the current\n     * pointer offset to the popped value.\n     * @see {@link IOBuffer#pushMark}\n     */\n    popMark() {\n        const offset = this._marks.pop();\n        if (offset === undefined) {\n            throw new Error('Mark stack empty');\n        }\n        this.seek(offset);\n        return this;\n    }\n    /**\n     * Move the pointer offset back to 0.\n     */\n    rewind() {\n        this.offset = 0;\n        return this;\n    }\n    /**\n     * Make sure the buffer has sufficient memory to write a given byteLength at\n     * the current pointer offset.\n     * If the buffer's memory is insufficient, this method will create a new\n     * buffer (a copy) with a length that is twice (byteLength + current offset).\n     * @param byteLength\n     */\n    ensureAvailable(byteLength = 1) {\n        if (!this.available(byteLength)) {\n            const lengthNeeded = this.offset + byteLength;\n            const newLength = lengthNeeded * 2;\n            const newArray = new Uint8Array(newLength);\n            newArray.set(new Uint8Array(this.buffer));\n            this.buffer = newArray.buffer;\n            this.length = this.byteLength = newLength;\n            this._data = new DataView(this.buffer);\n        }\n        return this;\n    }\n    /**\n     * Read a byte and return false if the byte's value is 0, or true otherwise.\n     * Moves pointer forward by one byte.\n     */\n    readBoolean() {\n        return this.readUint8() !== 0;\n    }\n    /**\n     * Read a signed 8-bit integer and move pointer forward by 1 byte.\n     */\n    readInt8() {\n        return this._data.getInt8(this.offset++);\n    }\n    /**\n     * Read an unsigned 8-bit integer and move pointer forward by 1 byte.\n     */\n    readUint8() {\n        return this._data.getUint8(this.offset++);\n    }\n    /**\n     * Alias for {@link IOBuffer#readUint8}.\n     */\n    readByte() {\n        return this.readUint8();\n    }\n    /**\n     * Read `n` bytes and move pointer forward by `n` bytes.\n     */\n    readBytes(n = 1) {\n        const bytes = new Uint8Array(n);\n        for (let i = 0; i < n; i++) {\n            bytes[i] = this.readByte();\n        }\n        return bytes;\n    }\n    /**\n     * Read a 16-bit signed integer and move pointer forward by 2 bytes.\n     */\n    readInt16() {\n        const value = this._data.getInt16(this.offset, this.littleEndian);\n        this.offset += 2;\n        return value;\n    }\n    /**\n     * Read a 16-bit unsigned integer and move pointer forward by 2 bytes.\n     */\n    readUint16() {\n        const value = this._data.getUint16(this.offset, this.littleEndian);\n        this.offset += 2;\n        return value;\n    }\n    /**\n     * Read a 32-bit signed integer and move pointer forward by 4 bytes.\n     */\n    readInt32() {\n        const value = this._data.getInt32(this.offset, this.littleEndian);\n        this.offset += 4;\n        return value;\n    }\n    /**\n     * Read a 32-bit unsigned integer and move pointer forward by 4 bytes.\n     */\n    readUint32() {\n        const value = this._data.getUint32(this.offset, this.littleEndian);\n        this.offset += 4;\n        return value;\n    }\n    /**\n     * Read a 32-bit floating number and move pointer forward by 4 bytes.\n     */\n    readFloat32() {\n        const value = this._data.getFloat32(this.offset, this.littleEndian);\n        this.offset += 4;\n        return value;\n    }\n    /**\n     * Read a 64-bit floating number and move pointer forward by 8 bytes.\n     */\n    readFloat64() {\n        const value = this._data.getFloat64(this.offset, this.littleEndian);\n        this.offset += 8;\n        return value;\n    }\n    /**\n     * Read a 64-bit signed integer number and move pointer forward by 8 bytes.\n     */\n    readBigInt64() {\n        const value = this._data.getBigInt64(this.offset, this.littleEndian);\n        this.offset += 8;\n        return value;\n    }\n    /**\n     * Read a 64-bit unsigned integer number and move pointer forward by 8 bytes.\n     */\n    readBigUint64() {\n        const value = this._data.getBigUint64(this.offset, this.littleEndian);\n        this.offset += 8;\n        return value;\n    }\n    /**\n     * Read a 1-byte ASCII character and move pointer forward by 1 byte.\n     */\n    readChar() {\n        return String.fromCharCode(this.readInt8());\n    }\n    /**\n     * Read `n` 1-byte ASCII characters and move pointer forward by `n` bytes.\n     */\n    readChars(n = 1) {\n        let result = '';\n        for (let i = 0; i < n; i++) {\n            result += this.readChar();\n        }\n        return result;\n    }\n    /**\n     * Read the next `n` bytes, return a UTF-8 decoded string and move pointer\n     * forward by `n` bytes.\n     */\n    readUtf8(n = 1) {\n        return decode(this.readBytes(n));\n    }\n    /**\n     * Read the next `n` bytes, return a string decoded with `encoding` and move pointer\n     * forward by `n` bytes.\n     * If no encoding is passed, the function is equivalent to @see {@link IOBuffer#readUtf8}\n     */\n    decodeText(n = 1, encoding = 'utf-8') {\n        return decode(this.readBytes(n), encoding);\n    }\n    /**\n     * Write 0xff if the passed value is truthy, 0x00 otherwise and move pointer\n     * forward by 1 byte.\n     */\n    writeBoolean(value) {\n        this.writeUint8(value ? 0xff : 0x00);\n        return this;\n    }\n    /**\n     * Write `value` as an 8-bit signed integer and move pointer forward by 1 byte.\n     */\n    writeInt8(value) {\n        this.ensureAvailable(1);\n        this._data.setInt8(this.offset++, value);\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as an 8-bit unsigned integer and move pointer forward by 1\n     * byte.\n     */\n    writeUint8(value) {\n        this.ensureAvailable(1);\n        this._data.setUint8(this.offset++, value);\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * An alias for {@link IOBuffer#writeUint8}.\n     */\n    writeByte(value) {\n        return this.writeUint8(value);\n    }\n    /**\n     * Write all elements of `bytes` as uint8 values and move pointer forward by\n     * `bytes.length` bytes.\n     */\n    writeBytes(bytes) {\n        this.ensureAvailable(bytes.length);\n        for (let i = 0; i < bytes.length; i++) {\n            this._data.setUint8(this.offset++, bytes[i]);\n        }\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 16-bit signed integer and move pointer forward by 2\n     * bytes.\n     */\n    writeInt16(value) {\n        this.ensureAvailable(2);\n        this._data.setInt16(this.offset, value, this.littleEndian);\n        this.offset += 2;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 16-bit unsigned integer and move pointer forward by 2\n     * bytes.\n     */\n    writeUint16(value) {\n        this.ensureAvailable(2);\n        this._data.setUint16(this.offset, value, this.littleEndian);\n        this.offset += 2;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 32-bit signed integer and move pointer forward by 4\n     * bytes.\n     */\n    writeInt32(value) {\n        this.ensureAvailable(4);\n        this._data.setInt32(this.offset, value, this.littleEndian);\n        this.offset += 4;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 32-bit unsigned integer and move pointer forward by 4\n     * bytes.\n     */\n    writeUint32(value) {\n        this.ensureAvailable(4);\n        this._data.setUint32(this.offset, value, this.littleEndian);\n        this.offset += 4;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 32-bit floating number and move pointer forward by 4\n     * bytes.\n     */\n    writeFloat32(value) {\n        this.ensureAvailable(4);\n        this._data.setFloat32(this.offset, value, this.littleEndian);\n        this.offset += 4;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 64-bit floating number and move pointer forward by 8\n     * bytes.\n     */\n    writeFloat64(value) {\n        this.ensureAvailable(8);\n        this._data.setFloat64(this.offset, value, this.littleEndian);\n        this.offset += 8;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 64-bit signed bigint and move pointer forward by 8\n     * bytes.\n     */\n    writeBigInt64(value) {\n        this.ensureAvailable(8);\n        this._data.setBigInt64(this.offset, value, this.littleEndian);\n        this.offset += 8;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write `value` as a 64-bit unsigned bigint and move pointer forward by 8\n     * bytes.\n     */\n    writeBigUint64(value) {\n        this.ensureAvailable(8);\n        this._data.setBigUint64(this.offset, value, this.littleEndian);\n        this.offset += 8;\n        this._updateLastWrittenByte();\n        return this;\n    }\n    /**\n     * Write the charCode of `str`'s first character as an 8-bit unsigned integer\n     * and move pointer forward by 1 byte.\n     */\n    writeChar(str) {\n        return this.writeUint8(str.charCodeAt(0));\n    }\n    /**\n     * Write the charCodes of all `str`'s characters as 8-bit unsigned integers\n     * and move pointer forward by `str.length` bytes.\n     */\n    writeChars(str) {\n        for (let i = 0; i < str.length; i++) {\n            this.writeUint8(str.charCodeAt(i));\n        }\n        return this;\n    }\n    /**\n     * UTF-8 encode and write `str` to the current pointer offset and move pointer\n     * forward according to the encoded length.\n     */\n    writeUtf8(str) {\n        return this.writeBytes(encode(str));\n    }\n    /**\n     * Export a Uint8Array view of the internal buffer.\n     * The view starts at the byte offset and its length\n     * is calculated to stop at the last written byte or the original length.\n     */\n    toArray() {\n        return new Uint8Array(this.buffer, this.byteOffset, this.lastWrittenByte);\n    }\n    /**\n     * Update the last written byte offset\n     * @private\n     */\n    _updateLastWrittenByte() {\n        if (this.offset > this.lastWrittenByte) {\n            this.lastWrittenByte = this.offset;\n        }\n    }\n}\n//# sourceMappingURL=IOBuffer.js.map","/**\n * Throws a non-valid NetCDF exception if the statement it's true\n * @ignore\n * @param {boolean} statement - Throws if true\n * @param {string} reason - Reason to throw\n */\nexport function notNetcdf(statement, reason) {\n  if (statement) {\n    throw new TypeError(`Not a valid NetCDF v3.x file: ${reason}`);\n  }\n}\n\n/**\n * Moves 1, 2, or 3 bytes to next 4-byte boundary\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n */\nexport function padding(buffer) {\n  if (buffer.offset % 4 !== 0) {\n    buffer.skip(4 - (buffer.offset % 4));\n  }\n}\n\n/**\n * Reads the name\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @return {string} - Name\n */\nexport function readName(buffer) {\n  // Read name\n  let nameLength = buffer.readUint32();\n  let name = buffer.readChars(nameLength);\n\n  // validate name\n  // TODO\n\n  // Apply padding\n  padding(buffer);\n  return name;\n}\n","import { notNetcdf } from \"./utils.js\";\n\nconst types = {\n  BYTE: 1,\n  CHAR: 2,\n  SHORT: 3,\n  INT: 4,\n  FLOAT: 5,\n  DOUBLE: 6,\n};\n\n/**\n * Parse a number into their respective type\n * @ignore\n * @param {number} type - integer that represents the type\n * @return {string} - parsed value of the type\n */\nexport function num2str(type) {\n  switch (Number(type)) {\n    case types.BYTE:\n      return \"byte\";\n    case types.CHAR:\n      return \"char\";\n    case types.SHORT:\n      return \"short\";\n    case types.INT:\n      return \"int\";\n    case types.FLOAT:\n      return \"float\";\n    case types.DOUBLE:\n      return \"double\";\n    /* istanbul ignore next */\n    default:\n      return \"undefined\";\n  }\n}\n\n/**\n * Parse a number type identifier to his size in bytes\n * @ignore\n * @param {number} type - integer that represents the type\n * @return {number} -size of the type\n */\nexport function num2bytes(type) {\n  switch (Number(type)) {\n    case types.BYTE:\n      return 1;\n    case types.CHAR:\n      return 1;\n    case types.SHORT:\n      return 2;\n    case types.INT:\n      return 4;\n    case types.FLOAT:\n      return 4;\n    case types.DOUBLE:\n      return 8;\n    /* istanbul ignore next */\n    default:\n      return -1;\n  }\n}\n\n/**\n * Reverse search of num2str\n * @ignore\n * @param {string} type - string that represents the type\n * @return {number} - parsed value of the type\n */\nexport function str2num(type) {\n  switch (String(type)) {\n    case \"byte\":\n      return types.BYTE;\n    case \"char\":\n      return types.CHAR;\n    case \"short\":\n      return types.SHORT;\n    case \"int\":\n      return types.INT;\n    case \"float\":\n      return types.FLOAT;\n    case \"double\":\n      return types.DOUBLE;\n    /* istanbul ignore next */\n    default:\n      return -1;\n  }\n}\n\n/**\n * Auxiliary function to read numeric data\n * @ignore\n * @param {number} size - Size of the element to read\n * @param {function} bufferReader - Function to read next value\n * @return {Array<number>|number}\n */\nfunction readNumber(size, bufferReader) {\n  if (size !== 1) {\n    let numbers = new Array(size);\n    for (let i = 0; i < size; i++) {\n      numbers[i] = bufferReader();\n    }\n    return numbers;\n  } else {\n    return bufferReader();\n  }\n}\n\n/**\n * Given a type and a size reads the next element\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @param {number} type - Type of the data to read\n * @param {number} size - Size of the element to read\n * @return {string|Array<number>|number}\n */\nexport function readType(buffer, type, size) {\n  switch (type) {\n    case types.BYTE:\n      return buffer.readBytes(size);\n    case types.CHAR:\n      return trimNull(buffer.readChars(size));\n    case types.SHORT:\n      return readNumber(size, buffer.readInt16.bind(buffer));\n    case types.INT:\n      return readNumber(size, buffer.readInt32.bind(buffer));\n    case types.FLOAT:\n      return readNumber(size, buffer.readFloat32.bind(buffer));\n    case types.DOUBLE:\n      return readNumber(size, buffer.readFloat64.bind(buffer));\n    /* istanbul ignore next */\n    default:\n      notNetcdf(true, `non valid type ${type}`);\n      return undefined;\n  }\n}\n\n/**\n * Removes null terminate value\n * @ignore\n * @param {string} value - String to trim\n * @return {string} - Trimmed string\n */\nfunction trimNull(value) {\n  if (value.charCodeAt(value.length - 1) === 0) {\n    return value.substring(0, value.length - 1);\n  }\n  return value;\n}\n","import { num2str, readType } from \"./types.js\";\nimport { padding, notNetcdf, readName } from \"./utils.js\";\n\n// Grammar constants\nconst ZERO = 0;\nconst NC_DIMENSION = 10;\nconst NC_VARIABLE = 11;\nconst NC_ATTRIBUTE = 12;\n\n/**\n * Read the header of the file\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @param {number} version - Version of the file\n * @return {object} - Object with the fields:\n *  * `recordDimension`: Number with the length of record dimension\n *  * `dimensions`: List of dimensions\n *  * `globalAttributes`: List of global attributes\n *  * `variables`: List of variables\n */\nexport function header(buffer, version) {\n  // Length of record dimension\n  // sum of the varSize's of all the record variables.\n  let header = { recordDimension: { length: buffer.readUint32() } };\n\n  // Version\n  header.version = version;\n\n  // List of dimensions\n  let dimList = dimensionsList(buffer);\n  header.recordDimension.id = dimList.recordId; // id of the unlimited dimension\n  header.recordDimension.name = dimList.recordName; // name of the unlimited dimension\n  header.dimensions = dimList.dimensions;\n\n  // List of global attributes\n  header.globalAttributes = attributesList(buffer);\n\n  // List of variables\n  let variables = variablesList(buffer, dimList.recordId, version);\n  header.variables = variables.variables;\n  header.recordDimension.recordStep = variables.recordStep;\n\n  return header;\n}\n\nconst NC_UNLIMITED = 0;\n\n/**\n * List of dimensions\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @return {object} - Ojbect containing the following properties:\n *  * `dimensions` that is an array of dimension object:\n *  * `name`: String with the name of the dimension\n *  * `size`: Number with the size of the dimension dimensions: dimensions\n *  * `recordId`: the id of the dimension that has unlimited size or undefined,\n *  * `recordName`: name of the dimension that has unlimited size\n */\nfunction dimensionsList(buffer) {\n  let recordId, recordName;\n  const dimList = buffer.readUint32();\n  let dimensions;\n  if (dimList === ZERO) {\n    notNetcdf(\n      buffer.readUint32() !== ZERO,\n      \"wrong empty tag for list of dimensions\"\n    );\n    return [];\n  } else {\n    notNetcdf(dimList !== NC_DIMENSION, \"wrong tag for list of dimensions\");\n\n    // Length of dimensions\n    const dimensionSize = buffer.readUint32();\n    dimensions = new Array(dimensionSize);\n    for (let dim = 0; dim < dimensionSize; dim++) {\n      // Read name\n      let name = readName(buffer);\n\n      // Read dimension size\n      const size = buffer.readUint32();\n      if (size === NC_UNLIMITED) {\n        // in netcdf 3 one field can be of size unlimmited\n        recordId = dim;\n        recordName = name;\n      }\n\n      dimensions[dim] = {\n        name,\n        size,\n      };\n    }\n  }\n  return {\n    dimensions,\n    recordId,\n    recordName,\n  };\n}\n\n/**\n * List of attributes\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @return {Array<object>} - List of attributes with:\n *  * `name`: String with the name of the attribute\n *  * `type`: String with the type of the attribute\n *  * `value`: A number or string with the value of the attribute\n */\nfunction attributesList(buffer) {\n  const gAttList = buffer.readUint32();\n  let attributes;\n  if (gAttList === ZERO) {\n    notNetcdf(\n      buffer.readUint32() !== ZERO,\n      \"wrong empty tag for list of attributes\"\n    );\n    return [];\n  } else {\n    notNetcdf(gAttList !== NC_ATTRIBUTE, \"wrong tag for list of attributes\");\n\n    // Length of attributes\n    const attributeSize = buffer.readUint32();\n    attributes = new Array(attributeSize);\n    for (let gAtt = 0; gAtt < attributeSize; gAtt++) {\n      // Read name\n      let name = readName(buffer);\n\n      // Read type\n      let type = buffer.readUint32();\n      notNetcdf(type < 1 || type > 6, `non valid type ${type}`);\n\n      // Read attribute\n      let size = buffer.readUint32();\n      let value = readType(buffer, type, size);\n\n      // Apply padding\n      padding(buffer);\n\n      attributes[gAtt] = {\n        name,\n        type: num2str(type),\n        value,\n      };\n    }\n  }\n  return attributes;\n}\n\n/**\n * List of variables\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @param {number} recordId - Id of the unlimited dimension (also called record dimension)\n *                            This value may be undefined if there is no unlimited dimension\n * @param {number} version - Version of the file\n * @return {object} - Number of recordStep and list of variables with:\n *  * `name`: String with the name of the variable\n *  * `dimensions`: Array with the dimension IDs of the variable\n *  * `attributes`: Array with the attributes of the variable\n *  * `type`: String with the type of the variable\n *  * `size`: Number with the size of the variable\n *  * `offset`: Number with the offset where of the variable begins\n *  * `record`: True if is a record variable, false otherwise (unlimited size)\n */\n\nfunction variablesList(buffer, recordId, version) {\n  const varList = buffer.readUint32();\n  let recordStep = 0;\n  let variables;\n  if (varList === ZERO) {\n    notNetcdf(\n      buffer.readUint32() !== ZERO,\n      \"wrong empty tag for list of variables\"\n    );\n    return [];\n  } else {\n    notNetcdf(varList !== NC_VARIABLE, \"wrong tag for list of variables\");\n\n    // Length of variables\n    const variableSize = buffer.readUint32();\n    variables = new Array(variableSize);\n    for (let v = 0; v < variableSize; v++) {\n      // Read name\n      let name = readName(buffer);\n\n      // Read dimensionality of the variable\n      const dimensionality = buffer.readUint32();\n\n      // Index into the list of dimensions\n      let dimensionsIds = new Array(dimensionality);\n      for (let dim = 0; dim < dimensionality; dim++) {\n        dimensionsIds[dim] = buffer.readUint32();\n      }\n\n      // Read variables size\n      let attributes = attributesList(buffer);\n\n      // Read type\n      let type = buffer.readUint32();\n      notNetcdf(type < 1 && type > 6, `non valid type ${type}`);\n\n      // Read variable size\n      // The 32-bit varSize field is not large enough to contain the size of variables that require\n      // more than 2^32 - 4 bytes, so 2^32 - 1 is used in the varSize field for such variables.\n      const varSize = buffer.readUint32();\n\n      // Read offset\n      let offset = buffer.readUint32();\n      if (version === 2) {\n        notNetcdf(offset > 0, \"offsets larger than 4GB not supported\");\n        offset = buffer.readUint32();\n      }\n\n      let record = false;\n      // Count amount of record variables\n      if (typeof recordId !== \"undefined\" && dimensionsIds[0] === recordId) {\n        recordStep += varSize;\n        record = true;\n      }\n      variables[v] = {\n        name,\n        dimensions: dimensionsIds,\n        attributes,\n        type: num2str(type),\n        size: varSize,\n        offset,\n        record,\n      };\n    }\n  }\n\n  return {\n    variables,\n    recordStep,\n  };\n}\n","export function toString() {\n  let result = [];\n\n  result.push(\"DIMENSIONS\");\n  for (let dimension of this.dimensions) {\n    result.push(`  ${dimension.name.padEnd(30)} = size: ${dimension.size}`);\n  }\n\n  result.push(\"\");\n  result.push(\"GLOBAL ATTRIBUTES\");\n  for (let attribute of this.globalAttributes) {\n    result.push(`  ${attribute.name.padEnd(30)} = ${attribute.value}`);\n  }\n\n  let variables = JSON.parse(JSON.stringify(this.variables));\n  result.push(\"\");\n  result.push(\"VARIABLES:\");\n  for (let variable of variables) {\n    variable.value = this.getDataVariable(variable);\n    let stringify = JSON.stringify(variable.value);\n    if (stringify.length > 50) stringify = stringify.substring(0, 50);\n    if (!isNaN(variable.value.length)) {\n      stringify += ` (length: ${variable.value.length})`;\n    }\n    result.push(`  ${variable.name.padEnd(30)} = ${stringify}`);\n  }\n  return result.join(\"\\n\");\n}\n","import { IOBuffer } from \"iobuffer\";\n\nimport { record, nonRecord } from \"./data.js\";\nimport { header } from \"./header.js\";\nimport { toString } from \"./toString.js\";\nimport { notNetcdf } from \"./utils.js\";\n\n/**\n * Reads a NetCDF v3.x file\n * https://www.unidata.ucar.edu/software/netcdf/docs/file_format_specifications.html\n * @param {ArrayBuffer} data - ArrayBuffer or any Typed Array (including Node.js' Buffer from v4) with the data\n * @constructor\n */\nexport class NetCDFReader {\n  constructor(data) {\n    const buffer = new IOBuffer(data);\n    buffer.setBigEndian();\n\n    // Validate that it's a NetCDF file\n    notNetcdf(buffer.readChars(3) !== \"CDF\", \"should start with CDF\");\n\n    // Check the NetCDF format\n    const version = buffer.readByte();\n    notNetcdf(version > 2, \"unknown version\");\n\n    // Read the header\n    this.header = header(buffer, version);\n    this.buffer = buffer;\n  }\n\n  /**\n   * @return {string} - Version for the NetCDF format\n   */\n  get version() {\n    if (this.header.version === 1) {\n      return \"classic format\";\n    } else {\n      return \"64-bit offset format\";\n    }\n  }\n\n  /**\n   * @return {object} - Metadata for the record dimension\n   *  * `length`: Number of elements in the record dimension\n   *  * `id`: Id number in the list of dimensions for the record dimension\n   *  * `name`: String with the name of the record dimension\n   *  * `recordStep`: Number with the record variables step size\n   */\n  get recordDimension() {\n    return this.header.recordDimension;\n  }\n\n  /**\n   * @return {Array<object>} - List of dimensions with:\n   *  * `name`: String with the name of the dimension\n   *  * `size`: Number with the size of the dimension\n   */\n  get dimensions() {\n    return this.header.dimensions;\n  }\n\n  /**\n   * @return {Array<object>} - List of global attributes with:\n   *  * `name`: String with the name of the attribute\n   *  * `type`: String with the type of the attribute\n   *  * `value`: A number or string with the value of the attribute\n   */\n  get globalAttributes() {\n    return this.header.globalAttributes;\n  }\n\n  /**\n   * Returns the value of an attribute\n   * @param {string} attributeName\n   * @return {string} Value of the attributeName or null\n   */\n  getAttribute(attributeName) {\n    const attribute = this.globalAttributes.find(\n      (val) => val.name === attributeName\n    );\n    if (attribute) return attribute.value;\n    return null;\n  }\n\n  /**\n   * Returns the value of a variable as a string\n   * @param {string} variableName\n   * @return {string} Value of the variable as a string or null\n   */\n  getDataVariableAsString(variableName) {\n    const variable = this.getDataVariable(variableName);\n    if (variable) return variable.join(\"\");\n    return null;\n  }\n\n  /**\n   * @return {Array<object>} - List of variables with:\n   *  * `name`: String with the name of the variable\n   *  * `dimensions`: Array with the dimension IDs of the variable\n   *  * `attributes`: Array with the attributes of the variable\n   *  * `type`: String with the type of the variable\n   *  * `size`: Number with the size of the variable\n   *  * `offset`: Number with the offset where of the variable begins\n   *  * `record`: True if is a record variable, false otherwise\n   */\n  get variables() {\n    return this.header.variables;\n  }\n\n  toString() {\n    return toString.call(this);\n  }\n\n  /**\n   * Retrieves the data for a given variable\n   * @param {string|object} variableName - Name of the variable to search or variable object\n   * @return {Array} - List with the variable values\n   */\n  getDataVariable(variableName) {\n    let variable;\n    if (typeof variableName === \"string\") {\n      // search the variable\n      variable = this.header.variables.find((val) => {\n        return val.name === variableName;\n      });\n    } else {\n      variable = variableName;\n    }\n\n    // throws if variable not found\n    notNetcdf(variable === undefined, `variable not found: ${variableName}`);\n\n    // go to the offset position\n    this.buffer.seek(variable.offset);\n\n    if (variable.record) {\n      // record variable case\n      return record(this.buffer, variable, this.header.recordDimension);\n    } else {\n      // non-record variable case\n      return nonRecord(this.buffer, variable);\n    }\n  }\n\n  /**\n   * Check if a dataVariable exists\n   * @param {string} variableName - Name of the variable to find\n   * @return {boolean}\n   */\n  dataVariableExists(variableName) {\n    const variable = this.header.variables.find((val) => {\n      return val.name === variableName;\n    });\n    return variable !== undefined;\n  }\n\n  /**\n   * Check if an attribute exists\n   * @param {string} attributeName - Name of the attribute to find\n   * @return {boolean}\n   */\n  attributeExists(attributeName) {\n    const attribute = this.globalAttributes.find(\n      (val) => val.name === attributeName\n    );\n    return attribute !== undefined;\n  }\n}\n","import { num2bytes, str2num, readType } from \"./types.js\";\n\n// const STREAMING = 4294967295;\n\n/**\n * Read data for the given non-record variable\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @param {object} variable - Variable metadata\n * @return {Array} - Data of the element\n */\nexport function nonRecord(buffer, variable) {\n  // variable type\n  const type = str2num(variable.type);\n\n  // size of the data\n  let size = variable.size / num2bytes(type);\n\n  // iterates over the data\n  let data = new Array(size);\n  for (let i = 0; i < size; i++) {\n    data[i] = readType(buffer, type, 1);\n  }\n\n  return data;\n}\n\n/**\n * Read data for the given record variable\n * @ignore\n * @param {IOBuffer} buffer - Buffer for the file data\n * @param {object} variable - Variable metadata\n * @param {object} recordDimension - Record dimension metadata\n * @return {Array} - Data of the element\n */\nexport function record(buffer, variable, recordDimension) {\n  // variable type\n  const type = str2num(variable.type);\n  const width = variable.size ? variable.size / num2bytes(type) : 1;\n\n  // size of the data\n  // TODO streaming data\n  let size = recordDimension.length;\n\n  // iterates over the data\n  let data = new Array(size);\n  const step = recordDimension.recordStep;\n\n  for (let i = 0; i < size; i++) {\n    let currentOffset = buffer.offset;\n    data[i] = readType(buffer, type, width);\n    buffer.seek(currentOffset + step);\n  }\n\n  return data;\n}\n"],"names":["decode","bytes","encoding","decoder","TextDecoder","encoder","TextEncoder","IOBuffer","constructor","data","options","dataIsGiven","ArrayBuffer","this","lastWrittenByte","byteLength","offset","dvOffset","isView","buffer","byteOffset","length","littleEndian","_data","DataView","_mark","_marks","available","isLittleEndian","setLittleEndian","isBigEndian","setBigEndian","skip","n","back","seek","mark","reset","pushMark","push","popMark","pop","undefined","Error","rewind","ensureAvailable","newLength","newArray","Uint8Array","set","readBoolean","readUint8","readInt8","getInt8","getUint8","readByte","readBytes","i","readInt16","value","getInt16","readUint16","getUint16","readInt32","getInt32","readUint32","getUint32","readFloat32","getFloat32","readFloat64","getFloat64","readBigInt64","getBigInt64","readBigUint64","getBigUint64","readChar","String","fromCharCode","readChars","result","readUtf8","decodeText","writeBoolean","writeUint8","writeInt8","setInt8","_updateLastWrittenByte","setUint8","writeByte","writeBytes","writeInt16","setInt16","writeUint16","setUint16","writeInt32","setInt32","writeUint32","setUint32","writeFloat32","setFloat32","writeFloat64","setFloat64","writeBigInt64","setBigInt64","writeBigUint64","setBigUint64","writeChar","str","charCodeAt","writeChars","writeUtf8","encode","toArray","notNetcdf","statement","reason","TypeError","padding","readName","nameLength","name","types","num2str","type","Number","num2bytes","str2num","readNumber","size","bufferReader","numbers","Array","readType","substring","trimNull","bind","header","version","recordDimension","dimList","recordId","recordName","dimensions","dimensionSize","dim","dimensionsList","id","globalAttributes","attributesList","variables","varList","recordStep","variableSize","v","dimensionality","dimensionsIds","attributes","varSize","record","variablesList","gAttList","attributeSize","gAtt","toString","dimension","padEnd","attribute","JSON","parse","stringify","variable","getDataVariable","isNaN","join","getAttribute","attributeName","find","val","getDataVariableAsString","variableName","call","width","step","currentOffset","nonRecord","dataVariableExists","attributeExists"],"mappings":"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"}