velo-plot 2.20.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-ivzLqxVb.js → ChartCore-BpzRvN4Y.js} +978 -861
- 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/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/ChartCore.d.ts +2 -2
- package/dist/core/chart/types.d.ts +1 -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/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-BBpJwOct.js → index-0InEyj0q.js} +119 -121
- 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-CaXWSOTk.js.map +1 -1
- package/dist/index-Dag88bW4.js.map +1 -1
- package/dist/index-qhscKTDy.js.map +1 -1
- package/dist/index-qunX30Xu.js.map +1 -1
- package/dist/index-x4stH3jD.js.map +1 -1
- package/dist/{index.core-COREBDNq.js → index.core-BmZe2jRQ.js} +9 -9
- package/dist/index.core-BmZe2jRQ.js.map +1 -0
- package/dist/index.core.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/indicators--eJGmVox.js.map +1 -1
- package/dist/{mockDatafeed-927foCM4.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/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 +2 -2
- 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/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/index.d.ts +1 -1
- 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.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.d.ts +2 -2
- package/dist/plugins/ml-integration.js +5 -5
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/offscreen.d.ts +2 -2
- package/dist/plugins/pattern-recognition.d.ts +2 -2
- package/dist/plugins/pattern-recognition.js +1 -1
- 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.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.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/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/testing/index.d.ts +1 -1
- package/dist/theme/index.d.ts +2 -1
- package/dist/trading.js +6 -6
- 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 +452 -443
- 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 +2 -0
- package/dist/workers/pool.d.ts +9 -0
- package/package.json +88 -10
- package/dist/ChartCore-ivzLqxVb.js.map +0 -1
- package/dist/SciPlot-CEU4ApgD.js +0 -463
- package/dist/SciPlot-CEU4ApgD.js.map +0 -1
- package/dist/createStackedChart-DxNW0VkF.js +0 -705
- package/dist/createStackedChart-DxNW0VkF.js.map +0 -1
- package/dist/index-BBpJwOct.js.map +0 -1
- package/dist/index-DoYxf1cV.js.map +0 -1
- package/dist/index.core-COREBDNq.js.map +0 -1
- package/dist/mockDatafeed-927foCM4.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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createStackedChart-DxNW0VkF.js","sources":["../src/core/stacked/types.ts","../src/core/stacked/stackExport.ts","../src/core/stacked/paneResize.ts","../src/core/stacked/paneAxis.ts","../src/core/stacked/createStackedChart.ts"],"sourcesContent":["import type { Chart } from \"../chart/types\";\nimport type { ChartGroup } from \"../sync\";\nimport type { SyncAxis, SyncOptions } from \"../sync\";\nimport type { ChartOptions as RootChartOptions, Range, SeriesOptions } from \"../../types\";\nimport type { LayoutOptions } from \"../layout\";\nimport type { AddIndicatorResult } from \"../indicator/addIndicator\";\n\n/** Stack layout direction */\nexport type StackDirection = \"vertical\" | \"horizontal\";\n\n/** Per-pane configuration (max 5 panes per stack) */\nexport interface StackedPaneConfig {\n id: string;\n /** Flex ratio (e.g. 0.6) or CSS length (\"24%\", \"80px\") — height ratio when vertical, width ratio when horizontal */\n height: number | string;\n /** Chart options excluding container/id (series added via chart API or `series`) */\n chart?: Omit<RootChartOptions, \"container\" | \"id\">;\n /** Series to add immediately after pane chart is created */\n series?: SeriesOptions[];\n /** Show native X axis (default: only bottom pane when vertical + sharedXAxis; each pane when horizontal) */\n showXAxis?: boolean;\n /** Show native Y axis (default: only first pane when horizontal + sharedYAxis) */\n showYAxis?: boolean;\n /** Receive pan/zoom (default: true on every pane) */\n interactive?: boolean;\n /** Lock Y range — skips auto fit on Y for this pane */\n yRange?: Range | \"auto\";\n}\n\nexport interface StackedChartOptions {\n /** Root container (will be cleared and filled with pane layout) */\n container: HTMLDivElement;\n /** 1–5 stacked panes */\n panes: StackedPaneConfig[];\n /** Layout direction (default: vertical — panes top to bottom) */\n direction?: StackDirection;\n /** Pane that drives sync (default: first pane) */\n masterPaneId?: string;\n /** Shared date/time row on bottom pane only (vertical layout) */\n sharedXAxis?: \"bottom\" | \"none\";\n /** Shared Y axis on left pane only (horizontal layout) */\n sharedYAxis?: \"left\" | \"none\";\n /** Shared theme applied to every pane */\n theme?: string | object;\n devicePixelRatio?: number;\n /** Gap between panes in CSS pixels (default: 0) */\n gap?: number;\n /** Enable VS Code–style drag resize between panes (default: false) */\n resizable?:\n | boolean\n | {\n /** Min pane height as fraction of available stack height (default: 1/6) */\n minPaneRatio?: number;\n /** Absolute min pane height in px — overrides ratio when larger */\n minPanePx?: number;\n dividerSize?: number;\n };\n /** Show legend on panes (default: false — set true on stack or per-pane chart) */\n showLegend?: boolean;\n /**\n * Pan/zoom sync between panes.\n * Default: X-axis sync via master pane (`axis: 'x'`, Y independent).\n * Pass `false` for fully independent panes.\n */\n sync?: boolean | StackedSyncOptions;\n /** Shared margin overrides — left/right aligned automatically across panes */\n layout?: Partial<LayoutOptions>;\n}\n\nexport interface StackedChart {\n readonly container: HTMLDivElement;\n getPane(id: string): Chart | undefined;\n getPanes(): Chart[];\n getMaster(): Chart;\n getGroup(): ChartGroup;\n fitAll(options?: { x?: Range; padding?: number }): void;\n resetAll(): void;\n resize(): void;\n /** Current flex ratios keyed by pane id */\n getPaneRatios(): Record<string, number>;\n /** Set flex ratios (same keys as pane ids); triggers resize */\n setPaneRatios(ratios: Record<string, number>): void;\n /** Sync axis mode: `x` (default), `y`, `xy`, or `none` */\n setSyncAxis(axis: SyncAxis): void;\n getSyncAxis(): SyncAxis;\n /** Update pan/zoom/cursor sync options at runtime */\n setSyncOptions(options: Partial<StackedSyncOptions>): void;\n /** Resolves when all pane charts have started rendering */\n whenReady(): Promise<void>;\n /** Append a pane at runtime (max 5 panes) */\n addPane(pane: StackedPaneConfig): Chart;\n /** Calculate + mount indicator pane or overlay on master price chart */\n addIndicator(\n preset: import(\"../indicator/addIndicator\").IndicatorPresetName,\n options?: import(\"../indicator/addIndicator\").AddIndicatorOptions,\n ): Promise<AddIndicatorResult & { paneId?: string; chart?: Chart }>;\n /** Export the entire stack as one PNG/JPEG/WebP image (WYSIWYG layout) */\n exportImage(options?: StackSnapshotOptions): Promise<string>;\n /** Alias for exportImage */\n snapshot(options?: StackSnapshotOptions): Promise<string>;\n destroy(): void;\n}\n\nexport const STACKED_MAX_PANES = 5;\n/** Default minimum pane height as a fraction of available stack height (1/6). */\nexport const STACKED_DEFAULT_MIN_PANE_RATIO = 1 / 6;\nexport const STACKED_COMPACT_MARGIN = { top: 4, bottom: 8, left: 4 };\nexport const STACKED_FULL_X_MARGIN = { bottom: 55 };\nexport const STACKED_FULL_Y_MARGIN = { left: 55 };\n\n/** Options for full-stack image export */\nexport type StackSnapshotFormat = \"png\" | \"jpeg\" | \"webp\";\nexport type StackSnapshotResolution = \"standard\" | \"2k\" | \"4k\" | \"8k\" | number;\n\nexport interface StackSnapshotOptions {\n format?: StackSnapshotFormat;\n quality?: number;\n resolution?: StackSnapshotResolution;\n includeBackground?: boolean;\n includeDividers?: boolean;\n transparent?: boolean;\n download?: boolean;\n fileName?: string;\n}\n\n/** Pan/zoom sync between stacked panes (Y stays independent when axis is `x`). */\nexport type StackedSyncOptions = Pick<\n SyncOptions,\n | \"axis\"\n | \"syncCursor\"\n | \"syncSelection\"\n | \"syncZoom\"\n | \"syncPan\"\n | \"bidirectional\"\n | \"debounce\"\n>;\n","/**\n * Full-stack snapshot export — composes all pane charts at exact layout positions.\n */\n\nimport type { Chart } from \"../chart/types\";\n\nexport type StackExportFormat = \"png\" | \"jpeg\" | \"webp\";\nexport type StackExportResolution = \"standard\" | \"2k\" | \"4k\" | \"8k\" | number;\n\nexport interface StackExportOptions {\n format?: StackExportFormat;\n quality?: number;\n resolution?: StackExportResolution;\n includeBackground?: boolean;\n includeDividers?: boolean;\n transparent?: boolean;\n}\n\n/** @internal Exported for unit tests */\nexport function stackResolutionScale(res: StackExportResolution): number {\n if (typeof res === \"number\") return res;\n switch (res) {\n case \"8k\":\n return 8;\n case \"4k\":\n return 4;\n case \"2k\":\n return 2;\n default:\n return 1;\n }\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = reject;\n img.src = src;\n });\n}\n\nfunction relativeRect(\n el: HTMLElement,\n containerRect: DOMRect,\n): { x: number; y: number; width: number; height: number } {\n const r = el.getBoundingClientRect();\n return {\n x: r.left - containerRect.left,\n y: r.top - containerRect.top,\n width: r.width,\n height: r.height,\n };\n}\n\n/**\n * Compose every pane chart into one raster image matching the on-screen stack layout.\n */\nexport async function exportStackImage(\n container: HTMLDivElement,\n paneWrappers: HTMLDivElement[],\n paneCharts: Chart[],\n dividers: HTMLDivElement[],\n backgroundColor: string,\n options: StackExportOptions = {},\n): Promise<string> {\n const {\n format = \"png\",\n quality = 0.92,\n resolution = \"standard\",\n includeBackground = true,\n includeDividers = true,\n transparent = false,\n } = options;\n\n const scale = stackResolutionScale(resolution);\n const baseDpr = paneCharts[0]?.getDPR() ?? (typeof window !== \"undefined\" ? window.devicePixelRatio : 1);\n const exportDpr = baseDpr * scale;\n const originalDprs = paneCharts.map((c) => c.getDPR());\n\n try {\n if (scale > 1) {\n for (const chart of paneCharts) {\n // Lock the DPR so the enlarged backing store survives the resize() that\n // setDPR/exportImage would otherwise revert (see ChartCore.resize).\n if (typeof chart.setDevicePixelRatioOverride === \"function\") {\n chart.setDevicePixelRatioOverride(exportDpr);\n } else {\n chart.setDPR(exportDpr);\n }\n chart.render();\n }\n await new Promise((r) => requestAnimationFrame(r));\n await new Promise((r) => requestAnimationFrame(r));\n await new Promise((r) => setTimeout(r, 50));\n }\n\n const containerRect = container.getBoundingClientRect();\n const outW = Math.max(1, Math.round(containerRect.width * exportDpr));\n const outH = Math.max(1, Math.round(containerRect.height * exportDpr));\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = outW;\n canvas.height = outH;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Failed to create export canvas\");\n\n if (!transparent && includeBackground) {\n ctx.fillStyle = backgroundColor || \"#ffffff\";\n ctx.fillRect(0, 0, outW, outH);\n }\n\n const imageType = format === \"jpeg\" ? \"jpeg\" : \"png\";\n\n for (let i = 0; i < paneWrappers.length; i++) {\n const rect = relativeRect(paneWrappers[i], containerRect);\n const dataUrl = paneCharts[i].exportImage(imageType);\n const img = await loadImage(dataUrl);\n ctx.drawImage(\n img,\n Math.round(rect.x * exportDpr),\n Math.round(rect.y * exportDpr),\n Math.round(rect.width * exportDpr),\n Math.round(rect.height * exportDpr),\n );\n }\n\n if (includeDividers && dividers.length) {\n ctx.fillStyle = \"rgba(128, 128, 128, 0.35)\";\n for (const divider of dividers) {\n const rect = relativeRect(divider, containerRect);\n ctx.fillRect(\n Math.round(rect.x * exportDpr),\n Math.round(rect.y * exportDpr),\n Math.max(1, Math.round(rect.width * exportDpr)),\n Math.max(1, Math.round(rect.height * exportDpr)),\n );\n }\n }\n\n const mime = format === \"jpeg\" ? \"image/jpeg\" : format === \"webp\" ? \"image/webp\" : \"image/png\";\n return canvas.toDataURL(mime, quality);\n } finally {\n if (scale > 1) {\n for (let i = 0; i < paneCharts.length; i++) {\n if (typeof paneCharts[i].setDevicePixelRatioOverride === \"function\") {\n paneCharts[i].setDevicePixelRatioOverride!(null);\n } else {\n paneCharts[i].setDPR(originalDprs[i]);\n }\n paneCharts[i].render();\n }\n }\n }\n}\n","/**\n * VS Code–style drag dividers between stacked chart panes (vertical or horizontal).\n */\n\nimport { STACKED_DEFAULT_MIN_PANE_RATIO } from \"./types\";\nimport type { StackDirection } from \"./types\";\n\nexport interface PaneResizeOptions {\n /** Stack layout direction */\n direction?: StackDirection;\n /** Min pane size as fraction of available stack dimension (default 1/6) */\n minPaneRatio?: number;\n /** Absolute min pane size in px */\n minPanePx?: number;\n /** Divider hit area size (default 6) */\n dividerSize?: number;\n onResize?: (ratiosById: Record<string, number>) => void;\n onDragStart?: (leadingIdx: number, trailingIdx: number) => number[];\n onDragMove?: (sizesPx: number[], leadingIdx: number, trailingIdx: number) => void;\n onDragEnd?: (finalSizesPx: number[]) => void;\n}\n\nconst DIVIDER_CLASS = \"velo-pane-divider\";\nconst RESIZING_CLASS = \"velo-pane-resizing\";\n\nfunction injectDividerStyles(direction: StackDirection): void {\n if (typeof document === \"undefined\") return;\n let style = document.getElementById(\"velo-pane-divider-styles\") as HTMLStyleElement | null;\n if (!style) {\n style = document.createElement(\"style\");\n style.id = \"velo-pane-divider-styles\";\n document.head.appendChild(style);\n }\n\n const isHorizontal = direction === \"horizontal\";\n const cursor = isHorizontal ? \"ew-resize\" : \"ns-resize\";\n const handleGlyph = isHorizontal ? \"⇔\" : \"⇕\";\n\n style.textContent = `\n .${DIVIDER_CLASS} {\n flex: 0 0 var(--velo-divider-size, 6px);\n position: relative;\n cursor: ${cursor};\n touch-action: none;\n z-index: 20;\n background: transparent;\n user-select: none;\n }\n .${DIVIDER_CLASS}::after {\n content: \"\";\n position: absolute;\n background: rgba(128, 128, 128, 0.35);\n transition: background 0.15s;\n }\n .${DIVIDER_CLASS}[data-direction=\"vertical\"]::after {\n left: 0;\n right: 0;\n top: 50%;\n transform: translateY(-50%);\n height: 1px;\n }\n .${DIVIDER_CLASS}[data-direction=\"horizontal\"]::after {\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n width: 1px;\n }\n .${DIVIDER_CLASS}:hover::after,\n .${RESIZING_CLASS} .${DIVIDER_CLASS}::after {\n background: rgba(0, 242, 255, 0.65);\n }\n .${DIVIDER_CLASS}[data-direction=\"vertical\"]:hover::after,\n .${RESIZING_CLASS} .${DIVIDER_CLASS}[data-direction=\"vertical\"]::after {\n height: 2px;\n }\n .${DIVIDER_CLASS}[data-direction=\"horizontal\"]:hover::after,\n .${RESIZING_CLASS} .${DIVIDER_CLASS}[data-direction=\"horizontal\"]::after {\n width: 2px;\n }\n .${DIVIDER_CLASS}-handle {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.15s;\n pointer-events: none;\n color: rgba(0, 242, 255, 0.9);\n font-size: 10px;\n line-height: 1;\n }\n .${DIVIDER_CLASS}:hover .${DIVIDER_CLASS}-handle,\n .${RESIZING_CLASS} .${DIVIDER_CLASS}-handle {\n opacity: 1;\n }\n .${RESIZING_CLASS} {\n cursor: ${cursor} !important;\n }\n .${RESIZING_CLASS} * {\n cursor: ${cursor} !important;\n }\n .${RESIZING_CLASS} [data-pane-id] {\n position: relative !important;\n overflow: hidden !important;\n }\n `;\n\n void handleGlyph;\n}\n\nfunction createDividerElement(index: number, size: number, direction: StackDirection): HTMLDivElement {\n const divider = document.createElement(\"div\");\n divider.className = DIVIDER_CLASS;\n divider.dataset.dividerIndex = String(index);\n divider.dataset.direction = direction;\n divider.style.setProperty(\"--velo-divider-size\", `${size}px`);\n\n const handle = document.createElement(\"div\");\n handle.className = `${DIVIDER_CLASS}-handle`;\n handle.textContent = direction === \"horizontal\" ? \"⇔\" : \"⇕\";\n divider.appendChild(handle);\n\n return divider;\n}\n\nexport interface PaneResizeController {\n dividers: HTMLDivElement[];\n destroy: () => void;\n}\n\nfunction paneFlexStyle(ratio: number | string, direction: StackDirection): string {\n const minDim = direction === \"horizontal\" ? \"min-width:0;\" : \"min-height:0;\";\n if (typeof ratio === \"number\") {\n return `flex:${ratio} 1 0;${minDim}`;\n }\n return `flex:1 1 ${ratio};${minDim}`;\n}\n\nexport function resolveMinPaneHeightPx(\n availHeight: number,\n paneCount: number,\n minPaneRatio = STACKED_DEFAULT_MIN_PANE_RATIO,\n minPanePx = 0,\n): number {\n if (paneCount < 1 || availHeight <= 0) return 1;\n const byRatio = availHeight * minPaneRatio;\n const minH = Math.max(minPanePx, byRatio);\n return Math.min(minH, availHeight / paneCount);\n}\n\nexport function resolveMinPaneWidthPx(\n availWidth: number,\n paneCount: number,\n minPaneRatio = STACKED_DEFAULT_MIN_PANE_RATIO,\n minPanePx = 0,\n): number {\n return resolveMinPaneHeightPx(availWidth, paneCount, minPaneRatio, minPanePx);\n}\n\nexport function normalizePaneHeights(heightsPx: number[], targetTotal: number): number[] {\n const n = heightsPx.length;\n if (n === 0) return heightsPx;\n const total = Math.max(1, Math.round(targetTotal));\n const sum = heightsPx.reduce((s, h) => s + h, 0);\n if (sum <= 0) {\n const even = Math.floor(total / n);\n const out = heightsPx.map(() => even);\n out[n - 1] = total - even * (n - 1);\n return out;\n }\n\n const scaled = heightsPx.map((h) => (h / sum) * total);\n const out: number[] = [];\n let allocated = 0;\n for (let i = 0; i < n - 1; i++) {\n out.push(Math.max(1, Math.round(scaled[i])));\n allocated += out[i];\n }\n out.push(Math.max(1, total - allocated));\n return out;\n}\n\nexport const normalizePaneWidths = normalizePaneHeights;\n\nexport function attachPaneResize(\n container: HTMLDivElement,\n paneWrappers: HTMLDivElement[],\n paneIds: string[],\n ratios: number[],\n options: PaneResizeOptions = {},\n): PaneResizeController {\n const direction = options.direction ?? \"vertical\";\n const isHorizontal = direction === \"horizontal\";\n injectDividerStyles(direction);\n\n const minPaneRatio = options.minPaneRatio ?? STACKED_DEFAULT_MIN_PANE_RATIO;\n const minPanePx = options.minPanePx ?? 0;\n const dividerSize = options.dividerSize ?? 6;\n const paneCount = paneWrappers.length;\n\n const minPaneSize = (avail: number) =>\n isHorizontal\n ? resolveMinPaneWidthPx(avail, paneCount, minPaneRatio, minPanePx)\n : resolveMinPaneHeightPx(avail, paneCount, minPaneRatio, minPanePx);\n\n const dividers: HTMLDivElement[] = [];\n const cleanups: (() => void)[] = [];\n\n if (paneWrappers.length < 2) {\n return { dividers, destroy: () => {} };\n }\n\n const availableSize = (): number => {\n const dividerTotal = dividers.length * dividerSize;\n const main = isHorizontal ? container.clientWidth : container.clientHeight;\n return Math.max(1, main - dividerTotal);\n };\n\n const applyRatios = (\n leadingIdx: number,\n trailingIdx: number,\n delta: number,\n sizesPx: number[],\n ) => {\n const avail = availableSize();\n const minS = minPaneSize(avail);\n\n const othersSum = sizesPx.reduce(\n (s, h, idx) => (idx === leadingIdx || idx === trailingIdx ? s : s + h),\n 0,\n );\n const pairTotal = avail - othersSum;\n\n let leadingSize = sizesPx[leadingIdx] + delta;\n leadingSize = Math.max(minS, Math.min(pairTotal - minS, leadingSize));\n const trailingSize = pairTotal - leadingSize;\n\n sizesPx[leadingIdx] = leadingSize;\n sizesPx[trailingIdx] = trailingSize;\n\n const total = ratios.reduce((s, r) => s + r, 0);\n ratios[leadingIdx] = (leadingSize / avail) * total;\n ratios[trailingIdx] = (trailingSize / avail) * total;\n\n options.onDragMove?.(sizesPx, leadingIdx, trailingIdx);\n\n if (options.onResize) {\n const byId: Record<string, number> = {};\n for (let i = 0; i < paneIds.length; i++) {\n byId[paneIds[i]] = ratios[i];\n }\n options.onResize(byId);\n }\n };\n\n for (let i = 0; i < paneWrappers.length - 1; i++) {\n const divider = createDividerElement(i, dividerSize, direction);\n const leadingWrapper = paneWrappers[i];\n leadingWrapper.after(divider);\n dividers.push(divider);\n\n const onPointerDown = (e: PointerEvent) => {\n e.preventDefault();\n divider.setPointerCapture(e.pointerId);\n container.classList.add(RESIZING_CLASS);\n\n const sizesPx =\n options.onDragStart?.(i, i + 1) ??\n paneWrappers.map((w) =>\n isHorizontal ? w.getBoundingClientRect().width : w.getBoundingClientRect().height,\n );\n\n options.onDragMove?.(sizesPx, i, i + 1);\n\n let lastCoord = isHorizontal ? e.clientX : e.clientY;\n\n const onMove = (ev: PointerEvent) => {\n const coord = isHorizontal ? ev.clientX : ev.clientY;\n const d = coord - lastCoord;\n lastCoord = coord;\n if (d !== 0) applyRatios(i, i + 1, d, sizesPx);\n };\n\n const onUp = (ev: PointerEvent) => {\n divider.releasePointerCapture(ev.pointerId);\n container.classList.remove(RESIZING_CLASS);\n divider.removeEventListener(\"pointermove\", onMove);\n divider.removeEventListener(\"pointerup\", onUp);\n divider.removeEventListener(\"pointercancel\", onUp);\n options.onDragEnd?.(sizesPx);\n };\n\n divider.addEventListener(\"pointermove\", onMove);\n divider.addEventListener(\"pointerup\", onUp);\n divider.addEventListener(\"pointercancel\", onUp);\n };\n\n divider.addEventListener(\"pointerdown\", onPointerDown);\n cleanups.push(() => divider.removeEventListener(\"pointerdown\", onPointerDown));\n }\n\n return {\n dividers,\n destroy: () => {\n for (const fn of cleanups) fn();\n for (const d of dividers) d.remove();\n container.classList.remove(RESIZING_CLASS);\n },\n };\n}\n\nexport function applyPaneFlexRatios(\n paneWrappers: HTMLDivElement[],\n ratios: number[],\n direction: StackDirection = \"vertical\",\n): void {\n for (let i = 0; i < paneWrappers.length; i++) {\n paneWrappers[i].style.cssText = `${paneFlexStyle(ratios[i], direction)}position:relative;overflow:hidden;`;\n }\n}\n\nexport function initialPaneRatio(height: number | string): number {\n return typeof height === \"number\" ? height : 1;\n}\n\nexport { paneFlexStyle };\n","import type { Chart } from \"../chart/types\";\n\n/** Adaptive Y tick count from pane height (~1 tick per 36px, capped by base). */\nexport function tickCountForPaneHeight(heightPx: number, base = 6): number {\n if (!Number.isFinite(heightPx) || heightPx <= 0) return base;\n const adaptive = Math.floor(heightPx / 36);\n return Math.max(2, Math.min(base, adaptive));\n}\n\n/** Adaptive X tick count from pane width. */\nexport function tickCountForPaneWidth(widthPx: number, base = 8): number {\n if (!Number.isFinite(widthPx) || widthPx <= 0) return base;\n const adaptive = Math.floor(widthPx / 72);\n return Math.max(2, Math.min(base, adaptive));\n}\n\nexport interface PaneAxisMeta {\n chart: Chart;\n wrapper: HTMLDivElement;\n baseYTickCount: number;\n baseXTickCount: number;\n showXAxis: boolean;\n}\n\nexport function readBaseYTickCount(yAxis?: { tickCount?: number } | { tickCount?: number }[]): number {\n if (!yAxis) return 6;\n const axes = Array.isArray(yAxis) ? yAxis : [yAxis];\n return axes[0]?.tickCount ?? 6;\n}\n\nexport function adaptPaneAxes(meta: PaneAxisMeta): void {\n const h = meta.wrapper.clientHeight;\n const w = meta.wrapper.clientWidth;\n const yTicks = tickCountForPaneHeight(h, meta.baseYTickCount);\n\n meta.chart.updateYAxis(\"default\", { tickCount: yTicks });\n\n if (meta.showXAxis) {\n const xTicks = tickCountForPaneWidth(w, meta.baseXTickCount);\n meta.chart.updateXAxis({ tickCount: xTicks });\n }\n}\n\nexport function adaptAllPaneAxes(metas: PaneAxisMeta[]): void {\n for (const m of metas) adaptPaneAxes(m);\n}\n","import { createChart } from \"../Chart\";\nimport type { Chart } from \"../chart/types\";\nimport { MARGINS } from \"../chart/types\";\nimport { createChartGroup } from \"../sync\";\nimport type { SyncOptions } from \"../sync\";\nimport type { AxisOptions, SeriesOptions } from \"../../types\";\nimport { mergeLayoutOptions } from \"../layout\";\nimport { buildIndicatorSeries } from \"../indicator/buildIndicatorSeries\";\nimport type { IndicatorSeriesOptions } from \"../indicator/types\";\nimport type {\n StackedChart,\n StackedChartOptions,\n StackedPaneConfig,\n StackedSyncOptions,\n StackSnapshotOptions,\n StackDirection,\n} from \"./types\";\nimport {\n STACKED_MAX_PANES,\n STACKED_COMPACT_MARGIN,\n STACKED_FULL_X_MARGIN,\n} from \"./types\";\nimport { exportStackImage } from \"./stackExport\";\nimport { getInitQueueStatus } from \"../ChartInitQueue\";\nimport {\n addIndicatorToChart,\n buildIndicatorPaneFromPreset,\n type AddIndicatorOptions,\n type IndicatorPresetName,\n} from \"../indicator/addIndicator\";\nimport { extractPriceSeries, resolveSourceSeries } from \"../indicator/indicatorPresets\";\nimport {\n attachPaneResize,\n applyPaneFlexRatios,\n initialPaneRatio,\n normalizePaneHeights,\n type PaneResizeController,\n} from \"./paneResize\";\nimport {\n adaptAllPaneAxes,\n readBaseYTickCount,\n type PaneAxisMeta,\n} from \"./paneAxis\";\n\nfunction countYAxes(yAxis?: AxisOptions | AxisOptions[]): { left: number; right: number } {\n const axes = yAxis ? (Array.isArray(yAxis) ? yAxis : [yAxis]) : [{}];\n let left = 0;\n let right = 0;\n for (const a of axes) {\n if (a.position === \"right\") right++;\n else left++;\n }\n return { left: Math.max(1, left), right };\n}\n\nfunction computeAlignedLeftMargin(panes: StackedPaneConfig[], baseLeft: number): number {\n let maxExtra = 0;\n for (const pane of panes) {\n const { left } = countYAxes(pane.chart?.yAxis);\n maxExtra = Math.max(maxExtra, (left - 1) * 65);\n }\n return baseLeft + maxExtra;\n}\n\nfunction computeAlignedRightMargin(panes: StackedPaneConfig[], baseRight: number): number {\n let maxExtra = 0;\n for (const pane of panes) {\n const { right } = countYAxes(pane.chart?.yAxis);\n maxExtra = Math.max(maxExtra, right * 65);\n }\n return baseRight + maxExtra;\n}\n\n// Pane ratios are always numeric (see initialPaneRatio), so this only handles\n// the numeric flex-grow form.\nfunction paneFlexStyle(ratio: number, direction: StackDirection): string {\n const minDim = direction === \"horizontal\" ? \"min-width:0;\" : \"min-height:0;\";\n return `flex:${ratio} 1 0;${minDim}`;\n}\n\nfunction expandPaneSeries(series?: SeriesOptions[]): SeriesOptions[] {\n if (!series?.length) return [];\n const out: SeriesOptions[] = [];\n for (const s of series) {\n if (s.type === \"indicator\") {\n out.push(...buildIndicatorSeries(s as IndicatorSeriesOptions));\n } else {\n out.push(s);\n }\n }\n return out;\n}\n\nfunction buildPaneChartOptions(\n pane: StackedPaneConfig,\n chartContainer: HTMLDivElement,\n stack: StackedChartOptions,\n index: number,\n total: number,\n alignedMargins: { left: number; right: number; top: number; bottom: number },\n showXAxis: boolean,\n showYAxis: boolean,\n direction: StackDirection,\n): Parameters<typeof createChart>[0] {\n const isFirst = index === 0;\n const isLast = index === total - 1;\n const isHorizontal = direction === \"horizontal\";\n const sharedBottom = !isHorizontal && stack.sharedXAxis !== \"none\";\n const compactX = sharedBottom && !showXAxis;\n const sharedLeft = isHorizontal && (stack.sharedYAxis ?? \"left\") !== \"none\";\n const compactY = sharedLeft && !showYAxis;\n const paneGap = stack.gap ?? 0;\n const compactMargin = paneGap > 0 ? STACKED_COMPACT_MARGIN : { top: 0, bottom: 0, left: 0 };\n\n const margins = isHorizontal\n ? {\n top: alignedMargins.top,\n right: isLast ? alignedMargins.right : compactMargin.left,\n left: compactY ? compactMargin.left : alignedMargins.left,\n bottom: alignedMargins.bottom,\n }\n : {\n top: isFirst ? alignedMargins.top : compactMargin.top,\n right: alignedMargins.right,\n left: alignedMargins.left,\n bottom: compactX\n ? compactMargin.bottom\n : isLast\n ? (stack.layout?.margins?.bottom ?? STACKED_FULL_X_MARGIN.bottom)\n : alignedMargins.bottom,\n };\n\n const baseX = pane.chart?.xAxis ?? {};\n const xAxis = {\n ...baseX,\n showLine: showXAxis ? baseX.showLine ?? true : false,\n showTicks: showXAxis ? baseX.showTicks ?? true : false,\n showLabels: showXAxis ? baseX.showLabels ?? true : false,\n };\n\n const baseY = pane.chart?.yAxis ?? {};\n const yAxisRaw = Array.isArray(baseY) ? baseY : [baseY];\n const yAxis = yAxisRaw.map((axis) => ({\n ...axis,\n showLine: showYAxis ? axis.showLine ?? true : false,\n showTicks: showYAxis ? axis.showTicks ?? true : false,\n showLabels: showYAxis ? axis.showLabels ?? true : false,\n }));\n const yAxisOption = Array.isArray(pane.chart?.yAxis) ? yAxis : yAxis[0];\n\n const isInteractive = pane.interactive ?? true;\n if (!isInteractive) {\n chartContainer.style.pointerEvents = \"none\";\n }\n\n return {\n ...pane.chart,\n id: pane.id,\n container: chartContainer,\n showLegend: pane.chart?.showLegend ?? stack.showLegend ?? false,\n theme: pane.chart?.theme ?? stack.theme,\n devicePixelRatio: stack.devicePixelRatio ?? pane.chart?.devicePixelRatio,\n loading: pane.chart?.loading ?? false,\n xAxis,\n yAxis: yAxisOption,\n layout: mergeLayoutOptions({\n ...stack.layout,\n ...pane.chart?.layout,\n margins: { ...margins, ...stack.layout?.margins, ...pane.chart?.layout?.margins },\n }),\n };\n}\n\nfunction wrapperStyle(ratio: number, gap: number, index: number, direction: StackDirection): string {\n const gapStyle =\n gap > 0 && index > 0\n ? direction === \"horizontal\"\n ? `margin-left:${gap}px;`\n : `margin-top:${gap}px;`\n : \"\";\n return `${paneFlexStyle(ratio, direction)}position:relative;overflow:hidden;${gapStyle}`;\n}\n\nfunction resolveStackSyncOptions(\n sync: StackedChartOptions[\"sync\"],\n masterPaneId: string,\n direction: StackDirection,\n): SyncOptions {\n if (sync === false) {\n return {\n axis: \"none\",\n syncCursor: false,\n syncZoom: false,\n syncPan: false,\n bidirectional: true,\n masterId: undefined,\n };\n }\n\n const defaultAxis: SyncOptions[\"axis\"] = direction === \"horizontal\" ? \"y\" : \"x\";\n\n return {\n axis: defaultAxis,\n bidirectional: true,\n masterId: masterPaneId,\n syncCursor: true,\n syncZoom: true,\n syncPan: true,\n ...(typeof sync === \"object\" ? sync : {}),\n };\n}\n\nexport function createStackedChart(options: StackedChartOptions): StackedChart {\n const { container, panes } = options;\n if (!container) throw new Error(\"[StackedChart] container is required\");\n if (panes.length < 1 || panes.length > STACKED_MAX_PANES) {\n throw new Error(`[StackedChart] panes must be 1–${STACKED_MAX_PANES}`);\n }\n\n const masterPaneId = options.masterPaneId ?? panes[0].id;\n const direction: StackDirection = options.direction ?? \"vertical\";\n const isHorizontal = direction === \"horizontal\";\n const sharedXAxis = options.sharedXAxis ?? \"bottom\";\n const sharedYAxis = options.sharedYAxis ?? \"left\";\n const gap = options.gap ?? 0;\n const resizableOpt = options.resizable;\n const resizable = !!resizableOpt;\n const resizeDividerSize =\n typeof resizableOpt === \"object\" ? (resizableOpt.dividerSize ?? 6) : 6;\n\n const baseLayout = mergeLayoutOptions(options.layout);\n const baseLeft = baseLayout.margins?.left ?? MARGINS.left;\n const baseRight = baseLayout.margins?.right ?? MARGINS.right;\n const baseTop = baseLayout.margins?.top ?? MARGINS.top;\n const alignedLeft = computeAlignedLeftMargin(panes, baseLeft);\n const alignedRight = computeAlignedRightMargin(panes, baseRight);\n\n container.replaceChildren();\n container.style.display = \"flex\";\n container.style.flexDirection = isHorizontal ? \"row\" : \"column\";\n container.style.width = \"100%\";\n const existingHeight = container.offsetHeight || parseInt(getComputedStyle(container).height, 10);\n const existingWidth = container.offsetWidth || parseInt(getComputedStyle(container).width, 10);\n if (isHorizontal) {\n if (existingWidth > 0) {\n container.style.width = `${existingWidth}px`;\n container.style.minWidth = `${existingWidth}px`;\n }\n container.style.height = existingHeight > 0 ? `${existingHeight}px` : \"320px\";\n container.style.minHeight = container.style.height;\n } else {\n if (existingHeight > 0) {\n container.style.height = `${existingHeight}px`;\n container.style.minHeight = `${existingHeight}px`;\n } else if (!container.style.height) {\n container.style.minHeight = \"320px\";\n }\n }\n container.style.overflow = \"hidden\";\n container.style.position = \"relative\";\n\n const paneIds = panes.map((p) => p.id);\n const paneRatios = panes.map((p) => initialPaneRatio(p.height));\n const paneCharts = new Map<string, Chart>();\n const paneWrappers: HTMLDivElement[] = [];\n const paneAxisMetas: PaneAxisMeta[] = [];\n let paneResizeCtrl: PaneResizeController | null = null;\n let isPaneDragging = false;\n let resizeRaf = 0;\n let dragLayoutRaf = 0;\n let pendingDragLayout: {\n sizes: number[];\n leadingIdx: number;\n trailingIdx: number;\n } | null = null;\n\n const commitPaneLayout = (affected?: number[]) => {\n const indices =\n affected ??\n Array.from({ length: paneWrappers.length }, (_, i) => i);\n\n for (const i of indices) {\n const chart = paneCharts.get(paneIds[i]);\n if (chart) {\n chart.resize();\n }\n }\n adaptAllPaneAxes(\n indices.map((i) => paneAxisMetas[i]).filter(Boolean),\n );\n };\n\n const scheduleStackResize = () => {\n if (resizeRaf) return;\n resizeRaf = requestAnimationFrame(() => {\n resizeRaf = 0;\n if (isPaneDragging) return;\n commitPaneLayout();\n });\n };\n\n const resizeObserver = new ResizeObserver(() => {\n if (isPaneDragging) return;\n scheduleStackResize();\n });\n resizeObserver.observe(container);\n\n const applyFlexCss = () => {\n for (let i = 0; i < paneWrappers.length; i++) {\n paneWrappers[i].style.cssText = wrapperStyle(paneRatios[i], gap, i, direction);\n }\n };\n\n const stackAvailSize = () => {\n const dividerTotal = (paneWrappers.length - 1) * resizeDividerSize;\n if (isHorizontal) {\n return Math.max(1, container.clientWidth - dividerTotal);\n }\n return Math.max(1, container.clientHeight - dividerTotal);\n };\n\n const restorePaneChartDivs = () => {\n for (const wrapper of paneWrappers) {\n const chartDiv = wrapper.firstElementChild as HTMLDivElement | null;\n if (chartDiv) {\n chartDiv.style.cssText = \"position:absolute;inset:0;width:100%;height:100%;\";\n }\n }\n };\n\n const initDragSizes = (): number[] => {\n const avail = stackAvailSize();\n const measured = paneWrappers.map((w) =>\n isHorizontal ? w.getBoundingClientRect().width : w.getBoundingClientRect().height,\n );\n const sum = measured.reduce((s, h) => s + h, 0);\n return sum > 0 ? measured.map((h) => h * (avail / sum)) : measured;\n };\n\n const applyDragPaneSizes = (sizesPx: number[]) => {\n for (let i = 0; i < paneWrappers.length; i++) {\n const size = Math.max(1, Math.round(sizesPx[i]));\n const gapStyle =\n gap > 0 && i > 0\n ? isHorizontal\n ? `margin-left:${gap}px;`\n : `margin-top:${gap}px;`\n : \"\";\n const dim = isHorizontal ? \"width\" : \"height\";\n paneWrappers[i].style.cssText = `${dim}:${size}px;flex:0 0 auto;min-height:0;min-width:0;position:relative;overflow:hidden;${gapStyle}`;\n }\n };\n\n const flushDragLayout = () => {\n dragLayoutRaf = 0;\n if (!isPaneDragging || !pendingDragLayout) return;\n\n const { sizes, leadingIdx, trailingIdx } = pendingDragLayout;\n applyDragPaneSizes(sizes);\n\n for (const i of [leadingIdx, trailingIdx]) {\n const chart = paneCharts.get(paneIds[i]);\n if (chart) {\n chart.resize();\n adaptAllPaneAxes([paneAxisMetas[i]]);\n }\n }\n };\n\n const scheduleDragLayout = (\n sizesPx: number[],\n leadingIdx: number,\n trailingIdx: number,\n ) => {\n pendingDragLayout = { sizes: sizesPx, leadingIdx, trailingIdx };\n if (dragLayoutRaf) return;\n dragLayoutRaf = requestAnimationFrame(flushDragLayout);\n };\n\n const syncRatiosFromSizes = (sizesPx: number[]) => {\n const total = sizesPx.reduce((s, h) => s + h, 0);\n if (total <= 0) return;\n const totalR = paneRatios.reduce((s, r) => s + r, 0);\n for (let i = 0; i < paneRatios.length; i++) {\n paneRatios[i] = (sizesPx[i] / total) * totalR;\n }\n };\n\n const setAllChartsResizeSuspended = (suspended: boolean) => {\n for (const chart of paneCharts.values()) {\n chart.setResizeSuspended?.(suspended);\n }\n };\n\n const setInactiveChartsResizeSuspended = (\n topIdx: number,\n bottomIdx: number,\n ) => {\n for (let i = 0; i < paneIds.length; i++) {\n if (i === topIdx || i === bottomIdx) continue;\n paneCharts.get(paneIds[i])?.setResizeSuspended?.(true);\n }\n paneCharts.get(paneIds[topIdx])?.setResizeSuspended?.(false);\n paneCharts.get(paneIds[bottomIdx])?.setResizeSuspended?.(false);\n };\n\n const alignedBottom = isHorizontal\n ? (options.layout?.margins?.bottom ?? STACKED_FULL_X_MARGIN.bottom)\n : MARGINS.bottom;\n\n for (let i = 0; i < panes.length; i++) {\n const pane = panes[i];\n const isFirst = i === 0;\n const isLast = i === panes.length - 1;\n\n const showXAxis = isHorizontal\n ? (pane.showXAxis ?? true)\n : (pane.showXAxis ?? (sharedXAxis === \"bottom\" ? isLast : true));\n\n const showYAxis = isHorizontal\n ? (pane.showYAxis ?? (sharedYAxis === \"left\" ? isFirst : true))\n : (pane.showYAxis ?? true);\n\n const wrapper = document.createElement(\"div\");\n wrapper.dataset.paneId = pane.id;\n wrapper.style.cssText = wrapperStyle(paneRatios[i], gap, i, direction);\n\n const chartDiv = document.createElement(\"div\");\n chartDiv.style.cssText = \"position:absolute;inset:0;width:100%;height:100%;\";\n\n wrapper.appendChild(chartDiv);\n container.appendChild(wrapper);\n paneWrappers.push(wrapper);\n\n const chart = createChart(\n buildPaneChartOptions(\n pane,\n chartDiv,\n options,\n i,\n panes.length,\n {\n left: isHorizontal && !showYAxis ? MARGINS.left : alignedLeft,\n right: alignedRight,\n top: baseTop,\n bottom: alignedBottom,\n },\n showXAxis,\n showYAxis,\n direction,\n ),\n );\n\n const seriesList = expandPaneSeries(pane.series);\n if (seriesList.length) {\n for (const s of seriesList) chart.addSeries(s);\n }\n\n if (pane.yRange && pane.yRange !== \"auto\") {\n chart.zoom({ y: pane.yRange, animate: false });\n }\n\n paneCharts.set(pane.id, chart);\n\n paneAxisMetas.push({\n chart,\n wrapper,\n baseYTickCount: readBaseYTickCount(pane.chart?.yAxis),\n baseXTickCount: pane.chart?.xAxis?.tickCount ?? 8,\n showXAxis,\n });\n }\n\n if (resizable && panes.length > 1) {\n const resizeOpts =\n typeof resizableOpt === \"object\"\n ? {\n minPaneRatio: resizableOpt.minPaneRatio,\n minPanePx: resizableOpt.minPanePx,\n dividerSize: resizableOpt.dividerSize,\n }\n : {};\n paneResizeCtrl = attachPaneResize(\n container,\n paneWrappers,\n paneIds,\n paneRatios,\n {\n direction,\n ...resizeOpts,\n onDragStart: (leadingIdx, trailingIdx) => {\n isPaneDragging = true;\n setAllChartsResizeSuspended(true);\n setInactiveChartsResizeSuspended(leadingIdx, trailingIdx);\n return initDragSizes();\n },\n onDragMove: (sizes, leadingIdx, trailingIdx) => {\n scheduleDragLayout(sizes, leadingIdx, trailingIdx);\n },\n onDragEnd: (finalSizes) => {\n if (dragLayoutRaf) {\n cancelAnimationFrame(dragLayoutRaf);\n dragLayoutRaf = 0;\n }\n pendingDragLayout = null;\n isPaneDragging = false;\n const normalized = normalizePaneHeights(finalSizes, stackAvailSize());\n syncRatiosFromSizes(normalized);\n restorePaneChartDivs();\n applyFlexCss();\n setAllChartsResizeSuspended(false);\n commitPaneLayout();\n },\n },\n );\n }\n\n const master = paneCharts.get(masterPaneId);\n if (!master) {\n throw new Error(`[StackedChart] masterPaneId \"${masterPaneId}\" not found in panes`);\n }\n\n const group = createChartGroup(\n Array.from(paneCharts.values()),\n resolveStackSyncOptions(options.sync, masterPaneId, direction),\n );\n\n const getBackgroundColor = (): string => {\n const theme = master.theme ?? master.baseTheme;\n return theme?.backgroundColor ?? \"#ffffff\";\n };\n\n const waitForStackReady = (): Promise<void> => {\n const maxWait = 8000;\n const started = Date.now();\n\n const waitForInitQueue = (): Promise<void> =>\n new Promise((resolve) => {\n const poll = () => {\n const q = getInitQueueStatus();\n if ((q.pending === 0 && !q.isProcessing) || Date.now() - started > maxWait) {\n resolve();\n return;\n }\n setTimeout(poll, 50);\n };\n poll();\n });\n\n return waitForInitQueue().then(() => {\n return new Promise<void>((resolve) => {\n requestAnimationFrame(() => {\n commitPaneLayout();\n resolve();\n });\n });\n });\n };\n\n const runStackExport = async (opts: StackSnapshotOptions = {}): Promise<string> => {\n await waitForStackReady();\n for (const c of paneCharts.values()) c.render();\n await new Promise((r) => requestAnimationFrame(r));\n\n const dataUrl = await exportStackImage(\n container,\n paneWrappers,\n Array.from(paneCharts.values()),\n paneResizeCtrl?.dividers ?? [],\n getBackgroundColor(),\n opts,\n );\n\n if (opts.download) {\n const ext = opts.format === \"jpeg\" ? \"jpg\" : opts.format ?? \"png\";\n const link = document.createElement(\"a\");\n link.download = `${opts.fileName ?? \"velo-plot-stack\"}.${ext}`;\n link.href = dataUrl;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n\n return dataUrl;\n };\n\n const mountPane = (pane: StackedPaneConfig): Chart => {\n if (paneCharts.size >= STACKED_MAX_PANES) {\n throw new Error(`[StackedChart] Cannot exceed ${STACKED_MAX_PANES} panes`);\n }\n if (paneCharts.has(pane.id)) {\n throw new Error(`[StackedChart] Pane \"${pane.id}\" already exists`);\n }\n\n if (!isHorizontal && sharedXAxis === \"bottom\" && paneIds.length > 0) {\n const prevId = paneIds[paneIds.length - 1];\n paneCharts.get(prevId)?.updateXAxis({\n showLabels: false,\n showTicks: false,\n showLine: false,\n });\n }\n\n const newRatio = initialPaneRatio(pane.height ?? 0.25);\n const total = paneRatios.reduce((a, b) => a + b, 0);\n const scale = total > 0 ? (1 - newRatio) / total : 1;\n for (let j = 0; j < paneRatios.length; j++) paneRatios[j] *= scale;\n\n const index = paneIds.length;\n paneIds.push(pane.id);\n paneRatios.push(newRatio);\n\n const wrapper = document.createElement(\"div\");\n wrapper.dataset.paneId = pane.id;\n wrapper.style.cssText = wrapperStyle(paneRatios[index], gap, index, direction);\n\n const chartDiv = document.createElement(\"div\");\n chartDiv.style.cssText = \"position:absolute;inset:0;width:100%;height:100%;\";\n wrapper.appendChild(chartDiv);\n container.appendChild(wrapper);\n paneWrappers.push(wrapper);\n\n const isLast = true;\n const showXAxis = isHorizontal\n ? (pane.showXAxis ?? true)\n : (pane.showXAxis ?? (sharedXAxis === \"bottom\" ? isLast : true));\n const showYAxis = isHorizontal\n ? (pane.showYAxis ?? (sharedYAxis === \"left\" ? index === 0 : true))\n : (pane.showYAxis ?? true);\n\n const chart = createChart(\n buildPaneChartOptions(\n pane,\n chartDiv,\n options,\n index,\n paneIds.length,\n {\n left: isHorizontal && !showYAxis ? MARGINS.left : alignedLeft,\n right: alignedRight,\n top: baseTop,\n bottom: alignedBottom,\n },\n showXAxis,\n showYAxis,\n direction,\n ),\n );\n\n const seriesList = expandPaneSeries(pane.series);\n for (const s of seriesList) chart.addSeries(s);\n if (pane.yRange && pane.yRange !== \"auto\") {\n chart.zoom({ y: pane.yRange, animate: false });\n }\n\n paneCharts.set(pane.id, chart);\n paneAxisMetas.push({\n chart,\n wrapper,\n baseYTickCount: readBaseYTickCount(pane.chart?.yAxis),\n baseXTickCount: pane.chart?.xAxis?.tickCount ?? 8,\n showXAxis,\n });\n\n group.add(chart);\n applyFlexCss();\n commitPaneLayout();\n return chart;\n };\n\n const stack: StackedChart = {\n container,\n getPane(id: string) {\n return paneCharts.get(id);\n },\n getPanes() {\n return Array.from(paneCharts.values());\n },\n getMaster() {\n return master;\n },\n getGroup() {\n return group;\n },\n fitAll(opts) {\n group.fitAll(opts);\n },\n resetAll() {\n group.resetAll();\n },\n resize() {\n commitPaneLayout();\n },\n getPaneRatios() {\n const out: Record<string, number> = {};\n for (let i = 0; i < paneIds.length; i++) {\n out[paneIds[i]] = paneRatios[i];\n }\n return out;\n },\n setPaneRatios(ratios: Record<string, number>) {\n for (let i = 0; i < paneIds.length; i++) {\n const id = paneIds[i];\n if (ratios[id] !== undefined) paneRatios[i] = ratios[id];\n }\n applyPaneFlexRatios(paneWrappers, paneRatios, direction);\n commitPaneLayout();\n },\n setSyncAxis(axis) {\n group.syncAxis(axis);\n },\n getSyncAxis() {\n return group.getOptions().axis ?? \"x\";\n },\n setSyncOptions(syncOpts: Partial<StackedSyncOptions>) {\n group.updateOptions(syncOpts);\n },\n whenReady() {\n return waitForStackReady();\n },\n exportImage(opts) {\n return runStackExport(opts);\n },\n snapshot(opts) {\n return runStackExport(opts);\n },\n addPane(pane: StackedPaneConfig): Chart {\n return mountPane(pane);\n },\n async addIndicator(preset: IndicatorPresetName, opts: AddIndicatorOptions = {}) {\n const priceChart = paneCharts.get(masterPaneId) ?? master;\n if (opts.pane !== \"new\") {\n const overlay = await addIndicatorToChart(priceChart, preset, opts);\n return { ...overlay, chart: priceChart };\n }\n\n const source = resolveSourceSeries(priceChart, opts.sourceSeriesId);\n const { x, prices } = extractPriceSeries(source);\n const paneConfig = await buildIndicatorPaneFromPreset(preset, x, prices, {\n id: opts.id ?? preset,\n label: opts.label ?? preset.toUpperCase(),\n height: opts.paneHeight ?? 0.25,\n showXAxis: opts.showXAxis,\n period: opts.period,\n fastPeriod: opts.fastPeriod,\n slowPeriod: opts.slowPeriod,\n signalPeriod: opts.signalPeriod,\n stdDev: opts.stdDev,\n }, source);\n\n const chart = mountPane(paneConfig);\n return {\n id: paneConfig.id,\n preset,\n placement: \"oscillator\" as const,\n seriesIds: paneConfig.series?.map((s) => s.id) ?? [],\n paneId: paneConfig.id,\n chart,\n };\n },\n destroy() {\n if (resizeRaf) cancelAnimationFrame(resizeRaf);\n if (dragLayoutRaf) cancelAnimationFrame(dragLayoutRaf);\n resizeObserver.disconnect();\n paneResizeCtrl?.destroy();\n group.destroy();\n for (const c of paneCharts.values()) c.destroy();\n paneCharts.clear();\n container.replaceChildren();\n },\n };\n\n return stack;\n}\n"],"names":["STACKED_MAX_PANES","STACKED_DEFAULT_MIN_PANE_RATIO","STACKED_COMPACT_MARGIN","STACKED_FULL_X_MARGIN","stackResolutionScale","res","loadImage","src","resolve","reject","img","relativeRect","el","containerRect","r","exportStackImage","container","paneWrappers","paneCharts","dividers","backgroundColor","options","format","quality","resolution","includeBackground","includeDividers","transparent","scale","exportDpr","_a","originalDprs","c","chart","outW","outH","canvas","ctx","imageType","i","rect","dataUrl","divider","mime","DIVIDER_CLASS","RESIZING_CLASS","injectDividerStyles","direction","style","cursor","createDividerElement","index","size","handle","paneFlexStyle","ratio","minDim","resolveMinPaneHeightPx","availHeight","paneCount","minPaneRatio","minPanePx","byRatio","minH","resolveMinPaneWidthPx","availWidth","normalizePaneHeights","heightsPx","targetTotal","n","total","sum","s","h","even","out","scaled","allocated","attachPaneResize","paneIds","ratios","isHorizontal","dividerSize","minPaneSize","avail","cleanups","availableSize","dividerTotal","main","applyRatios","leadingIdx","trailingIdx","delta","sizesPx","minS","othersSum","idx","pairTotal","leadingSize","trailingSize","byId","onPointerDown","e","w","_b","lastCoord","onMove","ev","coord","d","onUp","fn","applyPaneFlexRatios","initialPaneRatio","height","tickCountForPaneHeight","heightPx","base","adaptive","tickCountForPaneWidth","widthPx","readBaseYTickCount","yAxis","adaptPaneAxes","meta","yTicks","xTicks","adaptAllPaneAxes","metas","m","countYAxes","axes","left","right","computeAlignedLeftMargin","panes","baseLeft","maxExtra","pane","computeAlignedRightMargin","baseRight","expandPaneSeries","series","buildIndicatorSeries","buildPaneChartOptions","chartContainer","stack","alignedMargins","showXAxis","showYAxis","isFirst","isLast","compactX","compactY","compactMargin","margins","baseX","_c","xAxis","baseY","_d","axis","yAxisOption","_e","_f","_g","_h","_i","mergeLayoutOptions","_j","_k","_m","_l","wrapperStyle","gap","gapStyle","resolveStackSyncOptions","sync","masterPaneId","createStackedChart","sharedXAxis","sharedYAxis","resizableOpt","resizable","resizeDividerSize","baseLayout","MARGINS","baseTop","alignedLeft","alignedRight","existingHeight","existingWidth","p","paneRatios","paneAxisMetas","paneResizeCtrl","isPaneDragging","resizeRaf","dragLayoutRaf","pendingDragLayout","commitPaneLayout","affected","indices","_","scheduleStackResize","resizeObserver","applyFlexCss","stackAvailSize","restorePaneChartDivs","wrapper","chartDiv","initDragSizes","measured","applyDragPaneSizes","dim","flushDragLayout","sizes","scheduleDragLayout","syncRatiosFromSizes","totalR","setAllChartsResizeSuspended","suspended","setInactiveChartsResizeSuspended","topIdx","bottomIdx","alignedBottom","createChart","seriesList","resizeOpts","finalSizes","normalized","master","group","createChartGroup","getBackgroundColor","theme","waitForStackReady","started","poll","q","getInitQueueStatus","runStackExport","opts","ext","link","mountPane","prevId","newRatio","a","b","j","id","syncOpts","preset","priceChart","addIndicatorToChart","source","resolveSourceSeries","x","prices","extractPriceSeries","paneConfig","buildIndicatorPaneFromPreset"],"mappings":";;AAuGO,MAAMA,KAAoB,GAEpBC,KAAiC,IAAI,GACrCC,KAAyB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,EAAA,GACpDC,KAAwB,EAAE,QAAQ,GAAA;ACxFxC,SAASC,GAAqBC,GAAoC;AACvE,MAAI,OAAOA,KAAQ,SAAU,QAAOA;AACpC,UAAQA,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EAAA;AAEb;AAEA,SAASC,GAAUC,GAAwC;AACzD,SAAO,IAAI,QAAQ,CAACC,GAASC,MAAW;AACtC,UAAMC,IAAM,IAAI,MAAA;AAChB,IAAAA,EAAI,SAAS,MAAMF,EAAQE,CAAG,GAC9BA,EAAI,UAAUD,GACdC,EAAI,MAAMH;AAAA,EACZ,CAAC;AACH;AAEA,SAASI,GACPC,GACAC,GACyD;AACzD,QAAMC,IAAIF,EAAG,sBAAA;AACb,SAAO;AAAA,IACL,GAAGE,EAAE,OAAOD,EAAc;AAAA,IAC1B,GAAGC,EAAE,MAAMD,EAAc;AAAA,IACzB,OAAOC,EAAE;AAAA,IACT,QAAQA,EAAE;AAAA,EAAA;AAEd;AAKA,eAAsBC,GACpBC,GACAC,GACAC,GACAC,GACAC,GACAC,IAA8B,IACb;;AACjB,QAAM;AAAA,IACJ,QAAAC,IAAS;AAAA,IACT,SAAAC,IAAU;AAAA,IACV,YAAAC,IAAa;AAAA,IACb,mBAAAC,IAAoB;AAAA,IACpB,iBAAAC,IAAkB;AAAA,IAClB,aAAAC,IAAc;AAAA,EAAA,IACZN,GAEEO,IAAQxB,GAAqBoB,CAAU,GAEvCK,OADUC,IAAAZ,EAAW,CAAC,MAAZ,gBAAAY,EAAe,cAAa,OAAO,SAAW,MAAc,OAAO,mBAAmB,MAC1EF,GACtBG,IAAeb,EAAW,IAAI,CAACc,MAAMA,EAAE,QAAQ;AAErD,MAAI;AACF,QAAIJ,IAAQ,GAAG;AACb,iBAAWK,KAASf;AAGlB,QAAI,OAAOe,EAAM,+BAAgC,aAC/CA,EAAM,4BAA4BJ,CAAS,IAE3CI,EAAM,OAAOJ,CAAS,GAExBI,EAAM,OAAA;AAER,YAAM,IAAI,QAAQ,CAACnB,MAAM,sBAAsBA,CAAC,CAAC,GACjD,MAAM,IAAI,QAAQ,CAACA,MAAM,sBAAsBA,CAAC,CAAC,GACjD,MAAM,IAAI,QAAQ,CAACA,MAAM,WAAWA,GAAG,EAAE,CAAC;AAAA,IAC5C;AAEA,UAAMD,IAAgBG,EAAU,sBAAA,GAC1BkB,IAAO,KAAK,IAAI,GAAG,KAAK,MAAMrB,EAAc,QAAQgB,CAAS,CAAC,GAC9DM,IAAO,KAAK,IAAI,GAAG,KAAK,MAAMtB,EAAc,SAASgB,CAAS,CAAC,GAE/DO,IAAS,SAAS,cAAc,QAAQ;AAC9C,IAAAA,EAAO,QAAQF,GACfE,EAAO,SAASD;AAChB,UAAME,IAAMD,EAAO,WAAW,IAAI;AAClC,QAAI,CAACC,EAAK,OAAM,IAAI,MAAM,gCAAgC;AAE1D,IAAI,CAACV,KAAeF,MAClBY,EAAI,YAAYjB,KAAmB,WACnCiB,EAAI,SAAS,GAAG,GAAGH,GAAMC,CAAI;AAG/B,UAAMG,IAAYhB,MAAW,SAAS,SAAS;AAE/C,aAASiB,IAAI,GAAGA,IAAItB,EAAa,QAAQsB,KAAK;AAC5C,YAAMC,IAAO7B,GAAaM,EAAasB,CAAC,GAAG1B,CAAa,GAClD4B,IAAUvB,EAAWqB,CAAC,EAAE,YAAYD,CAAS,GAC7C5B,IAAM,MAAMJ,GAAUmC,CAAO;AACnC,MAAAJ,EAAI;AAAA,QACF3B;AAAA,QACA,KAAK,MAAM8B,EAAK,IAAIX,CAAS;AAAA,QAC7B,KAAK,MAAMW,EAAK,IAAIX,CAAS;AAAA,QAC7B,KAAK,MAAMW,EAAK,QAAQX,CAAS;AAAA,QACjC,KAAK,MAAMW,EAAK,SAASX,CAAS;AAAA,MAAA;AAAA,IAEtC;AAEA,QAAIH,KAAmBP,EAAS,QAAQ;AACtC,MAAAkB,EAAI,YAAY;AAChB,iBAAWK,KAAWvB,GAAU;AAC9B,cAAMqB,IAAO7B,GAAa+B,GAAS7B,CAAa;AAChD,QAAAwB,EAAI;AAAA,UACF,KAAK,MAAMG,EAAK,IAAIX,CAAS;AAAA,UAC7B,KAAK,MAAMW,EAAK,IAAIX,CAAS;AAAA,UAC7B,KAAK,IAAI,GAAG,KAAK,MAAMW,EAAK,QAAQX,CAAS,CAAC;AAAA,UAC9C,KAAK,IAAI,GAAG,KAAK,MAAMW,EAAK,SAASX,CAAS,CAAC;AAAA,QAAA;AAAA,MAEnD;AAAA,IACF;AAEA,UAAMc,IAAOrB,MAAW,SAAS,eAAeA,MAAW,SAAS,eAAe;AACnF,WAAOc,EAAO,UAAUO,GAAMpB,CAAO;AAAA,EACvC,UAAA;AACE,QAAIK,IAAQ;AACV,eAASW,IAAI,GAAGA,IAAIrB,EAAW,QAAQqB;AACrC,QAAI,OAAOrB,EAAWqB,CAAC,EAAE,+BAAgC,aACvDrB,EAAWqB,CAAC,EAAE,4BAA6B,IAAI,IAE/CrB,EAAWqB,CAAC,EAAE,OAAOR,EAAaQ,CAAC,CAAC,GAEtCrB,EAAWqB,CAAC,EAAE,OAAA;AAAA,EAGpB;AACF;ACpIA,MAAMK,IAAgB,qBAChBC,IAAiB;AAEvB,SAASC,GAAoBC,GAAiC;AAC5D,MAAI,OAAO,WAAa,IAAa;AACrC,MAAIC,IAAQ,SAAS,eAAe,0BAA0B;AAC9D,EAAKA,MACHA,IAAQ,SAAS,cAAc,OAAO,GACtCA,EAAM,KAAK,4BACX,SAAS,KAAK,YAAYA,CAAK;AAIjC,QAAMC,IADeF,MAAc,eACL,cAAc;AAG5C,EAAAC,EAAM,cAAc;AAAA,OACfJ,CAAa;AAAA;AAAA;AAAA,gBAGJK,CAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAMfL,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAMbA,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAObA,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAObA,CAAa;AAAA,OACbC,CAAc,KAAKD,CAAa;AAAA;AAAA;AAAA,OAGhCA,CAAa;AAAA,OACbC,CAAc,KAAKD,CAAa;AAAA;AAAA;AAAA,OAGhCA,CAAa;AAAA,OACbC,CAAc,KAAKD,CAAa;AAAA;AAAA;AAAA,OAGhCA,CAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAiBbA,CAAa,WAAWA,CAAa;AAAA,OACrCC,CAAc,KAAKD,CAAa;AAAA;AAAA;AAAA,OAGhCC,CAAc;AAAA,gBACLI,CAAM;AAAA;AAAA,OAEfJ,CAAc;AAAA,gBACLI,CAAM;AAAA;AAAA,OAEfJ,CAAc;AAAA;AAAA;AAAA;AAAA;AAOrB;AAEA,SAASK,GAAqBC,GAAeC,GAAcL,GAA2C;AACpG,QAAML,IAAU,SAAS,cAAc,KAAK;AAC5C,EAAAA,EAAQ,YAAYE,GACpBF,EAAQ,QAAQ,eAAe,OAAOS,CAAK,GAC3CT,EAAQ,QAAQ,YAAYK,GAC5BL,EAAQ,MAAM,YAAY,uBAAuB,GAAGU,CAAI,IAAI;AAE5D,QAAMC,IAAS,SAAS,cAAc,KAAK;AAC3C,SAAAA,EAAO,YAAY,GAAGT,CAAa,WACnCS,EAAO,cAAcN,MAAc,eAAe,MAAM,KACxDL,EAAQ,YAAYW,CAAM,GAEnBX;AACT;AAOA,SAASY,GAAcC,GAAwBR,GAAmC;AAChF,QAAMS,IAAST,MAAc,eAAe,iBAAiB;AAC7D,SAAI,OAAOQ,KAAU,WACZ,QAAQA,CAAK,QAAQC,CAAM,KAE7B,YAAYD,CAAK,IAAIC,CAAM;AACpC;AAEO,SAASC,GACdC,GACAC,GACAC,IAAe3D,IACf4D,IAAY,GACJ;AACR,MAAIF,IAAY,KAAKD,KAAe,EAAG,QAAO;AAC9C,QAAMI,IAAUJ,IAAcE,GACxBG,IAAO,KAAK,IAAIF,GAAWC,CAAO;AACxC,SAAO,KAAK,IAAIC,GAAML,IAAcC,CAAS;AAC/C;AAEO,SAASK,GACdC,GACAN,GACAC,IAAe3D,IACf4D,IAAY,GACJ;AACR,SAAOJ,GAAuBQ,GAAYN,GAAWC,GAAcC,CAAS;AAC9E;AAEO,SAASK,GAAqBC,GAAqBC,GAA+B;AACvF,QAAMC,IAAIF,EAAU;AACpB,MAAIE,MAAM,EAAG,QAAOF;AACpB,QAAMG,IAAQ,KAAK,IAAI,GAAG,KAAK,MAAMF,CAAW,CAAC,GAC3CG,IAAMJ,EAAU,OAAO,CAACK,GAAGC,MAAMD,IAAIC,GAAG,CAAC;AAC/C,MAAIF,KAAO,GAAG;AACZ,UAAMG,IAAO,KAAK,MAAMJ,IAAQD,CAAC,GAC3BM,IAAMR,EAAU,IAAI,MAAMO,CAAI;AACpCC,WAAAA,EAAIN,IAAI,CAAC,IAAIC,IAAQI,KAAQL,IAAI,IAC1BM;AAAAA,EACT;AAEA,QAAMC,IAAST,EAAU,IAAI,CAACM,MAAOA,IAAIF,IAAOD,CAAK,GAC/CK,IAAgB,CAAA;AACtB,MAAIE,IAAY;AAChB,WAAStC,IAAI,GAAGA,IAAI8B,IAAI,GAAG9B;AACzB,IAAAoC,EAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAMC,EAAOrC,CAAC,CAAC,CAAC,CAAC,GAC3CsC,KAAaF,EAAIpC,CAAC;AAEpB,SAAAoC,EAAI,KAAK,KAAK,IAAI,GAAGL,IAAQO,CAAS,CAAC,GAChCF;AACT;AAIO,SAASG,GACd9D,GACAC,GACA8D,GACAC,GACA3D,IAA6B,IACP;AACtB,QAAM0B,IAAY1B,EAAQ,aAAa,YACjC4D,IAAelC,MAAc;AACnC,EAAAD,GAAoBC,CAAS;AAE7B,QAAMa,IAAevC,EAAQ,gBAAgBpB,IACvC4D,IAAYxC,EAAQ,aAAa,GACjC6D,IAAc7D,EAAQ,eAAe,GACrCsC,IAAY1C,EAAa,QAEzBkE,IAAc,CAACC,MACnBH,IACIjB,GAAsBoB,GAAOzB,GAAWC,GAAcC,CAAS,IAC/DJ,GAAuB2B,GAAOzB,GAAWC,GAAcC,CAAS,GAEhE1C,IAA6B,CAAA,GAC7BkE,IAA2B,CAAA;AAEjC,MAAIpE,EAAa,SAAS;AACxB,WAAO,EAAE,UAAAE,GAAU,SAAS,MAAM;AAAA,IAAC,EAAA;AAGrC,QAAMmE,IAAgB,MAAc;AAClC,UAAMC,IAAepE,EAAS,SAAS+D,GACjCM,IAAOP,IAAejE,EAAU,cAAcA,EAAU;AAC9D,WAAO,KAAK,IAAI,GAAGwE,IAAOD,CAAY;AAAA,EACxC,GAEME,IAAc,CAClBC,GACAC,GACAC,GACAC,MACG;;AACH,UAAMT,IAAQE,EAAA,GACRQ,IAAOX,EAAYC,CAAK,GAExBW,IAAYF,EAAQ;AAAA,MACxB,CAACrB,GAAGC,GAAGuB,MAASA,MAAQN,KAAcM,MAAQL,IAAcnB,IAAIA,IAAIC;AAAA,MACpE;AAAA,IAAA,GAEIwB,IAAYb,IAAQW;AAE1B,QAAIG,IAAcL,EAAQH,CAAU,IAAIE;AACxC,IAAAM,IAAc,KAAK,IAAIJ,GAAM,KAAK,IAAIG,IAAYH,GAAMI,CAAW,CAAC;AACpE,UAAMC,IAAeF,IAAYC;AAEjC,IAAAL,EAAQH,CAAU,IAAIQ,GACtBL,EAAQF,CAAW,IAAIQ;AAEvB,UAAM7B,IAAQU,EAAO,OAAO,CAACR,GAAG1D,MAAM0D,IAAI1D,GAAG,CAAC;AAM9C,QALAkE,EAAOU,CAAU,IAAKQ,IAAcd,IAASd,GAC7CU,EAAOW,CAAW,IAAKQ,IAAef,IAASd,IAE/CxC,IAAAT,EAAQ,eAAR,QAAAS,EAAA,KAAAT,GAAqBwE,GAASH,GAAYC,IAEtCtE,EAAQ,UAAU;AACpB,YAAM+E,IAA+B,CAAA;AACrC,eAAS7D,IAAI,GAAGA,IAAIwC,EAAQ,QAAQxC;AAClC,QAAA6D,EAAKrB,EAAQxC,CAAC,CAAC,IAAIyC,EAAOzC,CAAC;AAE7B,MAAAlB,EAAQ,SAAS+E,CAAI;AAAA,IACvB;AAAA,EACF;AAEA,WAAS7D,IAAI,GAAGA,IAAItB,EAAa,SAAS,GAAGsB,KAAK;AAChD,UAAMG,IAAUQ,GAAqBX,GAAG2C,GAAanC,CAAS;AAE9D,IADuB9B,EAAasB,CAAC,EACtB,MAAMG,CAAO,GAC5BvB,EAAS,KAAKuB,CAAO;AAErB,UAAM2D,IAAgB,CAACC,MAAoB;;AACzC,MAAAA,EAAE,eAAA,GACF5D,EAAQ,kBAAkB4D,EAAE,SAAS,GACrCtF,EAAU,UAAU,IAAI6B,CAAc;AAEtC,YAAMgD,MACJ/D,IAAAT,EAAQ,gBAAR,gBAAAS,EAAA,KAAAT,GAAsBkB,GAAGA,IAAI,OAC7BtB,EAAa;AAAA,QAAI,CAACsF,MAChBtB,IAAesB,EAAE,wBAAwB,QAAQA,EAAE,wBAAwB;AAAA,MAAA;AAG/E,OAAAC,IAAAnF,EAAQ,eAAR,QAAAmF,EAAA,KAAAnF,GAAqBwE,GAAStD,GAAGA,IAAI;AAErC,UAAIkE,IAAYxB,IAAeqB,EAAE,UAAUA,EAAE;AAE7C,YAAMI,IAAS,CAACC,MAAqB;AACnC,cAAMC,IAAQ3B,IAAe0B,EAAG,UAAUA,EAAG,SACvCE,IAAID,IAAQH;AAClB,QAAAA,IAAYG,GACRC,MAAM,KAAGpB,EAAYlD,GAAGA,IAAI,GAAGsE,GAAGhB,CAAO;AAAA,MAC/C,GAEMiB,IAAO,CAACH,MAAqB;;AACjC,QAAAjE,EAAQ,sBAAsBiE,EAAG,SAAS,GAC1C3F,EAAU,UAAU,OAAO6B,CAAc,GACzCH,EAAQ,oBAAoB,eAAegE,CAAM,GACjDhE,EAAQ,oBAAoB,aAAaoE,CAAI,GAC7CpE,EAAQ,oBAAoB,iBAAiBoE,CAAI,IACjDhF,IAAAT,EAAQ,cAAR,QAAAS,EAAA,KAAAT,GAAoBwE;AAAA,MACtB;AAEA,MAAAnD,EAAQ,iBAAiB,eAAegE,CAAM,GAC9ChE,EAAQ,iBAAiB,aAAaoE,CAAI,GAC1CpE,EAAQ,iBAAiB,iBAAiBoE,CAAI;AAAA,IAChD;AAEA,IAAApE,EAAQ,iBAAiB,eAAe2D,CAAa,GACrDhB,EAAS,KAAK,MAAM3C,EAAQ,oBAAoB,eAAe2D,CAAa,CAAC;AAAA,EAC/E;AAEA,SAAO;AAAA,IACL,UAAAlF;AAAA,IACA,SAAS,MAAM;AACb,iBAAW4F,KAAM1B,EAAU,CAAA0B,EAAA;AAC3B,iBAAWF,KAAK1F,EAAU,CAAA0F,EAAE,OAAA;AAC5B,MAAA7F,EAAU,UAAU,OAAO6B,CAAc;AAAA,IAC3C;AAAA,EAAA;AAEJ;AAEO,SAASmE,GACd/F,GACA+D,GACAjC,IAA4B,YACtB;AACN,WAASR,IAAI,GAAGA,IAAItB,EAAa,QAAQsB;AACvC,IAAAtB,EAAasB,CAAC,EAAE,MAAM,UAAU,GAAGe,GAAc0B,EAAOzC,CAAC,GAAGQ,CAAS,CAAC;AAE1E;AAEO,SAASkE,GAAiBC,GAAiC;AAChE,SAAO,OAAOA,KAAW,WAAWA,IAAS;AAC/C;ACtUO,SAASC,GAAuBC,GAAkBC,IAAO,GAAW;AACzE,MAAI,CAAC,OAAO,SAASD,CAAQ,KAAKA,KAAY,EAAG,QAAOC;AACxD,QAAMC,IAAW,KAAK,MAAMF,IAAW,EAAE;AACzC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAIC,GAAMC,CAAQ,CAAC;AAC7C;AAGO,SAASC,GAAsBC,GAAiBH,IAAO,GAAW;AACvE,MAAI,CAAC,OAAO,SAASG,CAAO,KAAKA,KAAW,EAAG,QAAOH;AACtD,QAAMC,IAAW,KAAK,MAAME,IAAU,EAAE;AACxC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAIH,GAAMC,CAAQ,CAAC;AAC7C;AAUO,SAASG,GAAmBC,GAAmE;;AACpG,SAAKA,MAEE5F,KADM,MAAM,QAAQ4F,CAAK,IAAIA,IAAQ,CAACA,CAAK,GACtC,CAAC,MAAN,gBAAA5F,EAAS,cAAa,IAFV;AAGrB;AAEO,SAAS6F,GAAcC,GAA0B;AACtD,QAAMnD,IAAImD,EAAK,QAAQ,cACjBrB,IAAIqB,EAAK,QAAQ,aACjBC,IAASV,GAAuB1C,GAAGmD,EAAK,cAAc;AAI5D,MAFAA,EAAK,MAAM,YAAY,WAAW,EAAE,WAAWC,GAAQ,GAEnDD,EAAK,WAAW;AAClB,UAAME,IAASP,GAAsBhB,GAAGqB,EAAK,cAAc;AAC3D,IAAAA,EAAK,MAAM,YAAY,EAAE,WAAWE,GAAQ;AAAA,EAC9C;AACF;AAEO,SAASC,GAAiBC,GAA6B;AAC5D,aAAWC,KAAKD,EAAO,CAAAL,GAAcM,CAAC;AACxC;ACDA,SAASC,GAAWR,GAAsE;AACxF,QAAMS,IAAOT,IAAS,MAAM,QAAQA,CAAK,IAAIA,IAAQ,CAACA,CAAK,IAAK,CAAC,EAAE;AACnE,MAAIU,IAAO,GACPC,IAAQ;AACZ,aAAW,KAAKF;AACd,IAAI,EAAE,aAAa,UAASE,MACvBD;AAEP,SAAO,EAAE,MAAM,KAAK,IAAI,GAAGA,CAAI,GAAG,OAAAC,EAAA;AACpC;AAEA,SAASC,GAAyBC,GAA4BC,GAA0B;;AACtF,MAAIC,IAAW;AACf,aAAWC,KAAQH,GAAO;AACxB,UAAM,EAAE,MAAAH,EAAA,IAASF,IAAWpG,IAAA4G,EAAK,UAAL,gBAAA5G,EAAY,KAAK;AAC7C,IAAA2G,IAAW,KAAK,IAAIA,IAAWL,IAAO,KAAK,EAAE;AAAA,EAC/C;AACA,SAAOI,IAAWC;AACpB;AAEA,SAASE,GAA0BJ,GAA4BK,GAA2B;;AACxF,MAAIH,IAAW;AACf,aAAWC,KAAQH,GAAO;AACxB,UAAM,EAAE,OAAAF,EAAA,IAAUH,IAAWpG,IAAA4G,EAAK,UAAL,gBAAA5G,EAAY,KAAK;AAC9C,IAAA2G,IAAW,KAAK,IAAIA,GAAUJ,IAAQ,EAAE;AAAA,EAC1C;AACA,SAAOO,IAAYH;AACrB;AAIA,SAASnF,GAAcC,GAAeR,GAAmC;AAEvE,SAAO,QAAQQ,CAAK,QADLR,MAAc,eAAe,iBAAiB,eAC3B;AACpC;AAEA,SAAS8F,GAAiBC,GAA2C;AACnE,MAAI,EAACA,KAAA,QAAAA,EAAQ,QAAQ,QAAO,CAAA;AAC5B,QAAMnE,IAAuB,CAAA;AAC7B,aAAWH,KAAKsE;AACd,IAAItE,EAAE,SAAS,cACbG,EAAI,KAAK,GAAGoE,GAAqBvE,CAA2B,CAAC,IAE7DG,EAAI,KAAKH,CAAC;AAGd,SAAOG;AACT;AAEA,SAASqE,GACPN,GACAO,GACAC,GACA/F,GACAmB,GACA6E,GACAC,GACAC,GACAtG,GACmC;;AACnC,QAAMuG,IAAUnG,MAAU,GACpBoG,IAASpG,MAAUmB,IAAQ,GAC3BW,IAAelC,MAAc,cAE7ByG,IADe,CAACvE,KAAgBiE,EAAM,gBAAgB,UAC3B,CAACE,GAE5BK,IADaxE,MAAiBiE,EAAM,eAAe,YAAY,UACtC,CAACG,GAE1BK,KADUR,EAAM,OAAO,KACG,IAAIhJ,KAAyB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,EAAA,GAElFyJ,IAAU1E,IACZ;AAAA,IACE,KAAKkE,EAAe;AAAA,IACpB,OAAOI,IAASJ,EAAe,QAAQO,EAAc;AAAA,IACrD,MAAMD,IAAWC,EAAc,OAAOP,EAAe;AAAA,IACrD,QAAQA,EAAe;AAAA,EAAA,IAEzB;AAAA,IACE,KAAKG,IAAUH,EAAe,MAAMO,EAAc;AAAA,IAClD,OAAOP,EAAe;AAAA,IACtB,MAAMA,EAAe;AAAA,IACrB,QAAQK,IACJE,EAAc,SACdH,MACG/C,KAAA1E,IAAAoH,EAAM,WAAN,gBAAApH,EAAc,YAAd,gBAAA0E,EAAuB,WAAUrG,GAAsB,SACxDgJ,EAAe;AAAA,EAAA,GAGrBS,MAAQC,IAAAnB,EAAK,UAAL,gBAAAmB,EAAY,UAAS,CAAA,GAC7BC,IAAQ;AAAA,IACZ,GAAGF;AAAA,IACH,UAAUR,IAAYQ,EAAM,YAAY,KAAO;AAAA,IAC/C,WAAWR,IAAYQ,EAAM,aAAa,KAAO;AAAA,IACjD,YAAYR,IAAYQ,EAAM,cAAc,KAAO;AAAA,EAAA,GAG/CG,MAAQC,IAAAtB,EAAK,UAAL,gBAAAsB,EAAY,UAAS,CAAA,GAE7BtC,KADW,MAAM,QAAQqC,CAAK,IAAIA,IAAQ,CAACA,CAAK,GAC/B,IAAI,CAACE,OAAU;AAAA,IACpC,GAAGA;AAAA,IACH,UAAUZ,IAAYY,EAAK,YAAY,KAAO;AAAA,IAC9C,WAAWZ,IAAYY,EAAK,aAAa,KAAO;AAAA,IAChD,YAAYZ,IAAYY,EAAK,cAAc,KAAO;AAAA,EAAA,EAClD,GACIC,IAAc,MAAM,SAAQC,IAAAzB,EAAK,UAAL,gBAAAyB,EAAY,KAAK,IAAIzC,IAAQA,EAAM,CAAC;AAGtE,UADsBgB,EAAK,eAAe,QAExCO,EAAe,MAAM,gBAAgB,SAGhC;AAAA,IACL,GAAGP,EAAK;AAAA,IACR,IAAIA,EAAK;AAAA,IACT,WAAWO;AAAA,IACX,cAAYmB,IAAA1B,EAAK,UAAL,gBAAA0B,EAAY,eAAclB,EAAM,cAAc;AAAA,IAC1D,SAAOmB,IAAA3B,EAAK,UAAL,gBAAA2B,EAAY,UAASnB,EAAM;AAAA,IAClC,kBAAkBA,EAAM,sBAAoBoB,IAAA5B,EAAK,UAAL,gBAAA4B,EAAY;AAAA,IACxD,WAASC,IAAA7B,EAAK,UAAL,gBAAA6B,EAAY,YAAW;AAAA,IAChC,OAAAT;AAAA,IACA,OAAOI;AAAA,IACP,QAAQM,GAAmB;AAAA,MACzB,GAAGtB,EAAM;AAAA,MACT,IAAGuB,IAAA/B,EAAK,UAAL,gBAAA+B,EAAY;AAAA,MACf,SAAS,EAAE,GAAGd,GAAS,IAAGe,KAAAxB,EAAM,WAAN,gBAAAwB,GAAc,SAAS,IAAGC,MAAAC,KAAAlC,EAAK,UAAL,gBAAAkC,GAAY,WAAZ,gBAAAD,GAAoB,QAAA;AAAA,IAAQ,CACjF;AAAA,EAAA;AAEL;AAEA,SAASE,GAAatH,GAAeuH,GAAa3H,GAAeJ,GAAmC;AAClG,QAAMgI,IACJD,IAAM,KAAK3H,IAAQ,IACfJ,MAAc,eACZ,eAAe+H,CAAG,QAClB,cAAcA,CAAG,QACnB;AACN,SAAO,GAAGxH,GAAcC,GAAOR,CAAS,CAAC,qCAAqCgI,CAAQ;AACxF;AAEA,SAASC,GACPC,GACAC,GACAnI,GACa;AACb,SAAIkI,MAAS,KACJ;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,IACT,eAAe;AAAA,IACf,UAAU;AAAA,EAAA,IAMP;AAAA,IACL,MAHuClI,MAAc,eAAe,MAAM;AAAA,IAI1E,eAAe;AAAA,IACf,UAAUmI;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,SAAS;AAAA,IACT,GAAI,OAAOD,KAAS,WAAWA,IAAO,CAAA;AAAA,EAAC;AAE3C;AAEO,SAASE,GAAmB9J,GAA4C;;AAC7E,QAAM,EAAE,WAAAL,GAAW,OAAAuH,EAAA,IAAUlH;AAC7B,MAAI,CAACL,EAAW,OAAM,IAAI,MAAM,sCAAsC;AACtE,MAAIuH,EAAM,SAAS,KAAKA,EAAM,SAASvI;AACrC,UAAM,IAAI,MAAM,kCAAkCA,EAAiB,EAAE;AAGvE,QAAMkL,IAAe7J,EAAQ,gBAAgBkH,EAAM,CAAC,EAAE,IAChDxF,IAA4B1B,EAAQ,aAAa,YACjD4D,IAAelC,MAAc,cAC7BqI,IAAc/J,EAAQ,eAAe,UACrCgK,IAAchK,EAAQ,eAAe,QACrCyJ,IAAMzJ,EAAQ,OAAO,GACrBiK,IAAejK,EAAQ,WACvBkK,IAAY,CAAC,CAACD,GACdE,IACJ,OAAOF,KAAiB,WAAYA,EAAa,eAAe,IAAK,GAEjEG,IAAajB,GAAmBnJ,EAAQ,MAAM,GAC9CmH,MAAW1G,KAAA2J,EAAW,YAAX,gBAAA3J,GAAoB,SAAQ4J,EAAQ,MAC/C9C,MAAYpC,KAAAiF,EAAW,YAAX,gBAAAjF,GAAoB,UAASkF,EAAQ,OACjDC,MAAU9B,KAAA4B,EAAW,YAAX,gBAAA5B,GAAoB,QAAO6B,EAAQ,KAC7CE,IAActD,GAAyBC,GAAOC,CAAQ,GACtDqD,IAAelD,GAA0BJ,GAAOK,CAAS;AAE/D,EAAA5H,EAAU,gBAAA,GACVA,EAAU,MAAM,UAAU,QAC1BA,EAAU,MAAM,gBAAgBiE,IAAe,QAAQ,UACvDjE,EAAU,MAAM,QAAQ;AACxB,QAAM8K,IAAiB9K,EAAU,gBAAgB,SAAS,iBAAiBA,CAAS,EAAE,QAAQ,EAAE,GAC1F+K,IAAgB/K,EAAU,eAAe,SAAS,iBAAiBA,CAAS,EAAE,OAAO,EAAE;AAC7F,EAAIiE,KACE8G,IAAgB,MAClB/K,EAAU,MAAM,QAAQ,GAAG+K,CAAa,MACxC/K,EAAU,MAAM,WAAW,GAAG+K,CAAa,OAE7C/K,EAAU,MAAM,SAAS8K,IAAiB,IAAI,GAAGA,CAAc,OAAO,SACtE9K,EAAU,MAAM,YAAYA,EAAU,MAAM,UAExC8K,IAAiB,KACnB9K,EAAU,MAAM,SAAS,GAAG8K,CAAc,MAC1C9K,EAAU,MAAM,YAAY,GAAG8K,CAAc,QACnC9K,EAAU,MAAM,WAC1BA,EAAU,MAAM,YAAY,UAGhCA,EAAU,MAAM,WAAW,UAC3BA,EAAU,MAAM,WAAW;AAE3B,QAAM+D,IAAUwD,EAAM,IAAI,CAACyD,MAAMA,EAAE,EAAE,GAC/BC,IAAa1D,EAAM,IAAI,CAACyD,MAAM/E,GAAiB+E,EAAE,MAAM,CAAC,GACxD9K,wBAAiB,IAAA,GACjBD,IAAiC,CAAA,GACjCiL,IAAgC,CAAA;AACtC,MAAIC,IAA8C,MAC9CC,IAAiB,IACjBC,IAAY,GACZC,IAAgB,GAChBC,IAIO;AAEX,QAAMC,IAAmB,CAACC,MAAwB;AAChD,UAAMC,IAEJ,MAAM,KAAK,EAAE,QAAQzL,EAAa,UAAU,CAAC0L,GAAGpK,MAAMA,CAAC;AAEzD,eAAWA,KAAKmK,GAAS;AACvB,YAAMzK,IAAQf,EAAW,IAAI6D,EAAQxC,CAAC,CAAC;AACvC,MAAIN,KACFA,EAAM,OAAA;AAAA,IAEV;AACA,IAAA8F;AAAA,MACE2E,EAAQ,IAAI,CAACnK,MAAM2J,EAAc3J,CAAC,CAAC,EAAE,OAAO,OAAO;AAAA,IAAA;AAAA,EAEvD,GAEMqK,IAAsB,MAAM;AAChC,IAAIP,MACJA,IAAY,sBAAsB,MAAM;AAEtC,MADAA,IAAY,GACR,CAAAD,KACJI,EAAA;AAAA,IACF,CAAC;AAAA,EACH,GAEMK,IAAiB,IAAI,eAAe,MAAM;AAC9C,IAAIT,KACJQ,EAAA;AAAA,EACF,CAAC;AACD,EAAAC,EAAe,QAAQ7L,CAAS;AAEhC,QAAM8L,IAAe,MAAM;AACzB,aAASvK,IAAI,GAAGA,IAAItB,EAAa,QAAQsB;AACvC,MAAAtB,EAAasB,CAAC,EAAE,MAAM,UAAUsI,GAAaoB,EAAW1J,CAAC,GAAGuI,GAAKvI,GAAGQ,CAAS;AAAA,EAEjF,GAEMgK,IAAiB,MAAM;AAC3B,UAAMxH,KAAgBtE,EAAa,SAAS,KAAKuK;AACjD,WAAIvG,IACK,KAAK,IAAI,GAAGjE,EAAU,cAAcuE,CAAY,IAElD,KAAK,IAAI,GAAGvE,EAAU,eAAeuE,CAAY;AAAA,EAC1D,GAEMyH,IAAuB,MAAM;AACjC,eAAWC,KAAWhM,GAAc;AAClC,YAAMiM,IAAWD,EAAQ;AACzB,MAAIC,MACFA,EAAS,MAAM,UAAU;AAAA,IAE7B;AAAA,EACF,GAEMC,KAAgB,MAAgB;AACpC,UAAM/H,IAAQ2H,EAAA,GACRK,IAAWnM,EAAa;AAAA,MAAI,CAACsF,MACjCtB,IAAesB,EAAE,wBAAwB,QAAQA,EAAE,wBAAwB;AAAA,IAAA,GAEvEhC,IAAM6I,EAAS,OAAO,CAAC5I,GAAGC,MAAMD,IAAIC,GAAG,CAAC;AAC9C,WAAOF,IAAM,IAAI6I,EAAS,IAAI,CAAC3I,MAAMA,KAAKW,IAAQb,EAAI,IAAI6I;AAAA,EAC5D,GAEMC,KAAqB,CAACxH,MAAsB;AAChD,aAAS,IAAI,GAAG,IAAI5E,EAAa,QAAQ,KAAK;AAC5C,YAAMmC,IAAO,KAAK,IAAI,GAAG,KAAK,MAAMyC,EAAQ,CAAC,CAAC,CAAC,GACzCkF,IACJD,IAAM,KAAK,IAAI,IACX7F,IACE,eAAe6F,CAAG,QAClB,cAAcA,CAAG,QACnB,IACAwC,IAAMrI,IAAe,UAAU;AACrC,MAAAhE,EAAa,CAAC,EAAE,MAAM,UAAU,GAAGqM,CAAG,IAAIlK,CAAI,+EAA+E2H,CAAQ;AAAA,IACvI;AAAA,EACF,GAEMwC,KAAkB,MAAM;AAE5B,QADAjB,IAAgB,GACZ,CAACF,KAAkB,CAACG,EAAmB;AAE3C,UAAM,EAAE,OAAAiB,GAAO,YAAA9H,GAAY,aAAAC,EAAA,IAAgB4G;AAC3C,IAAAc,GAAmBG,CAAK;AAExB,eAAWjL,KAAK,CAACmD,GAAYC,CAAW,GAAG;AACzC,YAAM1D,IAAQf,EAAW,IAAI6D,EAAQxC,CAAC,CAAC;AACvC,MAAIN,MACFA,EAAM,OAAA,GACN8F,GAAiB,CAACmE,EAAc3J,CAAC,CAAC,CAAC;AAAA,IAEvC;AAAA,EACF,GAEMkL,IAAqB,CACzB5H,GACAH,GACAC,MACG;AAEH,IADA4G,IAAoB,EAAE,OAAO1G,GAAS,YAAAH,GAAY,aAAAC,EAAA,GAC9C,CAAA2G,MACJA,IAAgB,sBAAsBiB,EAAe;AAAA,EACvD,GAEMG,KAAsB,CAAC7H,MAAsB;AACjD,UAAMvB,IAAQuB,EAAQ,OAAO,CAACrB,GAAGC,MAAMD,IAAIC,GAAG,CAAC;AAC/C,QAAIH,KAAS,EAAG;AAChB,UAAMqJ,IAAS1B,EAAW,OAAO,CAACzH,GAAG1D,MAAM0D,IAAI1D,GAAG,CAAC;AACnD,aAASyB,IAAI,GAAGA,IAAI0J,EAAW,QAAQ1J;AACrC,MAAA0J,EAAW1J,CAAC,IAAKsD,EAAQtD,CAAC,IAAI+B,IAASqJ;AAAA,EAE3C,GAEMC,KAA8B,CAACC,MAAuB;;AAC1D,eAAW5L,KAASf,EAAW;AAC7B,OAAAY,IAAAG,EAAM,uBAAN,QAAAH,EAAA,KAAAG,GAA2B4L;AAAA,EAE/B,GAEMC,KAAmC,CACvCC,GACAC,MACG;;AACH,aAASzL,IAAI,GAAGA,IAAIwC,EAAQ,QAAQxC;AAClC,MAAIA,MAAMwL,KAAUxL,MAAMyL,MAC1BxH,KAAA1E,IAAAZ,EAAW,IAAI6D,EAAQxC,CAAC,CAAC,MAAzB,gBAAAT,EAA4B,uBAA5B,QAAA0E,EAAA,KAAA1E,GAAiD;AAEnD,KAAAkI,KAAAH,IAAA3I,EAAW,IAAI6D,EAAQgJ,CAAM,CAAC,MAA9B,gBAAAlE,EAAiC,uBAAjC,QAAAG,EAAA,KAAAH,GAAsD,MACtDO,KAAAD,IAAAjJ,EAAW,IAAI6D,EAAQiJ,CAAS,CAAC,MAAjC,gBAAA7D,EAAoC,uBAApC,QAAAC,EAAA,KAAAD,GAAyD;AAAA,EAC3D,GAEM8D,KAAgBhJ,MACjBkF,MAAAH,KAAA3I,EAAQ,WAAR,gBAAA2I,GAAgB,YAAhB,gBAAAG,GAAyB,WAAUhK,GAAsB,SAC1DuL,EAAQ;AAEZ,WAASnJ,IAAI,GAAGA,IAAIgG,EAAM,QAAQhG,KAAK;AACrC,UAAMmG,IAAOH,EAAMhG,CAAC,GACd+G,IAAU/G,MAAM,GAChBgH,IAAShH,MAAMgG,EAAM,SAAS,GAE9Ba,IAAYnE,IACbyD,EAAK,aAAa,KAClBA,EAAK,cAAc0C,MAAgB,WAAW7B,IAAS,KAEtDF,IAAYpE,IACbyD,EAAK,cAAc2C,MAAgB,SAAS/B,IAAU,MACtDZ,EAAK,aAAa,IAEjBuE,IAAU,SAAS,cAAc,KAAK;AAC5C,IAAAA,EAAQ,QAAQ,SAASvE,EAAK,IAC9BuE,EAAQ,MAAM,UAAUpC,GAAaoB,EAAW1J,CAAC,GAAGuI,GAAKvI,GAAGQ,CAAS;AAErE,UAAMmK,IAAW,SAAS,cAAc,KAAK;AAC7C,IAAAA,EAAS,MAAM,UAAU,qDAEzBD,EAAQ,YAAYC,CAAQ,GAC5BlM,EAAU,YAAYiM,CAAO,GAC7BhM,EAAa,KAAKgM,CAAO;AAEzB,UAAMhL,IAAQiM;AAAA,MACZlF;AAAA,QACEN;AAAA,QACAwE;AAAA,QACA7L;AAAA,QACAkB;AAAA,QACAgG,EAAM;AAAA,QACN;AAAA,UACE,MAAMtD,KAAgB,CAACoE,IAAYqC,EAAQ,OAAOE;AAAA,UAClD,OAAOC;AAAA,UACP,KAAKF;AAAA,UACL,QAAQsC;AAAA,QAAA;AAAA,QAEV7E;AAAA,QACAC;AAAA,QACAtG;AAAA,MAAA;AAAA,IACF,GAGIoL,IAAatF,GAAiBH,EAAK,MAAM;AAC/C,QAAIyF,EAAW;AACb,iBAAW3J,KAAK2J,EAAY,CAAAlM,EAAM,UAAUuC,CAAC;AAG/C,IAAIkE,EAAK,UAAUA,EAAK,WAAW,UACjCzG,EAAM,KAAK,EAAE,GAAGyG,EAAK,QAAQ,SAAS,IAAO,GAG/CxH,EAAW,IAAIwH,EAAK,IAAIzG,CAAK,GAE7BiK,EAAc,KAAK;AAAA,MACjB,OAAAjK;AAAA,MACA,SAAAgL;AAAA,MACA,gBAAgBxF,IAAmB2C,KAAA1B,EAAK,UAAL,gBAAA0B,GAAY,KAAK;AAAA,MACpD,kBAAgBE,MAAAD,KAAA3B,EAAK,UAAL,gBAAA2B,GAAY,UAAZ,gBAAAC,GAAmB,cAAa;AAAA,MAChD,WAAAlB;AAAA,IAAA,CACD;AAAA,EACH;AAEA,MAAImC,KAAahD,EAAM,SAAS,GAAG;AACjC,UAAM6F,IACJ,OAAO9C,KAAiB,WACpB;AAAA,MACE,cAAcA,EAAa;AAAA,MAC3B,WAAWA,EAAa;AAAA,MACxB,aAAaA,EAAa;AAAA,IAAA,IAE5B,CAAA;AACN,IAAAa,IAAiBrH;AAAA,MACf9D;AAAA,MACAC;AAAA,MACA8D;AAAA,MACAkH;AAAA,MACA;AAAA,QACE,WAAAlJ;AAAA,QACA,GAAGqL;AAAA,QACH,aAAa,CAAC1I,GAAYC,OACxByG,IAAiB,IACjBwB,GAA4B,EAAI,GAChCE,GAAiCpI,GAAYC,CAAW,GACjDwH,GAAA;AAAA,QAET,YAAY,CAACK,GAAO9H,GAAYC,MAAgB;AAC9C,UAAA8H,EAAmBD,GAAO9H,GAAYC,CAAW;AAAA,QACnD;AAAA,QACA,WAAW,CAAC0I,MAAe;AACzB,UAAI/B,MACF,qBAAqBA,CAAa,GAClCA,IAAgB,IAElBC,IAAoB,MACpBH,IAAiB;AACjB,gBAAMkC,IAAapK,GAAqBmK,GAAYtB,EAAA,CAAgB;AACpE,UAAAW,GAAoBY,CAAU,GAC9BtB,EAAA,GACAF,EAAA,GACAc,GAA4B,EAAK,GACjCpB,EAAA;AAAA,QACF;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAEA,QAAM+B,IAASrN,EAAW,IAAIgK,CAAY;AAC1C,MAAI,CAACqD;AACH,UAAM,IAAI,MAAM,gCAAgCrD,CAAY,sBAAsB;AAGpF,QAAMsD,IAAQC;AAAA,IACZ,MAAM,KAAKvN,EAAW,QAAQ;AAAA,IAC9B8J,GAAwB3J,EAAQ,MAAM6J,GAAcnI,CAAS;AAAA,EAAA,GAGzD2L,KAAqB,MAAc;AACvC,UAAMC,IAAQJ,EAAO,SAASA,EAAO;AACrC,YAAOI,KAAA,gBAAAA,EAAO,oBAAmB;AAAA,EACnC,GAEMC,KAAoB,MAAqB;AAE7C,UAAMC,IAAU,KAAK,IAAA;AAerB,WAZE,IAAI,QAAQ,CAACrO,MAAY;AACvB,YAAMsO,IAAO,MAAM;AACjB,cAAMC,IAAIC,GAAA;AACV,YAAKD,EAAE,YAAY,KAAK,CAACA,EAAE,gBAAiB,KAAK,IAAA,IAAQF,IAAU,KAAS;AAC1E,UAAArO,EAAA;AACA;AAAA,QACF;AACA,mBAAWsO,GAAM,EAAE;AAAA,MACrB;AACA,MAAAA,EAAA;AAAA,IACF,CAAC,EAEuB,KAAK,MACtB,IAAI,QAAc,CAACtO,MAAY;AACpC,4BAAsB,MAAM;AAC1B,QAAAgM,EAAA,GACAhM,EAAA;AAAA,MACF,CAAC;AAAA,IACH,CAAC,CACF;AAAA,EACH,GAEMyO,KAAiB,OAAOC,IAA6B,OAAwB;AACjF,UAAMN,GAAA;AACN,eAAW5M,KAAKd,EAAW,OAAA,KAAY,OAAA;AACvC,UAAM,IAAI,QAAQ,CAACJ,MAAM,sBAAsBA,CAAC,CAAC;AAEjD,UAAM2B,IAAU,MAAM1B;AAAA,MACpBC;AAAA,MACAC;AAAA,MACA,MAAM,KAAKC,EAAW,QAAQ;AAAA,OAC9BiL,KAAA,gBAAAA,EAAgB,aAAY,CAAA;AAAA,MAC5BuC,GAAA;AAAA,MACAQ;AAAA,IAAA;AAGF,QAAIA,EAAK,UAAU;AACjB,YAAMC,IAAMD,EAAK,WAAW,SAAS,QAAQA,EAAK,UAAU,OACtDE,IAAO,SAAS,cAAc,GAAG;AACvC,MAAAA,EAAK,WAAW,GAAGF,EAAK,YAAY,iBAAiB,IAAIC,CAAG,IAC5DC,EAAK,OAAO3M,GACZ,SAAS,KAAK,YAAY2M,CAAI,GAC9BA,EAAK,MAAA,GACL,SAAS,KAAK,YAAYA,CAAI;AAAA,IAChC;AAEA,WAAO3M;AAAA,EACT,GAEM4M,KAAY,CAAC3G,MAAmC;;AACpD,QAAIxH,EAAW,QAAQlB;AACrB,YAAM,IAAI,MAAM,gCAAgCA,EAAiB,QAAQ;AAE3E,QAAIkB,EAAW,IAAIwH,EAAK,EAAE;AACxB,YAAM,IAAI,MAAM,wBAAwBA,EAAK,EAAE,kBAAkB;AAGnE,QAAI,CAACzD,KAAgBmG,MAAgB,YAAYrG,EAAQ,SAAS,GAAG;AACnE,YAAMuK,IAASvK,EAAQA,EAAQ,SAAS,CAAC;AACzC,OAAAjD,KAAAZ,EAAW,IAAIoO,CAAM,MAArB,QAAAxN,GAAwB,YAAY;AAAA,QAClC,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,UAAU;AAAA,MAAA;AAAA,IAEd;AAEA,UAAMyN,IAAWtI,GAAiByB,EAAK,UAAU,IAAI,GAC/CpE,IAAQ2H,EAAW,OAAO,CAACuD,GAAGC,OAAMD,IAAIC,IAAG,CAAC,GAC5C7N,IAAQ0C,IAAQ,KAAK,IAAIiL,KAAYjL,IAAQ;AACnD,aAASoL,IAAI,GAAGA,IAAIzD,EAAW,QAAQyD,IAAK,CAAAzD,EAAWyD,CAAC,KAAK9N;AAE7D,UAAMuB,IAAQ4B,EAAQ;AACtB,IAAAA,EAAQ,KAAK2D,EAAK,EAAE,GACpBuD,EAAW,KAAKsD,CAAQ;AAExB,UAAMtC,IAAU,SAAS,cAAc,KAAK;AAC5C,IAAAA,EAAQ,QAAQ,SAASvE,EAAK,IAC9BuE,EAAQ,MAAM,UAAUpC,GAAaoB,EAAW9I,CAAK,GAAG2H,GAAK3H,GAAOJ,CAAS;AAE7E,UAAMmK,IAAW,SAAS,cAAc,KAAK;AAC7C,IAAAA,EAAS,MAAM,UAAU,qDACzBD,EAAQ,YAAYC,CAAQ,GAC5BlM,EAAU,YAAYiM,CAAO,GAC7BhM,EAAa,KAAKgM,CAAO;AAGzB,UAAM7D,IAAYnE,IACbyD,EAAK,aAAa,KAClBA,EAAK,cAAc0C,MAAgB,WAHzB,KAG6C,KACtD/B,IAAYpE,IACbyD,EAAK,cAAc2C,MAAgB,SAASlI,MAAU,IAAI,MAC1DuF,EAAK,aAAa,IAEjBzG,IAAQiM;AAAA,MACZlF;AAAA,QACEN;AAAA,QACAwE;AAAA,QACA7L;AAAA,QACA8B;AAAA,QACA4B,EAAQ;AAAA,QACR;AAAA,UACE,MAAME,KAAgB,CAACoE,IAAYqC,EAAQ,OAAOE;AAAA,UAClD,OAAOC;AAAA,UACP,KAAKF;AAAA,UACL,QAAQsC;AAAA,QAAA;AAAA,QAEV7E;AAAA,QACAC;AAAA,QACAtG;AAAA,MAAA;AAAA,IACF,GAGIoL,KAAatF,GAAiBH,EAAK,MAAM;AAC/C,eAAWlE,KAAK2J,GAAY,CAAAlM,EAAM,UAAUuC,CAAC;AAC7C,WAAIkE,EAAK,UAAUA,EAAK,WAAW,UACjCzG,EAAM,KAAK,EAAE,GAAGyG,EAAK,QAAQ,SAAS,IAAO,GAG/CxH,EAAW,IAAIwH,EAAK,IAAIzG,CAAK,GAC7BiK,EAAc,KAAK;AAAA,MACjB,OAAAjK;AAAA,MACA,SAAAgL;AAAA,MACA,gBAAgBxF,IAAmBjB,KAAAkC,EAAK,UAAL,gBAAAlC,GAAY,KAAK;AAAA,MACpD,kBAAgBwD,MAAAH,KAAAnB,EAAK,UAAL,gBAAAmB,GAAY,UAAZ,gBAAAG,GAAmB,cAAa;AAAA,MAChD,WAAAZ;AAAA,IAAA,CACD,GAEDoF,EAAM,IAAIvM,CAAK,GACf6K,EAAA,GACAN,EAAA,GACOvK;AAAA,EACT;AAwGA,SAtG4B;AAAA,IAC1B,WAAAjB;AAAA,IACA,QAAQ2O,GAAY;AAClB,aAAOzO,EAAW,IAAIyO,CAAE;AAAA,IAC1B;AAAA,IACA,WAAW;AACT,aAAO,MAAM,KAAKzO,EAAW,OAAA,CAAQ;AAAA,IACvC;AAAA,IACA,YAAY;AACV,aAAOqN;AAAA,IACT;AAAA,IACA,WAAW;AACT,aAAOC;AAAA,IACT;AAAA,IACA,OAAOU,GAAM;AACX,MAAAV,EAAM,OAAOU,CAAI;AAAA,IACnB;AAAA,IACA,WAAW;AACT,MAAAV,EAAM,SAAA;AAAA,IACR;AAAA,IACA,SAAS;AACP,MAAAhC,EAAA;AAAA,IACF;AAAA,IACA,gBAAgB;AACd,YAAM7H,IAA8B,CAAA;AACpC,eAAS,IAAI,GAAG,IAAII,EAAQ,QAAQ;AAClC,QAAAJ,EAAII,EAAQ,CAAC,CAAC,IAAIkH,EAAW,CAAC;AAEhC,aAAOtH;AAAA,IACT;AAAA,IACA,cAAcK,GAAgC;AAC5C,eAAS,IAAI,GAAG,IAAID,EAAQ,QAAQ,KAAK;AACvC,cAAM4K,IAAK5K,EAAQ,CAAC;AACpB,QAAIC,EAAO2K,CAAE,MAAM,aAAsB,CAAC,IAAI3K,EAAO2K,CAAE;AAAA,MACzD;AACA,MAAA3I,GAAoB/F,GAAcgL,GAAYlJ,CAAS,GACvDyJ,EAAA;AAAA,IACF;AAAA,IACA,YAAYvC,GAAM;AAChB,MAAAuE,EAAM,SAASvE,CAAI;AAAA,IACrB;AAAA,IACA,cAAc;AACZ,aAAOuE,EAAM,aAAa,QAAQ;AAAA,IACpC;AAAA,IACA,eAAeoB,GAAuC;AACpD,MAAApB,EAAM,cAAcoB,CAAQ;AAAA,IAC9B;AAAA,IACA,YAAY;AACV,aAAOhB,GAAA;AAAA,IACT;AAAA,IACA,YAAYM,GAAM;AAChB,aAAOD,GAAeC,CAAI;AAAA,IAC5B;AAAA,IACA,SAASA,GAAM;AACb,aAAOD,GAAeC,CAAI;AAAA,IAC5B;AAAA,IACA,QAAQxG,GAAgC;AACtC,aAAO2G,GAAU3G,CAAI;AAAA,IACvB;AAAA,IACA,MAAM,aAAamH,GAA6BX,IAA4B,IAAI;;AAC9E,YAAMY,IAAa5O,EAAW,IAAIgK,CAAY,KAAKqD;AACnD,UAAIW,EAAK,SAAS;AAEhB,eAAO,EAAE,GADO,MAAMa,GAAoBD,GAAYD,GAAQX,CAAI,GAC7C,OAAOY,EAAA;AAG9B,YAAME,IAASC,GAAoBH,GAAYZ,EAAK,cAAc,GAC5D,EAAE,GAAAgB,GAAG,QAAAC,MAAWC,GAAmBJ,CAAM,GACzCK,IAAa,MAAMC,GAA6BT,GAAQK,GAAGC,GAAQ;AAAA,QACvE,IAAIjB,EAAK,MAAMW;AAAA,QACf,OAAOX,EAAK,SAASW,EAAO,YAAA;AAAA,QAC5B,QAAQX,EAAK,cAAc;AAAA,QAC3B,WAAWA,EAAK;AAAA,QAChB,QAAQA,EAAK;AAAA,QACb,YAAYA,EAAK;AAAA,QACjB,YAAYA,EAAK;AAAA,QACjB,cAAcA,EAAK;AAAA,QACnB,QAAQA,EAAK;AAAA,MAAA,GACZc,CAAM,GAEH/N,IAAQoN,GAAUgB,CAAU;AAClC,aAAO;AAAA,QACL,IAAIA,EAAW;AAAA,QACf,QAAAR;AAAA,QACA,WAAW;AAAA,QACX,aAAW/N,IAAAuO,EAAW,WAAX,gBAAAvO,EAAmB,IAAI,CAAC0C,MAAMA,EAAE,QAAO,CAAA;AAAA,QAClD,QAAQ6L,EAAW;AAAA,QACnB,OAAApO;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,UAAU;AACR,MAAIoK,0BAAgCA,CAAS,GACzCC,0BAAoCA,CAAa,GACrDO,EAAe,WAAA,GACfV,KAAA,QAAAA,EAAgB,WAChBqC,EAAM,QAAA;AACN,iBAAWxM,KAAKd,EAAW,OAAA,KAAY,QAAA;AACvC,MAAAA,EAAW,MAAA,GACXF,EAAU,gBAAA;AAAA,IACZ;AAAA,EAAA;AAIJ;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-BBpJwOct.js","sources":["../src/workers/downsample.ts","../src/workers/downsampleAsync.ts","../src/plugins/virtualization/index.ts"],"sourcesContent":["/**\n * LTTB (Largest-Triangle-Three-Buckets) Downsampling Algorithm\n *\n * This algorithm downsamples time-series data while preserving visual features.\n * It's much better than naive sampling for preserving peaks and valleys.\n *\n * Reference: https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf\n */\n\nexport interface DownsampleResult {\n x: Float32Array;\n y: Float32Array;\n /** Original indices of selected points */\n indices: Uint32Array;\n}\n\n/**\n * Downsample data using LTTB algorithm\n *\n * @param x - X values (e.g., potential)\n * @param y - Y values (e.g., current)\n * @param targetPoints - Number of output points\n * @returns Downsampled data\n */\nexport function lttbDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number\n): DownsampleResult {\n const length = x.length;\n\n // No need to downsample\n if (targetPoints >= length || targetPoints <= 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const outX = new Float32Array(targetPoints);\n const outY = new Float32Array(targetPoints);\n const outIndices = new Uint32Array(targetPoints);\n\n // Always include first point\n outX[0] = x[0];\n outY[0] = y[0];\n outIndices[0] = 0;\n\n // Bucket size\n const bucketSize = (length - 2) / (targetPoints - 2);\n\n let a = 0; // Previous selected point index\n let outIdx = 1;\n\n for (let i = 0; i < targetPoints - 2; i++) {\n // Calculate bucket boundaries\n const bucketStart = Math.floor((i + 1) * bucketSize) + 1;\n const bucketEnd = Math.floor((i + 2) * bucketSize) + 1;\n\n // Calculate average point of next bucket\n const nextBucketStart = Math.min(bucketEnd, length - 1);\n const nextBucketEnd = Math.min(\n Math.floor((i + 3) * bucketSize) + 1,\n length\n );\n\n let avgX = 0;\n let avgY = 0;\n let avgCount = 0;\n\n for (let j = nextBucketStart; j < nextBucketEnd; j++) {\n avgX += x[j];\n avgY += y[j];\n avgCount++;\n }\n\n if (avgCount > 0) {\n avgX /= avgCount;\n avgY /= avgCount;\n }\n\n // Find point in current bucket with largest triangle area\n let maxArea = -1;\n let maxIndex = bucketStart;\n\n const aX = x[a];\n const aY = y[a];\n\n for (let j = bucketStart; j < bucketEnd && j < length; j++) {\n // Calculate triangle area (simplified: |x1(y2-y3) + x2(y3-y1) + x3(y1-y2)| / 2)\n const area = Math.abs(\n (aX - avgX) * (y[j] - aY) - (aX - x[j]) * (avgY - aY)\n );\n\n if (area > maxArea) {\n maxArea = area;\n maxIndex = j;\n }\n }\n\n // Store selected point\n outX[outIdx] = x[maxIndex];\n outY[outIdx] = y[maxIndex];\n outIndices[outIdx] = maxIndex;\n\n a = maxIndex;\n outIdx++;\n }\n\n // Always include last point\n outX[targetPoints - 1] = x[length - 1];\n outY[targetPoints - 1] = y[length - 1];\n outIndices[targetPoints - 1] = length - 1;\n\n return { x: outX, y: outY, indices: outIndices };\n}\n\n/**\n * Min-Max per bucket downsampling\n *\n * Simpler alternative to LTTB that preserves extremes in each bucket.\n * Uses 2 points per bucket (min and max), so output is ~2x target.\n */\nexport function minMaxDownsample(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n bucketCount: number\n): DownsampleResult {\n const length = x.length;\n\n if (bucketCount >= length / 2) {\n return {\n x: new Float32Array(x),\n y: new Float32Array(y),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const bucketSize = length / bucketCount;\n const outX: number[] = [];\n const outY: number[] = [];\n const outIndices: number[] = [];\n\n for (let b = 0; b < bucketCount; b++) {\n const start = Math.floor(b * bucketSize);\n const end = Math.floor((b + 1) * bucketSize);\n\n let minY = Infinity;\n let maxY = -Infinity;\n let minIdx = start;\n let maxIdx = start;\n\n for (let i = start; i < end && i < length; i++) {\n if (y[i] < minY) {\n minY = y[i];\n minIdx = i;\n }\n if (y[i] > maxY) {\n maxY = y[i];\n maxIdx = i;\n }\n }\n\n // Add points in order (min first if it comes before max)\n if (minIdx <= maxIdx) {\n outX.push(x[minIdx], x[maxIdx]);\n outY.push(y[minIdx], y[maxIdx]);\n outIndices.push(minIdx, maxIdx);\n } else {\n outX.push(x[maxIdx], x[minIdx]);\n outY.push(y[maxIdx], y[minIdx]);\n outIndices.push(maxIdx, minIdx);\n }\n }\n\n return {\n x: new Float32Array(outX),\n y: new Float32Array(outY),\n indices: new Uint32Array(outIndices),\n };\n}\n\n/**\n * Calculate optimal target points based on canvas width\n */\nexport function calculateTargetPoints(\n dataLength: number,\n canvasWidth: number,\n pointsPerPixel = 2\n): number {\n // Never draw more than pointsPerPixel per pixel\n const maxPoints = canvasWidth * pointsPerPixel;\n return Math.min(dataLength, maxPoints);\n}\n\nexport interface OhlcDownsampleResult {\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n indices: Uint32Array;\n}\n\n/**\n * Aggregate OHLC bars into fewer buckets while preserving extremes.\n * Each bucket: open=first open, close=last close, high=max high, low=min low, x=last x.\n */\nexport function ohlcMinMaxDownsample(\n x: Float32Array | Float64Array,\n open: Float32Array | Float64Array,\n high: Float32Array | Float64Array,\n low: Float32Array | Float64Array,\n close: Float32Array | Float64Array,\n targetBars: number,\n): OhlcDownsampleResult {\n const length = x.length;\n if (targetBars >= length || targetBars <= 1 || length === 0) {\n return {\n x: new Float32Array(x),\n open: new Float32Array(open),\n high: new Float32Array(high),\n low: new Float32Array(low),\n close: new Float32Array(close),\n indices: new Uint32Array(Array.from({ length }, (_, i) => i)),\n };\n }\n\n const bucketSize = length / targetBars;\n const outX: number[] = [];\n const outOpen: number[] = [];\n const outHigh: number[] = [];\n const outLow: number[] = [];\n const outClose: number[] = [];\n const outIndices: number[] = [];\n\n for (let b = 0; b < targetBars; b++) {\n const start = Math.floor(b * bucketSize);\n const end = Math.min(length, Math.floor((b + 1) * bucketSize));\n if (start >= end) continue;\n\n let hi = -Infinity;\n let lo = Infinity;\n let lastIdx = start;\n\n for (let i = start; i < end; i++) {\n if (high[i] > hi) hi = high[i];\n if (low[i] < lo) lo = low[i];\n lastIdx = i;\n }\n\n outOpen.push(open[start]);\n outHigh.push(hi);\n outLow.push(lo);\n outClose.push(close[lastIdx]);\n outX.push(x[lastIdx]);\n outIndices.push(lastIdx);\n }\n\n return {\n x: new Float32Array(outX),\n open: new Float32Array(outOpen),\n high: new Float32Array(outHigh),\n low: new Float32Array(outLow),\n close: new Float32Array(outClose),\n indices: new Uint32Array(outIndices),\n };\n}\n\n/** Binary search lower bound: first index where x[i] >= value */\nexport function lowerBoundX(\n x: Float32Array | Float64Array,\n value: number,\n): number {\n let lo = 0;\n let hi = x.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (x[mid] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\n/** Binary search upper bound: first index where x[i] > value */\nexport function upperBoundX(\n x: Float32Array | Float64Array,\n value: number,\n): number {\n let lo = 0;\n let hi = x.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (x[mid] <= value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport interface ViewportSlice {\n x: Float32Array;\n y?: Float32Array;\n open?: Float32Array;\n high?: Float32Array;\n low?: Float32Array;\n close?: Float32Array;\n start: number;\n end: number;\n}\n\n/**\n * Slice sorted x-series to visible range plus buffer (fraction of visible width).\n */\nexport function sliceSeriesToViewport(\n source: {\n x: Float32Array | Float64Array;\n y?: Float32Array | Float64Array;\n open?: Float32Array | Float64Array;\n high?: Float32Array | Float64Array;\n low?: Float32Array | Float64Array;\n close?: Float32Array | Float64Array;\n },\n xMin: number,\n xMax: number,\n bufferRatio = 0.5,\n): ViewportSlice {\n const length = source.x.length;\n if (length === 0) {\n return { x: new Float32Array(0), start: 0, end: 0 };\n }\n\n const range = Math.max(xMax - xMin, 1e-12);\n const paddedMin = xMin - range * bufferRatio;\n const paddedMax = xMax + range * bufferRatio;\n\n let start = lowerBoundX(source.x, paddedMin);\n let end = upperBoundX(source.x, paddedMax);\n start = Math.max(0, start);\n end = Math.min(length, Math.max(end, start + 1));\n\n const slice = <T extends Float32Array | Float64Array>(arr: T | undefined): Float32Array | undefined => {\n if (!arr) return undefined;\n return new Float32Array(arr.subarray(start, end));\n };\n\n return {\n x: new Float32Array(source.x.subarray(start, end)),\n y: slice(source.y),\n open: slice(source.open),\n high: slice(source.high),\n low: slice(source.low),\n close: slice(source.close),\n start,\n end,\n };\n}\n","/**\n * Async downsampling via shared worker pool (main-thread fallback in Node/tests).\n * @module workers/downsampleAsync\n */\n\nimport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n type OhlcDownsampleResult,\n type DownsampleResult,\n} from \"./downsample\";\nimport { WorkerPool, nextTaskId } from \"./pool\";\n\ntype DownsampleTask = {\n id: string;\n type: \"downsample\";\n x: Float32Array;\n y: Float32Array;\n targetPoints: number;\n algorithm: \"lttb\" | \"minmax\";\n};\n\ntype OhlcDownsampleTask = {\n id: string;\n type: \"ohlc-downsample\";\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n targetBars: number;\n};\n\ntype DownsampleWorkerResult =\n | {\n id: string;\n type: \"downsample-result\";\n x: Float32Array;\n y: Float32Array;\n }\n | {\n id: string;\n type: \"ohlc-downsample-result\";\n x: Float32Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n }\n | { id: string; type: \"error\"; error: string };\n\nlet pool: WorkerPool<DownsampleTask | OhlcDownsampleTask, DownsampleWorkerResult> | null = null;\n\nfunction getPool() {\n if (pool) return pool;\n\n pool = new WorkerPool<DownsampleTask | OhlcDownsampleTask, DownsampleWorkerResult>(\n () => new Worker(new URL(\"./downsample.worker.ts\", import.meta.url), { type: \"module\" }),\n {\n poolSize: 2,\n syncFallback: true,\n syncHandler: (task) => {\n if (task.type === \"downsample\") {\n const result =\n task.algorithm === \"minmax\"\n ? minMaxDownsample(task.x, task.y, Math.ceil(task.targetPoints / 2))\n : lttbDownsample(task.x, task.y, task.targetPoints);\n return { id: task.id, type: \"downsample-result\", x: result.x, y: result.y };\n }\n\n const result = ohlcMinMaxDownsample(\n task.x,\n task.open,\n task.high,\n task.low,\n task.close,\n task.targetBars,\n );\n return {\n id: task.id,\n type: \"ohlc-downsample-result\",\n x: result.x,\n open: result.open,\n high: result.high,\n low: result.low,\n close: result.close,\n };\n },\n },\n );\n\n return pool;\n}\n\nexport async function downsampleAsync(\n x: Float32Array,\n y: Float32Array,\n targetPoints: number,\n algorithm: \"lttb\" | \"minmax\" = \"lttb\",\n): Promise<DownsampleResult> {\n const id = nextTaskId(\"downsample\");\n const result = await getPool().run({\n id,\n type: \"downsample\",\n x,\n y,\n targetPoints,\n algorithm,\n });\n\n // Worker/pool failures surface as a rejected run() promise (sync fallback or\n // reject), so a resolved value is always a success payload; we only guard the\n // shape here.\n if (result.type !== \"downsample-result\") {\n throw new Error(\"Unexpected downsample worker response\");\n }\n\n return {\n x: result.x,\n y: result.y,\n indices: new Uint32Array(result.x.length),\n };\n}\n\nexport async function ohlcDownsampleAsync(\n x: Float32Array,\n open: Float32Array,\n high: Float32Array,\n low: Float32Array,\n close: Float32Array,\n targetBars: number,\n): Promise<OhlcDownsampleResult> {\n const id = nextTaskId(\"ohlc-downsample\");\n const result = await getPool().run({\n id,\n type: \"ohlc-downsample\",\n x,\n open,\n high,\n low,\n close,\n targetBars,\n });\n\n if (result.type !== \"ohlc-downsample-result\") {\n throw new Error(\"Unexpected OHLC downsample worker response\");\n }\n\n return {\n x: result.x,\n open: result.open,\n high: result.high,\n low: result.low,\n close: result.close,\n indices: new Uint32Array(result.x.length),\n };\n}\n\nexport function destroyDownsamplePool(): void {\n pool?.destroy();\n pool = null;\n}\n\nexport function getDownsamplePoolSize(): number {\n return pool?.size() ?? 0;\n}\n","/**\n * @fileoverview Data virtualization plugin (LOD/min-max)\n * @module plugins/virtualization\n */\n\nimport type {\n PluginVirtualizationConfig,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n} from \"./types\";\nimport type { ChartPlugin, PluginContext, PluginManifest } from \"../types\";\nimport type { Series } from \"../../core/Series\";\nimport type { SeriesUpdateData } from \"../../types\";\nimport {\n lttbDownsample,\n minMaxDownsample,\n ohlcMinMaxDownsample,\n calculateTargetPoints,\n sliceSeriesToViewport,\n} from \"../../workers/downsample\";\nimport { downsampleAsync, ohlcDownsampleAsync } from \"../../workers/downsampleAsync\";\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-virtualization\",\n version: \"1.0.0\",\n description: \"Viewport-aware data virtualization with LOD strategies\",\n provides: [\"performance\", \"data-virtualization\"],\n tags: [\"performance\", \"lod\", \"virtualization\"],\n};\n\nconst DEFAULT_CONFIG: Required<PluginVirtualizationConfig> = {\n enabled: true,\n precision: \"lod\",\n mode: \"lod\",\n targetPoints: \"auto\",\n pointsPerPixel: 2,\n lodLevels: [1, 4, 8, 16],\n strategy: \"lttb\",\n reuseOriginalData: true,\n syncWithLazyLoad: true,\n includeSeries: [],\n excludeSeries: [],\n debug: false,\n viewportBuffer: 0.5,\n useWorker: true,\n workerThreshold: 250_000,\n};\n\ntype SeriesCache = {\n x: Float32Array | Float64Array;\n y?: Float32Array | Float64Array;\n open?: Float32Array | Float64Array;\n high?: Float32Array | Float64Array;\n low?: Float32Array | Float64Array;\n close?: Float32Array | Float64Array;\n};\n\nexport function PluginVirtualization(\n userConfig: Partial<PluginVirtualizationConfig> = {}\n): ChartPlugin<PluginVirtualizationConfig> {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n let ctx: PluginContext | null = null;\n let isInternalUpdate = false;\n\n const originalData = new Map<string, SeriesCache>();\n const stats = new Map<string, VirtualizationStats>();\n\n let originalUpdateSeries: ((id: string, data: SeriesUpdateData) => void) | null = null;\n let originalAppendData: ((id: string, x: number[] | Float32Array, y: number[] | Float32Array) => void) | null = null;\n let refreshRaf = 0;\n const applyGeneration = new Map<string, number>();\n let lastViewKey = \"\";\n\n function log(message: string, ...args: unknown[]) {\n if (config.debug && ctx) {\n ctx.log.info(`[Virtualization] ${message}`, ...args);\n }\n }\n\n function shouldVirtualize(series: Series): boolean {\n if (!config.enabled) return false;\n if (config.precision === \"full\") return false;\n if (config.includeSeries.length > 0 && !config.includeSeries.includes(series.getId())) return false;\n if (config.excludeSeries.includes(series.getId())) return false;\n\n const type = series.getType();\n return (\n type === \"line\" ||\n type === \"scatter\" ||\n type === \"line+scatter\" ||\n type === \"step\" ||\n type === \"step+scatter\" ||\n type === \"candlestick\" ||\n type === \"bar\"\n );\n }\n\n function isOhlcSeries(series: Series): boolean {\n return series.getType() === \"candlestick\";\n }\n\n function buildUpdatePayload(cache: SeriesCache): SeriesUpdateData {\n if (cache.open && cache.high && cache.low && cache.close) {\n return {\n x: cache.x,\n open: cache.open,\n high: cache.high,\n low: cache.low,\n close: cache.close,\n };\n }\n return { x: cache.x, y: cache.y! };\n }\n\n function getTargetPoints(dataLength: number): number {\n if (!ctx) return dataLength;\n if (config.targetPoints !== \"auto\") return Math.max(2, config.targetPoints);\n const width = ctx.render.canvasSize.width / ctx.render.pixelRatio;\n return calculateTargetPoints(dataLength, width, config.pointsPerPixel);\n }\n\n function downsampleData(\n x: Float32Array | Float64Array,\n y: Float32Array | Float64Array,\n targetPoints: number,\n strategy: VirtualizationStrategy\n ): { x: Float32Array; y: Float32Array } {\n if (targetPoints >= x.length || x.length <= 2) {\n return { x: new Float32Array(x), y: new Float32Array(y) };\n }\n\n if (strategy === \"minmax\") {\n const bucketCount = Math.ceil(targetPoints / 2);\n const result = minMaxDownsample(x, y, bucketCount);\n return { x: result.x, y: result.y };\n }\n\n const result = lttbDownsample(x, y, targetPoints);\n return { x: result.x, y: result.y };\n }\n\n function cacheOriginal(seriesId: string, data: SeriesCache): void {\n if (!config.reuseOriginalData) return;\n if (originalData.has(seriesId)) return;\n originalData.set(seriesId, { ...data });\n }\n\n function restoreOriginal(seriesId: string): SeriesCache | null {\n return originalData.get(seriesId) ?? null;\n }\n\n function updateStats(\n seriesId: string,\n originalPoints: number,\n renderedPoints: number,\n targetPoints: number,\n mode: VirtualizationMode,\n strategy: VirtualizationStrategy,\n ): void {\n stats.set(seriesId, {\n seriesId,\n originalPoints,\n renderedPoints,\n targetPoints,\n lastUpdated: Date.now(),\n mode,\n strategy,\n });\n }\n\n function captureOriginalFromSeries(series: Series): SeriesCache | null {\n const live = series.getData();\n if (!live?.x?.length) return null;\n\n if (isOhlcSeries(series)) {\n if (!live.open || !live.high || !live.low || !live.close) return null;\n const cache: SeriesCache = {\n x: live.x,\n open: live.open,\n high: live.high,\n low: live.low,\n close: live.close,\n };\n cacheOriginal(series.getId(), cache);\n return cache;\n }\n\n if (!live.y) return null;\n const cache: SeriesCache = { x: live.x, y: live.y };\n cacheOriginal(series.getId(), cache);\n return cache;\n }\n\n function getSourceData(series: Series): SeriesCache | null {\n return restoreOriginal(series.getId()) ?? captureOriginalFromSeries(series);\n }\n\n function getViewportSource(source: SeriesCache): SeriesCache {\n if (!ctx) return source;\n const bounds = ctx.data.getViewBounds?.();\n if (!bounds) return source;\n\n const sliced = sliceSeriesToViewport(\n source,\n bounds.xMin,\n bounds.xMax,\n config.viewportBuffer,\n );\n if (sliced.end - sliced.start >= source.x.length) return source;\n\n return {\n x: sliced.x,\n y: sliced.y,\n open: sliced.open,\n high: sliced.high,\n low: sliced.low,\n close: sliced.close,\n };\n }\n\n function commitDownsampled(seriesId: string, payload: SeriesUpdateData): void {\n if (!originalUpdateSeries) return;\n isInternalUpdate = true;\n originalUpdateSeries(seriesId, payload);\n isInternalUpdate = false;\n }\n\n async function runDownsample(\n source: SeriesCache,\n targetPoints: number,\n strategy: VirtualizationStrategy,\n ): Promise<{ x: Float32Array; y: Float32Array }> {\n const x = new Float32Array(source.x);\n const y = new Float32Array(source.y!);\n\n if (config.useWorker && x.length >= config.workerThreshold) {\n const algorithm = strategy === \"minmax\" ? \"minmax\" : \"lttb\";\n const result = await downsampleAsync(x, y, targetPoints, algorithm);\n return { x: result.x, y: result.y };\n }\n\n return downsampleData(x, y, targetPoints, strategy);\n }\n\n async function applyVirtualization(series: Series): Promise<void> {\n if (!ctx || !originalUpdateSeries) return;\n const seriesId = series.getId();\n\n if (!shouldVirtualize(series)) {\n const original = restoreOriginal(seriesId);\n if (original && config.reuseOriginalData) {\n commitDownsampled(seriesId, buildUpdatePayload(original));\n }\n return;\n }\n\n const source = getSourceData(series);\n if (!source?.x?.length) return;\n\n const viewportSource = getViewportSource(source);\n const gen = (applyGeneration.get(seriesId) ?? 0) + 1;\n applyGeneration.set(seriesId, gen);\n\n if (isOhlcSeries(series)) {\n if (!viewportSource.open || !viewportSource.high || !viewportSource.low || !viewportSource.close) {\n return;\n }\n\n const targetBars = getTargetPoints(viewportSource.x.length);\n const x = new Float32Array(viewportSource.x);\n const open = new Float32Array(viewportSource.open);\n const high = new Float32Array(viewportSource.high);\n const low = new Float32Array(viewportSource.low);\n const close = new Float32Array(viewportSource.close);\n\n const downsampled =\n config.useWorker && x.length >= config.workerThreshold\n ? await ohlcDownsampleAsync(x, open, high, low, close, targetBars)\n : ohlcMinMaxDownsample(x, open, high, low, close, targetBars);\n\n if (applyGeneration.get(seriesId) !== gen) return;\n\n commitDownsampled(seriesId, {\n x: downsampled.x,\n open: downsampled.open,\n high: downsampled.high,\n low: downsampled.low,\n close: downsampled.close,\n });\n\n updateStats(seriesId, source.x.length, downsampled.x.length, targetBars, config.mode, \"minmax\");\n return;\n }\n\n if (!viewportSource.y) return;\n\n const targetPoints = getTargetPoints(viewportSource.x.length);\n const strategy = series.getType() === \"bar\" ? \"minmax\" : config.strategy;\n const downsampled = await runDownsample(viewportSource, targetPoints, strategy);\n\n if (applyGeneration.get(seriesId) !== gen) return;\n\n commitDownsampled(seriesId, { x: downsampled.x, y: downsampled.y });\n updateStats(seriesId, source.x.length, downsampled.x.length, targetPoints, config.mode, strategy);\n }\n\n function refreshAll(): void {\n if (!ctx) return;\n ctx.data.getAllSeries().forEach((series) => {\n void applyVirtualization(series);\n });\n }\n\n function scheduleRefreshAll(): void {\n if (!ctx) return;\n const bounds = ctx.data.getViewBounds?.();\n if (bounds) {\n const key = `${bounds.xMin}:${bounds.xMax}:${bounds.yMin}:${bounds.yMax}:${ctx.render.canvasSize.width}`;\n if (key === lastViewKey) return;\n lastViewKey = key;\n }\n\n if (refreshRaf) return;\n refreshRaf = requestAnimationFrame(() => {\n refreshRaf = 0;\n refreshAll();\n });\n }\n\n function handleUpdateSeries(id: string, data: SeriesUpdateData): void {\n if (!ctx || !originalUpdateSeries) return;\n if (!config.enabled || isInternalUpdate) {\n originalUpdateSeries(id, data);\n return;\n }\n\n const series = ctx.chart.getSeries?.(id) as Series | undefined;\n if (!series) {\n originalUpdateSeries(id, data);\n return;\n }\n\n const original = restoreOriginal(id);\n if (original && config.reuseOriginalData) {\n isInternalUpdate = true;\n originalUpdateSeries(id, buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n\n originalUpdateSeries(id, data);\n\n const updatedSeries = ctx.chart.getSeries?.(id) as Series | undefined;\n if (updatedSeries) {\n originalData.delete(id);\n captureOriginalFromSeries(updatedSeries);\n void applyVirtualization(updatedSeries);\n }\n }\n\n function handleAppendData(\n id: string,\n x: number[] | Float32Array,\n y: number[] | Float32Array\n ): void {\n if (!ctx || !originalAppendData || !originalUpdateSeries) return;\n\n if (!config.enabled || isInternalUpdate) {\n originalAppendData(id, x, y);\n return;\n }\n\n const series = ctx.chart.getSeries?.(id) as Series | undefined;\n if (!series) {\n originalAppendData(id, x, y);\n return;\n }\n\n const original = restoreOriginal(id);\n if (original && config.reuseOriginalData) {\n isInternalUpdate = true;\n originalUpdateSeries(id, buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n\n originalAppendData(id, x, y);\n\n const updatedSeries = ctx.chart.getSeries?.(id) as Series | undefined;\n if (updatedSeries) {\n const cached = restoreOriginal(id);\n if (cached?.y && config.reuseOriginalData) {\n // Replace (not cacheOriginal, which no-ops on an existing entry) so the\n // full-resolution cache grows with the appended points.\n originalData.set(id, {\n x: appendTyped(cached.x, x),\n y: appendTyped(cached.y, y),\n });\n } else {\n originalData.delete(id);\n captureOriginalFromSeries(updatedSeries);\n }\n void applyVirtualization(updatedSeries);\n }\n }\n\n function appendTyped(\n existing: Float32Array | Float64Array,\n incoming: number[] | Float32Array,\n ): Float32Array {\n const next = incoming instanceof Float32Array ? incoming : Float32Array.from(incoming);\n const merged = new Float32Array(existing.length + next.length);\n merged.set(existing);\n merged.set(next, existing.length);\n return merged;\n }\n\n const api: VirtualizationAPI & Record<string, unknown> = {\n enable() {\n config.enabled = true;\n refreshAll();\n },\n disable() {\n config.enabled = false;\n if (!ctx || !originalUpdateSeries) return;\n const updater = originalUpdateSeries;\n ctx.data.getAllSeries().forEach((series) => {\n const original = restoreOriginal(series.getId());\n if (original) {\n isInternalUpdate = true;\n updater(series.getId(), buildUpdatePayload(original));\n isInternalUpdate = false;\n }\n });\n },\n isEnabled() {\n return config.enabled;\n },\n updateConfig(newConfig) {\n Object.assign(config, newConfig);\n refreshAll();\n },\n invalidate(seriesId) {\n if (!ctx) return;\n if (seriesId) {\n const series = ctx.chart.getSeries?.(seriesId) as Series | undefined;\n if (series) applyVirtualization(series);\n return;\n }\n refreshAll();\n },\n getStats(seriesId) {\n return stats.get(seriesId) ?? null;\n },\n getAllStats() {\n return Array.from(stats.values());\n },\n };\n\n return {\n manifest,\n onInit(pluginCtx: PluginContext) {\n ctx = pluginCtx;\n // API is exposed via plugin.api / chart.virtualization getter (ChartPluginBridge)\n\n const chart = ctx.chart as any;\n originalUpdateSeries = chart.updateSeries?.bind(chart) ?? null;\n originalAppendData = chart.appendData?.bind(chart) ?? null;\n\n if (originalUpdateSeries) {\n chart.updateSeries = (id: string, data: SeriesUpdateData) => handleUpdateSeries(id, data);\n }\n\n if (originalAppendData) {\n chart.appendData = (id: string, x: number[] | Float32Array, y: number[] | Float32Array) =>\n handleAppendData(id, x, y);\n }\n\n ctx.events.on(\"zoom\", () => scheduleRefreshAll());\n ctx.events.on(\"pan\", () => scheduleRefreshAll());\n ctx.events.on(\"resize\", () => {\n lastViewKey = \"\";\n scheduleRefreshAll();\n });\n\n refreshAll();\n log(\"Initialized\");\n },\n onDestroy(pluginCtx: PluginContext) {\n if (refreshRaf) cancelAnimationFrame(refreshRaf);\n refreshRaf = 0;\n applyGeneration.clear();\n if (originalUpdateSeries) {\n (pluginCtx.chart as any).updateSeries = originalUpdateSeries;\n }\n if (originalAppendData) {\n (pluginCtx.chart as any).appendData = originalAppendData;\n }\n ctx = null;\n originalData.clear();\n stats.clear();\n },\n api,\n };\n}\n\nexport default PluginVirtualization;\n\n// Type exports\nexport type {\n PluginVirtualizationConfig,\n VirtualizationAPI,\n VirtualizationStats,\n VirtualizationMode,\n VirtualizationStrategy,\n} from \"./types\";\n"],"names":["lttbDownsample","x","y","targetPoints","length","_","i","outX","outY","outIndices","bucketSize","a","outIdx","bucketStart","bucketEnd","nextBucketStart","nextBucketEnd","avgX","avgY","avgCount","j","maxArea","maxIndex","aX","aY","area","minMaxDownsample","bucketCount","b","start","end","minY","maxY","minIdx","maxIdx","calculateTargetPoints","dataLength","canvasWidth","pointsPerPixel","maxPoints","ohlcMinMaxDownsample","open","high","low","close","targetBars","outOpen","outHigh","outLow","outClose","hi","lo","lastIdx","lowerBoundX","value","mid","upperBoundX","sliceSeriesToViewport","source","xMin","xMax","bufferRatio","range","paddedMin","paddedMax","slice","arr","pool","getPool","WorkerPool","task","result","downsampleAsync","algorithm","id","nextTaskId","ohlcDownsampleAsync","destroyDownsamplePool","getDownsamplePoolSize","manifest","DEFAULT_CONFIG","PluginVirtualization","userConfig","config","ctx","isInternalUpdate","originalData","stats","originalUpdateSeries","originalAppendData","refreshRaf","applyGeneration","lastViewKey","log","message","args","shouldVirtualize","series","type","isOhlcSeries","buildUpdatePayload","cache","getTargetPoints","width","downsampleData","strategy","cacheOriginal","seriesId","data","restoreOriginal","updateStats","originalPoints","renderedPoints","mode","captureOriginalFromSeries","live","_a","getSourceData","getViewportSource","bounds","_b","sliced","commitDownsampled","payload","runDownsample","applyVirtualization","original","viewportSource","gen","downsampled","refreshAll","scheduleRefreshAll","key","handleUpdateSeries","updatedSeries","_d","_c","handleAppendData","cached","appendTyped","existing","incoming","next","merged","pluginCtx","chart","updater","newConfig"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-DoYxf1cV.js","sources":["../src/core/keybindings/index.ts","../src/plugins/keyboard/index.ts"],"sourcesContent":["/**\n * Sci Plot - Keyboard Shortcuts Module\n * \n * Provides customizable keyboard shortcuts for chart interactions.\n * Supports key combinations, custom actions, and enable/disable per key.\n * \n * @module keybindings\n */\n\n// ============================================\n// Types\n// ============================================\n\n/** Available built-in actions */\nexport type KeyAction =\n | 'resetZoom'\n | 'autoScale'\n | 'zoomIn'\n | 'zoomOut'\n | 'panLeft'\n | 'panRight'\n | 'panUp'\n | 'panDown'\n | 'togglePan'\n | 'toggleSelect'\n | 'clearSelection'\n | 'deleteSelected'\n | 'selectAll'\n | 'copy'\n | 'exportImage'\n | 'toggleLegend'\n | 'toggleDebug'\n | 'escape'\n | 'undo'\n | 'redo'\n | 'custom';\n\n/** Key binding configuration */\nexport interface KeyBinding {\n /** The key code (e.g., 'KeyR', 'Escape', 'ArrowLeft') */\n key: string;\n /** Action to perform */\n action: KeyAction;\n /** Require Ctrl/Cmd key */\n ctrl?: boolean;\n /** Require Shift key */\n shift?: boolean;\n /** Require Alt key */\n alt?: boolean;\n /** Require Meta key (Cmd on Mac) */\n meta?: boolean;\n /** Custom handler function (required if action is 'custom') */\n handler?: () => void;\n /** Whether this binding is enabled (default: true) */\n enabled?: boolean;\n /** Description for help/UI display */\n description?: string;\n}\n\n/** Callbacks for keyboard actions */\nexport interface KeyBindingCallbacks {\n onResetZoom?: () => void;\n onAutoScale?: () => void;\n onZoomIn?: () => void;\n onZoomOut?: () => void;\n onPanLeft?: () => void;\n onPanRight?: () => void;\n onPanUp?: () => void;\n onPanDown?: () => void;\n onTogglePan?: () => void;\n onToggleSelect?: () => void;\n onClearSelection?: () => void;\n onDeleteSelected?: () => void;\n onSelectAll?: () => void;\n onCopy?: () => void;\n onExportImage?: () => void;\n onToggleLegend?: () => void;\n onToggleDebug?: () => void;\n onEscape?: () => void;\n onUndo?: () => void;\n onRedo?: () => void;\n}\n\nexport interface KeyBindingManagerOptions {\n /** Enable keyboard shortcuts (default: true) */\n enabled?: boolean;\n /** Custom key bindings (merged with defaults) */\n bindings?: KeyBinding[];\n /** Override all default bindings (replace instead of merge) */\n replaceDefaults?: boolean;\n /** Callbacks for built-in actions */\n callbacks: KeyBindingCallbacks;\n /** Target element for keyboard events (default: document) */\n target?: HTMLElement | Document;\n /** Prevent default browser behavior for matched keys (default: true) */\n preventDefault?: boolean;\n}\n\n// ============================================\n// Default Key Bindings\n// ============================================\n\nexport const DEFAULT_KEY_BINDINGS: KeyBinding[] = [\n // Zoom/Scale\n { key: 'KeyR', action: 'resetZoom', description: 'Reset zoom to fit data' },\n { key: 'KeyH', action: 'autoScale', description: 'Auto-scale axes' },\n { key: 'Equal', action: 'zoomIn', ctrl: true, description: 'Zoom in' },\n { key: 'Minus', action: 'zoomOut', ctrl: true, description: 'Zoom out' },\n { key: 'Digit0', action: 'resetZoom', ctrl: true, description: 'Reset zoom' },\n \n // Pan (Arrow keys)\n { key: 'ArrowLeft', action: 'panLeft', description: 'Pan left' },\n { key: 'ArrowRight', action: 'panRight', description: 'Pan right' },\n { key: 'ArrowUp', action: 'panUp', description: 'Pan up' },\n { key: 'ArrowDown', action: 'panDown', description: 'Pan down' },\n \n // Mode toggles\n { key: 'KeyP', action: 'togglePan', description: 'Toggle pan mode' },\n { key: 'KeyS', action: 'toggleSelect', description: 'Toggle select mode' },\n \n // Selection\n { key: 'Escape', action: 'escape', description: 'Clear selection / Cancel' },\n { key: 'Delete', action: 'deleteSelected', description: 'Delete selected points' },\n { key: 'Backspace', action: 'deleteSelected', description: 'Delete selected points' },\n { key: 'KeyA', action: 'selectAll', ctrl: true, description: 'Select all points' },\n \n // Clipboard\n { key: 'KeyC', action: 'copy', ctrl: true, description: 'Copy selected to clipboard' },\n \n // Export\n { key: 'KeyE', action: 'exportImage', ctrl: true, description: 'Export chart as image' },\n \n // UI toggles\n { key: 'KeyL', action: 'toggleLegend', description: 'Toggle legend visibility' },\n { key: 'KeyD', action: 'toggleDebug', ctrl: true, shift: true, description: 'Toggle debug overlay' },\n \n // Undo/Redo\n { key: 'KeyZ', action: 'undo', ctrl: true, description: 'Undo' },\n { key: 'KeyZ', action: 'redo', ctrl: true, shift: true, description: 'Redo' },\n { key: 'KeyY', action: 'redo', ctrl: true, description: 'Redo' },\n];\n\n// ============================================\n// Key Binding Manager\n// ============================================\n\nexport class KeyBindingManager {\n private bindings: KeyBinding[] = [];\n private callbacks: KeyBindingCallbacks;\n private target: HTMLElement | Document;\n private enabled: boolean = true;\n private preventDefault: boolean = true;\n private boundHandler: (e: KeyboardEvent) => void;\n\n constructor(options: KeyBindingManagerOptions) {\n this.callbacks = options.callbacks;\n this.target = options.target || document;\n this.enabled = options.enabled !== false;\n this.preventDefault = options.preventDefault !== false;\n\n // Merge or replace bindings\n if (options.replaceDefaults) {\n this.bindings = [...(options.bindings || [])];\n } else {\n this.bindings = [...DEFAULT_KEY_BINDINGS, ...(options.bindings || [])];\n }\n\n // Bind handler\n this.boundHandler = this.handleKeyDown.bind(this);\n this.attach();\n }\n\n /**\n * Attach keyboard event listeners\n */\n attach(): void {\n this.target.addEventListener('keydown', this.boundHandler as EventListener);\n }\n\n /**\n * Detach keyboard event listeners\n */\n detach(): void {\n this.target.removeEventListener('keydown', this.boundHandler as EventListener);\n }\n\n /**\n * Enable/disable all keyboard shortcuts\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /**\n * Check if keyboard shortcuts are enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Add a custom key binding\n */\n addBinding(binding: KeyBinding): void {\n this.bindings.push(binding);\n }\n\n /**\n * Remove a key binding by key code\n */\n removeBinding(key: string, modifiers?: { ctrl?: boolean; shift?: boolean; alt?: boolean }): void {\n this.bindings = this.bindings.filter(b => {\n if (b.key !== key) return true;\n if (modifiers) {\n if (modifiers.ctrl !== undefined && b.ctrl !== modifiers.ctrl) return true;\n if (modifiers.shift !== undefined && b.shift !== modifiers.shift) return true;\n if (modifiers.alt !== undefined && b.alt !== modifiers.alt) return true;\n }\n return false;\n });\n }\n\n /**\n * Update an existing binding\n */\n updateBinding(key: string, updates: Partial<KeyBinding>): void {\n const binding = this.bindings.find(b => b.key === key);\n if (binding) {\n Object.assign(binding, updates);\n }\n }\n\n /**\n * Enable/disable a specific binding\n */\n setBindingEnabled(key: string, enabled: boolean): void {\n const binding = this.bindings.find(b => b.key === key);\n if (binding) {\n binding.enabled = enabled;\n }\n }\n\n /**\n * Get all current bindings\n */\n getBindings(): KeyBinding[] {\n return [...this.bindings];\n }\n\n /**\n * Get binding for a specific key\n */\n getBinding(key: string): KeyBinding | undefined {\n return this.bindings.find(b => b.key === key);\n }\n\n /**\n * Get a formatted list of all shortcuts (for help display)\n */\n getShortcutList(): { key: string; description: string }[] {\n return this.bindings\n .filter(b => b.enabled !== false && b.description)\n .map(b => ({\n key: this.formatKeyBinding(b),\n description: b.description || b.action,\n }));\n }\n\n /**\n * Format a key binding for display\n */\n formatKeyBinding(binding: KeyBinding): string {\n const parts: string[] = [];\n if (binding.ctrl) parts.push('Ctrl');\n if (binding.alt) parts.push('Alt');\n if (binding.shift) parts.push('Shift');\n if (binding.meta) parts.push('⌘');\n \n // Convert key code to display name\n let keyName = binding.key;\n if (keyName.startsWith('Key')) {\n keyName = keyName.slice(3);\n } else if (keyName.startsWith('Digit')) {\n keyName = keyName.slice(5);\n } else if (keyName === 'Equal') {\n keyName = '+';\n } else if (keyName === 'Minus') {\n keyName = '-';\n } else if (keyName.startsWith('Arrow')) {\n keyName = '←→↑↓'['LeftRightUpDown'.indexOf(keyName.slice(5)) / 5 | 0] || keyName;\n }\n \n parts.push(keyName);\n return parts.join('+');\n }\n\n /**\n * Handle keydown events\n */\n private handleKeyDown(e: KeyboardEvent): void {\n if (!this.enabled) return;\n\n // Skip if typing in an input element\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n\n // Find matching binding\n const binding = this.findMatchingBinding(e);\n if (!binding || binding.enabled === false) return;\n\n // Execute action\n const executed = this.executeAction(binding);\n \n if (executed && this.preventDefault) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n /**\n * Find a binding that matches the current key event\n */\n private findMatchingBinding(e: KeyboardEvent): KeyBinding | undefined {\n return this.bindings.find(b => {\n if (b.key !== e.code) return false;\n if (b.ctrl && !e.ctrlKey && !e.metaKey) return false;\n if (b.shift && !e.shiftKey) return false;\n if (b.alt && !e.altKey) return false;\n if (b.meta && !e.metaKey) return false;\n \n // Also check that extra modifiers aren't pressed\n if (!b.ctrl && (e.ctrlKey || e.metaKey)) return false;\n if (!b.shift && e.shiftKey) return false;\n if (!b.alt && e.altKey) return false;\n \n return true;\n });\n }\n\n /**\n * Execute the action for a binding\n */\n private executeAction(binding: KeyBinding): boolean {\n const { action, handler } = binding;\n\n switch (action) {\n case 'resetZoom':\n this.callbacks.onResetZoom?.();\n return true;\n case 'autoScale':\n this.callbacks.onAutoScale?.();\n return true;\n case 'zoomIn':\n this.callbacks.onZoomIn?.();\n return true;\n case 'zoomOut':\n this.callbacks.onZoomOut?.();\n return true;\n case 'panLeft':\n this.callbacks.onPanLeft?.();\n return true;\n case 'panRight':\n this.callbacks.onPanRight?.();\n return true;\n case 'panUp':\n this.callbacks.onPanUp?.();\n return true;\n case 'panDown':\n this.callbacks.onPanDown?.();\n return true;\n case 'togglePan':\n this.callbacks.onTogglePan?.();\n return true;\n case 'toggleSelect':\n this.callbacks.onToggleSelect?.();\n return true;\n case 'clearSelection':\n case 'escape':\n this.callbacks.onEscape?.();\n this.callbacks.onClearSelection?.();\n return true;\n case 'deleteSelected':\n this.callbacks.onDeleteSelected?.();\n return true;\n case 'selectAll':\n this.callbacks.onSelectAll?.();\n return true;\n case 'copy':\n this.callbacks.onCopy?.();\n return true;\n case 'exportImage':\n this.callbacks.onExportImage?.();\n return true;\n case 'toggleLegend':\n this.callbacks.onToggleLegend?.();\n return true;\n case 'toggleDebug':\n this.callbacks.onToggleDebug?.();\n return true;\n case 'undo':\n this.callbacks.onUndo?.();\n return true;\n case 'redo':\n this.callbacks.onRedo?.();\n return true;\n case 'custom':\n handler?.();\n return true;\n default:\n return false;\n }\n }\n\n /**\n * Destroy the manager and cleanup\n */\n destroy(): void {\n this.detach();\n this.bindings = [];\n }\n}\n\n// ============================================\n// Convenience Functions\n// ============================================\n\n/**\n * Create a simple key binding configuration\n */\nexport function createKeyBinding(\n key: string,\n action: KeyAction,\n options?: Partial<KeyBinding>\n): KeyBinding {\n return {\n key,\n action,\n ...options,\n };\n}\n\n/**\n * Parse a shortcut string (e.g., \"Ctrl+R\") into a KeyBinding\n */\nexport function parseShortcut(shortcut: string, action: KeyAction): KeyBinding {\n const parts = shortcut.split('+').map(p => p.trim().toLowerCase());\n const binding: KeyBinding = {\n key: '',\n action,\n ctrl: false,\n shift: false,\n alt: false,\n meta: false,\n };\n\n for (const part of parts) {\n switch (part) {\n case 'ctrl':\n case 'control':\n binding.ctrl = true;\n break;\n case 'shift':\n binding.shift = true;\n break;\n case 'alt':\n binding.alt = true;\n break;\n case 'meta':\n case 'cmd':\n case 'command':\n binding.meta = true;\n break;\n default:\n // Convert to key code\n if (part.length === 1) {\n if (/[a-z]/i.test(part)) {\n binding.key = 'Key' + part.toUpperCase();\n } else if (/[0-9]/.test(part)) {\n binding.key = 'Digit' + part;\n } else if (part === '+') {\n binding.key = 'Equal';\n } else if (part === '-') {\n binding.key = 'Minus';\n }\n } else {\n // Handle special keys\n const specialKeys: Record<string, string> = {\n 'escape': 'Escape',\n 'esc': 'Escape',\n 'enter': 'Enter',\n 'return': 'Enter',\n 'space': 'Space',\n 'tab': 'Tab',\n 'delete': 'Delete',\n 'backspace': 'Backspace',\n 'left': 'ArrowLeft',\n 'right': 'ArrowRight',\n 'up': 'ArrowUp',\n 'down': 'ArrowDown',\n };\n binding.key = specialKeys[part] || part;\n }\n }\n }\n\n return binding;\n}\n","/**\n * Sci 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":["DEFAULT_KEY_BINDINGS","KeyBindingManager","options","__publicField","enabled","binding","key","modifiers","b","updates","parts","keyName","target","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_A","_B","_C","_D","_E","_F","_G","_H","_I","_J","_K","_L","_M","_N","action","handler","createKeyBinding","parseShortcut","shortcut","p","part","specialKeys","manifestKeyboard","PluginKeyboard","config","manager","ctx","chart","drawing","url","a"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.core-COREBDNq.js","sources":["../src/renderer/RendererInterface.ts","../src/plugins/PluginRegistry.ts","../src/plugins/index.ts"],"sourcesContent":["/**\n * WebGL Renderer Interface & Factory\n *\n * This module provides a common interface for WebGL rendering.\n * Currently optimized for NativeWebGLRenderer (zero dependencies).\n */\n\nimport type { Bounds } from '../types';\nimport { NativeWebGLRenderer } from './NativeWebGLRenderer';\n\n// ============================================\n// Common Types\n// ============================================\n\nexport interface SeriesRenderData {\n id: string;\n buffer: WebGLBuffer;\n count: number;\n style: any;\n visible: boolean;\n type: string;\n zBounds?: { min: number; max: number };\n colormapTexture?: WebGLTexture;\n}\n\nexport interface RenderOptions {\n bounds: Bounds;\n backgroundColor?: [number, number, number, number];\n}\n\n// ============================================\n// Renderer Interface\n// ============================================\n\n/**\n * Common interface for all WebGL renderer implementations\n */\nexport interface IWebGLRenderer {\n /** Check if WebGL is available and initialized */\n readonly available: boolean;\n\n /**\n * Create or update a GPU buffer with interleaved X,Y data\n * @param id - Unique buffer identifier\n * @param data - Interleaved Float32Array [x0, y0, x1, y1, ...]\n */\n createBuffer(id: string, data: Float32Array): void;\n\n /**\n * Get a buffer by ID\n */\n getBuffer(id: string): WebGLBuffer | undefined;\n\n /**\n * Delete a buffer and free GPU memory\n */\n deleteBuffer(id: string): void;\n \n /** \n * Create a 1D texture for heatmaps \n */\n createColormapTexture(id: string, data: Uint8Array): WebGLTexture;\n\n /**\n * Render a frame with all visible series\n */\n render(series: SeriesRenderData[], options: RenderOptions): void;\n\n /**\n * Handle canvas resize\n */\n resize(): void;\n\n /**\n * Get WebGL capabilities/limits\n */\n getLimits(): Record<string, unknown>;\n\n /**\n * Cleanup and destroy all GPU resources\n */\n destroy(): void;\n}\n\n// ============================================\n// Factory Functions\n// ============================================\n\n/**\n * Create a WebGL renderer (Native WebGL)\n *\n * @param canvas - Target canvas element\n */\nexport function createRenderer(canvas: HTMLCanvasElement): IWebGLRenderer {\n return new NativeWebGLRenderer(canvas);\n}\n\n/**\n * Create a renderer synchronously (native only)\n */\nexport { NativeWebGLRenderer as createNativeRenderer } from './NativeWebGLRenderer';\n","/**\n * Sci Plot - Global Plugin Registry\n * \n * Provides a global registry for third-party plugins that can be\n * discovered and loaded by name without explicit imports.\n * \n * @module plugins/PluginRegistry\n */\n\nimport type {\n PluginFactory,\n PluginManifest,\n PluginCapability,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Global Registry Implementation\n// ============================================\n\nclass PluginRegistryImpl implements PluginRegistry {\n private entries = new Map<string, PluginRegistryEntry>();\n\n /**\n * Register a plugin globally\n */\n register(entry: PluginRegistryEntry): void {\n const name = entry.manifest.name;\n\n if (this.entries.has(name)) {\n console.warn(\n `[SciPlot Registry] Plugin \"${name}\" is already registered, overwriting`\n );\n }\n\n this.entries.set(name, entry);\n }\n\n /**\n * Unregister a plugin\n */\n unregister(name: string): boolean {\n const existed = this.entries.has(name);\n this.entries.delete(name);\n return existed;\n }\n\n /**\n * Get a registered plugin factory by name\n */\n get(name: string): PluginFactory | undefined {\n return this.entries.get(name)?.factory;\n }\n\n /**\n * List all registered plugins\n */\n list(): PluginManifest[] {\n return Array.from(this.entries.values()).map((e) => e.manifest);\n }\n\n /**\n * Search plugins by capability\n */\n findByCapability(capability: PluginCapability): PluginManifest[] {\n const results: PluginManifest[] = [];\n\n this.entries.forEach((entry) => {\n if (entry.manifest.provides?.includes(capability)) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Search plugins by tag\n */\n findByTag(tag: string): PluginManifest[] {\n const results: PluginManifest[] = [];\n const lowerTag = tag.toLowerCase();\n\n this.entries.forEach((entry) => {\n if (entry.manifest.tags?.some((t) => t.toLowerCase().includes(lowerTag))) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Check if a plugin is registered\n */\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n /**\n * Get plugin count\n */\n get size(): number {\n return this.entries.size;\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.entries.clear();\n }\n}\n\n// ============================================\n// Singleton Instance\n// ============================================\n\nlet registryInstance: PluginRegistryImpl | null = null;\n\n/**\n * Get the global plugin registry singleton\n */\nexport function getPluginRegistry(): PluginRegistry {\n if (!registryInstance) {\n registryInstance = new PluginRegistryImpl();\n }\n return registryInstance;\n}\n\n/**\n * Register a plugin in the global registry\n * Shorthand for getPluginRegistry().register()\n */\nexport function registerPlugin(entry: PluginRegistryEntry): void {\n getPluginRegistry().register(entry);\n}\n\n/**\n * Create a plugin factory with manifest validation\n */\nexport function definePlugin<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n return (config?: TConfig) => {\n const plugin = factory(config);\n return {\n ...plugin,\n manifest,\n };\n };\n}\n\n/**\n * Register a plugin from definition\n */\nexport function defineAndRegister<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n const pluginFactory = definePlugin(manifest, factory);\n registerPlugin({ manifest, factory: pluginFactory as PluginFactory });\n return pluginFactory;\n}\n\n// ============================================\n// Plugin Discovery Helpers\n// ============================================\n\n/**\n * Load a plugin from the registry by name\n */\nexport async function loadPlugin<TConfig = unknown>(\n name: string,\n config?: TConfig\n): Promise<import(\"./types\").ChartPlugin<TConfig> | undefined> {\n const factory = getPluginRegistry().get(name);\n if (!factory) {\n console.warn(`[SciPlot] Plugin \"${name}\" not found in registry`);\n return undefined;\n }\n return factory(config) as import(\"./types\").ChartPlugin<TConfig>;\n}\n\n/**\n * List available plugins by category\n */\nexport function listPluginsByCategory(): Record<PluginCapability, PluginManifest[]> {\n const registry = getPluginRegistry();\n const categories: PluginCapability[] = [\n \"analysis\",\n \"visualization\",\n \"interaction\",\n \"data-source\",\n \"export\",\n \"ui\",\n \"annotation\",\n \"theme\",\n ];\n\n const result: Record<string, PluginManifest[]> = {};\n categories.forEach((cat) => {\n result[cat] = registry.findByCapability(cat);\n });\n\n return result as Record<PluginCapability, PluginManifest[]>;\n}\n\n// ============================================\n// Plugin Validation\n// ============================================\n\n/**\n * Validate a plugin manifest\n */\nexport function validateManifest(manifest: PluginManifest): string[] {\n const errors: string[] = [];\n\n if (!manifest.name) {\n errors.push(\"Missing required field: name\");\n } else if (!/^[@a-z0-9-]+\\/[a-z0-9-]+$|^[a-z0-9-]+$/.test(manifest.name)) {\n errors.push(\n 'Invalid name format. Use lowercase with hyphens, optionally scoped (e.g., \"@org/name\")'\n );\n }\n\n if (!manifest.version) {\n errors.push(\"Missing required field: version\");\n } else if (!/^\\d+\\.\\d+\\.\\d+$/.test(manifest.version)) {\n errors.push(\"Invalid version format. Use semantic versioning (e.g., 1.0.0)\");\n }\n\n if (manifest.dependencies) {\n if (!Array.isArray(manifest.dependencies)) {\n errors.push(\"dependencies must be an array\");\n }\n }\n\n if (manifest.provides) {\n if (!Array.isArray(manifest.provides)) {\n errors.push(\"provides must be an array\");\n }\n }\n\n return errors;\n}\n\n/**\n * Validate a plugin for compatibility\n */\nexport function checkPluginCompatibility(\n manifest: PluginManifest,\n engineVersion: string\n): { compatible: boolean; warnings: string[] } {\n const warnings: string[] = [];\n\n if (manifest.engineVersion) {\n const [reqMajor] = manifest.engineVersion.split(\".\").map(Number);\n const [curMajor] = engineVersion.split(\".\").map(Number);\n\n if (reqMajor > curMajor) {\n return {\n compatible: false,\n warnings: [\n `Plugin requires engine v${manifest.engineVersion}, current is v${engineVersion}`,\n ],\n };\n }\n\n if (reqMajor < curMajor) {\n warnings.push(\n `Plugin was built for engine v${manifest.engineVersion}, may have compatibility issues`\n );\n }\n }\n\n return { compatible: true, warnings };\n}\n","/**\n * Sci Plot - Plugin System\n * \n * Comprehensive plugin architecture for extending chart functionality.\n * \n * Features:\n * - Complete lifecycle hooks (init, render, data, view, interaction, destroy)\n * - Rich plugin context with access to all chart internals\n * - Plugin storage for persistent state\n * - Dependency management between plugins\n * - Global registry for third-party plugins\n * - Built-in plugins for common use cases\n * \n * @packageDocumentation\n * @module plugins\n */\n\n// ============================================\n// Core Types\n// ============================================\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext,\n EventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n\n // Manager Types\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Core Implementation\n// ============================================\nexport { createPluginContext } from \"./PluginContext\";\nexport type { ContextDependencies } from \"./PluginContext\";\n\nexport { PluginManagerImpl } from \"./PluginManager\";\n\n// ============================================\n// Registry\n// ============================================\nexport {\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n} from \"./PluginRegistry\";\n\n// ============================================\n// Built-in Plugins\n// ============================================\nexport {\n // Individual plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n\n // Plugin collection\n BuiltinPlugins,\n\n // Plugin configs\n type CrosshairPluginConfig,\n type StatsPluginConfig,\n type WatermarkPluginConfig,\n type GridHighlightConfig,\n type DataLoggerConfig,\n type DirectionIndicatorConfig,\n} from \"./builtins\";\n\n// ============================================\n// Modular Plugins\n// ============================================\nexport { Plugin3D, type Plugin3DConfig } from \"./3d\";\nexport { PluginGpu, type PluginGpuConfig } from \"./gpu\";\nexport { PluginAnalysis, type PluginAnalysisConfig } from \"./analysis\";\nexport { PluginTools, type PluginToolsConfig } from \"./tools\";\nexport { PluginAnnotations, type PluginAnnotationsConfig } from \"./annotations\";\nexport { PluginStreaming, type PluginStreamingConfig } from \"./streaming\";\nexport { PluginThemeEditor, type PluginThemeEditorConfig } from \"./theme-editor\";\nexport { PluginI18n, type PluginI18nConfig } from \"./i18n\";\nexport { PluginKeyboard, type PluginKeyboardConfig } from \"./keyboard\";\nexport { PluginClipboard, type PluginClipboardConfig } from \"./clipboard\";\nexport { PluginSync, type PluginSyncConfig } from \"./sync\";\nexport { PluginDebug, type PluginDebugConfig } from \"./debug\";\nexport { PluginLoading, type PluginLoadingConfig } from \"./loading\";\nexport { PluginDataExport, type PluginDataExportConfig } from \"./data-export\";\nexport { PluginContextMenu, type PluginContextMenuConfig } from \"./context-menu\";\nexport { PluginAnomalyDetection, type PluginAnomalyDetectionConfig, type AnomalyDetectionResult, type AnomalyPoint, type AnomalyMethod } from \"./anomaly-detection\";\nexport { PluginMLIntegration, type PluginMLIntegrationConfig, type MLIntegrationAPI, type MLModelAPI, type PredictionResult, type VisualizationConfig } from \"./ml-integration\";\nexport { PluginPatternRecognition, type PluginPatternRecognitionConfig, type PatternRecognitionAPI, type PatternMatch, type PatternDetectionResult } from \"./pattern-recognition\";\nexport { PluginRegression, type PluginRegressionConfig, type RegressionAPI, type RegressionResult, type RegressionData } from \"./regression\";\nexport { PluginRadar, type PluginRadarConfig, type RadarAPI, type RadarSeriesData, type RadarPoint } from \"./radar\";\nexport { PluginSnapshot, type PluginSnapshotConfig, type SnapshotExportAPI, type SnapshotExportOptions, type SnapshotResolution, type SnapshotFormat } from \"./snapshot\";\nexport { PluginDataTransform, type PluginDataTransformConfig, type DataTransformAPI, type TransformOp, type TransformType } from \"./data-transform\";\nexport { PluginLaTeX, type PluginLaTeXConfig, type LaTeXPluginAPI, type LaTeXDimensions } from \"./latex\";\nexport * from \"./forecasting\";\n\n// Drag & Drop Editing\nexport { PluginDragEdit, type PluginDragEditConfig, type DragEditAPI, type DragEditEvent } from \"./drag-edit\";\n\n// Caching\nexport { PluginCaching, type PluginCachingConfig, type CachingAPI, type CacheStats } from \"./caching\";\n\n// Lazy Loading\nexport { PluginLazyLoad, type PluginLazyLoadConfig, type LazyLoadAPI, type DataProvider } from \"./lazy-load\";\n\n// Broken Axis\nexport { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type AxisBreak } from \"./broken-axis\";\n\n// Video Recorder\nexport { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from \"./video-recorder\";\n\n// Offscreen Rendering\nexport { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from \"./offscreen\";\n\n// Virtualization\nexport { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from \"./virtualization\";\n\n// Stage 2 — Trading\nexport { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from \"./drawing-tools\";\nexport { PluginReplay, type PluginReplayConfig, type ReplayAPI } from \"./replay\";\n\n// ROI\nexport { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from \"./roi\";\n\n// ============================================\n// Helper for creating typed plugins\n// ============================================\n\n/**\n * Helper function to create a plugin with proper typing\n * \n * @example\n * ```typescript\n * const MyPlugin = createPlugin({\n * manifest: {\n * name: 'my-plugin',\n * version: '1.0.0',\n * provides: ['analysis'],\n * },\n * onInit(ctx) {\n * ctx.log.info('Plugin initialized!');\n * },\n * onAfterRender(ctx, event) {\n * // Custom rendering\n * },\n * api: {\n * doSomething() { return 'done'; }\n * }\n * });\n * \n * chart.use(MyPlugin);\n * ```\n */\nexport function createPlugin<TConfig = void, TApi extends Record<string, unknown> = {}>(\n definition: import(\"./types\").ChartPlugin<TConfig> & { api?: TApi }\n): import(\"./types\").ChartPlugin<TConfig> & { api: TApi } {\n return definition as import(\"./types\").ChartPlugin<TConfig> & { api: TApi };\n}\n\n/**\n * Helper function to create a configurable plugin factory\n * \n * @example\n * ```typescript\n * interface MyConfig {\n * color: string;\n * enabled: boolean;\n * }\n * \n * const MyPlugin = createConfigurablePlugin<MyConfig>(\n * {\n * name: 'my-plugin',\n * version: '1.0.0',\n * },\n * (config) => ({\n * onInit(ctx) {\n * ctx.log.info(`Color: ${config?.color}`);\n * }\n * })\n * );\n * \n * chart.use(MyPlugin({ color: 'red', enabled: true }));\n * ```\n */\nexport function createConfigurablePlugin<TConfig = void>(\n manifest: import(\"./types\").PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): import(\"./types\").PluginFactory<TConfig> {\n return (config?: TConfig) => ({\n ...factory(config),\n manifest,\n });\n}\n"],"names":["createRenderer","canvas","NativeWebGLRenderer","PluginRegistryImpl","__publicField","entry","name","existed","_a","capability","results","tag","lowerTag","t","registryInstance","getPluginRegistry","registerPlugin","definePlugin","manifest","factory","config","defineAndRegister","pluginFactory","loadPlugin","listPluginsByCategory","registry","categories","result","cat","validateManifest","errors","checkPluginCompatibility","engineVersion","warnings","reqMajor","curMajor","createPlugin","definition","createConfigurablePlugin"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mockDatafeed-927foCM4.js","sources":["../src/plugins/drawing-tools/snapToCandle.ts","../src/plugins/drawing-tools/measure.ts","../src/plugins/drawing-tools/index.ts","../src/plugins/replay/index.ts","../src/trading/datafeed.ts","../src/trading/mockDatafeed.ts"],"sourcesContent":["/**\n * Snap drawing points to nearest candlestick O/H/L/C (TradingView-style magnet).\n */\n\nexport interface CandleSnapInput {\n x: number;\n y: number;\n barX: Float32Array | Float64Array;\n open: Float32Array | Float64Array;\n high: Float32Array | Float64Array;\n low: Float32Array | Float64Array;\n close: Float32Array | Float64Array;\n dataToPixelX: (x: number) => number;\n dataToPixelY: (y: number) => number;\n pixelThreshold?: number;\n enabled?: boolean;\n}\n\nexport function findNearestBarIndex(\n barX: Float32Array | Float64Array,\n x: number,\n): number {\n if (barX.length === 0) return -1;\n let bestIdx = 0;\n let bestDist = Math.abs(barX[0] - x);\n for (let i = 1; i < barX.length; i++) {\n const d = Math.abs(barX[i] - x);\n if (d < bestDist) {\n bestDist = d;\n bestIdx = i;\n }\n }\n return bestIdx;\n}\n\nexport function snapToCandle(input: CandleSnapInput): { x: number; y: number } {\n if (input.enabled === false || input.barX.length === 0) {\n return { x: input.x, y: input.y };\n }\n\n const idx = findNearestBarIndex(input.barX, input.x);\n if (idx < 0) return { x: input.x, y: input.y };\n\n const barX = input.barX[idx];\n const candidates = [\n input.open[idx],\n input.high[idx],\n input.low[idx],\n input.close[idx],\n ];\n\n const clickPy = input.dataToPixelY(input.y);\n const threshold = input.pixelThreshold ?? 12;\n let bestY = input.y;\n let bestPyDist = Infinity;\n\n for (const cy of candidates) {\n const py = input.dataToPixelY(cy);\n const dist = Math.abs(py - clickPy);\n if (dist < bestPyDist && dist <= threshold) {\n bestPyDist = dist;\n bestY = cy;\n }\n }\n\n return { x: barX, y: bestY };\n}\n","/**\n * Measurement helper for the price-range / measure tool (TradingView-style).\n */\n\nexport interface MeasurePoint {\n x: number;\n y: number;\n}\n\nexport interface Measurement {\n /** Absolute price change (end - start) */\n change: number;\n /** Percentage change relative to the start price */\n percent: number;\n /** Number of bars spanned (rounded X distance) */\n bars: number;\n /** True when the range moves up (change >= 0) */\n up: boolean;\n}\n\nexport function computeMeasurement(a: MeasurePoint, b: MeasurePoint): Measurement {\n const change = b.y - a.y;\n const denom = Math.abs(a.y);\n const percent = denom > 0 ? (change / denom) * 100 : 0;\n const bars = Math.round(Math.abs(b.x - a.x));\n return { change, percent, bars, up: change >= 0 };\n}\n\nexport function formatMeasurement(m: Measurement): string {\n const sign = m.change >= 0 ? \"+\" : \"\";\n return `${sign}${m.change.toFixed(2)} (${sign}${m.percent.toFixed(2)}%) · ${m.bars} bars`;\n}\n\n/** Compact price formatting used for level labels. */\nexport function formatPrice(value: number): string {\n const abs = Math.abs(value);\n const decimals = abs >= 1000 ? 0 : abs >= 1 ? 2 : 4;\n return value.toLocaleString(\"en-US\", {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n}\n","/**\n * PluginDrawingTools — interactive drawing on chart (Stage 2.9).\n * TradingView-style live preview, drag-to-draw, optional candle magnet.\n */\n\nimport type { ChartPlugin, InteractionEvent, PluginContext, PluginManifest } from \"../types\";\nimport type { Annotation } from \"../../core/annotations/types\";\nimport type { Series } from \"../../core/Series\";\nimport { snapToCandle } from \"./snapToCandle\";\nimport { computeMeasurement, formatMeasurement, formatPrice } from \"./measure\";\n\nexport type DrawingMode =\n | \"none\"\n | \"pan\"\n | \"trendline\"\n | \"horizontal\"\n | \"vertical\"\n | \"rectangle\"\n | \"fibonacci\"\n | \"measure\";\n\nconst FIB_LEVELS = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1];\nconst DRAG_THRESHOLD_PX = 4;\nconst DEFAULT_MEASURE_UP = \"#26a69a\";\nconst DEFAULT_MEASURE_DOWN = \"#ef5350\";\n\nexport interface PluginDrawingToolsConfig {\n /** Default stroke color */\n color?: string;\n /** Enable candle magnet by default */\n magnet?: boolean;\n /** Return to pan mode after each completed stroke (default true) */\n autoDeselect?: boolean;\n /** Notified when drawing mode changes (including auto-deselect to none) */\n onModeChange?: (mode: DrawingMode) => void;\n /** Color for upward measurements (default green) */\n measureUpColor?: string;\n /** Color for downward measurements (default red) */\n measureDownColor?: string;\n}\n\nfunction withAlpha(color: string, alpha: string): string {\n return color.startsWith(\"#\") && color.length === 7 ? color + alpha : color;\n}\n\nexport interface DrawingToolsAPI {\n setMode(mode: DrawingMode): void;\n getMode(): DrawingMode;\n setMagnet(enabled: boolean): void;\n isMagnet(): boolean;\n undo(): boolean;\n redo(): boolean;\n clear(): void;\n}\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-drawing-tools\",\n version: \"1.0.0\",\n description: \"Interactive trendline, horizontal, vertical, rectangle, and fibonacci drawing\",\n provides: [\"drawing\"],\n tags: [\"drawing\", \"annotations\", \"trading\"],\n};\n\ninterface DrawPoint {\n x: number;\n y: number;\n}\n\ninterface DrawState {\n mode: DrawingMode;\n pending: DrawPoint | null;\n start: DrawPoint | null;\n dragging: boolean;\n dragMoved: boolean;\n dragStartPixel: { x: number; y: number } | null;\n cursor: DrawPoint | null;\n magnet: boolean;\n undoStack: Annotation[][];\n redoStack: Annotation[][];\n}\n\nfunction isDrawingMode(mode: DrawingMode): boolean {\n return mode !== \"none\" && mode !== \"pan\";\n}\n\nfunction findCandlestickSeries(ctx: PluginContext): Series | undefined {\n for (const s of ctx.data.getAllSeries()) {\n if (s.getType() === \"candlestick\") return s;\n }\n return undefined;\n}\n\nexport function PluginDrawingTools(\n config: PluginDrawingToolsConfig = {},\n): ChartPlugin<PluginDrawingToolsConfig> {\n let ctx: PluginContext | null = null;\n const autoDeselect = config.autoDeselect !== false;\n let state: DrawState = {\n mode: \"none\",\n pending: null,\n start: null,\n dragging: false,\n dragMoved: false,\n dragStartPixel: null,\n cursor: null,\n magnet: config.magnet ?? false,\n undoStack: [],\n redoStack: [],\n };\n\n const stroke = config.color ?? \"#38bdf8\";\n const measureUp = config.measureUpColor ?? DEFAULT_MEASURE_UP;\n const measureDown = config.measureDownColor ?? DEFAULT_MEASURE_DOWN;\n\n function snapshot(): Annotation[] {\n return ctx?.chart.getAnnotations?.() ?? [];\n }\n\n function pushUndo(): void {\n state.undoStack.push(snapshot());\n state.redoStack = [];\n }\n\n function resetInteractionState(): void {\n state.pending = null;\n state.start = null;\n state.dragging = false;\n state.dragMoved = false;\n state.dragStartPixel = null;\n }\n\n function setModeInternal(mode: DrawingMode): void {\n state.mode = mode;\n resetInteractionState();\n config.onModeChange?.(mode);\n ctx?.requestRender?.();\n }\n\n function finishStroke(): void {\n resetInteractionState();\n if (autoDeselect) {\n setModeInternal(\"none\");\n } else {\n ctx?.requestRender?.();\n }\n }\n\n function resolvePoint(x: number, y: number): DrawPoint {\n if (!ctx || !state.magnet) return { x, y };\n const series = findCandlestickSeries(ctx);\n if (!series) return { x, y };\n const d = series.getData();\n if (!d.open || !d.high || !d.low || !d.close) return { x, y };\n return snapToCandle({\n x,\n y,\n barX: d.x,\n open: d.open,\n high: d.high,\n low: d.low,\n close: d.close,\n dataToPixelX: ctx.coords.dataToPixelX,\n dataToPixelY: (dy) => ctx!.coords.dataToPixelY(dy),\n enabled: true,\n });\n }\n\n function pointFromEvent(pluginCtx: PluginContext, event: InteractionEvent): DrawPoint {\n return resolvePoint(\n pluginCtx.coords.pixelToDataX(event.pixelX),\n pluginCtx.coords.pixelToDataY(event.pixelY),\n );\n }\n\n function commitHorizontal(y: number): void {\n if (!ctx) return;\n pushUndo();\n ctx.chart.addAnnotation({\n type: \"horizontal-line\",\n y,\n color: stroke,\n interactive: true,\n });\n }\n\n function commitVertical(x: number): void {\n if (!ctx) return;\n pushUndo();\n ctx.chart.addAnnotation({\n type: \"vertical-line\",\n x,\n color: stroke,\n interactive: true,\n });\n }\n\n function commitMeasure(p0: DrawPoint, p1: DrawPoint): void {\n if (!ctx) return;\n pushUndo();\n\n const m = computeMeasurement(p0, p1);\n const color = m.up ? measureUp : measureDown;\n const midX = (p0.x + p1.x) / 2;\n ctx.chart.addAnnotation({\n type: \"rectangle\",\n xMin: Math.min(p0.x, p1.x),\n xMax: Math.max(p0.x, p1.x),\n yMin: Math.min(p0.y, p1.y),\n yMax: Math.max(p0.y, p1.y),\n strokeColor: color,\n fillColor: withAlpha(color, \"33\"),\n interactive: true,\n });\n ctx.chart.addAnnotation({\n type: \"arrow\",\n x1: midX,\n y1: p0.y,\n x2: midX,\n y2: p1.y,\n color,\n headStyle: \"filled\",\n interactive: true,\n });\n ctx.chart.addAnnotation({\n type: \"text\",\n x: midX,\n y: p1.y,\n text: formatMeasurement(m),\n color: \"#ffffff\",\n backgroundColor: color,\n padding: 4,\n fontWeight: \"bold\",\n anchor: m.up ? \"bottom-center\" : \"top-center\",\n interactive: true,\n });\n }\n\n function commitTwoPoint(p0: DrawPoint, p1: DrawPoint): void {\n if (!ctx) return;\n\n if (state.mode === \"measure\") {\n commitMeasure(p0, p1);\n return;\n }\n\n pushUndo();\n\n if (state.mode === \"trendline\") {\n ctx.chart.addAnnotation({\n type: \"arrow\",\n x1: p0.x,\n y1: p0.y,\n x2: p1.x,\n y2: p1.y,\n color: stroke,\n interactive: true,\n });\n } else if (state.mode === \"rectangle\") {\n ctx.chart.addAnnotation({\n type: \"rectangle\",\n xMin: Math.min(p0.x, p1.x),\n xMax: Math.max(p0.x, p1.x),\n yMin: Math.min(p0.y, p1.y),\n yMax: Math.max(p0.y, p1.y),\n strokeColor: stroke,\n fillColor: stroke + \"22\",\n interactive: true,\n });\n } else if (state.mode === \"fibonacci\") {\n const yMin = Math.min(p0.y, p1.y);\n const yMax = Math.max(p0.y, p1.y);\n for (const level of FIB_LEVELS) {\n const fy = yMax - (yMax - yMin) * level;\n ctx.chart.addAnnotation({\n type: \"horizontal-line\",\n y: fy,\n color: stroke,\n lineDash: level === 0 || level === 1 ? undefined : [4, 4],\n label: `${(level * 100).toFixed(1)}% ${formatPrice(fy)}`,\n labelPosition: \"right\",\n interactive: true,\n });\n }\n }\n }\n\n function drawPreview(\n c2d: CanvasRenderingContext2D,\n plotArea: { x: number; y: number; width: number; height: number },\n coords: PluginContext[\"coords\"],\n ): void {\n const mode = state.mode;\n if (!isDrawingMode(mode) || !state.cursor) return;\n\n const cursor = state.cursor;\n const anchor = state.pending ?? state.start;\n\n c2d.save();\n c2d.strokeStyle = stroke;\n c2d.lineWidth = 1.5;\n c2d.setLineDash([6, 4]);\n c2d.globalAlpha = 0.85;\n\n const toPx = (x: number, y: number) => ({\n px: coords.dataToPixelX(x),\n py: coords.dataToPixelY(y),\n });\n\n if (mode === \"horizontal\") {\n const { py } = toPx(0, cursor.y);\n c2d.beginPath();\n c2d.moveTo(plotArea.x, py);\n c2d.lineTo(plotArea.x + plotArea.width, py);\n c2d.stroke();\n } else if (mode === \"vertical\") {\n const { px } = toPx(cursor.x, 0);\n c2d.beginPath();\n c2d.moveTo(px, plotArea.y);\n c2d.lineTo(px, plotArea.y + plotArea.height);\n c2d.stroke();\n } else if (anchor) {\n const a = toPx(anchor.x, anchor.y);\n const b = toPx(cursor.x, cursor.y);\n\n if (mode === \"trendline\") {\n c2d.beginPath();\n c2d.moveTo(a.px, a.py);\n c2d.lineTo(b.px, b.py);\n c2d.stroke();\n } else if (mode === \"rectangle\") {\n const x = Math.min(a.px, b.px);\n const y = Math.min(a.py, b.py);\n const w = Math.abs(b.px - a.px);\n const h = Math.abs(b.py - a.py);\n c2d.strokeRect(x, y, w, h);\n c2d.fillStyle = stroke + \"22\";\n c2d.fillRect(x, y, w, h);\n } else if (mode === \"fibonacci\") {\n const yMin = Math.min(anchor.y, cursor.y);\n const yMax = Math.max(anchor.y, cursor.y);\n c2d.font = \"11px sans-serif\";\n c2d.textAlign = \"left\";\n c2d.textBaseline = \"bottom\";\n for (const level of FIB_LEVELS) {\n const fy = yMax - (yMax - yMin) * level;\n const { py } = toPx(0, fy);\n c2d.beginPath();\n c2d.moveTo(plotArea.x, py);\n c2d.lineTo(plotArea.x + plotArea.width, py);\n c2d.stroke();\n c2d.save();\n c2d.setLineDash([]);\n c2d.globalAlpha = 1;\n c2d.fillStyle = stroke;\n c2d.fillText(\n `${(level * 100).toFixed(1)}% ${formatPrice(fy)}`,\n plotArea.x + 4,\n py - 2,\n );\n c2d.restore();\n }\n } else if (mode === \"measure\") {\n drawMeasurePreview(c2d, a, b, anchor, cursor);\n }\n }\n\n c2d.restore();\n }\n\n function drawMeasurePreview(\n c2d: CanvasRenderingContext2D,\n a: { px: number; py: number },\n b: { px: number; py: number },\n anchor: DrawPoint,\n cursor: DrawPoint,\n ): void {\n const m = computeMeasurement(anchor, cursor);\n const color = m.up ? measureUp : measureDown;\n const x = Math.min(a.px, b.px);\n const y = Math.min(a.py, b.py);\n const w = Math.abs(b.px - a.px);\n const h = Math.abs(b.py - a.py);\n\n c2d.setLineDash([]);\n c2d.globalAlpha = 0.9;\n c2d.fillStyle = withAlpha(color, \"33\");\n c2d.fillRect(x, y, w, h);\n c2d.strokeStyle = color;\n c2d.lineWidth = 1.5;\n c2d.strokeRect(x, y, w, h);\n\n // Vertical direction arrow at the horizontal center.\n const midX = (a.px + b.px) / 2;\n c2d.beginPath();\n c2d.moveTo(midX, a.py);\n c2d.lineTo(midX, b.py);\n c2d.stroke();\n const headLen = 7;\n const dir = b.py >= a.py ? 1 : -1;\n c2d.beginPath();\n c2d.moveTo(midX, b.py);\n c2d.lineTo(midX - 4, b.py - dir * headLen);\n c2d.lineTo(midX + 4, b.py - dir * headLen);\n c2d.closePath();\n c2d.fillStyle = color;\n c2d.fill();\n\n // Label with change / percent / bars.\n const label = formatMeasurement(m);\n c2d.font = \"12px sans-serif\";\n const textW = c2d.measureText(label).width;\n const padX = 6;\n const boxW = textW + padX * 2;\n const boxH = 20;\n const boxX = midX - boxW / 2;\n const boxY = m.up ? b.py - boxH - 8 : b.py + 8;\n c2d.globalAlpha = 1;\n c2d.fillStyle = color;\n c2d.fillRect(boxX, boxY, boxW, boxH);\n c2d.fillStyle = \"#ffffff\";\n c2d.textAlign = \"center\";\n c2d.textBaseline = \"middle\";\n c2d.fillText(label, midX, boxY + boxH / 2);\n }\n\n function handleMouseDown(pluginCtx: PluginContext, event: InteractionEvent): void {\n if (!event.inPlotArea) return;\n\n event.preventDefault();\n const point = pointFromEvent(pluginCtx, event);\n\n if (state.mode === \"horizontal\") {\n commitHorizontal(point.y);\n finishStroke();\n return;\n }\n\n if (state.mode === \"vertical\") {\n commitVertical(point.x);\n finishStroke();\n return;\n }\n\n if (state.pending) {\n commitTwoPoint(state.pending, point);\n finishStroke();\n return;\n }\n\n state.start = point;\n state.dragging = true;\n state.dragMoved = false;\n state.dragStartPixel = { x: event.pixelX, y: event.pixelY };\n state.cursor = point;\n pluginCtx.requestRender?.();\n }\n\n function handleMouseMove(pluginCtx: PluginContext, event: InteractionEvent): void {\n const point = pointFromEvent(pluginCtx, event);\n state.cursor = point;\n\n if (state.dragging && state.dragStartPixel) {\n const dx = event.pixelX - state.dragStartPixel.x;\n const dy = event.pixelY - state.dragStartPixel.y;\n if (Math.hypot(dx, dy) >= DRAG_THRESHOLD_PX) {\n state.dragMoved = true;\n }\n }\n\n event.preventDefault();\n pluginCtx.requestRender?.();\n }\n\n function handleMouseUp(pluginCtx: PluginContext, event: InteractionEvent): void {\n if (!state.dragging || !state.start) return;\n\n const point = pointFromEvent(pluginCtx, event);\n const start = state.start;\n state.dragging = false;\n state.dragStartPixel = null;\n\n if (state.dragMoved) {\n commitTwoPoint(start, point);\n finishStroke();\n return;\n }\n\n state.pending = start;\n state.start = null;\n state.cursor = point;\n pluginCtx.requestRender?.();\n }\n\n const api: DrawingToolsAPI & Record<string, unknown> = {\n setMode(mode) {\n setModeInternal(mode);\n },\n getMode() {\n return state.mode;\n },\n setMagnet(enabled) {\n state.magnet = enabled;\n },\n isMagnet() {\n return state.magnet;\n },\n undo() {\n if (!ctx || state.undoStack.length === 0) return false;\n state.redoStack.push(snapshot());\n const prev = state.undoStack.pop()!;\n const current = snapshot();\n for (const a of current) ctx.chart.removeAnnotation(a.id!);\n for (const a of prev) ctx.chart.addAnnotation(a);\n return true;\n },\n redo() {\n if (!ctx || state.redoStack.length === 0) return false;\n state.undoStack.push(snapshot());\n const next = state.redoStack.pop()!;\n const current = snapshot();\n for (const a of current) ctx.chart.removeAnnotation(a.id!);\n for (const a of next) ctx.chart.addAnnotation(a);\n return true;\n },\n clear() {\n if (!ctx) return;\n pushUndo();\n for (const a of snapshot()) ctx.chart.removeAnnotation(a.id!);\n },\n };\n\n return {\n manifest,\n api,\n onInit(pluginCtx) {\n ctx = pluginCtx;\n },\n onDestroy() {\n ctx = null;\n },\n onInteraction(pluginCtx, event) {\n if (!isDrawingMode(state.mode)) return;\n\n if (event.type === \"mousedown\") {\n handleMouseDown(pluginCtx, event);\n return;\n }\n\n if (event.type === \"mousemove\") {\n handleMouseMove(pluginCtx, event);\n return;\n }\n\n if (event.type === \"mouseup\") {\n handleMouseUp(pluginCtx, event);\n }\n },\n onRenderOverlay(pluginCtx) {\n const c2d = pluginCtx.render.ctx2d;\n if (!c2d) return;\n drawPreview(c2d, pluginCtx.render.plotArea, pluginCtx.coords);\n },\n };\n}\n\nexport { snapToCandle, findNearestBarIndex } from \"./snapToCandle\";\nexport default PluginDrawingTools;\n","/**\n * PluginReplay — bar-by-bar playback (Stage 2.17 MVP).\n */\n\nimport type { ChartPlugin, PluginContext, PluginManifest } from \"../types\";\n\nexport interface PluginReplayConfig {\n /** Series id to replay */\n seriesId: string;\n /** Milliseconds between frames at 1x speed */\n frameMs?: number;\n}\n\nexport interface ReplayAPI {\n play(speed?: number): void;\n pause(): void;\n step(count?: number): void;\n seek(index: number): void;\n getIndex(): number;\n getLength(): number;\n isPlaying(): boolean;\n}\n\nconst manifest: PluginManifest = {\n name: \"velo-plot-replay\",\n version: \"1.0.0\",\n description: \"Bar-by-bar chart replay with speed control\",\n provides: [\"replay\"],\n tags: [\"replay\", \"trading\"],\n};\n\ninterface ReplayBuffer {\n x: Float32Array;\n open?: Float32Array;\n high?: Float32Array;\n low?: Float32Array;\n close?: Float32Array;\n y?: Float32Array;\n}\n\nexport function PluginReplay(config: PluginReplayConfig): ChartPlugin<PluginReplayConfig> {\n let ctx: PluginContext | null = null;\n let buffer: ReplayBuffer | null = null;\n let index = 0;\n let timer: ReturnType<typeof setInterval> | null = null;\n let speed = 1;\n const frameMs = config.frameMs ?? 250;\n\n function applyWindow(end: number): void {\n if (!ctx || !buffer) return;\n const n = Math.min(end + 1, buffer.x.length);\n const slice = (arr?: Float32Array) => (arr ? arr.subarray(0, n) : undefined);\n ctx.chart.updateSeries(config.seriesId, {\n x: slice(buffer.x)!,\n y: slice(buffer.y),\n open: slice(buffer.open),\n high: slice(buffer.high),\n low: slice(buffer.low),\n close: slice(buffer.close),\n });\n }\n\n const api: ReplayAPI & Record<string, unknown> = {\n play(s = 1) {\n if (!buffer) return;\n speed = Math.max(0.1, s);\n if (timer) clearInterval(timer);\n timer = setInterval(() => {\n if (index >= buffer!.x.length - 1) {\n api.pause();\n return;\n }\n index++;\n applyWindow(index);\n }, frameMs / speed);\n },\n pause() {\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n },\n step(count = 1) {\n if (!buffer) return;\n index = Math.min(buffer.x.length - 1, index + count);\n applyWindow(index);\n },\n seek(i) {\n if (!buffer) return;\n index = Math.max(0, Math.min(buffer.x.length - 1, i));\n applyWindow(index);\n },\n getIndex() {\n return index;\n },\n getLength() {\n return buffer?.x.length ?? 0;\n },\n isPlaying() {\n return timer != null;\n },\n };\n\n return {\n manifest,\n api,\n onInit(pluginCtx) {\n ctx = pluginCtx;\n const series = ctx.chart.getSeries(config.seriesId);\n if (!series) {\n console.warn(`[PluginReplay] Series \"${config.seriesId}\" not found`);\n return;\n }\n const d = series.getData();\n buffer = {\n x: Float32Array.from(d.x),\n y: d.y ? Float32Array.from(d.y) : undefined,\n open: d.open ? Float32Array.from(d.open) : undefined,\n high: d.high ? Float32Array.from(d.high) : undefined,\n low: d.low ? Float32Array.from(d.low) : undefined,\n close: d.close ? Float32Array.from(d.close) : undefined,\n };\n index = Math.max(0, buffer.x.length - 1);\n },\n onDestroy() {\n api.pause();\n ctx = null;\n buffer = null;\n },\n };\n}\n\nexport default PluginReplay;\n","/**\n * UDF-inspired datafeed contract for trading charts (Stage 2.24).\n */\n\nexport interface SymbolInfo {\n symbol: string;\n name: string;\n description?: string;\n timezone?: string;\n session?: string;\n pricescale?: number;\n minmov?: number;\n}\n\nexport interface Bar {\n time: number;\n open: number;\n high: number;\n low: number;\n close: number;\n volume?: number;\n}\n\nexport interface HistoryRequest {\n symbol: string;\n resolution: string;\n from: number;\n to: number;\n}\n\nexport interface SubscribeBarsRequest {\n symbol: string;\n resolution: string;\n onBar: (bar: Bar) => void;\n}\n\n/**\n * TradingView UDF-style adapter surface.\n */\nexport interface DatafeedAdapter {\n resolveSymbol(symbol: string): Promise<SymbolInfo>;\n getBars(request: HistoryRequest): Promise<Bar[]>;\n subscribeBars(request: SubscribeBarsRequest): () => void;\n}\n\n/** Convert bars to typed OHLC arrays for velo-plot series. */\nexport function barsToOhlc(bars: Bar[]): {\n x: Float64Array;\n open: Float32Array;\n high: Float32Array;\n low: Float32Array;\n close: Float32Array;\n volume: Float32Array;\n} {\n const n = bars.length;\n const x = new Float64Array(n);\n const open = new Float32Array(n);\n const high = new Float32Array(n);\n const low = new Float32Array(n);\n const close = new Float32Array(n);\n const volume = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n const b = bars[i];\n x[i] = b.time;\n open[i] = b.open;\n high[i] = b.high;\n low[i] = b.low;\n close[i] = b.close;\n volume[i] = b.volume ?? 0;\n }\n return { x, open, high, low, close, volume };\n}\n","/**\n * Mock datafeed for demos and tests (Stage 2.25).\n */\n\nimport type {\n Bar,\n DatafeedAdapter,\n HistoryRequest,\n SubscribeBarsRequest,\n SymbolInfo,\n} from \"./datafeed\";\n\nexport interface MockDatafeedOptions {\n symbol?: string;\n barMs?: number;\n basePrice?: number;\n seed?: number;\n}\n\nfunction pseudoRandom(seed: number): () => number {\n let s = seed;\n return () => {\n s = (s * 16807) % 2147483647;\n return (s - 1) / 2147483646;\n };\n}\n\nfunction generateBars(from: number, to: number, barMs: number, base: number, rand: () => number): Bar[] {\n const bars: Bar[] = [];\n let price = base;\n for (let t = from; t <= to; t += barMs) {\n const open = price;\n const delta = (rand() - 0.48) * 2;\n const close = Math.max(1, open + delta);\n const high = Math.max(open, close) + rand() * 1.5;\n const low = Math.min(open, close) - rand() * 1.5;\n bars.push({\n time: t,\n open,\n high,\n low,\n close,\n volume: 1000 + rand() * 5000,\n });\n price = close;\n }\n return bars;\n}\n\nexport function createMockDatafeed(options: MockDatafeedOptions = {}): DatafeedAdapter {\n const barMs = options.barMs ?? 60_000;\n const basePrice = options.basePrice ?? 100;\n const rand = pseudoRandom(options.seed ?? 42);\n const cache = new Map<string, Bar[]>();\n\n return {\n async resolveSymbol(sym: string): Promise<SymbolInfo> {\n return {\n symbol: sym,\n name: sym,\n description: `Mock symbol ${sym}`,\n timezone: \"UTC\",\n session: \"24x7\",\n pricescale: 100,\n };\n },\n\n async getBars(request: HistoryRequest): Promise<Bar[]> {\n const key = `${request.symbol}:${request.from}:${request.to}`;\n if (!cache.has(key)) {\n cache.set(\n key,\n generateBars(request.from, request.to, barMs, basePrice, rand),\n );\n }\n return cache.get(key)!;\n },\n\n subscribeBars(request: SubscribeBarsRequest): () => void {\n let last = basePrice + rand() * 5;\n const timer = setInterval(() => {\n const open = last;\n const close = Math.max(1, open + (rand() - 0.5) * 2);\n const high = Math.max(open, close) + rand();\n const low = Math.min(open, close) - rand();\n request.onBar({\n time: Date.now(),\n open,\n high,\n low,\n close,\n volume: 1000 + rand() * 3000,\n });\n last = close;\n }, barMs);\n return () => clearInterval(timer);\n },\n };\n}\n"],"names":["findNearestBarIndex","barX","x","bestIdx","bestDist","d","snapToCandle","input","idx","candidates","clickPy","threshold","bestY","bestPyDist","cy","py","dist","computeMeasurement","a","b","change","denom","percent","bars","formatMeasurement","m","sign","formatPrice","value","abs","decimals","FIB_LEVELS","DRAG_THRESHOLD_PX","DEFAULT_MEASURE_UP","DEFAULT_MEASURE_DOWN","withAlpha","color","alpha","manifest","isDrawingMode","mode","findCandlestickSeries","ctx","s","PluginDrawingTools","config","autoDeselect","state","stroke","measureUp","measureDown","snapshot","_a","_b","pushUndo","resetInteractionState","setModeInternal","finishStroke","resolvePoint","y","series","dy","pointFromEvent","pluginCtx","event","commitHorizontal","commitVertical","commitMeasure","p0","p1","midX","commitTwoPoint","yMin","yMax","level","fy","drawPreview","c2d","plotArea","coords","cursor","anchor","toPx","px","w","h","drawMeasurePreview","headLen","dir","label","boxW","boxH","boxX","boxY","handleMouseDown","point","handleMouseMove","dx","handleMouseUp","start","enabled","prev","current","next","PluginReplay","buffer","index","timer","speed","frameMs","applyWindow","end","n","slice","arr","api","count","i","barsToOhlc","open","high","low","close","volume","pseudoRandom","seed","generateBars","from","to","barMs","base","rand","price","t","delta","createMockDatafeed","options","basePrice","cache","sym","request","key","last"],"mappings":"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"}
|