{"version":3,"file":"formula.cjs","names":["FORMULA_ERRORS","name","value","divideByZero","cycle","syntax","FORMULA_BLANK","kind","formulaNumber","formulaText","formulaBoolean","formulaError","code","isFormulaError","toFormulaValue","raw","undefined","Number","isFinite","Date","getTime","formulaDisplay","String","asNumber","parsed","textOf","firstError","values","find","numbersIn","out","n","push","extreme","numbers","pick","length","mean","reduce","total","round","places","a","b","factor","Math","numeric","fn","truthy","arg","args","index","FUNCTIONS","SUM","MIN","min","MAX","max","AVG","ABS","abs","ROUND","IF","test","AND","every","v","OR","some","NOT","CONCAT","map","join","LEN","UPPER","toUpperCase","LOWER","toLowerCase","COALESCE","compare","left","right","localeCompare","isComparison","op","includes","compareResult","order","arithmetic","applyBinary","error","evaluateFormula","node","scope","key","operand","FORMULA_FUNCTIONS","Object","keys","formulaSortValue","ParseFailure","Error","COMPARISONS","isNameChar","char","test","Cursor","at","constructor","text","skip","length","peek","take","what","startsWith","expect","fail","done","number","start","raw","slice","value","Number","isFinite","string","quote","bracketed","trim","name","message","primary","cursor","inner","expression","kind","key","next","args","push","unary","operand","productOp","undefined","product","left","op","right","additiveOp","sum","concat","find","candidate","parseFormula","body","replace","ok","node","error","formulaRefs","seen","walk","current","includes","argument","evaluateFormula","FORMULA_BLANK","FORMULA_ERRORS","formulaDisplay","formulaError","formulaSortValue","isFormulaError","toFormulaValue","formulaRefs","parseFormula","findCycles","deps","inCycle","Set","state","Map","stack","visit","key","seen","get","member","slice","lastIndexOf","add","set","push","dep","pop","keys","parseAll","specs","parsed","errors","spec","result","formula","node","ok","message","formatValue","value","format","text","buildFormulaColumns","formulaKeys","map","graph","refs","filter","ref","has","cycles","cyclic","stored","row","raw","undefined","valueOf","cycle","syntax","next","readRef","memos","WeakMap","cached","signature","JSON","stringify","forRow","hit","columns","header","accessor","sortValue","exportValue","sortable","MAX_FORMULA_COLUMNS","decodeField","value","decodeURIComponent","serializeFormulaColumns","specs","parts","spec","key","trim","formula","head","encodeURIComponent","header","push","undefined","slice","join","deserializeFormulaColumns","raw","seen","Set","part","split","fields","length","has","add","useCallback","useEffect","useMemo","useRef","useState","useSyncExternalStore","useResolvedAdapter","PARAM_FORMULA","deserializeFormulaColumns","serializeFormulaColumns","FORMULA_URL_WRITE_DEBOUNCE_MS","NO_FORMULAS","useFormulaUrlState","options","urlAdapter","urlSync","urlKey","defaultFormulas","ns","param","resolved","search","onChange","subscribe","getSearch","pending","setPending","flushTimer","formulas","raw","URLSearchParams","get","persist","next","params","value","set","length","delete","setSearch","toString","onFormulasChange","current","clearTimeout","setTimeout","latestRef","last","write"],"sources":["../src/formula/evaluate.ts","../src/formula/parse.ts","../src/formula/formulaColumn.ts","../src/formula/formulaUrlCodec.ts","../src/formula/useFormulaUrlState.ts"],"sourcesContent":["/**\n * Evaluating a parsed formula against a row.\n *\n * Errors are **values**, not exceptions. A spreadsheet showing `#DIV/0!` in\n * one cell is still a working spreadsheet; a table that threw would lose the\n * other nine hundred rows because one of them had a zero in it.\n *\n * A value is a **tagged union** rather than a bare `number | string | …`.\n * That costs a `.kind` at every use and buys two things. An error stops being\n * a string: with sentinel strings, data that genuinely contains the text\n * `#REF!` is indistinguishable from a cell that failed, and every function\n * has to guess which it holds. And every function here returns exactly one\n * type — a helper returning \"a number, or the error explaining why not\" makes\n * each caller re-discriminate by hand, which is precisely where a missed\n * check turns an error into a zero and a wrong total starts looking right.\n */\nimport type { SortableValue } from \"../types\";\nimport type { FormulaNode } from \"./parse\";\n\n/** The error values a formula can produce, spelled as a spreadsheet spells them. */\nexport const FORMULA_ERRORS = {\n  /** A column the formula names does not exist. */\n  name: \"#NAME?\",\n  /** A number was needed and the value was not one. */\n  value: \"#VALUE!\",\n  /** Division by zero. */\n  divideByZero: \"#DIV/0!\",\n  /** The formula depends on itself, directly or through others. */\n  cycle: \"#CYCLE!\",\n  /** The formula could not be parsed at all. */\n  syntax: \"#ERROR!\",\n} as const;\n\n/** One of the error codes above. */\nexport type FormulaErrorCode =\n  (typeof FORMULA_ERRORS)[keyof typeof FORMULA_ERRORS];\n\n/** What a formula evaluates to. */\nexport type FormulaValue =\n  | { readonly kind: \"number\"; readonly value: number }\n  | { readonly kind: \"text\"; readonly value: string }\n  | { readonly kind: \"boolean\"; readonly value: boolean }\n  | { readonly kind: \"blank\" }\n  | { readonly kind: \"error\"; readonly code: FormulaErrorCode };\n\n/** An empty cell. */\nexport const FORMULA_BLANK: FormulaValue = { kind: \"blank\" };\n\n/** A number value. */\nexport function formulaNumber(value: number): FormulaValue {\n  return { kind: \"number\", value };\n}\n\n/** A text value. */\nexport function formulaText(value: string): FormulaValue {\n  return { kind: \"text\", value };\n}\n\n/** A boolean value. */\nexport function formulaBoolean(value: boolean): FormulaValue {\n  return { kind: \"boolean\", value };\n}\n\n/** An error value. */\nexport function formulaError(code: FormulaErrorCode): FormulaValue {\n  return { kind: \"error\", code };\n}\n\n/**\n * Whether a value is an error rather than an answer.\n *\n * @param value - Any formula result.\n * @returns Whether it failed.\n */\nexport function isFormulaError(value: FormulaValue): boolean {\n  return value.kind === \"error\";\n}\n\n/**\n * Turn a raw field off a row into a formula value.\n *\n * Anything the engine has no kind for — an object, a function — is `#VALUE!`\n * rather than its stringification. `[object Object]` in a cell is not a\n * rendering of the data, it is a rendering of the fact that nobody decided\n * what to do, and it would go on to be concatenated into totals and exports.\n *\n * @param raw - The field as it sits on the row.\n * @returns The value a formula sees.\n */\nexport function toFormulaValue(raw: unknown): FormulaValue {\n  if (raw === null || raw === undefined || raw === \"\") return FORMULA_BLANK;\n  if (typeof raw === \"number\") {\n    return formulaNumber(Number.isFinite(raw) ? raw : 0);\n  }\n  if (typeof raw === \"boolean\") return formulaBoolean(raw);\n  if (typeof raw === \"string\") return formulaText(raw);\n  // A date is a number in a spreadsheet, and its time is the number it is.\n  if (raw instanceof Date) return formulaNumber(raw.getTime());\n  return formulaError(FORMULA_ERRORS.value);\n}\n\n/**\n * How a value reads in a cell.\n *\n * @param value - The evaluated value.\n * @returns Its display text; an error shows as its code.\n */\nexport function formulaDisplay(value: FormulaValue): string {\n  switch (value.kind) {\n    case \"number\":\n      return String(value.value);\n    case \"text\":\n      return value.value;\n    case \"boolean\":\n      return value.value ? \"TRUE\" : \"FALSE\";\n    case \"blank\":\n      return \"\";\n    case \"error\":\n      return value.code;\n  }\n}\n\n/** How the evaluator reads a column off the row it was given. */\nexport type FormulaScope = (key: string) => FormulaValue | undefined;\n\n/**\n * The number a value stands for.\n *\n * Blank is zero the way a spreadsheet treats an empty cell, text that parses\n * is its number, and anything else is `#VALUE!`. Returns a value rather than\n * `number | error` so no caller has to re-check which it got.\n */\nfunction asNumber(value: FormulaValue): FormulaValue {\n  switch (value.kind) {\n    case \"number\":\n      return value;\n    case \"boolean\":\n      return formulaNumber(value.value ? 1 : 0);\n    case \"blank\":\n      return formulaNumber(0);\n    case \"error\":\n      return value;\n    case \"text\": {\n      const parsed = Number(value.value);\n      return Number.isFinite(parsed)\n        ? formulaNumber(parsed)\n        : formulaError(FORMULA_ERRORS.value);\n    }\n  }\n}\n\n/** Text, for `&` and the string functions. */\nfunction textOf(value: FormulaValue): string {\n  return formulaDisplay(value);\n}\n\n/** The first error among some values — how errors propagate outward. */\nfunction firstError(values: readonly FormulaValue[]): FormulaValue | undefined {\n  return values.find((value) => value.kind === \"error\");\n}\n\n/**\n * Every number in a list, with non-numbers skipped rather than counted as 0 —\n * a spreadsheet skips a text cell in a SUM. Callers check {@link firstError}\n * FIRST: an error is not a value to skip, it is one to propagate.\n */\nfunction numbersIn(values: readonly FormulaValue[]): number[] {\n  const out: number[] = [];\n  for (const value of values) {\n    const n = asNumber(value);\n    if (n.kind === \"number\") out.push(n.value);\n  }\n  return out;\n}\n\n/** The smallest or largest of some numbers; nothing at all is zero. */\nfunction extreme(\n  numbers: readonly number[],\n  pick: (...values: number[]) => number\n): FormulaValue {\n  return formulaNumber(numbers.length > 0 ? pick(...numbers) : 0);\n}\n\n/** The mean, or the error that says there was nothing to average. */\nfunction mean(numbers: readonly number[]): FormulaValue {\n  // Zero would be a number someone acts on; an error is one they check.\n  if (numbers.length === 0) return formulaError(FORMULA_ERRORS.divideByZero);\n  return formulaNumber(\n    numbers.reduce((total, n) => total + n, 0) / numbers.length\n  );\n}\n\n/** Round to a number of places, propagating either operand's error. */\nfunction round(value: FormulaValue, places: FormulaValue): FormulaValue {\n  const a = asNumber(value);\n  if (a.kind !== \"number\") return a;\n  const b = asNumber(places);\n  if (b.kind !== \"number\") return b;\n  const factor = 10 ** b.value;\n  return formulaNumber(Math.round(a.value * factor) / factor);\n}\n\n/** Apply a unary numeric function, propagating an error operand. */\nfunction numeric(value: FormulaValue, fn: (n: number) => number): FormulaValue {\n  const n = asNumber(value);\n  return n.kind === \"number\" ? formulaNumber(fn(n.value)) : n;\n}\n\n/** Spreadsheet truthiness: zero and empty are false, everything else true. */\nfunction truthy(value: FormulaValue): boolean {\n  switch (value.kind) {\n    case \"boolean\":\n      return value.value;\n    case \"number\":\n      return value.value !== 0;\n    case \"blank\":\n      return false;\n    case \"text\":\n      return value.value !== \"\" && value.value !== \"FALSE\";\n    case \"error\":\n      return false;\n  }\n}\n\n/** The argument at a position, or blank when the caller left it out. */\nfunction arg(args: readonly FormulaValue[], index: number): FormulaValue {\n  return args[index] ?? FORMULA_BLANK;\n}\n\n/** The built-in functions, by upper-case name. */\nconst FUNCTIONS: Record<\n  string,\n  (args: readonly FormulaValue[]) => FormulaValue\n> = {\n  SUM: (args) =>\n    firstError(args) ??\n    formulaNumber(numbersIn(args).reduce((total, n) => total + n, 0)),\n  MIN: (args) => firstError(args) ?? extreme(numbersIn(args), Math.min),\n  MAX: (args) => firstError(args) ?? extreme(numbersIn(args), Math.max),\n  AVG: (args) => firstError(args) ?? mean(numbersIn(args)),\n  ABS: (args) => numeric(arg(args, 0), Math.abs),\n  ROUND: (args) => round(arg(args, 0), arg(args, 1)),\n  IF: (args) => {\n    const test = arg(args, 0);\n    if (test.kind === \"error\") return test;\n    return truthy(test)\n      ? (args[1] ?? formulaBoolean(true))\n      : (args[2] ?? formulaBoolean(false));\n  },\n  AND: (args) =>\n    firstError(args) ?? formulaBoolean(args.every((v) => truthy(v))),\n  OR: (args) => firstError(args) ?? formulaBoolean(args.some((v) => truthy(v))),\n  NOT: (args) => firstError(args) ?? formulaBoolean(!truthy(arg(args, 0))),\n  CONCAT: (args) =>\n    firstError(args) ?? formulaText(args.map((v) => textOf(v)).join(\"\")),\n  LEN: (args) => firstError(args) ?? formulaNumber(textOf(arg(args, 0)).length),\n  UPPER: (args) =>\n    firstError(args) ?? formulaText(textOf(arg(args, 0)).toUpperCase()),\n  LOWER: (args) =>\n    firstError(args) ?? formulaText(textOf(arg(args, 0)).toLowerCase()),\n  // The one function that deliberately does NOT propagate: its whole job is\n  // to answer \"what should I use when this is missing\".\n  COALESCE: (args) =>\n    args.find((value) => value.kind !== \"blank\" && value.kind !== \"error\") ??\n    FORMULA_BLANK,\n};\n\n/** Compare two values the way a spreadsheet does — numbers if both are. */\nfunction compare(left: FormulaValue, right: FormulaValue): number {\n  const a = asNumber(left);\n  const b = asNumber(right);\n  if (a.kind === \"number\" && b.kind === \"number\") return a.value - b.value;\n  return textOf(left).localeCompare(textOf(right));\n}\n\n/** Whether an operator compares rather than computes. */\nfunction isComparison(op: string): boolean {\n  return [\"=\", \"<>\", \"<\", \"<=\", \">\", \">=\"].includes(op);\n}\n\n/** The result of a comparison operator over an ordering. */\nfunction compareResult(op: string, order: number): FormulaValue {\n  switch (op) {\n    case \"=\":\n      return formulaBoolean(order === 0);\n    case \"<>\":\n      return formulaBoolean(order !== 0);\n    case \"<\":\n      return formulaBoolean(order < 0);\n    case \"<=\":\n      return formulaBoolean(order <= 0);\n    case \">\":\n      return formulaBoolean(order > 0);\n    default:\n      return formulaBoolean(order >= 0);\n  }\n}\n\n/** The result of an arithmetic operator over two numbers. */\nfunction arithmetic(op: string, a: number, b: number): FormulaValue {\n  switch (op) {\n    case \"+\":\n      return formulaNumber(a + b);\n    case \"-\":\n      return formulaNumber(a - b);\n    case \"*\":\n      return formulaNumber(a * b);\n    default:\n      // Division. A zero divisor is the error a spreadsheet is famous for,\n      // and returning Infinity instead would be a number nobody can act on.\n      return b === 0\n        ? formulaError(FORMULA_ERRORS.divideByZero)\n        : formulaNumber(a / b);\n  }\n}\n\n/** Apply a binary operator to two already-evaluated values. */\nfunction applyBinary(\n  op: string,\n  left: FormulaValue,\n  right: FormulaValue\n): FormulaValue {\n  const error = firstError([left, right]);\n  if (error) return error;\n  if (op === \"&\") return formulaText(textOf(left) + textOf(right));\n  if (isComparison(op)) return compareResult(op, compare(left, right));\n\n  const a = asNumber(left);\n  if (a.kind !== \"number\") return a;\n  const b = asNumber(right);\n  if (b.kind !== \"number\") return b;\n  return arithmetic(op, a.value, b.value);\n}\n\n/**\n * Evaluate a parsed formula against one row.\n *\n * Never throws. Every failure is one of {@link FORMULA_ERRORS}, and an error\n * anywhere in an expression comes out of it rather than being counted as\n * zero.\n *\n * @param node - The parsed formula.\n * @param scope - Reads a column's value; `undefined` for a column that is not\n *   there, which becomes `#NAME?`.\n * @returns The value for the cell.\n */\nexport function evaluateFormula(\n  node: FormulaNode,\n  scope: FormulaScope\n): FormulaValue {\n  switch (node.kind) {\n    case \"number\":\n      return formulaNumber(node.value);\n    case \"string\":\n      return formulaText(node.value);\n    case \"ref\":\n      return scope(node.key) ?? formulaError(FORMULA_ERRORS.name);\n    case \"unary\":\n      return numeric(evaluateFormula(node.operand, scope), (n) => -n);\n    case \"binary\":\n      return applyBinary(\n        node.op,\n        evaluateFormula(node.left, scope),\n        evaluateFormula(node.right, scope)\n      );\n    case \"call\": {\n      const fn = FUNCTIONS[node.name.toUpperCase()];\n      if (!fn) return formulaError(FORMULA_ERRORS.name);\n      return fn(node.args.map((a) => evaluateFormula(a, scope)));\n    }\n  }\n}\n\n/** The function names the engine knows — for a formula bar's autocomplete. */\nexport const FORMULA_FUNCTIONS: readonly string[] = Object.keys(FUNCTIONS);\n\n/**\n * How a value sorts, for a formula column's `sortValue`.\n *\n * Each kind sorts as what it is: a number numerically, text as text, a boolean\n * with FALSE before TRUE. A key is not the number a value could be coerced to —\n * coercing text to a number gives every row in an `=UPPER(name)` column the\n * same key, and a column where every key is equal is a column whose header\n * does nothing when it is clicked.\n *\n * A blank and an error have no place in an ordering, so both come back as\n * `null`: the table's comparator groups those at the END in either direction,\n * which is where a spreadsheet leaves an error too. Ties among them keep the\n * order the rows already had, so the grouping is deterministic rather than\n * merely consistent-looking.\n *\n * @param value - The evaluated value.\n * @returns The key the table's comparator orders by.\n */\nexport function formulaSortValue(value: FormulaValue): SortableValue {\n  switch (value.kind) {\n    case \"number\":\n      return value.value;\n    case \"text\":\n      return value.value;\n    case \"boolean\":\n      return value.value;\n    case \"blank\":\n    case \"error\":\n      return null;\n  }\n}\n","/**\n * Parsing a spreadsheet formula into a tree.\n *\n * The one rule this file exists to keep: **a formula is text, and it is\n * parsed.** It is never handed to `eval`, `new Function`, or anything else\n * that would run it as JavaScript. A user-typed formula is untrusted input in\n * exactly the way a URL is, and a table that evaluates one has handed the\n * page to whoever typed it — including, in a shared saved view, to whoever\n * sent the link.\n *\n * The grammar is deliberately small, because a formula language grows one\n * \"just add\" at a time until it is a programming language nobody can secure:\n *\n * ```\n * expression → comparison\n * comparison → concat ( (\"=\" | \"<>\" | \"<\" | \"<=\" | \">\" | \">=\") concat )?\n * concat     → sum ( \"&\" sum )*\n * sum        → product ( (\"+\" | \"-\") product )*\n * product    → unary ( (\"*\" | \"/\") unary )*\n * unary      → \"-\" unary | primary\n * primary    → number | string | reference | call | \"(\" expression \")\"\n * call       → NAME \"(\" ( expression ( \",\" expression )* )? \")\"\n * reference  → NAME | \"[\" any-text \"]\"\n * ```\n *\n * `&` concatenates, as it does in a spreadsheet — and it binds BELOW `+` and\n * `-`, also as it does in a spreadsheet: `=\"a\" & 2 + 3` is `\"a5\"`, because the\n * arithmetic finishes before the join. Sharing the additive level instead read\n * it as `(\"a\" & 2) + 3` and answered `#VALUE!`, which is the arithmetic of a\n * language nobody writes formulas in.\n *\n * Bracketed references exist so a column called \"Unit Price\" can be named\n * without inventing an escaping rule for spaces.\n *\n * A parse failure is a returned error, not an exception: the formula bar has\n * to show something useful while someone is still typing, and half a formula\n * is the normal state of one being written.\n */\n\n/** A binary operator the grammar accepts. */\nexport type BinaryOp =\n  | \"+\"\n  | \"-\"\n  | \"*\"\n  | \"/\"\n  | \"&\"\n  | \"=\"\n  | \"<>\"\n  | \"<\"\n  | \"<=\"\n  | \">\"\n  | \">=\";\n\n/** One node of a parsed formula. */\nexport type FormulaNode =\n  | { readonly kind: \"number\"; readonly value: number }\n  | { readonly kind: \"string\"; readonly value: string }\n  | { readonly kind: \"ref\"; readonly key: string }\n  | { readonly kind: \"unary\"; readonly operand: FormulaNode }\n  | {\n      readonly kind: \"binary\";\n      readonly op: BinaryOp;\n      readonly left: FormulaNode;\n      readonly right: FormulaNode;\n    }\n  | {\n      readonly kind: \"call\";\n      readonly name: string;\n      readonly args: readonly FormulaNode[];\n    };\n\n/** What {@link parseFormula} answers with. */\nexport interface ParseResult {\n  /** Whether the text parsed. */\n  readonly ok: boolean;\n  /** The tree, when it did. */\n  readonly node?: FormulaNode;\n  /** What was wrong, when it did not — in words a formula bar can show. */\n  readonly message?: string;\n}\n\n/** Thrown inside the parser and caught at its edge; never escapes. */\nclass ParseFailure extends Error {}\n\n/** The comparison operators, longest first so `<=` wins over `<`. */\nconst COMPARISONS: readonly BinaryOp[] = [\"<>\", \"<=\", \">=\", \"=\", \"<\", \">\"];\n\n/** Whether a character can start or continue an unbracketed name. */\nfunction isNameChar(char: string): boolean {\n  return /[A-Za-z0-9_.]/.test(char);\n}\n\n/**\n * A cursor over the formula text.\n *\n * A hand-written recursive-descent parser rather than a grammar library: the\n * grammar is nine lines, and a dependency that can parse anything is a\n * dependency that can parse more than this is willing to run.\n */\nclass Cursor {\n  private at = 0;\n\n  constructor(private readonly text: string) {}\n\n  /** Skip any run of whitespace. */\n  skip(): void {\n    while (this.at < this.text.length && /\\s/.test(this.text[this.at] ?? \"\")) {\n      this.at++;\n    }\n  }\n\n  /** The character under the cursor, or `\"\"` at the end. */\n  peek(): string {\n    this.skip();\n    return this.text[this.at] ?? \"\";\n  }\n\n  /** Whether the rest starts with this text, and consume it if so. */\n  take(what: string): boolean {\n    this.skip();\n    if (!this.text.startsWith(what, this.at)) return false;\n    this.at += what.length;\n    return true;\n  }\n\n  /** Consume this text or fail with a message naming what was expected. */\n  expect(what: string): void {\n    if (!this.take(what)) this.fail(`expected ${what}`);\n  }\n\n  /** Whether everything has been consumed. */\n  done(): boolean {\n    this.skip();\n    return this.at >= this.text.length;\n  }\n\n  /** Read a number literal. */\n  number(): number {\n    this.skip();\n    const start = this.at;\n    while (/[0-9.]/.test(this.text[this.at] ?? \"\")) this.at++;\n    const raw = this.text.slice(start, this.at);\n    const value = Number(raw);\n    if (!Number.isFinite(value)) this.fail(`\"${raw}\" is not a number`);\n    return value;\n  }\n\n  /** Read a quoted string literal, either quote style. */\n  string(quote: string): string {\n    const start = this.at;\n    while (this.at < this.text.length && this.text[this.at] !== quote) {\n      this.at++;\n    }\n    if (this.at >= this.text.length) this.fail(\"unclosed quote\");\n    const value = this.text.slice(start, this.at);\n    this.at++;\n    return value;\n  }\n\n  /** Read a bracketed name, which may contain anything but `]`. */\n  bracketed(): string {\n    const start = this.at;\n    while (this.at < this.text.length && this.text[this.at] !== \"]\") {\n      this.at++;\n    }\n    if (this.at >= this.text.length) this.fail(\"unclosed [\");\n    const value = this.text.slice(start, this.at).trim();\n    this.at++;\n    if (value === \"\") this.fail(\"empty [] reference\");\n    return value;\n  }\n\n  /** Read a bare name. */\n  name(): string {\n    this.skip();\n    const start = this.at;\n    while (isNameChar(this.text[this.at] ?? \"\")) this.at++;\n    const value = this.text.slice(start, this.at);\n    if (value === \"\") this.fail(`unexpected \"${this.peek()}\"`);\n    return value;\n  }\n\n  /** Give up with a message the formula bar can show. */\n  fail(message: string): never {\n    throw new ParseFailure(message);\n  }\n}\n\n/** `primary → number | string | reference | call | \"(\" expression \")\"` */\nfunction primary(cursor: Cursor): FormulaNode {\n  if (cursor.take(\"(\")) {\n    const inner = expression(cursor);\n    cursor.expect(\")\");\n    return inner;\n  }\n  if (cursor.take('\"')) return { kind: \"string\", value: cursor.string('\"') };\n  if (cursor.take(\"'\")) return { kind: \"string\", value: cursor.string(\"'\") };\n  if (cursor.take(\"[\")) return { kind: \"ref\", key: cursor.bracketed() };\n\n  const next = cursor.peek();\n  if (/[0-9.]/.test(next)) return { kind: \"number\", value: cursor.number() };\n\n  const name = cursor.name();\n  if (!cursor.take(\"(\")) return { kind: \"ref\", key: name };\n\n  const args: FormulaNode[] = [];\n  if (!cursor.take(\")\")) {\n    do {\n      args.push(expression(cursor));\n    } while (cursor.take(\",\"));\n    cursor.expect(\")\");\n  }\n  return { kind: \"call\", name, args };\n}\n\n/** `unary → \"-\" unary | primary` */\nfunction unary(cursor: Cursor): FormulaNode {\n  if (cursor.take(\"-\")) return { kind: \"unary\", operand: unary(cursor) };\n  return primary(cursor);\n}\n\n/** The multiplicative operator at the cursor, if there is one. */\nfunction productOp(cursor: Cursor): BinaryOp | undefined {\n  if (cursor.take(\"*\")) return \"*\";\n  if (cursor.take(\"/\")) return \"/\";\n  return undefined;\n}\n\n/** `product → unary ( (\"*\" | \"/\") unary )*` */\nfunction product(cursor: Cursor): FormulaNode {\n  let left = unary(cursor);\n  for (;;) {\n    const op = productOp(cursor);\n    if (!op) return left;\n    left = { kind: \"binary\", op, left, right: unary(cursor) };\n  }\n}\n\n/** The additive operator at the cursor, if there is one. */\nfunction additiveOp(cursor: Cursor): BinaryOp | undefined {\n  if (cursor.take(\"+\")) return \"+\";\n  if (cursor.take(\"-\")) return \"-\";\n  return undefined;\n}\n\n/** `sum → product ( (\"+\" | \"-\") product )*` */\nfunction sum(cursor: Cursor): FormulaNode {\n  let left = product(cursor);\n  for (;;) {\n    const op = additiveOp(cursor);\n    if (!op) return left;\n    left = { kind: \"binary\", op, left, right: product(cursor) };\n  }\n}\n\n/**\n * `concat → sum ( \"&\" sum )*` — its own level, below the arithmetic and above\n * the comparisons, which is where a spreadsheet puts it. Left-associative, so\n * `=a & b & c` joins in reading order.\n */\nfunction concat(cursor: Cursor): FormulaNode {\n  let left = sum(cursor);\n  while (cursor.take(\"&\")) {\n    left = { kind: \"binary\", op: \"&\", left, right: sum(cursor) };\n  }\n  return left;\n}\n\n/**\n * `comparison → concat ( COMPARISON concat )?` — one level, as spreadsheets\n * have. Both sides join first, so `=\"a\" & \"b\" = \"ab\"` compares two strings\n * rather than concatenating a comparison.\n */\nfunction expression(cursor: Cursor): FormulaNode {\n  const left = concat(cursor);\n  const op = COMPARISONS.find((candidate) => cursor.take(candidate));\n  if (!op) return left;\n  return { kind: \"binary\", op, left, right: concat(cursor) };\n}\n\n/**\n * Parse a formula.\n *\n * A leading `=` is accepted and ignored, because that is how people type one.\n *\n * @param text - The formula as the user typed it.\n * @returns The tree, or the reason it could not be parsed. Never throws.\n */\nexport function parseFormula(text: string): ParseResult {\n  const body = text.trim().replace(/^=/, \"\");\n  if (body.trim() === \"\") return { ok: false, message: \"empty formula\" };\n  const cursor = new Cursor(body);\n  try {\n    const node = expression(cursor);\n    if (!cursor.done()) {\n      return { ok: false, message: `unexpected \"${cursor.peek()}\"` };\n    }\n    return { ok: true, node };\n  } catch (error) {\n    if (error instanceof ParseFailure) {\n      return { ok: false, message: error.message };\n    }\n    throw error;\n  }\n}\n\n/**\n * Every column a formula reads, so a cache knows what to watch.\n *\n * @param node - A parsed formula.\n * @returns The referenced keys, each once, in the order first seen.\n */\nexport function formulaRefs(node: FormulaNode): string[] {\n  const seen: string[] = [];\n  const walk = (current: FormulaNode): void => {\n    switch (current.kind) {\n      case \"ref\":\n        if (!seen.includes(current.key)) seen.push(current.key);\n        return;\n      case \"unary\":\n        walk(current.operand);\n        return;\n      case \"binary\":\n        walk(current.left);\n        walk(current.right);\n        return;\n      case \"call\":\n        for (const argument of current.args) walk(argument);\n        return;\n      default:\n        return;\n    }\n  };\n  walk(node);\n  return seen;\n}\n","/**\n * Turning formulas into columns.\n *\n * Computed columns already gave the table a derivation that sorts, filters\n * and exports on the underlying value rather than the formatted string, and\n * recomputes only when a declared dependency changes. A formula column is a\n * second front end onto that — the user types the derivation instead of a\n * developer writing it — so this builds the same `ColumnDef` rather than a\n * parallel mechanism with its own cache and its own bugs.\n *\n * What formulas add that hand-written derivations cannot have is **cycles**.\n * `a = b + 1` and `b = a + 1` is one keystroke away at all times, and the\n * naive evaluation of it is a stack overflow that takes the page with it. So\n * the cycle is found in the dependency graph before anything is evaluated,\n * and every column in it renders `#CYCLE!` — a report rather than a hang.\n */\nimport type { ColumnDef } from \"../types\";\nimport {\n  evaluateFormula,\n  FORMULA_BLANK,\n  FORMULA_ERRORS,\n  formulaDisplay,\n  formulaError,\n  formulaSortValue,\n  type FormulaValue,\n  isFormulaError,\n  toFormulaValue,\n} from \"./evaluate\";\nimport { formulaRefs, parseFormula, type ParseResult } from \"./parse\";\n\n/** One user-typed formula column. */\nexport interface FormulaColumnSpec {\n  /** Column key — also the name other formulas reference it by. */\n  key: string;\n  /** Header caption. Defaults to the key. */\n  header?: string;\n  /** The formula text, as the user typed it. A leading `=` is fine. */\n  formula: string;\n  /** Format the result for display. The raw value still sorts and exports. */\n  format?: (value: FormulaValue) => string;\n}\n\n/** What {@link buildFormulaColumns} reports back. */\nexport interface FormulaColumnsResult<TRow> {\n  /** The columns, ready to concatenate with the declared ones. */\n  columns: readonly ColumnDef<TRow>[];\n  /** Formulas that would not parse, by key, with the parser's message. */\n  errors: Readonly<Record<string, string>>;\n  /** Keys that take part in a dependency cycle, if any. */\n  cycles: readonly string[];\n}\n\n/** The keys involved in any cycle among the formula columns. */\nfunction findCycles(deps: ReadonlyMap<string, readonly string[]>): string[] {\n  const inCycle = new Set<string>();\n  const state = new Map<string, \"visiting\" | \"done\">();\n  const stack: string[] = [];\n\n  const visit = (key: string): void => {\n    const seen = state.get(key);\n    if (seen === \"done\") return;\n    if (seen === \"visiting\") {\n      // Everything from where this key first appeared to here is the loop.\n      for (const member of stack.slice(stack.lastIndexOf(key))) {\n        inCycle.add(member);\n      }\n      return;\n    }\n    state.set(key, \"visiting\");\n    stack.push(key);\n    for (const dep of deps.get(key) ?? []) visit(dep);\n    stack.pop();\n    state.set(key, \"done\");\n  };\n\n  for (const key of deps.keys()) visit(key);\n  return [...inCycle];\n}\n\n/** What {@link parseAll} hands back. */\ninterface ParsedSpecs {\n  parsed: Map<string, ParseResult>;\n  deps: Map<string, string[]>;\n  errors: Record<string, string>;\n}\n\n/** Parse every spec once, collecting what failed. */\nfunction parseAll(specs: readonly FormulaColumnSpec[]): ParsedSpecs {\n  const parsed = new Map<string, ParseResult>();\n  const deps = new Map<string, string[]>();\n  const errors: Record<string, string> = {};\n  for (const spec of specs) {\n    const result = parseFormula(spec.formula);\n    parsed.set(spec.key, result);\n    deps.set(spec.key, result.node ? formulaRefs(result.node) : []);\n    if (!result.ok) errors[spec.key] = result.message ?? \"invalid formula\";\n  }\n  return { parsed, deps, errors };\n}\n\n/** One cell's text: the host's formatter, except on an error value. */\nfunction formatValue(\n  value: FormulaValue,\n  format: FormulaColumnSpec[\"format\"]\n): string {\n  // An error shows as itself: formatting it as currency or a percentage would\n  // hide which cell went wrong.\n  if (isFormulaError(value)) return formulaDisplay(value);\n  const text: string = format ? format(value) : formulaDisplay(value);\n  return text;\n}\n\n/**\n * Build columns from user-typed formulas.\n *\n * @typeParam TRow - The row type.\n * @param specs - The formula columns, in the order to show them.\n * @returns The columns, plus any formula that would not parse and any cycle.\n */\nexport function buildFormulaColumns<TRow extends object>(\n  specs: readonly FormulaColumnSpec[]\n): FormulaColumnsResult<TRow> {\n  const { parsed, deps, errors } = parseAll(specs);\n\n  // Only formula columns can take part in a cycle: a declared column is a\n  // leaf, because its value does not depend on anything the user typed.\n  const formulaKeys = new Set(specs.map((spec) => spec.key));\n  const graph = new Map<string, string[]>();\n  for (const [key, refs] of deps) {\n    graph.set(\n      key,\n      refs.filter((ref) => formulaKeys.has(ref))\n    );\n  }\n  const cycles = findCycles(graph);\n  const cyclic = new Set(cycles);\n\n  /** A field on the row, or `undefined` when there is no such column. */\n  const stored = (row: TRow, key: string): FormulaValue | undefined => {\n    const raw = (row as Record<string, unknown>)[key];\n    const value: FormulaValue | undefined =\n      raw === undefined ? undefined : toFormulaValue(raw);\n    return value;\n  };\n\n  /**\n   * One formula column's value. Reading another formula column from here is\n   * safe precisely because the cycles are already known and short-circuited.\n   */\n  const valueOf = (row: TRow, key: string, seen: Set<string>): FormulaValue => {\n    if (cyclic.has(key) || seen.has(key)) {\n      return formulaError(FORMULA_ERRORS.cycle);\n    }\n    const result = parsed.get(key);\n    if (!result) return stored(row, key) ?? FORMULA_BLANK;\n    const node = result.node;\n    if (!result.ok || !node) return formulaError(FORMULA_ERRORS.syntax);\n    const next = new Set(seen).add(key);\n    return evaluateFormula(node, (ref) => readRef(row, ref, next));\n  };\n\n  /** One reference: another formula column, or a field on the row. */\n  const readRef = (\n    row: TRow,\n    ref: string,\n    seen: Set<string>\n  ): FormulaValue | undefined => {\n    const value: FormulaValue | undefined = formulaKeys.has(ref)\n      ? valueOf(row, ref, seen)\n      : stored(row, ref);\n    return value;\n  };\n\n  /**\n   * One row's value, memoized per row and per dependency set.\n   *\n   * This is `computed()`'s cache rule, applied here rather than through it:\n   * a formula column needs its display text, its sort key and its export\n   * value to differ — \"30\", 30, \"30\" — and `computed` derives all three from\n   * one value by design. The dependency graph above is still the shared one;\n   * only this memo is local.\n   *\n   * The cache is keyed on the row OBJECT, so update a row by replacing it —\n   * the way React state is written anyway — never by mutating it in place. The\n   * signature covers the fields a formula reads directly, but a formula\n   * reading another FORMULA column holds only that column's name as its\n   * dependency, and a name is not a value: mutating the row underneath leaves\n   * the outer formula showing the answer to the previous data.\n   */\n  interface Memo {\n    deps: string;\n    value: FormulaValue;\n  }\n  const memos = new WeakMap<object, Map<string, Memo>>();\n  const cached = (row: TRow, key: string): FormulaValue => {\n    const signature = JSON.stringify(\n      (deps.get(key) ?? []).map((ref) => stored(row, ref))\n    );\n    const forRow: Map<string, Memo> = memos.get(row) ?? new Map<string, Memo>();\n    memos.set(row, forRow);\n    const hit = forRow.get(key);\n    if (hit?.deps === signature) return hit.value;\n    const value = valueOf(row, key, new Set());\n    forRow.set(key, { deps: signature, value });\n    return value;\n  };\n\n  const columns: ColumnDef<TRow>[] = specs.map((spec) => ({\n    key: spec.key,\n    header: spec.header ?? spec.key,\n    // The cell shows text; the comparator gets the value underneath it, so\n    // \"$1,240.00\" never sorts before \"$90.00\"; the export gets the text a\n    // spreadsheet cell should hold.\n    accessor: (row: TRow) => formatValue(cached(row, spec.key), spec.format),\n    // Sorts on the VALUE, never on the cell text: a number orders numerically\n    // however it is formatted, and text orders as text.\n    sortValue: (row: TRow) => formulaSortValue(cached(row, spec.key)),\n    exportValue: (row: TRow) => formatValue(cached(row, spec.key), spec.format),\n    sortable: true,\n  }));\n\n  return { columns, errors, cycles };\n}\n","/**\n * Formula columns as a URL parameter — the encoding on its own, without the\n * hook that keeps it in sync.\n *\n * A typed formula is the most expensive table state there is to reproduce by\n * hand, because it is not a choice among things the table offers: it is text\n * somebody wrote. It sits in the URL beside sort, filters and the pivot for\n * exactly that reason, and a [saved view](../url/useSavedViews.ts) captures it\n * with the rest.\n *\n * The encoding is one entry per column, `key:formula` (plus `:header` when the\n * header is not the key), entries joined by `;`, every field percent-encoded so\n * a formula may itself contain the delimiters:\n * `formula=total:quantity%20*%20unitPrice:Total`.\n *\n * **Nothing here parses or evaluates a formula.** Reading a URL produces\n * `FormulaColumnSpec`s and stops — the text stays text until the engine is\n * asked for a value, which is the same rule the parser exists to keep. A codec\n * that \"checked\" a formula by running it would have handed the page to whoever\n * sent the link, in the one place that is easiest to do and hardest to notice.\n *\n * A `format` function cannot travel: a function has no URL form. The entry\n * still travels — the formula computes the same value either way, so the link\n * loses the presentation and keeps the column, unlike a pivot's custom\n * aggregator, where the function IS the computation.\n *\n * The codec lives apart from {@link ./useFormulaUrlState} because the two ends\n * of a shared link do not run in the same place: the table writes the parameter\n * in a browser, and a route handler reads it in Node. Keeping the reading half\n * free of React is what lets `@adapttable/core/query` decode the same string a\n * backend never renders.\n */\nimport type { FormulaColumnSpec } from \"./formulaColumn\";\n\n/**\n * How many formula columns one URL may describe.\n *\n * A URL is hostile input, and a formula column is work per row rather than a\n * flag: a hand-edited parameter naming two hundred of them would be a page\n * that renders once, slowly, for no reason anyone asked for. The limit is the\n * same kind of clamp the column-layout codec puts on a width.\n */\nconst MAX_FORMULA_COLUMNS = 24;\n\n/**\n * Decode one field, tolerating the malformed input a hand-edited URL brings.\n *\n * Local rather than shared with `url/serialize`: this module deliberately\n * imports nothing at runtime, because it is one of the two files a backend can\n * read a shared link with in a process where React is not installed.\n */\nfunction decodeField(value: string): string {\n  try {\n    return decodeURIComponent(value);\n  } catch {\n    return value;\n  }\n}\n\n/**\n * Write formula columns as a URL parameter value.\n *\n * @param specs - The columns to serialize, in the order to show them.\n * @returns The parameter value, or `\"\"` when there is nothing to say.\n */\nexport function serializeFormulaColumns(\n  specs: readonly FormulaColumnSpec[]\n): string {\n  const parts: string[] = [];\n  for (const spec of specs) {\n    const key = spec.key.trim();\n    const formula = spec.formula.trim();\n    // A column with no key or no formula is not a column. Writing it would\n    // produce a link that reads back as one entry fewer than it looks.\n    if (key === \"\" || formula === \"\") continue;\n    const head = `${encodeURIComponent(key)}:${encodeURIComponent(formula)}`;\n    const header = spec.header?.trim();\n    parts.push(\n      header === undefined || header === \"\" || header === key\n        ? head\n        : `${head}:${encodeURIComponent(header)}`\n    );\n  }\n  return parts.slice(0, MAX_FORMULA_COLUMNS).join(\";\");\n}\n\n/**\n * Read formula columns back from a URL parameter value.\n *\n * A malformed entry is dropped rather than thrown: a URL is user input, and a\n * hand-edited one should degrade to the columns it still describes instead of\n * an error page. The formula text is carried through untouched and unparsed.\n *\n * @param raw - The parameter value.\n * @returns The columns it describes, in order, each key appearing once.\n */\nexport function deserializeFormulaColumns(\n  raw: string | null\n): FormulaColumnSpec[] {\n  if (!raw) return [];\n  const specs: FormulaColumnSpec[] = [];\n  const seen = new Set<string>();\n  for (const part of raw.split(\";\")) {\n    const fields = part.split(\":\");\n    // Two fields, or three with a header. Anything else is an entry whose\n    // delimiters were not written by this codec, and guessing which field is\n    // the formula is how a link starts computing something else.\n    if (fields.length < 2 || fields.length > 3) continue;\n    const key = decodeField(fields[0] ?? \"\").trim();\n    const formula = decodeField(fields[1] ?? \"\").trim();\n    if (key === \"\" || formula === \"\") continue;\n    // First entry wins: two columns under one key is one column shadowing the\n    // other, and which one won would depend on render order.\n    if (seen.has(key)) continue;\n    seen.add(key);\n    const header = fields.length === 3 ? decodeField(fields[2]!).trim() : \"\";\n    specs.push({ key, formula, ...(header === \"\" ? {} : { header }) });\n    if (specs.length === MAX_FORMULA_COLUMNS) break;\n  }\n  return specs;\n}\n","/**\n * The formula columns in the URL, so a typed column survives a reload and can\n * be sent to someone.\n *\n * Everything else a table holds is a choice among things the table offered. A\n * formula is text somebody wrote, which makes it both the most expensive state\n * to rebuild by hand and the most worth putting in a link — and, once it is in\n * a link, the state that must never be executed on the way back in. The\n * encoding is in {@link ./formulaUrlCodec}, which reads specs and nothing else;\n * evaluation happens later, in the engine, on purpose.\n */\nimport {\n  useCallback,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  useSyncExternalStore,\n} from \"react\";\n\nimport { type UrlStateAdapter, useResolvedAdapter } from \"../url/adapter\";\nimport { PARAM_FORMULA } from \"../url/serialize\";\nimport type { FormulaColumnSpec } from \"./formulaColumn\";\nimport {\n  deserializeFormulaColumns,\n  serializeFormulaColumns,\n} from \"./formulaUrlCodec\";\n\n/**\n * Trailing debounce for URL persistence. A formula bar that writes as it is\n * typed commits one list per keystroke, and `history.replaceState` at that rate\n * trips Safari's limit (~100 calls per 30s, then it throws). Reads stay instant\n * through the optimistic overlay below; only the URL write waits.\n */\nexport const FORMULA_URL_WRITE_DEBOUNCE_MS = 150;\n\n/** Stable identity for \"no formula columns\", so a read cannot churn a memo. */\nconst NO_FORMULAS: readonly FormulaColumnSpec[] = [];\n\n/** What {@link useFormulaUrlState} needs. */\nexport interface UseFormulaUrlStateOptions {\n  /** URL-state backend. Defaults to the browser History API. */\n  urlAdapter?: UrlStateAdapter;\n  /** When `false`, keep the columns in a local memory store. Defaults `true`. */\n  urlSync?: boolean;\n  /** Namespace, when several tables share one URL (`left.formula`). */\n  urlKey?: string;\n  /** The columns applied while the URL carries none. Defaults to none. */\n  defaultFormulas?: readonly FormulaColumnSpec[];\n}\n\n/** The controlled pair to hand a formula bar and {@link buildFormulaColumns}. */\nexport interface UseFormulaUrlStateResult {\n  /** The columns — from the URL, or the default while the URL is silent. */\n  formulas: readonly FormulaColumnSpec[];\n  /** Persist a new list. Wire to whatever adds and removes a column. */\n  onFormulasChange: (next: readonly FormulaColumnSpec[]) => void;\n}\n\n/**\n * Keep the formula columns in the URL.\n *\n * @param options - See {@link UseFormulaUrlStateOptions}.\n * @returns The current columns and a change handler that persists them.\n */\nexport function useFormulaUrlState(\n  options: UseFormulaUrlStateOptions = {}\n): UseFormulaUrlStateResult {\n  const { urlAdapter, urlSync, urlKey, defaultFormulas } = options;\n  const ns = urlKey ? `${urlKey}.` : \"\";\n  const param = `${ns}${PARAM_FORMULA}`;\n  const resolved = useResolvedAdapter(urlAdapter, urlSync ?? true);\n  // Same SSR rule as the other URL hooks: only an explicit adapter is trusted\n  // to be hydration-consistent; the default history adapter hydrates from \"\".\n  const search = useSyncExternalStore(\n    (onChange) => resolved.subscribe(onChange),\n    () => resolved.getSearch(),\n    () => (urlAdapter ? urlAdapter.getSearch() : \"\")\n  );\n  // Optimistic overlay: the list that has not reached the URL yet.\n  const [pending, setPending] = useState<readonly FormulaColumnSpec[] | null>(\n    null\n  );\n  const flushTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  const formulas = useMemo<readonly FormulaColumnSpec[]>(() => {\n    if (pending) return pending;\n    const raw = new URLSearchParams(search).get(param);\n    // Absent means nothing has been said, so the default applies. Present and\n    // empty means someone removed the last column, which is not the same thing.\n    if (raw === null) return defaultFormulas ?? NO_FORMULAS;\n    return deserializeFormulaColumns(raw);\n  }, [pending, search, param, defaultFormulas]);\n\n  const persist = useCallback(\n    (next: readonly FormulaColumnSpec[]) => {\n      const params = new URLSearchParams(resolved.getSearch());\n      const value = serializeFormulaColumns(next);\n      if (value !== \"\") params.set(param, value);\n      else if (defaultFormulas && defaultFormulas.length > 0) {\n        // An emptied list writes the empty marker when there is a default to\n        // displace: deleting the parameter reads back as \"nothing has been\n        // said\", and the removed columns would return on the next read.\n        params.set(param, \"\");\n      } else params.delete(param);\n      resolved.setSearch(params.toString());\n    },\n    [resolved, param, defaultFormulas]\n  );\n\n  const onFormulasChange = useCallback(\n    (next: readonly FormulaColumnSpec[]) => {\n      setPending(next);\n      if (flushTimer.current) clearTimeout(flushTimer.current);\n      flushTimer.current = setTimeout(() => {\n        flushTimer.current = null;\n        persist(next);\n        setPending(null);\n      }, FORMULA_URL_WRITE_DEBOUNCE_MS);\n    },\n    [persist]\n  );\n\n  // Flush a pending list on unmount so a formula typed and navigated away from\n  // is not lost.\n  const latestRef = useRef<{\n    pending: readonly FormulaColumnSpec[] | null;\n    persist: typeof persist;\n  }>({ pending, persist });\n  latestRef.current = { pending, persist };\n  useEffect(\n    () => () => {\n      if (flushTimer.current) {\n        clearTimeout(flushTimer.current);\n        // Invariant: a live timer implies a pending list — the timeout clears\n        // the timer BEFORE it clears `pending`.\n        const { pending: last, persist: write } = latestRef.current;\n        write(last!);\n      }\n    },\n    []\n  );\n\n  return { formulas, onFormulasChange };\n}\n"],"mappings":"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"}