@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.
Files changed (367) hide show
  1. package/LICENSE +396 -0
  2. package/README.md +114 -0
  3. package/dist/assets/favicon.svg +17 -0
  4. package/dist/components/CLAUDE.md +44 -0
  5. package/dist/components/browser/Breadcrumb.svelte +50 -0
  6. package/dist/components/browser/Breadcrumb.svelte.d.ts +7 -0
  7. package/dist/components/browser/CreateFolderDialog.svelte +98 -0
  8. package/dist/components/browser/CreateFolderDialog.svelte.d.ts +6 -0
  9. package/dist/components/browser/DeleteConfirmDialog.svelte +90 -0
  10. package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +8 -0
  11. package/dist/components/browser/DropZone.svelte +83 -0
  12. package/dist/components/browser/DropZone.svelte.d.ts +7 -0
  13. package/dist/components/browser/FileBrowser.svelte +229 -0
  14. package/dist/components/browser/FileBrowser.svelte.d.ts +3 -0
  15. package/dist/components/browser/FileRow.svelte +112 -0
  16. package/dist/components/browser/FileRow.svelte.d.ts +9 -0
  17. package/dist/components/browser/FileTreeSidebar.svelte +559 -0
  18. package/dist/components/browser/FileTreeSidebar.svelte.d.ts +8 -0
  19. package/dist/components/browser/RenameDialog.svelte +101 -0
  20. package/dist/components/browser/RenameDialog.svelte.d.ts +8 -0
  21. package/dist/components/browser/SearchBar.svelte +40 -0
  22. package/dist/components/browser/SearchBar.svelte.d.ts +6 -0
  23. package/dist/components/browser/UploadButton.svelte +65 -0
  24. package/dist/components/browser/UploadButton.svelte.d.ts +3 -0
  25. package/dist/components/editor/CodeMirrorEditor.svelte +404 -0
  26. package/dist/components/editor/CodeMirrorEditor.svelte.d.ts +12 -0
  27. package/dist/components/editor/MilkdownEditor.svelte +98 -0
  28. package/dist/components/editor/MilkdownEditor.svelte.d.ts +9 -0
  29. package/dist/components/editor/SqlEditor.svelte +173 -0
  30. package/dist/components/editor/SqlEditor.svelte.d.ts +7 -0
  31. package/dist/components/editor/SqlResultBlock.svelte +199 -0
  32. package/dist/components/editor/SqlResultBlock.svelte.d.ts +9 -0
  33. package/dist/components/layout/ConnectionDialog.svelte +439 -0
  34. package/dist/components/layout/ConnectionDialog.svelte.d.ts +9 -0
  35. package/dist/components/layout/LocaleToggle.svelte +32 -0
  36. package/dist/components/layout/LocaleToggle.svelte.d.ts +3 -0
  37. package/dist/components/layout/SafeLockToggle.svelte +37 -0
  38. package/dist/components/layout/SafeLockToggle.svelte.d.ts +18 -0
  39. package/dist/components/layout/Sidebar.svelte +314 -0
  40. package/dist/components/layout/Sidebar.svelte.d.ts +3 -0
  41. package/dist/components/layout/StatusBar.svelte +73 -0
  42. package/dist/components/layout/StatusBar.svelte.d.ts +3 -0
  43. package/dist/components/layout/TabBar.svelte +102 -0
  44. package/dist/components/layout/TabBar.svelte.d.ts +7 -0
  45. package/dist/components/layout/ThemeToggle.svelte +52 -0
  46. package/dist/components/layout/ThemeToggle.svelte.d.ts +3 -0
  47. package/dist/components/ui/badge/badge.svelte +49 -0
  48. package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
  49. package/dist/components/ui/badge/index.d.ts +1 -0
  50. package/dist/components/ui/badge/index.js +1 -0
  51. package/dist/components/ui/button/button.svelte +82 -0
  52. package/dist/components/ui/button/button.svelte.d.ts +64 -0
  53. package/dist/components/ui/button/index.d.ts +2 -0
  54. package/dist/components/ui/button/index.js +4 -0
  55. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +40 -0
  56. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
  57. package/dist/components/ui/context-menu/context-menu-content.svelte +28 -0
  58. package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +10 -0
  59. package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  60. package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
  61. package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
  62. package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
  63. package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
  64. package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
  65. package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
  66. package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
  67. package/dist/components/ui/context-menu/context-menu-portal.svelte +7 -0
  68. package/dist/components/ui/context-menu/context-menu-portal.svelte.d.ts +3 -0
  69. package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  70. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
  71. package/dist/components/ui/context-menu/context-menu-radio-item.svelte +33 -0
  72. package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
  73. package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
  74. package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
  75. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  76. package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
  77. package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  78. package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
  79. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  80. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
  81. package/dist/components/ui/context-menu/context-menu-sub.svelte +7 -0
  82. package/dist/components/ui/context-menu/context-menu-sub.svelte.d.ts +3 -0
  83. package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  84. package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
  85. package/dist/components/ui/context-menu/context-menu.svelte +7 -0
  86. package/dist/components/ui/context-menu/context-menu.svelte.d.ts +3 -0
  87. package/dist/components/ui/context-menu/index.d.ts +17 -0
  88. package/dist/components/ui/context-menu/index.js +19 -0
  89. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  90. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
  91. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
  92. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
  93. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +29 -0
  94. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
  95. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  96. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
  97. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +7 -0
  98. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
  99. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +27 -0
  100. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
  101. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +24 -0
  102. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
  103. package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  104. package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
  105. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  106. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
  107. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +33 -0
  108. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
  109. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  110. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
  111. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
  112. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
  113. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
  114. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +4 -0
  115. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  116. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
  117. package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  118. package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
  119. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  120. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
  121. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
  122. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
  123. package/dist/components/ui/dropdown-menu/index.d.ts +18 -0
  124. package/dist/components/ui/dropdown-menu/index.js +18 -0
  125. package/dist/components/ui/input/index.d.ts +2 -0
  126. package/dist/components/ui/input/index.js +4 -0
  127. package/dist/components/ui/input/input.svelte +52 -0
  128. package/dist/components/ui/input/input.svelte.d.ts +13 -0
  129. package/dist/components/ui/resizable/index.d.ts +4 -0
  130. package/dist/components/ui/resizable/index.js +6 -0
  131. package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
  132. package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
  133. package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
  134. package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
  135. package/dist/components/ui/scroll-area/index.d.ts +3 -0
  136. package/dist/components/ui/scroll-area/index.js +5 -0
  137. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  138. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
  139. package/dist/components/ui/scroll-area/scroll-area.svelte +47 -0
  140. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
  141. package/dist/components/ui/separator/index.d.ts +2 -0
  142. package/dist/components/ui/separator/index.js +4 -0
  143. package/dist/components/ui/separator/separator.svelte +21 -0
  144. package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
  145. package/dist/components/ui/sheet/index.d.ts +11 -0
  146. package/dist/components/ui/sheet/index.js +13 -0
  147. package/dist/components/ui/sheet/sheet-close.svelte +7 -0
  148. package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
  149. package/dist/components/ui/sheet/sheet-content.svelte +62 -0
  150. package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
  151. package/dist/components/ui/sheet/sheet-description.svelte +17 -0
  152. package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
  153. package/dist/components/ui/sheet/sheet-footer.svelte +20 -0
  154. package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
  155. package/dist/components/ui/sheet/sheet-header.svelte +20 -0
  156. package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
  157. package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
  158. package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
  159. package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
  160. package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
  161. package/dist/components/ui/sheet/sheet-title.svelte +13 -0
  162. package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
  163. package/dist/components/ui/sheet/sheet-trigger.svelte +7 -0
  164. package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
  165. package/dist/components/ui/sheet/sheet.svelte +7 -0
  166. package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -0
  167. package/dist/components/ui/switch/index.d.ts +2 -0
  168. package/dist/components/ui/switch/index.js +4 -0
  169. package/dist/components/ui/switch/switch.svelte +28 -0
  170. package/dist/components/ui/switch/switch.svelte.d.ts +8 -0
  171. package/dist/components/ui/tabs/index.d.ts +5 -0
  172. package/dist/components/ui/tabs/index.js +7 -0
  173. package/dist/components/ui/tabs/tabs-content.svelte +17 -0
  174. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  175. package/dist/components/ui/tabs/tabs-list.svelte +16 -0
  176. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  177. package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
  178. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  179. package/dist/components/ui/tabs/tabs.svelte +19 -0
  180. package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
  181. package/dist/components/ui/tooltip/index.d.ts +6 -0
  182. package/dist/components/ui/tooltip/index.js +8 -0
  183. package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
  184. package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
  185. package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
  186. package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
  187. package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
  188. package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
  189. package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  190. package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
  191. package/dist/components/ui/tooltip/tooltip.svelte +7 -0
  192. package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
  193. package/dist/components/viewers/ArchiveViewer.svelte +586 -0
  194. package/dist/components/viewers/ArchiveViewer.svelte.d.ts +7 -0
  195. package/dist/components/viewers/CLAUDE.md +60 -0
  196. package/dist/components/viewers/CodeViewer.svelte +553 -0
  197. package/dist/components/viewers/CodeViewer.svelte.d.ts +7 -0
  198. package/dist/components/viewers/CogViewer.svelte +1345 -0
  199. package/dist/components/viewers/CogViewer.svelte.d.ts +7 -0
  200. package/dist/components/viewers/CopcViewer.svelte +25 -0
  201. package/dist/components/viewers/CopcViewer.svelte.d.ts +7 -0
  202. package/dist/components/viewers/DatabaseViewer.svelte +169 -0
  203. package/dist/components/viewers/DatabaseViewer.svelte.d.ts +7 -0
  204. package/dist/components/viewers/FileInfo.svelte +174 -0
  205. package/dist/components/viewers/FileInfo.svelte.d.ts +10 -0
  206. package/dist/components/viewers/FlatGeobufViewer.svelte +755 -0
  207. package/dist/components/viewers/FlatGeobufViewer.svelte.d.ts +7 -0
  208. package/dist/components/viewers/GeoParquetMapViewer.svelte +278 -0
  209. package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +17 -0
  210. package/dist/components/viewers/ImageViewer.svelte +233 -0
  211. package/dist/components/viewers/ImageViewer.svelte.d.ts +7 -0
  212. package/dist/components/viewers/LoadProgress.svelte +93 -0
  213. package/dist/components/viewers/LoadProgress.svelte.d.ts +15 -0
  214. package/dist/components/viewers/MapViewer.svelte +234 -0
  215. package/dist/components/viewers/MapViewer.svelte.d.ts +7 -0
  216. package/dist/components/viewers/MarkdownViewer.svelte +478 -0
  217. package/dist/components/viewers/MarkdownViewer.svelte.d.ts +7 -0
  218. package/dist/components/viewers/MediaViewer.svelte +121 -0
  219. package/dist/components/viewers/MediaViewer.svelte.d.ts +7 -0
  220. package/dist/components/viewers/ModelViewer.svelte +164 -0
  221. package/dist/components/viewers/ModelViewer.svelte.d.ts +7 -0
  222. package/dist/components/viewers/NotebookViewer.svelte +389 -0
  223. package/dist/components/viewers/NotebookViewer.svelte.d.ts +7 -0
  224. package/dist/components/viewers/PdfViewer.svelte +278 -0
  225. package/dist/components/viewers/PdfViewer.svelte.d.ts +7 -0
  226. package/dist/components/viewers/PmtilesViewer.svelte +191 -0
  227. package/dist/components/viewers/PmtilesViewer.svelte.d.ts +7 -0
  228. package/dist/components/viewers/QueryHistoryPanel.svelte +159 -0
  229. package/dist/components/viewers/QueryHistoryPanel.svelte.d.ts +8 -0
  230. package/dist/components/viewers/RawViewer.svelte +117 -0
  231. package/dist/components/viewers/RawViewer.svelte.d.ts +7 -0
  232. package/dist/components/viewers/StacMapViewer.svelte +20 -0
  233. package/dist/components/viewers/StacMapViewer.svelte.d.ts +7 -0
  234. package/dist/components/viewers/StyleEditorOverlay.svelte +27 -0
  235. package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +7 -0
  236. package/dist/components/viewers/TableGrid.svelte +355 -0
  237. package/dist/components/viewers/TableGrid.svelte.d.ts +12 -0
  238. package/dist/components/viewers/TableStatusBar.svelte +92 -0
  239. package/dist/components/viewers/TableStatusBar.svelte.d.ts +11 -0
  240. package/dist/components/viewers/TableToolbar.svelte +382 -0
  241. package/dist/components/viewers/TableToolbar.svelte.d.ts +25 -0
  242. package/dist/components/viewers/TableViewer.svelte +923 -0
  243. package/dist/components/viewers/TableViewer.svelte.d.ts +7 -0
  244. package/dist/components/viewers/ViewerRouter.svelte +70 -0
  245. package/dist/components/viewers/ViewerRouter.svelte.d.ts +7 -0
  246. package/dist/components/viewers/ZarrMapViewer.svelte +288 -0
  247. package/dist/components/viewers/ZarrMapViewer.svelte.d.ts +17 -0
  248. package/dist/components/viewers/ZarrViewer.svelte +256 -0
  249. package/dist/components/viewers/ZarrViewer.svelte.d.ts +7 -0
  250. package/dist/components/viewers/map/AttributeTable.svelte +52 -0
  251. package/dist/components/viewers/map/AttributeTable.svelte.d.ts +8 -0
  252. package/dist/components/viewers/map/MapContainer.svelte +158 -0
  253. package/dist/components/viewers/map/MapContainer.svelte.d.ts +12 -0
  254. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +389 -0
  255. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte.d.ts +10 -0
  256. package/dist/components/viewers/pmtiles/PmtilesMapView.svelte +332 -0
  257. package/dist/components/viewers/pmtiles/PmtilesMapView.svelte.d.ts +11 -0
  258. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +373 -0
  259. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte.d.ts +12 -0
  260. package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte +112 -0
  261. package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte.d.ts +10 -0
  262. package/dist/file-icons/CLAUDE.md +21 -0
  263. package/dist/file-icons/FileTypeIcon.svelte +74 -0
  264. package/dist/file-icons/FileTypeIcon.svelte.d.ts +9 -0
  265. package/dist/file-icons/index.d.ts +56 -0
  266. package/dist/file-icons/index.js +1070 -0
  267. package/dist/i18n/CLAUDE.md +19 -0
  268. package/dist/i18n/ar.d.ts +1 -0
  269. package/dist/i18n/ar.js +404 -0
  270. package/dist/i18n/en.d.ts +1 -0
  271. package/dist/i18n/en.js +404 -0
  272. package/dist/i18n/index.svelte.d.ts +9 -0
  273. package/dist/i18n/index.svelte.js +27 -0
  274. package/dist/index.d.ts +20 -0
  275. package/dist/index.js +13 -0
  276. package/dist/query/CLAUDE.md +22 -0
  277. package/dist/query/engine.d.ts +56 -0
  278. package/dist/query/engine.js +6 -0
  279. package/dist/query/index.d.ts +4 -0
  280. package/dist/query/index.js +19 -0
  281. package/dist/query/wasm.d.ts +20 -0
  282. package/dist/query/wasm.js +890 -0
  283. package/dist/storage/CLAUDE.md +23 -0
  284. package/dist/storage/adapter.d.ts +21 -0
  285. package/dist/storage/adapter.js +1 -0
  286. package/dist/storage/browser-azure.d.ts +25 -0
  287. package/dist/storage/browser-azure.js +271 -0
  288. package/dist/storage/browser-cloud.d.ts +32 -0
  289. package/dist/storage/browser-cloud.js +293 -0
  290. package/dist/storage/index.d.ts +11 -0
  291. package/dist/storage/index.js +37 -0
  292. package/dist/storage/url-adapter.d.ts +19 -0
  293. package/dist/storage/url-adapter.js +51 -0
  294. package/dist/stores/CLAUDE.md +29 -0
  295. package/dist/stores/browser.svelte.d.ts +28 -0
  296. package/dist/stores/browser.svelte.js +160 -0
  297. package/dist/stores/connections.svelte.d.ts +56 -0
  298. package/dist/stores/connections.svelte.js +272 -0
  299. package/dist/stores/credentials.svelte.d.ts +56 -0
  300. package/dist/stores/credentials.svelte.js +79 -0
  301. package/dist/stores/files.svelte.d.ts +20 -0
  302. package/dist/stores/files.svelte.js +76 -0
  303. package/dist/stores/query-history.svelte.d.ts +16 -0
  304. package/dist/stores/query-history.svelte.js +57 -0
  305. package/dist/stores/safelock.svelte.d.ts +8 -0
  306. package/dist/stores/safelock.svelte.js +52 -0
  307. package/dist/stores/settings.svelte.d.ts +11 -0
  308. package/dist/stores/settings.svelte.js +101 -0
  309. package/dist/stores/tab-resources.svelte.d.ts +25 -0
  310. package/dist/stores/tab-resources.svelte.js +61 -0
  311. package/dist/stores/tabs.svelte.d.ts +17 -0
  312. package/dist/stores/tabs.svelte.js +110 -0
  313. package/dist/types/notebookjs.d.ts +14 -0
  314. package/dist/types.d.ts +47 -0
  315. package/dist/types.js +1 -0
  316. package/dist/utils/CLAUDE.md +54 -0
  317. package/dist/utils/analytics.d.ts +10 -0
  318. package/dist/utils/analytics.js +38 -0
  319. package/dist/utils/archive.d.ts +70 -0
  320. package/dist/utils/archive.js +333 -0
  321. package/dist/utils/column-types.d.ts +5 -0
  322. package/dist/utils/column-types.js +137 -0
  323. package/dist/utils/deck.d.ts +98 -0
  324. package/dist/utils/deck.js +208 -0
  325. package/dist/utils/evidence-context.d.ts +22 -0
  326. package/dist/utils/evidence-context.js +56 -0
  327. package/dist/utils/export.d.ts +2 -0
  328. package/dist/utils/export.js +51 -0
  329. package/dist/utils/format.d.ts +14 -0
  330. package/dist/utils/format.js +56 -0
  331. package/dist/utils/geoarrow.d.ts +32 -0
  332. package/dist/utils/geoarrow.js +672 -0
  333. package/dist/utils/hex.d.ts +10 -0
  334. package/dist/utils/hex.js +27 -0
  335. package/dist/utils/host-detection.d.ts +23 -0
  336. package/dist/utils/host-detection.js +289 -0
  337. package/dist/utils/map-selection.d.ts +12 -0
  338. package/dist/utils/map-selection.js +45 -0
  339. package/dist/utils/markdown-sql.d.ts +30 -0
  340. package/dist/utils/markdown-sql.js +73 -0
  341. package/dist/utils/markdown.d.ts +18 -0
  342. package/dist/utils/markdown.js +146 -0
  343. package/dist/utils/model3d.d.ts +13 -0
  344. package/dist/utils/model3d.js +62 -0
  345. package/dist/utils/parquet-metadata.d.ts +58 -0
  346. package/dist/utils/parquet-metadata.js +228 -0
  347. package/dist/utils/pdf.d.ts +8 -0
  348. package/dist/utils/pdf.js +28 -0
  349. package/dist/utils/pmtiles-tile.d.ts +38 -0
  350. package/dist/utils/pmtiles-tile.js +64 -0
  351. package/dist/utils/pmtiles.d.ts +46 -0
  352. package/dist/utils/pmtiles.js +135 -0
  353. package/dist/utils/shiki.d.ts +8 -0
  354. package/dist/utils/shiki.js +98 -0
  355. package/dist/utils/storage-url.d.ts +64 -0
  356. package/dist/utils/storage-url.js +374 -0
  357. package/dist/utils/url-state.d.ts +40 -0
  358. package/dist/utils/url-state.js +113 -0
  359. package/dist/utils/url.d.ts +27 -0
  360. package/dist/utils/url.js +115 -0
  361. package/dist/utils/wkb.d.ts +43 -0
  362. package/dist/utils/wkb.js +345 -0
  363. package/dist/utils/zarr.d.ts +39 -0
  364. package/dist/utils/zarr.js +204 -0
  365. package/dist/utils.d.ts +12 -0
  366. package/dist/utils.js +5 -0
  367. package/package.json +203 -0
@@ -0,0 +1,117 @@
1
+ <script lang="ts">
2
+ import { onDestroy } from 'svelte';
3
+ import { Badge } from '../ui/badge/index.js';
4
+ import { t } from '../../i18n/index.svelte.js';
5
+ import { getAdapter } from '../../storage/index.js';
6
+ import { tabResources } from '../../stores/tab-resources.svelte.js';
7
+ import type { Tab } from '../../types';
8
+ import { formatFileSize } from '../../utils/format';
9
+ import { generateHexDump, type HexRow } from '../../utils/hex';
10
+
11
+ let { tab }: { tab: Tab } = $props();
12
+
13
+ const MAX_BYTES = 8192;
14
+
15
+ let abortController: AbortController | null = null;
16
+ let rows = $state<HexRow[]>([]);
17
+ let fileSize = $state(0);
18
+ let loading = $state(true);
19
+ let error = $state<string | null>(null);
20
+ let truncated = $state(false);
21
+
22
+ function cleanup() {
23
+ abortController?.abort();
24
+ abortController = null;
25
+ rows = [];
26
+ fileSize = 0;
27
+ }
28
+
29
+ $effect(() => {
30
+ if (!tab) return;
31
+ const unregister = tabResources.register(tab.id, cleanup);
32
+ return unregister;
33
+ });
34
+ onDestroy(cleanup);
35
+
36
+ $effect(() => {
37
+ if (!tab) return;
38
+ loadHexDump();
39
+ });
40
+
41
+ async function loadHexDump() {
42
+ abortController?.abort();
43
+ abortController = new AbortController();
44
+ const { signal } = abortController;
45
+
46
+ loading = true;
47
+ error = null;
48
+
49
+ try {
50
+ const adapter = getAdapter(tab.source, tab.connectionId);
51
+ const meta = await adapter.head(tab.path, signal);
52
+ fileSize = meta.size;
53
+
54
+ const data = await adapter.read(tab.path, 0, MAX_BYTES, signal);
55
+ truncated = fileSize > MAX_BYTES;
56
+ rows = generateHexDump(data);
57
+ } catch (err) {
58
+ if (err instanceof DOMException && err.name === 'AbortError') return;
59
+ error = err instanceof Error ? err.message : String(err);
60
+ } finally {
61
+ loading = false;
62
+ }
63
+ }
64
+ </script>
65
+
66
+ <div class="flex h-full flex-col">
67
+ <div
68
+ class="flex items-center gap-1 border-b border-zinc-200 px-2 py-1.5 sm:gap-2 sm:px-4 dark:border-zinc-800"
69
+ >
70
+ <span class="truncate max-w-[120px] text-sm font-medium text-zinc-700 sm:max-w-none dark:text-zinc-300">{tab.name}</span>
71
+ {#if tab.extension}
72
+ <Badge variant="secondary">{tab.extension}</Badge>
73
+ {/if}
74
+ {#if !loading && fileSize > 0}
75
+ <span class="hidden text-xs text-zinc-400 sm:inline dark:text-zinc-500">
76
+ {formatFileSize(fileSize)}
77
+ </span>
78
+ {#if truncated}
79
+ <span class="hidden text-xs text-amber-500 sm:inline">
80
+ ({t('raw.showingFirst').replace('{size}', formatFileSize(MAX_BYTES))})
81
+ </span>
82
+ {/if}
83
+ {/if}
84
+ </div>
85
+
86
+ <div class="flex-1 overflow-auto bg-zinc-950 p-4 font-mono text-xs">
87
+ {#if loading}
88
+ <p class="text-zinc-400">{t('raw.loading')}</p>
89
+ {:else if error}
90
+ <p class="text-red-400">{error}</p>
91
+ {:else}
92
+ <table class="w-full border-collapse">
93
+ <thead>
94
+ <tr class="text-zinc-500">
95
+ <th class="px-2 pb-2 text-start">Offset</th>
96
+ <th class="px-2 pb-2 text-start" colspan="2">Hex</th>
97
+ <th class="px-2 pb-2 text-start">ASCII</th>
98
+ </tr>
99
+ </thead>
100
+ <tbody>
101
+ {#each rows as row}
102
+ <tr class="hover:bg-zinc-800/50">
103
+ <td class="px-2 py-px text-zinc-500">{row.offset}</td>
104
+ <td class="px-2 py-px text-zinc-300">
105
+ {row.hex.slice(0, 8).join(' ')}
106
+ </td>
107
+ <td class="px-2 py-px text-zinc-300">
108
+ {row.hex.slice(8).join(' ')}
109
+ </td>
110
+ <td class="px-2 py-px text-emerald-400">{row.ascii}</td>
111
+ </tr>
112
+ {/each}
113
+ </tbody>
114
+ </table>
115
+ {/if}
116
+ </div>
117
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { Tab } from '../../types';
2
+ type $$ComponentProps = {
3
+ tab: Tab;
4
+ };
5
+ declare const RawViewer: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type RawViewer = ReturnType<typeof RawViewer>;
7
+ export default RawViewer;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { Tab } from '../../types';
3
+ import { buildHttpsUrl } from '../../utils/url.js';
4
+
5
+ let { tab }: { tab: Tab } = $props();
6
+
7
+ const fileUrl = $derived(buildHttpsUrl(tab));
8
+ const iframeSrc = $derived(
9
+ `https://developmentseed.org/stac-map?href=${encodeURIComponent(fileUrl)}`
10
+ );
11
+ </script>
12
+
13
+ <div class="relative flex h-full overflow-hidden">
14
+ <iframe
15
+ src={iframeSrc}
16
+ class="h-full w-full border-0"
17
+ title="STAC Map"
18
+ allow="fullscreen"
19
+ ></iframe>
20
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { Tab } from '../../types';
2
+ type $$ComponentProps = {
3
+ tab: Tab;
4
+ };
5
+ declare const StacMapViewer: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type StacMapViewer = ReturnType<typeof StacMapViewer>;
7
+ export default StacMapViewer;
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ let { styleUrl, onclose }: { styleUrl: string; onclose: () => void } = $props();
3
+
4
+ const maputnikUrl = $derived(
5
+ `https://maplibre.org/maputnik/?style=${encodeURIComponent(styleUrl)}`
6
+ );
7
+ </script>
8
+
9
+ <div class="fixed inset-0 z-50 flex flex-col bg-zinc-950">
10
+ <div
11
+ class="flex items-center justify-between border-b border-zinc-800 bg-zinc-900 px-4 py-2"
12
+ >
13
+ <span class="text-sm font-medium text-zinc-300">Maputnik Style Editor</span>
14
+ <button
15
+ class="rounded px-3 py-1 text-xs text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200"
16
+ onclick={onclose}
17
+ >
18
+ Close
19
+ </button>
20
+ </div>
21
+ <iframe
22
+ src={maputnikUrl}
23
+ class="flex-1 border-0"
24
+ title="Maputnik Style Editor"
25
+ allow="clipboard-read; clipboard-write"
26
+ ></iframe>
27
+ </div>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ styleUrl: string;
3
+ onclose: () => void;
4
+ };
5
+ declare const StyleEditorOverlay: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type StyleEditorOverlay = ReturnType<typeof StyleEditorOverlay>;
7
+ export default StyleEditorOverlay;
@@ -0,0 +1,355 @@
1
+ <script lang="ts">
2
+ import ArrowDownIcon from '@lucide/svelte/icons/arrow-down';
3
+ import ArrowUpIcon from '@lucide/svelte/icons/arrow-up';
4
+ import CheckIcon from '@lucide/svelte/icons/check';
5
+ import ClipboardIcon from '@lucide/svelte/icons/clipboard';
6
+ import ColumnsIcon from '@lucide/svelte/icons/columns-3';
7
+ import CopyIcon from '@lucide/svelte/icons/copy';
8
+ import RowsIcon from '@lucide/svelte/icons/rows-3';
9
+ import XIcon from '@lucide/svelte/icons/x';
10
+ import { onDestroy } from 'svelte';
11
+ import { t } from '../../i18n/index.svelte.js';
12
+ import {
13
+ classifyType,
14
+ type TypeCategory,
15
+ typeBadgeClass,
16
+ typeLabel
17
+ } from '../../utils/column-types.js';
18
+
19
+ const INITIAL_ROWS = 100;
20
+ const BATCH_SIZE = 100;
21
+ const DEFAULT_WIDTH = 150;
22
+ const MIN_WIDTH = 60;
23
+ const ROW_NUM_WIDTH = 52;
24
+
25
+ let {
26
+ columns,
27
+ rows,
28
+ totalRows = 0,
29
+ columnTypes = {} as Record<string, string>,
30
+ sortColumn = null as string | null,
31
+ sortDirection = null as 'asc' | 'desc' | null,
32
+ onSort
33
+ }: {
34
+ columns: string[];
35
+ rows: Record<string, any>[];
36
+ totalRows?: number;
37
+ columnTypes?: Record<string, string>;
38
+ sortColumn?: string | null;
39
+ sortDirection?: 'asc' | 'desc' | null;
40
+ onSort?: (column: string, direction: 'asc' | 'desc' | null) => void;
41
+ } = $props();
42
+
43
+ // ── Progressive rendering (append-on-scroll) ──
44
+
45
+ let renderedCount = $state(0);
46
+
47
+ $effect(() => {
48
+ // Reset when rows data changes
49
+ void rows;
50
+ renderedCount = Math.min(INITIAL_ROWS, rows.length);
51
+ });
52
+
53
+ const displayRows = $derived(rows.slice(0, renderedCount));
54
+
55
+ function onScroll(e: Event) {
56
+ const el = e.target as HTMLDivElement;
57
+ if (renderedCount < rows.length && el.scrollHeight - el.scrollTop < el.clientHeight * 2) {
58
+ renderedCount = Math.min(renderedCount + BATCH_SIZE, rows.length);
59
+ }
60
+ }
61
+
62
+ // ── Precompute type categories ──
63
+
64
+ const columnCategories = $derived(
65
+ Object.fromEntries(
66
+ columns.map((col) => [col, classifyType(columnTypes[col] || 'VARCHAR')])
67
+ ) as Record<string, TypeCategory>
68
+ );
69
+
70
+ // ── Resizable columns ──
71
+
72
+ let resizeCleanup: (() => void) | null = null;
73
+ let columnWidths = $state<Record<string, number>>({});
74
+
75
+ const tableWidth = $derived(
76
+ ROW_NUM_WIDTH + columns.reduce((sum, col) => sum + (columnWidths[col] || DEFAULT_WIDTH), 0)
77
+ );
78
+
79
+ function startResize(col: string, e: MouseEvent) {
80
+ e.preventDefault();
81
+ e.stopPropagation();
82
+ const startX = e.clientX;
83
+ const startW = columnWidths[col] || DEFAULT_WIDTH;
84
+
85
+ function onMove(ev: MouseEvent) {
86
+ columnWidths[col] = Math.max(MIN_WIDTH, startW + (ev.clientX - startX));
87
+ }
88
+ function onUp() {
89
+ document.removeEventListener('mousemove', onMove);
90
+ document.removeEventListener('mouseup', onUp);
91
+ resizeCleanup = null;
92
+ }
93
+ document.addEventListener('mousemove', onMove);
94
+ document.addEventListener('mouseup', onUp);
95
+ resizeCleanup = () => {
96
+ document.removeEventListener('mousemove', onMove);
97
+ document.removeEventListener('mouseup', onUp);
98
+ };
99
+ }
100
+
101
+ onDestroy(() => resizeCleanup?.());
102
+
103
+ function resetWidth(col: string) {
104
+ delete columnWidths[col];
105
+ columnWidths = { ...columnWidths };
106
+ }
107
+
108
+ // ── Sort ──
109
+
110
+ function handleHeaderClick(col: string) {
111
+ if (!onSort) return;
112
+ if (sortColumn === col) {
113
+ if (sortDirection === 'asc') onSort(col, 'desc');
114
+ else if (sortDirection === 'desc') onSort(col, null);
115
+ else onSort(col, 'asc');
116
+ } else {
117
+ onSort(col, 'asc');
118
+ }
119
+ }
120
+
121
+ // ── Context menu ──
122
+
123
+ let ctxMenu = $state<{
124
+ x: number;
125
+ y: number;
126
+ value: string;
127
+ rowData: Record<string, any>;
128
+ colName: string;
129
+ } | null>(null);
130
+
131
+ let copied = $state(false);
132
+
133
+ function handleContextMenu(e: MouseEvent, value: any, row: Record<string, any>, col: string) {
134
+ e.preventDefault();
135
+ const category = columnCategories[col];
136
+ ctxMenu = {
137
+ x: e.clientX,
138
+ y: e.clientY,
139
+ value: isNull(value) ? 'NULL' : formatCell(value, category),
140
+ rowData: row,
141
+ colName: col
142
+ };
143
+ copied = false;
144
+ }
145
+
146
+ async function copyToClipboard(text: string) {
147
+ try {
148
+ await navigator.clipboard.writeText(text);
149
+ copied = true;
150
+ setTimeout(() => {
151
+ ctxMenu = null;
152
+ copied = false;
153
+ }, 400);
154
+ } catch {
155
+ ctxMenu = null;
156
+ }
157
+ }
158
+
159
+ function copyCell() {
160
+ if (ctxMenu) copyToClipboard(ctxMenu.value);
161
+ }
162
+
163
+ function copyRow() {
164
+ if (!ctxMenu) return;
165
+ // Exclude internal columns like __wkb
166
+ const clean: Record<string, any> = {};
167
+ for (const [k, v] of Object.entries(ctxMenu.rowData)) {
168
+ if (!k.startsWith('__')) clean[k] = v;
169
+ }
170
+ copyToClipboard(JSON.stringify(clean, (_k, v) => (typeof v === 'bigint' ? v.toString() : v), 2));
171
+ }
172
+
173
+ function copyColumn() {
174
+ if (!ctxMenu) return;
175
+ const col = ctxMenu.colName;
176
+ const values = rows.map((r) => {
177
+ const v = r[col];
178
+ return v == null ? 'NULL' : typeof v === 'bigint' ? v.toString() : String(v);
179
+ });
180
+ copyToClipboard(values.join('\n'));
181
+ }
182
+
183
+ // ── Cell rendering ──
184
+
185
+ function formatCell(value: any, category: TypeCategory): string {
186
+ if (value === null || value === undefined) return 'NULL';
187
+ if (typeof value === 'boolean') return '';
188
+ if (category === 'date' && (value instanceof Date || typeof value === 'number')) {
189
+ try {
190
+ const d = value instanceof Date ? value : new Date(value);
191
+ return d.toLocaleString();
192
+ } catch {
193
+ return String(value);
194
+ }
195
+ }
196
+ if (typeof value === 'bigint') return value.toString();
197
+ if (typeof value === 'object') {
198
+ return JSON.stringify(value, (_k, v) => (typeof v === 'bigint' ? v.toString() : v));
199
+ }
200
+ return String(value);
201
+ }
202
+
203
+ function isNull(value: any): boolean {
204
+ return value === null || value === undefined;
205
+ }
206
+ </script>
207
+
208
+ <svelte:window onclick={() => (ctxMenu = null)} onkeydown={(e) => { if (e.key === 'Escape') ctxMenu = null; }} />
209
+
210
+ <div class="flex-1 overflow-auto" onscroll={onScroll}>
211
+ <table
212
+ class="border-collapse"
213
+ style="table-layout: fixed; width: {tableWidth}px;"
214
+ >
215
+ <colgroup>
216
+ <col style="width: {ROW_NUM_WIDTH}px" />
217
+ {#each columns as col}
218
+ <col style="width: {columnWidths[col] || DEFAULT_WIDTH}px" />
219
+ {/each}
220
+ </colgroup>
221
+
222
+ <thead class="sticky top-0 z-10">
223
+ <tr class="bg-zinc-100 dark:bg-zinc-900">
224
+ <th
225
+ class="border-b border-e border-zinc-200 px-2 py-2 text-start text-xs font-medium text-zinc-400 dark:border-zinc-700 dark:text-zinc-500"
226
+ >
227
+ #
228
+ </th>
229
+ {#each columns as col}
230
+ {@const category = columnCategories[col]}
231
+ <th
232
+ class="group relative select-none border-b border-e border-zinc-200 px-3 py-1.5 dark:border-zinc-700"
233
+ class:text-start={category !== 'number'}
234
+ class:text-end={category === 'number'}
235
+ class:cursor-pointer={!!onSort}
236
+ onclick={() => handleHeaderClick(col)}
237
+ >
238
+ <div class="flex items-center gap-1.5" class:justify-end={category === 'number'}>
239
+ <span
240
+ class="inline-flex h-4 shrink-0 items-center rounded border px-1 text-[9px] font-semibold leading-none {typeBadgeClass(category)}"
241
+ title={columnTypes[col] || 'unknown'}
242
+ >
243
+ {typeLabel(category)}
244
+ </span>
245
+ <span class="truncate text-xs font-semibold text-zinc-700 dark:text-zinc-300">{col}</span>
246
+ {#if sortColumn === col}
247
+ {#if sortDirection === 'asc'}
248
+ <ArrowUpIcon class="size-3 shrink-0 text-blue-500" />
249
+ {:else if sortDirection === 'desc'}
250
+ <ArrowDownIcon class="size-3 shrink-0 text-blue-500" />
251
+ {/if}
252
+ {/if}
253
+ </div>
254
+ {#if columnTypes[col]}
255
+ <div class="mt-0.5 truncate text-[10px] font-normal text-zinc-400 dark:text-zinc-500">
256
+ {columnTypes[col]}
257
+ </div>
258
+ {/if}
259
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
260
+ <div
261
+ class="absolute end-0 top-0 h-full w-1.5 cursor-col-resize bg-transparent transition-colors hover:bg-blue-400/60"
262
+ onmousedown={(e) => startResize(col, e)}
263
+ ondblclick={(e) => { e.stopPropagation(); resetWidth(col); }}
264
+ role="separator"
265
+ aria-orientation="vertical"
266
+ ></div>
267
+ </th>
268
+ {/each}
269
+ </tr>
270
+ </thead>
271
+
272
+ <tbody>
273
+ {#each displayRows as row, i (i)}
274
+ <tr class="hover:bg-blue-50/50 dark:hover:bg-zinc-800/40">
275
+ <td
276
+ class="border-b border-e border-zinc-100 px-2 py-1 text-xs tabular-nums text-zinc-400 dark:border-zinc-800 dark:text-zinc-600"
277
+ >
278
+ {i + 1}
279
+ </td>
280
+ {#each columns as col}
281
+ {@const category = columnCategories[col]}
282
+ {@const cellValue = row[col]}
283
+ {@const cellIsNull = isNull(cellValue)}
284
+ <td
285
+ class="overflow-hidden text-ellipsis whitespace-nowrap border-b border-e border-zinc-100 px-3 py-1 text-[13px] dark:border-zinc-800"
286
+ class:text-end={category === 'number' && !cellIsNull}
287
+ class:font-mono={category === 'number' && !cellIsNull}
288
+ title={cellIsNull ? 'NULL' : formatCell(cellValue, category)}
289
+ oncontextmenu={(e) => handleContextMenu(e, cellValue, row, col)}
290
+ >
291
+ {#if cellIsNull}
292
+ <span class="text-[11px] italic text-zinc-400 dark:text-zinc-600">null</span>
293
+ {:else if typeof cellValue === 'boolean'}
294
+ {#if cellValue}
295
+ <CheckIcon class="inline size-3.5 text-green-500" />
296
+ {:else}
297
+ <XIcon class="inline size-3.5 text-red-400" />
298
+ {/if}
299
+ {:else}
300
+ <span class="text-zinc-800 dark:text-zinc-200">
301
+ {formatCell(cellValue, category)}
302
+ </span>
303
+ {/if}
304
+ </td>
305
+ {/each}
306
+ </tr>
307
+ {/each}
308
+ </tbody>
309
+ </table>
310
+
311
+ {#if renderedCount < rows.length}
312
+ <div class="py-2 text-center text-xs text-zinc-400 dark:text-zinc-600">
313
+ {t('statusBar.rowsLabel')}: {renderedCount.toLocaleString()} / {rows.length.toLocaleString()} — scroll for more
314
+ </div>
315
+ {/if}
316
+ </div>
317
+
318
+ <!-- Context menu -->
319
+ {#if ctxMenu}
320
+ <div
321
+ class="fixed z-50 min-w-40 rounded-lg border border-zinc-200 bg-white py-1 shadow-xl dark:border-zinc-700 dark:bg-zinc-800"
322
+ style="left: {ctxMenu.x}px; top: {ctxMenu.y}px;"
323
+ role="menu"
324
+ >
325
+ <button
326
+ class="flex w-full items-center gap-2 px-3 py-1.5 text-start text-xs text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
327
+ onclick={copyCell}
328
+ role="menuitem"
329
+ >
330
+ <ClipboardIcon class="size-3.5 text-zinc-400" />
331
+ {t('table.copyCell')}
332
+ </button>
333
+ <button
334
+ class="flex w-full items-center gap-2 px-3 py-1.5 text-start text-xs text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
335
+ onclick={copyRow}
336
+ role="menuitem"
337
+ >
338
+ <RowsIcon class="size-3.5 text-zinc-400" />
339
+ {t('table.copyRow')}
340
+ </button>
341
+ <button
342
+ class="flex w-full items-center gap-2 px-3 py-1.5 text-start text-xs text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-700"
343
+ onclick={copyColumn}
344
+ role="menuitem"
345
+ >
346
+ <ColumnsIcon class="size-3.5 text-zinc-400" />
347
+ {t('table.copyColumn')}
348
+ </button>
349
+ {#if copied}
350
+ <div class="border-t border-zinc-200 px-3 py-1 text-center text-[10px] text-green-500 dark:border-zinc-700">
351
+ Copied!
352
+ </div>
353
+ {/if}
354
+ </div>
355
+ {/if}
@@ -0,0 +1,12 @@
1
+ type $$ComponentProps = {
2
+ columns: string[];
3
+ rows: Record<string, any>[];
4
+ totalRows?: number;
5
+ columnTypes?: Record<string, string>;
6
+ sortColumn?: string | null;
7
+ sortDirection?: 'asc' | 'desc' | null;
8
+ onSort?: (column: string, direction: 'asc' | 'desc' | null) => void;
9
+ };
10
+ declare const TableGrid: import("svelte").Component<$$ComponentProps, {}, "">;
11
+ type TableGrid = ReturnType<typeof TableGrid>;
12
+ export default TableGrid;
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
3
+ import DownloadIcon from '@lucide/svelte/icons/download';
4
+ import { t } from '../../i18n/index.svelte.js';
5
+ import { exportToCsv, exportToJson } from '../../utils/export.js';
6
+
7
+ let {
8
+ rowCount = 0,
9
+ executionTimeMs = 0,
10
+ loading = false,
11
+ columns = [] as string[],
12
+ rows = [] as Record<string, any>[],
13
+ fileName = 'export'
14
+ }: {
15
+ rowCount?: number;
16
+ executionTimeMs?: number;
17
+ loading?: boolean;
18
+ columns?: string[];
19
+ rows?: Record<string, any>[];
20
+ fileName?: string;
21
+ } = $props();
22
+
23
+ let exportOpen = $state(false);
24
+
25
+ function handleExportCsv() {
26
+ exportToCsv(columns, rows, fileName);
27
+ exportOpen = false;
28
+ }
29
+
30
+ function handleExportJson() {
31
+ exportToJson(columns, rows, fileName);
32
+ exportOpen = false;
33
+ }
34
+
35
+ function handleClickOutside(e: MouseEvent) {
36
+ exportOpen = false;
37
+ }
38
+ </script>
39
+
40
+ <svelte:window onclick={() => { if (exportOpen) exportOpen = false; }} />
41
+
42
+ <div class="flex h-7 items-center justify-between border-t border-zinc-200 bg-zinc-50 px-3 text-xs text-zinc-500 dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-400">
43
+ <!-- Left side -->
44
+ <div>
45
+ {#if loading}
46
+ <span class="animate-pulse">{t('statusBar.runningQuery')}</span>
47
+ {:else if rowCount > 0}
48
+ <span>{rowCount.toLocaleString()} {t('statusBar.rowsLabel')}</span>
49
+ {#if executionTimeMs > 0}
50
+ <span class="text-zinc-400 dark:text-zinc-500"> {t('statusBar.inTime', { time: executionTimeMs })}</span>
51
+ {/if}
52
+ {:else}
53
+ <span>{t('statusBar.noResults')}</span>
54
+ {/if}
55
+ </div>
56
+
57
+ <!-- Right side: export dropdown -->
58
+ <div class="relative">
59
+ <button
60
+ class="flex items-center gap-1 rounded px-1.5 py-0.5 hover:bg-zinc-200 dark:hover:bg-zinc-800"
61
+ onclick={(e) => { e.stopPropagation(); exportOpen = !exportOpen; }}
62
+ disabled={rows.length === 0}
63
+ class:opacity-40={rows.length === 0}
64
+ >
65
+ <DownloadIcon class="size-3" />
66
+ <span>{t('statusBar.export')}</span>
67
+ <ChevronDownIcon class="size-3" />
68
+ </button>
69
+
70
+ {#if exportOpen}
71
+ <div
72
+ class="absolute bottom-full end-0 mb-1 w-32 rounded border border-zinc-200 bg-white py-1 shadow-lg dark:border-zinc-700 dark:bg-zinc-800"
73
+ role="menu"
74
+ >
75
+ <button
76
+ class="w-full px-3 py-1.5 text-start text-xs hover:bg-zinc-100 dark:hover:bg-zinc-700"
77
+ onclick={(e) => { e.stopPropagation(); handleExportCsv(); }}
78
+ role="menuitem"
79
+ >
80
+ {t('statusBar.exportCsv')}
81
+ </button>
82
+ <button
83
+ class="w-full px-3 py-1.5 text-start text-xs hover:bg-zinc-100 dark:hover:bg-zinc-700"
84
+ onclick={(e) => { e.stopPropagation(); handleExportJson(); }}
85
+ role="menuitem"
86
+ >
87
+ {t('statusBar.exportJson')}
88
+ </button>
89
+ </div>
90
+ {/if}
91
+ </div>
92
+ </div>
@@ -0,0 +1,11 @@
1
+ type $$ComponentProps = {
2
+ rowCount?: number;
3
+ executionTimeMs?: number;
4
+ loading?: boolean;
5
+ columns?: string[];
6
+ rows?: Record<string, any>[];
7
+ fileName?: string;
8
+ };
9
+ declare const TableStatusBar: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type TableStatusBar = ReturnType<typeof TableStatusBar>;
11
+ export default TableStatusBar;