@walkthru-earth/objex 0.1.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/LICENSE +396 -0
- package/README.md +114 -0
- package/dist/assets/favicon.svg +17 -0
- package/dist/components/CLAUDE.md +44 -0
- package/dist/components/browser/Breadcrumb.svelte +50 -0
- package/dist/components/browser/Breadcrumb.svelte.d.ts +7 -0
- package/dist/components/browser/CreateFolderDialog.svelte +98 -0
- package/dist/components/browser/CreateFolderDialog.svelte.d.ts +6 -0
- package/dist/components/browser/DeleteConfirmDialog.svelte +90 -0
- package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +8 -0
- package/dist/components/browser/DropZone.svelte +83 -0
- package/dist/components/browser/DropZone.svelte.d.ts +7 -0
- package/dist/components/browser/FileBrowser.svelte +229 -0
- package/dist/components/browser/FileBrowser.svelte.d.ts +3 -0
- package/dist/components/browser/FileRow.svelte +112 -0
- package/dist/components/browser/FileRow.svelte.d.ts +9 -0
- package/dist/components/browser/FileTreeSidebar.svelte +559 -0
- package/dist/components/browser/FileTreeSidebar.svelte.d.ts +8 -0
- package/dist/components/browser/RenameDialog.svelte +101 -0
- package/dist/components/browser/RenameDialog.svelte.d.ts +8 -0
- package/dist/components/browser/SearchBar.svelte +40 -0
- package/dist/components/browser/SearchBar.svelte.d.ts +6 -0
- package/dist/components/browser/UploadButton.svelte +65 -0
- package/dist/components/browser/UploadButton.svelte.d.ts +3 -0
- package/dist/components/editor/CodeMirrorEditor.svelte +404 -0
- package/dist/components/editor/CodeMirrorEditor.svelte.d.ts +12 -0
- package/dist/components/editor/MilkdownEditor.svelte +98 -0
- package/dist/components/editor/MilkdownEditor.svelte.d.ts +9 -0
- package/dist/components/editor/SqlEditor.svelte +173 -0
- package/dist/components/editor/SqlEditor.svelte.d.ts +7 -0
- package/dist/components/editor/SqlResultBlock.svelte +199 -0
- package/dist/components/editor/SqlResultBlock.svelte.d.ts +9 -0
- package/dist/components/layout/ConnectionDialog.svelte +439 -0
- package/dist/components/layout/ConnectionDialog.svelte.d.ts +9 -0
- package/dist/components/layout/LocaleToggle.svelte +32 -0
- package/dist/components/layout/LocaleToggle.svelte.d.ts +3 -0
- package/dist/components/layout/SafeLockToggle.svelte +37 -0
- package/dist/components/layout/SafeLockToggle.svelte.d.ts +18 -0
- package/dist/components/layout/Sidebar.svelte +314 -0
- package/dist/components/layout/Sidebar.svelte.d.ts +3 -0
- package/dist/components/layout/StatusBar.svelte +73 -0
- package/dist/components/layout/StatusBar.svelte.d.ts +3 -0
- package/dist/components/layout/TabBar.svelte +102 -0
- package/dist/components/layout/TabBar.svelte.d.ts +7 -0
- package/dist/components/layout/ThemeToggle.svelte +52 -0
- package/dist/components/layout/ThemeToggle.svelte.d.ts +3 -0
- package/dist/components/ui/badge/badge.svelte +49 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
- package/dist/components/ui/badge/index.d.ts +1 -0
- package/dist/components/ui/badge/index.js +1 -0
- package/dist/components/ui/button/button.svelte +82 -0
- package/dist/components/ui/button/button.svelte.d.ts +64 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +4 -0
- package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +40 -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 +28 -0
- package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +10 -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-portal.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-portal.svelte.d.ts +3 -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 +33 -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-sub.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-sub.svelte.d.ts +3 -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/context-menu.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu.svelte.d.ts +3 -0
- package/dist/components/ui/context-menu/index.d.ts +17 -0
- package/dist/components/ui/context-menu/index.js +19 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +29 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +24 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +33 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/index.d.ts +18 -0
- package/dist/components/ui/dropdown-menu/index.js +18 -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/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 +47 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -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/sheet/index.d.ts +11 -0
- package/dist/components/ui/sheet/index.js +13 -0
- package/dist/components/ui/sheet/sheet-close.svelte +7 -0
- package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-content.svelte +62 -0
- package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
- package/dist/components/ui/sheet/sheet-description.svelte +17 -0
- package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-footer.svelte +20 -0
- package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-header.svelte +20 -0
- package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
- package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
- package/dist/components/ui/sheet/sheet-title.svelte +13 -0
- package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte +7 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet.svelte +7 -0
- package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -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 +28 -0
- package/dist/components/ui/switch/switch.svelte.d.ts +8 -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/tooltip/index.d.ts +6 -0
- package/dist/components/ui/tooltip/index.js +8 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/components/viewers/ArchiveViewer.svelte +586 -0
- package/dist/components/viewers/ArchiveViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CLAUDE.md +60 -0
- package/dist/components/viewers/CodeViewer.svelte +553 -0
- package/dist/components/viewers/CodeViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CogViewer.svelte +1345 -0
- package/dist/components/viewers/CogViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CopcViewer.svelte +25 -0
- package/dist/components/viewers/CopcViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/DatabaseViewer.svelte +169 -0
- package/dist/components/viewers/DatabaseViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/FileInfo.svelte +174 -0
- package/dist/components/viewers/FileInfo.svelte.d.ts +10 -0
- package/dist/components/viewers/FlatGeobufViewer.svelte +755 -0
- package/dist/components/viewers/FlatGeobufViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/GeoParquetMapViewer.svelte +278 -0
- package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +17 -0
- package/dist/components/viewers/ImageViewer.svelte +233 -0
- package/dist/components/viewers/ImageViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/LoadProgress.svelte +93 -0
- package/dist/components/viewers/LoadProgress.svelte.d.ts +15 -0
- package/dist/components/viewers/MapViewer.svelte +234 -0
- package/dist/components/viewers/MapViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/MarkdownViewer.svelte +478 -0
- package/dist/components/viewers/MarkdownViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/MediaViewer.svelte +121 -0
- package/dist/components/viewers/MediaViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/ModelViewer.svelte +164 -0
- package/dist/components/viewers/ModelViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/NotebookViewer.svelte +389 -0
- package/dist/components/viewers/NotebookViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/PdfViewer.svelte +278 -0
- package/dist/components/viewers/PdfViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/PmtilesViewer.svelte +191 -0
- package/dist/components/viewers/PmtilesViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/QueryHistoryPanel.svelte +159 -0
- package/dist/components/viewers/QueryHistoryPanel.svelte.d.ts +8 -0
- package/dist/components/viewers/RawViewer.svelte +117 -0
- package/dist/components/viewers/RawViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/StacMapViewer.svelte +20 -0
- package/dist/components/viewers/StacMapViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/StyleEditorOverlay.svelte +27 -0
- package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +7 -0
- package/dist/components/viewers/TableGrid.svelte +355 -0
- package/dist/components/viewers/TableGrid.svelte.d.ts +12 -0
- package/dist/components/viewers/TableStatusBar.svelte +92 -0
- package/dist/components/viewers/TableStatusBar.svelte.d.ts +11 -0
- package/dist/components/viewers/TableToolbar.svelte +382 -0
- package/dist/components/viewers/TableToolbar.svelte.d.ts +25 -0
- package/dist/components/viewers/TableViewer.svelte +923 -0
- package/dist/components/viewers/TableViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/ViewerRouter.svelte +70 -0
- package/dist/components/viewers/ViewerRouter.svelte.d.ts +7 -0
- package/dist/components/viewers/ZarrMapViewer.svelte +288 -0
- package/dist/components/viewers/ZarrMapViewer.svelte.d.ts +17 -0
- package/dist/components/viewers/ZarrViewer.svelte +256 -0
- package/dist/components/viewers/ZarrViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/map/AttributeTable.svelte +52 -0
- package/dist/components/viewers/map/AttributeTable.svelte.d.ts +8 -0
- package/dist/components/viewers/map/MapContainer.svelte +158 -0
- package/dist/components/viewers/map/MapContainer.svelte.d.ts +12 -0
- package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +389 -0
- package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte.d.ts +10 -0
- package/dist/components/viewers/pmtiles/PmtilesMapView.svelte +332 -0
- package/dist/components/viewers/pmtiles/PmtilesMapView.svelte.d.ts +11 -0
- package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +373 -0
- package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte.d.ts +12 -0
- package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte +112 -0
- package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte.d.ts +10 -0
- package/dist/file-icons/CLAUDE.md +21 -0
- package/dist/file-icons/FileTypeIcon.svelte +74 -0
- package/dist/file-icons/FileTypeIcon.svelte.d.ts +9 -0
- package/dist/file-icons/index.d.ts +56 -0
- package/dist/file-icons/index.js +1070 -0
- package/dist/i18n/CLAUDE.md +19 -0
- package/dist/i18n/ar.d.ts +1 -0
- package/dist/i18n/ar.js +404 -0
- package/dist/i18n/en.d.ts +1 -0
- package/dist/i18n/en.js +404 -0
- package/dist/i18n/index.svelte.d.ts +9 -0
- package/dist/i18n/index.svelte.js +27 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +13 -0
- package/dist/query/CLAUDE.md +22 -0
- package/dist/query/engine.d.ts +56 -0
- package/dist/query/engine.js +6 -0
- package/dist/query/index.d.ts +4 -0
- package/dist/query/index.js +19 -0
- package/dist/query/wasm.d.ts +20 -0
- package/dist/query/wasm.js +890 -0
- package/dist/storage/CLAUDE.md +23 -0
- package/dist/storage/adapter.d.ts +21 -0
- package/dist/storage/adapter.js +1 -0
- package/dist/storage/browser-azure.d.ts +25 -0
- package/dist/storage/browser-azure.js +271 -0
- package/dist/storage/browser-cloud.d.ts +32 -0
- package/dist/storage/browser-cloud.js +293 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.js +37 -0
- package/dist/storage/url-adapter.d.ts +19 -0
- package/dist/storage/url-adapter.js +51 -0
- package/dist/stores/CLAUDE.md +29 -0
- package/dist/stores/browser.svelte.d.ts +28 -0
- package/dist/stores/browser.svelte.js +160 -0
- package/dist/stores/connections.svelte.d.ts +56 -0
- package/dist/stores/connections.svelte.js +272 -0
- package/dist/stores/credentials.svelte.d.ts +56 -0
- package/dist/stores/credentials.svelte.js +79 -0
- package/dist/stores/files.svelte.d.ts +20 -0
- package/dist/stores/files.svelte.js +76 -0
- package/dist/stores/query-history.svelte.d.ts +16 -0
- package/dist/stores/query-history.svelte.js +57 -0
- package/dist/stores/safelock.svelte.d.ts +8 -0
- package/dist/stores/safelock.svelte.js +52 -0
- package/dist/stores/settings.svelte.d.ts +11 -0
- package/dist/stores/settings.svelte.js +101 -0
- package/dist/stores/tab-resources.svelte.d.ts +25 -0
- package/dist/stores/tab-resources.svelte.js +61 -0
- package/dist/stores/tabs.svelte.d.ts +17 -0
- package/dist/stores/tabs.svelte.js +110 -0
- package/dist/types/notebookjs.d.ts +14 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.js +1 -0
- package/dist/utils/CLAUDE.md +54 -0
- package/dist/utils/analytics.d.ts +10 -0
- package/dist/utils/analytics.js +38 -0
- package/dist/utils/archive.d.ts +70 -0
- package/dist/utils/archive.js +333 -0
- package/dist/utils/column-types.d.ts +5 -0
- package/dist/utils/column-types.js +137 -0
- package/dist/utils/deck.d.ts +98 -0
- package/dist/utils/deck.js +208 -0
- package/dist/utils/evidence-context.d.ts +22 -0
- package/dist/utils/evidence-context.js +56 -0
- package/dist/utils/export.d.ts +2 -0
- package/dist/utils/export.js +51 -0
- package/dist/utils/format.d.ts +14 -0
- package/dist/utils/format.js +56 -0
- package/dist/utils/geoarrow.d.ts +32 -0
- package/dist/utils/geoarrow.js +672 -0
- package/dist/utils/hex.d.ts +10 -0
- package/dist/utils/hex.js +27 -0
- package/dist/utils/host-detection.d.ts +23 -0
- package/dist/utils/host-detection.js +289 -0
- package/dist/utils/map-selection.d.ts +12 -0
- package/dist/utils/map-selection.js +45 -0
- package/dist/utils/markdown-sql.d.ts +30 -0
- package/dist/utils/markdown-sql.js +73 -0
- package/dist/utils/markdown.d.ts +18 -0
- package/dist/utils/markdown.js +146 -0
- package/dist/utils/model3d.d.ts +13 -0
- package/dist/utils/model3d.js +62 -0
- package/dist/utils/parquet-metadata.d.ts +58 -0
- package/dist/utils/parquet-metadata.js +228 -0
- package/dist/utils/pdf.d.ts +8 -0
- package/dist/utils/pdf.js +28 -0
- package/dist/utils/pmtiles-tile.d.ts +38 -0
- package/dist/utils/pmtiles-tile.js +64 -0
- package/dist/utils/pmtiles.d.ts +46 -0
- package/dist/utils/pmtiles.js +135 -0
- package/dist/utils/shiki.d.ts +8 -0
- package/dist/utils/shiki.js +98 -0
- package/dist/utils/storage-url.d.ts +64 -0
- package/dist/utils/storage-url.js +374 -0
- package/dist/utils/url-state.d.ts +40 -0
- package/dist/utils/url-state.js +113 -0
- package/dist/utils/url.d.ts +27 -0
- package/dist/utils/url.js +115 -0
- package/dist/utils/wkb.d.ts +43 -0
- package/dist/utils/wkb.js +345 -0
- package/dist/utils/zarr.d.ts +39 -0
- package/dist/utils/zarr.js +204 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +5 -0
- package/package.json +203 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ChevronUpIcon from '@lucide/svelte/icons/chevron-up';
|
|
3
|
+
import XIcon from '@lucide/svelte/icons/x';
|
|
4
|
+
import type { PMTiles } from 'pmtiles';
|
|
5
|
+
import { t } from '../../../i18n/index.svelte.js';
|
|
6
|
+
import type { PmtilesMetadata } from '../../../utils/pmtiles';
|
|
7
|
+
import {
|
|
8
|
+
type DecodedTile,
|
|
9
|
+
decodeMvtTile,
|
|
10
|
+
layerHue,
|
|
11
|
+
tileMimeType,
|
|
12
|
+
tileToImageUrl
|
|
13
|
+
} from '../../../utils/pmtiles-tile.js';
|
|
14
|
+
import SvgTileRenderer from './SvgTileRenderer.svelte';
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
metadata,
|
|
18
|
+
pmtiles,
|
|
19
|
+
initialZ,
|
|
20
|
+
initialX,
|
|
21
|
+
initialY
|
|
22
|
+
}: {
|
|
23
|
+
metadata: PmtilesMetadata;
|
|
24
|
+
pmtiles: PMTiles;
|
|
25
|
+
initialZ?: number;
|
|
26
|
+
initialX?: number;
|
|
27
|
+
initialY?: number;
|
|
28
|
+
} = $props();
|
|
29
|
+
|
|
30
|
+
let inputZ = $state(0);
|
|
31
|
+
let inputX = $state(0);
|
|
32
|
+
let inputY = $state(0);
|
|
33
|
+
|
|
34
|
+
// Initialize from props (using derived to track prop changes)
|
|
35
|
+
const _initZ = $derived(initialZ ?? metadata.minZoom);
|
|
36
|
+
const _initX = $derived(initialX ?? 0);
|
|
37
|
+
const _initY = $derived(initialY ?? 0);
|
|
38
|
+
|
|
39
|
+
// Seed inputs once on mount
|
|
40
|
+
let seeded = false;
|
|
41
|
+
$effect(() => {
|
|
42
|
+
if (!seeded) {
|
|
43
|
+
inputZ = _initZ;
|
|
44
|
+
inputX = _initX;
|
|
45
|
+
inputY = _initY;
|
|
46
|
+
seeded = true;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
let tile = $state<DecodedTile | null>(null);
|
|
51
|
+
let rasterUrl = $state<string | null>(null);
|
|
52
|
+
let loading = $state(false);
|
|
53
|
+
let error = $state<string | null>(null);
|
|
54
|
+
let tileSize = $state(0);
|
|
55
|
+
|
|
56
|
+
let selectedLayerName = $state<string | null>(null);
|
|
57
|
+
let selectedFeatureIdx = $state<number | null>(null);
|
|
58
|
+
let showLayerPanel = $state(true);
|
|
59
|
+
let layerVisibility = $state<Record<string, boolean>>({});
|
|
60
|
+
|
|
61
|
+
const isVector = $derived(metadata.format === 'mvt');
|
|
62
|
+
|
|
63
|
+
// Auto-fetch when initial coordinates arrive from archive view
|
|
64
|
+
let lastInitKey = '';
|
|
65
|
+
$effect(() => {
|
|
66
|
+
const key = `${initialZ}/${initialX}/${initialY}`;
|
|
67
|
+
if (
|
|
68
|
+
key !== lastInitKey &&
|
|
69
|
+
initialZ !== undefined &&
|
|
70
|
+
initialX !== undefined &&
|
|
71
|
+
initialY !== undefined
|
|
72
|
+
) {
|
|
73
|
+
lastInitKey = key;
|
|
74
|
+
inputZ = initialZ;
|
|
75
|
+
inputX = initialX;
|
|
76
|
+
inputY = initialY;
|
|
77
|
+
fetchTile();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
async function fetchTile() {
|
|
82
|
+
loading = true;
|
|
83
|
+
error = null;
|
|
84
|
+
tile = null;
|
|
85
|
+
rasterUrl = null;
|
|
86
|
+
selectedLayerName = null;
|
|
87
|
+
selectedFeatureIdx = null;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
if (isVector) {
|
|
91
|
+
const result = await decodeMvtTile(pmtiles, inputZ, inputX, inputY);
|
|
92
|
+
if (!result) {
|
|
93
|
+
error = t('pmtiles.tileNotFound');
|
|
94
|
+
} else {
|
|
95
|
+
tile = result;
|
|
96
|
+
tileSize = result.rawSize;
|
|
97
|
+
// Init visibility
|
|
98
|
+
const vis: Record<string, boolean> = {};
|
|
99
|
+
for (const l of result.layers) vis[l.name] = true;
|
|
100
|
+
layerVisibility = vis;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
const mime = tileMimeType(metadata.format);
|
|
104
|
+
const url = await tileToImageUrl(pmtiles, inputZ, inputX, inputY, mime);
|
|
105
|
+
if (!url) {
|
|
106
|
+
error = t('pmtiles.tileNotFound');
|
|
107
|
+
} else {
|
|
108
|
+
rasterUrl = url;
|
|
109
|
+
const resp = await pmtiles.getZxy(inputZ, inputX, inputY);
|
|
110
|
+
tileSize = resp ? new Uint8Array(resp.data).length : 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
error = e instanceof Error ? e.message : String(e);
|
|
115
|
+
} finally {
|
|
116
|
+
loading = false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function navigateParent() {
|
|
121
|
+
if (inputZ <= 0) return;
|
|
122
|
+
inputZ = inputZ - 1;
|
|
123
|
+
inputX = Math.floor(inputX / 2);
|
|
124
|
+
inputY = Math.floor(inputY / 2);
|
|
125
|
+
fetchTile();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function navigateChild(dx: number, dy: number) {
|
|
129
|
+
inputZ = inputZ + 1;
|
|
130
|
+
inputX = inputX * 2 + dx;
|
|
131
|
+
inputY = inputY * 2 + dy;
|
|
132
|
+
fetchTile();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
136
|
+
if (e.key === 'Enter') fetchTile();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function selectFeature(layerName: string, featureIndex: number) {
|
|
140
|
+
selectedLayerName = layerName;
|
|
141
|
+
selectedFeatureIdx = featureIndex;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const selectedFeature = $derived.by(() => {
|
|
145
|
+
if (!tile || selectedLayerName === null || selectedFeatureIdx === null) return null;
|
|
146
|
+
const layer = tile.layers.find((l) => l.name === selectedLayerName);
|
|
147
|
+
if (!layer || selectedFeatureIdx >= layer.features.length) return null;
|
|
148
|
+
return layer.features[selectedFeatureIdx];
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const selectedFeatureKey = $derived(
|
|
152
|
+
selectedLayerName !== null && selectedFeatureIdx !== null
|
|
153
|
+
? `${selectedLayerName}:${selectedFeatureIdx}`
|
|
154
|
+
: null
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
function formatBytes(bytes: number): string {
|
|
158
|
+
if (bytes === 0) return '0 B';
|
|
159
|
+
const units = ['B', 'KB', 'MB'];
|
|
160
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
161
|
+
return `${(bytes / 1024 ** i).toFixed(i > 0 ? 1 : 0)} ${units[i]}`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function formatValue(v: unknown): string {
|
|
165
|
+
if (v === null || v === undefined) return 'NULL';
|
|
166
|
+
if (typeof v === 'object') return JSON.stringify(v);
|
|
167
|
+
return String(v);
|
|
168
|
+
}
|
|
169
|
+
</script>
|
|
170
|
+
|
|
171
|
+
<div class="flex h-full flex-col overflow-hidden">
|
|
172
|
+
<!-- Navigation bar -->
|
|
173
|
+
<div
|
|
174
|
+
class="flex shrink-0 flex-wrap items-center gap-2 border-b border-zinc-200 px-3 py-2 dark:border-zinc-800"
|
|
175
|
+
>
|
|
176
|
+
<!-- Z/X/Y inputs -->
|
|
177
|
+
<div class="flex items-center gap-1 text-xs">
|
|
178
|
+
<span class="text-muted-foreground">z</span>
|
|
179
|
+
<input
|
|
180
|
+
type="number"
|
|
181
|
+
bind:value={inputZ}
|
|
182
|
+
min={0}
|
|
183
|
+
max={30}
|
|
184
|
+
class="w-12 rounded border border-zinc-300 bg-transparent px-1.5 py-0.5 text-center font-mono text-xs dark:border-zinc-700"
|
|
185
|
+
onkeydown={handleKeydown}
|
|
186
|
+
/>
|
|
187
|
+
<span class="text-muted-foreground">x</span>
|
|
188
|
+
<input
|
|
189
|
+
type="number"
|
|
190
|
+
bind:value={inputX}
|
|
191
|
+
min={0}
|
|
192
|
+
class="w-16 rounded border border-zinc-300 bg-transparent px-1.5 py-0.5 text-center font-mono text-xs dark:border-zinc-700"
|
|
193
|
+
onkeydown={handleKeydown}
|
|
194
|
+
/>
|
|
195
|
+
<span class="text-muted-foreground">y</span>
|
|
196
|
+
<input
|
|
197
|
+
type="number"
|
|
198
|
+
bind:value={inputY}
|
|
199
|
+
min={0}
|
|
200
|
+
class="w-16 rounded border border-zinc-300 bg-transparent px-1.5 py-0.5 text-center font-mono text-xs dark:border-zinc-700"
|
|
201
|
+
onkeydown={handleKeydown}
|
|
202
|
+
/>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<button
|
|
206
|
+
class="rounded bg-primary/90 px-3 py-1 text-xs text-primary-foreground hover:bg-primary"
|
|
207
|
+
onclick={fetchTile}
|
|
208
|
+
disabled={loading}
|
|
209
|
+
>
|
|
210
|
+
{loading ? '...' : t('pmtiles.fetchTile')}
|
|
211
|
+
</button>
|
|
212
|
+
|
|
213
|
+
<!-- Tile size badge -->
|
|
214
|
+
{#if tileSize > 0}
|
|
215
|
+
<span class="text-[10px] tabular-nums text-muted-foreground">
|
|
216
|
+
{formatBytes(tileSize)}
|
|
217
|
+
</span>
|
|
218
|
+
{/if}
|
|
219
|
+
|
|
220
|
+
<div class="ms-auto flex items-center gap-1">
|
|
221
|
+
<!-- Parent -->
|
|
222
|
+
<button
|
|
223
|
+
class="rounded bg-card/80 p-1 text-xs text-card-foreground hover:bg-card disabled:opacity-30"
|
|
224
|
+
onclick={navigateParent}
|
|
225
|
+
disabled={inputZ <= 0}
|
|
226
|
+
title={t('pmtiles.parent')}
|
|
227
|
+
>
|
|
228
|
+
<ChevronUpIcon class="size-3.5" />
|
|
229
|
+
</button>
|
|
230
|
+
|
|
231
|
+
<!-- Children 2x2 -->
|
|
232
|
+
<div class="grid grid-cols-2 gap-px">
|
|
233
|
+
{#each [[0, 0], [1, 0], [0, 1], [1, 1]] as [dx, dy]}
|
|
234
|
+
<button
|
|
235
|
+
class="size-4 rounded-sm bg-card/80 text-[8px] leading-none text-card-foreground hover:bg-card"
|
|
236
|
+
onclick={() => navigateChild(dx, dy)}
|
|
237
|
+
title="z{inputZ + 1}/{inputX * 2 + dx}/{inputY * 2 + dy}"
|
|
238
|
+
>
|
|
239
|
+
{dx}{dy}
|
|
240
|
+
</button>
|
|
241
|
+
{/each}
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<!-- Main content -->
|
|
247
|
+
<div class="flex min-h-0 flex-1 overflow-hidden">
|
|
248
|
+
{#if loading}
|
|
249
|
+
<div class="flex flex-1 items-center justify-center text-xs text-muted-foreground">
|
|
250
|
+
Loading tile...
|
|
251
|
+
</div>
|
|
252
|
+
{:else if error}
|
|
253
|
+
<div class="flex flex-1 items-center justify-center text-xs text-red-400">
|
|
254
|
+
{error}
|
|
255
|
+
</div>
|
|
256
|
+
{:else if tile}
|
|
257
|
+
<!-- SVG render area -->
|
|
258
|
+
<div class="relative min-w-0 flex-1 overflow-hidden p-2">
|
|
259
|
+
<SvgTileRenderer
|
|
260
|
+
{tile}
|
|
261
|
+
visibleLayers={layerVisibility}
|
|
262
|
+
{selectedFeatureKey}
|
|
263
|
+
onFeatureClick={selectFeature}
|
|
264
|
+
/>
|
|
265
|
+
|
|
266
|
+
<!-- Layer panel overlay -->
|
|
267
|
+
{#if showLayerPanel}
|
|
268
|
+
<div
|
|
269
|
+
class="absolute left-4 top-4 z-10 max-h-[50%] w-44 overflow-auto rounded bg-card/95 p-2 text-xs shadow-lg backdrop-blur-sm"
|
|
270
|
+
>
|
|
271
|
+
<div class="mb-1 flex items-center justify-between">
|
|
272
|
+
<span class="font-medium text-card-foreground">{t('pmtiles.layers')}</span>
|
|
273
|
+
<button
|
|
274
|
+
class="rounded p-0.5 text-zinc-400 hover:text-zinc-200"
|
|
275
|
+
onclick={() => (showLayerPanel = false)}
|
|
276
|
+
>
|
|
277
|
+
<XIcon class="size-3" />
|
|
278
|
+
</button>
|
|
279
|
+
</div>
|
|
280
|
+
{#each tile.layers as layer, i}
|
|
281
|
+
<label
|
|
282
|
+
class="flex cursor-pointer items-center gap-1.5 rounded px-1 py-0.5 hover:bg-zinc-800/50"
|
|
283
|
+
>
|
|
284
|
+
<input
|
|
285
|
+
type="checkbox"
|
|
286
|
+
checked={layerVisibility[layer.name] !== false}
|
|
287
|
+
onchange={() => (layerVisibility[layer.name] = !layerVisibility[layer.name])}
|
|
288
|
+
class="size-3 accent-primary"
|
|
289
|
+
/>
|
|
290
|
+
<span
|
|
291
|
+
class="inline-block size-2 shrink-0 rounded-sm"
|
|
292
|
+
style="background: hsl({layerHue(i)}, 70%, 55%)"
|
|
293
|
+
></span>
|
|
294
|
+
<span class="truncate text-card-foreground">{layer.name}</span>
|
|
295
|
+
<span class="ms-auto text-[10px] text-muted-foreground">
|
|
296
|
+
{layer.features.length}
|
|
297
|
+
</span>
|
|
298
|
+
</label>
|
|
299
|
+
{/each}
|
|
300
|
+
</div>
|
|
301
|
+
{/if}
|
|
302
|
+
</div>
|
|
303
|
+
|
|
304
|
+
<!-- Feature properties panel -->
|
|
305
|
+
<div
|
|
306
|
+
class="flex w-56 shrink-0 flex-col border-s border-zinc-200 lg:w-64 dark:border-zinc-800"
|
|
307
|
+
>
|
|
308
|
+
<div
|
|
309
|
+
class="shrink-0 border-b border-zinc-200 px-3 py-1.5 text-[11px] font-medium uppercase tracking-wider text-muted-foreground dark:border-zinc-800"
|
|
310
|
+
>
|
|
311
|
+
{t('pmtiles.featureProperties')}
|
|
312
|
+
</div>
|
|
313
|
+
{#if selectedFeature && selectedLayerName !== null}
|
|
314
|
+
<div class="flex-1 overflow-auto">
|
|
315
|
+
<div class="border-b border-zinc-200 px-3 py-2 dark:border-zinc-800">
|
|
316
|
+
<div class="flex items-center gap-1.5 text-xs">
|
|
317
|
+
<span
|
|
318
|
+
class="inline-block size-2 rounded-sm"
|
|
319
|
+
style="background: hsl({layerHue(tile.layers.findIndex((l) => l.name === selectedLayerName))}, 70%, 55%)"
|
|
320
|
+
></span>
|
|
321
|
+
<span class="font-medium">{selectedLayerName}</span>
|
|
322
|
+
</div>
|
|
323
|
+
<div class="mt-0.5 text-[10px] text-muted-foreground">
|
|
324
|
+
{selectedFeature.type}
|
|
325
|
+
{#if selectedFeature.id !== undefined}
|
|
326
|
+
· ID: {selectedFeature.id}
|
|
327
|
+
{/if}
|
|
328
|
+
· #{selectedFeatureIdx}
|
|
329
|
+
</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="divide-y divide-zinc-100 dark:divide-zinc-800">
|
|
332
|
+
{#each Object.entries(selectedFeature.properties) as [key, value]}
|
|
333
|
+
<div class="px-3 py-1.5">
|
|
334
|
+
<div class="text-[10px] font-medium text-zinc-500 dark:text-zinc-400">
|
|
335
|
+
{key}
|
|
336
|
+
</div>
|
|
337
|
+
<div
|
|
338
|
+
class="break-all text-xs text-zinc-700 dark:text-zinc-300"
|
|
339
|
+
title={formatValue(value)}
|
|
340
|
+
>
|
|
341
|
+
{formatValue(value)}
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
{/each}
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
{:else}
|
|
348
|
+
<div
|
|
349
|
+
class="flex flex-1 items-center justify-center px-4 text-center text-xs text-muted-foreground"
|
|
350
|
+
>
|
|
351
|
+
{t('pmtiles.selectFeature')}
|
|
352
|
+
</div>
|
|
353
|
+
{/if}
|
|
354
|
+
</div>
|
|
355
|
+
{:else if rasterUrl}
|
|
356
|
+
<!-- Raster tile preview -->
|
|
357
|
+
<div class="flex flex-1 items-center justify-center bg-zinc-950 p-4">
|
|
358
|
+
<img
|
|
359
|
+
src={rasterUrl}
|
|
360
|
+
alt="Tile {inputZ}/{inputX}/{inputY}"
|
|
361
|
+
class="max-h-full max-w-full rounded border border-zinc-800"
|
|
362
|
+
style="image-rendering: pixelated;"
|
|
363
|
+
/>
|
|
364
|
+
</div>
|
|
365
|
+
{:else}
|
|
366
|
+
<div
|
|
367
|
+
class="flex flex-1 items-center justify-center text-xs text-muted-foreground"
|
|
368
|
+
>
|
|
369
|
+
{t('pmtiles.noTileLoaded')}
|
|
370
|
+
</div>
|
|
371
|
+
{/if}
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PMTiles } from 'pmtiles';
|
|
2
|
+
import type { PmtilesMetadata } from '../../../utils/pmtiles';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
metadata: PmtilesMetadata;
|
|
5
|
+
pmtiles: PMTiles;
|
|
6
|
+
initialZ?: number;
|
|
7
|
+
initialX?: number;
|
|
8
|
+
initialY?: number;
|
|
9
|
+
};
|
|
10
|
+
declare const PmtilesTileInspector: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type PmtilesTileInspector = ReturnType<typeof PmtilesTileInspector>;
|
|
12
|
+
export default PmtilesTileInspector;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { DecodedLayer, DecodedTile } from '../../../utils/pmtiles-tile.js';
|
|
3
|
+
import { layerHue } from '../../../utils/pmtiles-tile.js';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
tile,
|
|
7
|
+
visibleLayers = {},
|
|
8
|
+
selectedFeatureKey = null,
|
|
9
|
+
onFeatureClick
|
|
10
|
+
}: {
|
|
11
|
+
tile: DecodedTile;
|
|
12
|
+
visibleLayers?: Record<string, boolean>;
|
|
13
|
+
selectedFeatureKey?: string | null;
|
|
14
|
+
onFeatureClick?: (layer: string, featureIndex: number) => void;
|
|
15
|
+
} = $props();
|
|
16
|
+
|
|
17
|
+
const SVG_SIZE = 512;
|
|
18
|
+
|
|
19
|
+
function featureKey(layerName: string, idx: number): string {
|
|
20
|
+
return `${layerName}:${idx}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function scale(layer: DecodedLayer): number {
|
|
24
|
+
return SVG_SIZE / layer.extent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function pointsToPath(rings: number[][][], s: number, close: boolean): string {
|
|
28
|
+
return rings
|
|
29
|
+
.map((ring) => {
|
|
30
|
+
const pts = ring.map((p) => `${(p[0] * s).toFixed(1)},${(p[1] * s).toFixed(1)}`);
|
|
31
|
+
return `M${pts.join('L')}${close ? 'Z' : ''}`;
|
|
32
|
+
})
|
|
33
|
+
.join('');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isVisible(layerName: string): boolean {
|
|
37
|
+
return visibleLayers[layerName] !== false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Build a flat list of all layer names with their index for color assignment. */
|
|
41
|
+
const layerIndex = $derived(new Map(tile.layers.map((l, i) => [l.name, i])));
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<svg
|
|
45
|
+
viewBox="0 0 {SVG_SIZE} {SVG_SIZE}"
|
|
46
|
+
class="h-full w-full rounded bg-zinc-950"
|
|
47
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
+
>
|
|
49
|
+
<!-- Grid lines -->
|
|
50
|
+
<g stroke="rgba(63,63,70,0.3)" stroke-width="0.5" fill="none">
|
|
51
|
+
{#each [0, 128, 256, 384, 512] as v}
|
|
52
|
+
<line x1={v} y1="0" x2={v} y2={SVG_SIZE} />
|
|
53
|
+
<line x1="0" y1={v} x2={SVG_SIZE} y2={v} />
|
|
54
|
+
{/each}
|
|
55
|
+
</g>
|
|
56
|
+
|
|
57
|
+
{#each tile.layers as layer}
|
|
58
|
+
{#if isVisible(layer.name)}
|
|
59
|
+
{@const s = scale(layer)}
|
|
60
|
+
{@const hue = layerHue(layerIndex.get(layer.name) ?? 0)}
|
|
61
|
+
<g>
|
|
62
|
+
{#each layer.features as feature, fi}
|
|
63
|
+
{@const key = featureKey(layer.name, fi)}
|
|
64
|
+
{@const selected = key === selectedFeatureKey}
|
|
65
|
+
{#if feature.type === 'Polygon'}
|
|
66
|
+
<path
|
|
67
|
+
d={pointsToPath(feature.geometry, s, true)}
|
|
68
|
+
fill="hsla({hue}, 70%, 55%, {selected ? 0.5 : 0.25})"
|
|
69
|
+
stroke="hsl({hue}, 70%, {selected ? '80%' : '45%'})"
|
|
70
|
+
stroke-width={selected ? 2 : 0.8}
|
|
71
|
+
class="cursor-pointer"
|
|
72
|
+
role="button"
|
|
73
|
+
tabindex="-1"
|
|
74
|
+
onclick={() => onFeatureClick?.(layer.name, fi)}
|
|
75
|
+
onkeydown={() => {}}
|
|
76
|
+
/>
|
|
77
|
+
{:else if feature.type === 'LineString'}
|
|
78
|
+
<path
|
|
79
|
+
d={pointsToPath(feature.geometry, s, false)}
|
|
80
|
+
fill="none"
|
|
81
|
+
stroke="hsl({hue}, 70%, {selected ? '80%' : '50%'})"
|
|
82
|
+
stroke-width={selected ? 2.5 : 1.2}
|
|
83
|
+
class="cursor-pointer"
|
|
84
|
+
role="button"
|
|
85
|
+
tabindex="-1"
|
|
86
|
+
onclick={() => onFeatureClick?.(layer.name, fi)}
|
|
87
|
+
onkeydown={() => {}}
|
|
88
|
+
/>
|
|
89
|
+
{:else if feature.type === 'Point'}
|
|
90
|
+
{#each feature.geometry as ring}
|
|
91
|
+
{#each ring as pt}
|
|
92
|
+
<circle
|
|
93
|
+
cx={(pt[0] * s).toFixed(1)}
|
|
94
|
+
cy={(pt[1] * s).toFixed(1)}
|
|
95
|
+
r={selected ? 5 : 3}
|
|
96
|
+
fill="hsl({hue}, 70%, 55%)"
|
|
97
|
+
stroke={selected ? '#ffc800' : 'white'}
|
|
98
|
+
stroke-width={selected ? 2 : 0.8}
|
|
99
|
+
class="cursor-pointer"
|
|
100
|
+
role="button"
|
|
101
|
+
tabindex="-1"
|
|
102
|
+
onclick={() => onFeatureClick?.(layer.name, fi)}
|
|
103
|
+
onkeydown={() => {}}
|
|
104
|
+
/>
|
|
105
|
+
{/each}
|
|
106
|
+
{/each}
|
|
107
|
+
{/if}
|
|
108
|
+
{/each}
|
|
109
|
+
</g>
|
|
110
|
+
{/if}
|
|
111
|
+
{/each}
|
|
112
|
+
</svg>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DecodedTile } from '../../../utils/pmtiles-tile.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
tile: DecodedTile;
|
|
4
|
+
visibleLayers?: Record<string, boolean>;
|
|
5
|
+
selectedFeatureKey?: string | null;
|
|
6
|
+
onFeatureClick?: (layer: string, featureIndex: number) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const SvgTileRenderer: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type SvgTileRenderer = ReturnType<typeof SvgTileRenderer>;
|
|
10
|
+
export default SvgTileRenderer;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file-icons/
|
|
2
|
+
|
|
3
|
+
Extension → file type registry. Maps 200+ extensions to viewer, icon, category, DuckDB read function.
|
|
4
|
+
|
|
5
|
+
```mermaid
|
|
6
|
+
graph LR
|
|
7
|
+
EXT[".parquet"] --> FT[getFileTypeInfo]
|
|
8
|
+
FT --> VK[getViewerKind → 'table']
|
|
9
|
+
FT --> DR[getDuckDbReadFn → 'read_parquet']
|
|
10
|
+
FT --> CN[isCloudNativeFormat → true]
|
|
11
|
+
FT --> QR[isQueryable → true]
|
|
12
|
+
FT --> IC[FileTypeIcon.svelte]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| File | Exports | Used by |
|
|
16
|
+
|------|---------|---------|
|
|
17
|
+
| `index.ts` | `getFileTypeInfo()`, `getDuckDbReadFn()`, `buildDuckDbSource()`, `isCloudNativeFormat()`, `getViewerKind()`, `isQueryable()`, `getMimeType()` | StatusBar, FileRow, ViewerRouter, TableViewer, query/wasm, +page.svelte, lib/index.ts |
|
|
18
|
+
| `FileTypeIcon.svelte` | Icon component (Lucide icons by category) | FileRow, TabBar |
|
|
19
|
+
|
|
20
|
+
Types: `FileCategory`, `ViewerKind`, `DuckDbReadFn`, `FileTypeInfo` (interface).
|
|
21
|
+
Published to npm. No Svelte dependency in `index.ts`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import ArchiveIcon from '@lucide/svelte/icons/archive';
|
|
3
|
+
import BookTextIcon from '@lucide/svelte/icons/book-text';
|
|
4
|
+
import BoxIcon from '@lucide/svelte/icons/box';
|
|
5
|
+
import BracesIcon from '@lucide/svelte/icons/braces';
|
|
6
|
+
import Columns3Icon from '@lucide/svelte/icons/columns-3';
|
|
7
|
+
import DatabaseIcon from '@lucide/svelte/icons/database';
|
|
8
|
+
import DatabaseZapIcon from '@lucide/svelte/icons/database-zap';
|
|
9
|
+
import FileIcon from '@lucide/svelte/icons/file';
|
|
10
|
+
import FileCodeIcon from '@lucide/svelte/icons/file-code';
|
|
11
|
+
import FileTextIcon from '@lucide/svelte/icons/file-text';
|
|
12
|
+
import FilmIcon from '@lucide/svelte/icons/film';
|
|
13
|
+
import FolderIcon from '@lucide/svelte/icons/folder';
|
|
14
|
+
import FolderOpenIcon from '@lucide/svelte/icons/folder-open';
|
|
15
|
+
import GlobeIcon from '@lucide/svelte/icons/globe';
|
|
16
|
+
import ImageIcon from '@lucide/svelte/icons/image';
|
|
17
|
+
import LayersIcon from '@lucide/svelte/icons/layers';
|
|
18
|
+
import MapIcon from '@lucide/svelte/icons/map';
|
|
19
|
+
import MusicIcon from '@lucide/svelte/icons/music';
|
|
20
|
+
import PaintbrushIcon from '@lucide/svelte/icons/paintbrush';
|
|
21
|
+
import PaletteIcon from '@lucide/svelte/icons/palette';
|
|
22
|
+
import SettingsIcon from '@lucide/svelte/icons/settings';
|
|
23
|
+
import TableIcon from '@lucide/svelte/icons/table';
|
|
24
|
+
import TerminalIcon from '@lucide/svelte/icons/terminal';
|
|
25
|
+
import ZapIcon from '@lucide/svelte/icons/zap';
|
|
26
|
+
import { getFileTypeInfo } from './index.js';
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
extension = '',
|
|
30
|
+
isDir = false,
|
|
31
|
+
isOpen = false,
|
|
32
|
+
class: className = 'size-4'
|
|
33
|
+
}: {
|
|
34
|
+
extension?: string;
|
|
35
|
+
isDir?: boolean;
|
|
36
|
+
isOpen?: boolean;
|
|
37
|
+
class?: string;
|
|
38
|
+
} = $props();
|
|
39
|
+
|
|
40
|
+
const info = $derived(getFileTypeInfo(extension, isDir));
|
|
41
|
+
|
|
42
|
+
const ICON_MAP: Record<string, any> = {
|
|
43
|
+
Columns3: Columns3Icon,
|
|
44
|
+
Table: TableIcon,
|
|
45
|
+
Braces: BracesIcon,
|
|
46
|
+
Globe: GlobeIcon,
|
|
47
|
+
Zap: ZapIcon,
|
|
48
|
+
FileCode: FileCodeIcon,
|
|
49
|
+
FileText: FileTextIcon,
|
|
50
|
+
Image: ImageIcon,
|
|
51
|
+
Palette: PaletteIcon,
|
|
52
|
+
Film: FilmIcon,
|
|
53
|
+
Music: MusicIcon,
|
|
54
|
+
Archive: ArchiveIcon,
|
|
55
|
+
Map: MapIcon,
|
|
56
|
+
Layers: LayersIcon,
|
|
57
|
+
Database: DatabaseIcon,
|
|
58
|
+
DatabaseZap: DatabaseZapIcon,
|
|
59
|
+
Box: BoxIcon,
|
|
60
|
+
Terminal: TerminalIcon,
|
|
61
|
+
BookText: BookTextIcon,
|
|
62
|
+
Settings: SettingsIcon,
|
|
63
|
+
Paintbrush: PaintbrushIcon,
|
|
64
|
+
Folder: FolderIcon,
|
|
65
|
+
FolderOpen: FolderOpenIcon,
|
|
66
|
+
File: FileIcon
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const Icon = $derived(
|
|
70
|
+
isDir ? (isOpen ? FolderOpenIcon : FolderIcon) : ICON_MAP[info.icon] || FileIcon
|
|
71
|
+
);
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<Icon class="{info.color} {className}" />
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
extension?: string;
|
|
3
|
+
isDir?: boolean;
|
|
4
|
+
isOpen?: boolean;
|
|
5
|
+
class?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const FileTypeIcon: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type FileTypeIcon = ReturnType<typeof FileTypeIcon>;
|
|
9
|
+
export default FileTypeIcon;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized file type detection module.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for extension → icon, color, label, category,
|
|
5
|
+
* viewer, DuckDB read function, MIME type, and queryability.
|
|
6
|
+
*
|
|
7
|
+
* Used by: FileRow, FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.
|
|
8
|
+
*/
|
|
9
|
+
export type FileCategory = 'data' | 'geo' | 'code' | 'document' | 'config' | 'image' | 'video' | 'audio' | 'archive' | 'database' | '3d' | 'other';
|
|
10
|
+
export type ViewerKind = 'table' | 'image' | 'video' | 'audio' | 'markdown' | 'code' | 'cog' | 'pmtiles' | 'flatgeobuf' | 'pdf' | '3d' | 'archive' | 'database' | 'zarr' | 'copc' | 'notebook' | 'raw';
|
|
11
|
+
export type DuckDbReadFn = 'read_parquet' | 'read_csv' | 'read_json' | 'ST_Read';
|
|
12
|
+
export interface FileTypeInfo {
|
|
13
|
+
/** Lucide icon name */
|
|
14
|
+
icon: string;
|
|
15
|
+
/** Tailwind color classes (light + dark) */
|
|
16
|
+
color: string;
|
|
17
|
+
/** Human-readable type label, e.g. "Apache Parquet" */
|
|
18
|
+
label: string;
|
|
19
|
+
/** High-level category */
|
|
20
|
+
category: FileCategory;
|
|
21
|
+
/** Which viewer component to use */
|
|
22
|
+
viewer: ViewerKind;
|
|
23
|
+
/** Whether this file can be queried with DuckDB */
|
|
24
|
+
queryable: boolean;
|
|
25
|
+
/** DuckDB read function (null if not queryable) */
|
|
26
|
+
duckdbReadFn: DuckDbReadFn | null;
|
|
27
|
+
/** MIME type */
|
|
28
|
+
mimeType: string;
|
|
29
|
+
}
|
|
30
|
+
declare const DEFAULT_INFO: FileTypeInfo;
|
|
31
|
+
declare const FOLDER_INFO: FileTypeInfo;
|
|
32
|
+
/**
|
|
33
|
+
* Returns full file type information for a given extension.
|
|
34
|
+
* Extension may be with or without leading dot: ".parquet" or "parquet".
|
|
35
|
+
*/
|
|
36
|
+
export declare function getFileTypeInfo(extension: string, isDir?: boolean): FileTypeInfo;
|
|
37
|
+
/** Returns the DuckDB read function name for a file path. Falls back to read_parquet. */
|
|
38
|
+
export declare function getDuckDbReadFn(pathOrExt: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Returns a DuckDB FROM-clause expression for a file.
|
|
41
|
+
*
|
|
42
|
+
* For GeoJSON files the raw `read_json_auto` returns a single row with the
|
|
43
|
+
* FeatureCollection structure (`type`, `features`, `bbox`). This helper
|
|
44
|
+
* unnests the features array so each feature becomes its own row with
|
|
45
|
+
* property columns + a geometry column.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildDuckDbSource(pathOrExt: string, url: string): string;
|
|
48
|
+
export declare function isCloudNativeFormat(pathOrExt: string): boolean;
|
|
49
|
+
/** Returns the viewer kind for a given extension. */
|
|
50
|
+
export declare function getViewerKind(extension: string): ViewerKind;
|
|
51
|
+
/** Returns whether a file can be queried with DuckDB. */
|
|
52
|
+
export declare function isQueryable(extension: string): boolean;
|
|
53
|
+
/** Returns the MIME type for a file extension. */
|
|
54
|
+
export declare function getMimeType(extension: string): string;
|
|
55
|
+
/** Re-export folder info for components that need it directly. */
|
|
56
|
+
export { FOLDER_INFO, DEFAULT_INFO };
|