{"version":3,"sources":["../src/index.ts","../src/components/AIAnalyst.tsx","../src/hooks/useAIAnalyst.ts","../src/components/CalculatedFieldModal.tsx","../src/components/ChartBuilder.tsx","../src/components/ColumnFilter.tsx","../src/components/DateRangeFilter.tsx","../src/components/NumericRangeFilter.tsx","../src/components/DataGrid.tsx","../src/hooks/useExcelGrid.ts","../src/hooks/useGridFeatures.ts","../src/hooks/useLicense.ts","../src/hooks/usePivotTable.ts","../src/components/DrillThroughModal.tsx","../src/components/ExportMenu.tsx","../src/components/PivotConfig.tsx","../src/components/PivotSkeleton.tsx"],"sourcesContent":["/**\n * TinyPivot React\n * A powerful Excel-like data grid and pivot table component for React\n *\n * @packageDocumentation\n */\n\n// Components\nexport { AIAnalyst, ColumnFilter, DataGrid, PivotConfig, PivotSkeleton } from './components'\n\n// Hooks\nexport {\n  configureLicenseSecret,\n  copyToClipboard,\n  enableDemoMode,\n  exportPivotToCSV,\n  exportPivotToXLSX,\n  exportToCSV,\n  exportToXLSX,\n  formatCellValue,\n  formatSelectionForClipboard,\n  getAggregationLabel,\n  getColumnUniqueValues,\n  setLicenseKey,\n  useAIAnalyst,\n  useColumnResize,\n  useExcelGrid,\n  useGlobalSearch,\n  useLicense,\n  usePagination,\n  usePivotTable,\n  useRowSelection,\n} from './hooks'\nexport type { UseAIAnalystOptions } from './hooks'\n\n// Re-export types from core\nexport type {\n  // Pivot Types\n  AggregationFunction,\n  // AI Data Analyst Types\n  AIAnalystConfig,\n  AIColumnSchema,\n  AIConversation,\n  AIConversationUpdateEvent,\n  AIDataLoadedEvent,\n  AIDataSource,\n  AIErrorEvent,\n  AIMessage,\n  AIMessageMetadata,\n  AIQueryExecutedEvent,\n\n  AITableSchema,\n  CellClickEvent,\n\n  // Grid Types\n  ColumnStats,\n  CopyEvent,\n  // Component Props Types\n  DataGridProps,\n  // Drill-through types\n  DrillThroughDescriptor,\n  DrillThroughResult,\n  ExportEvent,\n  ExportOptions,\n  FieldRoleOverrides,\n  FieldStats,\n  // Event Types\n  FilterEvent,\n  GridOptions,\n\n  LicenseInfo,\n  // License Types\n  LicenseType,\n\n  // Feature Types\n  PaginationOptions,\n  PivotCell,\n\n  PivotConfig as PivotConfigType,\n  PivotField,\n  PivotGroupStart,\n  PivotLayout,\n  PivotResult,\n  PivotRowMeta,\n  PivotTableProps,\n  PivotValueField,\n  RowSelectionChangeEvent,\n  SelectionBounds,\n\n  SelectionChangeEvent,\n  SortEvent,\n  XlsxExportOptions,\n} from '@smallwebco/tinypivot-core'\n","/**\n * TinyPivot React - AI Data Analyst Component\n * Split-panel layout: 1/4 chat, 3/4 data preview\n * Each query step shows data visually with expandable SQL\n */\nimport type {\n  AIAnalystConfig,\n  AIConversationUpdateEvent,\n  AIDataLoadedEvent,\n  AIErrorEvent,\n  AIMessage,\n  AIQueryExecutedEvent,\n  AITableSchema,\n  ResolvedTheme,\n} from '@smallwebco/tinypivot-core'\nimport { stripSQLFromContent } from '@smallwebco/tinypivot-core'\nimport React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'\nimport { useAIAnalyst } from '../hooks/useAIAnalyst'\n\ninterface AIAnalystProps {\n  config: AIAnalystConfig\n  theme?: ResolvedTheme\n  onDataLoaded?: (payload: AIDataLoadedEvent) => void\n  onConversationUpdate?: (payload: AIConversationUpdateEvent) => void\n  onQueryExecuted?: (payload: AIQueryExecutedEvent) => void\n  onError?: (payload: AIErrorEvent) => void\n  onViewResults?: (payload: { data: Record<string, unknown>[], query: string }) => void\n}\n\nexport interface AIAnalystHandle {\n  loadFullData: () => Promise<Record<string, unknown>[] | null>\n  selectedDataSource: string | undefined\n}\n\nexport const AIAnalyst = forwardRef<AIAnalystHandle, AIAnalystProps>(({\n  config,\n  theme = 'light',\n  onDataLoaded,\n  onConversationUpdate,\n  onQueryExecuted,\n  onError,\n  onViewResults,\n}, ref) => {\n  const {\n    messages,\n    hasMessages,\n    isLoading,\n    isLoadingTables,\n    schemas,\n    selectedDataSource,\n    selectedDataSourceInfo,\n    lastLoadedData,\n    dataSources,\n    selectDataSource,\n    sendMessage,\n    clearConversation,\n    loadFullData,\n  } = useAIAnalyst({\n    config,\n    onDataLoaded,\n    onConversationUpdate,\n    onQueryExecuted,\n    onError,\n  })\n\n  const isDarkTheme = theme === 'dark' || (typeof theme === 'string' && theme.endsWith('-dark'))\n\n  // Expose methods to parent via ref\n  useImperativeHandle(ref, () => ({\n    loadFullData,\n    selectedDataSource,\n  }), [loadFullData, selectedDataSource])\n\n  const [inputText, setInputText] = useState('')\n  const [searchQuery, setSearchQuery] = useState('')\n  const [selectedMessageId, setSelectedMessageId] = useState<string | null>(null)\n  const [showSqlPanel, setShowSqlPanel] = useState(false)\n  const messagesContainerRef = useRef<HTMLDivElement>(null)\n  const textareaRef = useRef<HTMLTextAreaElement>(null)\n\n  // Filter data sources by search\n  const filteredDataSources = useMemo(() => {\n    if (!searchQuery.trim())\n      return dataSources\n    const q = searchQuery.toLowerCase()\n    return dataSources.filter((ds: { name: string, description?: string, table: string }) =>\n      ds.name.toLowerCase().includes(q)\n      || ds.description?.toLowerCase().includes(q)\n      || ds.table.toLowerCase().includes(q),\n    )\n  }, [dataSources, searchQuery])\n\n  // Get schema for selected data source\n  const currentSchema: AITableSchema | undefined = useMemo(() => {\n    if (!selectedDataSource)\n      return undefined\n    return schemas.get(selectedDataSource)\n  }, [selectedDataSource, schemas])\n\n  // Get data for the selected message (or latest)\n  const previewData = useMemo(() => {\n    if (selectedMessageId) {\n      const msg = messages.find((m: AIMessage) => m.id === selectedMessageId)\n      if (msg?.metadata?.data) {\n        return msg.metadata.data.slice(0, 100)\n      }\n    }\n    if (!lastLoadedData)\n      return []\n    return lastLoadedData.slice(0, 100)\n  }, [selectedMessageId, messages, lastLoadedData])\n\n  // Get full data for the selected message\n  const fullPreviewData = useMemo(() => {\n    if (selectedMessageId) {\n      const msg = messages.find((m: AIMessage) => m.id === selectedMessageId)\n      if (msg?.metadata?.data) {\n        return msg.metadata.data\n      }\n    }\n    return lastLoadedData || []\n  }, [selectedMessageId, messages, lastLoadedData])\n\n  // Get column keys from preview data\n  const previewColumns = useMemo(() => {\n    if (previewData.length > 0) {\n      return Object.keys(previewData[0])\n    }\n    if (currentSchema) {\n      return currentSchema.columns.map((c: { name: string }) => c.name)\n    }\n    return []\n  }, [previewData, currentSchema])\n\n  // Get the selected message's query\n  const selectedQuery = useMemo(() => {\n    if (selectedMessageId) {\n      const msg = messages.find((m: AIMessage) => m.id === selectedMessageId)\n      return msg?.metadata?.query || ''\n    }\n    for (let i = messages.length - 1; i >= 0; i--) {\n      if (messages[i].metadata?.data) {\n        return messages[i].metadata?.query || ''\n      }\n    }\n    return ''\n  }, [selectedMessageId, messages])\n\n  // Scroll to bottom when messages change and auto-select latest with data\n  useEffect(() => {\n    if (messagesContainerRef.current) {\n      messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight\n    }\n    const latestWithData = [...messages].reverse().find((m: AIMessage) => m.metadata?.data)\n    if (latestWithData) {\n      setSelectedMessageId(latestWithData.id)\n    }\n  }, [messages])\n\n  // Auto-resize textarea\n  const autoResizeTextarea = useCallback(() => {\n    if (textareaRef.current) {\n      textareaRef.current.style.height = 'auto'\n      textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 120)}px`\n    }\n  }, [])\n\n  useEffect(() => {\n    autoResizeTextarea()\n  }, [inputText, autoResizeTextarea])\n\n  const handleSubmit = useCallback((e: React.FormEvent) => {\n    e.preventDefault()\n    if (!inputText.trim() || isLoading)\n      return\n    sendMessage(inputText)\n    setInputText('')\n    if (textareaRef.current) {\n      textareaRef.current.style.height = 'auto'\n    }\n  }, [inputText, isLoading, sendMessage])\n\n  const handleKeydown = useCallback((e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n    if (e.key === 'Enter' && !e.shiftKey) {\n      e.preventDefault()\n      if (!inputText.trim() || isLoading)\n        return\n      sendMessage(inputText)\n      setInputText('')\n      if (textareaRef.current) {\n        textareaRef.current.style.height = 'auto'\n      }\n    }\n  }, [inputText, isLoading, sendMessage])\n\n  const handleViewResults = useCallback(() => {\n    if (fullPreviewData.length > 0) {\n      onViewResults?.({ data: fullPreviewData, query: selectedQuery })\n    }\n  }, [fullPreviewData, selectedQuery, onViewResults])\n\n  const selectMessage = useCallback((messageId: string) => {\n    const msg = messages.find((m: AIMessage) => m.id === messageId)\n    if (msg?.metadata?.data) {\n      setSelectedMessageId(messageId)\n    }\n  }, [messages])\n\n  const copyToClipboard = useCallback((text: string) => {\n    navigator.clipboard.writeText(text)\n  }, [])\n\n  const handleClearConversation = useCallback(() => {\n    clearConversation()\n    setSearchQuery('')\n    setSelectedMessageId(null)\n    setShowSqlPanel(false)\n  }, [clearConversation])\n\n  const handleChangeDataSource = useCallback(() => {\n    clearConversation()\n    setSearchQuery('')\n    setSelectedMessageId(null)\n    setShowSqlPanel(false)\n  }, [clearConversation])\n\n  const toggleSqlPanel = useCallback(() => {\n    setShowSqlPanel(prev => !prev)\n  }, [])\n\n  const getColumnTypeIcon = (type: string): string => {\n    const t = type.toLowerCase()\n    if (t.includes('int') || t.includes('float') || t.includes('decimal') || t.includes('number'))\n      return '#'\n    if (t.includes('date') || t.includes('time'))\n      return 'D'\n    if (t.includes('bool'))\n      return '?'\n    return 'T'\n  }\n\n  const formatCellValue = (value: unknown): string => {\n    if (value === null || value === undefined)\n      return ''\n    if (typeof value === 'number') {\n      if (Math.abs(value) >= 1000) {\n        return value.toLocaleString('en-US', { maximumFractionDigits: 2 })\n      }\n      return String(value)\n    }\n    return String(value)\n  }\n\n  const getMessageContent = (message: AIMessage): string => {\n    // Strip SQL blocks and clean up markdown formatting\n    return stripSQLFromContent(message.content)\n      .replace(/\\*\\*/g, '')\n      .replace(/`([^`]+)`/g, '$1')\n      .trim()\n  }\n\n  const hasQueryResult = (message: AIMessage): boolean => {\n    return !!message.metadata?.data && message.metadata.data.length > 0\n  }\n\n  // Render data source picker (full screen)\n  if (!selectedDataSource) {\n    return (\n      <div className={`vpg-ai-analyst ${isDarkTheme ? 'vpg-theme-dark' : ''}`}>\n        <div className=\"vpg-ai-picker-fullscreen\">\n          <div className=\"vpg-ai-picker-content\">\n            <div className=\"vpg-ai-picker-header\">\n              <div className=\"vpg-ai-icon-lg\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                  <path d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z\" />\n                  <circle cx=\"7.5\" cy=\"14.5\" r=\"1.5\" fill=\"currentColor\" />\n                  <circle cx=\"16.5\" cy=\"14.5\" r=\"1.5\" fill=\"currentColor\" />\n                </svg>\n              </div>\n              <h2>AI Data Analyst</h2>\n              <p>Select a data source to start exploring with AI</p>\n            </div>\n\n            {dataSources.length === 0 && !isLoadingTables ? (\n              <div className=\"vpg-ai-empty-state\">\n                <p>No data sources configured.</p>\n                <a\n                  href=\"https://tinypivot.com/docs/ai-analyst\"\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className=\"vpg-ai-docs-link\"\n                >\n                  <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                    <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n                    <polyline points=\"15 3 21 3 21 9\" />\n                    <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n                  </svg>\n                  View Documentation\n                </a>\n              </div>\n            ) : (\n              <>\n                <div className=\"vpg-ai-search\">\n                  <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                    <circle cx=\"11\" cy=\"11\" r=\"8\" />\n                    <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n                  </svg>\n                  <input\n                    type=\"text\"\n                    value={searchQuery}\n                    onChange={e => setSearchQuery(e.target.value)}\n                    placeholder=\"Search data sources...\"\n                    className=\"vpg-ai-search-input\"\n                  />\n                </div>\n                <div className=\"vpg-ai-datasource-grid\">\n                  {filteredDataSources.map((ds: { id: string, name: string, description?: string }) => (\n                    <button\n                      key={ds.id}\n                      className=\"vpg-ai-datasource-card\"\n                      onClick={() => selectDataSource(ds.id)}\n                    >\n                      <div className=\"vpg-ai-datasource-icon\">\n                        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                          <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n                          <path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\" />\n                        </svg>\n                      </div>\n                      <div className=\"vpg-ai-datasource-info\">\n                        <span className=\"vpg-ai-datasource-name\">{ds.name}</span>\n                        {ds.description && (\n                          <span className=\"vpg-ai-datasource-desc\">{ds.description}</span>\n                        )}\n                      </div>\n                    </button>\n                  ))}\n                </div>\n                {filteredDataSources.length === 0 && (\n                  <div className=\"vpg-ai-no-results\">\n                    No data sources match \"\n                    {searchQuery}\n                    \"\n                  </div>\n                )}\n              </>\n            )}\n          </div>\n        </div>\n      </div>\n    )\n  }\n\n  // Render split layout\n  return (\n    <div className={`vpg-ai-analyst ${isDarkTheme ? 'vpg-theme-dark' : ''}`}>\n      <div className=\"vpg-ai-split-layout\">\n        {/* Left Panel: Chat */}\n        <div className=\"vpg-ai-chat-panel\">\n          {/* Chat Header */}\n          <div className=\"vpg-ai-chat-header\">\n            <button\n              className=\"vpg-ai-back-btn\"\n              title=\"Change data source\"\n              onClick={handleChangeDataSource}\n            >\n              <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                <polyline points=\"15 18 9 12 15 6\" />\n              </svg>\n            </button>\n            <div className=\"vpg-ai-chat-title\">\n              <span className=\"vpg-ai-chat-name\">{selectedDataSourceInfo?.name}</span>\n            </div>\n            {hasMessages && (\n              <button\n                className=\"vpg-ai-clear-btn\"\n                title=\"Clear conversation\"\n                onClick={handleClearConversation}\n              >\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                  <polyline points=\"3 6 5 6 21 6\" />\n                  <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n                </svg>\n              </button>\n            )}\n          </div>\n\n          {/* Messages */}\n          <div ref={messagesContainerRef} className=\"vpg-ai-messages\">\n            {/* Welcome message */}\n            {!hasMessages && (\n              <div className=\"vpg-ai-welcome\">\n                <p>Ask questions about your data</p>\n                <div className=\"vpg-ai-suggestions\">\n                  <button onClick={() => sendMessage('Show me a summary of the data')}>\n                    Summary\n                  </button>\n                  <button onClick={() => sendMessage('Show me the top 10 records')}>\n                    Top 10\n                  </button>\n                  <button onClick={() => sendMessage('What are the trends?')}>\n                    Trends\n                  </button>\n                </div>\n              </div>\n            )}\n\n            {/* Message list */}\n            {messages.map((message: AIMessage) => {\n              if (message.role === 'user') {\n                return (\n                  <div key={message.id} className=\"vpg-ai-msg vpg-ai-msg-user\">\n                    <span>{message.content}</span>\n                  </div>\n                )\n              }\n\n              if (hasQueryResult(message)) {\n                return (\n                  <div\n                    key={message.id}\n                    className={`vpg-ai-msg vpg-ai-msg-result ${selectedMessageId === message.id ? 'vpg-ai-msg-selected' : ''}`}\n                    onClick={() => selectMessage(message.id)}\n                  >\n                    {/* Header with result badge and SQL toggle */}\n                    <div className=\"vpg-ai-result-header\">\n                      <div className=\"vpg-ai-result-badge\">\n                        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                          <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\" />\n                          <polyline points=\"22 4 12 14.01 9 11.01\" />\n                        </svg>\n                        <span>\n                          {message.metadata?.rowCount?.toLocaleString()}\n                          {' '}\n                          rows\n                        </span>\n                      </div>\n                      {/* SQL toggle button - toggles right pane SQL panel */}\n                      {message.metadata?.query && (\n                        <button\n                          className={`vpg-ai-sql-toggle ${showSqlPanel && selectedMessageId === message.id ? 'vpg-ai-sql-expanded' : ''}`}\n                          title=\"View SQL query\"\n                          onClick={(e) => {\n                            e.stopPropagation()\n                            toggleSqlPanel()\n                          }}\n                        >\n                          <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                            <polyline points=\"16 18 22 12 16 6\" />\n                            <polyline points=\"8 6 2 12 8 18\" />\n                          </svg>\n                          <span>SQL</span>\n                        </button>\n                      )}\n                    </div>\n                    {/* Full message content (insight from AI) */}\n                    <div className=\"vpg-ai-result-content\">\n                      {getMessageContent(message)}\n                    </div>\n                  </div>\n                )\n              }\n\n              // Regular assistant message\n              return (\n                <div key={message.id} className=\"vpg-ai-msg vpg-ai-msg-assistant\">\n                  <div className=\"vpg-ai-assistant-content\">{getMessageContent(message)}</div>\n                  {message.metadata?.error && (\n                    <div className=\"vpg-ai-msg-error\">\n                      <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                        <circle cx=\"12\" cy=\"12\" r=\"10\" />\n                        <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" />\n                        <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\" />\n                      </svg>\n                      Error\n                    </div>\n                  )}\n                </div>\n              )\n            })}\n\n            {/* Loading indicator */}\n            {isLoading && (\n              <div className=\"vpg-ai-msg vpg-ai-msg-loading\">\n                <div className=\"vpg-ai-typing\">\n                  <span />\n                  <span />\n                  <span />\n                </div>\n              </div>\n            )}\n          </div>\n\n          {/* Input Area */}\n          <div className=\"vpg-ai-input-area\">\n            <form className=\"vpg-ai-input-form\" onSubmit={handleSubmit}>\n              <textarea\n                ref={textareaRef}\n                className=\"vpg-ai-input\"\n                placeholder=\"Ask about your data...\"\n                disabled={isLoading}\n                rows={1}\n                value={inputText}\n                onChange={e => setInputText(e.target.value)}\n                onKeyDown={handleKeydown}\n              />\n              <button\n                type=\"submit\"\n                className=\"vpg-ai-send-btn\"\n                disabled={!inputText.trim() || isLoading}\n                title=\"Send\"\n              >\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                  <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n                  <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n                </svg>\n              </button>\n            </form>\n            {/* Input footer with model name and actions */}\n            <div className=\"vpg-ai-input-footer\">\n              {config.aiModelName && (\n                <span className=\"vpg-ai-model-name\">{config.aiModelName}</span>\n              )}\n              <div className=\"vpg-ai-input-actions\">\n                {fullPreviewData.length > 0 && (\n                  <button\n                    className=\"vpg-ai-action-btn vpg-ai-action-primary\"\n                    title=\"View in Grid tab\"\n                    onClick={handleViewResults}\n                  >\n                    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                      <polyline points=\"9 18 15 12 9 6\" />\n                    </svg>\n                    View in Grid\n                  </button>\n                )}\n              </div>\n            </div>\n          </div>\n        </div>\n\n        {/* Right Panel: Data Scratchpad */}\n        <div className=\"vpg-ai-preview-panel\">\n          {/* Header with schema */}\n          <div className=\"vpg-ai-preview-header\">\n            <div className=\"vpg-ai-preview-title-row\">\n              <h3>{selectedDataSourceInfo?.name}</h3>\n              <div className=\"vpg-ai-preview-meta\">\n                {fullPreviewData.length > 0 && (\n                  <span className=\"vpg-ai-preview-count\">\n                    {fullPreviewData.length.toLocaleString()}\n                    {' '}\n                    rows\n                  </span>\n                )}\n                {selectedQuery && (\n                  <button\n                    className={`vpg-ai-preview-sql-btn ${showSqlPanel ? 'vpg-ai-sql-active' : ''}`}\n                    title=\"Toggle SQL query\"\n                    onClick={toggleSqlPanel}\n                  >\n                    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                      <polyline points=\"16 18 22 12 16 6\" />\n                      <polyline points=\"8 6 2 12 8 18\" />\n                    </svg>\n                    SQL\n                  </button>\n                )}\n                {fullPreviewData.length > 0 && (\n                  <button\n                    className=\"vpg-ai-preview-view-btn\"\n                    title=\"View in Grid\"\n                    onClick={handleViewResults}\n                  >\n                    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                      <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n                      <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n                      <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\" />\n                    </svg>\n                    View in Grid\n                  </button>\n                )}\n              </div>\n            </div>\n            {/* Schema chips in preview header */}\n            {currentSchema && (\n              <div className=\"vpg-ai-schema-bar\">\n                {currentSchema.columns.map((col: { name: string, type: string }) => (\n                  <div\n                    key={col.name}\n                    className=\"vpg-ai-schema-chip\"\n                    title={`${col.name} (${col.type})`}\n                  >\n                    <span className=\"vpg-ai-chip-type\">{getColumnTypeIcon(col.type)}</span>\n                    <span className=\"vpg-ai-chip-name\">{col.name}</span>\n                  </div>\n                ))}\n              </div>\n            )}\n          </div>\n\n          {/* SQL Panel (expandable, above the table) */}\n          {showSqlPanel && selectedQuery && (\n            <div className=\"vpg-ai-sql-panel\">\n              <div className=\"vpg-ai-sql-panel-header\">\n                <span className=\"vpg-ai-sql-panel-title\">SQL Query</span>\n                <div className=\"vpg-ai-sql-panel-actions\">\n                  <button\n                    className=\"vpg-ai-copy-btn\"\n                    title=\"Copy SQL\"\n                    onClick={() => copyToClipboard(selectedQuery)}\n                  >\n                    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                      <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n                      <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n                    </svg>\n                  </button>\n                  <button\n                    className=\"vpg-ai-sql-panel-close\"\n                    title=\"Close\"\n                    onClick={() => setShowSqlPanel(false)}\n                  >\n                    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                      <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n                      <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n                    </svg>\n                  </button>\n                </div>\n              </div>\n              <pre className=\"vpg-ai-sql-panel-code\"><code>{selectedQuery}</code></pre>\n            </div>\n          )}\n\n          {/* Loading state */}\n          {isLoading ? (\n            <div className=\"vpg-ai-preview-loading\">\n              <div className=\"vpg-ai-preview-spinner\" />\n              <span>Running query...</span>\n            </div>\n          ) : previewData.length === 0 && currentSchema ? (\n            /* Ready state (schema loaded, no data yet) */\n            <div className=\"vpg-ai-preview-ready\">\n              <div className=\"vpg-ai-preview-ready-icon\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n                  <ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\" />\n                  <path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\" />\n                  <path d=\"M3 12c0 1.66 4 3 9 3s9-1.34 9-3\" />\n                </svg>\n              </div>\n              <p>Data source connected</p>\n              <span>\n                {currentSchema.columns.length}\n                {' '}\n                columns available\n              </span>\n              <div className=\"vpg-ai-preview-hint\">\n                Ask a question to explore the data\n              </div>\n            </div>\n          ) : previewData.length === 0 ? (\n            /* No schema loaded yet */\n            <div className=\"vpg-ai-preview-empty\">\n              <div className=\"vpg-ai-preview-empty-icon\">\n                <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n                  <path d=\"M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n                </svg>\n              </div>\n              <p>Loading data source...</p>\n            </div>\n          ) : (\n            /* Data table */\n            <div className=\"vpg-ai-preview-table-container\">\n              <table className=\"vpg-ai-preview-table\">\n                <thead>\n                  <tr>\n                    {previewColumns.map((col: string) => (\n                      <th key={col}>{col}</th>\n                    ))}\n                  </tr>\n                </thead>\n                <tbody>\n                  {previewData.map((row: Record<string, unknown>, idx: number) => (\n                    <tr key={idx}>\n                      {previewColumns.map((col: string) => (\n                        <td key={col}>{formatCellValue(row[col])}</td>\n                      ))}\n                    </tr>\n                  ))}\n                </tbody>\n              </table>\n              {fullPreviewData.length > 100 && (\n                <div className=\"vpg-ai-preview-more\">\n                  Showing 100 of\n                  {' '}\n                  {fullPreviewData.length.toLocaleString()}\n                  {' '}\n                  rows.\n                  <button onClick={handleViewResults}>View all in Grid</button>\n                </div>\n              )}\n            </div>\n          )}\n        </div>\n      </div>\n    </div>\n  )\n})\n","/**\n * TinyPivot React - AI Analyst Hook\n * Manages AI conversation state and data fetching\n */\nimport type {\n  AIAnalystConfig,\n  AIConversation,\n  AIConversationUpdateEvent,\n  AIDataLoadedEvent,\n  AIDataSource,\n  AIErrorEvent,\n  AIProxyResponse,\n  AIQueryExecutedEvent,\n  AITableSchema,\n  ListTablesResponse,\n  SchemaResponse,\n} from '@smallwebco/tinypivot-core'\nimport {\n  addMessageToConversation,\n  buildSystemPrompt,\n  createAssistantMessage,\n  createConversation,\n  createUserMessage,\n  extractSQLFromResponse,\n  findDemoResponse,\n  getDefaultDemoResponse,\n  getDemoSchema,\n  getInitialDemoData,\n  getLatestConversationData,\n  getMessagesForAPI,\n  setConversationDataSource,\n  validateSQLSafety,\n} from '@smallwebco/tinypivot-core'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nexport interface UseAIAnalystOptions {\n  config: AIAnalystConfig\n  onDataLoaded?: (event: AIDataLoadedEvent) => void\n  onConversationUpdate?: (event: AIConversationUpdateEvent) => void\n  onQueryExecuted?: (event: AIQueryExecutedEvent) => void\n  onError?: (event: AIErrorEvent) => void\n}\n\nexport function useAIAnalyst(options: UseAIAnalystOptions) {\n  const { config, onDataLoaded, onConversationUpdate, onQueryExecuted, onError } = options\n\n  // Use refs to avoid stale closures in callbacks\n  const configRef = useRef(config)\n  configRef.current = config\n\n  // LocalStorage key for persistence\n  const storageKey = config.persistToLocalStorage\n    ? `tinypivot-ai-conversation-${config.sessionId || 'default'}`\n    : null\n\n  // Load initial conversation from localStorage if enabled\n  const loadFromStorage = useCallback((): AIConversation => {\n    if (storageKey && typeof window !== 'undefined') {\n      try {\n        const stored = localStorage.getItem(storageKey)\n        if (stored) {\n          const parsed = JSON.parse(stored)\n          if (parsed.id && Array.isArray(parsed.messages)) {\n            return parsed as AIConversation\n          }\n        }\n      }\n      catch (e) {\n        console.warn('[TinyPivot] Failed to load conversation from localStorage:', e)\n      }\n    }\n    return createConversation(config.sessionId)\n  }, [storageKey, config.sessionId])\n\n  // Save conversation to localStorage if enabled\n  const saveToStorage = useCallback((conv: AIConversation) => {\n    if (storageKey && typeof window !== 'undefined') {\n      try {\n        // Custom replacer to handle BigInt values (common in DuckDB results)\n        const replacer = (_key: string, value: unknown) => {\n          if (typeof value === 'bigint') {\n            return Number(value)\n          }\n          return value\n        }\n        localStorage.setItem(storageKey, JSON.stringify(conv, replacer))\n      }\n      catch (e) {\n        console.warn('[TinyPivot] Failed to save conversation to localStorage:', e)\n      }\n    }\n  }, [storageKey])\n\n  const initialConversationRef = useRef<AIConversation | null>(null)\n  if (!initialConversationRef.current) {\n    initialConversationRef.current = loadFromStorage()\n  }\n\n  // State\n  const [conversation, setConversation] = useState<AIConversation>(initialConversationRef.current)\n  const [schemas, setSchemas] = useState<Map<string, AITableSchema>>(new Map())\n  const [allSchemas, setAllSchemas] = useState<AITableSchema[]>([]) // All table schemas for JOINs\n  const [isLoading, setIsLoading] = useState(false)\n  const [error, setError] = useState<string | null>(null)\n  const [lastLoadedData, setLastLoadedData] = useState<Record<string, unknown>[] | null>(\n    () => getLatestConversationData(initialConversationRef.current!),\n  )\n\n  // Dynamic data sources (discovered from endpoint)\n  const [discoveredDataSources, setDiscoveredDataSources] = useState<AIDataSource[]>([])\n  const [isLoadingTables, setIsLoadingTables] = useState(false)\n  const dataSourceLoadPromisesRef = useRef(new Map<string, Promise<void>>())\n  const hydratedPersistedSelectionRef = useRef(false)\n\n  // Get effective data sources (config or discovered)\n  const effectiveDataSources = useMemo<AIDataSource[]>(() => {\n    if (config.dataSources && config.dataSources.length > 0) {\n      return config.dataSources\n    }\n    return discoveredDataSources\n  }, [config.dataSources, discoveredDataSources])\n\n  // Save to storage whenever conversation changes\n  useEffect(() => {\n    saveToStorage(conversation)\n  }, [conversation, saveToStorage])\n\n  // Computed values\n  const selectedDataSource = conversation.dataSourceId\n  const selectedDataSourceInfo = useMemo(\n    () => effectiveDataSources.find((ds: AIDataSource) => ds.id === conversation.dataSourceId),\n    [effectiveDataSources, conversation.dataSourceId],\n  )\n  const messages = conversation.messages\n  const hasMessages = conversation.messages.length > 0\n\n  /**\n   * Fetch schemas for ALL tables at once (enables JOINs)\n   */\n  const fetchAllSchemas = useCallback(async () => {\n    if (!configRef.current.endpoint)\n      return\n\n    try {\n      const response = await fetch(configRef.current.endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ action: 'get-all-schemas' }),\n      })\n\n      if (!response.ok) {\n        throw new Error(`Failed to fetch all schemas: ${response.statusText}`)\n      }\n\n      const data: SchemaResponse = await response.json()\n\n      if (data.error) {\n        throw new Error(data.error)\n      }\n\n      // Store all schemas for JOIN support\n      setAllSchemas(data.schemas)\n\n      // Also populate the individual schemas map\n      setSchemas((prev) => {\n        const newMap = new Map(prev)\n        for (const schema of data.schemas) {\n          newMap.set(schema.table, schema)\n        }\n        return newMap\n      })\n    }\n    catch (err) {\n      // Schema fetch is optional - continue without it\n      console.warn('[TinyPivot] Failed to fetch all schemas:', err)\n    }\n  }, [])\n\n  /**\n   * Fetch available tables from endpoint (auto-discovery mode)\n   */\n  const fetchTables = useCallback(async () => {\n    if (!configRef.current.endpoint)\n      return\n\n    setIsLoadingTables(true)\n    try {\n      const response = await fetch(configRef.current.endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({ action: 'list-tables' }),\n      })\n\n      if (!response.ok) {\n        throw new Error(`Failed to fetch tables: ${response.statusText}`)\n      }\n\n      const data: ListTablesResponse = await response.json()\n\n      if (data.error) {\n        throw new Error(data.error)\n      }\n\n      // Convert to AIDataSource format\n      setDiscoveredDataSources(data.tables.map((t: { name: string, description?: string }) => ({\n        id: t.name,\n        table: t.name,\n        name: t.name.charAt(0).toUpperCase() + t.name.slice(1), // Capitalize\n        description: t.description,\n      })))\n\n      // Fetch all schemas for JOIN support\n      await fetchAllSchemas()\n    }\n    catch (err) {\n      console.warn('[TinyPivot] Failed to fetch tables:', err)\n      onError?.({\n        message: err instanceof Error ? err.message : 'Failed to fetch tables',\n        type: 'network',\n      })\n    }\n    finally {\n      setIsLoadingTables(false)\n    }\n  }, [onError, fetchAllSchemas])\n\n  // Initialize: fetch tables if using endpoint\n  useEffect(() => {\n    if (configRef.current.endpoint && (!config.dataSources || config.dataSources.length === 0)) {\n      fetchTables()\n    }\n  }, [fetchTables, config.dataSources])\n\n  /**\n   * Fetch schema from the unified endpoint\n   */\n  const fetchSchema = useCallback(async (dataSource: AIDataSource) => {\n    if (!configRef.current.endpoint)\n      return\n\n    try {\n      const response = await fetch(configRef.current.endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          action: 'get-schema',\n          tables: [dataSource.table],\n        }),\n      })\n\n      if (!response.ok) {\n        throw new Error(`Failed to fetch schema: ${response.statusText}`)\n      }\n\n      const data: SchemaResponse = await response.json()\n\n      if (data.error) {\n        throw new Error(data.error)\n      }\n\n      if (data.schemas.length > 0) {\n        setSchemas(prev => new Map(prev).set(dataSource.id, data.schemas[0]))\n      }\n    }\n    catch (err) {\n      // Schema fetch is optional - continue without it\n      console.warn('Failed to fetch schema:', err)\n    }\n  }, [])\n\n  /**\n   * Fetch sample data (first 100 rows) from the unified endpoint\n   */\n  const fetchSampleData = useCallback(async (dataSource: AIDataSource) => {\n    if (!configRef.current.endpoint)\n      return\n\n    try {\n      const sql = `SELECT * FROM ${dataSource.table} LIMIT 100`\n      const response = await fetch(configRef.current.endpoint, {\n        method: 'POST',\n        headers: { 'Content-Type': 'application/json' },\n        body: JSON.stringify({\n          action: 'query',\n          sql,\n          table: dataSource.table,\n        }),\n      })\n\n      if (!response.ok) {\n        throw new Error(`Failed to fetch sample data: ${response.statusText}`)\n      }\n\n      const result = await response.json()\n\n      if (result.error) {\n        throw new Error(result.error)\n      }\n\n      if (result.data && result.data.length > 0) {\n        setLastLoadedData(result.data)\n        onDataLoaded?.({\n          data: result.data,\n          query: sql,\n          dataSourceId: dataSource.id,\n          rowCount: result.data.length,\n        })\n      }\n    }\n    catch (err) {\n      // Sample data fetch is optional - continue without it\n      console.warn('Failed to fetch sample data:', err)\n    }\n  }, [onDataLoaded])\n\n  const loadDataSourceState = useCallback(async (dataSource: AIDataSource) => {\n    const currentConfig = configRef.current\n\n    if (currentConfig.dataSourceLoader) {\n      const { data, schema } = await currentConfig.dataSourceLoader(dataSource.id)\n      if (schema) {\n        setSchemas(prev => new Map(prev).set(dataSource.id, schema))\n      }\n      if (data && data.length > 0) {\n        setLastLoadedData(data)\n        onDataLoaded?.({\n          data,\n          query: `SELECT * FROM ${dataSource.table} LIMIT 100`,\n          dataSourceId: dataSource.id,\n          rowCount: data.length,\n        })\n      }\n      return\n    }\n\n    if (currentConfig.demoMode) {\n      const demoSchema = getDemoSchema(dataSource.id)\n      if (demoSchema) {\n        setSchemas(prev => new Map(prev).set(dataSource.id, demoSchema))\n      }\n\n      const initialData = getInitialDemoData(dataSource.id)\n      if (initialData) {\n        setLastLoadedData(initialData)\n        onDataLoaded?.({\n          data: initialData,\n          query: `SELECT * FROM ${dataSource.table} LIMIT 10`,\n          dataSourceId: dataSource.id,\n          rowCount: initialData.length,\n        })\n      }\n      return\n    }\n\n    if (currentConfig.endpoint) {\n      await fetchSchema(dataSource)\n      await fetchSampleData(dataSource)\n    }\n  }, [fetchSchema, fetchSampleData, onDataLoaded])\n\n  const ensureDataSourceState = useCallback(async (dataSource: AIDataSource) => {\n    const existingLoad = dataSourceLoadPromisesRef.current.get(dataSource.id)\n    if (existingLoad) {\n      return existingLoad\n    }\n\n    const loadPromise = loadDataSourceState(dataSource)\n      .catch((err) => {\n        console.warn('Failed to load data source:', err)\n      })\n      .finally(() => {\n        dataSourceLoadPromisesRef.current.delete(dataSource.id)\n      })\n\n    dataSourceLoadPromisesRef.current.set(dataSource.id, loadPromise)\n    return loadPromise\n  }, [loadDataSourceState])\n\n  /**\n   * Select a data source and fetch its schema\n   */\n  const selectDataSource = useCallback(async (dataSourceId: string) => {\n    const dataSource = effectiveDataSources.find(ds => ds.id === dataSourceId)\n    if (!dataSource) {\n      setError(`Data source \"${dataSourceId}\" not found`)\n      return\n    }\n\n    // Update conversation\n    setConversation((prev) => {\n      const updated = setConversationDataSource(prev, dataSourceId)\n      const withMessage = addMessageToConversation(\n        updated,\n        createAssistantMessage(\n          `I'm now connected to **${dataSource.name}**. ${dataSource.description || ''}\\n\\nWhat would you like to know about this data?`,\n        ),\n      )\n      onConversationUpdate?.({ conversation: withMessage })\n      return withMessage\n    })\n\n    await ensureDataSourceState(dataSource)\n  }, [effectiveDataSources, ensureDataSourceState, onConversationUpdate])\n\n  useEffect(() => {\n    if (hydratedPersistedSelectionRef.current) {\n      return\n    }\n\n    const initialConversation = initialConversationRef.current\n    const initialDataSourceId = initialConversation?.dataSourceId\n    if (!initialDataSourceId) {\n      hydratedPersistedSelectionRef.current = true\n      return\n    }\n\n    const dataSource = effectiveDataSources.find(ds => ds.id === initialDataSourceId)\n    if (!dataSource) {\n      return\n    }\n\n    const hasPersistedPreviewData = !!getLatestConversationData(initialConversation)\n    const hasSchema = schemas.has(initialDataSourceId)\n    const hasPreviewData = !!lastLoadedData?.length || hasPersistedPreviewData\n\n    hydratedPersistedSelectionRef.current = true\n\n    if (!hasSchema || !hasPreviewData) {\n      void ensureDataSourceState(dataSource)\n    }\n  }, [effectiveDataSources, ensureDataSourceState, lastLoadedData, schemas])\n\n  /**\n   * Call the AI endpoint\n   */\n  const callAIEndpoint = useCallback(async (\n    userInput: string,\n    currentConversation: AIConversation,\n    currentSchemas: Map<string, AITableSchema>,\n    currentDataSources: AIDataSource[],\n    currentAllSchemas: AITableSchema[],\n  ): Promise<string> => {\n    if (!configRef.current.endpoint) {\n      throw new Error('No endpoint configured. Set `endpoint` in AI analyst config.')\n    }\n\n    const dataSourceId = currentConversation.dataSourceId\n\n    // Build system prompt using effective data sources\n    // Pass allSchemas to enable JOINs with related tables\n    const systemPrompt = buildSystemPrompt(\n      currentDataSources,\n      currentSchemas,\n      dataSourceId,\n      currentAllSchemas.length > 0 ? currentAllSchemas : undefined,\n    )\n\n    // Get conversation messages for API\n    const apiMessages = getMessagesForAPI(currentConversation)\n\n    // Add system prompt and current user message\n    const messages = [\n      { role: 'user' as const, content: systemPrompt },\n      { role: 'assistant' as const, content: 'I understand. I\\'m ready to help you analyze the data.' },\n      ...apiMessages.slice(0, -1), // Exclude the just-added user message\n      { role: 'user' as const, content: userInput },\n    ]\n\n    const response = await fetch(configRef.current.endpoint, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ action: 'chat', messages }),\n    })\n\n    if (!response.ok) {\n      throw new Error(`AI request failed: ${response.statusText}`)\n    }\n\n    const data: AIProxyResponse = await response.json()\n\n    if (data.error) {\n      throw new Error(data.error)\n    }\n\n    return data.content\n  }, [])\n\n  /**\n   * Execute a SQL query and update the specified message with results\n   * @param sql The SQL query to execute\n   * @param currentConversation Current conversation state\n   * @param currentDataSources Available data sources\n   * @param messageId Optional message ID to update with results (instead of adding new message)\n   */\n  const executeQuery = useCallback(async (\n    sql: string,\n    currentConversation: AIConversation,\n    currentDataSources: AIDataSource[],\n    messageId?: string,\n  ) => {\n    const dataSourceId = currentConversation.dataSourceId\n    if (!dataSourceId)\n      return\n\n    const dataSource = currentDataSources.find((ds: { id: string }) => ds.id === dataSourceId)\n    if (!dataSource)\n      return\n\n    const startTime = Date.now()\n\n    try {\n      let data: { data?: Record<string, unknown>[], rowCount?: number, truncated?: boolean, error?: string, success?: boolean }\n\n      // Use custom query executor if provided (demo mode)\n      if (configRef.current.queryExecutor) {\n        const result = await configRef.current.queryExecutor(sql, dataSource.table)\n        data = {\n          data: result.data,\n          rowCount: result.rowCount,\n          truncated: result.truncated,\n          error: result.error,\n          success: !result.error,\n        }\n      }\n      // Use unified endpoint\n      else if (configRef.current.endpoint) {\n        const response = await fetch(configRef.current.endpoint, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            action: 'query',\n            sql,\n            table: dataSource.table,\n          }),\n        })\n\n        data = await response.json()\n      }\n      else {\n        throw new Error('No query executor or endpoint configured')\n      }\n\n      const duration = Date.now() - startTime\n\n      if (!data.success || data.error) {\n        // Add error message\n        setConversation((prev: AIConversation) => {\n          const updated = addMessageToConversation(\n            prev,\n            createAssistantMessage(\n              `The query failed: ${data.error || 'Unknown error'}. Would you like me to try a different approach?`,\n              { error: data.error, query: sql },\n            ),\n          )\n          onConversationUpdate?.({ conversation: updated })\n          return updated\n        })\n\n        onQueryExecuted?.({\n          query: sql,\n          rowCount: 0,\n          duration,\n          dataSourceId,\n          success: false,\n          error: data.error,\n        })\n\n        onError?.({\n          message: data.error || 'Query failed',\n          query: sql,\n          type: 'query',\n        })\n        return\n      }\n\n      // Success - load data\n      if (data.data) {\n        setLastLoadedData(data.data)\n\n        // Update the existing message with data, or add a new one if no messageId\n        if (messageId) {\n          // Find and update the existing message's metadata with the data\n          setConversation((prev: AIConversation) => {\n            const updatedMessages = prev.messages.map((msg) => {\n              if (msg.id === messageId) {\n                return {\n                  ...msg,\n                  metadata: {\n                    ...msg.metadata,\n                    data: data.data,\n                    rowCount: data.rowCount,\n                    truncated: data.truncated,\n                  },\n                }\n              }\n              return msg\n            })\n            const updated = {\n              ...prev,\n              messages: updatedMessages,\n              updatedAt: Date.now(),\n            }\n            onConversationUpdate?.({ conversation: updated })\n            return updated\n          })\n        }\n        else {\n          // Fallback: add a new message (shouldn't happen in normal flow)\n          const truncatedNote = data.truncated\n            ? ` (limited to ${configRef.current.maxRows || 10000} rows)`\n            : ''\n\n          setConversation((prev: AIConversation) => {\n            const updated = addMessageToConversation(\n              prev,\n              createAssistantMessage(\n                `Retrieved **${data.rowCount} rows**${truncatedNote}.`,\n                { query: sql, rowCount: data.rowCount, data: data.data },\n              ),\n            )\n            onConversationUpdate?.({ conversation: updated })\n            return updated\n          })\n        }\n\n        onDataLoaded?.({\n          data: data.data,\n          query: sql,\n          dataSourceId,\n          rowCount: data.rowCount || data.data.length,\n        })\n\n        onQueryExecuted?.({\n          query: sql,\n          rowCount: data.rowCount || data.data.length,\n          duration,\n          dataSourceId,\n          success: true,\n        })\n      }\n    }\n    catch (err) {\n      const duration = Date.now() - startTime\n      const errorMsg = err instanceof Error ? err.message : 'Query execution failed'\n\n      setConversation((prev: AIConversation) => {\n        const updated = addMessageToConversation(\n          prev,\n          createAssistantMessage(\n            `Failed to execute query: ${errorMsg}`,\n            { error: errorMsg, query: sql },\n          ),\n        )\n        onConversationUpdate?.({ conversation: updated })\n        return updated\n      })\n\n      onQueryExecuted?.({\n        query: sql,\n        rowCount: 0,\n        duration,\n        dataSourceId,\n        success: false,\n        error: errorMsg,\n      })\n\n      onError?.({\n        message: errorMsg,\n        query: sql,\n        type: 'network',\n      })\n    }\n  }, [onConversationUpdate, onDataLoaded, onQueryExecuted, onError])\n\n  /**\n   * Handle demo mode responses\n   */\n  const handleDemoResponse = useCallback(async (\n    userInput: string,\n    currentConversation: AIConversation,\n  ) => {\n    // Simulate loading delay\n    await new Promise(resolve => setTimeout(resolve, 800))\n\n    const dataSourceId = currentConversation.dataSourceId\n\n    if (!dataSourceId) {\n      setConversation((prev) => {\n        const updated = addMessageToConversation(\n          prev,\n          createAssistantMessage(\n            'Please select a data source first by clicking one of the options above.',\n          ),\n        )\n        onConversationUpdate?.({ conversation: updated })\n        return updated\n      })\n      return\n    }\n\n    // Find matching demo response\n    const demoTrigger = findDemoResponse(dataSourceId, userInput)\n\n    if (demoTrigger) {\n      // Add AI response\n      setConversation((prev) => {\n        const updated = addMessageToConversation(\n          prev,\n          createAssistantMessage(demoTrigger.response, {\n            query: demoTrigger.query,\n            rowCount: demoTrigger.mockData?.length,\n          }),\n        )\n        onConversationUpdate?.({ conversation: updated })\n        return updated\n      })\n\n      // Load mock data\n      if (demoTrigger.mockData) {\n        setLastLoadedData(demoTrigger.mockData)\n\n        onDataLoaded?.({\n          data: demoTrigger.mockData,\n          query: demoTrigger.query || '',\n          dataSourceId,\n          rowCount: demoTrigger.mockData.length,\n        })\n\n        onQueryExecuted?.({\n          query: demoTrigger.query || '',\n          rowCount: demoTrigger.mockData.length,\n          duration: 150, // Fake duration\n          dataSourceId,\n          success: true,\n        })\n      }\n    }\n    else {\n      // Use default response\n      const defaultResponse = getDefaultDemoResponse(dataSourceId)\n      setConversation((prev) => {\n        const updated = addMessageToConversation(\n          prev,\n          createAssistantMessage(defaultResponse),\n        )\n        onConversationUpdate?.({ conversation: updated })\n        return updated\n      })\n    }\n  }, [onConversationUpdate, onDataLoaded, onQueryExecuted])\n\n  /**\n   * Send a message to the AI\n   */\n  const sendMessage = useCallback(async (content: string) => {\n    if (!content.trim())\n      return\n    if (isLoading)\n      return\n\n    setError(null)\n    setIsLoading(true)\n\n    // Add user message\n    let updatedConversation: AIConversation\n    setConversation((prev) => {\n      updatedConversation = addMessageToConversation(prev, createUserMessage(content))\n      onConversationUpdate?.({ conversation: updatedConversation })\n      return updatedConversation\n    })\n\n    try {\n      // Wait for state to update\n      await new Promise(resolve => setTimeout(resolve, 0))\n\n      // Get current state\n      const currentConv = updatedConversation!\n\n      // Handle demo mode\n      if (configRef.current.demoMode) {\n        await handleDemoResponse(content, currentConv)\n        return\n      }\n\n      // Check if data source is selected\n      if (!currentConv.dataSourceId) {\n        setConversation((prev) => {\n          const updated = addMessageToConversation(\n            prev,\n            createAssistantMessage(\n              'Please select a data source first by clicking one of the options above.',\n            ),\n          )\n          onConversationUpdate?.({ conversation: updated })\n          return updated\n        })\n        return\n      }\n\n      // Call AI endpoint\n      const aiResponse = await callAIEndpoint(content, currentConv, schemas, effectiveDataSources, allSchemas)\n\n      // Check if AI wants to run a query\n      const sqlQuery = extractSQLFromResponse(aiResponse)\n\n      if (sqlQuery) {\n        // Validate SQL\n        const validation = validateSQLSafety(sqlQuery)\n        if (!validation.valid) {\n          setConversation((prev) => {\n            const updated = addMessageToConversation(\n              prev,\n              createAssistantMessage(\n                `I generated an invalid query: ${validation.error}. Let me try again with a corrected approach.`,\n                { error: validation.error },\n              ),\n            )\n            onConversationUpdate?.({ conversation: updated })\n            return updated\n          })\n          return\n        }\n\n        // Create the AI message and capture its ID for updating with query results\n        const aiMessage = createAssistantMessage(aiResponse, { query: sqlQuery })\n\n        setConversation((prev) => {\n          const updated = addMessageToConversation(prev, aiMessage)\n          onConversationUpdate?.({ conversation: updated })\n          return updated\n        })\n\n        // Execute query and update the same message with data\n        await executeQuery(sqlQuery, currentConv, effectiveDataSources, aiMessage.id)\n      }\n      else {\n        // Just add AI response\n        setConversation((prev) => {\n          const updated = addMessageToConversation(\n            prev,\n            createAssistantMessage(aiResponse),\n          )\n          onConversationUpdate?.({ conversation: updated })\n          return updated\n        })\n      }\n    }\n    catch (err) {\n      const errorMsg = err instanceof Error ? err.message : 'An error occurred'\n      setError(errorMsg)\n\n      setConversation((prev) => {\n        const updated = addMessageToConversation(\n          prev,\n          createAssistantMessage(\n            `Sorry, I encountered an error: ${errorMsg}. Please try again.`,\n            { error: errorMsg },\n          ),\n        )\n        onConversationUpdate?.({ conversation: updated })\n        return updated\n      })\n\n      onError?.({\n        message: errorMsg,\n        type: 'ai',\n      })\n    }\n    finally {\n      setIsLoading(false)\n    }\n  }, [isLoading, schemas, effectiveDataSources, callAIEndpoint, executeQuery, handleDemoResponse, onConversationUpdate, onError])\n\n  /**\n   * Load full data for the currently selected data source\n   * Returns the full dataset (not limited) for displaying in the grid\n   */\n  const loadFullData = useCallback(async (): Promise<Record<string, unknown>[] | null> => {\n    const dataSourceId = conversation.dataSourceId\n    if (!dataSourceId) {\n      return null\n    }\n\n    const dataSource = effectiveDataSources.find(ds => ds.id === dataSourceId)\n    if (!dataSource) {\n      return null\n    }\n\n    const currentConfig = configRef.current\n\n    // Use custom data source loader if provided\n    if (currentConfig.dataSourceLoader) {\n      try {\n        const { data } = await currentConfig.dataSourceLoader(dataSourceId)\n        if (data && data.length > 0) {\n          return data\n        }\n      }\n      catch (err) {\n        console.warn('Failed to load full data:', err)\n        onError?.({\n          message: err instanceof Error ? err.message : 'Failed to load full data',\n          type: 'network',\n        })\n      }\n      return null\n    }\n\n    // Use query executor to get all data\n    if (currentConfig.queryExecutor) {\n      try {\n        const result = await currentConfig.queryExecutor(\n          `SELECT * FROM ${dataSource.table}`,\n          dataSource.table,\n        )\n        if (result.data && result.data.length > 0) {\n          return result.data\n        }\n      }\n      catch (err) {\n        console.warn('Failed to load full data via query:', err)\n        onError?.({\n          message: err instanceof Error ? err.message : 'Failed to load full data',\n          type: 'network',\n        })\n      }\n      return null\n    }\n\n    // Use endpoint query action\n    if (currentConfig.endpoint) {\n      try {\n        const response = await fetch(currentConfig.endpoint, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            action: 'query',\n            sql: `SELECT * FROM ${dataSource.table}`,\n            table: dataSource.table,\n          }),\n        })\n\n        if (!response.ok) {\n          throw new Error(`Failed to load data: ${response.statusText}`)\n        }\n\n        const data = await response.json()\n        if (data.data && data.data.length > 0) {\n          return data.data\n        }\n      }\n      catch (err) {\n        console.warn('Failed to load full data from endpoint:', err)\n        onError?.({\n          message: err instanceof Error ? err.message : 'Failed to load full data',\n          type: 'network',\n        })\n      }\n      return null\n    }\n\n    // Demo mode - get initial data\n    if (currentConfig.demoMode) {\n      const initialData = getInitialDemoData(dataSourceId)\n      return initialData || null\n    }\n\n    return null\n  }, [conversation.dataSourceId, effectiveDataSources, onError])\n\n  /**\n   * Clear the conversation\n   */\n  const clearConversation = useCallback(() => {\n    hydratedPersistedSelectionRef.current = true\n    const newConv = createConversation(configRef.current.sessionId)\n    setConversation(newConv)\n    setError(null)\n    setLastLoadedData(null)\n    onConversationUpdate?.({ conversation: newConv })\n  }, [onConversationUpdate])\n\n  /**\n   * Export conversation for persistence\n   */\n  const exportConversation = useCallback((): AIConversation => {\n    return { ...conversation }\n  }, [conversation])\n\n  /**\n   * Import a conversation\n   */\n  const importConversation = useCallback((conv: AIConversation) => {\n    hydratedPersistedSelectionRef.current = true\n    setConversation(conv)\n    setLastLoadedData(getLatestConversationData(conv))\n    onConversationUpdate?.({ conversation: conv })\n  }, [onConversationUpdate])\n\n  return {\n    // State\n    conversation,\n    messages,\n    hasMessages,\n    schemas,\n    isLoading,\n    isLoadingTables,\n    error,\n    lastLoadedData,\n    selectedDataSource,\n    selectedDataSourceInfo,\n    /** Available data sources (either from config or auto-discovered) */\n    dataSources: effectiveDataSources,\n\n    // Actions\n    selectDataSource,\n    sendMessage,\n    clearConversation,\n    exportConversation,\n    importConversation,\n    /** Refresh table list from endpoint */\n    fetchTables,\n    /** Load full data for the currently selected data source */\n    loadFullData,\n  }\n}\n","import type { CalculatedField } from '@smallwebco/tinypivot-core'\nimport { validateSimpleFormula } from '@smallwebco/tinypivot-core'\n/**\n * Calculated Field Modal for React\n * UI for creating custom calculated fields with formulas\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { createPortal } from 'react-dom'\n\ninterface CalculatedFieldModalProps {\n  show: boolean\n  availableFields: string[]\n  existingField?: CalculatedField | null\n  onClose: () => void\n  onSave: (field: CalculatedField) => void\n  theme?: string\n}\n\nexport function CalculatedFieldModal({\n  show,\n  availableFields,\n  existingField,\n  onClose,\n  onSave,\n  theme,\n}: CalculatedFieldModalProps) {\n  // Form state\n  const [name, setName] = useState('')\n  const [formula, setFormula] = useState('')\n  const [formatAs, setFormatAs] = useState<'number' | 'percent' | 'currency'>('number')\n  const [decimals, setDecimals] = useState(2)\n  const [error, setError] = useState<string | null>(null)\n\n  // Reset form when modal opens\n  useEffect(() => {\n    if (show) {\n      if (existingField) {\n        setName(existingField.name)\n        setFormula(existingField.formula)\n        setFormatAs(existingField.formatAs || 'number')\n        setDecimals(existingField.decimals ?? 2)\n      }\n      else {\n        setName('')\n        setFormula('')\n        setFormatAs('number')\n        setDecimals(2)\n      }\n      setError(null)\n    }\n  }, [show, existingField])\n\n  // Validate formula on change\n  const validationError = useMemo(() => {\n    if (!formula.trim())\n      return null\n    return validateSimpleFormula(formula, availableFields)\n  }, [formula, availableFields])\n\n  // Insert field into formula\n  const insertField = useCallback((field: string) => {\n    setFormula((prev) => {\n      if (prev.trim() && !prev.endsWith(' ')) {\n        return `${prev} ${field}`\n      }\n      return prev + field\n    })\n  }, [])\n\n  // Insert operator into formula\n  const insertOperator = useCallback((op: string) => {\n    setFormula((prev) => {\n      if (prev.trim() && !prev.endsWith(' ')) {\n        return `${prev} ${op} `\n      }\n      return `${prev + op} `\n    })\n  }, [])\n\n  // Save calculated field\n  const handleSave = useCallback(() => {\n    if (!name.trim()) {\n      setError('Name is required')\n      return\n    }\n\n    const validationResult = validateSimpleFormula(formula, availableFields)\n    if (validationResult) {\n      setError(validationResult)\n      return\n    }\n\n    const field: CalculatedField = {\n      id: existingField?.id || `calc_${Date.now()}`,\n      name: name.trim(),\n      formula: formula.trim(),\n      formatAs,\n      decimals,\n    }\n\n    onSave(field)\n    onClose()\n  }, [name, formula, formatAs, decimals, existingField, availableFields, onSave, onClose])\n\n  // Handle overlay click\n  const handleOverlayClick = useCallback((e: React.MouseEvent) => {\n    if (e.target === e.currentTarget) {\n      onClose()\n    }\n  }, [onClose])\n\n  if (!show)\n    return null\n\n  const modalContent = (\n    <div className={`vpg-modal-overlay vpg-theme-${theme ?? 'light'}`} onClick={handleOverlayClick}>\n      <div className=\"vpg-modal\">\n        <div className=\"vpg-modal-header\">\n          <h3>\n            {existingField ? 'Edit' : 'Create'}\n            {' '}\n            Calculated Field\n          </h3>\n          <button className=\"vpg-modal-close\" onClick={onClose}>×</button>\n        </div>\n\n        <div className=\"vpg-modal-body\">\n          {/* Name */}\n          <div className=\"vpg-form-group\">\n            <label className=\"vpg-label\">Name</label>\n            <input\n              type=\"text\"\n              className=\"vpg-input\"\n              placeholder=\"e.g., Profit Margin %\"\n              value={name}\n              onChange={e => setName(e.target.value)}\n            />\n          </div>\n\n          {/* Formula */}\n          <div className=\"vpg-form-group\">\n            <label className=\"vpg-label\">Formula</label>\n            <textarea\n              className=\"vpg-textarea\"\n              placeholder=\"e.g., revenue / units\"\n              rows={2}\n              value={formula}\n              onChange={e => setFormula(e.target.value)}\n            />\n            <div className=\"vpg-formula-hint\">Use field names with math operators: + - * / ( )</div>\n            {validationError && <div className=\"vpg-error\">{validationError}</div>}\n          </div>\n\n          {/* Quick Insert: Operators */}\n          <div className=\"vpg-form-group\">\n            <label className=\"vpg-label-small\">Operators</label>\n            <div className=\"vpg-button-group\">\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator('+')}>+</button>\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator('-')}>−</button>\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator('*')}>×</button>\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator('/')}>÷</button>\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator('(')}>(</button>\n              <button className=\"vpg-insert-btn vpg-op-btn\" onClick={() => insertOperator(')')}>)</button>\n            </div>\n          </div>\n\n          {/* Quick Insert: Fields (numeric only) */}\n          <div className=\"vpg-form-group\">\n            <label className=\"vpg-label-small\">Insert Field</label>\n            {availableFields.length > 0\n              ? (\n                  <div className=\"vpg-button-group vpg-field-buttons\">\n                    {availableFields.map(field => (\n                      <button\n                        key={field}\n                        className=\"vpg-insert-btn vpg-field-btn\"\n                        onClick={() => insertField(field)}\n                      >\n                        {field}\n                      </button>\n                    ))}\n                  </div>\n                )\n              : (\n                  <div className=\"vpg-no-fields\">No numeric fields available</div>\n                )}\n          </div>\n\n          {/* Format Options */}\n          <div className=\"vpg-form-row\">\n            <div className=\"vpg-form-group vpg-form-group-half\">\n              <label className=\"vpg-label\">Format As</label>\n              <select\n                className=\"vpg-select\"\n                value={formatAs}\n                onChange={e => setFormatAs(e.target.value as 'number' | 'percent' | 'currency')}\n              >\n                <option value=\"number\">Number</option>\n                <option value=\"percent\">Percentage</option>\n                <option value=\"currency\">Currency ($)</option>\n              </select>\n            </div>\n            <div className=\"vpg-form-group vpg-form-group-half\">\n              <label className=\"vpg-label\">Decimals</label>\n              <input\n                type=\"number\"\n                className=\"vpg-input\"\n                min={0}\n                max={6}\n                value={decimals}\n                onChange={e => setDecimals(Number(e.target.value))}\n              />\n            </div>\n          </div>\n\n          {/* Error */}\n          {error && <div className=\"vpg-error vpg-error-box\">{error}</div>}\n        </div>\n\n        <div className=\"vpg-modal-footer\">\n          <button className=\"vpg-btn vpg-btn-secondary\" onClick={onClose}>Cancel</button>\n          <button className=\"vpg-btn vpg-btn-primary\" onClick={handleSave}>\n            {existingField ? 'Update' : 'Add'}\n            {' '}\n            Field\n          </button>\n        </div>\n      </div>\n    </div>\n  )\n\n  // Guard for SSR\n  if (typeof document === 'undefined')\n    return null\n  return createPortal(modalContent, document.body)\n}\n","import type {\n  ChartAggregation,\n  ChartConfig,\n  ChartFieldInfo,\n  ChartType,\n  ResolvedTheme,\n} from '@smallwebco/tinypivot-core'\n/**\n * TinyPivot React - Chart Builder Component\n * Drag-and-drop chart configuration with ApexCharts rendering\n */\nimport type { ApexOptions } from 'apexcharts'\nimport {\n  analyzeFieldsForChart,\n  CHART_AGGREGATIONS,\n  CHART_COLORS,\n  CHART_TYPES,\n  createDefaultChartConfig,\n  getChartGuidance,\n  isChartConfigValid,\n  processChartData,\n  processChartDataForHeatmap,\n  processChartDataForPie,\n  processChartDataForScatter,\n} from '@smallwebco/tinypivot-core'\nimport React, { Suspense, useCallback, useEffect, useMemo, useState } from 'react'\n\n// Lazy load ApexCharts to avoid SSR issues (window not defined in Node.js)\nconst Chart = React.lazy(() => import('react-apexcharts'))\n\ninterface ChartBuilderProps {\n  data: Record<string, unknown>[]\n  theme?: ResolvedTheme\n  fieldRoleOverrides?: Record<string, import('@smallwebco/tinypivot-core').FieldRole>\n  onConfigChange?: (config: ChartConfig) => void\n}\n\nexport function ChartBuilder({\n  data,\n  theme = 'light',\n  fieldRoleOverrides,\n  onConfigChange,\n}: ChartBuilderProps) {\n  // Chart configuration state\n  const [chartConfig, setChartConfig] = useState<ChartConfig>(createDefaultChartConfig())\n\n  // Drag state\n  const [draggingField, setDraggingField] = useState<ChartFieldInfo | null>(null)\n  const [dragOverZone, setDragOverZone] = useState<string | null>(null)\n\n  // Field analysis (applies consumer overrides when provided)\n  const fieldInfos = useMemo(() => analyzeFieldsForChart(data, fieldRoleOverrides), [data, fieldRoleOverrides])\n\n  // Separate fields by role\n  const dimensions = useMemo(\n    () => fieldInfos.filter(f => f.role === 'dimension' || f.role === 'temporal'),\n    [fieldInfos],\n  )\n  const measures = useMemo(\n    () => fieldInfos.filter(f => f.role === 'measure'),\n    [fieldInfos],\n  )\n\n  // Current guidance message\n  const guidance = useMemo(() => getChartGuidance(chartConfig), [chartConfig])\n\n  // Check if chart is ready to render\n  const chartIsValid = useMemo(() => isChartConfigValid(chartConfig), [chartConfig])\n\n  // Get currently selected chart type info\n  const selectedChartType = useMemo(\n    () => CHART_TYPES.find(ct => ct.type === chartConfig.type),\n    [chartConfig.type],\n  )\n\n  // Check if scatter/bubble needs numeric fields\n  const isScatterType = useMemo(\n    () => ['scatter', 'bubble'].includes(chartConfig.type),\n    [chartConfig.type],\n  )\n  const isHeatmapType = useMemo(\n    () => chartConfig.type === 'heatmap',\n    [chartConfig.type],\n  )\n\n  // Dynamic zone labels based on chart type\n  const zoneLabels = useMemo(() => {\n    const type = chartConfig.type\n    switch (type) {\n      case 'scatter':\n      case 'bubble':\n        return {\n          xAxis: 'X-Axis (measure)',\n          xAxisPlaceholder: 'Drop a measure',\n          yAxis: 'Y-Axis (measure)',\n          yAxisPlaceholder: 'Drop a measure',\n          series: 'Color by (optional)',\n          seriesPlaceholder: 'Group points by dimension',\n          showSize: type === 'bubble',\n          showSeries: true,\n        }\n      case 'heatmap':\n        return {\n          xAxis: 'X-Axis (dimension)',\n          xAxisPlaceholder: 'Drop a dimension',\n          yAxis: 'Y-Axis (dimension)',\n          yAxisPlaceholder: 'Drop a dimension',\n          series: 'Value / Intensity',\n          seriesPlaceholder: 'Drop a measure for color intensity',\n          showSize: false,\n          showSeries: true,\n        }\n      case 'pie':\n      case 'donut':\n        return {\n          xAxis: 'Slices (dimension)',\n          xAxisPlaceholder: 'Drop a dimension',\n          yAxis: 'Values (measure)',\n          yAxisPlaceholder: 'Drop a measure',\n          series: '',\n          seriesPlaceholder: '',\n          showSize: false,\n          showSeries: false,\n        }\n      case 'radar':\n        return {\n          xAxis: 'Axes (dimension)',\n          xAxisPlaceholder: 'Drop a dimension',\n          yAxis: 'Values (measure)',\n          yAxisPlaceholder: 'Drop a measure',\n          series: 'Compare by (optional)',\n          seriesPlaceholder: 'Group by dimension',\n          showSize: false,\n          showSeries: true,\n        }\n      case 'stackedBar':\n        return {\n          xAxis: 'X-Axis (dimension)',\n          xAxisPlaceholder: 'Drop a dimension',\n          yAxis: 'Y-Axis (measure)',\n          yAxisPlaceholder: 'Drop a measure',\n          series: 'Series (stacking field)',\n          seriesPlaceholder: 'Drop a dimension to stack by',\n          showSize: false,\n          showSeries: true,\n        }\n      default: // bar, line, area\n        return {\n          xAxis: 'X-Axis (dimension)',\n          xAxisPlaceholder: 'Drop a dimension',\n          yAxis: 'Y-Axis (measure)',\n          yAxisPlaceholder: 'Drop a measure',\n          series: 'Color / Series (optional)',\n          seriesPlaceholder: 'Group by dimension',\n          showSize: false,\n          showSeries: true,\n        }\n    }\n  }, [chartConfig.type])\n\n  // Drag handlers\n  const handleDragStart = useCallback((field: ChartFieldInfo, event: React.DragEvent) => {\n    setDraggingField(field)\n    event.dataTransfer?.setData('text/plain', field.field)\n  }, [])\n\n  const handleDragEnd = useCallback(() => {\n    setDraggingField(null)\n    setDragOverZone(null)\n  }, [])\n\n  const handleDragOver = useCallback((zone: string, event: React.DragEvent) => {\n    event.preventDefault()\n    setDragOverZone(zone)\n  }, [])\n\n  const handleDragLeave = useCallback(() => {\n    setDragOverZone(null)\n  }, [])\n\n  const handleDrop = useCallback((zone: string, event: React.DragEvent) => {\n    event.preventDefault()\n    setDragOverZone(null)\n\n    if (!draggingField)\n      return\n\n    const field = draggingField\n    const chartField = {\n      field: field.field,\n      label: field.label,\n      role: field.role,\n      aggregation: field.role === 'measure' ? 'sum' as ChartAggregation : undefined,\n    }\n\n    let newConfig = { ...chartConfig }\n    switch (zone) {\n      case 'xAxis':\n        newConfig = { ...newConfig, xAxis: chartField }\n        break\n      case 'yAxis':\n        newConfig = { ...newConfig, yAxis: chartField }\n        break\n      case 'series':\n        newConfig = { ...newConfig, seriesField: chartField }\n        break\n      case 'size':\n        newConfig = { ...newConfig, sizeField: chartField }\n        break\n      case 'color':\n        newConfig = { ...newConfig, colorField: chartField }\n        break\n    }\n\n    setChartConfig(newConfig)\n    onConfigChange?.(newConfig)\n  }, [chartConfig, draggingField, onConfigChange])\n\n  const removeField = useCallback((zone: string) => {\n    let newConfig = { ...chartConfig }\n    switch (zone) {\n      case 'xAxis':\n        newConfig = { ...newConfig, xAxis: undefined }\n        break\n      case 'yAxis':\n        newConfig = { ...newConfig, yAxis: undefined }\n        break\n      case 'series':\n        newConfig = { ...newConfig, seriesField: undefined }\n        break\n      case 'size':\n        newConfig = { ...newConfig, sizeField: undefined }\n        break\n      case 'color':\n        newConfig = { ...newConfig, colorField: undefined }\n        break\n    }\n    setChartConfig(newConfig)\n    onConfigChange?.(newConfig)\n  }, [chartConfig, onConfigChange])\n\n  const selectChartType = useCallback((type: ChartType) => {\n    const newConfig = { ...chartConfig, type }\n    setChartConfig(newConfig)\n    onConfigChange?.(newConfig)\n  }, [chartConfig, onConfigChange])\n\n  const updateAggregation = useCallback((zone: string, aggregation: ChartAggregation) => {\n    let field\n    switch (zone) {\n      case 'xAxis':\n        field = chartConfig.xAxis\n        break\n      case 'yAxis':\n        field = chartConfig.yAxis\n        break\n      case 'size':\n        field = chartConfig.sizeField\n        break\n      case 'color':\n        field = chartConfig.colorField\n        break\n      default:\n        return\n    }\n    if (!field)\n      return\n\n    const updated = { ...field, aggregation }\n    let newConfig = { ...chartConfig }\n    switch (zone) {\n      case 'xAxis':\n        newConfig = { ...newConfig, xAxis: updated }\n        break\n      case 'yAxis':\n        newConfig = { ...newConfig, yAxis: updated }\n        break\n      case 'size':\n        newConfig = { ...newConfig, sizeField: updated }\n        break\n      case 'color':\n        newConfig = { ...newConfig, colorField: updated }\n        break\n    }\n    setChartConfig(newConfig)\n    onConfigChange?.(newConfig)\n  }, [chartConfig, onConfigChange])\n\n  // Chart rendering helpers\n  type ApexChartType = 'bar' | 'line' | 'area' | 'pie' | 'donut' | 'radar' | 'scatter' | 'heatmap' | 'bubble'\n\n  const getApexChartType = useCallback((type: ChartType): ApexChartType => {\n    const mapping: Record<ChartType, ApexChartType> = {\n      bar: 'bar',\n      stackedBar: 'bar',\n      line: 'line',\n      area: 'area',\n      pie: 'pie',\n      donut: 'donut',\n      radar: 'radar',\n      scatter: 'scatter',\n      bubble: 'bubble',\n      heatmap: 'heatmap',\n    }\n    return mapping[type] || 'bar'\n  }, [])\n\n  const formatValue = useCallback((val: unknown, format?: string, decimals?: number): string => {\n    // Handle non-number values (ApexCharts sometimes passes strings or undefined)\n    if (val === null || val === undefined)\n      return ''\n    if (typeof val !== 'number')\n      return String(val)\n    if (Number.isNaN(val))\n      return ''\n\n    const dec = decimals ?? 0\n    if (format === 'percent') {\n      return `${val.toFixed(dec)}%`\n    }\n    if (format === 'currency') {\n      return `$${val.toLocaleString(undefined, { minimumFractionDigits: dec, maximumFractionDigits: dec })}`\n    }\n    if (Math.abs(val) >= 1000) {\n      return val.toLocaleString(undefined, { maximumFractionDigits: dec })\n    }\n    return val.toFixed(dec)\n  }, [])\n\n  // Chart options\n  const chartOptions = useMemo<ApexOptions>(() => {\n    const isDark = theme === 'dark' || (typeof theme === 'string' && theme.endsWith('-dark'))\n    const config = chartConfig\n    const options = config.options || {}\n\n    const baseOptions: ApexOptions = {\n      chart: {\n        type: getApexChartType(config.type),\n        background: 'transparent',\n        foreColor: isDark ? '#e2e8f0' : '#334155',\n        toolbar: {\n          show: true,\n          tools: {\n            download: true,\n            selection: false,\n            zoom: options.enableZoom ?? false,\n            zoomin: options.enableZoom ?? false,\n            zoomout: options.enableZoom ?? false,\n            pan: false,\n            reset: options.enableZoom ?? false,\n          },\n          export: {\n            csv: { filename: 'chart-data' },\n            svg: { filename: 'chart' },\n            png: { filename: 'chart' },\n          },\n        },\n        animations: {\n          enabled: options.animated ?? true,\n          speed: 400,\n          dynamicAnimation: { enabled: true, speed: 300 },\n        },\n        fontFamily: 'system-ui, -apple-system, sans-serif',\n      },\n      colors: options.colors || CHART_COLORS,\n      theme: {\n        mode: isDark ? 'dark' : 'light',\n      },\n      grid: {\n        show: options.showGrid ?? true,\n        borderColor: isDark ? '#334155' : '#e2e8f0',\n      },\n      legend: {\n        show: options.showLegend ?? true,\n        position: options.legendPosition || 'top',\n      },\n      dataLabels: {\n        enabled: options.showDataLabels ?? false,\n      },\n      tooltip: {\n        theme: isDark ? 'dark' : 'light',\n        style: {\n          fontSize: '12px',\n        },\n      },\n      stroke: {\n        curve: 'smooth',\n        width: config.type === 'line' ? 3 : config.type === 'area' ? 2 : 0,\n      },\n      fill: {\n        opacity: config.type === 'area' ? 0.4 : 1,\n      },\n    }\n\n    // Add axis titles\n    if (config.xAxis) {\n      baseOptions.xaxis = {\n        ...baseOptions.xaxis,\n        title: { text: options.xAxisTitle || config.xAxis.label },\n        labels: {\n          style: { colors: isDark ? '#94a3b8' : '#64748b' },\n        },\n      }\n    }\n\n    if (config.yAxis && !['pie', 'donut', 'radar'].includes(config.type)) {\n      baseOptions.yaxis = {\n        title: { text: options.yAxisTitle || config.yAxis.label },\n        labels: {\n          style: { colors: isDark ? '#94a3b8' : '#64748b' },\n          formatter: (val: number) => formatValue(val, options.valueFormat, options.decimals),\n        },\n      }\n    }\n\n    // Chart title\n    if (options.title) {\n      baseOptions.title = {\n        text: options.title,\n        style: {\n          fontSize: '16px',\n          fontWeight: '600',\n          color: isDark ? '#e2e8f0' : '#334155',\n        },\n      }\n    }\n\n    // Stacking — forced on for stackedBar, optional for bar/area\n    if (config.type === 'stackedBar' || (options.stacked && ['bar', 'area'].includes(config.type))) {\n      baseOptions.chart!.stacked = true\n    }\n\n    // Pie/Donut specific\n    if (config.type === 'pie' || config.type === 'donut') {\n      baseOptions.plotOptions = {\n        pie: {\n          donut: {\n            size: config.type === 'donut' ? '55%' : '0%',\n            labels: {\n              show: config.type === 'donut',\n              total: {\n                show: true,\n                label: 'Total',\n                formatter: (w) => {\n                  const total = w.globals.seriesTotals.reduce((a: number, b: number) => a + b, 0)\n                  return formatValue(total, options.valueFormat, options.decimals)\n                },\n              },\n            },\n          },\n        },\n      }\n    }\n\n    // Radar specific\n    if (config.type === 'radar') {\n      baseOptions.plotOptions = {\n        radar: {\n          polygons: {\n            strokeColors: isDark ? '#334155' : '#e2e8f0',\n            fill: { colors: isDark ? ['#1e293b', '#0f172a'] : ['#f8fafc', '#f1f5f9'] },\n          },\n        },\n      }\n    }\n\n    return baseOptions\n  }, [chartConfig, theme, getApexChartType, formatValue])\n\n  const chartSeries = useMemo(() => {\n    const config = chartConfig\n\n    if (!chartIsValid)\n      return []\n\n    // Process based on chart type\n    if (config.type === 'pie' || config.type === 'donut') {\n      const chartData = processChartDataForPie(data, config)\n      return chartData.series[0]?.data || []\n    }\n\n    if (config.type === 'scatter' || config.type === 'bubble') {\n      const scatterData = processChartDataForScatter(data, config)\n      return scatterData.series\n    }\n\n    if (config.type === 'heatmap') {\n      const heatmapData = processChartDataForHeatmap(data, config)\n      return heatmapData.series\n    }\n\n    // Standard charts (bar, line, area, etc.)\n    const chartData = processChartData(data, config)\n    return chartData.series\n  }, [data, chartConfig, chartIsValid])\n\n  const chartLabels = useMemo(() => {\n    const config = chartConfig\n\n    if (!chartIsValid)\n      return []\n\n    if (config.type === 'pie' || config.type === 'donut') {\n      const chartData = processChartDataForPie(data, config)\n      return chartData.categories\n    }\n\n    const chartData = processChartData(data, config)\n    return chartData.categories\n  }, [data, chartConfig, chartIsValid])\n\n  // Update xaxis categories in options\n  const chartOptionsWithCategories = useMemo<ApexOptions>(() => {\n    const options = { ...chartOptions }\n    const config = chartConfig\n\n    // Heatmap, scatter, bubble have x values in data itself\n    if (!['pie', 'donut', 'scatter', 'bubble', 'heatmap'].includes(config.type)) {\n      options.xaxis = {\n        ...options.xaxis,\n        categories: chartLabels,\n      }\n    }\n\n    if (config.type === 'pie' || config.type === 'donut') {\n      options.labels = chartLabels\n    }\n\n    // Heatmap specific options\n    if (config.type === 'heatmap') {\n      options.chart = {\n        ...options.chart,\n        type: 'heatmap',\n      }\n      options.xaxis = {\n        ...options.xaxis,\n        type: 'category',\n      }\n      options.dataLabels = {\n        enabled: true,\n        style: {\n          colors: ['#fff'],\n          fontSize: '10px',\n        },\n        formatter: (val: unknown) => {\n          if (val === null || val === undefined)\n            return ''\n          if (typeof val !== 'number')\n            return String(val)\n          if (val >= 1000000)\n            return `${(val / 1000000).toFixed(1)}M`\n          if (val >= 1000)\n            return `${(val / 1000).toFixed(0)}K`\n          return Math.round(val).toLocaleString()\n        },\n      }\n      options.plotOptions = {\n        heatmap: {\n          shadeIntensity: 0.5,\n          radius: 2,\n          enableShades: true,\n          colorScale: {\n            inverse: false,\n          },\n        },\n      }\n      // Use a single color that varies by intensity\n      options.colors = ['#6366f1']\n      // Disable legend for heatmap (color scale is self-explanatory)\n      options.legend = { show: false }\n    }\n\n    return options\n  }, [chartOptions, chartConfig, chartLabels])\n\n  // Icons for chart types (inline SVG paths)\n  const getChartIcon = useCallback((type: ChartType): string => {\n    const icons: Record<ChartType, string> = {\n      bar: 'M3 3v18h18V3H3zm4 14H5v-6h2v6zm4 0H9V7h2v10zm4 0h-2V9h2v8zm4 0h-2v-4h2v4z',\n      stackedBar: 'M3 3v18h18V3H3zm4 14H5v-3h2v3zm0-4H5v-3h2v3zm4 4H9v-5h2v5zm0-6H9v-4h2v4zm4 6h-2v-3h2v3zm0-4h-2v-5h2v5zm4 4h-2v-2h2v2zm0-3h-2v-2h2v2z',\n      line: 'M3.5 18.5l6-6 4 4 8-8M14.5 8.5h6v6',\n      area: 'M3 17l6-6 4 4 8-8v10H3z',\n      pie: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8v8l5.66 5.66C14.28 19.04 13.18 20 12 20z',\n      donut: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4z',\n      scatter: 'M7 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5-6a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm-3 4a2 2 0 1 0 0-4 2 2 0 0 0 0 4z',\n      bubble: 'M7 14a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm5-5a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm5 7a4 4 0 1 0 0-8 4 4 0 0 0 0 8z',\n      heatmap: 'M3 3h4v4H3V3zm6 0h4v4H9V3zm6 0h4v4h-4V3zM3 9h4v4H3V9zm6 0h4v4H9V9zm6 0h4v4h-4V9zM3 15h4v4H3v-4zm6 0h4v4H9v-4zm6 0h4v4h-4v-4z',\n      radar: 'M12 2L4 6v6c0 5.55 3.84 10.74 8 12 4.16-1.26 8-6.45 8-12V6l-8-4zm0 3.18l6 3v5.09c0 4.08-2.76 7.91-6 9.14V5.18z',\n    }\n    return icons[type] || icons.bar\n  }, [])\n\n  // Emit initial config on mount\n  useEffect(() => {\n    onConfigChange?.(chartConfig)\n    // Only run on mount - intentionally not including dependencies\n  }, [])\n\n  return (\n    <div className=\"vpg-chart-builder\">\n      {/* Chart Type Selector */}\n      <div className=\"vpg-chart-type-bar\">\n        {CHART_TYPES.map(ct => (\n          <button\n            key={ct.type}\n            className={`vpg-chart-type-btn ${chartConfig.type === ct.type ? 'active' : ''}`}\n            title={ct.description}\n            onClick={() => selectChartType(ct.type)}\n          >\n            <svg className=\"vpg-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n              <path d={getChartIcon(ct.type)} />\n            </svg>\n            <span className=\"vpg-chart-type-label\">{ct.label.replace(' Chart', '')}</span>\n          </button>\n        ))}\n      </div>\n\n      <div className=\"vpg-chart-builder-content\">\n        {/* Field Lists */}\n        <div className=\"vpg-chart-fields-panel\">\n          <div className=\"vpg-chart-fields-section\">\n            <h4 className=\"vpg-chart-fields-title\">\n              <svg className=\"vpg-icon-sm\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                <path d=\"M4 6h16M4 12h10M4 18h6\" />\n              </svg>\n              Dimensions\n              <span className=\"vpg-chart-fields-hint\">(text/date)</span>\n            </h4>\n            <div className=\"vpg-chart-fields-list\">\n              {dimensions.map(field => (\n                <div\n                  key={field.field}\n                  className=\"vpg-chart-field-chip vpg-field-dimension\"\n                  draggable\n                  onDragStart={e => handleDragStart(field, e)}\n                  onDragEnd={handleDragEnd}\n                >\n                  <span className=\"vpg-field-name\">{field.label}</span>\n                  <span className=\"vpg-field-type\">{field.role === 'temporal' ? 'date' : 'text'}</span>\n                </div>\n              ))}\n              {dimensions.length === 0 && (\n                <div className=\"vpg-chart-fields-empty\">\n                  No dimension fields detected\n                </div>\n              )}\n            </div>\n          </div>\n\n          <div className=\"vpg-chart-fields-section\">\n            <h4 className=\"vpg-chart-fields-title\">\n              <svg className=\"vpg-icon-sm\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                <path d=\"M16 8v8M12 11v5M8 14v2M4 4v16h16\" />\n              </svg>\n              Measures\n              <span className=\"vpg-chart-fields-hint\">(numbers)</span>\n            </h4>\n            <div className=\"vpg-chart-fields-list\">\n              {measures.map(field => (\n                <div\n                  key={field.field}\n                  className=\"vpg-chart-field-chip vpg-field-measure\"\n                  draggable\n                  onDragStart={e => handleDragStart(field, e)}\n                  onDragEnd={handleDragEnd}\n                >\n                  <span className=\"vpg-field-name\">{field.label}</span>\n                  <span className=\"vpg-field-type\">#</span>\n                </div>\n              ))}\n              {measures.length === 0 && (\n                <div className=\"vpg-chart-fields-empty\">\n                  No numeric fields detected\n                </div>\n              )}\n            </div>\n          </div>\n        </div>\n\n        {/* Drop Zones */}\n        <div className=\"vpg-chart-config-panel\">\n          {/* X-Axis */}\n          <div className=\"vpg-chart-drop-zone-wrapper\">\n            <label className=\"vpg-chart-zone-label\">{zoneLabels.xAxis}</label>\n            <div\n              className={`vpg-chart-drop-zone ${dragOverZone === 'xAxis' ? 'drag-over' : ''} ${chartConfig.xAxis ? 'has-field' : ''}`}\n              onDragOver={e => handleDragOver('xAxis', e)}\n              onDragLeave={handleDragLeave}\n              onDrop={e => handleDrop('xAxis', e)}\n            >\n              {chartConfig.xAxis\n                ? (\n                    <>\n                      <span className=\"vpg-zone-field-name\">{chartConfig.xAxis.label}</span>\n                      {isScatterType && chartConfig.xAxis.role === 'measure' && (\n                        <select\n                          className=\"vpg-zone-aggregation\"\n                          value={chartConfig.xAxis.aggregation || 'sum'}\n                          onChange={e => updateAggregation('xAxis', e.target.value as ChartAggregation)}\n                        >\n                          {CHART_AGGREGATIONS.map(agg => (\n                            <option key={agg.value} value={agg.value}>\n                              {agg.symbol}\n                            </option>\n                          ))}\n                        </select>\n                      )}\n                      <button className=\"vpg-zone-remove-btn\" onClick={() => removeField('xAxis')}>\n                        <svg className=\"vpg-icon-xs\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                          <path d=\"M6 18L18 6M6 6l12 12\" />\n                        </svg>\n                      </button>\n                    </>\n                  )\n                : (\n                    <span className=\"vpg-zone-placeholder\">{zoneLabels.xAxisPlaceholder}</span>\n                  )}\n            </div>\n          </div>\n\n          {/* Y-Axis */}\n          <div className=\"vpg-chart-drop-zone-wrapper\">\n            <label className=\"vpg-chart-zone-label\">{zoneLabels.yAxis}</label>\n            <div\n              className={`vpg-chart-drop-zone ${dragOverZone === 'yAxis' ? 'drag-over' : ''} ${chartConfig.yAxis ? 'has-field' : ''}`}\n              onDragOver={e => handleDragOver('yAxis', e)}\n              onDragLeave={handleDragLeave}\n              onDrop={e => handleDrop('yAxis', e)}\n            >\n              {chartConfig.yAxis\n                ? (\n                    <>\n                      <span className=\"vpg-zone-field-name\">{chartConfig.yAxis.label}</span>\n                      {chartConfig.yAxis.role === 'measure' && !isHeatmapType && (\n                        <select\n                          className=\"vpg-zone-aggregation\"\n                          value={chartConfig.yAxis.aggregation || 'sum'}\n                          onChange={e => updateAggregation('yAxis', e.target.value as ChartAggregation)}\n                        >\n                          {CHART_AGGREGATIONS.map(agg => (\n                            <option key={agg.value} value={agg.value}>\n                              {agg.symbol}\n                            </option>\n                          ))}\n                        </select>\n                      )}\n                      <button className=\"vpg-zone-remove-btn\" onClick={() => removeField('yAxis')}>\n                        <svg className=\"vpg-icon-xs\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                          <path d=\"M6 18L18 6M6 6l12 12\" />\n                        </svg>\n                      </button>\n                    </>\n                  )\n                : (\n                    <span className=\"vpg-zone-placeholder\">{zoneLabels.yAxisPlaceholder}</span>\n                  )}\n            </div>\n          </div>\n\n          {/* Series / Color (conditional) */}\n          {zoneLabels.showSeries && (\n            <div className=\"vpg-chart-drop-zone-wrapper\">\n              <label className=\"vpg-chart-zone-label\">{zoneLabels.series}</label>\n              <div\n                className={`vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === 'series' ? 'drag-over' : ''} ${(isHeatmapType ? chartConfig.colorField : chartConfig.seriesField) ? 'has-field' : ''}`}\n                onDragOver={e => handleDragOver(isHeatmapType ? 'color' : 'series', e)}\n                onDragLeave={handleDragLeave}\n                onDrop={e => handleDrop(isHeatmapType ? 'color' : 'series', e)}\n              >\n                {(isHeatmapType ? chartConfig.colorField : chartConfig.seriesField)\n                  ? (\n                      <>\n                        <span className=\"vpg-zone-field-name\">\n                          {isHeatmapType ? chartConfig.colorField?.label : chartConfig.seriesField?.label}\n                        </span>\n                        {isHeatmapType && chartConfig.colorField?.role === 'measure' && (\n                          <select\n                            className=\"vpg-zone-aggregation\"\n                            value={chartConfig.colorField?.aggregation || 'sum'}\n                            onChange={e => updateAggregation('color', e.target.value as ChartAggregation)}\n                          >\n                            {CHART_AGGREGATIONS.map(agg => (\n                              <option key={agg.value} value={agg.value}>\n                                {agg.symbol}\n                              </option>\n                            ))}\n                          </select>\n                        )}\n                        <button className=\"vpg-zone-remove-btn\" onClick={() => removeField(isHeatmapType ? 'color' : 'series')}>\n                          <svg className=\"vpg-icon-xs\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                            <path d=\"M6 18L18 6M6 6l12 12\" />\n                          </svg>\n                        </button>\n                      </>\n                    )\n                  : (\n                      <span className=\"vpg-zone-placeholder\">{zoneLabels.seriesPlaceholder}</span>\n                    )}\n              </div>\n            </div>\n          )}\n\n          {/* Size (for bubble charts) */}\n          {zoneLabels.showSize && (\n            <div className=\"vpg-chart-drop-zone-wrapper\">\n              <label className=\"vpg-chart-zone-label\">Size (number)</label>\n              <div\n                className={`vpg-chart-drop-zone vpg-zone-optional ${dragOverZone === 'size' ? 'drag-over' : ''} ${chartConfig.sizeField ? 'has-field' : ''}`}\n                onDragOver={e => handleDragOver('size', e)}\n                onDragLeave={handleDragLeave}\n                onDrop={e => handleDrop('size', e)}\n              >\n                {chartConfig.sizeField\n                  ? (\n                      <>\n                        <span className=\"vpg-zone-field-name\">{chartConfig.sizeField.label}</span>\n                        {chartConfig.sizeField.role === 'measure' && (\n                          <select\n                            className=\"vpg-zone-aggregation\"\n                            value={chartConfig.sizeField.aggregation || 'sum'}\n                            onChange={e => updateAggregation('size', e.target.value as ChartAggregation)}\n                          >\n                            {CHART_AGGREGATIONS.map(agg => (\n                              <option key={agg.value} value={agg.value}>\n                                {agg.symbol}\n                              </option>\n                            ))}\n                          </select>\n                        )}\n                        <button className=\"vpg-zone-remove-btn\" onClick={() => removeField('size')}>\n                          <svg className=\"vpg-icon-xs\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n                            <path d=\"M6 18L18 6M6 6l12 12\" />\n                          </svg>\n                        </button>\n                      </>\n                    )\n                  : (\n                      <span className=\"vpg-zone-placeholder\">Drop a number for bubble size</span>\n                    )}\n              </div>\n            </div>\n          )}\n\n          {/* Guidance */}\n          <div className=\"vpg-chart-guidance\">\n            <svg className=\"vpg-icon-sm\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n              <circle cx=\"12\" cy=\"12\" r=\"10\" />\n              <path d=\"M12 16v-4M12 8h.01\" />\n            </svg>\n            <span>{guidance}</span>\n          </div>\n        </div>\n\n        {/* Chart Preview */}\n        <div className=\"vpg-chart-preview-panel\">\n          {chartIsValid\n            ? (\n                <div className=\"vpg-chart-container\">\n                  <Suspense fallback={(\n                    <div className=\"vpg-chart-loading\">\n                      <div className=\"vpg-chart-spinner\" />\n                      <span>Loading chart...</span>\n                    </div>\n                  )}\n                  >\n                    <Chart\n                      key={`${chartConfig.type}-${JSON.stringify(chartConfig.xAxis)}-${JSON.stringify(chartConfig.yAxis)}`}\n                      type={getApexChartType(chartConfig.type)}\n                      options={chartOptionsWithCategories}\n                      series={chartSeries}\n                      height=\"100%\"\n                    />\n                  </Suspense>\n                </div>\n              )\n            : (\n                <div className=\"vpg-chart-empty-state\">\n                  <svg className=\"vpg-icon-lg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\">\n                    <path d={getChartIcon(chartConfig.type)} />\n                  </svg>\n                  <h3>Build your chart</h3>\n                  <p>Drag fields from the left panel to configure your visualization</p>\n                  <div className=\"vpg-chart-hint\">\n                    <strong>{selectedChartType?.label}</strong>\n                    :\n                    {' '}\n                    {selectedChartType?.description}\n                  </div>\n                </div>\n              )}\n        </div>\n      </div>\n    </div>\n  )\n}\n","import type { ColumnStats, DateFormat, DateRange, NumberFormat, NumericRange } from '@smallwebco/tinypivot-core'\n/**\n * Column Filter Dropdown Component for React\n * Shows unique values with checkboxes, search, and sort controls\n * For numeric and date columns, also provides a range filter option\n */\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { DateRangeFilter } from './DateRangeFilter'\nimport { NumericRangeFilter } from './NumericRangeFilter'\n\ntype FilterMode = 'values' | 'range'\n\ninterface ColumnFilterProps {\n  columnId: string\n  columnName: string\n  stats: ColumnStats\n  selectedValues: string[]\n  sortDirection: 'asc' | 'desc' | null\n  /** Current numeric range filter (if any) */\n  numericRange?: NumericRange | null\n  /** Current date range filter (if any) */\n  dateRange?: DateRange | null\n  /** Number display format */\n  numberFormat?: NumberFormat\n  /** Date display format */\n  dateFormat?: DateFormat\n  onFilter: (values: string[]) => void\n  onSort: (direction: 'asc' | 'desc' | null) => void\n  onClose: () => void\n  /** Called when a numeric range filter is applied */\n  onRangeFilter?: (range: NumericRange | null) => void\n  /** Called when a date range filter is applied */\n  onDateRangeFilter?: (range: DateRange | null) => void\n}\n\nexport function ColumnFilter({\n  columnName,\n  stats,\n  selectedValues,\n  sortDirection,\n  numericRange,\n  dateRange,\n  numberFormat,\n  dateFormat,\n  onFilter,\n  onSort,\n  onClose,\n  onRangeFilter,\n  onDateRangeFilter,\n}: ColumnFilterProps) {\n  const [searchQuery, setSearchQuery] = useState('')\n  const [localSelected, setLocalSelected] = useState<Set<string>>(new Set(selectedValues))\n  const dropdownRef = useRef<HTMLDivElement>(null)\n  const searchInputRef = useRef<HTMLInputElement>(null)\n\n  // Filter mode (values vs range) - available for numeric and date columns\n  const isNumericColumn = stats.type === 'number'\n    && stats.numericMin !== undefined\n    && stats.numericMax !== undefined\n\n  const isDateColumn = stats.type === 'date'\n    && stats.dateMin !== undefined\n    && stats.dateMax !== undefined\n\n  // Determine initial mode based on existing filters\n  const [filterMode, setFilterMode] = useState<FilterMode>(\n    numericRange || dateRange ? 'range' : 'values',\n  )\n\n  // Local range for the numeric filter\n  const [localRange, setLocalRange] = useState<NumericRange | null>(numericRange ?? null)\n\n  // Local date range for the date filter\n  const [localDateRange, setLocalDateRange] = useState<DateRange | null>(dateRange ?? null)\n\n  // Include blank option if there are null values\n  const hasBlankValues = stats.nullCount > 0\n\n  // Filtered unique values based on search\n  const filteredValues = useMemo(() => {\n    const values = stats.uniqueValues\n    if (!searchQuery)\n      return values\n\n    const query = searchQuery.toLowerCase()\n    return values.filter(v => v.toLowerCase().includes(query))\n  }, [stats.uniqueValues, searchQuery])\n\n  // All values including blank\n  const allValues = useMemo(() => {\n    const values = [...filteredValues]\n    if (hasBlankValues && (!searchQuery || '(blank)'.includes(searchQuery.toLowerCase()))) {\n      values.unshift('(blank)')\n    }\n    return values\n  }, [filteredValues, hasBlankValues, searchQuery])\n\n  // Check states (kept for potential future use)\n  const _isAllSelected = useMemo(\n    () => allValues.every(v => localSelected.has(v)),\n    [allValues, localSelected],\n  )\n\n  // Toggle single value\n  const toggleValue = useCallback((value: string) => {\n    setLocalSelected((prev) => {\n      const next = new Set(prev)\n      if (next.has(value)) {\n        next.delete(value)\n      }\n      else {\n        next.add(value)\n      }\n      return next\n    })\n  }, [])\n\n  // Select all visible\n  const selectAll = useCallback(() => {\n    setLocalSelected((prev) => {\n      const next = new Set(prev)\n      for (const value of allValues) {\n        next.add(value)\n      }\n      return next\n    })\n  }, [allValues])\n\n  // Clear all\n  const clearAll = useCallback(() => {\n    setLocalSelected(new Set())\n  }, [])\n\n  // Apply filter\n  const applyFilter = useCallback(() => {\n    if (localSelected.size === 0) {\n      onFilter([])\n    }\n    else {\n      onFilter(Array.from(localSelected))\n    }\n    onClose()\n  }, [localSelected, onFilter, onClose])\n\n  // Sort handlers\n  const sortAscending = useCallback(() => {\n    onSort(sortDirection === 'asc' ? null : 'asc')\n  }, [sortDirection, onSort])\n\n  const sortDescending = useCallback(() => {\n    onSort(sortDirection === 'desc' ? null : 'desc')\n  }, [sortDirection, onSort])\n\n  // Clear filter only\n  const clearFilter = useCallback(() => {\n    setLocalSelected(new Set())\n    onFilter([])\n    onClose()\n  }, [onFilter, onClose])\n\n  // Handle range filter change from the NumericRangeFilter component\n  const handleRangeChange = useCallback((range: NumericRange | null) => {\n    setLocalRange(range)\n  }, [])\n\n  // Apply the range filter\n  const applyRangeFilter = useCallback(() => {\n    onRangeFilter?.(localRange)\n    onClose()\n  }, [localRange, onRangeFilter, onClose])\n\n  // Clear range filter\n  const clearRangeFilter = useCallback(() => {\n    setLocalRange(null)\n    onRangeFilter?.(null)\n    onClose()\n  }, [onRangeFilter, onClose])\n\n  // Handle date range filter change from the DateRangeFilter component\n  const handleDateRangeChange = useCallback((range: DateRange | null) => {\n    setLocalDateRange(range)\n  }, [])\n\n  // Apply the date range filter\n  const applyDateRangeFilter = useCallback(() => {\n    onDateRangeFilter?.(localDateRange)\n    onClose()\n  }, [localDateRange, onDateRangeFilter, onClose])\n\n  // Clear date range filter\n  const clearDateRangeFilter = useCallback(() => {\n    setLocalDateRange(null)\n    onDateRangeFilter?.(null)\n    onClose()\n  }, [onDateRangeFilter, onClose])\n\n  // Click outside handler\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n        onClose()\n      }\n    }\n\n    document.addEventListener('mousedown', handleClickOutside)\n    return () => document.removeEventListener('mousedown', handleClickOutside)\n  }, [onClose])\n\n  // Keyboard handling\n  useEffect(() => {\n    const handleKeydown = (event: KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        onClose()\n      }\n      else if (event.key === 'Enter' && event.ctrlKey) {\n        applyFilter()\n      }\n    }\n\n    document.addEventListener('keydown', handleKeydown)\n    return () => document.removeEventListener('keydown', handleKeydown)\n  }, [onClose, applyFilter])\n\n  // Focus search on mount\n  useEffect(() => {\n    searchInputRef.current?.focus()\n  }, [])\n\n  // Sync with props\n  useEffect(() => {\n    setLocalSelected(new Set(selectedValues))\n  }, [selectedValues])\n\n  // Sync numeric range with props\n  useEffect(() => {\n    setLocalRange(numericRange ?? null)\n    if (numericRange) {\n      setFilterMode('range')\n    }\n  }, [numericRange])\n\n  // Sync date range with props\n  useEffect(() => {\n    setLocalDateRange(dateRange ?? null)\n    if (dateRange) {\n      setFilterMode('range')\n    }\n  }, [dateRange])\n\n  return (\n    <div ref={dropdownRef} className=\"vpg-filter-dropdown\">\n      {/* Header */}\n      <div className=\"vpg-filter-header\">\n        <span className=\"vpg-filter-title\">{columnName}</span>\n        <span className=\"vpg-filter-count\">\n          {stats.uniqueValues.length.toLocaleString()}\n          {' '}\n          unique\n        </span>\n      </div>\n\n      {/* Sort Controls */}\n      <div className=\"vpg-sort-controls\">\n        <button\n          className={`vpg-sort-btn ${sortDirection === 'asc' ? 'active' : ''}`}\n          title={isDateColumn ? 'Sort Old to New' : isNumericColumn ? 'Sort Low to High' : 'Sort A to Z'}\n          onClick={sortAscending}\n        >\n          <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12\"\n            />\n          </svg>\n          <span>{isDateColumn ? 'Old\\u2192New' : isNumericColumn ? '1\\u21929' : 'A\\u2192Z'}</span>\n        </button>\n        <button\n          className={`vpg-sort-btn ${sortDirection === 'desc' ? 'active' : ''}`}\n          title={isDateColumn ? 'Sort New to Old' : isNumericColumn ? 'Sort High to Low' : 'Sort Z to A'}\n          onClick={sortDescending}\n        >\n          <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4\"\n            />\n          </svg>\n          <span>{isDateColumn ? 'New\\u2192Old' : isNumericColumn ? '9\\u21921' : 'Z\\u2192A'}</span>\n        </button>\n      </div>\n\n      <div className=\"vpg-divider\" />\n\n      {/* Filter Mode Tabs (for numeric and date columns) */}\n      {(isNumericColumn || isDateColumn) && (\n        <div className=\"vpg-filter-tabs\">\n          <button\n            className={`vpg-tab-btn ${filterMode === 'values' ? 'active' : ''}`}\n            onClick={() => setFilterMode('values')}\n          >\n            <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"\n              />\n            </svg>\n            Values\n          </button>\n          <button\n            className={`vpg-tab-btn ${filterMode === 'range' ? 'active' : ''}`}\n            onClick={() => setFilterMode('range')}\n          >\n            <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01\"\n              />\n            </svg>\n            Range\n          </button>\n        </div>\n      )}\n\n      {/* Values Filter Mode */}\n      {((!isNumericColumn && !isDateColumn) || filterMode === 'values') && (\n        <>\n          {/* Search */}\n          <div className=\"vpg-search-container\">\n            <svg className=\"vpg-search-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n              />\n            </svg>\n            <input\n              ref={searchInputRef}\n              type=\"text\"\n              value={searchQuery}\n              onChange={e => setSearchQuery(e.target.value)}\n              placeholder=\"Search values...\"\n              className=\"vpg-search-input\"\n            />\n            {searchQuery && (\n              <button className=\"vpg-clear-search\" onClick={() => setSearchQuery('')}>\n                &times;\n              </button>\n            )}\n          </div>\n\n          {/* Select All / Clear All */}\n          <div className=\"vpg-bulk-actions\">\n            <button className=\"vpg-bulk-btn\" onClick={selectAll}>\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n                />\n              </svg>\n              Select All\n            </button>\n            <button className=\"vpg-bulk-btn\" onClick={clearAll}>\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M6 18L18 6M6 6l12 12\"\n                />\n              </svg>\n              Clear All\n            </button>\n          </div>\n\n          {/* Values List */}\n          <div className=\"vpg-values-list\">\n            {allValues.map(value => (\n              <label\n                key={value}\n                className={`vpg-value-item ${localSelected.has(value) ? 'selected' : ''}`}\n              >\n                <input\n                  type=\"checkbox\"\n                  checked={localSelected.has(value)}\n                  onChange={() => toggleValue(value)}\n                  className=\"vpg-value-checkbox\"\n                />\n                <span className={`vpg-value-text ${value === '(blank)' ? 'vpg-blank' : ''}`}>\n                  {value}\n                </span>\n              </label>\n            ))}\n\n            {allValues.length === 0 && <div className=\"vpg-no-results\">No matching values</div>}\n          </div>\n\n          {/* Footer for Values Mode */}\n          <div className=\"vpg-filter-footer\">\n            <button className=\"vpg-btn-clear\" onClick={clearFilter}>\n              Clear Filter\n            </button>\n            <button className=\"vpg-btn-apply\" onClick={applyFilter}>\n              Apply\n            </button>\n          </div>\n        </>\n      )}\n\n      {/* Numeric Range Filter Mode */}\n      {isNumericColumn && filterMode === 'range' && (\n        <>\n          <NumericRangeFilter\n            dataMin={stats.numericMin!}\n            dataMax={stats.numericMax!}\n            currentRange={localRange}\n            onChange={handleRangeChange}\n            numberFormat={numberFormat}\n          />\n\n          {/* Footer for Range Mode */}\n          <div className=\"vpg-filter-footer\">\n            <button className=\"vpg-btn-clear\" onClick={clearRangeFilter}>\n              Clear Filter\n            </button>\n            <button className=\"vpg-btn-apply\" onClick={applyRangeFilter}>\n              Apply\n            </button>\n          </div>\n        </>\n      )}\n\n      {/* Date Range Filter Mode */}\n      {isDateColumn && filterMode === 'range' && (\n        <>\n          <DateRangeFilter\n            dataMin={stats.dateMin!}\n            dataMax={stats.dateMax!}\n            currentRange={localDateRange}\n            onChange={handleDateRangeChange}\n            dateFormat={dateFormat}\n          />\n\n          {/* Footer for Date Range Mode */}\n          <div className=\"vpg-filter-footer\">\n            <button className=\"vpg-btn-clear\" onClick={clearDateRangeFilter}>\n              Clear Filter\n            </button>\n            <button className=\"vpg-btn-apply\" onClick={applyDateRangeFilter}>\n              Apply\n            </button>\n          </div>\n        </>\n      )}\n    </div>\n  )\n}\n","import type { DateFormat, DateRange } from '@smallwebco/tinypivot-core'\nimport { formatDate, getDatePlaceholder, parseDateInput } from '@smallwebco/tinypivot-core'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\n\ninterface DateRangeFilterProps {\n  dataMin: string // ISO date string\n  dataMax: string // ISO date string\n  currentRange: DateRange | null\n  onChange: (range: DateRange | null) => void\n  dateFormat?: DateFormat\n}\n\nexport function DateRangeFilter({\n  dataMin,\n  dataMax,\n  currentRange,\n  onChange,\n  dateFormat = 'iso',\n}: DateRangeFilterProps) {\n  const [localMinText, setLocalMinText] = useState('')\n  const [localMaxText, setLocalMaxText] = useState('')\n  const [minError, setMinError] = useState(false)\n  const [maxError, setMaxError] = useState(false)\n\n  const formattedMin = useMemo(() => formatDate(dataMin, dateFormat), [dataMin, dateFormat])\n  const formattedMax = useMemo(() => formatDate(dataMax, dateFormat), [dataMax, dateFormat])\n\n  const isFilterActive = localMinText !== '' || localMaxText !== ''\n\n  const emitChange = useCallback(() => {\n    const min = localMinText ? parseDateInput(localMinText, dateFormat) : null\n    const max = localMaxText ? parseDateInput(localMaxText, dateFormat) : null\n    if (min === null && max === null) {\n      onChange(null)\n    }\n    else {\n      onChange({ min, max })\n    }\n  }, [localMinText, localMaxText, dateFormat, onChange])\n\n  const handleMinBlur = useCallback(() => {\n    if (localMinText === '') {\n      setMinError(false)\n      emitChange()\n      return\n    }\n    const parsed = parseDateInput(localMinText, dateFormat)\n    setMinError(parsed === null)\n    if (parsed !== null)\n      emitChange()\n  }, [localMinText, dateFormat, emitChange])\n\n  const handleMaxBlur = useCallback(() => {\n    if (localMaxText === '') {\n      setMaxError(false)\n      emitChange()\n      return\n    }\n    const parsed = parseDateInput(localMaxText, dateFormat)\n    setMaxError(parsed === null)\n    if (parsed !== null)\n      emitChange()\n  }, [localMaxText, dateFormat, emitChange])\n\n  const clearFilter = useCallback(() => {\n    setLocalMinText('')\n    setLocalMaxText('')\n    setMinError(false)\n    setMaxError(false)\n    onChange(null)\n  }, [onChange])\n\n  const setFullRange = useCallback(() => {\n    setLocalMinText(formatDate(dataMin, dateFormat))\n    setLocalMaxText(formatDate(dataMax, dateFormat))\n    setMinError(false)\n    setMaxError(false)\n    onChange({ min: dataMin, max: dataMax })\n  }, [dataMin, dataMax, dateFormat, onChange])\n\n  // Sync with props\n  useEffect(() => {\n    if (currentRange?.min) {\n      setLocalMinText(formatDate(currentRange.min, dateFormat))\n    }\n    else {\n      setLocalMinText('')\n    }\n    if (currentRange?.max) {\n      setLocalMaxText(formatDate(currentRange.max, dateFormat))\n    }\n    else {\n      setLocalMaxText('')\n    }\n    setMinError(false)\n    setMaxError(false)\n  }, [currentRange, dateFormat])\n\n  const handleKeyDown = useCallback((e: React.KeyboardEvent, handler: () => void) => {\n    if (e.key === 'Enter')\n      handler()\n  }, [])\n\n  return (\n    <div className=\"vpg-range-filter\">\n      <div className=\"vpg-range-info\">\n        <span className=\"vpg-range-label\">Data range:</span>\n        <span className=\"vpg-range-bounds\">\n          {formattedMin}\n          {' '}\n          &ndash;\n          {' '}\n          {formattedMax}\n        </span>\n      </div>\n\n      <div className=\"vpg-range-inputs\">\n        <div className=\"vpg-input-group\">\n          <label className=\"vpg-input-label\">From</label>\n          <input\n            type=\"text\"\n            className={`vpg-range-input ${minError ? 'vpg-input-error' : ''}`}\n            placeholder={getDatePlaceholder(dateFormat)}\n            value={localMinText}\n            onChange={e => setLocalMinText(e.target.value)}\n            onBlur={handleMinBlur}\n            onKeyDown={e => handleKeyDown(e, handleMinBlur)}\n          />\n        </div>\n        <span className=\"vpg-input-separator\">to</span>\n        <div className=\"vpg-input-group\">\n          <label className=\"vpg-input-label\">To</label>\n          <input\n            type=\"text\"\n            className={`vpg-range-input ${maxError ? 'vpg-input-error' : ''}`}\n            placeholder={getDatePlaceholder(dateFormat)}\n            value={localMaxText}\n            onChange={e => setLocalMaxText(e.target.value)}\n            onBlur={handleMaxBlur}\n            onKeyDown={e => handleKeyDown(e, handleMaxBlur)}\n          />\n        </div>\n      </div>\n\n      <div className=\"vpg-range-actions\">\n        <button className=\"vpg-range-btn\" disabled={!isFilterActive} onClick={clearFilter}>\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n          </svg>\n          Clear\n        </button>\n        <button className=\"vpg-range-btn\" onClick={setFullRange}>\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4\" />\n          </svg>\n          Full Range\n        </button>\n      </div>\n\n      {isFilterActive && !minError && !maxError && (\n        <div className=\"vpg-filter-summary\">\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\" />\n          </svg>\n          <span>\n            Showing dates\n            {localMinText && (\n              <strong>\n                {' '}\n                from\n                {' '}\n                {localMinText}\n              </strong>\n            )}\n            {localMinText && localMaxText && ' '}\n            {localMaxText && (\n              <strong>\n                to\n                {' '}\n                {localMaxText}\n              </strong>\n            )}\n          </span>\n        </div>\n      )}\n    </div>\n  )\n}\n","import type { NumberFormat, NumericRange } from '@smallwebco/tinypivot-core'\nimport { formatNumber } from '@smallwebco/tinypivot-core'\n/**\n * Numeric Range Filter Component for React\n * Provides an intuitive dual-handle slider and input fields for filtering numeric data\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\n\ninterface NumericRangeFilterProps {\n  dataMin: number\n  dataMax: number\n  currentRange: NumericRange | null\n  onChange: (range: NumericRange | null) => void\n  numberFormat?: NumberFormat\n}\n\nexport function NumericRangeFilter({\n  dataMin,\n  dataMax,\n  currentRange,\n  onChange,\n  numberFormat = 'us',\n}: NumericRangeFilterProps) {\n  // Local state for the range values\n  const [localMin, setLocalMin] = useState<number | null>(currentRange?.min ?? null)\n  const [localMax, setLocalMax] = useState<number | null>(currentRange?.max ?? null)\n\n  // Calculate step based on data range\n  const step = useMemo(() => {\n    const range = dataMax - dataMin\n    if (range === 0)\n      return 1\n    if (range <= 1)\n      return 0.01\n    if (range <= 10)\n      return 0.1\n    if (range <= 100)\n      return 1\n    if (range <= 1000)\n      return 10\n    return 10 ** (Math.floor(Math.log10(range)) - 2)\n  }, [dataMin, dataMax])\n\n  // Format numbers for display\n  const formatValue = useCallback((val: number | null): string => {\n    if (val === null)\n      return ''\n    return formatNumber(val, numberFormat)\n  }, [numberFormat])\n\n  // Check if filter is active\n  const isFilterActive = localMin !== null || localMax !== null\n\n  // Calculate slider percentages for visual representation\n  const minPercent = useMemo(() => {\n    if (localMin === null || dataMax === dataMin)\n      return 0\n    return ((localMin - dataMin) / (dataMax - dataMin)) * 100\n  }, [localMin, dataMin, dataMax])\n\n  const maxPercent = useMemo(() => {\n    if (localMax === null || dataMax === dataMin)\n      return 100\n    return ((localMax - dataMin) / (dataMax - dataMin)) * 100\n  }, [localMax, dataMin, dataMax])\n\n  // Handle min slider change\n  const handleMinSlider = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    const value = Number.parseFloat(event.target.value)\n    setLocalMin(() => {\n      // Ensure min doesn't exceed max\n      if (localMax !== null && value > localMax) {\n        return localMax\n      }\n      return value\n    })\n  }, [localMax])\n\n  // Handle max slider change\n  const handleMaxSlider = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    const value = Number.parseFloat(event.target.value)\n    setLocalMax(() => {\n      // Ensure max doesn't go below min\n      if (localMin !== null && value < localMin) {\n        return localMin\n      }\n      return value\n    })\n  }, [localMin])\n\n  // Handle slider change complete (emit change)\n  const handleSliderChange = useCallback(() => {\n    if (localMin === null && localMax === null) {\n      onChange(null)\n    }\n    else {\n      onChange({ min: localMin, max: localMax })\n    }\n  }, [localMin, localMax, onChange])\n\n  // Handle min input change\n  const handleMinInput = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    const value = event.target.value === '' ? null : Number.parseFloat(event.target.value)\n    if (value !== null && !Number.isNaN(value)) {\n      // Clamp to data bounds\n      setLocalMin(Math.max(dataMin, Math.min(value, localMax ?? dataMax)))\n    }\n    else if (value === null) {\n      setLocalMin(null)\n    }\n  }, [dataMin, dataMax, localMax])\n\n  // Handle max input change\n  const handleMaxInput = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {\n    const value = event.target.value === '' ? null : Number.parseFloat(event.target.value)\n    if (value !== null && !Number.isNaN(value)) {\n      // Clamp to data bounds\n      setLocalMax(Math.min(dataMax, Math.max(value, localMin ?? dataMin)))\n    }\n    else if (value === null) {\n      setLocalMax(null)\n    }\n  }, [dataMin, dataMax, localMin])\n\n  // Handle input blur (emit change)\n  const handleInputBlur = useCallback(() => {\n    if (localMin === null && localMax === null) {\n      onChange(null)\n    }\n    else {\n      onChange({ min: localMin, max: localMax })\n    }\n  }, [localMin, localMax, onChange])\n\n  // Clear the filter\n  const clearFilter = useCallback(() => {\n    setLocalMin(null)\n    setLocalMax(null)\n    onChange(null)\n  }, [onChange])\n\n  // Set to full range\n  const setFullRange = useCallback(() => {\n    setLocalMin(dataMin)\n    setLocalMax(dataMax)\n    onChange({ min: dataMin, max: dataMax })\n  }, [dataMin, dataMax, onChange])\n\n  // Sync with props\n  useEffect(() => {\n    setLocalMin(currentRange?.min ?? null)\n    setLocalMax(currentRange?.max ?? null)\n  }, [currentRange])\n\n  return (\n    <div className=\"vpg-range-filter\">\n      {/* Data range info */}\n      <div className=\"vpg-range-info\">\n        <span className=\"vpg-range-label\">Data range:</span>\n        <span className=\"vpg-range-bounds\">\n          {formatValue(dataMin)}\n          {' '}\n          –\n          {formatValue(dataMax)}\n        </span>\n      </div>\n\n      {/* Dual slider track */}\n      <div className=\"vpg-slider-container\">\n        <div className=\"vpg-slider-track\">\n          <div\n            className=\"vpg-slider-fill\"\n            style={{\n              left: `${minPercent}%`,\n              right: `${100 - maxPercent}%`,\n            }}\n          />\n        </div>\n\n        {/* Min slider (lower handle) */}\n        <input\n          type=\"range\"\n          className=\"vpg-slider vpg-slider-min\"\n          min={dataMin}\n          max={dataMax}\n          step={step}\n          value={localMin ?? dataMin}\n          onChange={handleMinSlider}\n          onMouseUp={handleSliderChange}\n          onTouchEnd={handleSliderChange}\n        />\n\n        {/* Max slider (upper handle) */}\n        <input\n          type=\"range\"\n          className=\"vpg-slider vpg-slider-max\"\n          min={dataMin}\n          max={dataMax}\n          step={step}\n          value={localMax ?? dataMax}\n          onChange={handleMaxSlider}\n          onMouseUp={handleSliderChange}\n          onTouchEnd={handleSliderChange}\n        />\n      </div>\n\n      {/* Input fields for precise entry */}\n      <div className=\"vpg-range-inputs\">\n        <div className=\"vpg-input-group\">\n          <label className=\"vpg-input-label\">Min</label>\n          <input\n            type=\"number\"\n            className=\"vpg-range-input\"\n            placeholder={formatValue(dataMin)}\n            value={localMin ?? ''}\n            step={step}\n            onChange={handleMinInput}\n            onBlur={handleInputBlur}\n          />\n        </div>\n        <span className=\"vpg-input-separator\">to</span>\n        <div className=\"vpg-input-group\">\n          <label className=\"vpg-input-label\">Max</label>\n          <input\n            type=\"number\"\n            className=\"vpg-range-input\"\n            placeholder={formatValue(dataMax)}\n            value={localMax ?? ''}\n            step={step}\n            onChange={handleMaxInput}\n            onBlur={handleInputBlur}\n          />\n        </div>\n      </div>\n\n      {/* Quick actions */}\n      <div className=\"vpg-range-actions\">\n        <button\n          className=\"vpg-range-btn\"\n          disabled={!isFilterActive}\n          onClick={clearFilter}\n        >\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M6 18L18 6M6 6l12 12\"\n            />\n          </svg>\n          Clear\n        </button>\n        <button className=\"vpg-range-btn\" onClick={setFullRange}>\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4\"\n            />\n          </svg>\n          Full Range\n        </button>\n      </div>\n\n      {/* Current filter display */}\n      {isFilterActive && (\n        <div className=\"vpg-filter-summary\">\n          <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n            />\n          </svg>\n          <span>\n            Showing values\n            {' '}\n            {localMin !== null && (\n              <strong>\n                ≥\n                {formatValue(localMin)}\n              </strong>\n            )}\n            {localMin !== null && localMax !== null && ' and '}\n            {localMax !== null && (\n              <strong>\n                ≤\n                {formatValue(localMax)}\n              </strong>\n            )}\n          </span>\n        </div>\n      )}\n    </div>\n  )\n}\n","/**\n * TinyPivot React - Main DataGrid Component\n * Excel-like data grid with optional pivot table functionality\n */\nimport type {\n  AIAnalystConfig,\n  AIConversationUpdateEvent,\n  AIDataLoadedEvent,\n  AIErrorEvent,\n  AIQueryExecutedEvent,\n  ChartConfig,\n  DateFormat,\n  DateRange,\n  DrillThroughResult,\n  NumberFormat,\n  PivotLayout,\n  Theme,\n} from '@smallwebco/tinypivot-core'\nimport type { AIAnalystHandle } from './AIAnalyst'\nimport { canUseDrillThrough, formatDate as coreFormatDate, formatNumber as coreFormatNumber, getDrillThroughRows, getFieldUniqueValues } from '@smallwebco/tinypivot-core'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useExcelGrid } from '../hooks/useExcelGrid'\nimport {\n  copyToClipboard,\n  exportPivotToCSV,\n  exportPivotToXLSX,\n  exportToCSV,\n  exportToXLSX,\n  formatSelectionForClipboard,\n} from '../hooks/useGridFeatures'\nimport { useLicense } from '../hooks/useLicense'\nimport { usePivotTable } from '../hooks/usePivotTable'\nimport { AIAnalyst } from './AIAnalyst'\nimport { ChartBuilder } from './ChartBuilder'\nimport { ColumnFilter } from './ColumnFilter'\nimport { DrillThroughModal } from './DrillThroughModal'\nimport { ExportMenu } from './ExportMenu'\nimport { PivotConfig } from './PivotConfig'\nimport { PivotSkeleton } from './PivotSkeleton'\n\n// Re-export AI types for public API\nexport type { AIAnalystConfig, AIConversationUpdateEvent, AIDataLoadedEvent, AIErrorEvent, AIQueryExecutedEvent }\n\ninterface DataGridProps {\n  data: Record<string, unknown>[]\n  loading?: boolean\n  rowHeight?: number\n  headerHeight?: number\n  fontSize?: 'xs' | 'sm' | 'base'\n  showPivot?: boolean\n  enableExport?: boolean\n  enableSearch?: boolean\n  enablePagination?: boolean\n  pageSize?: number\n  enableColumnResize?: boolean\n  enableClipboard?: boolean\n  theme?: Theme\n  stripedRows?: boolean\n  exportFilename?: string\n  enableVerticalResize?: boolean\n  initialHeight?: number\n  minHeight?: number\n  maxHeight?: number\n  /** Number display format */\n  numberFormat?: NumberFormat\n  /** Date display format */\n  dateFormat?: DateFormat\n  /** Override auto-detected chart field roles per column name */\n  fieldRoleOverrides?: Record<string, import('@smallwebco/tinypivot-core').FieldRole>\n  /** AI Data Analyst configuration (Pro feature, disabled by default) */\n  aiAnalyst?: AIAnalystConfig\n  /** Enable row group collapse/expand (default true) */\n  enableDrillDown?: boolean\n  /** Enable drill-through on double-click (Pro feature, default true) */\n  enableDrillThrough?: boolean\n  /** Pivot row layout: 'grouped' merges repeated parent cells, 'tabular' repeats every value */\n  pivotLayout?: PivotLayout\n  onCellClick?: (payload: {\n    row: number\n    col: number\n    value: unknown\n    rowData: Record<string, unknown>\n  }) => void\n  onSelectionChange?: (payload: { cells: Array<{ row: number, col: number }>, values: unknown[] }) => void\n  onExport?: (payload: { rowCount: number, filename: string }) => void\n  onCopy?: (payload: { text: string, cellCount: number }) => void\n  // AI Analyst events\n  onAIDataLoaded?: (payload: AIDataLoadedEvent) => void\n  onAIConversationUpdate?: (payload: AIConversationUpdateEvent) => void\n  onAIQueryExecuted?: (payload: AIQueryExecutedEvent) => void\n  onAIError?: (payload: AIErrorEvent) => void\n  // Drill-down/through events\n  onCollapseChange?: (collapsedPaths: string[]) => void\n  onDrillThrough?: (result: DrillThroughResult) => void\n}\n\nconst MIN_COL_WIDTH = 120\nconst MAX_COL_WIDTH = 350\n\nexport function DataGrid({\n  data,\n  loading = false,\n  fontSize: initialFontSize = 'xs',\n  showPivot = true,\n  enableExport = true,\n  enableSearch = true,\n  enablePagination = false,\n  pageSize = 50,\n  enableColumnResize = true,\n  enableClipboard = true,\n  theme = 'light',\n  stripedRows = true,\n  exportFilename = 'data-export.csv',\n  enableVerticalResize = true,\n  initialHeight = 600,\n  minHeight = 300,\n  maxHeight = 1200,\n  numberFormat = 'us',\n  dateFormat = 'iso',\n  fieldRoleOverrides,\n  aiAnalyst,\n  enableDrillDown = true,\n  enableDrillThrough = true,\n  pivotLayout = 'grouped',\n  onCellClick,\n  onExport,\n  onCopy,\n  onAIDataLoaded,\n  onAIConversationUpdate,\n  onAIQueryExecuted,\n  onAIError,\n  onCollapseChange,\n  onDrillThrough,\n}: DataGridProps) {\n  const { showWatermark, canUsePivot, canUseCharts, canUseAIAnalyst, canUseXlsxExport, isDemo, licenseInfo } = useLicense()\n\n  // Drill-through state\n  const [drillThroughResult, setDrillThroughResult] = useState<DrillThroughResult | null>(null)\n  const [showDrillThroughModal, setShowDrillThroughModal] = useState(false)\n\n  // Check if AI Analyst should be shown (enabled in config + licensed)\n  const showAIAnalyst = aiAnalyst?.enabled && canUseAIAnalyst\n\n  // Theme handling\n  const currentTheme = useMemo(() => {\n    if (theme === 'auto') {\n      return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'\n    }\n    return theme\n  }, [theme])\n\n  // State\n  const [currentFontSize, setCurrentFontSize] = useState(initialFontSize)\n  const [globalSearchTerm, setGlobalSearchTerm] = useState('')\n  const [showSearchInput, setShowSearchInput] = useState(false)\n  const [currentPage, setCurrentPage] = useState(1)\n  const [columnWidths, setColumnWidths] = useState<Record<string, number>>({})\n  const [resizingColumnId, setResizingColumnId] = useState<string | null>(null)\n  const [resizeStartX, setResizeStartX] = useState(0)\n  const [resizeStartWidth, setResizeStartWidth] = useState(0)\n  const [gridHeight, setGridHeight] = useState(initialHeight)\n  const [isResizingVertically, setIsResizingVertically] = useState(false)\n  const [verticalResizeStartY, setVerticalResizeStartY] = useState(0)\n  const [verticalResizeStartHeight, setVerticalResizeStartHeight] = useState(0)\n  const [showCopyToast, setShowCopyToast] = useState(false)\n  const [copyToastMessage, setCopyToastMessage] = useState('')\n  const [viewMode, setViewMode] = useState<'ai' | 'grid' | 'pivot' | 'chart'>('grid')\n\n  // AI Analyst ref (for accessing loadFullData)\n  const aiAnalystRef = useRef<AIAnalystHandle>(null)\n\n  // AI-loaded data (replaces current data when AI loads results)\n  const [aiLoadedData, setAiLoadedData] = useState<Record<string, unknown>[] | null>(null)\n\n  // Loading state for full data reset\n  const [isLoadingFullData, setIsLoadingFullData] = useState(false)\n\n  // Data to display - AI loaded data takes precedence\n  const displayData = useMemo(() => aiLoadedData || data, [aiLoadedData, data])\n  const [_chartConfig, setChartConfig] = useState<ChartConfig | null>(null)\n\n  const handleChartConfigChange = useCallback((config: ChartConfig) => {\n    setChartConfig(config)\n  }, [])\n  const [showPivotConfig, setShowPivotConfig] = useState(true)\n  const [draggingField, setDraggingField] = useState<string | null>(null)\n  const [activeFilterColumn, setActiveFilterColumn] = useState<string | null>(null)\n  const [filterDropdownPosition, setFilterDropdownPosition] = useState({ top: 0, left: 0, maxHeight: 400 })\n  const [selectedCell, setSelectedCell] = useState<{ row: number, col: number } | null>(null)\n  const [selectionStart, setSelectionStart] = useState<{ row: number, col: number } | null>(null)\n  const [selectionEnd, setSelectionEnd] = useState<{ row: number, col: number } | null>(null)\n  const [isSelecting, setIsSelecting] = useState(false)\n\n  const tableContainerRef = useRef<HTMLDivElement>(null)\n  const tableBodyRef = useRef<HTMLTableSectionElement>(null)\n\n  const fontSizeOptions = [\n    { value: 'xs' as const, label: 'S' },\n    { value: 'sm' as const, label: 'M' },\n    { value: 'base' as const, label: 'L' },\n  ]\n\n  // Grid composable\n  const {\n    table,\n    columnKeys,\n    filteredRowCount,\n    totalRowCount,\n    getColumnStats,\n    hasActiveFilter,\n    setColumnFilter,\n    getColumnFilterValues,\n    clearAllFilters,\n    toggleSort,\n    getSortDirection,\n    columnFilters,\n    activeFilters,\n    // Numeric range filters\n    setNumericRangeFilter,\n    getNumericRangeFilter,\n    // Date range filters\n    setDateRangeFilter,\n    getDateRangeFilter,\n  } = useExcelGrid({ data: displayData, enableSorting: true, enableFiltering: true })\n\n  // Filtered data for pivot table\n  const filteredDataForPivot = useMemo(() => {\n    const filteredRows = table.getFilteredRowModel().rows\n    return filteredRows.map(row => row.original)\n  }, [table, columnFilters])\n\n  // Pivot table composable\n  const {\n    rowFields: pivotRowFields,\n    columnFields: pivotColumnFields,\n    valueFields: pivotValueFields,\n    showRowTotals: pivotShowRowTotals,\n    showColumnTotals: pivotShowColumnTotals,\n    calculatedFields: pivotCalculatedFields,\n    availableFields: pivotAvailableFields,\n    isConfigured: pivotIsConfigured,\n    pivotResult,\n    addRowField,\n    removeRowField,\n    addColumnField,\n    removeColumnField,\n    addValueField,\n    removeValueField,\n    updateValueFieldAggregation,\n    clearConfig: clearPivotConfig,\n    autoSuggestConfig,\n    setShowRowTotals: setPivotShowRowTotals,\n    setShowColumnTotals: setPivotShowColumnTotals,\n    setRowFields,\n    setColumnFields,\n    addCalculatedField,\n    removeCalculatedField,\n    toggleCollapsedPath,\n    fieldFilters: pivotFieldFilters,\n    activeFieldFilters: pivotActiveFieldFilters,\n    setFieldFilter: setPivotFieldFilter,\n  } = usePivotTable(filteredDataForPivot, enableDrillDown)\n\n  // Unique values per axis field — powers the axis filter UI in PivotConfig\n  const getPivotFieldValues = useCallback(\n    (field: string): string[] => getFieldUniqueValues(filteredDataForPivot, field),\n    [filteredDataForPivot],\n  )\n\n  const handleToggleCollapse = useCallback(\n    (key: string, altKey: boolean) => {\n      const next = toggleCollapsedPath(key, altKey, pivotRowFields, pivotResult)\n      onCollapseChange?.(Array.from(next))\n    },\n    [toggleCollapsedPath, pivotRowFields, pivotResult, onCollapseChange],\n  )\n\n  const handleDrillThroughCell = useCallback(\n    (payload: { rowPath: string[], columnPath: string[], valueFieldIndex: number }) => {\n      if (!enableDrillThrough)\n        return\n\n      if (!canUseDrillThrough(licenseInfo)) {\n        console.warn('[TinyPivot] \"Drill-through\" requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.')\n        return\n      }\n\n      const pivotConfig = {\n        rowFields: pivotRowFields,\n        columnFields: pivotColumnFields,\n        valueFields: pivotValueFields,\n        showRowTotals: pivotShowRowTotals,\n        showColumnTotals: pivotShowColumnTotals,\n        fieldFilters: pivotActiveFieldFilters,\n      }\n\n      const result = getDrillThroughRows(\n        filteredDataForPivot,\n        pivotConfig,\n        payload.rowPath,\n        payload.columnPath,\n        payload.valueFieldIndex,\n      )\n\n      setDrillThroughResult(result)\n      setShowDrillThroughModal(true)\n      onDrillThrough?.(result)\n    },\n    [\n      enableDrillThrough,\n      licenseInfo,\n      pivotRowFields,\n      pivotColumnFields,\n      pivotValueFields,\n      pivotShowRowTotals,\n      pivotShowColumnTotals,\n      pivotActiveFieldFilters,\n      filteredDataForPivot,\n      onDrillThrough,\n    ],\n  )\n\n  const handleCloseDrillThroughModal = useCallback(() => {\n    setShowDrillThroughModal(false)\n  }, [])\n\n  // Active filters info for display\n  const activeFilterInfo = useMemo(() => {\n    if (activeFilters.length === 0)\n      return null\n    return activeFilters.map((f) => {\n      if (f.type === 'range' && f.range) {\n        // Format numeric range filter display\n        const parts = []\n        if (f.range.min !== null)\n          parts.push(`\\u2265 ${f.range.min}`)\n        if (f.range.max !== null)\n          parts.push(`\\u2264 ${f.range.max}`)\n        return {\n          column: f.column,\n          valueCount: 1,\n          displayText: parts.join(' and '),\n          isRange: true,\n        }\n      }\n      if (f.type === 'dateRange' && f.dateRange) {\n        // Format date range filter display\n        const parts = []\n        if (f.dateRange.min !== null)\n          parts.push(`from ${coreFormatDate(f.dateRange.min, dateFormat)}`)\n        if (f.dateRange.max !== null)\n          parts.push(`to ${coreFormatDate(f.dateRange.max, dateFormat)}`)\n        return {\n          column: f.column,\n          valueCount: 1,\n          displayText: parts.join(' '),\n          isRange: true,\n        }\n      }\n      return {\n        column: f.column,\n        valueCount: f.values?.length || 0,\n        values: f.values || [],\n        isRange: false,\n      }\n    })\n  }, [activeFilters, dateFormat])\n\n  // Rows - depends on columnFilters to recompute when filters change\n  const rows = useMemo(() => table.getFilteredRowModel().rows, [table, columnFilters])\n\n  // Filtered data based on global search\n  const searchFilteredData = useMemo(() => {\n    if (!globalSearchTerm.trim() || !enableSearch) {\n      return rows\n    }\n    const term = globalSearchTerm.toLowerCase().trim()\n    return rows.filter((row) => {\n      for (const col of columnKeys) {\n        const value = row.original[col]\n        if (value === null || value === undefined)\n          continue\n        if (String(value).toLowerCase().includes(term)) {\n          return true\n        }\n      }\n      return false\n    })\n  }, [rows, globalSearchTerm, enableSearch, columnKeys])\n\n  // Paginated rows\n  const totalSearchedRows = searchFilteredData.length\n  const totalPages = useMemo(() => {\n    if (!enablePagination)\n      return 1\n    return Math.max(1, Math.ceil(totalSearchedRows / pageSize))\n  }, [enablePagination, totalSearchedRows, pageSize])\n\n  const paginatedRows = useMemo(() => {\n    if (!enablePagination)\n      return searchFilteredData\n    const start = (currentPage - 1) * pageSize\n    const end = start + pageSize\n    return searchFilteredData.slice(start, end)\n  }, [enablePagination, searchFilteredData, currentPage, pageSize])\n\n  // Reset to page 1 when filters or search changes\n  useEffect(() => {\n    setCurrentPage(1)\n  }, [columnFilters, globalSearchTerm])\n\n  // Selection bounds\n  const selectionBounds = useMemo(() => {\n    if (!selectionStart || !selectionEnd)\n      return null\n    return {\n      minRow: Math.min(selectionStart.row, selectionEnd.row),\n      maxRow: Math.max(selectionStart.row, selectionEnd.row),\n      minCol: Math.min(selectionStart.col, selectionEnd.col),\n      maxCol: Math.max(selectionStart.col, selectionEnd.col),\n    }\n  }, [selectionStart, selectionEnd])\n\n  // Selection stats\n  const selectionStats = useMemo(() => {\n    if (!selectionBounds)\n      return null\n    const { minRow, maxRow, minCol, maxCol } = selectionBounds\n\n    const values: number[] = []\n    let count = 0\n\n    for (let r = minRow; r <= maxRow; r++) {\n      const row = rows[r]\n      if (!row)\n        continue\n\n      for (let c = minCol; c <= maxCol; c++) {\n        const colId = columnKeys[c]\n        if (!colId)\n          continue\n\n        const value = row.original[colId]\n        count++\n\n        if (value !== null && value !== undefined && value !== '') {\n          const num = typeof value === 'number' ? value : Number.parseFloat(String(value))\n          if (!Number.isNaN(num)) {\n            values.push(num)\n          }\n        }\n      }\n    }\n\n    if (values.length === 0)\n      return { count, sum: null, avg: null, numericCount: 0 }\n\n    const sum = values.reduce((a, b) => a + b, 0)\n    const avg = sum / values.length\n\n    return { count, sum, avg, numericCount: values.length }\n  }, [selectionBounds, rows, columnKeys])\n\n  // Calculate column widths\n  useEffect(() => {\n    // Skip during SSR (no document available)\n    if (typeof document === 'undefined')\n      return\n    if (displayData.length === 0)\n      return\n\n    const widths: Record<string, number> = {}\n    const sampleSize = Math.min(100, displayData.length)\n    const canvas = document.createElement('canvas')\n    const ctx = canvas.getContext('2d')\n    if (!ctx)\n      return\n\n    ctx.font = '13px system-ui, -apple-system, sans-serif'\n\n    for (const key of columnKeys) {\n      let maxWidth = ctx.measureText(key).width + 56\n\n      for (let i = 0; i < sampleSize; i++) {\n        const value = displayData[i][key]\n        const text = value === null || value === undefined ? '' : String(value)\n        const width = ctx.measureText(text).width + 28\n        maxWidth = Math.max(maxWidth, width)\n      }\n\n      widths[key] = Math.min(Math.max(maxWidth, MIN_COL_WIDTH), MAX_COL_WIDTH)\n    }\n\n    setColumnWidths(widths)\n  }, [displayData, columnKeys])\n\n  // Column resize handlers\n  const startColumnResize = useCallback(\n    (columnId: string, event: React.MouseEvent) => {\n      if (!enableColumnResize)\n        return\n      event.preventDefault()\n      event.stopPropagation()\n\n      setResizingColumnId(columnId)\n      setResizeStartX(event.clientX)\n      setResizeStartWidth(columnWidths[columnId] || MIN_COL_WIDTH)\n    },\n    [enableColumnResize, columnWidths],\n  )\n\n  useEffect(() => {\n    if (!resizingColumnId)\n      return\n\n    const handleResizeMove = (event: MouseEvent) => {\n      const diff = event.clientX - resizeStartX\n      const newWidth = Math.max(MIN_COL_WIDTH, Math.min(MAX_COL_WIDTH, resizeStartWidth + diff))\n      setColumnWidths(prev => ({\n        ...prev,\n        [resizingColumnId]: newWidth,\n      }))\n    }\n\n    const handleResizeEnd = () => {\n      setResizingColumnId(null)\n    }\n\n    document.addEventListener('mousemove', handleResizeMove)\n    document.addEventListener('mouseup', handleResizeEnd)\n    return () => {\n      document.removeEventListener('mousemove', handleResizeMove)\n      document.removeEventListener('mouseup', handleResizeEnd)\n    }\n  }, [resizingColumnId, resizeStartX, resizeStartWidth])\n\n  // Vertical resize handlers\n  const startVerticalResize = useCallback(\n    (event: React.MouseEvent) => {\n      if (!enableVerticalResize)\n        return\n      event.preventDefault()\n\n      setIsResizingVertically(true)\n      setVerticalResizeStartY(event.clientY)\n      setVerticalResizeStartHeight(gridHeight)\n    },\n    [enableVerticalResize, gridHeight],\n  )\n\n  useEffect(() => {\n    if (!isResizingVertically)\n      return\n\n    const handleVerticalResizeMove = (event: MouseEvent) => {\n      const diff = event.clientY - verticalResizeStartY\n      const newHeight = Math.max(minHeight, Math.min(maxHeight, verticalResizeStartHeight + diff))\n      setGridHeight(newHeight)\n    }\n\n    const handleVerticalResizeEnd = () => {\n      setIsResizingVertically(false)\n    }\n\n    document.addEventListener('mousemove', handleVerticalResizeMove)\n    document.addEventListener('mouseup', handleVerticalResizeEnd)\n    return () => {\n      document.removeEventListener('mousemove', handleVerticalResizeMove)\n      document.removeEventListener('mouseup', handleVerticalResizeEnd)\n    }\n  }, [isResizingVertically, verticalResizeStartY, verticalResizeStartHeight, minHeight, maxHeight])\n\n  // Export handlers\n  const handleExport = useCallback(() => {\n    if (viewMode === 'pivot') {\n      if (!pivotResult)\n        return\n\n      const pivotFilename = exportFilename.replace('.csv', '-pivot.csv')\n      exportPivotToCSV(\n        {\n          headers: pivotResult.headers,\n          rowHeaders: pivotResult.rowHeaders,\n          data: pivotResult.data,\n          rowTotals: pivotResult.rowTotals,\n          columnTotals: pivotResult.columnTotals,\n          grandTotal: pivotResult.grandTotal,\n          showRowTotals: pivotShowRowTotals,\n          showColumnTotals: pivotShowColumnTotals,\n        },\n        pivotRowFields,\n        pivotColumnFields,\n        pivotValueFields,\n        { filename: pivotFilename },\n      )\n\n      onExport?.({ rowCount: pivotResult.rowHeaders.length, filename: pivotFilename })\n      return\n    }\n\n    const dataToExport\n      = enableSearch && globalSearchTerm.trim()\n        ? searchFilteredData.map(row => row.original)\n        : rows.map(row => row.original)\n\n    exportToCSV(dataToExport, columnKeys, {\n      filename: exportFilename,\n      includeHeaders: true,\n    })\n\n    onExport?.({ rowCount: dataToExport.length, filename: exportFilename })\n  }, [\n    viewMode,\n    pivotResult,\n    exportFilename,\n    pivotShowRowTotals,\n    pivotShowColumnTotals,\n    pivotRowFields,\n    pivotColumnFields,\n    pivotValueFields,\n    enableSearch,\n    globalSearchTerm,\n    searchFilteredData,\n    rows,\n    columnKeys,\n    onExport,\n  ])\n\n  const handleExportXLSX = useCallback(async () => {\n    if (viewMode === 'pivot') {\n      if (!pivotResult)\n        return\n\n      const xlsxFilename = exportFilename.replace('.csv', '-pivot.xlsx')\n\n      try {\n        await exportPivotToXLSX(\n          {\n            headers: pivotResult.headers,\n            rowHeaders: pivotResult.rowHeaders,\n            data: pivotResult.data,\n            rowTotals: pivotResult.rowTotals,\n            columnTotals: pivotResult.columnTotals,\n            grandTotal: pivotResult.grandTotal,\n            showRowTotals: pivotShowRowTotals,\n            showColumnTotals: pivotShowColumnTotals,\n          },\n          pivotRowFields,\n          pivotColumnFields,\n          pivotValueFields,\n          { filename: xlsxFilename },\n          { rows: filteredDataForPivot, columns: columnKeys },\n        )\n        onExport?.({ rowCount: pivotResult.rowHeaders.length, filename: xlsxFilename })\n      }\n      catch (err) {\n        console.error('[TinyPivot] XLSX pivot export failed:', err)\n      }\n      return\n    }\n\n    const dataToExport\n      = enableSearch && globalSearchTerm.trim()\n        ? searchFilteredData.map(row => row.original)\n        : rows.map(row => row.original)\n\n    const xlsxFilename = exportFilename.replace('.csv', '.xlsx')\n\n    try {\n      await exportToXLSX(dataToExport, columnKeys, { filename: xlsxFilename })\n      onExport?.({ rowCount: dataToExport.length, filename: xlsxFilename })\n    }\n    catch (err) {\n      console.error('[TinyPivot] XLSX export failed:', err)\n    }\n  }, [\n    viewMode,\n    pivotResult,\n    exportFilename,\n    pivotShowRowTotals,\n    pivotShowColumnTotals,\n    pivotRowFields,\n    pivotColumnFields,\n    pivotValueFields,\n    enableSearch,\n    globalSearchTerm,\n    searchFilteredData,\n    rows,\n    columnKeys,\n    filteredDataForPivot,\n    onExport,\n  ])\n\n  // Copy to clipboard\n  const copySelectionToClipboard = useCallback(() => {\n    if (!selectionBounds || !enableClipboard)\n      return\n\n    const text = formatSelectionForClipboard(\n      rows.map(r => r.original),\n      columnKeys,\n      selectionBounds,\n    )\n\n    copyToClipboard(\n      text,\n      () => {\n        const cellCount\n          = (selectionBounds.maxRow - selectionBounds.minRow + 1)\n            * (selectionBounds.maxCol - selectionBounds.minCol + 1)\n        setCopyToastMessage(`Copied ${cellCount} cell${cellCount > 1 ? 's' : ''}`)\n        setShowCopyToast(true)\n        setTimeout(setShowCopyToast, 2000, false)\n        onCopy?.({ text, cellCount })\n      },\n      (err) => {\n        setCopyToastMessage('Copy failed')\n        setShowCopyToast(true)\n        setTimeout(setShowCopyToast, 2000, false)\n        console.error('Copy failed:', err)\n      },\n    )\n  }, [selectionBounds, enableClipboard, rows, columnKeys, onCopy])\n\n  // Cell selection handlers\n  const handleMouseDown = useCallback(\n    (rowIndex: number, colIndex: number, event: React.MouseEvent) => {\n      event.preventDefault()\n\n      if (event.shiftKey && selectedCell) {\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n      }\n      else {\n        setSelectedCell({ row: rowIndex, col: colIndex })\n        setSelectionStart({ row: rowIndex, col: colIndex })\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n        setIsSelecting(true)\n      }\n\n      const row = rows[rowIndex]\n      if (row) {\n        const colId = columnKeys[colIndex]\n        onCellClick?.({\n          row: rowIndex,\n          col: colIndex,\n          value: row.original[colId],\n          rowData: row.original,\n        })\n      }\n    },\n    [selectedCell, rows, columnKeys, onCellClick],\n  )\n\n  const handleMouseEnter = useCallback(\n    (rowIndex: number, colIndex: number) => {\n      if (isSelecting) {\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n      }\n    },\n    [isSelecting],\n  )\n\n  // Track if we're showing AI-shaped data (filtered/aggregated by AI queries)\n  const isShowingAIData = aiLoadedData !== null\n\n  // Reset to full original dataset\n  // If AI Analyst is enabled and has a selected data source, load full data from that source\n  // Otherwise, just clear the AI loaded data to show original props.data\n  const resetToFullData = useCallback(async () => {\n    // If we have AI Analyst with a selected data source, load full data from it\n    if (aiAnalystRef.current?.selectedDataSource) {\n      setIsLoadingFullData(true)\n      try {\n        const fullData = await aiAnalystRef.current.loadFullData()\n        if (fullData && fullData.length > 0) {\n          setAiLoadedData(fullData)\n        }\n        else {\n          // Fall back to props.data if loading fails\n          setAiLoadedData(null)\n        }\n      }\n      catch (err) {\n        console.warn('Failed to load full data:', err)\n        setAiLoadedData(null)\n      }\n      finally {\n        setIsLoadingFullData(false)\n      }\n    }\n    else {\n      // No AI Analyst or no selected data source - just clear filters by resetting to props.data\n      setAiLoadedData(null)\n    }\n    // Also clear any grid filters\n    clearAllFilters()\n  }, [clearAllFilters])\n\n  // AI Analyst event handlers\n  const handleAIDataLoaded = useCallback(\n    (payload: AIDataLoadedEvent) => {\n      setAiLoadedData(payload.data)\n      // Don't auto-switch to grid - let user decide when to view results\n      onAIDataLoaded?.(payload)\n    },\n    [onAIDataLoaded],\n  )\n\n  const handleAIConversationUpdate = useCallback(\n    (payload: AIConversationUpdateEvent) => {\n      onAIConversationUpdate?.(payload)\n    },\n    [onAIConversationUpdate],\n  )\n\n  const handleAIQueryExecuted = useCallback(\n    (payload: AIQueryExecutedEvent) => {\n      onAIQueryExecuted?.(payload)\n    },\n    [onAIQueryExecuted],\n  )\n\n  const handleAIError = useCallback(\n    (payload: AIErrorEvent) => {\n      onAIError?.(payload)\n    },\n    [onAIError],\n  )\n\n  useEffect(() => {\n    const handleMouseUp = () => setIsSelecting(false)\n    document.addEventListener('mouseup', handleMouseUp)\n    return () => document.removeEventListener('mouseup', handleMouseUp)\n  }, [])\n\n  // Keyboard handling\n  useEffect(() => {\n    const handleKeydown = (event: KeyboardEvent) => {\n      // Handle Ctrl+C / Cmd+C for clipboard\n      if ((event.ctrlKey || event.metaKey) && event.key === 'c' && selectionBounds) {\n        event.preventDefault()\n        copySelectionToClipboard()\n        return\n      }\n\n      // Handle Escape\n      if (event.key === 'Escape') {\n        setSelectedCell(null)\n        setSelectionStart(null)\n        setSelectionEnd(null)\n        setShowSearchInput(false)\n        setGlobalSearchTerm('')\n      }\n    }\n\n    document.addEventListener('keydown', handleKeydown)\n    return () => document.removeEventListener('keydown', handleKeydown)\n  }, [selectionBounds, copySelectionToClipboard])\n\n  // Filter dropdown\n  const openFilterDropdown = useCallback(\n    (columnId: string, event: React.MouseEvent) => {\n      event.stopPropagation()\n      const target = event.currentTarget as HTMLElement\n      const headerCell = target.closest('.vpg-header-cell') as HTMLElement\n      const rect = headerCell?.getBoundingClientRect() || target.getBoundingClientRect()\n\n      const dropdownWidth = 280\n      const padding = 12\n\n      let left = rect.left\n      if (left + dropdownWidth > window.innerWidth - padding) {\n        left = window.innerWidth - dropdownWidth - padding\n      }\n      left = Math.max(padding, left)\n\n      const spaceBelow = window.innerHeight - rect.bottom - padding\n      const spaceAbove = rect.top - padding\n\n      let top: number\n      let maxDropdownHeight: number\n\n      if (spaceBelow >= 300 || spaceBelow >= spaceAbove) {\n        top = rect.bottom + 4\n        maxDropdownHeight = Math.min(400, spaceBelow - 4)\n      }\n      else {\n        maxDropdownHeight = Math.min(400, spaceAbove - 4)\n        top = rect.top - maxDropdownHeight - 4\n      }\n\n      setFilterDropdownPosition({ top, left, maxHeight: maxDropdownHeight })\n      setActiveFilterColumn(columnId)\n    },\n    [],\n  )\n\n  const closeFilterDropdown = useCallback(() => {\n    setActiveFilterColumn(null)\n  }, [])\n\n  const handleFilter = useCallback(\n    (columnId: string, values: string[]) => {\n      setColumnFilter(columnId, values)\n    },\n    [setColumnFilter],\n  )\n\n  const handleRangeFilter = useCallback(\n    (columnId: string, range: import('@smallwebco/tinypivot-core').NumericRange | null) => {\n      setNumericRangeFilter(columnId, range)\n    },\n    [setNumericRangeFilter],\n  )\n\n  const handleDateRangeFilter = useCallback(\n    (columnId: string, range: DateRange | null) => {\n      setDateRangeFilter(columnId, range)\n    },\n    [setDateRangeFilter],\n  )\n\n  const handleSort = useCallback(\n    (columnId: string, direction: 'asc' | 'desc' | null) => {\n      if (direction === null) {\n        const current = getSortDirection(columnId)\n        if (current) {\n          toggleSort(columnId)\n          if (getSortDirection(columnId)) {\n            toggleSort(columnId)\n          }\n        }\n      }\n      else {\n        const current = getSortDirection(columnId)\n        if (current === null) {\n          toggleSort(columnId)\n          if (direction === 'desc' && getSortDirection(columnId) === 'asc') {\n            toggleSort(columnId)\n          }\n        }\n        else if (current !== direction) {\n          toggleSort(columnId)\n        }\n      }\n    },\n    [getSortDirection, toggleSort],\n  )\n\n  const isCellSelected = useCallback(\n    (rowIndex: number, colIndex: number): boolean => {\n      if (!selectionBounds) {\n        return selectedCell?.row === rowIndex && selectedCell?.col === colIndex\n      }\n      const { minRow, maxRow, minCol, maxCol } = selectionBounds\n      return rowIndex >= minRow && rowIndex <= maxRow && colIndex >= minCol && colIndex <= maxCol\n    },\n    [selectionBounds, selectedCell],\n  )\n\n  const formatStatValue = (value: number | null): string => {\n    if (value === null)\n      return '-'\n    return coreFormatNumber(value, numberFormat)\n  }\n\n  // Format cell value\n  const noFormatPatterns\n    = /^(?:.*_)?(?:id|code|year|month|quarter|day|week|date|zip|phone|fax|ssn|ein|npi|ndc|gpi|hcpcs|icd|cpt|rx|bin|pcn|group|member|claim|rx_number|script|fill)(?:_.*)?$/i\n\n  const shouldFormatNumber = (columnId: string): boolean => {\n    return !noFormatPatterns.test(columnId)\n  }\n\n  const formatCellValueDisplay = (value: unknown, columnId: string): string => {\n    if (value === null || value === undefined)\n      return ''\n    if (value === '')\n      return ''\n\n    const stats = getColumnStats(columnId)\n\n    if (stats.type === 'date') {\n      return coreFormatDate(value, dateFormat)\n    }\n\n    if (stats.type === 'number') {\n      const num = typeof value === 'number' ? value : Number.parseFloat(String(value))\n      if (Number.isNaN(num))\n        return String(value)\n\n      if (shouldFormatNumber(columnId) && Math.abs(num) >= 1000) {\n        return coreFormatNumber(num, numberFormat)\n      }\n\n      if (Number.isInteger(num)) {\n        return String(num)\n      }\n      return coreFormatNumber(num, numberFormat, { maximumFractionDigits: 4 })\n    }\n\n    return String(value)\n  }\n\n  const totalTableWidth = useMemo(() => {\n    return columnKeys.reduce((sum, key) => sum + (columnWidths[key] || MIN_COL_WIDTH), 0)\n  }, [columnKeys, columnWidths])\n\n  const activeFilterCount = columnFilters.length\n\n  return (\n    <div\n      className={`vpg-data-grid vpg-font-${currentFontSize} vpg-theme-${currentTheme} ${stripedRows ? 'vpg-striped' : ''} ${resizingColumnId ? 'vpg-resizing' : ''} ${isResizingVertically ? 'vpg-resizing-vertical' : ''}`}\n      style={{ height: `${gridHeight}px` }}\n    >\n      {/* Copy Toast */}\n      {showCopyToast && (\n        <div className=\"vpg-toast\">\n          <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n          </svg>\n          {copyToastMessage}\n        </div>\n      )}\n\n      {/* Toolbar */}\n      <div className=\"vpg-toolbar\">\n        <div className=\"vpg-toolbar-left\">\n          {/* View mode toggle */}\n          {showPivot && (\n            <div className=\"vpg-view-toggle\">\n              {/* AI Analyst button (first, only if enabled) */}\n              {showAIAnalyst && (\n                <button\n                  className={`vpg-view-btn vpg-ai-btn ${viewMode === 'ai' ? 'active' : ''}`}\n                  onClick={() => setViewMode('ai')}\n                >\n                  <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                    <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z\" />\n                  </svg>\n                  AI Analyst\n                </button>\n              )}\n              {aiAnalyst?.enabled && !canUseAIAnalyst && (\n                <button\n                  className=\"vpg-view-btn vpg-ai-btn vpg-pro-feature\"\n                  title=\"AI Analyst (Pro feature)\"\n                  onClick={e => e.preventDefault()}\n                >\n                  <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                    <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h1a7 7 0 0 1 7 7h1a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1h-1v1a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-1H2a1 1 0 0 1-1-1v-3a1 1 0 0 1 1-1h1a7 7 0 0 1 7-7h1V5.73c-.6-.34-1-.99-1-1.73a2 2 0 0 1 2-2z\" />\n                  </svg>\n                  AI Analyst\n                  <span className=\"vpg-pro-badge\">Pro</span>\n                </button>\n              )}\n              <button\n                className={`vpg-view-btn ${viewMode === 'grid' ? 'active' : ''}`}\n                onClick={() => setViewMode('grid')}\n              >\n                <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={2}\n                    d=\"M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\n                  />\n                </svg>\n                Grid\n              </button>\n              <button\n                className={`vpg-view-btn vpg-pivot-btn ${viewMode === 'pivot' ? 'active' : ''}`}\n                onClick={() => setViewMode('pivot')}\n              >\n                <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={2}\n                    d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n                  />\n                </svg>\n                Pivot\n              </button>\n              <button\n                className={`vpg-view-btn vpg-chart-btn ${viewMode === 'chart' ? 'active' : ''} ${!canUseCharts ? 'vpg-pro-feature' : ''}`}\n                title={canUseCharts ? 'Chart Builder' : 'Chart Builder (Pro feature)'}\n                onClick={() => canUseCharts && setViewMode('chart')}\n              >\n                <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={2}\n                    d=\"M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z\"\n                  />\n                </svg>\n                Chart\n                {!canUseCharts && <span className=\"vpg-pro-badge\">Pro</span>}\n              </button>\n            </div>\n          )}\n\n          {/* Grid mode controls */}\n          {viewMode === 'grid' && (\n            <>\n              {/* Search */}\n              {enableSearch && (\n                <div className=\"vpg-search-container\">\n                  {!showSearchInput\n                    ? (\n                        <button\n                          className=\"vpg-icon-btn\"\n                          title=\"Search (Ctrl+F)\"\n                          onClick={() => setShowSearchInput(true)}\n                        >\n                          <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                            <path\n                              strokeLinecap=\"round\"\n                              strokeLinejoin=\"round\"\n                              strokeWidth={2}\n                              d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n                            />\n                          </svg>\n                        </button>\n                      )\n                    : (\n                        <div className=\"vpg-search-box\">\n                          <svg\n                            className=\"vpg-search-icon\"\n                            fill=\"none\"\n                            stroke=\"currentColor\"\n                            viewBox=\"0 0 24 24\"\n                          >\n                            <path\n                              strokeLinecap=\"round\"\n                              strokeLinejoin=\"round\"\n                              strokeWidth={2}\n                              d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n                            />\n                          </svg>\n                          <input\n                            type=\"text\"\n                            value={globalSearchTerm}\n                            onChange={e => setGlobalSearchTerm(e.target.value)}\n                            className=\"vpg-search-input\"\n                            placeholder=\"Search all columns...\"\n                            onKeyDown={(e) => {\n                              if (e.key === 'Escape') {\n                                setShowSearchInput(false)\n                                setGlobalSearchTerm('')\n                              }\n                            }}\n                            autoFocus\n                          />\n                          {globalSearchTerm && (\n                            <button className=\"vpg-search-clear\" onClick={() => setGlobalSearchTerm('')}>\n                              <svg\n                                className=\"vpg-icon-xs\"\n                                fill=\"none\"\n                                stroke=\"currentColor\"\n                                viewBox=\"0 0 24 24\"\n                              >\n                                <path\n                                  strokeLinecap=\"round\"\n                                  strokeLinejoin=\"round\"\n                                  strokeWidth={2}\n                                  d=\"M6 18L18 6M6 6l12 12\"\n                                />\n                              </svg>\n                            </button>\n                          )}\n                        </div>\n                      )}\n                </div>\n              )}\n\n              <div className=\"vpg-font-size-control\">\n                <span className=\"vpg-label\">Size:</span>\n                <div className=\"vpg-font-size-toggle\">\n                  {fontSizeOptions.map(opt => (\n                    <button\n                      key={opt.value}\n                      className={`vpg-font-size-btn ${currentFontSize === opt.value ? 'active' : ''}`}\n                      onClick={() => setCurrentFontSize(opt.value)}\n                    >\n                      {opt.label}\n                    </button>\n                  ))}\n                </div>\n              </div>\n\n              {activeFilterCount > 0 && (\n                <div className=\"vpg-filter-info\">\n                  <svg className=\"vpg-icon\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                    <path\n                      fillRule=\"evenodd\"\n                      d=\"M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z\"\n                      clipRule=\"evenodd\"\n                    />\n                  </svg>\n                  <span>\n                    {activeFilterCount}\n                    {' '}\n                    filter\n                    {activeFilterCount > 1 ? 's' : ''}\n                  </span>\n                </div>\n              )}\n\n              {globalSearchTerm && (\n                <div className=\"vpg-search-info\">\n                  <span>\n                    {totalSearchedRows}\n                    {' '}\n                    match\n                    {totalSearchedRows !== 1 ? 'es' : ''}\n                  </span>\n                </div>\n              )}\n            </>\n          )}\n\n          {/* Pivot mode controls */}\n          {viewMode === 'pivot' && canUsePivot && (\n            <>\n              <button\n                className={`vpg-config-toggle ${showPivotConfig ? 'active' : ''}`}\n                onClick={() => setShowPivotConfig(!showPivotConfig)}\n              >\n                <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={2}\n                    d=\"M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4\"\n                  />\n                </svg>\n                {showPivotConfig ? 'Hide' : 'Show'}\n                {' '}\n                Config\n              </button>\n\n              {pivotIsConfigured && (\n                <div className=\"vpg-pivot-status\">\n                  <svg className=\"vpg-icon\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                    <path\n                      fillRule=\"evenodd\"\n                      d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n                      clipRule=\"evenodd\"\n                    />\n                  </svg>\n                  <span>Pivot configured</span>\n                </div>\n              )}\n            </>\n          )}\n        </div>\n\n        <div className=\"vpg-toolbar-right\">\n          {viewMode === 'grid' && activeFilterCount > 0 && (\n            <button className=\"vpg-clear-filters\" onClick={clearAllFilters}>\n              <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M6 18L18 6M6 6l12 12\"\n                />\n              </svg>\n              Clear Filters\n            </button>\n          )}\n\n          {/* Reset to full data button (when showing AI-filtered results) */}\n          {viewMode === 'grid' && isShowingAIData && (\n            <button\n              className={`vpg-reset-data-btn${isLoadingFullData ? ' vpg-loading-btn' : ''}`}\n              disabled={isLoadingFullData}\n              title=\"Reset to full dataset\"\n              onClick={resetToFullData}\n            >\n              <svg className={`vpg-icon${isLoadingFullData ? ' vpg-spin' : ''}`} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n                />\n              </svg>\n              <span>{isLoadingFullData ? 'Loading...' : 'Full Data'}</span>\n            </button>\n          )}\n\n          {/* Copy button */}\n          {enableClipboard && selectionBounds && viewMode === 'grid' && (\n            <button\n              className=\"vpg-icon-btn\"\n              title=\"Copy selection (Ctrl+C)\"\n              onClick={copySelectionToClipboard}\n            >\n              <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n                />\n              </svg>\n            </button>\n          )}\n\n          {/* Export dropdown menu */}\n          {enableExport && viewMode === 'grid' && (\n            <ExportMenu\n              formats={[\n                { key: 'csv', label: 'CSV' },\n                { key: 'xlsx', label: 'Excel (.xlsx)', disabled: !canUseXlsxExport, badge: !canUseXlsxExport ? 'Pro' : undefined },\n              ]}\n              onSelect={key => key === 'csv' ? handleExport() : handleExportXLSX()}\n            />\n          )}\n          {enableExport && viewMode === 'pivot' && pivotIsConfigured && (\n            <ExportMenu\n              formats={[\n                { key: 'csv', label: 'CSV' },\n                { key: 'xlsx', label: 'Excel (.xlsx)', disabled: !canUseXlsxExport, badge: !canUseXlsxExport ? 'Pro' : undefined },\n              ]}\n              onSelect={key => key === 'csv' ? handleExport() : handleExportXLSX()}\n            />\n          )}\n        </div>\n      </div>\n\n      {/* AI Analyst View - always render if enabled, use CSS to hide for state preservation */}\n      {showAIAnalyst && aiAnalyst && (\n        <div className=\"vpg-ai-view\" style={{ display: viewMode === 'ai' ? undefined : 'none' }}>\n          <AIAnalyst\n            ref={aiAnalystRef}\n            config={aiAnalyst}\n            theme={currentTheme}\n            onDataLoaded={handleAIDataLoaded}\n            onConversationUpdate={handleAIConversationUpdate}\n            onQueryExecuted={handleAIQueryExecuted}\n            onError={handleAIError}\n          />\n        </div>\n      )}\n\n      {/* Grid View */}\n      {viewMode === 'grid' && (\n        <div ref={tableContainerRef} className=\"vpg-grid-container\" tabIndex={0}>\n          {loading && (\n            <div className=\"vpg-loading\">\n              <div className=\"vpg-spinner\" />\n              <span>Loading data...</span>\n            </div>\n          )}\n\n          {!loading && displayData.length === 0 && (\n            <div className=\"vpg-empty\">\n              <div className=\"vpg-empty-icon\">\n                <svg className=\"vpg-icon-lg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={1.5}\n                    d=\"M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n                  />\n                </svg>\n              </div>\n              <span>No data available</span>\n            </div>\n          )}\n\n          {!loading && displayData.length > 0 && filteredRowCount === 0 && (\n            <div className=\"vpg-empty\">\n              <div className=\"vpg-empty-icon vpg-warning\">\n                <svg className=\"vpg-icon-lg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={1.5}\n                    d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n                  />\n                </svg>\n              </div>\n              <span>No matching records</span>\n              <button className=\"vpg-clear-link\" onClick={clearAllFilters}>\n                Clear all filters\n              </button>\n            </div>\n          )}\n\n          {!loading && filteredRowCount > 0 && (\n            <div className=\"vpg-table-wrapper\">\n              <table className=\"vpg-table\" style={{ minWidth: `${totalTableWidth}px` }}>\n                <thead>\n                  <tr>\n                    {columnKeys.map(colId => (\n                      <th\n                        key={colId}\n                        className={`vpg-header-cell ${hasActiveFilter(colId) ? 'vpg-has-filter' : ''} ${getSortDirection(colId) !== null ? 'vpg-is-sorted' : ''} ${activeFilterColumn === colId ? 'vpg-is-active' : ''}`}\n                        style={{\n                          width: `${columnWidths[colId] || MIN_COL_WIDTH}px`,\n                          minWidth: `${columnWidths[colId] || MIN_COL_WIDTH}px`,\n                        }}\n                        onClick={(e) => {\n                          const target = e.target as HTMLElement\n                          if (target.closest('.vpg-dropdown-arrow')) {\n                            openFilterDropdown(colId, e)\n                          }\n                        }}\n                      >\n                        <div className=\"vpg-header-content\">\n                          <span className=\"vpg-header-text\">{colId}</span>\n                          <div className=\"vpg-header-icons\">\n                            {getSortDirection(colId) && (\n                              <span className=\"vpg-sort-indicator\">\n                                {getSortDirection(colId) === 'asc'\n                                  ? (\n                                      <svg\n                                        className=\"vpg-icon-sm\"\n                                        fill=\"currentColor\"\n                                        viewBox=\"0 0 20 20\"\n                                      >\n                                        <path\n                                          fillRule=\"evenodd\"\n                                          d=\"M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z\"\n                                          clipRule=\"evenodd\"\n                                        />\n                                      </svg>\n                                    )\n                                  : (\n                                      <svg\n                                        className=\"vpg-icon-sm\"\n                                        fill=\"currentColor\"\n                                        viewBox=\"0 0 20 20\"\n                                      >\n                                        <path\n                                          fillRule=\"evenodd\"\n                                          d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\"\n                                          clipRule=\"evenodd\"\n                                        />\n                                      </svg>\n                                    )}\n                              </span>\n                            )}\n                            {hasActiveFilter(colId) && (\n                              <span className=\"vpg-filter-indicator\">\n                                <svg\n                                  className=\"vpg-icon-xs\"\n                                  fill=\"currentColor\"\n                                  viewBox=\"0 0 20 20\"\n                                >\n                                  <path\n                                    fillRule=\"evenodd\"\n                                    d=\"M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z\"\n                                    clipRule=\"evenodd\"\n                                  />\n                                </svg>\n                              </span>\n                            )}\n                            <span className=\"vpg-dropdown-arrow\" title=\"Filter & Sort\">\n                              <svg\n                                className=\"vpg-icon-sm\"\n                                fill=\"none\"\n                                stroke=\"currentColor\"\n                                viewBox=\"0 0 24 24\"\n                              >\n                                <path\n                                  strokeLinecap=\"round\"\n                                  strokeLinejoin=\"round\"\n                                  strokeWidth={2}\n                                  d=\"M19 9l-7 7-7-7\"\n                                />\n                              </svg>\n                            </span>\n                          </div>\n                        </div>\n                        {enableColumnResize && (\n                          <div\n                            className=\"vpg-resize-handle\"\n                            onMouseDown={e => startColumnResize(colId, e)}\n                          />\n                        )}\n                      </th>\n                    ))}\n                  </tr>\n                </thead>\n\n                <tbody ref={tableBodyRef}>\n                  {paginatedRows.map((row, rowIndex) => (\n                    <tr key={row.id} className=\"vpg-row\">\n                      {columnKeys.map((colId, colIndex) => (\n                        <td\n                          key={colId}\n                          className={`vpg-cell ${isCellSelected(rowIndex, colIndex) ? 'vpg-selected' : ''} ${getColumnStats(colId).type === 'number' ? 'vpg-is-number' : ''}`}\n                          data-row={rowIndex}\n                          data-col={colIndex}\n                          style={{\n                            width: `${columnWidths[colId] || MIN_COL_WIDTH}px`,\n                            minWidth: `${columnWidths[colId] || MIN_COL_WIDTH}px`,\n                          }}\n                          onMouseDown={e => handleMouseDown(rowIndex, colIndex, e)}\n                          onMouseEnter={() => handleMouseEnter(rowIndex, colIndex)}\n                        >\n                          {formatCellValueDisplay(row.original[colId], colId)}\n                        </td>\n                      ))}\n                    </tr>\n                  ))}\n                </tbody>\n              </table>\n            </div>\n          )}\n        </div>\n      )}\n\n      {/* Pivot View */}\n      {viewMode === 'pivot' && (\n        <div className=\"vpg-pivot-container\">\n          {showPivotConfig && canUsePivot && (\n            <div className=\"vpg-pivot-config-panel\">\n              <PivotConfig\n                availableFields={pivotAvailableFields}\n                rowFields={pivotRowFields}\n                columnFields={pivotColumnFields}\n                valueFields={pivotValueFields}\n                showRowTotals={pivotShowRowTotals}\n                showColumnTotals={pivotShowColumnTotals}\n                calculatedFields={pivotCalculatedFields}\n                onShowRowTotalsChange={setPivotShowRowTotals}\n                onShowColumnTotalsChange={setPivotShowColumnTotals}\n                onClearConfig={clearPivotConfig}\n                onAutoSuggest={autoSuggestConfig}\n                onDragStart={(field, _e) => setDraggingField(field)}\n                onDragEnd={() => setDraggingField(null)}\n                onUpdateAggregation={updateValueFieldAggregation}\n                onAddRowField={addRowField}\n                onRemoveRowField={removeRowField}\n                onAddColumnField={addColumnField}\n                onRemoveColumnField={removeColumnField}\n                onAddValueField={addValueField}\n                onRemoveValueField={removeValueField}\n                onAddCalculatedField={addCalculatedField}\n                onRemoveCalculatedField={removeCalculatedField}\n                onUpdateCalculatedField={addCalculatedField}\n                theme={currentTheme}\n                fieldFilters={pivotFieldFilters}\n                getFieldValues={getPivotFieldValues}\n                onUpdateFieldFilter={setPivotFieldFilter}\n              />\n            </div>\n          )}\n\n          <div className={`vpg-pivot-main ${!showPivotConfig ? 'vpg-full-width' : ''}`}>\n            <PivotSkeleton\n              rowFields={pivotRowFields}\n              columnFields={pivotColumnFields}\n              valueFields={pivotValueFields}\n              calculatedFields={pivotCalculatedFields}\n              isConfigured={pivotIsConfigured}\n              draggingField={draggingField}\n              pivotResult={pivotResult}\n              hasActiveFieldFilters={Object.keys(pivotFieldFilters).length > 0}\n              fontSize={currentFontSize}\n              activeFilters={activeFilterInfo}\n              totalRowCount={totalRowCount}\n              filteredRowCount={filteredRowCount}\n              enableDrillDown={enableDrillDown}\n              enableDrillThrough={enableDrillThrough}\n              pivotLayout={pivotLayout}\n              onAddRowField={addRowField}\n              onRemoveRowField={removeRowField}\n              onAddColumnField={addColumnField}\n              onRemoveColumnField={removeColumnField}\n              onAddValueField={addValueField}\n              onRemoveValueField={removeValueField}\n              onUpdateAggregation={updateValueFieldAggregation}\n              onReorderRowFields={setRowFields}\n              onReorderColumnFields={setColumnFields}\n              onToggleCollapse={handleToggleCollapse}\n              onDrillThroughCell={handleDrillThroughCell}\n              theme={currentTheme}\n            />\n\n            <DrillThroughModal\n              show={showDrillThroughModal}\n              result={drillThroughResult}\n              rowFields={pivotRowFields}\n              columnFields={pivotColumnFields}\n              valueFields={pivotValueFields}\n              theme={currentTheme}\n              onClose={handleCloseDrillThroughModal}\n            />\n          </div>\n        </div>\n      )}\n\n      {/* Chart View */}\n      {viewMode === 'chart' && (\n        <div className=\"vpg-chart-view\">\n          {/* Filter indicator for chart */}\n          {activeFilterInfo && activeFilterInfo.length > 0 && (\n            <div className=\"vpg-chart-filter-bar\">\n              <svg className=\"vpg-icon\" fill=\"currentColor\" viewBox=\"0 0 20 20\">\n                <path fillRule=\"evenodd\" d=\"M3 3a1 1 0 011-1h12a1 1 0 011 1v3a1 1 0 01-.293.707L12 11.414V15a1 1 0 01-.293.707l-2 2A1 1 0 018 17v-5.586L3.293 6.707A1 1 0 013 6V3z\" clipRule=\"evenodd\" />\n              </svg>\n              <span>\n                Chart showing\n                {filteredRowCount.toLocaleString()}\n                {' '}\n                of\n                {totalRowCount.toLocaleString()}\n                {' '}\n                records\n              </span>\n              <button className=\"vpg-chart-clear-filters\" onClick={clearAllFilters}>\n                Clear filters\n              </button>\n            </div>\n          )}\n          <ChartBuilder\n            data={filteredDataForPivot}\n            theme={currentTheme}\n            fieldRoleOverrides={fieldRoleOverrides}\n            onConfigChange={handleChartConfigChange}\n          />\n        </div>\n      )}\n\n      {/* Footer */}\n      <div className=\"vpg-footer\">\n        <div className=\"vpg-footer-left\">\n          {viewMode === 'grid'\n            ? (\n                enablePagination\n                  ? (\n                      <>\n                        <span>\n                          {((currentPage - 1) * pageSize + 1).toLocaleString()}\n                          -\n                          {Math.min(currentPage * pageSize, totalSearchedRows).toLocaleString()}\n                        </span>\n                        <span className=\"vpg-separator\">of</span>\n                        <span>{totalSearchedRows.toLocaleString()}</span>\n                        {totalSearchedRows !== totalRowCount && (\n                          <span className=\"vpg-filtered-note\">\n                            (\n                            {totalRowCount.toLocaleString()}\n                            {' '}\n                            total)\n                          </span>\n                        )}\n                      </>\n                    )\n                  : filteredRowCount === totalRowCount && totalSearchedRows === totalRowCount\n                    ? (\n                        <span>\n                          {totalRowCount.toLocaleString()}\n                          {' '}\n                          records\n                        </span>\n                      )\n                    : (\n                        <>\n                          <span className=\"vpg-filtered-count\">{totalSearchedRows.toLocaleString()}</span>\n                          <span className=\"vpg-separator\">of</span>\n                          <span>{totalRowCount.toLocaleString()}</span>\n                          <span className=\"vpg-separator\">records</span>\n                        </>\n                      )\n              )\n            : viewMode === 'pivot'\n              ? (\n                  <>\n                    <span className=\"vpg-pivot-label\">Pivot Table</span>\n                    <span className=\"vpg-separator\">•</span>\n                    <span>\n                      {totalRowCount.toLocaleString()}\n                      {' '}\n                      source records\n                    </span>\n                  </>\n                )\n              : (\n                  <>\n                    <span className=\"vpg-chart-label\">Chart Builder</span>\n                    <span className=\"vpg-separator\">•</span>\n                    <span>\n                      {totalRowCount.toLocaleString()}\n                      {' '}\n                      records\n                    </span>\n                  </>\n                )}\n        </div>\n\n        {/* Pagination controls */}\n        {enablePagination && viewMode === 'grid' && totalPages > 1 && (\n          <div className=\"vpg-pagination\">\n            <button\n              className=\"vpg-page-btn\"\n              disabled={currentPage === 1}\n              onClick={() => setCurrentPage(1)}\n            >\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M11 19l-7-7 7-7m8 14l-7-7 7-7\"\n                />\n              </svg>\n            </button>\n            <button\n              className=\"vpg-page-btn\"\n              disabled={currentPage === 1}\n              onClick={() => setCurrentPage(p => Math.max(1, p - 1))}\n            >\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M15 19l-7-7 7-7\"\n                />\n              </svg>\n            </button>\n            <span className=\"vpg-page-info\">\n              Page\n              {' '}\n              {currentPage}\n              {' '}\n              of\n              {' '}\n              {totalPages}\n            </span>\n            <button\n              className=\"vpg-page-btn\"\n              disabled={currentPage === totalPages}\n              onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}\n            >\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M9 5l7 7-7 7\"\n                />\n              </svg>\n            </button>\n            <button\n              className=\"vpg-page-btn\"\n              disabled={currentPage === totalPages}\n              onClick={() => setCurrentPage(totalPages)}\n            >\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M13 5l7 7-7 7M5 5l7 7-7 7\"\n                />\n              </svg>\n            </button>\n          </div>\n        )}\n\n        {viewMode === 'grid' && selectionStats && selectionStats.count > 1 && (\n          <div className=\"vpg-selection-stats\">\n            <span className=\"vpg-stat\">\n              <span className=\"vpg-stat-label\">Count:</span>\n              <span className=\"vpg-stat-value\">{selectionStats.count}</span>\n            </span>\n            {selectionStats.numericCount > 0 && (\n              <>\n                <span className=\"vpg-stat-divider\">|</span>\n                <span className=\"vpg-stat\">\n                  <span className=\"vpg-stat-label\">Sum:</span>\n                  <span className=\"vpg-stat-value\">{formatStatValue(selectionStats.sum)}</span>\n                </span>\n                <span className=\"vpg-stat-divider\">|</span>\n                <span className=\"vpg-stat\">\n                  <span className=\"vpg-stat-label\">Avg:</span>\n                  <span className=\"vpg-stat-value\">{formatStatValue(selectionStats.avg)}</span>\n                </span>\n              </>\n            )}\n          </div>\n        )}\n\n        <div className=\"vpg-footer-right\">\n          {isDemo\n            ? (\n                <div className=\"vpg-demo-banner\">\n                  <span className=\"vpg-demo-badge\">DEMO</span>\n                  <span>Pro features enabled</span>\n                  <a href=\"https://tiny-pivot.com/#pricing\" target=\"_blank\" rel=\"noopener noreferrer\">\n                    Get License →\n                  </a>\n                </div>\n              )\n            : showWatermark\n              ? (\n                  <span className=\"vpg-watermark-inline\">\n                    <a href=\"https://tiny-pivot.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n                      <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n                        <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" />\n                        <rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" />\n                        <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" />\n                        <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" />\n                      </svg>\n                      Powered by TinyPivot\n                    </a>\n                  </span>\n                )\n              : null}\n        </div>\n      </div>\n\n      {/* Vertical Resize Handle */}\n      {enableVerticalResize && (\n        <div className=\"vpg-vertical-resize-handle\" onMouseDown={startVerticalResize}>\n          <div className=\"vpg-resize-grip\">\n            <span></span>\n            <span></span>\n            <span></span>\n          </div>\n        </div>\n      )}\n\n      {/* Filter Dropdown Portal */}\n      {activeFilterColumn && typeof document !== 'undefined'\n        && createPortal(\n          <div\n            className=\"vpg-filter-portal\"\n            style={{\n              position: 'fixed',\n              top: `${filterDropdownPosition.top}px`,\n              left: `${filterDropdownPosition.left}px`,\n              maxHeight: `${filterDropdownPosition.maxHeight}px`,\n              zIndex: 9999,\n            }}\n          >\n            <ColumnFilter\n              columnId={activeFilterColumn}\n              columnName={activeFilterColumn}\n              stats={getColumnStats(activeFilterColumn)}\n              selectedValues={getColumnFilterValues(activeFilterColumn)}\n              sortDirection={getSortDirection(activeFilterColumn)}\n              numericRange={getNumericRangeFilter(activeFilterColumn)}\n              dateRange={getDateRangeFilter(activeFilterColumn)}\n              numberFormat={numberFormat}\n              dateFormat={dateFormat}\n              onFilter={values => handleFilter(activeFilterColumn, values)}\n              onRangeFilter={range => handleRangeFilter(activeFilterColumn, range)}\n              onDateRangeFilter={range => handleDateRangeFilter(activeFilterColumn, range)}\n              onSort={dir => handleSort(activeFilterColumn, dir)}\n              onClose={closeFilterDropdown}\n            />\n          </div>,\n          document.body,\n        )}\n    </div>\n  )\n}\n","import type { ColumnFilterValue, ColumnStats, DateRange, NumericRange } from '@smallwebco/tinypivot-core'\nimport type { ColumnDef, ColumnFiltersState, FilterFn, SortingState, VisibilityState } from '@tanstack/react-table'\nimport { formatCellValue, getColumnUniqueValues, isDateRange, isNumericRange } from '@smallwebco/tinypivot-core'\nimport {\n\n  getCoreRowModel,\n  getFilteredRowModel,\n  getSortedRowModel,\n\n  useReactTable,\n\n} from '@tanstack/react-table'\n/**\n * Excel-like Grid Hook for React\n * Provides Excel-like filtering, sorting, and data manipulation functionality\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\n\n// Re-export for convenience\nexport { formatCellValue, getColumnUniqueValues, isDateRange, isNumericRange }\n\nexport interface ExcelGridOptions<T> {\n  data: T[]\n  columns?: string[]\n  enableSorting?: boolean\n  enableFiltering?: boolean\n  pageSize?: number\n}\n\n/**\n * Combined filter function for Excel-style filtering, numeric range, and date range filtering\n */\nconst multiSelectFilter: FilterFn<unknown> = (row, columnId, filterValue: ColumnFilterValue | undefined) => {\n  if (!filterValue)\n    return true\n\n  // Handle numeric range filter\n  if (isNumericRange(filterValue)) {\n    const cellValue = row.getValue(columnId)\n    if (cellValue === null || cellValue === undefined || cellValue === '') {\n      return false // Exclude null/empty values from numeric range filtering\n    }\n    const num = typeof cellValue === 'number' ? cellValue : Number.parseFloat(String(cellValue))\n    if (Number.isNaN(num))\n      return false\n\n    const { min, max } = filterValue\n    if (min !== null && num < min)\n      return false\n    if (max !== null && num > max)\n      return false\n    return true\n  }\n\n  // Handle date range filter\n  if (isDateRange(filterValue)) {\n    const cellValue = row.getValue(columnId)\n    if (cellValue === null || cellValue === undefined || cellValue === '') {\n      return false\n    }\n    const dateObj = cellValue instanceof Date ? cellValue : new Date(String(cellValue))\n    if (Number.isNaN(dateObj.getTime()))\n      return false\n    const dateStr = dateObj.toISOString().split('T')[0]\n\n    const { min, max } = filterValue\n    if (min !== null && dateStr < min)\n      return false\n    if (max !== null && dateStr > max)\n      return false\n    return true\n  }\n\n  // Handle multi-select array filter\n  if (Array.isArray(filterValue) && filterValue.length > 0) {\n    const cellValue = row.getValue(columnId)\n    const cellString\n      = cellValue === null || cellValue === undefined || cellValue === ''\n        ? '(blank)'\n        : String(cellValue)\n    return filterValue.includes(cellString)\n  }\n\n  return true\n}\n\n/**\n * Excel-like grid hook\n */\nexport function useExcelGrid<T extends Record<string, unknown>>(options: ExcelGridOptions<T>) {\n  const { data, enableSorting = true, enableFiltering = true } = options\n\n  // State\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({})\n  const [globalFilter, setGlobalFilter] = useState('')\n\n  // Column statistics cache\n  const [columnStatsCache, setColumnStatsCache] = useState<Record<string, ColumnStats>>({})\n\n  const dataSignature = useMemo(\n    () => `${Date.now()}-${Math.random().toString(36).slice(2)}`,\n    [data],\n  )\n\n  // Compute columns from data\n  const columnKeys = useMemo(() => {\n    if (data.length === 0)\n      return []\n    return Object.keys(data[0] as Record<string, unknown>)\n  }, [data])\n\n  // Get column stats (memoized)\n  const getColumnStats = useCallback(\n    (columnKey: string): ColumnStats => {\n      const cacheKey = `${columnKey}-${dataSignature}`\n      if (!columnStatsCache[cacheKey]) {\n        const stats = getColumnUniqueValues(data, columnKey)\n        setColumnStatsCache(prev => ({ ...prev, [cacheKey]: stats }))\n        return stats\n      }\n      return columnStatsCache[cacheKey]\n    },\n    [data, columnStatsCache, dataSignature],\n  )\n\n  // Clear stats cache\n  const clearStatsCache = useCallback(() => {\n    setColumnStatsCache({})\n  }, [])\n\n  useEffect(() => {\n    clearStatsCache()\n  }, [dataSignature, clearStatsCache])\n\n  // Create column definitions dynamically\n  const columnDefs = useMemo<ColumnDef<T, unknown>[]>(() => {\n    return columnKeys.map((key) => {\n      const stats = getColumnStats(key)\n\n      return {\n        id: key,\n        accessorKey: key,\n        header: key,\n        cell: info => formatCellValue(info.getValue(), stats.type),\n        filterFn: multiSelectFilter,\n        meta: {\n          type: stats.type,\n          uniqueCount: stats.uniqueValues.length,\n        },\n      } as ColumnDef<T, unknown>\n    })\n  }, [columnKeys, getColumnStats])\n\n  // Create table instance\n  const table = useReactTable({\n    data,\n    columns: columnDefs,\n    state: {\n      sorting,\n      columnFilters,\n      columnVisibility,\n      globalFilter,\n    },\n    onSortingChange: setSorting,\n    onColumnFiltersChange: setColumnFilters,\n    onColumnVisibilityChange: setColumnVisibility,\n    onGlobalFilterChange: setGlobalFilter,\n    getCoreRowModel: getCoreRowModel(),\n    getSortedRowModel: enableSorting ? getSortedRowModel() : undefined,\n    getFilteredRowModel: enableFiltering ? getFilteredRowModel() : undefined,\n    filterFns: {\n      multiSelect: multiSelectFilter,\n    },\n    enableSorting,\n    enableFilters: enableFiltering,\n  })\n\n  // Computed properties\n  const filteredRowCount = table.getFilteredRowModel().rows.length\n  const totalRowCount = data.length\n\n  // Active filters (handles array values, numeric ranges, and date ranges)\n  const activeFilters = useMemo(() => {\n    return columnFilters.map((f) => {\n      const filterValue = f.value as ColumnFilterValue | undefined\n\n      // Handle numeric range\n      if (filterValue && isNumericRange(filterValue)) {\n        return {\n          column: f.id,\n          type: 'range' as const,\n          range: filterValue,\n          dateRange: null as DateRange | null,\n          values: [] as string[],\n        }\n      }\n\n      // Handle date range\n      if (filterValue && isDateRange(filterValue)) {\n        return {\n          column: f.id,\n          type: 'dateRange' as const,\n          range: null as NumericRange | null,\n          dateRange: filterValue,\n          values: [] as string[],\n        }\n      }\n\n      // Handle value array\n      return {\n        column: f.id,\n        type: 'values' as const,\n        values: Array.isArray(filterValue) ? filterValue : [],\n        range: null as NumericRange | null,\n        dateRange: null as DateRange | null,\n      }\n    })\n  }, [columnFilters])\n\n  // Check if column has active filter (handles array, numeric range, and date range)\n  const hasActiveFilter = useCallback(\n    (columnId: string): boolean => {\n      const column = table.getColumn(columnId)\n      if (!column)\n        return false\n      const filterValue = column.getFilterValue() as ColumnFilterValue | undefined\n      if (!filterValue)\n        return false\n\n      // Check for numeric range\n      if (isNumericRange(filterValue)) {\n        return filterValue.min !== null || filterValue.max !== null\n      }\n\n      // Check for date range\n      if (isDateRange(filterValue)) {\n        return filterValue.min !== null || filterValue.max !== null\n      }\n\n      // Check for value array\n      return Array.isArray(filterValue) && filterValue.length > 0\n    },\n    [table],\n  )\n\n  // Set column filter (value-based)\n  const setColumnFilter = useCallback(\n    (columnId: string, values: string[]) => {\n      const column = table.getColumn(columnId)\n      if (column) {\n        // Let the table's onColumnFiltersChange handler update the state\n        // Do NOT manually call setColumnFilters after - it causes a race condition\n        // where the stale state overwrites the pending update\n        column.setFilterValue(values.length === 0 ? undefined : values)\n      }\n    },\n    [table],\n  )\n\n  // Set numeric range filter\n  const setNumericRangeFilter = useCallback(\n    (columnId: string, range: NumericRange | null) => {\n      const column = table.getColumn(columnId)\n      if (column) {\n        if (!range || (range.min === null && range.max === null)) {\n          column.setFilterValue(undefined)\n        }\n        else {\n          column.setFilterValue(range)\n        }\n      }\n    },\n    [table],\n  )\n\n  // Get numeric range filter for a column\n  const getNumericRangeFilter = useCallback(\n    (columnId: string): NumericRange | null => {\n      const column = table.getColumn(columnId)\n      if (!column)\n        return null\n      const filterValue = column.getFilterValue() as ColumnFilterValue | undefined\n      if (filterValue && isNumericRange(filterValue)) {\n        return filterValue\n      }\n      return null\n    },\n    [table],\n  )\n\n  // Set date range filter\n  const setDateRangeFilter = useCallback(\n    (columnId: string, range: DateRange | null) => {\n      const column = table.getColumn(columnId)\n      if (column) {\n        if (!range || (range.min === null && range.max === null)) {\n          column.setFilterValue(undefined)\n        }\n        else {\n          column.setFilterValue(range)\n        }\n      }\n    },\n    [table],\n  )\n\n  // Get date range filter for a column\n  const getDateRangeFilter = useCallback(\n    (columnId: string): DateRange | null => {\n      const column = table.getColumn(columnId)\n      if (!column)\n        return null\n      const filterValue = column.getFilterValue() as ColumnFilterValue | undefined\n      if (filterValue && isDateRange(filterValue)) {\n        return filterValue\n      }\n      return null\n    },\n    [table],\n  )\n\n  // Clear all filters\n  const clearAllFilters = useCallback(() => {\n    table.resetColumnFilters()\n    setGlobalFilter('')\n    // Force sync columnFilters state\n    setColumnFilters([])\n  }, [table])\n\n  // Get filter values for a specific column\n  const getColumnFilterValues = useCallback(\n    (columnId: string): string[] => {\n      const column = table.getColumn(columnId)\n      if (!column)\n        return []\n      const filterValue = column.getFilterValue()\n      return Array.isArray(filterValue) ? filterValue : []\n    },\n    [table],\n  )\n\n  // Toggle column sort\n  const toggleSort = useCallback((columnId: string) => {\n    setSorting((prev) => {\n      const current = prev.find(s => s.id === columnId)\n      if (!current) {\n        return [{ id: columnId, desc: false }]\n      }\n      else if (!current.desc) {\n        return [{ id: columnId, desc: true }]\n      }\n      else {\n        return []\n      }\n    })\n  }, [])\n\n  // Get sort direction for column\n  const getSortDirection = useCallback(\n    (columnId: string): 'asc' | 'desc' | null => {\n      const sort = sorting.find(s => s.id === columnId)\n      if (!sort)\n        return null\n      return sort.desc ? 'desc' : 'asc'\n    },\n    [sorting],\n  )\n\n  return {\n    // Table instance\n    table,\n\n    // State\n    sorting,\n    columnFilters,\n    columnVisibility,\n    globalFilter,\n    columnKeys,\n    setSorting,\n    setColumnFilters,\n    setGlobalFilter,\n\n    // Computed\n    filteredRowCount,\n    totalRowCount,\n    activeFilters,\n\n    // Methods\n    getColumnStats,\n    clearStatsCache,\n    hasActiveFilter,\n    setColumnFilter,\n    getColumnFilterValues,\n    clearAllFilters,\n    toggleSort,\n    getSortDirection,\n    // Numeric range filters\n    setNumericRangeFilter,\n    getNumericRangeFilter,\n    // Date range filters\n    setDateRangeFilter,\n    getDateRangeFilter,\n  }\n}\n","import type { ExportOptions, PaginationOptions, PivotExportData, PivotValueField, SelectionBounds, SourceData, XlsxExportOptions } from '@smallwebco/tinypivot-core'\nimport {\n  copyToClipboard as coreCopyToClipboard,\n  exportPivotToCSV as coreExportPivotToCSV,\n  exportPivotToXLSX as coreExportPivotToXLSX,\n  exportToCSV as coreExportToCSV,\n  exportToXLSX as coreExportToXLSX,\n  formatSelectionForClipboard as coreFormatSelection,\n} from '@smallwebco/tinypivot-core'\n/**\n * Grid Features Hook for React\n * Provides CSV export, clipboard, pagination, and other utility features\n */\nimport { useCallback, useMemo, useState } from 'react'\n\n// Re-export core functions\nexport function exportToCSV<T extends Record<string, unknown>>(\n  data: T[],\n  columns: string[],\n  options?: ExportOptions,\n): void {\n  coreExportToCSV(data, columns, options)\n}\n\nexport function exportPivotToCSV(\n  pivotData: PivotExportData,\n  rowFields: string[],\n  columnFields: string[],\n  valueFields: PivotValueField[],\n  options?: ExportOptions,\n): void {\n  coreExportPivotToCSV(pivotData, rowFields, columnFields, valueFields, options)\n}\n\nexport async function exportToXLSX<T extends Record<string, unknown>>(\n  data: T[],\n  columns: string[],\n  options?: XlsxExportOptions,\n): Promise<void> {\n  await coreExportToXLSX(data, columns, options)\n}\n\nexport async function exportPivotToXLSX(\n  pivotData: PivotExportData,\n  rowFields: string[],\n  columnFields: string[],\n  valueFields: PivotValueField[],\n  options?: XlsxExportOptions,\n  sourceData?: SourceData,\n): Promise<void> {\n  await coreExportPivotToXLSX(pivotData, rowFields, columnFields, valueFields, options, sourceData)\n}\n\nexport function copyToClipboard(\n  text: string,\n  onSuccess?: () => void,\n  onError?: (err: Error) => void,\n): void {\n  coreCopyToClipboard(text, onSuccess, onError)\n}\n\nexport function formatSelectionForClipboard<T extends Record<string, unknown>>(\n  rows: T[],\n  columns: string[],\n  selectionBounds: SelectionBounds,\n): string {\n  return coreFormatSelection(rows, columns, selectionBounds)\n}\n\n/**\n * Pagination hook\n */\nexport function usePagination<T>(data: T[], options: PaginationOptions = {}) {\n  const [pageSize, setPageSize] = useState(options.pageSize ?? 50)\n  const [currentPage, setCurrentPage] = useState(options.currentPage ?? 1)\n\n  const totalPages = useMemo(\n    () => Math.max(1, Math.ceil(data.length / pageSize)),\n    [data.length, pageSize],\n  )\n\n  const paginatedData = useMemo(() => {\n    const start = (currentPage - 1) * pageSize\n    const end = start + pageSize\n    return data.slice(start, end)\n  }, [data, currentPage, pageSize])\n\n  const startIndex = useMemo(() => (currentPage - 1) * pageSize + 1, [currentPage, pageSize])\n  const endIndex = useMemo(\n    () => Math.min(currentPage * pageSize, data.length),\n    [currentPage, pageSize, data.length],\n  )\n\n  const goToPage = useCallback(\n    (page: number) => {\n      setCurrentPage(Math.max(1, Math.min(page, totalPages)))\n    },\n    [totalPages],\n  )\n\n  const nextPage = useCallback(() => {\n    if (currentPage < totalPages) {\n      setCurrentPage(prev => prev + 1)\n    }\n  }, [currentPage, totalPages])\n\n  const prevPage = useCallback(() => {\n    if (currentPage > 1) {\n      setCurrentPage(prev => prev - 1)\n    }\n  }, [currentPage])\n\n  const firstPage = useCallback(() => {\n    setCurrentPage(1)\n  }, [])\n\n  const lastPage = useCallback(() => {\n    setCurrentPage(totalPages)\n  }, [totalPages])\n\n  const updatePageSize = useCallback((size: number) => {\n    setPageSize(size)\n    setCurrentPage(1)\n  }, [])\n\n  return {\n    pageSize,\n    currentPage,\n    totalPages,\n    paginatedData,\n    startIndex,\n    endIndex,\n    goToPage,\n    nextPage,\n    prevPage,\n    firstPage,\n    lastPage,\n    setPageSize: updatePageSize,\n  }\n}\n\n/**\n * Global search/filter hook\n */\nexport function useGlobalSearch<T extends Record<string, unknown>>(data: T[], columns: string[]) {\n  const [searchTerm, setSearchTerm] = useState('')\n  const [caseSensitive, setCaseSensitive] = useState(false)\n\n  const filteredData = useMemo(() => {\n    if (!searchTerm.trim()) {\n      return data\n    }\n\n    const term = caseSensitive ? searchTerm.trim() : searchTerm.trim().toLowerCase()\n\n    return data.filter((row) => {\n      for (const col of columns) {\n        const value = row[col]\n        if (value === null || value === undefined)\n          continue\n\n        const strValue = caseSensitive ? String(value) : String(value).toLowerCase()\n\n        if (strValue.includes(term)) {\n          return true\n        }\n      }\n      return false\n    })\n  }, [data, columns, searchTerm, caseSensitive])\n\n  const clearSearch = useCallback(() => {\n    setSearchTerm('')\n  }, [])\n\n  return {\n    searchTerm,\n    setSearchTerm,\n    caseSensitive,\n    setCaseSensitive,\n    filteredData,\n    clearSearch,\n  }\n}\n\n/**\n * Row selection hook\n */\nexport function useRowSelection<T>(data: T[]) {\n  const [selectedRowIndices, setSelectedRowIndices] = useState<Set<number>>(new Set())\n\n  const selectedRows = useMemo(() => {\n    return Array.from(selectedRowIndices)\n      .sort((a, b) => a - b)\n      .map(idx => data[idx])\n      .filter(Boolean)\n  }, [data, selectedRowIndices])\n\n  const allSelected = useMemo(() => {\n    return data.length > 0 && selectedRowIndices.size === data.length\n  }, [data.length, selectedRowIndices.size])\n\n  const someSelected = useMemo(() => {\n    return selectedRowIndices.size > 0 && selectedRowIndices.size < data.length\n  }, [data.length, selectedRowIndices.size])\n\n  const toggleRow = useCallback((index: number) => {\n    setSelectedRowIndices((prev) => {\n      const next = new Set(prev)\n      if (next.has(index)) {\n        next.delete(index)\n      }\n      else {\n        next.add(index)\n      }\n      return next\n    })\n  }, [])\n\n  const selectRow = useCallback((index: number) => {\n    setSelectedRowIndices(prev => new Set([...prev, index]))\n  }, [])\n\n  const deselectRow = useCallback((index: number) => {\n    setSelectedRowIndices((prev) => {\n      const next = new Set(prev)\n      next.delete(index)\n      return next\n    })\n  }, [])\n\n  const selectAll = useCallback(() => {\n    setSelectedRowIndices(new Set(data.map((_, idx) => idx)))\n  }, [data])\n\n  const deselectAll = useCallback(() => {\n    setSelectedRowIndices(new Set())\n  }, [])\n\n  const toggleAll = useCallback(() => {\n    if (allSelected) {\n      deselectAll()\n    }\n    else {\n      selectAll()\n    }\n  }, [allSelected, selectAll, deselectAll])\n\n  const isSelected = useCallback(\n    (index: number): boolean => {\n      return selectedRowIndices.has(index)\n    },\n    [selectedRowIndices],\n  )\n\n  const selectRange = useCallback((startIndex: number, endIndex: number) => {\n    const min = Math.min(startIndex, endIndex)\n    const max = Math.max(startIndex, endIndex)\n    setSelectedRowIndices((prev) => {\n      const next = new Set(prev)\n      for (let i = min; i <= max; i++) {\n        next.add(i)\n      }\n      return next\n    })\n  }, [])\n\n  return {\n    selectedRowIndices,\n    selectedRows,\n    allSelected,\n    someSelected,\n    toggleRow,\n    selectRow,\n    deselectRow,\n    selectAll,\n    deselectAll,\n    toggleAll,\n    isSelected,\n    selectRange,\n  }\n}\n\n/**\n * Column resizing hook\n */\nexport function useColumnResize(\n  initialWidths: Record<string, number>,\n  minWidth = 60,\n  maxWidth = 600,\n) {\n  const [columnWidths, setColumnWidths] = useState<Record<string, number>>({ ...initialWidths })\n  const [isResizing, setIsResizing] = useState(false)\n  const [resizingColumn, setResizingColumn] = useState<string | null>(null)\n\n  const startResize = useCallback(\n    (columnId: string, event: React.MouseEvent) => {\n      setIsResizing(true)\n      setResizingColumn(columnId)\n      const startX = event.clientX\n      const startWidth = columnWidths[columnId] || 150\n\n      const handleMouseMove = (e: MouseEvent) => {\n        const diff = e.clientX - startX\n        const newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + diff))\n        setColumnWidths(prev => ({\n          ...prev,\n          [columnId]: newWidth,\n        }))\n      }\n\n      const handleMouseUp = () => {\n        setIsResizing(false)\n        setResizingColumn(null)\n        document.removeEventListener('mousemove', handleMouseMove)\n        document.removeEventListener('mouseup', handleMouseUp)\n      }\n\n      document.addEventListener('mousemove', handleMouseMove)\n      document.addEventListener('mouseup', handleMouseUp)\n    },\n    [columnWidths, minWidth, maxWidth],\n  )\n\n  const resetColumnWidth = useCallback(\n    (columnId: string) => {\n      if (initialWidths[columnId]) {\n        setColumnWidths(prev => ({\n          ...prev,\n          [columnId]: initialWidths[columnId],\n        }))\n      }\n    },\n    [initialWidths],\n  )\n\n  const resetAllWidths = useCallback(() => {\n    setColumnWidths({ ...initialWidths })\n  }, [initialWidths])\n\n  return {\n    columnWidths,\n    setColumnWidths,\n    isResizing,\n    resizingColumn,\n    startResize,\n    resetColumnWidth,\n    resetAllWidths,\n  }\n}\n","import type { LicenseInfo } from '@smallwebco/tinypivot-core'\nimport {\n  canUseAIAnalyst as coreCanUseAIAnalyst,\n  canUseCharts as coreCanUseCharts,\n  canUsePivot as coreCanUsePivot,\n  canUseXlsxExport as coreCanUseXlsxExport,\n  configureLicenseSecret as coreConfigureLicenseSecret,\n  isPro as coreIsPro,\n  shouldShowWatermark as coreShouldShowWatermark,\n  getDemoLicenseInfo,\n  getFreeLicenseInfo,\n  logProRequired,\n  validateLicenseKey,\n} from '@smallwebco/tinypivot-core'\n/**\n * License Management Hook for React\n * Wraps core license logic with React state management\n */\nimport { useCallback, useMemo, useState } from 'react'\n\n// Global state (shared across all hook instances)\nlet globalLicenseInfo: LicenseInfo = getFreeLicenseInfo()\nlet globalDemoMode = false\nconst listeners = new Set<() => void>()\n\nfunction notifyListeners() {\n  listeners.forEach(listener => listener())\n}\n\n/**\n * Set the license key for the library\n */\nexport async function setLicenseKey(key: string): Promise<void> {\n  globalLicenseInfo = await validateLicenseKey(key)\n\n  if (!globalLicenseInfo.isValid) {\n    console.warn('[TinyPivot] License validation failed. Check the console for environment details. Running in free mode.')\n  }\n  else if (globalLicenseInfo.type !== 'free') {\n    console.info(`[TinyPivot] Pro license activated (${globalLicenseInfo.type})`)\n  }\n\n  notifyListeners()\n}\n\n/**\n * Enable demo mode - requires the correct demo secret\n * Returns true if activation succeeded, false if secret was invalid\n */\nexport async function enableDemoMode(secret: string): Promise<boolean> {\n  const demoLicense = await getDemoLicenseInfo(secret)\n  if (!demoLicense) {\n    console.warn('[TinyPivot] Demo mode activation failed - invalid secret')\n    return false\n  }\n  globalDemoMode = true\n  globalLicenseInfo = demoLicense\n  console.info('[TinyPivot] Demo mode enabled - all Pro features unlocked for evaluation')\n  notifyListeners()\n  return true\n}\n\n/**\n * Configure the license secret\n */\nexport function configureLicenseSecret(secret: string): void {\n  coreConfigureLicenseSecret(secret)\n}\n\n/**\n * Hook for accessing license information\n */\nexport function useLicense() {\n  const [, forceUpdate] = useState({})\n\n  // Subscribe to global state changes\n  useState(() => {\n    const update = () => forceUpdate({})\n    listeners.add(update)\n    return () => listeners.delete(update)\n  })\n\n  const isDemo = globalDemoMode\n  const licenseInfo = globalLicenseInfo\n\n  const isPro = useMemo(\n    () => globalDemoMode || coreIsPro(licenseInfo),\n    [licenseInfo],\n  )\n\n  const canUsePivot = useMemo(\n    () => globalDemoMode || coreCanUsePivot(licenseInfo),\n    [licenseInfo],\n  )\n\n  const canUseAdvancedAggregations = useMemo(\n    () => globalDemoMode || licenseInfo.features.advancedAggregations,\n    [licenseInfo],\n  )\n\n  const canUsePercentageMode = useMemo(\n    () => globalDemoMode || licenseInfo.features.percentageMode,\n    [licenseInfo],\n  )\n\n  const canUseCharts = useMemo(\n    () => globalDemoMode || coreCanUseCharts(licenseInfo),\n    [licenseInfo],\n  )\n\n  const canUseAIAnalyst = useMemo(\n    () => globalDemoMode || coreCanUseAIAnalyst(licenseInfo),\n    [licenseInfo],\n  )\n\n  const canUseXlsxExport = useMemo(\n    () => globalDemoMode || coreCanUseXlsxExport(licenseInfo),\n    [licenseInfo],\n  )\n\n  const showWatermark = useMemo(\n    () => coreShouldShowWatermark(licenseInfo, globalDemoMode),\n    [licenseInfo],\n  )\n\n  const requirePro = useCallback((feature: string): boolean => {\n    if (!isPro) {\n      logProRequired(feature)\n      return false\n    }\n    return true\n  }, [isPro])\n\n  return {\n    licenseInfo,\n    isDemo,\n    isPro,\n    canUsePivot,\n    canUseAdvancedAggregations,\n    canUsePercentageMode,\n    canUseCharts,\n    canUseAIAnalyst,\n    canUseXlsxExport,\n    showWatermark,\n    requirePro,\n  }\n}\n","import type {\n  AggregationFunction,\n  CalculatedField,\n  FieldStats,\n  PivotConfig,\n  PivotResult,\n  PivotValueField,\n} from '@smallwebco/tinypivot-core'\nimport {\n  computeAvailableFields,\n  computePivotResult,\n  generateStorageKey,\n  getAggregationLabel,\n  getUnassignedFields,\n  isConfigValidForFields,\n  isPivotConfigured,\n  loadCalculatedFields,\n  loadPivotConfig,\n  saveCalculatedFields,\n  savePivotConfig,\n} from '@smallwebco/tinypivot-core'\n/**\n * Pivot Table Hook for React\n * Wraps core pivot logic with React state management\n */\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useLicense } from './useLicense'\n\n// Re-export for convenience\nexport { getAggregationLabel }\n\ninterface UsePivotTableReturn {\n  // State\n  rowFields: string[]\n  columnFields: string[]\n  valueFields: PivotValueField[]\n  showRowTotals: boolean\n  showColumnTotals: boolean\n  calculatedFields: CalculatedField[]\n  collapsedPaths: Set<string>\n  fieldFilters: Record<string, string[]>\n\n  // Computed\n  availableFields: FieldStats[]\n  unassignedFields: FieldStats[]\n  isConfigured: boolean\n  activeFieldFilters: Record<string, string[]>\n  pivotResult: PivotResult | null\n\n  // Actions\n  addRowField: (field: string) => void\n  removeRowField: (field: string) => void\n  addColumnField: (field: string) => void\n  removeColumnField: (field: string) => void\n  addValueField: (field: string, aggregation?: AggregationFunction) => void\n  removeValueField: (field: string, aggregation?: AggregationFunction) => void\n  updateValueFieldAggregation: (\n    field: string,\n    oldAgg: AggregationFunction,\n    newAgg: AggregationFunction,\n  ) => void\n  clearConfig: () => void\n  setShowRowTotals: (value: boolean) => void\n  setShowColumnTotals: (value: boolean) => void\n  autoSuggestConfig: () => void\n  setRowFields: (fields: string[]) => void\n  setColumnFields: (fields: string[]) => void\n  addCalculatedField: (field: CalculatedField) => void\n  removeCalculatedField: (id: string) => void\n  toggleCollapsedPath: (key: string, altKey: boolean, rowFields: string[], currentPivotResult: PivotResult | null) => Set<string>\n  setFieldFilter: (field: string, excludedValues: string[]) => void\n  clearFieldFilter: (field: string) => void\n}\n\n/**\n * Main pivot table hook\n */\nexport function usePivotTable(data: Record<string, unknown>[], enableDrillDown = true): UsePivotTableReturn {\n  const { canUsePivot, requirePro } = useLicense()\n\n  // Configuration state\n  const [rowFields, setRowFieldsState] = useState<string[]>([])\n  const [columnFields, setColumnFieldsState] = useState<string[]>([])\n  const [valueFields, setValueFields] = useState<PivotValueField[]>([])\n  const [showRowTotals, setShowRowTotals] = useState(true)\n  const [showColumnTotals, setShowColumnTotals] = useState(true)\n  const [calculatedFields, setCalculatedFields] = useState<CalculatedField[]>(() => loadCalculatedFields())\n  const [currentStorageKey, setCurrentStorageKey] = useState<string | null>(null)\n  const [collapsedPaths, setCollapsedPaths] = useState<Set<string>>(new Set())\n  // Axis value filters: field → excluded values. Filters are kept for\n  // unassigned fields too (so re-adding a field restores its filter), but\n  // only filters on current row/column fields are applied to the pivot.\n  const [fieldFilters, setFieldFilters] = useState<Record<string, string[]>>({})\n\n  // Compute available fields from data\n  const availableFields = useMemo((): FieldStats[] => {\n    return computeAvailableFields(data)\n  }, [data])\n\n  // Get fields that haven't been assigned yet\n  const unassignedFields = useMemo(() => {\n    return getUnassignedFields(availableFields, rowFields, columnFields, valueFields)\n  }, [availableFields, rowFields, columnFields, valueFields])\n\n  // Check if pivot is configured\n  const isConfigured = useMemo(() => {\n    return isPivotConfigured({\n      rowFields,\n      columnFields,\n      valueFields,\n      showRowTotals,\n      showColumnTotals,\n    })\n  }, [rowFields, columnFields, valueFields, showRowTotals, showColumnTotals])\n\n  // Filters restricted to fields currently on an axis — the only ones applied\n  const activeFieldFilters = useMemo((): Record<string, string[]> => {\n    const active: Record<string, string[]> = {}\n    for (const [field, excluded] of Object.entries(fieldFilters)) {\n      if (excluded.length > 0 && (rowFields.includes(field) || columnFields.includes(field))) {\n        active[field] = excluded\n      }\n    }\n    return active\n  }, [fieldFilters, rowFields, columnFields])\n\n  // Build pivot result\n  const pivotResult = useMemo((): PivotResult | null => {\n    if (!isConfigured)\n      return null\n    if (!canUsePivot)\n      return null\n\n    return computePivotResult(data, {\n      rowFields,\n      columnFields,\n      valueFields,\n      showRowTotals,\n      showColumnTotals,\n      calculatedFields,\n      fieldFilters: activeFieldFilters,\n    }, { collapsedPaths: enableDrillDown ? collapsedPaths : new Set<string>() })\n  }, [data, isConfigured, canUsePivot, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields, activeFieldFilters, collapsedPaths, enableDrillDown])\n\n  // Load/save config from storage\n  useEffect(() => {\n    if (data.length === 0)\n      return\n\n    const newKeys = Object.keys(data[0])\n    const storageKey = generateStorageKey(newKeys)\n\n    if (storageKey !== currentStorageKey) {\n      setCurrentStorageKey(storageKey)\n\n      const savedConfig = loadPivotConfig(storageKey)\n      if (savedConfig && isConfigValidForFields(savedConfig, newKeys)) {\n        setRowFieldsState(savedConfig.rowFields)\n        setColumnFieldsState(savedConfig.columnFields)\n        setValueFields(savedConfig.valueFields)\n        setShowRowTotals(savedConfig.showRowTotals)\n        setShowColumnTotals(savedConfig.showColumnTotals)\n        if (savedConfig.calculatedFields) {\n          setCalculatedFields(savedConfig.calculatedFields)\n        }\n        setFieldFilters(savedConfig.fieldFilters ?? {})\n      }\n      else {\n        // Validate current config\n        const currentConfig: PivotConfig = {\n          rowFields,\n          columnFields,\n          valueFields,\n          showRowTotals,\n          showColumnTotals,\n        }\n        if (!isConfigValidForFields(currentConfig, newKeys)) {\n          // Mirror Vue's clearConfig(): stale filters from the previous\n          // dataset must not silently apply to (and persist under) the new one\n          setRowFieldsState([])\n          setColumnFieldsState([])\n          setValueFields([])\n          setFieldFilters({})\n        }\n      }\n\n      // Load collapsed paths from separate sessionStorage key\n      try {\n        const collapsedKey = `${storageKey}-collapsed`\n        const raw = sessionStorage.getItem(collapsedKey)\n        if (raw) {\n          const parsed = JSON.parse(raw) as string[]\n          setCollapsedPaths(new Set(parsed))\n        }\n        else {\n          setCollapsedPaths(new Set())\n        }\n      }\n      catch {\n        setCollapsedPaths(new Set())\n      }\n    }\n  }, [data])\n\n  // Save config when it changes\n  useEffect(() => {\n    if (!currentStorageKey)\n      return\n\n    const config: PivotConfig = {\n      rowFields,\n      columnFields,\n      valueFields,\n      showRowTotals,\n      showColumnTotals,\n      calculatedFields,\n      fieldFilters,\n    }\n    savePivotConfig(currentStorageKey, config)\n  }, [currentStorageKey, rowFields, columnFields, valueFields, showRowTotals, showColumnTotals, calculatedFields, fieldFilters])\n\n  // Save collapsedPaths separately when it or the storage key changes\n  useEffect(() => {\n    if (!currentStorageKey)\n      return\n    try {\n      const collapsedKey = `${currentStorageKey}-collapsed`\n      sessionStorage.setItem(collapsedKey, JSON.stringify(Array.from(collapsedPaths)))\n    }\n    catch {\n      // sessionStorage not available (SSR or private browsing)\n    }\n  }, [collapsedPaths, currentStorageKey])\n\n  // Actions - pivot is free with sum aggregation, Pro required for other aggregations\n  const addRowField = useCallback(\n    (field: string) => {\n      if (!rowFields.includes(field)) {\n        setRowFieldsState(prev => [...prev, field])\n      }\n    },\n    [rowFields],\n  )\n\n  const removeRowField = useCallback((field: string) => {\n    setRowFieldsState(prev => prev.filter(f => f !== field))\n  }, [])\n\n  const setRowFields = useCallback((fields: string[]) => {\n    setRowFieldsState(fields)\n  }, [])\n\n  const addColumnField = useCallback(\n    (field: string) => {\n      if (!columnFields.includes(field)) {\n        setColumnFieldsState(prev => [...prev, field])\n      }\n    },\n    [columnFields],\n  )\n\n  const removeColumnField = useCallback((field: string) => {\n    setColumnFieldsState(prev => prev.filter(f => f !== field))\n  }, [])\n\n  const setColumnFields = useCallback((fields: string[]) => {\n    setColumnFieldsState(fields)\n  }, [])\n\n  const addValueField = useCallback(\n    (field: string, aggregation: AggregationFunction = 'sum') => {\n      // Pro required for non-sum aggregations\n      if (aggregation !== 'sum' && !requirePro(`${aggregation} aggregation`)) {\n        return\n      }\n      setValueFields((prev) => {\n        if (prev.some(v => v.field === field && v.aggregation === aggregation)) {\n          return prev\n        }\n        return [...prev, { field, aggregation }]\n      })\n    },\n    [requirePro],\n  )\n\n  const removeValueField = useCallback((field: string, aggregation?: AggregationFunction) => {\n    setValueFields((prev) => {\n      if (aggregation) {\n        return prev.filter(v => !(v.field === field && v.aggregation === aggregation))\n      }\n      return prev.filter(v => v.field !== field)\n    })\n  }, [])\n\n  const updateValueFieldAggregation = useCallback(\n    (field: string, oldAgg: AggregationFunction, newAgg: AggregationFunction) => {\n      setValueFields(prev =>\n        prev.map((v) => {\n          if (v.field === field && v.aggregation === oldAgg) {\n            return { ...v, aggregation: newAgg }\n          }\n          return v\n        }),\n      )\n    },\n    [],\n  )\n\n  const clearConfig = useCallback(() => {\n    setRowFieldsState([])\n    setColumnFieldsState([])\n    setValueFields([])\n    setFieldFilters({})\n  }, [])\n\n  // Axis value filter management\n  const setFieldFilter = useCallback((field: string, excludedValues: string[]) => {\n    setFieldFilters((prev) => {\n      const next = { ...prev }\n      if (excludedValues.length === 0) {\n        delete next[field]\n      }\n      else {\n        next[field] = [...excludedValues]\n      }\n      return next\n    })\n  }, [])\n\n  const clearFieldFilter = useCallback((field: string) => {\n    setFieldFilter(field, [])\n  }, [setFieldFilter])\n\n  const autoSuggestConfig = useCallback(() => {\n    if (!requirePro('Pivot Table - Auto Suggest'))\n      return\n    if (availableFields.length === 0)\n      return\n\n    const categoricalFields = availableFields.filter(f => !f.isNumeric && f.uniqueCount < 50)\n    const numericFields = availableFields.filter(f => f.isNumeric)\n\n    if (categoricalFields.length > 0 && numericFields.length > 0) {\n      setRowFieldsState([categoricalFields[0].field])\n      setValueFields([{ field: numericFields[0].field, aggregation: 'sum' }])\n    }\n  }, [availableFields, requirePro])\n\n  // Calculated field management\n  const addCalculatedField = useCallback((field: CalculatedField) => {\n    setCalculatedFields((prev) => {\n      const existing = prev.findIndex(f => f.id === field.id)\n      let updated: CalculatedField[]\n      if (existing >= 0) {\n        updated = [...prev.slice(0, existing), field, ...prev.slice(existing + 1)]\n      }\n      else {\n        updated = [...prev, field]\n      }\n      saveCalculatedFields(updated)\n      return updated\n    })\n  }, [])\n\n  const removeCalculatedField = useCallback((id: string) => {\n    setCalculatedFields((prev) => {\n      const updated = prev.filter(f => f.id !== id)\n      saveCalculatedFields(updated)\n      return updated\n    })\n    // Also remove from value fields if it was being used\n    setValueFields(prev => prev.filter(v => v.field !== `calc:${id}`))\n  }, [])\n\n  const toggleCollapsedPath = useCallback(\n    (key: string, altKey: boolean, _rowFields: string[], currentPivotResult: PivotResult | null) => {\n      if (!altKey) {\n        const next = new Set(collapsedPaths)\n        if (next.has(key)) {\n          next.delete(key)\n        }\n        else {\n          next.add(key)\n        }\n        setCollapsedPaths(next)\n        return next\n      }\n\n      // Alt-click: toggle all groups at the same depth\n      if (!currentPivotResult)\n        return new Set<string>()\n\n      // Determine which depth this key belongs to by looking at groupStarts\n      let targetDepth = -1\n      for (const meta of currentPivotResult.rowMeta) {\n        for (const gs of meta.groupStarts) {\n          if (gs.key === key) {\n            targetDepth = gs.depth\n            break\n          }\n        }\n        if (targetDepth >= 0)\n          break\n      }\n\n      if (targetDepth < 0)\n        return new Set<string>()\n\n      // Collect all keys at this depth\n      const keysAtDepth = new Set<string>()\n      for (const meta of currentPivotResult.rowMeta) {\n        for (const gs of meta.groupStarts) {\n          if (gs.depth === targetDepth) {\n            keysAtDepth.add(gs.key)\n          }\n        }\n      }\n\n      // If the clicked key is currently collapsed, expand all; otherwise collapse all\n      const shouldCollapse = !collapsedPaths.has(key)\n      const next = new Set(collapsedPaths)\n      for (const k of keysAtDepth) {\n        if (shouldCollapse) {\n          next.add(k)\n        }\n        else {\n          next.delete(k)\n        }\n      }\n      setCollapsedPaths(next)\n      return next\n    },\n    [collapsedPaths],\n  )\n\n  return {\n    // State\n    rowFields,\n    columnFields,\n    valueFields,\n    showRowTotals,\n    showColumnTotals,\n    calculatedFields,\n    collapsedPaths,\n    fieldFilters,\n\n    // Computed\n    availableFields,\n    unassignedFields,\n    isConfigured,\n    activeFieldFilters,\n    pivotResult,\n\n    // Actions\n    addRowField,\n    removeRowField,\n    addColumnField,\n    removeColumnField,\n    addValueField,\n    removeValueField,\n    updateValueFieldAggregation,\n    clearConfig,\n    setShowRowTotals,\n    setShowColumnTotals,\n    autoSuggestConfig,\n    setRowFields,\n    setColumnFields,\n    addCalculatedField,\n    removeCalculatedField,\n    toggleCollapsedPath,\n    setFieldFilter,\n    clearFieldFilter,\n  }\n}\n","/**\n * Drill-Through Modal for React\n * Displays source rows for a pivot cell in a paginated table\n */\nimport type { DrillThroughResult, PivotValueField } from '@smallwebco/tinypivot-core'\nimport { exportToCSV, exportToXLSX, getAggregationLabel } from '@smallwebco/tinypivot-core'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { ExportMenu } from './ExportMenu'\n\ninterface DrillThroughModalProps {\n  show: boolean\n  result: DrillThroughResult | null\n  rowFields: string[]\n  columnFields: string[]\n  valueFields: PivotValueField[]\n  onClose: () => void\n  theme?: string\n}\n\nconst PAGE_SIZE = 50\n\nexport function DrillThroughModal({\n  show,\n  result,\n  onClose,\n  theme,\n}: DrillThroughModalProps) {\n  const [currentPage, setCurrentPage] = useState(1)\n\n  // Reset page when modal opens or result changes\n  useEffect(() => {\n    if (show) {\n      setCurrentPage(1)\n    }\n  }, [show, result])\n\n  // Keyboard listener — only depends on show and onClose\n  useEffect(() => {\n    if (!show)\n      return\n\n    const handleKeydown = (event: KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        onClose()\n      }\n    }\n\n    document.addEventListener('keydown', handleKeydown)\n    return () => document.removeEventListener('keydown', handleKeydown)\n  }, [show, onClose])\n\n  // Column keys from the first row\n  const columns = useMemo((): string[] => {\n    if (!result || result.rows.length === 0)\n      return []\n    return Object.keys(result.rows[0])\n  }, [result])\n\n  // Total pages\n  const totalPages = useMemo(() => {\n    if (!result)\n      return 1\n    return Math.max(1, Math.ceil(result.rows.length / PAGE_SIZE))\n  }, [result])\n\n  // Rows for current page\n  const pageRows = useMemo(() => {\n    if (!result)\n      return []\n    const start = (currentPage - 1) * PAGE_SIZE\n    return result.rows.slice(start, start + PAGE_SIZE)\n  }, [result, currentPage])\n\n  // Modal title\n  const modalTitle = useMemo(() => {\n    if (!result)\n      return 'Drill Through'\n\n    const { descriptor } = result\n    const parts: string[] = []\n\n    if (descriptor.rowPath.length > 0)\n      parts.push(descriptor.rowPath.join(' × '))\n    if (descriptor.columnPath.length > 0)\n      parts.push(descriptor.columnPath.join(' × '))\n\n    const slice = parts.length > 0 ? parts.join(' × ') : 'Grand Total'\n    const aggLabel = getAggregationLabel(descriptor.aggregation)\n    const valueStr = descriptor.formattedValue !== '-'\n      ? ` = ${descriptor.formattedValue}`\n      : ''\n\n    return `${slice} — ${aggLabel} of ${descriptor.valueField}${valueStr} · ${descriptor.rowCount} rows`\n  }, [result])\n\n  const handleOverlayClick = useCallback((e: React.MouseEvent) => {\n    if (e.target === e.currentTarget) {\n      onClose()\n    }\n  }, [onClose])\n\n  const handleExport = useCallback(() => {\n    if (!result || result.rows.length === 0)\n      return\n    exportToCSV(result.rows, columns, { filename: 'drill-through.csv' })\n  }, [result, columns])\n\n  const handleExportXLSX = useCallback(async () => {\n    if (!result || result.rows.length === 0)\n      return\n    try {\n      await exportToXLSX(result.rows, columns, { filename: 'drill-through.xlsx' })\n    }\n    catch (err) {\n      console.error('[TinyPivot] XLSX export failed:', err)\n    }\n  }, [result, columns])\n\n  const onExport = useCallback(\n    (key: string) => {\n      if (key === 'csv') {\n        handleExport()\n      }\n      else {\n        handleExportXLSX()\n      }\n    },\n    [handleExport, handleExportXLSX],\n  )\n\n  const formatCellValue = (value: unknown): string => {\n    if (value === null || value === undefined)\n      return ''\n    return String(value)\n  }\n\n  if (!show || typeof document === 'undefined')\n    return null\n\n  return createPortal(\n    <div className={`vpg-modal-overlay vpg-theme-${theme ?? 'light'}`} onClick={handleOverlayClick}>\n      <div className=\"vpg-modal vpg-drill-modal\">\n        <div className=\"vpg-modal-header\">\n          <h3 className=\"vpg-drill-title\">{modalTitle}</h3>\n          <button className=\"vpg-modal-close\" onClick={onClose}>×</button>\n        </div>\n\n        <div className=\"vpg-modal-body vpg-drill-body\">\n          {!result || result.rows.length === 0\n            ? (\n                <div className=\"vpg-drill-empty\">\n                  No source rows found for this cell.\n                </div>\n              )\n            : (\n                <>\n                  <div className=\"vpg-drill-table-wrapper\">\n                    <table className=\"vpg-drill-table\">\n                      <thead>\n                        <tr>\n                          {columns.map(col => (\n                            <th key={col}>{col}</th>\n                          ))}\n                        </tr>\n                      </thead>\n                      <tbody>\n                        {pageRows.map((row, rowIdx) => (\n                          <tr key={rowIdx}>\n                            {columns.map(col => (\n                              <td key={col}>{formatCellValue(row[col])}</td>\n                            ))}\n                          </tr>\n                        ))}\n                      </tbody>\n                    </table>\n                  </div>\n\n                  {totalPages > 1 && (\n                    <div className=\"vpg-drill-pagination\">\n                      <button\n                        className=\"vpg-page-btn\"\n                        disabled={currentPage === 1}\n                        onClick={() => setCurrentPage(p => Math.max(1, p - 1))}\n                      >\n                        ←\n                      </button>\n                      <span>\n                        Page\n                        {' '}\n                        {currentPage}\n                        {' '}\n                        of\n                        {' '}\n                        {totalPages}\n                      </span>\n                      <button\n                        className=\"vpg-page-btn\"\n                        disabled={currentPage === totalPages}\n                        onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}\n                      >\n                        →\n                      </button>\n                    </div>\n                  )}\n                </>\n              )}\n        </div>\n\n        <div className=\"vpg-modal-footer\">\n          {result && result.rows.length > 0 && (\n            <ExportMenu\n              formats={[\n                { key: 'csv', label: 'CSV' },\n                { key: 'xlsx', label: 'Excel (.xlsx)' },\n              ]}\n              onSelect={onExport}\n            />\n          )}\n          <button className=\"vpg-btn vpg-btn-primary\" onClick={onClose}>\n            Close\n          </button>\n        </div>\n      </div>\n    </div>,\n    document.body,\n  )\n}\n","/**\n * Export dropdown menu component\n * Renders a single \"Export ▾\" button that opens a list of format options.\n * Disabled items are shown greyed with an optional badge, but cannot be selected.\n */\nimport React, { useCallback, useEffect, useRef, useState } from 'react'\n\nexport interface ExportFormat {\n  key: string\n  label: string\n  disabled?: boolean\n  badge?: string\n}\n\ninterface ExportMenuProps {\n  label?: string\n  formats: ExportFormat[]\n  onSelect: (key: string) => void\n}\n\nexport function ExportMenu({ label = 'Export', formats, onSelect }: ExportMenuProps) {\n  const [isOpen, setIsOpen] = useState(false)\n  const wrapperRef = useRef<HTMLDivElement>(null)\n\n  const toggle = useCallback(() => {\n    setIsOpen(prev => !prev)\n  }, [])\n\n  const select = useCallback(\n    (format: ExportFormat) => {\n      if (format.disabled)\n        return\n      setIsOpen(false)\n      onSelect(format.key)\n    },\n    [onSelect],\n  )\n\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (wrapperRef.current && !wrapperRef.current.contains(event.target as Node)) {\n        setIsOpen(false)\n      }\n    }\n\n    const handleKeydown = (event: KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        setIsOpen(false)\n      }\n    }\n\n    document.addEventListener('mousedown', handleClickOutside)\n    document.addEventListener('keydown', handleKeydown)\n\n    return () => {\n      document.removeEventListener('mousedown', handleClickOutside)\n      document.removeEventListener('keydown', handleKeydown)\n    }\n  }, [])\n\n  return (\n    <div ref={wrapperRef} className=\"vpg-export-menu\">\n      <button\n        className={`vpg-export-btn${isOpen ? ' vpg-export-btn--open' : ''}`}\n        onClick={toggle}\n      >\n        <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n          <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" />\n        </svg>\n        {label}\n        <svg className=\"vpg-icon-xs vpg-export-caret\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n          <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n        </svg>\n      </button>\n\n      {isOpen && (\n        <div className=\"vpg-export-dropdown\">\n          {formats.map(format => (\n            <button\n              key={format.key}\n              className={`vpg-export-item${format.disabled ? ' vpg-export-item--disabled' : ''}`}\n              disabled={format.disabled}\n              onClick={() => select(format)}\n            >\n              <span className=\"vpg-export-item-label\">{format.label}</span>\n              {format.badge && <span className=\"vpg-pro-badge\">{format.badge}</span>}\n            </button>\n          ))}\n        </div>\n      )}\n    </div>\n  )\n}\n","import type { AggregationFunction, CalculatedField, FieldStats, PivotValueField } from '@smallwebco/tinypivot-core'\nimport { AGGREGATION_OPTIONS, getAggregationSymbol } from '@smallwebco/tinypivot-core'\n/**\n * Pivot Table Configuration Panel for React\n * Draggable fields with aggregation selection\n */\nimport React, { useCallback, useMemo, useState } from 'react'\nimport { useLicense } from '../hooks/useLicense'\nimport { CalculatedFieldModal } from './CalculatedFieldModal'\n\n// Check if an aggregation requires Pro license (everything except sum)\nfunction aggregationRequiresPro(agg: AggregationFunction): boolean {\n  return agg !== 'sum'\n}\n\n// Extended field stats for calculated fields\ninterface ExtendedFieldStats extends FieldStats {\n  isCalculated?: boolean\n  calcId?: string\n  calcName?: string\n  calcFormula?: string\n}\n\ninterface PivotConfigProps {\n  availableFields: FieldStats[]\n  rowFields: string[]\n  columnFields: string[]\n  valueFields: PivotValueField[]\n  showRowTotals: boolean\n  showColumnTotals: boolean\n  calculatedFields?: CalculatedField[]\n  onShowRowTotalsChange: (value: boolean) => void\n  onShowColumnTotalsChange: (value: boolean) => void\n  onClearConfig: () => void\n  onAutoSuggest: () => void\n  onDragStart: (field: string, event: React.DragEvent) => void\n  onDragEnd: () => void\n  onUpdateAggregation: (field: string, oldAgg: AggregationFunction, newAgg: AggregationFunction) => void\n  onAddRowField: (field: string) => void\n  onRemoveRowField: (field: string) => void\n  onAddColumnField: (field: string) => void\n  onRemoveColumnField: (field: string) => void\n  onAddValueField: (field: string, aggregation: AggregationFunction) => void\n  onRemoveValueField: (field: string, aggregation: AggregationFunction) => void\n  onAddCalculatedField?: (field: CalculatedField) => void\n  onRemoveCalculatedField?: (id: string) => void\n  onUpdateCalculatedField?: (field: CalculatedField) => void\n  theme?: string\n  /** Axis value filters: field → excluded values */\n  fieldFilters?: Record<string, string[]>\n  /** Returns the unique values of a field — enables the axis filter UI */\n  getFieldValues?: (field: string) => string[]\n  onUpdateFieldFilter?: (field: string, excludedValues: string[]) => void\n}\n\nfunction getFieldIcon(type: FieldStats['type'], isCalculated?: boolean): string {\n  if (isCalculated)\n    return 'ƒ'\n  switch (type) {\n    case 'number':\n      return '#'\n    case 'date':\n      return '📅'\n    case 'boolean':\n      return '✓'\n    default:\n      return 'Aa'\n  }\n}\n\nexport function PivotConfig({\n  availableFields,\n  rowFields,\n  columnFields,\n  valueFields,\n  showRowTotals,\n  calculatedFields,\n  onShowRowTotalsChange,\n  onShowColumnTotalsChange,\n  onClearConfig,\n  onAutoSuggest: _onAutoSuggest,\n  onDragStart,\n  onDragEnd,\n  onUpdateAggregation,\n  onRemoveRowField,\n  onRemoveColumnField,\n  onRemoveValueField,\n  onAddRowField,\n  onAddColumnField,\n  onAddCalculatedField,\n  onRemoveCalculatedField,\n  onUpdateCalculatedField,\n  theme,\n  fieldFilters,\n  getFieldValues,\n  onUpdateFieldFilter,\n}: PivotConfigProps) {\n  const [fieldSearch, setFieldSearch] = useState('')\n  const [showCalcModal, setShowCalcModal] = useState(false)\n  const [editingCalcField, setEditingCalcField] = useState<CalculatedField | null>(null)\n  const [openFilterField, setOpenFilterField] = useState<string | null>(null)\n  const [filterValueSearch, setFilterValueSearch] = useState('')\n  const { canUseAdvancedAggregations } = useLicense()\n\n  // Check if an aggregation is available based on license\n  const isAggregationAvailable = useCallback((agg: AggregationFunction): boolean => {\n    return !aggregationRequiresPro(agg) || canUseAdvancedAggregations\n  }, [canUseAdvancedAggregations])\n\n  // Get only numeric field names for calculated field formulas\n  const numericFieldNames = useMemo(() =>\n    availableFields\n      .filter(f => f.isNumeric)\n      .map(f => f.field), [availableFields])\n\n  // Convert calculated fields to virtual FieldStats for display\n  const calculatedFieldsAsStats = useMemo((): ExtendedFieldStats[] => {\n    if (!calculatedFields)\n      return []\n    return calculatedFields.map(calc => ({\n      field: `calc:${calc.id}`,\n      type: 'number' as const,\n      uniqueCount: 0,\n      isNumeric: true,\n      isCalculated: true,\n      calcId: calc.id,\n      calcName: calc.name,\n      calcFormula: calc.formula,\n    }))\n  }, [calculatedFields])\n\n  // Combined available fields (data fields + calculated fields)\n  const allAvailableFields = useMemo((): ExtendedFieldStats[] => [\n    ...availableFields.map(f => ({ ...f, isCalculated: false })),\n    ...calculatedFieldsAsStats,\n  ], [availableFields, calculatedFieldsAsStats])\n\n  // Assigned fields\n  const assignedFields = useMemo(() => {\n    const rowSet = new Set(rowFields)\n    const colSet = new Set(columnFields)\n    const valueMap = new Map(valueFields.map(v => [v.field, v]))\n\n    return allAvailableFields\n      .filter(f => rowSet.has(f.field) || colSet.has(f.field) || valueMap.has(f.field))\n      .map(f => ({\n        ...f,\n        assignedTo: rowSet.has(f.field)\n          ? ('row' as const)\n          : colSet.has(f.field)\n            ? ('column' as const)\n            : ('value' as const),\n        valueConfig: valueMap.get(f.field),\n      }))\n  }, [allAvailableFields, rowFields, columnFields, valueFields])\n\n  // Unassigned fields (including unassigned calculated fields)\n  const unassignedFields = useMemo(() => {\n    const rowSet = new Set(rowFields)\n    const colSet = new Set(columnFields)\n    const valSet = new Set(valueFields.map(v => v.field))\n\n    return allAvailableFields.filter(\n      f => !rowSet.has(f.field) && !colSet.has(f.field) && !valSet.has(f.field),\n    )\n  }, [allAvailableFields, rowFields, columnFields, valueFields])\n\n  const filteredUnassignedFields = useMemo(() => {\n    if (!fieldSearch.trim())\n      return unassignedFields\n    const search = fieldSearch.toLowerCase().trim()\n    return unassignedFields.filter((f) => {\n      const fieldName = f.field.toLowerCase()\n      const displayName = f.isCalculated && f.calcName ? f.calcName.toLowerCase() : ''\n      return fieldName.includes(search) || displayName.includes(search)\n    })\n  }, [unassignedFields, fieldSearch])\n\n  const assignedCount = assignedFields.length\n\n  // Get display name for field (handles calculated fields)\n  const getFieldDisplayName = useCallback((field: ExtendedFieldStats): string => {\n    if (field.isCalculated && field.calcName) {\n      return field.calcName\n    }\n    return field.field\n  }, [])\n\n  const handleDragStart = useCallback(\n    (field: string, event: React.DragEvent) => {\n      event.dataTransfer?.setData('text/plain', field)\n      event.dataTransfer!.effectAllowed = 'move'\n      onDragStart(field, event)\n    },\n    [onDragStart],\n  )\n\n  const handleAggregationChange = useCallback(\n    (field: string, currentAgg: AggregationFunction, newAgg: AggregationFunction) => {\n      // Prevent changing to Pro aggregations without license\n      if (!isAggregationAvailable(newAgg)) {\n        console.warn(`[TinyPivot] \"${newAgg}\" aggregation requires a Pro license. Visit https://tiny-pivot.com/#pricing to upgrade.`)\n        return\n      }\n      onUpdateAggregation(field, currentAgg, newAgg)\n    },\n    [onUpdateAggregation, isAggregationAvailable],\n  )\n\n  const toggleRowColumn = useCallback(\n    (field: string, currentAssignment: 'row' | 'column') => {\n      if (currentAssignment === 'row') {\n        onRemoveRowField(field)\n        onAddColumnField(field)\n      }\n      else {\n        onRemoveColumnField(field)\n        onAddRowField(field)\n      }\n    },\n    [onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddRowField],\n  )\n\n  const removeField = useCallback(\n    (field: string, assignedTo: 'row' | 'column' | 'value', valueConfig?: PivotValueField) => {\n      if (assignedTo === 'row') {\n        onRemoveRowField(field)\n      }\n      else if (assignedTo === 'column') {\n        onRemoveColumnField(field)\n      }\n      else if (valueConfig) {\n        onRemoveValueField(field, valueConfig.aggregation)\n      }\n    },\n    [onRemoveRowField, onRemoveColumnField, onRemoveValueField],\n  )\n\n  // Axis value filter helpers\n  const openFilterValues = useMemo(() => {\n    if (!openFilterField || !getFieldValues)\n      return []\n    return getFieldValues(openFilterField)\n  }, [openFilterField, getFieldValues])\n\n  const openFilterExcluded = useMemo(() => {\n    if (!openFilterField)\n      return new Set<string>()\n    return new Set(fieldFilters?.[openFilterField] ?? [])\n  }, [openFilterField, fieldFilters])\n\n  // Cap the rendered checkbox list — a high-cardinality field (IDs,\n  // timestamp-like columns) would otherwise mount tens of thousands of\n  // DOM nodes and freeze the tab. All/None still act on the full value set.\n  const MAX_RENDERED_FILTER_VALUES = 200\n\n  const filteredFilterValues = useMemo(() => {\n    const search = filterValueSearch.toLowerCase().trim()\n    if (!search)\n      return openFilterValues\n    return openFilterValues.filter(v => v.toLowerCase().includes(search))\n  }, [openFilterValues, filterValueSearch])\n\n  const openFilterSelectedCount = useMemo(\n    () => openFilterValues.filter(v => !openFilterExcluded.has(v)).length,\n    [openFilterValues, openFilterExcluded],\n  )\n\n  const canFilterField = useCallback(\n    (field: { assignedTo: string, isCalculated?: boolean }): boolean => {\n      return !!getFieldValues\n        && !!onUpdateFieldFilter\n        && !field.isCalculated\n        && (field.assignedTo === 'row' || field.assignedTo === 'column')\n    },\n    [getFieldValues, onUpdateFieldFilter],\n  )\n\n  const hasActiveFilter = useCallback(\n    (field: string): boolean => (fieldFilters?.[field]?.length ?? 0) > 0,\n    [fieldFilters],\n  )\n\n  const toggleFilterDropdown = useCallback((field: string) => {\n    setOpenFilterField(prev => (prev === field ? null : field))\n    setFilterValueSearch('')\n  }, [])\n\n  const toggleFilterValue = useCallback(\n    (field: string, value: string) => {\n      const excluded = new Set(fieldFilters?.[field] ?? [])\n      if (excluded.has(value)) {\n        excluded.delete(value)\n      }\n      else {\n        excluded.add(value)\n      }\n      onUpdateFieldFilter?.(field, Array.from(excluded))\n    },\n    [fieldFilters, onUpdateFieldFilter],\n  )\n\n  // Handle totals toggle (toggle both row and column together)\n  const handleTotalsToggle = useCallback((checked: boolean) => {\n    onShowRowTotalsChange(checked)\n    onShowColumnTotalsChange(checked)\n  }, [onShowRowTotalsChange, onShowColumnTotalsChange])\n\n  // Calculated field modal handlers\n  const openCalcModal = useCallback((field?: CalculatedField) => {\n    setEditingCalcField(field || null)\n    setShowCalcModal(true)\n  }, [])\n\n  const handleSaveCalcField = useCallback((field: CalculatedField) => {\n    if (editingCalcField && onUpdateCalculatedField) {\n      onUpdateCalculatedField(field)\n    }\n    else if (onAddCalculatedField) {\n      onAddCalculatedField(field)\n    }\n    setShowCalcModal(false)\n    setEditingCalcField(null)\n  }, [editingCalcField, onAddCalculatedField, onUpdateCalculatedField])\n\n  const handleCloseCalcModal = useCallback(() => {\n    setShowCalcModal(false)\n    setEditingCalcField(null)\n  }, [])\n\n  return (\n    <div className={`vpg-pivot-config ${theme ? `vpg-theme-${theme}` : ''}`}>\n      {/* Header */}\n      <div className=\"vpg-config-header\">\n        <h3 className=\"vpg-config-title\">\n          <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M4 6h16M4 10h16M4 14h16M4 18h16\"\n            />\n          </svg>\n          Fields\n        </h3>\n        <div className=\"vpg-header-actions\">\n          {assignedCount > 0 && (\n            <button\n              className=\"vpg-action-btn vpg-clear-btn\"\n              title=\"Clear all\"\n              onClick={onClearConfig}\n            >\n              <svg className=\"vpg-icon-sm\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M6 18L18 6M6 6l12 12\"\n                />\n              </svg>\n            </button>\n          )}\n        </div>\n      </div>\n\n      {/* Assigned Fields */}\n      {assignedCount > 0 && (\n        <div className=\"vpg-assigned-section\">\n          <div className=\"vpg-section-label\">Active</div>\n          <div className=\"vpg-assigned-list\">\n            {assignedFields.map(field => (\n              <React.Fragment key={field.field}>\n                <div\n                  className={`vpg-assigned-item vpg-type-${field.assignedTo}${field.isCalculated ? ' vpg-type-calc' : ''}`}\n                  title={field.isCalculated ? field.calcFormula : field.field}\n                  draggable\n                  onDragStart={e => handleDragStart(field.field, e)}\n                  onDragEnd={onDragEnd}\n                >\n                  <div className=\"vpg-item-main\">\n                    <span className={`vpg-item-badge ${field.assignedTo}${field.isCalculated ? ' calc' : ''}`}>\n                      {field.isCalculated\n                        ? 'ƒ'\n                        : field.assignedTo === 'row'\n                          ? 'R'\n                          : field.assignedTo === 'column'\n                            ? 'C'\n                            : getAggregationSymbol(field.valueConfig?.aggregation || 'sum')}\n                    </span>\n                    <span className=\"vpg-item-name\">{getFieldDisplayName(field)}</span>\n                  </div>\n\n                  <div className=\"vpg-item-actions\">\n                    {canFilterField(field) && (\n                      <button\n                        className={`vpg-filter-btn${hasActiveFilter(field.field) || openFilterField === field.field ? ' vpg-filter-btn-active' : ''}`}\n                        title={hasActiveFilter(field.field) ? `Filter items (${fieldFilters?.[field.field]?.length} hidden)` : 'Filter items'}\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          toggleFilterDropdown(field.field)\n                        }}\n                      >\n                        <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                          <path\n                            strokeLinecap=\"round\"\n                            strokeLinejoin=\"round\"\n                            strokeWidth={2}\n                            d=\"M3 4h18l-7 8v6l-4 2v-8L3 4z\"\n                          />\n                        </svg>\n                      </button>\n                    )}\n\n                    {(field.assignedTo === 'row' || field.assignedTo === 'column') && (\n                      <button\n                        className=\"vpg-toggle-btn\"\n                        title={field.assignedTo === 'row' ? 'Move to Columns' : 'Move to Rows'}\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          toggleRowColumn(field.field, field.assignedTo as 'row' | 'column')\n                        }}\n                      >\n                        <svg\n                          className=\"vpg-icon-xs\"\n                          fill=\"none\"\n                          stroke=\"currentColor\"\n                          viewBox=\"0 0 24 24\"\n                        >\n                          <path\n                            strokeLinecap=\"round\"\n                            strokeLinejoin=\"round\"\n                            strokeWidth={2}\n                            d=\"M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4\"\n                          />\n                        </svg>\n                      </button>\n                    )}\n\n                    {field.assignedTo === 'value' && field.valueConfig && (\n                      <select\n                        className=\"vpg-agg-select\"\n                        value={field.valueConfig.aggregation}\n                        onChange={(e) => {\n                          e.stopPropagation()\n                          handleAggregationChange(\n                            field.field,\n                            field.valueConfig!.aggregation,\n                            e.target.value as AggregationFunction,\n                          )\n                        }}\n                        onClick={e => e.stopPropagation()}\n                      >\n                        {AGGREGATION_OPTIONS.map(agg => (\n                          <option\n                            key={agg.value}\n                            value={agg.value}\n                            disabled={aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations}\n                          >\n                            {agg.symbol}\n                            {' '}\n                            {agg.label}\n                            {aggregationRequiresPro(agg.value) && !canUseAdvancedAggregations ? ' (Pro)' : ''}\n                          </option>\n                        ))}\n                      </select>\n                    )}\n\n                    <button\n                      className=\"vpg-remove-btn\"\n                      title=\"Remove\"\n                      onClick={(e) => {\n                        e.stopPropagation()\n                        removeField(field.field, field.assignedTo, field.valueConfig)\n                      }}\n                    >\n                      ×\n                    </button>\n                  </div>\n                </div>\n\n                {/* Axis value filter panel */}\n                {openFilterField === field.field && canFilterField(field) && (\n                  <div className=\"vpg-filter-panel\">\n                    <div className=\"vpg-filter-panel-header\">\n                      <span className=\"vpg-filter-panel-count\">\n                        {openFilterSelectedCount}\n                        {' of '}\n                        {openFilterValues.length}\n                        {' shown'}\n                      </span>\n                      <div className=\"vpg-filter-quick-actions\">\n                        <button\n                          className=\"vpg-filter-quick-btn\"\n                          onClick={() => onUpdateFieldFilter?.(field.field, [])}\n                        >\n                          All\n                        </button>\n                        <button\n                          className=\"vpg-filter-quick-btn\"\n                          onClick={() => onUpdateFieldFilter?.(field.field, [...openFilterValues])}\n                        >\n                          None\n                        </button>\n                      </div>\n                    </div>\n                    {openFilterValues.length > 8 && (\n                      <input\n                        type=\"text\"\n                        value={filterValueSearch}\n                        onChange={e => setFilterValueSearch(e.target.value)}\n                        placeholder=\"Search values...\"\n                        className=\"vpg-filter-search\"\n                      />\n                    )}\n                    <div className=\"vpg-filter-value-list\">\n                      {filteredFilterValues.slice(0, MAX_RENDERED_FILTER_VALUES).map(value => (\n                        <label key={value} className=\"vpg-filter-value-item\">\n                          <input\n                            type=\"checkbox\"\n                            checked={!openFilterExcluded.has(value)}\n                            onChange={() => toggleFilterValue(field.field, value)}\n                          />\n                          <span className=\"vpg-filter-value-label\" title={value}>{value}</span>\n                        </label>\n                      ))}\n                      {filteredFilterValues.length > MAX_RENDERED_FILTER_VALUES && (\n                        <div className=\"vpg-empty-hint\">\n                          {filteredFilterValues.length - MAX_RENDERED_FILTER_VALUES}\n                          {' more — search to narrow the list'}\n                        </div>\n                      )}\n                      {filteredFilterValues.length === 0 && (\n                        <div className=\"vpg-empty-hint\">No matching values</div>\n                      )}\n                    </div>\n                  </div>\n                )}\n              </React.Fragment>\n            ))}\n          </div>\n        </div>\n      )}\n\n      {/* Unassigned Fields */}\n      <div className=\"vpg-unassigned-section\">\n        <div className=\"vpg-section-header\">\n          <div className=\"vpg-section-label\">\n            Available\n            {' '}\n            <span className=\"vpg-count\">{unassignedFields.length}</span>\n          </div>\n        </div>\n\n        {/* Field Search */}\n        <div className=\"vpg-field-search\">\n          <svg className=\"vpg-search-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n            />\n          </svg>\n          <input\n            type=\"text\"\n            value={fieldSearch}\n            onChange={e => setFieldSearch(e.target.value)}\n            placeholder=\"Search fields...\"\n            className=\"vpg-search-input\"\n          />\n          {fieldSearch && (\n            <button className=\"vpg-clear-search\" onClick={() => setFieldSearch('')}>\n              <svg className=\"vpg-icon-xs\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M6 18L18 6M6 6l12 12\"\n                />\n              </svg>\n            </button>\n          )}\n        </div>\n\n        <div className=\"vpg-field-list\">\n          {filteredUnassignedFields.map(field => (\n            <div\n              key={field.field}\n              className={`vpg-field-item${field.isNumeric && !field.isCalculated ? ' vpg-is-numeric' : ''}${field.isCalculated ? ' vpg-is-calculated' : ''}`}\n              title={field.isCalculated ? field.calcFormula : field.field}\n              draggable\n              onDragStart={e => handleDragStart(field.field, e)}\n              onDragEnd={onDragEnd}\n            >\n              <span className={`vpg-field-type-icon${field.isCalculated ? ' vpg-calc-type' : ''}`} title={field.type}>\n                {getFieldIcon(field.type, field.isCalculated)}\n              </span>\n              <span className=\"vpg-field-name\">{getFieldDisplayName(field)}</span>\n              {field.isCalculated\n                ? (\n                    <>\n                      <button\n                        className=\"vpg-field-edit\"\n                        title=\"Edit calculated field\"\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          const calcField = calculatedFields?.find(c => c.id === field.calcId)\n                          if (calcField)\n                            openCalcModal(calcField)\n                        }}\n                      >\n                        ✎\n                      </button>\n                      <button\n                        className=\"vpg-field-delete\"\n                        title=\"Delete calculated field\"\n                        onClick={(e) => {\n                          e.stopPropagation()\n                          if (field.calcId && onRemoveCalculatedField) {\n                            onRemoveCalculatedField(field.calcId)\n                          }\n                        }}\n                      >\n                        ×\n                      </button>\n                    </>\n                  )\n                : (\n                    <span className=\"vpg-unique-count\">{field.uniqueCount}</span>\n                  )}\n            </div>\n          ))}\n          {filteredUnassignedFields.length === 0 && fieldSearch && (\n            <div className=\"vpg-empty-hint\">\n              No fields match \"\n              {fieldSearch}\n              \"\n            </div>\n          )}\n          {unassignedFields.length === 0 && <div className=\"vpg-empty-hint\">All fields assigned</div>}\n        </div>\n      </div>\n\n      {/* Options */}\n      <div className=\"vpg-options-section\">\n        <label className=\"vpg-option-toggle\">\n          <input\n            type=\"checkbox\"\n            checked={showRowTotals}\n            onChange={e => handleTotalsToggle(e.target.checked)}\n          />\n          <span>Totals</span>\n        </label>\n        <button className=\"vpg-calc-btn\" onClick={() => openCalcModal()} title=\"Add calculated field (e.g. Profit Margin %)\">\n          <span className=\"vpg-calc-icon\">ƒ</span>\n          <span>+ Calc</span>\n        </button>\n      </div>\n\n      {/* Calculated Field Modal */}\n      <CalculatedFieldModal\n        show={showCalcModal}\n        availableFields={numericFieldNames}\n        existingField={editingCalcField}\n        theme={theme}\n        onClose={handleCloseCalcModal}\n        onSave={handleSaveCalcField}\n      />\n    </div>\n  )\n}\n","import type { AggregationFunction, CalculatedField, PivotGroupStart, PivotLayout, PivotResult, PivotValueField } from '@smallwebco/tinypivot-core'\nimport { computeRowSpans, getAggregationLabel, getAggregationSymbol } from '@smallwebco/tinypivot-core'\n/**\n * Pivot Table Skeleton + Data Display for React\n * Visual layout for pivot configuration and results\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useLicense } from '../hooks/useLicense'\n\ninterface ActiveFilter {\n  column: string\n  valueCount: number\n  values?: string[]\n  displayText?: string\n  isRange?: boolean\n}\n\ninterface PivotSkeletonProps {\n  rowFields: string[]\n  columnFields: string[]\n  valueFields: PivotValueField[]\n  calculatedFields?: CalculatedField[]\n  isConfigured: boolean\n  draggingField: string | null\n  pivotResult: PivotResult | null\n  hasActiveFieldFilters?: boolean\n  fontSize?: 'xs' | 'sm' | 'base'\n  activeFilters?: ActiveFilter[] | null\n  totalRowCount?: number\n  filteredRowCount?: number\n  enableDrillDown?: boolean\n  enableDrillThrough?: boolean\n  onAddRowField: (field: string) => void\n  onRemoveRowField: (field: string) => void\n  onAddColumnField: (field: string) => void\n  onRemoveColumnField: (field: string) => void\n  onAddValueField: (field: string, aggregation: AggregationFunction) => void\n  onRemoveValueField: (field: string, aggregation: AggregationFunction) => void\n  onUpdateAggregation: (field: string, oldAgg: AggregationFunction, newAgg: AggregationFunction) => void\n  onReorderRowFields: (fields: string[]) => void\n  onReorderColumnFields: (fields: string[]) => void\n  onToggleCollapse?: (key: string, altKey: boolean) => void\n  onDrillThroughCell?: (payload: { rowPath: string[], columnPath: string[], valueFieldIndex: number }) => void\n  theme?: string\n  pivotLayout?: PivotLayout\n}\n\nexport function PivotSkeleton({\n  rowFields,\n  columnFields,\n  valueFields,\n  calculatedFields,\n  isConfigured,\n  draggingField,\n  pivotResult,\n  hasActiveFieldFilters,\n  fontSize = 'xs',\n  activeFilters,\n  totalRowCount,\n  filteredRowCount,\n  enableDrillDown,\n  enableDrillThrough,\n  onAddRowField,\n  onRemoveRowField,\n  onAddColumnField,\n  onRemoveColumnField,\n  onAddValueField,\n  onRemoveValueField,\n  onReorderRowFields,\n  onReorderColumnFields,\n  onToggleCollapse,\n  onDrillThroughCell,\n  theme,\n  pivotLayout = 'grouped',\n}: PivotSkeletonProps) {\n  const { showWatermark, canUsePivot, isDemo } = useLicense()\n\n  // Helper to get display name for value fields (resolves calc IDs to names)\n  const getValueFieldDisplayName = useCallback((field: string): string => {\n    if (field.startsWith('calc:')) {\n      const calcId = field.replace('calc:', '')\n      const calcField = calculatedFields?.find(c => c.id === calcId)\n      return calcField?.name || field\n    }\n    return field\n  }, [calculatedFields])\n\n  // Helper to check if field is a calculated field\n  const isCalculatedField = useCallback((field: string): boolean => {\n    return field.startsWith('calc:')\n  }, [])\n\n  // Drag state\n  const [dragOverArea, setDragOverArea] = useState<'row' | 'column' | 'value' | null>(null)\n\n  // Reorder drag state\n  const [reorderDragSource, setReorderDragSource] = useState<{ zone: 'row' | 'column', index: number } | null>(null)\n  const [reorderDropTarget, setReorderDropTarget] = useState<{ zone: 'row' | 'column', index: number } | null>(null)\n\n  // Sorting\n  type SortTarget = 'row' | number\n  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')\n  const [sortTarget, setSortTarget] = useState<SortTarget>('row')\n\n  const toggleSort = useCallback((target: SortTarget = 'row') => {\n    if (sortTarget === target) {\n      setSortDirection(prev => (prev === 'asc' ? 'desc' : 'asc'))\n    }\n    else {\n      setSortTarget(target)\n      setSortDirection('asc')\n    }\n  }, [sortTarget])\n\n  // Selection state for cell selection and copy\n  const [selectedCell, setSelectedCell] = useState<{ row: number, col: number } | null>(null)\n  const [selectionStart, setSelectionStart] = useState<{ row: number, col: number } | null>(null)\n  const [selectionEnd, setSelectionEnd] = useState<{ row: number, col: number } | null>(null)\n  const [isSelecting, setIsSelecting] = useState(false)\n  const [showCopyToast, setShowCopyToast] = useState(false)\n  const [copyToastMessage, setCopyToastMessage] = useState('')\n\n  const selectionBounds = useMemo(() => {\n    if (!selectionStart || !selectionEnd)\n      return null\n    return {\n      minRow: Math.min(selectionStart.row, selectionEnd.row),\n      maxRow: Math.max(selectionStart.row, selectionEnd.row),\n      minCol: Math.min(selectionStart.col, selectionEnd.col),\n      maxCol: Math.max(selectionStart.col, selectionEnd.col),\n    }\n  }, [selectionStart, selectionEnd])\n\n  const handleCellMouseDown = useCallback(\n    (rowIndex: number, colIndex: number, event: React.MouseEvent) => {\n      event.preventDefault()\n\n      if (event.shiftKey && selectedCell) {\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n      }\n      else {\n        setSelectedCell({ row: rowIndex, col: colIndex })\n        setSelectionStart({ row: rowIndex, col: colIndex })\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n        setIsSelecting(true)\n      }\n    },\n    [selectedCell],\n  )\n\n  const handleCellMouseEnter = useCallback(\n    (rowIndex: number, colIndex: number) => {\n      if (isSelecting) {\n        setSelectionEnd({ row: rowIndex, col: colIndex })\n      }\n    },\n    [isSelecting],\n  )\n\n  const isCellSelected = useCallback(\n    (rowIndex: number, colIndex: number): boolean => {\n      if (!selectionBounds) {\n        return selectedCell?.row === rowIndex && selectedCell?.col === colIndex\n      }\n      const { minRow, maxRow, minCol, maxCol } = selectionBounds\n      return rowIndex >= minRow && rowIndex <= maxRow && colIndex >= minCol && colIndex <= maxCol\n    },\n    [selectionBounds, selectedCell],\n  )\n\n  // Mouse up handler\n  useEffect(() => {\n    const handleMouseUp = () => setIsSelecting(false)\n    document.addEventListener('mouseup', handleMouseUp)\n    return () => document.removeEventListener('mouseup', handleMouseUp)\n  }, [])\n\n  // Sorted row indices\n  const sortedRowIndices = useMemo(() => {\n    if (!pivotResult)\n      return []\n\n    const indices = pivotResult.rowHeaders.map((_, i) => i)\n    const headers = pivotResult.rowHeaders\n    const data = pivotResult.data\n\n    indices.sort((a, b) => {\n      let cmp: number\n\n      if (sortTarget === 'row') {\n        const aHeader = headers[a]?.join(' / ') || ''\n        const bHeader = headers[b]?.join(' / ') || ''\n        cmp = aHeader.localeCompare(bHeader, undefined, { numeric: true, sensitivity: 'base' })\n      }\n      else {\n        const colIdx = sortTarget as number\n        const aVal = data[a]?.[colIdx]?.value ?? null\n        const bVal = data[b]?.[colIdx]?.value ?? null\n\n        if (aVal === null && bVal === null)\n          cmp = 0\n        else if (aVal === null)\n          cmp = 1\n        else if (bVal === null)\n          cmp = -1\n        else cmp = aVal - bVal\n      }\n\n      return sortDirection === 'asc' ? cmp : -cmp\n    })\n\n    return indices\n  }, [pivotResult, sortTarget, sortDirection])\n\n  // Grouped layout: per-cell rowspan information (indexed by [sortedPosition][columnIndex])\n  const rowSpans = useMemo(() => {\n    if (!pivotResult || pivotLayout !== 'grouped')\n      return null\n    return computeRowSpans(pivotResult.rowHeaders, sortedRowIndices, rowFields.length)\n  }, [pivotResult, pivotLayout, sortedRowIndices, rowFields.length])\n\n  // Copy selection to clipboard\n  const copySelectionToClipboard = useCallback(() => {\n    if (!selectionBounds || !pivotResult)\n      return\n\n    const { minRow, maxRow, minCol, maxCol } = selectionBounds\n    const lines: string[] = []\n\n    for (let r = minRow; r <= maxRow; r++) {\n      const sortedIdx = sortedRowIndices[r]\n      if (sortedIdx === undefined)\n        continue\n\n      const rowValues: string[] = []\n      for (let c = minCol; c <= maxCol; c++) {\n        const cell = pivotResult.data[sortedIdx]?.[c]\n        rowValues.push(cell?.formattedValue ?? '')\n      }\n      lines.push(rowValues.join('\\t'))\n    }\n\n    const text = lines.join('\\n')\n\n    navigator.clipboard.writeText(text).then(() => {\n      const cellCount = (maxRow - minRow + 1) * (maxCol - minCol + 1)\n      setCopyToastMessage(`Copied ${cellCount} cell${cellCount > 1 ? 's' : ''}`)\n      setShowCopyToast(true)\n      setTimeout(setShowCopyToast, 2000, false)\n    }).catch((err) => {\n      console.error('Copy failed:', err)\n    })\n  }, [selectionBounds, pivotResult, sortedRowIndices])\n\n  // Keyboard handler for copy\n  useEffect(() => {\n    const handleKeydown = (event: KeyboardEvent) => {\n      if (!selectionBounds)\n        return\n\n      if ((event.ctrlKey || event.metaKey) && event.key === 'c') {\n        event.preventDefault()\n        copySelectionToClipboard()\n        return\n      }\n\n      if (event.key === 'Escape') {\n        setSelectedCell(null)\n        setSelectionStart(null)\n        setSelectionEnd(null)\n      }\n    }\n\n    document.addEventListener('keydown', handleKeydown)\n    return () => document.removeEventListener('keydown', handleKeydown)\n  }, [selectionBounds, copySelectionToClipboard])\n\n  // Selection statistics for footer\n  const selectionStats = useMemo(() => {\n    if (!selectionBounds || !pivotResult)\n      return null\n\n    const { minRow, maxRow, minCol, maxCol } = selectionBounds\n    const values: number[] = []\n    let count = 0\n\n    for (let r = minRow; r <= maxRow; r++) {\n      const sortedIdx = sortedRowIndices[r]\n      if (sortedIdx === undefined)\n        continue\n\n      for (let c = minCol; c <= maxCol; c++) {\n        const cell = pivotResult.data[sortedIdx]?.[c]\n        count++\n        if (cell?.value !== null && cell?.value !== undefined && typeof cell.value === 'number') {\n          values.push(cell.value)\n        }\n      }\n    }\n\n    if (count <= 1)\n      return null\n\n    const sum = values.reduce((a, b) => a + b, 0)\n    const avg = values.length > 0 ? sum / values.length : 0\n\n    return {\n      count,\n      numericCount: values.length,\n      sum,\n      avg,\n    }\n  }, [selectionBounds, pivotResult, sortedRowIndices])\n\n  const formatStatValue = useCallback((val: number): string => {\n    if (Math.abs(val) >= 1_000_000)\n      return `${(val / 1_000_000).toFixed(2)}M`\n    if (Math.abs(val) >= 1_000)\n      return `${(val / 1_000).toFixed(2)}K`\n    return val.toFixed(2)\n  }, [])\n\n  // Column headers\n  const columnHeaderCells = useMemo(() => {\n    if (!pivotResult || pivotResult.headers.length === 0) {\n      return [\n        valueFields.map(vf => ({\n          label: `${getValueFieldDisplayName(vf.field)} (${getAggregationLabel(vf.aggregation)})`,\n          colspan: 1,\n        })),\n      ]\n    }\n\n    const result: Array<Array<{ label: string, colspan: number }>> = []\n\n    for (let level = 0; level < pivotResult.headers.length; level++) {\n      const headerRow = pivotResult.headers[level]\n      const cells: Array<{ label: string, colspan: number }> = []\n\n      let i = 0\n      while (i < headerRow.length) {\n        const value = headerRow[i]\n        let colspan = 1\n\n        while (i + colspan < headerRow.length && headerRow[i + colspan] === value) {\n          colspan++\n        }\n\n        cells.push({ label: value, colspan })\n        i += colspan\n      }\n\n      result.push(cells)\n    }\n\n    return result\n  }, [pivotResult, valueFields])\n\n  // Filter status\n  const hasActiveFilters = activeFilters && activeFilters.length > 0\n  const filterSummary = useMemo(() => {\n    if (!activeFilters || activeFilters.length === 0)\n      return ''\n    return activeFilters.map(f => f.column).join(', ')\n  }, [activeFilters])\n\n  // Detailed filter tooltip\n  const [showFilterTooltip, setShowFilterTooltip] = useState(false)\n  const filterTooltipDetails = useMemo(() => {\n    if (!activeFilters || activeFilters.length === 0)\n      return []\n    return activeFilters.map((f) => {\n      // Handle range filters\n      if (f.isRange && f.displayText) {\n        return {\n          column: f.column,\n          displayText: f.displayText,\n          isRange: true,\n          values: [] as string[],\n          remaining: 0,\n        }\n      }\n      // Handle value filters\n      const values = f.values || []\n      const maxDisplay = 5\n      const displayValues = values.slice(0, maxDisplay)\n      const remaining = values.length - maxDisplay\n      return {\n        column: f.column,\n        values: displayValues,\n        remaining: remaining > 0 ? remaining : 0,\n        isRange: false,\n      }\n    })\n  }, [activeFilters])\n\n  // Drag handlers\n  const handleDragOver = useCallback(\n    (area: 'row' | 'column' | 'value', event: React.DragEvent) => {\n      event.preventDefault()\n      event.dataTransfer!.dropEffect = 'move'\n      setDragOverArea(area)\n    },\n    [],\n  )\n\n  const handleDragLeave = useCallback(() => {\n    setDragOverArea(null)\n  }, [])\n\n  const handleDrop = useCallback(\n    (area: 'row' | 'column' | 'value', event: React.DragEvent) => {\n      event.preventDefault()\n      const field = event.dataTransfer?.getData('text/plain')\n\n      if (!field || field.startsWith('reorder:')) {\n        setDragOverArea(null)\n        return\n      }\n\n      if (rowFields.includes(field))\n        onRemoveRowField(field)\n      if (columnFields.includes(field))\n        onRemoveColumnField(field)\n      const existingValue = valueFields.find(v => v.field === field)\n      if (existingValue)\n        onRemoveValueField(field, existingValue.aggregation)\n\n      switch (area) {\n        case 'row':\n          onAddRowField(field)\n          break\n        case 'column':\n          onAddColumnField(field)\n          break\n        case 'value':\n          onAddValueField(field, 'sum')\n          break\n      }\n      setDragOverArea(null)\n    },\n    [rowFields, columnFields, valueFields, onAddRowField, onRemoveRowField, onAddColumnField, onRemoveColumnField, onAddValueField, onRemoveValueField],\n  )\n\n  // Reorder handlers for chips within zones\n  const handleChipDragStart = useCallback(\n    (zone: 'row' | 'column', index: number, event: React.DragEvent) => {\n      setReorderDragSource({ zone, index })\n      event.dataTransfer!.effectAllowed = 'move'\n      event.dataTransfer!.setData('text/plain', `reorder:${zone}:${index}`)\n      // Clear any zone drag-over state\n      requestAnimationFrame(() => {\n        setDragOverArea(null)\n      })\n    },\n    [],\n  )\n\n  const handleChipDragEnd = useCallback(() => {\n    setReorderDragSource(null)\n    setReorderDropTarget(null)\n  }, [])\n\n  const handleChipDragOver = useCallback(\n    (zone: 'row' | 'column', index: number, event: React.DragEvent) => {\n      event.preventDefault()\n      // Only handle reorder within same zone\n      if (reorderDragSource && reorderDragSource.zone === zone) {\n        event.dataTransfer!.dropEffect = 'move'\n        setReorderDropTarget({ zone, index })\n      }\n    },\n    [reorderDragSource],\n  )\n\n  const handleChipDragLeave = useCallback(() => {\n    setReorderDropTarget(null)\n  }, [])\n\n  const handleChipDrop = useCallback(\n    (zone: 'row' | 'column', targetIndex: number, event: React.DragEvent) => {\n      event.preventDefault()\n      event.stopPropagation()\n\n      if (!reorderDragSource || reorderDragSource.zone !== zone) {\n        return\n      }\n\n      const sourceIndex = reorderDragSource.index\n      if (sourceIndex === targetIndex) {\n        setReorderDragSource(null)\n        setReorderDropTarget(null)\n        return\n      }\n\n      // Create reordered array\n      const fields = zone === 'row' ? [...rowFields] : [...columnFields]\n      const [movedField] = fields.splice(sourceIndex, 1)\n      fields.splice(targetIndex, 0, movedField)\n\n      // Emit reorder event\n      if (zone === 'row') {\n        onReorderRowFields(fields)\n      }\n      else {\n        onReorderColumnFields(fields)\n      }\n\n      setReorderDragSource(null)\n      setReorderDropTarget(null)\n    },\n    [reorderDragSource, rowFields, columnFields, onReorderRowFields, onReorderColumnFields],\n  )\n\n  const isChipDragSource = useCallback(\n    (zone: 'row' | 'column', index: number): boolean => {\n      return reorderDragSource?.zone === zone && reorderDragSource?.index === index\n    },\n    [reorderDragSource],\n  )\n\n  const isChipDropTarget = useCallback(\n    (zone: 'row' | 'column', index: number): boolean => {\n      return reorderDropTarget?.zone === zone && reorderDropTarget?.index === index\n    },\n    [reorderDropTarget],\n  )\n\n  const currentFontSize = fontSize\n\n  // Computed column paths: for each colIdx, the column field path\n  const columnPaths = useMemo((): string[][] => {\n    if (!pivotResult || columnFields.length === 0)\n      return []\n\n    const numCols = pivotResult.data[0]?.length ?? 0\n    const numValueFields = valueFields.length || 1\n    const paths: string[][] = []\n\n    for (let colIdx = 0; colIdx < numCols; colIdx++) {\n      const colKeyIndex = Math.floor(colIdx / numValueFields)\n      const path: string[] = []\n      for (let h = 0; h < columnFields.length; h++) {\n        const headerRow = pivotResult.headers[h]\n        if (headerRow) {\n          path.push(headerRow[colKeyIndex * numValueFields] ?? '')\n        }\n      }\n      paths.push(path)\n    }\n\n    return paths\n  }, [pivotResult, columnFields, valueFields])\n\n  // Find groupStart for a given row and column index\n  const findGroupStart = useCallback((sortedIdx: number, idx: number): PivotGroupStart | null => {\n    if (!pivotResult)\n      return null\n    const meta = pivotResult.rowMeta[sortedIdx]\n    if (!meta)\n      return null\n    return meta.groupStarts.find(gs => gs.depth === idx) ?? null\n  }, [pivotResult])\n\n  // Handle chevron click\n  const handleChevronClick = useCallback((groupStart: PivotGroupStart, event: React.MouseEvent) => {\n    onToggleCollapse?.(groupStart.key, event.altKey)\n  }, [onToggleCollapse])\n\n  // Handle drill-through on a data cell\n  const handleDrillThroughCell = useCallback((sortedIdx: number, colIdx: number) => {\n    if (!pivotResult)\n      return\n    const meta = pivotResult.rowMeta[sortedIdx]\n    const rowPath = meta ? meta.path : []\n    const colPath = columnPaths[colIdx] ?? []\n    const numValueFields = valueFields.length || 1\n    const valueFieldIndex = colIdx % numValueFields\n    onDrillThroughCell?.({ rowPath, columnPath: colPath, valueFieldIndex })\n  }, [pivotResult, columnPaths, valueFields, onDrillThroughCell])\n\n  // Handle drill-through on a row total cell\n  const handleDrillThroughRowTotal = useCallback((sortedIdx: number) => {\n    if (!pivotResult)\n      return\n    const meta = pivotResult.rowMeta[sortedIdx]\n    const rowPath = meta ? meta.path : []\n    onDrillThroughCell?.({ rowPath, columnPath: [], valueFieldIndex: 0 })\n  }, [pivotResult, onDrillThroughCell])\n\n  // Handle drill-through on a column total cell\n  const handleDrillThroughColTotal = useCallback((colIdx: number) => {\n    const colPath = columnPaths[colIdx] ?? []\n    const numValueFields = valueFields.length || 1\n    const valueFieldIndex = colIdx % numValueFields\n    onDrillThroughCell?.({ rowPath: [], columnPath: colPath, valueFieldIndex })\n  }, [columnPaths, valueFields, onDrillThroughCell])\n\n  // Handle drill-through on the grand total cell\n  const handleDrillThroughGrandTotal = useCallback(() => {\n    onDrillThroughCell?.({ rowPath: [], columnPath: [], valueFieldIndex: 0 })\n  }, [onDrillThroughCell])\n\n  // Calculate width per row header column\n  const rowHeaderWidth = 180\n  const rowHeaderColWidth = useMemo(() => {\n    const numCols = Math.max(rowFields.length, 1)\n    return Math.max(rowHeaderWidth / numCols, 80)\n  }, [rowFields.length])\n\n  // Calculate left offset for each row header column (for sticky positioning)\n  const getRowHeaderLeftOffset = useCallback((fieldIdx: number): number => {\n    return fieldIdx * rowHeaderColWidth\n  }, [rowHeaderColWidth])\n\n  return (\n    <div\n      className={`vpg-pivot-skeleton vpg-font-${currentFontSize} ${theme ? `vpg-theme-${theme}` : ''} ${draggingField ? 'vpg-is-dragging' : ''}`}\n    >\n      {/* Copy Toast */}\n      {showCopyToast && (\n        <div className=\"vpg-toast\">\n          <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n          </svg>\n          {copyToastMessage}\n        </div>\n      )}\n\n      {/* Header Bar */}\n      <div className=\"vpg-skeleton-header\">\n        <div className=\"vpg-skeleton-title\">\n          <svg className=\"vpg-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              strokeWidth={2}\n              d=\"M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z\"\n            />\n          </svg>\n          <span>Pivot Table</span>\n        </div>\n\n        <div className=\"vpg-header-right\">\n          {hasActiveFilters && (\n            <div\n              className=\"vpg-filter-indicator\"\n              onMouseEnter={() => setShowFilterTooltip(true)}\n              onMouseLeave={() => setShowFilterTooltip(false)}\n            >\n              <svg\n                className=\"vpg-filter-icon\"\n                fill=\"none\"\n                stroke=\"currentColor\"\n                viewBox=\"0 0 24 24\"\n              >\n                <path\n                  strokeLinecap=\"round\"\n                  strokeLinejoin=\"round\"\n                  strokeWidth={2}\n                  d=\"M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z\"\n                />\n              </svg>\n              <span className=\"vpg-filter-text\">\n                Filtered:\n                {' '}\n                <strong>{filterSummary}</strong>\n                {filteredRowCount !== undefined && totalRowCount !== undefined && (\n                  <span className=\"vpg-filter-count\">\n                    (\n                    {filteredRowCount.toLocaleString()}\n                    {' '}\n                    of\n                    {' '}\n                    {totalRowCount.toLocaleString()}\n                    {' '}\n                    rows)\n                  </span>\n                )}\n              </span>\n\n              {/* Tooltip */}\n              {showFilterTooltip && (\n                <div className=\"vpg-filter-tooltip\">\n                  <div className=\"vpg-tooltip-header\">Active Filters</div>\n                  {filterTooltipDetails.map(filter => (\n                    <div key={filter.column} className=\"vpg-tooltip-filter\">\n                      <div className=\"vpg-tooltip-column\">{filter.column}</div>\n                      <div className=\"vpg-tooltip-values\">\n                        {filter.isRange\n                          ? (\n                              <span className=\"vpg-tooltip-value vpg-range-value\">{filter.displayText}</span>\n                            )\n                          : (\n                              <>\n                                {filter.values.map((val, idx) => (\n                                  <span key={idx} className=\"vpg-tooltip-value\">\n                                    {val}\n                                  </span>\n                                ))}\n                                {filter.remaining > 0 && (\n                                  <span className=\"vpg-tooltip-more\">\n                                    +\n                                    {filter.remaining}\n                                    {' '}\n                                    more\n                                  </span>\n                                )}\n                              </>\n                            )}\n                      </div>\n                    </div>\n                  ))}\n                  {filteredRowCount !== undefined && totalRowCount !== undefined && (\n                    <div className=\"vpg-tooltip-summary\">\n                      Showing\n                      {' '}\n                      {filteredRowCount.toLocaleString()}\n                      {' '}\n                      of\n                      {' '}\n                      {totalRowCount.toLocaleString()}\n                      {' '}\n                      rows\n                    </div>\n                  )}\n                </div>\n              )}\n            </div>\n          )}\n\n          {isConfigured && (\n            <div className=\"vpg-config-summary\">\n              <span className=\"vpg-summary-badge vpg-rows\">\n                {rowFields.length}\n                {' '}\n                row\n                {rowFields.length !== 1 ? 's' : ''}\n              </span>\n              <span className=\"vpg-summary-badge vpg-cols\">\n                {columnFields.length}\n                {' '}\n                col\n                {columnFields.length !== 1 ? 's' : ''}\n              </span>\n              <span className=\"vpg-summary-badge vpg-vals\">\n                {valueFields.length}\n                {' '}\n                val\n                {valueFields.length !== 1 ? 's' : ''}\n              </span>\n            </div>\n          )}\n        </div>\n      </div>\n\n      {/* Fallback message */}\n      {!canUsePivot ? (\n        <div className=\"vpg-pro-required\">\n          <div className=\"vpg-pro-content\">\n            <svg className=\"vpg-pro-icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n              <path\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n                strokeWidth={2}\n                d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n              />\n            </svg>\n            <h3>Pivot Unavailable</h3>\n            <p>Pivot mode could not be enabled in this session. Try reloading the page.</p>\n          </div>\n        </div>\n      ) : (\n        <>\n          {/* Config Bar */}\n          <div className=\"vpg-config-bar\">\n            {/* Row drop zone */}\n            <div\n              className={`vpg-drop-zone vpg-row-zone ${dragOverArea === 'row' ? 'vpg-drag-over' : ''}`}\n              onDragOver={e => handleDragOver('row', e)}\n              onDragLeave={handleDragLeave}\n              onDrop={e => handleDrop('row', e)}\n            >\n              <div className=\"vpg-zone-header\">\n                <span className=\"vpg-zone-icon vpg-row-icon\">↓</span>\n                <span className=\"vpg-zone-label\">Rows</span>\n              </div>\n              <div className=\"vpg-zone-chips\">\n                {rowFields.map((field, idx) => (\n                  <div\n                    key={field}\n                    className={`vpg-mini-chip vpg-row-chip ${isChipDragSource('row', idx) ? 'vpg-chip-dragging' : ''} ${isChipDropTarget('row', idx) ? 'vpg-chip-drop-target' : ''}`}\n                    draggable\n                    onDragStart={e => handleChipDragStart('row', idx, e)}\n                    onDragEnd={handleChipDragEnd}\n                    onDragOver={e => handleChipDragOver('row', idx, e)}\n                    onDragLeave={handleChipDragLeave}\n                    onDrop={e => handleChipDrop('row', idx, e)}\n                  >\n                    <span className=\"vpg-drag-handle\">⋮⋮</span>\n                    <span className=\"vpg-mini-name\">{field}</span>\n                    <button\n                      className=\"vpg-mini-remove\"\n                      onClick={(e) => { e.stopPropagation(); onRemoveRowField(field) }}\n                    >\n                      ×\n                    </button>\n                  </div>\n                ))}\n                {rowFields.length === 0 && <span className=\"vpg-zone-hint\">Drop here</span>}\n              </div>\n            </div>\n\n            {/* Column drop zone */}\n            <div\n              className={`vpg-drop-zone vpg-column-zone ${dragOverArea === 'column' ? 'vpg-drag-over' : ''}`}\n              onDragOver={e => handleDragOver('column', e)}\n              onDragLeave={handleDragLeave}\n              onDrop={e => handleDrop('column', e)}\n            >\n              <div className=\"vpg-zone-header\">\n                <span className=\"vpg-zone-icon vpg-column-icon\">→</span>\n                <span className=\"vpg-zone-label\">Columns</span>\n              </div>\n              <div className=\"vpg-zone-chips\">\n                {columnFields.map((field, idx) => (\n                  <div\n                    key={field}\n                    className={`vpg-mini-chip vpg-column-chip ${isChipDragSource('column', idx) ? 'vpg-chip-dragging' : ''} ${isChipDropTarget('column', idx) ? 'vpg-chip-drop-target' : ''}`}\n                    draggable\n                    onDragStart={e => handleChipDragStart('column', idx, e)}\n                    onDragEnd={handleChipDragEnd}\n                    onDragOver={e => handleChipDragOver('column', idx, e)}\n                    onDragLeave={handleChipDragLeave}\n                    onDrop={e => handleChipDrop('column', idx, e)}\n                  >\n                    <span className=\"vpg-drag-handle\">⋮⋮</span>\n                    <span className=\"vpg-mini-name\">{field}</span>\n                    <button\n                      className=\"vpg-mini-remove\"\n                      onClick={(e) => { e.stopPropagation(); onRemoveColumnField(field) }}\n                    >\n                      ×\n                    </button>\n                  </div>\n                ))}\n                {columnFields.length === 0 && <span className=\"vpg-zone-hint\">Drop here</span>}\n              </div>\n            </div>\n\n            {/* Values drop zone */}\n            <div\n              className={`vpg-drop-zone vpg-value-zone ${dragOverArea === 'value' ? 'vpg-drag-over' : ''}`}\n              onDragOver={e => handleDragOver('value', e)}\n              onDragLeave={handleDragLeave}\n              onDrop={e => handleDrop('value', e)}\n            >\n              <div className=\"vpg-zone-header\">\n                <span className=\"vpg-zone-icon vpg-value-icon\">Σ</span>\n                <span className=\"vpg-zone-label\">Values</span>\n              </div>\n              <div className=\"vpg-zone-chips\">\n                {valueFields.map(vf => (\n                  <div\n                    key={`${vf.field}-${vf.aggregation}`}\n                    className={`vpg-mini-chip vpg-value-chip${isCalculatedField(vf.field) ? ' vpg-calc-chip' : ''}`}\n                  >\n                    <span className=\"vpg-agg-symbol\">{isCalculatedField(vf.field) ? 'ƒ' : getAggregationSymbol(vf.aggregation)}</span>\n                    <span className=\"vpg-mini-name\">{getValueFieldDisplayName(vf.field)}</span>\n                    <button\n                      className=\"vpg-mini-remove\"\n                      onClick={() => onRemoveValueField(vf.field, vf.aggregation)}\n                    >\n                      ×\n                    </button>\n                  </div>\n                ))}\n                {valueFields.length === 0 && <span className=\"vpg-zone-hint\">Drop numeric</span>}\n              </div>\n            </div>\n          </div>\n\n          {/* Placeholder when not configured */}\n          {(!isConfigured || !pivotResult) && (\n            <div className=\"vpg-placeholder\">\n              <div className=\"vpg-placeholder-content\">\n                <svg\n                  className=\"vpg-placeholder-icon\"\n                  fill=\"none\"\n                  viewBox=\"0 0 24 24\"\n                  stroke=\"currentColor\"\n                >\n                  <path\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    strokeWidth={1.5}\n                    d=\"M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z\"\n                  />\n                </svg>\n                <span className=\"vpg-placeholder-text\">\n                  {valueFields.length === 0\n                    ? (\n                        <>\n                          Add a\n                          {' '}\n                          <strong>Values</strong>\n                          {' '}\n                          field to see your pivot table\n                        </>\n                      )\n                    : rowFields.length === 0 && columnFields.length === 0\n                      ? (\n                          <>\n                            Add\n                            {' '}\n                            <strong>Row</strong>\n                            {' '}\n                            or\n                            {' '}\n                            <strong>Column</strong>\n                            {' '}\n                            fields to group your data\n                          </>\n                        )\n                      : hasActiveFieldFilters\n                        ? (\n                            'All rows are hidden by axis filters — adjust or clear the filters to see results'\n                          )\n                        : (\n                            'Your pivot table will appear here'\n                          )}\n                </span>\n              </div>\n            </div>\n          )}\n\n          {/* Data Table */}\n          {isConfigured && pivotResult && (\n            <div className=\"vpg-table-container\">\n              <table className=\"vpg-pivot-table\">\n                <thead>\n                  {columnHeaderCells.map((headerRow, levelIdx) => (\n                    <tr key={`header-${levelIdx}`} className=\"vpg-column-header-row\">\n                      {levelIdx === 0 && (rowFields.length > 0 ? rowFields : ['Rows']).map((field, fieldIdx) => (\n                        <th\n                          key={`row-header-${fieldIdx}`}\n                          className=\"vpg-row-header-label\"\n                          rowSpan={columnHeaderCells.length}\n                          style={{ width: `${rowHeaderColWidth}px`, minWidth: '80px', left: `${getRowHeaderLeftOffset(fieldIdx)}px` }}\n                          onClick={() => toggleSort('row')}\n                        >\n                          <div className=\"vpg-header-content\">\n                            <span>{field}</span>\n                            {(fieldIdx === rowFields.length - 1 || rowFields.length === 0) && (\n                              <span className={`vpg-sort-indicator ${sortTarget === 'row' ? 'active' : ''}`}>\n                                {sortTarget === 'row' ? (sortDirection === 'asc' ? '↑' : '↓') : '⇅'}\n                              </span>\n                            )}\n                          </div>\n                        </th>\n                      ))}\n                      {headerRow.map((cell, idx) => (\n                        <th\n                          key={idx}\n                          className=\"vpg-column-header-cell\"\n                          colSpan={cell.colspan}\n                          onClick={() =>\n                            levelIdx === columnHeaderCells.length - 1 && toggleSort(idx)}\n                        >\n                          <div className=\"vpg-header-content\">\n                            <span>{cell.label}</span>\n                            {levelIdx === columnHeaderCells.length - 1 && (\n                              <span className={`vpg-sort-indicator ${sortTarget === idx ? 'active' : ''}`}>\n                                {sortTarget === idx\n                                  ? sortDirection === 'asc'\n                                    ? '↑'\n                                    : '↓'\n                                  : '⇅'}\n                              </span>\n                            )}\n                          </div>\n                        </th>\n                      ))}\n                      {pivotResult.rowTotals.length > 0 && levelIdx === 0 && (\n                        <th className=\"vpg-total-header\" rowSpan={columnHeaderCells.length}>\n                          Total\n                        </th>\n                      )}\n                    </tr>\n                  ))}\n                </thead>\n\n                <tbody>\n                  {sortedRowIndices.map((sortedIdx, rowPos) => (\n                    <tr\n                      key={sortedIdx}\n                      className={`vpg-data-row${pivotResult.rowMeta[sortedIdx]?.isSubtotal ? ' vpg-subtotal-row' : ''}`}\n                    >\n                      {/* Grouped layout: merge repeated parent cells via rowspan; omit skipped cells */}\n                      {rowSpans\n                        ? pivotResult.rowHeaders[sortedIdx].map((val, idx) => {\n                            if (!rowSpans[rowPos][idx].render)\n                              return null\n                            const groupStart = findGroupStart(sortedIdx, idx)\n                            return (\n                              <th\n                                key={`row-${sortedIdx}-${idx}`}\n                                className={`vpg-row-header-cell${enableDrillDown !== false && groupStart ? ' vpg-row-header-collapsible' : ''}`}\n                                rowSpan={rowSpans[rowPos][idx].rowspan}\n                                style={{ width: `${rowHeaderColWidth}px`, minWidth: '80px', left: `${getRowHeaderLeftOffset(idx)}px` }}\n                                onClick={enableDrillDown !== false && groupStart\n                                  ? (e) => { e.stopPropagation(); handleChevronClick(groupStart, e) }\n                                  : undefined}\n                              >\n                                {enableDrillDown !== false && groupStart && (\n                                  <span className=\"vpg-collapse-toggle\">\n                                    {groupStart.isCollapsed ? '▸' : '▾'}\n                                  </span>\n                                )}\n                                {val}\n                              </th>\n                            )\n                          })\n                        /* Tabular layout: render every cell, always rowspan=1 (current behavior) */\n                        : pivotResult.rowHeaders[sortedIdx].map((val, idx) => {\n                            const groupStart = findGroupStart(sortedIdx, idx)\n                            return (\n                              <th\n                                key={`row-${sortedIdx}-${idx}`}\n                                className=\"vpg-row-header-cell\"\n                                style={{ width: `${rowHeaderColWidth}px`, minWidth: '80px', left: `${getRowHeaderLeftOffset(idx)}px` }}\n                              >\n                                {enableDrillDown !== false && groupStart && (\n                                  <span\n                                    className=\"vpg-collapse-toggle\"\n                                    onClick={e => handleChevronClick(groupStart, e)}\n                                  >\n                                    {groupStart.isCollapsed ? '▸' : '▾'}\n                                  </span>\n                                )}\n                                {val}\n                              </th>\n                            )\n                          })}\n\n                      {pivotResult.data[sortedIdx].map((cell, colIdx) => (\n                        <td\n                          key={colIdx}\n                          className={`vpg-data-cell ${isCellSelected(rowPos, colIdx) ? 'selected' : ''} ${cell.value === null ? 'vpg-is-null' : ''}`}\n                          onMouseDown={e => handleCellMouseDown(rowPos, colIdx, e)}\n                          onMouseEnter={() => handleCellMouseEnter(rowPos, colIdx)}\n                          onDoubleClick={enableDrillThrough !== false ? () => handleDrillThroughCell(sortedIdx, colIdx) : undefined}\n                        >\n                          {cell.formattedValue}\n                        </td>\n                      ))}\n\n                      {pivotResult.rowTotals[sortedIdx] && (\n                        <td\n                          className=\"vpg-data-cell vpg-total-cell\"\n                          onDoubleClick={enableDrillThrough !== false ? () => handleDrillThroughRowTotal(sortedIdx) : undefined}\n                        >\n                          {pivotResult.rowTotals[sortedIdx].formattedValue}\n                        </td>\n                      )}\n                    </tr>\n                  ))}\n\n                  {pivotResult.columnTotals.length > 0 && (\n                    <tr className=\"vpg-totals-row\">\n                      <th\n                        className=\"vpg-row-header-cell vpg-total-label\"\n                        colSpan={Math.max(rowFields.length, 1)}\n                        style={{ width: `${rowHeaderWidth}px` }}\n                      >\n                        Total\n                      </th>\n                      {pivotResult.columnTotals.map((cell, colIdx) => (\n                        <td\n                          key={colIdx}\n                          className=\"vpg-data-cell vpg-total-cell\"\n                          onDoubleClick={enableDrillThrough !== false ? () => handleDrillThroughColTotal(colIdx) : undefined}\n                        >\n                          {cell.formattedValue}\n                        </td>\n                      ))}\n                      {pivotResult.rowTotals.length > 0 && (\n                        <td\n                          className=\"vpg-data-cell vpg-grand-total-cell\"\n                          onDoubleClick={enableDrillThrough !== false ? () => handleDrillThroughGrandTotal() : undefined}\n                        >\n                          {pivotResult.grandTotal.formattedValue}\n                        </td>\n                      )}\n                    </tr>\n                  )}\n                </tbody>\n              </table>\n            </div>\n          )}\n\n          {/* Footer */}\n          {isConfigured && pivotResult && (\n            <div className=\"vpg-skeleton-footer\">\n              <span className=\"vpg-footer-info\">\n                {pivotResult.rowHeaders.length}\n                {' '}\n                rows ×\n                {pivotResult.data[0]?.length || 0}\n                {' '}\n                columns\n              </span>\n\n              {selectionStats && selectionStats.count > 1 && (\n                <div className=\"vpg-selection-stats\">\n                  <span className=\"vpg-stat\">\n                    <span className=\"vpg-stat-label\">Count:</span>\n                    <span className=\"vpg-stat-value\">{selectionStats.count}</span>\n                  </span>\n                  {selectionStats.numericCount > 0 && (\n                    <>\n                      <span className=\"vpg-stat-divider\">|</span>\n                      <span className=\"vpg-stat\">\n                        <span className=\"vpg-stat-label\">Sum:</span>\n                        <span className=\"vpg-stat-value\">{formatStatValue(selectionStats.sum)}</span>\n                      </span>\n                      <span className=\"vpg-stat-divider\">|</span>\n                      <span className=\"vpg-stat\">\n                        <span className=\"vpg-stat-label\">Avg:</span>\n                        <span className=\"vpg-stat-value\">{formatStatValue(selectionStats.avg)}</span>\n                      </span>\n                    </>\n                  )}\n                </div>\n              )}\n            </div>\n          )}\n        </>\n      )}\n\n      {/* Watermark / Demo Banner */}\n      {showWatermark && canUsePivot && (\n        <div className={`vpg-watermark ${isDemo ? 'vpg-demo-mode' : ''}`}>\n          {isDemo\n            ? (\n                <>\n                  <span className=\"vpg-demo-badge\">DEMO</span>\n                  <span>Pro features unlocked for evaluation</span>\n                  <a\n                    href=\"https://tiny-pivot.com/#pricing\"\n                    target=\"_blank\"\n                    rel=\"noopener noreferrer\"\n                    className=\"vpg-get-pro\"\n                  >\n                    Get Pro License →\n                  </a>\n                </>\n              )\n            : (\n                <a href=\"https://tiny-pivot.com\" target=\"_blank\" rel=\"noopener noreferrer\">\n                  Powered by TinyPivot\n                </a>\n              )}\n        </div>\n      )}\n    </div>\n  )\n}\n"],"mappings":"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","names":["import_tinypivot_core","import_react","messages","copyToClipboard","formatCellValue","import_tinypivot_core","import_react","import_jsx_runtime","import_tinypivot_core","import_react","import_jsx_runtime","React","chartData","import_react","import_tinypivot_core","import_react","import_jsx_runtime","import_tinypivot_core","import_react","import_jsx_runtime","import_jsx_runtime","import_tinypivot_core","import_react","import_react_dom","import_tinypivot_core","import_react","import_tinypivot_core","import_react","coreExportToCSV","coreExportPivotToCSV","coreExportToXLSX","coreExportPivotToXLSX","coreCopyToClipboard","coreFormatSelection","import_tinypivot_core","import_react","coreConfigureLicenseSecret","coreIsPro","coreCanUsePivot","coreCanUseCharts","coreCanUseAIAnalyst","coreCanUseXlsxExport","coreShouldShowWatermark","import_tinypivot_core","import_react","next","import_tinypivot_core","import_react","import_react_dom","import_react","import_jsx_runtime","import_jsx_runtime","formatCellValue","import_tinypivot_core","import_react","import_jsx_runtime","React","import_tinypivot_core","import_react","import_jsx_runtime","import_jsx_runtime","coreFormatDate","xlsxFilename","coreFormatNumber"]}