@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.
- package/README.md +11 -2
- package/dist/components/browser/FileBrowser.svelte +41 -54
- package/dist/components/browser/FileTreeSidebar.svelte +43 -7
- package/dist/components/layout/ConnectionDialog.svelte +100 -1
- package/dist/components/layout/Sidebar.svelte +43 -25
- package/dist/components/viewers/CodeViewer.svelte +23 -0
- package/dist/components/viewers/CogControls.svelte +208 -0
- package/dist/components/viewers/CogControls.svelte.d.ts +12 -0
- package/dist/components/viewers/CogViewer.svelte +353 -1160
- package/dist/components/viewers/CogViewer.svelte.d.ts +1 -1
- package/dist/components/viewers/DatabaseViewer.svelte +345 -37
- package/dist/components/viewers/MarkdownViewer.svelte +1 -1
- package/dist/components/viewers/TableViewer.svelte +123 -41
- package/dist/components/viewers/ZarrMapViewer.svelte +29 -0
- package/dist/components/viewers/ZarrViewer.svelte +1 -4
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +6 -2
- package/dist/file-icons/index.d.ts +1 -1
- package/dist/file-icons/index.js +12 -2
- package/dist/i18n/ar.js +24 -0
- package/dist/i18n/en.js +24 -0
- package/dist/i18n/index.svelte.d.ts +0 -1
- package/dist/i18n/index.svelte.js +0 -3
- package/dist/index.d.ts +11 -0
- package/dist/index.js +10 -0
- package/dist/query/engine.d.ts +20 -4
- package/dist/query/index.d.ts +2 -1
- package/dist/query/index.js +1 -0
- package/dist/query/source.d.ts +30 -0
- package/dist/query/source.js +37 -0
- package/dist/query/wasm.d.ts +7 -5
- package/dist/query/wasm.js +138 -85
- package/dist/storage/providers.d.ts +47 -0
- package/dist/storage/providers.js +160 -0
- package/dist/stores/connections.svelte.js +5 -31
- package/dist/stores/files.svelte.d.ts +2 -8
- package/dist/stores/files.svelte.js +5 -38
- package/dist/stores/query-history.svelte.js +3 -25
- package/dist/stores/settings.svelte.d.ts +1 -0
- package/dist/stores/settings.svelte.js +10 -30
- package/dist/stores/tabs.svelte.d.ts +9 -2
- package/dist/stores/tabs.svelte.js +11 -2
- package/dist/types.d.ts +11 -0
- package/dist/utils/cloud-url.d.ts +27 -0
- package/dist/utils/cloud-url.js +61 -0
- package/dist/utils/cog.d.ts +244 -0
- package/dist/utils/cog.js +1039 -0
- package/dist/utils/deck.d.ts +0 -18
- package/dist/utils/deck.js +0 -36
- package/dist/utils/export.d.ts +22 -2
- package/dist/utils/export.js +35 -10
- package/dist/utils/file-sort.d.ts +20 -0
- package/dist/utils/file-sort.js +41 -0
- package/dist/utils/geometry-type.d.ts +52 -0
- package/dist/utils/geometry-type.js +76 -0
- package/dist/utils/local-storage.d.ts +16 -0
- package/dist/utils/local-storage.js +37 -0
- package/dist/utils/markdown-sql.d.ts +1 -1
- package/dist/utils/markdown-sql.js +3 -4
- package/dist/utils/pmtiles-tile.d.ts +0 -2
- package/dist/utils/pmtiles-tile.js +0 -8
- package/dist/utils/url-state.d.ts +6 -0
- package/dist/utils/url-state.js +34 -26
- package/dist/utils/url.d.ts +13 -25
- package/dist/utils/url.js +17 -78
- package/dist/utils/zarr-tab.d.ts +22 -0
- package/dist/utils/zarr-tab.js +30 -0
- package/dist/utils/zarr.d.ts +0 -2
- package/dist/utils/zarr.js +73 -44
- package/package.json +50 -46
- package/dist/components/ui/tabs/index.d.ts +0 -5
- package/dist/components/ui/tabs/index.js +0 -7
- package/dist/components/ui/tabs/tabs-content.svelte +0 -17
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +0 -4
- package/dist/components/ui/tabs/tabs-list.svelte +0 -16
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +0 -4
- package/dist/components/ui/tabs/tabs-trigger.svelte +0 -20
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +0 -4
- package/dist/components/ui/tabs/tabs.svelte +0 -19
- package/dist/components/ui/tabs/tabs.svelte.d.ts +0 -4
- package/dist/components/viewers/MapViewer.svelte +0 -234
- package/dist/components/viewers/MapViewer.svelte.d.ts +0 -7
- package/dist/components/viewers/StyleEditorOverlay.svelte +0 -27
- 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;
|