{
  "version": 3,
  "sources": ["../src/decode.ts"],
  "sourcesContent": ["import { arr2text, text2arr, arr2hex } from '@substrate-system/uint8-util'\n\nconst INTEGER_START = 0x69  // 'i'\nconst STRING_DELIM = 0x3A  // ':'\nconst DICTIONARY_START = 0x64  // 'd'\nconst LIST_START = 0x6C  // 'l'\nconst END_OF_TYPE = 0x65  // 'e'\n\nexport type Decoded =\n    | Record<string, any>\n    | Array<any>\n    | string\n    | number;\n\nexport interface Decoder {\n    (data:Uint8Array|string):Decoded|null\n    (data:Uint8Array|string, encoding:string):Decoded|null\n    (data:Uint8Array|string, start:number, encoding:string):Decoded|null\n    (data:Uint8Array|string, start:number, end:number, encoding:string):Decoded|null\n    data:Uint8Array|null;\n    bytes:number;\n    position:number;\n    encoding:string|null;\n    next:()=>Record<string, any>|Array<any>|Uint8Array|string|number|null;\n    dictionary:()=>Record<string, any>|null;\n    list:()=>any[];\n    buffer:()=>Uint8Array|string;\n    find:(ch:number)=>number|null;\n    integer:()=>number;\n}\n\n/**\n * Decode bencoded data.\n *\n * @param  {Uint8Array|string} data The buffer to decode\n * @param  {number} [start] Optional start index\n * @param  {number} [end] Optional end index\n * @param  {string} [encoding] Optional encoding type (utf8, etc)\n * @return {Decoded}\n */\nconst decode:Decoder = function decode (\n    data:Uint8Array|string,\n    start?:number|string,\n    end?:number|string,\n    encoding?:string\n):Decoded|null {\n    if (!data || data.length === 0) {\n        throw new Error('Missing data to decode.')\n    }\n\n    if (typeof start !== 'number' && encoding == null) {\n        encoding = start\n        start = undefined\n    }\n\n    if (typeof end !== 'number' && encoding == null) {\n        encoding = end\n        end = undefined\n    }\n\n    decode.position = 0\n    decode.encoding = encoding || null\n\n    decode.data = !(ArrayBuffer.isView(data)) ?\n        text2arr(data) :\n        new Uint8Array(data.slice(\n            start as number|undefined,\n            end as number|undefined)\n        )\n\n    decode.bytes = decode.data.length\n\n    return decode.next()\n}\n\ndecode.bytes = 0\ndecode.position = 0\ndecode.data = null\ndecode.encoding = null\n\ndecode.next = function ():Record<string, any>|Array<any>|Uint8Array|string|number|null {\n    switch (decode.data![decode.position]) {\n        case DICTIONARY_START:\n            return decode.dictionary()\n        case LIST_START:\n            return decode.list()\n        case INTEGER_START:\n            return decode.integer()\n        default:\n            return decode.buffer()\n    }\n}\n\ndecode.find = function (chr:number):number|null {\n    if (!decode.data?.length) return null\n    let i = decode.position\n    const c = decode.data.length\n    const d = decode.data\n\n    while (i < c) {\n        if (d[i] === chr) return i\n        i++\n    }\n\n    throw new Error(\n        'Invalid data: Missing delimiter \"' +\n        String.fromCharCode(chr) + '\" [0x' +\n        chr.toString(16) + ']'\n    )\n}\n\ndecode.dictionary = function ():Record<string, any>|null {\n    if (!decode.data) return null\n    decode.position++\n\n    const dict = {}\n\n    while (decode.data[decode.position] !== END_OF_TYPE) {\n        const buffer = decode.buffer()\n        if (typeof buffer === 'string') {\n            dict[buffer] = decode.next()\n            continue\n        }\n        let key = arr2text(buffer)\n        if (key.includes('\\uFFFD')) key = arr2hex(buffer)\n        dict[key] = decode.next()\n    }\n\n    decode.position++\n\n    return dict\n}\n\ndecode.list = function ():any[] {\n    decode.position++\n\n    const lst:any[] = []\n\n    while (decode.data![decode.position] !== END_OF_TYPE) {\n        lst.push(decode.next())\n    }\n\n    decode.position++\n\n    return lst\n}\n\ndecode.integer = function () {\n    const end = decode.find(END_OF_TYPE)\n    const number = getIntFromBuffer(decode.data, decode.position + 1, end)\n    if (!end) throw new Error('not end')\n\n    decode.position += end + 1 - decode.position\n\n    return number\n}\n\ndecode.buffer = function ():Uint8Array|string {\n    const sep = decode.find(STRING_DELIM)\n    const newIndex = (sep || 0) + 1\n    const length = getIntFromBuffer(decode.data, decode.position, sep)\n    const end = newIndex + length\n\n    decode.position = end\n\n    return decode.encoding ?\n        arr2text(decode.data!.slice(newIndex, end)) :\n        decode.data!.slice(newIndex, end)\n}\n\nexport default decode\n\n/**\n * replaces parseInt(buffer.toString('ascii', start, end)).\n * For strings with less then ~30 charachters, this is actually a lot faster.\n *\n * @param {Uint8Array} data\n * @param {Number} start\n * @param {Number} end\n * @return {Number} calculated number\n */\nfunction getIntFromBuffer (buffer, start, end) {\n    let sum = 0\n    let sign = 1\n\n    for (let i = start; i < end; i++) {\n        const num = buffer[i]\n\n        if (num < 58 && num >= 48) {\n            sum = sum * 10 + (num - 48)\n            continue\n        }\n\n        if (i === start && num === 43) { // +\n            continue\n        }\n\n        if (i === start && num === 45) { // -\n            sign = -1\n            continue\n        }\n\n        if (num === 46) { // .\n            // its a float. break here.\n            break\n        }\n\n        throw new Error('not a number: buffer[' + i + '] = ' + num)\n    }\n\n    return sum * sign\n}\n"],
  "mappings": "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",
  "names": ["decode"]
}
