{
  "version": 3,
  "sources": ["../../../../../src/functions/text/concatenate/concatenate.ts"],
  "sourcesContent": [
    "import {\n  FormulaError,\n  type FunctionDefinition,\n  type FunctionEvaluationResult,\n  type CellString,\n  type CellAddress,\n  type SpreadsheetRange,\n  type SpilledValuesEvaluationResult,\n  type ErrorEvaluationResult,\n  type SingleEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\nimport type { FunctionNode } from \"../../../parser/ast.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * CONCATENATE function - Joins several text strings into one text string\n *\n * Usage: CONCATENATE(text1, text2, ...)\n *\n * text1, text2, ...: Text strings to be joined together.\n *\n * Example: CONCATENATE(\"Hello\", \" \", \"World\") returns \"Hello World\"\n *\n * Note:\n * - Takes 1 or more arguments\n * - Supports type coercion: strings, numbers, and booleans are converted to strings\n * - Numbers: converted to string representation (123 -> \"123\", Infinity -> \"INFINITY\")\n * - Booleans: TRUE -> \"TRUE\", FALSE -> \"FALSE\"\n * - Supports dynamic arrays (spilled values) for arguments\n * - If any argument is a spilled value, the result will be spilled\n */\n\n/**\n * Helper function to convert a cell value to string with type coercion\n */\nfunction coerceToString(\n  result: FunctionEvaluationResult,\n  context: EvaluationContext\n): string | ErrorEvaluationResult {\n  if (result.type !== \"value\") {\n    return {\n      type: \"error\",\n      err: FormulaError.VALUE,\n      message: \"Invalid argument type\",\n      errAddress: context.dependencyNode,\n    };\n  }\n\n  switch (result.result.type) {\n    case \"string\":\n      return result.result.value;\n    case \"number\":\n      // Convert number to string\n      if (result.result.value === Infinity) {\n        return \"INFINITY\";\n      } else if (result.result.value === -Infinity) {\n        return \"-INFINITY\";\n      } else if (isNaN(result.result.value)) {\n        return \"NaN\";\n      } else {\n        return result.result.value.toString();\n      }\n    case \"boolean\":\n      // Convert boolean to string\n      return result.result.value ? \"TRUE\" : \"FALSE\";\n    case \"infinity\":\n      return result.result.sign === \"positive\" ? \"INFINITY\" : \"-INFINITY\";\n    default:\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"Cannot convert argument to string\",\n        errAddress: context.dependencyNode,\n      };\n  }\n}\n\n/**\n * Helper function to perform CONCATENATE operation on evaluated arguments\n */\nfunction concatenateOperation(\n  textResults: FunctionEvaluationResult[],\n  context: EvaluationContext\n): { type: \"value\"; result: CellString } | ErrorEvaluationResult {\n  let result = \"\";\n  for (const textResult of textResults) {\n    const stringValue = coerceToString(textResult, context);\n    if (typeof stringValue === \"object\" && stringValue.type === \"error\") {\n      return stringValue;\n    }\n    result += stringValue;\n  }\n  return { type: \"value\", result: { type: \"string\", value: result } };\n}\n\n/**\n * Helper for creating spilled-values result for CONCATENATE function\n */\nfunction createConcatenateSpilledResult(\n  this: FormulaEvaluator,\n  {\n    textResults,\n    context,\n  }: {\n    textResults: FunctionEvaluationResult[];\n    context: EvaluationContext;\n  }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n  const spilledResults = textResults.filter(\n    (result) => result.type === \"spilled-values\"\n  );\n\n  if (spilledResults.length === 0) {\n    throw new Error(\n      \"createConcatenateSpilledResult called without spilled values\"\n    );\n  }\n\n  return {\n    type: \"spilled-values\",\n    spillArea: (origin: CellAddress): SpreadsheetRange => {\n      // Calculate spill area (union of all spilled ranges)\n      let spillArea: SpreadsheetRange | undefined;\n\n      for (const result of textResults) {\n        if (result.type === \"spilled-values\") {\n          const currentSpillArea = result.spillArea(origin);\n          if (!spillArea) {\n            spillArea = currentSpillArea;\n          } else {\n            spillArea = this.unionRanges(\n              this.projectRange(spillArea, origin),\n              this.projectRange(currentSpillArea, origin)\n            );\n          }\n        }\n      }\n\n      if (!spillArea) {\n        throw new Error(\"No spilled values found\");\n      }\n      return spillArea;\n    },\n    source: \"CONCATENATE with spilled values\",\n    evaluate: (spilledCell, evalContext): SingleEvaluationResult => {\n      // Evaluate all arguments at this spilled position\n      const spilledTextResults: FunctionEvaluationResult[] = [];\n\n      for (const textResult of textResults) {\n        if (textResult.type === \"spilled-values\") {\n          const spillResult = textResult.evaluate(spilledCell, evalContext);\n          if (spillResult === undefined) {\n            return {\n              type: \"error\",\n              err: FormulaError.REF,\n              message: \"The spilled results have not been evaluated\",\n              errAddress: context.dependencyNode,\n            };\n          }\n          if (spillResult.type === \"error\") {\n            return spillResult;\n          }\n          spilledTextResults.push(spillResult);\n        } else {\n          spilledTextResults.push(textResult);\n        }\n      }\n\n      return concatenateOperation(spilledTextResults, context);\n    },\n    evaluateAllCells: (intersectingRange) => {\n      throw new Error(\n        \"WIP: evaluateAllCells for CONCATENATE is not implemented\"\n      );\n    },\n  };\n}\n\n/**\n * CONCATENATE function implementation\n */\nexport const CONCATENATE: FunctionDefinition = {\n  name: \"CONCATENATE\",\n  evaluate: function (\n    node: FunctionNode,\n    context: EvaluationContext\n  ): FunctionEvaluationResult {\n    if (node.args.length < 1) {\n      return {\n        type: \"error\",\n        err: FormulaError.VALUE,\n        message: \"CONCATENATE function requires at least 1 argument\",\n        errAddress: context.dependencyNode,\n      };\n    }\n\n    // Evaluate all arguments\n    const textResults: FunctionEvaluationResult[] = [];\n    for (const arg of node.args) {\n      const result = this.evaluateNode(arg, context);\n      if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n        return result;\n      }\n      textResults.push(result);\n    }\n\n    // Check if any arguments are spilled values\n    const hasSpilledValues = textResults.some(\n      (result) => result.type === \"spilled-values\"\n    );\n\n    if (hasSpilledValues) {\n      return createConcatenateSpilledResult.call(this, {\n        textResults,\n        context,\n      });\n    }\n\n    // All arguments are single values - type coercion will be handled in concatenateOperation\n\n    // Perform concatenation\n    return concatenateOperation(textResults, context);\n  },\n  aliases: [\"CONCAT\"],\n};\n"
  ],
  "mappings": "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",
  "debugId": "E486EB6FD50D339A64756E2164756E21",
  "names": []
}