{"version":3,"file":"exportWriter-CXVl4p8H.cjs","names":["cellSpanMark","colSpan","rowSpan","undefined","bodyCellsHaveRowSpan","cellsByRow","cells","values","cell","spanningArmed","columns","getCellSpan","some","column","clampSpan","value","remaining","Number","isFinite","Math","min","floor","max","columnSpanOf","row","rowSpanOf","resolveCellSpan","args","remainingCols","remainingRows","asked","clipColSpanAtPin","start","pinOffset","startSide","key","side","span","offset","length","next","keyOf","col","markCoverage","origins","covered","origin","set","rowOffset","colOffset","firstWindowedColumn","windowKeys","has","windowedColSpan","startCol","originSpan","options","localRow","firstRowIndex","sectionRows","armed","rowIndex","columnIndex","sectionRowIndex","collectOrigins","rows","Map","windowedOriginCell","rowSpanContinuation","cover","emitRowCells","get","push","buildBodyCells","getRowId","result","markCoveredRectangle","seen","add","coveredAddressSet","Set","rowSpanSignature","map","join","cellsForRow","rowKey","isBrowser","cellText","value","String","Date","Number","isNaN","getTime","toISOString","slice","FORMULA_PREFIX_RE","escapeCell","delimiter","escapeFormulas","text","test","includes","replaceAll","isTypedCell","isFinite","defaultCsvValue","row","column","fromAccessor","accessor","fromSort","sortValue","rowsToCsv","rows","columns","options","getValue","matrixToCsv","headers","map","c","header","key","table","head","join","body","downloadCsv","filename","csv","blob","Blob","type","url","URL","createObjectURL","anchor","document","createElement","href","download","click","revokeObjectURL","coveredAddressSet","spanningArmed","isBrowser","getPath","defaultCsvValue","matrixToCsv","exportCellValue","row","column","exportValue","value","path","key","Date","Number","isNaN","getTime","columnWidthChars","raw","width","pixels","NaN","parseFloat","isFinite","undefined","Math","min","max","tableChrome","columns","headers","map","header","keys","widths","viewRowValues","entry","role","fromValues","values","labelKey","label","buildExportTable","rows","span","chrome","firstRowIndex","view","body","meta","level","summary","Object","length","push","rowMeta","coveredSet","getCellSpan","dataRows","rowIndex","col","has","total","BOM","csvWriter","extension","build","table","escapeFormulas","text","parts","mimeType","defaultExportFilename","writer","downloadExportFile","filename","payload","blob","Blob","type","url","URL","createObjectURL","anchor","document","createElement","href","download","click","revokeObjectURL"],"sources":["../src/rows/cellSpan.ts","../src/export/csv.ts","../src/export/exportWriter.ts"],"sourcesContent":["/**\n * Row and column spanning — one cell list per row, every kit.\n *\n * A span is a rectangle. The origin cell carries `colSpan` / `rowSpan`; every\n * covered cell is omitted from that row's list so a kit just maps the list.\n * Column pins clip a span at the pin boundary (a pinned cell and a scrolling\n * cell cannot share one `<td>`). A column window clips the same way: a span\n * that starts off-screen continues on the first visible column it covers.\n *\n * Mobile cards ignore geometry — a card is a list of fields, not a grid.\n * Spans are derived from data, so there is nothing to put in the URL.\n */\nimport type { PinOffset } from \"../columns/useColumnLayout\";\nimport type { ColumnDef } from \"../types\";\n\n/** What {@link GetCellSpan} may return. Omitted sides default to 1. */\nexport interface CellSpanRequest {\n  colSpan?: number;\n  rowSpan?: number;\n}\n\n/** Arguments {@link GetCellSpan} receives for one origin. */\nexport interface GetCellSpanArgs<TRow> {\n  row: TRow;\n  column: ColumnDef<TRow>;\n  /** Dataset-relative row index (page offset included). */\n  rowIndex: number;\n  /** Index in the full visible column list. */\n  columnIndex: number;\n  /**\n   * Rows in visual body order (pinned top, then scroll, then pinned\n   * bottom). Walk this list for a consecutive merge so pinning a teammate\n   * does not split one Team run into two cells.\n   */\n  sectionRows: readonly TRow[];\n  /** Index of `row` in {@link GetCellSpanArgs.sectionRows}. */\n  sectionRowIndex: number;\n}\n\n/** Host callback that decides a cell's span. */\nexport type GetCellSpan<TRow> = (\n  args: GetCellSpanArgs<TRow>\n) => CellSpanRequest | undefined;\n\n/**\n * How a spanned cell is painted. `\"merged\"` (the default) is the spreadsheet\n * look: centered content, one fill across the span. `\"plain\"` is geometry\n * only — same chrome as a 1×1 cell — so a host can draw a calendar bar\n * themselves.\n */\nexport type CellSpanAppearance = \"merged\" | \"plain\";\n\n/** `\"2x1\"` when this cell owns more than one slot; otherwise nothing. */\nexport function cellSpanMark(\n  colSpan: number,\n  rowSpan: number\n): string | undefined {\n  if (colSpan <= 1 && rowSpan <= 1) return undefined;\n  return `${colSpan}x${rowSpan}`;\n}\n\n/** One body cell a kit renders — covered cells never appear. */\nexport interface BodyCell<TRow> {\n  column: ColumnDef<TRow>;\n  /** Index in the full visible column list — what focus addresses. */\n  columnIndex: number;\n  colSpan: number;\n  rowSpan: number;\n}\n\n/** True when any origin cell is taller than one row. */\nexport function bodyCellsHaveRowSpan(\n  cellsByRow: ReadonlyMap<string, readonly { rowSpan: number }[]>\n): boolean {\n  for (const cells of cellsByRow.values()) {\n    for (const cell of cells) {\n      if (cell.rowSpan > 1) return true;\n    }\n  }\n  return false;\n}\n\n/** True when the host asked for any span. */\nexport function spanningArmed<TRow>(\n  columns: readonly ColumnDef<TRow>[],\n  getCellSpan: GetCellSpan<TRow> | undefined\n): boolean {\n  if (getCellSpan) return true;\n  return columns.some(\n    (column) => column.colSpan !== undefined || column.rowSpan !== undefined\n  );\n}\n\nfunction clampSpan(value: number | undefined, remaining: number): number {\n  if (value === undefined || !Number.isFinite(value) || value < 1) return 1;\n  return Math.min(Math.floor(value), Math.max(1, remaining));\n}\n\nfunction columnSpanOf<TRow>(\n  column: ColumnDef<TRow>,\n  row: TRow\n): number | undefined {\n  return typeof column.colSpan === \"function\"\n    ? column.colSpan(row)\n    : column.colSpan;\n}\n\nfunction rowSpanOf<TRow>(\n  column: ColumnDef<TRow>,\n  row: TRow\n): number | undefined {\n  return typeof column.rowSpan === \"function\"\n    ? column.rowSpan(row)\n    : column.rowSpan;\n}\n\n/** Resolve one origin's span, clamped to what is left of the grid. */\nexport function resolveCellSpan<TRow>(\n  args: GetCellSpanArgs<TRow>,\n  getCellSpan: GetCellSpan<TRow> | undefined,\n  remainingCols: number,\n  remainingRows: number\n): { colSpan: number; rowSpan: number } {\n  const asked = getCellSpan?.(args);\n  return {\n    colSpan: clampSpan(\n      asked?.colSpan ?? columnSpanOf(args.column, args.row),\n      remainingCols\n    ),\n    rowSpan: clampSpan(\n      asked?.rowSpan ?? rowSpanOf(args.column, args.row),\n      remainingRows\n    ),\n  };\n}\n\n/** Clip a column span so it does not cross a pin boundary. */\nexport function clipColSpanAtPin<TRow>(\n  columns: readonly ColumnDef<TRow>[],\n  start: number,\n  colSpan: number,\n  pinOffset?: (key: string) => PinOffset | undefined\n): number {\n  if (!pinOffset || colSpan <= 1) return colSpan;\n  const startSide = pinOffset(columns[start]?.key ?? \"\")?.side;\n  let span = 1;\n  for (let offset = 1; offset < colSpan && start + offset < columns.length; ) {\n    const next = columns[start + offset];\n    if (!next || pinOffset(next.key)?.side !== startSide) break;\n    span += 1;\n    offset += 1;\n  }\n  return span;\n}\n\nfunction keyOf(row: number, col: number): string {\n  return `${row}:${col}`;\n}\n\ninterface Origin {\n  row: number;\n  col: number;\n  colSpan: number;\n  rowSpan: number;\n}\n\nfunction markCoverage(\n  origins: Map<string, Origin>,\n  covered: Map<string, Origin>,\n  origin: Origin\n): void {\n  origins.set(keyOf(origin.row, origin.col), origin);\n  for (let rowOffset = 0; rowOffset < origin.rowSpan; rowOffset += 1) {\n    for (let colOffset = 0; colOffset < origin.colSpan; colOffset += 1) {\n      if (rowOffset === 0 && colOffset === 0) continue;\n      covered.set(\n        keyOf(origin.row + rowOffset, origin.col + colOffset),\n        origin\n      );\n    }\n  }\n}\n\nfunction firstWindowedColumn(\n  origin: Origin,\n  columns: readonly { key: string }[],\n  windowKeys: ReadonlySet<string>\n): number | undefined {\n  for (let offset = 0; offset < origin.colSpan; offset += 1) {\n    const column = columns[origin.col + offset];\n    if (column && windowKeys.has(column.key)) return origin.col + offset;\n  }\n  return undefined;\n}\n\nfunction windowedColSpan(\n  origin: Origin,\n  startCol: number,\n  columns: readonly { key: string }[],\n  windowKeys: ReadonlySet<string>\n): number {\n  let span = 0;\n  for (let col = startCol; col < origin.col + origin.colSpan; col += 1) {\n    const column = columns[col];\n    if (!column || !windowKeys.has(column.key)) break;\n    span += 1;\n  }\n  return Math.max(1, span);\n}\n\nfunction originSpan<TRow>(options: {\n  row: TRow;\n  column: ColumnDef<TRow>;\n  localRow: number;\n  col: number;\n  firstRowIndex: number;\n  remainingCols: number;\n  remainingRows: number;\n  sectionRows: readonly TRow[];\n  getCellSpan: GetCellSpan<TRow> | undefined;\n  armed: boolean;\n}): { colSpan: number; rowSpan: number } {\n  const {\n    row,\n    column,\n    localRow,\n    col,\n    firstRowIndex,\n    remainingCols,\n    remainingRows,\n    sectionRows,\n    getCellSpan,\n    armed,\n  } = options;\n  if (!armed) return { colSpan: 1, rowSpan: 1 };\n  return resolveCellSpan(\n    {\n      row,\n      column,\n      rowIndex: firstRowIndex + localRow,\n      columnIndex: col,\n      sectionRows,\n      sectionRowIndex: localRow,\n    },\n    getCellSpan,\n    remainingCols,\n    remainingRows\n  );\n}\n\nfunction collectOrigins<TRow>(options: {\n  rows: readonly TRow[];\n  columns: readonly ColumnDef<TRow>[];\n  getCellSpan?: GetCellSpan<TRow>;\n  firstRowIndex: number;\n  pinOffset?: (key: string) => PinOffset | undefined;\n}): { origins: Map<string, Origin>; covered: Map<string, Origin> } {\n  const { rows, columns, getCellSpan, firstRowIndex, pinOffset } = options;\n  const origins = new Map<string, Origin>();\n  const covered = new Map<string, Origin>();\n  const armed = spanningArmed(columns, getCellSpan);\n  for (let localRow = 0; localRow < rows.length; localRow += 1) {\n    const row = rows[localRow]!;\n    for (let col = 0; col < columns.length; col += 1) {\n      if (covered.has(keyOf(localRow, col))) continue;\n      const span = originSpan({\n        row,\n        column: columns[col]!,\n        localRow,\n        col,\n        firstRowIndex,\n        remainingCols: columns.length - col,\n        remainingRows: rows.length - localRow,\n        sectionRows: rows,\n        getCellSpan,\n        armed,\n      });\n      markCoverage(origins, covered, {\n        row: localRow,\n        col,\n        colSpan: clipColSpanAtPin(columns, col, span.colSpan, pinOffset),\n        rowSpan: span.rowSpan,\n      });\n    }\n  }\n  return { origins, covered };\n}\n\nfunction windowedOriginCell<TRow>(\n  origin: Origin,\n  columns: readonly ColumnDef<TRow>[],\n  windowKeys: ReadonlySet<string> | undefined\n): BodyCell<TRow> | undefined {\n  const startCol = windowKeys\n    ? firstWindowedColumn(origin, columns, windowKeys)\n    : origin.col;\n  if (startCol === undefined) return undefined;\n  return {\n    column: columns[startCol]!,\n    columnIndex: startCol,\n    colSpan: windowKeys\n      ? windowedColSpan(origin, startCol, columns, windowKeys)\n      : origin.colSpan,\n    rowSpan: origin.rowSpan,\n  };\n}\n\n/** Row-span whose origin sits outside this section (or off the window). */\nfunction rowSpanContinuation<TRow>(\n  cover: Origin | undefined,\n  localRow: number,\n  col: number,\n  columns: readonly ColumnDef<TRow>[],\n  windowKeys: ReadonlySet<string> | undefined\n): BodyCell<TRow> | undefined {\n  if (!cover || !windowKeys || cover.row === localRow) return undefined;\n  if (firstWindowedColumn(cover, columns, windowKeys) !== col) return undefined;\n  if (windowKeys.has(columns[cover.col]?.key ?? \"\")) return undefined;\n  return {\n    column: columns[col]!,\n    columnIndex: col,\n    colSpan: windowedColSpan(cover, col, columns, windowKeys),\n    rowSpan: cover.rowSpan - (localRow - cover.row),\n  };\n}\n\nfunction emitRowCells<TRow>(\n  localRow: number,\n  columns: readonly ColumnDef<TRow>[],\n  origins: Map<string, Origin>,\n  covered: Map<string, Origin>,\n  windowKeys: ReadonlySet<string> | undefined\n): BodyCell<TRow>[] {\n  const cells: BodyCell<TRow>[] = [];\n  for (let col = 0; col < columns.length; col += 1) {\n    const origin = origins.get(keyOf(localRow, col));\n    if (origin) {\n      const cell = windowedOriginCell(origin, columns, windowKeys);\n      if (cell) cells.push(cell);\n      continue;\n    }\n    const cell = rowSpanContinuation(\n      covered.get(keyOf(localRow, col)),\n      localRow,\n      col,\n      columns,\n      windowKeys\n    );\n    if (cell) cells.push(cell);\n  }\n  return cells;\n}\n\n/**\n * Per-row body cells for the visual body (pinned top, scroll, then pinned\n * bottom). A consecutive merge walks that whole list so pinning a teammate\n * does not split one Team run. HTML `rowSpan` still needs those rows in\n * one tbody.\n */\nexport function buildBodyCells<TRow>(options: {\n  rows: readonly TRow[];\n  columns: readonly ColumnDef<TRow>[];\n  getRowId: (row: TRow) => string;\n  getCellSpan?: GetCellSpan<TRow>;\n  firstRowIndex?: number;\n  pinOffset?: (key: string) => PinOffset | undefined;\n  windowKeys?: ReadonlySet<string>;\n}): ReadonlyMap<string, readonly BodyCell<TRow>[]> {\n  const { rows, columns, getRowId, getCellSpan, pinOffset, windowKeys } =\n    options;\n  const result = new Map<string, BodyCell<TRow>[]>();\n  if (columns.length === 0) {\n    for (const row of rows) result.set(getRowId(row), []);\n    return result;\n  }\n  const { origins, covered } = collectOrigins({\n    rows,\n    columns,\n    getCellSpan,\n    firstRowIndex: options.firstRowIndex ?? 0,\n    pinOffset,\n  });\n  for (let localRow = 0; localRow < rows.length; localRow += 1) {\n    result.set(\n      getRowId(rows[localRow]!),\n      emitRowCells(localRow, columns, origins, covered, windowKeys)\n    );\n  }\n  return result;\n}\n\nfunction markCoveredRectangle(\n  covered: Set<string>,\n  seen: Set<string>,\n  localRow: number,\n  col: number,\n  firstRowIndex: number,\n  colSpan: number,\n  rowSpan: number\n): void {\n  for (let rowOffset = 0; rowOffset < rowSpan; rowOffset += 1) {\n    for (let colOffset = 0; colOffset < colSpan; colOffset += 1) {\n      seen.add(keyOf(localRow + rowOffset, col + colOffset));\n      if (rowOffset === 0 && colOffset === 0) continue;\n      covered.add(keyOf(firstRowIndex + localRow + rowOffset, col + colOffset));\n    }\n  }\n}\n\n/** Addresses (`row:col`, dataset-relative) covered by a span, not origins. */\nexport function coveredAddressSet<TRow>(options: {\n  rows: readonly TRow[];\n  columns: readonly ColumnDef<TRow>[];\n  getCellSpan?: GetCellSpan<TRow>;\n  firstRowIndex?: number;\n  pinOffset?: (key: string) => PinOffset | undefined;\n}): ReadonlySet<string> {\n  const { rows, columns, getCellSpan, pinOffset } = options;\n  const firstRowIndex = options.firstRowIndex ?? 0;\n  const covered = new Set<string>();\n  if (!spanningArmed(columns, getCellSpan)) return covered;\n  const seen = new Set<string>();\n  for (let localRow = 0; localRow < rows.length; localRow += 1) {\n    const row = rows[localRow]!;\n    for (let col = 0; col < columns.length; col += 1) {\n      if (seen.has(keyOf(localRow, col))) continue;\n      const span = resolveCellSpan(\n        {\n          row,\n          column: columns[col]!,\n          rowIndex: firstRowIndex + localRow,\n          columnIndex: col,\n          sectionRows: rows,\n          sectionRowIndex: localRow,\n        },\n        getCellSpan,\n        columns.length - col,\n        rows.length - localRow\n      );\n      markCoveredRectangle(\n        covered,\n        seen,\n        localRow,\n        col,\n        firstRowIndex,\n        clipColSpanAtPin(columns, col, span.colSpan, pinOffset),\n        span.rowSpan\n      );\n    }\n  }\n  return covered;\n}\n\n/** Memo digest so a virtualized row repaints when its spans change. */\nexport function rowSpanSignature<TRow>(\n  cells: readonly BodyCell<TRow>[] | undefined\n): string {\n  if (!cells || cells.length === 0) return \"\";\n  return cells\n    .map((cell) => `${cell.column.key}:${cell.colSpan}x${cell.rowSpan}`)\n    .join(\",\");\n}\n\n/** Look up a row's cells; empty when the row is unknown. */\nexport function cellsForRow<TRow>(\n  cellsByRow: ReadonlyMap<string, readonly BodyCell<TRow>[]> | undefined,\n  rowKey: string\n): readonly BodyCell<TRow>[] {\n  return cellsByRow?.get(rowKey) ?? [];\n}\n","import type { ColumnDef } from \"../types\";\nimport { isBrowser } from \"../utils/env\";\n\n/** Options for {@link rowsToCsv}. */\nexport interface RowsToCsvOptions<TRow> {\n  /**\n   * Resolve a cell's CSV value. Defaults to the column's `accessor` when it\n   * yields a primitive, falling back to `sortValue`, else an empty string —\n   * so JSX cells export their underlying value instead of `[object Object]`.\n   */\n  getValue?: (row: TRow, column: ColumnDef<TRow>) => unknown;\n  /** Field delimiter. Defaults to `\",\"`. */\n  delimiter?: string;\n  /**\n   * Neutralise spreadsheet formula injection: string cells beginning with\n   * `=`, `+`, `-`, `@`, tab or carriage return are prefixed with `'` so\n   * Excel and Google Sheets show them as text instead of executing them.\n   * Number and boolean cells are never touched. Disable ONLY when the\n   * output is consumed by machines, never opened in a spreadsheet.\n   * @defaultValue true\n   */\n  escapeFormulas?: boolean;\n}\n\n/** A cell value as text: primitives stringify, a date is its ISO day, anything else is empty. */\nfunction cellText(value: unknown): string {\n  if (typeof value === \"string\") return value;\n  if (typeof value === \"number\" || typeof value === \"boolean\") {\n    return String(value);\n  }\n  if (value instanceof Date && !Number.isNaN(value.getTime())) {\n    return value.toISOString().slice(0, 10);\n  }\n  return \"\";\n}\n\n/** Characters that make a spreadsheet treat a leading cell as a formula. */\nconst FORMULA_PREFIX_RE = /^[=+\\-@\\t\\r]/;\n\n/** RFC-4180 quoting: wrap when the value carries delimiter/quote/newline. */\nfunction escapeCell(\n  value: unknown,\n  delimiter: string,\n  escapeFormulas: boolean\n): string {\n  let text = cellText(value);\n  // Only string values can smuggle formulas — a numeric -5 stays a number.\n  if (\n    escapeFormulas &&\n    typeof value === \"string\" &&\n    FORMULA_PREFIX_RE.test(text)\n  ) {\n    text = `'${text}`;\n  }\n  if (\n    text.includes(delimiter) ||\n    text.includes('\"') ||\n    text.includes(\"\\n\") ||\n    text.includes(\"\\r\")\n  ) {\n    return `\"${text.replaceAll('\"', '\"\"')}\"`;\n  }\n  return text;\n}\n\n/** A value a file can type: a primitive, or a real `Date`. */\nfunction isTypedCell(value: unknown): boolean {\n  if (typeof value === \"string\" || typeof value === \"boolean\") return true;\n  if (typeof value === \"number\") return Number.isFinite(value);\n  return value instanceof Date && !Number.isNaN(value.getTime());\n}\n\n/**\n * How a cell resolves when nothing overrides it: the display value, since a\n * CSV with no other instruction should carry what the table shows.\n *\n * Internal to the export module — exported so the table-level export can fall\n * back to it after checking a column's `exportValue`.\n */\nexport function defaultCsvValue<TRow>(\n  row: TRow,\n  column: ColumnDef<TRow>\n): unknown {\n  const fromAccessor = column.accessor?.(row);\n  if (isTypedCell(fromAccessor)) return fromAccessor;\n  const fromSort = column.sortValue?.(row);\n  return isTypedCell(fromSort) ? fromSort : (fromSort ?? \"\");\n}\n\n/**\n * Serialize rows to CSV using the table's own column definitions: the header\n * row uses each column's string `header` (else its key), and cells resolve\n * via `accessor` → `sortValue`. Pure and headless — pair with\n * {@link downloadCsv} or send the string anywhere.\n *\n * @typeParam TRow - The row type.\n * @param rows - The rows to export (e.g. `source.rows`, or the full set).\n * @param columns - The columns to export, in order.\n * @param options - See {@link RowsToCsvOptions}.\n * @returns The CSV text (no BOM; {@link downloadCsv} adds one for Excel).\n */\nexport function rowsToCsv<TRow>(\n  rows: readonly TRow[],\n  columns: readonly ColumnDef<TRow>[],\n  options: RowsToCsvOptions<TRow> = {}\n): string {\n  const { getValue = defaultCsvValue } = options;\n  return matrixToCsv(\n    {\n      headers: columns.map((c) =>\n        typeof c.header === \"string\" ? c.header : c.key\n      ),\n      rows: rows.map((row) => columns.map((column) => getValue(row, column))),\n    },\n    options\n  );\n}\n\n/**\n * The same CSV, from values that are already resolved.\n *\n * This is the one place that writes CSV. The table-level export resolves its\n * cells once and hands the result to a writer, so routing `rowsToCsv` through\n * here is what keeps the two from ever disagreeing about quoting, line endings\n * or formula escaping.\n *\n * @param table - Headers and one array of values per row.\n * @param options - Delimiter and formula escaping.\n * @returns The CSV text (no BOM).\n */\nexport function matrixToCsv(\n  table: {\n    headers: readonly string[];\n    rows: readonly (readonly unknown[])[];\n  },\n  options: { delimiter?: string; escapeFormulas?: boolean } = {}\n): string {\n  const { delimiter = \",\", escapeFormulas = true } = options;\n  const head = table.headers\n    .map((header) => escapeCell(header, delimiter, escapeFormulas))\n    .join(delimiter);\n  const body = table.rows.map((row) =>\n    row\n      .map((value) => escapeCell(value, delimiter, escapeFormulas))\n      .join(delimiter)\n  );\n  return [head, ...body].join(\"\\r\\n\");\n}\n\n/**\n * Trigger a browser download of CSV text (UTF-8 with BOM, so Excel opens\n * unicode correctly). No-op outside the browser.\n *\n * @param filename - Download name, e.g. `\"people.csv\"`.\n * @param csv - The CSV text from {@link rowsToCsv}.\n */\nexport function downloadCsv(filename: string, csv: string): void {\n  if (!isBrowser()) return;\n  const blob = new Blob([\"\\uFEFF\", csv], { type: \"text/csv;charset=utf-8\" });\n  const url = URL.createObjectURL(blob);\n  const anchor = document.createElement(\"a\");\n  anchor.href = url;\n  anchor.download = filename;\n  anchor.click();\n  URL.revokeObjectURL(url);\n}\n","/**\n * What turns a resolved export into a file.\n *\n * Scopes and formats are separate questions. Which rows and columns leave the\n * table is decided once — page, all, selected, the highlighted range, and any\n * column subset — and a **writer** decides what the bytes look like. That split\n * is what lets one scope API serve CSV and XLSX without either format knowing\n * the other exists, and it is why adding a format later costs a writer rather\n * than a second export pipeline.\n *\n * A writer is handed **resolved values**, not rows and columns. Every format\n * would otherwise repeat the same resolution — a column's `exportValue`, then\n * its accessor, then `sortValue` — and the first one to get it slightly wrong\n * would quietly disagree with the others about what the same table contains.\n * Resolving once puts that beyond doubt, and it makes a writer non-generic:\n * `xlsxWriter()` drops into a table of any row type without a type argument.\n *\n * The other reason formats stay separate is weight. CSV is built in, so it\n * lives here. XLSX is a separate entry (`@adapttable/core/xlsx`) that only an\n * app importing it ever downloads — a table that exports CSV must not ship a\n * ZIP encoder.\n */\nimport {\n  coveredAddressSet,\n  type GetCellSpan,\n  spanningArmed,\n} from \"../rows/cellSpan\";\nimport type { ColumnDef } from \"../types\";\nimport { isBrowser } from \"../utils/env\";\nimport { getPath } from \"../utils/path\";\nimport { defaultCsvValue, matrixToCsv } from \"./csv\";\n\n/**\n * What a structured export row is: a data leaf, a group header, or a\n * total. CSV ignores the distinction; a spreadsheet uses it for outline\n * levels and for which rows are bold.\n */\nexport type ExportRowRole = \"data\" | \"group\" | \"aggregate\";\n\n/** Per-row structure a writer may honour. Aligned with {@link ExportTable.rows}. */\nexport interface ExportRowMeta {\n  /** What this row is. */\n  role: ExportRowRole;\n  /** Outline depth from zero — group headers sit at their grouping level. */\n  level: number;\n}\n\n/**\n * One row of a grouped or tree-shaped export, before values are resolved.\n *\n * A flat table never produces these. When they are present the file follows\n * the view the reader can see — headers, leaves, footers — instead of a\n * denormalised leaf list.\n */\nexport type ExportViewEntry<TRow> =\n  | { role: \"data\"; row: TRow; level: number }\n  | {\n      role: \"group\" | \"aggregate\";\n      label: string;\n      level: number;\n      /** Column that receives the label when that cell would otherwise be empty. */\n      labelKey?: string;\n      values?: Readonly<Partial<Record<string, unknown>>>;\n    };\n\n/**\n * An export after the scopes are applied and the cells are resolved: headers,\n * keys, and one row of values per exported row.\n */\nexport interface ExportTable {\n  /** Column headings, in file order. */\n  headers: readonly string[];\n  /** Column keys, in the same order — for a format that names its fields. */\n  keys: readonly string[];\n  /** One array of values per row, aligned to `headers`. */\n  rows: readonly (readonly unknown[])[];\n  /**\n   * Structure for each row, when the export is a grouped or tree view.\n   * Absent on a flat table, so existing writers keep seeing exactly what\n   * they always did.\n   */\n  rowMeta?: readonly ExportRowMeta[];\n  /**\n   * Suggested character widths, aligned to `headers`. A column that did not\n   * state a width is `undefined` and the writer picks its own default.\n   */\n  widths?: readonly (number | undefined)[];\n}\n\n/** What a writer is given: the resolved export, exactly as it will ship. */\nexport interface ExportWriteContext {\n  /** The values to write. */\n  table: ExportTable;\n  /** The filename the file will be given — for a writer that embeds a title. */\n  filename: string;\n  /** The CSV formula-injection guard; formats without the flaw ignore it. */\n  escapeFormulas?: boolean;\n}\n\n/** A built file, ready to hand to the browser. */\nexport interface ExportPayload {\n  /** The content, in the pieces a `Blob` takes. */\n  parts: readonly BlobPart[];\n  /** MIME type for the download. */\n  mimeType: string;\n  /**\n   * The file as text, for `onAfterExport` and for hosts that keep a copy.\n   * Binary formats leave this empty — their bytes are in `parts`.\n   */\n  text: string;\n}\n\n/** A file format the export button can produce. */\nexport interface ExportWriter {\n  /** Extension used when no filename was given, e.g. `\"xlsx\"`. */\n  extension: string;\n  /** Build the file from the resolved values. */\n  build: (context: ExportWriteContext) => ExportPayload;\n}\n\n/**\n * A column's own `exportValue` wins, because it exists precisely to say the\n * file should carry something other than the screen. Without one, the default\n * display-value resolution stands.\n */\nfunction exportCellValue<TRow>(row: TRow, column: ColumnDef<TRow>): unknown {\n  if (column.exportValue) return column.exportValue(row);\n  const value = defaultCsvValue(row, column);\n  if (value !== \"\") return value;\n  const path = getPath(row, column.key);\n  return path instanceof Date && !Number.isNaN(path.getTime()) ? path : value;\n}\n\n/** Character width a spreadsheet can use, from a column's own `width`. */\nfunction columnWidthChars<TRow>(column: ColumnDef<TRow>): number | undefined {\n  const raw = column.width;\n  let pixels = Number.NaN;\n  if (typeof raw === \"number\") pixels = raw;\n  else if (typeof raw === \"string\") pixels = Number.parseFloat(raw);\n  if (!Number.isFinite(pixels) || pixels <= 0) return undefined;\n  // Excel's width unit is roughly a character. A pixel width divided by\n  // eight is the usual conversion; clamp so a 400px column does not become\n  // a poster and a 20px one does not vanish.\n  return Math.min(40, Math.max(8, pixels / 8));\n}\n\nfunction tableChrome<TRow>(columns: readonly ColumnDef<TRow>[]): {\n  headers: string[];\n  keys: string[];\n  widths: (number | undefined)[];\n} {\n  return {\n    headers: columns.map((column) =>\n      typeof column.header === \"string\" ? column.header : column.key\n    ),\n    keys: columns.map((column) => column.key),\n    widths: columns.map(columnWidthChars),\n  };\n}\n\nfunction viewRowValues<TRow>(\n  entry: ExportViewEntry<TRow>,\n  columns: readonly ColumnDef<TRow>[]\n): unknown[] {\n  if (entry.role === \"data\") {\n    return columns.map((column) => exportCellValue(entry.row, column));\n  }\n  return columns.map((column) => {\n    const fromValues = entry.values?.[column.key];\n    if (fromValues !== undefined) return fromValues;\n    return column.key === entry.labelKey ? entry.label : \"\";\n  });\n}\n\n/**\n * Resolve rows and columns into the values a file carries.\n *\n * Values keep their type — a number stays a number — because a format that can\n * express one should say so, and text is a lossy last resort rather than the\n * only option.\n *\n * @typeParam TRow - The row type.\n * @param rows - The rows a scope resolved to, in table order.\n * @param columns - The columns a scope resolved to, in file order.\n * @returns The resolved table a writer receives.\n */\nexport function buildExportTable<TRow>(\n  rows: readonly TRow[],\n  columns: readonly ColumnDef<TRow>[],\n  span?: {\n    getCellSpan?: GetCellSpan<TRow>;\n    firstRowIndex?: number;\n    view?: readonly ExportViewEntry<TRow>[];\n    summary?: Readonly<Partial<Record<string, unknown>>>;\n  }\n): ExportTable {\n  const chrome = tableChrome(columns);\n  const firstRowIndex = span?.firstRowIndex ?? 0;\n  const view = span?.view;\n  if (view) {\n    const body = view.map((entry) => ({\n      values: viewRowValues(entry, columns),\n      meta: { role: entry.role, level: entry.level } satisfies ExportRowMeta,\n    }));\n    const summary = span?.summary;\n    if (summary && Object.keys(summary).length > 0) {\n      body.push({\n        values: columns.map((column) => summary[column.key] ?? \"\"),\n        meta: { role: \"aggregate\", level: 0 },\n      });\n    }\n    return {\n      ...chrome,\n      rows: body.map((row) => row.values),\n      rowMeta: body.map((row) => row.meta),\n    };\n  }\n  const coveredSet =\n    span?.getCellSpan && spanningArmed(columns, span.getCellSpan)\n      ? coveredAddressSet({\n          rows,\n          columns,\n          getCellSpan: span.getCellSpan,\n          firstRowIndex,\n        })\n      : undefined;\n  const dataRows = rows.map((row, rowIndex) =>\n    columns.map((column, col) => {\n      if (coveredSet?.has(`${firstRowIndex + rowIndex}:${col}`)) return \"\";\n      return exportCellValue(row, column);\n    })\n  );\n  const summary = span?.summary;\n  if (summary && Object.keys(summary).length > 0) {\n    const total = columns.map((column) => summary[column.key] ?? \"\");\n    return {\n      ...chrome,\n      rows: [...dataRows, total],\n      rowMeta: [\n        ...dataRows.map(() => ({ role: \"data\" as const, level: 0 })),\n        { role: \"aggregate\", level: 0 },\n      ],\n    };\n  }\n  return {\n    ...chrome,\n    rows: dataRows,\n  };\n}\n\n/** The UTF-8 byte-order mark, which is what makes Excel read the file as UTF-8. */\nconst BOM = \"\\uFEFF\";\n\n/**\n * The built-in writer: comma-separated text, UTF-8 with a BOM so Excel opens\n * unicode correctly. This is what the export button uses when no writer is\n * given.\n */\nexport const csvWriter: ExportWriter = {\n  extension: \"csv\",\n  build: ({ table, escapeFormulas }) => {\n    const text = matrixToCsv(table, { escapeFormulas });\n    return { parts: [BOM, text], mimeType: \"text/csv;charset=utf-8\", text };\n  },\n};\n\n/** `\"export.xlsx\"` — the name when the caller did not choose one. */\nexport function defaultExportFilename(writer: ExportWriter): string {\n  return `export.${writer.extension}`;\n}\n\n/**\n * Hand a built file to the browser. No-op outside it, so a server render that\n * reaches this does nothing rather than throwing.\n *\n * @param filename - Download name, e.g. `\"people.xlsx\"`.\n * @param payload - The file from {@link ExportWriter.build}.\n */\nexport function downloadExportFile(\n  filename: string,\n  payload: ExportPayload\n): void {\n  if (!isBrowser()) return;\n  const blob = new Blob([...payload.parts], { type: payload.mimeType });\n  const url = URL.createObjectURL(blob);\n  const anchor = document.createElement(\"a\");\n  anchor.href = url;\n  anchor.download = filename;\n  anchor.click();\n  URL.revokeObjectURL(url);\n}\n"],"mappings":"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"}