selva-shared 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/components/AppLayout.svelte +439 -0
- package/dist/components/AppLayout.svelte.d.ts +17 -0
- package/dist/components/CollapsedPanelStrip.svelte +67 -0
- package/dist/components/CollapsedPanelStrip.svelte.d.ts +11 -0
- package/dist/components/ComputeMessages.svelte +172 -0
- package/dist/components/ComputeMessages.svelte.d.ts +7 -0
- package/dist/components/ErrorScreen.svelte +55 -0
- package/dist/components/ErrorScreen.svelte.d.ts +9 -0
- package/dist/components/StateManager.svelte +318 -0
- package/dist/components/StateManager.svelte.d.ts +9 -0
- package/dist/components/Viewer.svelte +207 -0
- package/dist/components/Viewer.svelte.d.ts +12 -0
- package/dist/components/layout/FooterItemRenderer.svelte +20 -0
- package/dist/components/layout/FooterItemRenderer.svelte.d.ts +7 -0
- package/dist/components/layout/PageContainer.svelte +36 -0
- package/dist/components/layout/PageContainer.svelte.d.ts +12 -0
- package/dist/components/layout/PageFooter.svelte +223 -0
- package/dist/components/layout/PageFooter.svelte.d.ts +9 -0
- package/dist/components/layout/PageHeader.svelte +89 -0
- package/dist/components/layout/PageHeader.svelte.d.ts +12 -0
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +4 -0
- package/dist/components/preview/ChartOutput.svelte +257 -0
- package/dist/components/preview/ChartOutput.svelte.d.ts +8 -0
- package/dist/components/preview/Group.svelte +121 -0
- package/dist/components/preview/Group.svelte.d.ts +23 -0
- package/dist/components/preview/InputControl.svelte +119 -0
- package/dist/components/preview/InputControl.svelte.d.ts +11 -0
- package/dist/components/preview/OutputDisplay.svelte +296 -0
- package/dist/components/preview/OutputDisplay.svelte.d.ts +9 -0
- package/dist/components/preview/TabBar.svelte +36 -0
- package/dist/components/preview/TabBar.svelte.d.ts +8 -0
- package/dist/components/preview/TabContent.svelte +124 -0
- package/dist/components/preview/TabContent.svelte.d.ts +13 -0
- package/dist/components/preview/TabLayout.svelte +109 -0
- package/dist/components/preview/TabLayout.svelte.d.ts +13 -0
- package/dist/components/preview/index.d.ts +3 -0
- package/dist/components/preview/index.js +4 -0
- package/dist/components/preview/inputs/CheckboxInput.svelte +29 -0
- package/dist/components/preview/inputs/CheckboxInput.svelte.d.ts +10 -0
- package/dist/components/preview/inputs/ColorInput.svelte +21 -0
- package/dist/components/preview/inputs/ColorInput.svelte.d.ts +7 -0
- package/dist/components/preview/inputs/DropdownInput.svelte +40 -0
- package/dist/components/preview/inputs/DropdownInput.svelte.d.ts +10 -0
- package/dist/components/preview/inputs/FileInput.svelte +358 -0
- package/dist/components/preview/inputs/FileInput.svelte.d.ts +10 -0
- package/dist/components/preview/inputs/NumberInput.svelte +152 -0
- package/dist/components/preview/inputs/NumberInput.svelte.d.ts +11 -0
- package/dist/components/preview/inputs/TextInput.svelte +74 -0
- package/dist/components/preview/inputs/TextInput.svelte.d.ts +11 -0
- package/dist/components/preview/inputs/index.d.ts +6 -0
- package/dist/components/preview/inputs/index.js +6 -0
- package/dist/components/ui/CalculateButton.svelte +56 -0
- package/dist/components/ui/CalculateButton.svelte.d.ts +9 -0
- package/dist/components/ui/SolvingIndicator.svelte +55 -0
- package/dist/components/ui/SolvingIndicator.svelte.d.ts +6 -0
- package/dist/components/ui/StateDisplay.svelte +106 -0
- package/dist/components/ui/StateDisplay.svelte.d.ts +10 -0
- package/dist/components/ui/alert/alert-description.svelte +23 -0
- package/dist/components/ui/alert/alert-description.svelte.d.ts +5 -0
- package/dist/components/ui/alert/alert-title.svelte +20 -0
- package/dist/components/ui/alert/alert-title.svelte.d.ts +5 -0
- package/dist/components/ui/alert/alert.svelte +44 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +26 -0
- package/dist/components/ui/alert/index.d.ts +5 -0
- package/dist/components/ui/alert/index.js +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
- package/dist/components/ui/alert-dialog/alert-dialog-action.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
- package/dist/components/ui/alert-dialog/alert-dialog-cancel.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
- package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +8 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
- package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +5 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
- package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
- package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
- package/dist/components/ui/alert-dialog/alert-dialog-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/alert-dialog/index.d.ts +12 -0
- package/dist/components/ui/alert-dialog/index.js +15 -0
- package/dist/components/ui/badge/badge.svelte +50 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
- package/dist/components/ui/badge/index.d.ts +2 -0
- package/dist/components/ui/badge/index.js +2 -0
- package/dist/components/ui/button/button.svelte +83 -0
- package/dist/components/ui/button/button.svelte.d.ts +67 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +4 -0
- package/dist/components/ui/button-group/button-group-separator.svelte +20 -0
- package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +13 -0
- package/dist/components/ui/button-group/button-group-text.svelte +30 -0
- package/dist/components/ui/button-group/button-group-text.svelte.d.ts +11 -0
- package/dist/components/ui/button-group/button-group.svelte +46 -0
- package/dist/components/ui/button-group/button-group.svelte.d.ts +26 -0
- package/dist/components/ui/button-group/index.d.ts +4 -0
- package/dist/components/ui/button-group/index.js +6 -0
- package/dist/components/ui/card/card-action.svelte +20 -0
- package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-content.svelte +15 -0
- package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-description.svelte +20 -0
- package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-footer.svelte +20 -0
- package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-header.svelte +23 -0
- package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
- package/dist/components/ui/card/card-title.svelte +20 -0
- package/dist/components/ui/card/card-title.svelte.d.ts +5 -0
- package/dist/components/ui/card/card.svelte +23 -0
- package/dist/components/ui/card/card.svelte.d.ts +5 -0
- package/dist/components/ui/card/index.d.ts +8 -0
- package/dist/components/ui/card/index.js +10 -0
- package/dist/components/ui/checkbox/checkbox.svelte +36 -0
- package/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
- package/dist/components/ui/checkbox/index.d.ts +2 -0
- package/dist/components/ui/checkbox/index.js +4 -0
- package/dist/components/ui/collapsible/collapsible-content.svelte +7 -0
- package/dist/components/ui/collapsible/collapsible-content.svelte.d.ts +4 -0
- package/dist/components/ui/collapsible/collapsible-trigger.svelte +7 -0
- package/dist/components/ui/collapsible/collapsible-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/collapsible/collapsible.svelte +11 -0
- package/dist/components/ui/collapsible/collapsible.svelte.d.ts +4 -0
- package/dist/components/ui/collapsible/index.d.ts +4 -0
- package/dist/components/ui/collapsible/index.js +6 -0
- package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
- package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/context-menu/context-menu-content.svelte +25 -0
- package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +7 -0
- package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
- package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
- package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
- package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
- package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
- package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
- package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
- package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
- package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
- package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
- package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/index.d.ts +16 -0
- package/dist/components/ui/context-menu/index.js +19 -0
- package/dist/components/ui/dialog/dialog-close.svelte +7 -0
- package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-content.svelte +43 -0
- package/dist/components/ui/dialog/dialog-content.svelte.d.ts +11 -0
- package/dist/components/ui/dialog/dialog-description.svelte +17 -0
- package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-footer.svelte +20 -0
- package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +5 -0
- package/dist/components/ui/dialog/dialog-header.svelte +20 -0
- package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte +20 -0
- package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-title.svelte +17 -0
- package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte +7 -0
- package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dialog/index.d.ts +11 -0
- package/dist/components/ui/dialog/index.js +14 -0
- package/dist/components/ui/field/field-content.svelte +20 -0
- package/dist/components/ui/field/field-content.svelte.d.ts +5 -0
- package/dist/components/ui/field/field-description.svelte +25 -0
- package/dist/components/ui/field/field-description.svelte.d.ts +5 -0
- package/dist/components/ui/field/field-error.svelte +58 -0
- package/dist/components/ui/field/field-error.svelte.d.ts +12 -0
- package/dist/components/ui/field/field-group.svelte +23 -0
- package/dist/components/ui/field/field-group.svelte.d.ts +5 -0
- package/dist/components/ui/field/field-label.svelte +26 -0
- package/dist/components/ui/field/field-label.svelte.d.ts +10 -0
- package/dist/components/ui/field/field-legend.svelte +29 -0
- package/dist/components/ui/field/field-legend.svelte.d.ts +8 -0
- package/dist/components/ui/field/field-separator.svelte +38 -0
- package/dist/components/ui/field/field-separator.svelte.d.ts +9 -0
- package/dist/components/ui/field/field-set.svelte +24 -0
- package/dist/components/ui/field/field-set.svelte.d.ts +5 -0
- package/dist/components/ui/field/field-title.svelte +23 -0
- package/dist/components/ui/field/field-title.svelte.d.ts +5 -0
- package/dist/components/ui/field/field.svelte +53 -0
- package/dist/components/ui/field/field.svelte.d.ts +29 -0
- package/dist/components/ui/field/index.d.ts +11 -0
- package/dist/components/ui/field/index.js +13 -0
- package/dist/components/ui/index.d.ts +21 -0
- package/dist/components/ui/index.js +24 -0
- package/dist/components/ui/input/index.d.ts +2 -0
- package/dist/components/ui/input/index.js +4 -0
- package/dist/components/ui/input/input.svelte +52 -0
- package/dist/components/ui/input/input.svelte.d.ts +13 -0
- package/dist/components/ui/label/index.d.ts +2 -0
- package/dist/components/ui/label/index.js +4 -0
- package/dist/components/ui/label/label.svelte +20 -0
- package/dist/components/ui/label/label.svelte.d.ts +4 -0
- package/dist/components/ui/mode-toggle/index.d.ts +1 -0
- package/dist/components/ui/mode-toggle/index.js +1 -0
- package/dist/components/ui/mode-toggle/mode-toggle.svelte +16 -0
- package/dist/components/ui/mode-toggle/mode-toggle.svelte.d.ts +18 -0
- package/dist/components/ui/resizable/index.d.ts +4 -0
- package/dist/components/ui/resizable/index.js +6 -0
- package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
- package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
- package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
- package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
- package/dist/components/ui/scroll-area/index.d.ts +3 -0
- package/dist/components/ui/scroll-area/index.js +5 -0
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte +43 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
- package/dist/components/ui/select/index.d.ts +11 -0
- package/dist/components/ui/select/index.js +14 -0
- package/dist/components/ui/select/select-content.svelte +40 -0
- package/dist/components/ui/select/select-content.svelte.d.ts +8 -0
- package/dist/components/ui/select/select-group-heading.svelte +21 -0
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +10 -0
- package/dist/components/ui/select/select-group.svelte +7 -0
- package/dist/components/ui/select/select-group.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-item.svelte +38 -0
- package/dist/components/ui/select/select-item.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-label.svelte +20 -0
- package/dist/components/ui/select/select-label.svelte.d.ts +6 -0
- package/dist/components/ui/select/select-scroll-down-button.svelte +20 -0
- package/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-scroll-up-button.svelte +20 -0
- package/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-separator.svelte +18 -0
- package/dist/components/ui/select/select-separator.svelte.d.ts +4 -0
- package/dist/components/ui/select/select-trigger.svelte +29 -0
- package/dist/components/ui/select/select-trigger.svelte.d.ts +8 -0
- package/dist/components/ui/separator/index.d.ts +2 -0
- package/dist/components/ui/separator/index.js +4 -0
- package/dist/components/ui/separator/separator.svelte +21 -0
- package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
- package/dist/components/ui/slider/index.d.ts +2 -0
- package/dist/components/ui/slider/index.js +4 -0
- package/dist/components/ui/slider/slider.svelte +52 -0
- package/dist/components/ui/slider/slider.svelte.d.ts +5 -0
- package/dist/components/ui/sonner/index.d.ts +2 -0
- package/dist/components/ui/sonner/index.js +2 -0
- package/dist/components/ui/sonner/sonner.svelte +13 -0
- package/dist/components/ui/sonner/sonner.svelte.d.ts +4 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +4 -0
- package/dist/components/ui/switch/switch.svelte +29 -0
- package/dist/components/ui/switch/switch.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/index.d.ts +5 -0
- package/dist/components/ui/tabs/index.js +7 -0
- package/dist/components/ui/tabs/tabs-content.svelte +17 -0
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-list.svelte +16 -0
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs.svelte +19 -0
- package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
- package/dist/components/ui/textarea/index.d.ts +2 -0
- package/dist/components/ui/textarea/index.js +4 -0
- package/dist/components/ui/textarea/textarea.svelte +23 -0
- package/dist/components/ui/textarea/textarea.svelte.d.ts +5 -0
- package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
- package/dist/components/ui/theme-switcher/ThemeSwitcher.svelte.d.ts +3 -0
- package/dist/components/ui/theme-switcher/index.d.ts +1 -0
- package/dist/components/ui/theme-switcher/index.js +1 -0
- package/dist/composables/useFooterItem.svelte.d.ts +15 -0
- package/dist/composables/useFooterItem.svelte.js +31 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +6 -0
- package/dist/contexts/FOOTER_USAGE.md +164 -0
- package/dist/contexts/footerContext.svelte.d.ts +17 -0
- package/dist/contexts/footerContext.svelte.js +24 -0
- package/dist/dummy-output-values.d.ts +3 -0
- package/dist/dummy-output-values.js +53 -0
- package/dist/dummy-surface-chart.json +13 -0
- package/dist/example-schema-left-only.json +367 -0
- package/dist/example-schema-right-only.json +322 -0
- package/dist/example-schema.json +1582 -0
- package/dist/features/preview/handlers.d.ts +55 -0
- package/dist/features/preview/handlers.js +175 -0
- package/dist/features/preview/index.d.ts +2 -0
- package/dist/features/preview/index.js +2 -0
- package/dist/features/preview/notifications.d.ts +11 -0
- package/dist/features/preview/notifications.js +41 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +39 -0
- package/dist/stores/themeStore.svelte.d.ts +12 -0
- package/dist/stores/themeStore.svelte.js +42 -0
- package/dist/styles/base.css +142 -0
- package/dist/styles/themes/cyberpunk.css +98 -0
- package/dist/styles/themes/neutral.css +72 -0
- package/dist/styles/themes/ocean.css +75 -0
- package/dist/styles/themes/selva.css +105 -0
- package/dist/themes.d.ts +5 -0
- package/dist/themes.js +13 -0
- package/dist/types/generated/index.d.ts +6 -0
- package/dist/types/generated/index.js +6 -0
- package/dist/types/generated/preset.d.ts +80 -0
- package/dist/types/generated/preset.js +7 -0
- package/dist/types/generated/schema.d.ts +451 -0
- package/dist/types/generated/schema.js +48 -0
- package/dist/utils/computeThrottle.svelte.d.ts +28 -0
- package/dist/utils/computeThrottle.svelte.js +93 -0
- package/dist/utils/debounce.d.ts +14 -0
- package/dist/utils/debounce.js +25 -0
- package/dist/utils/file-download.d.ts +26 -0
- package/dist/utils/file-download.js +76 -0
- package/dist/utils/loadScript.d.ts +14 -0
- package/dist/utils/loadScript.js +41 -0
- package/dist/utils/param-exporter.d.ts +30 -0
- package/dist/utils/param-exporter.js +186 -0
- package/dist/utils/solving.svelte.d.ts +12 -0
- package/dist/utils/solving.svelte.js +86 -0
- package/dist/utils/utils-shared.d.ts +9 -0
- package/dist/utils/utils-shared.js +53 -0
- package/dist/utils/visibility-rules.d.ts +12 -0
- package/dist/utils/visibility-rules.js +52 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +5 -0
- package/package.json +70 -0
- package/src/lib/components/AppLayout.svelte +439 -0
- package/src/lib/components/CollapsedPanelStrip.svelte +67 -0
- package/src/lib/components/ComputeMessages.svelte +172 -0
- package/src/lib/components/ErrorScreen.svelte +55 -0
- package/src/lib/components/StateManager.svelte +318 -0
- package/src/lib/components/Viewer.svelte +207 -0
- package/src/lib/components/layout/FooterItemRenderer.svelte +20 -0
- package/src/lib/components/layout/PageContainer.svelte +36 -0
- package/src/lib/components/layout/PageFooter.svelte +223 -0
- package/src/lib/components/layout/PageHeader.svelte +89 -0
- package/src/lib/components/layout/index.ts +4 -0
- package/src/lib/components/preview/ChartOutput.svelte +257 -0
- package/src/lib/components/preview/Group.svelte +121 -0
- package/src/lib/components/preview/InputControl.svelte +119 -0
- package/src/lib/components/preview/OutputDisplay.svelte +296 -0
- package/src/lib/components/preview/TabBar.svelte +36 -0
- package/src/lib/components/preview/TabContent.svelte +124 -0
- package/src/lib/components/preview/TabLayout.svelte +109 -0
- package/src/lib/components/preview/index.ts +4 -0
- package/src/lib/components/preview/inputs/CheckboxInput.svelte +29 -0
- package/src/lib/components/preview/inputs/ColorInput.svelte +21 -0
- package/src/lib/components/preview/inputs/DropdownInput.svelte +40 -0
- package/src/lib/components/preview/inputs/FileInput.svelte +358 -0
- package/src/lib/components/preview/inputs/NumberInput.svelte +152 -0
- package/src/lib/components/preview/inputs/TextInput.svelte +74 -0
- package/src/lib/components/preview/inputs/index.ts +6 -0
- package/src/lib/components/ui/CalculateButton.svelte +56 -0
- package/src/lib/components/ui/SolvingIndicator.svelte +55 -0
- package/src/lib/components/ui/StateDisplay.svelte +106 -0
- package/src/lib/components/ui/alert/alert-description.svelte +23 -0
- package/src/lib/components/ui/alert/alert-title.svelte +20 -0
- package/src/lib/components/ui/alert/alert.svelte +44 -0
- package/src/lib/components/ui/alert/index.ts +14 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +18 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +18 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +27 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +17 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +20 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +17 -0
- package/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +7 -0
- package/src/lib/components/ui/alert-dialog/index.ts +39 -0
- package/src/lib/components/ui/badge/badge.svelte +50 -0
- package/src/lib/components/ui/badge/index.ts +2 -0
- package/src/lib/components/ui/button/button.svelte +83 -0
- package/src/lib/components/ui/button/index.ts +17 -0
- package/src/lib/components/ui/button-group/button-group-separator.svelte +20 -0
- package/src/lib/components/ui/button-group/button-group-text.svelte +30 -0
- package/src/lib/components/ui/button-group/button-group.svelte +46 -0
- package/src/lib/components/ui/button-group/index.ts +13 -0
- package/src/lib/components/ui/card/card-action.svelte +20 -0
- package/src/lib/components/ui/card/card-content.svelte +15 -0
- package/src/lib/components/ui/card/card-description.svelte +20 -0
- package/src/lib/components/ui/card/card-footer.svelte +20 -0
- package/src/lib/components/ui/card/card-header.svelte +23 -0
- package/src/lib/components/ui/card/card-title.svelte +20 -0
- package/src/lib/components/ui/card/card.svelte +23 -0
- package/src/lib/components/ui/card/index.ts +25 -0
- package/src/lib/components/ui/checkbox/checkbox.svelte +36 -0
- package/src/lib/components/ui/checkbox/index.ts +6 -0
- package/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
- package/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
- package/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
- package/src/lib/components/ui/collapsible/index.ts +13 -0
- package/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte +38 -0
- package/src/lib/components/ui/context-menu/context-menu-content.svelte +25 -0
- package/src/lib/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
- package/src/lib/components/ui/context-menu/context-menu-group.svelte +7 -0
- package/src/lib/components/ui/context-menu/context-menu-item.svelte +27 -0
- package/src/lib/components/ui/context-menu/context-menu-label.svelte +24 -0
- package/src/lib/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
- package/src/lib/components/ui/context-menu/context-menu-radio-item.svelte +31 -0
- package/src/lib/components/ui/context-menu/context-menu-separator.svelte +17 -0
- package/src/lib/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
- package/src/lib/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
- package/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
- package/src/lib/components/ui/context-menu/context-menu-trigger.svelte +7 -0
- package/src/lib/components/ui/context-menu/index.ts +51 -0
- package/src/lib/components/ui/dialog/dialog-close.svelte +7 -0
- package/src/lib/components/ui/dialog/dialog-content.svelte +43 -0
- package/src/lib/components/ui/dialog/dialog-description.svelte +17 -0
- package/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
- package/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
- package/src/lib/components/ui/dialog/dialog-overlay.svelte +20 -0
- package/src/lib/components/ui/dialog/dialog-title.svelte +17 -0
- package/src/lib/components/ui/dialog/dialog-trigger.svelte +7 -0
- package/src/lib/components/ui/dialog/index.ts +37 -0
- package/src/lib/components/ui/field/field-content.svelte +20 -0
- package/src/lib/components/ui/field/field-description.svelte +25 -0
- package/src/lib/components/ui/field/field-error.svelte +58 -0
- package/src/lib/components/ui/field/field-group.svelte +23 -0
- package/src/lib/components/ui/field/field-label.svelte +26 -0
- package/src/lib/components/ui/field/field-legend.svelte +29 -0
- package/src/lib/components/ui/field/field-separator.svelte +38 -0
- package/src/lib/components/ui/field/field-set.svelte +24 -0
- package/src/lib/components/ui/field/field-title.svelte +23 -0
- package/src/lib/components/ui/field/field.svelte +53 -0
- package/src/lib/components/ui/field/index.ts +33 -0
- package/src/lib/components/ui/index.ts +33 -0
- package/src/lib/components/ui/input/index.ts +7 -0
- package/src/lib/components/ui/input/input.svelte +52 -0
- package/src/lib/components/ui/label/index.ts +7 -0
- package/src/lib/components/ui/label/label.svelte +20 -0
- package/src/lib/components/ui/mode-toggle/index.ts +1 -0
- package/src/lib/components/ui/mode-toggle/mode-toggle.svelte +16 -0
- package/src/lib/components/ui/resizable/index.ts +13 -0
- package/src/lib/components/ui/resizable/resizable-handle.svelte +30 -0
- package/src/lib/components/ui/resizable/resizable-pane-group.svelte +20 -0
- package/src/lib/components/ui/scroll-area/index.ts +10 -0
- package/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
- package/src/lib/components/ui/scroll-area/scroll-area.svelte +43 -0
- package/src/lib/components/ui/select/index.ts +37 -0
- package/src/lib/components/ui/select/select-content.svelte +40 -0
- package/src/lib/components/ui/select/select-group-heading.svelte +21 -0
- package/src/lib/components/ui/select/select-group.svelte +7 -0
- package/src/lib/components/ui/select/select-item.svelte +38 -0
- package/src/lib/components/ui/select/select-label.svelte +20 -0
- package/src/lib/components/ui/select/select-scroll-down-button.svelte +20 -0
- package/src/lib/components/ui/select/select-scroll-up-button.svelte +20 -0
- package/src/lib/components/ui/select/select-separator.svelte +18 -0
- package/src/lib/components/ui/select/select-trigger.svelte +29 -0
- package/src/lib/components/ui/separator/index.ts +7 -0
- package/src/lib/components/ui/separator/separator.svelte +21 -0
- package/src/lib/components/ui/slider/index.ts +7 -0
- package/src/lib/components/ui/slider/slider.svelte +52 -0
- package/src/lib/components/ui/sonner/index.ts +2 -0
- package/src/lib/components/ui/sonner/sonner.svelte +13 -0
- package/src/lib/components/ui/switch/index.ts +7 -0
- package/src/lib/components/ui/switch/switch.svelte +29 -0
- package/src/lib/components/ui/tabs/index.ts +16 -0
- package/src/lib/components/ui/tabs/tabs-content.svelte +17 -0
- package/src/lib/components/ui/tabs/tabs-list.svelte +16 -0
- package/src/lib/components/ui/tabs/tabs-trigger.svelte +20 -0
- package/src/lib/components/ui/tabs/tabs.svelte +19 -0
- package/src/lib/components/ui/textarea/index.ts +7 -0
- package/src/lib/components/ui/textarea/textarea.svelte +23 -0
- package/src/lib/components/ui/theme-switcher/ThemeSwitcher.svelte +39 -0
- package/src/lib/components/ui/theme-switcher/index.ts +1 -0
- package/src/lib/composables/useFooterItem.svelte.ts +39 -0
- package/src/lib/constants.ts +6 -0
- package/src/lib/contexts/FOOTER_USAGE.md +164 -0
- package/src/lib/contexts/footerContext.svelte.ts +52 -0
- package/src/lib/dummy-output-values.ts +62 -0
- package/src/lib/dummy-surface-chart.json +13 -0
- package/src/lib/example-schema-left-only.json +367 -0
- package/src/lib/example-schema-right-only.json +322 -0
- package/src/lib/example-schema.json +1582 -0
- package/src/lib/features/preview/handlers.ts +243 -0
- package/src/lib/features/preview/index.ts +2 -0
- package/src/lib/features/preview/notifications.ts +52 -0
- package/src/lib/index.ts +52 -0
- package/src/lib/stores/themeStore.svelte.ts +54 -0
- package/src/lib/styles/base.css +142 -0
- package/src/lib/styles/themes/cyberpunk.css +98 -0
- package/src/lib/styles/themes/neutral.css +72 -0
- package/src/lib/styles/themes/ocean.css +75 -0
- package/src/lib/styles/themes/selva.css +105 -0
- package/src/lib/themes.ts +18 -0
- package/src/lib/types/generated/index.ts +6 -0
- package/src/lib/types/generated/preset.ts +82 -0
- package/src/lib/types/generated/schema.ts +527 -0
- package/src/lib/utils/computeThrottle.svelte.ts +117 -0
- package/src/lib/utils/debounce.ts +30 -0
- package/src/lib/utils/file-download.ts +88 -0
- package/src/lib/utils/loadScript.ts +52 -0
- package/src/lib/utils/param-exporter.ts +242 -0
- package/src/lib/utils/solving.svelte.ts +100 -0
- package/src/lib/utils/utils-shared.ts +57 -0
- package/src/lib/utils/visibility-rules.ts +97 -0
- package/src/lib/utils.ts +13 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrapper utilities for file downloads from Grasshopper outputs
|
|
3
|
+
* Uses the core package implementation for file handling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { downloadFileData, type FileData } from 'selva-compute';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Download file(s) from Grasshopper outputs
|
|
10
|
+
* Single files are downloaded directly, multiple files are packaged as ZIP
|
|
11
|
+
*/
|
|
12
|
+
export async function downloadFiles(
|
|
13
|
+
fileData: FileData | FileData[],
|
|
14
|
+
fileName: string = 'grasshopper-output'
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
try {
|
|
17
|
+
const filesArray = Array.isArray(fileData) ? fileData : [fileData];
|
|
18
|
+
|
|
19
|
+
if (filesArray.length === 0) {
|
|
20
|
+
console.warn('[FileDownload] No files to download');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (filesArray.length === 1) {
|
|
25
|
+
// Single file - download directly
|
|
26
|
+
await downloadSingleFile(filesArray[0]);
|
|
27
|
+
} else {
|
|
28
|
+
// Multiple files - use core's ZIP functionality
|
|
29
|
+
await downloadFileData(filesArray, fileName);
|
|
30
|
+
}
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('[FileDownload] Error downloading files:', error);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Download a single file directly
|
|
39
|
+
*/
|
|
40
|
+
async function downloadSingleFile(fileData: FileData): Promise<void> {
|
|
41
|
+
try {
|
|
42
|
+
await downloadFileData([fileData], fileData.fileName.replace(/\.[^.]*$/, ''));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('[FileDownload] Error downloading single file:', error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if data is FileData
|
|
51
|
+
*/
|
|
52
|
+
export function isFileData(data: unknown): data is FileData {
|
|
53
|
+
return (
|
|
54
|
+
typeof data === 'object' &&
|
|
55
|
+
data !== null &&
|
|
56
|
+
'fileName' in data &&
|
|
57
|
+
'data' in data &&
|
|
58
|
+
'isBase64Encoded' in data
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if data is FileData array
|
|
64
|
+
*/
|
|
65
|
+
export function isFileDataArray(data: unknown): data is FileData[] {
|
|
66
|
+
return Array.isArray(data) && data.length > 0 && isFileData(data[0]);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Format file size for display
|
|
71
|
+
*/
|
|
72
|
+
export function formatFileSize(bytes: number): string {
|
|
73
|
+
if (bytes === 0) return '0 Bytes';
|
|
74
|
+
|
|
75
|
+
const k = 1024;
|
|
76
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
77
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
78
|
+
|
|
79
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get approximate file size from base64 string
|
|
84
|
+
*/
|
|
85
|
+
export function getBase64FileSize(base64: string): number {
|
|
86
|
+
// Base64 encoded string is approximately 33% larger than original
|
|
87
|
+
return Math.ceil((base64.length * 3) / 4);
|
|
88
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load an external script from a CDN with automatic deduplication.
|
|
3
|
+
* All calls to load the same script will share a single promise,
|
|
4
|
+
* preventing duplicate script tags and race conditions.
|
|
5
|
+
*
|
|
6
|
+
* @param src The script URL
|
|
7
|
+
* @param options Script attributes (crossOrigin, async, etc.)
|
|
8
|
+
* @returns Promise that resolves when script is loaded
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const scriptLoaders = new Map<string, Promise<void>>();
|
|
12
|
+
|
|
13
|
+
export function loadScript(
|
|
14
|
+
src: string,
|
|
15
|
+
options?: {
|
|
16
|
+
crossOrigin?: string;
|
|
17
|
+
async?: boolean;
|
|
18
|
+
defer?: boolean;
|
|
19
|
+
}
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
// Return existing promise if already loading/loaded
|
|
22
|
+
if (scriptLoaders.has(src)) {
|
|
23
|
+
return scriptLoaders.get(src)!;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check if script already exists in DOM
|
|
27
|
+
if (document.querySelector(`script[src="${src}"]`)) {
|
|
28
|
+
const resolved = Promise.resolve();
|
|
29
|
+
scriptLoaders.set(src, resolved);
|
|
30
|
+
return resolved;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Create and load script
|
|
34
|
+
const promise = new Promise<void>((resolve, reject) => {
|
|
35
|
+
const script = document.createElement('script');
|
|
36
|
+
script.src = src;
|
|
37
|
+
if (options?.crossOrigin) script.crossOrigin = options.crossOrigin;
|
|
38
|
+
if (options?.async !== undefined) script.async = options.async;
|
|
39
|
+
if (options?.defer !== undefined) script.defer = options.defer;
|
|
40
|
+
|
|
41
|
+
script.onload = () => resolve();
|
|
42
|
+
script.onerror = () => {
|
|
43
|
+
scriptLoaders.delete(src);
|
|
44
|
+
reject(new Error(`Failed to load script: ${src}`));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
document.head.appendChild(script);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
scriptLoaders.set(src, promise);
|
|
51
|
+
return promise;
|
|
52
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
UISchema,
|
|
3
|
+
ParameterPreset,
|
|
4
|
+
ParameterState,
|
|
5
|
+
ValidationIssueMessage,
|
|
6
|
+
GroupConfig
|
|
7
|
+
} from '../types/generated';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generate a UUID v4 (with fallback for older environments)
|
|
11
|
+
*/
|
|
12
|
+
function generateUUID(): string {
|
|
13
|
+
if (typeof crypto !== 'undefined' && crypto.randomUUID) {
|
|
14
|
+
return crypto.randomUUID();
|
|
15
|
+
}
|
|
16
|
+
// Fallback for older browsers/environments
|
|
17
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
18
|
+
const r = (Math.random() * 16) | 0;
|
|
19
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
20
|
+
return v.toString(16);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a saved state from current schema and values
|
|
26
|
+
*/
|
|
27
|
+
export function createSavedState(
|
|
28
|
+
schema: UISchema,
|
|
29
|
+
currentValues: Record<string, unknown>,
|
|
30
|
+
metadata: {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
author?: string;
|
|
34
|
+
tags?: string[];
|
|
35
|
+
}
|
|
36
|
+
): ParameterPreset {
|
|
37
|
+
// Collect parameter states from schema
|
|
38
|
+
const parameters: ParameterState[] = [];
|
|
39
|
+
|
|
40
|
+
const processGroup = (group: GroupConfig) => {
|
|
41
|
+
for (const item of group.items || []) {
|
|
42
|
+
if (item.type === 'input') {
|
|
43
|
+
const value = currentValues[item.paramId];
|
|
44
|
+
|
|
45
|
+
// Find the input parameter definition for type info
|
|
46
|
+
const inputDef = schema.inputs.find((i) => i.id === item.paramId);
|
|
47
|
+
|
|
48
|
+
if (value !== undefined && inputDef) {
|
|
49
|
+
parameters.push({
|
|
50
|
+
paramId: item.paramId,
|
|
51
|
+
nickname: inputDef.nickname,
|
|
52
|
+
displayName: item.displayName || inputDef.nickname,
|
|
53
|
+
paramType: inputDef.paramType,
|
|
54
|
+
value,
|
|
55
|
+
groupName: group.label
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (schema.layout) {
|
|
63
|
+
if (schema.layout.type === 'tabbed') {
|
|
64
|
+
for (const tab of schema.layout.tabs) {
|
|
65
|
+
for (const group of tab.groups || []) {
|
|
66
|
+
processGroup(group);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else if (schema.layout.type === 'flat') {
|
|
70
|
+
for (const group of schema.layout.groups || []) {
|
|
71
|
+
processGroup(group);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
id: generateUUID(),
|
|
78
|
+
name: metadata.name,
|
|
79
|
+
description: metadata.description,
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
schemaId: schema.id,
|
|
82
|
+
documentId: schema.documentId || '',
|
|
83
|
+
projectFileName: schema.projectFileName || '',
|
|
84
|
+
pluginVersion: schema.pluginVersion || '',
|
|
85
|
+
author: metadata.author,
|
|
86
|
+
tags: metadata.tags || [],
|
|
87
|
+
parameters
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validate a saved state against the current schema
|
|
93
|
+
*/
|
|
94
|
+
export function validateSavedState(
|
|
95
|
+
savedState: ParameterPreset,
|
|
96
|
+
currentSchema: UISchema
|
|
97
|
+
): {
|
|
98
|
+
isValid: boolean;
|
|
99
|
+
issues: ValidationIssueMessage[];
|
|
100
|
+
canLoad: boolean; // Can we load despite issues?
|
|
101
|
+
} {
|
|
102
|
+
const issues: ValidationIssueMessage[] = [];
|
|
103
|
+
|
|
104
|
+
// Check document ID match
|
|
105
|
+
if (savedState.documentId !== (currentSchema.documentId || '')) {
|
|
106
|
+
issues.push({
|
|
107
|
+
paramId: '__document__',
|
|
108
|
+
severity: 'error',
|
|
109
|
+
message: 'Document ID mismatch - this state was saved for a different document',
|
|
110
|
+
details: {
|
|
111
|
+
expected: currentSchema.documentId || '',
|
|
112
|
+
actual: savedState.documentId
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check schema ID match (warning only)
|
|
118
|
+
if (savedState.schemaId !== currentSchema.id) {
|
|
119
|
+
issues.push({
|
|
120
|
+
paramId: '__schema__',
|
|
121
|
+
severity: 'warning',
|
|
122
|
+
message: 'Schema has changed since this state was saved',
|
|
123
|
+
details: {
|
|
124
|
+
expected: currentSchema.id,
|
|
125
|
+
actual: savedState.schemaId
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Validate each parameter
|
|
131
|
+
for (const paramState of savedState.parameters) {
|
|
132
|
+
const inputDef = currentSchema.inputs.find((i) => i.id === paramState.paramId);
|
|
133
|
+
|
|
134
|
+
if (!inputDef) {
|
|
135
|
+
issues.push({
|
|
136
|
+
paramId: paramState.paramId,
|
|
137
|
+
severity: 'error',
|
|
138
|
+
message: `Parameter "${paramState.nickname}" no longer exists in the schema`
|
|
139
|
+
});
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Check nickname changed (warning)
|
|
144
|
+
if (inputDef.nickname !== paramState.nickname) {
|
|
145
|
+
issues.push({
|
|
146
|
+
paramId: paramState.paramId,
|
|
147
|
+
severity: 'warning',
|
|
148
|
+
message: `Parameter nickname changed`,
|
|
149
|
+
details: {
|
|
150
|
+
expected: paramState.nickname,
|
|
151
|
+
actual: inputDef.nickname
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Can load if no errors (warnings are ok)
|
|
158
|
+
const hasErrors = issues.some((i) => i.severity === 'error');
|
|
159
|
+
const canLoad = !hasErrors;
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
isValid: issues.length === 0,
|
|
163
|
+
issues,
|
|
164
|
+
canLoad
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Extract values from saved state that can be safely loaded
|
|
170
|
+
*/
|
|
171
|
+
export function extractLoadableValues(
|
|
172
|
+
savedState: ParameterPreset,
|
|
173
|
+
currentSchema: UISchema,
|
|
174
|
+
validation: ReturnType<typeof validateSavedState>
|
|
175
|
+
): Record<string, unknown> {
|
|
176
|
+
const values: Record<string, unknown> = {};
|
|
177
|
+
|
|
178
|
+
// Get param IDs with errors
|
|
179
|
+
const errorParamIds = new Set(
|
|
180
|
+
validation.issues
|
|
181
|
+
.filter(
|
|
182
|
+
(i) => i.severity === 'error' && i.paramId !== '__document__' && i.paramId !== '__schema__'
|
|
183
|
+
)
|
|
184
|
+
.map((i) => i.paramId)
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Extract values for parameters without errors
|
|
188
|
+
for (const paramState of savedState.parameters) {
|
|
189
|
+
if (!errorParamIds.has(paramState.paramId)) {
|
|
190
|
+
// Verify parameter still exists
|
|
191
|
+
const inputDef = currentSchema.inputs.find((i) => i.id === paramState.paramId);
|
|
192
|
+
if (inputDef) {
|
|
193
|
+
values[paramState.paramId] = paramState.value;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return values;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Export state as .sps (Selva Param State) file
|
|
203
|
+
*/
|
|
204
|
+
export function exportStateAsJson(savedState: ParameterPreset): void {
|
|
205
|
+
const json = JSON.stringify(savedState, null, 2);
|
|
206
|
+
const blob = new Blob([json], { type: 'application/json' });
|
|
207
|
+
const url = URL.createObjectURL(blob);
|
|
208
|
+
|
|
209
|
+
// Use a more reliable method: add to DOM, trigger, then remove
|
|
210
|
+
const link = document.createElement('a');
|
|
211
|
+
link.href = url;
|
|
212
|
+
link.download = `${savedState.name.replace(/[^a-z0-9]/gi, '_')}_${savedState.timestamp.split('T')[0].replace(/-/g, '_')}.sps`;
|
|
213
|
+
|
|
214
|
+
// Ensure visibility for older browsers
|
|
215
|
+
link.style.display = 'none';
|
|
216
|
+
document.body.appendChild(link);
|
|
217
|
+
|
|
218
|
+
// Use setTimeout to ensure DOM is ready
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
link.click();
|
|
221
|
+
// Clean up after click
|
|
222
|
+
setTimeout(() => {
|
|
223
|
+
document.body.removeChild(link);
|
|
224
|
+
URL.revokeObjectURL(url);
|
|
225
|
+
}, 100);
|
|
226
|
+
}, 0);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Import state from .sps (Selva Param State) file
|
|
231
|
+
*/
|
|
232
|
+
export async function importStateFromJson(file: File): Promise<ParameterPreset> {
|
|
233
|
+
const text = await file.text();
|
|
234
|
+
const state = JSON.parse(text) as ParameterPreset;
|
|
235
|
+
|
|
236
|
+
// Basic validation
|
|
237
|
+
if (!state.id || !state.name || !state.documentId || !state.parameters) {
|
|
238
|
+
throw new Error('Invalid saved state file format');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return state;
|
|
242
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { untrack } from 'svelte';
|
|
2
|
+
|
|
3
|
+
// How many solves to keep in history for averaging
|
|
4
|
+
const HISTORY_SIZE = 3;
|
|
5
|
+
// If expected solve time is below this, skip the indicator entirely
|
|
6
|
+
const FAST_THRESHOLD_MS = 200;
|
|
7
|
+
// If expected solve time is above this, show indicator immediately (no delay)
|
|
8
|
+
const SLOW_THRESHOLD_MS = 600;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an adaptive solving indicator that measures actual solve durations
|
|
12
|
+
* and adjusts its visibility delay accordingly.
|
|
13
|
+
*
|
|
14
|
+
* - Fast solves (<200ms avg): indicator never shown (avoids flicker)
|
|
15
|
+
* - Slow solves (>600ms avg): indicator shown immediately
|
|
16
|
+
* - In between: indicator shown after a proportional delay
|
|
17
|
+
* - First solve: shows immediately (no history yet)
|
|
18
|
+
*/
|
|
19
|
+
export function createSolvingIndicator(isSolving: () => boolean) {
|
|
20
|
+
let show = $state(false);
|
|
21
|
+
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
22
|
+
|
|
23
|
+
// Solve duration history
|
|
24
|
+
const solveHistory: number[] = [];
|
|
25
|
+
let solveStartTime: number | null = null;
|
|
26
|
+
let hasHistory = false;
|
|
27
|
+
|
|
28
|
+
function getExpectedDuration(): number {
|
|
29
|
+
if (solveHistory.length === 0) return Infinity; // unknown → show immediately
|
|
30
|
+
return solveHistory.reduce((a, b) => a + b, 0) / solveHistory.length;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function recordSolveEnd() {
|
|
34
|
+
if (solveStartTime !== null) {
|
|
35
|
+
const duration = performance.now() - solveStartTime;
|
|
36
|
+
solveHistory.push(duration);
|
|
37
|
+
if (solveHistory.length > HISTORY_SIZE) {
|
|
38
|
+
solveHistory.shift();
|
|
39
|
+
}
|
|
40
|
+
solveStartTime = null;
|
|
41
|
+
hasHistory = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
$effect(() => {
|
|
46
|
+
const solving = isSolving();
|
|
47
|
+
|
|
48
|
+
untrack(() => {
|
|
49
|
+
if (solving) {
|
|
50
|
+
solveStartTime = performance.now();
|
|
51
|
+
|
|
52
|
+
const expected = getExpectedDuration();
|
|
53
|
+
|
|
54
|
+
// Skip indicator entirely for consistently fast solves
|
|
55
|
+
if (hasHistory && expected < FAST_THRESHOLD_MS) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Delay: 0 for slow/unknown, proportional for mid-range
|
|
60
|
+
const delay =
|
|
61
|
+
expected === Infinity || expected >= SLOW_THRESHOLD_MS
|
|
62
|
+
? 0
|
|
63
|
+
: Math.round(
|
|
64
|
+
((expected - FAST_THRESHOLD_MS) / (SLOW_THRESHOLD_MS - FAST_THRESHOLD_MS)) * 300
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (!timeout) {
|
|
68
|
+
if (delay === 0) {
|
|
69
|
+
show = true;
|
|
70
|
+
} else {
|
|
71
|
+
timeout = setTimeout(() => {
|
|
72
|
+
show = true;
|
|
73
|
+
timeout = null;
|
|
74
|
+
}, delay);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
recordSolveEnd();
|
|
79
|
+
|
|
80
|
+
if (timeout) {
|
|
81
|
+
clearTimeout(timeout);
|
|
82
|
+
timeout = null;
|
|
83
|
+
}
|
|
84
|
+
show = false;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
if (timeout) {
|
|
90
|
+
clearTimeout(timeout);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
get show() {
|
|
97
|
+
return show;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { UISchema } from '$lib/types/generated';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get default value for a parameter type
|
|
5
|
+
*/
|
|
6
|
+
export function getDefaultValue(paramType: string): unknown {
|
|
7
|
+
switch (paramType) {
|
|
8
|
+
case 'number':
|
|
9
|
+
case 'integer':
|
|
10
|
+
return 0;
|
|
11
|
+
case 'boolean':
|
|
12
|
+
return false;
|
|
13
|
+
case 'text':
|
|
14
|
+
return '';
|
|
15
|
+
default:
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Ensure schema has proper layout defaults
|
|
22
|
+
*/
|
|
23
|
+
export function ensureSchemaLayoutDefaults(schema: UISchema | null): UISchema | null {
|
|
24
|
+
if (!schema) return null;
|
|
25
|
+
|
|
26
|
+
if (!schema.layout) {
|
|
27
|
+
schema.layout = {
|
|
28
|
+
type: 'tabbed',
|
|
29
|
+
gap: 16,
|
|
30
|
+
tabs: []
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated v1 schema migration
|
|
36
|
+
* TODO(v2.0.0): Remove this block - all schemas should have layout.type
|
|
37
|
+
*/
|
|
38
|
+
if (schema.layout && !schema.layout.type) {
|
|
39
|
+
if ('tabs' in schema.layout) {
|
|
40
|
+
(schema.layout as any).type = 'tabbed';
|
|
41
|
+
} else if ('groups' in schema.layout) {
|
|
42
|
+
(schema.layout as any).type = 'flat';
|
|
43
|
+
} else {
|
|
44
|
+
(schema.layout as any).type = 'tabbed';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (schema.layout.type === 'tabbed' && !schema.layout.tabs) {
|
|
49
|
+
schema.layout.tabs = [];
|
|
50
|
+
}
|
|
51
|
+
// Ensure instanceSolve has a default value
|
|
52
|
+
if (schema.instanceSolve === undefined) {
|
|
53
|
+
schema.instanceSolve = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return schema;
|
|
57
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LayoutItem,
|
|
3
|
+
VisibilityRule,
|
|
4
|
+
VisibilityCondition,
|
|
5
|
+
GroupVisibilityCondition
|
|
6
|
+
} from '$lib/types/generated';
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Types
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
export interface VisibilityResult {
|
|
13
|
+
visible: boolean;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
defaultValue?: unknown;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Rule operators
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
type RuleOperatorFn = (a: unknown, b: unknown, values?: unknown[]) => boolean;
|
|
23
|
+
|
|
24
|
+
const RULE_OPERATORS: Record<string, RuleOperatorFn> = {
|
|
25
|
+
equals: (a, b) => a === b,
|
|
26
|
+
notEquals: (a, b) => a !== b,
|
|
27
|
+
greaterThan: (a, b) => Number(a) > Number(b),
|
|
28
|
+
lessThan: (a, b) => Number(a) < Number(b),
|
|
29
|
+
greaterThanOrEqual: (a, b) => Number(a) >= Number(b),
|
|
30
|
+
lessThanOrEqual: (a, b) => Number(a) <= Number(b),
|
|
31
|
+
between: (a, _, vals) =>
|
|
32
|
+
vals?.length === 2 && Number(a) >= Number(vals[0]) && Number(a) <= Number(vals[1]),
|
|
33
|
+
in: (a, _, vals) => vals?.includes(String(a)) ?? false,
|
|
34
|
+
notIn: (a, _, vals) => !(vals?.includes(String(a)) ?? false),
|
|
35
|
+
matches: (a, b) => {
|
|
36
|
+
try {
|
|
37
|
+
return new RegExp(String(b)).test(String(a));
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Condition evaluation
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
export function evaluateRule(rule: VisibilityRule, values: Record<string, unknown>): boolean {
|
|
49
|
+
const fn = RULE_OPERATORS[rule.operator];
|
|
50
|
+
return fn ? fn(values[rule.paramId], rule.value, rule.values) : false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function evaluateCondition(
|
|
54
|
+
condition: VisibilityCondition | GroupVisibilityCondition,
|
|
55
|
+
values: Record<string, unknown>
|
|
56
|
+
): boolean {
|
|
57
|
+
const results = condition.rules.map((rule) => evaluateRule(rule, values));
|
|
58
|
+
return condition.mode === 'any' ? results.some(Boolean) : results.every(Boolean);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Item / group visibility
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
type ActionFn = (met: boolean, defaultValue?: unknown) => VisibilityResult;
|
|
66
|
+
|
|
67
|
+
const ACTIONS: Record<string, ActionFn> = {
|
|
68
|
+
show: (met) => ({ visible: met, disabled: false }),
|
|
69
|
+
hide: (met, dv) => ({ visible: !met, disabled: false, defaultValue: dv }),
|
|
70
|
+
disable: (met, dv) => ({ visible: true, disabled: met, defaultValue: met ? dv : undefined })
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export function evaluateVisibility(
|
|
74
|
+
item: LayoutItem,
|
|
75
|
+
values: Record<string, unknown>
|
|
76
|
+
): VisibilityResult {
|
|
77
|
+
if (item.type === 'linebreak') return { visible: true, disabled: false };
|
|
78
|
+
if (!item.visibilityCondition?.rules) return { visible: true, disabled: false };
|
|
79
|
+
|
|
80
|
+
const { action = 'show', defaultValue } = item.visibilityCondition;
|
|
81
|
+
const met = evaluateCondition(item.visibilityCondition, values);
|
|
82
|
+
const actionFn = ACTIONS[action] ?? ACTIONS.show;
|
|
83
|
+
|
|
84
|
+
return actionFn(met, defaultValue);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function evaluateGroupVisibility(
|
|
88
|
+
group: { visibilityCondition?: GroupVisibilityCondition },
|
|
89
|
+
values: Record<string, unknown>
|
|
90
|
+
): boolean {
|
|
91
|
+
if (!group.visibilityCondition?.rules) return true;
|
|
92
|
+
|
|
93
|
+
const { action = 'show' } = group.visibilityCondition;
|
|
94
|
+
const met = evaluateCondition(group.visibilityCondition, values);
|
|
95
|
+
|
|
96
|
+
return action === 'hide' ? !met : met;
|
|
97
|
+
}
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
export function cn(...inputs: ClassValue[]) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
|
|
12
|
+
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
|
13
|
+
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
|