@chartgpu/chartgpu 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +208 -0
- package/dist/ChartGPU.d.ts +146 -0
- package/dist/ChartGPU.d.ts.map +1 -0
- package/dist/components/createAnnotationConfigDialog.d.ts +24 -0
- package/dist/components/createAnnotationConfigDialog.d.ts.map +1 -0
- package/dist/components/createDataZoomSlider.d.ts +14 -0
- package/dist/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/components/createLegend.d.ts +9 -0
- package/dist/components/createLegend.d.ts.map +1 -0
- package/dist/components/createTextOverlay.d.ts +17 -0
- package/dist/components/createTextOverlay.d.ts.map +1 -0
- package/dist/components/createTooltip.d.ts +12 -0
- package/dist/components/createTooltip.d.ts.map +1 -0
- package/dist/components/formatTooltip.d.ts +19 -0
- package/dist/components/formatTooltip.d.ts.map +1 -0
- package/dist/config/OptionResolver.d.ts +137 -0
- package/dist/config/OptionResolver.d.ts.map +1 -0
- package/dist/config/defaults.d.ts +56 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/types.d.ts +553 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/core/GPUContext.d.ts +242 -0
- package/dist/core/GPUContext.d.ts.map +1 -0
- package/dist/core/RenderScheduler.d.ts +174 -0
- package/dist/core/RenderScheduler.d.ts.map +1 -0
- package/dist/core/createAnimationController.d.ts +15 -0
- package/dist/core/createAnimationController.d.ts.map +1 -0
- package/dist/core/createRenderCoordinator.d.ts +78 -0
- package/dist/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts +183 -0
- package/dist/core/renderCoordinator/animation/animationHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts +88 -0
- package/dist/core/renderCoordinator/annotations/processAnnotations.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts +91 -0
- package/dist/core/renderCoordinator/axis/axisLabelHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts +53 -0
- package/dist/core/renderCoordinator/axis/computeAxisTicks.d.ts.map +1 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts +66 -0
- package/dist/core/renderCoordinator/data/computeVisibleSlice.d.ts.map +1 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts +69 -0
- package/dist/core/renderCoordinator/gpu/textureManager.d.ts.map +1 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts +160 -0
- package/dist/core/renderCoordinator/interaction/interactionHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts +36 -0
- package/dist/core/renderCoordinator/render/renderAnnotationLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts +40 -0
- package/dist/core/renderCoordinator/render/renderAxisLabels.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts +70 -0
- package/dist/core/renderCoordinator/render/renderOverlays.d.ts.map +1 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts +146 -0
- package/dist/core/renderCoordinator/render/renderSeries.d.ts.map +1 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts +112 -0
- package/dist/core/renderCoordinator/renderers/rendererPool.d.ts.map +1 -0
- package/dist/core/renderCoordinator/types.d.ts +19 -0
- package/dist/core/renderCoordinator/types.d.ts.map +1 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts +104 -0
- package/dist/core/renderCoordinator/ui/tooltipLegendHelpers.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts +122 -0
- package/dist/core/renderCoordinator/utils/axisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts +69 -0
- package/dist/core/renderCoordinator/utils/boundsComputation.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts +52 -0
- package/dist/core/renderCoordinator/utils/canvasUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts +71 -0
- package/dist/core/renderCoordinator/utils/dataPointUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/index.d.ts +12 -0
- package/dist/core/renderCoordinator/utils/index.d.ts.map +1 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts +149 -0
- package/dist/core/renderCoordinator/utils/timeAxisUtils.d.ts.map +1 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts +129 -0
- package/dist/core/renderCoordinator/zoom/zoomHelpers.d.ts.map +1 -0
- package/dist/data/cartesianData.d.ts +72 -0
- package/dist/data/cartesianData.d.ts.map +1 -0
- package/dist/data/createDataStore.d.ts +27 -0
- package/dist/data/createDataStore.d.ts.map +1 -0
- package/dist/data/createStreamBuffer.d.ts +20 -0
- package/dist/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/data/lttbSample.d.ts +5 -0
- package/dist/data/lttbSample.d.ts.map +1 -0
- package/dist/data/ohlcSample.d.ts +21 -0
- package/dist/data/ohlcSample.d.ts.map +1 -0
- package/dist/data/packDataPoints.d.ts +65 -0
- package/dist/data/packDataPoints.d.ts.map +1 -0
- package/dist/data/sampleSeries.d.ts +20 -0
- package/dist/data/sampleSeries.d.ts.map +1 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js +772 -0
- package/dist/esm/ChartGPUWorkerController-B50J-8sx.js.map +1 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js +7150 -0
- package/dist/esm/OptionResolver-R_gJDRSD.js.map +1 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js +779 -0
- package/dist/esm/assets/worker-entry-Wg897auv.js.map +1 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js +1224 -0
- package/dist/esm/createChartInWorker-C4fEeJL8.js.map +1 -0
- package/dist/esm/index.js +795 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.cjs +1270 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10504 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts +115 -0
- package/dist/interaction/createAnnotationAuthoring.d.ts.map +1 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts +28 -0
- package/dist/interaction/createAnnotationDragHandler.d.ts.map +1 -0
- package/dist/interaction/createAnnotationHitTester.d.ts +32 -0
- package/dist/interaction/createAnnotationHitTester.d.ts.map +1 -0
- package/dist/interaction/createChartSync.d.ts +27 -0
- package/dist/interaction/createChartSync.d.ts.map +1 -0
- package/dist/interaction/createEventManager.d.ts +24 -0
- package/dist/interaction/createEventManager.d.ts.map +1 -0
- package/dist/interaction/createHoverState.d.ts +20 -0
- package/dist/interaction/createHoverState.d.ts.map +1 -0
- package/dist/interaction/createInsideZoom.d.ts +14 -0
- package/dist/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/interaction/createZoomState.d.ts +63 -0
- package/dist/interaction/createZoomState.d.ts.map +1 -0
- package/dist/interaction/findCandlestick.d.ts +41 -0
- package/dist/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/interaction/findNearestPoint.d.ts +61 -0
- package/dist/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/interaction/findPieSlice.d.ts +36 -0
- package/dist/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/interaction/findPointsAtX.d.ts +37 -0
- package/dist/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts +58 -0
- package/dist/renderers/createAnnotationMarkerRenderer.d.ts.map +1 -0
- package/dist/renderers/createAreaRenderer.d.ts +19 -0
- package/dist/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/renderers/createBarRenderer.d.ts +20 -0
- package/dist/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/renderers/createGridRenderer.d.ts +45 -0
- package/dist/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/renderers/createLineRenderer.d.ts +18 -0
- package/dist/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createPieRenderer.d.ts +18 -0
- package/dist/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts +81 -0
- package/dist/renderers/createReferenceLineRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/renderers/createScatterRenderer.d.ts +20 -0
- package/dist/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/renderers/rendererUtils.d.ts +100 -0
- package/dist/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/themes/darkTheme.d.ts +11 -0
- package/dist/themes/darkTheme.d.ts.map +1 -0
- package/dist/themes/index.d.ts +8 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/lightTheme.d.ts +11 -0
- package/dist/themes/lightTheme.d.ts.map +1 -0
- package/dist/themes/types.d.ts +14 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/types/ChartGPU.d.ts +99 -0
- package/dist/types/ChartGPU.d.ts.map +1 -0
- package/dist/types/components/createDataZoomSlider.d.ts +14 -0
- package/dist/types/components/createDataZoomSlider.d.ts.map +1 -0
- package/dist/types/components/createLegend.d.ts +9 -0
- package/dist/types/components/createLegend.d.ts.map +1 -0
- package/dist/types/components/createTextOverlay.d.ts +17 -0
- package/dist/types/components/createTextOverlay.d.ts.map +1 -0
- package/dist/types/components/createTooltip.d.ts +12 -0
- package/dist/types/components/createTooltip.d.ts.map +1 -0
- package/dist/types/components/formatTooltip.d.ts +19 -0
- package/dist/types/components/formatTooltip.d.ts.map +1 -0
- package/dist/types/config/OptionResolver.d.ts +134 -0
- package/dist/types/config/OptionResolver.d.ts.map +1 -0
- package/dist/types/config/defaults.d.ts +55 -0
- package/dist/types/config/defaults.d.ts.map +1 -0
- package/dist/types/config/types.d.ts +485 -0
- package/dist/types/config/types.d.ts.map +1 -0
- package/dist/types/core/GPUContext.d.ts +242 -0
- package/dist/types/core/GPUContext.d.ts.map +1 -0
- package/dist/types/core/RenderScheduler.d.ts +174 -0
- package/dist/types/core/RenderScheduler.d.ts.map +1 -0
- package/dist/types/core/createAnimationController.d.ts +15 -0
- package/dist/types/core/createAnimationController.d.ts.map +1 -0
- package/dist/types/core/createRenderCoordinator.d.ts +129 -0
- package/dist/types/core/createRenderCoordinator.d.ts.map +1 -0
- package/dist/types/data/createDataStore.d.ts +33 -0
- package/dist/types/data/createDataStore.d.ts.map +1 -0
- package/dist/types/data/createStreamBuffer.d.ts +20 -0
- package/dist/types/data/createStreamBuffer.d.ts.map +1 -0
- package/dist/types/data/lttbSample.d.ts +5 -0
- package/dist/types/data/lttbSample.d.ts.map +1 -0
- package/dist/types/data/ohlcSample.d.ts +21 -0
- package/dist/types/data/ohlcSample.d.ts.map +1 -0
- package/dist/types/data/packDataPoints.d.ts +79 -0
- package/dist/types/data/packDataPoints.d.ts.map +1 -0
- package/dist/types/data/sampleSeries.d.ts +3 -0
- package/dist/types/data/sampleSeries.d.ts.map +1 -0
- package/dist/types/index.d.ts +35 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/interaction/createChartSync.d.ts +12 -0
- package/dist/types/interaction/createChartSync.d.ts.map +1 -0
- package/dist/types/interaction/createEventManager.d.ts +24 -0
- package/dist/types/interaction/createEventManager.d.ts.map +1 -0
- package/dist/types/interaction/createHoverState.d.ts +20 -0
- package/dist/types/interaction/createHoverState.d.ts.map +1 -0
- package/dist/types/interaction/createInsideZoom.d.ts +14 -0
- package/dist/types/interaction/createInsideZoom.d.ts.map +1 -0
- package/dist/types/interaction/createZoomState.d.ts +63 -0
- package/dist/types/interaction/createZoomState.d.ts.map +1 -0
- package/dist/types/interaction/findCandlestick.d.ts +41 -0
- package/dist/types/interaction/findCandlestick.d.ts.map +1 -0
- package/dist/types/interaction/findNearestPoint.d.ts +61 -0
- package/dist/types/interaction/findNearestPoint.d.ts.map +1 -0
- package/dist/types/interaction/findPieSlice.d.ts +36 -0
- package/dist/types/interaction/findPieSlice.d.ts.map +1 -0
- package/dist/types/interaction/findPointsAtX.d.ts +37 -0
- package/dist/types/interaction/findPointsAtX.d.ts.map +1 -0
- package/dist/types/renderers/createAreaRenderer.d.ts +18 -0
- package/dist/types/renderers/createAreaRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createAxisRenderer.d.ts +19 -0
- package/dist/types/renderers/createAxisRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createBarRenderer.d.ts +20 -0
- package/dist/types/renderers/createBarRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts +19 -0
- package/dist/types/renderers/createCandlestickRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts +43 -0
- package/dist/types/renderers/createCrosshairRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createGridRenderer.d.ts +45 -0
- package/dist/types/renderers/createGridRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts +41 -0
- package/dist/types/renderers/createHighlightRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createLineRenderer.d.ts +18 -0
- package/dist/types/renderers/createLineRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createPieRenderer.d.ts +18 -0
- package/dist/types/renderers/createPieRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts +14 -0
- package/dist/types/renderers/createScatterDensityRenderer.d.ts.map +1 -0
- package/dist/types/renderers/createScatterRenderer.d.ts +19 -0
- package/dist/types/renderers/createScatterRenderer.d.ts.map +1 -0
- package/dist/types/renderers/rendererUtils.d.ts +100 -0
- package/dist/types/renderers/rendererUtils.d.ts.map +1 -0
- package/dist/types/themes/darkTheme.d.ts +11 -0
- package/dist/types/themes/darkTheme.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +8 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/dist/types/themes/lightTheme.d.ts +11 -0
- package/dist/types/themes/lightTheme.d.ts.map +1 -0
- package/dist/types/themes/types.d.ts +14 -0
- package/dist/types/themes/types.d.ts.map +1 -0
- package/dist/types/utils/axisLabelStyling.d.ts +27 -0
- package/dist/types/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/types/utils/checkWebGPU.d.ts +39 -0
- package/dist/types/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/types/utils/colors.d.ts +14 -0
- package/dist/types/utils/colors.d.ts.map +1 -0
- package/dist/types/utils/easing.d.ts +9 -0
- package/dist/types/utils/easing.d.ts.map +1 -0
- package/dist/types/utils/scales.d.ts +79 -0
- package/dist/types/utils/scales.d.ts.map +1 -0
- package/dist/utils/axisLabelStyling.d.ts +20 -0
- package/dist/utils/axisLabelStyling.d.ts.map +1 -0
- package/dist/utils/checkWebGPU.d.ts +39 -0
- package/dist/utils/checkWebGPU.d.ts.map +1 -0
- package/dist/utils/colors.d.ts +14 -0
- package/dist/utils/colors.d.ts.map +1 -0
- package/dist/utils/easing.d.ts +9 -0
- package/dist/utils/easing.d.ts.map +1 -0
- package/dist/utils/scales.d.ts +79 -0
- package/dist/utils/scales.d.ts.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/checkWebGPU.ts","../../src/ChartGPU.ts","../../src/interaction/createChartSync.ts","../../src/core/RenderScheduler.ts","../../src/index.ts"],"sourcesContent":["/**\n * WebGPU support detection and validation\n * \n * Provides utilities to check if WebGPU is available and usable in the current environment.\n * Results are memoized to avoid redundant checks.\n */\n\n/**\n * Result of WebGPU support check\n */\nexport interface WebGPUSupportResult {\n /** Whether WebGPU is supported and available */\n readonly supported: boolean;\n /** Optional reason explaining why WebGPU is not supported */\n readonly reason?: string;\n}\n\n// Memoized support check result\nlet cachedSupportCheck: Promise<WebGPUSupportResult> | null = null;\n\n/**\n * Checks if WebGPU is supported and available in the current environment.\n * \n * This function performs comprehensive checks:\n * - SSR-safe: validates that window and navigator are available\n * - Checks for navigator.gpu API presence\n * - Attempts to request a WebGPU adapter to verify actual support\n * - First tries high-performance adapter to match GPUContext behavior\n * - Falls back to default adapter if high-performance fails\n * \n * The result is memoized for performance, so multiple calls return the same promise.\n * \n * @returns Promise resolving to support check result with optional reason\n * \n * @example\n * ```typescript\n * const { supported, reason } = await checkWebGPUSupport();\n * if (!supported) {\n * console.error('WebGPU not available:', reason);\n * }\n * ```\n */\nexport async function checkWebGPUSupport(): Promise<WebGPUSupportResult> {\n // Return cached result if available\n if (cachedSupportCheck) {\n return cachedSupportCheck;\n }\n\n // Create and cache the promise\n cachedSupportCheck = (async (): Promise<WebGPUSupportResult> => {\n // SSR-safe checks: ensure we're in a browser environment\n if (typeof window === 'undefined') {\n return {\n supported: false,\n reason: 'Not running in a browser environment (window is undefined).',\n };\n }\n\n if (typeof navigator === 'undefined') {\n return {\n supported: false,\n reason: 'Navigator is not available in this environment.',\n };\n }\n\n // Check for navigator.gpu API\n if (!navigator.gpu) {\n return {\n supported: false,\n reason: 'WebGPU API (navigator.gpu) is not available. Your browser does not support WebGPU.',\n };\n }\n\n // Attempt to request an adapter to verify actual support\n try {\n // First attempt: high-performance adapter (aligns with GPUContext behavior)\n let adapter = await navigator.gpu.requestAdapter({\n powerPreference: 'high-performance',\n });\n\n // Second attempt: default adapter if high-performance is unavailable\n if (!adapter) {\n adapter = await navigator.gpu.requestAdapter();\n }\n\n // If both attempts fail, WebGPU is not usable\n if (!adapter) {\n return {\n supported: false,\n reason: 'No compatible WebGPU adapter found. This may occur if: (1) no GPU is available, (2) GPU drivers are outdated or incompatible, (3) running in a VM or headless environment, or (4) WebGPU is disabled in browser settings.',\n };\n }\n\n // Success: WebGPU is supported and an adapter is available\n return { supported: true };\n } catch (error) {\n // Adapter request threw an error\n let reason = 'Failed to request WebGPU adapter.';\n\n // Try to extract useful error information\n if (error instanceof DOMException) {\n reason = `Failed to request WebGPU adapter: ${error.name}`;\n if (error.message) {\n reason += ` - ${error.message}`;\n }\n } else if (error instanceof Error) {\n reason = `Failed to request WebGPU adapter: ${error.message}`;\n } else {\n reason = `Failed to request WebGPU adapter: ${String(error)}`;\n }\n\n return { supported: false, reason };\n }\n })();\n\n return cachedSupportCheck;\n}\n","import { GPUContext } from './core/GPUContext';\nimport { createRenderCoordinator } from './core/createRenderCoordinator';\nimport type { RenderCoordinator } from './core/createRenderCoordinator';\nimport { resolveOptionsForChart } from './config/OptionResolver';\nimport type { ResolvedCandlestickSeriesConfig, ResolvedChartGPUOptions, ResolvedPieSeriesConfig } from './config/OptionResolver';\nimport type { ChartGPUOptions, DataPoint, DataPointTuple, OHLCDataPoint, OHLCDataPointTuple, PieCenter, PieRadius } from './config/types';\nimport { createDataZoomSlider } from './components/createDataZoomSlider';\nimport type { DataZoomSlider } from './components/createDataZoomSlider';\nimport type { ZoomRange, ZoomState } from './interaction/createZoomState';\nimport { computeCandlestickBodyWidthRange, findCandlestick } from './interaction/findCandlestick';\nimport { findNearestPoint } from './interaction/findNearestPoint';\nimport type { NearestPointMatch } from './interaction/findNearestPoint';\nimport { findPieSlice } from './interaction/findPieSlice';\nimport { createLinearScale } from './utils/scales';\nimport type { LinearScale } from './utils/scales';\nimport { checkWebGPUSupport } from './utils/checkWebGPU';\nimport type {\n PerformanceMetrics,\n PerformanceCapabilities,\n ExactFPS,\n Milliseconds,\n Bytes,\n FrameTimeStats,\n GPUTimingStats,\n MemoryStats,\n FrameDropStats,\n} from './config/types';\n\n/**\n * Circular buffer size for frame timestamps (120 frames = 2 seconds at 60fps).\n */\nconst FRAME_BUFFER_SIZE = 120;\n\n/**\n * Expected frame time at 60fps (16.67ms).\n */\nconst EXPECTED_FRAME_TIME_MS = 1000 / 60;\n\n/**\n * Frame drop threshold multiplier (1.5x expected frame time).\n */\nconst FRAME_DROP_THRESHOLD_MULTIPLIER = 1.5;\n\nexport interface ChartGPUInstance {\n readonly options: Readonly<ChartGPUOptions>;\n readonly disposed: boolean;\n setOption(options: ChartGPUOptions): void;\n /**\n * Appends new points to a cartesian series at runtime (streaming).\n *\n * For candlestick series, pass `OHLCDataPoint[]`.\n * For other cartesian series (line, area, bar, scatter), pass `DataPoint[]`.\n * Pie series are non-cartesian and are not supported by streaming append.\n */\n appendData(seriesIndex: number, newPoints: DataPoint[] | OHLCDataPoint[]): void;\n resize(): void;\n dispose(): void;\n on(eventName: 'crosshairMove', callback: ChartGPUCrosshairMoveCallback): void;\n on(eventName: ChartGPUEventName, callback: ChartGPUEventCallback): void;\n off(eventName: 'crosshairMove', callback: ChartGPUCrosshairMoveCallback): void;\n off(eventName: ChartGPUEventName, callback: ChartGPUEventCallback): void;\n /**\n * Gets the current “interaction x” in domain units (or `null` when inactive).\n *\n * This is derived from pointer movement inside the plot grid and can also be driven\n * externally via `setInteractionX(...)` (e.g. chart sync).\n */\n getInteractionX(): number | null;\n /**\n * Drives the chart’s crosshair + tooltip from a domain-space x value.\n *\n * Passing `null` clears the interaction (hides crosshair/tooltip).\n */\n setInteractionX(x: number | null, source?: unknown): void;\n /**\n * Alias for `setInteractionX(...)` for chart sync semantics.\n */\n setCrosshairX(x: number | null, source?: unknown): void;\n /**\n * Subscribes to interaction x changes (domain units).\n *\n * Returns an unsubscribe function.\n */\n onInteractionXChange(callback: (x: number | null, source?: unknown) => void): () => void;\n /**\n * Returns the current percent-space zoom window (or `null` when zoom is disabled).\n */\n getZoomRange(): Readonly<{ start: number; end: number }> | null;\n /**\n * Sets the percent-space zoom window.\n *\n * No-op when zoom is disabled.\n */\n setZoomRange(start: number, end: number): void;\n /**\n * Gets the latest performance metrics.\n * Returns exact FPS and detailed frame statistics.\n * \n * @returns Current performance metrics, or null if not available\n */\n getPerformanceMetrics(): Readonly<PerformanceMetrics> | null;\n /**\n * Gets the performance capabilities of the current environment.\n * Indicates which performance features are supported.\n * \n * @returns Performance capabilities, or null if not initialized\n */\n getPerformanceCapabilities(): Readonly<PerformanceCapabilities> | null;\n /**\n * Registers a callback to be notified of performance metric updates.\n * Callback is invoked every frame with the latest metrics.\n * \n * @param callback - Function to call with updated metrics\n * @returns Unsubscribe function to remove the callback\n */\n onPerformanceUpdate(callback: (metrics: Readonly<PerformanceMetrics>) => void): () => void;\n}\n\n// Type-only alias so callsites can write `ChartGPU[]` for chart instances (while `ChartGPU` the value\n// remains the creation API exported from `src/index.ts`).\nexport type ChartGPU = ChartGPUInstance;\n\nexport type ChartGPUEventName = 'click' | 'mouseover' | 'mouseout' | 'crosshairMove';\n\nexport type ChartGPUEventPayload = Readonly<{\n readonly seriesIndex: number | null;\n readonly dataIndex: number | null;\n readonly value: readonly [number, number] | null;\n readonly seriesName: string | null;\n readonly event: PointerEvent;\n}>;\n\nexport type ChartGPUCrosshairMovePayload = Readonly<{\n readonly x: number | null;\n readonly source?: unknown;\n}>;\n\nexport type ChartGPUEventCallback = (payload: ChartGPUEventPayload) => void;\n\nexport type ChartGPUCrosshairMoveCallback = (payload: ChartGPUCrosshairMovePayload) => void;\n\ntype AnyChartGPUEventCallback = ChartGPUEventCallback | ChartGPUCrosshairMoveCallback;\n\ntype ListenerRegistry = Readonly<Record<ChartGPUEventName, Set<AnyChartGPUEventCallback>>>;\n\ntype TapCandidate = {\n readonly pointerId: number;\n readonly startClientX: number;\n readonly startClientY: number;\n readonly startTimeMs: number;\n};\n\nconst DEFAULT_TAP_MAX_DISTANCE_CSS_PX = 6;\nconst DEFAULT_TAP_MAX_TIME_MS = 500;\n\ntype Bounds = Readonly<{ xMin: number; xMax: number; yMin: number; yMax: number }>;\n\nconst isTupleDataPoint = (p: DataPoint): p is DataPointTuple => Array.isArray(p);\nconst isTupleOHLCDataPoint = (p: OHLCDataPoint): p is OHLCDataPointTuple => Array.isArray(p);\n\nconst getPointXY = (p: DataPoint): { readonly x: number; readonly y: number } => {\n if (isTupleDataPoint(p)) return { x: p[0], y: p[1] };\n return { x: p.x, y: p.y };\n};\n\nconst getOHLCTimestamp = (p: OHLCDataPoint): number => (isTupleOHLCDataPoint(p) ? p[0] : p.timestamp);\nconst getOHLCClose = (p: OHLCDataPoint): number => (isTupleOHLCDataPoint(p) ? p[2] : p.close);\n\nconst hasSliderDataZoom = (options: ChartGPUOptions): boolean => options.dataZoom?.some((z) => z?.type === 'slider') ?? false;\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\n\ntype InteractionScalesCache = {\n rectWidthCss: number;\n rectHeightCss: number;\n plotWidthCss: number;\n plotHeightCss: number;\n xDomainMin: number;\n xDomainMax: number;\n yDomainMin: number;\n yDomainMax: number;\n xScale: LinearScale;\n yScale: LinearScale;\n};\n\nconst computeRawBoundsFromData = (data: ReadonlyArray<DataPoint>): Bounds | null => {\n let xMin = Number.POSITIVE_INFINITY;\n let xMax = Number.NEGATIVE_INFINITY;\n let yMin = Number.POSITIVE_INFINITY;\n let yMax = Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < data.length; i++) {\n const { x, y } = getPointXY(data[i]!);\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (x < xMin) xMin = x;\n if (x > xMax) xMax = x;\n if (y < yMin) yMin = y;\n if (y > yMax) yMax = y;\n }\n\n if (!Number.isFinite(xMin) || !Number.isFinite(xMax) || !Number.isFinite(yMin) || !Number.isFinite(yMax)) {\n return null;\n }\n\n // Keep bounds usable for downstream scale derivation.\n if (xMin === xMax) xMax = xMin + 1;\n if (yMin === yMax) yMax = yMin + 1;\n\n return { xMin, xMax, yMin, yMax };\n};\n\nconst extendBoundsWithDataPoints = (bounds: Bounds | null, points: ReadonlyArray<DataPoint>): Bounds | null => {\n if (points.length === 0) return bounds;\n\n let b = bounds;\n if (!b) {\n const seeded = computeRawBoundsFromData(points);\n if (!seeded) return bounds;\n b = seeded;\n }\n\n let xMin = b.xMin;\n let xMax = b.xMax;\n let yMin = b.yMin;\n let yMax = b.yMax;\n\n for (let i = 0; i < points.length; i++) {\n const { x, y } = getPointXY(points[i]!);\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (x < xMin) xMin = x;\n if (x > xMax) xMax = x;\n if (y < yMin) yMin = y;\n if (y > yMax) yMax = y;\n }\n\n // Keep bounds usable for downstream scale derivation.\n if (xMin === xMax) xMax = xMin + 1;\n if (yMin === yMax) yMax = yMin + 1;\n\n return { xMin, xMax, yMin, yMax };\n};\n\nconst extendBoundsWithOHLCDataPoints = (bounds: Bounds | null, points: ReadonlyArray<OHLCDataPoint>): Bounds | null => {\n if (points.length === 0) return bounds;\n\n let xMin = bounds?.xMin ?? Number.POSITIVE_INFINITY;\n let xMax = bounds?.xMax ?? Number.NEGATIVE_INFINITY;\n let yMin = bounds?.yMin ?? Number.POSITIVE_INFINITY;\n let yMax = bounds?.yMax ?? Number.NEGATIVE_INFINITY;\n\n for (let i = 0; i < points.length; i++) {\n const p = points[i]!;\n const timestamp = getOHLCTimestamp(p);\n const low = isTupleOHLCDataPoint(p) ? p[3] : p.low;\n const high = isTupleOHLCDataPoint(p) ? p[4] : p.high;\n\n if (!Number.isFinite(timestamp) || !Number.isFinite(low) || !Number.isFinite(high)) continue;\n if (timestamp < xMin) xMin = timestamp;\n if (timestamp > xMax) xMax = timestamp;\n if (low < yMin) yMin = low;\n if (high > yMax) yMax = high;\n }\n\n if (!Number.isFinite(xMin) || !Number.isFinite(xMax) || !Number.isFinite(yMin) || !Number.isFinite(yMax)) {\n return bounds;\n }\n\n // Keep bounds usable for downstream scale derivation.\n if (xMin === xMax) xMax = xMin + 1;\n if (yMin === yMax) yMax = yMin + 1;\n\n return { xMin, xMax, yMin, yMax };\n};\n\nconst computeGlobalBounds = (\n series: ResolvedChartGPUOptions['series'],\n runtimeRawBoundsByIndex?: ReadonlyArray<Bounds | null> | null\n): Bounds => {\n let xMin = Number.POSITIVE_INFINITY;\n let xMax = Number.NEGATIVE_INFINITY;\n let yMin = Number.POSITIVE_INFINITY;\n let yMax = Number.NEGATIVE_INFINITY;\n\n for (let s = 0; s < series.length; s++) {\n const seriesConfig = series[s]!;\n // Pie series are non-cartesian; they don't participate in x/y bounds.\n if (seriesConfig.type === 'pie') continue;\n\n // Prefer the chart-owned runtime bounds (kept up to date by appendData()).\n const runtimeBoundsCandidate = runtimeRawBoundsByIndex?.[s] ?? null;\n if (runtimeBoundsCandidate) {\n const b = runtimeBoundsCandidate;\n if (\n Number.isFinite(b.xMin) &&\n Number.isFinite(b.xMax) &&\n Number.isFinite(b.yMin) &&\n Number.isFinite(b.yMax)\n ) {\n if (b.xMin < xMin) xMin = b.xMin;\n if (b.xMax > xMax) xMax = b.xMax;\n if (b.yMin < yMin) yMin = b.yMin;\n if (b.yMax > yMax) yMax = b.yMax;\n continue;\n }\n }\n\n // Prefer resolver-provided bounds when available (avoids O(n) scans on initial setOption()).\n // (Resolved series types include `rawBounds` for cartesian series; keep this defensive.)\n const rawBoundsCandidate = (seriesConfig as unknown as { rawBounds?: Bounds | null }).rawBounds ?? null;\n if (rawBoundsCandidate) {\n const b = rawBoundsCandidate;\n if (\n Number.isFinite(b.xMin) &&\n Number.isFinite(b.xMax) &&\n Number.isFinite(b.yMin) &&\n Number.isFinite(b.yMax)\n ) {\n if (b.xMin < xMin) xMin = b.xMin;\n if (b.xMax > xMax) xMax = b.xMax;\n if (b.yMin < yMin) yMin = b.yMin;\n if (b.yMax > yMax) yMax = b.yMax;\n continue;\n }\n }\n\n const data = seriesConfig.data as ReadonlyArray<DataPoint>;\n for (let i = 0; i < data.length; i++) {\n const { x, y } = getPointXY(data[i]!);\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n if (x < xMin) xMin = x;\n if (x > xMax) xMax = x;\n if (y < yMin) yMin = y;\n if (y > yMax) yMax = y;\n }\n }\n\n if (!Number.isFinite(xMin) || !Number.isFinite(xMax) || !Number.isFinite(yMin) || !Number.isFinite(yMax)) {\n return { xMin: 0, xMax: 1, yMin: 0, yMax: 1 };\n }\n\n if (xMin === xMax) xMax = xMin + 1;\n if (yMin === yMax) yMax = yMin + 1;\n\n return { xMin, xMax, yMin, yMax };\n};\n\nconst normalizeDomain = (\n minCandidate: number,\n maxCandidate: number\n): { readonly min: number; readonly max: number } => {\n let min = minCandidate;\n let max = maxCandidate;\n\n if (!Number.isFinite(min) || !Number.isFinite(max)) {\n min = 0;\n max = 1;\n }\n\n if (min === max) {\n max = min + 1;\n } else if (min > max) {\n const t = min;\n min = max;\n max = t;\n }\n\n return { min, max };\n};\n\ntype CartesianHitTestMatch = Readonly<{\n kind: 'cartesian';\n match: NearestPointMatch;\n}>;\n\ntype PieHitTestMatch = Readonly<{\n kind: 'pie';\n seriesIndex: number;\n dataIndex: number;\n sliceValue: number;\n}>;\n\ntype CandlestickHitTestMatch = Readonly<{\n kind: 'candlestick';\n seriesIndex: number;\n dataIndex: number;\n point: OHLCDataPoint;\n}>;\n\ntype HitTestMatch = CartesianHitTestMatch | PieHitTestMatch | CandlestickHitTestMatch;\n\nconst parseNumberOrPercent = (value: number | string, basis: number): number | null => {\n if (typeof value === 'number') return Number.isFinite(value) ? value : null;\n if (typeof value !== 'string') return null;\n\n const s = value.trim();\n if (s.length === 0) return null;\n\n if (s.endsWith('%')) {\n const pct = Number.parseFloat(s.slice(0, -1));\n if (!Number.isFinite(pct)) return null;\n return (pct / 100) * basis;\n }\n\n // Be permissive: allow numeric strings like \"120\" even though the public type primarily documents percent strings.\n const n = Number.parseFloat(s);\n return Number.isFinite(n) ? n : null;\n};\n\nconst resolvePieCenterPlotCss = (\n center: PieCenter | undefined,\n plotWidthCss: number,\n plotHeightCss: number\n): { readonly x: number; readonly y: number } => {\n const xRaw = center?.[0] ?? '50%';\n const yRaw = center?.[1] ?? '50%';\n\n const x = parseNumberOrPercent(xRaw, plotWidthCss);\n const y = parseNumberOrPercent(yRaw, plotHeightCss);\n\n return {\n x: Number.isFinite(x) ? x! : plotWidthCss * 0.5,\n y: Number.isFinite(y) ? y! : plotHeightCss * 0.5,\n };\n};\n\nconst isPieRadiusTuple = (radius: PieRadius): radius is readonly [inner: number | string, outer: number | string] =>\n Array.isArray(radius);\n\nconst resolvePieRadiiCss = (\n radius: PieRadius | undefined,\n maxRadiusCss: number\n): { readonly inner: number; readonly outer: number } => {\n // Default similar to common chart libs (mirrors `createPieRenderer.ts` and coordinator helpers).\n if (radius == null) return { inner: 0, outer: maxRadiusCss * 0.7 };\n\n if (isPieRadiusTuple(radius)) {\n const inner = parseNumberOrPercent(radius[0], maxRadiusCss);\n const outer = parseNumberOrPercent(radius[1], maxRadiusCss);\n const innerCss = Math.max(0, Number.isFinite(inner) ? inner! : 0);\n const outerCss = Math.max(innerCss, Number.isFinite(outer) ? outer! : maxRadiusCss * 0.7);\n return { inner: innerCss, outer: Math.min(maxRadiusCss, outerCss) };\n }\n\n const outer = parseNumberOrPercent(radius, maxRadiusCss);\n const outerCss = Math.max(0, Number.isFinite(outer) ? outer! : maxRadiusCss * 0.7);\n return { inner: 0, outer: Math.min(maxRadiusCss, outerCss) };\n};\n\nexport async function createChartGPU(\n container: HTMLElement,\n options: ChartGPUOptions\n): Promise<ChartGPUInstance> {\n // Check WebGPU support before creating canvas or any resources\n const supportCheck = await checkWebGPUSupport();\n if (!supportCheck.supported) {\n const reason = supportCheck.reason || 'Unknown reason';\n throw new Error(\n `ChartGPU: WebGPU is not available.\\n` +\n `Reason: ${reason}\\n` +\n `Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\\n` +\n `Resources:\\n` +\n ` - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\\n` +\n ` - Browser compatibility: https://caniuse.com/webgpu\\n` +\n ` - WebGPU specification: https://www.w3.org/TR/webgpu/\\n` +\n ` - Check your system: https://webgpureport.org/`\n );\n }\n\n const canvas = document.createElement('canvas');\n\n // Ensure the canvas participates in layout and can size via the container.\n canvas.style.display = 'block';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n\n // Append before awaiting so it appears immediately and has measurable size.\n container.appendChild(canvas);\n\n let disposed = false;\n let gpuContext: GPUContext | null = null;\n let coordinator: RenderCoordinator | null = null;\n let coordinatorTargetFormat: GPUTextureFormat | null = null;\n let unsubscribeCoordinatorInteractionXChange: (() => void) | null = null;\n\n let dataZoomSliderHost: HTMLDivElement | null = null;\n let dataZoomSlider: DataZoomSlider | null = null;\n\n let currentOptions: ChartGPUOptions = options;\n let resolvedOptions: ResolvedChartGPUOptions = resolveOptionsForChart(currentOptions);\n\n // Chart-owned runtime series store for hit-testing only (cartesian only).\n // - `runtimeRawDataByIndex[i]` is a mutable array used to reflect streaming appends.\n // - `runtimeRawBoundsByIndex[i]` is incrementally updated to keep scale/bounds derivation cheap.\n let runtimeRawDataByIndex: Array<DataPoint[] | OHLCDataPoint[]> = new Array(resolvedOptions.series.length).fill(null).map(() => []);\n let runtimeRawBoundsByIndex: Array<Bounds | null> = new Array(resolvedOptions.series.length).fill(null);\n let runtimeHitTestSeriesCache: ResolvedChartGPUOptions['series'] | null = null;\n let runtimeHitTestSeriesVersion = 0;\n\n const initRuntimeHitTestStoreFromResolvedOptions = (): void => {\n runtimeRawDataByIndex = new Array(resolvedOptions.series.length).fill(null).map(() => []);\n runtimeRawBoundsByIndex = new Array(resolvedOptions.series.length).fill(null);\n runtimeHitTestSeriesCache = null;\n runtimeHitTestSeriesVersion++;\n\n for (let i = 0; i < resolvedOptions.series.length; i++) {\n const s = resolvedOptions.series[i]!;\n if (s.type === 'pie') continue;\n\n if (s.type === 'candlestick') {\n const raw = ((s as unknown as { rawData?: ReadonlyArray<OHLCDataPoint> }).rawData ?? s.data) as ReadonlyArray<OHLCDataPoint>;\n runtimeRawDataByIndex[i] = raw.length === 0 ? [] : raw.slice();\n runtimeRawBoundsByIndex[i] = ((s as unknown as { rawBounds?: Bounds | null }).rawBounds ?? null);\n } else {\n const raw = ((s as unknown as { rawData?: ReadonlyArray<DataPoint> }).rawData ?? s.data) as ReadonlyArray<DataPoint>;\n runtimeRawDataByIndex[i] = raw.length === 0 ? [] : raw.slice();\n runtimeRawBoundsByIndex[i] = ((s as unknown as { rawBounds?: Bounds | null }).rawBounds ?? null) ?? computeRawBoundsFromData(raw);\n }\n }\n };\n\n const getRuntimeHitTestSeries = (): ResolvedChartGPUOptions['series'] => {\n if (runtimeHitTestSeriesCache) return runtimeHitTestSeriesCache;\n // Replace cartesian series `data` with chart-owned runtime data (pie series are unchanged).\n runtimeHitTestSeriesCache = resolvedOptions.series.map((s, i) => {\n if (s.type === 'pie') return s;\n if (s.type === 'candlestick') {\n return { ...s, data: runtimeRawDataByIndex[i] ?? (s.data as ReadonlyArray<OHLCDataPoint>) };\n }\n return { ...s, data: runtimeRawDataByIndex[i] ?? (s.data as ReadonlyArray<DataPoint>) };\n }) as ResolvedChartGPUOptions['series'];\n return runtimeHitTestSeriesCache;\n };\n\n initRuntimeHitTestStoreFromResolvedOptions();\n\n // Cache global bounds and interaction scales; avoids O(N) data scans per pointer move.\n let cachedGlobalBounds: Bounds = computeGlobalBounds(resolvedOptions.series, runtimeRawBoundsByIndex);\n let interactionScalesCache: InteractionScalesCache | null = null;\n\n const listeners: ListenerRegistry = {\n click: new Set<ChartGPUEventCallback>(),\n mouseover: new Set<ChartGPUEventCallback>(),\n mouseout: new Set<ChartGPUEventCallback>(),\n crosshairMove: new Set<ChartGPUCrosshairMoveCallback>(),\n };\n\n let tapCandidate: TapCandidate | null = null;\n let suppressNextLostPointerCaptureId: number | null = null;\n\n let hovered: HitTestMatch | null = null;\n\n // Prevent spamming console.warn for repeated misuse.\n const warnedPieAppendSeries = new Set<number>();\n\n let scheduledRaf: number | null = null;\n let lastConfigured: { width: number; height: number; format: GPUTextureFormat } | null = null;\n let isDirty = true;\n\n // Performance tracking state\n const frameTimestamps = new Float64Array(FRAME_BUFFER_SIZE);\n let frameTimestampIndex = 0;\n let frameTimestampCount = 0;\n let totalFrames = 0;\n let totalDroppedFrames = 0;\n let consecutiveDroppedFrames = 0;\n let lastDropTimestamp = 0;\n const startTime = performance.now();\n let lastFrameTime = 0;\n let lastCPUTime = 0;\n const performanceUpdateCallbacks = new Set<(metrics: Readonly<PerformanceMetrics>) => void>();\n\n const hasHoverListeners = (): boolean => listeners.mouseover.size > 0 || listeners.mouseout.size > 0;\n const hasClickListeners = (): boolean => listeners.click.size > 0;\n\n const cancelPendingFrame = (): void => {\n if (scheduledRaf === null) return;\n cancelAnimationFrame(scheduledRaf);\n scheduledRaf = null;\n };\n\n const requestRender = (): void => {\n if (disposed) return;\n isDirty = true;\n if (scheduledRaf !== null) return;\n\n scheduledRaf = requestAnimationFrame(() => {\n scheduledRaf = null;\n if (disposed) return;\n\n // Record frame timestamp BEFORE rendering\n const frameStartTime = performance.now();\n frameTimestamps[frameTimestampIndex] = frameStartTime;\n frameTimestampIndex = (frameTimestampIndex + 1) % FRAME_BUFFER_SIZE;\n if (frameTimestampCount < FRAME_BUFFER_SIZE) {\n frameTimestampCount++;\n }\n totalFrames++;\n\n // Frame drop detection (only after first frame)\n if (lastFrameTime > 0) {\n const deltaTime = frameStartTime - lastFrameTime;\n if (deltaTime > EXPECTED_FRAME_TIME_MS * FRAME_DROP_THRESHOLD_MULTIPLIER) {\n totalDroppedFrames++;\n consecutiveDroppedFrames++;\n lastDropTimestamp = frameStartTime;\n } else {\n // Reset consecutive counter on successful frame\n consecutiveDroppedFrames = 0;\n }\n }\n lastFrameTime = frameStartTime;\n\n // Requirement: on RAF tick, call resize() first.\n resizeInternal(false);\n \n if (isDirty) {\n isDirty = false;\n coordinator?.render();\n }\n\n const frameEndTime = performance.now();\n lastCPUTime = frameEndTime - frameStartTime;\n\n // Calculate and emit performance metrics\n const metrics = calculatePerformanceMetrics();\n for (const callback of performanceUpdateCallbacks) {\n try {\n callback(metrics);\n } catch (error) {\n console.error('Error in performance update callback:', error);\n }\n }\n });\n };\n\n const unbindCoordinatorInteractionXChange = (): void => {\n if (!unsubscribeCoordinatorInteractionXChange) return;\n try {\n unsubscribeCoordinatorInteractionXChange();\n } finally {\n unsubscribeCoordinatorInteractionXChange = null;\n }\n };\n\n const disposeDataZoomSlider = (): void => {\n dataZoomSlider?.dispose();\n dataZoomSlider = null;\n };\n\n const disposeDataZoomSliderHost = (): void => {\n dataZoomSliderHost?.remove();\n dataZoomSliderHost = null;\n };\n\n const disposeDataZoomUi = (): void => {\n disposeDataZoomSlider();\n disposeDataZoomSliderHost();\n };\n\n const DATA_ZOOM_SLIDER_HEIGHT_CSS_PX = 32;\n const DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX = 8;\n const DATA_ZOOM_SLIDER_RESERVE_CSS_PX = DATA_ZOOM_SLIDER_HEIGHT_CSS_PX + DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX;\n\n const ensureDataZoomSliderHost = (): HTMLDivElement => {\n if (dataZoomSliderHost) return dataZoomSliderHost;\n\n // Ensure the host's absolute positioning is anchored to the chart container.\n // If the container is already positioned, avoid overwriting user styles.\n try {\n const pos = window.getComputedStyle(container).position;\n if (pos === 'static') container.style.position = 'relative';\n } catch {\n // best-effort\n }\n\n const host = document.createElement('div');\n host.style.position = 'absolute';\n host.style.left = '0';\n host.style.right = '0';\n host.style.bottom = '0';\n host.style.height = `${DATA_ZOOM_SLIDER_RESERVE_CSS_PX}px`;\n host.style.paddingTop = `${DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX}px`;\n host.style.boxSizing = 'border-box';\n host.style.pointerEvents = 'auto';\n host.style.zIndex = '5';\n container.appendChild(host);\n dataZoomSliderHost = host;\n return host;\n };\n\n const computeZoomInOutAnchorRatio = (range: ZoomRange, center: number): number => {\n const span = range.end - range.start;\n if (!Number.isFinite(span) || span === 0) return 0.5;\n return clamp((center - range.start) / span, 0, 1);\n };\n\n const createCoordinatorZoomStateLike = (): ZoomState => {\n const getRange: ZoomState['getRange'] = () => coordinator?.getZoomRange() ?? { start: 0, end: 100 };\n const setRange: ZoomState['setRange'] = (start, end) => {\n coordinator?.setZoomRange(start, end);\n };\n const zoomIn: ZoomState['zoomIn'] = (center, factor) => {\n if (!Number.isFinite(center) || !Number.isFinite(factor) || factor <= 1) return;\n const r = coordinator?.getZoomRange();\n if (!r) return;\n const c = clamp(center, 0, 100);\n const ratio = computeZoomInOutAnchorRatio(r, c);\n const span = r.end - r.start;\n const nextSpan = span / factor;\n const nextStart = c - ratio * nextSpan;\n coordinator?.setZoomRange(nextStart, nextStart + nextSpan);\n };\n const zoomOut: ZoomState['zoomOut'] = (center, factor) => {\n if (!Number.isFinite(center) || !Number.isFinite(factor) || factor <= 1) return;\n const r = coordinator?.getZoomRange();\n if (!r) return;\n const c = clamp(center, 0, 100);\n const ratio = computeZoomInOutAnchorRatio(r, c);\n const span = r.end - r.start;\n const nextSpan = span * factor;\n const nextStart = c - ratio * nextSpan;\n coordinator?.setZoomRange(nextStart, nextStart + nextSpan);\n };\n const pan: ZoomState['pan'] = (delta) => {\n if (!Number.isFinite(delta)) return;\n const r = coordinator?.getZoomRange();\n if (!r) return;\n coordinator?.setZoomRange(r.start + delta, r.end + delta);\n };\n const onChange: ZoomState['onChange'] = (callback) => coordinator?.onZoomRangeChange(callback) ?? (() => {});\n\n return { getRange, setRange, zoomIn, zoomOut, pan, onChange };\n };\n\n const syncDataZoomUi = (): void => {\n const shouldHaveSlider = hasSliderDataZoom(currentOptions);\n if (!shouldHaveSlider) {\n disposeDataZoomUi();\n return;\n }\n\n // Slider requires a coordinator-backed zoom state.\n if (!coordinator) return;\n if (!coordinator.getZoomRange()) return;\n\n const host = ensureDataZoomSliderHost();\n if (!dataZoomSlider) {\n dataZoomSlider = createDataZoomSlider(host, createCoordinatorZoomStateLike(), {\n height: DATA_ZOOM_SLIDER_HEIGHT_CSS_PX,\n marginTop: 0, // host provides vertical spacing\n });\n }\n dataZoomSlider.update(resolvedOptions.theme);\n };\n\n const bindCoordinatorInteractionXChange = (): void => {\n unbindCoordinatorInteractionXChange();\n if (disposed) return;\n if (!coordinator) return;\n\n unsubscribeCoordinatorInteractionXChange = coordinator.onInteractionXChange((x, source) => {\n emit('crosshairMove', { x, source });\n });\n };\n\n const recreateCoordinator = (): void => {\n if (disposed) return;\n if (!gpuContext || !gpuContext.initialized) return;\n\n const prevZoomRange = coordinator?.getZoomRange() ?? null;\n\n unbindCoordinatorInteractionXChange();\n // Coordinator recreation invalidates zoom subscriptions; recreate the slider if present.\n disposeDataZoomSlider();\n coordinator?.dispose();\n coordinator = createRenderCoordinator(gpuContext, resolvedOptions, { onRequestRender: requestRender });\n coordinatorTargetFormat = gpuContext.preferredFormat;\n bindCoordinatorInteractionXChange();\n\n if (prevZoomRange) coordinator.setZoomRange(prevZoomRange.start, prevZoomRange.end);\n syncDataZoomUi();\n };\n\n const resizeInternal = (shouldRequestRenderAfterChanges: boolean): void => {\n if (disposed) return;\n\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n const maxDimension = gpuContext?.device?.limits.maxTextureDimension2D ?? 8192;\n const width = Math.min(maxDimension, Math.max(1, Math.round(rect.width * dpr)));\n const height = Math.min(maxDimension, Math.max(1, Math.round(rect.height * dpr)));\n\n const sizeChanged = canvas.width !== width || canvas.height !== height;\n if (sizeChanged) {\n canvas.width = width;\n canvas.height = height;\n }\n\n const device = gpuContext?.device;\n const canvasContext = gpuContext?.canvasContext;\n const preferredFormat = gpuContext?.preferredFormat;\n\n let didConfigure = false;\n if (device && canvasContext && preferredFormat) {\n const shouldConfigure =\n sizeChanged ||\n !lastConfigured ||\n lastConfigured.width !== canvas.width ||\n lastConfigured.height !== canvas.height ||\n lastConfigured.format !== preferredFormat;\n\n if (shouldConfigure) {\n canvasContext.configure({\n device,\n format: preferredFormat,\n alphaMode: 'opaque',\n });\n lastConfigured = { width: canvas.width, height: canvas.height, format: preferredFormat };\n didConfigure = true;\n\n // Requirement: if the target format changes, recreate coordinator/pipelines.\n if (coordinator && coordinatorTargetFormat !== preferredFormat) {\n recreateCoordinator();\n }\n }\n }\n\n if (shouldRequestRenderAfterChanges && (sizeChanged || didConfigure)) {\n // Requirement: resize() requests a render after size/config changes.\n requestRender();\n }\n };\n\n const resize = (): void => resizeInternal(true);\n\n const getNearestPointFromPointerEvent = (\n e: PointerEvent\n ): { readonly match: HitTestMatch | null; readonly isInGrid: boolean } => {\n const rect = canvas.getBoundingClientRect();\n if (!(rect.width > 0) || !(rect.height > 0)) return { match: null, isInGrid: false };\n\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n const plotLeftCss = resolvedOptions.grid.left;\n const plotTopCss = resolvedOptions.grid.top;\n const plotWidthCss = rect.width - resolvedOptions.grid.left - resolvedOptions.grid.right;\n const plotHeightCss = rect.height - resolvedOptions.grid.top - resolvedOptions.grid.bottom;\n if (!(plotWidthCss > 0) || !(plotHeightCss > 0)) return { match: null, isInGrid: false };\n\n const gridX = x - plotLeftCss;\n const gridY = y - plotTopCss;\n\n const isInGrid =\n gridX >= 0 &&\n gridX <= plotWidthCss &&\n gridY >= 0 &&\n gridY <= plotHeightCss;\n\n if (!isInGrid) return { match: null, isInGrid: false };\n\n const xMin = resolvedOptions.xAxis.min ?? cachedGlobalBounds.xMin;\n const xMax = resolvedOptions.xAxis.max ?? cachedGlobalBounds.xMax;\n const yMin = resolvedOptions.yAxis.min ?? cachedGlobalBounds.yMin;\n const yMax = resolvedOptions.yAxis.max ?? cachedGlobalBounds.yMax;\n\n // Make hit-testing zoom-aware (mirror coordinator percent->domain mapping).\n const baseXDomain = normalizeDomain(xMin, xMax);\n const zoomRange = coordinator?.getZoomRange() ?? null;\n const xDomain = (() => {\n if (!zoomRange) return baseXDomain;\n const span = baseXDomain.max - baseXDomain.min;\n if (!Number.isFinite(span) || span === 0) return baseXDomain;\n const start = zoomRange.start;\n const end = zoomRange.end;\n const zMin = baseXDomain.min + (start / 100) * span;\n const zMax = baseXDomain.min + (end / 100) * span;\n return normalizeDomain(zMin, zMax);\n })();\n const yDomain = normalizeDomain(yMin, yMax);\n\n // Cache hit-testing scales for identical (rect, grid, axis domain) inputs.\n const canReuseScales =\n interactionScalesCache !== null &&\n interactionScalesCache.rectWidthCss === rect.width &&\n interactionScalesCache.rectHeightCss === rect.height &&\n interactionScalesCache.plotWidthCss === plotWidthCss &&\n interactionScalesCache.plotHeightCss === plotHeightCss &&\n interactionScalesCache.xDomainMin === xDomain.min &&\n interactionScalesCache.xDomainMax === xDomain.max &&\n interactionScalesCache.yDomainMin === yDomain.min &&\n interactionScalesCache.yDomainMax === yDomain.max;\n\n if (!canReuseScales) {\n // IMPORTANT: grid-local CSS px ranges (0..plotWidth/Height), for interaction hit-testing.\n const xScale = createLinearScale().domain(xDomain.min, xDomain.max).range(0, plotWidthCss);\n const yScale = createLinearScale().domain(yDomain.min, yDomain.max).range(plotHeightCss, 0);\n interactionScalesCache = {\n rectWidthCss: rect.width,\n rectHeightCss: rect.height,\n plotWidthCss,\n plotHeightCss,\n xDomainMin: xDomain.min,\n xDomainMax: xDomain.max,\n yDomainMin: yDomain.min,\n yDomainMax: yDomain.max,\n xScale,\n yScale,\n };\n }\n\n // At this point, the cache must exist (either reused or created above).\n const scales = interactionScalesCache!;\n\n // Story 4.14: pie slice hit-testing (grid-local CSS px).\n const pieMatch = (() => {\n const maxRadiusCss = 0.5 * Math.min(plotWidthCss, plotHeightCss);\n if (!(maxRadiusCss > 0)) return null;\n\n // Prefer later series indices (deterministic and mirrors the coordinator tooltip logic).\n for (let i = resolvedOptions.series.length - 1; i >= 0; i--) {\n const s = resolvedOptions.series[i];\n if (s.type !== 'pie') continue;\n const pieSeries = s as ResolvedPieSeriesConfig;\n const center = resolvePieCenterPlotCss(pieSeries.center, plotWidthCss, plotHeightCss);\n const radii = resolvePieRadiiCss(pieSeries.radius, maxRadiusCss);\n const m = findPieSlice(gridX, gridY, { seriesIndex: i, series: pieSeries }, center, radii);\n if (!m) continue;\n\n const v = m.slice.value;\n return {\n kind: 'pie' as const,\n seriesIndex: m.seriesIndex,\n dataIndex: m.dataIndex,\n sliceValue: typeof v === 'number' && Number.isFinite(v) ? v : 0,\n };\n }\n return null;\n })();\n\n if (pieMatch) return { match: pieMatch, isInGrid: true };\n\n // Candlestick body hit-testing (grid-local CSS px), prefer later series indices.\n for (let i = resolvedOptions.series.length - 1; i >= 0; i--) {\n const s = resolvedOptions.series[i];\n if (s?.type !== 'candlestick') continue;\n\n const seriesCfg = s as ResolvedCandlestickSeriesConfig;\n const barWidthRange = computeCandlestickBodyWidthRange(seriesCfg, seriesCfg.data, scales.xScale, plotWidthCss);\n const m = findCandlestick([seriesCfg], gridX, gridY, scales.xScale, scales.yScale, barWidthRange);\n if (!m) continue;\n\n return {\n match: { kind: 'candlestick', seriesIndex: i, dataIndex: m.dataIndex, point: m.point },\n isInGrid: true,\n };\n }\n\n const cartesianMatch = findNearestPoint(\n getRuntimeHitTestSeries(),\n gridX,\n gridY,\n scales.xScale,\n scales.yScale\n );\n\n return {\n match: cartesianMatch ? ({ kind: 'cartesian', match: cartesianMatch } as const) : null,\n isInGrid: true,\n };\n };\n\n const calculateExactFPS = (): ExactFPS => {\n if (frameTimestampCount < 2) {\n return 0 as ExactFPS;\n }\n\n const startIndex = (frameTimestampIndex - frameTimestampCount + FRAME_BUFFER_SIZE) % FRAME_BUFFER_SIZE;\n \n let totalDelta = 0;\n for (let i = 1; i < frameTimestampCount; i++) {\n const prevIndex = (startIndex + i - 1) % FRAME_BUFFER_SIZE;\n const currIndex = (startIndex + i) % FRAME_BUFFER_SIZE;\n const delta = frameTimestamps[currIndex] - frameTimestamps[prevIndex];\n totalDelta += delta;\n }\n\n const avgFrameTime = totalDelta / (frameTimestampCount - 1);\n const fps = avgFrameTime > 0 ? 1000 / avgFrameTime : 0;\n \n return fps as ExactFPS;\n };\n\n const calculateFrameTimeStats = (): FrameTimeStats => {\n if (frameTimestampCount < 2) {\n return {\n min: 0 as Milliseconds,\n max: 0 as Milliseconds,\n avg: 0 as Milliseconds,\n p50: 0 as Milliseconds,\n p95: 0 as Milliseconds,\n p99: 0 as Milliseconds,\n };\n }\n\n const startIndex = (frameTimestampIndex - frameTimestampCount + FRAME_BUFFER_SIZE) % FRAME_BUFFER_SIZE;\n \n const deltas = new Array<number>(frameTimestampCount - 1);\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n let sum = 0;\n \n for (let i = 1; i < frameTimestampCount; i++) {\n const prevIndex = (startIndex + i - 1) % FRAME_BUFFER_SIZE;\n const currIndex = (startIndex + i) % FRAME_BUFFER_SIZE;\n const delta = frameTimestamps[currIndex] - frameTimestamps[prevIndex];\n deltas[i - 1] = delta;\n \n if (delta < min) min = delta;\n if (delta > max) max = delta;\n sum += delta;\n }\n\n const avg = sum / deltas.length;\n\n // Sort for percentile calculations\n deltas.sort((a, b) => a - b);\n\n const p50Index = Math.floor(deltas.length * 0.50);\n const p95Index = Math.floor(deltas.length * 0.95);\n const p99Index = Math.floor(deltas.length * 0.99);\n\n return {\n min: min as Milliseconds,\n max: max as Milliseconds,\n avg: avg as Milliseconds,\n p50: deltas[p50Index] as Milliseconds,\n p95: deltas[p95Index] as Milliseconds,\n p99: deltas[p99Index] as Milliseconds,\n };\n };\n\n const calculatePerformanceMetrics = (): PerformanceMetrics => {\n const fps = calculateExactFPS();\n const frameTimeStats = calculateFrameTimeStats();\n \n const gpuTiming: GPUTimingStats = {\n enabled: false, // GPU timing not yet implemented for main thread\n cpuTime: lastCPUTime as Milliseconds,\n gpuTime: 0 as Milliseconds,\n };\n \n const memory: MemoryStats = {\n used: 0 as Bytes,\n peak: 0 as Bytes,\n allocated: 0 as Bytes,\n };\n \n const frameDrops: FrameDropStats = {\n totalDrops: totalDroppedFrames,\n consecutiveDrops: consecutiveDroppedFrames,\n lastDropTimestamp: lastDropTimestamp as Milliseconds,\n };\n \n const elapsedTime = performance.now() - startTime;\n \n return {\n fps,\n frameTimeStats,\n gpuTiming,\n memory,\n frameDrops,\n totalFrames,\n elapsedTime: elapsedTime as Milliseconds,\n };\n };\n\n const buildPayload = (match: HitTestMatch | null, event: PointerEvent): ChartGPUEventPayload => {\n if (!match) {\n return { seriesIndex: null, dataIndex: null, value: null, seriesName: null, event };\n }\n\n const seriesIndex = match.kind === 'cartesian' ? match.match.seriesIndex : match.seriesIndex;\n const dataIndex = match.kind === 'cartesian' ? match.match.dataIndex : match.dataIndex;\n\n const series = resolvedOptions.series[seriesIndex];\n const seriesNameRaw = series?.name ?? null;\n const seriesName = seriesNameRaw && seriesNameRaw.trim().length > 0 ? seriesNameRaw : null;\n\n if (match.kind === 'pie') {\n // Pie series are non-cartesian; expose slice value in y so consumers can read a numeric.\n return {\n seriesIndex,\n dataIndex,\n value: [0, match.sliceValue],\n seriesName,\n event,\n };\n }\n\n if (match.kind === 'candlestick') {\n const timestamp = getOHLCTimestamp(match.point);\n const close = getOHLCClose(match.point);\n return {\n seriesIndex,\n dataIndex,\n value: [timestamp, close],\n seriesName,\n event,\n };\n }\n\n const { x, y } = getPointXY(match.match.point);\n return {\n seriesIndex,\n dataIndex,\n value: [x, y],\n seriesName,\n event,\n };\n };\n\n const emit = (\n eventName: ChartGPUEventName,\n payload: ChartGPUEventPayload | ChartGPUCrosshairMovePayload\n ): void => {\n if (disposed) return;\n for (const cb of listeners[eventName]) (cb as (p: typeof payload) => void)(payload);\n };\n\n const setHovered = (next: HitTestMatch | null, event: PointerEvent): void => {\n const prev = hovered;\n hovered = next;\n\n if (prev === null && next === null) return;\n\n if (prev === null && next !== null) {\n emit('mouseover', buildPayload(next, event));\n return;\n }\n\n if (prev !== null && next === null) {\n emit('mouseout', buildPayload(prev, event));\n return;\n }\n\n if (prev === null || next === null) return;\n\n const prevSeriesIndex = prev.kind === 'cartesian' ? prev.match.seriesIndex : prev.seriesIndex;\n const prevDataIndex = prev.kind === 'cartesian' ? prev.match.dataIndex : prev.dataIndex;\n const nextSeriesIndex = next.kind === 'cartesian' ? next.match.seriesIndex : next.seriesIndex;\n const nextDataIndex = next.kind === 'cartesian' ? next.match.dataIndex : next.dataIndex;\n\n const samePoint = prevSeriesIndex === nextSeriesIndex && prevDataIndex === nextDataIndex;\n if (samePoint) return;\n\n emit('mouseout', buildPayload(prev, event));\n emit('mouseover', buildPayload(next, event));\n };\n\n const clearTapCandidateIfMatches = (e: PointerEvent): void => {\n if (!tapCandidate) return;\n if (!e.isPrimary) return;\n if (e.pointerId !== tapCandidate.pointerId) return;\n tapCandidate = null;\n };\n\n const onPointerMove = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasHoverListeners()) return;\n const { match, isInGrid } = getNearestPointFromPointerEvent(e);\n if (!isInGrid) {\n setHovered(null, e);\n return;\n }\n setHovered(match, e);\n };\n\n const onPointerLeave = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasHoverListeners() && !tapCandidate) return;\n clearTapCandidateIfMatches(e);\n setHovered(null, e);\n };\n\n const onPointerCancel = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasHoverListeners() && !tapCandidate) return;\n clearTapCandidateIfMatches(e);\n setHovered(null, e);\n };\n\n const onLostPointerCapture = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasHoverListeners() && !tapCandidate && suppressNextLostPointerCaptureId !== e.pointerId) return;\n if (suppressNextLostPointerCaptureId === e.pointerId) {\n suppressNextLostPointerCaptureId = null;\n return;\n }\n clearTapCandidateIfMatches(e);\n setHovered(null, e);\n };\n\n const onPointerDown = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasClickListeners()) return;\n if (!e.isPrimary) return;\n\n // For mouse, only allow left button.\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n\n tapCandidate = {\n pointerId: e.pointerId,\n startClientX: e.clientX,\n startClientY: e.clientY,\n startTimeMs: e.timeStamp,\n };\n\n // Optional pointer capture improves reliability for touch/pen.\n try {\n canvas.setPointerCapture(e.pointerId);\n } catch {\n // best-effort\n }\n };\n\n const onPointerUp = (e: PointerEvent): void => {\n if (disposed) return;\n if (!hasClickListeners()) return;\n if (!e.isPrimary) return;\n if (!tapCandidate || e.pointerId !== tapCandidate.pointerId) return;\n\n const dt = e.timeStamp - tapCandidate.startTimeMs;\n const dx = e.clientX - tapCandidate.startClientX;\n const dy = e.clientY - tapCandidate.startClientY;\n const distSq = dx * dx + dy * dy;\n\n tapCandidate = null;\n\n // Release capture if we have it; suppress the resulting lostpointercapture.\n try {\n if (canvas.hasPointerCapture(e.pointerId)) {\n suppressNextLostPointerCaptureId = e.pointerId;\n canvas.releasePointerCapture(e.pointerId);\n }\n } catch {\n // best-effort\n }\n\n const maxDist = DEFAULT_TAP_MAX_DISTANCE_CSS_PX;\n const isTap = dt <= DEFAULT_TAP_MAX_TIME_MS && distSq <= maxDist * maxDist;\n if (!isTap) return;\n\n const { match } = getNearestPointFromPointerEvent(e);\n emit('click', buildPayload(match, e));\n };\n\n canvas.addEventListener('pointermove', onPointerMove, { passive: true });\n canvas.addEventListener('pointerleave', onPointerLeave, { passive: true });\n canvas.addEventListener('pointercancel', onPointerCancel, { passive: true });\n canvas.addEventListener('lostpointercapture', onLostPointerCapture, { passive: true });\n canvas.addEventListener('pointerdown', onPointerDown, { passive: true });\n canvas.addEventListener('pointerup', onPointerUp, { passive: true });\n\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n\n try {\n // Requirement: dispose order: cancel RAF, coordinator.dispose(), gpuContext.destroy(), remove canvas.\n cancelPendingFrame();\n disposeDataZoomUi();\n unbindCoordinatorInteractionXChange();\n coordinator?.dispose();\n coordinator = null;\n coordinatorTargetFormat = null;\n gpuContext?.destroy();\n } finally {\n tapCandidate = null;\n suppressNextLostPointerCaptureId = null;\n hovered = null;\n interactionScalesCache = null;\n\n canvas.removeEventListener('pointermove', onPointerMove);\n canvas.removeEventListener('pointerleave', onPointerLeave);\n canvas.removeEventListener('pointercancel', onPointerCancel);\n canvas.removeEventListener('lostpointercapture', onLostPointerCapture);\n canvas.removeEventListener('pointerdown', onPointerDown);\n canvas.removeEventListener('pointerup', onPointerUp);\n\n listeners.click.clear();\n listeners.mouseover.clear();\n listeners.mouseout.clear();\n listeners.crosshairMove.clear();\n\n gpuContext = null;\n canvas.remove();\n }\n };\n\n const instance: ChartGPUInstance = {\n get options() {\n return currentOptions;\n },\n get disposed() {\n return disposed;\n },\n setOption(nextOptions) {\n if (disposed) return;\n currentOptions = nextOptions;\n resolvedOptions = resolveOptionsForChart(nextOptions);\n coordinator?.setOptions(resolvedOptions);\n initRuntimeHitTestStoreFromResolvedOptions();\n cachedGlobalBounds = computeGlobalBounds(resolvedOptions.series, runtimeRawBoundsByIndex);\n interactionScalesCache = null;\n syncDataZoomUi();\n\n // Requirement: setOption triggers a render (and thus series parsing/extent/scales update inside render).\n requestRender();\n },\n appendData(seriesIndex, newPoints) {\n if (disposed) return;\n if (!Number.isFinite(seriesIndex)) return;\n if (seriesIndex < 0 || seriesIndex >= resolvedOptions.series.length) return;\n if (!newPoints || newPoints.length === 0) return;\n\n const s = resolvedOptions.series[seriesIndex]!;\n if (s.type === 'pie') {\n // Pie series are non-cartesian and currently not supported by streaming append.\n if (!warnedPieAppendSeries.has(seriesIndex)) {\n warnedPieAppendSeries.add(seriesIndex);\n console.warn(\n `ChartGPU.appendData(${seriesIndex}, ...): pie series are not supported by streaming append. Use setOption(...) to replace pie data.`\n );\n }\n return;\n }\n\n // Forward to coordinator (GPU buffers + render-state updates), then keep ChartGPU's\n // hit-testing runtime store in sync.\n coordinator?.appendData(seriesIndex, newPoints);\n\n if (s.type === 'candlestick') {\n // Handle candlestick series with OHLC data points.\n const owned = (runtimeRawDataByIndex[seriesIndex] ?? []) as OHLCDataPoint[];\n owned.push(...(newPoints as OHLCDataPoint[]));\n runtimeRawDataByIndex[seriesIndex] = owned;\n\n runtimeRawBoundsByIndex[seriesIndex] = extendBoundsWithOHLCDataPoints(\n runtimeRawBoundsByIndex[seriesIndex],\n newPoints as OHLCDataPoint[]\n );\n } else {\n // Handle other cartesian series (line, area, bar, scatter).\n const owned = (runtimeRawDataByIndex[seriesIndex] ?? []) as DataPoint[];\n owned.push(...(newPoints as DataPoint[]));\n runtimeRawDataByIndex[seriesIndex] = owned;\n\n runtimeRawBoundsByIndex[seriesIndex] = extendBoundsWithDataPoints(\n runtimeRawBoundsByIndex[seriesIndex],\n newPoints as DataPoint[]\n );\n }\n\n cachedGlobalBounds = computeGlobalBounds(resolvedOptions.series, runtimeRawBoundsByIndex);\n\n runtimeHitTestSeriesCache = null;\n runtimeHitTestSeriesVersion++;\n interactionScalesCache = null;\n\n // Ensure a render is scheduled (coalesced) like setOption does.\n requestRender();\n },\n resize,\n dispose,\n on(eventName, callback) {\n if (disposed) return;\n listeners[eventName].add(callback as AnyChartGPUEventCallback);\n },\n off(eventName, callback) {\n listeners[eventName].delete(callback as AnyChartGPUEventCallback);\n },\n getInteractionX() {\n if (disposed) return null;\n return coordinator?.getInteractionX() ?? null;\n },\n setInteractionX(x, source) {\n if (disposed) return;\n coordinator?.setInteractionX(x, source);\n },\n setCrosshairX(x, source) {\n if (disposed) return;\n coordinator?.setInteractionX(x, source);\n },\n onInteractionXChange(callback) {\n if (disposed) return () => {};\n return coordinator?.onInteractionXChange(callback) ?? (() => {});\n },\n getZoomRange() {\n if (disposed) return null;\n return coordinator?.getZoomRange() ?? null;\n },\n setZoomRange(start, end) {\n if (disposed) return;\n coordinator?.setZoomRange(start, end);\n },\n getPerformanceMetrics() {\n if (disposed) return null;\n return calculatePerformanceMetrics();\n },\n getPerformanceCapabilities() {\n if (disposed) return null;\n return {\n gpuTimingSupported: false, // Not yet implemented for main thread\n highResTimerSupported: typeof performance !== 'undefined' && typeof performance.now === 'function',\n performanceMetricsSupported: true,\n };\n },\n onPerformanceUpdate(callback) {\n if (disposed) return () => {};\n performanceUpdateCallbacks.add(callback);\n return () => {\n performanceUpdateCallbacks.delete(callback);\n };\n },\n };\n\n try {\n // Establish initial canvas backing size before WebGPU initialization.\n resizeInternal(false);\n\n // Try to create GPU context; wrap errors with detailed WebGPU unavailability message\n try {\n gpuContext = await GPUContext.create(canvas);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `ChartGPU: WebGPU is not available.\\n` +\n `Reason: ${errorMessage}\\n` +\n `Browser support: Chrome/Edge 113+, Safari 18+, Firefox not yet supported.\\n` +\n `Resources:\\n` +\n ` - MDN WebGPU API: https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API\\n` +\n ` - Browser compatibility: https://caniuse.com/webgpu\\n` +\n ` - WebGPU specification: https://www.w3.org/TR/webgpu/\\n` +\n ` - Check your system: https://webgpureport.org/`\n );\n }\n\n gpuContext.device?.lost.then((info) => {\n if (disposed) return;\n if (info.reason !== 'destroyed') {\n console.warn('WebGPU device lost:', info);\n }\n // Requirement: device loss routes through the same dispose path.\n dispose();\n });\n\n // Ensure canvas configuration matches the final measured size/format.\n resizeInternal(false);\n\n // Requirement: after GPUContext is initialized, create RenderCoordinator with resolved options.\n recreateCoordinator();\n\n // Mount data-zoom UI (if configured).\n syncDataZoomUi();\n\n // Kick an initial render.\n requestRender();\n return instance;\n } catch (error) {\n instance.dispose();\n throw error;\n }\n}\n\nexport const ChartGPU = {\n create: createChartGPU,\n};\n\n","import type { ChartGPU, ChartGPUCrosshairMovePayload } from '../ChartGPU';\n\nexport type DisconnectCharts = () => void;\n\n/**\n * Connects multiple charts so pointer movement in one chart drives crosshair/tooltip x\n * in the other charts (domain x sync). Returns a `disconnect()` function.\n *\n * Notes:\n * - Syncs interaction only (crosshair + tooltip x), not zoom/options.\n * - Uses a per-connection loop guard to prevent feedback.\n */\nexport function connectCharts(charts: ChartGPU[]): DisconnectCharts {\n const connectionToken = Symbol('ChartGPU.connectCharts');\n\n let disconnected = false;\n const unsubscribeFns: Array<() => void> = [];\n\n const broadcast = (sourceChart: ChartGPU, x: number | null): void => {\n for (const chart of charts) {\n if (chart === sourceChart) continue;\n if (chart.disposed) continue;\n chart.setCrosshairX(x, connectionToken);\n }\n };\n\n for (const chart of charts) {\n if (chart.disposed) continue;\n\n const onCrosshairMove = (payload: ChartGPUCrosshairMovePayload): void => {\n if (disconnected) return;\n if (payload.source === connectionToken) return;\n if (chart.disposed) return;\n broadcast(chart, payload.x);\n };\n\n chart.on('crosshairMove', onCrosshairMove);\n const unsub = (): void => chart.off('crosshairMove', onCrosshairMove);\n unsubscribeFns.push(unsub);\n }\n\n return () => {\n if (disconnected) return;\n disconnected = true;\n\n for (const unsub of unsubscribeFns) unsub();\n unsubscribeFns.length = 0;\n\n // Clear any “stuck” remote interactions.\n for (const chart of charts) {\n if (chart.disposed) continue;\n chart.setCrosshairX(null, connectionToken);\n }\n };\n}\n\n","/**\n * RenderScheduler - 60fps render loop management\n * \n * Manages a requestAnimationFrame-based render loop that runs at 60fps,\n * providing delta time tracking and frame scheduling control.\n * \n * This module provides both functional and class-based APIs for maximum flexibility.\n * The functional API is preferred for better type safety and immutability.\n */\n\n/**\n * Callback function type for render frames.\n * Receives delta time in milliseconds since the last frame.\n */\nexport type RenderCallback = (deltaTime: number) => void;\n\nimport type { ExactFPS, Milliseconds, FrameTimeStats, FrameDropStats } from '../config/types';\n\n/**\n * Represents the state of a render scheduler.\n * All properties are readonly to ensure immutability.\n */\nexport interface RenderSchedulerState {\n readonly id: symbol;\n readonly running: boolean;\n}\n\n/**\n * Circular buffer for frame timestamps (120 frames = 2 seconds at 60fps).\n * Uses Float64Array for high-precision timestamps from performance.now().\n */\nconst FRAME_BUFFER_SIZE = 120;\n\n/**\n * Expected frame time at 60fps (16.67ms).\n * Used for frame drop detection.\n */\nconst EXPECTED_FRAME_TIME_MS = 1000 / 60;\n\n/**\n * Frame drop threshold multiplier (1.5x expected frame time).\n * Frame times exceeding this are counted as drops.\n */\nconst FRAME_DROP_THRESHOLD_MULTIPLIER = 1.5;\n\n/**\n * Internal mutable state for the render scheduler.\n * Stored separately from the public state interface.\n */\ninterface RenderSchedulerInternalState {\n rafId: number | null;\n callback: RenderCallback | null;\n lastFrameTime: number;\n dirty: boolean;\n frameHandler: ((time: number) => void) | null;\n \n // Performance tracking\n frameTimestamps: Float64Array;\n frameTimestampIndex: number;\n frameTimestampCount: number;\n totalFrames: number;\n totalDroppedFrames: number;\n consecutiveDroppedFrames: number;\n lastDropTimestamp: number;\n startTime: number;\n}\n\n/**\n * Map to store internal mutable state for each scheduler state instance.\n * Keyed by the state's unique ID symbol.\n */\nconst internalStateMap = new Map<symbol, RenderSchedulerInternalState>();\n\n/**\n * Creates a new RenderScheduler state with initial values.\n * \n * @returns A new RenderSchedulerState instance\n */\nexport function createRenderScheduler(): RenderSchedulerState {\n const id = Symbol('RenderScheduler');\n const state: RenderSchedulerState = {\n id,\n running: false,\n };\n\n // Initialize internal mutable state\n internalStateMap.set(id, {\n rafId: null,\n callback: null,\n lastFrameTime: 0,\n dirty: false,\n frameHandler: null,\n \n // Performance tracking\n frameTimestamps: new Float64Array(FRAME_BUFFER_SIZE),\n frameTimestampIndex: 0,\n frameTimestampCount: 0,\n totalFrames: 0,\n totalDroppedFrames: 0,\n consecutiveDroppedFrames: 0,\n lastDropTimestamp: 0,\n startTime: performance.now(),\n });\n\n return state;\n}\n\n/**\n * Starts the render loop.\n * \n * Begins a requestAnimationFrame loop that calls the provided callback\n * every frame with the delta time in milliseconds since the last frame.\n * Returns a new state object with running set to true.\n * \n * @param state - The scheduler state to start\n * @param callback - Function to call each frame with delta time\n * @returns A new RenderSchedulerState with running set to true\n * @throws {Error} If callback is not provided\n * @throws {Error} If scheduler is already running\n * @throws {Error} If state is invalid\n */\nexport function startRenderScheduler(\n state: RenderSchedulerState,\n callback: RenderCallback\n): RenderSchedulerState {\n if (!callback) {\n throw new Error('Render callback is required');\n }\n\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n throw new Error('Invalid scheduler state. Use createRenderScheduler() to create a new state.');\n }\n\n if (state.running) {\n throw new Error('RenderScheduler is already running. Call stopRenderScheduler() before starting again.');\n }\n\n // Update internal state\n internalState.callback = callback;\n internalState.lastFrameTime = performance.now();\n internalState.dirty = true;\n\n const schedulerId = state.id;\n const frameHandler = (currentTime: number) => {\n // Look up internal state - may be null if scheduler was destroyed\n const currentInternalState = internalStateMap.get(schedulerId);\n if (!currentInternalState || !currentInternalState.callback) {\n // Scheduler was stopped or destroyed, exit gracefully\n return;\n }\n\n // Clear rafId at the start - we are no longer scheduled (now idle)\n currentInternalState.rafId = null;\n\n // Record frame timestamp in circular buffer BEFORE rendering\n // Use performance.now() exclusively for exact FPS measurement\n const timestamp = performance.now();\n currentInternalState.frameTimestamps[currentInternalState.frameTimestampIndex] = timestamp;\n currentInternalState.frameTimestampIndex = (currentInternalState.frameTimestampIndex + 1) % FRAME_BUFFER_SIZE;\n if (currentInternalState.frameTimestampCount < FRAME_BUFFER_SIZE) {\n currentInternalState.frameTimestampCount++;\n }\n currentInternalState.totalFrames++;\n\n // Calculate deltaTime with capping to prevent animation jumps after idle\n let deltaTime = currentTime - currentInternalState.lastFrameTime;\n // Cap deltaTime to 100ms (1/10th second) to prevent huge jumps\n const MAX_DELTA_TIME = 100;\n if (deltaTime > MAX_DELTA_TIME) {\n deltaTime = MAX_DELTA_TIME;\n }\n\n // Frame drop detection (only after first frame)\n if (currentInternalState.lastFrameTime > 0 && deltaTime > EXPECTED_FRAME_TIME_MS * FRAME_DROP_THRESHOLD_MULTIPLIER) {\n currentInternalState.totalDroppedFrames++;\n currentInternalState.consecutiveDroppedFrames++;\n currentInternalState.lastDropTimestamp = timestamp;\n } else if (currentInternalState.lastFrameTime > 0) {\n // Reset consecutive counter on successful frame\n currentInternalState.consecutiveDroppedFrames = 0;\n }\n\n currentInternalState.lastFrameTime = currentTime;\n\n // Only render if dirty\n if (currentInternalState.dirty) {\n // Reset dirty flag BEFORE calling callback\n currentInternalState.dirty = false;\n\n // Call the render callback with delta time\n currentInternalState.callback(deltaTime);\n\n // After callback returns, check if dirty was set again (callback-triggered renders for animations)\n // Re-check internal state in case it was destroyed during callback execution\n const nextInternalState = internalStateMap.get(schedulerId);\n if (nextInternalState && nextInternalState.callback && nextInternalState.dirty) {\n // Schedule another frame since callback requested a render\n nextInternalState.rafId = requestAnimationFrame(frameHandler);\n }\n }\n // If not dirty, we remain idle (rafId stays null, no frame scheduled)\n };\n\n // Store frameHandler in internal state so requestRender() can access it\n internalState.frameHandler = frameHandler;\n\n // Start the first frame\n internalState.rafId = requestAnimationFrame(frameHandler);\n\n // Return new state with running set to true\n return {\n id: state.id,\n running: true,\n };\n}\n\n/**\n * Stops the render loop.\n * \n * Cancels any pending requestAnimationFrame calls and stops the loop.\n * Returns a new state object with running set to false.\n * The scheduler can be restarted by calling startRenderScheduler() again.\n * \n * @param state - The scheduler state to stop\n * @returns A new RenderSchedulerState with running set to false\n * @throws {Error} If state is invalid\n */\nexport function stopRenderScheduler(state: RenderSchedulerState): RenderSchedulerState {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n throw new Error('Invalid scheduler state. Use createRenderScheduler() to create a new state.');\n }\n\n internalState.callback = null;\n internalState.frameHandler = null;\n\n if (internalState.rafId !== null) {\n cancelAnimationFrame(internalState.rafId);\n internalState.rafId = null;\n }\n\n // Return new state with running set to false\n return {\n id: state.id,\n running: false,\n };\n}\n\n/**\n * Marks the current frame as dirty and schedules a render if idle.\n * \n * This function implements render-on-demand: it schedules a frame when the\n * scheduler is idle. Multiple calls coalesce into a single frame.\n * \n * @param state - The scheduler state\n * @throws {Error} If state is invalid\n */\nexport function requestRender(state: RenderSchedulerState): void {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n throw new Error('Invalid scheduler state. Use createRenderScheduler() to create a new state.');\n }\n\n // Mark as dirty\n internalState.dirty = true;\n\n // If not running, return early\n if (internalState.callback === null) {\n return;\n }\n\n // If already scheduled, return early (coalescing)\n if (internalState.rafId !== null) {\n return;\n }\n\n // Idle - schedule a frame\n // Reset lastFrameTime to current time to ensure reasonable deltaTime after idle\n internalState.lastFrameTime = performance.now();\n \n // Schedule RAF using the stored frameHandler\n if (internalState.frameHandler) {\n internalState.rafId = requestAnimationFrame(internalState.frameHandler);\n }\n}\n\n/**\n * Calculates exact FPS from frame timestamp deltas.\n * \n * Uses the circular buffer of performance.now() timestamps to calculate\n * frame-perfect FPS. Algorithm:\n * 1. Sum all frame time deltas in the buffer\n * 2. Divide by (count - 1) to get average frame time\n * 3. Convert to FPS: 1000ms / avg_frame_time\n * \n * Returns 0 if insufficient data (< 2 frames).\n * \n * @param state - The scheduler state\n * @returns Exact FPS measurement\n */\nexport function getCurrentFPS(state: RenderSchedulerState): ExactFPS {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n return 0 as ExactFPS;\n }\n\n const count = internalState.frameTimestampCount;\n if (count < 2) {\n return 0 as ExactFPS; // Need at least 2 frames to calculate FPS\n }\n\n // Calculate sum of deltas between consecutive timestamps\n const timestamps = internalState.frameTimestamps;\n const bufferSize = FRAME_BUFFER_SIZE;\n const startIndex = (internalState.frameTimestampIndex - count + bufferSize) % bufferSize;\n \n let totalDelta = 0;\n for (let i = 1; i < count; i++) {\n const prevIndex = (startIndex + i - 1) % bufferSize;\n const currIndex = (startIndex + i) % bufferSize;\n const delta = timestamps[currIndex] - timestamps[prevIndex];\n totalDelta += delta;\n }\n\n const avgFrameTime = totalDelta / (count - 1);\n const fps = avgFrameTime > 0 ? 1000 / avgFrameTime : 0;\n \n return fps as ExactFPS;\n}\n\n/**\n * Calculates frame time statistics from the circular buffer.\n * \n * Computes min, max, avg, and percentiles (p50, p95, p99) for frame times.\n * Returns zero stats if insufficient data.\n * \n * @param state - The scheduler state\n * @returns Frame time statistics\n */\nexport function getFrameStats(state: RenderSchedulerState): FrameTimeStats {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n return {\n min: 0 as Milliseconds,\n max: 0 as Milliseconds,\n avg: 0 as Milliseconds,\n p50: 0 as Milliseconds,\n p95: 0 as Milliseconds,\n p99: 0 as Milliseconds,\n };\n }\n\n const count = internalState.frameTimestampCount;\n if (count < 2) {\n return {\n min: 0 as Milliseconds,\n max: 0 as Milliseconds,\n avg: 0 as Milliseconds,\n p50: 0 as Milliseconds,\n p95: 0 as Milliseconds,\n p99: 0 as Milliseconds,\n };\n }\n\n // Extract deltas from circular buffer\n const timestamps = internalState.frameTimestamps;\n const bufferSize = FRAME_BUFFER_SIZE;\n const startIndex = (internalState.frameTimestampIndex - count + bufferSize) % bufferSize;\n \n const deltas = new Array<number>(count - 1);\n let min = Number.POSITIVE_INFINITY;\n let max = Number.NEGATIVE_INFINITY;\n let sum = 0;\n \n for (let i = 1; i < count; i++) {\n const prevIndex = (startIndex + i - 1) % bufferSize;\n const currIndex = (startIndex + i) % bufferSize;\n const delta = timestamps[currIndex] - timestamps[prevIndex];\n deltas[i - 1] = delta;\n \n if (delta < min) min = delta;\n if (delta > max) max = delta;\n sum += delta;\n }\n\n const avg = sum / deltas.length;\n\n // Sort for percentile calculations\n deltas.sort((a, b) => a - b);\n\n const p50Index = Math.floor(deltas.length * 0.50);\n const p95Index = Math.floor(deltas.length * 0.95);\n const p99Index = Math.floor(deltas.length * 0.99);\n\n return {\n min: min as Milliseconds,\n max: max as Milliseconds,\n avg: avg as Milliseconds,\n p50: deltas[p50Index] as Milliseconds,\n p95: deltas[p95Index] as Milliseconds,\n p99: deltas[p99Index] as Milliseconds,\n };\n}\n\n/**\n * Gets frame drop statistics for the scheduler.\n * \n * @param state - The scheduler state\n * @returns Frame drop statistics\n */\nexport function getFrameDropStats(state: RenderSchedulerState): FrameDropStats {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n return {\n totalDrops: 0,\n consecutiveDrops: 0,\n lastDropTimestamp: 0 as Milliseconds,\n };\n }\n\n return {\n totalDrops: internalState.totalDroppedFrames,\n consecutiveDrops: internalState.consecutiveDroppedFrames,\n lastDropTimestamp: internalState.lastDropTimestamp as Milliseconds,\n };\n}\n\n/**\n * Gets total frames rendered and elapsed time.\n * \n * @param state - The scheduler state\n * @returns Object with totalFrames and elapsedTime\n */\nexport function getTotalFrames(state: RenderSchedulerState): { totalFrames: number; elapsedTime: Milliseconds } {\n const internalState = internalStateMap.get(state.id);\n if (!internalState) {\n return { totalFrames: 0, elapsedTime: 0 as Milliseconds };\n }\n\n const elapsedTime = performance.now() - internalState.startTime;\n return {\n totalFrames: internalState.totalFrames,\n elapsedTime: elapsedTime as Milliseconds,\n };\n}\n\n/**\n * Destroys the render scheduler and cleans up resources.\n * Stops the loop if running and removes internal state from the map.\n * Returns a new state object with reset values.\n * After calling this, the scheduler must be recreated before use.\n * \n * **Important:** Always call this function when done with a scheduler to prevent memory leaks.\n * The internal state map will retain entries until explicitly destroyed.\n * \n * @param state - The scheduler state to destroy\n * @returns A new RenderSchedulerState with reset values\n */\nexport function destroyRenderScheduler(state: RenderSchedulerState): RenderSchedulerState {\n const internalState = internalStateMap.get(state.id);\n \n if (internalState) {\n // Stop the loop if running\n if (internalState.rafId !== null) {\n cancelAnimationFrame(internalState.rafId);\n internalState.rafId = null;\n }\n \n // Clear callback and frameHandler to prevent further execution\n internalState.callback = null;\n internalState.frameHandler = null;\n \n // Clean up internal state from map to prevent memory leak\n internalStateMap.delete(state.id);\n }\n\n // Return new state with reset values\n return createRenderScheduler();\n}\n\n/**\n * Convenience function that creates a scheduler and starts it in one step.\n * \n * @param callback - Function to call each frame with delta time\n * @returns A RenderSchedulerState with the loop running\n * @throws {Error} If callback is not provided\n * \n * @example\n * ```typescript\n * const scheduler = createRenderSchedulerAsync((deltaTime) => {\n * renderFrame(deltaTime);\n * });\n * ```\n */\nexport function createRenderSchedulerAsync(callback: RenderCallback): RenderSchedulerState {\n const state = createRenderScheduler();\n return startRenderScheduler(state, callback);\n}\n\n/**\n * RenderScheduler class wrapper for backward compatibility.\n * \n * This class provides a class-based API that internally uses the functional implementation.\n * Use the functional API directly for better type safety and immutability.\n */\nexport class RenderScheduler {\n private _state: RenderSchedulerState;\n\n /**\n * Checks if the scheduler is currently running.\n */\n get running(): boolean {\n return this._state.running;\n }\n\n /**\n * Creates a new RenderScheduler instance.\n */\n constructor() {\n this._state = createRenderScheduler();\n }\n\n /**\n * Starts the render loop.\n * \n * @param callback - Function to call each frame with delta time\n * @throws {Error} If callback is not provided or scheduler already running\n */\n start(callback: RenderCallback): void {\n this._state = startRenderScheduler(this._state, callback);\n }\n\n /**\n * Stops the render loop.\n */\n stop(): void {\n this._state = stopRenderScheduler(this._state);\n }\n\n /**\n * Marks the current frame as dirty, indicating it needs to be rendered.\n */\n requestRender(): void {\n requestRender(this._state);\n }\n\n /**\n * Destroys the render scheduler and cleans up resources.\n * After calling destroy(), the scheduler must be recreated before use.\n */\n destroy(): void {\n this._state = destroyRenderScheduler(this._state);\n }\n}\n","/**\n * ChartGPU - A GPU-accelerated charting library built with WebGPU\n */\n\nexport const version = '1.0.0';\n\n// Chart API (Phase 1)\nimport { ChartGPU as ChartGPUNamespace } from './ChartGPU';\nimport { createChartInWorker } from './worker/createChartInWorker';\n\n// Export ChartGPU namespace with both create and createInWorker\nexport const ChartGPU = {\n ...ChartGPUNamespace,\n createInWorker: createChartInWorker,\n};\n\nexport { createChartGPU as createChart } from './ChartGPU';\nexport type { ChartGPUInstance } from './ChartGPU';\nexport type {\n ChartGPUEventName,\n ChartGPUEventPayload,\n ChartGPUCrosshairMovePayload,\n ChartGPUEventCallback,\n ChartGPUCrosshairMoveCallback,\n} from './ChartGPU';\nexport type {\n AreaStyleConfig,\n AnimationConfig,\n AxisConfig,\n AxisLabel,\n AxisType,\n BarItemStyleConfig,\n CandlestickItemStyleConfig,\n CandlestickSeriesConfig,\n CandlestickStyle,\n ChartGPUOptions,\n DataZoomConfig,\n DataPoint,\n GridConfig,\n LegendItem,\n LineStyleConfig,\n AreaSeriesConfig,\n LineSeriesConfig,\n BarSeriesConfig,\n NormalizedPointerEvent,\n PerformanceMetrics,\n PointerEventData,\n OHLCDataPoint,\n PieCenter,\n PieDataItem,\n PieItemStyleConfig,\n PieRadius,\n PieSeriesConfig,\n ScatterSeriesConfig,\n ScatterSymbol,\n ScatterPointTuple,\n SeriesConfig,\n SeriesSampling,\n SeriesType,\n TooltipConfig,\n TooltipData,\n TooltipParams,\n} from './config/types';\n\n// Options defaults + resolution\nexport { candlestickDefaults, defaultOptions } from './config/defaults';\nexport { OptionResolver, resolveOptions } from './config/OptionResolver';\nexport type {\n ResolvedCandlestickSeriesConfig,\n ResolvedChartGPUOptions,\n ResolvedAreaSeriesConfig,\n ResolvedAreaStyleConfig,\n ResolvedGridConfig,\n ResolvedLineSeriesConfig,\n ResolvedLineStyleConfig,\n ResolvedSeriesConfig,\n} from './config/OptionResolver';\n\n// Themes\nexport type { ThemeConfig } from './themes/types';\nexport { darkTheme, lightTheme, getTheme } from './themes';\nexport type { ThemeName } from './themes';\n\n// Scales - Pure utilities\nexport { createLinearScale, createCategoryScale } from './utils/scales';\nexport type { LinearScale, CategoryScale } from './utils/scales';\n\n// Data utilities - Zero-copy transfer helpers\nexport { packDataPoints, packOHLCDataPoints } from './data/packDataPoints';\n\n// Chart sync (interaction)\nexport { connectCharts } from './interaction/createChartSync';\n\n// Core exports - Functional API (preferred)\nexport type {\n GPUContextState,\n GPUContextOptions,\n SupportedCanvas,\n} from './core/GPUContext';\nexport {\n createGPUContext,\n createGPUContextAsync,\n initializeGPUContext,\n getCanvasTexture,\n clearScreen,\n destroyGPUContext,\n} from './core/GPUContext';\n\n// Class-based API (for backward compatibility)\nexport { GPUContext } from './core/GPUContext';\n\n// Render scheduler - Functional API (preferred)\nexport type { RenderSchedulerState, RenderCallback } from './core/RenderScheduler';\nexport {\n createRenderScheduler,\n createRenderSchedulerAsync,\n startRenderScheduler,\n stopRenderScheduler,\n requestRender,\n destroyRenderScheduler,\n} from './core/RenderScheduler';\n\n// Render coordinator types\nexport type { RenderCoordinatorCallbacks } from './core/createRenderCoordinator';\n\n// Class-based API (for backward compatibility)\nexport { RenderScheduler } from './core/RenderScheduler';\n\n// Worker API - Main thread proxy and types\nexport { ChartGPUWorkerProxy } from './worker/ChartGPUWorkerProxy';\nexport { ChartGPUWorkerError, XY_STRIDE, OHLC_STRIDE } from './worker/types';\nexport type { WorkerConfig, PendingRequest, StrideBytes } from './worker/types';\n\n// Worker protocol types (Main ↔ Worker communication)\nexport type {\n WorkerInboundMessage,\n WorkerOutboundMessage,\n InitMessage,\n SetOptionMessage,\n AppendDataMessage,\n AppendDataBatchMessage,\n ResizeMessage,\n ForwardPointerEventMessage,\n SetZoomRangeMessage,\n SetInteractionXMessage,\n SetAnimationMessage,\n DisposeMessage,\n ReadyMessage,\n RenderedMessage,\n TooltipUpdateMessage,\n LegendUpdateMessage,\n AxisLabelsUpdateMessage,\n WorkerEventPayload,\n HoverChangeMessage,\n ClickMessage,\n CrosshairMoveMessage,\n ZoomChangeMessage,\n DeviceLostMessage,\n DisposedMessage,\n ErrorMessage,\n} from './worker/protocol';\n"],"names":["cachedSupportCheck","checkWebGPUSupport","adapter","error","reason","FRAME_BUFFER_SIZE","EXPECTED_FRAME_TIME_MS","FRAME_DROP_THRESHOLD_MULTIPLIER","DEFAULT_TAP_MAX_DISTANCE_CSS_PX","DEFAULT_TAP_MAX_TIME_MS","isTupleDataPoint","p","isTupleOHLCDataPoint","getPointXY","getOHLCTimestamp","getOHLCClose","hasSliderDataZoom","options","_a","z","clamp","v","lo","hi","computeRawBoundsFromData","data","xMin","xMax","yMin","yMax","i","x","y","extendBoundsWithDataPoints","bounds","points","b","seeded","extendBoundsWithOHLCDataPoints","timestamp","low","high","computeGlobalBounds","series","runtimeRawBoundsByIndex","s","seriesConfig","runtimeBoundsCandidate","rawBoundsCandidate","normalizeDomain","minCandidate","maxCandidate","min","max","t","parseNumberOrPercent","value","basis","pct","n","resolvePieCenterPlotCss","center","plotWidthCss","plotHeightCss","xRaw","yRaw","isPieRadiusTuple","radius","resolvePieRadiiCss","maxRadiusCss","inner","outer","innerCss","outerCss","createChartGPU","container","supportCheck","canvas","disposed","gpuContext","coordinator","coordinatorTargetFormat","unsubscribeCoordinatorInteractionXChange","dataZoomSliderHost","dataZoomSlider","currentOptions","resolvedOptions","resolveOptionsForChart","runtimeRawDataByIndex","runtimeHitTestSeriesCache","initRuntimeHitTestStoreFromResolvedOptions","raw","getRuntimeHitTestSeries","cachedGlobalBounds","interactionScalesCache","listeners","tapCandidate","suppressNextLostPointerCaptureId","hovered","warnedPieAppendSeries","scheduledRaf","lastConfigured","isDirty","frameTimestamps","frameTimestampIndex","frameTimestampCount","totalFrames","totalDroppedFrames","consecutiveDroppedFrames","lastDropTimestamp","startTime","lastFrameTime","lastCPUTime","performanceUpdateCallbacks","hasHoverListeners","hasClickListeners","cancelPendingFrame","requestRender","frameStartTime","resizeInternal","metrics","calculatePerformanceMetrics","callback","unbindCoordinatorInteractionXChange","disposeDataZoomSlider","disposeDataZoomSliderHost","disposeDataZoomUi","DATA_ZOOM_SLIDER_HEIGHT_CSS_PX","DATA_ZOOM_SLIDER_MARGIN_TOP_CSS_PX","DATA_ZOOM_SLIDER_RESERVE_CSS_PX","ensureDataZoomSliderHost","host","computeZoomInOutAnchorRatio","range","span","createCoordinatorZoomStateLike","start","end","factor","r","c","ratio","nextSpan","nextStart","delta","syncDataZoomUi","createDataZoomSlider","bindCoordinatorInteractionXChange","source","emit","recreateCoordinator","prevZoomRange","createRenderCoordinator","shouldRequestRenderAfterChanges","rect","dpr","maxDimension","width","height","sizeChanged","device","canvasContext","preferredFormat","didConfigure","resize","getNearestPointFromPointerEvent","plotLeftCss","plotTopCss","gridX","gridY","baseXDomain","zoomRange","xDomain","zMin","zMax","yDomain","xScale","createLinearScale","yScale","scales","pieMatch","pieSeries","radii","m","findPieSlice","seriesCfg","barWidthRange","computeCandlestickBodyWidthRange","findCandlestick","cartesianMatch","findNearestPoint","calculateExactFPS","startIndex","totalDelta","prevIndex","currIndex","avgFrameTime","calculateFrameTimeStats","deltas","sum","avg","a","p50Index","p95Index","p99Index","fps","frameTimeStats","gpuTiming","memory","frameDrops","elapsedTime","buildPayload","match","event","seriesIndex","dataIndex","seriesNameRaw","seriesName","close","eventName","payload","cb","setHovered","next","prev","prevSeriesIndex","prevDataIndex","nextSeriesIndex","nextDataIndex","clearTapCandidateIfMatches","onPointerMove","isInGrid","onPointerLeave","onPointerCancel","onLostPointerCapture","onPointerDown","onPointerUp","dt","dx","dy","distSq","maxDist","dispose","instance","nextOptions","newPoints","owned","GPUContext","errorMessage","info","ChartGPU","connectCharts","charts","connectionToken","disconnected","unsubscribeFns","broadcast","sourceChart","chart","onCrosshairMove","unsub","internalStateMap","createRenderScheduler","id","state","startRenderScheduler","internalState","schedulerId","frameHandler","currentTime","currentInternalState","deltaTime","MAX_DELTA_TIME","nextInternalState","stopRenderScheduler","destroyRenderScheduler","createRenderSchedulerAsync","RenderScheduler","version","ChartGPUNamespace","createChartInWorker"],"mappings":"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"}
|