{
  "version": 3,
  "sources": ["../../../../../src/functions/text/left/left.ts"],
  "sourcesContent": [
    "import {\n  FormulaError,\n  type FunctionDefinition,\n  type FunctionEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport { createMidSpilledResult, midOperation } from \"../text-helpers.mjs\";\n\n/**\n * LEFT function - Returns the leftmost characters from a text string\n *\n * Usage: LEFT(text, num_chars)\n *\n * text: The text string to extract characters from.\n * num_chars: The number of characters to extract from the left side of the text.\n *\n * Example: LEFT(\"Hello, World!\", 5) returns \"Hello\"\n *\n * Note:\n * - If num_chars is less than 0, the function returns an error.\n * - If num_chars is greater than the length of text, the function returns the entire text.\n * - Supports dynamic arrays (spilled values) for both arguments\n * - Strict type checking: text must be string, num_chars must be number\n * - Implemented as MID(text, 1, num_chars)\n */\nexport const LEFT: FunctionDefinition = {\n  name: \"LEFT\",\n  evaluate: function (node, context): FunctionEvaluationResult {\n    if (node.args.length < 1 || node.args.length > 2) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"LEFT function takes 1 or 2 arguments\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Evaluate the text argument\n    const textResult = this.evaluateNode(node.args[0]!, context);\n    if (textResult.type === \"error\") {\n      return textResult;\n    }\n\n    // Evaluate the numChars argument (optional, defaults to 1)\n    let numCharsResult: FunctionEvaluationResult;\n    if (node.args.length > 1) {\n      numCharsResult = this.evaluateNode(node.args[1]!, context);\n      if (numCharsResult.type === \"error\") {\n        return numCharsResult;\n      }\n    } else {\n      numCharsResult = {\n        type: \"value\",\n        result: { type: \"number\", value: 1 },\n      };\n    }\n\n    // Create start_num argument (always 1 for LEFT)\n    const startNumResult: FunctionEvaluationResult = {\n      type: \"value\",\n      result: { type: \"number\", value: 1 },\n    };\n\n    // Handle spilled-values inputs using MID's spilled result handler\n    if (textResult.type === \"spilled-values\" || numCharsResult.type === \"spilled-values\") {\n      return createMidSpilledResult.call(this, {\n        textResult,\n        startNumResult,\n        numCharsResult,\n        context,\n      });\n    }\n\n    // Both arguments are single values\n    if (textResult.type === \"awaiting-evaluation\") {\n      return textResult;\n    }\n\n    if (numCharsResult.type === \"awaiting-evaluation\") {\n      return numCharsResult;\n    }\n\n    // Strict type checking - no coercion\n    if (textResult.result.type !== \"string\") {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Text argument must be a string\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    if (numCharsResult.result.type !== \"number\") {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"NumChars argument must be a number\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Use MID operation: LEFT(text, num_chars) = MID(text, 1, num_chars)\n    const result = midOperation(textResult, startNumResult, numCharsResult, context);\n    if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n      return result;\n    }\n    return {\n      type: \"value\",\n      result: result.result,\n    };\n  },\n};"
  ],
  "mappings": ";AAAA;AAAA;AAAA;AAKA;AAmBO,IAAM,OAA2B;AAAA,EACtC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,GAAG;AAAA,MAChD,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,aAAa,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC3D,IAAI,WAAW,SAAS,SAAS;AAAA,MAC/B,OAAO;AAAA,IACT;AAAA,IAGA,IAAI;AAAA,IACJ,IAAI,KAAK,KAAK,SAAS,GAAG;AAAA,MACxB,iBAAiB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,MACzD,IAAI,eAAe,SAAS,SAAS;AAAA,QACnC,OAAO;AAAA,MACT;AAAA,IACF,EAAO;AAAA,MACL,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,UAAU,OAAO,EAAE;AAAA,MACrC;AAAA;AAAA,IAIF,MAAM,iBAA2C;AAAA,MAC/C,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,UAAU,OAAO,EAAE;AAAA,IACrC;AAAA,IAGA,IAAI,WAAW,SAAS,oBAAoB,eAAe,SAAS,kBAAkB;AAAA,MACpF,OAAO,uBAAuB,KAAK,MAAM;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAGA,IAAI,WAAW,SAAS,uBAAuB;AAAA,MAC7C,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,eAAe,SAAS,uBAAuB;AAAA,MACjD,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,WAAW,OAAO,SAAS,UAAU;AAAA,MACvC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,IAAI,eAAe,OAAO,SAAS,UAAU;AAAA,MAC3C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,SAAS,aAAa,YAAY,gBAAgB,gBAAgB,OAAO;AAAA,IAC/E,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,MACpE,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,OAAO;AAAA,IACjB;AAAA;AAEJ;",
  "debugId": "9FEBA907DCD3BA3D64756E2164756E21",
  "names": []
}