velo-plot 2.0.0 → 3.0.0
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/README.md +15 -8
- package/dist/{ChartCore-BhQ4j7f5.js → ChartCore-BpzRvN4Y.js} +998 -855
- package/dist/ChartCore-BpzRvN4Y.js.map +1 -0
- package/dist/a11y-Bw6urYpr.js +105 -0
- package/dist/a11y-Bw6urYpr.js.map +1 -0
- package/dist/angular/hooks-entry.d.ts +1 -0
- package/dist/angular/hooks.d.ts +26 -0
- package/dist/angular/index.d.ts +8 -0
- package/dist/angular/velo-plot.component.d.ts +46 -0
- package/dist/angular-hooks.d.ts +1 -0
- package/dist/angular-hooks.js +9 -0
- package/dist/angular-hooks.js.map +1 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +166 -0
- package/dist/angular.js.map +1 -0
- package/dist/assets/indicator.worker-bv0zC4EX.js.map +1 -1
- package/dist/astro/StackedPlot.astro +19 -0
- package/dist/astro/VeloPlot.astro +23 -0
- package/dist/{axisFormat-SPX-CD5s.js → axisFormat-CzumxpCL.js} +3 -3
- package/dist/axisFormat-CzumxpCL.js.map +1 -0
- package/dist/bindings/shared/a11y.d.ts +26 -0
- package/dist/bindings/shared/chartLifecycle.d.ts +16 -0
- package/dist/bindings/shared/chartSyncBridge.d.ts +8 -0
- package/dist/bindings/shared/dimensions.d.ts +1 -0
- package/dist/bindings/shared/index.d.ts +9 -0
- package/dist/bindings/shared/indicatorBridge.d.ts +11 -0
- package/dist/bindings/shared/optionsSync.d.ts +7 -0
- package/dist/bindings/shared/seriesDiff.d.ts +8 -0
- package/dist/bindings/shared/stackedSync.d.ts +9 -0
- package/dist/bindings/shared/types.d.ts +46 -0
- package/dist/bindings/test-utils/index.d.ts +35 -0
- package/dist/bindings/test-utils/mockLifecycle.d.ts +120 -0
- package/dist/bindings/test-utils/vitestSveltePlugin.d.ts +3 -0
- package/dist/chartSyncBridge-DbWrwtyP.js +57 -0
- package/dist/chartSyncBridge-DbWrwtyP.js.map +1 -0
- package/dist/core/Chart.d.ts +1 -1
- package/dist/core/InteractionManager.d.ts +7 -1
- package/dist/core/OverlayRenderer.d.ts +5 -0
- package/dist/core/annotations/types.d.ts +1 -1
- package/dist/core/chart/ChartAxisManager.d.ts +2 -0
- package/dist/core/chart/ChartCore.d.ts +17 -2
- package/dist/core/chart/ChartPluginBridge.d.ts +1 -0
- package/dist/core/chart/ChartRenderLoop.d.ts +2 -0
- package/dist/core/chart/ChartStateManager.d.ts +2 -0
- package/dist/core/chart/types.d.ts +6 -1
- package/dist/core/clipboard/index.d.ts +1 -1
- package/dist/core/debug/index.d.ts +1 -1
- package/dist/core/keybindings/index.d.ts +1 -1
- package/dist/core/loading/index.d.ts +1 -1
- package/dist/core/locale/index.d.ts +1 -1
- package/dist/core/stacked/paneResize.d.ts +3 -0
- package/dist/core/stacked/types.d.ts +10 -0
- package/dist/core/sync/index.d.ts +0 -1
- package/dist/core/theme-editor/index.d.ts +1 -1
- package/dist/createStackedChart-Dm-YqUT7.js +756 -0
- package/dist/createStackedChart-Dm-YqUT7.js.map +1 -0
- package/dist/examples/PluginDemonstration.d.ts +1 -1
- package/dist/gpuRenderer-BpaMYz-k.js.map +1 -1
- package/dist/hooks-CYPCxoZx.js +69 -0
- package/dist/hooks-CYPCxoZx.js.map +1 -0
- package/dist/{index-D7dTq6VB.js → index-0InEyj0q.js} +130 -134
- package/dist/index-0InEyj0q.js.map +1 -0
- package/dist/index-BMiZoKmm.js.map +1 -1
- package/dist/{index-DoYxf1cV.js → index-CWxIHdwX.js} +38 -98
- package/dist/index-CWxIHdwX.js.map +1 -0
- package/dist/{index-CUGS98p4.js → index-CaXWSOTk.js} +3 -6
- package/dist/index-CaXWSOTk.js.map +1 -0
- package/dist/index-Dag88bW4.js.map +1 -1
- package/dist/index-qhscKTDy.js.map +1 -1
- package/dist/{index-CWipqOLP.js → index-qunX30Xu.js} +2 -2
- package/dist/index-qunX30Xu.js.map +1 -0
- package/dist/index-x4stH3jD.js.map +1 -1
- package/dist/{index.core-fpZ1dYN0.js → index.core-BmZe2jRQ.js} +30 -29
- package/dist/index.core-BmZe2jRQ.js.map +1 -0
- package/dist/index.core.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/indicators--eJGmVox.js.map +1 -1
- package/dist/{mockDatafeed-Cdg5hKEo.js → mockDatafeed-DHIDPcpX.js} +150 -146
- package/dist/mockDatafeed-DHIDPcpX.js.map +1 -0
- package/dist/optionsSync-QUiN4Inw.js +119 -0
- package/dist/optionsSync-QUiN4Inw.js.map +1 -0
- package/dist/plugins/3d/index.d.ts +2 -2
- package/dist/plugins/3d.d.ts +2 -2
- package/dist/plugins/3d.js.map +1 -1
- package/dist/plugins/analysis/contours.d.ts +31 -0
- package/dist/plugins/analysis/index.d.ts +1 -1
- package/dist/plugins/analysis/indicators.d.ts +1 -1
- package/dist/plugins/analysis.d.ts +2 -2
- package/dist/plugins/analysis.js +495 -408
- package/dist/plugins/analysis.js.map +1 -1
- package/dist/plugins/annotations/index.d.ts +1 -1
- package/dist/plugins/annotations.d.ts +2 -2
- package/dist/plugins/annotations.js.map +1 -1
- package/dist/plugins/anomaly-detection.js +1 -1
- package/dist/plugins/anomaly-detection.js.map +1 -1
- package/dist/plugins/broken-axis.d.ts +2 -2
- package/dist/plugins/broken-axis.js +170 -181
- package/dist/plugins/broken-axis.js.map +1 -1
- package/dist/plugins/builtins/crosshair/CrosshairPlugin.d.ts +1 -1
- package/dist/plugins/builtins/index.d.ts +1 -1
- package/dist/plugins/caching.d.ts +2 -2
- package/dist/plugins/clipboard/index.d.ts +2 -2
- package/dist/plugins/clipboard.d.ts +2 -2
- package/dist/plugins/clipboard.js.map +1 -1
- package/dist/plugins/context-menu/index.d.ts +1 -1
- package/dist/plugins/context-menu.d.ts +2 -2
- package/dist/plugins/context-menu.js +1 -1
- package/dist/plugins/context-menu.js.map +1 -1
- package/dist/plugins/data-export/index.d.ts +1 -1
- package/dist/plugins/data-export.d.ts +2 -2
- package/dist/plugins/data-export.js +2 -2
- package/dist/plugins/data-export.js.map +1 -1
- package/dist/plugins/data-transform.d.ts +2 -2
- package/dist/plugins/data-transform.js +19 -19
- package/dist/plugins/data-transform.js.map +1 -1
- package/dist/plugins/debug/index.d.ts +2 -2
- package/dist/plugins/debug.d.ts +2 -2
- package/dist/plugins/debug.js +2 -2
- package/dist/plugins/debug.js.map +1 -1
- package/dist/plugins/forecasting/algorithms.d.ts +7 -2
- package/dist/plugins/forecasting/index.d.ts +1 -1
- package/dist/plugins/forecasting/types.d.ts +13 -3
- package/dist/plugins/forecasting.js +355 -175
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/gpu/index.d.ts +2 -2
- package/dist/plugins/gpu.d.ts +2 -2
- package/dist/plugins/gpu.js.map +1 -1
- package/dist/plugins/i18n/index.d.ts +2 -2
- package/dist/plugins/i18n.d.ts +2 -2
- package/dist/plugins/i18n.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/keyboard.d.ts +2 -2
- package/dist/plugins/keyboard.js +65 -5
- package/dist/plugins/keyboard.js.map +1 -1
- package/dist/plugins/latex/symbols.d.ts +50 -0
- package/dist/plugins/latex/types.d.ts +13 -1
- package/dist/plugins/latex.js +351 -331
- package/dist/plugins/latex.js.map +1 -1
- package/dist/plugins/lazy-load.d.ts +2 -2
- package/dist/plugins/loading/index.d.ts +1 -1
- package/dist/plugins/loading.d.ts +2 -2
- package/dist/plugins/ml-integration/native-algorithms.d.ts +24 -4
- package/dist/plugins/ml-integration/types.d.ts +19 -0
- package/dist/plugins/ml-integration.d.ts +2 -2
- package/dist/plugins/ml-integration.js +190 -139
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/offscreen.d.ts +2 -2
- package/dist/plugins/pattern-recognition/types.d.ts +28 -1
- package/dist/plugins/pattern-recognition.d.ts +2 -2
- package/dist/plugins/pattern-recognition.js +417 -344
- package/dist/plugins/pattern-recognition.js.map +1 -1
- package/dist/plugins/radar.d.ts +2 -2
- package/dist/plugins/regression.d.ts +2 -2
- package/dist/plugins/regression.js +1 -1
- package/dist/plugins/regression.js.map +1 -1
- package/dist/plugins/roi.js +9 -9
- package/dist/plugins/roi.js.map +1 -1
- package/dist/plugins/snapshot/index.d.ts +1 -1
- package/dist/plugins/snapshot/types.d.ts +1 -1
- package/dist/plugins/snapshot.d.ts +2 -2
- package/dist/plugins/snapshot.js +36 -36
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/streaming/index.d.ts +2 -2
- package/dist/plugins/streaming.d.ts +2 -2
- package/dist/plugins/sync/index.d.ts +3 -2
- package/dist/plugins/sync.d.ts +2 -2
- package/dist/plugins/sync.js +1 -1
- package/dist/plugins/sync.js.map +1 -1
- package/dist/plugins/theme-editor/index.d.ts +1 -1
- package/dist/plugins/theme-editor.d.ts +2 -2
- package/dist/plugins/tools/index.d.ts +1 -1
- package/dist/plugins/tools/tooltip/index.d.ts +1 -1
- package/dist/plugins/tools.d.ts +2 -2
- package/dist/plugins/tools.js +1 -1
- package/dist/plugins/types.d.ts +1 -1
- package/dist/plugins/video-recorder.d.ts +2 -2
- package/dist/plugins/virtualization.d.ts +2 -2
- package/dist/plugins/virtualization.js +1 -1
- package/dist/pool-DZ8shSqv.js +109 -0
- package/dist/pool-DZ8shSqv.js.map +1 -0
- package/dist/react/StackedPlot.d.ts +31 -0
- package/dist/react/VeloPlot.d.ts +29 -0
- package/dist/react/index.d.ts +25 -3
- package/dist/react/useChartSync.d.ts +8 -0
- package/dist/react/useIndicator.d.ts +12 -0
- package/dist/react/useVeloPlot.d.ts +19 -0
- package/dist/react.js +328 -24
- package/dist/react.js.map +1 -1
- package/dist/scientific/index.d.ts +48 -0
- package/dist/scientific.d.ts +1 -0
- package/dist/scientific.js +91 -0
- package/dist/scientific.js.map +1 -0
- package/dist/solid/VeloPlot.d.ts +16 -0
- package/dist/solid/index.d.ts +13 -0
- package/dist/solid/useChartSync.d.ts +6 -0
- package/dist/solid/useIndicator.d.ts +11 -0
- package/dist/solid/useStackedPlot.d.ts +14 -0
- package/dist/solid/useVeloPlot.d.ts +18 -0
- package/dist/solid.d.ts +1 -0
- package/dist/solid.js +172 -0
- package/dist/solid.js.map +1 -0
- package/dist/stackedSync-tnrunZMt.js +100 -0
- package/dist/stackedSync-tnrunZMt.js.map +1 -0
- package/dist/svelte/StackedPlot.svelte +29 -0
- package/dist/svelte/StackedPlot.test.ts +114 -0
- package/dist/svelte/VeloPlot.svelte +44 -0
- package/dist/svelte/VeloPlot.test.ts +105 -0
- package/dist/svelte/index.d.ts +11 -0
- package/dist/svelte/index.test.ts +20 -0
- package/dist/svelte/index.ts +15 -0
- package/dist/svelte/useChartSync.d.ts +8 -0
- package/dist/svelte/useChartSync.test.ts +49 -0
- package/dist/svelte/useChartSync.ts +29 -0
- package/dist/svelte/useIndicator.d.ts +13 -0
- package/dist/svelte/useIndicator.test.ts +67 -0
- package/dist/svelte/useIndicator.ts +43 -0
- package/dist/svelte/useStackedPlot.d.ts +16 -0
- package/dist/svelte/useStackedPlot.test.ts +76 -0
- package/dist/svelte/useStackedPlot.ts +54 -0
- package/dist/svelte/useVeloPlot.d.ts +21 -0
- package/dist/svelte/useVeloPlot.test.ts +100 -0
- package/dist/svelte/useVeloPlot.ts +81 -0
- package/dist/svelte.d.ts +1 -0
- package/dist/svelte.js +143 -0
- package/dist/svelte.js.map +1 -0
- package/dist/symbols-DT0eLlpW.js +568 -0
- package/dist/symbols-DT0eLlpW.js.map +1 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/theme/index.d.ts +2 -1
- package/dist/trading.js +7 -7
- package/dist/types.d.ts +1 -1
- package/dist/{utils-BK5UUXxj.js → utils-Dx0h0bgQ.js} +9 -9
- package/dist/{utils-BK5UUXxj.js.map → utils-Dx0h0bgQ.js.map} +1 -1
- package/dist/velo-plot.full.js +444 -433
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +15 -15
- package/dist/vue/StackedPlot.vue.d.ts +48 -0
- package/dist/vue/VeloPlot.vue.d.ts +64 -0
- package/dist/vue/index.d.ts +250 -0
- package/dist/vue/useChartSync.d.ts +52 -0
- package/dist/vue/useIndicator.d.ts +23 -0
- package/dist/vue/useStackedPlot.d.ts +15 -0
- package/dist/vue/useVeloPlot.d.ts +20 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +312 -0
- package/dist/vue.js.map +1 -0
- package/dist/workers/indicatorsAsync.d.ts +26 -0
- package/dist/workers/pool.d.ts +9 -0
- package/package.json +88 -10
- package/dist/ChartCore-BhQ4j7f5.js.map +0 -1
- package/dist/SciPlot-GJvw7GJo.js +0 -463
- package/dist/SciPlot-GJvw7GJo.js.map +0 -1
- package/dist/axisFormat-SPX-CD5s.js.map +0 -1
- package/dist/createStackedChart-DJSmqerD.js +0 -706
- package/dist/createStackedChart-DJSmqerD.js.map +0 -1
- package/dist/index-CUGS98p4.js.map +0 -1
- package/dist/index-CWipqOLP.js.map +0 -1
- package/dist/index-D7dTq6VB.js.map +0 -1
- package/dist/index-DoYxf1cV.js.map +0 -1
- package/dist/index.core-fpZ1dYN0.js.map +0 -1
- package/dist/mockDatafeed-Cdg5hKEo.js.map +0 -1
- package/dist/pool-15HMCNv8.js +0 -88
- package/dist/pool-15HMCNv8.js.map +0 -1
- package/dist/react/SciPlot.d.ts +0 -60
- package/dist/react/useSciPlot.d.ts +0 -56
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecasting.js","sources":["../../src/plugins/forecasting/algorithms.ts","../../src/plugins/forecasting/index.ts"],"sourcesContent":["/**\n * Forecasting Algorithms\n * \n * Native implementations of time series forecasting methods.\n */\n\nimport type { ForecastingMethod, ForecastingParams, ForecastingResult } from './types';\n\n/**\n * Main dispatcher for forecasting algorithms\n */\nexport function calculateForecast(\n x: number[] | Float64Array | Float32Array,\n y: number[] | Float64Array | Float32Array,\n method: ForecastingMethod,\n horizon: number,\n params: ForecastingParams = {}\n): ForecastingResult {\n const n = x.length;\n if (n === 0) throw new Error(\"Dataset is empty\");\n\n // Determine time step (assuming regular intervals)\n const dt = n > 1 ? (x[n - 1] - x[0]) / (n - 1) : 1;\n const lastX = x[n - 1];\n\n let result: { yValues: number[], lower?: number[], upper?: number[] };\n\n switch (method) {\n case 'sma':\n result = forecastSMA(y, horizon, params.windowSize || 10);\n break;\n case 'ema':\n result = forecastEMA(y, horizon, params.alpha || 0.3);\n break;\n case 'linear':\n result = forecastLinear(x, y, horizon);\n break;\n case 'expSmoothing':\n result = forecastSimpleExpSmoothing(y, horizon, params.alpha || 0.3);\n break;\n case 'holt':\n result = forecastHolt(y, horizon, params.alpha || 0.3, params.beta || 0.1);\n break;\n case 'wma':\n result = forecastWMA(y, horizon, params.windowSize || 10);\n break;\n case 'holtWinters':\n result = forecastHoltWinters(\n y, \n horizon, \n params.period || 12, \n params.alpha || 0.3, \n params.beta || 0.1, \n params.gamma || 0.1\n );\n break;\n default:\n throw new Error(`Method ${method} not implemented yet`);\n }\n\n // Generate future X values\n const futureX = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n futureX[i] = lastX + (i + 1) * dt;\n }\n\n return {\n xValues: futureX,\n yValues: result.yValues,\n lowerBound: result.lower,\n upperBound: result.upper,\n method,\n metadata: calculateFitMetrics(y, result.yValues) // Simplified for now\n };\n}\n\n/**\n * Weighted Moving Average (WMA)\n * Uses linear weights on the trailing window; projects flat at last WMA value.\n */\nfunction forecastWMA(y: number[] | Float64Array | Float32Array, horizon: number, window: number) {\n const n = y.length;\n const effectiveWindow = Math.min(window, n);\n let weightedSum = 0;\n let weightTotal = 0;\n for (let i = 0; i < effectiveWindow; i++) {\n const weight = i + 1;\n weightedSum += y[n - effectiveWindow + i] * weight;\n weightTotal += weight;\n }\n const wma = weightedSum / weightTotal;\n return { yValues: new Array(horizon).fill(wma) };\n}\n\n/**\n * Simple Moving Average (SMA)\n * Historical SMA used for projection (flat line at last average)\n */\nfunction forecastSMA(y: number[] | Float64Array | Float32Array, horizon: number, window: number) {\n const n = y.length;\n const effectiveWindow = Math.min(window, n);\n \n let sum = 0;\n for (let i = n - effectiveWindow; i < n; i++) {\n sum += y[i];\n }\n const avg = sum / effectiveWindow;\n\n // SMA projection is usually a flat line unless we slide the window (which requires predictions)\n return {\n yValues: new Array(horizon).fill(avg)\n };\n}\n\n/**\n * Exponential Moving Average (EMA)\n */\nfunction forecastEMA(y: number[] | Float64Array | Float32Array, horizon: number, alpha: number) {\n const n = y.length;\n let ema = y[0];\n \n for (let i = 1; i < n; i++) {\n ema = alpha * y[i] + (1 - alpha) * ema;\n }\n\n return {\n yValues: new Array(horizon).fill(ema)\n };\n}\n\n/**\n * Linear Trend Projection\n * Fits y = mx + b to the historical data\n */\nfunction forecastLinear(x: any, y: any, horizon: number) {\n const n = x.length;\n let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;\n \n for (let i = 0; i < n; i++) {\n sumX += x[i];\n sumY += y[i];\n sumXY += x[i] * y[i];\n sumXX += x[i] * x[i];\n }\n\n const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);\n const intercept = (sumY - slope * sumX) / n;\n\n const lastX = x[n - 1];\n const dt = n > 1 ? (x[n - 1] - x[0]) / (n - 1) : 1;\n const yValues = new Array(horizon);\n\n for (let i = 0; i < horizon; i++) {\n const nextX = lastX + (i + 1) * dt;\n yValues[i] = slope * nextX + intercept;\n }\n\n return { yValues };\n}\n\n/**\n * Simple Exponential Smoothing (SES)\n */\nfunction forecastSimpleExpSmoothing(y: any, horizon: number, alpha: number) {\n const n = y.length;\n let level = y[0];\n \n for (let i = 1; i < n; i++) {\n level = alpha * y[i] + (1 - alpha) * level;\n }\n\n return {\n yValues: new Array(horizon).fill(level)\n };\n}\n\n/**\n * Holt's Linear Trend (Double Exponential Smoothing)\n */\nfunction forecastHolt(y: any, horizon: number, alpha: number, beta: number) {\n const n = y.length;\n if (n < 2) return { yValues: new Array(horizon).fill(y[0] || 0) };\n\n let level = y[0];\n let trend = y[1] - y[0];\n\n for (let i = 1; i < n; i++) {\n const lastLevel = level;\n level = alpha * y[i] + (1 - alpha) * (level + trend);\n trend = beta * (level - lastLevel) + (1 - beta) * trend;\n }\n\n const yValues = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n yValues[i] = level + (i + 1) * trend;\n }\n\n return { yValues };\n}\n\n/**\n * Holt-Winters (Triple Exponential Smoothing)\n */\nfunction forecastHoltWinters(y: any, horizon: number, period: number, alpha: number, beta: number, gamma: number) {\n const n = y.length;\n if (n < period * 2) {\n // Fallback to Holt if not enough data for seasonality\n return forecastHolt(y, horizon, alpha, beta);\n }\n\n // 1. Initial Seasonality\n const seasonals = new Array(period);\n const seasonAverages = new Array(Math.floor(n / period));\n for (let i = 0; i < seasonAverages.length; i++) {\n let sum = 0;\n for (let j = 0; j < period; j++) {\n sum += y[i * period + j];\n }\n seasonAverages[i] = sum / period;\n }\n\n for (let i = 0; i < period; i++) {\n let sumOverAvg = 0;\n for (let j = 0; j < seasonAverages.length; j++) {\n sumOverAvg += y[j * period + i] - seasonAverages[j];\n }\n seasonals[i] = sumOverAvg / seasonAverages.length;\n }\n\n // 2. Initial Level and Trend\n let level = seasonAverages[0];\n let trend = (seasonAverages[seasonAverages.length - 1] - seasonAverages[0]) / ((seasonAverages.length - 1) * period);\n\n // 3. Update coefficients\n for (let i = 0; i < n; i++) {\n const lastLevel = level;\n const val = y[i];\n level = alpha * (val - seasonals[i % period]) + (1 - alpha) * (level + trend);\n trend = beta * (level - lastLevel) + (1 - beta) * trend;\n seasonals[i % period] = gamma * (val - level) + (1 - gamma) * seasonals[i % period];\n }\n\n // 4. Forecast\n const yValues = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n const m = (i + 1);\n yValues[i] = (level + m * trend) + seasonals[(n + i) % period];\n }\n\n return { yValues };\n}\n\n/**\n * Calculate common error metrics\n */\nfunction calculateFitMetrics(_historical: any, _forecast: number[]) {\n // This is a simplified placeholder\n // Real metrics should compare historical with a \"back-forecast\"\n return {\n mse: 0,\n mae: 0,\n r2: 1\n };\n}\n","/**\n * Sci Plot - Forecasting Plugin\n * \n * Provides time series forecasting capabilities using native statistical models.\n */\n\nimport type { \n PluginForecastingConfig, \n ForecastingAPI, \n ForecastingOptions, \n ForecastingResult, \n ForecastingVisualizationConfig \n} from './types';\nimport { calculateForecast } from './algorithms';\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n AfterRenderEvent\n} from '../types';\n\nconst manifestForecasting: PluginManifest = {\n name: \"velo-plot-forecasting\",\n version: \"1.0.0\",\n description: \"Time series forecasting for velo-plot\",\n provides: [\"analysis\", \"forecasting\"],\n tags: [\"statistics\", \"forecasting\", \"analysis\"],\n};\n\n/**\n * Forecasting Plugin for Sci Plot\n */\nexport function PluginForecasting(\n config: Partial<PluginForecastingConfig> = {}\n): ChartPlugin<PluginForecastingConfig> {\n let ctx: PluginContext | null = null;\n const activeForecasts = new Map<string, { result: ForecastingResult, config: ForecastingVisualizationConfig }>();\n\n const api: ForecastingAPI = {\n forecast(data: any, options: ForecastingOptions): ForecastingResult {\n let x: any, y: any;\n \n if (Array.isArray(data)) {\n y = data;\n x = data.map((_, i) => i);\n } else if (data.x && data.y) {\n x = data.x;\n y = data.y;\n } else {\n throw new Error(\"Invalid data format for forecasting\");\n }\n\n return calculateForecast(x, y, options.method, options.horizon, options.params);\n },\n\n async forecastSeries(seriesId: string, options: ForecastingOptions): Promise<ForecastingResult> {\n if (!ctx) throw new Error(\"Plugin not initialized\");\n \n const series = ctx.data.getAllSeries().find(s => s.getId() === seriesId);\n if (!series) throw new Error(`Series not found: ${seriesId}`);\n \n const data = series.getData();\n return this.forecast(data, options);\n },\n\n visualize(result: ForecastingResult, vizConfig: ForecastingVisualizationConfig = {}) {\n const id = `forecast-${Math.random().toString(36).substr(2, 9)}`;\n const mergedConfig = {\n showLine: true,\n showConfidenceInterval: true,\n ...config.defaultVisualization,\n ...vizConfig\n };\n \n activeForecasts.set(id, { result, config: mergedConfig });\n ctx?.requestRender();\n return id;\n },\n\n clear(id?: string) {\n if (id) {\n activeForecasts.delete(id);\n } else {\n activeForecasts.clear();\n }\n ctx?.requestRender();\n }\n };\n\n function drawForecasts(pCtx: PluginContext) {\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n activeForecasts.forEach((viz) => {\n const { result, config: vizConfig } = viz;\n const { xValues, yValues, lowerBound, upperBound } = result;\n\n ctx2d.save();\n\n // 1. Draw Confidence Interval\n if (vizConfig.showConfidenceInterval && lowerBound && upperBound) {\n ctx2d.beginPath();\n const opacity = vizConfig.intervalStyle?.opacity ?? 0.15;\n const color = vizConfig.intervalStyle?.fillColor || (vizConfig.lineStyle?.color || '#3b82f6');\n \n ctx2d.fillStyle = color.startsWith('rgba') ? color : color + Math.floor(opacity * 255).toString(16).padStart(2, '0');\n \n for (let i = 0; i < xValues.length; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(upperBound[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n \n for (let i = xValues.length - 1; i >= 0; i--) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(lowerBound[i]);\n ctx2d.lineTo(px, py);\n }\n \n ctx2d.closePath();\n ctx2d.fill();\n }\n\n // 2. Draw Forecast Line\n if (vizConfig.showLine) {\n ctx2d.beginPath();\n ctx2d.strokeStyle = vizConfig.lineStyle?.color || '#3b82f6';\n ctx2d.lineWidth = vizConfig.lineStyle?.width || 2;\n if (vizConfig.lineStyle?.dash) {\n ctx2d.setLineDash(vizConfig.lineStyle.dash);\n } else {\n ctx2d.setLineDash([5, 5]); // Default dashed for forecast\n }\n\n for (let i = 0; i < xValues.length; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(yValues[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n ctx2d.stroke();\n }\n\n ctx2d.restore();\n });\n }\n\n return {\n manifest: manifestForecasting,\n onInit(c: PluginContext) {\n ctx = c;\n },\n onRenderOverlay(pCtx: PluginContext, _event: AfterRenderEvent) {\n drawForecasts(pCtx);\n },\n api\n };\n}\n\n// Re-export types and constants\nexport * from './types';\nexport * from './algorithms';\nexport { manifestForecasting };\n"],"names":["calculateForecast","x","y","method","horizon","params","n","dt","lastX","result","forecastSMA","forecastEMA","forecastLinear","forecastSimpleExpSmoothing","forecastHolt","forecastWMA","forecastHoltWinters","futureX","i","calculateFitMetrics","window","effectiveWindow","weightedSum","weightTotal","weight","wma","sum","avg","alpha","ema","sumX","sumY","sumXY","sumXX","slope","intercept","yValues","nextX","level","beta","trend","lastLevel","period","gamma","seasonals","seasonAverages","j","sumOverAvg","val","m","_historical","_forecast","manifestForecasting","PluginForecasting","config","ctx","activeForecasts","api","data","options","_","seriesId","series","s","vizConfig","id","mergedConfig","drawForecasts","pCtx","render","coords","ctx2d","viz","_a","_b","_c","_d","_e","_f","xValues","lowerBound","upperBound","opacity","color","px","py","c","_event"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"forecasting.js","sources":["../../src/plugins/forecasting/algorithms.ts","../../src/plugins/forecasting/index.ts"],"sourcesContent":["/**\n * Forecasting Algorithms\n *\n * Native implementations of time series forecasting methods.\n *\n * ---------------------------------------------------------------------------\n * Method status audit (task 3.1)\n * ---------------------------------------------------------------------------\n * | Method | Status | Notes |\n * |---------------|--------------|-------------------------------------------|\n * | sma | implemented | Flat projection at trailing average |\n * | wma | implemented | Flat projection at weighted trailing avg |\n * | ema | implemented | Flat projection at last EMA value |\n * | expSmoothing | implemented | Simple exponential smoothing (SES) |\n * | holt | implemented | Double exponential smoothing (trend) |\n * | holtWinters | implemented | Triple exponential smoothing (seasonal) |\n * | linear | implemented | OLS linear trend projection |\n * | arima | implemented | ARIMA(p,d,q) via Hannan-Rissanen (simple) |\n *\n * Every public method returns a finite forecast plus 95% (configurable)\n * confidence bands derived from in-sample one-step residuals. No public\n * method throws for a supported `ForecastingMethod`.\n */\n\nimport type { ForecastingMethod, ForecastingParams, ForecastingResult } from './types';\n\n/** Internal result of a single method: forecast plus in-sample fitted values. */\ninterface MethodResult {\n /** Point forecast for the requested horizon. */\n yValues: number[];\n /**\n * In-sample one-step-ahead fitted values aligned with the history `y`.\n * `fitted[i]` is the prediction of `y[i]` using only `y[0..i-1]`.\n * `null` entries are ignored when computing residuals.\n */\n fitted?: (number | null)[];\n /** Whether forecast uncertainty accumulates with the horizon (sqrt growth). */\n accumulates: boolean;\n}\n\nfunction toArray(a: number[] | Float64Array | Float32Array): number[] {\n return Array.from(a);\n}\n\n/**\n * Map a confidence level (e.g. 0.95) to a normal-distribution z multiplier.\n */\nfunction zForConfidence(confidence: number): number {\n const table: Array<[number, number]> = [\n [0.5, 0.674],\n [0.68, 0.994],\n [0.8, 1.282],\n [0.9, 1.645],\n [0.95, 1.96],\n [0.975, 2.241],\n [0.99, 2.576],\n [0.995, 2.807],\n ];\n let best = table[0];\n let bestDiff = Infinity;\n for (const entry of table) {\n const diff = Math.abs(entry[0] - confidence);\n if (diff < bestDiff) {\n bestDiff = diff;\n best = entry;\n }\n }\n return best[1];\n}\n\n/**\n * Main dispatcher for forecasting algorithms.\n */\nexport function calculateForecast(\n x: number[] | Float64Array | Float32Array,\n y: number[] | Float64Array | Float32Array,\n method: ForecastingMethod,\n horizon: number,\n params: ForecastingParams = {},\n confidence = 0.95\n): ForecastingResult {\n const n = x.length;\n if (n === 0) throw new Error('Dataset is empty');\n\n const ya = toArray(y);\n const xa = toArray(x);\n\n // Determine time step (assuming regular intervals)\n const dt = n > 1 ? (xa[n - 1] - xa[0]) / (n - 1) : 1;\n const lastX = xa[n - 1];\n\n let result: MethodResult;\n\n switch (method) {\n case 'sma':\n result = forecastSMA(ya, horizon, params.windowSize || 10);\n break;\n case 'ema':\n result = forecastEMA(ya, horizon, params.alpha ?? 0.3);\n break;\n case 'linear':\n result = forecastLinear(xa, ya, horizon);\n break;\n case 'expSmoothing':\n result = forecastSimpleExpSmoothing(ya, horizon, params.alpha ?? 0.3);\n break;\n case 'holt':\n result = forecastHolt(ya, horizon, params.alpha ?? 0.3, params.beta ?? 0.1);\n break;\n case 'wma':\n result = forecastWMA(ya, horizon, params.windowSize || 10);\n break;\n case 'holtWinters':\n result = forecastHoltWinters(\n ya,\n horizon,\n params.period || 12,\n params.alpha ?? 0.3,\n params.beta ?? 0.1,\n params.gamma ?? 0.1\n );\n break;\n case 'arima':\n result = forecastARIMA(\n ya,\n horizon,\n params.p ?? 1,\n params.d ?? 1,\n params.q ?? 0\n );\n break;\n default:\n throw new Error(`Method ${method} not implemented yet`);\n }\n\n // Generate future X values\n const futureX = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n futureX[i] = lastX + (i + 1) * dt;\n }\n\n // Compute residual-based statistics and confidence bands.\n const metrics = calculateFitMetrics(ya, result.fitted);\n const z = zForConfidence(confidence);\n const sigma = metrics.rmse;\n const { lower, upper } = buildConfidenceBands(\n result.yValues,\n sigma,\n z,\n result.accumulates\n );\n\n return {\n xValues: futureX,\n yValues: result.yValues,\n lowerBound: lower,\n upperBound: upper,\n method,\n metadata: { ...metrics, confidence },\n };\n}\n\n/**\n * Build symmetric confidence bands around the point forecast.\n * When `accumulates` is true the uncertainty widens with sqrt(horizon step),\n * reflecting the compounding error of trend/AR models.\n */\nfunction buildConfidenceBands(\n yValues: number[],\n sigma: number,\n z: number,\n accumulates: boolean\n): { lower: number[]; upper: number[] } {\n const lower = new Array(yValues.length);\n const upper = new Array(yValues.length);\n for (let i = 0; i < yValues.length; i++) {\n const growth = accumulates ? Math.sqrt(i + 1) : 1;\n const margin = z * sigma * growth;\n lower[i] = yValues[i] - margin;\n upper[i] = yValues[i] + margin;\n }\n return { lower, upper };\n}\n\n// ===========================================================================\n// Moving-average family\n// ===========================================================================\n\n/**\n * Weighted Moving Average (WMA).\n * Uses linear weights on the trailing window; projects flat at last WMA value.\n */\nfunction forecastWMA(y: number[], horizon: number, window: number): MethodResult {\n const n = y.length;\n const effectiveWindow = Math.min(window, n);\n\n const wmaAt = (end: number): number => {\n // end is always >= 1 here, so the trailing window w is always >= 1.\n const w = Math.min(effectiveWindow, end);\n let weightedSum = 0;\n let weightTotal = 0;\n for (let i = 0; i < w; i++) {\n const weight = i + 1;\n weightedSum += y[end - w + i] * weight;\n weightTotal += weight;\n }\n return weightedSum / weightTotal;\n };\n\n const fitted: (number | null)[] = new Array(n).fill(null);\n for (let i = 1; i < n; i++) fitted[i] = wmaAt(i);\n\n const wma = wmaAt(n);\n return { yValues: new Array(horizon).fill(wma), fitted, accumulates: false };\n}\n\n/**\n * Simple Moving Average (SMA).\n * Historical SMA used for projection (flat line at last average).\n */\nfunction forecastSMA(y: number[], horizon: number, window: number): MethodResult {\n const n = y.length;\n const effectiveWindow = Math.min(window, n);\n\n const smaAt = (end: number): number => {\n // end is always >= 1 here, so the trailing window w is always >= 1.\n const w = Math.min(effectiveWindow, end);\n let sum = 0;\n for (let i = end - w; i < end; i++) sum += y[i];\n return sum / w;\n };\n\n const fitted: (number | null)[] = new Array(n).fill(null);\n for (let i = 1; i < n; i++) fitted[i] = smaAt(i);\n\n const avg = smaAt(n);\n return { yValues: new Array(horizon).fill(avg), fitted, accumulates: false };\n}\n\n/**\n * Exponential Moving Average (EMA).\n */\nfunction forecastEMA(y: number[], horizon: number, alpha: number): MethodResult {\n const n = y.length;\n let ema = y[0];\n const fitted: (number | null)[] = new Array(n).fill(null);\n\n for (let i = 1; i < n; i++) {\n fitted[i] = ema; // one-step forecast is the previous EMA\n ema = alpha * y[i] + (1 - alpha) * ema;\n }\n\n return { yValues: new Array(horizon).fill(ema), fitted, accumulates: false };\n}\n\n/**\n * Linear Trend Projection.\n * Fits y = mx + b to the historical data.\n */\nfunction forecastLinear(x: number[], y: number[], horizon: number): MethodResult {\n const n = x.length;\n let sumX = 0,\n sumY = 0,\n sumXY = 0,\n sumXX = 0;\n\n for (let i = 0; i < n; i++) {\n sumX += x[i];\n sumY += y[i];\n sumXY += x[i] * y[i];\n sumXX += x[i] * x[i];\n }\n\n const denom = n * sumXX - sumX * sumX;\n const slope = denom !== 0 ? (n * sumXY - sumX * sumY) / denom : 0;\n const intercept = (sumY - slope * sumX) / n;\n\n const fitted: (number | null)[] = new Array(n);\n for (let i = 0; i < n; i++) fitted[i] = slope * x[i] + intercept;\n\n const lastX = x[n - 1];\n const dt = n > 1 ? (x[n - 1] - x[0]) / (n - 1) : 1;\n const yValues = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n const nextX = lastX + (i + 1) * dt;\n yValues[i] = slope * nextX + intercept;\n }\n\n return { yValues, fitted, accumulates: true };\n}\n\n/**\n * Simple Exponential Smoothing (SES).\n */\nfunction forecastSimpleExpSmoothing(y: number[], horizon: number, alpha: number): MethodResult {\n const n = y.length;\n let level = y[0];\n const fitted: (number | null)[] = new Array(n).fill(null);\n\n for (let i = 1; i < n; i++) {\n fitted[i] = level;\n level = alpha * y[i] + (1 - alpha) * level;\n }\n\n return { yValues: new Array(horizon).fill(level), fitted, accumulates: false };\n}\n\n/**\n * Holt's Linear Trend (Double Exponential Smoothing).\n */\nfunction forecastHolt(y: number[], horizon: number, alpha: number, beta: number): MethodResult {\n const n = y.length;\n if (n < 2) {\n return { yValues: new Array(horizon).fill(y[0] || 0), fitted: [], accumulates: true };\n }\n\n let level = y[0];\n let trend = y[1] - y[0];\n const fitted: (number | null)[] = new Array(n).fill(null);\n\n for (let i = 1; i < n; i++) {\n fitted[i] = level + trend; // one-step forecast\n const lastLevel = level;\n level = alpha * y[i] + (1 - alpha) * (level + trend);\n trend = beta * (level - lastLevel) + (1 - beta) * trend;\n }\n\n const yValues = new Array(horizon);\n for (let i = 0; i < horizon; i++) yValues[i] = level + (i + 1) * trend;\n\n return { yValues, fitted, accumulates: true };\n}\n\n/**\n * Holt-Winters (Triple Exponential Smoothing, additive seasonality).\n */\nfunction forecastHoltWinters(\n y: number[],\n horizon: number,\n period: number,\n alpha: number,\n beta: number,\n gamma: number\n): MethodResult {\n const n = y.length;\n if (n < period * 2) {\n // Fallback to Holt if not enough data for seasonality\n return forecastHolt(y, horizon, alpha, beta);\n }\n\n // 1. Initial Seasonality\n const seasonals = new Array(period);\n const seasonAverages = new Array(Math.floor(n / period));\n for (let i = 0; i < seasonAverages.length; i++) {\n let sum = 0;\n for (let j = 0; j < period; j++) sum += y[i * period + j];\n seasonAverages[i] = sum / period;\n }\n\n for (let i = 0; i < period; i++) {\n let sumOverAvg = 0;\n for (let j = 0; j < seasonAverages.length; j++) {\n sumOverAvg += y[j * period + i] - seasonAverages[j];\n }\n seasonals[i] = sumOverAvg / seasonAverages.length;\n }\n\n // 2. Initial Level and Trend\n let level = seasonAverages[0];\n let trend =\n (seasonAverages[seasonAverages.length - 1] - seasonAverages[0]) /\n ((seasonAverages.length - 1) * period);\n\n const fitted: (number | null)[] = new Array(n).fill(null);\n\n // 3. Update coefficients\n for (let i = 0; i < n; i++) {\n const seasonal = seasonals[i % period];\n if (i > 0) fitted[i] = level + trend + seasonal;\n const lastLevel = level;\n const val = y[i];\n level = alpha * (val - seasonal) + (1 - alpha) * (level + trend);\n trend = beta * (level - lastLevel) + (1 - beta) * trend;\n seasonals[i % period] = gamma * (val - level) + (1 - gamma) * seasonal;\n }\n\n // 4. Forecast\n const yValues = new Array(horizon);\n for (let i = 0; i < horizon; i++) {\n const m = i + 1;\n yValues[i] = level + m * trend + seasonals[(n + i) % period];\n }\n\n return { yValues, fitted, accumulates: true };\n}\n\n// ===========================================================================\n// ARIMA(p, d, q)\n// ===========================================================================\n\n/**\n * Simple native ARIMA implementation.\n *\n * - Differences the series `d` times to achieve (approximate) stationarity.\n * - Estimates AR(p) and MA(q) coefficients using the two-stage\n * Hannan-Rissanen procedure (long AR to recover innovations, then OLS on\n * lagged values and lagged innovations).\n * - Forecasts recursively on the differenced scale, then integrates back.\n *\n * Falls back to Holt's linear trend when there is not enough data to fit the\n * requested orders, so the method never throws for valid input.\n */\nfunction forecastARIMA(\n y: number[],\n horizon: number,\n p: number,\n d: number,\n q: number\n): MethodResult {\n const n = y.length;\n const order = Math.max(p, q);\n // Need enough observations to difference and fit; otherwise degrade gracefully.\n if (n < d + order + 2 || n < 4) {\n return forecastHolt(y, horizon, 0.3, 0.1);\n }\n\n // 1. Difference d times, keeping every intermediate level for integration.\n const diffLevels: number[][] = [y.slice()];\n for (let k = 0; k < d; k++) {\n diffLevels.push(difference(diffLevels[k]));\n }\n const w = diffLevels[d]; // fully differenced (stationary) series\n const m = w.length;\n\n // Center the differenced series around its mean.\n const mean = w.reduce((s, v) => s + v, 0) / m;\n const wc = w.map((v) => v - mean);\n\n // 2. Stage 1 - recover innovation (residual) estimates via a long AR fit.\n let innovations = new Array(m).fill(0);\n if (q > 0) {\n const arLong = Math.min(Math.max(p + q + 2, 5), Math.floor(m / 2));\n const { residuals } = fitAR(wc, arLong);\n innovations = residuals;\n }\n\n // 3. Stage 2 - regress w_t on its p lags and q lagged innovations.\n const start = Math.max(p, q);\n const rows: number[][] = [];\n const targets: number[] = [];\n for (let t = start; t < m; t++) {\n const row: number[] = [];\n for (let i = 1; i <= p; i++) row.push(wc[t - i]);\n for (let j = 1; j <= q; j++) row.push(innovations[t - j]);\n rows.push(row);\n targets.push(wc[t]);\n }\n\n let coeffs: number[] = [];\n if (rows.length > 0 && rows[0].length > 0) {\n coeffs = olsSolve(rows, targets);\n }\n if (coeffs.length !== p + q || coeffs.some((c) => !Number.isFinite(c))) {\n // Fitting failed (singular/ill-conditioned) - fall back.\n return forecastHolt(y, horizon, 0.3, 0.1);\n }\n const ar = coeffs.slice(0, p);\n const ma = coeffs.slice(p, p + q);\n\n // 4. In-sample one-step fitted values (on original scale) for residual sigma.\n const fitted: (number | null)[] = new Array(n).fill(null);\n const fittedResiduals = new Array(m).fill(0);\n for (let t = start; t < m; t++) {\n let pred = 0;\n for (let i = 1; i <= p; i++) pred += ar[i - 1] * wc[t - i];\n for (let j = 1; j <= q; j++) pred += ma[j - 1] * fittedResiduals[t - j];\n fittedResiduals[t] = wc[t] - pred;\n // Map differenced fitted value back to the original scale by adding the\n // previous original observation chain. For d>=1 we approximate by adding\n // the last non-differenced value; exact integration below handles forecasts.\n fitted[t + (n - m)] = integrateFittedPoint(diffLevels, d, t, pred + mean);\n }\n\n // 5. Recursive forecast on the differenced/centered scale.\n const wHist = wc.slice();\n const eHist = fittedResiduals.slice();\n const forecastDiff: number[] = [];\n for (let h = 0; h < horizon; h++) {\n let pred = 0;\n // wHist/eHist always have at least `order` entries here, so the lag index\n // is always in range.\n for (let i = 1; i <= p; i++) {\n pred += ar[i - 1] * wHist[wHist.length - i];\n }\n for (let j = 1; j <= q; j++) {\n pred += ma[j - 1] * eHist[eHist.length - j];\n }\n wHist.push(pred);\n eHist.push(0); // expected future innovation is zero\n forecastDiff.push(pred + mean);\n }\n\n // 6. Integrate the forecast back d times to the original scale.\n const yValues = integrateForecast(diffLevels, d, forecastDiff);\n\n return { yValues, fitted, accumulates: true };\n}\n\n/** First difference of a series. */\nfunction difference(series: number[]): number[] {\n const out = new Array(series.length - 1);\n for (let i = 1; i < series.length; i++) out[i - 1] = series[i] - series[i - 1];\n return out;\n}\n\n/**\n * Integrate a differenced forecast back to the original scale.\n * `diffLevels[0]` is the original series, `diffLevels[d]` fully differenced.\n */\nfunction integrateForecast(diffLevels: number[][], d: number, forecastDiff: number[]): number[] {\n let current = forecastDiff.slice();\n for (let k = d; k >= 1; k--) {\n const parent = diffLevels[k - 1];\n let last = parent[parent.length - 1];\n const integrated = new Array(current.length);\n for (let i = 0; i < current.length; i++) {\n last += current[i];\n integrated[i] = last;\n }\n current = integrated;\n }\n return current;\n}\n\n/**\n * Best-effort mapping of a single in-sample differenced prediction back to the\n * original scale (used only for residual-sigma estimation).\n */\nfunction integrateFittedPoint(\n diffLevels: number[][],\n d: number,\n t: number,\n diffPred: number\n): number {\n if (d === 0) return diffPred;\n // Add the previous observed original value chain.\n const parent = diffLevels[d - 1];\n // parent is one longer than the differenced series, so index t is in range.\n const base = parent[t];\n // For d>1 this is an approximation; sufficient for a residual scale estimate.\n return base + diffPred;\n}\n\n/**\n * Fit an AR(order) model via ordinary least squares and return coefficients\n * plus the in-sample residuals aligned to the input series (leading entries 0).\n */\nfunction fitAR(series: number[], order: number): { coeffs: number[]; residuals: number[] } {\n const m = series.length;\n const rows: number[][] = [];\n const targets: number[] = [];\n for (let t = order; t < m; t++) {\n const row: number[] = [];\n for (let i = 1; i <= order; i++) row.push(series[t - i]);\n rows.push(row);\n targets.push(series[t]);\n }\n const coeffs = rows.length > 0 ? olsSolve(rows, targets) : new Array(order).fill(0);\n const residuals = new Array(m).fill(0);\n for (let t = order; t < m; t++) {\n let pred = 0;\n for (let i = 1; i <= order; i++) pred += (coeffs[i - 1] || 0) * series[t - i];\n residuals[t] = series[t] - pred;\n }\n return { coeffs, residuals };\n}\n\n/**\n * Solve a linear least-squares problem `X b = y` via the normal equations\n * with Gaussian elimination. Returns [] on a singular system.\n */\nfunction olsSolve(X: number[][], y: number[]): number[] {\n const rows = X.length;\n const cols = X[0].length;\n\n // Normal equations: (XᵀX) b = Xᵀy\n const xtx: number[][] = Array.from({ length: cols }, () => new Array(cols).fill(0));\n const xty: number[] = new Array(cols).fill(0);\n\n for (let i = 0; i < rows; i++) {\n for (let a = 0; a < cols; a++) {\n xty[a] += X[i][a] * y[i];\n for (let b = 0; b < cols; b++) {\n xtx[a][b] += X[i][a] * X[i][b];\n }\n }\n }\n\n // Tiny ridge term to stabilise near-singular systems.\n for (let a = 0; a < cols; a++) xtx[a][a] += 1e-8;\n\n return gaussianSolve(xtx, xty);\n}\n\n/**\n * Solve `A x = b` for a square matrix via Gaussian elimination with partial\n * pivoting. Returns [] if the matrix is singular.\n */\nexport function gaussianSolve(A: number[][], b: number[]): number[] {\n const n = b.length;\n const M = A.map((row, i) => [...row, b[i]]);\n\n for (let col = 0; col < n; col++) {\n // Partial pivot\n let pivot = col;\n for (let r = col + 1; r < n; r++) {\n if (Math.abs(M[r][col]) > Math.abs(M[pivot][col])) pivot = r;\n }\n if (Math.abs(M[pivot][col]) < 1e-12) return [];\n [M[col], M[pivot]] = [M[pivot], M[col]];\n\n // Eliminate\n for (let r = 0; r < n; r++) {\n if (r === col) continue;\n const factor = M[r][col] / M[col][col];\n for (let c = col; c <= n; c++) M[r][c] -= factor * M[col][c];\n }\n }\n\n const x = new Array(n);\n for (let i = 0; i < n; i++) x[i] = M[i][n] / M[i][i];\n return x;\n}\n\n/**\n * Compute error metrics from in-sample one-step residuals.\n * `rmse` doubles as the residual sigma used to build confidence bands.\n */\nfunction calculateFitMetrics(\n historical: number[],\n fitted?: (number | null)[]\n): { mse: number; rmse: number; mae: number; r2: number } {\n if (!fitted || fitted.length === 0) {\n return { mse: 0, rmse: 0, mae: 0, r2: 0 };\n }\n\n let sse = 0;\n let sae = 0;\n let count = 0;\n const observed: number[] = [];\n\n for (let i = 0; i < fitted.length && i < historical.length; i++) {\n const f = fitted[i];\n if (f === null || f === undefined || !Number.isFinite(f)) continue;\n const err = historical[i] - f;\n sse += err * err;\n sae += Math.abs(err);\n observed.push(historical[i]);\n count++;\n }\n\n if (count === 0) return { mse: 0, rmse: 0, mae: 0, r2: 0 };\n\n const mse = sse / count;\n const rmse = Math.sqrt(mse);\n const mae = sae / count;\n\n const mean = observed.reduce((s, v) => s + v, 0) / observed.length;\n const sst = observed.reduce((s, v) => s + (v - mean) * (v - mean), 0);\n const r2 = sst > 0 ? 1 - sse / sst : 0;\n\n return {\n mse: round(mse),\n rmse: round(rmse),\n mae: round(mae),\n r2: round(r2),\n };\n}\n\nfunction round(v: number): number {\n return Math.round(v * 1e6) / 1e6;\n}\n","/**\n * Velo Plot - Forecasting Plugin\n * \n * Provides time series forecasting capabilities using native statistical models.\n */\n\nimport type { \n PluginForecastingConfig, \n ForecastingAPI, \n ForecastingOptions, \n ForecastingResult, \n ForecastingVisualizationConfig \n} from './types';\nimport { calculateForecast } from './algorithms';\nimport type { \n PluginManifest, \n ChartPlugin, \n PluginContext,\n AfterRenderEvent\n} from '../types';\n\nconst manifestForecasting: PluginManifest = {\n name: \"velo-plot-forecasting\",\n version: \"1.0.0\",\n description: \"Time series forecasting for velo-plot\",\n provides: [\"analysis\", \"forecasting\"],\n tags: [\"statistics\", \"forecasting\", \"analysis\"],\n};\n\n/**\n * Forecasting Plugin for Velo Plot\n */\nexport function PluginForecasting(\n config: Partial<PluginForecastingConfig> = {}\n): ChartPlugin<PluginForecastingConfig> {\n let ctx: PluginContext | null = null;\n const activeForecasts = new Map<string, { result: ForecastingResult, config: ForecastingVisualizationConfig }>();\n\n const api: ForecastingAPI = {\n forecast(data: any, options: ForecastingOptions): ForecastingResult {\n let x: any, y: any;\n\n // Allow `forecast('seriesId', options)` by resolving the series data.\n if (typeof data === 'string') {\n if (!ctx) throw new Error('Plugin not initialized');\n const series = ctx.data.getAllSeries().find(s => s.getId() === data);\n if (!series) throw new Error(`Series not found: ${data}`);\n const seriesData = series.getData();\n x = seriesData.x;\n y = seriesData.y;\n } else if (Array.isArray(data)) {\n y = data;\n x = data.map((_, i) => i);\n } else if (data.x && data.y) {\n x = data.x;\n y = data.y;\n } else {\n throw new Error(\"Invalid data format for forecasting\");\n }\n\n return calculateForecast(x, y, options.method, options.horizon, options.params, options.confidence);\n },\n\n async forecastSeries(seriesId: string, options: ForecastingOptions): Promise<ForecastingResult> {\n if (!ctx) throw new Error(\"Plugin not initialized\");\n \n const series = ctx.data.getAllSeries().find(s => s.getId() === seriesId);\n if (!series) throw new Error(`Series not found: ${seriesId}`);\n \n const data = series.getData();\n return this.forecast(data, options);\n },\n\n visualize(result: ForecastingResult, vizConfig: ForecastingVisualizationConfig = {}) {\n const id = `forecast-${Math.random().toString(36).substr(2, 9)}`;\n const mergedConfig = {\n showLine: true,\n showConfidenceInterval: true,\n ...config.defaultVisualization,\n ...vizConfig\n };\n \n activeForecasts.set(id, { result, config: mergedConfig });\n ctx?.requestRender();\n return id;\n },\n\n clear(id?: string) {\n if (id) {\n activeForecasts.delete(id);\n } else {\n activeForecasts.clear();\n }\n ctx?.requestRender();\n }\n };\n\n function drawForecasts(pCtx: PluginContext) {\n const { render, coords } = pCtx;\n const { ctx2d } = render;\n if (!ctx2d) return;\n\n activeForecasts.forEach((viz) => {\n const { result, config: vizConfig } = viz;\n const { xValues, yValues, lowerBound, upperBound } = result;\n\n ctx2d.save();\n\n // 1. Draw Confidence Interval\n if (vizConfig.showConfidenceInterval && lowerBound && upperBound) {\n ctx2d.beginPath();\n const opacity = vizConfig.intervalStyle?.opacity ?? 0.15;\n const color = vizConfig.intervalStyle?.fillColor || (vizConfig.lineStyle?.color || '#3b82f6');\n \n ctx2d.fillStyle = color.startsWith('rgba') ? color : color + Math.floor(opacity * 255).toString(16).padStart(2, '0');\n \n for (let i = 0; i < xValues.length; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(upperBound[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n \n for (let i = xValues.length - 1; i >= 0; i--) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(lowerBound[i]);\n ctx2d.lineTo(px, py);\n }\n \n ctx2d.closePath();\n ctx2d.fill();\n }\n\n // 2. Draw Forecast Line\n if (vizConfig.showLine) {\n ctx2d.beginPath();\n ctx2d.strokeStyle = vizConfig.lineStyle?.color || '#3b82f6';\n ctx2d.lineWidth = vizConfig.lineStyle?.width || 2;\n if (vizConfig.lineStyle?.dash) {\n ctx2d.setLineDash(vizConfig.lineStyle.dash);\n } else {\n ctx2d.setLineDash([5, 5]); // Default dashed for forecast\n }\n\n for (let i = 0; i < xValues.length; i++) {\n const px = coords.dataToPixelX(xValues[i]);\n const py = coords.dataToPixelY(yValues[i]);\n if (i === 0) ctx2d.moveTo(px, py);\n else ctx2d.lineTo(px, py);\n }\n ctx2d.stroke();\n }\n\n ctx2d.restore();\n });\n }\n\n return {\n manifest: manifestForecasting,\n onInit(c: PluginContext) {\n ctx = c;\n },\n onRenderOverlay(pCtx: PluginContext, _event: AfterRenderEvent) {\n drawForecasts(pCtx);\n },\n api\n };\n}\n\n// Re-export types and constants\nexport * from './types';\nexport * from './algorithms';\nexport { manifestForecasting };\n"],"names":["toArray","a","zForConfidence","confidence","table","best","bestDiff","entry","diff","calculateForecast","x","y","method","horizon","params","n","ya","xa","dt","lastX","result","forecastSMA","forecastEMA","forecastLinear","forecastSimpleExpSmoothing","forecastHolt","forecastWMA","forecastHoltWinters","forecastARIMA","futureX","i","metrics","calculateFitMetrics","z","sigma","lower","upper","buildConfidenceBands","yValues","accumulates","growth","margin","window","effectiveWindow","wmaAt","end","w","weightedSum","weightTotal","weight","fitted","wma","smaAt","sum","avg","alpha","ema","sumX","sumY","sumXY","sumXX","denom","slope","intercept","nextX","level","beta","trend","lastLevel","period","gamma","seasonals","seasonAverages","j","sumOverAvg","seasonal","val","m","p","d","q","order","diffLevels","k","difference","mean","s","v","wc","innovations","arLong","residuals","fitAR","start","rows","targets","t","row","coeffs","olsSolve","c","ar","ma","fittedResiduals","pred","integrateFittedPoint","wHist","eHist","forecastDiff","h","integrateForecast","series","out","current","parent","last","integrated","diffPred","X","cols","xtx","xty","b","gaussianSolve","A","M","col","pivot","r","factor","historical","sse","sae","count","observed","f","err","mse","rmse","mae","sst","r2","round","manifestForecasting","PluginForecasting","config","ctx","activeForecasts","api","data","options","seriesData","_","seriesId","vizConfig","id","mergedConfig","drawForecasts","pCtx","render","coords","ctx2d","viz","_a","_b","_c","_d","_e","_f","xValues","lowerBound","upperBound","opacity","color","px","py","_event"],"mappings":"AAwCA,SAASA,EAAQC,GAAqD;AACpE,SAAO,MAAM,KAAKA,CAAC;AACrB;AAKA,SAASC,EAAeC,GAA4B;AAClD,QAAMC,IAAiC;AAAA,IACrC,CAAC,KAAK,KAAK;AAAA,IACX,CAAC,MAAM,KAAK;AAAA,IACZ,CAAC,KAAK,KAAK;AAAA,IACX,CAAC,KAAK,KAAK;AAAA,IACX,CAAC,MAAM,IAAI;AAAA,IACX,CAAC,OAAO,KAAK;AAAA,IACb,CAAC,MAAM,KAAK;AAAA,IACZ,CAAC,OAAO,KAAK;AAAA,EAAA;AAEf,MAAIC,IAAOD,EAAM,CAAC,GACdE,IAAW;AACf,aAAWC,KAASH,GAAO;AACzB,UAAMI,IAAO,KAAK,IAAID,EAAM,CAAC,IAAIJ,CAAU;AAC3C,IAAIK,IAAOF,MACTA,IAAWE,GACXH,IAAOE;AAAA,EAEX;AACA,SAAOF,EAAK,CAAC;AACf;AAKO,SAASI,EACdC,GACAC,GACAC,GACAC,GACAC,IAA4B,CAAA,GAC5BX,IAAa,MACM;AACnB,QAAMY,IAAIL,EAAE;AACZ,MAAIK,MAAM,EAAG,OAAM,IAAI,MAAM,kBAAkB;AAE/C,QAAMC,IAAKhB,EAAQW,CAAC,GACdM,IAAKjB,EAAQU,CAAC,GAGdQ,IAAKH,IAAI,KAAKE,EAAGF,IAAI,CAAC,IAAIE,EAAG,CAAC,MAAMF,IAAI,KAAK,GAC7CI,IAAQF,EAAGF,IAAI,CAAC;AAEtB,MAAIK;AAEJ,UAAQR,GAAA;AAAA,IACN,KAAK;AACH,MAAAQ,IAASC,EAAYL,GAAIH,GAASC,EAAO,cAAc,EAAE;AACzD;AAAA,IACF,KAAK;AACH,MAAAM,IAASE,EAAYN,GAAIH,GAASC,EAAO,SAAS,GAAG;AACrD;AAAA,IACF,KAAK;AACH,MAAAM,IAASG,EAAeN,GAAID,GAAIH,CAAO;AACvC;AAAA,IACF,KAAK;AACH,MAAAO,IAASI,EAA2BR,GAAIH,GAASC,EAAO,SAAS,GAAG;AACpE;AAAA,IACF,KAAK;AACH,MAAAM,IAASK,EAAaT,GAAIH,GAASC,EAAO,SAAS,KAAKA,EAAO,QAAQ,GAAG;AAC1E;AAAA,IACF,KAAK;AACH,MAAAM,IAASM,EAAYV,GAAIH,GAASC,EAAO,cAAc,EAAE;AACzD;AAAA,IACF,KAAK;AACH,MAAAM,IAASO;AAAA,QACPX;AAAA,QACAH;AAAA,QACAC,EAAO,UAAU;AAAA,QACjBA,EAAO,SAAS;AAAA,QAChBA,EAAO,QAAQ;AAAA,QACfA,EAAO,SAAS;AAAA,MAAA;AAElB;AAAA,IACF,KAAK;AACH,MAAAM,IAASQ;AAAA,QACPZ;AAAA,QACAH;AAAA,QACAC,EAAO,KAAK;AAAA,QACZA,EAAO,KAAK;AAAA,QACZA,EAAO,KAAK;AAAA,MAAA;AAEd;AAAA,IACF;AACE,YAAM,IAAI,MAAM,UAAUF,CAAM,sBAAsB;AAAA,EAAA;AAI1D,QAAMiB,IAAU,IAAI,MAAMhB,CAAO;AACjC,WAASiB,IAAI,GAAGA,IAAIjB,GAASiB;AAC3B,IAAAD,EAAQC,CAAC,IAAIX,KAASW,IAAI,KAAKZ;AAIjC,QAAMa,IAAUC,EAAoBhB,GAAII,EAAO,MAAM,GAC/Ca,IAAI/B,EAAeC,CAAU,GAC7B+B,IAAQH,EAAQ,MAChB,EAAE,OAAAI,GAAO,OAAAC,EAAA,IAAUC;AAAA,IACvBjB,EAAO;AAAA,IACPc;AAAA,IACAD;AAAA,IACAb,EAAO;AAAA,EAAA;AAGT,SAAO;AAAA,IACL,SAASS;AAAA,IACT,SAAST,EAAO;AAAA,IAChB,YAAYe;AAAA,IACZ,YAAYC;AAAA,IACZ,QAAAxB;AAAA,IACA,UAAU,EAAE,GAAGmB,GAAS,YAAA5B,EAAA;AAAA,EAAW;AAEvC;AAOA,SAASkC,EACPC,GACAJ,GACAD,GACAM,GACsC;AACtC,QAAMJ,IAAQ,IAAI,MAAMG,EAAQ,MAAM,GAChCF,IAAQ,IAAI,MAAME,EAAQ,MAAM;AACtC,WAASR,IAAI,GAAGA,IAAIQ,EAAQ,QAAQR,KAAK;AACvC,UAAMU,IAASD,IAAc,KAAK,KAAKT,IAAI,CAAC,IAAI,GAC1CW,IAASR,IAAIC,IAAQM;AAC3B,IAAAL,EAAML,CAAC,IAAIQ,EAAQR,CAAC,IAAIW,GACxBL,EAAMN,CAAC,IAAIQ,EAAQR,CAAC,IAAIW;AAAA,EAC1B;AACA,SAAO,EAAE,OAAAN,GAAO,OAAAC,EAAA;AAClB;AAUA,SAASV,EAAYf,GAAaE,GAAiB6B,GAA8B;AAC/E,QAAM3B,IAAIJ,EAAE,QACNgC,IAAkB,KAAK,IAAID,GAAQ3B,CAAC,GAEpC6B,IAAQ,CAACC,MAAwB;AAErC,UAAMC,IAAI,KAAK,IAAIH,GAAiBE,CAAG;AACvC,QAAIE,IAAc,GACdC,IAAc;AAClB,aAASlB,IAAI,GAAGA,IAAIgB,GAAGhB,KAAK;AAC1B,YAAMmB,IAASnB,IAAI;AACnB,MAAAiB,KAAepC,EAAEkC,IAAMC,IAAIhB,CAAC,IAAImB,GAChCD,KAAeC;AAAA,IACjB;AACA,WAAOF,IAAcC;AAAA,EACvB,GAEME,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AACxD,WAASe,IAAI,GAAGA,IAAIf,GAAGe,IAAK,CAAAoB,EAAOpB,CAAC,IAAIc,EAAMd,CAAC;AAE/C,QAAMqB,IAAMP,EAAM7B,CAAC;AACnB,SAAO,EAAE,SAAS,IAAI,MAAMF,CAAO,EAAE,KAAKsC,CAAG,GAAG,QAAAD,GAAQ,aAAa,GAAA;AACvE;AAMA,SAAS7B,EAAYV,GAAaE,GAAiB6B,GAA8B;AAC/E,QAAM3B,IAAIJ,EAAE,QACNgC,IAAkB,KAAK,IAAID,GAAQ3B,CAAC,GAEpCqC,IAAQ,CAACP,MAAwB;AAErC,UAAMC,IAAI,KAAK,IAAIH,GAAiBE,CAAG;AACvC,QAAIQ,IAAM;AACV,aAASvB,IAAIe,IAAMC,GAAGhB,IAAIe,GAAKf,IAAK,CAAAuB,KAAO1C,EAAEmB,CAAC;AAC9C,WAAOuB,IAAMP;AAAA,EACf,GAEMI,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AACxD,WAASe,IAAI,GAAGA,IAAIf,GAAGe,IAAK,CAAAoB,EAAOpB,CAAC,IAAIsB,EAAMtB,CAAC;AAE/C,QAAMwB,IAAMF,EAAMrC,CAAC;AACnB,SAAO,EAAE,SAAS,IAAI,MAAMF,CAAO,EAAE,KAAKyC,CAAG,GAAG,QAAAJ,GAAQ,aAAa,GAAA;AACvE;AAKA,SAAS5B,EAAYX,GAAaE,GAAiB0C,GAA6B;AAC9E,QAAMxC,IAAIJ,EAAE;AACZ,MAAI6C,IAAM7C,EAAE,CAAC;AACb,QAAMuC,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AAExD,WAASe,IAAI,GAAGA,IAAIf,GAAGe;AACrB,IAAAoB,EAAOpB,CAAC,IAAI0B,GACZA,IAAMD,IAAQ5C,EAAEmB,CAAC,KAAK,IAAIyB,KAASC;AAGrC,SAAO,EAAE,SAAS,IAAI,MAAM3C,CAAO,EAAE,KAAK2C,CAAG,GAAG,QAAAN,GAAQ,aAAa,GAAA;AACvE;AAMA,SAAS3B,EAAeb,GAAaC,GAAaE,GAA+B;AAC/E,QAAME,IAAIL,EAAE;AACZ,MAAI+C,IAAO,GACTC,IAAO,GACPC,IAAQ,GACRC,IAAQ;AAEV,WAAS9B,IAAI,GAAGA,IAAIf,GAAGe;AACrB,IAAA2B,KAAQ/C,EAAEoB,CAAC,GACX4B,KAAQ/C,EAAEmB,CAAC,GACX6B,KAASjD,EAAEoB,CAAC,IAAInB,EAAEmB,CAAC,GACnB8B,KAASlD,EAAEoB,CAAC,IAAIpB,EAAEoB,CAAC;AAGrB,QAAM+B,IAAQ9C,IAAI6C,IAAQH,IAAOA,GAC3BK,IAAQD,MAAU,KAAK9C,IAAI4C,IAAQF,IAAOC,KAAQG,IAAQ,GAC1DE,KAAaL,IAAOI,IAAQL,KAAQ1C,GAEpCmC,IAA4B,IAAI,MAAMnC,CAAC;AAC7C,WAASe,IAAI,GAAGA,IAAIf,GAAGe,IAAK,CAAAoB,EAAOpB,CAAC,IAAIgC,IAAQpD,EAAEoB,CAAC,IAAIiC;AAEvD,QAAM5C,IAAQT,EAAEK,IAAI,CAAC,GACfG,IAAKH,IAAI,KAAKL,EAAEK,IAAI,CAAC,IAAIL,EAAE,CAAC,MAAMK,IAAI,KAAK,GAC3CuB,IAAU,IAAI,MAAMzB,CAAO;AACjC,WAASiB,IAAI,GAAGA,IAAIjB,GAASiB,KAAK;AAChC,UAAMkC,IAAQ7C,KAASW,IAAI,KAAKZ;AAChC,IAAAoB,EAAQR,CAAC,IAAIgC,IAAQE,IAAQD;AAAA,EAC/B;AAEA,SAAO,EAAE,SAAAzB,GAAS,QAAAY,GAAQ,aAAa,GAAA;AACzC;AAKA,SAAS1B,EAA2Bb,GAAaE,GAAiB0C,GAA6B;AAC7F,QAAMxC,IAAIJ,EAAE;AACZ,MAAIsD,IAAQtD,EAAE,CAAC;AACf,QAAMuC,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AAExD,WAASe,IAAI,GAAGA,IAAIf,GAAGe;AACrB,IAAAoB,EAAOpB,CAAC,IAAImC,GACZA,IAAQV,IAAQ5C,EAAEmB,CAAC,KAAK,IAAIyB,KAASU;AAGvC,SAAO,EAAE,SAAS,IAAI,MAAMpD,CAAO,EAAE,KAAKoD,CAAK,GAAG,QAAAf,GAAQ,aAAa,GAAA;AACzE;AAKA,SAASzB,EAAad,GAAaE,GAAiB0C,GAAeW,GAA4B;AAC7F,QAAMnD,IAAIJ,EAAE;AACZ,MAAII,IAAI;AACN,WAAO,EAAE,SAAS,IAAI,MAAMF,CAAO,EAAE,KAAKF,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,GAAI,aAAa,GAAA;AAGjF,MAAIsD,IAAQtD,EAAE,CAAC,GACXwD,IAAQxD,EAAE,CAAC,IAAIA,EAAE,CAAC;AACtB,QAAMuC,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AAExD,WAAS,IAAI,GAAG,IAAIA,GAAG,KAAK;AAC1B,IAAAmC,EAAO,CAAC,IAAIe,IAAQE;AACpB,UAAMC,IAAYH;AAClB,IAAAA,IAAQV,IAAQ5C,EAAE,CAAC,KAAK,IAAI4C,MAAUU,IAAQE,IAC9CA,IAAQD,KAAQD,IAAQG,MAAc,IAAIF,KAAQC;AAAA,EACpD;AAEA,QAAM7B,IAAU,IAAI,MAAMzB,CAAO;AACjC,WAAS,IAAI,GAAG,IAAIA,GAAS,OAAa,CAAC,IAAIoD,KAAS,IAAI,KAAKE;AAEjE,SAAO,EAAE,SAAA7B,GAAS,QAAAY,GAAQ,aAAa,GAAA;AACzC;AAKA,SAASvB,EACPhB,GACAE,GACAwD,GACAd,GACAW,GACAI,GACc;AACd,QAAMvD,IAAIJ,EAAE;AACZ,MAAII,IAAIsD,IAAS;AAEf,WAAO5C,EAAad,GAAGE,GAAS0C,GAAOW,CAAI;AAI7C,QAAMK,IAAY,IAAI,MAAMF,CAAM,GAC5BG,IAAiB,IAAI,MAAM,KAAK,MAAMzD,IAAIsD,CAAM,CAAC;AACvD,WAASvC,IAAI,GAAGA,IAAI0C,EAAe,QAAQ1C,KAAK;AAC9C,QAAIuB,IAAM;AACV,aAASoB,IAAI,GAAGA,IAAIJ,GAAQI,IAAK,CAAApB,KAAO1C,EAAEmB,IAAIuC,IAASI,CAAC;AACxD,IAAAD,EAAe1C,CAAC,IAAIuB,IAAMgB;AAAA,EAC5B;AAEA,WAASvC,IAAI,GAAGA,IAAIuC,GAAQvC,KAAK;AAC/B,QAAI4C,IAAa;AACjB,aAASD,IAAI,GAAGA,IAAID,EAAe,QAAQC;AACzC,MAAAC,KAAc/D,EAAE8D,IAAIJ,IAASvC,CAAC,IAAI0C,EAAeC,CAAC;AAEpD,IAAAF,EAAUzC,CAAC,IAAI4C,IAAaF,EAAe;AAAA,EAC7C;AAGA,MAAIP,IAAQO,EAAe,CAAC,GACxBL,KACDK,EAAeA,EAAe,SAAS,CAAC,IAAIA,EAAe,CAAC,OAC3DA,EAAe,SAAS,KAAKH;AAEjC,QAAMnB,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI;AAGxD,WAASe,IAAI,GAAGA,IAAIf,GAAGe,KAAK;AAC1B,UAAM6C,IAAWJ,EAAUzC,IAAIuC,CAAM;AACrC,IAAIvC,IAAI,MAAGoB,EAAOpB,CAAC,IAAImC,IAAQE,IAAQQ;AACvC,UAAMP,IAAYH,GACZW,IAAMjE,EAAEmB,CAAC;AACf,IAAAmC,IAAQV,KAASqB,IAAMD,MAAa,IAAIpB,MAAUU,IAAQE,IAC1DA,IAAQD,KAAQD,IAAQG,MAAc,IAAIF,KAAQC,GAClDI,EAAUzC,IAAIuC,CAAM,IAAIC,KAASM,IAAMX,MAAU,IAAIK,KAASK;AAAA,EAChE;AAGA,QAAMrC,IAAU,IAAI,MAAMzB,CAAO;AACjC,WAASiB,IAAI,GAAGA,IAAIjB,GAASiB,KAAK;AAChC,UAAM+C,IAAI/C,IAAI;AACd,IAAAQ,EAAQR,CAAC,IAAImC,IAAQY,IAAIV,IAAQI,GAAWxD,IAAIe,KAAKuC,CAAM;AAAA,EAC7D;AAEA,SAAO,EAAE,SAAA/B,GAAS,QAAAY,GAAQ,aAAa,GAAA;AACzC;AAkBA,SAAStB,EACPjB,GACAE,GACAiE,GACAC,GACAC,GACc;AACd,QAAMjE,IAAIJ,EAAE,QACNsE,IAAQ,KAAK,IAAIH,GAAGE,CAAC;AAE3B,MAAIjE,IAAIgE,IAAIE,IAAQ,KAAKlE,IAAI;AAC3B,WAAOU,EAAad,GAAGE,GAAS,KAAK,GAAG;AAI1C,QAAMqE,IAAyB,CAACvE,EAAE,OAAO;AACzC,WAASwE,IAAI,GAAGA,IAAIJ,GAAGI;AACrB,IAAAD,EAAW,KAAKE,EAAWF,EAAWC,CAAC,CAAC,CAAC;AAE3C,QAAMrC,IAAIoC,EAAWH,CAAC,GAChBF,IAAI/B,EAAE,QAGNuC,IAAOvC,EAAE,OAAO,CAACwC,GAAGC,MAAMD,IAAIC,GAAG,CAAC,IAAIV,GACtCW,IAAK1C,EAAE,IAAI,CAACyC,MAAMA,IAAIF,CAAI;AAGhC,MAAII,IAAc,IAAI,MAAMZ,CAAC,EAAE,KAAK,CAAC;AACrC,MAAIG,IAAI,GAAG;AACT,UAAMU,IAAS,KAAK,IAAI,KAAK,IAAIZ,IAAIE,IAAI,GAAG,CAAC,GAAG,KAAK,MAAMH,IAAI,CAAC,CAAC,GAC3D,EAAE,WAAAc,EAAA,IAAcC,EAAMJ,GAAIE,CAAM;AACtC,IAAAD,IAAcE;AAAA,EAChB;AAGA,QAAME,IAAQ,KAAK,IAAIf,GAAGE,CAAC,GACrBc,IAAmB,CAAA,GACnBC,IAAoB,CAAA;AAC1B,WAASC,IAAIH,GAAOG,IAAInB,GAAGmB,KAAK;AAC9B,UAAMC,IAAgB,CAAA;AACtB,aAASnE,IAAI,GAAGA,KAAKgD,GAAGhD,OAAS,KAAK0D,EAAGQ,IAAIlE,CAAC,CAAC;AAC/C,aAAS2C,IAAI,GAAGA,KAAKO,GAAGP,OAAS,KAAKgB,EAAYO,IAAIvB,CAAC,CAAC;AACxD,IAAAqB,EAAK,KAAKG,CAAG,GACbF,EAAQ,KAAKP,EAAGQ,CAAC,CAAC;AAAA,EACpB;AAEA,MAAIE,IAAmB,CAAA;AAIvB,MAHIJ,EAAK,SAAS,KAAKA,EAAK,CAAC,EAAE,SAAS,MACtCI,IAASC,EAASL,GAAMC,CAAO,IAE7BG,EAAO,WAAWpB,IAAIE,KAAKkB,EAAO,KAAK,CAACE,MAAM,CAAC,OAAO,SAASA,CAAC,CAAC;AAEnE,WAAO3E,EAAad,GAAGE,GAAS,KAAK,GAAG;AAE1C,QAAMwF,IAAKH,EAAO,MAAM,GAAGpB,CAAC,GACtBwB,IAAKJ,EAAO,MAAMpB,GAAGA,IAAIE,CAAC,GAG1B9B,IAA4B,IAAI,MAAMnC,CAAC,EAAE,KAAK,IAAI,GAClDwF,IAAkB,IAAI,MAAM1B,CAAC,EAAE,KAAK,CAAC;AAC3C,WAASmB,IAAIH,GAAOG,IAAInB,GAAGmB,KAAK;AAC9B,QAAIQ,IAAO;AACX,aAAS1E,IAAI,GAAGA,KAAKgD,GAAGhD,IAAK,CAAA0E,KAAQH,EAAGvE,IAAI,CAAC,IAAI0D,EAAGQ,IAAIlE,CAAC;AACzD,aAAS2C,IAAI,GAAGA,KAAKO,GAAGP,IAAK,CAAA+B,KAAQF,EAAG7B,IAAI,CAAC,IAAI8B,EAAgBP,IAAIvB,CAAC;AACtE,IAAA8B,EAAgBP,CAAC,IAAIR,EAAGQ,CAAC,IAAIQ,GAI7BtD,EAAO8C,KAAKjF,IAAI8D,EAAE,IAAI4B,EAAqBvB,GAAYH,GAAGiB,GAAGQ,IAAOnB,CAAI;AAAA,EAC1E;AAGA,QAAMqB,IAAQlB,EAAG,MAAA,GACXmB,IAAQJ,EAAgB,MAAA,GACxBK,IAAyB,CAAA;AAC/B,WAASC,IAAI,GAAGA,IAAIhG,GAASgG,KAAK;AAChC,QAAIL,IAAO;AAGX,aAAS1E,IAAI,GAAGA,KAAKgD,GAAGhD;AACtB,MAAA0E,KAAQH,EAAGvE,IAAI,CAAC,IAAI4E,EAAMA,EAAM,SAAS5E,CAAC;AAE5C,aAAS2C,IAAI,GAAGA,KAAKO,GAAGP;AACtB,MAAA+B,KAAQF,EAAG7B,IAAI,CAAC,IAAIkC,EAAMA,EAAM,SAASlC,CAAC;AAE5C,IAAAiC,EAAM,KAAKF,CAAI,GACfG,EAAM,KAAK,CAAC,GACZC,EAAa,KAAKJ,IAAOnB,CAAI;AAAA,EAC/B;AAKA,SAAO,EAAE,SAFOyB,EAAkB5B,GAAYH,GAAG6B,CAAY,GAE3C,QAAA1D,GAAQ,aAAa,GAAA;AACzC;AAGA,SAASkC,EAAW2B,GAA4B;AAC9C,QAAMC,IAAM,IAAI,MAAMD,EAAO,SAAS,CAAC;AACvC,WAASjF,IAAI,GAAGA,IAAIiF,EAAO,QAAQjF,IAAK,CAAAkF,EAAIlF,IAAI,CAAC,IAAIiF,EAAOjF,CAAC,IAAIiF,EAAOjF,IAAI,CAAC;AAC7E,SAAOkF;AACT;AAMA,SAASF,EAAkB5B,GAAwBH,GAAW6B,GAAkC;AAC9F,MAAIK,IAAUL,EAAa,MAAA;AAC3B,WAASzB,IAAIJ,GAAGI,KAAK,GAAGA,KAAK;AAC3B,UAAM+B,IAAShC,EAAWC,IAAI,CAAC;AAC/B,QAAIgC,IAAOD,EAAOA,EAAO,SAAS,CAAC;AACnC,UAAME,IAAa,IAAI,MAAMH,EAAQ,MAAM;AAC3C,aAASnF,IAAI,GAAGA,IAAImF,EAAQ,QAAQnF;AAClC,MAAAqF,KAAQF,EAAQnF,CAAC,GACjBsF,EAAWtF,CAAC,IAAIqF;AAElB,IAAAF,IAAUG;AAAA,EACZ;AACA,SAAOH;AACT;AAMA,SAASR,EACPvB,GACAH,GACAiB,GACAqB,GACQ;AACR,SAAItC,MAAM,IAAUsC,IAELnC,EAAWH,IAAI,CAAC,EAEXiB,CAAC,IAEPqB;AAChB;AAMA,SAASzB,EAAMmB,GAAkB9B,GAA0D;AACzF,QAAMJ,IAAIkC,EAAO,QACXjB,IAAmB,CAAA,GACnBC,IAAoB,CAAA;AAC1B,WAASC,IAAIf,GAAOe,IAAInB,GAAGmB,KAAK;AAC9B,UAAMC,IAAgB,CAAA;AACtB,aAAS,IAAI,GAAG,KAAKhB,GAAO,OAAS,KAAK8B,EAAOf,IAAI,CAAC,CAAC;AACvD,IAAAF,EAAK,KAAKG,CAAG,GACbF,EAAQ,KAAKgB,EAAOf,CAAC,CAAC;AAAA,EACxB;AACA,QAAME,IAASJ,EAAK,SAAS,IAAIK,EAASL,GAAMC,CAAO,IAAI,IAAI,MAAMd,CAAK,EAAE,KAAK,CAAC,GAC5EU,IAAY,IAAI,MAAMd,CAAC,EAAE,KAAK,CAAC;AACrC,WAASmB,IAAIf,GAAOe,IAAInB,GAAGmB,KAAK;AAC9B,QAAIQ,IAAO;AACX,aAAS,IAAI,GAAG,KAAKvB,GAAO,IAAK,CAAAuB,MAASN,EAAO,IAAI,CAAC,KAAK,KAAKa,EAAOf,IAAI,CAAC;AAC5E,IAAAL,EAAUK,CAAC,IAAIe,EAAOf,CAAC,IAAIQ;AAAA,EAC7B;AACA,SAAO,EAAE,QAAAN,GAAQ,WAAAP,EAAA;AACnB;AAMA,SAASQ,EAASmB,GAAe3G,GAAuB;AACtD,QAAMmF,IAAOwB,EAAE,QACTC,IAAOD,EAAE,CAAC,EAAE,QAGZE,IAAkB,MAAM,KAAK,EAAE,QAAQD,EAAA,GAAQ,MAAM,IAAI,MAAMA,CAAI,EAAE,KAAK,CAAC,CAAC,GAC5EE,IAAgB,IAAI,MAAMF,CAAI,EAAE,KAAK,CAAC;AAE5C,WAASzF,IAAI,GAAGA,IAAIgE,GAAMhE;AACxB,aAAS7B,IAAI,GAAGA,IAAIsH,GAAMtH,KAAK;AAC7B,MAAAwH,EAAIxH,CAAC,KAAKqH,EAAExF,CAAC,EAAE7B,CAAC,IAAIU,EAAEmB,CAAC;AACvB,eAAS4F,IAAI,GAAGA,IAAIH,GAAMG;AACxB,QAAAF,EAAIvH,CAAC,EAAEyH,CAAC,KAAKJ,EAAExF,CAAC,EAAE7B,CAAC,IAAIqH,EAAExF,CAAC,EAAE4F,CAAC;AAAA,IAEjC;AAIF,WAASzH,IAAI,GAAGA,IAAIsH,GAAMtH,IAAK,CAAAuH,EAAIvH,CAAC,EAAEA,CAAC,KAAK;AAE5C,SAAO0H,EAAcH,GAAKC,CAAG;AAC/B;AAMO,SAASE,EAAcC,GAAeF,GAAuB;AAClE,QAAM3G,IAAI2G,EAAE,QACNG,IAAID,EAAE,IAAI,CAAC3B,GAAKnE,MAAM,CAAC,GAAGmE,GAAKyB,EAAE5F,CAAC,CAAC,CAAC;AAE1C,WAASgG,IAAM,GAAGA,IAAM/G,GAAG+G,KAAO;AAEhC,QAAIC,IAAQD;AACZ,aAASE,IAAIF,IAAM,GAAGE,IAAIjH,GAAGiH;AAC3B,MAAI,KAAK,IAAIH,EAAEG,CAAC,EAAEF,CAAG,CAAC,IAAI,KAAK,IAAID,EAAEE,CAAK,EAAED,CAAG,CAAC,MAAGC,IAAQC;AAE7D,QAAI,KAAK,IAAIH,EAAEE,CAAK,EAAED,CAAG,CAAC,IAAI,MAAO,QAAO,CAAA;AAC5C,KAACD,EAAEC,CAAG,GAAGD,EAAEE,CAAK,CAAC,IAAI,CAACF,EAAEE,CAAK,GAAGF,EAAEC,CAAG,CAAC;AAGtC,aAASE,IAAI,GAAGA,IAAIjH,GAAGiH,KAAK;AAC1B,UAAIA,MAAMF,EAAK;AACf,YAAMG,IAASJ,EAAEG,CAAC,EAAEF,CAAG,IAAID,EAAEC,CAAG,EAAEA,CAAG;AACrC,eAAS1B,IAAI0B,GAAK1B,KAAKrF,GAAGqF,IAAK,CAAAyB,EAAEG,CAAC,EAAE5B,CAAC,KAAK6B,IAASJ,EAAEC,CAAG,EAAE1B,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM1F,IAAI,IAAI,MAAMK,CAAC;AACrB,WAASe,IAAI,GAAGA,IAAIf,GAAGe,OAAOA,CAAC,IAAI+F,EAAE/F,CAAC,EAAEf,CAAC,IAAI8G,EAAE/F,CAAC,EAAEA,CAAC;AACnD,SAAOpB;AACT;AAMA,SAASsB,EACPkG,GACAhF,GACwD;AACxD,MAAI,CAACA,KAAUA,EAAO,WAAW;AAC/B,WAAO,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,EAAA;AAGxC,MAAIiF,IAAM,GACNC,IAAM,GACNC,IAAQ;AACZ,QAAMC,IAAqB,CAAA;AAE3B,WAASxG,IAAI,GAAGA,IAAIoB,EAAO,UAAUpB,IAAIoG,EAAW,QAAQpG,KAAK;AAC/D,UAAMyG,IAAIrF,EAAOpB,CAAC;AAClB,QAAIyG,KAAM,QAA2B,CAAC,OAAO,SAASA,CAAC,EAAG;AAC1D,UAAMC,IAAMN,EAAWpG,CAAC,IAAIyG;AAC5B,IAAAJ,KAAOK,IAAMA,GACbJ,KAAO,KAAK,IAAII,CAAG,GACnBF,EAAS,KAAKJ,EAAWpG,CAAC,CAAC,GAC3BuG;AAAA,EACF;AAEA,MAAIA,MAAU,EAAG,QAAO,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,EAAA;AAEvD,QAAMI,IAAMN,IAAME,GACZK,IAAO,KAAK,KAAKD,CAAG,GACpBE,IAAMP,IAAMC,GAEZhD,IAAOiD,EAAS,OAAO,CAAChD,GAAGC,MAAMD,IAAIC,GAAG,CAAC,IAAI+C,EAAS,QACtDM,IAAMN,EAAS,OAAO,CAAChD,GAAGC,MAAMD,KAAKC,IAAIF,MAASE,IAAIF,IAAO,CAAC,GAC9DwD,IAAKD,IAAM,IAAI,IAAIT,IAAMS,IAAM;AAErC,SAAO;AAAA,IACL,KAAKE,EAAML,CAAG;AAAA,IACd,MAAMK,EAAMJ,CAAI;AAAA,IAChB,KAAKI,EAAMH,CAAG;AAAA,IACd,IAAIG,EAAMD,CAAE;AAAA,EAAA;AAEhB;AAEA,SAASC,EAAMvD,GAAmB;AAChC,SAAO,KAAK,MAAMA,IAAI,GAAG,IAAI;AAC/B;ACppBA,MAAMwD,IAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,YAAY,aAAa;AAAA,EACpC,MAAM,CAAC,cAAc,eAAe,UAAU;AAChD;AAKO,SAASC,EACdC,IAA2C,IACL;AACtC,MAAIC,IAA4B;AAChC,QAAMC,wBAAsB,IAAA,GAEtBC,IAAsB;AAAA,IAC1B,SAASC,GAAWC,GAAgD;AAClE,UAAI5I,GAAQC;AAGZ,UAAI,OAAO0I,KAAS,UAAU;AAC5B,YAAI,CAACH,EAAK,OAAM,IAAI,MAAM,wBAAwB;AAClD,cAAMnC,IAASmC,EAAI,KAAK,aAAA,EAAe,KAAK,CAAA5D,MAAKA,EAAE,MAAA,MAAY+D,CAAI;AACnE,YAAI,CAACtC,EAAQ,OAAM,IAAI,MAAM,qBAAqBsC,CAAI,EAAE;AACxD,cAAME,IAAaxC,EAAO,QAAA;AAC1B,QAAArG,IAAI6I,EAAW,GACf5I,IAAI4I,EAAW;AAAA,MACjB,WAAW,MAAM,QAAQF,CAAI;AAC3B,QAAA1I,IAAI0I,GACJ3I,IAAI2I,EAAK,IAAI,CAACG,GAAG1H,MAAMA,CAAC;AAAA,eACfuH,EAAK,KAAKA,EAAK;AACxB,QAAA3I,IAAI2I,EAAK,GACT1I,IAAI0I,EAAK;AAAA;AAET,cAAM,IAAI,MAAM,qCAAqC;AAGvD,aAAO5I,EAAkBC,GAAGC,GAAG2I,EAAQ,QAAQA,EAAQ,SAASA,EAAQ,QAAQA,EAAQ,UAAU;AAAA,IACpG;AAAA,IAEA,MAAM,eAAeG,GAAkBH,GAAyD;AAC9F,UAAI,CAACJ,EAAK,OAAM,IAAI,MAAM,wBAAwB;AAElD,YAAMnC,IAASmC,EAAI,KAAK,aAAA,EAAe,KAAK,CAAA5D,MAAKA,EAAE,MAAA,MAAYmE,CAAQ;AACvE,UAAI,CAAC1C,EAAQ,OAAM,IAAI,MAAM,qBAAqB0C,CAAQ,EAAE;AAE5D,YAAMJ,IAAOtC,EAAO,QAAA;AACpB,aAAO,KAAK,SAASsC,GAAMC,CAAO;AAAA,IACpC;AAAA,IAEA,UAAUlI,GAA2BsI,IAA4C,IAAI;AACnF,YAAMC,IAAK,YAAY,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,OAAO,GAAG,CAAC,CAAC,IACxDC,IAAe;AAAA,QACnB,UAAU;AAAA,QACV,wBAAwB;AAAA,QACxB,GAAGX,EAAO;AAAA,QACV,GAAGS;AAAA,MAAA;AAGL,aAAAP,EAAgB,IAAIQ,GAAI,EAAE,QAAAvI,GAAQ,QAAQwI,GAAc,GACxDV,KAAA,QAAAA,EAAK,iBACES;AAAA,IACT;AAAA,IAEA,MAAMA,GAAa;AACjB,MAAIA,IACFR,EAAgB,OAAOQ,CAAE,IAEzBR,EAAgB,MAAA,GAElBD,KAAA,QAAAA,EAAK;AAAA,IACP;AAAA,EAAA;AAGF,WAASW,EAAcC,GAAqB;AAC1C,UAAM,EAAE,QAAAC,GAAQ,QAAAC,EAAA,IAAWF,GACrB,EAAE,OAAAG,MAAUF;AAClB,IAAKE,KAELd,EAAgB,QAAQ,CAACe,MAAQ;AD9DrC,UAAAC,GAAAC,GAAAC,GAAAC,GAAAC,GAAAC;AC+DM,YAAM,EAAE,QAAApJ,GAAQ,QAAQsI,EAAA,IAAcQ,GAChC,EAAE,SAAAO,GAAS,SAAAnI,GAAS,YAAAoI,GAAY,YAAAC,MAAevJ;AAKrD,UAHA6I,EAAM,KAAA,GAGFP,EAAU,0BAA0BgB,KAAcC,GAAY;AAChE,QAAAV,EAAM,UAAA;AACN,cAAMW,MAAUT,IAAAT,EAAU,kBAAV,gBAAAS,EAAyB,YAAW,MAC9CU,MAAQT,IAAAV,EAAU,kBAAV,gBAAAU,EAAyB,gBAAcC,IAAAX,EAAU,cAAV,gBAAAW,EAAqB,UAAS;AAEnF,QAAAJ,EAAM,YAAYY,EAAM,WAAW,MAAM,IAAIA,IAAQA,IAAQ,KAAK,MAAMD,IAAU,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAEnH,iBAAS9I,IAAI,GAAGA,IAAI2I,EAAQ,QAAQ3I,KAAK;AACvC,gBAAMgJ,IAAKd,EAAO,aAAaS,EAAQ3I,CAAC,CAAC,GACnCiJ,IAAKf,EAAO,aAAaW,EAAW7I,CAAC,CAAC;AAC5C,UAAIA,MAAM,IAAGmI,EAAM,OAAOa,GAAIC,CAAE,IAC3Bd,EAAM,OAAOa,GAAIC,CAAE;AAAA,QAC1B;AAEA,iBAASjJ,IAAI2I,EAAQ,SAAS,GAAG3I,KAAK,GAAGA,KAAK;AAC5C,gBAAMgJ,IAAKd,EAAO,aAAaS,EAAQ3I,CAAC,CAAC,GACnCiJ,IAAKf,EAAO,aAAaU,EAAW5I,CAAC,CAAC;AAC5C,UAAAmI,EAAM,OAAOa,GAAIC,CAAE;AAAA,QACrB;AAEA,QAAAd,EAAM,UAAA,GACNA,EAAM,KAAA;AAAA,MACR;AAGA,UAAIP,EAAU,UAAU;AACtB,QAAAO,EAAM,UAAA,GACNA,EAAM,gBAAcK,IAAAZ,EAAU,cAAV,gBAAAY,EAAqB,UAAS,WAClDL,EAAM,cAAYM,IAAAb,EAAU,cAAV,gBAAAa,EAAqB,UAAS,IAC5CC,IAAAd,EAAU,cAAV,QAAAc,EAAqB,OACvBP,EAAM,YAAYP,EAAU,UAAU,IAAI,IAE1CO,EAAM,YAAY,CAAC,GAAG,CAAC,CAAC;AAG1B,iBAASnI,IAAI,GAAGA,IAAI2I,EAAQ,QAAQ3I,KAAK;AACvC,gBAAMgJ,IAAKd,EAAO,aAAaS,EAAQ3I,CAAC,CAAC,GACnCiJ,IAAKf,EAAO,aAAa1H,EAAQR,CAAC,CAAC;AACzC,UAAIA,MAAM,IAAGmI,EAAM,OAAOa,GAAIC,CAAE,IAC3Bd,EAAM,OAAOa,GAAIC,CAAE;AAAA,QAC1B;AACA,QAAAd,EAAM,OAAA;AAAA,MACR;AAEA,MAAAA,EAAM,QAAA;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,UAAUlB;AAAA,IACV,OAAO3C,GAAkB;AACvB,MAAA8C,IAAM9C;AAAA,IACR;AAAA,IACA,gBAAgB0D,GAAqBkB,GAA0B;AAC7D,MAAAnB,EAAcC,CAAI;AAAA,IACpB;AAAA,IACA,KAAAV;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChartPlugin } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* VeloPlot Engine - GPU Abstraction Plugin
|
|
4
4
|
*
|
|
5
5
|
* Provides WebGPU and WebGL2 backend support, GPU compute capabilities,
|
|
6
6
|
* and performance benchmarking tools.
|
|
@@ -16,7 +16,7 @@ export interface PluginGpuConfig {
|
|
|
16
16
|
enableCompute?: boolean;
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* VeloPlot GPU Plugin
|
|
20
20
|
*
|
|
21
21
|
* Enables high-performance GPU-accelerated rendering and compute.
|
|
22
22
|
*/
|
package/dist/plugins/gpu.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './gpu/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './gpu/index'
|
|
3
|
+
export default VeloPlot
|
package/dist/plugins/gpu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gpu.js","sources":["../../src/gpu/resources/bufferStore.ts","../../src/gpu/resources/textureStore.ts","../../src/gpu/resources/pipelineCache.ts","../../src/gpu/benchmark/benchmark.ts","../../src/gpu/compute/shaders.ts","../../src/gpu/compute/gpuCompute.ts","../../src/plugins/gpu/index.ts"],"sourcesContent":["/**\n * BufferStore - Manages GPU buffer lifecycle\n * \n * Provides a unified interface for buffer management across backends.\n * Handles buffer creation, updates, and cleanup.\n */\n\nimport type { BufferId, BufferUsage } from \"../types\";\n\nexport interface BufferEntry {\n id: BufferId;\n usage: BufferUsage;\n byteLength: number;\n lastUpdated: number;\n}\n\nexport interface IBufferStore {\n /** Create or update a buffer with new data */\n createOrUpdate(id: BufferId, data: ArrayBufferView, usage?: BufferUsage): void;\n \n /** Partially update a buffer at an offset */\n partialUpdate(id: BufferId, data: ArrayBufferView, offsetBytes: number): boolean;\n \n /** Get buffer metadata */\n getInfo(id: BufferId): BufferEntry | undefined;\n \n /** Check if buffer exists */\n has(id: BufferId): boolean;\n \n /** Delete a buffer */\n delete(id: BufferId): void;\n \n /** Get all buffer IDs */\n keys(): IterableIterator<BufferId>;\n \n /** Get buffer count */\n readonly size: number;\n \n /** Cleanup all buffers */\n destroy(): void;\n}\n\n/**\n * Abstract base class for buffer stores\n */\nexport abstract class BaseBufferStore implements IBufferStore {\n protected entries = new Map<BufferId, BufferEntry>();\n \n abstract createOrUpdate(id: BufferId, data: ArrayBufferView, usage?: BufferUsage): void;\n abstract partialUpdate(id: BufferId, data: ArrayBufferView, offsetBytes: number): boolean;\n abstract delete(id: BufferId): void;\n abstract destroy(): void;\n \n getInfo(id: BufferId): BufferEntry | undefined {\n return this.entries.get(id);\n }\n \n has(id: BufferId): boolean {\n return this.entries.has(id);\n }\n \n keys(): IterableIterator<BufferId> {\n return this.entries.keys();\n }\n \n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * TextureStore - Manages GPU texture lifecycle\n * \n * Provides a unified interface for texture management across backends.\n */\n\nimport type { TextureId, TextureFormat } from \"../types\";\n\nexport interface TextureEntry {\n id: TextureId;\n format: TextureFormat;\n width: number;\n height: number;\n lastUpdated: number;\n}\n\nexport interface ITextureStore {\n /** Create or update a 1D texture (for colormaps) */\n createOrUpdate1D(id: TextureId, data: Uint8Array, width?: number): void;\n \n /** Create or update a 2D texture */\n createOrUpdate2D(id: TextureId, data: Uint8Array, width: number, height: number): void;\n \n /** Get texture metadata */\n getInfo(id: TextureId): TextureEntry | undefined;\n \n /** Check if texture exists */\n has(id: TextureId): boolean;\n \n /** Delete a texture */\n delete(id: TextureId): void;\n \n /** Get all texture IDs */\n keys(): IterableIterator<TextureId>;\n \n /** Get texture count */\n readonly size: number;\n \n /** Cleanup all textures */\n destroy(): void;\n}\n\n/**\n * Abstract base class for texture stores\n */\nexport abstract class BaseTextureStore implements ITextureStore {\n protected entries = new Map<TextureId, TextureEntry>();\n \n abstract createOrUpdate1D(id: TextureId, data: Uint8Array, width?: number): void;\n abstract createOrUpdate2D(id: TextureId, data: Uint8Array, width: number, height: number): void;\n abstract delete(id: TextureId): void;\n abstract destroy(): void;\n \n getInfo(id: TextureId): TextureEntry | undefined {\n return this.entries.get(id);\n }\n \n has(id: TextureId): boolean {\n return this.entries.has(id);\n }\n \n keys(): IterableIterator<TextureId> {\n return this.entries.keys();\n }\n \n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * PipelineCache - Manages GPU pipeline lifecycle\n * \n * Caches compiled pipelines to avoid recompilation overhead.\n */\n\nexport type PipelineKind = \n | \"triangle\"\n | \"line\"\n | \"point\"\n | \"band\"\n | \"heatmap\";\n\nexport interface PipelineKey {\n kind: PipelineKind;\n variant?: string; // For future shader variants\n}\n\nexport interface IPipelineCache {\n /** Get or create a pipeline */\n getOrCreate<T>(key: PipelineKey, factory: () => T): T;\n \n /** Check if pipeline exists */\n has(key: PipelineKey): boolean;\n \n /** Delete a pipeline */\n delete(key: PipelineKey): void;\n \n /** Get pipeline count */\n readonly size: number;\n \n /** Cleanup all pipelines */\n destroy(): void;\n}\n\nfunction keyToString(key: PipelineKey): string {\n return key.variant ? `${key.kind}:${key.variant}` : key.kind;\n}\n\n/**\n * Generic pipeline cache implementation\n */\nexport class PipelineCache implements IPipelineCache {\n private pipelines = new Map<string, any>();\n \n getOrCreate<T>(key: PipelineKey, factory: () => T): T {\n const keyStr = keyToString(key);\n \n if (!this.pipelines.has(keyStr)) {\n const pipeline = factory();\n this.pipelines.set(keyStr, pipeline);\n }\n \n return this.pipelines.get(keyStr) as T;\n }\n \n has(key: PipelineKey): boolean {\n return this.pipelines.has(keyToString(key));\n }\n \n delete(key: PipelineKey): void {\n this.pipelines.delete(keyToString(key));\n }\n \n get size(): number {\n return this.pipelines.size;\n }\n \n destroy(): void {\n // Note: Actual pipeline destruction is backend-specific\n this.pipelines.clear();\n }\n}\n","/**\n * GPU Benchmark Utilities\n * \n * Provides tools for measuring rendering performance across backends.\n */\n\nexport interface BenchmarkResult {\n backend: \"webgpu\" | \"webgl\" | \"unknown\";\n pointCount: number;\n fps: number;\n avgFrameTime: number; // ms\n minFrameTime: number; // ms\n maxFrameTime: number; // ms\n totalFrames: number;\n duration: number; // ms\n}\n\nexport interface BenchmarkOptions {\n /** Number of points to render */\n pointCount?: number;\n \n /** Duration of benchmark in milliseconds */\n durationMs?: number;\n \n /** Warm-up frames before measuring */\n warmupFrames?: number;\n \n /** Callback for progress updates */\n onProgress?: (progress: number) => void;\n}\n\n/**\n * Benchmark runner for GPU backends\n */\nexport class GpuBenchmark {\n private canvas: HTMLCanvasElement;\n private results: BenchmarkResult[] = [];\n \n constructor(canvas?: HTMLCanvasElement) {\n this.canvas = canvas ?? document.createElement(\"canvas\");\n if (!canvas) {\n this.canvas.width = 800;\n this.canvas.height = 600;\n }\n }\n \n /**\n * Generate random line data\n */\n private generateLineData(pointCount: number): Float32Array {\n const data = new Float32Array(pointCount * 2);\n for (let i = 0; i < pointCount; i++) {\n data[i * 2] = i / (pointCount - 1); // x: 0 to 1\n data[i * 2 + 1] = Math.random(); // y: random\n }\n return data;\n }\n \n /**\n * Measure frame times\n */\n private async measureFrameTimes(\n renderFn: () => void,\n durationMs: number,\n warmupFrames: number = 10,\n onProgress?: (progress: number) => void\n ): Promise<{ frameTimes: number[]; duration: number }> {\n const frameTimes: number[] = [];\n let lastTime = performance.now();\n let warmupCount = 0;\n const startTime = performance.now();\n \n return new Promise((resolve) => {\n const loop = () => {\n const now = performance.now();\n const elapsed = now - startTime;\n \n if (elapsed >= durationMs + (warmupFrames * 16)) {\n resolve({ frameTimes, duration: elapsed - (warmupFrames * 16) });\n return;\n }\n \n renderFn();\n \n if (warmupCount >= warmupFrames) {\n frameTimes.push(now - lastTime);\n \n if (onProgress) {\n const progress = Math.min(1, elapsed / durationMs);\n onProgress(progress);\n }\n } else {\n warmupCount++;\n }\n \n lastTime = now;\n requestAnimationFrame(loop);\n };\n \n requestAnimationFrame(loop);\n });\n }\n \n /**\n * Run benchmark with WebGPU backend\n */\n async benchmarkWebGPU(options: BenchmarkOptions = {}): Promise<BenchmarkResult | null> {\n // Dynamic import to handle environments without WebGPU\n const { WebGPUBackend } = await import(\"../backends/webgpu/WebGPUBackend\");\n \n if (!WebGPUBackend.isSupported()) {\n console.warn(\"[Benchmark] WebGPU not supported\");\n return null;\n }\n \n const pointCount = options.pointCount ?? 100000;\n const durationMs = options.durationMs ?? 5000;\n const warmupFrames = options.warmupFrames ?? 30;\n \n const backend = new WebGPUBackend(this.canvas);\n await backend.init();\n \n backend.setViewport({\n width: this.canvas.width,\n height: this.canvas.height,\n dpr: 1,\n });\n \n const data = this.generateLineData(pointCount);\n backend.createOrUpdateBuffer(\"bench-line\", data, { usage: \"vertex\" });\n \n const drawList = {\n items: [{\n id: \"bench-line\",\n kind: \"line\" as const,\n bufferId: \"bench-line\",\n count: pointCount,\n visible: true,\n style: { color: [0, 0.9, 1, 1] as const },\n }],\n };\n \n const frame = {\n viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },\n clearColor: [0.1, 0.1, 0.15, 1] as const,\n };\n \n const bounds = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 };\n \n const renderFn = () => {\n (backend as any).renderWithBounds(drawList, frame, bounds);\n };\n \n const { frameTimes, duration } = await this.measureFrameTimes(\n renderFn,\n durationMs,\n warmupFrames,\n options.onProgress\n );\n \n backend.destroy();\n \n const result = this.calculateResult(\"webgpu\", pointCount, frameTimes, duration);\n this.results.push(result);\n return result;\n }\n \n /**\n * Run benchmark with WebGL backend\n */\n async benchmarkWebGL(options: BenchmarkOptions = {}): Promise<BenchmarkResult | null> {\n const { WebGLBackend } = await import(\"../backends/webgl/WebGLBackend\");\n \n if (!WebGLBackend.isSupported()) {\n console.warn(\"[Benchmark] WebGL not supported\");\n return null;\n }\n \n const pointCount = options.pointCount ?? 100000;\n const durationMs = options.durationMs ?? 5000;\n const warmupFrames = options.warmupFrames ?? 30;\n \n const backend = new WebGLBackend(this.canvas);\n await backend.init();\n \n backend.setViewport({\n width: this.canvas.width,\n height: this.canvas.height,\n dpr: 1,\n });\n \n const data = this.generateLineData(pointCount);\n backend.createOrUpdateBuffer(\"bench-line\", data, { usage: \"vertex\" });\n \n const drawList = {\n items: [{\n id: \"bench-line\",\n kind: \"line\" as const,\n bufferId: \"bench-line\",\n count: pointCount,\n visible: true,\n style: { color: [0, 0.9, 1, 1] as const },\n }],\n };\n \n const frame = {\n viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },\n clearColor: [0.1, 0.1, 0.15, 1] as const,\n };\n \n const bounds = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 };\n \n const renderFn = () => {\n backend.renderWithBounds(drawList, frame, bounds);\n };\n \n const { frameTimes, duration } = await this.measureFrameTimes(\n renderFn,\n durationMs,\n warmupFrames,\n options.onProgress\n );\n \n backend.destroy();\n \n const result = this.calculateResult(\"webgl\", pointCount, frameTimes, duration);\n this.results.push(result);\n return result;\n }\n \n /**\n * Calculate benchmark result from frame times\n */\n private calculateResult(\n backend: \"webgpu\" | \"webgl\",\n pointCount: number,\n frameTimes: number[],\n duration: number\n ): BenchmarkResult {\n if (frameTimes.length === 0) {\n return {\n backend,\n pointCount,\n fps: 0,\n avgFrameTime: 0,\n minFrameTime: 0,\n maxFrameTime: 0,\n totalFrames: 0,\n duration,\n };\n }\n \n const sum = frameTimes.reduce((a, b) => a + b, 0);\n const avg = sum / frameTimes.length;\n const min = Math.min(...frameTimes);\n const max = Math.max(...frameTimes);\n \n return {\n backend,\n pointCount,\n fps: Math.round(1000 / avg),\n avgFrameTime: Math.round(avg * 100) / 100,\n minFrameTime: Math.round(min * 100) / 100,\n maxFrameTime: Math.round(max * 100) / 100,\n totalFrames: frameTimes.length,\n duration: Math.round(duration),\n };\n }\n \n /**\n * Run comparative benchmark\n */\n async runComparison(options: BenchmarkOptions = {}): Promise<{\n webgpu: BenchmarkResult | null;\n webgl: BenchmarkResult | null;\n winner: \"webgpu\" | \"webgl\" | \"tie\" | \"unknown\";\n speedup: number;\n }> {\n const webgpu = await this.benchmarkWebGPU(options);\n const webgl = await this.benchmarkWebGL(options);\n \n let winner: \"webgpu\" | \"webgl\" | \"tie\" | \"unknown\" = \"unknown\";\n let speedup = 1;\n \n if (webgpu && webgl) {\n if (webgpu.fps > webgl.fps * 1.05) {\n winner = \"webgpu\";\n speedup = webgpu.fps / webgl.fps;\n } else if (webgl.fps > webgpu.fps * 1.05) {\n winner = \"webgl\";\n speedup = webgl.fps / webgpu.fps;\n } else {\n winner = \"tie\";\n speedup = 1;\n }\n } else if (webgpu) {\n winner = \"webgpu\";\n } else if (webgl) {\n winner = \"webgl\";\n }\n \n return { webgpu, webgl, winner, speedup: Math.round(speedup * 100) / 100 };\n }\n \n /**\n * Get all results\n */\n getResults(): BenchmarkResult[] {\n return [...this.results];\n }\n \n /**\n * Clear results\n */\n clearResults(): void {\n this.results = [];\n }\n \n /**\n * Format result as string\n */\n static formatResult(result: BenchmarkResult): string {\n return [\n `Backend: ${result.backend.toUpperCase()}`,\n `Points: ${result.pointCount.toLocaleString()}`,\n `FPS: ${result.fps}`,\n `Avg Frame: ${result.avgFrameTime}ms`,\n `Min/Max: ${result.minFrameTime}ms / ${result.maxFrameTime}ms`,\n `Frames: ${result.totalFrames}`,\n `Duration: ${result.duration}ms`,\n ].join(\" | \");\n }\n}\n","/**\n * GPU Compute - Compute shader infrastructure for WebGPU\n * \n * Provides GPU-accelerated data analysis capabilities.\n */\n\n// ============================================\n// Statistics Compute Shader\n// ============================================\n\nexport const STATS_COMPUTE_WGSL = `\nstruct StatsResult {\n min_val: f32,\n max_val: f32,\n sum: f32,\n sum_sq: f32,\n count: u32,\n padding: vec3<u32>,\n}\n\n@group(0) @binding(0) var<storage, read> input_data: array<f32>;\n@group(0) @binding(1) var<storage, read_write> result: StatsResult;\n\nvar<workgroup> local_min: array<f32, 256>;\nvar<workgroup> local_max: array<f32, 256>;\nvar<workgroup> local_sum: array<f32, 256>;\nvar<workgroup> local_sum_sq: array<f32, 256>;\nvar<workgroup> local_count: array<u32, 256>;\n\n@compute @workgroup_size(256)\nfn main(\n @builtin(global_invocation_id) global_id: vec3<u32>,\n @builtin(local_invocation_id) local_id: vec3<u32>,\n @builtin(workgroup_id) workgroup_id: vec3<u32>\n) {\n let idx = global_id.x;\n let lid = local_id.x;\n let data_len = arrayLength(&input_data);\n \n // Initialize local values\n if (idx < data_len) {\n let val = input_data[idx];\n local_min[lid] = val;\n local_max[lid] = val;\n local_sum[lid] = val;\n local_sum_sq[lid] = val * val;\n local_count[lid] = 1u;\n } else {\n local_min[lid] = 3.402823e+38; // f32 max\n local_max[lid] = -3.402823e+38; // f32 min\n local_sum[lid] = 0.0;\n local_sum_sq[lid] = 0.0;\n local_count[lid] = 0u;\n }\n \n workgroupBarrier();\n \n // Parallel reduction\n for (var stride: u32 = 128u; stride > 0u; stride = stride >> 1u) {\n if (lid < stride) {\n local_min[lid] = min(local_min[lid], local_min[lid + stride]);\n local_max[lid] = max(local_max[lid], local_max[lid + stride]);\n local_sum[lid] = local_sum[lid] + local_sum[lid + stride];\n local_sum_sq[lid] = local_sum_sq[lid] + local_sum_sq[lid + stride];\n local_count[lid] = local_count[lid] + local_count[lid + stride];\n }\n workgroupBarrier();\n }\n \n // First thread writes result (atomic for multi-workgroup)\n if (lid == 0u) {\n // Use atomics for multi-workgroup reduction\n // For now, we assume single workgroup or post-process on CPU\n result.min_val = local_min[0];\n result.max_val = local_max[0];\n result.sum = local_sum[0];\n result.sum_sq = local_sum_sq[0];\n result.count = local_count[0];\n }\n}\n`;\n\n// ============================================\n// Min/Max Compute Shader (for bounds calculation)\n// ============================================\n\nexport const MINMAX_COMPUTE_WGSL = `\nstruct MinMax {\n min_x: f32,\n max_x: f32,\n min_y: f32,\n max_y: f32,\n}\n\n@group(0) @binding(0) var<storage, read> points: array<vec2<f32>>;\n@group(0) @binding(1) var<storage, read_write> result: MinMax;\n\nvar<workgroup> local_min_x: array<f32, 256>;\nvar<workgroup> local_max_x: array<f32, 256>;\nvar<workgroup> local_min_y: array<f32, 256>;\nvar<workgroup> local_max_y: array<f32, 256>;\n\n@compute @workgroup_size(256)\nfn main(\n @builtin(global_invocation_id) global_id: vec3<u32>,\n @builtin(local_invocation_id) local_id: vec3<u32>\n) {\n let idx = global_id.x;\n let lid = local_id.x;\n let data_len = arrayLength(&points);\n \n if (idx < data_len) {\n let pt = points[idx];\n local_min_x[lid] = pt.x;\n local_max_x[lid] = pt.x;\n local_min_y[lid] = pt.y;\n local_max_y[lid] = pt.y;\n } else {\n local_min_x[lid] = 3.402823e+38;\n local_max_x[lid] = -3.402823e+38;\n local_min_y[lid] = 3.402823e+38;\n local_max_y[lid] = -3.402823e+38;\n }\n \n workgroupBarrier();\n \n for (var stride: u32 = 128u; stride > 0u; stride = stride >> 1u) {\n if (lid < stride) {\n local_min_x[lid] = min(local_min_x[lid], local_min_x[lid + stride]);\n local_max_x[lid] = max(local_max_x[lid], local_max_x[lid + stride]);\n local_min_y[lid] = min(local_min_y[lid], local_min_y[lid + stride]);\n local_max_y[lid] = max(local_max_y[lid], local_max_y[lid + stride]);\n }\n workgroupBarrier();\n }\n \n if (lid == 0u) {\n result.min_x = local_min_x[0];\n result.max_x = local_max_x[0];\n result.min_y = local_min_y[0];\n result.max_y = local_max_y[0];\n }\n}\n`;\n\n// ============================================\n// Downsample Compute Shader (Min-Max per bucket)\n// ============================================\n\nexport const DOWNSAMPLE_COMPUTE_WGSL = `\nstruct Params {\n input_count: u32,\n output_count: u32,\n bucket_size: u32,\n padding: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> input_points: array<vec2<f32>>;\n@group(0) @binding(2) var<storage, read_write> output_points: array<vec2<f32>>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) global_id: vec3<u32>) {\n let bucket_idx = global_id.x;\n \n if (bucket_idx >= params.output_count / 2u) {\n return;\n }\n \n let start = bucket_idx * params.bucket_size;\n let end = min(start + params.bucket_size, params.input_count);\n \n if (start >= params.input_count) {\n return;\n }\n \n var min_y = input_points[start].y;\n var max_y = input_points[start].y;\n var min_idx = start;\n var max_idx = start;\n \n for (var i = start; i < end; i = i + 1u) {\n let y = input_points[i].y;\n if (y < min_y) {\n min_y = y;\n min_idx = i;\n }\n if (y > max_y) {\n max_y = y;\n max_idx = i;\n }\n }\n \n // Output min and max points (preserving x,y pairs)\n let out_base = bucket_idx * 2u;\n \n // Ensure min comes before max in x order\n if (min_idx <= max_idx) {\n output_points[out_base] = input_points[min_idx];\n output_points[out_base + 1u] = input_points[max_idx];\n } else {\n output_points[out_base] = input_points[max_idx];\n output_points[out_base + 1u] = input_points[min_idx];\n }\n}\n`;\n\n// ============================================\n// Peak Detection Compute Shader\n// ============================================\n\nexport const PEAK_DETECT_COMPUTE_WGSL = `\nstruct Params {\n data_count: u32,\n threshold: f32,\n min_distance: u32,\n padding: u32,\n}\n\nstruct Peak {\n index: u32,\n value: f32,\n is_peak: u32,\n padding: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> data: array<f32>;\n@group(0) @binding(2) var<storage, read_write> peaks: array<Peak>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) global_id: vec3<u32>) {\n let idx = global_id.x;\n \n if (idx >= params.data_count) {\n return;\n }\n \n peaks[idx].index = idx;\n peaks[idx].value = data[idx];\n peaks[idx].is_peak = 0u;\n \n // Skip edges\n if (idx < params.min_distance || idx >= params.data_count - params.min_distance) {\n return;\n }\n \n let val = data[idx];\n \n // Check if above threshold\n if (val < params.threshold) {\n return;\n }\n \n // Check if local maximum\n var is_max = true;\n for (var i = 1u; i <= params.min_distance; i = i + 1u) {\n if (data[idx - i] >= val || data[idx + i] >= val) {\n is_max = false;\n break;\n }\n }\n \n if (is_max) {\n peaks[idx].is_peak = 1u;\n }\n}\n`;\n","/**\n * GPU Compute Engine\n * \n * Provides GPU-accelerated data analysis using WebGPU compute shaders.\n * Includes statistics calculation, bounds computation, downsampling, and peak detection.\n */\n\nimport {\n STATS_COMPUTE_WGSL,\n MINMAX_COMPUTE_WGSL,\n DOWNSAMPLE_COMPUTE_WGSL,\n PEAK_DETECT_COMPUTE_WGSL,\n} from \"./shaders\";\n\nexport interface DataStats {\n min: number;\n max: number;\n mean: number;\n std: number;\n count: number;\n}\n\nexport interface DataBounds {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n}\n\nexport interface Peak {\n index: number;\n value: number;\n}\n\nexport interface GpuComputeOptions {\n /** WebGPU device (if already available) */\n device?: any;\n}\n\n/**\n * GPU Compute Engine for data analysis\n */\nexport class GpuCompute {\n private device: any = null;\n private statsPipeline: any = null;\n private minmaxPipeline: any = null;\n private downsamplePipeline: any = null;\n private peaksPipeline: any = null;\n \n private isInitialized = false;\n \n constructor(private options: GpuComputeOptions = {}) {}\n \n /**\n * Check if GPU compute is available\n */\n static isSupported(): boolean {\n return (\n typeof (globalThis as any).navigator !== \"undefined\" &&\n typeof (globalThis as any).navigator.gpu !== \"undefined\"\n );\n }\n \n /**\n * Initialize the compute engine\n */\n async init(): Promise<void> {\n if (this.options.device) {\n this.device = this.options.device;\n } else {\n if (!GpuCompute.isSupported()) {\n throw new Error(\"[GpuCompute] WebGPU not supported\");\n }\n \n const gpu = (globalThis as any).navigator.gpu;\n const adapter = await gpu.requestAdapter({ powerPreference: \"high-performance\" });\n if (!adapter) {\n throw new Error(\"[GpuCompute] Failed to get adapter\");\n }\n \n this.device = await adapter.requestDevice();\n }\n \n // Create pipelines\n await this.createPipelines();\n this.isInitialized = true;\n }\n \n private async createPipelines(): Promise<void> {\n // Stats pipeline\n const statsModule = this.device.createShaderModule({ code: STATS_COMPUTE_WGSL });\n this.statsPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: statsModule, entryPoint: \"main\" },\n });\n \n // MinMax pipeline\n const minmaxModule = this.device.createShaderModule({ code: MINMAX_COMPUTE_WGSL });\n this.minmaxPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: minmaxModule, entryPoint: \"main\" },\n });\n \n // Downsample pipeline\n const downsampleModule = this.device.createShaderModule({ code: DOWNSAMPLE_COMPUTE_WGSL });\n this.downsamplePipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: downsampleModule, entryPoint: \"main\" },\n });\n \n // Peak detection pipeline\n const peaksModule = this.device.createShaderModule({ code: PEAK_DETECT_COMPUTE_WGSL });\n this.peaksPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: peaksModule, entryPoint: \"main\" },\n });\n }\n \n /**\n * Calculate statistics for a 1D array of values\n */\n async calculateStats(data: Float32Array): Promise<DataStats> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create input buffer\n const inputBuffer = this.device.createBuffer({\n size: data.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, data);\n \n // Create result buffer (32 bytes: 5 floats + padding)\n const resultBuffer = this.device.createBuffer({\n size: 32,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Create staging buffer for readback\n const stagingBuffer = this.device.createBuffer({\n size: 32,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Create bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.statsPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: inputBuffer } },\n { binding: 1, resource: { buffer: resultBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.statsPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(data.length / 256);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n // Copy result to staging\n encoder.copyBufferToBuffer(resultBuffer, 0, stagingBuffer, 0, 32);\n \n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultData = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n inputBuffer.destroy();\n resultBuffer.destroy();\n stagingBuffer.destroy();\n \n const [min, max, sum, sumSq, countFloat] = resultData;\n const count = Math.floor(countFloat);\n const mean = count > 0 ? sum / count : 0;\n const variance = count > 1 ? (sumSq - (sum * sum) / count) / (count - 1) : 0;\n const std = Math.sqrt(Math.max(0, variance));\n \n return { min, max, mean, std, count };\n }\n \n /**\n * Calculate bounds for 2D point data\n */\n async calculateBounds(points: Float32Array): Promise<DataBounds> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create input buffer (vec2 array)\n const inputBuffer = this.device.createBuffer({\n size: points.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, points);\n \n // Create result buffer (16 bytes: 4 floats)\n const resultBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.minmaxPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: inputBuffer } },\n { binding: 1, resource: { buffer: resultBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.minmaxPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const pointCount = points.length / 2;\n const workgroups = Math.ceil(pointCount / 256);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(resultBuffer, 0, stagingBuffer, 0, 16);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultData = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n inputBuffer.destroy();\n resultBuffer.destroy();\n stagingBuffer.destroy();\n \n return {\n xMin: resultData[0],\n xMax: resultData[1],\n yMin: resultData[2],\n yMax: resultData[3],\n };\n }\n \n /**\n * Downsample point data using min-max algorithm\n */\n async downsample(\n points: Float32Array,\n targetCount: number\n ): Promise<Float32Array> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const pointCount = points.length / 2;\n if (pointCount <= targetCount) {\n return points; // No downsampling needed\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Calculate bucket size (output is 2 points per bucket: min and max)\n const outputPairs = Math.ceil(targetCount / 2);\n const bucketSize = Math.ceil(pointCount / outputPairs);\n const outputCount = outputPairs * 2;\n \n // Create params buffer\n const paramsData = new Uint32Array([pointCount, outputCount, bucketSize, 0]);\n const paramsBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(paramsBuffer, 0, paramsData);\n \n // Create input buffer\n const inputBuffer = this.device.createBuffer({\n size: points.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, points);\n \n // Create output buffer\n const outputSize = outputCount * 2 * 4; // vec2 * count * sizeof(float)\n const outputBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.downsamplePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: paramsBuffer } },\n { binding: 1, resource: { buffer: inputBuffer } },\n { binding: 2, resource: { buffer: outputBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.downsamplePipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(outputPairs / 64);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(outputBuffer, 0, stagingBuffer, 0, outputSize);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const result = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n paramsBuffer.destroy();\n inputBuffer.destroy();\n outputBuffer.destroy();\n stagingBuffer.destroy();\n \n return result;\n }\n \n /**\n * Detect peaks in 1D data\n */\n async detectPeaks(\n data: Float32Array,\n options: { threshold?: number; minDistance?: number } = {}\n ): Promise<Peak[]> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const threshold = options.threshold ?? 0;\n const minDistance = options.minDistance ?? 1;\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create params buffer\n const paramsData = new Float32Array([\n data.length,\n threshold,\n minDistance,\n 0, // padding\n ]);\n const paramsBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(paramsBuffer, 0, new Uint8Array(paramsData.buffer));\n \n // Input buffer\n const inputBuffer = this.device.createBuffer({\n size: data.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, data);\n \n // Output buffer (Peak struct = 16 bytes each)\n const outputSize = data.length * 16;\n const outputBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.peaksPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: paramsBuffer } },\n { binding: 1, resource: { buffer: inputBuffer } },\n { binding: 2, resource: { buffer: outputBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.peaksPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(data.length / 64);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(outputBuffer, 0, stagingBuffer, 0, outputSize);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultBuffer = new ArrayBuffer(outputSize);\n new Uint8Array(resultBuffer).set(new Uint8Array(stagingBuffer.getMappedRange()));\n stagingBuffer.unmap();\n \n // Parse peaks\n const resultView = new DataView(resultBuffer);\n const peaks: Peak[] = [];\n \n for (let i = 0; i < data.length; i++) {\n const offset = i * 16;\n const isPeak = resultView.getUint32(offset + 8, true);\n \n if (isPeak) {\n peaks.push({\n index: resultView.getUint32(offset, true),\n value: resultView.getFloat32(offset + 4, true),\n });\n }\n }\n \n // Cleanup\n paramsBuffer.destroy();\n inputBuffer.destroy();\n outputBuffer.destroy();\n stagingBuffer.destroy();\n \n return peaks;\n }\n \n /**\n * Cleanup resources\n */\n destroy(): void {\n // Pipelines are managed by device, no explicit cleanup needed\n this.device = null;\n this.statsPipeline = null;\n this.minmaxPipeline = null;\n this.downsamplePipeline = null;\n this.peaksPipeline = null;\n this.isInitialized = false;\n }\n}\n","/**\n * SciPlot Engine - GPU Abstraction Plugin\n * \n * Provides WebGPU and WebGL2 backend support, GPU compute capabilities,\n * and performance benchmarking tools.\n * \n * @module plugins/gpu\n */\n\nexport {\n // Backends\n WebGPUBackend,\n WebGLBackend,\n\n // Renderer facade\n GpuRenderer,\n createGpuRenderer,\n\n // Adapter\n SeriesAdapter,\n parseColorToRGBA,\n\n // Resource management\n PipelineCache,\n BaseBufferStore,\n BaseTextureStore,\n\n // Benchmark\n GpuBenchmark,\n\n // GPU Compute\n GpuCompute,\n} from \"../../gpu\";\n\nexport * from \"../../gpu/types\";\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginGpuConfig {\n /** Preferred backend: 'webgpu' | 'webgl2' | 'webgl1' */\n preferredBackend?: string;\n /** Enable hardware acceleration for compute tasks */\n enableCompute?: boolean;\n}\n\nconst manifestGpu: PluginManifest = {\n name: \"velo-plot-gpu\",\n version: \"1.0.0\",\n description: \"GPU acceleration and WebGPU support for velo-plot\",\n provides: [\"renderer\", \"compute\"],\n tags: [\"gpu\", \"webgpu\", \"webgl2\", \"performance\"],\n};\n\n/**\n * SciPlot GPU Plugin\n * \n * Enables high-performance GPU-accelerated rendering and compute.\n */\nexport function PluginGpu(_config: PluginGpuConfig = {}): ChartPlugin<PluginGpuConfig> {\n return {\n manifest: manifestGpu,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport default PluginGpu;\n"],"names":["BaseBufferStore","__publicField","id","BaseTextureStore","keyToString","key","PipelineCache","factory","keyStr","pipeline","GpuBenchmark","canvas","pointCount","data","i","renderFn","durationMs","warmupFrames","onProgress","frameTimes","lastTime","warmupCount","startTime","resolve","loop","now","elapsed","progress","options","WebGPUBackend","n","backend","drawList","frame","bounds","duration","result","WebGLBackend","avg","a","b","min","max","webgpu","webgl","winner","speedup","STATS_COMPUTE_WGSL","MINMAX_COMPUTE_WGSL","DOWNSAMPLE_COMPUTE_WGSL","PEAK_DETECT_COMPUTE_WGSL","GpuCompute","adapter","statsModule","minmaxModule","downsampleModule","peaksModule","GPUBufferUsage","inputBuffer","resultBuffer","stagingBuffer","bindGroup","encoder","pass","workgroups","resultData","sum","sumSq","countFloat","count","mean","variance","std","points","targetCount","outputPairs","bucketSize","outputCount","paramsData","paramsBuffer","outputSize","outputBuffer","threshold","minDistance","resultView","peaks","offset","manifestGpu","PluginGpu","_config","_ctx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gpu.js","sources":["../../src/gpu/resources/bufferStore.ts","../../src/gpu/resources/textureStore.ts","../../src/gpu/resources/pipelineCache.ts","../../src/gpu/benchmark/benchmark.ts","../../src/gpu/compute/shaders.ts","../../src/gpu/compute/gpuCompute.ts","../../src/plugins/gpu/index.ts"],"sourcesContent":["/**\n * BufferStore - Manages GPU buffer lifecycle\n * \n * Provides a unified interface for buffer management across backends.\n * Handles buffer creation, updates, and cleanup.\n */\n\nimport type { BufferId, BufferUsage } from \"../types\";\n\nexport interface BufferEntry {\n id: BufferId;\n usage: BufferUsage;\n byteLength: number;\n lastUpdated: number;\n}\n\nexport interface IBufferStore {\n /** Create or update a buffer with new data */\n createOrUpdate(id: BufferId, data: ArrayBufferView, usage?: BufferUsage): void;\n \n /** Partially update a buffer at an offset */\n partialUpdate(id: BufferId, data: ArrayBufferView, offsetBytes: number): boolean;\n \n /** Get buffer metadata */\n getInfo(id: BufferId): BufferEntry | undefined;\n \n /** Check if buffer exists */\n has(id: BufferId): boolean;\n \n /** Delete a buffer */\n delete(id: BufferId): void;\n \n /** Get all buffer IDs */\n keys(): IterableIterator<BufferId>;\n \n /** Get buffer count */\n readonly size: number;\n \n /** Cleanup all buffers */\n destroy(): void;\n}\n\n/**\n * Abstract base class for buffer stores\n */\nexport abstract class BaseBufferStore implements IBufferStore {\n protected entries = new Map<BufferId, BufferEntry>();\n \n abstract createOrUpdate(id: BufferId, data: ArrayBufferView, usage?: BufferUsage): void;\n abstract partialUpdate(id: BufferId, data: ArrayBufferView, offsetBytes: number): boolean;\n abstract delete(id: BufferId): void;\n abstract destroy(): void;\n \n getInfo(id: BufferId): BufferEntry | undefined {\n return this.entries.get(id);\n }\n \n has(id: BufferId): boolean {\n return this.entries.has(id);\n }\n \n keys(): IterableIterator<BufferId> {\n return this.entries.keys();\n }\n \n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * TextureStore - Manages GPU texture lifecycle\n * \n * Provides a unified interface for texture management across backends.\n */\n\nimport type { TextureId, TextureFormat } from \"../types\";\n\nexport interface TextureEntry {\n id: TextureId;\n format: TextureFormat;\n width: number;\n height: number;\n lastUpdated: number;\n}\n\nexport interface ITextureStore {\n /** Create or update a 1D texture (for colormaps) */\n createOrUpdate1D(id: TextureId, data: Uint8Array, width?: number): void;\n \n /** Create or update a 2D texture */\n createOrUpdate2D(id: TextureId, data: Uint8Array, width: number, height: number): void;\n \n /** Get texture metadata */\n getInfo(id: TextureId): TextureEntry | undefined;\n \n /** Check if texture exists */\n has(id: TextureId): boolean;\n \n /** Delete a texture */\n delete(id: TextureId): void;\n \n /** Get all texture IDs */\n keys(): IterableIterator<TextureId>;\n \n /** Get texture count */\n readonly size: number;\n \n /** Cleanup all textures */\n destroy(): void;\n}\n\n/**\n * Abstract base class for texture stores\n */\nexport abstract class BaseTextureStore implements ITextureStore {\n protected entries = new Map<TextureId, TextureEntry>();\n \n abstract createOrUpdate1D(id: TextureId, data: Uint8Array, width?: number): void;\n abstract createOrUpdate2D(id: TextureId, data: Uint8Array, width: number, height: number): void;\n abstract delete(id: TextureId): void;\n abstract destroy(): void;\n \n getInfo(id: TextureId): TextureEntry | undefined {\n return this.entries.get(id);\n }\n \n has(id: TextureId): boolean {\n return this.entries.has(id);\n }\n \n keys(): IterableIterator<TextureId> {\n return this.entries.keys();\n }\n \n get size(): number {\n return this.entries.size;\n }\n}\n","/**\n * PipelineCache - Manages GPU pipeline lifecycle\n * \n * Caches compiled pipelines to avoid recompilation overhead.\n */\n\nexport type PipelineKind = \n | \"triangle\"\n | \"line\"\n | \"point\"\n | \"band\"\n | \"heatmap\";\n\nexport interface PipelineKey {\n kind: PipelineKind;\n variant?: string; // For future shader variants\n}\n\nexport interface IPipelineCache {\n /** Get or create a pipeline */\n getOrCreate<T>(key: PipelineKey, factory: () => T): T;\n \n /** Check if pipeline exists */\n has(key: PipelineKey): boolean;\n \n /** Delete a pipeline */\n delete(key: PipelineKey): void;\n \n /** Get pipeline count */\n readonly size: number;\n \n /** Cleanup all pipelines */\n destroy(): void;\n}\n\nfunction keyToString(key: PipelineKey): string {\n return key.variant ? `${key.kind}:${key.variant}` : key.kind;\n}\n\n/**\n * Generic pipeline cache implementation\n */\nexport class PipelineCache implements IPipelineCache {\n private pipelines = new Map<string, any>();\n \n getOrCreate<T>(key: PipelineKey, factory: () => T): T {\n const keyStr = keyToString(key);\n \n if (!this.pipelines.has(keyStr)) {\n const pipeline = factory();\n this.pipelines.set(keyStr, pipeline);\n }\n \n return this.pipelines.get(keyStr) as T;\n }\n \n has(key: PipelineKey): boolean {\n return this.pipelines.has(keyToString(key));\n }\n \n delete(key: PipelineKey): void {\n this.pipelines.delete(keyToString(key));\n }\n \n get size(): number {\n return this.pipelines.size;\n }\n \n destroy(): void {\n // Note: Actual pipeline destruction is backend-specific\n this.pipelines.clear();\n }\n}\n","/**\n * GPU Benchmark Utilities\n * \n * Provides tools for measuring rendering performance across backends.\n */\n\nexport interface BenchmarkResult {\n backend: \"webgpu\" | \"webgl\" | \"unknown\";\n pointCount: number;\n fps: number;\n avgFrameTime: number; // ms\n minFrameTime: number; // ms\n maxFrameTime: number; // ms\n totalFrames: number;\n duration: number; // ms\n}\n\nexport interface BenchmarkOptions {\n /** Number of points to render */\n pointCount?: number;\n \n /** Duration of benchmark in milliseconds */\n durationMs?: number;\n \n /** Warm-up frames before measuring */\n warmupFrames?: number;\n \n /** Callback for progress updates */\n onProgress?: (progress: number) => void;\n}\n\n/**\n * Benchmark runner for GPU backends\n */\nexport class GpuBenchmark {\n private canvas: HTMLCanvasElement;\n private results: BenchmarkResult[] = [];\n \n constructor(canvas?: HTMLCanvasElement) {\n this.canvas = canvas ?? document.createElement(\"canvas\");\n if (!canvas) {\n this.canvas.width = 800;\n this.canvas.height = 600;\n }\n }\n \n /**\n * Generate random line data\n */\n private generateLineData(pointCount: number): Float32Array {\n const data = new Float32Array(pointCount * 2);\n for (let i = 0; i < pointCount; i++) {\n data[i * 2] = i / (pointCount - 1); // x: 0 to 1\n data[i * 2 + 1] = Math.random(); // y: random\n }\n return data;\n }\n \n /**\n * Measure frame times\n */\n private async measureFrameTimes(\n renderFn: () => void,\n durationMs: number,\n warmupFrames: number = 10,\n onProgress?: (progress: number) => void\n ): Promise<{ frameTimes: number[]; duration: number }> {\n const frameTimes: number[] = [];\n let lastTime = performance.now();\n let warmupCount = 0;\n const startTime = performance.now();\n \n return new Promise((resolve) => {\n const loop = () => {\n const now = performance.now();\n const elapsed = now - startTime;\n \n if (elapsed >= durationMs + (warmupFrames * 16)) {\n resolve({ frameTimes, duration: elapsed - (warmupFrames * 16) });\n return;\n }\n \n renderFn();\n \n if (warmupCount >= warmupFrames) {\n frameTimes.push(now - lastTime);\n \n if (onProgress) {\n const progress = Math.min(1, elapsed / durationMs);\n onProgress(progress);\n }\n } else {\n warmupCount++;\n }\n \n lastTime = now;\n requestAnimationFrame(loop);\n };\n \n requestAnimationFrame(loop);\n });\n }\n \n /**\n * Run benchmark with WebGPU backend\n */\n async benchmarkWebGPU(options: BenchmarkOptions = {}): Promise<BenchmarkResult | null> {\n // Dynamic import to handle environments without WebGPU\n const { WebGPUBackend } = await import(\"../backends/webgpu/WebGPUBackend\");\n \n if (!WebGPUBackend.isSupported()) {\n console.warn(\"[Benchmark] WebGPU not supported\");\n return null;\n }\n \n const pointCount = options.pointCount ?? 100000;\n const durationMs = options.durationMs ?? 5000;\n const warmupFrames = options.warmupFrames ?? 30;\n \n const backend = new WebGPUBackend(this.canvas);\n await backend.init();\n \n backend.setViewport({\n width: this.canvas.width,\n height: this.canvas.height,\n dpr: 1,\n });\n \n const data = this.generateLineData(pointCount);\n backend.createOrUpdateBuffer(\"bench-line\", data, { usage: \"vertex\" });\n \n const drawList = {\n items: [{\n id: \"bench-line\",\n kind: \"line\" as const,\n bufferId: \"bench-line\",\n count: pointCount,\n visible: true,\n style: { color: [0, 0.9, 1, 1] as const },\n }],\n };\n \n const frame = {\n viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },\n clearColor: [0.1, 0.1, 0.15, 1] as const,\n };\n \n const bounds = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 };\n \n const renderFn = () => {\n (backend as any).renderWithBounds(drawList, frame, bounds);\n };\n \n const { frameTimes, duration } = await this.measureFrameTimes(\n renderFn,\n durationMs,\n warmupFrames,\n options.onProgress\n );\n \n backend.destroy();\n \n const result = this.calculateResult(\"webgpu\", pointCount, frameTimes, duration);\n this.results.push(result);\n return result;\n }\n \n /**\n * Run benchmark with WebGL backend\n */\n async benchmarkWebGL(options: BenchmarkOptions = {}): Promise<BenchmarkResult | null> {\n const { WebGLBackend } = await import(\"../backends/webgl/WebGLBackend\");\n \n if (!WebGLBackend.isSupported()) {\n console.warn(\"[Benchmark] WebGL not supported\");\n return null;\n }\n \n const pointCount = options.pointCount ?? 100000;\n const durationMs = options.durationMs ?? 5000;\n const warmupFrames = options.warmupFrames ?? 30;\n \n const backend = new WebGLBackend(this.canvas);\n await backend.init();\n \n backend.setViewport({\n width: this.canvas.width,\n height: this.canvas.height,\n dpr: 1,\n });\n \n const data = this.generateLineData(pointCount);\n backend.createOrUpdateBuffer(\"bench-line\", data, { usage: \"vertex\" });\n \n const drawList = {\n items: [{\n id: \"bench-line\",\n kind: \"line\" as const,\n bufferId: \"bench-line\",\n count: pointCount,\n visible: true,\n style: { color: [0, 0.9, 1, 1] as const },\n }],\n };\n \n const frame = {\n viewport: { width: this.canvas.width, height: this.canvas.height, dpr: 1 },\n clearColor: [0.1, 0.1, 0.15, 1] as const,\n };\n \n const bounds = { xMin: 0, xMax: 1, yMin: 0, yMax: 1 };\n \n const renderFn = () => {\n backend.renderWithBounds(drawList, frame, bounds);\n };\n \n const { frameTimes, duration } = await this.measureFrameTimes(\n renderFn,\n durationMs,\n warmupFrames,\n options.onProgress\n );\n \n backend.destroy();\n \n const result = this.calculateResult(\"webgl\", pointCount, frameTimes, duration);\n this.results.push(result);\n return result;\n }\n \n /**\n * Calculate benchmark result from frame times\n */\n private calculateResult(\n backend: \"webgpu\" | \"webgl\",\n pointCount: number,\n frameTimes: number[],\n duration: number\n ): BenchmarkResult {\n if (frameTimes.length === 0) {\n return {\n backend,\n pointCount,\n fps: 0,\n avgFrameTime: 0,\n minFrameTime: 0,\n maxFrameTime: 0,\n totalFrames: 0,\n duration,\n };\n }\n \n const sum = frameTimes.reduce((a, b) => a + b, 0);\n const avg = sum / frameTimes.length;\n const min = Math.min(...frameTimes);\n const max = Math.max(...frameTimes);\n \n return {\n backend,\n pointCount,\n fps: Math.round(1000 / avg),\n avgFrameTime: Math.round(avg * 100) / 100,\n minFrameTime: Math.round(min * 100) / 100,\n maxFrameTime: Math.round(max * 100) / 100,\n totalFrames: frameTimes.length,\n duration: Math.round(duration),\n };\n }\n \n /**\n * Run comparative benchmark\n */\n async runComparison(options: BenchmarkOptions = {}): Promise<{\n webgpu: BenchmarkResult | null;\n webgl: BenchmarkResult | null;\n winner: \"webgpu\" | \"webgl\" | \"tie\" | \"unknown\";\n speedup: number;\n }> {\n const webgpu = await this.benchmarkWebGPU(options);\n const webgl = await this.benchmarkWebGL(options);\n \n let winner: \"webgpu\" | \"webgl\" | \"tie\" | \"unknown\" = \"unknown\";\n let speedup = 1;\n \n if (webgpu && webgl) {\n if (webgpu.fps > webgl.fps * 1.05) {\n winner = \"webgpu\";\n speedup = webgpu.fps / webgl.fps;\n } else if (webgl.fps > webgpu.fps * 1.05) {\n winner = \"webgl\";\n speedup = webgl.fps / webgpu.fps;\n } else {\n winner = \"tie\";\n speedup = 1;\n }\n } else if (webgpu) {\n winner = \"webgpu\";\n } else if (webgl) {\n winner = \"webgl\";\n }\n \n return { webgpu, webgl, winner, speedup: Math.round(speedup * 100) / 100 };\n }\n \n /**\n * Get all results\n */\n getResults(): BenchmarkResult[] {\n return [...this.results];\n }\n \n /**\n * Clear results\n */\n clearResults(): void {\n this.results = [];\n }\n \n /**\n * Format result as string\n */\n static formatResult(result: BenchmarkResult): string {\n return [\n `Backend: ${result.backend.toUpperCase()}`,\n `Points: ${result.pointCount.toLocaleString()}`,\n `FPS: ${result.fps}`,\n `Avg Frame: ${result.avgFrameTime}ms`,\n `Min/Max: ${result.minFrameTime}ms / ${result.maxFrameTime}ms`,\n `Frames: ${result.totalFrames}`,\n `Duration: ${result.duration}ms`,\n ].join(\" | \");\n }\n}\n","/**\n * GPU Compute - Compute shader infrastructure for WebGPU\n * \n * Provides GPU-accelerated data analysis capabilities.\n */\n\n// ============================================\n// Statistics Compute Shader\n// ============================================\n\nexport const STATS_COMPUTE_WGSL = `\nstruct StatsResult {\n min_val: f32,\n max_val: f32,\n sum: f32,\n sum_sq: f32,\n count: u32,\n padding: vec3<u32>,\n}\n\n@group(0) @binding(0) var<storage, read> input_data: array<f32>;\n@group(0) @binding(1) var<storage, read_write> result: StatsResult;\n\nvar<workgroup> local_min: array<f32, 256>;\nvar<workgroup> local_max: array<f32, 256>;\nvar<workgroup> local_sum: array<f32, 256>;\nvar<workgroup> local_sum_sq: array<f32, 256>;\nvar<workgroup> local_count: array<u32, 256>;\n\n@compute @workgroup_size(256)\nfn main(\n @builtin(global_invocation_id) global_id: vec3<u32>,\n @builtin(local_invocation_id) local_id: vec3<u32>,\n @builtin(workgroup_id) workgroup_id: vec3<u32>\n) {\n let idx = global_id.x;\n let lid = local_id.x;\n let data_len = arrayLength(&input_data);\n \n // Initialize local values\n if (idx < data_len) {\n let val = input_data[idx];\n local_min[lid] = val;\n local_max[lid] = val;\n local_sum[lid] = val;\n local_sum_sq[lid] = val * val;\n local_count[lid] = 1u;\n } else {\n local_min[lid] = 3.402823e+38; // f32 max\n local_max[lid] = -3.402823e+38; // f32 min\n local_sum[lid] = 0.0;\n local_sum_sq[lid] = 0.0;\n local_count[lid] = 0u;\n }\n \n workgroupBarrier();\n \n // Parallel reduction\n for (var stride: u32 = 128u; stride > 0u; stride = stride >> 1u) {\n if (lid < stride) {\n local_min[lid] = min(local_min[lid], local_min[lid + stride]);\n local_max[lid] = max(local_max[lid], local_max[lid + stride]);\n local_sum[lid] = local_sum[lid] + local_sum[lid + stride];\n local_sum_sq[lid] = local_sum_sq[lid] + local_sum_sq[lid + stride];\n local_count[lid] = local_count[lid] + local_count[lid + stride];\n }\n workgroupBarrier();\n }\n \n // First thread writes result (atomic for multi-workgroup)\n if (lid == 0u) {\n // Use atomics for multi-workgroup reduction\n // For now, we assume single workgroup or post-process on CPU\n result.min_val = local_min[0];\n result.max_val = local_max[0];\n result.sum = local_sum[0];\n result.sum_sq = local_sum_sq[0];\n result.count = local_count[0];\n }\n}\n`;\n\n// ============================================\n// Min/Max Compute Shader (for bounds calculation)\n// ============================================\n\nexport const MINMAX_COMPUTE_WGSL = `\nstruct MinMax {\n min_x: f32,\n max_x: f32,\n min_y: f32,\n max_y: f32,\n}\n\n@group(0) @binding(0) var<storage, read> points: array<vec2<f32>>;\n@group(0) @binding(1) var<storage, read_write> result: MinMax;\n\nvar<workgroup> local_min_x: array<f32, 256>;\nvar<workgroup> local_max_x: array<f32, 256>;\nvar<workgroup> local_min_y: array<f32, 256>;\nvar<workgroup> local_max_y: array<f32, 256>;\n\n@compute @workgroup_size(256)\nfn main(\n @builtin(global_invocation_id) global_id: vec3<u32>,\n @builtin(local_invocation_id) local_id: vec3<u32>\n) {\n let idx = global_id.x;\n let lid = local_id.x;\n let data_len = arrayLength(&points);\n \n if (idx < data_len) {\n let pt = points[idx];\n local_min_x[lid] = pt.x;\n local_max_x[lid] = pt.x;\n local_min_y[lid] = pt.y;\n local_max_y[lid] = pt.y;\n } else {\n local_min_x[lid] = 3.402823e+38;\n local_max_x[lid] = -3.402823e+38;\n local_min_y[lid] = 3.402823e+38;\n local_max_y[lid] = -3.402823e+38;\n }\n \n workgroupBarrier();\n \n for (var stride: u32 = 128u; stride > 0u; stride = stride >> 1u) {\n if (lid < stride) {\n local_min_x[lid] = min(local_min_x[lid], local_min_x[lid + stride]);\n local_max_x[lid] = max(local_max_x[lid], local_max_x[lid + stride]);\n local_min_y[lid] = min(local_min_y[lid], local_min_y[lid + stride]);\n local_max_y[lid] = max(local_max_y[lid], local_max_y[lid + stride]);\n }\n workgroupBarrier();\n }\n \n if (lid == 0u) {\n result.min_x = local_min_x[0];\n result.max_x = local_max_x[0];\n result.min_y = local_min_y[0];\n result.max_y = local_max_y[0];\n }\n}\n`;\n\n// ============================================\n// Downsample Compute Shader (Min-Max per bucket)\n// ============================================\n\nexport const DOWNSAMPLE_COMPUTE_WGSL = `\nstruct Params {\n input_count: u32,\n output_count: u32,\n bucket_size: u32,\n padding: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> input_points: array<vec2<f32>>;\n@group(0) @binding(2) var<storage, read_write> output_points: array<vec2<f32>>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) global_id: vec3<u32>) {\n let bucket_idx = global_id.x;\n \n if (bucket_idx >= params.output_count / 2u) {\n return;\n }\n \n let start = bucket_idx * params.bucket_size;\n let end = min(start + params.bucket_size, params.input_count);\n \n if (start >= params.input_count) {\n return;\n }\n \n var min_y = input_points[start].y;\n var max_y = input_points[start].y;\n var min_idx = start;\n var max_idx = start;\n \n for (var i = start; i < end; i = i + 1u) {\n let y = input_points[i].y;\n if (y < min_y) {\n min_y = y;\n min_idx = i;\n }\n if (y > max_y) {\n max_y = y;\n max_idx = i;\n }\n }\n \n // Output min and max points (preserving x,y pairs)\n let out_base = bucket_idx * 2u;\n \n // Ensure min comes before max in x order\n if (min_idx <= max_idx) {\n output_points[out_base] = input_points[min_idx];\n output_points[out_base + 1u] = input_points[max_idx];\n } else {\n output_points[out_base] = input_points[max_idx];\n output_points[out_base + 1u] = input_points[min_idx];\n }\n}\n`;\n\n// ============================================\n// Peak Detection Compute Shader\n// ============================================\n\nexport const PEAK_DETECT_COMPUTE_WGSL = `\nstruct Params {\n data_count: u32,\n threshold: f32,\n min_distance: u32,\n padding: u32,\n}\n\nstruct Peak {\n index: u32,\n value: f32,\n is_peak: u32,\n padding: u32,\n}\n\n@group(0) @binding(0) var<uniform> params: Params;\n@group(0) @binding(1) var<storage, read> data: array<f32>;\n@group(0) @binding(2) var<storage, read_write> peaks: array<Peak>;\n\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) global_id: vec3<u32>) {\n let idx = global_id.x;\n \n if (idx >= params.data_count) {\n return;\n }\n \n peaks[idx].index = idx;\n peaks[idx].value = data[idx];\n peaks[idx].is_peak = 0u;\n \n // Skip edges\n if (idx < params.min_distance || idx >= params.data_count - params.min_distance) {\n return;\n }\n \n let val = data[idx];\n \n // Check if above threshold\n if (val < params.threshold) {\n return;\n }\n \n // Check if local maximum\n var is_max = true;\n for (var i = 1u; i <= params.min_distance; i = i + 1u) {\n if (data[idx - i] >= val || data[idx + i] >= val) {\n is_max = false;\n break;\n }\n }\n \n if (is_max) {\n peaks[idx].is_peak = 1u;\n }\n}\n`;\n","/**\n * GPU Compute Engine\n * \n * Provides GPU-accelerated data analysis using WebGPU compute shaders.\n * Includes statistics calculation, bounds computation, downsampling, and peak detection.\n */\n\nimport {\n STATS_COMPUTE_WGSL,\n MINMAX_COMPUTE_WGSL,\n DOWNSAMPLE_COMPUTE_WGSL,\n PEAK_DETECT_COMPUTE_WGSL,\n} from \"./shaders\";\n\nexport interface DataStats {\n min: number;\n max: number;\n mean: number;\n std: number;\n count: number;\n}\n\nexport interface DataBounds {\n xMin: number;\n xMax: number;\n yMin: number;\n yMax: number;\n}\n\nexport interface Peak {\n index: number;\n value: number;\n}\n\nexport interface GpuComputeOptions {\n /** WebGPU device (if already available) */\n device?: any;\n}\n\n/**\n * GPU Compute Engine for data analysis\n */\nexport class GpuCompute {\n private device: any = null;\n private statsPipeline: any = null;\n private minmaxPipeline: any = null;\n private downsamplePipeline: any = null;\n private peaksPipeline: any = null;\n \n private isInitialized = false;\n \n constructor(private options: GpuComputeOptions = {}) {}\n \n /**\n * Check if GPU compute is available\n */\n static isSupported(): boolean {\n return (\n typeof (globalThis as any).navigator !== \"undefined\" &&\n typeof (globalThis as any).navigator.gpu !== \"undefined\"\n );\n }\n \n /**\n * Initialize the compute engine\n */\n async init(): Promise<void> {\n if (this.options.device) {\n this.device = this.options.device;\n } else {\n if (!GpuCompute.isSupported()) {\n throw new Error(\"[GpuCompute] WebGPU not supported\");\n }\n \n const gpu = (globalThis as any).navigator.gpu;\n const adapter = await gpu.requestAdapter({ powerPreference: \"high-performance\" });\n if (!adapter) {\n throw new Error(\"[GpuCompute] Failed to get adapter\");\n }\n \n this.device = await adapter.requestDevice();\n }\n \n // Create pipelines\n await this.createPipelines();\n this.isInitialized = true;\n }\n \n private async createPipelines(): Promise<void> {\n // Stats pipeline\n const statsModule = this.device.createShaderModule({ code: STATS_COMPUTE_WGSL });\n this.statsPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: statsModule, entryPoint: \"main\" },\n });\n \n // MinMax pipeline\n const minmaxModule = this.device.createShaderModule({ code: MINMAX_COMPUTE_WGSL });\n this.minmaxPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: minmaxModule, entryPoint: \"main\" },\n });\n \n // Downsample pipeline\n const downsampleModule = this.device.createShaderModule({ code: DOWNSAMPLE_COMPUTE_WGSL });\n this.downsamplePipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: downsampleModule, entryPoint: \"main\" },\n });\n \n // Peak detection pipeline\n const peaksModule = this.device.createShaderModule({ code: PEAK_DETECT_COMPUTE_WGSL });\n this.peaksPipeline = await this.device.createComputePipelineAsync({\n layout: \"auto\",\n compute: { module: peaksModule, entryPoint: \"main\" },\n });\n }\n \n /**\n * Calculate statistics for a 1D array of values\n */\n async calculateStats(data: Float32Array): Promise<DataStats> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create input buffer\n const inputBuffer = this.device.createBuffer({\n size: data.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, data);\n \n // Create result buffer (32 bytes: 5 floats + padding)\n const resultBuffer = this.device.createBuffer({\n size: 32,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Create staging buffer for readback\n const stagingBuffer = this.device.createBuffer({\n size: 32,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Create bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.statsPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: inputBuffer } },\n { binding: 1, resource: { buffer: resultBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.statsPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(data.length / 256);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n // Copy result to staging\n encoder.copyBufferToBuffer(resultBuffer, 0, stagingBuffer, 0, 32);\n \n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultData = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n inputBuffer.destroy();\n resultBuffer.destroy();\n stagingBuffer.destroy();\n \n const [min, max, sum, sumSq, countFloat] = resultData;\n const count = Math.floor(countFloat);\n const mean = count > 0 ? sum / count : 0;\n const variance = count > 1 ? (sumSq - (sum * sum) / count) / (count - 1) : 0;\n const std = Math.sqrt(Math.max(0, variance));\n \n return { min, max, mean, std, count };\n }\n \n /**\n * Calculate bounds for 2D point data\n */\n async calculateBounds(points: Float32Array): Promise<DataBounds> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create input buffer (vec2 array)\n const inputBuffer = this.device.createBuffer({\n size: points.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, points);\n \n // Create result buffer (16 bytes: 4 floats)\n const resultBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.minmaxPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: inputBuffer } },\n { binding: 1, resource: { buffer: resultBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.minmaxPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const pointCount = points.length / 2;\n const workgroups = Math.ceil(pointCount / 256);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(resultBuffer, 0, stagingBuffer, 0, 16);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultData = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n inputBuffer.destroy();\n resultBuffer.destroy();\n stagingBuffer.destroy();\n \n return {\n xMin: resultData[0],\n xMax: resultData[1],\n yMin: resultData[2],\n yMax: resultData[3],\n };\n }\n \n /**\n * Downsample point data using min-max algorithm\n */\n async downsample(\n points: Float32Array,\n targetCount: number\n ): Promise<Float32Array> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const pointCount = points.length / 2;\n if (pointCount <= targetCount) {\n return points; // No downsampling needed\n }\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Calculate bucket size (output is 2 points per bucket: min and max)\n const outputPairs = Math.ceil(targetCount / 2);\n const bucketSize = Math.ceil(pointCount / outputPairs);\n const outputCount = outputPairs * 2;\n \n // Create params buffer\n const paramsData = new Uint32Array([pointCount, outputCount, bucketSize, 0]);\n const paramsBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(paramsBuffer, 0, paramsData);\n \n // Create input buffer\n const inputBuffer = this.device.createBuffer({\n size: points.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, points);\n \n // Create output buffer\n const outputSize = outputCount * 2 * 4; // vec2 * count * sizeof(float)\n const outputBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.downsamplePipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: paramsBuffer } },\n { binding: 1, resource: { buffer: inputBuffer } },\n { binding: 2, resource: { buffer: outputBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.downsamplePipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(outputPairs / 64);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(outputBuffer, 0, stagingBuffer, 0, outputSize);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const result = new Float32Array(stagingBuffer.getMappedRange().slice(0));\n stagingBuffer.unmap();\n \n // Cleanup\n paramsBuffer.destroy();\n inputBuffer.destroy();\n outputBuffer.destroy();\n stagingBuffer.destroy();\n \n return result;\n }\n \n /**\n * Detect peaks in 1D data\n */\n async detectPeaks(\n data: Float32Array,\n options: { threshold?: number; minDistance?: number } = {}\n ): Promise<Peak[]> {\n if (!this.isInitialized) {\n throw new Error(\"[GpuCompute] Not initialized\");\n }\n \n const threshold = options.threshold ?? 0;\n const minDistance = options.minDistance ?? 1;\n \n const GPUBufferUsage = (globalThis as any).GPUBufferUsage;\n \n // Create params buffer\n const paramsData = new Float32Array([\n data.length,\n threshold,\n minDistance,\n 0, // padding\n ]);\n const paramsBuffer = this.device.createBuffer({\n size: 16,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(paramsBuffer, 0, new Uint8Array(paramsData.buffer));\n \n // Input buffer\n const inputBuffer = this.device.createBuffer({\n size: data.byteLength,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST,\n });\n this.device.queue.writeBuffer(inputBuffer, 0, data);\n \n // Output buffer (Peak struct = 16 bytes each)\n const outputSize = data.length * 16;\n const outputBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,\n });\n \n // Staging buffer\n const stagingBuffer = this.device.createBuffer({\n size: outputSize,\n usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,\n });\n \n // Bind group\n const bindGroup = this.device.createBindGroup({\n layout: this.peaksPipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: { buffer: paramsBuffer } },\n { binding: 1, resource: { buffer: inputBuffer } },\n { binding: 2, resource: { buffer: outputBuffer } },\n ],\n });\n \n // Dispatch\n const encoder = this.device.createCommandEncoder();\n const pass = encoder.beginComputePass();\n pass.setPipeline(this.peaksPipeline);\n pass.setBindGroup(0, bindGroup);\n \n const workgroups = Math.ceil(data.length / 64);\n pass.dispatchWorkgroups(workgroups);\n pass.end();\n \n encoder.copyBufferToBuffer(outputBuffer, 0, stagingBuffer, 0, outputSize);\n this.device.queue.submit([encoder.finish()]);\n \n // Read back\n await stagingBuffer.mapAsync((globalThis as any).GPUMapMode.READ);\n const resultBuffer = new ArrayBuffer(outputSize);\n new Uint8Array(resultBuffer).set(new Uint8Array(stagingBuffer.getMappedRange()));\n stagingBuffer.unmap();\n \n // Parse peaks\n const resultView = new DataView(resultBuffer);\n const peaks: Peak[] = [];\n \n for (let i = 0; i < data.length; i++) {\n const offset = i * 16;\n const isPeak = resultView.getUint32(offset + 8, true);\n \n if (isPeak) {\n peaks.push({\n index: resultView.getUint32(offset, true),\n value: resultView.getFloat32(offset + 4, true),\n });\n }\n }\n \n // Cleanup\n paramsBuffer.destroy();\n inputBuffer.destroy();\n outputBuffer.destroy();\n stagingBuffer.destroy();\n \n return peaks;\n }\n \n /**\n * Cleanup resources\n */\n destroy(): void {\n // Pipelines are managed by device, no explicit cleanup needed\n this.device = null;\n this.statsPipeline = null;\n this.minmaxPipeline = null;\n this.downsamplePipeline = null;\n this.peaksPipeline = null;\n this.isInitialized = false;\n }\n}\n","/**\n * VeloPlot Engine - GPU Abstraction Plugin\n * \n * Provides WebGPU and WebGL2 backend support, GPU compute capabilities,\n * and performance benchmarking tools.\n * \n * @module plugins/gpu\n */\n\nexport {\n // Backends\n WebGPUBackend,\n WebGLBackend,\n\n // Renderer facade\n GpuRenderer,\n createGpuRenderer,\n\n // Adapter\n SeriesAdapter,\n parseColorToRGBA,\n\n // Resource management\n PipelineCache,\n BaseBufferStore,\n BaseTextureStore,\n\n // Benchmark\n GpuBenchmark,\n\n // GPU Compute\n GpuCompute,\n} from \"../../gpu\";\n\nexport * from \"../../gpu/types\";\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginGpuConfig {\n /** Preferred backend: 'webgpu' | 'webgl2' | 'webgl1' */\n preferredBackend?: string;\n /** Enable hardware acceleration for compute tasks */\n enableCompute?: boolean;\n}\n\nconst manifestGpu: PluginManifest = {\n name: \"velo-plot-gpu\",\n version: \"1.0.0\",\n description: \"GPU acceleration and WebGPU support for velo-plot\",\n provides: [\"renderer\", \"compute\"],\n tags: [\"gpu\", \"webgpu\", \"webgl2\", \"performance\"],\n};\n\n/**\n * VeloPlot GPU Plugin\n * \n * Enables high-performance GPU-accelerated rendering and compute.\n */\nexport function PluginGpu(_config: PluginGpuConfig = {}): ChartPlugin<PluginGpuConfig> {\n return {\n manifest: manifestGpu,\n\n onInit(_ctx: PluginContext) {\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport default PluginGpu;\n"],"names":["BaseBufferStore","__publicField","id","BaseTextureStore","keyToString","key","PipelineCache","factory","keyStr","pipeline","GpuBenchmark","canvas","pointCount","data","i","renderFn","durationMs","warmupFrames","onProgress","frameTimes","lastTime","warmupCount","startTime","resolve","loop","now","elapsed","progress","options","WebGPUBackend","n","backend","drawList","frame","bounds","duration","result","WebGLBackend","avg","a","b","min","max","webgpu","webgl","winner","speedup","STATS_COMPUTE_WGSL","MINMAX_COMPUTE_WGSL","DOWNSAMPLE_COMPUTE_WGSL","PEAK_DETECT_COMPUTE_WGSL","GpuCompute","adapter","statsModule","minmaxModule","downsampleModule","peaksModule","GPUBufferUsage","inputBuffer","resultBuffer","stagingBuffer","bindGroup","encoder","pass","workgroups","resultData","sum","sumSq","countFloat","count","mean","variance","std","points","targetCount","outputPairs","bucketSize","outputCount","paramsData","paramsBuffer","outputSize","outputBuffer","threshold","minDistance","resultView","peaks","offset","manifestGpu","PluginGpu","_config","_ctx"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChartPlugin } from '../types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* VeloPlot Engine - Internationalization (i18n) Plugin
|
|
4
4
|
*
|
|
5
5
|
* Provides localization support for dates, numbers, and strings.
|
|
6
6
|
*
|
|
@@ -14,7 +14,7 @@ export interface PluginI18nConfig {
|
|
|
14
14
|
customLocales?: Record<string, any>;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* VeloPlot i18n Plugin
|
|
18
18
|
*
|
|
19
19
|
* Adds support for multiple languages and local data formatting.
|
|
20
20
|
*/
|
package/dist/plugins/i18n.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './i18n/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './i18n/index'
|
|
3
|
+
export default VeloPlot
|
package/dist/plugins/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.js","sources":["../../src/plugins/i18n/index.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"file":"i18n.js","sources":["../../src/plugins/i18n/index.ts"],"sourcesContent":["/**\n * VeloPlot Engine - Internationalization (i18n) Plugin\n * \n * Provides localization support for dates, numbers, and strings.\n * \n * @module plugins/i18n\n */\n\nexport * from \"../../core/locale\";\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\nimport { setGlobalLocale } from \"../../core/locale\";\n\nexport interface PluginI18nConfig {\n /** Default locale to use */\n locale?: string;\n /** Custom locale definitions */\n customLocales?: Record<string, any>;\n}\n\nconst manifestI18n: PluginManifest = {\n name: \"velo-plot-i18n\",\n version: \"1.0.0\",\n description: \"Internationalization and localization for velo-plot\",\n provides: [\"ui\"],\n tags: [\"i18n\", \"l10n\", \"locale\", \"language\"],\n};\n\n/**\n * VeloPlot i18n Plugin\n * \n * Adds support for multiple languages and local data formatting.\n */\nexport function PluginI18n(config: PluginI18nConfig = {}): ChartPlugin<PluginI18nConfig> {\n return {\n manifest: manifestI18n,\n\n onInit(_ctx: PluginContext) {\n if (config.locale) {\n setGlobalLocale(config.locale);\n }\n },\n\n onDestroy(_ctx: PluginContext) {\n }\n };\n}\n\nexport default PluginI18n;\n"],"names":["manifestI18n","PluginI18n","config","_ctx","setGlobalLocale"],"mappings":";;AAoBA,MAAMA,IAA+B;AAAA,EACjC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,IAAI;AAAA,EACf,MAAM,CAAC,QAAQ,QAAQ,UAAU,UAAU;AAC/C;AAOO,SAASC,EAAWC,IAA2B,IAAmC;AACrF,SAAO;AAAA,IACH,UAAUF;AAAA,IAEV,OAAOG,GAAqB;AACxB,MAAID,EAAO,UACPE,EAAgBF,EAAO,MAAM;AAAA,IAErC;AAAA,IAEA,UAAUC,GAAqB;AAAA,IAC/B;AAAA,EAAA;AAER;"}
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './keyboard/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './keyboard/index'
|
|
3
|
+
export default VeloPlot
|
package/dist/plugins/keyboard.js
CHANGED
|
@@ -1,8 +1,68 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { K as c } from "../index-CWxIHdwX.js";
|
|
2
|
+
import { D as y } from "../index-CWxIHdwX.js";
|
|
3
|
+
const u = {
|
|
4
|
+
name: "velo-plot-keyboard",
|
|
5
|
+
version: "1.0.0",
|
|
6
|
+
description: "Keyboard shortcut management for velo-plot",
|
|
7
|
+
provides: ["interaction"],
|
|
8
|
+
tags: ["keyboard", "shortcuts", "interaction", "accessibility"]
|
|
9
|
+
};
|
|
10
|
+
function p(s = {}) {
|
|
11
|
+
let a = null;
|
|
12
|
+
return {
|
|
13
|
+
manifest: u,
|
|
14
|
+
onInit(l) {
|
|
15
|
+
var i;
|
|
16
|
+
const o = l.chart, t = (i = l.getPlugin) == null ? void 0 : i.call(l, "velo-plot-drawing-tools");
|
|
17
|
+
a = new c({
|
|
18
|
+
target: l.ui.container,
|
|
19
|
+
bindings: [...s.bindings ?? [], ...s.extraShortcuts ?? []],
|
|
20
|
+
replaceDefaults: s.replaceDefaults,
|
|
21
|
+
callbacks: {
|
|
22
|
+
onResetZoom: () => {
|
|
23
|
+
var e;
|
|
24
|
+
return (e = o.resetZoom) == null ? void 0 : e.call(o);
|
|
25
|
+
},
|
|
26
|
+
onAutoScale: () => {
|
|
27
|
+
var e;
|
|
28
|
+
return (e = o.autoScale) == null ? void 0 : e.call(o, !1);
|
|
29
|
+
},
|
|
30
|
+
onEscape: () => {
|
|
31
|
+
var e;
|
|
32
|
+
return (e = o.clearSelection) == null ? void 0 : e.call(o);
|
|
33
|
+
},
|
|
34
|
+
onExportImage: () => {
|
|
35
|
+
var e;
|
|
36
|
+
try {
|
|
37
|
+
const n = (e = o.exportImage) == null ? void 0 : e.call(o, "png");
|
|
38
|
+
if (n) {
|
|
39
|
+
const r = document.createElement("a");
|
|
40
|
+
r.href = n, r.download = "chart.png", r.click();
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
onUndo: () => {
|
|
46
|
+
var e, n;
|
|
47
|
+
return (n = (e = t == null ? void 0 : t.api) == null ? void 0 : e.undo) == null ? void 0 : n.call(e);
|
|
48
|
+
},
|
|
49
|
+
onRedo: () => {
|
|
50
|
+
var e, n;
|
|
51
|
+
return (n = (e = t == null ? void 0 : t.api) == null ? void 0 : e.redo) == null ? void 0 : n.call(e);
|
|
52
|
+
},
|
|
53
|
+
...s.callbacks
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
onDestroy() {
|
|
58
|
+
a == null || a.destroy(), a = null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
2
62
|
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
63
|
+
y as DEFAULT_KEY_BINDINGS,
|
|
64
|
+
c as KeyBindingManager,
|
|
65
|
+
p as PluginKeyboard,
|
|
66
|
+
p as default
|
|
7
67
|
};
|
|
8
68
|
//# sourceMappingURL=keyboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
1
|
+
{"version":3,"file":"keyboard.js","sources":["../../src/plugins/keyboard/index.ts"],"sourcesContent":["/**\n * Velo Plot - Keyboard Shortcuts Plugin\n */\n\nimport { KeyBindingManager, DEFAULT_KEY_BINDINGS } from \"../../core/keybindings\";\nimport type { KeyBinding, KeyBindingManagerOptions } from \"../../core/keybindings\";\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\n\nexport interface PluginKeyboardConfig extends Partial<KeyBindingManagerOptions> {\n extraShortcuts?: KeyBinding[];\n}\n\nconst manifestKeyboard: PluginManifest = {\n name: \"velo-plot-keyboard\",\n version: \"1.0.0\",\n description: \"Keyboard shortcut management for velo-plot\",\n provides: [\"interaction\"],\n tags: [\"keyboard\", \"shortcuts\", \"interaction\", \"accessibility\"],\n};\n\nexport function PluginKeyboard(config: PluginKeyboardConfig = {}): ChartPlugin<PluginKeyboardConfig> {\n let manager: KeyBindingManager | null = null;\n\n return {\n manifest: manifestKeyboard,\n\n onInit(ctx: PluginContext) {\n const chart = ctx.chart as any;\n const drawing = ctx.getPlugin?.(\"velo-plot-drawing-tools\") as { api?: { undo?: () => boolean; redo?: () => boolean } } | undefined;\n\n manager = new KeyBindingManager({\n target: ctx.ui.container,\n bindings: [...(config.bindings ?? []), ...(config.extraShortcuts ?? [])],\n replaceDefaults: config.replaceDefaults,\n callbacks: {\n onResetZoom: () => chart.resetZoom?.(),\n onAutoScale: () => chart.autoScale?.(false),\n onEscape: () => chart.clearSelection?.(),\n onExportImage: () => {\n try {\n const url = chart.exportImage?.(\"png\");\n if (url) {\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = \"chart.png\";\n a.click();\n }\n } catch {\n /* ignore */\n }\n },\n onUndo: () => drawing?.api?.undo?.(),\n onRedo: () => drawing?.api?.redo?.(),\n ...config.callbacks,\n },\n });\n },\n\n onDestroy() {\n manager?.destroy();\n manager = null;\n },\n };\n}\n\nexport { KeyBindingManager, DEFAULT_KEY_BINDINGS };\nexport default PluginKeyboard;\n"],"names":["manifestKeyboard","PluginKeyboard","config","manager","ctx","chart","drawing","_a","KeyBindingManager","url","a","_b"],"mappings":";;AAYA,MAAMA,IAAmC;AAAA,EACvC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,UAAU,CAAC,aAAa;AAAA,EACxB,MAAM,CAAC,YAAY,aAAa,eAAe,eAAe;AAChE;AAEO,SAASC,EAAeC,IAA+B,IAAuC;AACnG,MAAIC,IAAoC;AAExC,SAAO;AAAA,IACL,UAAUH;AAAA,IAEV,OAAOI,GAAoB;;AACzB,YAAMC,IAAQD,EAAI,OACZE,KAAUC,IAAAH,EAAI,cAAJ,gBAAAG,EAAA,KAAAH,GAAgB;AAEhC,MAAAD,IAAU,IAAIK,EAAkB;AAAA,QAC9B,QAAQJ,EAAI,GAAG;AAAA,QACf,UAAU,CAAC,GAAIF,EAAO,YAAY,CAAA,GAAK,GAAIA,EAAO,kBAAkB,EAAG;AAAA,QACvE,iBAAiBA,EAAO;AAAA,QACxB,WAAW;AAAA,UACT,aAAa,MAAA;;AAAM,oBAAAK,IAAAF,EAAM,cAAN,gBAAAE,EAAA,KAAAF;AAAA;AAAA,UACnB,aAAa,MAAA;;AAAM,oBAAAE,IAAAF,EAAM,cAAN,gBAAAE,EAAA,KAAAF,GAAkB;AAAA;AAAA,UACrC,UAAU,MAAA;;AAAM,oBAAAE,IAAAF,EAAM,mBAAN,gBAAAE,EAAA,KAAAF;AAAA;AAAA,UAChB,eAAe,MAAM;;AACnB,gBAAI;AACF,oBAAMI,KAAMF,IAAAF,EAAM,gBAAN,gBAAAE,EAAA,KAAAF,GAAoB;AAChC,kBAAII,GAAK;AACP,sBAAMC,IAAI,SAAS,cAAc,GAAG;AACpC,gBAAAA,EAAE,OAAOD,GACTC,EAAE,WAAW,aACbA,EAAE,MAAA;AAAA,cACJ;AAAA,YACF,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,UACA,QAAQ,MAAA;;AAAM,oBAAAC,KAAAJ,IAAAD,KAAA,gBAAAA,EAAS,QAAT,gBAAAC,EAAc,SAAd,gBAAAI,EAAA,KAAAJ;AAAA;AAAA,UACd,QAAQ,MAAA;;AAAM,oBAAAI,KAAAJ,IAAAD,KAAA,gBAAAA,EAAS,QAAT,gBAAAC,EAAc,SAAd,gBAAAI,EAAA,KAAAJ;AAAA;AAAA,UACd,GAAGL,EAAO;AAAA,QAAA;AAAA,MACZ,CACD;AAAA,IACH;AAAA,IAEA,YAAY;AACV,MAAAC,KAAA,QAAAA,EAAS,WACTA,IAAU;AAAA,IACZ;AAAA,EAAA;AAEJ;"}
|