triiiceratops 0.9.13 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ArrowCounterClockwise-C6n_F9YZ.js +136 -0
- package/dist/X-BUzsFa3u.js +886 -0
- package/dist/annotation_tool_point-CCJi2I8J.js +290 -0
- package/dist/components/AnnotationOverlay.svelte +179 -86
- package/dist/components/LeftFab.svelte +21 -9
- package/dist/components/OSDViewer.svelte +20 -3
- package/dist/components/ThumbnailGallery.svelte +4 -4
- package/dist/components/TriiiceratopsViewer.svelte +167 -49
- package/dist/components/TriiiceratopsViewer.svelte.d.ts +5 -5
- package/dist/components/TriiiceratopsViewerElement.svelte +2 -2
- package/dist/components/TriiiceratopsViewerElement.svelte.d.ts +2 -2
- package/dist/custom-element.d.ts +10 -0
- package/dist/custom-element.js +13 -0
- package/dist/image_filters_reset-CWe7vTJU.js +108 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/paraglide/messages/_index.d.ts +30 -0
- package/dist/paraglide/messages/_index.js +31 -1
- package/dist/paraglide/messages/annotation_editor_add_content.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_add_content.js +34 -0
- package/dist/paraglide/messages/annotation_editor_cancel.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_cancel.js +34 -0
- package/dist/paraglide/messages/annotation_editor_create_mode.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_create_mode.js +34 -0
- package/dist/paraglide/messages/annotation_editor_delete.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_delete.js +34 -0
- package/dist/paraglide/messages/annotation_editor_delete_message.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_delete_message.js +34 -0
- package/dist/paraglide/messages/annotation_editor_delete_title.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_delete_title.js +34 -0
- package/dist/paraglide/messages/annotation_editor_delete_tooltip.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_delete_tooltip.js +34 -0
- package/dist/paraglide/messages/annotation_editor_edit_mode.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_edit_mode.js +34 -0
- package/dist/paraglide/messages/annotation_editor_edit_section.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_edit_section.js +34 -0
- package/dist/paraglide/messages/annotation_editor_instruction_create.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_instruction_create.js +34 -0
- package/dist/paraglide/messages/annotation_editor_instruction_edit.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_instruction_edit.js +34 -0
- package/dist/paraglide/messages/annotation_editor_link_placeholder.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_link_placeholder.js +34 -0
- package/dist/paraglide/messages/annotation_editor_redo.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_redo.js +34 -0
- package/dist/paraglide/messages/annotation_editor_save.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_save.js +34 -0
- package/dist/paraglide/messages/annotation_editor_tag_placeholder.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_tag_placeholder.js +34 -0
- package/dist/paraglide/messages/annotation_editor_text_placeholder.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_text_placeholder.js +34 -0
- package/dist/paraglide/messages/annotation_editor_title.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_title.js +34 -0
- package/dist/paraglide/messages/annotation_editor_tool_label.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_tool_label.js +34 -0
- package/dist/paraglide/messages/annotation_editor_undo.d.ts +4 -0
- package/dist/paraglide/messages/annotation_editor_undo.js +34 -0
- package/dist/paraglide/messages/annotation_tool_point.d.ts +4 -0
- package/dist/paraglide/messages/annotation_tool_point.js +34 -0
- package/dist/paraglide/messages/annotation_tool_polygon.d.ts +4 -0
- package/dist/paraglide/messages/annotation_tool_polygon.js +34 -0
- package/dist/paraglide/messages/annotation_tool_rectangle.d.ts +4 -0
- package/dist/paraglide/messages/annotation_tool_rectangle.js +34 -0
- package/dist/paraglide/messages/image_adjustments_title.d.ts +4 -0
- package/dist/paraglide/messages/image_adjustments_title.js +34 -0
- package/dist/paraglide/messages/image_filters_brightness.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_brightness.js +34 -0
- package/dist/paraglide/messages/image_filters_contrast.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_contrast.js +34 -0
- package/dist/paraglide/messages/image_filters_effects.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_effects.js +34 -0
- package/dist/paraglide/messages/image_filters_grayscale.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_grayscale.js +34 -0
- package/dist/paraglide/messages/image_filters_invert.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_invert.js +34 -0
- package/dist/paraglide/messages/image_filters_reset.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_reset.js +34 -0
- package/dist/paraglide/messages/image_filters_saturation.d.ts +4 -0
- package/dist/paraglide/messages/image_filters_saturation.js +34 -0
- package/dist/paraglide/messages/plugins_tooltip.js +1 -1
- package/dist/plugins/annotation-editor/AnnotationEditorController.svelte +166 -0
- package/dist/plugins/annotation-editor/AnnotationEditorController.svelte.d.ts +9 -0
- package/dist/plugins/annotation-editor/AnnotationEditorPanel.svelte +315 -0
- package/dist/plugins/annotation-editor/AnnotationEditorPanel.svelte.d.ts +24 -0
- package/dist/plugins/annotation-editor/AnnotationManager.svelte.d.ts +39 -0
- package/dist/plugins/annotation-editor/AnnotationManager.svelte.js +433 -0
- package/dist/plugins/annotation-editor/adapters/LocalStorageAdapter.d.ts +20 -0
- package/dist/plugins/annotation-editor/adapters/LocalStorageAdapter.js +67 -0
- package/dist/plugins/annotation-editor/adapters/index.d.ts +2 -0
- package/dist/plugins/annotation-editor/adapters/index.js +1 -0
- package/dist/plugins/annotation-editor/adapters/types.d.ts +23 -0
- package/dist/plugins/annotation-editor/adapters/types.js +1 -0
- package/dist/plugins/annotation-editor/iife-entry.d.ts +15 -0
- package/dist/plugins/annotation-editor/iife-entry.js +35 -0
- package/dist/plugins/annotation-editor/index.d.ts +41 -0
- package/dist/plugins/annotation-editor/index.js +57 -0
- package/dist/plugins/annotation-editor/loader.svelte.d.ts +7 -0
- package/dist/plugins/annotation-editor/loader.svelte.js +32 -0
- package/dist/plugins/annotation-editor/types.d.ts +41 -0
- package/dist/plugins/annotation-editor/types.js +13 -0
- package/dist/plugins/annotation-editor.js +32824 -0
- package/dist/plugins/image-manipulation/ImageManipulationController.svelte +54 -0
- package/dist/plugins/image-manipulation/ImageManipulationController.svelte.d.ts +6 -0
- package/dist/plugins/image-manipulation/ImageManipulationPanel.svelte +19 -9
- package/dist/plugins/image-manipulation/ImageManipulationPanel.svelte.d.ts +1 -0
- package/dist/plugins/image-manipulation/iife-entry.d.ts +13 -0
- package/dist/plugins/image-manipulation/iife-entry.js +17 -0
- package/dist/plugins/image-manipulation/index.d.ts +15 -1
- package/dist/plugins/image-manipulation/index.js +21 -1
- package/dist/plugins/image-manipulation.js +265 -0
- package/dist/state/i18n.svelte.js +4 -2
- package/dist/state/manifests.svelte.d.ts +7 -2
- package/dist/state/manifests.svelte.js +45 -13
- package/dist/state/viewer.svelte.d.ts +16 -13
- package/dist/state/viewer.svelte.js +75 -84
- package/dist/triiiceratops-bundle.js +3260 -3155
- package/dist/triiiceratops-element.css +1 -0
- package/dist/triiiceratops-element.iife.js +99 -0
- package/dist/triiiceratops.css +1 -1
- package/dist/types/plugin.d.ts +21 -62
- package/dist/types/plugin.js +1 -23
- package/dist/utils/annotationAdapter.d.ts +12 -1
- package/dist/utils/annotationAdapter.js +98 -39
- package/package.json +13 -6
- package/dist/chunks/TriiiceratopsViewer-EViTQO_n.js +0 -10437
- package/dist/chunks/openseadragon-CHvATAD9.js +0 -12427
- package/dist/components/TriiiceratopsViewerElementImage.svelte +0 -143
- package/dist/components/TriiiceratopsViewerElementImage.svelte.d.ts +0 -27
- package/dist/custom-element-image.d.ts +0 -1
- package/dist/custom-element-image.js +0 -2
- package/dist/plugins/image-manipulation/ImageManipulationPlugin.svelte.d.ts +0 -19
- package/dist/plugins/image-manipulation/ImageManipulationPlugin.svelte.js +0 -87
- package/dist/triiiceratops-element-image.js +0 -555
- package/dist/triiiceratops-element.js +0 -114
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
$props();
|
|
12
12
|
|
|
13
13
|
let container: HTMLElement | undefined = $state();
|
|
14
|
-
let viewer: any | undefined = $state();
|
|
14
|
+
let viewer: any | undefined = $state.raw();
|
|
15
15
|
let OSD: any | undefined = $state();
|
|
16
16
|
|
|
17
17
|
// Track OSD state changes for reactivity
|
|
@@ -61,6 +61,12 @@
|
|
|
61
61
|
|
|
62
62
|
const results: any[] = [];
|
|
63
63
|
|
|
64
|
+
// Check if annotation editor is open to prevent double rendering
|
|
65
|
+
const editorPanel = viewerState.pluginPanels.find(
|
|
66
|
+
(p) => p.id === 'annotation-editor:panel',
|
|
67
|
+
);
|
|
68
|
+
const isEditorOpen = editorPanel ? editorPanel.isVisible() : false;
|
|
69
|
+
|
|
64
70
|
for (const anno of parsedAnnotations) {
|
|
65
71
|
// Filter based on visibility
|
|
66
72
|
if (anno.isSearchHit) {
|
|
@@ -96,7 +102,9 @@
|
|
|
96
102
|
height: pixelRect.height,
|
|
97
103
|
},
|
|
98
104
|
isSearchHit: anno.isSearchHit,
|
|
99
|
-
tooltip: anno.body.value,
|
|
105
|
+
tooltip: anno.body.map((b) => b.value).join(' '),
|
|
106
|
+
// Disable pointer events if editor is open so blue annotations can be selected
|
|
107
|
+
pointerEvents: isEditorOpen ? 'none' : 'auto',
|
|
100
108
|
});
|
|
101
109
|
} else if (anno.geometry.type === 'POLYGON') {
|
|
102
110
|
// Convert each point from image to viewport to pixel
|
|
@@ -140,7 +148,8 @@
|
|
|
140
148
|
},
|
|
141
149
|
points: relativePoints,
|
|
142
150
|
isSearchHit: anno.isSearchHit,
|
|
143
|
-
tooltip: anno.body.value,
|
|
151
|
+
tooltip: anno.body.map((b) => b.value).join(' '),
|
|
152
|
+
pointerEvents: isEditorOpen ? 'none' : 'auto',
|
|
144
153
|
});
|
|
145
154
|
}
|
|
146
155
|
}
|
|
@@ -170,6 +179,10 @@
|
|
|
170
179
|
animationTime: 0.5,
|
|
171
180
|
springStiffness: 7.0,
|
|
172
181
|
zoomPerClick: 2.0,
|
|
182
|
+
// Disable click-to-zoom to allow Annotorious click drawing
|
|
183
|
+
gestureSettingsMouse: {
|
|
184
|
+
clickToZoom: false,
|
|
185
|
+
},
|
|
173
186
|
});
|
|
174
187
|
|
|
175
188
|
// Notify plugins that OSD is ready
|
|
@@ -228,6 +241,7 @@
|
|
|
228
241
|
{#each renderedAnnotations as anno (anno.id)}
|
|
229
242
|
{#if anno.type === 'RECTANGLE'}
|
|
230
243
|
<div
|
|
244
|
+
id="annotation-visual-{anno.id}"
|
|
231
245
|
class="absolute border-2 transition-colors cursor-pointer pointer-events-auto {anno.isSearchHit
|
|
232
246
|
? 'border-yellow-400 bg-yellow-400/40 hover:bg-yellow-400/60'
|
|
233
247
|
: 'border-red-500 bg-red-500/20 hover:bg-red-500/40'}"
|
|
@@ -236,6 +250,7 @@
|
|
|
236
250
|
top: {anno.rect.y}px;
|
|
237
251
|
width: {anno.rect.width}px;
|
|
238
252
|
height: {anno.rect.height}px;
|
|
253
|
+
pointer-events: {anno.pointerEvents};
|
|
239
254
|
"
|
|
240
255
|
title={anno.tooltip}
|
|
241
256
|
></div>
|
|
@@ -247,10 +262,12 @@
|
|
|
247
262
|
top: {anno.bounds.y}px;
|
|
248
263
|
width: {anno.bounds.width}px;
|
|
249
264
|
height: {anno.bounds.height}px;
|
|
265
|
+
pointer-events: {anno.pointerEvents};
|
|
250
266
|
"
|
|
251
267
|
>
|
|
252
268
|
<title>{anno.tooltip}</title>
|
|
253
269
|
<polygon
|
|
270
|
+
id="annotation-visual-{anno.id}"
|
|
254
271
|
points={anno.points.map((p: any) => p.join(',')).join(' ')}
|
|
255
272
|
class="cursor-pointer transition-colors {anno.isSearchHit
|
|
256
273
|
? 'fill-yellow-400/40 stroke-yellow-400 hover:fill-yellow-400/60'
|
|
@@ -483,7 +483,7 @@
|
|
|
483
483
|
|
|
484
484
|
<!-- Content (Grid or Horizontal Scroll) -->
|
|
485
485
|
<div
|
|
486
|
-
class="flex-1
|
|
486
|
+
class="flex-1 px-1 bg-base-100 {isHorizontal
|
|
487
487
|
? 'overflow-x-auto overflow-y-hidden h-full'
|
|
488
488
|
: 'overflow-y-auto overflow-x-hidden'}"
|
|
489
489
|
>
|
|
@@ -493,12 +493,12 @@
|
|
|
493
493
|
: 'grid gap-2'}
|
|
494
494
|
style={isHorizontal
|
|
495
495
|
? ''
|
|
496
|
-
: 'grid-template-columns: repeat(auto-fill, minmax(
|
|
496
|
+
: 'grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));'}
|
|
497
497
|
>
|
|
498
498
|
{#each thumbnails as thumb}
|
|
499
499
|
<button
|
|
500
500
|
class="group flex flex-col gap-1 p-1 rounded hover:bg-base-200 transition-colors text-left relative shrink-0 {isHorizontal
|
|
501
|
-
? 'w-[
|
|
501
|
+
? 'w-[90px]'
|
|
502
502
|
: ''} {viewerState.canvasId === thumb.id
|
|
503
503
|
? 'ring-2 ring-primary bg-primary/5'
|
|
504
504
|
: ''}"
|
|
@@ -506,7 +506,7 @@
|
|
|
506
506
|
aria-label="Select canvas {thumb.label}"
|
|
507
507
|
>
|
|
508
508
|
<div
|
|
509
|
-
class="aspect-4
|
|
509
|
+
class="aspect-3/4 bg-base-300 rounded overflow-hidden relative w-full flex items-center justify-center"
|
|
510
510
|
>
|
|
511
511
|
{#if thumb.src}
|
|
512
512
|
<img
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { setContext, onDestroy } from 'svelte';
|
|
2
|
+
import { setContext, onDestroy, untrack } from 'svelte';
|
|
3
3
|
import { ViewerState, VIEWER_STATE_KEY } from '../state/viewer.svelte';
|
|
4
|
-
import type {
|
|
4
|
+
import type { PluginDef } from '../types/plugin';
|
|
5
5
|
import type { DaisyUITheme, ThemeConfig } from '../theme/types';
|
|
6
6
|
import type { ViewerConfig } from '../types/config';
|
|
7
7
|
import { applyTheme } from '../theme/themeManager';
|
|
@@ -13,23 +13,15 @@
|
|
|
13
13
|
import LeftFab from './LeftFab.svelte';
|
|
14
14
|
import MetadataDialog from './MetadataDialog.svelte';
|
|
15
15
|
import SearchPanel from './SearchPanel.svelte';
|
|
16
|
-
import { m } from '../state/i18n.svelte';
|
|
16
|
+
import { m, language } from '../state/i18n.svelte';
|
|
17
17
|
|
|
18
18
|
// SSR-safe browser detection for library consumers
|
|
19
19
|
const browser = typeof window !== 'undefined';
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
manifestId,
|
|
23
|
-
canvasId,
|
|
24
|
-
plugins = [],
|
|
25
|
-
theme,
|
|
26
|
-
themeConfig,
|
|
27
|
-
config = {},
|
|
28
|
-
viewerState = $bindable(),
|
|
29
|
-
}: {
|
|
21
|
+
interface Props {
|
|
30
22
|
manifestId?: string;
|
|
31
23
|
canvasId?: string;
|
|
32
|
-
plugins?:
|
|
24
|
+
plugins?: PluginDef[];
|
|
33
25
|
/** Built-in DaisyUI theme name. Defaults to 'light' or 'dark' based on prefers-color-scheme. */
|
|
34
26
|
theme?: DaisyUITheme;
|
|
35
27
|
/** Custom theme configuration to override the base theme's values. */
|
|
@@ -38,7 +30,17 @@
|
|
|
38
30
|
config?: ViewerConfig;
|
|
39
31
|
/** Bindable viewer state instance for external access (Svelte consumers) */
|
|
40
32
|
viewerState?: ViewerState;
|
|
41
|
-
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let {
|
|
36
|
+
manifestId,
|
|
37
|
+
canvasId,
|
|
38
|
+
plugins = [],
|
|
39
|
+
theme,
|
|
40
|
+
themeConfig,
|
|
41
|
+
config = {},
|
|
42
|
+
viewerState = $bindable(),
|
|
43
|
+
}: Props = $props();
|
|
42
44
|
|
|
43
45
|
// Reference to root element for applying theme
|
|
44
46
|
let rootElement: HTMLElement | undefined = $state();
|
|
@@ -101,11 +103,45 @@
|
|
|
101
103
|
}
|
|
102
104
|
});
|
|
103
105
|
|
|
104
|
-
// Register plugins reactively
|
|
106
|
+
// Register plugins reactively with cleanup
|
|
107
|
+
let registeredPluginIds: string[] = [];
|
|
108
|
+
|
|
105
109
|
$effect(() => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
// Create dependency on plugins prop by accessing it
|
|
111
|
+
const currentPlugins = plugins;
|
|
112
|
+
|
|
113
|
+
// Use untrack so that operations inside (like registerPlugin accessing/writing state)
|
|
114
|
+
// do NOT become dependencies of this effect. This prevents infinite loops.
|
|
115
|
+
untrack(() => {
|
|
116
|
+
// Cleanup previous plugins first
|
|
117
|
+
for (const id of registeredPluginIds) {
|
|
118
|
+
internalViewerState.unregisterPlugin(id);
|
|
119
|
+
}
|
|
120
|
+
registeredPluginIds = [];
|
|
121
|
+
|
|
122
|
+
// Register new plugins
|
|
123
|
+
for (const plugin of currentPlugins) {
|
|
124
|
+
const id =
|
|
125
|
+
plugin.id ||
|
|
126
|
+
`plugin-${Math.random().toString(36).substr(2, 9)}`;
|
|
127
|
+
// Create a copy with the ID to ensure stability for THIS registration
|
|
128
|
+
const defWithId = { ...plugin, id };
|
|
129
|
+
internalViewerState.registerPlugin(defWithId);
|
|
130
|
+
registeredPluginIds.push(id);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Cleanup on effect re-run
|
|
135
|
+
return () => {
|
|
136
|
+
for (const id of registeredPluginIds) {
|
|
137
|
+
internalViewerState.unregisterPlugin(id);
|
|
138
|
+
}
|
|
139
|
+
registeredPluginIds = [];
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
onDestroy(() => {
|
|
144
|
+
internalViewerState.destroyAllPlugins();
|
|
109
145
|
});
|
|
110
146
|
|
|
111
147
|
$effect(() => {
|
|
@@ -140,10 +176,45 @@
|
|
|
140
176
|
),
|
|
141
177
|
);
|
|
142
178
|
|
|
143
|
-
let manifestData = $derived(internalViewerState.
|
|
179
|
+
let manifestData = $derived(internalViewerState.manifestEntry);
|
|
144
180
|
let canvases = $derived(internalViewerState.canvases);
|
|
145
181
|
let currentCanvasIndex = $derived(internalViewerState.currentCanvasIndex);
|
|
146
182
|
|
|
183
|
+
// Effect to trigger deferred search once manifest is loaded
|
|
184
|
+
$effect(() => {
|
|
185
|
+
if (
|
|
186
|
+
internalViewerState.pendingSearchQuery &&
|
|
187
|
+
manifestData &&
|
|
188
|
+
!manifestData.isFetching &&
|
|
189
|
+
!manifestData.error &&
|
|
190
|
+
manifestData.manifesto
|
|
191
|
+
) {
|
|
192
|
+
const query = internalViewerState.pendingSearchQuery;
|
|
193
|
+
internalViewerState.pendingSearchQuery = null;
|
|
194
|
+
console.log(
|
|
195
|
+
'[Viewer] Manifest loaded, triggering deferred search:',
|
|
196
|
+
query,
|
|
197
|
+
);
|
|
198
|
+
internalViewerState.search(query);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Auto-select first canvas if none selected
|
|
203
|
+
$effect(() => {
|
|
204
|
+
if (
|
|
205
|
+
canvases &&
|
|
206
|
+
canvases.length > 0 &&
|
|
207
|
+
!internalViewerState.canvasId &&
|
|
208
|
+
!manifestData?.isFetching
|
|
209
|
+
) {
|
|
210
|
+
console.log(
|
|
211
|
+
'[Viewer] Auto-selecting first canvas:',
|
|
212
|
+
canvases[0].id,
|
|
213
|
+
);
|
|
214
|
+
internalViewerState.setCanvas(canvases[0].id);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
147
218
|
let tileSources = $derived.by(() => {
|
|
148
219
|
if (
|
|
149
220
|
!canvases ||
|
|
@@ -187,13 +258,19 @@
|
|
|
187
258
|
else if (body) resource = body;
|
|
188
259
|
}
|
|
189
260
|
|
|
190
|
-
// Check if resource is valid (Manifesto sometimes returns empty objects for v3 bodies)
|
|
191
|
-
|
|
261
|
+
// Check if resource is valid (Manifesto sometimes returns empty wrapper objects for v3 bodies)
|
|
262
|
+
// The wrapper may have getServices() that returns manifest-level services, so we can't rely on that.
|
|
263
|
+
// Instead, check if the resource has actual content (id, __jsonld, or a service property)
|
|
264
|
+
const resourceJson = resource?.__jsonld || resource;
|
|
265
|
+
const hasContent =
|
|
192
266
|
resource &&
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
267
|
+
(resource.id ||
|
|
268
|
+
resource['@id'] ||
|
|
269
|
+
(resourceJson &&
|
|
270
|
+
(resourceJson.service ||
|
|
271
|
+
resourceJson.id ||
|
|
272
|
+
resourceJson['@id'])));
|
|
273
|
+
if (resource && !hasContent) {
|
|
197
274
|
resource = null;
|
|
198
275
|
}
|
|
199
276
|
|
|
@@ -214,28 +291,27 @@
|
|
|
214
291
|
const getId = (thing: any) => thing.id || thing['@id'];
|
|
215
292
|
|
|
216
293
|
// Start of service detection logic
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
294
|
+
// Check raw json service FIRST - Manifesto's getServices() often returns
|
|
295
|
+
// manifest-level services instead of the image body's services
|
|
296
|
+
let services: any[] = [];
|
|
297
|
+
const rJson = resource.__jsonld || resource;
|
|
298
|
+
if (rJson.service) {
|
|
299
|
+
services = Array.isArray(rJson.service)
|
|
300
|
+
? rJson.service
|
|
301
|
+
: [rJson.service];
|
|
220
302
|
}
|
|
221
303
|
|
|
222
|
-
// Fallback
|
|
223
|
-
if (!services.length) {
|
|
224
|
-
|
|
225
|
-
// console.log('Checking raw resource for services:', rJson);
|
|
226
|
-
if (rJson.service) {
|
|
227
|
-
services = Array.isArray(rJson.service)
|
|
228
|
-
? rJson.service
|
|
229
|
-
: [rJson.service];
|
|
230
|
-
}
|
|
304
|
+
// Fallback to getServices() only if raw json didn't have services
|
|
305
|
+
if (!services.length && resource.getServices) {
|
|
306
|
+
services = resource.getServices();
|
|
231
307
|
}
|
|
232
308
|
|
|
233
|
-
// console.log('Found services:', services);
|
|
234
|
-
|
|
235
309
|
if (services.length > 0) {
|
|
236
310
|
// Find a valid image service
|
|
237
311
|
const service = services.find((s: any) => {
|
|
238
|
-
const type = s.getType
|
|
312
|
+
const type = s.getType
|
|
313
|
+
? s.getType()
|
|
314
|
+
: s.type || s['@type'] || '';
|
|
239
315
|
const profile = s.getProfile ? s.getProfile() : s.profile || '';
|
|
240
316
|
return (
|
|
241
317
|
type === 'ImageService1' ||
|
|
@@ -299,7 +375,7 @@
|
|
|
299
375
|
>
|
|
300
376
|
<!-- Gallery (when docked left) -->
|
|
301
377
|
{#if internalViewerState.showThumbnailGallery && internalViewerState.dockSide === 'left'}
|
|
302
|
-
<div class="h-full w-[
|
|
378
|
+
<div class="h-full w-[140px] pointer-events-auto relative">
|
|
303
379
|
<ThumbnailGallery {canvases} />
|
|
304
380
|
</div>
|
|
305
381
|
{/if}
|
|
@@ -307,7 +383,10 @@
|
|
|
307
383
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
308
384
|
{#if panel.isVisible() && panel.position === 'left'}
|
|
309
385
|
<div class="h-full relative pointer-events-auto">
|
|
310
|
-
<panel.component
|
|
386
|
+
<panel.component
|
|
387
|
+
{...panel.props ?? {}}
|
|
388
|
+
locale={language.current}
|
|
389
|
+
/>
|
|
311
390
|
</div>
|
|
312
391
|
{/if}
|
|
313
392
|
{/each}
|
|
@@ -322,7 +401,7 @@
|
|
|
322
401
|
<!-- Top Area (Gallery) -->
|
|
323
402
|
{#if internalViewerState.showThumbnailGallery && internalViewerState.dockSide === 'top'}
|
|
324
403
|
<div
|
|
325
|
-
class="flex-none h-[
|
|
404
|
+
class="flex-none h-[160px] w-full pointer-events-auto relative z-20"
|
|
326
405
|
>
|
|
327
406
|
<ThumbnailGallery {canvases} />
|
|
328
407
|
</div>
|
|
@@ -355,7 +434,7 @@
|
|
|
355
434
|
viewerState={internalViewerState}
|
|
356
435
|
/>
|
|
357
436
|
{/key}
|
|
358
|
-
{:else}
|
|
437
|
+
{:else if manifestData && !manifestData.isFetching && !tileSources}
|
|
359
438
|
<div
|
|
360
439
|
class="w-full h-full flex items-center justify-center text-base-content/50"
|
|
361
440
|
>
|
|
@@ -378,7 +457,10 @@
|
|
|
378
457
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
379
458
|
{#if panel.isVisible() && panel.position === 'overlay'}
|
|
380
459
|
<div class="absolute inset-0 z-40 pointer-events-none">
|
|
381
|
-
<panel.component
|
|
460
|
+
<panel.component
|
|
461
|
+
{...panel.props ?? {}}
|
|
462
|
+
locale={language.current}
|
|
463
|
+
/>
|
|
382
464
|
</div>
|
|
383
465
|
{/if}
|
|
384
466
|
{/each}
|
|
@@ -397,7 +479,7 @@
|
|
|
397
479
|
<!-- Bottom Area (Gallery) -->
|
|
398
480
|
{#if internalViewerState.showThumbnailGallery && internalViewerState.dockSide === 'bottom'}
|
|
399
481
|
<div
|
|
400
|
-
class="flex-none h-[
|
|
482
|
+
class="flex-none h-[160px] w-full pointer-events-auto relative z-20"
|
|
401
483
|
>
|
|
402
484
|
<ThumbnailGallery {canvases} />
|
|
403
485
|
</div>
|
|
@@ -407,7 +489,10 @@
|
|
|
407
489
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
408
490
|
{#if panel.isVisible() && panel.position === 'bottom'}
|
|
409
491
|
<div class="relative w-full z-40 pointer-events-auto">
|
|
410
|
-
<panel.component
|
|
492
|
+
<panel.component
|
|
493
|
+
{...panel.props ?? {}}
|
|
494
|
+
locale={language.current}
|
|
495
|
+
/>
|
|
411
496
|
</div>
|
|
412
497
|
{/if}
|
|
413
498
|
{/each}
|
|
@@ -430,7 +515,7 @@
|
|
|
430
515
|
|
|
431
516
|
<!-- Gallery (when docked right) -->
|
|
432
517
|
{#if internalViewerState.showThumbnailGallery && internalViewerState.dockSide === 'right'}
|
|
433
|
-
<div class="h-full w-[
|
|
518
|
+
<div class="h-full w-[140px] pointer-events-auto relative">
|
|
434
519
|
<ThumbnailGallery {canvases} />
|
|
435
520
|
</div>
|
|
436
521
|
{/if}
|
|
@@ -439,10 +524,43 @@
|
|
|
439
524
|
{#each internalViewerState.pluginPanels as panel (panel.id)}
|
|
440
525
|
{#if panel.isVisible() && panel.position === 'right'}
|
|
441
526
|
<div class="h-full relative pointer-events-auto">
|
|
442
|
-
<panel.component
|
|
527
|
+
<panel.component
|
|
528
|
+
{...panel.props ?? {}}
|
|
529
|
+
locale={language.current}
|
|
530
|
+
/>
|
|
443
531
|
</div>
|
|
444
532
|
{/if}
|
|
445
533
|
{/each}
|
|
446
534
|
</div>
|
|
447
535
|
{/if}
|
|
448
536
|
</div>
|
|
537
|
+
|
|
538
|
+
<style>
|
|
539
|
+
/* Scoped scrollbar styles for the viewer */
|
|
540
|
+
:global(#triiiceratops-viewer *) {
|
|
541
|
+
scrollbar-width: thin;
|
|
542
|
+
scrollbar-color: var(--fallback-bc, oklch(var(--bc) / 0.2)) transparent;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
:global(#triiiceratops-viewer ::-webkit-scrollbar) {
|
|
546
|
+
width: 4px;
|
|
547
|
+
height: 4px;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
:global(#triiiceratops-viewer ::-webkit-scrollbar-track) {
|
|
551
|
+
background: transparent;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
:global(#triiiceratops-viewer ::-webkit-scrollbar-thumb) {
|
|
555
|
+
background-color: var(--fallback-bc, oklch(var(--bc) / 0.2));
|
|
556
|
+
border-radius: 9999px;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
:global(#triiiceratops-viewer ::-webkit-scrollbar-thumb:hover) {
|
|
560
|
+
background-color: var(--fallback-bc, oklch(var(--bc) / 0.4));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
:global(#triiiceratops-viewer ::-webkit-scrollbar-corner) {
|
|
564
|
+
background: transparent;
|
|
565
|
+
}
|
|
566
|
+
</style>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ViewerState } from '../state/viewer.svelte';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PluginDef } from '../types/plugin';
|
|
3
3
|
import type { DaisyUITheme, ThemeConfig } from '../theme/types';
|
|
4
4
|
import type { ViewerConfig } from '../types/config';
|
|
5
|
-
|
|
5
|
+
interface Props {
|
|
6
6
|
manifestId?: string;
|
|
7
7
|
canvasId?: string;
|
|
8
|
-
plugins?:
|
|
8
|
+
plugins?: PluginDef[];
|
|
9
9
|
/** Built-in DaisyUI theme name. Defaults to 'light' or 'dark' based on prefers-color-scheme. */
|
|
10
10
|
theme?: DaisyUITheme;
|
|
11
11
|
/** Custom theme configuration to override the base theme's values. */
|
|
@@ -14,7 +14,7 @@ type $$ComponentProps = {
|
|
|
14
14
|
config?: ViewerConfig;
|
|
15
15
|
/** Bindable viewer state instance for external access (Svelte consumers) */
|
|
16
16
|
viewerState?: ViewerState;
|
|
17
|
-
}
|
|
18
|
-
declare const TriiiceratopsViewer: import("svelte").Component
|
|
17
|
+
}
|
|
18
|
+
declare const TriiiceratopsViewer: import("svelte").Component<Props, {}, "viewerState">;
|
|
19
19
|
type TriiiceratopsViewer = ReturnType<typeof TriiiceratopsViewer>;
|
|
20
20
|
export default TriiiceratopsViewer;
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
<script lang="ts">
|
|
36
36
|
import styles from '../../app.css?inline';
|
|
37
37
|
import TriiiceratopsViewer from './TriiiceratopsViewer.svelte';
|
|
38
|
-
import type {
|
|
38
|
+
import type { PluginDef } from '../types/plugin';
|
|
39
39
|
import type { DaisyUITheme, ThemeConfig } from '../theme/types';
|
|
40
40
|
import type { ViewerConfig } from '../types/config';
|
|
41
41
|
import { isBuiltInTheme, parseThemeConfig } from '../theme/themeManager';
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}: {
|
|
52
52
|
manifestId?: string;
|
|
53
53
|
canvasId?: string;
|
|
54
|
-
plugins?:
|
|
54
|
+
plugins?: PluginDef[];
|
|
55
55
|
/**
|
|
56
56
|
* Built-in DaisyUI theme name (e.g., 'light', 'dark', 'cupcake').
|
|
57
57
|
* When not specified, inherits the theme from the parent context.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PluginDef } from '../types/plugin';
|
|
2
2
|
import type { ThemeConfig } from '../theme/types';
|
|
3
3
|
import type { ViewerConfig } from '../types/config';
|
|
4
4
|
type $$ComponentProps = {
|
|
5
5
|
manifestId?: string;
|
|
6
6
|
canvasId?: string;
|
|
7
|
-
plugins?:
|
|
7
|
+
plugins?: PluginDef[];
|
|
8
8
|
/**
|
|
9
9
|
* Built-in DaisyUI theme name (e.g., 'light', 'dark', 'cupcake').
|
|
10
10
|
* When not specified, inherits the theme from the parent context.
|
package/dist/custom-element.d.ts
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
+
import * as svelte from 'svelte';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__TriiiceratopsSvelteRuntime: {
|
|
5
|
+
svelte: typeof svelte;
|
|
6
|
+
internal: unknown;
|
|
7
|
+
};
|
|
8
|
+
TriiiceratopsPlugins?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
1
11
|
import './components/TriiiceratopsViewerElement.svelte';
|
package/dist/custom-element.js
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
// Entry point for custom element build
|
|
2
2
|
// Importing this module registers the <triiiceratops-viewer> custom element
|
|
3
|
+
// Expose Svelte internals for IIFE plugin builds
|
|
4
|
+
// Plugins built as IIFE need to share the same Svelte runtime instance
|
|
5
|
+
// so that getContext/setContext work correctly across bundle boundaries
|
|
6
|
+
// @ts-expect-error - svelte/internal/client is not typed but exists at runtime
|
|
7
|
+
import * as svelteInternal from 'svelte/internal/client';
|
|
8
|
+
import * as svelte from 'svelte';
|
|
9
|
+
window.__TriiiceratopsSvelteRuntime = {
|
|
10
|
+
svelte,
|
|
11
|
+
internal: svelteInternal,
|
|
12
|
+
};
|
|
13
|
+
// Initialize the plugins namespace
|
|
14
|
+
window.TriiiceratopsPlugins = window.TriiiceratopsPlugins || {};
|
|
15
|
+
// Register the custom element
|
|
3
16
|
import './components/TriiiceratopsViewerElement.svelte';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { a as t } from "./X-BUzsFa3u.js";
|
|
2
|
+
const s = (
|
|
3
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
4
|
+
() => (
|
|
5
|
+
/** @type {LocalizedString} */
|
|
6
|
+
"Image Adjustments"
|
|
7
|
+
)
|
|
8
|
+
), a = (
|
|
9
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
10
|
+
() => (
|
|
11
|
+
/** @type {LocalizedString} */
|
|
12
|
+
"Bildanpassungen"
|
|
13
|
+
)
|
|
14
|
+
), v = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? s() : a(), l = (
|
|
15
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
16
|
+
() => (
|
|
17
|
+
/** @type {LocalizedString} */
|
|
18
|
+
"Brightness"
|
|
19
|
+
)
|
|
20
|
+
), i = (
|
|
21
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
22
|
+
() => (
|
|
23
|
+
/** @type {LocalizedString} */
|
|
24
|
+
"Helligkeit"
|
|
25
|
+
)
|
|
26
|
+
), y = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? l() : i(), o = (
|
|
27
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
28
|
+
() => (
|
|
29
|
+
/** @type {LocalizedString} */
|
|
30
|
+
"Contrast"
|
|
31
|
+
)
|
|
32
|
+
), c = (
|
|
33
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
34
|
+
() => (
|
|
35
|
+
/** @type {LocalizedString} */
|
|
36
|
+
"Kontrast"
|
|
37
|
+
)
|
|
38
|
+
), B = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? o() : c(), _ = (
|
|
39
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
40
|
+
() => (
|
|
41
|
+
/** @type {LocalizedString} */
|
|
42
|
+
"Saturation"
|
|
43
|
+
)
|
|
44
|
+
), u = (
|
|
45
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
46
|
+
() => (
|
|
47
|
+
/** @type {LocalizedString} */
|
|
48
|
+
"Sättigung"
|
|
49
|
+
)
|
|
50
|
+
), C = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? _() : u(), f = (
|
|
51
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
52
|
+
() => (
|
|
53
|
+
/** @type {LocalizedString} */
|
|
54
|
+
"Effects"
|
|
55
|
+
)
|
|
56
|
+
), g = (
|
|
57
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
58
|
+
() => (
|
|
59
|
+
/** @type {LocalizedString} */
|
|
60
|
+
"Effekte"
|
|
61
|
+
)
|
|
62
|
+
), E = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? f() : g(), m = (
|
|
63
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
64
|
+
() => (
|
|
65
|
+
/** @type {LocalizedString} */
|
|
66
|
+
"Invert Colors"
|
|
67
|
+
)
|
|
68
|
+
), d = (
|
|
69
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
70
|
+
() => (
|
|
71
|
+
/** @type {LocalizedString} */
|
|
72
|
+
"Farben umkehren"
|
|
73
|
+
)
|
|
74
|
+
), G = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? m() : d(), p = (
|
|
75
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
76
|
+
() => (
|
|
77
|
+
/** @type {LocalizedString} */
|
|
78
|
+
"Grayscale"
|
|
79
|
+
)
|
|
80
|
+
), b = (
|
|
81
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
82
|
+
() => (
|
|
83
|
+
/** @type {LocalizedString} */
|
|
84
|
+
"Graustufen"
|
|
85
|
+
)
|
|
86
|
+
), I = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? p() : b(), h = (
|
|
87
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
88
|
+
() => (
|
|
89
|
+
/** @type {LocalizedString} */
|
|
90
|
+
"Reset to Default"
|
|
91
|
+
)
|
|
92
|
+
), j = (
|
|
93
|
+
/** @type {(inputs: {}) => LocalizedString} */
|
|
94
|
+
() => (
|
|
95
|
+
/** @type {LocalizedString} */
|
|
96
|
+
"Zurücksetzen"
|
|
97
|
+
)
|
|
98
|
+
), S = /* @__NO_SIDE_EFFECTS__ */ (n = {}, e = {}) => (e.locale ?? t()) === "en" ? h() : j();
|
|
99
|
+
export {
|
|
100
|
+
y as a,
|
|
101
|
+
B as b,
|
|
102
|
+
E as c,
|
|
103
|
+
I as d,
|
|
104
|
+
G as e,
|
|
105
|
+
S as f,
|
|
106
|
+
C as g,
|
|
107
|
+
v as i
|
|
108
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,7 @@ export { default as TriiiceratopsViewer } from './components/TriiiceratopsViewer
|
|
|
2
2
|
export { ViewerState, VIEWER_STATE_KEY } from './state/viewer.svelte';
|
|
3
3
|
export type { ViewerStateSnapshot } from './state/viewer.svelte';
|
|
4
4
|
export { ManifestsState } from './state/manifests.svelte';
|
|
5
|
-
export type {
|
|
6
|
-
export { BasePlugin } from './types/plugin';
|
|
5
|
+
export type { PluginDef, PluginMenuButton, PluginPanel } from './types/plugin';
|
|
7
6
|
export type { ThemeConfig, DaisyUITheme } from './theme/types';
|
|
8
7
|
export { DAISYUI_THEMES } from './theme/types';
|
|
9
8
|
export { applyTheme, applyBuiltInTheme, applyThemeConfig, clearThemeConfig, isBuiltInTheme, parseThemeConfig, } from './theme/themeManager';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,6 @@ export { default as TriiiceratopsViewer } from './components/TriiiceratopsViewer
|
|
|
3
3
|
// Type exports for TypeScript users
|
|
4
4
|
export { ViewerState, VIEWER_STATE_KEY } from './state/viewer.svelte';
|
|
5
5
|
export { ManifestsState } from './state/manifests.svelte';
|
|
6
|
-
export { BasePlugin } from './types/plugin';
|
|
7
6
|
export { DAISYUI_THEMES } from './theme/types';
|
|
8
7
|
export { applyTheme, applyBuiltInTheme, applyThemeConfig, clearThemeConfig, isBuiltInTheme, parseThemeConfig, } from './theme/themeManager';
|
|
9
8
|
export { hexToOklch, normalizeColor } from './theme/colorUtils';
|