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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-menu.js","sources":["../../src/plugins/context-menu/renderer.ts","../../src/plugins/context-menu/index.ts"],"sourcesContent":["/**\n * Context Menu Renderer\n * \n * Handles DOM creation and rendering of the context menu.\n * \n * @module plugins/context-menu/renderer\n */\n\nimport type { \n MenuItem, \n MenuStyle, \n MenuPosition,\n MenuContext,\n MenuState \n} from \"./types\";\n\n// ============================================\n// Default Styles\n// ============================================\n\nconst DEFAULT_STYLE: Required<MenuStyle> = {\n backgroundColor: 'rgba(30, 30, 40, 0.95)',\n textColor: '#e0e0e0',\n borderColor: 'rgba(100, 100, 120, 0.5)',\n borderRadius: '8px',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1)',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '13px',\n itemPadding: '8px 16px',\n hoverBackground: 'rgba(0, 242, 255, 0.15)',\n separatorColor: 'rgba(100, 100, 120, 0.3)',\n disabledOpacity: 0.4,\n minWidth: '180px',\n maxWidth: '300px',\n animationDuration: '150ms'\n};\n\n// ============================================\n// Menu Renderer Class\n// ============================================\n\nexport class MenuRenderer {\n private _container: HTMLElement;\n private menuElement: HTMLDivElement | null = null;\n private style: Required<MenuStyle>;\n private onItemClick: (item: MenuItem, context: MenuContext) => void;\n private zIndex: number;\n\n constructor(\n container: HTMLElement,\n style: MenuStyle | undefined,\n zIndex: number,\n onItemClick: (item: MenuItem, context: MenuContext) => void\n ) {\n this._container = container;\n this.style = { ...DEFAULT_STYLE, ...style };\n this.zIndex = zIndex;\n this.onItemClick = onItemClick;\n }\n\n /**\n * Show the context menu\n */\n show(state: MenuState): void {\n this.hide();\n\n if (!state.items.length || !state.context) return;\n\n this.menuElement = this.createMenu(state.items, state.context);\n this.positionMenu(state.position);\n document.body.appendChild(this.menuElement);\n\n // Animate in\n requestAnimationFrame(() => {\n if (this.menuElement) {\n this.menuElement.style.opacity = '1';\n this.menuElement.style.transform = 'scale(1)';\n }\n });\n\n // Add click-outside listener\n document.addEventListener('mousedown', this.handleOutsideClick);\n document.addEventListener('keydown', this.handleKeyDown);\n }\n\n /**\n * Hide the context menu\n */\n hide(): void {\n if (this.menuElement) {\n this.menuElement.style.opacity = '0';\n this.menuElement.style.transform = 'scale(0.95)';\n \n setTimeout(() => {\n if (this.menuElement?.parentNode) {\n this.menuElement.parentNode.removeChild(this.menuElement);\n }\n this.menuElement = null;\n }, 100);\n }\n\n document.removeEventListener('mousedown', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /**\n * Check if menu is visible\n */\n isVisible(): boolean {\n return this.menuElement !== null;\n }\n\n /**\n * Destroy the renderer\n */\n destroy(): void {\n this.hide();\n }\n\n /**\n * Update styling\n */\n updateStyle(style: MenuStyle): void {\n this.style = { ...DEFAULT_STYLE, ...style };\n }\n\n /**\n * Get container reference\n */\n getContainer(): HTMLElement {\n return this._container;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createMenu(items: MenuItem[], context: MenuContext): HTMLDivElement {\n const menu = document.createElement('div');\n menu.className = 'velo-plot-context-menu';\n menu.style.cssText = this.getMenuStyle();\n\n items.forEach(item => {\n const element = this.createMenuItem(item, context);\n if (element) {\n menu.appendChild(element);\n }\n });\n\n return menu;\n }\n\n private createMenuItem(item: MenuItem, context: MenuContext): HTMLElement | null {\n // Hidden items\n if ('hidden' in item && item.hidden) return null;\n\n // Separator\n if (item.type === 'separator') {\n const sep = document.createElement('div');\n sep.className = 'velo-plot-menu-separator';\n sep.style.cssText = `\n height: 1px;\n margin: 4px 8px;\n background: ${this.style.separatorColor};\n `;\n return sep;\n }\n\n // Regular item\n const el = document.createElement('div');\n el.className = 'velo-plot-menu-item';\n \n const isDisabled = 'disabled' in item && Boolean(item.disabled);\n el.style.cssText = this.getItemStyle(isDisabled);\n\n // Icon\n if ('icon' in item && item.icon) {\n const icon = document.createElement('span');\n icon.className = 'velo-plot-menu-icon';\n icon.style.cssText = 'margin-right: 12px; width: 16px; text-align: center;';\n icon.textContent = item.icon;\n el.appendChild(icon);\n }\n\n // Label\n const label = document.createElement('span');\n label.className = 'velo-plot-menu-label';\n label.style.cssText = 'flex: 1;';\n label.textContent = item.label;\n el.appendChild(label);\n\n // Checkbox/Radio indicator\n if (item.type === 'checkbox') {\n const check = document.createElement('span');\n check.style.cssText = 'margin-left: 12px; width: 16px;';\n check.textContent = item.checked ? '✓' : '';\n el.appendChild(check);\n }\n\n if (item.type === 'radio') {\n const radio = document.createElement('span');\n radio.style.cssText = 'margin-left: 12px; width: 16px;';\n radio.textContent = item.selected ? '●' : '○';\n el.appendChild(radio);\n }\n\n // Shortcut\n if ('shortcut' in item && item.shortcut) {\n const shortcut = document.createElement('span');\n shortcut.className = 'velo-plot-menu-shortcut';\n shortcut.style.cssText = `\n margin-left: 24px;\n opacity: 0.5;\n font-size: 11px;\n `;\n shortcut.textContent = item.shortcut;\n el.appendChild(shortcut);\n }\n\n // Submenu arrow\n if (item.type === 'submenu') {\n const arrow = document.createElement('span');\n arrow.style.cssText = 'margin-left: 8px;';\n arrow.textContent = '▶';\n el.appendChild(arrow);\n\n // Create submenu on hover\n el.addEventListener('mouseenter', () => {\n this.showSubmenu(el, item.items, context);\n });\n el.addEventListener('mouseleave', (e: MouseEvent) => {\n this.hideSubmenu(el, e);\n });\n }\n\n // Hover effects\n if (!isDisabled) {\n el.addEventListener('mouseenter', () => {\n el.style.background = this.style.hoverBackground;\n });\n el.addEventListener('mouseleave', () => {\n el.style.background = 'transparent';\n });\n\n // Click handler\n el.addEventListener('click', (e) => {\n e.stopPropagation();\n if (item.type !== 'submenu') {\n this.onItemClick(item, context);\n }\n });\n }\n\n return el;\n }\n\n private showSubmenu(parent: HTMLElement, items: MenuItem[], context: MenuContext): void {\n // Remove any existing submenu\n const existing = parent.querySelector('.velo-plot-submenu');\n if (existing) return;\n\n const submenu = document.createElement('div');\n submenu.className = 'velo-plot-submenu';\n submenu.style.cssText = `\n ${this.getMenuStyle()}\n position: absolute;\n left: 100%;\n top: 0;\n margin-left: 4px;\n `;\n\n items.forEach(item => {\n const el = this.createMenuItem(item, context);\n if (el) submenu.appendChild(el);\n });\n\n parent.style.position = 'relative';\n parent.appendChild(submenu);\n }\n\n private hideSubmenu(parent: HTMLElement, e: MouseEvent): void {\n const submenu = parent.querySelector('.velo-plot-submenu');\n if (!submenu) return;\n\n // Check if moving to submenu\n const rect = submenu.getBoundingClientRect();\n if (\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom\n ) {\n return;\n }\n\n setTimeout(() => {\n submenu.remove();\n }, 100);\n }\n\n private positionMenu(position: MenuPosition): void {\n if (!this.menuElement) return;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n // Initial position\n this.menuElement.style.left = `${position.x}px`;\n this.menuElement.style.top = `${position.y}px`;\n\n // Get actual dimensions\n const rect = this.menuElement.getBoundingClientRect();\n\n // Adjust if off-screen\n if (rect.right > viewportWidth) {\n this.menuElement.style.left = `${position.x - rect.width}px`;\n }\n if (rect.bottom > viewportHeight) {\n this.menuElement.style.top = `${position.y - rect.height}px`;\n }\n }\n\n private getMenuStyle(): string {\n return `\n position: fixed;\n z-index: ${this.zIndex};\n background: ${this.style.backgroundColor};\n color: ${this.style.textColor};\n border: 1px solid ${this.style.borderColor};\n border-radius: ${this.style.borderRadius};\n box-shadow: ${this.style.boxShadow};\n font-family: ${this.style.fontFamily};\n font-size: ${this.style.fontSize};\n min-width: ${this.style.minWidth};\n max-width: ${this.style.maxWidth};\n padding: 4px 0;\n opacity: 0;\n transform: scale(0.95);\n transform-origin: top left;\n transition: opacity ${this.style.animationDuration}, transform ${this.style.animationDuration};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n `;\n }\n\n private getItemStyle(disabled: boolean): string {\n return `\n display: flex;\n align-items: center;\n padding: ${this.style.itemPadding};\n cursor: ${disabled ? 'default' : 'pointer'};\n opacity: ${disabled ? this.style.disabledOpacity : 1};\n user-select: none;\n transition: background 100ms;\n `;\n }\n\n private handleOutsideClick = (e: MouseEvent): void => {\n if (this.menuElement && !this.menuElement.contains(e.target as Node)) {\n this.hide();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.hide();\n }\n };\n}\n","/**\n * Sci Plot - Context Menu Plugin\n * \n * Provides a customizable right-click context menu for chart interactions.\n * \n * @module plugins/context-menu\n * \n * @example\n * ```typescript\n * import { createChart } from 'velo-plot';\n * import { PluginContextMenu } from 'velo-plot/plugins/context-menu';\n * \n * const chart = createChart({ container });\n * chart.use(PluginContextMenu({\n * items: [\n * { label: 'Zoom to Fit', icon: '🔍', action: 'zoomToFit' },\n * { type: 'separator' },\n * { label: 'Export...', icon: '💾', type: 'submenu', items: [\n * { label: 'CSV', action: 'exportCSV' },\n * { label: 'JSON', action: 'exportJSON' },\n * ]},\n * ]\n * }));\n * ```\n */\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\nimport type {\n PluginContextMenuConfig,\n MenuItem,\n MenuContext,\n MenuState,\n BuiltinAction,\n MenuActionItem\n} from \"./types\";\nimport { MenuRenderer } from \"./renderer\";\n\n// Re-export types\nexport * from \"./types\";\n\n// ============================================\n// Default Menu Items\n// ============================================\n\nconst DEFAULT_PLOT_ITEMS: MenuItem[] = [\n { \n label: 'Zoom to Fit', \n icon: '⊡', \n action: 'zoomToFit',\n shortcut: 'Home'\n },\n { \n label: 'Reset View', \n icon: '↻', \n action: 'resetView',\n shortcut: 'R'\n },\n { type: 'separator' },\n {\n label: 'Interaction Mode',\n icon: '✋',\n type: 'submenu',\n items: [\n { label: 'Pan', icon: '✋', action: 'panMode' },\n { label: 'Box Zoom', icon: '⬚', action: 'boxZoomMode' },\n { label: 'Select', icon: '➤', action: 'selectMode' },\n ]\n },\n { type: 'separator' },\n {\n label: 'Export',\n icon: '💾',\n type: 'submenu',\n items: [\n { label: 'CSV', icon: '📄', action: 'exportCSV' },\n { label: 'JSON', icon: '📋', action: 'exportJSON' },\n { label: 'Image', icon: '🖼️', action: 'exportImage' },\n ]\n },\n { \n label: 'Copy to Clipboard', \n icon: '📋', \n action: 'copyToClipboard',\n shortcut: 'Ctrl+C'\n },\n { type: 'separator' },\n {\n label: 'Annotations',\n icon: '📝',\n type: 'submenu',\n items: [\n { label: 'Add Horizontal Line', icon: '—', action: 'addHorizontalLine' },\n { label: 'Add Vertical Line', icon: '|', action: 'addVerticalLine' },\n { label: 'Add Text', icon: 'T', action: 'addTextAnnotation' },\n { type: 'separator' },\n { label: 'Clear All', icon: '🗑️', action: 'clearAnnotations' },\n ]\n },\n { type: 'separator' },\n { \n label: 'Toggle Legend', \n icon: '☰', \n action: 'toggleLegend',\n shortcut: 'L'\n },\n { \n label: 'Toggle Grid', \n icon: '#', \n action: 'toggleGrid',\n shortcut: 'G'\n },\n { \n label: 'Show Statistics', \n icon: '📊', \n action: 'showStats',\n shortcut: 'S'\n },\n];\n\n// ============================================\n// Plugin Definition\n// ============================================\n\nconst manifestContextMenu: PluginManifest = {\n name: \"velo-plot-context-menu\",\n version: \"1.0.0\",\n description: \"Customizable right-click context menu for velo-plot\",\n author: \"Sci Plot Team\",\n provides: [\"interaction\"],\n tags: [\"context-menu\", \"right-click\", \"menu\", \"ui\"],\n};\n\n/**\n * Sci Plot Context Menu Plugin\n * \n * Adds a customizable context menu with built-in actions and \n * extensibility for custom menu items.\n */\nexport function PluginContextMenu(\n config: PluginContextMenuConfig = {}\n): ChartPlugin<PluginContextMenuConfig> {\n \n const {\n enabled = true,\n items = [],\n templates = [],\n useDefaults = true,\n style,\n preventDefault = true,\n showOnRightClick = true,\n showOnLongPress = true,\n longPressDuration = 500,\n beforeShow,\n afterHide,\n zIndex = 10000\n } = config;\n\n let _ctx: PluginContext | null = null;\n let renderer: MenuRenderer | null = null;\n let state: MenuState = {\n visible: false,\n position: { x: 0, y: 0 },\n items: [],\n submenuPath: [],\n context: null\n };\n\n // Long press handling\n let longPressTimer: ReturnType<typeof setTimeout> | null = null;\n let longPressStart: { x: number; y: number } | null = null;\n\n // ============================================\n // Action Handlers\n // ============================================\n\n function executeAction(action: BuiltinAction, context: MenuContext): void {\n if (!_ctx) return;\n\n const chart = _ctx.chart as any;\n\n switch (action) {\n case 'zoomToFit':\n chart.zoomToFit?.();\n break;\n \n case 'zoomIn':\n chart.zoom?.(1.5);\n break;\n \n case 'zoomOut':\n chart.zoom?.(0.67);\n break;\n \n case 'resetView':\n chart.resetView?.();\n break;\n \n case 'panMode':\n chart.setMode?.('pan');\n break;\n \n case 'boxZoomMode':\n chart.setMode?.('boxZoom');\n break;\n \n case 'selectMode':\n chart.setMode?.('select');\n break;\n \n case 'exportCSV':\n executeExport('csv');\n break;\n \n case 'exportJSON':\n executeExport('json');\n break;\n \n case 'exportImage':\n downloadImage();\n break;\n \n case 'copyToClipboard':\n copyToClipboard();\n break;\n \n case 'toggleLegend':\n chart.setShowLegend?.(!chart.getShowLegend?.());\n break;\n \n case 'toggleGrid':\n chart.setShowGrid?.(!chart.getShowGrid?.());\n break;\n \n case 'toggleCrosshair':\n // Toggle crosshair if available\n break;\n \n case 'addHorizontalLine':\n addAnnotation('hline', context);\n break;\n \n case 'addVerticalLine':\n addAnnotation('vline', context);\n break;\n \n case 'addTextAnnotation':\n addAnnotation('text', context);\n break;\n \n case 'clearAnnotations':\n chart.clearAnnotations?.();\n break;\n \n case 'showStats':\n // Show stats panel\n break;\n }\n }\n\n function executeExport(format: 'csv' | 'json'): void {\n const chart = _ctx?.chart as any;\n const exportPlugin = chart?.plugins?.get('velo-plot-data-export')?.api;\n \n if (exportPlugin) {\n exportPlugin.download(format);\n } else {\n // Fallback to basic export\n const data = chart.toCSV?.() || chart.toJSON?.();\n if (data) {\n downloadString(data, `chart.${format}`, `text/${format}`);\n }\n }\n }\n\n function downloadImage(): void {\n const chart = _ctx?.chart as any;\n const dataUrl = chart.toImage?.('png');\n if (dataUrl) {\n const link = document.createElement('a');\n link.href = dataUrl;\n link.download = 'chart.png';\n link.click();\n }\n }\n\n function copyToClipboard(): void {\n const chart = _ctx?.chart as any;\n const data = chart.toCSV?.();\n if (data) {\n navigator.clipboard.writeText(data).catch(console.error);\n }\n }\n\n function addAnnotation(type: 'hline' | 'vline' | 'text', context: MenuContext): void {\n if (!context.dataPosition) return;\n \n const chart = _ctx?.chart as any;\n const { x, y } = context.dataPosition;\n\n switch (type) {\n case 'hline':\n chart.addAnnotation?.({\n type: 'horizontalLine',\n y,\n color: '#ff6b6b',\n label: `Y = ${y.toFixed(4)}`\n });\n break;\n \n case 'vline':\n chart.addAnnotation?.({\n type: 'verticalLine',\n x,\n color: '#4ecdc4',\n label: `X = ${x.toFixed(4)}`\n });\n break;\n \n case 'text':\n chart.addAnnotation?.({\n type: 'text',\n x,\n y,\n text: 'Annotation',\n color: '#ffffff'\n });\n break;\n }\n }\n\n function downloadString(content: string, filename: string, type: string): void {\n const blob = new Blob([content], { type });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n link.click();\n URL.revokeObjectURL(url);\n }\n\n // ============================================\n // Menu Logic\n // ============================================\n\n function buildMenuContext(event: MouseEvent): MenuContext {\n const chart = _ctx?.chart as any;\n const container = _ctx?.ui.container;\n \n if (!container) {\n return {\n chart,\n event,\n pixelPosition: { x: event.clientX, y: event.clientY },\n dataPosition: null,\n seriesId: null,\n annotationId: null,\n pointIndex: null,\n area: 'outside'\n };\n }\n\n const rect = container.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Determine area\n const plotArea = _ctx?.render.plotArea;\n let area: MenuContext['area'] = 'outside';\n \n if (plotArea) {\n if (x >= plotArea.x && x <= plotArea.x + plotArea.width &&\n y >= plotArea.y && y <= plotArea.y + plotArea.height) {\n area = 'plot';\n } else if (y > plotArea.y + plotArea.height) {\n area = 'xAxis';\n } else if (x < plotArea.x) {\n area = 'yAxis';\n }\n }\n\n // Convert to data coordinates\n let dataPosition: { x: number; y: number } | null = null;\n if (area === 'plot' && _ctx) {\n dataPosition = {\n x: _ctx.coords.pixelToDataX(x),\n y: _ctx.coords.pixelToDataY(y)\n };\n }\n\n // Try to detect series/point\n let seriesId: string | null = null;\n let pointIndex: number | null = null;\n \n if (dataPosition && _ctx) {\n const pick = _ctx.coords.pickPoint(x, y, 10);\n if (pick) {\n seriesId = pick.seriesId;\n pointIndex = pick.index;\n }\n }\n\n return {\n chart,\n event,\n pixelPosition: { x, y },\n dataPosition,\n seriesId,\n annotationId: null,\n pointIndex,\n area\n };\n }\n\n function getMenuItems(context: MenuContext): MenuItem[] {\n // Try templates first\n for (const template of templates) {\n if (template.condition?.(context)) {\n return [...template.items];\n }\n }\n\n // Build items based on context\n let menuItems: MenuItem[] = [];\n\n if (useDefaults) {\n menuItems = [...DEFAULT_PLOT_ITEMS];\n }\n\n // Add custom items\n if (items.length > 0) {\n if (menuItems.length > 0) {\n menuItems.push({ type: 'separator' });\n }\n menuItems.push(...items);\n }\n\n // Apply beforeShow hook\n if (beforeShow) {\n const result = beforeShow(context);\n if (result === false) {\n return [];\n }\n menuItems = result;\n }\n\n return menuItems;\n }\n\n function showMenu(event: MouseEvent): void {\n if (!enabled || !_ctx) return;\n\n const context = buildMenuContext(event);\n const menuItems = getMenuItems(context);\n\n if (menuItems.length === 0) return;\n\n state = {\n visible: true,\n position: { x: event.clientX, y: event.clientY },\n items: menuItems,\n submenuPath: [],\n context\n };\n\n renderer?.show(state);\n }\n\n function hideMenu(): void {\n state = {\n ...state,\n visible: false,\n context: null\n };\n\n renderer?.hide();\n afterHide?.();\n }\n\n function handleItemClick(item: MenuItem, context: MenuContext): void {\n hideMenu();\n\n if (item.type === 'separator' || item.type === 'submenu') {\n return;\n }\n\n if (item.type === 'checkbox' && item.onChange) {\n item.onChange(!item.checked, context);\n return;\n }\n\n if (item.type === 'radio' && item.onChange) {\n item.onChange(item.value, context);\n return;\n }\n\n // Action item\n const actionItem = item as MenuActionItem;\n \n if (actionItem.onClick) {\n actionItem.onClick(context);\n } else if (actionItem.action) {\n executeAction(actionItem.action, context);\n }\n }\n\n // ============================================\n // Event Handlers\n // ============================================\n\n function handleContextMenu(e: MouseEvent): void {\n if (!showOnRightClick) return;\n \n if (preventDefault) {\n e.preventDefault();\n }\n\n showMenu(e);\n }\n\n function handleTouchStart(e: TouchEvent): void {\n if (!showOnLongPress) return;\n\n const touch = e.touches[0];\n longPressStart = { x: touch.clientX, y: touch.clientY };\n\n longPressTimer = setTimeout(() => {\n if (longPressStart) {\n const syntheticEvent = new MouseEvent('contextmenu', {\n clientX: longPressStart.x,\n clientY: longPressStart.y\n });\n showMenu(syntheticEvent);\n }\n }, longPressDuration);\n }\n\n function handleTouchMove(e: TouchEvent): void {\n if (!longPressStart || !longPressTimer) return;\n\n const touch = e.touches[0];\n const dx = touch.clientX - longPressStart.x;\n const dy = touch.clientY - longPressStart.y;\n\n // Cancel if moved too far\n if (Math.sqrt(dx * dx + dy * dy) > 10) {\n clearTimeout(longPressTimer);\n longPressTimer = null;\n longPressStart = null;\n }\n }\n\n function handleTouchEnd(): void {\n if (longPressTimer) {\n clearTimeout(longPressTimer);\n longPressTimer = null;\n }\n longPressStart = null;\n }\n\n // ============================================\n // Plugin Implementation\n // ============================================\n\n return {\n manifest: manifestContextMenu,\n\n onInit(ctx: PluginContext) {\n _ctx = ctx;\n\n const container = ctx.ui.container;\n\n renderer = new MenuRenderer(\n container,\n style,\n zIndex,\n handleItemClick\n );\n\n // Attach event listeners\n container.addEventListener('contextmenu', handleContextMenu);\n container.addEventListener('touchstart', handleTouchStart, { passive: true });\n container.addEventListener('touchmove', handleTouchMove, { passive: true });\n container.addEventListener('touchend', handleTouchEnd);\n\n ctx.log.info('ContextMenu plugin initialized');\n },\n\n onDestroy() {\n const container = _ctx?.ui.container;\n\n if (container) {\n container.removeEventListener('contextmenu', handleContextMenu);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n }\n\n renderer?.destroy();\n renderer = null;\n _ctx = null;\n },\n\n api: {\n /**\n * Show the context menu programmatically\n */\n show(x: number, y: number, customItems?: MenuItem[]) {\n const event = new MouseEvent('contextmenu', { clientX: x, clientY: y });\n const context = buildMenuContext(event);\n \n state = {\n visible: true,\n position: { x, y },\n items: customItems || getMenuItems(context),\n submenuPath: [],\n context\n };\n\n renderer?.show(state);\n },\n\n /**\n * Hide the context menu\n */\n hide() {\n hideMenu();\n },\n\n /**\n * Check if menu is visible\n */\n isVisible(): boolean {\n return renderer?.isVisible() ?? false;\n },\n\n /**\n * Update menu items dynamically\n */\n setItems(newItems: MenuItem[]) {\n // Update for next show\n (config as any).items = newItems;\n },\n\n /**\n * Enable/disable the menu\n */\n setEnabled(value: boolean) {\n (config as any).enabled = value;\n },\n\n /**\n * Update styling\n */\n setStyle(newStyle: typeof style) {\n renderer?.updateStyle(newStyle || {});\n },\n\n /**\n * Get available built-in actions\n */\n getBuiltinActions(): BuiltinAction[] {\n return [\n 'zoomToFit', 'zoomIn', 'zoomOut', 'resetView',\n 'panMode', 'boxZoomMode', 'selectMode',\n 'exportCSV', 'exportJSON', 'exportImage', 'copyToClipboard',\n 'toggleLegend', 'toggleGrid', 'toggleCrosshair',\n 'addHorizontalLine', 'addVerticalLine', 'addTextAnnotation', 'clearAnnotations',\n 'showStats'\n ];\n }\n }\n };\n}\n\nexport default PluginContextMenu;\n"],"names":["DEFAULT_STYLE","MenuRenderer","container","style","zIndex","onItemClick","__publicField","e","state","_a","items","context","menu","item","element","sep","el","isDisabled","icon","label","check","radio","shortcut","arrow","parent","submenu","rect","position","viewportWidth","viewportHeight","disabled","DEFAULT_PLOT_ITEMS","manifestContextMenu","PluginContextMenu","config","enabled","templates","useDefaults","preventDefault","showOnRightClick","showOnLongPress","longPressDuration","beforeShow","afterHide","_ctx","renderer","longPressTimer","longPressStart","executeAction","action","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","chart","executeExport","downloadImage","copyToClipboard","addAnnotation","format","exportPlugin","data","downloadString","dataUrl","link","type","x","y","content","filename","blob","url","buildMenuContext","event","plotArea","area","dataPosition","seriesId","pointIndex","pick","getMenuItems","template","menuItems","result","showMenu","hideMenu","handleItemClick","actionItem","handleContextMenu","handleTouchStart","touch","syntheticEvent","handleTouchMove","dx","dy","handleTouchEnd","ctx","customItems","newItems","value","newStyle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"context-menu.js","sources":["../../src/plugins/context-menu/renderer.ts","../../src/plugins/context-menu/index.ts"],"sourcesContent":["/**\n * Context Menu Renderer\n * \n * Handles DOM creation and rendering of the context menu.\n * \n * @module plugins/context-menu/renderer\n */\n\nimport type { \n MenuItem, \n MenuStyle, \n MenuPosition,\n MenuContext,\n MenuState \n} from \"./types\";\n\n// ============================================\n// Default Styles\n// ============================================\n\nconst DEFAULT_STYLE: Required<MenuStyle> = {\n backgroundColor: 'rgba(30, 30, 40, 0.95)',\n textColor: '#e0e0e0',\n borderColor: 'rgba(100, 100, 120, 0.5)',\n borderRadius: '8px',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1)',\n fontFamily: 'system-ui, -apple-system, sans-serif',\n fontSize: '13px',\n itemPadding: '8px 16px',\n hoverBackground: 'rgba(0, 242, 255, 0.15)',\n separatorColor: 'rgba(100, 100, 120, 0.3)',\n disabledOpacity: 0.4,\n minWidth: '180px',\n maxWidth: '300px',\n animationDuration: '150ms'\n};\n\n// ============================================\n// Menu Renderer Class\n// ============================================\n\nexport class MenuRenderer {\n private _container: HTMLElement;\n private menuElement: HTMLDivElement | null = null;\n private style: Required<MenuStyle>;\n private onItemClick: (item: MenuItem, context: MenuContext) => void;\n private zIndex: number;\n\n constructor(\n container: HTMLElement,\n style: MenuStyle | undefined,\n zIndex: number,\n onItemClick: (item: MenuItem, context: MenuContext) => void\n ) {\n this._container = container;\n this.style = { ...DEFAULT_STYLE, ...style };\n this.zIndex = zIndex;\n this.onItemClick = onItemClick;\n }\n\n /**\n * Show the context menu\n */\n show(state: MenuState): void {\n this.hide();\n\n if (!state.items.length || !state.context) return;\n\n this.menuElement = this.createMenu(state.items, state.context);\n this.positionMenu(state.position);\n document.body.appendChild(this.menuElement);\n\n // Animate in\n requestAnimationFrame(() => {\n if (this.menuElement) {\n this.menuElement.style.opacity = '1';\n this.menuElement.style.transform = 'scale(1)';\n }\n });\n\n // Add click-outside listener\n document.addEventListener('mousedown', this.handleOutsideClick);\n document.addEventListener('keydown', this.handleKeyDown);\n }\n\n /**\n * Hide the context menu\n */\n hide(): void {\n if (this.menuElement) {\n this.menuElement.style.opacity = '0';\n this.menuElement.style.transform = 'scale(0.95)';\n \n setTimeout(() => {\n if (this.menuElement?.parentNode) {\n this.menuElement.parentNode.removeChild(this.menuElement);\n }\n this.menuElement = null;\n }, 100);\n }\n\n document.removeEventListener('mousedown', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleKeyDown);\n }\n\n /**\n * Check if menu is visible\n */\n isVisible(): boolean {\n return this.menuElement !== null;\n }\n\n /**\n * Destroy the renderer\n */\n destroy(): void {\n this.hide();\n }\n\n /**\n * Update styling\n */\n updateStyle(style: MenuStyle): void {\n this.style = { ...DEFAULT_STYLE, ...style };\n }\n\n /**\n * Get container reference\n */\n getContainer(): HTMLElement {\n return this._container;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private createMenu(items: MenuItem[], context: MenuContext): HTMLDivElement {\n const menu = document.createElement('div');\n menu.className = 'velo-plot-context-menu';\n menu.style.cssText = this.getMenuStyle();\n\n items.forEach(item => {\n const element = this.createMenuItem(item, context);\n if (element) {\n menu.appendChild(element);\n }\n });\n\n return menu;\n }\n\n private createMenuItem(item: MenuItem, context: MenuContext): HTMLElement | null {\n // Hidden items\n if ('hidden' in item && item.hidden) return null;\n\n // Separator\n if (item.type === 'separator') {\n const sep = document.createElement('div');\n sep.className = 'velo-plot-menu-separator';\n sep.style.cssText = `\n height: 1px;\n margin: 4px 8px;\n background: ${this.style.separatorColor};\n `;\n return sep;\n }\n\n // Regular item\n const el = document.createElement('div');\n el.className = 'velo-plot-menu-item';\n \n const isDisabled = 'disabled' in item && Boolean(item.disabled);\n el.style.cssText = this.getItemStyle(isDisabled);\n\n // Icon\n if ('icon' in item && item.icon) {\n const icon = document.createElement('span');\n icon.className = 'velo-plot-menu-icon';\n icon.style.cssText = 'margin-right: 12px; width: 16px; text-align: center;';\n icon.textContent = item.icon;\n el.appendChild(icon);\n }\n\n // Label\n const label = document.createElement('span');\n label.className = 'velo-plot-menu-label';\n label.style.cssText = 'flex: 1;';\n label.textContent = item.label;\n el.appendChild(label);\n\n // Checkbox/Radio indicator\n if (item.type === 'checkbox') {\n const check = document.createElement('span');\n check.style.cssText = 'margin-left: 12px; width: 16px;';\n check.textContent = item.checked ? '✓' : '';\n el.appendChild(check);\n }\n\n if (item.type === 'radio') {\n const radio = document.createElement('span');\n radio.style.cssText = 'margin-left: 12px; width: 16px;';\n radio.textContent = item.selected ? '●' : '○';\n el.appendChild(radio);\n }\n\n // Shortcut\n if ('shortcut' in item && item.shortcut) {\n const shortcut = document.createElement('span');\n shortcut.className = 'velo-plot-menu-shortcut';\n shortcut.style.cssText = `\n margin-left: 24px;\n opacity: 0.5;\n font-size: 11px;\n `;\n shortcut.textContent = item.shortcut;\n el.appendChild(shortcut);\n }\n\n // Submenu arrow\n if (item.type === 'submenu') {\n const arrow = document.createElement('span');\n arrow.style.cssText = 'margin-left: 8px;';\n arrow.textContent = '▶';\n el.appendChild(arrow);\n\n // Create submenu on hover\n el.addEventListener('mouseenter', () => {\n this.showSubmenu(el, item.items, context);\n });\n el.addEventListener('mouseleave', (e: MouseEvent) => {\n this.hideSubmenu(el, e);\n });\n }\n\n // Hover effects\n if (!isDisabled) {\n el.addEventListener('mouseenter', () => {\n el.style.background = this.style.hoverBackground;\n });\n el.addEventListener('mouseleave', () => {\n el.style.background = 'transparent';\n });\n\n // Click handler\n el.addEventListener('click', (e) => {\n e.stopPropagation();\n if (item.type !== 'submenu') {\n this.onItemClick(item, context);\n }\n });\n }\n\n return el;\n }\n\n private showSubmenu(parent: HTMLElement, items: MenuItem[], context: MenuContext): void {\n // Remove any existing submenu\n const existing = parent.querySelector('.velo-plot-submenu');\n if (existing) return;\n\n const submenu = document.createElement('div');\n submenu.className = 'velo-plot-submenu';\n submenu.style.cssText = `\n ${this.getMenuStyle()}\n position: absolute;\n left: 100%;\n top: 0;\n margin-left: 4px;\n `;\n\n items.forEach(item => {\n const el = this.createMenuItem(item, context);\n if (el) submenu.appendChild(el);\n });\n\n parent.style.position = 'relative';\n parent.appendChild(submenu);\n }\n\n private hideSubmenu(parent: HTMLElement, e: MouseEvent): void {\n const submenu = parent.querySelector('.velo-plot-submenu');\n if (!submenu) return;\n\n // Check if moving to submenu\n const rect = submenu.getBoundingClientRect();\n if (\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom\n ) {\n return;\n }\n\n setTimeout(() => {\n submenu.remove();\n }, 100);\n }\n\n private positionMenu(position: MenuPosition): void {\n if (!this.menuElement) return;\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n // Initial position\n this.menuElement.style.left = `${position.x}px`;\n this.menuElement.style.top = `${position.y}px`;\n\n // Get actual dimensions\n const rect = this.menuElement.getBoundingClientRect();\n\n // Adjust if off-screen\n if (rect.right > viewportWidth) {\n this.menuElement.style.left = `${position.x - rect.width}px`;\n }\n if (rect.bottom > viewportHeight) {\n this.menuElement.style.top = `${position.y - rect.height}px`;\n }\n }\n\n private getMenuStyle(): string {\n return `\n position: fixed;\n z-index: ${this.zIndex};\n background: ${this.style.backgroundColor};\n color: ${this.style.textColor};\n border: 1px solid ${this.style.borderColor};\n border-radius: ${this.style.borderRadius};\n box-shadow: ${this.style.boxShadow};\n font-family: ${this.style.fontFamily};\n font-size: ${this.style.fontSize};\n min-width: ${this.style.minWidth};\n max-width: ${this.style.maxWidth};\n padding: 4px 0;\n opacity: 0;\n transform: scale(0.95);\n transform-origin: top left;\n transition: opacity ${this.style.animationDuration}, transform ${this.style.animationDuration};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n `;\n }\n\n private getItemStyle(disabled: boolean): string {\n return `\n display: flex;\n align-items: center;\n padding: ${this.style.itemPadding};\n cursor: ${disabled ? 'default' : 'pointer'};\n opacity: ${disabled ? this.style.disabledOpacity : 1};\n user-select: none;\n transition: background 100ms;\n `;\n }\n\n private handleOutsideClick = (e: MouseEvent): void => {\n if (this.menuElement && !this.menuElement.contains(e.target as Node)) {\n this.hide();\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Escape') {\n this.hide();\n }\n };\n}\n","/**\n * Velo Plot - Context Menu Plugin\n * \n * Provides a customizable right-click context menu for chart interactions.\n * \n * @module plugins/context-menu\n * \n * @example\n * ```typescript\n * import { createChart } from 'velo-plot';\n * import { PluginContextMenu } from 'velo-plot/plugins/context-menu';\n * \n * const chart = createChart({ container });\n * chart.use(PluginContextMenu({\n * items: [\n * { label: 'Zoom to Fit', icon: '🔍', action: 'zoomToFit' },\n * { type: 'separator' },\n * { label: 'Export...', icon: '💾', type: 'submenu', items: [\n * { label: 'CSV', action: 'exportCSV' },\n * { label: 'JSON', action: 'exportJSON' },\n * ]},\n * ]\n * }));\n * ```\n */\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\nimport type {\n PluginContextMenuConfig,\n MenuItem,\n MenuContext,\n MenuState,\n BuiltinAction,\n MenuActionItem\n} from \"./types\";\nimport { MenuRenderer } from \"./renderer\";\n\n// Re-export types\nexport * from \"./types\";\n\n// ============================================\n// Default Menu Items\n// ============================================\n\nconst DEFAULT_PLOT_ITEMS: MenuItem[] = [\n { \n label: 'Zoom to Fit', \n icon: '⊡', \n action: 'zoomToFit',\n shortcut: 'Home'\n },\n { \n label: 'Reset View', \n icon: '↻', \n action: 'resetView',\n shortcut: 'R'\n },\n { type: 'separator' },\n {\n label: 'Interaction Mode',\n icon: '✋',\n type: 'submenu',\n items: [\n { label: 'Pan', icon: '✋', action: 'panMode' },\n { label: 'Box Zoom', icon: '⬚', action: 'boxZoomMode' },\n { label: 'Select', icon: '➤', action: 'selectMode' },\n ]\n },\n { type: 'separator' },\n {\n label: 'Export',\n icon: '💾',\n type: 'submenu',\n items: [\n { label: 'CSV', icon: '📄', action: 'exportCSV' },\n { label: 'JSON', icon: '📋', action: 'exportJSON' },\n { label: 'Image', icon: '🖼️', action: 'exportImage' },\n ]\n },\n { \n label: 'Copy to Clipboard', \n icon: '📋', \n action: 'copyToClipboard',\n shortcut: 'Ctrl+C'\n },\n { type: 'separator' },\n {\n label: 'Annotations',\n icon: '📝',\n type: 'submenu',\n items: [\n { label: 'Add Horizontal Line', icon: '—', action: 'addHorizontalLine' },\n { label: 'Add Vertical Line', icon: '|', action: 'addVerticalLine' },\n { label: 'Add Text', icon: 'T', action: 'addTextAnnotation' },\n { type: 'separator' },\n { label: 'Clear All', icon: '🗑️', action: 'clearAnnotations' },\n ]\n },\n { type: 'separator' },\n { \n label: 'Toggle Legend', \n icon: '☰', \n action: 'toggleLegend',\n shortcut: 'L'\n },\n { \n label: 'Toggle Grid', \n icon: '#', \n action: 'toggleGrid',\n shortcut: 'G'\n },\n { \n label: 'Show Statistics', \n icon: '📊', \n action: 'showStats',\n shortcut: 'S'\n },\n];\n\n// ============================================\n// Plugin Definition\n// ============================================\n\nconst manifestContextMenu: PluginManifest = {\n name: \"velo-plot-context-menu\",\n version: \"1.0.0\",\n description: \"Customizable right-click context menu for velo-plot\",\n author: \"Velo Plot Team\",\n provides: [\"interaction\"],\n tags: [\"context-menu\", \"right-click\", \"menu\", \"ui\"],\n};\n\n/**\n * Velo Plot Context Menu Plugin\n * \n * Adds a customizable context menu with built-in actions and \n * extensibility for custom menu items.\n */\nexport function PluginContextMenu(\n config: PluginContextMenuConfig = {}\n): ChartPlugin<PluginContextMenuConfig> {\n \n const {\n enabled = true,\n items = [],\n templates = [],\n useDefaults = true,\n style,\n preventDefault = true,\n showOnRightClick = true,\n showOnLongPress = true,\n longPressDuration = 500,\n beforeShow,\n afterHide,\n zIndex = 10000\n } = config;\n\n let _ctx: PluginContext | null = null;\n let renderer: MenuRenderer | null = null;\n let state: MenuState = {\n visible: false,\n position: { x: 0, y: 0 },\n items: [],\n submenuPath: [],\n context: null\n };\n\n // Long press handling\n let longPressTimer: ReturnType<typeof setTimeout> | null = null;\n let longPressStart: { x: number; y: number } | null = null;\n\n // ============================================\n // Action Handlers\n // ============================================\n\n function executeAction(action: BuiltinAction, context: MenuContext): void {\n if (!_ctx) return;\n\n const chart = _ctx.chart as any;\n\n switch (action) {\n case 'zoomToFit':\n chart.zoomToFit?.();\n break;\n \n case 'zoomIn':\n chart.zoom?.(1.5);\n break;\n \n case 'zoomOut':\n chart.zoom?.(0.67);\n break;\n \n case 'resetView':\n chart.resetView?.();\n break;\n \n case 'panMode':\n chart.setMode?.('pan');\n break;\n \n case 'boxZoomMode':\n chart.setMode?.('boxZoom');\n break;\n \n case 'selectMode':\n chart.setMode?.('select');\n break;\n \n case 'exportCSV':\n executeExport('csv');\n break;\n \n case 'exportJSON':\n executeExport('json');\n break;\n \n case 'exportImage':\n downloadImage();\n break;\n \n case 'copyToClipboard':\n copyToClipboard();\n break;\n \n case 'toggleLegend':\n chart.setShowLegend?.(!chart.getShowLegend?.());\n break;\n \n case 'toggleGrid':\n chart.setShowGrid?.(!chart.getShowGrid?.());\n break;\n \n case 'toggleCrosshair':\n // Toggle crosshair if available\n break;\n \n case 'addHorizontalLine':\n addAnnotation('hline', context);\n break;\n \n case 'addVerticalLine':\n addAnnotation('vline', context);\n break;\n \n case 'addTextAnnotation':\n addAnnotation('text', context);\n break;\n \n case 'clearAnnotations':\n chart.clearAnnotations?.();\n break;\n \n case 'showStats':\n // Show stats panel\n break;\n }\n }\n\n function executeExport(format: 'csv' | 'json'): void {\n const chart = _ctx?.chart as any;\n const exportPlugin = chart?.plugins?.get('velo-plot-data-export')?.api;\n \n if (exportPlugin) {\n exportPlugin.download(format);\n } else {\n // Fallback to basic export\n const data = chart.toCSV?.() || chart.toJSON?.();\n if (data) {\n downloadString(data, `chart.${format}`, `text/${format}`);\n }\n }\n }\n\n function downloadImage(): void {\n const chart = _ctx?.chart as any;\n const dataUrl = chart.toImage?.('png');\n if (dataUrl) {\n const link = document.createElement('a');\n link.href = dataUrl;\n link.download = 'chart.png';\n link.click();\n }\n }\n\n function copyToClipboard(): void {\n const chart = _ctx?.chart as any;\n const data = chart.toCSV?.();\n if (data) {\n navigator.clipboard.writeText(data).catch(console.error);\n }\n }\n\n function addAnnotation(type: 'hline' | 'vline' | 'text', context: MenuContext): void {\n if (!context.dataPosition) return;\n \n const chart = _ctx?.chart as any;\n const { x, y } = context.dataPosition;\n\n switch (type) {\n case 'hline':\n chart.addAnnotation?.({\n type: 'horizontalLine',\n y,\n color: '#ff6b6b',\n label: `Y = ${y.toFixed(4)}`\n });\n break;\n \n case 'vline':\n chart.addAnnotation?.({\n type: 'verticalLine',\n x,\n color: '#4ecdc4',\n label: `X = ${x.toFixed(4)}`\n });\n break;\n \n case 'text':\n chart.addAnnotation?.({\n type: 'text',\n x,\n y,\n text: 'Annotation',\n color: '#ffffff'\n });\n break;\n }\n }\n\n function downloadString(content: string, filename: string, type: string): void {\n const blob = new Blob([content], { type });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n link.click();\n URL.revokeObjectURL(url);\n }\n\n // ============================================\n // Menu Logic\n // ============================================\n\n function buildMenuContext(event: MouseEvent): MenuContext {\n const chart = _ctx?.chart as any;\n const container = _ctx?.ui.container;\n \n if (!container) {\n return {\n chart,\n event,\n pixelPosition: { x: event.clientX, y: event.clientY },\n dataPosition: null,\n seriesId: null,\n annotationId: null,\n pointIndex: null,\n area: 'outside'\n };\n }\n\n const rect = container.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n\n // Determine area\n const plotArea = _ctx?.render.plotArea;\n let area: MenuContext['area'] = 'outside';\n \n if (plotArea) {\n if (x >= plotArea.x && x <= plotArea.x + plotArea.width &&\n y >= plotArea.y && y <= plotArea.y + plotArea.height) {\n area = 'plot';\n } else if (y > plotArea.y + plotArea.height) {\n area = 'xAxis';\n } else if (x < plotArea.x) {\n area = 'yAxis';\n }\n }\n\n // Convert to data coordinates\n let dataPosition: { x: number; y: number } | null = null;\n if (area === 'plot' && _ctx) {\n dataPosition = {\n x: _ctx.coords.pixelToDataX(x),\n y: _ctx.coords.pixelToDataY(y)\n };\n }\n\n // Try to detect series/point\n let seriesId: string | null = null;\n let pointIndex: number | null = null;\n \n if (dataPosition && _ctx) {\n const pick = _ctx.coords.pickPoint(x, y, 10);\n if (pick) {\n seriesId = pick.seriesId;\n pointIndex = pick.index;\n }\n }\n\n return {\n chart,\n event,\n pixelPosition: { x, y },\n dataPosition,\n seriesId,\n annotationId: null,\n pointIndex,\n area\n };\n }\n\n function getMenuItems(context: MenuContext): MenuItem[] {\n // Try templates first\n for (const template of templates) {\n if (template.condition?.(context)) {\n return [...template.items];\n }\n }\n\n // Build items based on context\n let menuItems: MenuItem[] = [];\n\n if (useDefaults) {\n menuItems = [...DEFAULT_PLOT_ITEMS];\n }\n\n // Add custom items\n if (items.length > 0) {\n if (menuItems.length > 0) {\n menuItems.push({ type: 'separator' });\n }\n menuItems.push(...items);\n }\n\n // Apply beforeShow hook\n if (beforeShow) {\n const result = beforeShow(context);\n if (result === false) {\n return [];\n }\n menuItems = result;\n }\n\n return menuItems;\n }\n\n function showMenu(event: MouseEvent): void {\n if (!enabled || !_ctx) return;\n\n const context = buildMenuContext(event);\n const menuItems = getMenuItems(context);\n\n if (menuItems.length === 0) return;\n\n state = {\n visible: true,\n position: { x: event.clientX, y: event.clientY },\n items: menuItems,\n submenuPath: [],\n context\n };\n\n renderer?.show(state);\n }\n\n function hideMenu(): void {\n state = {\n ...state,\n visible: false,\n context: null\n };\n\n renderer?.hide();\n afterHide?.();\n }\n\n function handleItemClick(item: MenuItem, context: MenuContext): void {\n hideMenu();\n\n if (item.type === 'separator' || item.type === 'submenu') {\n return;\n }\n\n if (item.type === 'checkbox' && item.onChange) {\n item.onChange(!item.checked, context);\n return;\n }\n\n if (item.type === 'radio' && item.onChange) {\n item.onChange(item.value, context);\n return;\n }\n\n // Action item\n const actionItem = item as MenuActionItem;\n \n if (actionItem.onClick) {\n actionItem.onClick(context);\n } else if (actionItem.action) {\n executeAction(actionItem.action, context);\n }\n }\n\n // ============================================\n // Event Handlers\n // ============================================\n\n function handleContextMenu(e: MouseEvent): void {\n if (!showOnRightClick) return;\n \n if (preventDefault) {\n e.preventDefault();\n }\n\n showMenu(e);\n }\n\n function handleTouchStart(e: TouchEvent): void {\n if (!showOnLongPress) return;\n\n const touch = e.touches[0];\n longPressStart = { x: touch.clientX, y: touch.clientY };\n\n longPressTimer = setTimeout(() => {\n if (longPressStart) {\n const syntheticEvent = new MouseEvent('contextmenu', {\n clientX: longPressStart.x,\n clientY: longPressStart.y\n });\n showMenu(syntheticEvent);\n }\n }, longPressDuration);\n }\n\n function handleTouchMove(e: TouchEvent): void {\n if (!longPressStart || !longPressTimer) return;\n\n const touch = e.touches[0];\n const dx = touch.clientX - longPressStart.x;\n const dy = touch.clientY - longPressStart.y;\n\n // Cancel if moved too far\n if (Math.sqrt(dx * dx + dy * dy) > 10) {\n clearTimeout(longPressTimer);\n longPressTimer = null;\n longPressStart = null;\n }\n }\n\n function handleTouchEnd(): void {\n if (longPressTimer) {\n clearTimeout(longPressTimer);\n longPressTimer = null;\n }\n longPressStart = null;\n }\n\n // ============================================\n // Plugin Implementation\n // ============================================\n\n return {\n manifest: manifestContextMenu,\n\n onInit(ctx: PluginContext) {\n _ctx = ctx;\n\n const container = ctx.ui.container;\n\n renderer = new MenuRenderer(\n container,\n style,\n zIndex,\n handleItemClick\n );\n\n // Attach event listeners\n container.addEventListener('contextmenu', handleContextMenu);\n container.addEventListener('touchstart', handleTouchStart, { passive: true });\n container.addEventListener('touchmove', handleTouchMove, { passive: true });\n container.addEventListener('touchend', handleTouchEnd);\n\n ctx.log.info('ContextMenu plugin initialized');\n },\n\n onDestroy() {\n const container = _ctx?.ui.container;\n\n if (container) {\n container.removeEventListener('contextmenu', handleContextMenu);\n container.removeEventListener('touchstart', handleTouchStart);\n container.removeEventListener('touchmove', handleTouchMove);\n container.removeEventListener('touchend', handleTouchEnd);\n }\n\n renderer?.destroy();\n renderer = null;\n _ctx = null;\n },\n\n api: {\n /**\n * Show the context menu programmatically\n */\n show(x: number, y: number, customItems?: MenuItem[]) {\n const event = new MouseEvent('contextmenu', { clientX: x, clientY: y });\n const context = buildMenuContext(event);\n \n state = {\n visible: true,\n position: { x, y },\n items: customItems || getMenuItems(context),\n submenuPath: [],\n context\n };\n\n renderer?.show(state);\n },\n\n /**\n * Hide the context menu\n */\n hide() {\n hideMenu();\n },\n\n /**\n * Check if menu is visible\n */\n isVisible(): boolean {\n return renderer?.isVisible() ?? false;\n },\n\n /**\n * Update menu items dynamically\n */\n setItems(newItems: MenuItem[]) {\n // Update for next show\n (config as any).items = newItems;\n },\n\n /**\n * Enable/disable the menu\n */\n setEnabled(value: boolean) {\n (config as any).enabled = value;\n },\n\n /**\n * Update styling\n */\n setStyle(newStyle: typeof style) {\n renderer?.updateStyle(newStyle || {});\n },\n\n /**\n * Get available built-in actions\n */\n getBuiltinActions(): BuiltinAction[] {\n return [\n 'zoomToFit', 'zoomIn', 'zoomOut', 'resetView',\n 'panMode', 'boxZoomMode', 'selectMode',\n 'exportCSV', 'exportJSON', 'exportImage', 'copyToClipboard',\n 'toggleLegend', 'toggleGrid', 'toggleCrosshair',\n 'addHorizontalLine', 'addVerticalLine', 'addTextAnnotation', 'clearAnnotations',\n 'showStats'\n ];\n }\n }\n };\n}\n\nexport default PluginContextMenu;\n"],"names":["DEFAULT_STYLE","MenuRenderer","container","style","zIndex","onItemClick","__publicField","e","state","_a","items","context","menu","item","element","sep","el","isDisabled","icon","label","check","radio","shortcut","arrow","parent","submenu","rect","position","viewportWidth","viewportHeight","disabled","DEFAULT_PLOT_ITEMS","manifestContextMenu","PluginContextMenu","config","enabled","templates","useDefaults","preventDefault","showOnRightClick","showOnLongPress","longPressDuration","beforeShow","afterHide","_ctx","renderer","longPressTimer","longPressStart","executeAction","action","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","chart","executeExport","downloadImage","copyToClipboard","addAnnotation","format","exportPlugin","data","downloadString","dataUrl","link","type","x","y","content","filename","blob","url","buildMenuContext","event","plotArea","area","dataPosition","seriesId","pointIndex","pick","getMenuItems","template","menuItems","result","showMenu","hideMenu","handleItemClick","actionItem","handleContextMenu","handleTouchStart","touch","syntheticEvent","handleTouchMove","dx","dy","handleTouchEnd","ctx","customItems","newItems","value","newStyle"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { PluginDataExportConfig } from './types';
|
|
|
3
3
|
|
|
4
4
|
export * from './types';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Velo Plot Data Export Plugin
|
|
7
7
|
*
|
|
8
8
|
* Provides comprehensive data export functionality with support for
|
|
9
9
|
* multiple scientific and standard data formats.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './data-export/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './data-export/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -43,7 +43,7 @@ function _(r, s) {
|
|
|
43
43
|
precision: e = 6,
|
|
44
44
|
scientificThreshold: p = 1e6
|
|
45
45
|
} = s, v = [], O = s.format === "xlsx" ? D.xlsx.bom : "";
|
|
46
|
-
if (f && Object.keys(l).length > 0 && (v.push("#
|
|
46
|
+
if (f && Object.keys(l).length > 0 && (v.push("# Velo Plot Data Export"), n && v.push(`# Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}`), Object.entries(l).forEach(([d, x]) => {
|
|
47
47
|
v.push(`# ${d}: ${x}`);
|
|
48
48
|
}), v.push("")), i) {
|
|
49
49
|
const d = [];
|
|
@@ -220,7 +220,7 @@ const k = {
|
|
|
220
220
|
name: "velo-plot-data-export",
|
|
221
221
|
version: "1.0.0",
|
|
222
222
|
description: "Advanced data export capabilities for velo-plot",
|
|
223
|
-
author: "
|
|
223
|
+
author: "Velo Plot Team",
|
|
224
224
|
provides: ["export"],
|
|
225
225
|
tags: ["export", "csv", "json", "matlab", "python", "data"]
|
|
226
226
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-export.js","sources":["../../src/plugins/data-export/formatters.ts","../../src/plugins/data-export/index.ts"],"sourcesContent":["/**\n * Data Export Formatters\n * \n * Handles conversion of chart data to various output formats.\n * \n * @module plugins/data-export/formatters\n */\n\nimport type { \n DataExportOptions, \n ExportFormat, \n FormatConfig,\n SeriesExportInfo,\n MatlabExportData,\n NumpyExportData\n} from \"./types\";\n\n// ============================================\n// Format Configurations\n// ============================================\n\nexport const FORMAT_CONFIGS: Record<ExportFormat, FormatConfig> = {\n csv: {\n mimeType: 'text/csv',\n extension: '.csv'\n },\n tsv: {\n mimeType: 'text/tab-separated-values',\n extension: '.tsv'\n },\n json: {\n mimeType: 'application/json',\n extension: '.json'\n },\n matlab: {\n mimeType: 'application/json',\n extension: '.mat.json'\n },\n python: {\n mimeType: 'application/json',\n extension: '.npy.json'\n },\n xlsx: {\n mimeType: 'text/csv;charset=utf-8',\n extension: '.csv',\n bom: '\\uFEFF' // UTF-8 BOM for Excel\n },\n binary: {\n mimeType: 'application/octet-stream',\n extension: '.bin',\n binary: true\n }\n};\n\n// ============================================\n// CSV/TSV Formatter\n// ============================================\n\n/**\n * Format data as CSV or TSV\n */\nexport function formatCSV(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const {\n delimiter = options.format === 'tsv' ? '\\t' : ',',\n lineEnding = '\\n',\n includeHeaders = true,\n includeTimestamp = false,\n includeMetadata = false,\n metadata = {},\n precision = 6,\n scientificThreshold = 1e6\n } = options;\n\n const lines: string[] = [];\n const bom = options.format === 'xlsx' ? FORMAT_CONFIGS.xlsx.bom : '';\n\n // Add metadata as comments (if supported)\n if (includeMetadata && Object.keys(metadata).length > 0) {\n lines.push(`# Sci Plot Data Export`);\n if (includeTimestamp) {\n lines.push(`# Timestamp: ${new Date().toISOString()}`);\n }\n Object.entries(metadata).forEach(([key, value]) => {\n lines.push(`# ${key}: ${value}`);\n });\n lines.push('');\n }\n\n // Generate headers\n if (includeHeaders) {\n const headers: string[] = [];\n seriesData.forEach(s => {\n const prefix = seriesData.length > 1 ? `${s.name || s.id}_` : '';\n headers.push(`${prefix}x`, `${prefix}y`);\n \n // Add additional columns if present\n if (s.data.y2) headers.push(`${prefix}y2`);\n if (s.data.yError) headers.push(`${prefix}yError`);\n if (s.data.open) headers.push(`${prefix}open`, `${prefix}high`, `${prefix}low`, `${prefix}close`);\n });\n lines.push(headers.join(delimiter));\n }\n\n // Find max length\n const maxLength = Math.max(...seriesData.map(s => s.data.x.length));\n\n // Generate data rows\n for (let i = 0; i < maxLength; i++) {\n const row: string[] = [];\n \n seriesData.forEach(s => {\n const { x, y, y2, yError, open, high, low, close } = s.data;\n \n if (i < x.length) {\n row.push(\n formatNumber(x[i], precision, scientificThreshold),\n formatNumber(y[i], precision, scientificThreshold)\n );\n if (y2) row.push(formatNumber(y2[i], precision, scientificThreshold));\n if (yError) row.push(formatNumber(yError[i], precision, scientificThreshold));\n if (open && high && low && close) {\n row.push(\n formatNumber(open[i], precision, scientificThreshold),\n formatNumber(high[i], precision, scientificThreshold),\n formatNumber(low[i], precision, scientificThreshold),\n formatNumber(close[i], precision, scientificThreshold)\n );\n }\n } else {\n row.push('', '');\n if (s.data.y2) row.push('');\n if (s.data.yError) row.push('');\n if (s.data.open) row.push('', '', '', '');\n }\n });\n \n lines.push(row.join(delimiter));\n }\n\n return bom + lines.join(lineEnding);\n}\n\n// ============================================\n// JSON Formatter\n// ============================================\n\n/**\n * Format data as JSON\n */\nexport function formatJSON(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions,\n viewBounds?: { xMin: number; xMax: number; yMin: number; yMax: number }\n): string {\n const {\n precision = 6,\n prettyPrint = true,\n includeMetadata = true,\n metadata = {}\n } = options;\n\n const exportData: Record<string, unknown> = {\n version: '1.0',\n exportDate: new Date().toISOString(),\n format: 'velo-plot-json'\n };\n\n if (includeMetadata) {\n exportData.metadata = {\n ...metadata,\n seriesCount: seriesData.length,\n totalPoints: seriesData.reduce((sum, s) => sum + s.pointCount, 0)\n };\n }\n\n if (viewBounds) {\n exportData.viewBounds = viewBounds;\n }\n\n exportData.series = seriesData.map(s => ({\n id: s.id,\n name: s.name || s.id,\n type: s.type,\n pointCount: s.pointCount,\n yAxisId: s.yAxisId,\n style: s.style,\n data: {\n x: roundArray(Array.from(s.data.x), precision),\n y: roundArray(Array.from(s.data.y), precision),\n ...(s.data.y2 && { y2: roundArray(Array.from(s.data.y2), precision) }),\n ...(s.data.yError && { yError: roundArray(Array.from(s.data.yError), precision) }),\n ...(s.data.open && { \n open: roundArray(Array.from(s.data.open), precision),\n high: roundArray(Array.from(s.data.high!), precision),\n low: roundArray(Array.from(s.data.low!), precision),\n close: roundArray(Array.from(s.data.close!), precision)\n })\n }\n }));\n\n return JSON.stringify(exportData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// MATLAB Format\n// ============================================\n\n/**\n * Format data for MATLAB compatibility\n * Outputs JSON that can be easily loaded in MATLAB using jsondecode()\n */\nexport function formatMATLAB(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const { precision = 6, prettyPrint = true } = options;\n\n const matlabData: {\n format: string;\n version: string;\n created: string;\n variables: MatlabExportData[];\n } = {\n format: 'matlab-compatible-json',\n version: '1.0',\n created: new Date().toISOString(),\n variables: []\n };\n\n seriesData.forEach(s => {\n const xData = roundArray(Array.from(s.data.x), precision);\n const yData = roundArray(Array.from(s.data.y), precision);\n const safeName = sanitizeVariableName(s.name || s.id);\n\n // Create x variable\n matlabData.variables.push({\n name: `${safeName}_x`,\n type: 'double',\n size: [xData.length, 1],\n data: xData\n });\n\n // Create y variable\n matlabData.variables.push({\n name: `${safeName}_y`,\n type: 'double',\n size: [yData.length, 1],\n data: yData\n });\n\n // Create combined matrix variable\n matlabData.variables.push({\n name: safeName,\n type: 'double',\n size: [xData.length, 2],\n data: interleaveArrays(xData, yData)\n });\n });\n\n return JSON.stringify(matlabData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// Python/NumPy Format\n// ============================================\n\n/**\n * Format data for Python/NumPy compatibility\n * Outputs JSON that can be easily loaded in Python\n */\nexport function formatPython(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const { precision = 6, prettyPrint = true } = options;\n\n const pythonData: {\n format: string;\n version: string;\n created: string;\n import_code: string;\n arrays: Record<string, NumpyExportData>;\n } = {\n format: 'numpy-compatible-json',\n version: '1.0',\n created: new Date().toISOString(),\n import_code: `\n# Load data in Python:\nimport json\nimport numpy as np\n\nwith open('data.npy.json', 'r') as f:\n data = json.load(f)\n\n# Access arrays:\n# x = np.array(data['arrays']['series_name']['x']['data'], dtype=np.float32)\n# y = np.array(data['arrays']['series_name']['y']['data'], dtype=np.float32)\n`.trim(),\n arrays: {}\n };\n\n seriesData.forEach(s => {\n const safeName = sanitizeVariableName(s.name || s.id);\n const xData = roundArray(Array.from(s.data.x), precision);\n const yData = roundArray(Array.from(s.data.y), precision);\n\n pythonData.arrays[safeName] = {\n dtype: 'float32',\n shape: [xData.length, 2],\n data: interleaveArrays(xData, yData),\n name: safeName\n };\n\n // Also provide separate x and y arrays\n pythonData.arrays[`${safeName}_x`] = {\n dtype: 'float32',\n shape: [xData.length],\n data: xData,\n name: `${safeName}_x`\n };\n\n pythonData.arrays[`${safeName}_y`] = {\n dtype: 'float32',\n shape: [yData.length],\n data: yData,\n name: `${safeName}_y`\n };\n });\n\n return JSON.stringify(pythonData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// Binary Format\n// ============================================\n\n/**\n * Format data as binary Float32Array\n * \n * Binary format structure:\n * - Header (32 bytes): magic number, version, series count, reserved\n * - Per series: name length (4 bytes), name (UTF-8), point count (4 bytes), x data, y data\n */\nexport function formatBinary(\n seriesData: SeriesExportInfo[]\n): ArrayBuffer {\n // Calculate total size\n let totalSize = 32; // Header\n \n seriesData.forEach(s => {\n const nameBytes = new TextEncoder().encode(s.name || s.id);\n totalSize += 4 + nameBytes.length; // name length + name\n totalSize += 4; // point count\n totalSize += s.data.x.length * 4 * 2; // x and y as Float32\n });\n \n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const encoder = new TextEncoder();\n \n let offset = 0;\n \n // Header\n // Magic number: \"SCE1\" (Sci Plot v1)\n view.setUint8(offset++, 0x53); // S\n view.setUint8(offset++, 0x43); // C\n view.setUint8(offset++, 0x45); // E\n view.setUint8(offset++, 0x31); // 1\n \n // Version\n view.setUint32(offset, 1, true); offset += 4;\n \n // Series count\n view.setUint32(offset, seriesData.length, true); offset += 4;\n \n // Timestamp (milliseconds since epoch)\n const timestamp = Math.floor(Date.now() / 1000);\n view.setUint32(offset, timestamp, true); offset += 4;\n \n // Reserved (16 bytes)\n offset += 16;\n \n // Series data\n seriesData.forEach(s => {\n const nameBytes = encoder.encode(s.name || s.id);\n \n // Name length\n view.setUint32(offset, nameBytes.length, true); offset += 4;\n \n // Name\n new Uint8Array(buffer, offset, nameBytes.length).set(nameBytes);\n offset += nameBytes.length;\n \n // Point count\n const pointCount = s.data.x.length;\n view.setUint32(offset, pointCount, true); offset += 4;\n \n // X data\n const xFloat32 = new Float32Array(buffer, offset, pointCount);\n for (let i = 0; i < pointCount; i++) {\n xFloat32[i] = s.data.x[i];\n }\n offset += pointCount * 4;\n \n // Y data\n const yFloat32 = new Float32Array(buffer, offset, pointCount);\n for (let i = 0; i < pointCount; i++) {\n yFloat32[i] = s.data.y[i];\n }\n offset += pointCount * 4;\n });\n \n return buffer;\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Format a number with appropriate precision\n */\nfunction formatNumber(value: number, precision: number, scientificThreshold: number): string {\n if (!isFinite(value)) {\n return isNaN(value) ? 'NaN' : (value > 0 ? 'Inf' : '-Inf');\n }\n \n const absValue = Math.abs(value);\n if (absValue !== 0 && (absValue >= scientificThreshold || absValue < 1e-4)) {\n return value.toExponential(precision);\n }\n \n return value.toFixed(precision);\n}\n\n/**\n * Round array values to specified precision\n */\nfunction roundArray(arr: number[], precision: number): number[] {\n const factor = Math.pow(10, precision);\n return arr.map(v => Math.round(v * factor) / factor);\n}\n\n/**\n * Sanitize string for use as variable name\n */\nfunction sanitizeVariableName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^[0-9]/, '_$&')\n .substring(0, 63);\n}\n\n/**\n * Interleave two arrays [a0, b0, a1, b1, ...]\n */\nfunction interleaveArrays(a: number[], b: number[]): number[] {\n const result: number[] = [];\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n if (i < a.length) result.push(a[i]);\n if (i < b.length) result.push(b[i]);\n }\n return result;\n}\n","/**\n * Sci Plot - Data Export Plugin\n * \n * Advanced data export capabilities for scientific chart data.\n * Supports multiple formats including CSV, JSON, MATLAB, and Python.\n * \n * @module plugins/data-export\n * \n * @example\n * ```typescript\n * import { createChart } from 'velo-plot';\n * import { PluginDataExport } from 'velo-plot/plugins/data-export';\n * \n * const chart = createChart({ container });\n * chart.use(PluginDataExport({\n * defaultFormat: 'csv',\n * autoDownload: true\n * }));\n * \n * // Export visible data\n * const result = await chart.export('csv', { range: 'visible' });\n * \n * // Export all data to MATLAB format\n * await chart.export('matlab', { \n * seriesIds: ['voltage', 'current'],\n * includeMetadata: true \n * });\n * ```\n */\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\nimport type { \n PluginDataExportConfig, \n DataExportOptions, \n ExportResult,\n ExportFormat,\n SeriesExportInfo,\n ExportRange\n} from \"./types\";\nimport { \n FORMAT_CONFIGS,\n formatCSV, \n formatJSON, \n formatMATLAB, \n formatPython,\n formatBinary\n} from \"./formatters\";\n\n// Re-export types\nexport * from \"./types\";\n\n// ============================================\n// Plugin Definition\n// ============================================\n\nconst manifestDataExport: PluginManifest = {\n name: \"velo-plot-data-export\",\n version: \"1.0.0\",\n description: \"Advanced data export capabilities for velo-plot\",\n author: \"Sci Plot Team\",\n provides: [\"export\"],\n tags: [\"export\", \"csv\", \"json\", \"matlab\", \"python\", \"data\"],\n};\n\n/**\n * Sci Plot Data Export Plugin\n * \n * Provides comprehensive data export functionality with support for\n * multiple scientific and standard data formats.\n * \n * @param config - Plugin configuration options\n * @returns ChartPlugin instance\n */\nexport function PluginDataExport(\n config: PluginDataExportConfig = {}\n): ChartPlugin<PluginDataExportConfig> {\n \n const {\n formats = ['csv', 'tsv', 'json', 'matlab', 'python', 'xlsx', 'binary'],\n defaultFormat = 'csv',\n defaultPrecision = 6,\n includeMetadata = true,\n autoDownload = false,\n filenameGenerator,\n beforeExport,\n afterExport\n } = config;\n\n let _ctx: PluginContext | null = null;\n\n // ============================================\n // Internal Helpers\n // ============================================\n\n /**\n * Collect series data for export\n */\n function collectSeriesData(\n seriesIds?: string[],\n range?: ExportRange\n ): SeriesExportInfo[] {\n if (!_ctx) return [];\n\n const allSeries = _ctx.data.getAllSeries();\n const seriesToExport = seriesIds \n ? allSeries.filter(s => seriesIds.includes(s.getId()))\n : allSeries;\n\n return seriesToExport.map(s => {\n let data = s.getData();\n \n // Filter by range if specified\n if (range === 'visible' && data) {\n const bounds = _ctx!.data.getViewBounds();\n const filteredIndices: number[] = [];\n \n for (let i = 0; i < data.x.length; i++) {\n if (data.x[i] >= bounds.xMin && data.x[i] <= bounds.xMax) {\n filteredIndices.push(i);\n }\n }\n \n if (filteredIndices.length > 0 && filteredIndices.length < data.x.length) {\n const newX = new Float32Array(filteredIndices.length);\n const newY = new Float32Array(filteredIndices.length);\n \n filteredIndices.forEach((idx, i) => {\n newX[i] = data!.x[idx];\n newY[i] = data!.y[idx];\n });\n \n data = { ...data, x: newX, y: newY };\n }\n }\n\n return {\n id: s.getId(),\n name: s.getName?.() ?? s.getId(),\n type: s.getType(),\n data: data || { x: new Float32Array(0), y: new Float32Array(0) },\n pointCount: data?.x.length ?? 0,\n style: s.getStyle() as Record<string, unknown>,\n yAxisId: s.getYAxisId?.()\n };\n });\n }\n\n /**\n * Generate filename based on format and content\n */\n function generateFilename(format: ExportFormat, seriesIds: string[]): string {\n if (filenameGenerator) {\n return filenameGenerator(format, seriesIds);\n }\n \n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19);\n const seriesPart = seriesIds.length <= 3 \n ? seriesIds.join('_') \n : `${seriesIds.length}_series`;\n \n const config = FORMAT_CONFIGS[format];\n return `velo-plot_${seriesPart}_${timestamp}${config.extension}`;\n }\n\n /**\n * Execute export operation\n */\n function doExport(options: DataExportOptions): ExportResult {\n const format = options.format ?? defaultFormat;\n const warnings: string[] = [];\n\n // Validate format\n if (!formats.includes(format)) {\n return {\n success: false,\n error: `Format '${format}' is not enabled. Available: ${formats.join(', ')}`,\n contentType: 'text/plain',\n filename: 'error.txt',\n seriesCount: 0,\n pointCount: 0,\n timestamp: new Date().toISOString()\n };\n }\n\n // Apply beforeExport hook\n let finalOptions: DataExportOptions = { ...options, precision: options.precision ?? defaultPrecision };\n if (beforeExport) {\n const hookResult = beforeExport(finalOptions);\n if (hookResult === false) {\n return {\n success: false,\n error: 'Export cancelled by beforeExport hook',\n contentType: 'text/plain',\n filename: 'cancelled.txt',\n seriesCount: 0,\n pointCount: 0,\n timestamp: new Date().toISOString()\n };\n }\n finalOptions = hookResult;\n }\n\n // Collect data\n const seriesData = collectSeriesData(finalOptions.seriesIds, finalOptions.range);\n \n if (seriesData.length === 0) {\n warnings.push('No series data found to export');\n }\n\n const totalPoints = seriesData.reduce((sum, s) => sum + s.pointCount, 0);\n const formatConfig = FORMAT_CONFIGS[format];\n const filename = finalOptions.filename ?? generateFilename(format, seriesData.map(s => s.id));\n\n let content: string | undefined;\n let blob: Blob | undefined;\n\n try {\n // Format data\n switch (format) {\n case 'csv':\n case 'tsv':\n case 'xlsx':\n content = formatCSV(seriesData, { ...finalOptions, format });\n break;\n \n case 'json':\n content = formatJSON(\n seriesData, \n finalOptions,\n _ctx?.data.getViewBounds()\n );\n break;\n \n case 'matlab':\n content = formatMATLAB(seriesData, finalOptions);\n break;\n \n case 'python':\n content = formatPython(seriesData, finalOptions);\n break;\n \n case 'binary':\n const buffer = formatBinary(seriesData);\n blob = new Blob([buffer], { type: formatConfig.mimeType });\n break;\n }\n\n // Create blob for string content\n if (content && !blob) {\n blob = new Blob([content], { type: formatConfig.mimeType });\n }\n\n } catch (error) {\n return {\n success: false,\n error: `Export failed: ${(error as Error).message}`,\n contentType: 'text/plain',\n filename: 'error.txt',\n seriesCount: seriesData.length,\n pointCount: totalPoints,\n timestamp: new Date().toISOString()\n };\n }\n\n const result: ExportResult = {\n success: true,\n content,\n blob,\n contentType: formatConfig.mimeType,\n filename,\n seriesCount: seriesData.length,\n pointCount: totalPoints,\n timestamp: new Date().toISOString(),\n warnings: warnings.length > 0 ? warnings : undefined\n };\n\n // Apply afterExport hook\n if (afterExport) {\n afterExport(result);\n }\n\n return result;\n }\n\n /**\n * Download a blob as a file\n */\n function downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n // ============================================\n // Plugin Implementation\n // ============================================\n\n const pluginApi: any = {\n /**\n * Export chart data to specified format\n * \n * @param format - Export format\n * @param options - Export options\n * @returns Export result with content/blob\n */\n export(format: ExportFormat, options: Partial<DataExportOptions> = {}): ExportResult {\n const fullOptions: DataExportOptions = {\n format,\n includeHeaders: true,\n includeTimestamp: true,\n includeMetadata,\n prettyPrint: true,\n ...options\n };\n\n const result = doExport(fullOptions);\n\n // Auto download if enabled and successful\n if (autoDownload && result.success && result.blob) {\n downloadBlob(result.blob, result.filename);\n }\n\n return result;\n },\n\n /**\n * Export and immediately download\n * \n * @param format - Export format\n * @param options - Export options\n */\n download(format: ExportFormat, options: Partial<DataExportOptions> = {}): ExportResult {\n const fullOptions: DataExportOptions = {\n format,\n includeHeaders: true,\n includeTimestamp: true,\n includeMetadata,\n prettyPrint: true,\n ...options\n };\n const result = doExport(fullOptions);\n \n if (result.success && result.blob) {\n downloadBlob(result.blob, result.filename);\n }\n \n return result;\n },\n\n /**\n * Export to CSV format\n */\n toCSV(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'csv', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to JSON format\n */\n toJSON(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'json', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to MATLAB format\n */\n toMATLAB(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'matlab', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to Python/NumPy format\n */\n toPython(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'python', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to Excel-compatible CSV\n */\n toExcel(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'xlsx', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to binary format\n */\n toBinary(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'binary', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Get available export formats\n */\n getFormats(): ExportFormat[] {\n return [...formats];\n },\n\n /**\n * Check if a format is supported\n */\n supportsFormat(format: ExportFormat): boolean {\n return formats.includes(format);\n },\n\n /**\n * Get format configuration\n */\n getFormatConfig(format: ExportFormat) {\n return FORMAT_CONFIGS[format];\n }\n };\n\n return {\n manifest: manifestDataExport,\n\n onInit(ctx: PluginContext) {\n _ctx = ctx;\n ctx.log.info(`DataExport plugin initialized with formats: ${formats.join(', ')}`);\n },\n\n onDestroy() {\n _ctx = null;\n },\n\n api: pluginApi\n };\n}\n\nexport default PluginDataExport;\n"],"names":["FORMAT_CONFIGS","formatCSV","seriesData","options","delimiter","lineEnding","includeHeaders","includeTimestamp","includeMetadata","metadata","precision","scientificThreshold","lines","bom","key","value","headers","s","prefix","maxLength","i","row","x","y","y2","yError","open","high","low","close","formatNumber","formatJSON","viewBounds","prettyPrint","exportData","sum","roundArray","formatMATLAB","matlabData","xData","yData","safeName","sanitizeVariableName","interleaveArrays","formatPython","pythonData","formatBinary","totalSize","nameBytes","buffer","view","encoder","offset","timestamp","pointCount","xFloat32","yFloat32","absValue","arr","factor","v","name","a","b","result","len","manifestDataExport","PluginDataExport","config","formats","defaultFormat","defaultPrecision","autoDownload","filenameGenerator","beforeExport","afterExport","_ctx","collectSeriesData","seriesIds","range","allSeries","_a","_b","data","bounds","filteredIndices","newX","newY","idx","generateFilename","format","seriesPart","doExport","warnings","finalOptions","hookResult","totalPoints","formatConfig","filename","content","blob","error","downloadBlob","url","link","ctx","fullOptions"],"mappings":"AAqBO,MAAMA,IAAqD;AAAA,EAChE,KAAK;AAAA,IACH,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAAA,EAEb,KAAK;AAAA,IACH,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAAA,EAEb,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAAA,EAEb,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAAA,EAEb,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,EAAA;AAAA,EAEb,MAAM;AAAA,IACJ,UAAU;AAAA,IACV,WAAW;AAAA,IACX,KAAK;AAAA;AAAA,EAAA;AAAA,EAEP,QAAQ;AAAA,IACN,UAAU;AAAA,IACV,WAAW;AAAA,IACX,QAAQ;AAAA,EAAA;AAEZ;AASO,SAASC,EACdC,GACAC,GACQ;AACR,QAAM;AAAA,IACJ,WAAAC,IAAYD,EAAQ,WAAW,QAAQ,MAAO;AAAA,IAC9C,YAAAE,IAAa;AAAA;AAAA,IACb,gBAAAC,IAAiB;AAAA,IACjB,kBAAAC,IAAmB;AAAA,IACnB,iBAAAC,IAAkB;AAAA,IAClB,UAAAC,IAAW,CAAA;AAAA,IACX,WAAAC,IAAY;AAAA,IACZ,qBAAAC,IAAsB;AAAA,EAAA,IACpBR,GAEES,IAAkB,CAAA,GAClBC,IAAMV,EAAQ,WAAW,SAASH,EAAe,KAAK,MAAM;AAelE,MAZIQ,KAAmB,OAAO,KAAKC,CAAQ,EAAE,SAAS,MACpDG,EAAM,KAAK,wBAAwB,GAC/BL,KACFK,EAAM,KAAK,iBAAgB,oBAAI,QAAO,YAAA,CAAa,EAAE,GAEvD,OAAO,QAAQH,CAAQ,EAAE,QAAQ,CAAC,CAACK,GAAKC,CAAK,MAAM;AACjD,IAAAH,EAAM,KAAK,KAAKE,CAAG,KAAKC,CAAK,EAAE;AAAA,EACjC,CAAC,GACDH,EAAM,KAAK,EAAE,IAIXN,GAAgB;AAClB,UAAMU,IAAoB,CAAA;AAC1B,IAAAd,EAAW,QAAQ,CAAAe,MAAK;AACtB,YAAMC,IAAShB,EAAW,SAAS,IAAI,GAAGe,EAAE,QAAQA,EAAE,EAAE,MAAM;AAC9D,MAAAD,EAAQ,KAAK,GAAGE,CAAM,KAAK,GAAGA,CAAM,GAAG,GAGnCD,EAAE,KAAK,QAAY,KAAK,GAAGC,CAAM,IAAI,GACrCD,EAAE,KAAK,YAAgB,KAAK,GAAGC,CAAM,QAAQ,GAC7CD,EAAE,KAAK,QAAMD,EAAQ,KAAK,GAAGE,CAAM,QAAQ,GAAGA,CAAM,QAAQ,GAAGA,CAAM,OAAO,GAAGA,CAAM,OAAO;AAAA,IAClG,CAAC,GACDN,EAAM,KAAKI,EAAQ,KAAKZ,CAAS,CAAC;AAAA,EACpC;AAGA,QAAMe,IAAY,KAAK,IAAI,GAAGjB,EAAW,IAAI,CAAAe,MAAKA,EAAE,KAAK,EAAE,MAAM,CAAC;AAGlE,WAASG,IAAI,GAAGA,IAAID,GAAWC,KAAK;AAClC,UAAMC,IAAgB,CAAA;AAEtB,IAAAnB,EAAW,QAAQ,CAAAe,MAAK;AACtB,YAAM,EAAE,GAAAK,GAAG,GAAAC,GAAG,IAAAC,GAAI,QAAAC,GAAQ,MAAAC,GAAM,MAAAC,GAAM,KAAAC,GAAK,OAAAC,EAAA,IAAUZ,EAAE;AAEvD,MAAIG,IAAIE,EAAE,UACRD,EAAI;AAAA,QACFS,EAAaR,EAAEF,CAAC,GAAGV,GAAWC,CAAmB;AAAA,QACjDmB,EAAaP,EAAEH,CAAC,GAAGV,GAAWC,CAAmB;AAAA,MAAA,GAE/Ca,OAAQ,KAAKM,EAAaN,EAAGJ,CAAC,GAAGV,GAAWC,CAAmB,CAAC,GAChEc,OAAY,KAAKK,EAAaL,EAAOL,CAAC,GAAGV,GAAWC,CAAmB,CAAC,GACxEe,KAAQC,KAAQC,KAAOC,KACzBR,EAAI;AAAA,QACFS,EAAaJ,EAAKN,CAAC,GAAGV,GAAWC,CAAmB;AAAA,QACpDmB,EAAaH,EAAKP,CAAC,GAAGV,GAAWC,CAAmB;AAAA,QACpDmB,EAAaF,EAAIR,CAAC,GAAGV,GAAWC,CAAmB;AAAA,QACnDmB,EAAaD,EAAMT,CAAC,GAAGV,GAAWC,CAAmB;AAAA,MAAA,MAIzDU,EAAI,KAAK,IAAI,EAAE,GACXJ,EAAE,KAAK,MAAII,EAAI,KAAK,EAAE,GACtBJ,EAAE,KAAK,UAAQI,EAAI,KAAK,EAAE,GAC1BJ,EAAE,KAAK,QAAMI,EAAI,KAAK,IAAI,IAAI,IAAI,EAAE;AAAA,IAE5C,CAAC,GAEDT,EAAM,KAAKS,EAAI,KAAKjB,CAAS,CAAC;AAAA,EAChC;AAEA,SAAOS,IAAMD,EAAM,KAAKP,CAAU;AACpC;AASO,SAAS0B,EACd7B,GACAC,GACA6B,GACQ;AACR,QAAM;AAAA,IACJ,WAAAtB,IAAY;AAAA,IACZ,aAAAuB,IAAc;AAAA,IACd,iBAAAzB,IAAkB;AAAA,IAClB,UAAAC,IAAW,CAAA;AAAA,EAAC,IACVN,GAEE+B,IAAsC;AAAA,IAC1C,SAAS;AAAA,IACT,aAAY,oBAAI,KAAA,GAAO,YAAA;AAAA,IACvB,QAAQ;AAAA,EAAA;AAGV,SAAI1B,MACF0B,EAAW,WAAW;AAAA,IACpB,GAAGzB;AAAA,IACH,aAAaP,EAAW;AAAA,IACxB,aAAaA,EAAW,OAAO,CAACiC,GAAKlB,MAAMkB,IAAMlB,EAAE,YAAY,CAAC;AAAA,EAAA,IAIhEe,MACFE,EAAW,aAAaF,IAG1BE,EAAW,SAAShC,EAAW,IAAI,CAAAe,OAAM;AAAA,IACvC,IAAIA,EAAE;AAAA,IACN,MAAMA,EAAE,QAAQA,EAAE;AAAA,IAClB,MAAMA,EAAE;AAAA,IACR,YAAYA,EAAE;AAAA,IACd,SAASA,EAAE;AAAA,IACX,OAAOA,EAAE;AAAA,IACT,MAAM;AAAA,MACJ,GAAGmB,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS;AAAA,MAC7C,GAAG0B,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS;AAAA,MAC7C,GAAIO,EAAE,KAAK,MAAM,EAAE,IAAImB,EAAW,MAAM,KAAKnB,EAAE,KAAK,EAAE,GAAGP,CAAS,EAAA;AAAA,MAClE,GAAIO,EAAE,KAAK,UAAU,EAAE,QAAQmB,EAAW,MAAM,KAAKnB,EAAE,KAAK,MAAM,GAAGP,CAAS,EAAA;AAAA,MAC9E,GAAIO,EAAE,KAAK,QAAQ;AAAA,QACjB,MAAMmB,EAAW,MAAM,KAAKnB,EAAE,KAAK,IAAI,GAAGP,CAAS;AAAA,QACnD,MAAM0B,EAAW,MAAM,KAAKnB,EAAE,KAAK,IAAK,GAAGP,CAAS;AAAA,QACpD,KAAK0B,EAAW,MAAM,KAAKnB,EAAE,KAAK,GAAI,GAAGP,CAAS;AAAA,QAClD,OAAO0B,EAAW,MAAM,KAAKnB,EAAE,KAAK,KAAM,GAAGP,CAAS;AAAA,MAAA;AAAA,IACxD;AAAA,EACF,EACA,GAEK,KAAK,UAAUwB,GAAY,MAAMD,IAAc,IAAI,MAAS;AACrE;AAUO,SAASI,EACdnC,GACAC,GACQ;AACR,QAAM,EAAE,WAAAO,IAAY,GAAG,aAAAuB,IAAc,OAAS9B,GAExCmC,IAKF;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAS,oBAAI,KAAA,GAAO,YAAA;AAAA,IACpB,WAAW,CAAA;AAAA,EAAC;AAGd,SAAApC,EAAW,QAAQ,CAAAe,MAAK;AACtB,UAAMsB,IAAQH,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS,GAClD8B,IAAQJ,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS,GAClD+B,IAAWC,EAAqBzB,EAAE,QAAQA,EAAE,EAAE;AAGpD,IAAAqB,EAAW,UAAU,KAAK;AAAA,MACxB,MAAM,GAAGG,CAAQ;AAAA,MACjB,MAAM;AAAA,MACN,MAAM,CAACF,EAAM,QAAQ,CAAC;AAAA,MACtB,MAAMA;AAAA,IAAA,CACP,GAGDD,EAAW,UAAU,KAAK;AAAA,MACxB,MAAM,GAAGG,CAAQ;AAAA,MACjB,MAAM;AAAA,MACN,MAAM,CAACD,EAAM,QAAQ,CAAC;AAAA,MACtB,MAAMA;AAAA,IAAA,CACP,GAGDF,EAAW,UAAU,KAAK;AAAA,MACxB,MAAMG;AAAA,MACN,MAAM;AAAA,MACN,MAAM,CAACF,EAAM,QAAQ,CAAC;AAAA,MACtB,MAAMI,EAAiBJ,GAAOC,CAAK;AAAA,IAAA,CACpC;AAAA,EACH,CAAC,GAEM,KAAK,UAAUF,GAAY,MAAML,IAAc,IAAI,MAAS;AACrE;AAUO,SAASW,EACd1C,GACAC,GACQ;AACR,QAAM,EAAE,WAAAO,IAAY,GAAG,aAAAuB,IAAc,OAAS9B,GAExC0C,IAMF;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAS,oBAAI,KAAA,GAAO,YAAA;AAAA,IACpB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWf,KAAA;AAAA,IACE,QAAQ,CAAA;AAAA,EAAC;AAGX,SAAA3C,EAAW,QAAQ,CAAAe,MAAK;AACtB,UAAMwB,IAAWC,EAAqBzB,EAAE,QAAQA,EAAE,EAAE,GAC9CsB,IAAQH,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS,GAClD8B,IAAQJ,EAAW,MAAM,KAAKnB,EAAE,KAAK,CAAC,GAAGP,CAAS;AAExD,IAAAmC,EAAW,OAAOJ,CAAQ,IAAI;AAAA,MAC5B,OAAO;AAAA,MACP,OAAO,CAACF,EAAM,QAAQ,CAAC;AAAA,MACvB,MAAMI,EAAiBJ,GAAOC,CAAK;AAAA,MACnC,MAAMC;AAAA,IAAA,GAIRI,EAAW,OAAO,GAAGJ,CAAQ,IAAI,IAAI;AAAA,MACnC,OAAO;AAAA,MACP,OAAO,CAACF,EAAM,MAAM;AAAA,MACpB,MAAMA;AAAA,MACN,MAAM,GAAGE,CAAQ;AAAA,IAAA,GAGnBI,EAAW,OAAO,GAAGJ,CAAQ,IAAI,IAAI;AAAA,MACnC,OAAO;AAAA,MACP,OAAO,CAACD,EAAM,MAAM;AAAA,MACpB,MAAMA;AAAA,MACN,MAAM,GAAGC,CAAQ;AAAA,IAAA;AAAA,EAErB,CAAC,GAEM,KAAK,UAAUI,GAAY,MAAMZ,IAAc,IAAI,MAAS;AACrE;AAaO,SAASa,EACd5C,GACa;AAEb,MAAI6C,IAAY;AAEhB,EAAA7C,EAAW,QAAQ,CAAAe,MAAK;AACtB,UAAM+B,IAAY,IAAI,cAAc,OAAO/B,EAAE,QAAQA,EAAE,EAAE;AACzD,IAAA8B,KAAa,IAAIC,EAAU,QAC3BD,KAAa,GACbA,KAAa9B,EAAE,KAAK,EAAE,SAAS,IAAI;AAAA,EACrC,CAAC;AAED,QAAMgC,IAAS,IAAI,YAAYF,CAAS,GAClCG,IAAO,IAAI,SAASD,CAAM,GAC1BE,IAAU,IAAI,YAAA;AAEpB,MAAIC,IAAS;AAIb,EAAAF,EAAK,SAASE,KAAU,EAAI,GAC5BF,EAAK,SAASE,KAAU,EAAI,GAC5BF,EAAK,SAASE,KAAU,EAAI,GAC5BF,EAAK,SAASE,KAAU,EAAI,GAG5BF,EAAK,UAAUE,GAAQ,GAAG,EAAI,GAAGA,KAAU,GAG3CF,EAAK,UAAUE,GAAQlD,EAAW,QAAQ,EAAI,GAAGkD,KAAU;AAG3D,QAAMC,IAAY,KAAK,MAAM,KAAK,IAAA,IAAQ,GAAI;AAC9C,SAAAH,EAAK,UAAUE,GAAQC,GAAW,EAAI,GAAGD,KAAU,GAGnDA,KAAU,IAGVlD,EAAW,QAAQ,CAAAe,MAAK;AACtB,UAAM+B,IAAYG,EAAQ,OAAOlC,EAAE,QAAQA,EAAE,EAAE;AAG/C,IAAAiC,EAAK,UAAUE,GAAQJ,EAAU,QAAQ,EAAI,GAAGI,KAAU,GAG1D,IAAI,WAAWH,GAAQG,GAAQJ,EAAU,MAAM,EAAE,IAAIA,CAAS,GAC9DI,KAAUJ,EAAU;AAGpB,UAAMM,IAAarC,EAAE,KAAK,EAAE;AAC5B,IAAAiC,EAAK,UAAUE,GAAQE,GAAY,EAAI,GAAGF,KAAU;AAGpD,UAAMG,IAAW,IAAI,aAAaN,GAAQG,GAAQE,CAAU;AAC5D,aAASlC,IAAI,GAAGA,IAAIkC,GAAYlC;AAC9B,MAAAmC,EAASnC,CAAC,IAAIH,EAAE,KAAK,EAAEG,CAAC;AAE1B,IAAAgC,KAAUE,IAAa;AAGvB,UAAME,IAAW,IAAI,aAAaP,GAAQG,GAAQE,CAAU;AAC5D,aAASlC,IAAI,GAAGA,IAAIkC,GAAYlC;AAC9B,MAAAoC,EAASpC,CAAC,IAAIH,EAAE,KAAK,EAAEG,CAAC;AAE1B,IAAAgC,KAAUE,IAAa;AAAA,EACzB,CAAC,GAEML;AACT;AASA,SAASnB,EAAaf,GAAeL,GAAmBC,GAAqC;AAC3F,MAAI,CAAC,SAASI,CAAK;AACjB,WAAO,MAAMA,CAAK,IAAI,QAASA,IAAQ,IAAI,QAAQ;AAGrD,QAAM0C,IAAW,KAAK,IAAI1C,CAAK;AAC/B,SAAI0C,MAAa,MAAMA,KAAY9C,KAAuB8C,IAAW,QAC5D1C,EAAM,cAAcL,CAAS,IAG/BK,EAAM,QAAQL,CAAS;AAChC;AAKA,SAAS0B,EAAWsB,GAAehD,GAA6B;AAC9D,QAAMiD,IAAS,KAAK,IAAI,IAAIjD,CAAS;AACrC,SAAOgD,EAAI,IAAI,CAAAE,MAAK,KAAK,MAAMA,IAAID,CAAM,IAAIA,CAAM;AACrD;AAKA,SAASjB,EAAqBmB,GAAsB;AAClD,SAAOA,EACJ,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,UAAU,KAAK,EACvB,UAAU,GAAG,EAAE;AACpB;AAKA,SAASlB,EAAiBmB,GAAaC,GAAuB;AAC5D,QAAMC,IAAmB,CAAA,GACnBC,IAAM,KAAK,IAAIH,EAAE,QAAQC,EAAE,MAAM;AACvC,WAAS,IAAI,GAAG,IAAIE,GAAK;AACvB,IAAI,IAAIH,EAAE,YAAe,KAAKA,EAAE,CAAC,CAAC,GAC9B,IAAIC,EAAE,YAAe,KAAKA,EAAE,CAAC,CAAC;AAEpC,SAAOC;AACT;AC5ZA,MAAME,IAAqC;AAAA,EACzC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,UAAU,CAAC,QAAQ;AAAA,EACnB,MAAM,CAAC,UAAU,OAAO,QAAQ,UAAU,UAAU,MAAM;AAC5D;AAWO,SAASC,EACdC,IAAiC,IACI;AAErC,QAAM;AAAA,IACJ,SAAAC,IAAU,CAAC,OAAO,OAAO,QAAQ,UAAU,UAAU,QAAQ,QAAQ;AAAA,IACrE,eAAAC,IAAgB;AAAA,IAChB,kBAAAC,IAAmB;AAAA,IACnB,iBAAA/D,IAAkB;AAAA,IAClB,cAAAgE,IAAe;AAAA,IACf,mBAAAC;AAAA,IACA,cAAAC;AAAA,IACA,aAAAC;AAAA,EAAA,IACEP;AAEJ,MAAIQ,IAA6B;AASjC,WAASC,EACPC,GACAC,GACoB;AACpB,QAAI,CAACH,EAAM,QAAO,CAAA;AAElB,UAAMI,IAAYJ,EAAK,KAAK,aAAA;AAK5B,YAJuBE,IACnBE,EAAU,OAAO,CAAA/D,MAAK6D,EAAU,SAAS7D,EAAE,MAAA,CAAO,CAAC,IACnD+D,GAEkB,IAAI,CAAA/D,MAAK;ADvF5B,UAAAgE,GAAAC;ACwFD,UAAIC,IAAOlE,EAAE,QAAA;AAGb,UAAI8D,MAAU,aAAaI,GAAM;AAC/B,cAAMC,IAASR,EAAM,KAAK,cAAA,GACpBS,IAA4B,CAAA;AAElC,iBAASjE,IAAI,GAAGA,IAAI+D,EAAK,EAAE,QAAQ/D;AACjC,UAAI+D,EAAK,EAAE/D,CAAC,KAAKgE,EAAO,QAAQD,EAAK,EAAE/D,CAAC,KAAKgE,EAAO,QAClDC,EAAgB,KAAKjE,CAAC;AAI1B,YAAIiE,EAAgB,SAAS,KAAKA,EAAgB,SAASF,EAAK,EAAE,QAAQ;AACxE,gBAAMG,IAAO,IAAI,aAAaD,EAAgB,MAAM,GAC9CE,IAAO,IAAI,aAAaF,EAAgB,MAAM;AAEpD,UAAAA,EAAgB,QAAQ,CAACG,GAAKpE,MAAM;AAClC,YAAAkE,EAAKlE,CAAC,IAAI+D,EAAM,EAAEK,CAAG,GACrBD,EAAKnE,CAAC,IAAI+D,EAAM,EAAEK,CAAG;AAAA,UACvB,CAAC,GAEDL,IAAO,EAAE,GAAGA,GAAM,GAAGG,GAAM,GAAGC,EAAA;AAAA,QAChC;AAAA,MACF;AAEA,aAAO;AAAA,QACL,IAAItE,EAAE,MAAA;AAAA,QACN,QAAMgE,IAAAhE,EAAE,YAAF,gBAAAgE,EAAA,KAAAhE,OAAiBA,EAAE,MAAA;AAAA,QACzB,MAAMA,EAAE,QAAA;AAAA,QACR,MAAMkE,KAAQ,EAAE,GAAG,IAAI,aAAa,CAAC,GAAG,GAAG,IAAI,aAAa,CAAC,EAAA;AAAA,QAC7D,aAAYA,KAAA,gBAAAA,EAAM,EAAE,WAAU;AAAA,QAC9B,OAAOlE,EAAE,SAAA;AAAA,QACT,UAASiE,IAAAjE,EAAE,eAAF,gBAAAiE,EAAA,KAAAjE;AAAA,MAAe;AAAA,IAE5B,CAAC;AAAA,EACH;AAKA,WAASwE,EAAiBC,GAAsBZ,GAA6B;AAC3E,QAAIL;AACF,aAAOA,EAAkBiB,GAAQZ,CAAS;AAG5C,UAAMzB,KAAY,oBAAI,KAAA,GAAO,YAAA,EAAc,QAAQ,SAAS,GAAG,EAAE,UAAU,GAAG,EAAE,GAC1EsC,IAAab,EAAU,UAAU,IACnCA,EAAU,KAAK,GAAG,IAClB,GAAGA,EAAU,MAAM,WAEjBV,IAASpE,EAAe0F,CAAM;AACpC,WAAO,aAAaC,CAAU,IAAItC,CAAS,GAAGe,EAAO,SAAS;AAAA,EAChE;AAKA,WAASwB,EAASzF,GAA0C;AAC1D,UAAMuF,IAASvF,EAAQ,UAAUmE,GAC3BuB,IAAqB,CAAA;AAG3B,QAAI,CAACxB,EAAQ,SAASqB,CAAM;AAC1B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,WAAWA,CAAM,gCAAgCrB,EAAQ,KAAK,IAAI,CAAC;AAAA,QAC1E,aAAa;AAAA,QACb,UAAU;AAAA,QACV,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MAAY;AAKtC,QAAIyB,IAAkC,EAAE,GAAG3F,GAAS,WAAWA,EAAQ,aAAaoE,EAAA;AACpF,QAAIG,GAAc;AAChB,YAAMqB,IAAarB,EAAaoB,CAAY;AAC5C,UAAIC,MAAe;AACjB,eAAO;AAAA,UACL,SAAS;AAAA,UACT,OAAO;AAAA,UACP,aAAa;AAAA,UACb,UAAU;AAAA,UACV,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,QAAY;AAGtC,MAAAD,IAAeC;AAAA,IACjB;AAGA,UAAM7F,IAAa2E,EAAkBiB,EAAa,WAAWA,EAAa,KAAK;AAE/E,IAAI5F,EAAW,WAAW,KACxB2F,EAAS,KAAK,gCAAgC;AAGhD,UAAMG,IAAc9F,EAAW,OAAO,CAACiC,GAAKlB,MAAMkB,IAAMlB,EAAE,YAAY,CAAC,GACjEgF,IAAejG,EAAe0F,CAAM,GACpCQ,IAAWJ,EAAa,YAAYL,EAAiBC,GAAQxF,EAAW,IAAI,CAAAe,MAAKA,EAAE,EAAE,CAAC;AAE5F,QAAIkF,GACAC;AAEJ,QAAI;AAEF,cAAQV,GAAA;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,UAAAS,IAAUlG,EAAUC,GAAY,EAAE,GAAG4F,GAAc,QAAAJ,GAAQ;AAC3D;AAAA,QAEF,KAAK;AACH,UAAAS,IAAUpE;AAAA,YACR7B;AAAA,YACA4F;AAAA,YACAlB,KAAA,gBAAAA,EAAM,KAAK;AAAA,UAAc;AAE3B;AAAA,QAEF,KAAK;AACH,UAAAuB,IAAU9D,EAAanC,GAAY4F,CAAY;AAC/C;AAAA,QAEF,KAAK;AACH,UAAAK,IAAUvD,EAAa1C,GAAY4F,CAAY;AAC/C;AAAA,QAEF,KAAK;AACH,gBAAM7C,IAASH,EAAa5C,CAAU;AACtC,UAAAkG,IAAO,IAAI,KAAK,CAACnD,CAAM,GAAG,EAAE,MAAMgD,EAAa,UAAU;AACzD;AAAA,MAAA;AAIJ,MAAIE,KAAW,CAACC,MACdA,IAAO,IAAI,KAAK,CAACD,CAAO,GAAG,EAAE,MAAMF,EAAa,UAAU;AAAA,IAG9D,SAASI,GAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO,kBAAmBA,EAAgB,OAAO;AAAA,QACjD,aAAa;AAAA,QACb,UAAU;AAAA,QACV,aAAanG,EAAW;AAAA,QACxB,YAAY8F;AAAA,QACZ,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MAAY;AAAA,IAEtC;AAEA,UAAMhC,IAAuB;AAAA,MAC3B,SAAS;AAAA,MACT,SAAAmC;AAAA,MACA,MAAAC;AAAA,MACA,aAAaH,EAAa;AAAA,MAC1B,UAAAC;AAAA,MACA,aAAahG,EAAW;AAAA,MACxB,YAAY8F;AAAA,MACZ,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MACtB,UAAUH,EAAS,SAAS,IAAIA,IAAW;AAAA,IAAA;AAI7C,WAAIlB,KACFA,EAAYX,CAAM,GAGbA;AAAA,EACT;AAKA,WAASsC,EAAaF,GAAYF,GAAwB;AACxD,UAAMK,IAAM,IAAI,gBAAgBH,CAAI,GAC9BI,IAAO,SAAS,cAAc,GAAG;AACvC,IAAAA,EAAK,OAAOD,GACZC,EAAK,WAAWN,GAChB,SAAS,KAAK,YAAYM,CAAI,GAC9BA,EAAK,MAAA,GACL,SAAS,KAAK,YAAYA,CAAI,GAC9B,IAAI,gBAAgBD,CAAG;AAAA,EACzB;AA0HA,SAAO;AAAA,IACL,UAAUrC;AAAA,IAEV,OAAOuC,GAAoB;AACzB,MAAA7B,IAAO6B,GACPA,EAAI,IAAI,KAAK,+CAA+CpC,EAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IAClF;AAAA,IAEA,YAAY;AACV,MAAAO,IAAO;AAAA,IACT;AAAA,IAEA,KAhIqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQrB,OAAOc,GAAsBvF,IAAsC,IAAkB;AACnF,cAAMuG,IAAiC;AAAA,UACrC,QAAAhB;AAAA,UACA,gBAAgB;AAAA,UAChB,kBAAkB;AAAA,UAClB,iBAAAlF;AAAA,UACA,aAAa;AAAA,UACb,GAAGL;AAAA,QAAA,GAGC6D,IAAS4B,EAASc,CAAW;AAGnC,eAAIlC,KAAgBR,EAAO,WAAWA,EAAO,QAC3CsC,EAAatC,EAAO,MAAMA,EAAO,QAAQ,GAGpCA;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,SAAS0B,GAAsBvF,IAAsC,IAAkB;AACrF,cAAMuG,IAAiC;AAAA,UACrC,QAAAhB;AAAA,UACA,gBAAgB;AAAA,UAChB,kBAAkB;AAAA,UAClB,iBAAAlF;AAAA,UACA,aAAa;AAAA,UACb,GAAGL;AAAA,QAAA,GAEC6D,IAAS4B,EAASc,CAAW;AAEnC,eAAI1C,EAAO,WAAWA,EAAO,QAC3BsC,EAAatC,EAAO,MAAMA,EAAO,QAAQ,GAGpCA;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM7D,IAAsC,IAAkB;AAC5D,eAAOyF,EAAS,EAAE,QAAQ,OAAO,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MACjI;AAAA;AAAA;AAAA;AAAA,MAKA,OAAOA,IAAsC,IAAkB;AAC7D,eAAOyF,EAAS,EAAE,QAAQ,QAAQ,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MAClI;AAAA;AAAA;AAAA;AAAA,MAKA,SAASA,IAAsC,IAAkB;AAC/D,eAAOyF,EAAS,EAAE,QAAQ,UAAU,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MACpI;AAAA;AAAA;AAAA;AAAA,MAKA,SAASA,IAAsC,IAAkB;AAC/D,eAAOyF,EAAS,EAAE,QAAQ,UAAU,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MACpI;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQA,IAAsC,IAAkB;AAC9D,eAAOyF,EAAS,EAAE,QAAQ,QAAQ,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MAClI;AAAA;AAAA;AAAA;AAAA,MAKA,SAASA,IAAsC,IAAkB;AAC/D,eAAOyF,EAAS,EAAE,QAAQ,UAAU,gBAAgB,IAAM,kBAAkB,IAAM,iBAAApF,GAAiB,aAAa,IAAM,GAAGL,GAAS;AAAA,MACpI;AAAA;AAAA;AAAA;AAAA,MAKA,aAA6B;AAC3B,eAAO,CAAC,GAAGkE,CAAO;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA,MAKA,eAAeqB,GAA+B;AAC5C,eAAOrB,EAAQ,SAASqB,CAAM;AAAA,MAChC;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAgBA,GAAsB;AACpC,eAAO1F,EAAe0F,CAAM;AAAA,MAC9B;AAAA,IAAA;AAAA,EAeK;AAET;"}
|
|
1
|
+
{"version":3,"file":"data-export.js","sources":["../../src/plugins/data-export/formatters.ts","../../src/plugins/data-export/index.ts"],"sourcesContent":["/**\n * Data Export Formatters\n * \n * Handles conversion of chart data to various output formats.\n * \n * @module plugins/data-export/formatters\n */\n\nimport type { \n DataExportOptions, \n ExportFormat, \n FormatConfig,\n SeriesExportInfo,\n MatlabExportData,\n NumpyExportData\n} from \"./types\";\n\n// ============================================\n// Format Configurations\n// ============================================\n\nexport const FORMAT_CONFIGS: Record<ExportFormat, FormatConfig> = {\n csv: {\n mimeType: 'text/csv',\n extension: '.csv'\n },\n tsv: {\n mimeType: 'text/tab-separated-values',\n extension: '.tsv'\n },\n json: {\n mimeType: 'application/json',\n extension: '.json'\n },\n matlab: {\n mimeType: 'application/json',\n extension: '.mat.json'\n },\n python: {\n mimeType: 'application/json',\n extension: '.npy.json'\n },\n xlsx: {\n mimeType: 'text/csv;charset=utf-8',\n extension: '.csv',\n bom: '\\uFEFF' // UTF-8 BOM for Excel\n },\n binary: {\n mimeType: 'application/octet-stream',\n extension: '.bin',\n binary: true\n }\n};\n\n// ============================================\n// CSV/TSV Formatter\n// ============================================\n\n/**\n * Format data as CSV or TSV\n */\nexport function formatCSV(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const {\n delimiter = options.format === 'tsv' ? '\\t' : ',',\n lineEnding = '\\n',\n includeHeaders = true,\n includeTimestamp = false,\n includeMetadata = false,\n metadata = {},\n precision = 6,\n scientificThreshold = 1e6\n } = options;\n\n const lines: string[] = [];\n const bom = options.format === 'xlsx' ? FORMAT_CONFIGS.xlsx.bom : '';\n\n // Add metadata as comments (if supported)\n if (includeMetadata && Object.keys(metadata).length > 0) {\n lines.push(`# Velo Plot Data Export`);\n if (includeTimestamp) {\n lines.push(`# Timestamp: ${new Date().toISOString()}`);\n }\n Object.entries(metadata).forEach(([key, value]) => {\n lines.push(`# ${key}: ${value}`);\n });\n lines.push('');\n }\n\n // Generate headers\n if (includeHeaders) {\n const headers: string[] = [];\n seriesData.forEach(s => {\n const prefix = seriesData.length > 1 ? `${s.name || s.id}_` : '';\n headers.push(`${prefix}x`, `${prefix}y`);\n \n // Add additional columns if present\n if (s.data.y2) headers.push(`${prefix}y2`);\n if (s.data.yError) headers.push(`${prefix}yError`);\n if (s.data.open) headers.push(`${prefix}open`, `${prefix}high`, `${prefix}low`, `${prefix}close`);\n });\n lines.push(headers.join(delimiter));\n }\n\n // Find max length\n const maxLength = Math.max(...seriesData.map(s => s.data.x.length));\n\n // Generate data rows\n for (let i = 0; i < maxLength; i++) {\n const row: string[] = [];\n \n seriesData.forEach(s => {\n const { x, y, y2, yError, open, high, low, close } = s.data;\n \n if (i < x.length) {\n row.push(\n formatNumber(x[i], precision, scientificThreshold),\n formatNumber(y[i], precision, scientificThreshold)\n );\n if (y2) row.push(formatNumber(y2[i], precision, scientificThreshold));\n if (yError) row.push(formatNumber(yError[i], precision, scientificThreshold));\n if (open && high && low && close) {\n row.push(\n formatNumber(open[i], precision, scientificThreshold),\n formatNumber(high[i], precision, scientificThreshold),\n formatNumber(low[i], precision, scientificThreshold),\n formatNumber(close[i], precision, scientificThreshold)\n );\n }\n } else {\n row.push('', '');\n if (s.data.y2) row.push('');\n if (s.data.yError) row.push('');\n if (s.data.open) row.push('', '', '', '');\n }\n });\n \n lines.push(row.join(delimiter));\n }\n\n return bom + lines.join(lineEnding);\n}\n\n// ============================================\n// JSON Formatter\n// ============================================\n\n/**\n * Format data as JSON\n */\nexport function formatJSON(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions,\n viewBounds?: { xMin: number; xMax: number; yMin: number; yMax: number }\n): string {\n const {\n precision = 6,\n prettyPrint = true,\n includeMetadata = true,\n metadata = {}\n } = options;\n\n const exportData: Record<string, unknown> = {\n version: '1.0',\n exportDate: new Date().toISOString(),\n format: 'velo-plot-json'\n };\n\n if (includeMetadata) {\n exportData.metadata = {\n ...metadata,\n seriesCount: seriesData.length,\n totalPoints: seriesData.reduce((sum, s) => sum + s.pointCount, 0)\n };\n }\n\n if (viewBounds) {\n exportData.viewBounds = viewBounds;\n }\n\n exportData.series = seriesData.map(s => ({\n id: s.id,\n name: s.name || s.id,\n type: s.type,\n pointCount: s.pointCount,\n yAxisId: s.yAxisId,\n style: s.style,\n data: {\n x: roundArray(Array.from(s.data.x), precision),\n y: roundArray(Array.from(s.data.y), precision),\n ...(s.data.y2 && { y2: roundArray(Array.from(s.data.y2), precision) }),\n ...(s.data.yError && { yError: roundArray(Array.from(s.data.yError), precision) }),\n ...(s.data.open && { \n open: roundArray(Array.from(s.data.open), precision),\n high: roundArray(Array.from(s.data.high!), precision),\n low: roundArray(Array.from(s.data.low!), precision),\n close: roundArray(Array.from(s.data.close!), precision)\n })\n }\n }));\n\n return JSON.stringify(exportData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// MATLAB Format\n// ============================================\n\n/**\n * Format data for MATLAB compatibility\n * Outputs JSON that can be easily loaded in MATLAB using jsondecode()\n */\nexport function formatMATLAB(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const { precision = 6, prettyPrint = true } = options;\n\n const matlabData: {\n format: string;\n version: string;\n created: string;\n variables: MatlabExportData[];\n } = {\n format: 'matlab-compatible-json',\n version: '1.0',\n created: new Date().toISOString(),\n variables: []\n };\n\n seriesData.forEach(s => {\n const xData = roundArray(Array.from(s.data.x), precision);\n const yData = roundArray(Array.from(s.data.y), precision);\n const safeName = sanitizeVariableName(s.name || s.id);\n\n // Create x variable\n matlabData.variables.push({\n name: `${safeName}_x`,\n type: 'double',\n size: [xData.length, 1],\n data: xData\n });\n\n // Create y variable\n matlabData.variables.push({\n name: `${safeName}_y`,\n type: 'double',\n size: [yData.length, 1],\n data: yData\n });\n\n // Create combined matrix variable\n matlabData.variables.push({\n name: safeName,\n type: 'double',\n size: [xData.length, 2],\n data: interleaveArrays(xData, yData)\n });\n });\n\n return JSON.stringify(matlabData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// Python/NumPy Format\n// ============================================\n\n/**\n * Format data for Python/NumPy compatibility\n * Outputs JSON that can be easily loaded in Python\n */\nexport function formatPython(\n seriesData: SeriesExportInfo[],\n options: DataExportOptions\n): string {\n const { precision = 6, prettyPrint = true } = options;\n\n const pythonData: {\n format: string;\n version: string;\n created: string;\n import_code: string;\n arrays: Record<string, NumpyExportData>;\n } = {\n format: 'numpy-compatible-json',\n version: '1.0',\n created: new Date().toISOString(),\n import_code: `\n# Load data in Python:\nimport json\nimport numpy as np\n\nwith open('data.npy.json', 'r') as f:\n data = json.load(f)\n\n# Access arrays:\n# x = np.array(data['arrays']['series_name']['x']['data'], dtype=np.float32)\n# y = np.array(data['arrays']['series_name']['y']['data'], dtype=np.float32)\n`.trim(),\n arrays: {}\n };\n\n seriesData.forEach(s => {\n const safeName = sanitizeVariableName(s.name || s.id);\n const xData = roundArray(Array.from(s.data.x), precision);\n const yData = roundArray(Array.from(s.data.y), precision);\n\n pythonData.arrays[safeName] = {\n dtype: 'float32',\n shape: [xData.length, 2],\n data: interleaveArrays(xData, yData),\n name: safeName\n };\n\n // Also provide separate x and y arrays\n pythonData.arrays[`${safeName}_x`] = {\n dtype: 'float32',\n shape: [xData.length],\n data: xData,\n name: `${safeName}_x`\n };\n\n pythonData.arrays[`${safeName}_y`] = {\n dtype: 'float32',\n shape: [yData.length],\n data: yData,\n name: `${safeName}_y`\n };\n });\n\n return JSON.stringify(pythonData, null, prettyPrint ? 2 : undefined);\n}\n\n// ============================================\n// Binary Format\n// ============================================\n\n/**\n * Format data as binary Float32Array\n * \n * Binary format structure:\n * - Header (32 bytes): magic number, version, series count, reserved\n * - Per series: name length (4 bytes), name (UTF-8), point count (4 bytes), x data, y data\n */\nexport function formatBinary(\n seriesData: SeriesExportInfo[]\n): ArrayBuffer {\n // Calculate total size\n let totalSize = 32; // Header\n \n seriesData.forEach(s => {\n const nameBytes = new TextEncoder().encode(s.name || s.id);\n totalSize += 4 + nameBytes.length; // name length + name\n totalSize += 4; // point count\n totalSize += s.data.x.length * 4 * 2; // x and y as Float32\n });\n \n const buffer = new ArrayBuffer(totalSize);\n const view = new DataView(buffer);\n const encoder = new TextEncoder();\n \n let offset = 0;\n \n // Header\n // Magic number: \"SCE1\" (Velo Plot v1)\n view.setUint8(offset++, 0x53); // S\n view.setUint8(offset++, 0x43); // C\n view.setUint8(offset++, 0x45); // E\n view.setUint8(offset++, 0x31); // 1\n \n // Version\n view.setUint32(offset, 1, true); offset += 4;\n \n // Series count\n view.setUint32(offset, seriesData.length, true); offset += 4;\n \n // Timestamp (milliseconds since epoch)\n const timestamp = Math.floor(Date.now() / 1000);\n view.setUint32(offset, timestamp, true); offset += 4;\n \n // Reserved (16 bytes)\n offset += 16;\n \n // Series data\n seriesData.forEach(s => {\n const nameBytes = encoder.encode(s.name || s.id);\n \n // Name length\n view.setUint32(offset, nameBytes.length, true); offset += 4;\n \n // Name\n new Uint8Array(buffer, offset, nameBytes.length).set(nameBytes);\n offset += nameBytes.length;\n \n // Point count\n const pointCount = s.data.x.length;\n view.setUint32(offset, pointCount, true); offset += 4;\n \n // X data\n const xFloat32 = new Float32Array(buffer, offset, pointCount);\n for (let i = 0; i < pointCount; i++) {\n xFloat32[i] = s.data.x[i];\n }\n offset += pointCount * 4;\n \n // Y data\n const yFloat32 = new Float32Array(buffer, offset, pointCount);\n for (let i = 0; i < pointCount; i++) {\n yFloat32[i] = s.data.y[i];\n }\n offset += pointCount * 4;\n });\n \n return buffer;\n}\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Format a number with appropriate precision\n */\nfunction formatNumber(value: number, precision: number, scientificThreshold: number): string {\n if (!isFinite(value)) {\n return isNaN(value) ? 'NaN' : (value > 0 ? 'Inf' : '-Inf');\n }\n \n const absValue = Math.abs(value);\n if (absValue !== 0 && (absValue >= scientificThreshold || absValue < 1e-4)) {\n return value.toExponential(precision);\n }\n \n return value.toFixed(precision);\n}\n\n/**\n * Round array values to specified precision\n */\nfunction roundArray(arr: number[], precision: number): number[] {\n const factor = Math.pow(10, precision);\n return arr.map(v => Math.round(v * factor) / factor);\n}\n\n/**\n * Sanitize string for use as variable name\n */\nfunction sanitizeVariableName(name: string): string {\n return name\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^[0-9]/, '_$&')\n .substring(0, 63);\n}\n\n/**\n * Interleave two arrays [a0, b0, a1, b1, ...]\n */\nfunction interleaveArrays(a: number[], b: number[]): number[] {\n const result: number[] = [];\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n if (i < a.length) result.push(a[i]);\n if (i < b.length) result.push(b[i]);\n }\n return result;\n}\n","/**\n * Velo Plot - Data Export Plugin\n * \n * Advanced data export capabilities for scientific chart data.\n * Supports multiple formats including CSV, JSON, MATLAB, and Python.\n * \n * @module plugins/data-export\n * \n * @example\n * ```typescript\n * import { createChart } from 'velo-plot';\n * import { PluginDataExport } from 'velo-plot/plugins/data-export';\n * \n * const chart = createChart({ container });\n * chart.use(PluginDataExport({\n * defaultFormat: 'csv',\n * autoDownload: true\n * }));\n * \n * // Export visible data\n * const result = await chart.export('csv', { range: 'visible' });\n * \n * // Export all data to MATLAB format\n * await chart.export('matlab', { \n * seriesIds: ['voltage', 'current'],\n * includeMetadata: true \n * });\n * ```\n */\n\nimport type { PluginManifest, ChartPlugin, PluginContext } from \"../types\";\nimport type { \n PluginDataExportConfig, \n DataExportOptions, \n ExportResult,\n ExportFormat,\n SeriesExportInfo,\n ExportRange\n} from \"./types\";\nimport { \n FORMAT_CONFIGS,\n formatCSV, \n formatJSON, \n formatMATLAB, \n formatPython,\n formatBinary\n} from \"./formatters\";\n\n// Re-export types\nexport * from \"./types\";\n\n// ============================================\n// Plugin Definition\n// ============================================\n\nconst manifestDataExport: PluginManifest = {\n name: \"velo-plot-data-export\",\n version: \"1.0.0\",\n description: \"Advanced data export capabilities for velo-plot\",\n author: \"Velo Plot Team\",\n provides: [\"export\"],\n tags: [\"export\", \"csv\", \"json\", \"matlab\", \"python\", \"data\"],\n};\n\n/**\n * Velo Plot Data Export Plugin\n * \n * Provides comprehensive data export functionality with support for\n * multiple scientific and standard data formats.\n * \n * @param config - Plugin configuration options\n * @returns ChartPlugin instance\n */\nexport function PluginDataExport(\n config: PluginDataExportConfig = {}\n): ChartPlugin<PluginDataExportConfig> {\n \n const {\n formats = ['csv', 'tsv', 'json', 'matlab', 'python', 'xlsx', 'binary'],\n defaultFormat = 'csv',\n defaultPrecision = 6,\n includeMetadata = true,\n autoDownload = false,\n filenameGenerator,\n beforeExport,\n afterExport\n } = config;\n\n let _ctx: PluginContext | null = null;\n\n // ============================================\n // Internal Helpers\n // ============================================\n\n /**\n * Collect series data for export\n */\n function collectSeriesData(\n seriesIds?: string[],\n range?: ExportRange\n ): SeriesExportInfo[] {\n if (!_ctx) return [];\n\n const allSeries = _ctx.data.getAllSeries();\n const seriesToExport = seriesIds \n ? allSeries.filter(s => seriesIds.includes(s.getId()))\n : allSeries;\n\n return seriesToExport.map(s => {\n let data = s.getData();\n \n // Filter by range if specified\n if (range === 'visible' && data) {\n const bounds = _ctx!.data.getViewBounds();\n const filteredIndices: number[] = [];\n \n for (let i = 0; i < data.x.length; i++) {\n if (data.x[i] >= bounds.xMin && data.x[i] <= bounds.xMax) {\n filteredIndices.push(i);\n }\n }\n \n if (filteredIndices.length > 0 && filteredIndices.length < data.x.length) {\n const newX = new Float32Array(filteredIndices.length);\n const newY = new Float32Array(filteredIndices.length);\n \n filteredIndices.forEach((idx, i) => {\n newX[i] = data!.x[idx];\n newY[i] = data!.y[idx];\n });\n \n data = { ...data, x: newX, y: newY };\n }\n }\n\n return {\n id: s.getId(),\n name: s.getName?.() ?? s.getId(),\n type: s.getType(),\n data: data || { x: new Float32Array(0), y: new Float32Array(0) },\n pointCount: data?.x.length ?? 0,\n style: s.getStyle() as Record<string, unknown>,\n yAxisId: s.getYAxisId?.()\n };\n });\n }\n\n /**\n * Generate filename based on format and content\n */\n function generateFilename(format: ExportFormat, seriesIds: string[]): string {\n if (filenameGenerator) {\n return filenameGenerator(format, seriesIds);\n }\n \n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 19);\n const seriesPart = seriesIds.length <= 3 \n ? seriesIds.join('_') \n : `${seriesIds.length}_series`;\n \n const config = FORMAT_CONFIGS[format];\n return `velo-plot_${seriesPart}_${timestamp}${config.extension}`;\n }\n\n /**\n * Execute export operation\n */\n function doExport(options: DataExportOptions): ExportResult {\n const format = options.format ?? defaultFormat;\n const warnings: string[] = [];\n\n // Validate format\n if (!formats.includes(format)) {\n return {\n success: false,\n error: `Format '${format}' is not enabled. Available: ${formats.join(', ')}`,\n contentType: 'text/plain',\n filename: 'error.txt',\n seriesCount: 0,\n pointCount: 0,\n timestamp: new Date().toISOString()\n };\n }\n\n // Apply beforeExport hook\n let finalOptions: DataExportOptions = { ...options, precision: options.precision ?? defaultPrecision };\n if (beforeExport) {\n const hookResult = beforeExport(finalOptions);\n if (hookResult === false) {\n return {\n success: false,\n error: 'Export cancelled by beforeExport hook',\n contentType: 'text/plain',\n filename: 'cancelled.txt',\n seriesCount: 0,\n pointCount: 0,\n timestamp: new Date().toISOString()\n };\n }\n finalOptions = hookResult;\n }\n\n // Collect data\n const seriesData = collectSeriesData(finalOptions.seriesIds, finalOptions.range);\n \n if (seriesData.length === 0) {\n warnings.push('No series data found to export');\n }\n\n const totalPoints = seriesData.reduce((sum, s) => sum + s.pointCount, 0);\n const formatConfig = FORMAT_CONFIGS[format];\n const filename = finalOptions.filename ?? generateFilename(format, seriesData.map(s => s.id));\n\n let content: string | undefined;\n let blob: Blob | undefined;\n\n try {\n // Format data\n switch (format) {\n case 'csv':\n case 'tsv':\n case 'xlsx':\n content = formatCSV(seriesData, { ...finalOptions, format });\n break;\n \n case 'json':\n content = formatJSON(\n seriesData, \n finalOptions,\n _ctx?.data.getViewBounds()\n );\n break;\n \n case 'matlab':\n content = formatMATLAB(seriesData, finalOptions);\n break;\n \n case 'python':\n content = formatPython(seriesData, finalOptions);\n break;\n \n case 'binary':\n const buffer = formatBinary(seriesData);\n blob = new Blob([buffer], { type: formatConfig.mimeType });\n break;\n }\n\n // Create blob for string content\n if (content && !blob) {\n blob = new Blob([content], { type: formatConfig.mimeType });\n }\n\n } catch (error) {\n return {\n success: false,\n error: `Export failed: ${(error as Error).message}`,\n contentType: 'text/plain',\n filename: 'error.txt',\n seriesCount: seriesData.length,\n pointCount: totalPoints,\n timestamp: new Date().toISOString()\n };\n }\n\n const result: ExportResult = {\n success: true,\n content,\n blob,\n contentType: formatConfig.mimeType,\n filename,\n seriesCount: seriesData.length,\n pointCount: totalPoints,\n timestamp: new Date().toISOString(),\n warnings: warnings.length > 0 ? warnings : undefined\n };\n\n // Apply afterExport hook\n if (afterExport) {\n afterExport(result);\n }\n\n return result;\n }\n\n /**\n * Download a blob as a file\n */\n function downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n // ============================================\n // Plugin Implementation\n // ============================================\n\n const pluginApi: any = {\n /**\n * Export chart data to specified format\n * \n * @param format - Export format\n * @param options - Export options\n * @returns Export result with content/blob\n */\n export(format: ExportFormat, options: Partial<DataExportOptions> = {}): ExportResult {\n const fullOptions: DataExportOptions = {\n format,\n includeHeaders: true,\n includeTimestamp: true,\n includeMetadata,\n prettyPrint: true,\n ...options\n };\n\n const result = doExport(fullOptions);\n\n // Auto download if enabled and successful\n if (autoDownload && result.success && result.blob) {\n downloadBlob(result.blob, result.filename);\n }\n\n return result;\n },\n\n /**\n * Export and immediately download\n * \n * @param format - Export format\n * @param options - Export options\n */\n download(format: ExportFormat, options: Partial<DataExportOptions> = {}): ExportResult {\n const fullOptions: DataExportOptions = {\n format,\n includeHeaders: true,\n includeTimestamp: true,\n includeMetadata,\n prettyPrint: true,\n ...options\n };\n const result = doExport(fullOptions);\n \n if (result.success && result.blob) {\n downloadBlob(result.blob, result.filename);\n }\n \n return result;\n },\n\n /**\n * Export to CSV format\n */\n toCSV(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'csv', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to JSON format\n */\n toJSON(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'json', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to MATLAB format\n */\n toMATLAB(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'matlab', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to Python/NumPy format\n */\n toPython(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'python', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to Excel-compatible CSV\n */\n toExcel(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'xlsx', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Export to binary format\n */\n toBinary(options: Partial<DataExportOptions> = {}): ExportResult {\n return doExport({ format: 'binary', includeHeaders: true, includeTimestamp: true, includeMetadata, prettyPrint: true, ...options });\n },\n\n /**\n * Get available export formats\n */\n getFormats(): ExportFormat[] {\n return [...formats];\n },\n\n /**\n * Check if a format is supported\n */\n supportsFormat(format: ExportFormat): boolean {\n return formats.includes(format);\n },\n\n /**\n * Get format configuration\n */\n getFormatConfig(format: ExportFormat) {\n return FORMAT_CONFIGS[format];\n }\n };\n\n return {\n manifest: manifestDataExport,\n\n onInit(ctx: PluginContext) {\n _ctx = ctx;\n ctx.log.info(`DataExport plugin initialized with formats: ${formats.join(', ')}`);\n },\n\n onDestroy() {\n _ctx = null;\n },\n\n api: pluginApi\n };\n}\n\nexport default PluginDataExport;\n"],"names":["FORMAT_CONFIGS","formatCSV","seriesData","options","delimiter","lineEnding","includeHeaders","includeTimestamp","includeMetadata","metadata","precision","scientificThreshold","lines","bom","key","value","headers","s","prefix","maxLength","i","row","x","y","y2","yError","open","high","low","close","formatNumber","formatJSON","viewBounds","prettyPrint","exportData","sum","roundArray","formatMATLAB","matlabData","xData","yData","safeName","sanitizeVariableName","interleaveArrays","formatPython","pythonData","formatBinary","totalSize","nameBytes","buffer","view","encoder","offset","timestamp","pointCount","xFloat32","yFloat32","absValue","arr","factor","v","name","a","b","result","len","manifestDataExport","PluginDataExport","config","formats","defaultFormat","defaultPrecision","autoDownload","filenameGenerator","beforeExport","afterExport","_ctx","collectSeriesData","seriesIds","range","allSeries","_a","_b","data","bounds","filteredIndices","newX","newY","idx","generateFilename","format","seriesPart","doExport","warnings","finalOptions","hookResult","totalPoints","formatConfig","filename","content","blob","error","downloadBlob","url","link","ctx","fullOptions"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './data-transform/index'
|
|
2
|
-
import
|
|
3
|
-
export default
|
|
2
|
+
import VeloPlot from './data-transform/index'
|
|
3
|
+
export default VeloPlot
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { c as S, d as T } from "../math-Ddm2EZjj.js";
|
|
2
|
-
import { s as $, m as k } from "../utils-
|
|
2
|
+
import { s as $, m as k } from "../utils-Dx0h0bgQ.js";
|
|
3
3
|
const z = {
|
|
4
4
|
name: "data-transform",
|
|
5
5
|
version: "1.0.0",
|
|
6
6
|
description: "Advanced data transformation pipeline",
|
|
7
7
|
provides: ["data-transform", "processing"],
|
|
8
|
-
author: "
|
|
8
|
+
author: "Velo Plot Team"
|
|
9
9
|
};
|
|
10
10
|
function X(y = {}) {
|
|
11
11
|
const v = {
|
|
@@ -16,7 +16,7 @@ function X(y = {}) {
|
|
|
16
16
|
const g = /* @__PURE__ */ new Map();
|
|
17
17
|
async function b(t, e) {
|
|
18
18
|
if (!u) return;
|
|
19
|
-
const
|
|
19
|
+
const l = u.chart, s = l.getSeries(t);
|
|
20
20
|
if (!s)
|
|
21
21
|
throw new Error(`Series ${t} not found`);
|
|
22
22
|
if (!g.has(t)) {
|
|
@@ -29,25 +29,25 @@ function X(y = {}) {
|
|
|
29
29
|
const n = g.get(t);
|
|
30
30
|
let a = new Float32Array(n.x.buffer.slice(0)), r = new Float32Array(n.y.buffer.slice(0));
|
|
31
31
|
for (const o of e) {
|
|
32
|
-
const
|
|
33
|
-
a =
|
|
32
|
+
const i = await A(a, r, o);
|
|
33
|
+
a = i.x, r = i.y;
|
|
34
34
|
}
|
|
35
|
-
|
|
35
|
+
l.updateSeries(t, { x: a, y: r });
|
|
36
36
|
}
|
|
37
|
-
async function A(t, e,
|
|
38
|
-
const s =
|
|
39
|
-
switch (
|
|
37
|
+
async function A(t, e, l) {
|
|
38
|
+
const s = l.parameters || l;
|
|
39
|
+
switch (l.type) {
|
|
40
40
|
case "normalize": {
|
|
41
41
|
const n = s.range || [0, 1];
|
|
42
42
|
let a = 1 / 0, r = -1 / 0;
|
|
43
43
|
for (let c = 0; c < e.length; c++)
|
|
44
44
|
e[c] < a && (a = e[c]), e[c] > r && (r = e[c]);
|
|
45
|
-
const o = r - a,
|
|
45
|
+
const o = r - a, i = n[1] - n[0], f = new Float32Array(e.length);
|
|
46
46
|
if (o === 0)
|
|
47
47
|
f.fill(n[0]);
|
|
48
48
|
else
|
|
49
49
|
for (let c = 0; c < e.length; c++)
|
|
50
|
-
f[c] = n[0] + (e[c] - a) / o *
|
|
50
|
+
f[c] = n[0] + (e[c] - a) / o * i;
|
|
51
51
|
return { x: t, y: f };
|
|
52
52
|
}
|
|
53
53
|
case "smooth":
|
|
@@ -93,15 +93,15 @@ function X(y = {}) {
|
|
|
93
93
|
return { x: t, y: a };
|
|
94
94
|
}
|
|
95
95
|
default:
|
|
96
|
-
return console.warn(`Unknown transform type: ${
|
|
96
|
+
return console.warn(`Unknown transform type: ${l.type}`), { x: t, y: e };
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
function M(t, e,
|
|
100
|
-
if (t.length <= 1 ||
|
|
101
|
-
const s = new Float32Array(
|
|
102
|
-
for (let
|
|
103
|
-
const f = a +
|
|
104
|
-
s[
|
|
99
|
+
function M(t, e, l) {
|
|
100
|
+
if (t.length <= 1 || l <= 1) return { x: t, y: e };
|
|
101
|
+
const s = new Float32Array(l), n = new Float32Array(l), a = t[0], o = (t[t.length - 1] - a) / (l - 1);
|
|
102
|
+
for (let i = 0; i < l; i++) {
|
|
103
|
+
const f = a + i * o;
|
|
104
|
+
s[i] = f;
|
|
105
105
|
let c = 0, w = t.length - 2, m = 0;
|
|
106
106
|
for (; c <= w; ) {
|
|
107
107
|
const p = c + w >> 1;
|
|
@@ -112,7 +112,7 @@ function X(y = {}) {
|
|
|
112
112
|
t[p] < f ? c = p + 1 : w = p - 1;
|
|
113
113
|
}
|
|
114
114
|
const h = t[m], F = t[m + 1], d = e[m], D = e[m + 1], Y = (f - h) / (F - h);
|
|
115
|
-
n[
|
|
115
|
+
n[i] = d + Y * (D - d);
|
|
116
116
|
}
|
|
117
117
|
return { x: s, y: n };
|
|
118
118
|
}
|