@walkthru-earth/objex 1.0.0 → 1.2.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 (84) hide show
  1. package/README.md +11 -2
  2. package/dist/components/browser/FileBrowser.svelte +41 -54
  3. package/dist/components/browser/FileTreeSidebar.svelte +43 -7
  4. package/dist/components/layout/ConnectionDialog.svelte +100 -1
  5. package/dist/components/layout/Sidebar.svelte +43 -25
  6. package/dist/components/viewers/CodeViewer.svelte +23 -0
  7. package/dist/components/viewers/CogControls.svelte +208 -0
  8. package/dist/components/viewers/CogControls.svelte.d.ts +12 -0
  9. package/dist/components/viewers/CogViewer.svelte +353 -1160
  10. package/dist/components/viewers/CogViewer.svelte.d.ts +1 -1
  11. package/dist/components/viewers/DatabaseViewer.svelte +345 -37
  12. package/dist/components/viewers/MarkdownViewer.svelte +1 -1
  13. package/dist/components/viewers/TableViewer.svelte +123 -41
  14. package/dist/components/viewers/ZarrMapViewer.svelte +29 -0
  15. package/dist/components/viewers/ZarrViewer.svelte +1 -4
  16. package/dist/constants.d.ts +6 -2
  17. package/dist/constants.js +6 -2
  18. package/dist/file-icons/index.d.ts +1 -1
  19. package/dist/file-icons/index.js +12 -2
  20. package/dist/i18n/ar.js +24 -0
  21. package/dist/i18n/en.js +24 -0
  22. package/dist/i18n/index.svelte.d.ts +0 -1
  23. package/dist/i18n/index.svelte.js +0 -3
  24. package/dist/index.d.ts +11 -0
  25. package/dist/index.js +10 -0
  26. package/dist/query/engine.d.ts +20 -4
  27. package/dist/query/index.d.ts +2 -1
  28. package/dist/query/index.js +1 -0
  29. package/dist/query/source.d.ts +30 -0
  30. package/dist/query/source.js +37 -0
  31. package/dist/query/wasm.d.ts +7 -5
  32. package/dist/query/wasm.js +138 -85
  33. package/dist/storage/providers.d.ts +47 -0
  34. package/dist/storage/providers.js +160 -0
  35. package/dist/stores/connections.svelte.js +5 -31
  36. package/dist/stores/files.svelte.d.ts +2 -8
  37. package/dist/stores/files.svelte.js +5 -38
  38. package/dist/stores/query-history.svelte.js +3 -25
  39. package/dist/stores/settings.svelte.d.ts +1 -0
  40. package/dist/stores/settings.svelte.js +10 -30
  41. package/dist/stores/tabs.svelte.d.ts +9 -2
  42. package/dist/stores/tabs.svelte.js +11 -2
  43. package/dist/types.d.ts +11 -0
  44. package/dist/utils/cloud-url.d.ts +27 -0
  45. package/dist/utils/cloud-url.js +61 -0
  46. package/dist/utils/cog.d.ts +244 -0
  47. package/dist/utils/cog.js +1039 -0
  48. package/dist/utils/deck.d.ts +0 -18
  49. package/dist/utils/deck.js +0 -36
  50. package/dist/utils/export.d.ts +22 -2
  51. package/dist/utils/export.js +35 -10
  52. package/dist/utils/file-sort.d.ts +20 -0
  53. package/dist/utils/file-sort.js +41 -0
  54. package/dist/utils/geometry-type.d.ts +52 -0
  55. package/dist/utils/geometry-type.js +76 -0
  56. package/dist/utils/local-storage.d.ts +16 -0
  57. package/dist/utils/local-storage.js +37 -0
  58. package/dist/utils/markdown-sql.d.ts +1 -1
  59. package/dist/utils/markdown-sql.js +3 -4
  60. package/dist/utils/pmtiles-tile.d.ts +0 -2
  61. package/dist/utils/pmtiles-tile.js +0 -8
  62. package/dist/utils/url-state.d.ts +6 -0
  63. package/dist/utils/url-state.js +34 -26
  64. package/dist/utils/url.d.ts +13 -25
  65. package/dist/utils/url.js +17 -78
  66. package/dist/utils/zarr-tab.d.ts +22 -0
  67. package/dist/utils/zarr-tab.js +30 -0
  68. package/dist/utils/zarr.d.ts +0 -2
  69. package/dist/utils/zarr.js +73 -44
  70. package/package.json +50 -46
  71. package/dist/components/ui/tabs/index.d.ts +0 -5
  72. package/dist/components/ui/tabs/index.js +0 -7
  73. package/dist/components/ui/tabs/tabs-content.svelte +0 -17
  74. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +0 -4
  75. package/dist/components/ui/tabs/tabs-list.svelte +0 -16
  76. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +0 -4
  77. package/dist/components/ui/tabs/tabs-trigger.svelte +0 -20
  78. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +0 -4
  79. package/dist/components/ui/tabs/tabs.svelte +0 -19
  80. package/dist/components/ui/tabs/tabs.svelte.d.ts +0 -4
  81. package/dist/components/viewers/MapViewer.svelte +0 -234
  82. package/dist/components/viewers/MapViewer.svelte.d.ts +0 -7
  83. package/dist/components/viewers/StyleEditorOverlay.svelte +0 -27
  84. package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +0 -7
@@ -0,0 +1,208 @@
1
+ <script lang="ts">
2
+ import { t } from '../../i18n/index.svelte.js';
3
+ import {
4
+ type BandConfig,
5
+ COLOR_RAMP_STOPS,
6
+ type ColorRampId,
7
+ DEFAULT_RESCALE,
8
+ type RescaleConfig,
9
+ rampToGradientCss
10
+ } from '../../utils/cog.js';
11
+
12
+ let {
13
+ bandCount,
14
+ bandConfig,
15
+ onConfigChange,
16
+ rescale,
17
+ rescaleApplicable,
18
+ onRescaleChange
19
+ }: {
20
+ bandCount: number;
21
+ bandConfig: BandConfig;
22
+ onConfigChange: (config: BandConfig) => void;
23
+ rescale: RescaleConfig;
24
+ rescaleApplicable: boolean;
25
+ onRescaleChange: (rescale: RescaleConfig) => void;
26
+ } = $props();
27
+
28
+ const RAMP_IDS: ColorRampId[] = ['grayscale', 'terrain', 'viridis', 'magma', 'turbo', 'spectral'];
29
+
30
+ function bandOptions(count: number): { value: number; label: string }[] {
31
+ return Array.from({ length: count }, (_, i) => ({
32
+ value: i,
33
+ label: `${t('cog.band')} ${i + 1}`
34
+ }));
35
+ }
36
+
37
+ function setMode(mode: 'rgb' | 'single') {
38
+ onConfigChange({ ...bandConfig, mode });
39
+ }
40
+
41
+ function setBand(key: 'rBand' | 'gBand' | 'bBand' | 'band', value: number) {
42
+ onConfigChange({ ...bandConfig, [key]: value });
43
+ }
44
+
45
+ function setRamp(id: ColorRampId) {
46
+ onConfigChange({ ...bandConfig, colorRamp: id });
47
+ }
48
+
49
+ function setRescaleMin(value: number) {
50
+ // Keep min strictly less than max, clamp to [0, 1].
51
+ const clamped = Math.max(0, Math.min(1, value));
52
+ const next = Math.min(clamped, rescale.max - 0.001);
53
+ onRescaleChange({ min: Number.isFinite(next) ? next : 0, max: rescale.max });
54
+ }
55
+
56
+ function setRescaleMax(value: number) {
57
+ const clamped = Math.max(0, Math.min(1, value));
58
+ const next = Math.max(clamped, rescale.min + 0.001);
59
+ onRescaleChange({ min: rescale.min, max: Number.isFinite(next) ? next : 1 });
60
+ }
61
+
62
+ function resetRescale() {
63
+ onRescaleChange({ ...DEFAULT_RESCALE });
64
+ }
65
+ </script>
66
+
67
+ <div
68
+ class="absolute right-2 top-10 z-10 w-52 rounded bg-card/90 p-2.5 text-xs text-card-foreground backdrop-blur-sm"
69
+ >
70
+ <!-- Mode toggle -->
71
+ <div class="mb-2 flex gap-1">
72
+ <button
73
+ class="flex-1 rounded px-2 py-1 transition-colors"
74
+ class:bg-primary={bandConfig.mode === 'rgb'}
75
+ class:text-primary-foreground={bandConfig.mode === 'rgb'}
76
+ class:bg-muted={bandConfig.mode !== 'rgb'}
77
+ onclick={() => setMode('rgb')}
78
+ >
79
+ RGB
80
+ </button>
81
+ <button
82
+ class="flex-1 rounded px-2 py-1 transition-colors"
83
+ class:bg-primary={bandConfig.mode === 'single'}
84
+ class:text-primary-foreground={bandConfig.mode === 'single'}
85
+ class:bg-muted={bandConfig.mode !== 'single'}
86
+ onclick={() => setMode('single')}
87
+ >
88
+ {t('cog.singleBand')}
89
+ </button>
90
+ </div>
91
+
92
+ {#if bandConfig.mode === 'rgb'}
93
+ <!-- RGB band selectors -->
94
+ <div class="space-y-1">
95
+ {#each [
96
+ { key: 'rBand' as const, label: 'R', color: 'text-red-400' },
97
+ { key: 'gBand' as const, label: 'G', color: 'text-green-400' },
98
+ { key: 'bBand' as const, label: 'B', color: 'text-blue-400' }
99
+ ] as ch}
100
+ <div class="flex items-center gap-2">
101
+ <span class="w-3 font-bold {ch.color}">{ch.label}</span>
102
+ <select
103
+ class="flex-1 rounded border border-border bg-background px-1.5 py-0.5 text-xs"
104
+ value={bandConfig[ch.key]}
105
+ onchange={(e) =>
106
+ setBand(ch.key, Number((e.target as HTMLSelectElement).value))}
107
+ >
108
+ {#each bandOptions(bandCount) as opt}
109
+ <option value={opt.value}>{opt.label}</option>
110
+ {/each}
111
+ </select>
112
+ </div>
113
+ {/each}
114
+ </div>
115
+ {:else}
116
+ <!-- Single band selector -->
117
+ <div class="mb-2 flex items-center gap-2">
118
+ <span class="text-muted-foreground">{t('cog.band')}</span>
119
+ <select
120
+ class="flex-1 rounded border border-border bg-background px-1.5 py-0.5 text-xs"
121
+ value={bandConfig.band}
122
+ onchange={(e) =>
123
+ setBand('band', Number((e.target as HTMLSelectElement).value))}
124
+ >
125
+ {#each bandOptions(bandCount) as opt}
126
+ <option value={opt.value}>{opt.label}</option>
127
+ {/each}
128
+ </select>
129
+ </div>
130
+
131
+ <!-- Color ramp picker -->
132
+ <div class="space-y-1">
133
+ <span class="text-muted-foreground">{t('cog.colorRamp')}</span>
134
+ <div class="grid grid-cols-2 gap-1">
135
+ {#each RAMP_IDS as id}
136
+ <button
137
+ class="flex flex-col items-stretch rounded border px-1 py-0.5 transition-colors {bandConfig.colorRamp === id ? 'border-primary bg-muted' : 'border-transparent'}"
138
+ onclick={() => setRamp(id)}
139
+ title={id}
140
+ >
141
+ <div
142
+ class="h-2.5 w-full rounded-sm"
143
+ style="background: {rampToGradientCss(id)}"
144
+ ></div>
145
+ <span class="mt-0.5 text-center text-[10px] capitalize text-muted-foreground">
146
+ {id}
147
+ </span>
148
+ </button>
149
+ {/each}
150
+ </div>
151
+ </div>
152
+ {/if}
153
+
154
+ {#if rescaleApplicable}
155
+ <!-- GPU LinearRescale slider. Default uint pipeline only. -->
156
+ <div class="mt-2 space-y-1 border-t border-border pt-2">
157
+ <div class="flex items-center justify-between">
158
+ <span class="text-muted-foreground">{t('cog.rescale')}</span>
159
+ <button
160
+ class="text-[10px] text-muted-foreground hover:text-card-foreground"
161
+ onclick={resetRescale}
162
+ >
163
+ {t('cog.rescaleReset')}
164
+ </button>
165
+ </div>
166
+ <div class="flex items-center gap-1.5">
167
+ <input
168
+ type="number"
169
+ min="0"
170
+ max="1"
171
+ step="0.01"
172
+ class="w-14 rounded border border-border bg-background px-1 py-0.5 text-[11px] tabular-nums"
173
+ value={rescale.min}
174
+ oninput={(e) => setRescaleMin(Number((e.target as HTMLInputElement).value))}
175
+ />
176
+ <input
177
+ type="range"
178
+ min="0"
179
+ max="1"
180
+ step="0.01"
181
+ class="flex-1 accent-primary"
182
+ value={rescale.min}
183
+ oninput={(e) => setRescaleMin(Number((e.target as HTMLInputElement).value))}
184
+ />
185
+ </div>
186
+ <div class="flex items-center gap-1.5">
187
+ <input
188
+ type="number"
189
+ min="0"
190
+ max="1"
191
+ step="0.01"
192
+ class="w-14 rounded border border-border bg-background px-1 py-0.5 text-[11px] tabular-nums"
193
+ value={rescale.max}
194
+ oninput={(e) => setRescaleMax(Number((e.target as HTMLInputElement).value))}
195
+ />
196
+ <input
197
+ type="range"
198
+ min="0"
199
+ max="1"
200
+ step="0.01"
201
+ class="flex-1 accent-primary"
202
+ value={rescale.max}
203
+ oninput={(e) => setRescaleMax(Number((e.target as HTMLInputElement).value))}
204
+ />
205
+ </div>
206
+ </div>
207
+ {/if}
208
+ </div>
@@ -0,0 +1,12 @@
1
+ import { type BandConfig, type RescaleConfig } from '../../utils/cog.js';
2
+ type $$ComponentProps = {
3
+ bandCount: number;
4
+ bandConfig: BandConfig;
5
+ onConfigChange: (config: BandConfig) => void;
6
+ rescale: RescaleConfig;
7
+ rescaleApplicable: boolean;
8
+ onRescaleChange: (rescale: RescaleConfig) => void;
9
+ };
10
+ declare const CogControls: import("svelte").Component<$$ComponentProps, {}, "">;
11
+ type CogControls = ReturnType<typeof CogControls>;
12
+ export default CogControls;